@ -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=4 |
||||||
|
|
||||||
|
[{*.ng,*.sht,*.html,*.shtm,*.shtml,*.htm}] |
||||||
|
indent_style=space |
||||||
|
indent_size=4 |
||||||
|
|
||||||
|
[{*.jhm,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.tld,*.fxml,*.jrxml,*.xml,*.jnlp,*.wsdl}] |
||||||
|
indent_style=space |
||||||
|
indent_size=4 |
||||||
|
|
||||||
|
[{.babelrc,.stylelintrc,jest.config,.eslintrc,.prettierrc,*.json,*.jsb3,*.jsb2,*.bowerrc}] |
||||||
|
indent_style=space |
||||||
|
indent_size=4 |
||||||
|
|
||||||
|
[*.svg] |
||||||
|
indent_style=space |
||||||
|
indent_size=4 |
||||||
|
|
||||||
|
[*.js.map] |
||||||
|
indent_style=space |
||||||
|
indent_size=4 |
||||||
|
|
||||||
|
[*.less] |
||||||
|
indent_style=space |
||||||
|
indent_size=4 |
||||||
|
|
||||||
|
[*.vue] |
||||||
|
indent_style=space |
||||||
|
indent_size=4 |
||||||
|
|
||||||
|
[{.analysis_options,*.yml,*.yaml}] |
||||||
|
indent_style=space |
||||||
|
indent_size=4 |
||||||
|
|
||||||
@ -0,0 +1,6 @@ |
|||||||
|
NODE_ENV=development |
||||||
|
VUE_APP_PLATFORM_NAME=JeecgBoot 企业级低代码平台 |
||||||
|
# 开启单点登录 |
||||||
|
VUE_APP_SSO=false |
||||||
|
# 开启微应用模式 |
||||||
|
VUE_APP_QIANKUN=false |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
NODE_ENV=development |
||||||
|
VUE_APP_API_BASE_URL=http://localhost:8080/ |
||||||
|
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:8080/jeecg-boot |
||||||
|
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,19 @@ |
|||||||
|
node_modules |
||||||
|
.DS_Store |
||||||
|
.github |
||||||
|
dist |
||||||
|
.npmrc |
||||||
|
.cache |
||||||
|
|
||||||
|
## ide |
||||||
|
**/.idea |
||||||
|
*.iml |
||||||
|
|
||||||
|
## backend |
||||||
|
**/target |
||||||
|
**/logs |
||||||
|
**/dist |
||||||
|
|
||||||
|
## front |
||||||
|
package-lock.json |
||||||
|
yarn.lock |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
{ |
||||||
|
"printWidth": 120, |
||||||
|
"semi": false, |
||||||
|
"singleQuote": true |
||||||
|
} |
||||||
@ -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,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,120 @@ |
|||||||
|
{ |
||||||
|
"name": "vue-antd-jeecg", |
||||||
|
"version": "3.4.3", |
||||||
|
"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": { |
||||||
|
"@jeecg/antd-online-mini": "3.4.3-beta2", |
||||||
|
"ant-design-vue": "^1.7.2", |
||||||
|
"@antv/data-set": "^0.11.4", |
||||||
|
"viser-vue": "^2.4.8", |
||||||
|
"axios": "^0.18.0", |
||||||
|
"dayjs": "^1.8.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", |
||||||
|
"vue": "^2.6.10", |
||||||
|
"vue-cropper": "^0.5.4", |
||||||
|
"vue-i18n": "^8.7.0", |
||||||
|
"vue-loader": "^15.7.0", |
||||||
|
"vue-ls": "^3.2.0", |
||||||
|
"vue-router": "^3.0.1", |
||||||
|
"vuex": "^3.1.0", |
||||||
|
"vue-print-nb-jeecg": "^1.0.10", |
||||||
|
"clipboard": "^2.0.4", |
||||||
|
"vue-photo-preview": "^1.1.3", |
||||||
|
"vue-splitpane": "^1.0.4", |
||||||
|
"vuedraggable": "^2.20.0", |
||||||
|
"codemirror": "^5.46.0", |
||||||
|
"@tinymce/tinymce-vue": "2.1.0", |
||||||
|
"tinymce": "5.4.1", |
||||||
|
"@toast-ui/editor": "^2.1.2", |
||||||
|
"vue-area-linkage": "^5.1.0", |
||||||
|
"china-area-data": "^5.0.1", |
||||||
|
"dom-align": "1.12.0", |
||||||
|
"xe-utils": "2.4.8", |
||||||
|
"vxe-table": "2.9.13", |
||||||
|
"vxe-table-plugin-antd": "1.8.10", |
||||||
|
"cron-parser": "^2.10.0", |
||||||
|
"qiankun": "^2.5.1", |
||||||
|
"xss": "^1.0.13" |
||||||
|
}, |
||||||
|
"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", |
||||||
|
"eslint": "^5.16.0", |
||||||
|
"eslint-plugin-vue": "^5.1.0", |
||||||
|
"less": "^3.9.0", |
||||||
|
"less-loader": "^4.1.0", |
||||||
|
"vue-template-compiler": "^2.6.10", |
||||||
|
"html-webpack-plugin": "^4.2.0", |
||||||
|
"compression-webpack-plugin": "^3.1.0" |
||||||
|
}, |
||||||
|
"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" |
||||||
|
] |
||||||
|
} |
||||||
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,259 @@ |
|||||||
|
<!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>DB Bastion Server</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> |
||||||
|
After Width: | Height: | Size: 78 KiB |
@ -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,161 @@ |
|||||||
|
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]; |
||||||
|
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 { |
||||||
|
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 |
||||||
|
}) |
||||||
|
} |
||||||
|
After Width: | Height: | Size: 371 KiB |
|
After Width: | Height: | Size: 1.6 MiB |
|
After Width: | Height: | Size: 257 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
@ -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; |
||||||
|
} |
||||||
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 10 KiB |
@ -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,67 @@ |
|||||||
|
<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) { |
||||||
|
// 【issues/3854】附表控件类型为popup必填时未选择值提交表单会报错 |
||||||
|
if (event.$event && event.$event.type === 'valid-error') { |
||||||
|
return; |
||||||
|
} |
||||||
|
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; |
||||||
|
} |
||||||
|
:deep { |
||||||
|
.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,50 @@ |
|||||||
|
<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: 254 |
||||||
|
} |
||||||
|
}, |
||||||
|
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,90 @@ |
|||||||
|
<template> |
||||||
|
<v-chart :forceFit="true" :height="height" :data="data" :padding="[20, 20, 95, 20]" :scale="scale"> |
||||||
|
<v-tooltip></v-tooltip> |
||||||
|
<v-axis :dataKey="axis1Opts.dataKey" :line="axis1Opts.line" :tickLine="axis1Opts.tickLine" :grid="axis1Opts.grid"/> |
||||||
|
<v-axis :dataKey="axis2Opts.dataKey" :line="axis2Opts.line" :tickLine="axis2Opts.tickLine" :grid="axis2Opts.grid"/> |
||||||
|
<v-legend dataKey="user" marker="circle" :offset="30"/> |
||||||
|
<v-coord type="polar" radius="0.8"/> |
||||||
|
<v-line position="item*score" color="user" :size="2"/> |
||||||
|
<v-point position="item*score" color="user" :size="4" shape="circle"/> |
||||||
|
</v-chart> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
const axis1Opts = { |
||||||
|
dataKey: 'item', |
||||||
|
line: null, |
||||||
|
tickLine: null, |
||||||
|
grid: { |
||||||
|
lineStyle: { |
||||||
|
lineDash: null |
||||||
|
}, |
||||||
|
hideFirstLine: false |
||||||
|
} |
||||||
|
} |
||||||
|
const axis2Opts = { |
||||||
|
dataKey: 'score', |
||||||
|
line: null, |
||||||
|
tickLine: null, |
||||||
|
grid: { |
||||||
|
type: 'polygon', |
||||||
|
lineStyle: { |
||||||
|
lineDash: null |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const scale = [ |
||||||
|
{ |
||||||
|
dataKey: 'score', |
||||||
|
min: 0, |
||||||
|
max: 100 |
||||||
|
}, { |
||||||
|
dataKey: 'user', |
||||||
|
alias: '类型' |
||||||
|
} |
||||||
|
] |
||||||
|
|
||||||
|
const sourceData = [ |
||||||
|
{ item: '示例一', score: 40 }, |
||||||
|
{ item: '示例二', score: 20 }, |
||||||
|
{ item: '示例三', score: 67 }, |
||||||
|
{ item: '示例四', score: 43 }, |
||||||
|
{ item: '示例五', score: 90 } |
||||||
|
] |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'Radar', |
||||||
|
props: { |
||||||
|
height: { |
||||||
|
type: Number, |
||||||
|
default: 254 |
||||||
|
}, |
||||||
|
dataSource: { |
||||||
|
type: Array, |
||||||
|
default: () => [] |
||||||
|
} |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
axis1Opts, |
||||||
|
axis2Opts, |
||||||
|
scale, |
||||||
|
data: sourceData |
||||||
|
} |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
dataSource(newVal) { |
||||||
|
if (newVal.length === 0) { |
||||||
|
this.data = sourceData |
||||||
|
} else { |
||||||
|
this.data = newVal |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
|
||||||
|
</style> |
||||||
@ -0,0 +1,81 @@ |
|||||||
|
<template> |
||||||
|
<div class="rank"> |
||||||
|
<h4 class="title">{{ title }}</h4> |
||||||
|
<ul class="list" :style="{height:height?`${height}px`:'auto',overflow:'auto'}"> |
||||||
|
<li :key="index" v-for="(item, index) in list"> |
||||||
|
<span :class="index < 3 ? 'active' : null">{{ index + 1 }}</span> |
||||||
|
<span>{{ item.name }}</span> |
||||||
|
<span>{{ item.total }}</span> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
name: "RankList", |
||||||
|
// ['title', 'list'] |
||||||
|
props: { |
||||||
|
title: { |
||||||
|
type: String, |
||||||
|
default: '' |
||||||
|
}, |
||||||
|
list: { |
||||||
|
type: Array, |
||||||
|
default: null |
||||||
|
}, |
||||||
|
height: { |
||||||
|
type: Number, |
||||||
|
default: null |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="less" scoped> |
||||||
|
|
||||||
|
.rank { |
||||||
|
padding: 0 32px 32px 72px; |
||||||
|
|
||||||
|
.list { |
||||||
|
margin: 25px 0 0; |
||||||
|
padding: 0; |
||||||
|
list-style: none; |
||||||
|
|
||||||
|
li { |
||||||
|
margin-top: 16px; |
||||||
|
|
||||||
|
span { |
||||||
|
color: rgba(0, 0, 0, .65); |
||||||
|
font-size: 14px; |
||||||
|
line-height: 22px; |
||||||
|
|
||||||
|
&:first-child { |
||||||
|
background-color: #f5f5f5; |
||||||
|
border-radius: 20px; |
||||||
|
display: inline-block; |
||||||
|
font-size: 12px; |
||||||
|
font-weight: 600; |
||||||
|
margin-right: 24px; |
||||||
|
height: 20px; |
||||||
|
line-height: 20px; |
||||||
|
width: 20px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
&.active { |
||||||
|
background-color: #314659; |
||||||
|
color: #fff; |
||||||
|
} |
||||||
|
&:last-child { |
||||||
|
float: right; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.mobile .rank { |
||||||
|
padding: 0 32px 32px 32px; |
||||||
|
} |
||||||
|
|
||||||
|
</style> |
||||||
@ -0,0 +1,54 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<v-chart :forceFit="true" :height="height" :data="data"> |
||||||
|
<v-coord type="rect" direction="LB" /> |
||||||
|
<v-tooltip /> |
||||||
|
<v-legend /> |
||||||
|
<v-axis dataKey="State" :label="label" /> |
||||||
|
<v-stack-bar position="State*流程数量" color="流程状态" /> |
||||||
|
</v-chart> |
||||||
|
</div> |
||||||
|
|
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
const DataSet = require('@antv/data-set'); |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'StackBar', |
||||||
|
props: { |
||||||
|
dataSource: { |
||||||
|
type: Array, |
||||||
|
required: true, |
||||||
|
default: () => [ |
||||||
|
{ 'State': '请假', '流转中': 25, '已归档': 18 }, |
||||||
|
{ 'State': '出差', '流转中': 30, '已归档': 20 }, |
||||||
|
{ 'State': '加班', '流转中': 38, '已归档': 42}, |
||||||
|
{ 'State': '用车', '流转中': 51, '已归档': 67} |
||||||
|
] |
||||||
|
}, |
||||||
|
height: { |
||||||
|
type: Number, |
||||||
|
default: 254 |
||||||
|
} |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
label: { offset: 12 } |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
data() { |
||||||
|
const dv = new DataSet.View().source(this.dataSource); |
||||||
|
dv.transform({ |
||||||
|
type: 'fold', |
||||||
|
fields: ['流转中', '已归档'], |
||||||
|
key: '流程状态', |
||||||
|
value: '流程数量', |
||||||
|
retains: ['State'], |
||||||
|
}); |
||||||
|
return dv.rows; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
@ -0,0 +1,66 @@ |
|||||||
|
<template> |
||||||
|
<div :style="{ padding: '0 0 32px 32px' }"> |
||||||
|
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4> |
||||||
|
<v-chart |
||||||
|
:height="height" |
||||||
|
:data="data" |
||||||
|
:scale="scale" |
||||||
|
:forceFit="true" |
||||||
|
:padding="['auto', 'auto', '40', '50']"> |
||||||
|
<v-tooltip/> |
||||||
|
<v-axis/> |
||||||
|
<v-bar position="x*y"/> |
||||||
|
</v-chart> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'Bar', |
||||||
|
props: { |
||||||
|
title: { |
||||||
|
type: String, |
||||||
|
default: '' |
||||||
|
}, |
||||||
|
x: { |
||||||
|
type: String, |
||||||
|
default: 'x' |
||||||
|
}, |
||||||
|
y: { |
||||||
|
type: String, |
||||||
|
default: 'y' |
||||||
|
}, |
||||||
|
data: { |
||||||
|
type: Array, |
||||||
|
default: () => [] |
||||||
|
}, |
||||||
|
height: { |
||||||
|
type: Number, |
||||||
|
default: 254 |
||||||
|
} |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return {} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
scale() { |
||||||
|
return [ |
||||||
|
{ dataKey: 'x', title: this.x, alias: this.x }, |
||||||
|
{ dataKey: 'y', title: this.y, alias: this.y } |
||||||
|
] |
||||||
|
} |
||||||
|
}, |
||||||
|
created() { |
||||||
|
// this.getMonthBar() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// getMonthBar() { |
||||||
|
// this.$http.get('/analysis/month-bar') |
||||||
|
// .then(res => { |
||||||
|
// this.data = res.result |
||||||
|
// }) |
||||||
|
// } |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
@ -0,0 +1,84 @@ |
|||||||
|
<template> |
||||||
|
<div class="chart-trend"> |
||||||
|
{{ term }} |
||||||
|
<span>{{ rate }}%</span> |
||||||
|
<span :class="['trend-icon', trend]"><a-icon :type="'caret-' + trend"/></span> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
name: "Trend", |
||||||
|
props: { |
||||||
|
// 同title |
||||||
|
term: { |
||||||
|
type: String, |
||||||
|
default: '', |
||||||
|
required: true |
||||||
|
}, |
||||||
|
// 百分比 |
||||||
|
percentage: { |
||||||
|
type: Number, |
||||||
|
default: null |
||||||
|
}, |
||||||
|
type: { |
||||||
|
type: Boolean, |
||||||
|
default: null |
||||||
|
}, |
||||||
|
target: { |
||||||
|
type: Number, |
||||||
|
default: 0 |
||||||
|
}, |
||||||
|
value: { |
||||||
|
type: Number, |
||||||
|
default: 0 |
||||||
|
}, |
||||||
|
fixed: { |
||||||
|
type: Number, |
||||||
|
default: 2 |
||||||
|
} |
||||||
|
}, |
||||||
|
data () { |
||||||
|
return { |
||||||
|
trend: this.type && 'up' || 'down', |
||||||
|
rate: this.percentage |
||||||
|
} |
||||||
|
}, |
||||||
|
created () { |
||||||
|
let type = this.type === null ? this.value >= this.target : this.type |
||||||
|
this.trend = type ? 'up' : 'down'; |
||||||
|
this.rate = (this.percentage === null ? Math.abs(this.value - this.target) * 100 / this.target : this.percentage).toFixed(this.fixed) |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="less" scoped> |
||||||
|
.chart-trend { |
||||||
|
display: inline-block; |
||||||
|
font-size: 14px; |
||||||
|
line-height: 22px; |
||||||
|
|
||||||
|
.trend-icon { |
||||||
|
font-size: 12px; |
||||||
|
|
||||||
|
&.up, &.down { |
||||||
|
margin-left: 4px; |
||||||
|
position: relative; |
||||||
|
top: 1px; |
||||||
|
|
||||||
|
i { |
||||||
|
font-size: 12px; |
||||||
|
transform: scale(.83); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&.up { |
||||||
|
color: #f5222d; |
||||||
|
} |
||||||
|
&.down { |
||||||
|
color: #52c41a; |
||||||
|
top: -1px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
.antv-chart-mini { |
||||||
|
position: relative; |
||||||
|
width: 100%; |
||||||
|
|
||||||
|
.chart-wrapper { |
||||||
|
position: absolute; |
||||||
|
bottom: -28px; |
||||||
|
width: 100%; |
||||||
|
|
||||||
|
/* margin: 0 -5px; |
||||||
|
overflow: hidden;*/ |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
export const ChartEventMixins = { |
||||||
|
methods: { |
||||||
|
handleClick(event, chart) { |
||||||
|
this.handleEvent('click', event, chart) |
||||||
|
}, |
||||||
|
handleEvent(eventName, event, chart) { |
||||||
|
this.$emit(eventName, event, chart) |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,111 @@ |
|||||||
|
<template> |
||||||
|
<a-radio-group v-if="tagType=='radio'" @change="handleInput" :value="getValueSting" :disabled="disabled"> |
||||||
|
<a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio> |
||||||
|
</a-radio-group> |
||||||
|
|
||||||
|
<a-radio-group v-else-if="tagType=='radioButton'" buttonStyle="solid" @change="handleInput" :value="getValueSting" :disabled="disabled"> |
||||||
|
<a-radio-button v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio-button> |
||||||
|
</a-radio-group> |
||||||
|
|
||||||
|
<a-select v-else-if="tagType=='select'" :getPopupContainer = "getPopupContainer" :placeholder="placeholder" :disabled="disabled" :value="getValueSting" @change="handleInput"> |
||||||
|
<a-select-option :value="undefined">请选择</a-select-option> |
||||||
|
<a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value"> |
||||||
|
<span style="display: inline-block;width: 100%" :title=" item.text || item.label "> |
||||||
|
{{ item.text || item.label }} |
||||||
|
</span> |
||||||
|
</a-select-option> |
||||||
|
</a-select> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api' |
||||||
|
|
||||||
|
export default { |
||||||
|
name: "JDictSelectTag", |
||||||
|
props: { |
||||||
|
dictCode: String, |
||||||
|
placeholder: String, |
||||||
|
disabled: Boolean, |
||||||
|
value: [String, Number], |
||||||
|
type: String, |
||||||
|
getPopupContainer:{ |
||||||
|
type: Function, |
||||||
|
default: (node) => node.parentNode |
||||||
|
} |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
dictOptions: [], |
||||||
|
tagType:"" |
||||||
|
} |
||||||
|
}, |
||||||
|
watch:{ |
||||||
|
dictCode:{ |
||||||
|
immediate:true, |
||||||
|
handler() { |
||||||
|
this.initDictData() |
||||||
|
}, |
||||||
|
} |
||||||
|
}, |
||||||
|
created() { |
||||||
|
// console.log(this.dictCode); |
||||||
|
if(!this.type || this.type==="list"){ |
||||||
|
this.tagType = "select" |
||||||
|
}else{ |
||||||
|
this.tagType = this.type |
||||||
|
} |
||||||
|
//获取字典数据 |
||||||
|
// this.initDictData(); |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
getValueSting(){ |
||||||
|
// update-begin author:wangshuai date:20200601 for: 不显示placeholder的文字 ------ |
||||||
|
// 当有null或“” placeholder不显示 |
||||||
|
return this.value != null ? this.value.toString() : undefined; |
||||||
|
// update-end author:wangshuai date:20200601 for: 不显示placeholder的文字 ------ |
||||||
|
}, |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
initDictData() { |
||||||
|
//优先从缓存中读取字典配置 |
||||||
|
if(getDictItemsFromCache(this.dictCode)){ |
||||||
|
this.dictOptions = getDictItemsFromCache(this.dictCode); |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
//根据字典Code, 初始化字典数组 |
||||||
|
ajaxGetDictItems(this.dictCode, null).then((res) => { |
||||||
|
if (res.success) { |
||||||
|
// console.log(res.result); |
||||||
|
this.dictOptions = res.result; |
||||||
|
} |
||||||
|
}) |
||||||
|
}, |
||||||
|
handleInput(e='') { |
||||||
|
let val; |
||||||
|
if(Object.keys(e).includes('target')){ |
||||||
|
val = e.target.value |
||||||
|
}else{ |
||||||
|
val = e |
||||||
|
} |
||||||
|
console.log(val); |
||||||
|
this.$emit('change', val); |
||||||
|
//LOWCOD-2146 【菜单】数据规则,选择自定义SQL 规则值无法输入空格 |
||||||
|
this.$emit('input', val); |
||||||
|
}, |
||||||
|
setCurrentDictOptions(dictOptions){ |
||||||
|
this.dictOptions = dictOptions |
||||||
|
}, |
||||||
|
getCurrentDictOptions(){ |
||||||
|
return this.dictOptions |
||||||
|
} |
||||||
|
}, |
||||||
|
model:{ |
||||||
|
prop: 'value', |
||||||
|
event: 'change' |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
</style> |
||||||
@ -0,0 +1,147 @@ |
|||||||
|
/** |
||||||
|
* 字典 util |
||||||
|
* author: scott |
||||||
|
* date: 20190109 |
||||||
|
*/ |
||||||
|
|
||||||
|
import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api' |
||||||
|
import {getAction} from '@/api/manage' |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取字典数组 |
||||||
|
* @param dictCode 字典Code |
||||||
|
* @return List<Map> |
||||||
|
*/ |
||||||
|
export async function initDictOptions(dictCode) { |
||||||
|
if (!dictCode) { |
||||||
|
return '字典Code不能为空!'; |
||||||
|
} |
||||||
|
//优先从缓存中读取字典配置
|
||||||
|
if(getDictItemsFromCache(dictCode)){ |
||||||
|
let res = {} |
||||||
|
res.result = getDictItemsFromCache(dictCode); |
||||||
|
res.success = true; |
||||||
|
return res; |
||||||
|
} |
||||||
|
//获取字典数组
|
||||||
|
let res = await ajaxGetDictItems(dictCode); |
||||||
|
return res; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 字典值替换文本通用方法 |
||||||
|
* @param dictOptions 字典数组 |
||||||
|
* @param text 字典值 |
||||||
|
* @return String |
||||||
|
*/ |
||||||
|
export function filterDictText(dictOptions, text) { |
||||||
|
// --update-begin----author:sunjianlei---date:20200323------for: 字典翻译 text 允许逗号分隔 ---
|
||||||
|
if (text != null && Array.isArray(dictOptions)) { |
||||||
|
let result = [] |
||||||
|
// 允许多个逗号分隔,允许传数组对象
|
||||||
|
let splitText |
||||||
|
if (Array.isArray(text)) { |
||||||
|
splitText = text |
||||||
|
} else { |
||||||
|
splitText = text.toString().trim().split(',') |
||||||
|
} |
||||||
|
for (let txt of splitText) { |
||||||
|
let dictText = txt |
||||||
|
for (let dictItem of dictOptions) { |
||||||
|
if (dictItem.value && txt.toString() === dictItem.value.toString()) { |
||||||
|
dictText = (dictItem.text || dictItem.title || dictItem.label) |
||||||
|
break |
||||||
|
} |
||||||
|
} |
||||||
|
result.push(dictText) |
||||||
|
} |
||||||
|
return result.join(',') |
||||||
|
} |
||||||
|
return text |
||||||
|
// --update-end----author:sunjianlei---date:20200323------for: 字典翻译 text 允许逗号分隔 ---
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 字典值替换文本通用方法(多选) |
||||||
|
* @param dictOptions 字典数组 |
||||||
|
* @param text 字典值 |
||||||
|
* @return String |
||||||
|
*/ |
||||||
|
export function filterMultiDictText(dictOptions, text) { |
||||||
|
//js “!text” 认为0为空,所以做提前处理
|
||||||
|
if(text === 0 || text === '0'){ |
||||||
|
if(dictOptions){ |
||||||
|
for (let dictItem of dictOptions) { |
||||||
|
if (text == dictItem.value) { |
||||||
|
return dictItem.text |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if(!text || text=='null' || !dictOptions || dictOptions.length==0){ |
||||||
|
return "" |
||||||
|
} |
||||||
|
let re = ""; |
||||||
|
text = text.toString() |
||||||
|
let arr = text.split(",") |
||||||
|
dictOptions.forEach(function (option) { |
||||||
|
if(option){ |
||||||
|
for(let i=0;i<arr.length;i++){ |
||||||
|
if (arr[i] === option.value) { |
||||||
|
re += option.text+","; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
if(re==""){ |
||||||
|
return text; |
||||||
|
} |
||||||
|
return re.substring(0,re.length-1); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 翻译字段值对应的文本 |
||||||
|
* @param children |
||||||
|
* @returns string |
||||||
|
*/ |
||||||
|
export function filterDictTextByCache(dictCode, key) { |
||||||
|
if(key==null ||key.length==0){ |
||||||
|
return; |
||||||
|
} |
||||||
|
if (!dictCode) { |
||||||
|
return '字典Code不能为空!'; |
||||||
|
} |
||||||
|
//优先从缓存中读取字典配置
|
||||||
|
if(getDictItemsFromCache(dictCode)){ |
||||||
|
let item = getDictItemsFromCache(dictCode).filter(t => t["value"] == key) |
||||||
|
if(item && item.length>0){ |
||||||
|
return item[0]["text"] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** 通过code获取字典数组 */ |
||||||
|
export async function getDictItems(dictCode, params) { |
||||||
|
//优先从缓存中读取字典配置
|
||||||
|
if(getDictItemsFromCache(dictCode)){ |
||||||
|
let desformDictItems = getDictItemsFromCache(dictCode).map(item => ({...item, label: item.text})) |
||||||
|
return desformDictItems; |
||||||
|
} |
||||||
|
|
||||||
|
//缓存中没有,就请求后台
|
||||||
|
return await ajaxGetDictItems(dictCode, params).then(({success, result}) => { |
||||||
|
if (success) { |
||||||
|
let res = result.map(item => ({...item, label: item.text})) |
||||||
|
console.log('------- 从DB中获取到了字典-------dictCode : ', dictCode, res) |
||||||
|
return Promise.resolve(res) |
||||||
|
} else { |
||||||
|
console.error('getDictItems error: : ', res) |
||||||
|
return Promise.resolve([]) |
||||||
|
} |
||||||
|
}).catch((res) => { |
||||||
|
console.error('getDictItems error: ', res) |
||||||
|
return Promise.resolve([]) |
||||||
|
}) |
||||||
|
} |
||||||