| @ -0,0 +1,8 @@ | |||
| # Default ignored files | |||
| /shelf/ | |||
| /workspace.xml | |||
| # Editor-based HTTP Client requests | |||
| /httpRequests/ | |||
| # Datasource local storage ignored files | |||
| /dataSources/ | |||
| /dataSources.local.xml | |||
| @ -0,0 +1,33 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project version="4"> | |||
| <component name="CompilerConfiguration"> | |||
| <annotationProcessing> | |||
| <profile name="Maven default annotation processors profile" enabled="true"> | |||
| <sourceOutputDir name="target/generated-sources/annotations" /> | |||
| <sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> | |||
| <outputRelativeToContentRoot value="true" /> | |||
| <module name="module-system" /> | |||
| <module name="jeecg-system-cloud-api" /> | |||
| <module name="base-tools" /> | |||
| <module name="module-pay" /> | |||
| <module name="base-core" /> | |||
| <module name="module-common" /> | |||
| <module name="jeecg-system-local-api" /> | |||
| </profile> | |||
| </annotationProcessing> | |||
| </component> | |||
| <component name="JavacSettings"> | |||
| <option name="ADDITIONAL_OPTIONS_OVERRIDE"> | |||
| <module name="base-api" options="-parameters" /> | |||
| <module name="base-core" options="-parameters" /> | |||
| <module name="base-tools" options="-parameters" /> | |||
| <module name="jeecg-system-cloud-api" options="-parameters" /> | |||
| <module name="jeecg-system-local-api" options="-parameters" /> | |||
| <module name="module-base" options="-parameters" /> | |||
| <module name="module-common" options="-parameters" /> | |||
| <module name="module-pay" options="-parameters" /> | |||
| <module name="module-system" options="-parameters" /> | |||
| <module name="popularize-admin" options="-parameters" /> | |||
| </option> | |||
| </component> | |||
| </project> | |||
| @ -0,0 +1,15 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project version="4"> | |||
| <component name="Encoding"> | |||
| <file url="file://$PROJECT_DIR$/module-base/base-api/jeecg-system-cloud-api/src/main/java" charset="UTF-8" /> | |||
| <file url="file://$PROJECT_DIR$/module-base/base-api/jeecg-system-local-api/src/main/java" charset="UTF-8" /> | |||
| <file url="file://$PROJECT_DIR$/module-base/base-api/src/main/java" charset="UTF-8" /> | |||
| <file url="file://$PROJECT_DIR$/module-base/base-core/src/main/java" charset="UTF-8" /> | |||
| <file url="file://$PROJECT_DIR$/module-base/base-tools/src/main/java" charset="UTF-8" /> | |||
| <file url="file://$PROJECT_DIR$/module-base/src/main/java" charset="UTF-8" /> | |||
| <file url="file://$PROJECT_DIR$/module-common/src/main/java" charset="UTF-8" /> | |||
| <file url="file://$PROJECT_DIR$/module-pay/src/main/java" charset="UTF-8" /> | |||
| <file url="file://$PROJECT_DIR$/module-system/src/main/java" charset="UTF-8" /> | |||
| <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" /> | |||
| </component> | |||
| </project> | |||
| @ -0,0 +1,30 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project version="4"> | |||
| <component name="RemoteRepositoriesConfiguration"> | |||
| <remote-repository> | |||
| <option name="id" value="jeecg" /> | |||
| <option name="name" value="jeecg Repository" /> | |||
| <option name="url" value="https://maven.jeecg.org/nexus/content/repositories/jeecg" /> | |||
| </remote-repository> | |||
| <remote-repository> | |||
| <option name="id" value="aliyun" /> | |||
| <option name="name" value="aliyun Repository" /> | |||
| <option name="url" value="https://maven.aliyun.com/repository/public" /> | |||
| </remote-repository> | |||
| <remote-repository> | |||
| <option name="id" value="central" /> | |||
| <option name="name" value="Central Repository" /> | |||
| <option name="url" value="https://repo.maven.apache.org/maven2" /> | |||
| </remote-repository> | |||
| <remote-repository> | |||
| <option name="id" value="central" /> | |||
| <option name="name" value="Maven Central repository" /> | |||
| <option name="url" value="https://repo1.maven.org/maven2" /> | |||
| </remote-repository> | |||
| <remote-repository> | |||
| <option name="id" value="jboss.community" /> | |||
| <option name="name" value="JBoss Community repository" /> | |||
| <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> | |||
| </remote-repository> | |||
| </component> | |||
| </project> | |||
| @ -0,0 +1,12 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project version="4"> | |||
| <component name="ExternalStorageConfigurationManager" enabled="true" /> | |||
| <component name="MavenProjectsManager"> | |||
| <option name="originalFiles"> | |||
| <list> | |||
| <option value="$PROJECT_DIR$/pom.xml" /> | |||
| </list> | |||
| </option> | |||
| </component> | |||
| <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK" /> | |||
| </project> | |||
| @ -0,0 +1,6 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project version="4"> | |||
| <component name="VcsDirectoryMappings"> | |||
| <mapping directory="" vcs="Git" /> | |||
| </component> | |||
| </project> | |||
| @ -1,3 +1,195 @@ | |||
| # popularize-admin | |||
| Jeecg-Boot 低代码开发平台 | |||
| =============== | |||
| 推广小程序后台代码 | |||
| 当前最新版本: 3.2.0(发布日期:20220425) | |||
| ## 后端技术架构 | |||
| - 基础框架:Spring Boot 2.6.6 | |||
| - 持久层框架:Mybatis-plus 3.5.1 | |||
| - 安全框架:Apache Shiro 1.8.0,Jwt 3.11.0 | |||
| - 数据库连接池:阿里巴巴Druid 1.1.22 | |||
| - 缓存框架:redis | |||
| - 日志打印:logback | |||
| - 其他:fastjson,poi,Swagger-ui,quartz, lombok(简化代码)等。 | |||
| ## 开发环境 | |||
| - 语言:Java 8 | |||
| - IDE(JAVA): Eclipse安装lombok插件 或者 IDEA | |||
| - 依赖管理:Maven | |||
| - 数据库:MySQL5.7+ & Oracle 11g & SqlServer & postgresql & 国产等更多数据库 | |||
| - 缓存:Redis | |||
| ## 技术文档 | |||
| - 在线演示 : [http://boot.jeecg.com](http://boot.jeecg.com) | |||
| - 在线文档: [http://doc.jeecg.com](http://doc.jeecg.com) | |||
| - 常见问题: [http://jeecg.com/doc/qa](http://jeecg.com/doc/qa) | |||
| - QQ交流群 : ⑤860162132、④774126647(满)、③816531124(满)、②769925425(满)、①284271917(满) | |||
| ## 专项文档 | |||
| #### 一、查询过滤器用法 | |||
| ``` | |||
| QueryWrapper<?> queryWrapper = QueryGenerator.initQueryWrapper(?, req.getParameterMap()); | |||
| ``` | |||
| 代码示例: | |||
| ``` | |||
| @GetMapping(value = "/list") | |||
| public Result<IPage<JeecgDemo>> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, | |||
| @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, | |||
| HttpServletRequest req) { | |||
| Result<IPage<JeecgDemo>> result = new Result<IPage<JeecgDemo>>(); | |||
| //调用QueryGenerator的initQueryWrapper | |||
| QueryWrapper<JeecgDemo> queryWrapper = QueryGenerator.initQueryWrapper(jeecgDemo, req.getParameterMap()); | |||
| Page<JeecgDemo> page = new Page<JeecgDemo>(pageNo, pageSize); | |||
| IPage<JeecgDemo> pageList = jeecgDemoService.page(page, queryWrapper); | |||
| result.setSuccess(true); | |||
| result.setResult(pageList); | |||
| return result; | |||
| } | |||
| ``` | |||
| - 查询规则 (本规则不适用于高级查询,高级查询有自己对应的查询类型可以选择 ) | |||
| | 查询模式 | 用法 | 说明 | | |||
| |---------- |-------------------------------------------------------|------------------| | |||
| | 模糊查询 | 支持左右模糊和全模糊 需要在查询输入框内前或后带\*或是前后全部带\* | | | |||
| | 取非查询 | 在查询输入框前面输入! 则查询该字段不等于输入值的数据(数值类型不支持此种查询,可以将数值字段定义为字符串类型的) | | | |||
| | \> \>= < <= | 同取非查询 在输入框前面输入对应特殊字符即表示走对应规则查询 | | | |||
| | in查询 | 若传入的数据带,(逗号) 则表示该查询为in查询 | | | |||
| | 多选字段模糊查询 | 上述4 有一个特例,若某一查询字段前后都带逗号 则会将其视为走这种查询方式 ,该查询方式是将查询条件以逗号分割再遍历数组 将每个元素作like查询 用or拼接,例如 现在name传入值 ,a,b,c, 那么结果sql就是 name like '%a%' or name like '%b%' or name like '%c%' | | | |||
| #### 二、AutoPoi(EXCEL工具类-EasyPOI衍变升级重构版本) | |||
| [在线文档](https://github.com/zhangdaiscott/autopoi) | |||
| #### 三、代码生成器 | |||
| > 功能说明: 一键生成的代码(包括:controller、service、dao、mapper、entity、vue) | |||
| - 模板位置: src/main/resources/jeecg/code-template | |||
| - 技术文档: http://doc.jeecg.com/2043916 | |||
| #### 四、编码排重使用示例 | |||
| 重复校验效果: | |||
|  | |||
| 1.引入排重接口,代码如下: | |||
| ``` | |||
| import { duplicateCheck } from '@/api/api' | |||
| ``` | |||
| 2.找到编码必填校验规则的前端代码,代码如下: | |||
| ``` | |||
| <a-input placeholder="请输入编码" v-decorator="['code', validatorRules.code ]"/> | |||
| code: { | |||
| rules: [ | |||
| { required: true, message: '请输入编码!' }, | |||
| {validator: this.validateCode} | |||
| ] | |||
| }, | |||
| ``` | |||
| 3.找到rules里validator对应的方法在哪里,然后使用第一步中引入的排重校验接口. | |||
| 以用户online表单编码为示例,其中四个必传的参数有: | |||
| ``` | |||
| {tableName:表名,fieldName:字段名,fieldVal:字段值,dataId:表的主键}, | |||
| ``` | |||
| 具体使用代码如下: | |||
| ``` | |||
| validateCode(rule, value, callback){ | |||
| let pattern = /^[a-z|A-Z][a-z|A-Z|\d|_|-]{0,}$/; | |||
| if(!pattern.test(value)){ | |||
| callback('编码必须以字母开头,可包含数字、下划线、横杠'); | |||
| } else { | |||
| var params = { | |||
| tableName: "onl_cgreport_head", | |||
| fieldName: "code", | |||
| fieldVal: value, | |||
| dataId: this.model.id | |||
| }; | |||
| duplicateCheck(params).then((res)=>{ | |||
| if(res.success){ | |||
| callback(); | |||
| }else{ | |||
| callback(res.message); | |||
| } | |||
| }) | |||
| } | |||
| }, | |||
| ``` | |||
| ## docker镜像用法 | |||
| 文档: http://doc.jeecg.com/2043889 | |||
| ``` | |||
| 注意: 如果本地安装了mysql和redis,启动容器前先停掉本地服务,不然会端口冲突。 | |||
| net stop redis | |||
| net stop mysql | |||
| # 1.配置host | |||
| # jeecgboot | |||
| 127.0.0.1 jeecg-boot-redis | |||
| 127.0.0.1 jeecg-boot-mysql | |||
| 127.0.0.1 jeecg-boot-system | |||
| # 2.修改项目配置文件 application.yml | |||
| active: dev | |||
| # 3.修改application-dev.yml文件的数据库和redis链接 | |||
| 修改数据库连接和redis连接,将连接改成host方式 | |||
| # 4.先进JAVA项目jeecg-boot根路径 maven打包 | |||
| mvn clean package | |||
| # 5.构建镜像__容器组(当你改变本地代码,也可重新构建镜像) | |||
| docker-compose build | |||
| # 6.启动镜像__容器组(也可取代运行中的镜像) | |||
| docker-compose up -d | |||
| # 7.访问后台项目(注意要开启swagger) | |||
| http://localhost:8080/jeecg-boot/doc.html | |||
| ``` | |||
| @ -0,0 +1,23 @@ | |||
| docs | |||
| public | |||
| src | |||
| .dockerignore | |||
| .editorconfig | |||
| .eslintignore | |||
| .gitattributes | |||
| .gitignore | |||
| .prettierrc | |||
| babel.config.js | |||
| Dockerfile | |||
| idea.config.js | |||
| LICENSE | |||
| package.json | |||
| package-lock.json | |||
| README.md | |||
| vue.config.js | |||
| yarn | |||
| yarn.lock | |||
| yarn-error.log | |||
| .idea | |||
| .svn | |||
| node_modules | |||
| @ -0,0 +1,39 @@ | |||
| [*] | |||
| charset=utf-8 | |||
| end_of_line=crlf | |||
| insert_final_newline=false | |||
| indent_style=space | |||
| indent_size=2 | |||
| [{*.ng,*.sht,*.html,*.shtm,*.shtml,*.htm}] | |||
| indent_style=space | |||
| indent_size=2 | |||
| [{*.jhm,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.tld,*.fxml,*.jrxml,*.xml,*.jnlp,*.wsdl}] | |||
| indent_style=space | |||
| indent_size=2 | |||
| [{.babelrc,.stylelintrc,jest.config,.eslintrc,.prettierrc,*.json,*.jsb3,*.jsb2,*.bowerrc}] | |||
| indent_style=space | |||
| indent_size=2 | |||
| [*.svg] | |||
| indent_style=space | |||
| indent_size=2 | |||
| [*.js.map] | |||
| indent_style=space | |||
| indent_size=2 | |||
| [*.less] | |||
| indent_style=space | |||
| indent_size=2 | |||
| [*.vue] | |||
| indent_style=space | |||
| indent_size=2 | |||
| [{.analysis_options,*.yml,*.yaml}] | |||
| indent_style=space | |||
| indent_size=2 | |||
| @ -0,0 +1,6 @@ | |||
| NODE_ENV=production | |||
| VUE_APP_PLATFORM_NAME=陌美人后台管理系统 | |||
| # 开启单点登录 | |||
| VUE_APP_SSO=false | |||
| # 开启微应用模式 | |||
| VUE_APP_QIANKUN=false | |||
| @ -0,0 +1,7 @@ | |||
| NODE_ENV=development | |||
| VUE_APP_API_BASE_URL=http://localhost:8000/popularize-admin/ | |||
| VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas | |||
| VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview | |||
| # 微应用列表必须VUE_APP_SUB_开头,jeecg-app-1为子应用的项目名称,也是子应用的路由父路径 | |||
| VUE_APP_SUB_jeecg-app-1 = '//localhost:8092' | |||
| @ -0,0 +1,4 @@ | |||
| NODE_ENV=production | |||
| VUE_APP_API_BASE_URL=http://localhost:8000/popularize-admin/ | |||
| VUE_APP_CAS_BASE_URL=http://localhost:8888/cas | |||
| VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview | |||
| @ -0,0 +1,4 @@ | |||
| NODE_ENV=production | |||
| VUE_APP_API_BASE_URL=http://boot.jeecg.com:8080/jeecg-boot | |||
| VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas | |||
| VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview | |||
| @ -0,0 +1 @@ | |||
| /src | |||
| @ -0,0 +1 @@ | |||
| public/* linguist-vendored | |||
| @ -0,0 +1,21 @@ | |||
| .DS_Store | |||
| node_modules | |||
| /dist | |||
| # local env files | |||
| .env.local | |||
| .env.*.local | |||
| # Log files | |||
| npm-debug.log* | |||
| yarn-debug.log* | |||
| yarn-error.log* | |||
| # Editor directories and files | |||
| .idea | |||
| .vscode | |||
| *.suo | |||
| *.ntvs* | |||
| *.njsproj | |||
| *.sln | |||
| *.sw* | |||
| @ -0,0 +1,5 @@ | |||
| { | |||
| "printWidth": 120, | |||
| "semi": false, | |||
| "singleQuote": true | |||
| } | |||
| @ -0,0 +1 @@ | |||
| network-timeout 600000 | |||
| @ -0,0 +1,29 @@ | |||
| FROM nginx | |||
| MAINTAINER jeecgos@163.com | |||
| VOLUME /tmp | |||
| ENV LANG en_US.UTF-8 | |||
| RUN echo "server { \ | |||
| listen 80; \ | |||
| location ^~ /jeecg-boot { \ | |||
| proxy_pass http://jeecg-boot-system:8080/jeecg-boot/; \ | |||
| proxy_set_header Host jeecg-boot-system; \ | |||
| proxy_set_header X-Real-IP \$remote_addr; \ | |||
| proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; \ | |||
| } \ | |||
| #解决Router(mode: 'history')模式下,刷新路由地址不能找到页面的问题 \ | |||
| location / { \ | |||
| root /var/www/html/; \ | |||
| index index.html index.htm; \ | |||
| if (!-e \$request_filename) { \ | |||
| rewrite ^(.*)\$ /index.html?s=\$1 last; \ | |||
| break; \ | |||
| } \ | |||
| } \ | |||
| access_log /var/log/nginx/access.log ; \ | |||
| } " > /etc/nginx/conf.d/default.conf \ | |||
| && mkdir -p /var/www \ | |||
| && mkdir -p /var/www/html | |||
| ADD dist/ /var/www/html/ | |||
| EXPOSE 80 | |||
| EXPOSE 443 | |||
| @ -0,0 +1,213 @@ | |||
| Apache License | |||
| Version 2.0, January 2004 | |||
| http://www.apache.org/licenses/ | |||
| TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |||
| 1. Definitions. | |||
| "License" shall mean the terms and conditions for use, reproduction, | |||
| and distribution as defined by Sections 1 through 9 of this document. | |||
| "Licensor" shall mean the copyright owner or entity authorized by | |||
| the copyright owner that is granting the License. | |||
| "Legal Entity" shall mean the union of the acting entity and all | |||
| other entities that control, are controlled by, or are under common | |||
| control with that entity. For the purposes of this definition, | |||
| "control" means (i) the power, direct or indirect, to cause the | |||
| direction or management of such entity, whether by contract or | |||
| otherwise, or (ii) ownership of fifty percent (50%) or more of the | |||
| outstanding shares, or (iii) beneficial ownership of such entity. | |||
| "You" (or "Your") shall mean an individual or Legal Entity | |||
| exercising permissions granted by this License. | |||
| "Source" form shall mean the preferred form for making modifications, | |||
| including but not limited to software source code, documentation | |||
| source, and configuration files. | |||
| "Object" form shall mean any form resulting from mechanical | |||
| transformation or translation of a Source form, including but | |||
| not limited to compiled object code, generated documentation, | |||
| and conversions to other media types. | |||
| "Work" shall mean the work of authorship, whether in Source or | |||
| Object form, made available under the License, as indicated by a | |||
| copyright notice that is included in or attached to the work | |||
| (an example is provided in the Appendix below). | |||
| "Derivative Works" shall mean any work, whether in Source or Object | |||
| form, that is based on (or derived from) the Work and for which the | |||
| editorial revisions, annotations, elaborations, or other modifications | |||
| represent, as a whole, an original work of authorship. For the purposes | |||
| of this License, Derivative Works shall not include works that remain | |||
| separable from, or merely link (or bind by name) to the interfaces of, | |||
| the Work and Derivative Works thereof. | |||
| "Contribution" shall mean any work of authorship, including | |||
| the original version of the Work and any modifications or additions | |||
| to that Work or Derivative Works thereof, that is intentionally | |||
| submitted to Licensor for inclusion in the Work by the copyright owner | |||
| or by an individual or Legal Entity authorized to submit on behalf of | |||
| the copyright owner. For the purposes of this definition, "submitted" | |||
| means any form of electronic, verbal, or written communication sent | |||
| to the Licensor or its representatives, including but not limited to | |||
| communication on electronic mailing lists, source code control systems, | |||
| and issue tracking systems that are managed by, or on behalf of, the | |||
| Licensor for the purpose of discussing and improving the Work, but | |||
| excluding communication that is conspicuously marked or otherwise | |||
| designated in writing by the copyright owner as "Not a Contribution." | |||
| "Contributor" shall mean Licensor and any individual or Legal Entity | |||
| on behalf of whom a Contribution has been received by Licensor and | |||
| subsequently incorporated within the Work. | |||
| 2. Grant of Copyright License. Subject to the terms and conditions of | |||
| this License, each Contributor hereby grants to You a perpetual, | |||
| worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||
| copyright license to reproduce, prepare Derivative Works of, | |||
| publicly display, publicly perform, sublicense, and distribute the | |||
| Work and such Derivative Works in Source or Object form. | |||
| 3. Grant of Patent License. Subject to the terms and conditions of | |||
| this License, each Contributor hereby grants to You a perpetual, | |||
| worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||
| (except as stated in this section) patent license to make, have made, | |||
| use, offer to sell, sell, import, and otherwise transfer the Work, | |||
| where such license applies only to those patent claims licensable | |||
| by such Contributor that are necessarily infringed by their | |||
| Contribution(s) alone or by combination of their Contribution(s) | |||
| with the Work to which such Contribution(s) was submitted. If You | |||
| institute patent litigation against any entity (including a | |||
| cross-claim or counterclaim in a lawsuit) alleging that the Work | |||
| or a Contribution incorporated within the Work constitutes direct | |||
| or contributory patent infringement, then any patent licenses | |||
| granted to You under this License for that Work shall terminate | |||
| as of the date such litigation is filed. | |||
| 4. Redistribution. You may reproduce and distribute copies of the | |||
| Work or Derivative Works thereof in any medium, with or without | |||
| modifications, and in Source or Object form, provided that You | |||
| meet the following conditions: | |||
| (a) You must give any other recipients of the Work or | |||
| Derivative Works a copy of this License; and | |||
| (b) You must cause any modified files to carry prominent notices | |||
| stating that You changed the files; and | |||
| (c) You must retain, in the Source form of any Derivative Works | |||
| that You distribute, all copyright, patent, trademark, and | |||
| attribution notices from the Source form of the Work, | |||
| excluding those notices that do not pertain to any part of | |||
| the Derivative Works; and | |||
| (d) If the Work includes a "NOTICE" text file as part of its | |||
| distribution, then any Derivative Works that You distribute must | |||
| include a readable copy of the attribution notices contained | |||
| within such NOTICE file, excluding those notices that do not | |||
| pertain to any part of the Derivative Works, in at least one | |||
| of the following places: within a NOTICE text file distributed | |||
| as part of the Derivative Works; within the Source form or | |||
| documentation, if provided along with the Derivative Works; or, | |||
| within a display generated by the Derivative Works, if and | |||
| wherever such third-party notices normally appear. The contents | |||
| of the NOTICE file are for informational purposes only and | |||
| do not modify the License. You may add Your own attribution | |||
| notices within Derivative Works that You distribute, alongside | |||
| or as an addendum to the NOTICE text from the Work, provided | |||
| that such additional attribution notices cannot be construed | |||
| as modifying the License. | |||
| You may add Your own copyright statement to Your modifications and | |||
| may provide additional or different license terms and conditions | |||
| for use, reproduction, or distribution of Your modifications, or | |||
| for any such Derivative Works as a whole, provided Your use, | |||
| reproduction, and distribution of the Work otherwise complies with | |||
| the conditions stated in this License. | |||
| 5. Submission of Contributions. Unless You explicitly state otherwise, | |||
| any Contribution intentionally submitted for inclusion in the Work | |||
| by You to the Licensor shall be under the terms and conditions of | |||
| this License, without any additional terms or conditions. | |||
| Notwithstanding the above, nothing herein shall supersede or modify | |||
| the terms of any separate license agreement you may have executed | |||
| with Licensor regarding such Contributions. | |||
| 6. Trademarks. This License does not grant permission to use the trade | |||
| names, trademarks, service marks, or product names of the Licensor, | |||
| except as required for reasonable and customary use in describing the | |||
| origin of the Work and reproducing the content of the NOTICE file. | |||
| 7. Disclaimer of Warranty. Unless required by applicable law or | |||
| agreed to in writing, Licensor provides the Work (and each | |||
| Contributor provides its Contributions) on an "AS IS" BASIS, | |||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |||
| implied, including, without limitation, any warranties or conditions | |||
| of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | |||
| PARTICULAR PURPOSE. You are solely responsible for determining the | |||
| appropriateness of using or redistributing the Work and assume any | |||
| risks associated with Your exercise of permissions under this License. | |||
| 8. Limitation of Liability. In no event and under no legal theory, | |||
| whether in tort (including negligence), contract, or otherwise, | |||
| unless required by applicable law (such as deliberate and grossly | |||
| negligent acts) or agreed to in writing, shall any Contributor be | |||
| liable to You for damages, including any direct, indirect, special, | |||
| incidental, or consequential damages of any character arising as a | |||
| result of this License or out of the use or inability to use the | |||
| Work (including but not limited to damages for loss of goodwill, | |||
| work stoppage, computer failure or malfunction, or any and all | |||
| other commercial damages or losses), even if such Contributor | |||
| has been advised of the possibility of such damages. | |||
| 9. Accepting Warranty or Additional Liability. While redistributing | |||
| the Work or Derivative Works thereof, You may choose to offer, | |||
| and charge a fee for, acceptance of support, warranty, indemnity, | |||
| or other liability obligations and/or rights consistent with this | |||
| License. However, in accepting such obligations, You may act only | |||
| on Your own behalf and on Your sole responsibility, not on behalf | |||
| of any other Contributor, and only if You agree to indemnify, | |||
| defend, and hold each Contributor harmless for any liability | |||
| incurred by, or claims asserted against, such Contributor by reason | |||
| of your accepting any such warranty or additional liability. | |||
| END OF TERMS AND CONDITIONS | |||
| APPENDIX: How to apply the Apache License to your work. | |||
| To apply the Apache License to your work, attach the following | |||
| boilerplate notice, with the fields enclosed by brackets "[]" | |||
| replaced with your own identifying information. (Don't include | |||
| the brackets!) The text should be enclosed in the appropriate | |||
| comment syntax for the file format. We also recommend that a | |||
| file or class name and description of purpose be included on the | |||
| same "printed page" as the copyright notice for easier | |||
| identification within third-party archives. | |||
| Copyright (c) 2019 <a href="http://www.jeecg.com">Jeecg Boot</a> All rights reserved. | |||
| Licensed under the Apache License, Version 2.0 (the "License"); | |||
| you may not use this file except in compliance with the License. | |||
| You may obtain a copy of the License at | |||
| http://www.apache.org/licenses/LICENSE-2.0 | |||
| Unless required by applicable law or agreed to in writing, software | |||
| distributed under the License is distributed on an "AS IS" BASIS, | |||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| See the License for the specific language governing permissions and | |||
| limitations under the License. | |||
| In any case, you must not make any such use of this software as to develop software which may be considered competitive with this software. | |||
| 开源协议补充 | |||
| JeecgBoot 是由 北京国炬信息技术有限公司 发行的软件。 总部位于北京,地址:中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱:jeecgos@163.com | |||
| 本软件受适用的国家软件著作权法(包括国际条约)和双重保护许可。 | |||
| 1.允许基于本平台软件开展业务系统开发。 | |||
| 2.不得基于该平台软件的基础,修改包装成一个与JeecgBoot平台软件功能类似的产品进行发布、销售,或与JeecgBoot参与同类软件产品市场的竞争。 | |||
| 违反此条款属于侵权行为,须赔偿侵权经济损失,同时立即停止著作权侵权行为。 | |||
| 解释权归:http://www.jeecg.com | |||
| @ -0,0 +1,135 @@ | |||
| Ant Design Jeecg Vue | |||
| ==== | |||
| 当前最新版本: 3.1.0(发布日期:20220301) | |||
| Overview | |||
| ---- | |||
| 基于 [Ant Design of Vue](https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn/) 实现的 Ant Design Pro Vue 版 | |||
| Jeecg-boot 的前端UI框架,采用前后端分离方案,提供强大代码生成器的低代码平台。 | |||
| 前端页面代码和后端功能代码一键生成,不需要写任何代码,保持jeecg一贯的强大!! | |||
| #### 前端技术 | |||
| - 基础框架:[ant-design-vue](https://github.com/vueComponent/ant-design-vue) - Ant Design Of Vue 实现 | |||
| - JavaScript框架:Vue | |||
| - Webpack | |||
| - node | |||
| - yarn | |||
| - eslint | |||
| - @vue/cli 3.2.1 | |||
| - [vue-cropper](https://github.com/xyxiao001/vue-cropper) - 头像裁剪组件 | |||
| - [@antv/g2](https://antv.alipay.com/zh-cn/index.html) - Alipay AntV 数据可视化图表 | |||
| - [Viser-vue](https://viserjs.github.io/docs.html#/viser/guide/installation) - antv/g2 封装实现 | |||
| 项目下载和运行 | |||
| ---- | |||
| - 拉取项目代码 | |||
| ```bash | |||
| git clone https://github.com/zhangdaiscott/jeecg-boot.git | |||
| cd jeecg-boot/ant-design-vue-jeecg | |||
| ``` | |||
| - 安装依赖 | |||
| ``` | |||
| yarn install | |||
| ``` | |||
| - 开发模式运行 | |||
| ``` | |||
| yarn run serve | |||
| ``` | |||
| - 编译项目 | |||
| ``` | |||
| yarn run build | |||
| ``` | |||
| - Lints and fixes files | |||
| ``` | |||
| yarn run lint | |||
| ``` | |||
| 其他说明 | |||
| ---- | |||
| - 项目使用的 [vue-cli3](https://cli.vuejs.org/guide/), 请更新您的 cli | |||
| - 关闭 Eslint (不推荐) 移除 `package.json` 中 `eslintConfig` 整个节点代码 | |||
| - 修改 Ant Design 配色,在文件 `vue.config.js` 中,其他 less 变量覆盖参考 [ant design](https://ant.design/docs/react/customize-theme-cn) 官方说明 | |||
| ```ecmascript 6 | |||
| css: { | |||
| loaderOptions: { | |||
| less: { | |||
| modifyVars: { | |||
| /* less 变量覆盖,用于自定义 ant design 主题 */ | |||
| 'primary-color': '#F5222D', | |||
| 'link-color': '#F5222D', | |||
| 'border-radius-base': '4px', | |||
| }, | |||
| javascriptEnabled: true, | |||
| } | |||
| } | |||
| } | |||
| ``` | |||
| 附属文档 | |||
| ---- | |||
| - [Ant Design Vue](https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn) | |||
| - [报表 viser-vue](https://viserjs.github.io/demo.html#/viser/bar/basic-bar) | |||
| - [Vue](https://cn.vuejs.org/v2/guide) | |||
| - [路由/菜单说明](https://github.com/zhangdaiscott/jeecg-boot/tree/master/ant-design-vue-jeecg/src/router/README.md) | |||
| - [ANTD 默认配置项](https://github.com/zhangdaiscott/jeecg-boot/tree/master/ant-design-vue-jeecg/src/defaultSettings.js) | |||
| - 其他待补充... | |||
| 备注 | |||
| ---- | |||
| > @vue/cli 升级后,eslint 规则更新了。由于影响到全部 .vue 文件,需要逐个验证。既暂时关闭部分原本不验证的规则,后期维护时,在逐步修正这些 rules | |||
| Docker 镜像使用 | |||
| ---- | |||
| ``` | |||
| # 1.修改前端项目的后台域名 | |||
| .env.development | |||
| 域名改成: http://jeecg-boot-system:8080/jeecg-boot | |||
| # 2.先进入打包前端项目 | |||
| yarn run build | |||
| # 3.构建镜像 | |||
| docker build -t nginx:jeecgboot . | |||
| # 4.启动镜像 | |||
| docker run --name jeecg-boot-nginx -p 80:80 -d nginx:jeecgboot | |||
| # 5.配置host | |||
| # jeecgboot | |||
| 127.0.0.1 jeecg-boot-redis | |||
| 127.0.0.1 jeecg-boot-mysql | |||
| 127.0.0.1 jeecg-boot-system | |||
| # 6.访问前台项目 | |||
| http://localhost:80 | |||
| ``` | |||
| @ -0,0 +1,6 @@ | |||
| module.exports = { | |||
| presets: [ | |||
| ['@vue/app', | |||
| { useBuiltIns: 'entry' }] | |||
| ] | |||
| } | |||
| @ -0,0 +1,24 @@ | |||
| 'use strict' | |||
| const path = require('path') | |||
| function resolve (dir) { | |||
| return path.join(__dirname, '.', dir) | |||
| } | |||
| module.exports = { | |||
| context: path.resolve(__dirname, './'), | |||
| resolve: { | |||
| extensions: ['.js', '.vue', '.json'], | |||
| alias: { | |||
| 'config': resolve('config'), | |||
| '@': resolve('src'), | |||
| '@views': resolve('src/views'), | |||
| '@comp': resolve('src/components'), | |||
| '@core': resolve('src/core'), | |||
| '@utils': resolve('src/utils'), | |||
| '@entry': resolve('src/entry'), | |||
| '@router': resolve('src/router'), | |||
| '@store': resolve('src/store') | |||
| } | |||
| }, | |||
| } | |||
| @ -0,0 +1,123 @@ | |||
| { | |||
| "name": "vue-antd-jeecg", | |||
| "version": "3.1.0", | |||
| "private": true, | |||
| "scripts": { | |||
| "pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ", | |||
| "serve": "vue-cli-service serve", | |||
| "build:test": "vue-cli-service build --mode test", | |||
| "build": "vue-cli-service build", | |||
| "lint": "vue-cli-service lint" | |||
| }, | |||
| "dependencies": { | |||
| "@antv/data-set": "^0.11.4", | |||
| "@jeecg/antd-online-mini": "3.1.0-beta", | |||
| "@tinymce/tinymce-vue": "2.1.0", | |||
| "@toast-ui/editor": "^2.1.2", | |||
| "ant-design-vue": "^1.7.2", | |||
| "axios": "^0.18.0", | |||
| "china-area-data": "^5.0.1", | |||
| "clipboard": "^2.0.4", | |||
| "codemirror": "^5.46.0", | |||
| "cron-parser": "^2.10.0", | |||
| "dayjs": "^1.8.0", | |||
| "dom-align": "1.12.0", | |||
| "enquire.js": "^2.1.6", | |||
| "js-cookie": "^2.2.0", | |||
| "lodash.get": "^4.4.2", | |||
| "lodash.pick": "^4.4.0", | |||
| "md5": "^2.2.1", | |||
| "nprogress": "^0.2.0", | |||
| "qiankun": "^2.5.1", | |||
| "tinymce": "5.4.1", | |||
| "viser-vue": "^2.4.8", | |||
| "vue": "^2.6.10", | |||
| "vue-area-linkage": "^5.1.0", | |||
| "vue-cropper": "^0.5.4", | |||
| "vue-i18n": "^8.7.0", | |||
| "vue-loader": "^15.7.0", | |||
| "vue-ls": "^3.2.0", | |||
| "vue-photo-preview": "^1.1.3", | |||
| "vue-print-nb-jeecg": "^1.0.9", | |||
| "vue-router": "^3.0.1", | |||
| "vue-splitpane": "^1.0.4", | |||
| "vuedraggable": "^2.20.0", | |||
| "vuex": "^3.1.0", | |||
| "vxe-table": "2.9.13", | |||
| "vxe-table-plugin-antd": "1.8.10", | |||
| "webpack": "^4.4.1", | |||
| "webpack-dev-server": "^2.9.1", | |||
| "xe-utils": "2.4.8", | |||
| "yarn": "^1.22.19" | |||
| }, | |||
| "devDependencies": { | |||
| "@babel/polyfill": "^7.2.5", | |||
| "@vue/cli-plugin-babel": "^3.3.0", | |||
| "@vue/cli-plugin-eslint": "^3.3.0", | |||
| "@vue/cli-service": "^3.3.0", | |||
| "@vue/eslint-config-standard": "^4.0.0", | |||
| "babel-eslint": "7.2.3", | |||
| "compression-webpack-plugin": "^3.1.0", | |||
| "crypto-js": "^4.1.1", | |||
| "eslint": "^5.16.0", | |||
| "eslint-plugin-vue": "^5.1.0", | |||
| "html-webpack-plugin": "^4.2.0", | |||
| "less": "^3.9.0", | |||
| "less-loader": "^4.1.0", | |||
| "vue-template-compiler": "^2.6.10" | |||
| }, | |||
| "eslintConfig": { | |||
| "root": true, | |||
| "env": { | |||
| "node": true | |||
| }, | |||
| "extends": [ | |||
| "plugin:vue/strongly-recommended", | |||
| "@vue/standard" | |||
| ], | |||
| "parserOptions": { | |||
| "parser": "babel-eslint" | |||
| }, | |||
| "rules": { | |||
| "generator-star-spacing": "off", | |||
| "no-mixed-operators": 0, | |||
| "vue/max-attributes-per-line": [ | |||
| 2, | |||
| { | |||
| "singleline": 5, | |||
| "multiline": { | |||
| "max": 1, | |||
| "allowFirstLine": false | |||
| } | |||
| } | |||
| ], | |||
| "vue/attribute-hyphenation": 0, | |||
| "vue/html-self-closing": 0, | |||
| "vue/component-name-in-template-casing": 0, | |||
| "vue/html-closing-bracket-spacing": 0, | |||
| "vue/singleline-html-element-content-newline": 0, | |||
| "vue/no-unused-components": 0, | |||
| "vue/multiline-html-element-content-newline": 0, | |||
| "vue/no-use-v-if-with-v-for": 0, | |||
| "vue/html-closing-bracket-newline": 0, | |||
| "vue/no-parsing-error": 0, | |||
| "no-tabs": 0, | |||
| "indent": [ | |||
| "off", | |||
| 2 | |||
| ], | |||
| "no-console": 0, | |||
| "space-before-function-paren": 0 | |||
| } | |||
| }, | |||
| "postcss": { | |||
| "plugins": { | |||
| "autoprefixer": {} | |||
| } | |||
| }, | |||
| "browserslist": [ | |||
| "> 1%", | |||
| "last 2 versions", | |||
| "not ie <= 10" | |||
| ] | |||
| } | |||
| @ -0,0 +1,260 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="zh-cmn-Hans"> | |||
| <head> | |||
| <meta charset="utf-8"> | |||
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> | |||
| <meta name="viewport" content="width=device-width,initial-scale=1.0"> | |||
| <title>活动推广后台</title> | |||
| <link rel="icon" href="<%= BASE_URL %>logo.png"> | |||
| <script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script> | |||
| <style> | |||
| html, | |||
| body, | |||
| #app { | |||
| height: 100%; | |||
| margin: 0px; | |||
| padding: 0px; | |||
| } | |||
| .chromeframe { | |||
| margin: 0.2em 0; | |||
| background: #ccc; | |||
| color: #000; | |||
| padding: 0.2em 0; | |||
| } | |||
| #loader-wrapper { | |||
| position: fixed; | |||
| top: 0; | |||
| left: 0; | |||
| width: 100%; | |||
| height: 100%; | |||
| z-index: 999999; | |||
| } | |||
| #loader { | |||
| display: block; | |||
| position: relative; | |||
| left: 50%; | |||
| top: 50%; | |||
| width: 120px; | |||
| height: 120px; | |||
| margin: -75px 0 0 -75px; | |||
| border-radius: 50%; | |||
| border: 3px solid transparent; | |||
| /* COLOR 1 */ | |||
| border-top-color: #FFF; | |||
| -webkit-animation: spin 2s linear infinite; | |||
| /* Chrome, Opera 15+, Safari 5+ */ | |||
| -ms-animation: spin 2s linear infinite; | |||
| /* Chrome, Opera 15+, Safari 5+ */ | |||
| -moz-animation: spin 2s linear infinite; | |||
| /* Chrome, Opera 15+, Safari 5+ */ | |||
| -o-animation: spin 2s linear infinite; | |||
| /* Chrome, Opera 15+, Safari 5+ */ | |||
| animation: spin 2s linear infinite; | |||
| /* Chrome, Firefox 16+, IE 10+, Opera */ | |||
| z-index: 1001; | |||
| } | |||
| #loader:before { | |||
| content: ""; | |||
| position: absolute; | |||
| top: 5px; | |||
| left: 5px; | |||
| right: 5px; | |||
| bottom: 5px; | |||
| border-radius: 50%; | |||
| border: 3px solid transparent; | |||
| /* COLOR 2 */ | |||
| border-top-color: #FFF; | |||
| -webkit-animation: spin 3s linear infinite; | |||
| /* Chrome, Opera 15+, Safari 5+ */ | |||
| -moz-animation: spin 3s linear infinite; | |||
| /* Chrome, Opera 15+, Safari 5+ */ | |||
| -o-animation: spin 3s linear infinite; | |||
| /* Chrome, Opera 15+, Safari 5+ */ | |||
| -ms-animation: spin 3s linear infinite; | |||
| /* Chrome, Opera 15+, Safari 5+ */ | |||
| animation: spin 3s linear infinite; | |||
| /* Chrome, Firefox 16+, IE 10+, Opera */ | |||
| } | |||
| #loader:after { | |||
| content: ""; | |||
| position: absolute; | |||
| top: 15px; | |||
| left: 15px; | |||
| right: 15px; | |||
| bottom: 15px; | |||
| border-radius: 50%; | |||
| border: 3px solid transparent; | |||
| border-top-color: #FFF; | |||
| /* COLOR 3 */ | |||
| -moz-animation: spin 1.5s linear infinite; | |||
| /* Chrome, Opera 15+, Safari 5+ */ | |||
| -o-animation: spin 1.5s linear infinite; | |||
| /* Chrome, Opera 15+, Safari 5+ */ | |||
| -ms-animation: spin 1.5s linear infinite; | |||
| /* Chrome, Opera 15+, Safari 5+ */ | |||
| -webkit-animation: spin 1.5s linear infinite; | |||
| /* Chrome, Opera 15+, Safari 5+ */ | |||
| animation: spin 1.5s linear infinite; | |||
| /* Chrome, Firefox 16+, IE 10+, Opera */ | |||
| } | |||
| @-webkit-keyframes spin { | |||
| 0% { | |||
| -webkit-transform: rotate(0deg); | |||
| /* Chrome, Opera 15+, Safari 3.1+ */ | |||
| -ms-transform: rotate(0deg); | |||
| /* IE 9 */ | |||
| transform: rotate(0deg); | |||
| /* Firefox 16+, IE 10+, Opera */ | |||
| } | |||
| 100% { | |||
| -webkit-transform: rotate(360deg); | |||
| /* Chrome, Opera 15+, Safari 3.1+ */ | |||
| -ms-transform: rotate(360deg); | |||
| /* IE 9 */ | |||
| transform: rotate(360deg); | |||
| /* Firefox 16+, IE 10+, Opera */ | |||
| } | |||
| } | |||
| @keyframes spin { | |||
| 0% { | |||
| -webkit-transform: rotate(0deg); | |||
| /* Chrome, Opera 15+, Safari 3.1+ */ | |||
| -ms-transform: rotate(0deg); | |||
| /* IE 9 */ | |||
| transform: rotate(0deg); | |||
| /* Firefox 16+, IE 10+, Opera */ | |||
| } | |||
| 100% { | |||
| -webkit-transform: rotate(360deg); | |||
| /* Chrome, Opera 15+, Safari 3.1+ */ | |||
| -ms-transform: rotate(360deg); | |||
| /* IE 9 */ | |||
| transform: rotate(360deg); | |||
| /* Firefox 16+, IE 10+, Opera */ | |||
| } | |||
| } | |||
| #loader-wrapper .loader-section { | |||
| position: fixed; | |||
| top: 0; | |||
| width: 51%; | |||
| height: 100%; | |||
| background: #49a9ee; | |||
| /* Old browsers */ | |||
| z-index: 1000; | |||
| -webkit-transform: translateX(0); | |||
| /* Chrome, Opera 15+, Safari 3.1+ */ | |||
| -ms-transform: translateX(0); | |||
| /* IE 9 */ | |||
| transform: translateX(0); | |||
| /* Firefox 16+, IE 10+, Opera */ | |||
| } | |||
| #loader-wrapper .loader-section.section-left { | |||
| left: 0; | |||
| } | |||
| #loader-wrapper .loader-section.section-right { | |||
| right: 0; | |||
| } | |||
| /* Loaded */ | |||
| .loaded #loader-wrapper .loader-section.section-left { | |||
| -webkit-transform: translateX(-100%); | |||
| /* Chrome, Opera 15+, Safari 3.1+ */ | |||
| -ms-transform: translateX(-100%); | |||
| /* IE 9 */ | |||
| transform: translateX(-100%); | |||
| /* Firefox 16+, IE 10+, Opera */ | |||
| -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); | |||
| transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); | |||
| } | |||
| .loaded #loader-wrapper .loader-section.section-right { | |||
| -webkit-transform: translateX(100%); | |||
| /* Chrome, Opera 15+, Safari 3.1+ */ | |||
| -ms-transform: translateX(100%); | |||
| /* IE 9 */ | |||
| transform: translateX(100%); | |||
| /* Firefox 16+, IE 10+, Opera */ | |||
| -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); | |||
| transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); | |||
| } | |||
| .loaded #loader { | |||
| opacity: 0; | |||
| -webkit-transition: all 0.3s ease-out; | |||
| transition: all 0.3s ease-out; | |||
| } | |||
| .loaded #loader-wrapper { | |||
| visibility: hidden; | |||
| -webkit-transform: translateY(-100%); | |||
| /* Chrome, Opera 15+, Safari 3.1+ */ | |||
| -ms-transform: translateY(-100%); | |||
| /* IE 9 */ | |||
| transform: translateY(-100%); | |||
| /* Firefox 16+, IE 10+, Opera */ | |||
| -webkit-transition: all 0.3s 1s ease-out; | |||
| transition: all 0.3s 1s ease-out; | |||
| } | |||
| /* JavaScript Turned Off */ | |||
| .no-js #loader-wrapper { | |||
| display: none; | |||
| } | |||
| .no-js h1 { | |||
| color: #222222; | |||
| } | |||
| #loader-wrapper .load_title { | |||
| font-family: 'Open Sans'; | |||
| color: #FFF; | |||
| font-size: 14px; | |||
| width: 100%; | |||
| text-align: center; | |||
| z-index: 9999999999999; | |||
| position: absolute; | |||
| top: 60%; | |||
| opacity: 1; | |||
| line-height: 30px; | |||
| } | |||
| #loader-wrapper .load_title span { | |||
| font-weight: normal; | |||
| font-style: italic; | |||
| font-size: 14px; | |||
| color: #FFF; | |||
| opacity: 0.5; | |||
| } | |||
| /* 滚动条优化 start */ | |||
| ::-webkit-scrollbar{ | |||
| width:8px; | |||
| height:8px; | |||
| } | |||
| ::-webkit-scrollbar-track{ | |||
| background: #f6f6f6; | |||
| border-radius:2px; | |||
| } | |||
| ::-webkit-scrollbar-thumb{ | |||
| background: #cdcdcd; | |||
| border-radius:2px; | |||
| } | |||
| ::-webkit-scrollbar-thumb:hover{ | |||
| background: #747474; | |||
| } | |||
| ::-webkit-scrollbar-corner { | |||
| background: #f6f6f6; | |||
| } | |||
| /* 滚动条优化 end */ | |||
| </style> | |||
| <!-- 全局配置 --> | |||
| <script src="<%= BASE_URL %>static/config.js"></script> | |||
| </head> | |||
| <body> | |||
| <div id="app"> | |||
| <div id="loader-wrapper"> | |||
| <div id="loader"></div> | |||
| <div class="loader-section section-left"></div> | |||
| <div class="loader-section section-right"></div> | |||
| <div class="load_title">正在加载 陌美人后台管理系统,请耐心等待 | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </body> | |||
| </html> | |||
| @ -0,0 +1,11 @@ | |||
| /** | |||
| * 存放配置常量(当值不为空时会覆盖env配置) | |||
| */ | |||
| window._CONFIG = { | |||
| //接口父路径 | |||
| VUE_APP_API_BASE_URL: '', | |||
| //单点登录地址 | |||
| VUE_APP_CAS_BASE_URL: '', | |||
| //文件预览路径 | |||
| VUE_APP_ONLINE_BASE_URL: '' | |||
| } | |||
| @ -0,0 +1,261 @@ | |||
| tinymce.addI18n('zh_CN',{ | |||
| "Redo": "\u91cd\u590d", | |||
| "Undo": "\u64a4\u6d88", | |||
| "Cut": "\u526a\u5207", | |||
| "Copy": "\u590d\u5236", | |||
| "Paste": "\u7c98\u8d34", | |||
| "Select all": "\u5168\u9009", | |||
| "New document": "\u65b0\u6587\u6863", | |||
| "Ok": "\u786e\u5b9a", | |||
| "Cancel": "\u53d6\u6d88", | |||
| "Visual aids": "\u7f51\u683c\u7ebf", | |||
| "Bold": "\u7c97\u4f53", | |||
| "Italic": "\u659c\u4f53", | |||
| "Underline": "\u4e0b\u5212\u7ebf", | |||
| "Strikethrough": "\u5220\u9664\u7ebf", | |||
| "Superscript": "\u4e0a\u6807", | |||
| "Subscript": "\u4e0b\u6807", | |||
| "Clear formatting": "\u6e05\u9664\u683c\u5f0f", | |||
| "Align left": "\u5de6\u5bf9\u9f50", | |||
| "Align center": "\u5c45\u4e2d", | |||
| "Align right": "\u53f3\u5bf9\u9f50", | |||
| "Justify": "\u4e24\u7aef\u5bf9\u9f50", | |||
| "Bullet list": "\u9879\u76ee\u7b26\u53f7", | |||
| "Numbered list": "\u7f16\u53f7\u5217\u8868", | |||
| "Decrease indent": "\u51cf\u5c11\u7f29\u8fdb", | |||
| "Increase indent": "\u589e\u52a0\u7f29\u8fdb", | |||
| "Close": "\u5173\u95ed", | |||
| "Formats": "\u683c\u5f0f", | |||
| "Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u5bf9\u526a\u8d34\u677f\u7684\u8bbf\u95ee\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u952e\u8fdb\u884c\u590d\u5236\u7c98\u8d34\u3002", | |||
| "Headers": "\u6807\u9898", | |||
| "Header 1": "\u6807\u98981", | |||
| "Header 2": "\u6807\u98982", | |||
| "Header 3": "\u6807\u98983", | |||
| "Header 4": "\u6807\u98984", | |||
| "Header 5": "\u6807\u98985", | |||
| "Header 6": "\u6807\u98986", | |||
| "Headings": "\u6807\u9898", | |||
| "Heading 1": "\u6807\u98981", | |||
| "Heading 2": "\u6807\u98982", | |||
| "Heading 3": "\u6807\u98983", | |||
| "Heading 4": "\u6807\u98984", | |||
| "Heading 5": "\u6807\u98985", | |||
| "Heading 6": "\u6807\u98986", | |||
| "Preformatted": "\u9884\u683c\u5f0f\u5316", | |||
| "Div": "Div\u533a\u5757", | |||
| "Pre": "\u9884\u683c\u5f0f\u6587\u672c", | |||
| "Code": "\u4ee3\u7801", | |||
| "Paragraph": "\u6bb5\u843d", | |||
| "Blockquote": "\u5f15\u7528", | |||
| "Inline": "\u6587\u672c", | |||
| "Blocks": "\u533a\u5757", | |||
| "Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002", | |||
| "Font Family": "\u5b57\u4f53", | |||
| "Font Sizes": "\u5b57\u53f7", | |||
| "Class": "Class", | |||
| "Browse for an image": "\u6d4f\u89c8\u56fe\u50cf", | |||
| "OR": "\u6216", | |||
| "Drop an image here": "\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64", | |||
| "Upload": "\u4e0a\u4f20", | |||
| "Block": "\u5757", | |||
| "Align": "\u5bf9\u9f50", | |||
| "Default": "\u9ed8\u8ba4", | |||
| "Circle": "\u7a7a\u5fc3\u5706", | |||
| "Disc": "\u5b9e\u5fc3\u5706", | |||
| "Square": "\u65b9\u5757", | |||
| "Lower Alpha": "\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd", | |||
| "Lower Greek": "\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd", | |||
| "Lower Roman": "\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd", | |||
| "Upper Alpha": "\u5927\u5199\u82f1\u6587\u5b57\u6bcd", | |||
| "Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd", | |||
| "Anchor": "\u951a\u70b9", | |||
| "Name": "\u540d\u79f0", | |||
| "Id": "\u6807\u8bc6\u7b26", | |||
| "Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002", | |||
| "You have unsaved changes are you sure you want to navigate away?": "\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f", | |||
| "Restore last draft": "\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f", | |||
| "Special character": "\u7279\u6b8a\u7b26\u53f7", | |||
| "Source code": "\u6e90\u4ee3\u7801", | |||
| "Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b", | |||
| "Language": "\u8bed\u8a00", | |||
| "Code sample": "\u4ee3\u7801\u793a\u4f8b", | |||
| "Color": "\u989c\u8272", | |||
| "R": "R", | |||
| "G": "G", | |||
| "B": "B", | |||
| "Left to right": "\u4ece\u5de6\u5230\u53f3", | |||
| "Right to left": "\u4ece\u53f3\u5230\u5de6", | |||
| "Emoticons": "\u8868\u60c5", | |||
| "Document properties": "\u6587\u6863\u5c5e\u6027", | |||
| "Title": "\u6807\u9898", | |||
| "Keywords": "\u5173\u952e\u8bcd", | |||
| "Description": "\u63cf\u8ff0", | |||
| "Robots": "\u673a\u5668\u4eba", | |||
| "Author": "\u4f5c\u8005", | |||
| "Encoding": "\u7f16\u7801", | |||
| "Fullscreen": "\u5168\u5c4f", | |||
| "Action": "\u64cd\u4f5c", | |||
| "Shortcut": "\u5feb\u6377\u952e", | |||
| "Help": "\u5e2e\u52a9", | |||
| "Address": "\u5730\u5740", | |||
| "Focus to menubar": "\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f", | |||
| "Focus to toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f", | |||
| "Focus to element path": "\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84", | |||
| "Focus to contextual toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355", | |||
| "Insert link (if link plugin activated)": "\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", | |||
| "Save (if save plugin activated)": "\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", | |||
| "Find (if searchreplace plugin activated)": "\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", | |||
| "Plugins installed ({0}):": "\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):", | |||
| "Premium plugins:": "\u4f18\u79c0\u63d2\u4ef6\uff1a", | |||
| "Learn more...": "\u4e86\u89e3\u66f4\u591a...", | |||
| "You are using {0}": "\u4f60\u6b63\u5728\u4f7f\u7528 {0}", | |||
| "Plugins": "\u63d2\u4ef6", | |||
| "Handy Shortcuts": "\u5feb\u6377\u952e", | |||
| "Horizontal line": "\u6c34\u5e73\u5206\u5272\u7ebf", | |||
| "Insert\/edit image": "\u63d2\u5165\/\u7f16\u8f91\u56fe\u7247", | |||
| "Image description": "\u56fe\u7247\u63cf\u8ff0", | |||
| "Source": "\u5730\u5740", | |||
| "Dimensions": "\u5927\u5c0f", | |||
| "Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4", | |||
| "General": "\u666e\u901a", | |||
| "Advanced": "\u9ad8\u7ea7", | |||
| "Style": "\u6837\u5f0f", | |||
| "Vertical space": "\u5782\u76f4\u8fb9\u8ddd", | |||
| "Horizontal space": "\u6c34\u5e73\u8fb9\u8ddd", | |||
| "Border": "\u8fb9\u6846", | |||
| "Insert image": "\u63d2\u5165\u56fe\u7247", | |||
| "Image": "\u56fe\u7247", | |||
| "Image list": "\u56fe\u7247\u5217\u8868", | |||
| "Rotate counterclockwise": "\u9006\u65f6\u9488\u65cb\u8f6c", | |||
| "Rotate clockwise": "\u987a\u65f6\u9488\u65cb\u8f6c", | |||
| "Flip vertically": "\u5782\u76f4\u7ffb\u8f6c", | |||
| "Flip horizontally": "\u6c34\u5e73\u7ffb\u8f6c", | |||
| "Edit image": "\u7f16\u8f91\u56fe\u7247", | |||
| "Image options": "\u56fe\u7247\u9009\u9879", | |||
| "Zoom in": "\u653e\u5927", | |||
| "Zoom out": "\u7f29\u5c0f", | |||
| "Crop": "\u88c1\u526a", | |||
| "Resize": "\u8c03\u6574\u5927\u5c0f", | |||
| "Orientation": "\u65b9\u5411", | |||
| "Brightness": "\u4eae\u5ea6", | |||
| "Sharpen": "\u9510\u5316", | |||
| "Contrast": "\u5bf9\u6bd4\u5ea6", | |||
| "Color levels": "\u989c\u8272\u5c42\u6b21", | |||
| "Gamma": "\u4f3d\u9a6c\u503c", | |||
| "Invert": "\u53cd\u8f6c", | |||
| "Apply": "\u5e94\u7528", | |||
| "Back": "\u540e\u9000", | |||
| "Insert date\/time": "\u63d2\u5165\u65e5\u671f\/\u65f6\u95f4", | |||
| "Date\/time": "\u65e5\u671f\/\u65f6\u95f4", | |||
| "Insert link": "\u63d2\u5165\u94fe\u63a5", | |||
| "Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", | |||
| "Text to display": "\u663e\u793a\u6587\u5b57", | |||
| "Url": "\u5730\u5740", | |||
| "Target": "\u6253\u5f00\u65b9\u5f0f", | |||
| "None": "\u65e0", | |||
| "New window": "\u5728\u65b0\u7a97\u53e3\u6253\u5f00", | |||
| "Remove link": "\u5220\u9664\u94fe\u63a5", | |||
| "Anchors": "\u951a\u70b9", | |||
| "Link": "\u94fe\u63a5", | |||
| "Paste or type a link": "\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5", | |||
| "The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f", | |||
| "The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7f00\u5417\uff1f", | |||
| "Link list": "\u94fe\u63a5\u5217\u8868", | |||
| "Insert video": "\u63d2\u5165\u89c6\u9891", | |||
| "Insert\/edit video": "\u63d2\u5165\/\u7f16\u8f91\u89c6\u9891", | |||
| "Insert\/edit media": "\u63d2\u5165\/\u7f16\u8f91\u5a92\u4f53", | |||
| "Alternative source": "\u955c\u50cf", | |||
| "Poster": "\u5c01\u9762", | |||
| "Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:", | |||
| "Embed": "\u5185\u5d4c", | |||
| "Media": "\u5a92\u4f53", | |||
| "Nonbreaking space": "\u4e0d\u95f4\u65ad\u7a7a\u683c", | |||
| "Page break": "\u5206\u9875\u7b26", | |||
| "Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c", | |||
| "Preview": "\u9884\u89c8", | |||
| "Print": "\u6253\u5370", | |||
| "Save": "\u4fdd\u5b58", | |||
| "Find": "\u67e5\u627e", | |||
| "Replace with": "\u66ff\u6362\u4e3a", | |||
| "Replace": "\u66ff\u6362", | |||
| "Replace all": "\u5168\u90e8\u66ff\u6362", | |||
| "Prev": "\u4e0a\u4e00\u4e2a", | |||
| "Next": "\u4e0b\u4e00\u4e2a", | |||
| "Find and replace": "\u67e5\u627e\u548c\u66ff\u6362", | |||
| "Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.", | |||
| "Match case": "\u533a\u5206\u5927\u5c0f\u5199", | |||
| "Whole words": "\u5168\u5b57\u5339\u914d", | |||
| "Spellcheck": "\u62fc\u5199\u68c0\u67e5", | |||
| "Ignore": "\u5ffd\u7565", | |||
| "Ignore all": "\u5168\u90e8\u5ffd\u7565", | |||
| "Finish": "\u5b8c\u6210", | |||
| "Add to Dictionary": "\u6dfb\u52a0\u5230\u5b57\u5178", | |||
| "Insert table": "\u63d2\u5165\u8868\u683c", | |||
| "Table properties": "\u8868\u683c\u5c5e\u6027", | |||
| "Delete table": "\u5220\u9664\u8868\u683c", | |||
| "Cell": "\u5355\u5143\u683c", | |||
| "Row": "\u884c", | |||
| "Column": "\u5217", | |||
| "Cell properties": "\u5355\u5143\u683c\u5c5e\u6027", | |||
| "Merge cells": "\u5408\u5e76\u5355\u5143\u683c", | |||
| "Split cell": "\u62c6\u5206\u5355\u5143\u683c", | |||
| "Insert row before": "\u5728\u4e0a\u65b9\u63d2\u5165", | |||
| "Insert row after": "\u5728\u4e0b\u65b9\u63d2\u5165", | |||
| "Delete row": "\u5220\u9664\u884c", | |||
| "Row properties": "\u884c\u5c5e\u6027", | |||
| "Cut row": "\u526a\u5207\u884c", | |||
| "Copy row": "\u590d\u5236\u884c", | |||
| "Paste row before": "\u7c98\u8d34\u5230\u4e0a\u65b9", | |||
| "Paste row after": "\u7c98\u8d34\u5230\u4e0b\u65b9", | |||
| "Insert column before": "\u5728\u5de6\u4fa7\u63d2\u5165", | |||
| "Insert column after": "\u5728\u53f3\u4fa7\u63d2\u5165", | |||
| "Delete column": "\u5220\u9664\u5217", | |||
| "Cols": "\u5217", | |||
| "Rows": "\u884c", | |||
| "Width": "\u5bbd", | |||
| "Height": "\u9ad8", | |||
| "Cell spacing": "\u5355\u5143\u683c\u5916\u95f4\u8ddd", | |||
| "Cell padding": "\u5355\u5143\u683c\u5185\u8fb9\u8ddd", | |||
| "Caption": "\u6807\u9898", | |||
| "Left": "\u5de6\u5bf9\u9f50", | |||
| "Center": "\u5c45\u4e2d", | |||
| "Right": "\u53f3\u5bf9\u9f50", | |||
| "Cell type": "\u5355\u5143\u683c\u7c7b\u578b", | |||
| "Scope": "\u8303\u56f4", | |||
| "Alignment": "\u5bf9\u9f50\u65b9\u5f0f", | |||
| "H Align": "\u6c34\u5e73\u5bf9\u9f50", | |||
| "V Align": "\u5782\u76f4\u5bf9\u9f50", | |||
| "Top": "\u9876\u90e8\u5bf9\u9f50", | |||
| "Middle": "\u5782\u76f4\u5c45\u4e2d", | |||
| "Bottom": "\u5e95\u90e8\u5bf9\u9f50", | |||
| "Header cell": "\u8868\u5934\u5355\u5143\u683c", | |||
| "Row group": "\u884c\u7ec4", | |||
| "Column group": "\u5217\u7ec4", | |||
| "Row type": "\u884c\u7c7b\u578b", | |||
| "Header": "\u8868\u5934", | |||
| "Body": "\u8868\u4f53", | |||
| "Footer": "\u8868\u5c3e", | |||
| "Border color": "\u8fb9\u6846\u989c\u8272", | |||
| "Insert template": "\u63d2\u5165\u6a21\u677f", | |||
| "Templates": "\u6a21\u677f", | |||
| "Template": "\u6a21\u677f", | |||
| "Text color": "\u6587\u5b57\u989c\u8272", | |||
| "Background color": "\u80cc\u666f\u8272", | |||
| "Custom...": "\u81ea\u5b9a\u4e49...", | |||
| "Custom color": "\u81ea\u5b9a\u4e49\u989c\u8272", | |||
| "No color": "\u65e0", | |||
| "Table of Contents": "\u5185\u5bb9\u5217\u8868", | |||
| "Show blocks": "\u663e\u793a\u533a\u5757\u8fb9\u6846", | |||
| "Show invisible characters": "\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26", | |||
| "Words: {0}": "\u5b57\u6570\uff1a{0}", | |||
| "{0} words": "{0} \u5b57", | |||
| "File": "\u6587\u4ef6", | |||
| "Edit": "\u7f16\u8f91", | |||
| "Insert": "\u63d2\u5165", | |||
| "View": "\u89c6\u56fe", | |||
| "Format": "\u683c\u5f0f", | |||
| "Table": "\u8868\u683c", | |||
| "Tools": "\u5de5\u5177", | |||
| "Powered by {0}": "\u7531{0}\u9a71\u52a8", | |||
| "Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9" | |||
| }); | |||
| @ -0,0 +1,554 @@ | |||
| /** | |||
| * Copyright (c) Tiny Technologies, Inc. All rights reserved. | |||
| * Licensed under the LGPL or a commercial license. | |||
| * For LGPL see License.txt in the project root for license information. | |||
| * For commercial licenses see https://www.tiny.cloud/ | |||
| */ | |||
| .mce-content-body .mce-item-anchor { | |||
| background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'8'%20height%3D'12'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20d%3D'M0%200L8%200%208%2012%204.09117821%209%200%2012z'%2F%3E%3C%2Fsvg%3E%0A") no-repeat center; | |||
| cursor: default; | |||
| display: inline-block; | |||
| height: 12px !important; | |||
| padding: 0 2px; | |||
| -webkit-user-modify: read-only; | |||
| -moz-user-modify: read-only; | |||
| -webkit-user-select: all; | |||
| -moz-user-select: all; | |||
| -ms-user-select: all; | |||
| user-select: all; | |||
| width: 8px !important; | |||
| } | |||
| .mce-content-body .mce-item-anchor[data-mce-selected] { | |||
| outline-offset: 1px; | |||
| } | |||
| .tox-comments-visible .tox-comment { | |||
| background-color: #fff0b7; | |||
| } | |||
| .tox-comments-visible .tox-comment--active { | |||
| background-color: #ffe168; | |||
| } | |||
| .tox-checklist > li:not(.tox-checklist--hidden) { | |||
| list-style: none; | |||
| margin: .25em 0; | |||
| position: relative; | |||
| } | |||
| .tox-checklist > li:not(.tox-checklist--hidden)::before { | |||
| background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-unchecked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2215%22%20height%3D%2215%22%20x%3D%22.5%22%20y%3D%22.5%22%20fill-rule%3D%22nonzero%22%20stroke%3D%22%234C4C4C%22%20rx%3D%222%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A"); | |||
| background-size: 100%; | |||
| content: ''; | |||
| cursor: pointer; | |||
| height: 1em; | |||
| left: -1.5em; | |||
| position: absolute; | |||
| top: .125em; | |||
| width: 1em; | |||
| } | |||
| .tox-checklist li:not(.tox-checklist--hidden).tox-checklist--checked::before { | |||
| background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-checked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2216%22%20height%3D%2216%22%20fill%3D%22%234099FF%22%20fill-rule%3D%22nonzero%22%20rx%3D%222%22%2F%3E%3Cpath%20id%3D%22Path%22%20fill%3D%22%23FFF%22%20fill-rule%3D%22nonzero%22%20d%3D%22M11.5703186%2C3.14417309%20C11.8516238%2C2.73724603%2012.4164781%2C2.62829933%2012.83558%2C2.89774797%20C13.260121%2C3.17069355%2013.3759736%2C3.72932262%2013.0909105%2C4.14168582%20L7.7580587%2C11.8560195%20C7.43776896%2C12.3193404%206.76483983%2C12.3852142%206.35607322%2C11.9948725%20L3.02491697%2C8.8138662%20C2.66090143%2C8.46625845%202.65798871%2C7.89594698%203.01850234%2C7.54483354%20C3.373942%2C7.19866177%203.94940006%2C7.19592841%204.30829608%2C7.5386474%20L6.85276923%2C9.9684299%20L11.5703186%2C3.14417309%20Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A"); | |||
| } | |||
| /* stylelint-disable */ | |||
| /* http://prismjs.com/ */ | |||
| /** | |||
| * prism.js default theme for JavaScript, CSS and HTML | |||
| * Based on dabblet (http://dabblet.com) | |||
| * @author Lea Verou | |||
| */ | |||
| code[class*="language-"], | |||
| pre[class*="language-"] { | |||
| color: black; | |||
| text-shadow: 0 1px white; | |||
| font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; | |||
| font-size: .875rem; | |||
| direction: ltr; | |||
| text-align: left; | |||
| white-space: pre; | |||
| word-spacing: normal; | |||
| word-break: normal; | |||
| word-wrap: normal; | |||
| line-height: 1.5; | |||
| -moz-tab-size: 4; | |||
| tab-size: 4; | |||
| -webkit-hyphens: none; | |||
| -ms-hyphens: none; | |||
| hyphens: none; | |||
| } | |||
| pre[class*="language-"]::-moz-selection, | |||
| pre[class*="language-"] ::-moz-selection, | |||
| code[class*="language-"]::-moz-selection, | |||
| code[class*="language-"] ::-moz-selection { | |||
| text-shadow: none; | |||
| background: #b3d4fc; | |||
| } | |||
| pre[class*="language-"]::selection, | |||
| pre[class*="language-"] ::selection, | |||
| code[class*="language-"]::selection, | |||
| code[class*="language-"] ::selection { | |||
| text-shadow: none; | |||
| background: #b3d4fc; | |||
| } | |||
| @media print { | |||
| code[class*="language-"], | |||
| pre[class*="language-"] { | |||
| text-shadow: none; | |||
| } | |||
| } | |||
| /* Code blocks */ | |||
| pre[class*="language-"] { | |||
| padding: 1em; | |||
| margin: .5em 0; | |||
| overflow: auto; | |||
| } | |||
| :not(pre) > code[class*="language-"], | |||
| pre[class*="language-"] { | |||
| background: transparent !important; | |||
| border: 1px solid #ccc; | |||
| } | |||
| /* Inline code */ | |||
| :not(pre) > code[class*="language-"] { | |||
| padding: .1em; | |||
| border-radius: .3em; | |||
| } | |||
| .token.comment, | |||
| .token.prolog, | |||
| .token.doctype, | |||
| .token.cdata { | |||
| color: slategray; | |||
| } | |||
| .token.punctuation { | |||
| color: #999; | |||
| } | |||
| .namespace { | |||
| opacity: .7; | |||
| } | |||
| .token.property, | |||
| .token.tag, | |||
| .token.boolean, | |||
| .token.number, | |||
| .token.constant, | |||
| .token.symbol, | |||
| .token.deleted { | |||
| color: #905; | |||
| } | |||
| .token.selector, | |||
| .token.attr-name, | |||
| .token.string, | |||
| .token.char, | |||
| .token.builtin, | |||
| .token.inserted { | |||
| color: #690; | |||
| } | |||
| .token.operator, | |||
| .token.entity, | |||
| .token.url, | |||
| .language-css .token.string, | |||
| .style .token.string { | |||
| color: #a67f59; | |||
| background: rgba(255, 255, 255, 0.5); | |||
| } | |||
| .token.atrule, | |||
| .token.attr-value, | |||
| .token.keyword { | |||
| color: #07a; | |||
| } | |||
| .token.function { | |||
| color: #DD4A68; | |||
| } | |||
| .token.regex, | |||
| .token.important, | |||
| .token.variable { | |||
| color: #e90; | |||
| } | |||
| .token.important, | |||
| .token.bold { | |||
| font-weight: bold; | |||
| } | |||
| .token.italic { | |||
| font-style: italic; | |||
| } | |||
| .token.entity { | |||
| cursor: help; | |||
| } | |||
| /* stylelint-enable */ | |||
| .mce-content-body .mce-visual-caret { | |||
| background-color: black; | |||
| background-color: currentcolor; | |||
| position: absolute; | |||
| } | |||
| .mce-content-body .mce-visual-caret-hidden { | |||
| display: none; | |||
| } | |||
| .mce-content-body *[data-mce-caret] { | |||
| left: -1000px; | |||
| margin: 0; | |||
| padding: 0; | |||
| position: absolute; | |||
| right: auto; | |||
| top: 0; | |||
| } | |||
| .mce-content-body .mce-offscreen-selection { | |||
| left: -9999999999px; | |||
| max-width: 1000000px; | |||
| position: absolute; | |||
| } | |||
| .mce-content-body *[contentEditable=false] { | |||
| cursor: default; | |||
| } | |||
| .mce-content-body *[contentEditable=true] { | |||
| cursor: text; | |||
| } | |||
| .tox-cursor-format-painter { | |||
| cursor: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%0A%20%20%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M15%2C6%20C15%2C5.45%2014.55%2C5%2014%2C5%20L6%2C5%20C5.45%2C5%205%2C5.45%205%2C6%20L5%2C10%20C5%2C10.55%205.45%2C11%206%2C11%20L14%2C11%20C14.55%2C11%2015%2C10.55%2015%2C10%20L15%2C9%20L16%2C9%20L16%2C12%20L9%2C12%20L9%2C19%20C9%2C19.55%209.45%2C20%2010%2C20%20L11%2C20%20C11.55%2C20%2012%2C19.55%2012%2C19%20L12%2C14%20L18%2C14%20L18%2C7%20L15%2C7%20L15%2C6%20Z%22%2F%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M1%2C1%20L8.25%2C1%20C8.66421356%2C1%209%2C1.33578644%209%2C1.75%20L9%2C1.75%20C9%2C2.16421356%208.66421356%2C2.5%208.25%2C2.5%20L2.5%2C2.5%20L2.5%2C8.25%20C2.5%2C8.66421356%202.16421356%2C9%201.75%2C9%20L1.75%2C9%20C1.33578644%2C9%201%2C8.66421356%201%2C8.25%20L1%2C1%20Z%22%2F%3E%0A%20%20%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A"), default; | |||
| } | |||
| .mce-content-body figure.align-left { | |||
| float: left; | |||
| } | |||
| .mce-content-body figure.align-right { | |||
| float: right; | |||
| } | |||
| .mce-content-body figure.image.align-center { | |||
| display: table; | |||
| margin-left: auto; | |||
| margin-right: auto; | |||
| } | |||
| .mce-preview-object { | |||
| border: 1px solid gray; | |||
| display: inline-block; | |||
| line-height: 0; | |||
| margin: 0 2px 0 2px; | |||
| position: relative; | |||
| } | |||
| .mce-preview-object .mce-shim { | |||
| background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); | |||
| height: 100%; | |||
| left: 0; | |||
| position: absolute; | |||
| top: 0; | |||
| width: 100%; | |||
| } | |||
| .mce-preview-object[data-mce-selected="2"] .mce-shim { | |||
| display: none; | |||
| } | |||
| .mce-object { | |||
| background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%3E%3Cpath%20d%3D%22M4%203h16a1%201%200%200%201%201%201v16a1%201%200%200%201-1%201H4a1%201%200%200%201-1-1V4a1%201%200%200%201%201-1zm1%202v14h14V5H5zm4.79%202.565l5.64%204.028a.5.5%200%200%201%200%20.814l-5.64%204.028a.5.5%200%200%201-.79-.407V7.972a.5.5%200%200%201%20.79-.407z%22%2F%3E%3C%2Fsvg%3E%0A") no-repeat center; | |||
| border: 1px dashed #aaa; | |||
| } | |||
| .mce-pagebreak { | |||
| border: 1px dashed #aaa; | |||
| cursor: default; | |||
| display: block; | |||
| height: 5px; | |||
| margin-top: 15px; | |||
| page-break-before: always; | |||
| width: 100%; | |||
| } | |||
| @media print { | |||
| .mce-pagebreak { | |||
| border: 0; | |||
| } | |||
| } | |||
| .tiny-pageembed .mce-shim { | |||
| background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7); | |||
| height: 100%; | |||
| left: 0; | |||
| position: absolute; | |||
| top: 0; | |||
| width: 100%; | |||
| } | |||
| .tiny-pageembed[data-mce-selected="2"] .mce-shim { | |||
| display: none; | |||
| } | |||
| .tiny-pageembed { | |||
| display: inline-block; | |||
| position: relative; | |||
| } | |||
| .tiny-pageembed--21by9, | |||
| .tiny-pageembed--16by9, | |||
| .tiny-pageembed--4by3, | |||
| .tiny-pageembed--1by1 { | |||
| display: block; | |||
| overflow: hidden; | |||
| padding: 0; | |||
| position: relative; | |||
| width: 100%; | |||
| } | |||
| .tiny-pageembed--21by9::before, | |||
| .tiny-pageembed--16by9::before, | |||
| .tiny-pageembed--4by3::before, | |||
| .tiny-pageembed--1by1::before { | |||
| content: ""; | |||
| display: block; | |||
| } | |||
| .tiny-pageembed--21by9::before { | |||
| padding-top: 42.857143%; | |||
| } | |||
| .tiny-pageembed--16by9::before { | |||
| padding-top: 56.25%; | |||
| } | |||
| .tiny-pageembed--4by3::before { | |||
| padding-top: 75%; | |||
| } | |||
| .tiny-pageembed--1by1::before { | |||
| padding-top: 100%; | |||
| } | |||
| .tiny-pageembed--21by9 iframe, | |||
| .tiny-pageembed--16by9 iframe, | |||
| .tiny-pageembed--4by3 iframe, | |||
| .tiny-pageembed--1by1 iframe { | |||
| border: 0; | |||
| height: 100%; | |||
| left: 0; | |||
| position: absolute; | |||
| top: 0; | |||
| width: 100%; | |||
| } | |||
| .mce-content-body div.mce-resizehandle { | |||
| background-color: #4099ff; | |||
| border-color: #4099ff; | |||
| border-style: solid; | |||
| border-width: 1px; | |||
| box-sizing: border-box; | |||
| height: 10px; | |||
| position: absolute; | |||
| width: 10px; | |||
| z-index: 10000; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:hover { | |||
| background-color: #4099ff; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:nth-of-type(1) { | |||
| cursor: nwse-resize; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:nth-of-type(2) { | |||
| cursor: nesw-resize; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:nth-of-type(3) { | |||
| cursor: nwse-resize; | |||
| } | |||
| .mce-content-body div.mce-resizehandle:nth-of-type(4) { | |||
| cursor: nesw-resize; | |||
| } | |||
| .mce-content-body .mce-clonedresizable { | |||
| opacity: .5; | |||
| outline: 1px dashed black; | |||
| position: absolute; | |||
| z-index: 10000; | |||
| } | |||
| .mce-content-body .mce-resize-helper { | |||
| background: #555; | |||
| background: rgba(0, 0, 0, 0.75); | |||
| border: 1px; | |||
| border-radius: 3px; | |||
| color: white; | |||
| display: none; | |||
| font-family: sans-serif; | |||
| font-size: 12px; | |||
| line-height: 14px; | |||
| margin: 5px 10px; | |||
| padding: 5px; | |||
| position: absolute; | |||
| white-space: nowrap; | |||
| z-index: 10001; | |||
| } | |||
| .mce-match-marker { | |||
| background: #aaa; | |||
| color: #fff; | |||
| } | |||
| .mce-match-marker-selected { | |||
| background: #39f; | |||
| color: #fff; | |||
| } | |||
| .mce-content-body img[data-mce-selected], | |||
| .mce-content-body table[data-mce-selected] { | |||
| outline: 3px solid #b4d7ff; | |||
| } | |||
| .mce-content-body hr[data-mce-selected] { | |||
| outline: 3px solid #b4d7ff; | |||
| outline-offset: 1px; | |||
| } | |||
| .mce-content-body *[contentEditable=false] *[contentEditable=true]:focus { | |||
| outline: 3px solid #b4d7ff; | |||
| } | |||
| .mce-content-body *[contentEditable=false] *[contentEditable=true]:hover { | |||
| outline: 3px solid #b4d7ff; | |||
| } | |||
| .mce-content-body *[contentEditable=false][data-mce-selected] { | |||
| cursor: not-allowed; | |||
| outline: 3px solid #b4d7ff; | |||
| } | |||
| .mce-content-body.mce-content-readonly *[contentEditable=true]:focus, | |||
| .mce-content-body.mce-content-readonly *[contentEditable=true]:hover { | |||
| outline: none; | |||
| } | |||
| .mce-content-body *[data-mce-selected="inline-boundary"] { | |||
| background-color: #b4d7ff; | |||
| } | |||
| .mce-content-body .mce-edit-focus { | |||
| outline: 3px solid #b4d7ff; | |||
| } | |||
| .mce-content-body td[data-mce-selected], | |||
| .mce-content-body th[data-mce-selected] { | |||
| background-color: #b4d7ff !important; | |||
| } | |||
| .mce-content-body td[data-mce-selected]::-moz-selection, | |||
| .mce-content-body th[data-mce-selected]::-moz-selection { | |||
| background: none; | |||
| } | |||
| .mce-content-body td[data-mce-selected]::selection, | |||
| .mce-content-body th[data-mce-selected]::selection { | |||
| background: none; | |||
| } | |||
| .mce-content-body td[data-mce-selected] *, | |||
| .mce-content-body th[data-mce-selected] * { | |||
| -webkit-touch-callout: none; | |||
| -webkit-user-select: none; | |||
| -moz-user-select: none; | |||
| -ms-user-select: none; | |||
| user-select: none; | |||
| } | |||
| .mce-content-body img::-moz-selection { | |||
| background: none; | |||
| } | |||
| .mce-content-body img::selection { | |||
| background: none; | |||
| } | |||
| .ephox-snooker-resizer-bar { | |||
| background-color: #b4d7ff; | |||
| opacity: 0; | |||
| } | |||
| .ephox-snooker-resizer-cols { | |||
| cursor: col-resize; | |||
| } | |||
| .ephox-snooker-resizer-rows { | |||
| cursor: row-resize; | |||
| } | |||
| .ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging { | |||
| opacity: 1; | |||
| } | |||
| .mce-spellchecker-word { | |||
| background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%23ff0000'%20fill%3D'none'%20stroke-linecap%3D'round'%20stroke-opacity%3D'.5'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A"); | |||
| background-position: 0 calc(100% + 1px); | |||
| background-repeat: repeat-x; | |||
| background-size: auto 6px; | |||
| cursor: default; | |||
| height: 2rem; | |||
| } | |||
| .mce-spellchecker-grammar { | |||
| background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%23008800'%20fill%3D'none'%20stroke-linecap%3D'round'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A"); | |||
| background-position: 0 calc(100% + 1px); | |||
| background-repeat: repeat-x; | |||
| background-size: auto 6px; | |||
| cursor: default; | |||
| } | |||
| .mce-toc { | |||
| border: 1px solid gray; | |||
| } | |||
| .mce-toc h2 { | |||
| margin: 4px; | |||
| } | |||
| .mce-toc li { | |||
| list-style-type: none; | |||
| } | |||
| .mce-item-table, | |||
| .mce-item-table td, | |||
| .mce-item-table th, | |||
| .mce-item-table caption { | |||
| border: 1px dashed #bbb; | |||
| } | |||
| .mce-visualblocks p, | |||
| .mce-visualblocks h1, | |||
| .mce-visualblocks h2, | |||
| .mce-visualblocks h3, | |||
| .mce-visualblocks h4, | |||
| .mce-visualblocks h5, | |||
| .mce-visualblocks h6, | |||
| .mce-visualblocks div:not([data-mce-bogus]), | |||
| .mce-visualblocks section, | |||
| .mce-visualblocks article, | |||
| .mce-visualblocks blockquote, | |||
| .mce-visualblocks address, | |||
| .mce-visualblocks pre, | |||
| .mce-visualblocks figure, | |||
| .mce-visualblocks figcaption, | |||
| .mce-visualblocks hgroup, | |||
| .mce-visualblocks aside, | |||
| .mce-visualblocks ul, | |||
| .mce-visualblocks ol, | |||
| .mce-visualblocks dl { | |||
| background-repeat: no-repeat; | |||
| border: 1px dashed #bbb; | |||
| margin-left: 3px; | |||
| padding-top: 10px; | |||
| } | |||
| .mce-visualblocks p { | |||
| background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7); | |||
| } | |||
| .mce-visualblocks h1 { | |||
| background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==); | |||
| } | |||
| .mce-visualblocks h2 { | |||
| background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8Hybbx4oOuqgTynJd6bGlWg3DkJzoaUAAAOw==); | |||
| } | |||
| .mce-visualblocks h3 { | |||
| background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIZjI8Hybbx4oOuqgTynJf2Ln2NOHpQpmhAAQA7); | |||
| } | |||
| .mce-visualblocks h4 { | |||
| background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxInR0zqeAdhtJlXwV1oCll2HaWgAAOw==); | |||
| } | |||
| .mce-visualblocks h5 { | |||
| background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjane4iq5GlW05GgIkIZUAAAOw==); | |||
| } | |||
| .mce-visualblocks h6 { | |||
| background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjan04jep1iZ1XRlAo5bVgAAOw==); | |||
| } | |||
| .mce-visualblocks div:not([data-mce-bogus]) { | |||
| background-image: url(data:image/gif;base64,R0lGODlhEgAKAIABALu7u////yH5BAEAAAEALAAAAAASAAoAAAIfjI9poI0cgDywrhuxfbrzDEbQM2Ei5aRjmoySW4pAAQA7); | |||
| } | |||
| .mce-visualblocks section { | |||
| background-image: url(data:image/gif;base64,R0lGODlhKAAKAIABALu7u////yH5BAEAAAEALAAAAAAoAAoAAAI5jI+pywcNY3sBWHdNrplytD2ellDeSVbp+GmWqaDqDMepc8t17Y4vBsK5hDyJMcI6KkuYU+jpjLoKADs=); | |||
| } | |||
| .mce-visualblocks article { | |||
| background-image: url(data:image/gif;base64,R0lGODlhKgAKAIABALu7u////yH5BAEAAAEALAAAAAAqAAoAAAI6jI+pywkNY3wG0GBvrsd2tXGYSGnfiF7ikpXemTpOiJScasYoDJJrjsG9gkCJ0ag6KhmaIe3pjDYBBQA7); | |||
| } | |||
| .mce-visualblocks blockquote { | |||
| background-image: url(data:image/gif;base64,R0lGODlhPgAKAIABALu7u////yH5BAEAAAEALAAAAAA+AAoAAAJPjI+py+0Knpz0xQDyuUhvfoGgIX5iSKZYgq5uNL5q69asZ8s5rrf0yZmpNkJZzFesBTu8TOlDVAabUyatguVhWduud3EyiUk45xhTTgMBBQA7); | |||
| } | |||
| .mce-visualblocks address { | |||
| background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH5BAEAAAEALAAAAAAtAAoAAAI/jI+pywwNozSP1gDyyZcjb3UaRpXkWaXmZW4OqKLhBmLs+K263DkJK7OJeifh7FicKD9A1/IpGdKkyFpNmCkAADs=); | |||
| } | |||
| .mce-visualblocks pre { | |||
| background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==); | |||
| } | |||
| .mce-visualblocks figure { | |||
| background-image: url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7); | |||
| } | |||
| .mce-visualblocks figcaption { | |||
| border: 1px dashed #bbb; | |||
| } | |||
| .mce-visualblocks hgroup { | |||
| background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7); | |||
| } | |||
| .mce-visualblocks aside { | |||
| background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=); | |||
| } | |||
| .mce-visualblocks ul { | |||
| background-image: url(data:image/gif;base64,R0lGODlhDQAKAIAAALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGuYnqUVSjvw26DzzXiqIDlVwAAOw==); | |||
| } | |||
| .mce-visualblocks ol { | |||
| background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybH6HHt0qourxC6CvzXieHyeWQAAOw==); | |||
| } | |||
| .mce-visualblocks dl { | |||
| background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybEOnmOvUoWznTqeuEjNSCqeGRUAOw==); | |||
| } | |||
| .mce-nbsp, | |||
| .mce-shy { | |||
| background: #aaa; | |||
| } | |||
| .mce-shy::after { | |||
| content: '-'; | |||
| } | |||
| body { | |||
| font-family: sans-serif; | |||
| } | |||
| table { | |||
| border-collapse: collapse; | |||
| } | |||
| @ -0,0 +1,44 @@ | |||
| <template> | |||
| <a-config-provider :locale="locale"> | |||
| <div id="app"> | |||
| <router-view/> | |||
| </div> | |||
| </a-config-provider> | |||
| </template> | |||
| <script> | |||
| import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN' | |||
| import enquireScreen from '@/utils/device' | |||
| export default { | |||
| data () { | |||
| return { | |||
| locale: zhCN, | |||
| } | |||
| }, | |||
| created () { | |||
| let that = this | |||
| enquireScreen(deviceType => { | |||
| // tablet | |||
| if (deviceType === 0) { | |||
| that.$store.commit('TOGGLE_DEVICE', 'mobile') | |||
| that.$store.dispatch('setSidebar', false) | |||
| } | |||
| // mobile | |||
| else if (deviceType === 1) { | |||
| that.$store.commit('TOGGLE_DEVICE', 'mobile') | |||
| that.$store.dispatch('setSidebar', false) | |||
| } | |||
| else { | |||
| that.$store.commit('TOGGLE_DEVICE', 'desktop') | |||
| that.$store.dispatch('setSidebar', true) | |||
| } | |||
| }) | |||
| } | |||
| } | |||
| </script> | |||
| <style> | |||
| #app { | |||
| height: 100%; | |||
| } | |||
| </style> | |||
| @ -0,0 +1,30 @@ | |||
| import Vue from 'vue' | |||
| /** | |||
| * 将一个请求分组 | |||
| * | |||
| * @param getPromise 传入一个可以获取到Promise对象的方法 | |||
| * @param groupId 分组ID,如果不传或者为空则不分组 | |||
| * @param expire 过期时间,默认 半分钟 | |||
| */ | |||
| export function httpGroupRequest(getPromise, groupId, expire = 1000 * 30) { | |||
| if (groupId == null || groupId === '') { | |||
| console.log("--------popup----------getFrom DB-------with---no--groupId ") | |||
| return getPromise() | |||
| } | |||
| if (Vue.ls.get(groupId)) { | |||
| console.log("---------popup--------getFrom Cache--------groupId = " + groupId) | |||
| return Promise.resolve(Vue.ls.get(groupId)); | |||
| } else { | |||
| console.log("--------popup----------getFrom DB---------groupId = " + groupId) | |||
| } | |||
| // 还没有发出请求,就发出第一次的请求 | |||
| return getPromise().then(res => { | |||
| Vue.ls.set(groupId, res, expire); | |||
| return Promise.resolve(res); | |||
| }) | |||
| } | |||
| @ -0,0 +1,164 @@ | |||
| import { getAction, deleteAction, putAction, postAction, httpAction } from '@/api/manage' | |||
| import Vue from 'vue' | |||
| import {UI_CACHE_DB_DICT_DATA } from "@/store/mutation-types" | |||
| //角色管理 | |||
| const addRole = (params)=>postAction("/sys/role/add",params); | |||
| const editRole = (params)=>putAction("/sys/role/edit",params); | |||
| const checkRoleCode = (params)=>getAction("/sys/role/checkRoleCode",params); | |||
| const queryall = (params)=>getAction("/sys/role/queryall",params); | |||
| //用户管理 | |||
| const addUser = (params)=>postAction("/sys/user/add",params); | |||
| const editUser = (params)=>putAction("/sys/user/edit",params); | |||
| const queryUserRole = (params)=>getAction("/sys/user/queryUserRole",params); | |||
| const getUserList = (params)=>getAction("/sys/user/list",params); | |||
| const frozenBatch = (params)=>putAction("/sys/user/frozenBatch",params); | |||
| //验证用户是否存在 | |||
| const checkOnlyUser = (params)=>getAction("/sys/user/checkOnlyUser",params); | |||
| //改变密码 | |||
| const changePassword = (params)=>putAction("/sys/user/changePassword",params); | |||
| //权限管理 | |||
| const addPermission= (params)=>postAction("/sys/permission/add",params); | |||
| const editPermission= (params)=>putAction("/sys/permission/edit",params); | |||
| const getPermissionList = (params)=>getAction("/sys/permission/list",params); | |||
| const getSystemMenuList = (params)=>getAction("/sys/permission/getSystemMenuList",params); | |||
| const getSystemSubmenu = (params)=>getAction("/sys/permission/getSystemSubmenu",params); | |||
| const getSystemSubmenuBatch = (params) => getAction('/sys/permission/getSystemSubmenuBatch', params) | |||
| const queryTreeList = (params)=>getAction("/sys/permission/queryTreeList",params); | |||
| const queryTreeListForRole = (params)=>getAction("/sys/role/queryTreeList",params); | |||
| const queryListAsync = (params)=>getAction("/sys/permission/queryListAsync",params); | |||
| const queryRolePermission = (params)=>getAction("/sys/permission/queryRolePermission",params); | |||
| const saveRolePermission = (params)=>postAction("/sys/permission/saveRolePermission",params); | |||
| const queryPermissionsByUser = ()=>getAction("/sys/permission/getUserPermissionByToken"); | |||
| const loadAllRoleIds = (params)=>getAction("/sys/permission/loadAllRoleIds",params); | |||
| const getPermissionRuleList = (params)=>getAction("/sys/permission/getPermRuleListByPermId",params); | |||
| const queryPermissionRule = (params)=>getAction("/sys/permission/queryPermissionRule",params); | |||
| // 部门管理 | |||
| const queryDepartTreeList = (params)=>getAction("/sys/sysDepart/queryTreeList",params); | |||
| const queryDepartTreeSync = (params)=>getAction("/sys/sysDepart/queryDepartTreeSync",params); | |||
| const queryIdTree = (params)=>getAction("/sys/sysDepart/queryIdTree",params); | |||
| const queryParentName = (params)=>getAction("/sys/sysDepart/queryParentName",params); | |||
| const searchByKeywords = (params)=>getAction("/sys/sysDepart/searchBy",params); | |||
| const deleteByDepartId = (params)=>deleteAction("/sys/sysDepart/delete",params); | |||
| //二级部门管理 | |||
| const queryDepartPermission = (params)=>getAction("/sys/permission/queryDepartPermission",params); | |||
| const saveDepartPermission = (params)=>postAction("/sys/permission/saveDepartPermission",params); | |||
| const queryTreeListForDeptRole = (params)=>getAction("/sys/sysDepartPermission/queryTreeListForDeptRole",params); | |||
| const queryDeptRolePermission = (params)=>getAction("/sys/sysDepartPermission/queryDeptRolePermission",params); | |||
| const saveDeptRolePermission = (params)=>postAction("/sys/sysDepartPermission/saveDeptRolePermission",params); | |||
| const queryMyDepartTreeList = (params)=>getAction("/sys/sysDepart/queryMyDeptTreeList",params); | |||
| //日志管理 | |||
| const deleteLog = (params)=>deleteAction("/sys/log/delete",params); | |||
| const deleteLogList = (params)=>deleteAction("/sys/log/deleteBatch",params); | |||
| //数据字典 | |||
| const addDict = (params)=>postAction("/sys/dict/add",params); | |||
| const editDict = (params)=>putAction("/sys/dict/edit",params); | |||
| const treeList = (params)=>getAction("/sys/dict/treeList",params); | |||
| const addDictItem = (params)=>postAction("/sys/dictItem/add",params); | |||
| const editDictItem = (params)=>putAction("/sys/dictItem/edit",params); | |||
| //字典标签专用(通过code获取字典数组) | |||
| export const ajaxGetDictItems = (code, params)=>getAction(`/sys/dict/getDictItems/${code}`,params); | |||
| //从缓存中获取字典配置 | |||
| function getDictItemsFromCache(dictCode) { | |||
| if (Vue.ls.get(UI_CACHE_DB_DICT_DATA) && Vue.ls.get(UI_CACHE_DB_DICT_DATA)[dictCode]) { | |||
| let dictItems = Vue.ls.get(UI_CACHE_DB_DICT_DATA)[dictCode]; | |||
| //console.log("-----------getDictItemsFromCache----------dictCode="+dictCode+"---- dictItems=",dictItems) | |||
| return dictItems; | |||
| } | |||
| } | |||
| //系统通告 | |||
| const doReleaseData = (params)=>getAction("/sys/annountCement/doReleaseData",params); | |||
| const doReovkeData = (params)=>getAction("/sys/annountCement/doReovkeData",params); | |||
| //获取系统访问量 | |||
| const getLoginfo = (params)=>getAction("/sys/loginfo",params); | |||
| const getVisitInfo = (params)=>getAction("/sys/visitInfo",params); | |||
| // 根据部门主键查询用户信息 | |||
| const queryUserByDepId = (params)=>getAction("/sys/user/queryUserByDepId",params); | |||
| // 重复校验 | |||
| const duplicateCheck = (params)=>getAction("/sys/duplicate/check",params); | |||
| // 加载分类字典 | |||
| const loadCategoryData = (params)=>getAction("/sys/category/loadAllData",params); | |||
| const checkRuleByCode = (params) => getAction('/sys/checkRule/checkByCode', params) | |||
| //加载我的通告信息 | |||
| const getUserNoticeInfo= (params)=>getAction("/sys/sysAnnouncementSend/getMyAnnouncementSend",params); | |||
| const getTransitURL = url => `/sys/common/transitRESTful?url=${encodeURIComponent(url)}` | |||
| // 中转HTTP请求 | |||
| export const transitRESTful = { | |||
| get: (url, parameter) => getAction(getTransitURL(url), parameter), | |||
| post: (url, parameter) => postAction(getTransitURL(url), parameter), | |||
| put: (url, parameter) => putAction(getTransitURL(url), parameter), | |||
| http: (url, parameter) => httpAction(getTransitURL(url), parameter), | |||
| } | |||
| export { | |||
| // imgView, | |||
| // doMian, | |||
| addRole, | |||
| editRole, | |||
| checkRoleCode, | |||
| addUser, | |||
| editUser, | |||
| queryUserRole, | |||
| getUserList, | |||
| queryall, | |||
| frozenBatch, | |||
| checkOnlyUser, | |||
| changePassword, | |||
| getPermissionList, | |||
| addPermission, | |||
| editPermission, | |||
| queryTreeList, | |||
| queryListAsync, | |||
| queryRolePermission, | |||
| saveRolePermission, | |||
| queryPermissionsByUser, | |||
| loadAllRoleIds, | |||
| getPermissionRuleList, | |||
| queryPermissionRule, | |||
| queryDepartTreeList, | |||
| queryDepartTreeSync, | |||
| queryIdTree, | |||
| queryParentName, | |||
| searchByKeywords, | |||
| deleteByDepartId, | |||
| deleteLog, | |||
| deleteLogList, | |||
| addDict, | |||
| editDict, | |||
| treeList, | |||
| addDictItem, | |||
| editDictItem, | |||
| doReleaseData, | |||
| doReovkeData, | |||
| getLoginfo, | |||
| getVisitInfo, | |||
| queryUserByDepId, | |||
| duplicateCheck, | |||
| queryTreeListForRole, | |||
| getSystemMenuList, | |||
| getSystemSubmenu, | |||
| getSystemSubmenuBatch, | |||
| loadCategoryData, | |||
| checkRuleByCode, | |||
| queryDepartPermission, | |||
| saveDepartPermission, | |||
| queryTreeListForDeptRole, | |||
| queryDeptRolePermission, | |||
| saveDeptRolePermission, | |||
| queryMyDepartTreeList, | |||
| getUserNoticeInfo, | |||
| getDictItemsFromCache | |||
| } | |||
| @ -0,0 +1,10 @@ | |||
| const api = { | |||
| Login: '/sys/login', | |||
| Logout: '/sys/logout', | |||
| ForgePassword: '/auth/forge-password', | |||
| Register: '/auth/register', | |||
| SendSms: '/account/sms', | |||
| // get my info | |||
| UserInfo: '/user/info' | |||
| } | |||
| export default api | |||
| @ -0,0 +1,87 @@ | |||
| import api from './index' | |||
| import { axios } from '@/utils/request' | |||
| /** | |||
| * login func | |||
| * parameter: { | |||
| * username: '', | |||
| * password: '', | |||
| * remember_me: true, | |||
| * captcha: '12345' | |||
| * } | |||
| * @param parameter | |||
| * @returns {*} | |||
| */ | |||
| export function login(parameter) { | |||
| return axios({ | |||
| url: '/sys/login', | |||
| method: 'post', | |||
| data: parameter | |||
| }) | |||
| } | |||
| export function phoneLogin(parameter) { | |||
| return axios({ | |||
| url: '/sys/phoneLogin', | |||
| method: 'post', | |||
| data: parameter | |||
| }) | |||
| } | |||
| export function getSmsCaptcha(parameter) { | |||
| return axios({ | |||
| url: api.SendSms, | |||
| method: 'post', | |||
| data: parameter | |||
| }) | |||
| } | |||
| // export function getInfo() { | |||
| // return axios({ | |||
| // url: '/api/user/info', | |||
| // method: 'get', | |||
| // headers: { | |||
| // 'Content-Type': 'application/json;charset=UTF-8' | |||
| // } | |||
| // }) | |||
| // } | |||
| export function logout(logoutToken) { | |||
| return axios({ | |||
| url: '/sys/logout', | |||
| method: 'post', | |||
| headers: { | |||
| 'Content-Type': 'application/json;charset=UTF-8', | |||
| 'X-Access-Token': logoutToken | |||
| } | |||
| }) | |||
| } | |||
| /** | |||
| * 第三方登录 | |||
| * @param token | |||
| * @param thirdType | |||
| * @returns {*} | |||
| */ | |||
| export function thirdLogin(token,thirdType) { | |||
| return axios({ | |||
| url: `/sys/thirdLogin/getLoginUser/${token}/${thirdType}`, | |||
| method: 'get', | |||
| headers: { | |||
| 'Content-Type': 'application/json;charset=UTF-8' | |||
| } | |||
| }) | |||
| } | |||
| /** | |||
| * 强退其他账号 | |||
| * @param token | |||
| * @returns {*} | |||
| */ | |||
| export function forceLogout(parameter) { | |||
| return axios({ | |||
| url: '/sys/online/forceLogout', | |||
| method: 'post', | |||
| data: parameter | |||
| }) | |||
| } | |||
| @ -0,0 +1,197 @@ | |||
| import Vue from 'vue' | |||
| import { axios } from '@/utils/request' | |||
| import signMd5Utils from '@/utils/encryption/signMd5Utils' | |||
| const api = { | |||
| user: '/mock/api/user', | |||
| role: '/mock/api/role', | |||
| service: '/mock/api/service', | |||
| permission: '/mock/api/permission', | |||
| permissionNoPager: '/mock/api/permission/no-pager' | |||
| } | |||
| export default api | |||
| //post | |||
| export function postAction(url,parameter) { | |||
| let sign = signMd5Utils.getSign(url, parameter); | |||
| //将签名和时间戳,添加在请求接口 Header | |||
| let signHeader = {"X-Sign": sign,"X-TIMESTAMP": signMd5Utils.getDateTimeToString()}; | |||
| return axios({ | |||
| url: url, | |||
| method:'post' , | |||
| data: parameter, | |||
| headers: signHeader | |||
| }) | |||
| } | |||
| //post method= {post | put} | |||
| export function httpAction(url,parameter,method) { | |||
| let sign = signMd5Utils.getSign(url, parameter); | |||
| //将签名和时间戳,添加在请求接口 Header | |||
| let signHeader = {"X-Sign": sign,"X-TIMESTAMP": signMd5Utils.getDateTimeToString()}; | |||
| return axios({ | |||
| url: url, | |||
| method:method , | |||
| data: parameter, | |||
| headers: signHeader | |||
| }) | |||
| } | |||
| //put | |||
| export function putAction(url,parameter) { | |||
| return axios({ | |||
| url: url, | |||
| method:'put', | |||
| data: parameter | |||
| }) | |||
| } | |||
| //get | |||
| export function getAction(url,parameter) { | |||
| let sign = signMd5Utils.getSign(url, parameter); | |||
| //将签名和时间戳,添加在请求接口 Header | |||
| let signHeader = {"X-Sign": sign,"X-TIMESTAMP": signMd5Utils.getDateTimeToString()}; | |||
| return axios({ | |||
| url: url, | |||
| method: 'get', | |||
| params: parameter, | |||
| headers: signHeader | |||
| }) | |||
| } | |||
| //deleteAction | |||
| export function deleteAction(url,parameter) { | |||
| return axios({ | |||
| url: url, | |||
| method: 'delete', | |||
| params: parameter | |||
| }) | |||
| } | |||
| export function getUserList(parameter) { | |||
| return axios({ | |||
| url: api.user, | |||
| method: 'get', | |||
| params: parameter | |||
| }) | |||
| } | |||
| export function getRoleList(parameter) { | |||
| return axios({ | |||
| url: api.role, | |||
| method: 'get', | |||
| params: parameter | |||
| }) | |||
| } | |||
| export function getServiceList(parameter) { | |||
| return axios({ | |||
| url: api.service, | |||
| method: 'get', | |||
| params: parameter | |||
| }) | |||
| } | |||
| export function getPermissions(parameter) { | |||
| return axios({ | |||
| url: api.permissionNoPager, | |||
| method: 'get', | |||
| params: parameter | |||
| }) | |||
| } | |||
| // id == 0 add post | |||
| // id != 0 update put | |||
| export function saveService(parameter) { | |||
| return axios({ | |||
| url: api.service, | |||
| method: parameter.id == 0 ? 'post' : 'put', | |||
| data: parameter | |||
| }) | |||
| } | |||
| /** | |||
| * 下载文件 用于excel导出 | |||
| * @param url | |||
| * @param parameter | |||
| * @returns {*} | |||
| */ | |||
| export function downFile(url,parameter){ | |||
| return axios({ | |||
| url: url, | |||
| params: parameter, | |||
| method:'get' , | |||
| responseType: 'blob' | |||
| }) | |||
| } | |||
| /** | |||
| * 下载文件 | |||
| * @param url 文件路径 | |||
| * @param fileName 文件名 | |||
| * @param parameter | |||
| * @returns {*} | |||
| */ | |||
| export function downloadFile(url, fileName, parameter) { | |||
| return downFile(url, parameter).then((data) => { | |||
| if (!data || data.size === 0) { | |||
| Vue.prototype['$message'].warning('文件下载失败') | |||
| return | |||
| } | |||
| if (typeof window.navigator.msSaveBlob !== 'undefined') { | |||
| window.navigator.msSaveBlob(new Blob([data]), fileName) | |||
| } else { | |||
| let url = window.URL.createObjectURL(new Blob([data])) | |||
| let link = document.createElement('a') | |||
| link.style.display = 'none' | |||
| link.href = url | |||
| link.setAttribute('download', fileName) | |||
| document.body.appendChild(link) | |||
| link.click() | |||
| document.body.removeChild(link) //下载完成移除元素 | |||
| window.URL.revokeObjectURL(url) //释放掉blob对象 | |||
| } | |||
| }) | |||
| } | |||
| /** | |||
| * 文件上传 用于富文本上传图片 | |||
| * @param url | |||
| * @param parameter | |||
| * @returns {*} | |||
| */ | |||
| export function uploadAction(url,parameter){ | |||
| return axios({ | |||
| url: url, | |||
| data: parameter, | |||
| method:'post' , | |||
| headers: { | |||
| 'Content-Type': 'multipart/form-data', // 文件上传 | |||
| }, | |||
| }) | |||
| } | |||
| /** | |||
| * 获取文件服务访问路径 | |||
| * @param avatar | |||
| * @param subStr | |||
| * @returns {*} | |||
| */ | |||
| export function getFileAccessHttpUrl(avatar,subStr) { | |||
| if(!subStr) subStr = 'http' | |||
| try { | |||
| if(avatar && avatar.startsWith(subStr)){ | |||
| return avatar; | |||
| }else{ | |||
| if(avatar && avatar.length>0 && avatar.indexOf('[')==-1){ | |||
| return window._CONFIG['staticDomainURL'] + "/" + avatar; | |||
| } | |||
| } | |||
| }catch(err){ | |||
| return; | |||
| } | |||
| } | |||
| @ -0,0 +1,69 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
| <svg width="1361px" height="609px" viewBox="0 0 1361 609" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||
| <!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch --> | |||
| <title>Group 21</title> | |||
| <desc>Created with Sketch.</desc> | |||
| <defs></defs> | |||
| <g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | |||
| <g id="账户密码登录-校验" transform="translate(-79.000000, -82.000000)"> | |||
| <g id="Group-21" transform="translate(77.000000, 73.000000)"> | |||
| <g id="Group-18" opacity="0.8" transform="translate(74.901416, 569.699158) rotate(-7.000000) translate(-74.901416, -569.699158) translate(4.901416, 525.199158)"> | |||
| <ellipse id="Oval-11" fill="#CFDAE6" opacity="0.25" cx="63.5748792" cy="32.468367" rx="21.7830479" ry="21.766008"></ellipse> | |||
| <ellipse id="Oval-3" fill="#CFDAE6" opacity="0.599999964" cx="5.98746479" cy="13.8668601" rx="5.2173913" ry="5.21330997"></ellipse> | |||
| <path d="M38.1354514,88.3520215 C43.8984227,88.3520215 48.570234,83.6838647 48.570234,77.9254015 C48.570234,72.1669383 43.8984227,67.4987816 38.1354514,67.4987816 C32.3724801,67.4987816 27.7006688,72.1669383 27.7006688,77.9254015 C27.7006688,83.6838647 32.3724801,88.3520215 38.1354514,88.3520215 Z" id="Oval-3-Copy" fill="#CFDAE6" opacity="0.45"></path> | |||
| <path d="M64.2775582,33.1704963 L119.185836,16.5654915" id="Path-12" stroke="#CFDAE6" stroke-width="1.73913043" stroke-linecap="round" stroke-linejoin="round"></path> | |||
| <path d="M42.1431708,26.5002681 L7.71190162,14.5640702" id="Path-16" stroke="#E0B4B7" stroke-width="0.702678964" opacity="0.7" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path> | |||
| <path d="M63.9262187,33.521561 L43.6721326,69.3250951" id="Path-15" stroke="#BACAD9" stroke-width="0.702678964" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path> | |||
| <g id="Group-17" transform="translate(126.850922, 13.543654) rotate(30.000000) translate(-126.850922, -13.543654) translate(117.285705, 4.381889)" fill="#CFDAE6"> | |||
| <ellipse id="Oval-4" opacity="0.45" cx="9.13482653" cy="9.12768076" rx="9.13482653" ry="9.12768076"></ellipse> | |||
| <path d="M18.2696531,18.2553615 C18.2696531,13.2142826 14.1798519,9.12768076 9.13482653,9.12768076 C4.08980114,9.12768076 0,13.2142826 0,18.2553615 L18.2696531,18.2553615 Z" id="Oval-4" transform="translate(9.134827, 13.691521) scale(-1, -1) translate(-9.134827, -13.691521) "></path> | |||
| </g> | |||
| </g> | |||
| <g id="Group-14" transform="translate(216.294700, 123.725600) rotate(-5.000000) translate(-216.294700, -123.725600) translate(106.294700, 35.225600)"> | |||
| <ellipse id="Oval-2" fill="#CFDAE6" opacity="0.25" cx="29.1176471" cy="29.1402439" rx="29.1176471" ry="29.1402439"></ellipse> | |||
| <ellipse id="Oval-2" fill="#CFDAE6" opacity="0.3" cx="29.1176471" cy="29.1402439" rx="21.5686275" ry="21.5853659"></ellipse> | |||
| <ellipse id="Oval-2-Copy" stroke="#CFDAE6" opacity="0.4" cx="179.019608" cy="138.146341" rx="23.7254902" ry="23.7439024"></ellipse> | |||
| <ellipse id="Oval-2" fill="#BACAD9" opacity="0.5" cx="29.1176471" cy="29.1402439" rx="10.7843137" ry="10.7926829"></ellipse> | |||
| <path d="M29.1176471,39.9329268 L29.1176471,18.347561 C23.1616351,18.347561 18.3333333,23.1796097 18.3333333,29.1402439 C18.3333333,35.1008781 23.1616351,39.9329268 29.1176471,39.9329268 Z" id="Oval-2" fill="#BACAD9"></path> | |||
| <g id="Group-9" opacity="0.45" transform="translate(172.000000, 131.000000)" fill="#E6A1A6"> | |||
| <ellipse id="Oval-2-Copy-2" cx="7.01960784" cy="7.14634146" rx="6.47058824" ry="6.47560976"></ellipse> | |||
| <path d="M0.549019608,13.6219512 C4.12262681,13.6219512 7.01960784,10.722722 7.01960784,7.14634146 C7.01960784,3.56996095 4.12262681,0.670731707 0.549019608,0.670731707 L0.549019608,13.6219512 Z" id="Oval-2-Copy-2" transform="translate(3.784314, 7.146341) scale(-1, 1) translate(-3.784314, -7.146341) "></path> | |||
| </g> | |||
| <ellipse id="Oval-10" fill="#CFDAE6" cx="218.382353" cy="138.685976" rx="1.61764706" ry="1.61890244"></ellipse> | |||
| <ellipse id="Oval-10-Copy-2" fill="#E0B4B7" opacity="0.35" cx="179.558824" cy="175.381098" rx="1.61764706" ry="1.61890244"></ellipse> | |||
| <ellipse id="Oval-10-Copy" fill="#E0B4B7" opacity="0.35" cx="180.098039" cy="102.530488" rx="2.15686275" ry="2.15853659"></ellipse> | |||
| <path d="M28.9985381,29.9671598 L171.151018,132.876024" id="Path-11" stroke="#CFDAE6" opacity="0.8"></path> | |||
| </g> | |||
| <g id="Group-10" opacity="0.799999952" transform="translate(1054.100635, 36.659317) rotate(-11.000000) translate(-1054.100635, -36.659317) translate(1026.600635, 4.659317)"> | |||
| <ellipse id="Oval-7" stroke="#CFDAE6" stroke-width="0.941176471" cx="43.8135593" cy="32" rx="11.1864407" ry="11.2941176"></ellipse> | |||
| <g id="Group-12" transform="translate(34.596774, 23.111111)" fill="#BACAD9"> | |||
| <ellipse id="Oval-7" opacity="0.45" cx="9.18534718" cy="8.88888889" rx="8.47457627" ry="8.55614973"></ellipse> | |||
| <path d="M9.18534718,17.4450386 C13.8657264,17.4450386 17.6599235,13.6143199 17.6599235,8.88888889 C17.6599235,4.16345787 13.8657264,0.332739156 9.18534718,0.332739156 L9.18534718,17.4450386 Z" id="Oval-7"></path> | |||
| </g> | |||
| <path d="M34.6597385,24.809694 L5.71666084,4.76878945" id="Path-2" stroke="#CFDAE6" stroke-width="0.941176471"></path> | |||
| <ellipse id="Oval" stroke="#CFDAE6" stroke-width="0.941176471" cx="3.26271186" cy="3.29411765" rx="3.26271186" ry="3.29411765"></ellipse> | |||
| <ellipse id="Oval-Copy" fill="#F7E1AD" cx="2.79661017" cy="61.1764706" rx="2.79661017" ry="2.82352941"></ellipse> | |||
| <path d="M34.6312443,39.2922712 L5.06366663,59.785082" id="Path-10" stroke="#CFDAE6" stroke-width="0.941176471"></path> | |||
| </g> | |||
| <g id="Group-19" opacity="0.33" transform="translate(1282.537219, 446.502867) rotate(-10.000000) translate(-1282.537219, -446.502867) translate(1142.537219, 327.502867)"> | |||
| <g id="Group-17" transform="translate(141.333539, 104.502742) rotate(275.000000) translate(-141.333539, -104.502742) translate(129.333539, 92.502742)" fill="#BACAD9"> | |||
| <circle id="Oval-4" opacity="0.45" cx="11.6666667" cy="11.6666667" r="11.6666667"></circle> | |||
| <path d="M23.3333333,23.3333333 C23.3333333,16.8900113 18.1099887,11.6666667 11.6666667,11.6666667 C5.22334459,11.6666667 0,16.8900113 0,23.3333333 L23.3333333,23.3333333 Z" id="Oval-4" transform="translate(11.666667, 17.500000) scale(-1, -1) translate(-11.666667, -17.500000) "></path> | |||
| </g> | |||
| <circle id="Oval-5-Copy-6" fill="#CFDAE6" cx="201.833333" cy="87.5" r="5.83333333"></circle> | |||
| <path d="M143.5,88.8126685 L155.070501,17.6038544" id="Path-17" stroke="#BACAD9" stroke-width="1.16666667"></path> | |||
| <path d="M17.5,37.3333333 L127.466252,97.6449735" id="Path-18" stroke="#BACAD9" stroke-width="1.16666667"></path> | |||
| <polyline id="Path-19" stroke="#CFDAE6" stroke-width="1.16666667" points="143.902597 120.302281 174.935455 231.571342 38.5 147.510847 126.366941 110.833333"></polyline> | |||
| <path d="M159.833333,99.7453842 L195.416667,89.25" id="Path-20" stroke="#E0B4B7" stroke-width="1.16666667" opacity="0.6"></path> | |||
| <path d="M205.333333,82.1372105 L238.719406,36.1666667" id="Path-24" stroke="#BACAD9" stroke-width="1.16666667"></path> | |||
| <path d="M266.723424,132.231988 L207.083333,90.4166667" id="Path-25" stroke="#CFDAE6" stroke-width="1.16666667"></path> | |||
| <circle id="Oval-5" fill="#C1D1E0" cx="156.916667" cy="8.75" r="8.75"></circle> | |||
| <circle id="Oval-5-Copy-3" fill="#C1D1E0" cx="39.0833333" cy="148.75" r="5.25"></circle> | |||
| <circle id="Oval-5-Copy-2" fill-opacity="0.6" fill="#D1DEED" cx="8.75" cy="33.25" r="8.75"></circle> | |||
| <circle id="Oval-5-Copy-4" fill-opacity="0.6" fill="#D1DEED" cx="243.833333" cy="30.3333333" r="5.83333333"></circle> | |||
| <circle id="Oval-5-Copy-5" fill="#E0B4B7" cx="175.583333" cy="232.75" r="5.25"></circle> | |||
| </g> | |||
| </g> | |||
| </g> | |||
| </g> | |||
| </svg> | |||
| @ -0,0 +1,33 @@ | |||
| @active-color: #11da75; | |||
| ul { | |||
| max-height: 700px; | |||
| overflow-y: auto; | |||
| padding-left: .5rem; | |||
| img { | |||
| width:64px; | |||
| height:64px; | |||
| padding: .2rem; | |||
| margin: .3rem; | |||
| cursor: pointer; | |||
| &.active, &:hover { | |||
| border: 1px solid @active-color; | |||
| border-radius: 2px; | |||
| color: #fff; | |||
| transition: all .3s; | |||
| } | |||
| } | |||
| li { | |||
| list-style: none; | |||
| float: left; | |||
| text-align: center; | |||
| cursor: pointer; | |||
| color: #555; | |||
| transition: color .3s ease-in-out,background-color .3s ease-in-out; | |||
| position: relative; | |||
| margin: 3px 0; | |||
| border-radius: 4px; | |||
| background-color: #fff; | |||
| overflow: hidden; | |||
| padding: 10px 0 0; | |||
| } | |||
| } | |||
| @ -0,0 +1,259 @@ | |||
| .area-zoom-in-top-enter-active, | |||
| .area-zoom-in-top-leave-active { | |||
| opacity: 1; | |||
| transform: scaleY(1); | |||
| } | |||
| .area-zoom-in-top-enter, | |||
| .area-zoom-in-top-leave-active { | |||
| opacity: 0; | |||
| transform: scaleY(0); | |||
| } | |||
| .area-select { | |||
| box-sizing: border-box; | |||
| margin: 0; | |||
| padding: 0; | |||
| color: rgba(0, 0, 0, 0.65); | |||
| font-size: 14px; | |||
| font-variant: tabular-nums; | |||
| line-height: 1.5; | |||
| list-style: none; | |||
| font-feature-settings: 'tnum'; | |||
| position: relative; | |||
| outline: 0; | |||
| display: block; | |||
| background-color: #fff; | |||
| border: 1px solid #d9d9d9; | |||
| border-top-width: 1.02px; | |||
| border-radius: 4px; | |||
| outline: none; | |||
| transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| user-select: none; | |||
| } | |||
| .area-select-wrap .area-select { | |||
| display: inline-block; | |||
| } | |||
| .area-select * { | |||
| box-sizing: border-box; | |||
| } | |||
| .area-select:hover { | |||
| border-color: #40a9ff; | |||
| border-right-width: 1px !important; | |||
| outline: 0; | |||
| } | |||
| .area-select:active { | |||
| box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); | |||
| } | |||
| .area-select.small { | |||
| width: 126px; | |||
| } | |||
| .area-select.medium { | |||
| width: 160px; | |||
| } | |||
| .area-select.large { | |||
| width: 194px; | |||
| } | |||
| .area-select.is-disabled { | |||
| background: #eceff5; | |||
| cursor: not-allowed; | |||
| } | |||
| .area-select.is-disabled:hover { | |||
| border-color: #e1e2e6; | |||
| } | |||
| .area-select.is-disabled .area-selected-trigger { | |||
| cursor: not-allowed; | |||
| } | |||
| .area-select .area-selected-trigger { | |||
| position: relative; | |||
| display: block; | |||
| font-size: 14px; | |||
| cursor: pointer; | |||
| margin: 0; | |||
| overflow: hidden; | |||
| white-space: nowrap; | |||
| text-overflow: ellipsis; | |||
| height: 100%; | |||
| padding: 8px 20px 7px 12px; | |||
| } | |||
| .area-select .area-select-icon { | |||
| position: absolute; | |||
| top: 50%; | |||
| margin-top: -2px; | |||
| right: 6px; | |||
| content: ""; | |||
| width: 0; | |||
| height: 0; | |||
| border: 6px solid transparent; | |||
| border-top-color: rgba(0, 0, 0, 0.25); | |||
| transition: all .3s linear; | |||
| transform-origin: center; | |||
| } | |||
| .area-select .area-select-icon.active { | |||
| margin-top: -8px; | |||
| transform: rotate(180deg); | |||
| } | |||
| .area-selectable-list-wrap { | |||
| position: absolute; | |||
| width: 100%; | |||
| max-height: 275px; | |||
| z-index: 15000; | |||
| background-color: #fff; | |||
| box-sizing: border-box; | |||
| overflow-x: auto; | |||
| margin: 2px 0; | |||
| border-radius: 4px; | |||
| outline: none; | |||
| box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); | |||
| transition: opacity 0.15s, transform 0.3s !important; | |||
| transform-origin: center top !important; | |||
| } | |||
| .area-selectable-list { | |||
| position: relative; | |||
| margin: 0; | |||
| padding: 6px 0; | |||
| width: 100%; | |||
| font-size: 14px; | |||
| color: #565656; | |||
| list-style: none; | |||
| } | |||
| .area-selectable-list .area-select-option { | |||
| position: relative; | |||
| white-space: nowrap; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| cursor: pointer; | |||
| padding: 0 15px 0 10px; | |||
| height: 32px; | |||
| line-height: 32px; | |||
| } | |||
| .area-selectable-list .area-select-option.hover { | |||
| background-color: #e6f7ff; | |||
| } | |||
| .area-selectable-list .area-select-option.selected { | |||
| color: rgba(0, 0, 0, 0.65); | |||
| font-weight: 600; | |||
| background-color: #efefef; | |||
| } | |||
| .cascader-menu-list-wrap { | |||
| position: absolute; | |||
| white-space: nowrap; | |||
| z-index: 15000; | |||
| background-color: #fff; | |||
| box-sizing: border-box; | |||
| overflow: hidden; | |||
| font-size: 0; | |||
| margin: 2px 0; | |||
| border-radius: 4px; | |||
| outline: none; | |||
| box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); | |||
| transition: opacity 0.15s, transform 0.3s !important; | |||
| transform-origin: center top !important; | |||
| } | |||
| .cascader-menu-list { | |||
| position: relative; | |||
| margin: 0; | |||
| font-size: 14px; | |||
| color: #565656; | |||
| padding: 6px 0; | |||
| list-style: none; | |||
| display: inline-block; | |||
| height: 204px; | |||
| overflow-x: hidden; | |||
| overflow-y: auto; | |||
| min-width: 160px; | |||
| vertical-align: top; | |||
| background-color: #fff; | |||
| border-right: 1px solid #e4e7ed; | |||
| } | |||
| .cascader-menu-list:last-child { | |||
| border-right: none; | |||
| } | |||
| .cascader-menu-list .cascader-menu-option { | |||
| position: relative; | |||
| white-space: nowrap; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| cursor: pointer; | |||
| padding: 0 15px 0 10px; | |||
| height: 32px; | |||
| line-height: 32px; | |||
| } | |||
| .cascader-menu-list .cascader-menu-option.hover, | |||
| .cascader-menu-list .cascader-menu-option:hover { | |||
| background-color: #e6f7ff; | |||
| } | |||
| .cascader-menu-list .cascader-menu-option.selected { | |||
| color: rgba(0, 0, 0, 0.65); | |||
| font-weight: 600; | |||
| background-color: #efefef; | |||
| } | |||
| .cascader-menu-list .cascader-menu-option.cascader-menu-extensible:after { | |||
| position: absolute; | |||
| top: 50%; | |||
| margin-top: -4px; | |||
| right: 5px; | |||
| content: ""; | |||
| width: 0; | |||
| height: 0; | |||
| border: 4px solid transparent; | |||
| border-left-color: #a1a4ad; | |||
| } | |||
| .cascader-menu-list::-webkit-scrollbar, | |||
| .area-selectable-list-wrap::-webkit-scrollbar { | |||
| width: 8px; | |||
| background: transparent; | |||
| } | |||
| .area-selectable-list-wrap::-webkit-scrollbar-button:vertical:decremen, | |||
| .area-selectable-list-wrap::-webkit-scrollbar-button:vertical:end:decrement, | |||
| .area-selectable-list-wrap::-webkit-scrollbar-button:vertical:increment, | |||
| .area-selectable-list-wrap::-webkit-scrollbar-button:vertical:start:increment, | |||
| .cascader-menu-list::-webkit-scrollbar-button:vertical:decremen, | |||
| .cascader-menu-list::-webkit-scrollbar-button:vertical:end:decrement, | |||
| .cascader-menu-list::-webkit-scrollbar-button:vertical:increment, | |||
| .cascader-menu-list::-webkit-scrollbar-button:vertical:start:increment { | |||
| display: none; | |||
| } | |||
| .cascader-menu-list::-webkit-scrollbar-thumb:vertical, | |||
| .area-selectable-list-wrap::-webkit-scrollbar-thumb:vertical { | |||
| background-color: #b8b8b8; | |||
| border-radius: 4px; | |||
| } | |||
| .cascader-menu-list::-webkit-scrollbar-thumb:vertical:hover, | |||
| .area-selectable-list-wrap::-webkit-scrollbar-thumb:vertical:hover { | |||
| background-color: #777; | |||
| } | |||
| @ -0,0 +1,15 @@ | |||
| /** [表格主题样式一] 表格强制列不换行 */ | |||
| .j-table-force-nowrap { | |||
| td, th { | |||
| white-space: nowrap; | |||
| } | |||
| .ant-table-selection-column { | |||
| padding: 12px 22px !important; | |||
| } | |||
| /** 列自适应,弊端会导致列宽失效 */ | |||
| &.ant-table-wrapper .ant-table-content { | |||
| overflow-x: auto; | |||
| } | |||
| } | |||
| @ -0,0 +1 @@ | |||
| .cm-s-idea span.cm-meta{color:olive}.cm-s-idea span.cm-number{color:#00f}.cm-s-idea span.cm-keyword{line-height:1em;font-weight:700;color:navy}.cm-s-idea span.cm-atom{font-weight:700;color:navy}.cm-s-idea span.cm-def{color:#000}.cm-s-idea span.cm-variable{color:#000}.cm-s-idea span.cm-variable-2{color:#000}.cm-s-idea span.cm-type,.cm-s-idea span.cm-variable-3{color:#000}.cm-s-idea span.cm-property{color:#000}.cm-s-idea span.cm-operator{color:#000}.cm-s-idea span.cm-comment{color:grey}.cm-s-idea span.cm-string{color:green}.cm-s-idea span.cm-string-2{color:green}.cm-s-idea span.cm-qualifier{color:#555}.cm-s-idea span.cm-error{color:red}.cm-s-idea span.cm-attribute{color:#00f}.cm-s-idea span.cm-tag{color:navy}.cm-s-idea span.cm-link{color:#00f}.cm-s-idea .CodeMirror-activeline-background{background:#fffae3}.cm-s-idea span.cm-builtin{color:#30a}.cm-s-idea span.cm-bracket{color:#cc7}.cm-s-idea{font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif}.cm-s-idea .CodeMirror-matchingbracket{outline:1px solid grey;color:#000!important}.CodeMirror-hints.idea{font-family:Menlo,Monaco,Consolas,'Courier New',monospace;color:#616569;background-color:#ebf3fd!important}.CodeMirror-hints.idea .CodeMirror-hint-active{background-color:#a2b8c9!important;color:#5c6065!important} | |||
| @ -0,0 +1,61 @@ | |||
| /*列表上方操作按钮区域*/ | |||
| .ant-card-body .table-operator { | |||
| margin-bottom: 8px; | |||
| } | |||
| /** Button按钮间距 */ | |||
| .table-operator .ant-btn { | |||
| margin: 0 8px 8px 0; | |||
| } | |||
| .table-operator .ant-btn-group .ant-btn { | |||
| margin: 0; | |||
| } | |||
| .table-operator .ant-btn-group .ant-btn:last-child { | |||
| margin: 0 8px 8px 0; | |||
| } | |||
| /*列表td的padding设置 可以控制列表大小*/ | |||
| .ant-table-tbody .ant-table-row td { | |||
| padding-top: 15px; | |||
| padding-bottom: 15px; | |||
| } | |||
| /*列表页面弹出modal*/ | |||
| .ant-modal-cust-warp { | |||
| height: 100% | |||
| } | |||
| /*弹出modal Y轴滚动条*/ | |||
| .ant-modal-cust-warp .ant-modal-body { | |||
| height: calc(100% - 110px) !important; | |||
| overflow-y: auto | |||
| } | |||
| /*弹出modal 先有content后有body 故滚动条控制在body上*/ | |||
| .ant-modal-cust-warp .ant-modal-content { | |||
| height: 90% !important; | |||
| overflow-y: hidden | |||
| } | |||
| /*列表中有图片的加这个样式 参考用户管理*/ | |||
| .anty-img-wrap { | |||
| height: 25px; | |||
| position: relative; | |||
| } | |||
| .anty-img-wrap > img { | |||
| max-height: 100%; | |||
| } | |||
| /*列表中范围查询样式*/ | |||
| .query-group-cust{width: calc(50% - 10px)} | |||
| .query-group-split-cust:before{content:"~";width: 20px;display: inline-block;text-align: center} | |||
| /*erp风格子表外框padding设置*/ | |||
| .ant-card-wider-padding.cust-erp-sub-tab>.ant-card-body{padding:5px 12px} | |||
| /* 内嵌子表背景颜色 */ | |||
| .j-inner-table-wrapper /deep/ .ant-table-expanded-row .ant-table-wrapper .ant-table-tbody .ant-table-row { | |||
| background-color: #FFFFFF; | |||
| } | |||
| /**隐藏样式-modal确定按钮 */ | |||
| .jee-hidden{display: none} | |||
| @ -0,0 +1,28 @@ | |||
| /** | |||
| * 列表查询通用样式,移动端自适应 | |||
| */ | |||
| .search{ | |||
| margin-bottom: 54px; | |||
| } | |||
| .fold{ | |||
| width: calc(100% - 216px); | |||
| display: inline-block | |||
| } | |||
| .operator{ | |||
| margin-bottom: 18px; | |||
| } | |||
| @media screen and (max-width: 900px) { | |||
| .fold { | |||
| width: 100%; | |||
| } | |||
| } | |||
| .operator button { | |||
| margin-right: 5px; | |||
| } | |||
| i { | |||
| cursor: pointer; | |||
| } | |||
| .trcolor{ | |||
| background-color: rgba(255, 192, 203, 0.31); | |||
| color:red; | |||
| } | |||
| @ -0,0 +1,172 @@ | |||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
| <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> | |||
| <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="293px" height="293px" viewBox="0 0 293 293" enable-background="new 0 0 293 293" xml:space="preserve"> <image id="image0" width="293" height="293" x="0" y="0" | |||
| href="data:image/png;base64,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 | |||
| OjAwP26CAAAAAABJRU5ErkJggg==" /> | |||
| </svg> | |||
| @ -0,0 +1,77 @@ | |||
| import Vue from 'vue' | |||
| import { ACCESS_TOKEN } from "@/store/mutation-types" | |||
| import store from '@/store' | |||
| /** | |||
| * 单点登录 | |||
| */ | |||
| const init = (callback) => { | |||
| if (process.env.VUE_APP_SSO == 'true') { | |||
| console.log("-------单点登录开始-------"); | |||
| let token = Vue.ls.get(ACCESS_TOKEN); | |||
| let st = getUrlParam("ticket"); | |||
| let sevice = "http://" + window.location.host + "/"; | |||
| if (token) { | |||
| loginSuccess(callback); | |||
| } else { | |||
| if (st) { | |||
| validateSt(st, sevice, callback); | |||
| } else { | |||
| let serviceUrl = encodeURIComponent(sevice); | |||
| window.location.href = window._CONFIG['casPrefixUrl'] + "/login?service=" + serviceUrl; | |||
| } | |||
| } | |||
| console.log("-------单点登录结束-------"); | |||
| }else{ | |||
| callback && callback() | |||
| } | |||
| }; | |||
| const SSO = { | |||
| init: init | |||
| }; | |||
| function getUrlParam(paraName) { | |||
| let url = document.location.toString(); | |||
| let arrObj = url.split("?"); | |||
| if (arrObj.length > 1) { | |||
| let arrPara = arrObj[1].split("&"); | |||
| let arr; | |||
| for (let i = 0; i < arrPara.length; i++) { | |||
| arr = arrPara[i].split("="); | |||
| if (arr != null && arr[0] == paraName) { | |||
| return arr[1]; | |||
| } | |||
| } | |||
| return ""; | |||
| } | |||
| else { | |||
| return ""; | |||
| } | |||
| } | |||
| function validateSt(ticket,service,callback){ | |||
| let params = { | |||
| ticket: ticket, | |||
| service:service | |||
| }; | |||
| store.dispatch('ValidateLogin',params).then(res => { | |||
| //this.departConfirm(res) | |||
| if(res.success){ | |||
| loginSuccess(callback); | |||
| }else{ | |||
| let sevice = "http://"+window.location.host+"/"; | |||
| let serviceUrl = encodeURIComponent(sevice); | |||
| window.location.href = window._CONFIG['casPrefixUrl']+"/login?service="+serviceUrl; | |||
| } | |||
| }).catch((err) => { | |||
| console.log(err); | |||
| //that.requestFailed(err); | |||
| }); | |||
| } | |||
| function loginSuccess (callback) { | |||
| callback(); | |||
| } | |||
| export default SSO; | |||
| @ -0,0 +1,46 @@ | |||
| <template> | |||
| <tooltip v-if="tips !== ''"> | |||
| <template slot="title">{{ tips }}</template> | |||
| <avatar :size="avatarSize" :src="src" /> | |||
| </tooltip> | |||
| <avatar v-else :size="avatarSize" :src="src" /> | |||
| </template> | |||
| <script> | |||
| import Avatar from 'ant-design-vue/es/avatar' | |||
| import Tooltip from 'ant-design-vue/es/tooltip' | |||
| export default { | |||
| name: "AvatarItem", | |||
| components: { | |||
| Avatar, | |||
| Tooltip | |||
| }, | |||
| props: { | |||
| tips: { | |||
| type: String, | |||
| default: '', | |||
| required: false | |||
| }, | |||
| src: { | |||
| type: String, | |||
| default: '' | |||
| } | |||
| }, | |||
| data () { | |||
| return { | |||
| size: this.$parent.size | |||
| } | |||
| }, | |||
| computed: { | |||
| avatarSize () { | |||
| return this.size !== 'mini' && this.size || 20 | |||
| } | |||
| }, | |||
| watch: { | |||
| '$parent.size' (val) { | |||
| this.size = val | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,100 @@ | |||
| <!-- | |||
| <template> | |||
| <div :class="[prefixCls]"> | |||
| <ul> | |||
| <slot></slot> | |||
| <template v-for="item in filterEmpty($slots.default).slice(0, 3)"></template> | |||
| <template v-if="maxLength > 0 && filterEmpty($slots.default).length > maxLength"> | |||
| <avatar-item :size="size"> | |||
| <avatar :size="size !== 'mini' && size || 20" :style="excessItemsStyle">{{ `+${maxLength}` }}</avatar> | |||
| </avatar-item> | |||
| </template> | |||
| </ul> | |||
| </div> | |||
| </template> | |||
| --> | |||
| <script> | |||
| import Avatar from 'ant-design-vue/es/avatar' | |||
| import AvatarItem from './Item' | |||
| import { filterEmpty } from '@/components/_util/util' | |||
| export default { | |||
| AvatarItem, | |||
| name: "AvatarList", | |||
| components: { | |||
| Avatar, | |||
| AvatarItem | |||
| }, | |||
| props: { | |||
| prefixCls: { | |||
| type: String, | |||
| default: 'ant-pro-avatar-list' | |||
| }, | |||
| /** | |||
| * 头像大小 类型: large、small 、mini, default | |||
| * 默认值: default | |||
| */ | |||
| size: { | |||
| type: [String, Number], | |||
| default: 'default' | |||
| }, | |||
| /** | |||
| * 要显示的最大项目 | |||
| */ | |||
| maxLength: { | |||
| type: Number, | |||
| default: 0 | |||
| }, | |||
| /** | |||
| * 多余的项目风格 | |||
| */ | |||
| excessItemsStyle: { | |||
| type: Object, | |||
| default: () => { | |||
| return { | |||
| color: '#f56a00', | |||
| backgroundColor: '#fde3cf' | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| data () { | |||
| return {} | |||
| }, | |||
| methods: { | |||
| getItems(items) { | |||
| const classString = { | |||
| [`${this.prefixCls}-item`]: true, | |||
| [`${this.size}`]: true | |||
| } | |||
| if (this.maxLength > 0) { | |||
| items = items.slice(0, this.maxLength) | |||
| items.push((<Avatar size={ this.size } style={ this.excessItemsStyle }>{`+${this.maxLength}`}</Avatar>)) | |||
| } | |||
| const itemList = items.map((item) => ( | |||
| <li class={ classString }>{ item }</li> | |||
| )) | |||
| return itemList | |||
| } | |||
| }, | |||
| render () { | |||
| const { prefixCls, size } = this.$props | |||
| const classString = { | |||
| [`${prefixCls}`]: true, | |||
| [`${size}`]: true, | |||
| } | |||
| const items = filterEmpty(this.$slots.default) | |||
| const itemsDom = items && items.length ? <ul class={`${prefixCls}-items`}>{ this.getItems(items) }</ul> : null | |||
| return ( | |||
| <div class={ classString }> | |||
| { itemsDom } | |||
| </div> | |||
| ) | |||
| } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,4 @@ | |||
| import AvatarList from './List' | |||
| import "./index.less" | |||
| export default AvatarList | |||
| @ -0,0 +1,60 @@ | |||
| @import "../index"; | |||
| @avatar-list-prefix-cls: ~"@{ant-pro-prefix}-avatar-list"; | |||
| @avatar-list-item-prefix-cls: ~"@{ant-pro-prefix}-avatar-list-item"; | |||
| .@{avatar-list-prefix-cls} { | |||
| display: inline-block; | |||
| ul { | |||
| list-style: none; | |||
| display: inline-block; | |||
| padding: 0; | |||
| margin: 0 0 0 8px; | |||
| font-size: 0; | |||
| } | |||
| } | |||
| .@{avatar-list-item-prefix-cls} { | |||
| display: inline-block; | |||
| font-size: @font-size-base; | |||
| margin-left: -8px; | |||
| width: @avatar-size-base; | |||
| height: @avatar-size-base; | |||
| :global { | |||
| .ant-avatar { | |||
| border: 1px solid #fff; | |||
| cursor: pointer; | |||
| } | |||
| } | |||
| &.large { | |||
| width: @avatar-size-lg; | |||
| height: @avatar-size-lg; | |||
| } | |||
| &.small { | |||
| width: @avatar-size-sm; | |||
| height: @avatar-size-sm; | |||
| } | |||
| &.mini { | |||
| width: 20px; | |||
| height: 20px; | |||
| :global { | |||
| .ant-avatar { | |||
| width: 20px; | |||
| height: 20px; | |||
| line-height: 20px; | |||
| .ant-avatar-string { | |||
| font-size: 12px; | |||
| line-height: 18px; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @ -0,0 +1,111 @@ | |||
| <template> | |||
| <a-card :loading="loading" :body-style="{ padding: '20px 24px 8px' }" :bordered="false"> | |||
| <div class="chart-card-header"> | |||
| <div class="meta"> | |||
| <span class="chart-card-title">{{ title }}</span> | |||
| <span class="chart-card-action"> | |||
| <slot name="action"></slot> | |||
| </span> | |||
| </div> | |||
| <div class="total"><span>{{ total }}</span></div> | |||
| </div> | |||
| <div class="chart-card-content"> | |||
| <div class="content-fix"> | |||
| <slot></slot> | |||
| </div> | |||
| </div> | |||
| <div class="chart-card-footer"> | |||
| <div class="field"> | |||
| <slot name="footer"></slot> | |||
| </div> | |||
| </div> | |||
| </a-card> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| name: "ChartCard", | |||
| props: { | |||
| title: { | |||
| type: String, | |||
| default: '' | |||
| }, | |||
| total: { | |||
| type: String, | |||
| default: '' | |||
| }, | |||
| loading: { | |||
| type: Boolean, | |||
| default: false | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="less" scoped> | |||
| .chart-card-header { | |||
| position: relative; | |||
| overflow: hidden; | |||
| width: 100%; | |||
| .meta { | |||
| position: relative; | |||
| overflow: hidden; | |||
| width: 100%; | |||
| color: rgba(0, 0, 0, .45); | |||
| font-size: 14px; | |||
| line-height: 22px; | |||
| } | |||
| } | |||
| .chart-card-action { | |||
| cursor: pointer; | |||
| position: absolute; | |||
| top: 0; | |||
| right: 0; | |||
| } | |||
| .chart-card-footer { | |||
| border-top: 1px solid #e8e8e8; | |||
| padding-top: 9px; | |||
| margin-top: 8px; | |||
| > * { | |||
| position: relative; | |||
| } | |||
| .field { | |||
| white-space: nowrap; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| margin: 0; | |||
| } | |||
| } | |||
| .chart-card-content { | |||
| margin-bottom: 12px; | |||
| position: relative; | |||
| height: 46px; | |||
| width: 100%; | |||
| .content-fix { | |||
| position: absolute; | |||
| left: 0; | |||
| bottom: 0; | |||
| width: 100%; | |||
| } | |||
| } | |||
| .total { | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| word-break: break-all; | |||
| white-space: nowrap; | |||
| color: #000; | |||
| margin-top: 4px; | |||
| margin-bottom: 0; | |||
| font-size: 30px; | |||
| line-height: 38px; | |||
| height: 38px; | |||
| } | |||
| </style> | |||
| @ -0,0 +1,103 @@ | |||
| <template> | |||
| <span> | |||
| {{ lastTime | format }} | |||
| </span> | |||
| </template> | |||
| <script> | |||
| function fixedZero(val) { | |||
| return val * 1 < 10 ? `0${val}` : val; | |||
| } | |||
| export default { | |||
| name: "CountDown", | |||
| props: { | |||
| format: { | |||
| type: Function, | |||
| default: undefined | |||
| }, | |||
| target: { | |||
| type: [Date, Number], | |||
| required: true, | |||
| }, | |||
| onEnd: { | |||
| type: Function, | |||
| default: () => { | |||
| } | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| dateTime: '0', | |||
| originTargetTime: 0, | |||
| lastTime: 0, | |||
| timer: 0, | |||
| interval: 1000 | |||
| } | |||
| }, | |||
| filters: { | |||
| format(time) { | |||
| const hours = 60 * 60 * 1000; | |||
| const minutes = 60 * 1000; | |||
| const h = Math.floor(time / hours); | |||
| const m = Math.floor((time - h * hours) / minutes); | |||
| const s = Math.floor((time - h * hours - m * minutes) / 1000); | |||
| return `${fixedZero(h)}:${fixedZero(m)}:${fixedZero(s)}` | |||
| } | |||
| }, | |||
| created() { | |||
| this.initTime() | |||
| this.tick() | |||
| }, | |||
| methods: { | |||
| initTime() { | |||
| let lastTime = 0; | |||
| let targetTime = 0; | |||
| this.originTargetTime = this.target | |||
| try { | |||
| if (Object.prototype.toString.call(this.target) === '[object Date]') { | |||
| targetTime = this.target | |||
| } else { | |||
| targetTime = new Date(this.target).getTime() | |||
| } | |||
| } catch (e) { | |||
| throw new Error('invalid target prop') | |||
| } | |||
| lastTime = targetTime - new Date().getTime(); | |||
| this.lastTime = lastTime < 0 ? 0 : lastTime | |||
| }, | |||
| tick() { | |||
| const {onEnd} = this | |||
| this.timer = setTimeout(() => { | |||
| if (this.lastTime < this.interval) { | |||
| clearTimeout(this.timer) | |||
| this.lastTime = 0 | |||
| if (typeof onEnd === 'function') { | |||
| onEnd(); | |||
| } | |||
| } else { | |||
| this.lastTime -= this.interval | |||
| this.tick() | |||
| } | |||
| }, this.interval) | |||
| } | |||
| }, | |||
| beforeUpdate () { | |||
| if (this.originTargetTime !== this.target) { | |||
| this.initTime() | |||
| } | |||
| }, | |||
| beforeDestroy() { | |||
| clearTimeout(this.timer) | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| </style> | |||
| @ -0,0 +1,3 @@ | |||
| import CountDown from './CountDown' | |||
| export default CountDown | |||
| @ -0,0 +1,49 @@ | |||
| <script> | |||
| import { cutStrByFullLength, getStrFullLength } from '@/components/_util/StringUtil' | |||
| export default { | |||
| name: 'Ellipsis', | |||
| props: { | |||
| prefixCls: { | |||
| type: String, | |||
| default: 'ant-pro-ellipsis' | |||
| }, | |||
| tooltip: { | |||
| type: Boolean, | |||
| default: true, | |||
| }, | |||
| length: { | |||
| type: Number, | |||
| default: 25, | |||
| }, | |||
| lines: { | |||
| type: Number, | |||
| default: 1 | |||
| }, | |||
| fullWidthRecognition: { | |||
| type: Boolean, | |||
| default: false | |||
| } | |||
| }, | |||
| methods: {}, | |||
| render() { | |||
| const { tooltip, length } = this.$props | |||
| let text = '' | |||
| // 处理没有default插槽时的特殊情况 | |||
| if (this.$slots.default) { | |||
| text = this.$slots.default.map(vNode => vNode.text).join('') | |||
| } | |||
| // 判断是否显示 tooltip | |||
| if (tooltip && getStrFullLength(text) > length) { | |||
| return ( | |||
| <a-tooltip> | |||
| <template slot="title">{text}</template> | |||
| <span>{cutStrByFullLength(text, this.length) + '…'}</span> | |||
| </a-tooltip> | |||
| ) | |||
| } else { | |||
| return (<span>{text}</span>) | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,3 @@ | |||
| import Ellipsis from './Ellipsis' | |||
| export default Ellipsis | |||
| @ -0,0 +1,228 @@ | |||
| <template> | |||
| <div> | |||
| <template v-if="hasFile" v-for="(file, fileKey) of [innerFile || {}]"> | |||
| <div :key="fileKey" style="position: relative;"> | |||
| <a-tooltip v-if="file.status==='uploading'" :title="`上传中(${Math.floor(file.percent)}%)`"> | |||
| <a-icon type="loading"/> | |||
| <span style="margin-left:5px">上传中…</span> | |||
| </a-tooltip> | |||
| <a-tooltip v-else-if="file.status==='done'" :title="file.name"> | |||
| <a-icon type="paper-clip"/> | |||
| <span style="margin-left:5px">{{ ellipsisFileName }}</span> | |||
| </a-tooltip> | |||
| <a-tooltip v-else :title="file.message||'上传失败'"> | |||
| <a-icon type="exclamation-circle" style="color:red;"/> | |||
| <span style="margin-left:5px">{{ ellipsisFileName }}</span> | |||
| </a-tooltip> | |||
| <template style="width: 30px"> | |||
| <a-dropdown :trigger="['click']" placement="bottomRight" style="margin-left: 10px;"> | |||
| <a-tooltip title="操作"> | |||
| <a-icon | |||
| v-if="file.status!=='uploading'" | |||
| type="setting" | |||
| style="cursor: pointer;"/> | |||
| </a-tooltip> | |||
| <a-menu slot="overlay"> | |||
| <a-menu-item v-if="originColumn.allowDownload !== false" @click="handleClickDownloadFile"> | |||
| <span><a-icon type="download"/> 下载</span> | |||
| </a-menu-item> | |||
| <a-menu-item v-if="originColumn.allowRemove !== false" @click="handleClickDeleteFile"> | |||
| <span><a-icon type="delete"/> 删除</span> | |||
| </a-menu-item> | |||
| <a-menu-item @click="handleMoreOperation(originColumn)"> | |||
| <span><a-icon type="bars"/> 更多</span> | |||
| </a-menu-item> | |||
| </a-menu> | |||
| </a-dropdown> | |||
| </template> | |||
| </div> | |||
| </template> | |||
| <a-upload | |||
| v-show="!hasFile" | |||
| name="file" | |||
| :data="{'isup': 1}" | |||
| :multiple="false" | |||
| :action="uploadAction" | |||
| :headers="uploadHeaders" | |||
| :showUploadList="false" | |||
| v-bind="cellProps" | |||
| @change="handleChangeUpload" | |||
| > | |||
| <a-button icon="upload">{{originColumn.btnText || '上传文件'}}</a-button> | |||
| </a-upload> | |||
| <j-file-pop ref="filePop" @ok="handleFileSuccess" :number="number"/> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { getFileAccessHttpUrl } from '@api/manage' | |||
| import JVxeCellMixins from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins' | |||
| import { ACCESS_TOKEN } from '@/store/mutation-types' | |||
| import JFilePop from '@/components/jeecg/minipop/JFilePop' | |||
| import JVxeUploadCell from '@/components/jeecg/JVxeTable/components/cells/JVxeUploadCell' | |||
| export default { | |||
| name: 'JVxeFileCell', | |||
| mixins: [JVxeCellMixins], | |||
| components: {JFilePop}, | |||
| props: {}, | |||
| data() { | |||
| return { | |||
| innerFile: null, | |||
| number:0, | |||
| } | |||
| }, | |||
| computed: { | |||
| /** upload headers */ | |||
| uploadHeaders() { | |||
| let {originColumn: col} = this | |||
| let headers = {} | |||
| if (col.token === true) { | |||
| headers['X-Access-Token'] = this.$ls.get(ACCESS_TOKEN) | |||
| } | |||
| return headers | |||
| }, | |||
| /** 上传请求地址 */ | |||
| uploadAction() { | |||
| if (!this.originColumn.action) { | |||
| return window._CONFIG['domianURL'] + '/sys/common/upload' | |||
| } else { | |||
| return this.originColumn.action | |||
| } | |||
| }, | |||
| hasFile() { | |||
| return this.innerFile != null | |||
| }, | |||
| ellipsisFileName() { | |||
| let length = 5 | |||
| let file = this.innerFile | |||
| if (!file || !file.name) { | |||
| return '' | |||
| } | |||
| if (file.name.length > length) { | |||
| return file.name.substr(0, length) + '…' | |||
| } | |||
| return file.name | |||
| }, | |||
| responseName() { | |||
| if (this.originColumn.responseName) { | |||
| return this.originColumn.responseName | |||
| } else { | |||
| return 'message' | |||
| } | |||
| }, | |||
| }, | |||
| watch: { | |||
| innerValue: { | |||
| immediate: true, | |||
| handler() { | |||
| if (this.innerValue) { | |||
| this.innerFile = this.innerValue | |||
| } else { | |||
| this.innerFile = null | |||
| } | |||
| }, | |||
| }, | |||
| }, | |||
| methods: { | |||
| // 点击更多按钮 | |||
| handleMoreOperation(originColumn) { | |||
| //update-begin-author:wangshuai date:20201021 for:LOWCOD-969 判断传过来的字段是否存在number,用于控制上传文件 | |||
| if (originColumn.number) { | |||
| this.number = originColumn.number | |||
| } else { | |||
| this.number = 0 | |||
| } | |||
| //update-end-author:wangshuai date:20201021 for:LOWCOD-969 判断传过来的字段是否存在number,用于控制上传文件 | |||
| if(originColumn && originColumn.fieldExtendJson){ | |||
| let json = JSON.parse(originColumn.fieldExtendJson); | |||
| this.number = json.uploadnum?json.uploadnum:0; | |||
| } | |||
| let path = '' | |||
| if (this.innerFile) { | |||
| path = this.innerFile.path | |||
| } | |||
| this.$refs.filePop.show('', path) | |||
| }, | |||
| // 更多上传回调 | |||
| handleFileSuccess(file) { | |||
| if (file) { | |||
| this.innerFile.path = file.path | |||
| this.handleChangeCommon(this.innerFile) | |||
| } | |||
| }, | |||
| handleChangeUpload(info) { | |||
| let {originColumn: col} = this | |||
| let {file} = info | |||
| let value = { | |||
| name: file.name, | |||
| type: file.type, | |||
| size: file.size, | |||
| status: file.status, | |||
| percent: file.percent | |||
| } | |||
| if (file.response) { | |||
| value['responseName'] = file.response[this.responseName] | |||
| } | |||
| if (file.status === 'done') { | |||
| if (typeof file.response.success === 'boolean') { | |||
| if (file.response.success) { | |||
| value['path'] = file.response[this.responseName] | |||
| this.handleChangeCommon(value) | |||
| } else { | |||
| value['status'] = 'error' | |||
| value['message'] = file.response.message || '未知错误' | |||
| } | |||
| } else { | |||
| // 考虑到如果设置action上传路径为非jeecg-boot后台,可能不会返回 success 属性的情况,就默认为成功 | |||
| value['path'] = file.response[this.responseName] | |||
| this.handleChangeCommon(value) | |||
| } | |||
| } else if (file.status === 'error') { | |||
| value['message'] = file.response.message || '未知错误' | |||
| } | |||
| this.innerFile = value | |||
| }, | |||
| handleClickDownloadFile() { | |||
| let {url, path} = this.innerFile || {} | |||
| if (!url || url.length === 0) { | |||
| if (path && path.length > 0) { | |||
| url = getFileAccessHttpUrl(path.split(',')[0]) | |||
| } | |||
| } | |||
| if (url) { | |||
| window.open(url) | |||
| } | |||
| }, | |||
| handleClickDeleteFile() { | |||
| this.handleChangeCommon(null) | |||
| }, | |||
| }, | |||
| // 【组件增强】注释详见:JVxeCellMixins.js | |||
| enhanced: { | |||
| switches: {visible: true}, | |||
| getValue: value => JVxeUploadCell.enhanced.getValue(value), | |||
| setValue: value => JVxeUploadCell.enhanced.setValue(value), | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped lang="less"> | |||
| </style> | |||
| @ -0,0 +1,242 @@ | |||
| <template> | |||
| <div> | |||
| <template v-if="hasFile" v-for="(file, fileKey) of [innerFile || {}]"> | |||
| <div :key="fileKey" style="position: relative;"> | |||
| <template v-if="!file || !(file['url'] || file['path'] || file['message'])"> | |||
| <a-tooltip :title="'请稍后: ' + JSON.stringify (file) + ((file['url'] || file['path'] || file['message']))"> | |||
| <a-icon type="loading"/> | |||
| </a-tooltip> | |||
| </template> | |||
| <template v-else-if="file['path']"> | |||
| <img class="j-editable-image" :src="imgSrc" alt="无图片" @click="handleMoreOperation"/> | |||
| </template> | |||
| <a-tooltip v-else :title="file.message||'上传失败'" @click="handleClickShowImageError"> | |||
| <a-icon type="exclamation-circle" style="color:red;"/> | |||
| </a-tooltip> | |||
| <template style="width: 30px"> | |||
| <a-dropdown :trigger="['click']" placement="bottomRight" style="margin-left: 10px;"> | |||
| <a-tooltip title="操作"> | |||
| <a-icon | |||
| v-if="file.status!=='uploading'" | |||
| type="setting" | |||
| style="cursor: pointer;"/> | |||
| </a-tooltip> | |||
| <a-menu slot="overlay"> | |||
| <a-menu-item v-if="originColumn.allowDownload !== false" @click="handleClickDownloadFile"> | |||
| <span><a-icon type="download"/> 下载</span> | |||
| </a-menu-item> | |||
| <a-menu-item v-if="originColumn.allowRemove !== false" @click="handleClickDeleteFile"> | |||
| <span><a-icon type="delete"/> 删除</span> | |||
| </a-menu-item> | |||
| <a-menu-item @click="handleMoreOperation(originColumn)"> | |||
| <span><a-icon type="bars"/> 更多</span> | |||
| </a-menu-item> | |||
| </a-menu> | |||
| </a-dropdown> | |||
| </template> | |||
| </div> | |||
| </template> | |||
| <a-upload | |||
| v-show="!hasFile" | |||
| name="file" | |||
| :data="{'isup': 1}" | |||
| :multiple="false" | |||
| :action="uploadAction" | |||
| :headers="uploadHeaders" | |||
| :showUploadList="false" | |||
| v-bind="cellProps" | |||
| @change="handleChangeUpload" | |||
| > | |||
| <a-button icon="upload">{{originColumn.btnText || '上传图片'}}</a-button> | |||
| </a-upload> | |||
| <j-file-pop ref="filePop" @ok="handleFileSuccess" :number="number"/> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { getFileAccessHttpUrl } from '@api/manage' | |||
| import JVxeCellMixins from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins' | |||
| import { ACCESS_TOKEN } from '@/store/mutation-types' | |||
| import JFilePop from '@/components/jeecg/minipop/JFilePop' | |||
| import JVxeUploadCell from '@/components/jeecg/JVxeTable/components/cells/JVxeUploadCell' | |||
| export default { | |||
| name: 'JVxeImageCell', | |||
| mixins: [JVxeCellMixins], | |||
| components: {JFilePop}, | |||
| props: {}, | |||
| data() { | |||
| return { | |||
| innerFile: null, | |||
| number:0 | |||
| } | |||
| }, | |||
| computed: { | |||
| /** upload headers */ | |||
| uploadHeaders() { | |||
| let {originColumn: col} = this | |||
| let headers = {} | |||
| if (col.token === true) { | |||
| headers['X-Access-Token'] = this.$ls.get(ACCESS_TOKEN) | |||
| } | |||
| return headers | |||
| }, | |||
| /** 上传请求地址 */ | |||
| uploadAction() { | |||
| if (!this.originColumn.action) { | |||
| return window._CONFIG['domianURL'] + '/sys/common/upload' | |||
| } else { | |||
| return this.originColumn.action | |||
| } | |||
| }, | |||
| hasFile() { | |||
| return this.innerFile != null | |||
| }, | |||
| /** 预览图片地址 */ | |||
| imgSrc() { | |||
| if (this.innerFile) { | |||
| if (this.innerFile['url']) { | |||
| return this.innerFile['url'] | |||
| } else if (this.innerFile['path']) { | |||
| let path = this.innerFile['path'].split(',')[0] | |||
| return getFileAccessHttpUrl(path) | |||
| } | |||
| } | |||
| return '' | |||
| }, | |||
| responseName() { | |||
| if (this.originColumn.responseName) { | |||
| return this.originColumn.responseName | |||
| } else { | |||
| return 'message' | |||
| } | |||
| }, | |||
| }, | |||
| watch: { | |||
| innerValue: { | |||
| immediate: true, | |||
| handler() { | |||
| if (this.innerValue) { | |||
| this.innerFile = this.innerValue | |||
| } else { | |||
| this.innerFile = null | |||
| } | |||
| }, | |||
| }, | |||
| }, | |||
| methods: { | |||
| // 点击更多按钮 | |||
| handleMoreOperation(originColumn) { | |||
| //update-begin-author:wangshuai date:20201021 for:LOWCOD-969 判断传过来的字段是否存在number,用于控制上传文件 | |||
| if (originColumn.number) { | |||
| this.number = originColumn.number | |||
| } else { | |||
| this.number = 0 | |||
| } | |||
| //update-end-author:wangshuai date:20201021 for:LOWCOD-969 判断传过来的字段是否存在number,用于控制上传文件 | |||
| if(originColumn && originColumn.fieldExtendJson){ | |||
| let json = JSON.parse(originColumn.fieldExtendJson); | |||
| this.number = json.uploadnum?json.uploadnum:0; | |||
| } | |||
| let path = '' | |||
| if (this.innerFile) { | |||
| path = this.innerFile.path | |||
| } | |||
| this.$refs.filePop.show('', path, 'img') | |||
| }, | |||
| // 更多上传回调 | |||
| handleFileSuccess(file) { | |||
| if (file) { | |||
| this.innerFile.path = file.path | |||
| this.handleChangeCommon(this.innerFile) | |||
| } | |||
| }, | |||
| // 弹出上传出错详细信息 | |||
| handleClickShowImageError() { | |||
| let file = this.innerFile || null | |||
| if (file && file['message']) { | |||
| this.$error({title: '上传出错', content: '错误信息:' + file['message'], maskClosable: true}) | |||
| } | |||
| }, | |||
| handleChangeUpload(info) { | |||
| let {originColumn: col} = this | |||
| let {file} = info | |||
| let value = { | |||
| name: file.name, | |||
| type: file.type, | |||
| size: file.size, | |||
| status: file.status, | |||
| percent: file.percent | |||
| } | |||
| if (file.response) { | |||
| value['responseName'] = file.response[this.responseName] | |||
| } | |||
| if (file.status === 'done') { | |||
| if (typeof file.response.success === 'boolean') { | |||
| if (file.response.success) { | |||
| value['path'] = file.response[this.responseName] | |||
| this.handleChangeCommon(value) | |||
| } else { | |||
| value['status'] = 'error' | |||
| value['message'] = file.response.message || '未知错误' | |||
| } | |||
| } else { | |||
| // 考虑到如果设置action上传路径为非jeecg-boot后台,可能不会返回 success 属性的情况,就默认为成功 | |||
| value['path'] = file.response[this.responseName] | |||
| this.handleChangeCommon(value) | |||
| } | |||
| } else if (file.status === 'error') { | |||
| value['message'] = file.response.message || '未知错误' | |||
| } | |||
| this.innerFile = value | |||
| }, | |||
| handleClickDownloadFile() { | |||
| if (this.imgSrc) { | |||
| window.open(this.imgSrc) | |||
| } | |||
| }, | |||
| handleClickDeleteFile() { | |||
| this.handleChangeCommon(null) | |||
| }, | |||
| }, | |||
| // 【组件增强】注释详见:JVxeCellMixins.js | |||
| enhanced: { | |||
| switches: {visible: true}, | |||
| getValue: value => JVxeUploadCell.enhanced.getValue(value), | |||
| setValue: value => JVxeUploadCell.enhanced.setValue(value), | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped lang="less"> | |||
| .j-editable-image { | |||
| height: 32px; | |||
| max-width: 100px !important; | |||
| cursor: pointer; | |||
| &:hover { | |||
| opacity: 0.8; | |||
| } | |||
| &:active { | |||
| opacity: 0.6; | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,63 @@ | |||
| <template> | |||
| <j-popup | |||
| v-bind="popupProps" | |||
| @input="handlePopupInput" | |||
| /> | |||
| </template> | |||
| <script> | |||
| import JVxeCellMixins, { dispatchEvent, vModel } from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins' | |||
| export default { | |||
| name: 'JVxePopupCell', | |||
| mixins: [JVxeCellMixins], | |||
| computed: { | |||
| popupProps() { | |||
| const {innerValue, originColumn: col, caseId, cellProps} = this | |||
| return { | |||
| ...cellProps, | |||
| value: innerValue, | |||
| field: col.field || col.key, | |||
| code: col.popupCode, | |||
| orgFields: col.orgFields, | |||
| destFields: col.destFields, | |||
| groupId: caseId, | |||
| param: col.param, | |||
| sorter: col.sorter, | |||
| } | |||
| }, | |||
| }, | |||
| methods: { | |||
| /** popup回调 */ | |||
| handlePopupInput(value, others) { | |||
| const {row, originColumn: col} = this | |||
| // 存储输入的值 | |||
| let popupValue = value | |||
| if (others && Object.keys(others).length > 0) { | |||
| Object.keys(others).forEach(key => { | |||
| let currentValue = others[key] | |||
| // 当前列直接赋值,其他列通过vModel赋值 | |||
| if (key === col.key) { | |||
| popupValue = currentValue | |||
| } else { | |||
| vModel.call(this, currentValue, row, key) | |||
| } | |||
| }) | |||
| } | |||
| this.handleChangeCommon(popupValue) | |||
| }, | |||
| }, | |||
| // 【组件增强】注释详见:JVxeCellMixins.js | |||
| enhanced: { | |||
| aopEvents: { | |||
| editActived(event) { | |||
| dispatchEvent.call(this, event, 'ant-input') | |||
| }, | |||
| }, | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| </style> | |||
| @ -0,0 +1,60 @@ | |||
| <template> | |||
| <a-radio-group | |||
| :class="clazz" | |||
| :value="innerValue" | |||
| v-bind="cellProps" | |||
| @change="(e)=>handleChangeCommon(e.target.value)" | |||
| > | |||
| <a-radio | |||
| v-for="item of originColumn.options" | |||
| :key="item.value" | |||
| :value="item.value" | |||
| @click="$event=>handleRadioClick(item,$event)" | |||
| >{{ item.text }} | |||
| </a-radio> | |||
| </a-radio-group> | |||
| </template> | |||
| <script> | |||
| import JVxeCellMixins from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins' | |||
| export default { | |||
| name: 'JVxeRadioCell', | |||
| mixins: [JVxeCellMixins], | |||
| computed: { | |||
| scrolling() { | |||
| return !!this.renderOptions.scrolling | |||
| }, | |||
| clazz() { | |||
| return { | |||
| 'j-vxe-radio': true, | |||
| 'no-animation': this.scrolling | |||
| } | |||
| }, | |||
| }, | |||
| methods: { | |||
| handleRadioClick(item) { | |||
| if (this.originColumn.allowClear === true) { | |||
| // 取消选择 | |||
| if (item.value === this.innerValue) { | |||
| this.handleChangeCommon(null) | |||
| } | |||
| } | |||
| }, | |||
| }, | |||
| // 【组件增强】注释详见:JVxeCellMixins.js | |||
| enhanced: { | |||
| switches: {visible: true}, | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="less"> | |||
| // 关闭动画,防止滚动时动态赋值出现问题 | |||
| .j-vxe-radio.no-animation { | |||
| .ant-radio-inner, | |||
| .ant-radio-inner::after { | |||
| transition: none !important; | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,262 @@ | |||
| import debounce from 'lodash/debounce' | |||
| import { getAction } from '@/api/manage' | |||
| import { cloneObject } from '@/utils/util' | |||
| import { filterDictText } from '@/components/dict/JDictSelectUtil' | |||
| import { ajaxGetDictItems, getDictItemsFromCache } from '@/api/api' | |||
| import JVxeCellMixins, { dispatchEvent } from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins' | |||
| /** 公共资源 */ | |||
| const common = { | |||
| /** value - label map,防止重复查询(刷新清空缓存) */ | |||
| labelMap: new Map(), | |||
| /** 公共data */ | |||
| data() { | |||
| return { | |||
| loading: false, | |||
| innerSelectValue: null, | |||
| innerOptions: [], | |||
| } | |||
| }, | |||
| /** 公共计算属性 */ | |||
| computed: { | |||
| dict() { | |||
| return this.originColumn.dict | |||
| }, | |||
| options() { | |||
| if (this.isAsync) { | |||
| return this.innerOptions | |||
| } else { | |||
| return this.originColumn.options || [] | |||
| } | |||
| }, | |||
| // 是否是异步模式 | |||
| isAsync() { | |||
| let isAsync = this.originColumn.async | |||
| return (isAsync != null && isAsync !== '') ? !!isAsync : true | |||
| }, | |||
| }, | |||
| /** 公共属性监听 */ | |||
| watch: { | |||
| innerValue: { | |||
| immediate: true, | |||
| handler(value) { | |||
| if (value == null || value === '') { | |||
| this.innerSelectValue = null | |||
| } else { | |||
| this.loadDataByValue(value) | |||
| } | |||
| } | |||
| }, | |||
| dict() { | |||
| this.loadDataByDict() | |||
| } | |||
| }, | |||
| /** 公共方法 */ | |||
| methods: { | |||
| // 根据 value 查询数据,用于回显 | |||
| async loadDataByValue(value) { | |||
| if (this.isAsync) { | |||
| if (this.innerSelectValue !== value) { | |||
| if (common.labelMap.has(value)) { | |||
| this.innerOptions = cloneObject(common.labelMap.get(value)) | |||
| } else { | |||
| let {success, result} = await getAction(`/sys/dict/loadDictItem/${this.dict}`, {key: value}) | |||
| if (success && result && result.length > 0) { | |||
| this.innerOptions = [{value: value, text: result[0]}] | |||
| common.labelMap.set(value, cloneObject(this.innerOptions)) | |||
| } | |||
| } | |||
| } | |||
| } | |||
| this.innerSelectValue = (value || '').toString() | |||
| }, | |||
| // 初始化字典 | |||
| async loadDataByDict() { | |||
| if (!this.isAsync) { | |||
| // 如果字典项集合有数据 | |||
| if (!this.originColumn.options || this.originColumn.options.length === 0) { | |||
| // 根据字典Code, 初始化字典数组 | |||
| let dictStr = '' | |||
| if (this.dict) { | |||
| let arr = this.dict.split(',') | |||
| if (arr[0].indexOf('where') > 0) { | |||
| let tbInfo = arr[0].split('where') | |||
| dictStr = tbInfo[0].trim() + ',' + arr[1] + ',' + arr[2] + ',' + encodeURIComponent(tbInfo[1]) | |||
| } else { | |||
| dictStr = this.dict | |||
| } | |||
| if (this.dict.indexOf(',') === -1) { | |||
| //优先从缓存中读取字典配置 | |||
| let cache = getDictItemsFromCache(this.dict) | |||
| if (cache) { | |||
| this.innerOptions = cache | |||
| return | |||
| } | |||
| } | |||
| let {success, result} = await ajaxGetDictItems(dictStr, null) | |||
| if (success) { | |||
| this.innerOptions = result | |||
| } | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| }, | |||
| } | |||
| // 显示组件,自带翻译 | |||
| export const DictSearchSpanCell = { | |||
| name: 'JVxeSelectSearchSpanCell', | |||
| mixins: [JVxeCellMixins], | |||
| data() { | |||
| return { | |||
| ...common.data.apply(this), | |||
| } | |||
| }, | |||
| computed: { | |||
| ...common.computed, | |||
| }, | |||
| watch: { | |||
| ...common.watch, | |||
| }, | |||
| methods: { | |||
| ...common.methods, | |||
| }, | |||
| render(h) { | |||
| return h('span', {}, [ | |||
| filterDictText(this.innerOptions, this.innerSelectValue || this.innerValue) | |||
| ]) | |||
| }, | |||
| } | |||
| // 请求id | |||
| let requestId = 0 | |||
| // 输入选择组件 | |||
| export const DictSearchInputCell = { | |||
| name: 'JVxeSelectSearchInputCell', | |||
| mixins: [JVxeCellMixins], | |||
| data() { | |||
| return { | |||
| ...common.data.apply(this), | |||
| hasRequest: false, | |||
| scopedSlots: { | |||
| notFoundContent: () => { | |||
| if (this.loading) { | |||
| return <a-spin size="small"/> | |||
| } else if (this.hasRequest) { | |||
| return <div>没有查询到任何数据</div> | |||
| } else { | |||
| return <div>{this.tipsContent}</div> | |||
| } | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| computed: { | |||
| ...common.computed, | |||
| tipsContent() { | |||
| return this.originColumn.tipsContent || '请输入搜索内容' | |||
| }, | |||
| filterOption() { | |||
| if (this.isAsync) { | |||
| return null | |||
| } | |||
| return (input, option) => option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0 | |||
| }, | |||
| }, | |||
| watch: { | |||
| ...common.watch, | |||
| }, | |||
| created() { | |||
| this.loadData = debounce(this.loadData, 300)//消抖 | |||
| }, | |||
| methods: { | |||
| ...common.methods, | |||
| loadData(value) { | |||
| const currentRequestId = ++requestId | |||
| this.loading = true | |||
| this.innerOptions = [] | |||
| if (value == null || value.trim() === '') { | |||
| this.loading = false | |||
| this.hasRequest = false | |||
| return | |||
| } | |||
| // 字典code格式:table,text,code | |||
| this.hasRequest = true | |||
| getAction(`/sys/dict/loadDict/${this.dict}`, {keyword: value}).then(res => { | |||
| if (currentRequestId !== requestId) { | |||
| return | |||
| } | |||
| let {success, result, message} = res | |||
| if (success) { | |||
| this.innerOptions = result | |||
| result.forEach((item) => { | |||
| common.labelMap.set(item.value, [item]) | |||
| }) | |||
| } else { | |||
| this.$message.warning(message) | |||
| } | |||
| }).finally(() => { | |||
| this.loading = false | |||
| }) | |||
| }, | |||
| handleChange(selectedValue) { | |||
| this.innerSelectValue = selectedValue | |||
| this.handleChangeCommon(this.innerSelectValue) | |||
| }, | |||
| handleSearch(value) { | |||
| if (this.isAsync) { | |||
| // 在输入时也应该开启加载,因为loadData加了消抖,所以会有800ms的用户主观上认为的卡顿时间 | |||
| this.loading = true | |||
| if (this.innerOptions.length > 0) { | |||
| this.innerOptions = [] | |||
| } | |||
| this.loadData(value) | |||
| } | |||
| }, | |||
| renderOptionItem() { | |||
| let options = [] | |||
| this.options.forEach(({value, text, label, title, disabled}) => { | |||
| options.push( | |||
| <a-select-option key={value} value={value} disabled={disabled}>{text || label || title}</a-select-option> | |||
| ) | |||
| }) | |||
| return options | |||
| }, | |||
| }, | |||
| render() { | |||
| return ( | |||
| <a-select | |||
| showSearch | |||
| allowClear | |||
| value={this.innerSelectValue} | |||
| filterOption={this.filterOption} | |||
| style="width: 100%" | |||
| {...this.cellProps} | |||
| onSearch={this.handleSearch} | |||
| onChange={this.handleChange} | |||
| scopedSlots={this.scopedSlots} | |||
| > | |||
| {this.renderOptionItem()} | |||
| </a-select> | |||
| ) | |||
| }, | |||
| // 【组件增强】注释详见:JVxeCellMixins.js | |||
| enhanced: { | |||
| aopEvents: { | |||
| editActived(event) { | |||
| dispatchEvent.call(this, event, 'ant-select') | |||
| }, | |||
| }, | |||
| } | |||
| } | |||
| @ -0,0 +1,36 @@ | |||
| import { installCell, JVXETypes } from '@/components/jeecg/JVxeTable' | |||
| import JVxePopupCell from './JVxePopupCell' | |||
| import { DictSearchInputCell, DictSearchSpanCell } from './JVxeSelectDictSearchCell' | |||
| import JVxeFileCell from './JVxeFileCell' | |||
| import JVxeImageCell from './JVxeImageCell' | |||
| import JVxeRadioCell from './JVxeRadioCell' | |||
| import JVxeSelectCell from '@comp/jeecg/JVxeTable/components/cells/JVxeSelectCell' | |||
| import JVxeTextareaCell from '@comp/jeecg/JVxeTable/components/cells/JVxeTextareaCell' | |||
| // 注册online组件 | |||
| JVXETypes.input_pop = 'input_pop' | |||
| JVXETypes.list_multi = 'list_multi' | |||
| JVXETypes.sel_search = 'sel_search' | |||
| installCell(JVXETypes.input_pop, JVxeTextareaCell) | |||
| installCell(JVXETypes.list_multi, JVxeSelectCell) | |||
| installCell(JVXETypes.sel_search, JVxeSelectCell) | |||
| // 注册【popup】组件(普通封装方式) | |||
| JVXETypes.popup = 'popup' | |||
| installCell(JVXETypes.popup, JVxePopupCell) | |||
| // 注册【字典搜索下拉】组件(高级封装方式) | |||
| JVXETypes.selectDictSearch = 'select-dict-search' | |||
| installCell(JVXETypes.selectDictSearch, DictSearchInputCell, DictSearchSpanCell) | |||
| // 注册【文件上传】组件 | |||
| JVXETypes.file = 'file' | |||
| installCell(JVXETypes.file, JVxeFileCell) | |||
| // 注册【图片上传】组件 | |||
| JVXETypes.image = 'image' | |||
| installCell(JVXETypes.image, JVxeImageCell) | |||
| // 注册【单选框】组件 | |||
| JVXETypes.radio = 'radio' | |||
| installCell(JVXETypes.radio, JVxeRadioCell) | |||
| @ -0,0 +1,54 @@ | |||
| <!--<template>--> | |||
| <!-- <div :class="[prefixCls]">--> | |||
| <!-- <slot name="subtitle">--> | |||
| <!-- <div :class="[`${prefixCls}-subtitle`]">{{ typeof subTitle === 'string' ? subTitle : subTitle() }}</div>--> | |||
| <!-- </slot>--> | |||
| <!-- <div class="number-info-value">--> | |||
| <!-- <span>{{ total }}</span>--> | |||
| <!-- <span class="sub-total">--> | |||
| <!-- {{ subTotal }}--> | |||
| <!-- <icon :type="`caret-${status}`" />--> | |||
| <!-- </span>--> | |||
| <!-- </div>--> | |||
| <!-- </div>--> | |||
| <!--</template>--> | |||
| <!--<script>--> | |||
| <!-- import Icon from 'ant-design-vue/es/icon'--> | |||
| <!-- export default {--> | |||
| <!-- name: 'NumberInfo',--> | |||
| <!-- props: {--> | |||
| <!-- prefixCls: {--> | |||
| <!-- type: String,--> | |||
| <!-- default: 'ant-pro-number-info'--> | |||
| <!-- },--> | |||
| <!-- total: {--> | |||
| <!-- type: Number,--> | |||
| <!-- required: true--> | |||
| <!-- },--> | |||
| <!-- subTotal: {--> | |||
| <!-- type: Number,--> | |||
| <!-- required: true--> | |||
| <!-- },--> | |||
| <!-- subTitle: {--> | |||
| <!-- type: [String, Function],--> | |||
| <!-- default: ''--> | |||
| <!-- },--> | |||
| <!-- status: {--> | |||
| <!-- type: String,--> | |||
| <!-- default: 'up'--> | |||
| <!-- }--> | |||
| <!-- },--> | |||
| <!-- components: {--> | |||
| <!-- Icon--> | |||
| <!-- },--> | |||
| <!-- data () {--> | |||
| <!-- return {}--> | |||
| <!-- }--> | |||
| <!-- }--> | |||
| <!--</script>--> | |||
| <!--<style lang="less" scoped>--> | |||
| <!-- @import "index";--> | |||
| <!--</style>--> | |||
| @ -0,0 +1,3 @@ | |||
| import NumberInfo from './NumberInfo' | |||
| export default NumberInfo | |||
| @ -0,0 +1,55 @@ | |||
| @import "../index"; | |||
| @numberInfo-prefix-cls: ~"@{ant-pro-prefix}-number-info"; | |||
| .@{numberInfo-prefix-cls} { | |||
| .ant-pro-number-info-subtitle { | |||
| color: @text-color-secondary; | |||
| font-size: @font-size-base; | |||
| height: 22px; | |||
| line-height: 22px; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| word-break: break-all; | |||
| white-space: nowrap; | |||
| } | |||
| .number-info-value { | |||
| margin-top: 4px; | |||
| font-size: 0; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| word-break: break-all; | |||
| white-space: nowrap; | |||
| & > span { | |||
| color: @heading-color; | |||
| display: inline-block; | |||
| line-height: 32px; | |||
| height: 32px; | |||
| font-size: 24px; | |||
| margin-right: 32px; | |||
| } | |||
| .sub-total { | |||
| color: @text-color-secondary; | |||
| font-size: @font-size-lg; | |||
| vertical-align: top; | |||
| margin-right: 0; | |||
| i { | |||
| font-size: 12px; | |||
| transform: scale(0.82); | |||
| margin-left: 4px; | |||
| } | |||
| :global { | |||
| .anticon-caret-up { | |||
| color: @red-6; | |||
| } | |||
| .anticon-caret-down { | |||
| color: @green-6; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @ -0,0 +1,43 @@ | |||
| ####1._util包:存放自定义函数 详细见代码注释 | |||
| ####2.AvatarList:显示头像群并支持tip,用法参考src\views\Home.vue(如下图) | |||
|  | |||
| ####3.chart包:存放各种图表相关的组件,条形图柱形图折线图等等 具体用法参考首页 | |||
| ####4.countDown包:一个倒计时组件,用法参考home页,简单描述,该组件有3个属性, | |||
| target(时间/毫秒数)必填, | |||
| format(function,该方法接收一个毫秒数的参数,用于格式化显示当前倒计时时间)非必填, | |||
| onEnd倒计时结束触发函数 | |||
|  | |||
| ####5.dict包:数据字典专用,用法参考文件夹下readme文件 | |||
| ####6.Ellipsis包:字符串截取组件,可以指定字符串的显示长度,并将全部内容显示到tip中,简单使用参考src\views\system\PermissionList.vue | |||
| ####7.jeecg包:该包下自定义了很多列表/表单中用到的组件 参考包下readme文件 | |||
| ####8.jeecgbiz包:该包下定义了一些业务相关的组件,比如选择用户弹框,根据部门选择用户等等 | |||
| ####9.layouts+page包:系统页面布局相关组件,比如登陆进去之后页面顶部显示什么,底部显示什么,菜单点击触发多个tab的布局等等 一般情况不需要修改 | |||
| ####10.menun包:菜单组件,俩个,一个折叠菜单一个正常显示的菜单 | |||
| ####11.NumberInfo:数字信息显示组件 如下图 | |||
|  | |||
| ####12.online包:该包下封装了online表单的相关组件,用于展示表单各种控件,验证表单等等,相关用法参考readme | |||
| ####13.setting包:该包下封装了首页风格切换等功能如下图 | |||
|  | |||
| ####14.table包:一个二次封装的table组件,用于展示列表,参考readme | |||
| ####15.tools包: | |||
| Breadcrumb.vue:面包屑二次封装,支持路由跳转 | |||
| DetailList.vue:详情展示用法参考src\views\profile\advanced\Advanced.vue(效果如下图) | |||
|  | |||
| ```` | |||
| 个人认为该页面代码有两点值得学习: | |||
| 1.vue provide/inject的使用 | |||
| 2.该页面css定义方式,只定义一个顶层class,其余样式都定义在其下,这样只要顶层class不和别的页面冲突,整个页面的样式都是唯一生效的 | |||
| ```` | |||
| FooterToolBar.vue:fixed定位的底部,通过是否定义内部控件的属性slot="extra"决定是左浮动或是右浮动 | |||
| HeaderNotice.vue:首页通知(如下图) | |||
|  | |||
| HeaderInfo.vue:上下文字布局(如下图) | |||
|  | |||
| Logo.vue:首页左上侧的log图 | |||
|  | |||
| UserMenu.vue:首页右上侧的内容 | |||
|  | |||
| ####16.trend包 趋势显示组件(如下图) | |||
|  | |||
|  | |||
|  | |||
| @ -0,0 +1,41 @@ | |||
| <template> | |||
| <div :class="[prefixCls, reverseColor && 'reverse-color' ]"> | |||
| <span> | |||
| <slot name="term"></slot> | |||
| <span class="item-text"> | |||
| <slot></slot> | |||
| </span> | |||
| </span> | |||
| <span :class="[flag]"><a-icon :type="`caret-${flag}`"/></span> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| name: "Trend", | |||
| props: { | |||
| prefixCls: { | |||
| type: String, | |||
| default: 'ant-pro-trend' | |||
| }, | |||
| /** | |||
| * 上升下降标识:up|down | |||
| */ | |||
| flag: { | |||
| type: String, | |||
| required: true | |||
| }, | |||
| /** | |||
| * 颜色反转 | |||
| */ | |||
| reverseColor: { | |||
| type: Boolean, | |||
| default: false | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="less" scoped> | |||
| @import "index"; | |||
| </style> | |||
| @ -0,0 +1,3 @@ | |||
| import Trend from './Trend.vue' | |||
| export default Trend | |||
| @ -0,0 +1,42 @@ | |||
| @import "../index"; | |||
| @trend-prefix-cls: ~"@{ant-pro-prefix}-trend"; | |||
| .@{trend-prefix-cls} { | |||
| display: inline-block; | |||
| font-size: @font-size-base; | |||
| line-height: 22px; | |||
| .up, | |||
| .down { | |||
| margin-left: 4px; | |||
| position: relative; | |||
| top: 1px; | |||
| i { | |||
| font-size: 12px; | |||
| transform: scale(0.83); | |||
| } | |||
| } | |||
| .item-text { | |||
| display: inline-block; | |||
| margin-left: 8px; | |||
| color: rgba(0,0,0,.85); | |||
| } | |||
| .up { | |||
| color: @red-6; | |||
| } | |||
| .down { | |||
| color: @green-6; | |||
| top: -1px; | |||
| } | |||
| &.reverse-color .up { | |||
| color: @green-6; | |||
| } | |||
| &.reverse-color .down { | |||
| color: @red-6; | |||
| } | |||
| } | |||
| @ -0,0 +1,85 @@ | |||
| import Vue from 'vue' | |||
| /** | |||
| * 省市区 | |||
| */ | |||
| export default class Area { | |||
| /** | |||
| * 构造器 | |||
| * @param express | |||
| */ | |||
| constructor(pcaa) { | |||
| if(!pcaa){ | |||
| pcaa = Vue.prototype.$Jpcaa; | |||
| } | |||
| let arr = [] | |||
| const province = pcaa['86'] | |||
| Object.keys(province).map(key=>{ | |||
| arr.push({id:key, text:province[key], pid:'86', index:1}); | |||
| const city = pcaa[key]; | |||
| Object.keys(city).map(key2=>{ | |||
| arr.push({id:key2, text:city[key2], pid:key, index:2}); | |||
| const qu = pcaa[key2]; | |||
| if(qu){ | |||
| Object.keys(qu).map(key3=>{ | |||
| arr.push({id:key3, text:qu[key3], pid:key2, index:3}); | |||
| }) | |||
| } | |||
| }) | |||
| }) | |||
| this.all = arr; | |||
| } | |||
| get pca(){ | |||
| return this.all; | |||
| } | |||
| getCode(text){ | |||
| if(!text || text.length==0){ | |||
| return '' | |||
| } | |||
| for(let item of this.all){ | |||
| if(item.text === text){ | |||
| return item.id; | |||
| } | |||
| } | |||
| } | |||
| getText(code){ | |||
| if(!code || code.length==0){ | |||
| return '' | |||
| } | |||
| let arr = [] | |||
| this.getAreaBycode(code, arr, 3); | |||
| return arr.join('/') | |||
| } | |||
| getRealCode(code){ | |||
| let arr = [] | |||
| this.getPcode(code, arr, 3) | |||
| return arr; | |||
| } | |||
| getPcode(id, arr, index){ | |||
| for(let item of this.all){ | |||
| if(item.id === id && item.index == index){ | |||
| arr.unshift(id) | |||
| if(item.pid != '86'){ | |||
| this.getPcode(item.pid, arr, --index) | |||
| } | |||
| } | |||
| } | |||
| } | |||
| getAreaBycode(code, arr, index){ | |||
| for(let item of this.all){ | |||
| if(item.id === code && item.index == index){ | |||
| arr.unshift(item.text); | |||
| if(item.pid != '86'){ | |||
| this.getAreaBycode(item.pid, arr, --index) | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @ -0,0 +1,46 @@ | |||
| /** | |||
| * 获取字符串的长度ascii长度为1 中文长度为2 | |||
| * @param str | |||
| * @returns {number} | |||
| */ | |||
| export const getStrFullLength = (str = '') => | |||
| str.split('').reduce((pre, cur) => { | |||
| const charCode = cur.charCodeAt(0) | |||
| if (charCode >= 0 && charCode <= 128) { | |||
| return pre + 1 | |||
| } | |||
| return pre + 2 | |||
| }, 0) | |||
| /** | |||
| * 给定一个字符串和一个长度,将此字符串按指定长度截取 | |||
| * @param str | |||
| * @param maxLength | |||
| * @returns {string} | |||
| */ | |||
| export const cutStrByFullLength = (str = '', maxLength) => { | |||
| let showLength = 0 | |||
| return str.split('').reduce((pre, cur) => { | |||
| const charCode = cur.charCodeAt(0) | |||
| if (charCode >= 0 && charCode <= 128) { | |||
| showLength += 1 | |||
| } else { | |||
| showLength += 2 | |||
| } | |||
| if (showLength <= maxLength) { | |||
| return pre + cur | |||
| } | |||
| return pre | |||
| }, '') | |||
| } | |||
| // 下划线转换驼峰 | |||
| export function underLinetoHump(name) { | |||
| return name.replace(/\_(\w)/g, function(all, letter){ | |||
| return letter.toUpperCase(); | |||
| }); | |||
| } | |||
| // 驼峰转换下划线 | |||
| export function humptoUnderLine(name) { | |||
| return name.replace(/([A-Z])/g,"_$1").toLowerCase(); | |||
| } | |||
| @ -0,0 +1,12 @@ | |||
| /** | |||
| * components util | |||
| */ | |||
| /** | |||
| * 清理空值,对象 | |||
| * @param children | |||
| * @returns {*[]} | |||
| */ | |||
| export function filterEmpty (children = []) { | |||
| return children.filter(c => c.tag || (c.text && c.text.trim() !== '')) | |||
| } | |||
| @ -0,0 +1,88 @@ | |||
| <template> | |||
| <div :style="{ padding: '0' }"> | |||
| <h4 :style="{ marginBottom: '20px' }">{{ title }}</h4> | |||
| <v-chart ref="chart" :forceFit="true" :height="height" :data="dataSource" :scale="scale"> | |||
| <v-tooltip :shared="false"/> | |||
| <v-axis/> | |||
| <v-line position="x*y" :size="lineSize" :color="lineColor"/> | |||
| <v-area position="x*y" :color="color"/> | |||
| </v-chart> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { triggerWindowResizeEvent } from '@/utils/util' | |||
| export default { | |||
| name: 'AreaChartTy', | |||
| props: { | |||
| // 图表数据 | |||
| dataSource: { | |||
| type: Array, | |||
| required: true | |||
| }, | |||
| // 图表标题 | |||
| title: { | |||
| type: String, | |||
| default: '' | |||
| }, | |||
| // x 轴别名 | |||
| x: { | |||
| type: String, | |||
| default: 'x' | |||
| }, | |||
| // y 轴别名 | |||
| y: { | |||
| type: String, | |||
| default: 'y' | |||
| }, | |||
| // Y轴最小值 | |||
| min: { | |||
| type: Number, | |||
| default: 0 | |||
| }, | |||
| // Y轴最大值 | |||
| max: { | |||
| type: Number, | |||
| default: null | |||
| }, | |||
| // 图表高度 | |||
| height: { | |||
| type: Number, | |||
| default: 254 | |||
| }, | |||
| // 线的粗细 | |||
| lineSize: { | |||
| type: Number, | |||
| default: 2 | |||
| }, | |||
| // 面积的颜色 | |||
| color: { | |||
| type: String, | |||
| default: '' | |||
| }, | |||
| // 线的颜色 | |||
| lineColor: { | |||
| type: String, | |||
| default: '' | |||
| } | |||
| }, | |||
| computed: { | |||
| scale() { | |||
| return [ | |||
| { dataKey: 'x', title: this.x, alias: this.x }, | |||
| { dataKey: 'y', title: this.y, alias: this.y, min: this.min, max: this.max } | |||
| ] | |||
| } | |||
| }, | |||
| mounted() { | |||
| triggerWindowResizeEvent() | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="less" scoped> | |||
| @import "chart"; | |||
| </style> | |||
| @ -0,0 +1,51 @@ | |||
| <template> | |||
| <div :style="{ padding: '0 0 32px 32px' }"> | |||
| <h4 :style="{ marginBottom: '20px' }">{{ title }}</h4> | |||
| <v-chart :forceFit="true" :height="height" :data="dataSource" :scale="scale" :padding="padding"> | |||
| <v-tooltip/> | |||
| <v-axis/> | |||
| <v-bar position="x*y"/> | |||
| </v-chart> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { triggerWindowResizeEvent } from '@/utils/util' | |||
| export default { | |||
| name: 'Bar', | |||
| props: { | |||
| dataSource: { | |||
| type: Array, | |||
| required: true | |||
| }, | |||
| yaxisText: { | |||
| type: String, | |||
| default: 'y' | |||
| }, | |||
| title: { | |||
| type: String, | |||
| default: '' | |||
| }, | |||
| height: { | |||
| type: Number, | |||
| default: 400 | |||
| }, | |||
| }, | |||
| data() { | |||
| return { padding: ['auto', 'auto', '40', '50'] } | |||
| }, | |||
| computed: { | |||
| scale() { | |||
| return [{ | |||
| dataKey: 'y', | |||
| alias: this.yaxisText | |||
| }] | |||
| } | |||
| }, | |||
| mounted() { | |||
| triggerWindowResizeEvent() | |||
| } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,60 @@ | |||
| <template> | |||
| <div :style="{ padding: '0 50px 32px 0' }"> | |||
| <h4 :style="{ marginBottom: '20px' }">{{ title }}</h4> | |||
| <v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :padding=" padding" :onClick="handleClick"> | |||
| <v-tooltip/> | |||
| <v-legend/> | |||
| <v-axis/> | |||
| <v-bar position="type*bar"/> | |||
| <v-line position="type*line" color="#2fc25b" :size="3"/> | |||
| </v-chart> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { ChartEventMixins } from './mixins/ChartMixins' | |||
| export default { | |||
| name: 'BarAndLine', | |||
| mixins: [ChartEventMixins], | |||
| props: { | |||
| title: { | |||
| type: String, | |||
| default: '' | |||
| }, | |||
| dataSource: { | |||
| type: Array, | |||
| default: () => [ | |||
| { type: '10:10', bar: 200, line: 1000 }, | |||
| { type: '10:15', bar: 600, line: 1000}, | |||
| { type: '10:20', bar: 200, line: 1000}, | |||
| { type: '10:25', bar: 900, line: 1000}, | |||
| { type: '10:30', bar: 200, line: 1000}, | |||
| { type: '10:35', bar: 200, line: 1000}, | |||
| { type: '10:40', bar: 100, line: 1000} | |||
| ] | |||
| }, | |||
| height: { | |||
| type: Number, | |||
| default: 400 | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| padding: { top:50, right:50, bottom:100, left:50 }, | |||
| scale: [{ | |||
| dataKey: 'bar', | |||
| min: 0 | |||
| }, { | |||
| dataKey: 'line', | |||
| min: 0 | |||
| }] | |||
| } | |||
| }, | |||
| computed: { | |||
| data() { | |||
| return this.dataSource | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,96 @@ | |||
| <template> | |||
| <div :style="{ padding: '0 0 32px 32px' }"> | |||
| <h4 :style="{ marginBottom: '20px' }">{{ title }}</h4> | |||
| <v-chart :data="data" :height="height" :force-fit="true" :scale="scale" :onClick="handleClick"> | |||
| <v-tooltip/> | |||
| <v-axis/> | |||
| <v-legend/> | |||
| <v-bar position="x*y" color="type" :adjust="adjust"/> | |||
| </v-chart> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { DataSet } from '@antv/data-set' | |||
| import { ChartEventMixins } from './mixins/ChartMixins' | |||
| export default { | |||
| name: 'BarMultid', | |||
| mixins: [ChartEventMixins], | |||
| props: { | |||
| title: { | |||
| type: String, | |||
| default: '' | |||
| }, | |||
| dataSource: { | |||
| type: Array, | |||
| default: () => [ | |||
| { type: 'Jeecg', 'Jan.': 18.9, 'Feb.': 28.8, 'Mar.': 39.3, 'Apr.': 81.4, 'May': 47, 'Jun.': 20.3, 'Jul.': 24, 'Aug.': 35.6 }, | |||
| { type: 'Jeebt', 'Jan.': 12.4, 'Feb.': 23.2, 'Mar.': 34.5, 'Apr.': 99.7, 'May': 52.6, 'Jun.': 35.5, 'Jul.': 37.4, 'Aug.': 42.4 } | |||
| ] | |||
| }, | |||
| fields: { | |||
| type: Array, | |||
| default: () => ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.'] | |||
| }, | |||
| // 别名,需要的格式:[{field:'name',alias:'姓名'}, {field:'sex',alias:'性别'}] | |||
| aliases: { | |||
| type: Array, | |||
| default: () => [] | |||
| }, | |||
| height: { | |||
| type: Number, | |||
| default: 254 | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| adjust: [{ | |||
| type: 'dodge', | |||
| marginRatio: 1 / 32 | |||
| }] | |||
| } | |||
| }, | |||
| computed: { | |||
| data() { | |||
| const dv = new DataSet.View().source(this.dataSource) | |||
| dv.transform({ | |||
| type: 'fold', | |||
| fields: this.fields, | |||
| key: 'x', | |||
| value: 'y' | |||
| }) | |||
| // bar 使用不了 - 和 / 所以替换下 | |||
| let rows = dv.rows.map(row => { | |||
| if (typeof row.x === 'string') { | |||
| row.x = row.x.replace(/[-/]/g, '_') | |||
| } | |||
| return row | |||
| }) | |||
| // 替换别名 | |||
| rows.forEach(row => { | |||
| for (let item of this.aliases) { | |||
| if (item.field === row.type) { | |||
| row.type = item.alias | |||
| break | |||
| } | |||
| } | |||
| }) | |||
| return rows | |||
| }, | |||
| scale() { | |||
| return [ | |||
| { | |||
| type: 'cat', | |||
| dataKey: 'x' | |||
| } | |||
| ] | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| </style> | |||
| @ -0,0 +1,187 @@ | |||
| <template> | |||
| <div :style="{ padding: '0 0 32px 32px' }"> | |||
| <v-chart :forceFit="true" :height="300" :data="chartData" :scale="scale"> | |||
| <v-coord type="polar" :startAngle="-202.5" :endAngle="22.5" :radius="0.75"></v-coord> | |||
| <v-axis | |||
| dataKey="value" | |||
| :zIndex="2" | |||
| :line="null" | |||
| :label="axisLabel" | |||
| :subTickCount="4" | |||
| :subTickLine="axisSubTickLine" | |||
| :tickLine="axisTickLine" | |||
| :grid="null" | |||
| ></v-axis> | |||
| <v-axis dataKey="1" :show="false"></v-axis> | |||
| <v-series | |||
| gemo="point" | |||
| position="value*1" | |||
| shape="pointer" | |||
| color="#1890FF" | |||
| :active="false" | |||
| ></v-series> | |||
| <v-guide | |||
| type="arc" | |||
| :zIndex="0" | |||
| :top="false" | |||
| :start="arcGuide1Start" | |||
| :end="arcGuide1End" | |||
| :vStyle="arcGuide1Style" | |||
| ></v-guide> | |||
| <v-guide | |||
| type="arc" | |||
| :zIndex="1" | |||
| :start="arcGuide2Start" | |||
| :end="getArcGuide2End" | |||
| :vStyle="arcGuide2Style" | |||
| ></v-guide> | |||
| <v-guide | |||
| type="html" | |||
| :position="htmlGuidePosition" | |||
| :html="getHtmlGuideHtml()" | |||
| ></v-guide> | |||
| </v-chart> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { registerShape } from 'viser-vue'; | |||
| registerShape('point', 'pointer', { | |||
| draw(cfg, container) { | |||
| let point = cfg.points[0]; | |||
| point = this.parsePoint(point); | |||
| const center = this.parsePoint({ | |||
| x: 0, | |||
| y: 0, | |||
| }); | |||
| container.addShape('line', { | |||
| attrs: { | |||
| x1: center.x, | |||
| y1: center.y, | |||
| x2: point.x, | |||
| y2: point.y + 15, | |||
| stroke: cfg.color, | |||
| lineWidth: 5, | |||
| lineCap: 'round', | |||
| } | |||
| }); | |||
| return container.addShape('circle', { | |||
| attrs: { | |||
| x: center.x, | |||
| y: center.y, | |||
| r: 9.75, | |||
| stroke: cfg.color, | |||
| lineWidth: 4.5, | |||
| fill: '#fff', | |||
| } | |||
| }); | |||
| } | |||
| }); | |||
| const scale = [{ | |||
| dataKey: 'value', | |||
| min: 0, | |||
| max: 9, | |||
| tickInterval: 1, | |||
| nice: false, | |||
| }]; | |||
| const data = [ | |||
| { value: 7.0 }, | |||
| ]; | |||
| export default { | |||
| name:"DashChartDemo", | |||
| props:{ | |||
| datasource:{ | |||
| type: Number, | |||
| default:7 | |||
| }, | |||
| title: { | |||
| type: String, | |||
| default: '' | |||
| } | |||
| }, | |||
| created(){ | |||
| if(!this.datasource){ | |||
| this.chartData = data; | |||
| }else{ | |||
| this.chartData = [ | |||
| { value: this.datasource }, | |||
| ]; | |||
| } | |||
| this.getChartData() | |||
| }, | |||
| watch: { | |||
| 'datasource': function (val) { | |||
| this.chartData = [ | |||
| { value: val}, | |||
| ]; | |||
| this.getChartData(); | |||
| } | |||
| }, | |||
| methods:{ | |||
| getChartData(){ | |||
| if(this.chartData && this.chartData.length>0){ | |||
| this.abcd = this.chartData[0].value * 10 | |||
| }else{ | |||
| this.abcd = 70 | |||
| } | |||
| }, | |||
| getHtmlGuideHtml(){ | |||
| return '<div style="width: 300px;text-align: center;">\n' + | |||
| '<p style="font-size: 14px;color: #545454;margin: 0;">'+this.title+'</p>\n' + | |||
| '<p style="font-size: 36px;color: #545454;margin: 0;">'+this.abcd+'%</p>\n' + | |||
| '</div>' | |||
| }, | |||
| getArcGuide2End(){ | |||
| return [this.chartData[0].value, 0.945] | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| chartData:[], | |||
| height: 400, | |||
| scale: scale, | |||
| abcd:70, | |||
| axisLabel: { | |||
| offset: -16, | |||
| textStyle: { | |||
| fontSize: 18, | |||
| textAlign: 'center', | |||
| textBaseline: 'middle' | |||
| } | |||
| }, | |||
| axisSubTickLine: { | |||
| length: -8, | |||
| stroke: '#fff', | |||
| strokeOpacity: 1, | |||
| }, | |||
| axisTickLine: { | |||
| length: -17, | |||
| stroke: '#fff', | |||
| strokeOpacity: 1, | |||
| }, | |||
| arcGuide1Start: [0, 0.945], | |||
| arcGuide1End: [9, 0.945], | |||
| arcGuide1Style: { | |||
| stroke: '#CBCBCB', | |||
| lineWidth: 18, | |||
| }, | |||
| arcGuide2Start: [0, 0.945], | |||
| arcGuide2Style: { | |||
| stroke: '#1890FF', | |||
| lineWidth: 18, | |||
| }, | |||
| htmlGuidePosition: ['50%', '100%'], | |||
| htmlGuideHtml: ` | |||
| <div style="width: 300px;text-align: center;"> | |||
| <p style="font-size: 14px;color: #545454;margin: 0;">${this.title}</p> | |||
| <p style="font-size: 36px;color: #545454;margin: 0;">${this.abcd}%</p> | |||
| </div> | |||
| `, | |||
| }; | |||
| }, | |||
| }; | |||
| </script> | |||
| @ -0,0 +1,61 @@ | |||
| <template> | |||
| <div :style="{ padding: '0 0 32px 32px' }"> | |||
| <h4 :style="{ marginBottom: '20px' }">{{ title }}</h4> | |||
| <v-chart | |||
| height="254" | |||
| :data="datasource" | |||
| :forceFit="true" | |||
| :padding="['auto', 'auto', '40', '50']"> | |||
| <v-tooltip /> | |||
| <v-axis /> | |||
| <v-bar position="x*y"/> | |||
| </v-chart> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| const data = [] | |||
| for (let i = 0; i < 12; i += 1) { | |||
| data.push({ | |||
| x: `${i + 1}月`, | |||
| y: Math.floor(Math.random() * 1000) + 200 | |||
| }) | |||
| } | |||
| const tooltip = [ | |||
| 'x*y', | |||
| (x, y) => ({ | |||
| name: x, | |||
| value: y | |||
| }) | |||
| ] | |||
| const scale = [{ | |||
| dataKey: 'x', | |||
| min: 2 | |||
| }, { | |||
| dataKey: 'y', | |||
| title: '时间', | |||
| min: 1, | |||
| max: 22 | |||
| }] | |||
| export default { | |||
| name: "Bar", | |||
| props: { | |||
| title: { | |||
| type: String, | |||
| default: '' | |||
| } | |||
| }, | |||
| mounted(){ | |||
| this.datasource = data | |||
| }, | |||
| data () { | |||
| return { | |||
| datasource:[], | |||
| scale, | |||
| tooltip | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,95 @@ | |||
| <template> | |||
| <div :style="{ padding: '0 0 32px 32px' }"> | |||
| <h4 :style="{ marginBottom: '20px' }">{{ title }}</h4> | |||
| <v-chart :force-fit="true" :height="height" :data="data" :scale="scale" :onClick="handleClick"> | |||
| <v-tooltip/> | |||
| <v-axis/> | |||
| <v-legend/> | |||
| <v-line position="type*y" color="x"/> | |||
| <v-point position="type*y" color="x" :size="4" :v-style="style" :shape="'circle'"/> | |||
| </v-chart> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { DataSet } from '@antv/data-set' | |||
| import { ChartEventMixins } from './mixins/ChartMixins' | |||
| export default { | |||
| name: 'LineChartMultid', | |||
| mixins: [ChartEventMixins], | |||
| props: { | |||
| title: { | |||
| type: String, | |||
| default: '' | |||
| }, | |||
| dataSource: { | |||
| type: Array, | |||
| default: () => [ | |||
| { type: 'Jan', jeecg: 7.0, jeebt: 3.9 }, | |||
| { type: 'Feb', jeecg: 6.9, jeebt: 4.2 }, | |||
| { type: 'Mar', jeecg: 9.5, jeebt: 5.7 }, | |||
| { type: 'Apr', jeecg: 14.5, jeebt: 8.5 }, | |||
| { type: 'May', jeecg: 18.4, jeebt: 11.9 }, | |||
| { type: 'Jun', jeecg: 21.5, jeebt: 15.2 }, | |||
| { type: 'Jul', jeecg: 25.2, jeebt: 17.0 }, | |||
| { type: 'Aug', jeecg: 26.5, jeebt: 16.6 }, | |||
| { type: 'Sep', jeecg: 23.3, jeebt: 14.2 }, | |||
| { type: 'Oct', jeecg: 18.3, jeebt: 10.3 }, | |||
| { type: 'Nov', jeecg: 13.9, jeebt: 6.6 }, | |||
| { type: 'Dec', jeecg: 9.6, jeebt: 4.8 } | |||
| ] | |||
| }, | |||
| fields: { | |||
| type: Array, | |||
| default: () => ['jeecg', 'jeebt'] | |||
| }, | |||
| // 别名,需要的格式:[{field:'name',alias:'姓名'}, {field:'sex',alias:'性别'}] | |||
| aliases:{ | |||
| type: Array, | |||
| default: () => [] | |||
| }, | |||
| height: { | |||
| type: Number, | |||
| default: 254 | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| scale: [{ | |||
| type: 'cat', | |||
| dataKey: 'x', | |||
| min: 0, | |||
| max: 1 | |||
| }], | |||
| style: { stroke: '#fff', lineWidth: 1 } | |||
| } | |||
| }, | |||
| computed: { | |||
| data() { | |||
| const dv = new DataSet.View().source(this.dataSource) | |||
| dv.transform({ | |||
| type: 'fold', | |||
| fields: this.fields, | |||
| key: 'x', | |||
| value: 'y' | |||
| }) | |||
| let rows = dv.rows | |||
| // 替换别名 | |||
| rows.forEach(row => { | |||
| for (let item of this.aliases) { | |||
| if (item.field === row.x) { | |||
| row.x = item.alias | |||
| break | |||
| } | |||
| } | |||
| }) | |||
| return rows | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| </style> | |||
| @ -0,0 +1,80 @@ | |||
| <template> | |||
| <div> | |||
| <v-chart | |||
| :forceFit="true" | |||
| :height="height" | |||
| :width="width" | |||
| :data="data" | |||
| :scale="scale" | |||
| :padding="0"> | |||
| <v-tooltip/> | |||
| <v-interval | |||
| :shape="['liquid-fill-gauge']" | |||
| position="transfer*value" | |||
| color="" | |||
| :v-style="{ | |||
| lineWidth: 8, | |||
| opacity: 0.75 | |||
| }" | |||
| :tooltip="[ | |||
| 'transfer*value', | |||
| (transfer, value) => { | |||
| return { | |||
| name: transfer, | |||
| value, | |||
| }; | |||
| }, | |||
| ]" | |||
| ></v-interval> | |||
| <v-guide | |||
| v-for="(row, index) in data" | |||
| :key="index" | |||
| type="text" | |||
| :top="true" | |||
| :position="{ | |||
| gender: row.transfer, | |||
| value: 45 | |||
| }" | |||
| :content="row.value + '%'" | |||
| :v-style="{ | |||
| fontSize: 100, | |||
| textAlign: 'center', | |||
| opacity: 0.75, | |||
| }" | |||
| /> | |||
| </v-chart> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| const sourceDataConst = [ | |||
| { transfer: '一月', value: 813 }, | |||
| { transfer: '二月', value: 233 }, | |||
| { transfer: '三月', value: 561 } | |||
| ] | |||
| export default { | |||
| name: 'Liquid', | |||
| props: { | |||
| height: { | |||
| type: Number, | |||
| default: 0 | |||
| }, | |||
| width: { | |||
| type: Number, | |||
| default: 0 | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| data: sourceDataConst, | |||
| scale: [] | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| </style> | |||
| @ -0,0 +1,69 @@ | |||
| <template> | |||
| <div class="antv-chart-mini"> | |||
| <div class="chart-wrapper" :style="{ height: 46 }"> | |||
| <v-chart :force-fit="true" :height="height" :data="data" :scale="scale" :padding="[36, 0, 18, 0]"> | |||
| <v-tooltip/> | |||
| <v-smooth-area position="x*y"/> | |||
| </v-chart> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import moment from 'dayjs' | |||
| const sourceData = [] | |||
| const beginDay = new Date().getTime() | |||
| for (let i = 0; i < 10; i++) { | |||
| sourceData.push({ | |||
| x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'), | |||
| y: Math.round(Math.random() * 10) | |||
| }) | |||
| } | |||
| export default { | |||
| name: 'MiniArea', | |||
| props: { | |||
| dataSource: { | |||
| type: Array, | |||
| default: () => [] | |||
| }, | |||
| // x 轴别名 | |||
| x: { | |||
| type: String, | |||
| default: 'x' | |||
| }, | |||
| // y 轴别名 | |||
| y: { | |||
| type: String, | |||
| default: 'y' | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| data: [], | |||
| height: 100 | |||
| } | |||
| }, | |||
| computed: { | |||
| scale() { | |||
| return [ | |||
| { dataKey: 'x', title: this.x, alias: this.x }, | |||
| { dataKey: 'y', title: this.y, alias: this.y } | |||
| ] | |||
| } | |||
| }, | |||
| created() { | |||
| if (this.dataSource.length === 0) { | |||
| this.data = sourceData | |||
| } else { | |||
| this.data = this.dataSource | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="less" scoped> | |||
| @import "chart"; | |||
| </style> | |||
| @ -0,0 +1,76 @@ | |||
| <template> | |||
| <div :style="{'width':width==null?'auto':width+'px'}"> | |||
| <v-chart :forceFit="width==null" :height="height" :data="data" padding="0"> | |||
| <v-tooltip/> | |||
| <v-bar position="x*y"/> | |||
| </v-chart> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import moment from 'dayjs' | |||
| const sourceData = [] | |||
| const beginDay = new Date().getTime() | |||
| for (let i = 0; i < 10; i++) { | |||
| sourceData.push({ | |||
| x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'), | |||
| y: Math.round(Math.random() * 10) | |||
| }) | |||
| } | |||
| const tooltip = [ | |||
| 'x*y', | |||
| (x, y) => ({ | |||
| name: x, | |||
| value: y | |||
| }) | |||
| ] | |||
| const scale = [{ | |||
| dataKey: 'x', | |||
| min: 2 | |||
| }, { | |||
| dataKey: 'y', | |||
| title: '时间', | |||
| min: 1, | |||
| max: 30 | |||
| }] | |||
| export default { | |||
| name: 'MiniBar', | |||
| props: { | |||
| dataSource: { | |||
| type: Array, | |||
| default: () => [] | |||
| }, | |||
| width: { | |||
| type: Number, | |||
| default: null | |||
| }, | |||
| height: { | |||
| type: Number, | |||
| default: 200 | |||
| } | |||
| }, | |||
| created() { | |||
| if (this.dataSource.length === 0) { | |||
| this.data = sourceData | |||
| } else { | |||
| this.data = this.dataSource | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| tooltip, | |||
| data: [], | |||
| scale | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="less" scoped> | |||
| @import "chart"; | |||
| </style> | |||
| @ -0,0 +1,75 @@ | |||
| <template> | |||
| <div class="chart-mini-progress"> | |||
| <div class="target" :style="{ left: target + '%'}"> | |||
| <span :style="{ backgroundColor: color }"/> | |||
| <span :style="{ backgroundColor: color }"/> | |||
| </div> | |||
| <div class="progress-wrapper"> | |||
| <div class="progress" :style="{ backgroundColor: color, width: percentage + '%', height: height+'px' }"></div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| name: 'MiniProgress', | |||
| props: { | |||
| target: { | |||
| type: Number, | |||
| default: 0 | |||
| }, | |||
| height: { | |||
| type: Number, | |||
| default: 10 | |||
| }, | |||
| color: { | |||
| type: String, | |||
| default: '#13C2C2' | |||
| }, | |||
| percentage: { | |||
| type: Number, | |||
| default: 0 | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="less" scoped> | |||
| .chart-mini-progress { | |||
| padding: 5px 0; | |||
| position: relative; | |||
| width: 100%; | |||
| .target { | |||
| position: absolute; | |||
| top: 0; | |||
| bottom: 0; | |||
| span { | |||
| border-radius: 100px; | |||
| position: absolute; | |||
| top: 0; | |||
| left: 0; | |||
| height: 4px; | |||
| width: 2px; | |||
| &:last-child { | |||
| top: auto; | |||
| bottom: 0; | |||
| } | |||
| } | |||
| } | |||
| .progress-wrapper { | |||
| background-color: #f5f5f5; | |||
| position: relative; | |||
| .progress { | |||
| transition: all .4s cubic-bezier(.08, .82, .17, 1) 0s; | |||
| border-radius: 1px 0 0 1px; | |||
| background-color: #1890ff; | |||
| width: 0; | |||
| height: 100%; | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,70 @@ | |||
| <template> | |||
| <v-chart :forceFit="true" :height="height" :data="data" :scale="scale" :onClick="handleClick"> | |||
| <v-tooltip :showTitle="false" dataKey="item*percent"/> | |||
| <v-axis/> | |||
| <v-legend dataKey="item"/> | |||
| <v-pie position="percent" color="item" :v-style="pieStyle" :label="labelConfig"/> | |||
| <v-coord type="theta"/> | |||
| </v-chart> | |||
| </template> | |||
| <script> | |||
| const DataSet = require('@antv/data-set') | |||
| import { ChartEventMixins } from './mixins/ChartMixins' | |||
| export default { | |||
| name: 'Pie', | |||
| mixins: [ChartEventMixins], | |||
| props: { | |||
| title: { | |||
| type: String, | |||
| default: '' | |||
| }, | |||
| height: { | |||
| type: Number, | |||
| default: 254 | |||
| }, | |||
| dataSource: { | |||
| type: Array, | |||
| default: () => [ | |||
| { item: '示例一', count: 40 }, | |||
| { item: '示例二', count: 21 }, | |||
| { item: '示例三', count: 17 }, | |||
| { item: '示例四', count: 13 }, | |||
| { item: '示例五', count: 9 } | |||
| ] | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| scale: [{ | |||
| dataKey: 'percent', | |||
| min: 0, | |||
| formatter: '.0%' | |||
| }], | |||
| pieStyle: { | |||
| stroke: '#fff', | |||
| lineWidth: 1 | |||
| }, | |||
| labelConfig: ['percent', { | |||
| formatter: (val, item) => { | |||
| return item.point.item + ': ' + val | |||
| } | |||
| }] | |||
| } | |||
| }, | |||
| computed: { | |||
| data() { | |||
| let dv = new DataSet.View().source(this.dataSource) | |||
| // 计算数据百分比 | |||
| dv.transform({ | |||
| type: 'percent', | |||
| field: 'count', | |||
| dimension: 'item', | |||
| as: 'percent' | |||
| }) | |||
| return dv.rows | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,367 @@ | |||
| # 报表组件文档 | |||
| ## 柱状图 | |||
| ##### 引用方式 | |||
| ```js | |||
| import Bar from '@/components/chart/Bar' | |||
| ``` | |||
| ##### 参数列表 | |||
| | 参数名 | 类型 | 必填 | 说明 | | |||
| |------------|--------|----|------------| | |||
| | title | string | | 报表标题 | | |||
| | dataSource | array | ✔️ | 报表数据源 | | |||
| | height | number | | 报表高度,默认254 | | |||
| ##### dataSource 示例 | |||
| ```json | |||
| [ | |||
| { | |||
| "x": "1月", | |||
| "y": 320 | |||
| }, | |||
| { | |||
| "x": "2月", | |||
| "y": 457 | |||
| }, | |||
| { | |||
| "x": "3月", | |||
| "y": 182 | |||
| } | |||
| ] | |||
| ``` | |||
| ##### 代码示例 | |||
| ```html | |||
| <template> | |||
| <bar title="柱状图" :dataSource="dataSource" :height="420"/> | |||
| </template> | |||
| <script> | |||
| import Bar from '@/components/chart/Bar' | |||
| export default { | |||
| name: 'ChartDemo', | |||
| components: { | |||
| Bar | |||
| }, | |||
| data() { | |||
| return { | |||
| dataSource: [ | |||
| { | |||
| "x": "1月", | |||
| "y": 320 | |||
| }, | |||
| { | |||
| "x": "2月", | |||
| "y": 457 | |||
| }, | |||
| { | |||
| "x": "3月", | |||
| "y": 182 | |||
| } | |||
| ] | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style></style> | |||
| ``` | |||
| ## 多列柱状图 | |||
| ##### 引用方式 | |||
| ```js | |||
| import BarMultid from '@/components/chart/BarMultid' | |||
| ``` | |||
| ##### 参数列表 | |||
| | 参数名 | 类型 | 必填 | 说明 | | |||
| |------------|--------|----|------------| | |||
| | title | string | | 报表标题 | | |||
| | fields | array | | 主列字段列表 | | |||
| | dataSource | array | | 报表数据源 | | |||
| | height | number | | 报表高度,默认254 | | |||
| ##### fields 示例 | |||
| ```json | |||
| ["Jan.", "Feb.", "Mar.", "Apr.", "May", "Jun.", "Jul.", "Aug."] | |||
| ``` | |||
| ##### dataSource 示例 | |||
| ```json | |||
| [ | |||
| { | |||
| "type": "Jeecg", // 列名 | |||
| "Jan.": 18.9, | |||
| "Feb.": 28.8, | |||
| "Mar.": 39.3, | |||
| "Apr.": 81.4, | |||
| "May": 47, | |||
| "Jun.": 20.3, | |||
| "Jul.": 24, | |||
| "Aug.": 35.6 | |||
| }, | |||
| { | |||
| "type": "Jeebt", | |||
| "Jan.": 12.4, | |||
| "Feb.": 23.2, | |||
| "Mar.": 34.5, | |||
| "Apr.": 99.7, | |||
| "May": 52.6, | |||
| "Jun.": 35.5, | |||
| "Jul.": 37.4, | |||
| "Aug.": 42.4 | |||
| } | |||
| ] | |||
| ``` | |||
| ## 迷你柱状图 | |||
| 不带标题和数据轴的柱状图 | |||
| ##### 引用方式 | |||
| ```js | |||
| import MiniBar from '@/components/chart/MiniBar' | |||
| ``` | |||
| ##### 参数列表 | |||
| | 参数名 | 类型 | 必填 | 说明 | | |||
| |------------|--------|----|---------------| | |||
| | width | number | | 报表宽度度,默认自适应宽度 | | |||
| | height | number | | 报表高度,默认200 | | |||
| | dataSource | array | | 报表数据源 | | |||
| ##### dataSource 示例 | |||
| ```json | |||
| [ | |||
| { | |||
| "x": "1月", | |||
| "y": 320 | |||
| }, | |||
| { | |||
| "x": "2月", | |||
| "y": 457 | |||
| }, | |||
| { | |||
| "x": "3月", | |||
| "y": 182 | |||
| } | |||
| ] | |||
| ``` | |||
| ## 面积图 | |||
| ##### 引用方式 | |||
| ```js | |||
| import AreaChartTy from '@/components/chart/AreaChartTy' | |||
| ``` | |||
| ##### 参数列表 | |||
| | 参数名 | 类型 | 必填 | 说明 | | |||
| |------------|--------|----|------------| | |||
| | title | string | | 报表标题 | | |||
| | dataSource | array | ✔️ | 报表数据源 | | |||
| | height | number | | 报表高度,默认254 | | |||
| | lineSize | number | | 线的粗细,默认2 | | |||
| ##### dataSource 示例 | |||
| ```json | |||
| [ | |||
| { | |||
| "x": "1月", | |||
| "y": 320 | |||
| }, | |||
| { | |||
| "x": "2月", | |||
| "y": 457 | |||
| }, | |||
| { | |||
| "x": "3月", | |||
| "y": 182 | |||
| } | |||
| ] | |||
| ``` | |||
| ## 多行折线图 | |||
| ##### 引用方式 | |||
| ```js | |||
| import LineChartMultid from '@/components/chart/LineChartMultid' | |||
| ``` | |||
| ##### 参数列表 | |||
| | 参数名 | 类型 | 必填 | 说明 | | |||
| |------------|--------|----|------------| | |||
| | title | string | | 报表标题 | | |||
| | fields | array | | 主列字段列表 | | |||
| | dataSource | array | | 报表数据源 | | |||
| | height | number | | 报表高度,默认254 | | |||
| ##### fields 示例 | |||
| ```json | |||
| ["jeecg", "jeebt"] | |||
| ``` | |||
| ##### dataSource 示例 | |||
| ```json | |||
| [ | |||
| { | |||
| "type": "Jan", // 列名 | |||
| "jeecg": 7, | |||
| "jeebt": 3.9 | |||
| }, | |||
| { "type": "Feb", "jeecg": 6.9, "jeebt": 4.2 }, | |||
| { "type": "Mar", "jeecg": 9.5, "jeebt": 5.7 }, | |||
| { "type": "Apr", "jeecg": 14.5, "jeebt": 8.5 }, | |||
| { "type": "May", "jeecg": 18.4, "jeebt": 11.9 }, | |||
| { "type": "Jun", "jeecg": 21.5, "jeebt": 15.2 }, | |||
| { "type": "Jul", "jeecg": 25.2, "jeebt": 17 }, | |||
| { "type": "Aug", "jeecg": 26.5, "jeebt": 16.6 }, | |||
| { "type": "Sep", "jeecg": 23.3, "jeebt": 14.2 }, | |||
| { "type": "Oct", "jeecg": 18.3, "jeebt": 10.3 }, | |||
| { "type": "Nov", "jeecg": 13.9, "jeebt": 6.6 }, | |||
| { "type": "Dec", "jeecg": 9.6, "jeebt": 4.8 } | |||
| ] | |||
| ``` | |||
| ## 饼状图 | |||
| ##### 引用方式 | |||
| ```js | |||
| import Pie from '@/components/chart/Pie' | |||
| ``` | |||
| ##### 参数列表 | |||
| | 参数名 | 类型 | 必填 | 说明 | | |||
| |------------|--------|----|------------| | |||
| | dataSource | array | | 报表数据源 | | |||
| | height | number | | 报表高度,默认254 | | |||
| ##### dataSource 示例 | |||
| ```json | |||
| [ | |||
| // 所有的 percent 相加等于 100 | |||
| { "item": "一月", "percent": 40 }, | |||
| { "item": "二月", "percent": 21 }, | |||
| { "item": "三月", "percent": 17 }, | |||
| { "item": "四月", "percent": 13 }, | |||
| { "item": "五月", "percent": 9 } | |||
| ] | |||
| ``` | |||
| ## 雷达图 | |||
| ##### 引用方式 | |||
| ```js | |||
| import Radar from '@/components/chart/Radar' | |||
| ``` | |||
| ##### 参数列表 | |||
| | 参数名 | 类型 | 必填 | 说明 | | |||
| |------------|--------|----|------------| | |||
| | dataSource | array | | 报表数据源 | | |||
| | height | number | | 报表高度,默认254 | | |||
| ##### dataSource 示例 | |||
| ```json | |||
| [ | |||
| // score 最小值为 0,最大值为 100 | |||
| { "item": "一月", "score": 40 }, | |||
| { "item": "二月", "score": 20 }, | |||
| { "item": "三月", "score": 67 }, | |||
| { "item": "四月", "score": 43 }, | |||
| { "item": "五月", "score": 90 } | |||
| ] | |||
| ``` | |||
| ## 进度条 | |||
| ##### 引用方式 | |||
| ```js | |||
| import MiniProgress from '@/components/chart/MiniProgress' | |||
| ``` | |||
| ##### 参数列表 | |||
| | 参数名 | 类型 | 必填 | 说明 | | |||
| |------------|--------|----|-------------------| | |||
| | percentage | number | | 当前进度百分比,默认0,最高100 | | |||
| | target | number | | 目标值,默认10 | | |||
| | height | number | | 进度条高度,默认10 | | |||
| | color | string | | 进度条颜色,默认 #13C2C2 | | |||
| ## 仪表盘 | |||
| ##### 引用方式 | |||
| ```js | |||
| import DashChartDemo from '@/components/chart/DashChartDemo' | |||
| ``` | |||
| ##### 参数列表 | |||
| | 参数名 | 类型 | 必填 | 说明 | | |||
| |--------|--------|----|----------------| | |||
| | title | string | | 报表标题 | | |||
| | value | number | | 当前值,默认6.7,最大为9 | | |||
| | height | number | | 报表高度,默认254 | | |||
| ## 排名列表 | |||
| ##### 引用方式 | |||
| ```js | |||
| import RankList from '@/components/chart/RankList' | |||
| ``` | |||
| ##### 参数列表 | |||
| | 参数名 | 类型 | 必填 | 说明 | | |||
| |--------|--------|----|--------------| | |||
| | title | string | | 报表标题 | | |||
| | list | array | | 排名列表数据 | | |||
| | height | number | | 报表高度,默认自适应高度 | | |||
| ##### list 示例 | |||
| ```json | |||
| [ | |||
| { | |||
| "name": "北京朝阳 1 号店", | |||
| "total": 1981 | |||
| }, | |||
| { "name": "北京朝阳 2 号店", "total": 1359 }, | |||
| { "name": "北京朝阳 3 号店", "total": 1354 }, | |||
| { "name": "北京朝阳 4 号店", "total": 263 }, | |||
| { "name": "北京朝阳 5 号店", "total": 446 }, | |||
| { "name": "北京朝阳 6 号店", "total": 796 } | |||
| ] | |||
| ``` | |||