282 changed files with 42132 additions and 27825 deletions
@ -0,0 +1,4 @@ |
|||
> 1% |
|||
last 2 versions |
|||
Chrome >= 63 |
|||
not dead |
|||
@ -0,0 +1,15 @@ |
|||
# https://editorconfig.org |
|||
root = true |
|||
|
|||
[*] |
|||
indent_style = space |
|||
indent_size = 2 |
|||
tab_width = 2 |
|||
end_of_line = lf |
|||
charset = utf-8 |
|||
trim_trailing_whitespace = true |
|||
insert_final_newline = true |
|||
|
|||
[*.md] |
|||
trim_trailing_whitespace = false |
|||
insert_final_newline = false |
|||
@ -1,3 +1,2 @@ |
|||
VUE_APP_VERSION=3.0 |
|||
VUE_APP_NAME=Bmz Admin |
|||
VUE_APP_API_BASE_URL=http://api.base.ahbmz.com/api |
|||
VUE_APP_NAME=Ele Admin |
|||
VUE_APP_API_BASE_URL=https://v2.eleadmin.com/api |
|||
|
|||
@ -1 +1 @@ |
|||
VUE_APP_API_BASE_URL=http://api.base.ahbmz.com/api |
|||
VUE_APP_API_BASE_URL=https://v2.eleadmin.com/api |
|||
|
|||
@ -1,2 +1,2 @@ |
|||
NODE_ENV=production |
|||
VUE_APP_API_BASE_URL=https://v1.eleadmin.com/api |
|||
VUE_APP_API_BASE_URL=https://v2.eleadmin.com/api |
|||
|
|||
@ -1,16 +1,21 @@ |
|||
module.exports = { |
|||
root: true, |
|||
env: { |
|||
browser: true, |
|||
node: true, |
|||
es6: true |
|||
}, |
|||
parser: 'vue-eslint-parser', |
|||
extends: [ |
|||
"plugin:vue/essential", |
|||
'eslint:recommended' |
|||
'plugin:vue/essential', |
|||
'eslint:recommended', |
|||
'prettier', |
|||
'plugin:prettier/recommended' |
|||
], |
|||
parserOptions: { |
|||
parser: 'babel-eslint' |
|||
parser: '@babel/eslint-parser', |
|||
ecmaVersion: 2020, |
|||
sourceType: 'module' |
|||
}, |
|||
rules: { |
|||
//"no-unused-vars": "off"
|
|||
} |
|||
} |
|||
rules: {} |
|||
}; |
|||
|
|||
@ -0,0 +1,4 @@ |
|||
/public/* |
|||
/src/assets/* |
|||
/dist/* |
|||
/node_modules/* |
|||
@ -1,5 +1,3 @@ |
|||
module.exports = { |
|||
presets: [ |
|||
'@vue/cli-plugin-babel/preset' |
|||
] |
|||
} |
|||
presets: ['@vue/cli-plugin-babel/preset'] |
|||
}; |
|||
|
|||
Binary file not shown.
@ -1,14 +1,13 @@ |
|||
{ |
|||
"compilerOptions": { |
|||
"target": "es6", |
|||
"module": "esnext", |
|||
"moduleResolution": "node", |
|||
"baseUrl": "./", |
|||
"paths": { |
|||
"@/*": [ |
|||
"src/*" |
|||
] |
|||
} |
|||
"@/*": ["src/*"] |
|||
}, |
|||
"exclude": [ |
|||
"node_modules", |
|||
"dist" |
|||
] |
|||
"lib": ["esnext", "dom", "dom.iterable", "scripthost"] |
|||
}, |
|||
"exclude": ["node_modules", "dist"] |
|||
} |
|||
File diff suppressed because it is too large
@ -1,56 +1,63 @@ |
|||
{ |
|||
"name": "ele-admin-template", |
|||
"version": "1.2.0", |
|||
"version": "1.8.0", |
|||
"private": true, |
|||
"scripts": { |
|||
"serve": "vue-cli-service serve", |
|||
"build": "vue-cli-service build", |
|||
"build:preview": "vue-cli-service build --mode preview", |
|||
"build:report": "vue-cli-service build --report", |
|||
"lint": "vue-cli-service lint" |
|||
"lint": "vue-cli-service lint", |
|||
"clean:lib": "rimraf node_modules" |
|||
}, |
|||
"dependencies": { |
|||
"@amap/amap-jsapi-loader": "^0.0.7", |
|||
"@riophae/vue-treeselect": "^0.4.0", |
|||
"@amap/amap-jsapi-loader": "^1.0.1", |
|||
"@ant-design/colors": "^6.0.0", |
|||
"@bytemd/plugin-gfm": "^1.11.0", |
|||
"@bytemd/vue": "^1.11.0", |
|||
"@tinymce/tinymce-vue": "^3.2.8", |
|||
"axios": "^0.21.1", |
|||
"core-js": "^3.8.3", |
|||
"countup.js": "^2.0.7", |
|||
"cropperjs": "^1.5.9", |
|||
"echarts": "^4.9.0", |
|||
"echarts-wordcloud": "^1.1.3", |
|||
"ele-admin": "^1.2.0", |
|||
"element-ui": "^2.15.0", |
|||
"@vue/composition-api": "^1.4.9", |
|||
"axios": "^0.26.0", |
|||
"core-js": "^3.21.1", |
|||
"countup.js": "^2.0.8", |
|||
"cropperjs": "^1.5.12", |
|||
"echarts": "^5.3.0", |
|||
"echarts-wordcloud": "^2.0.0", |
|||
"ele-admin": "1.8.0", |
|||
"element-ui": "^2.15.7", |
|||
"github-markdown-css": "^5.1.0", |
|||
"nprogress": "^0.2.0", |
|||
"tinymce": "^5.7.0", |
|||
"vue": "^2.6.12", |
|||
"vue-axios": "^2.1.5", |
|||
"vue-clipboard2": "^0.3.1", |
|||
"qrcodejs2": "^0.0.2", |
|||
"tinymce": "^5.10.3", |
|||
"vue": "^2.6.14", |
|||
"vue-clipboard2": "^0.3.3", |
|||
"vue-countup-v2": "^4.0.0", |
|||
"vue-qr": "^2.3.0", |
|||
"vue-router": "^3.5.1", |
|||
"vue-echarts": "^6.0.2", |
|||
"vue-i18n": "^8.27.0", |
|||
"vue-router": "^3.5.3", |
|||
"vuedraggable": "^2.24.3", |
|||
"vuex": "^3.6.2", |
|||
"xgplayer-vue": "^1.1.5", |
|||
"xlsx": "^0.16.9" |
|||
"xlsx": "^0.18.2" |
|||
}, |
|||
"devDependencies": { |
|||
"@vue/cli-plugin-babel": "^4.5.11", |
|||
"@vue/cli-plugin-eslint": "^4.5.11", |
|||
"@vue/cli-plugin-router": "^4.5.11", |
|||
"@vue/cli-plugin-vuex": "^4.5.11", |
|||
"@vue/cli-service": "^4.5.11", |
|||
"babel-eslint": "^10.1.0", |
|||
"@babel/core": "^7.17.5", |
|||
"@babel/eslint-parser": "^7.17.0", |
|||
"@vue/cli-plugin-babel": "^5.0.1", |
|||
"@vue/cli-plugin-eslint": "^5.0.1", |
|||
"@vue/cli-plugin-router": "^5.0.1", |
|||
"@vue/cli-plugin-vuex": "^5.0.1", |
|||
"@vue/cli-service": "^5.0.1", |
|||
"compression-webpack-plugin": "^6.1.1", |
|||
"eslint": "^6.8.0", |
|||
"eslint-plugin-vue": "^7.6.0", |
|||
"sass": "^1.3.0", |
|||
"sass-loader": "^10.1.1", |
|||
"vue-template-compiler": "^2.6.12" |
|||
}, |
|||
"browserslist": [ |
|||
"> 1%", |
|||
"last 2 versions", |
|||
"not dead" |
|||
] |
|||
"eslint": "^8.10.0", |
|||
"eslint-config-prettier": "^8.4.0", |
|||
"eslint-plugin-prettier": "^4.0.0", |
|||
"eslint-plugin-vue": "^8.5.0", |
|||
"prettier": "^2.5.1", |
|||
"sass": "^1.49.9", |
|||
"sass-loader": "^12.6.0", |
|||
"vue-eslint-parser": "^8.3.0", |
|||
"vue-template-compiler": "^2.6.14", |
|||
"webpack": "^5.0.0" |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,19 @@ |
|||
module.exports = { |
|||
printWidth: 80, |
|||
tabWidth: 2, |
|||
useTabs: false, |
|||
semi: true, |
|||
singleQuote: true, |
|||
quoteProps: 'as-needed', |
|||
jsxSingleQuote: false, |
|||
trailingComma: 'none', |
|||
bracketSpacing: true, |
|||
bracketSameLine: false, |
|||
arrowParens: 'always', |
|||
requirePragma: false, |
|||
insertPragma: false, |
|||
proseWrap: 'never', |
|||
htmlWhitespaceSensitivity: 'strict', |
|||
vueIndentScriptAndStyle: true, |
|||
endOfLine: 'lf' |
|||
}; |
|||
@ -1,22 +1,69 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="zh-CN"> |
|||
<head> |
|||
<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"> |
|||
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
|||
<title><%= process.env.VUE_APP_NAME %></title> |
|||
</head> |
|||
<body> |
|||
<style> |
|||
.ele-admin-loading { |
|||
width: 36px; |
|||
font-size: 0; |
|||
display: inline-block; |
|||
transform: rotate(45deg); |
|||
animation: loadingRotate 1.2s infinite linear; |
|||
position: relative; |
|||
top: calc(50% - 18px); |
|||
left: calc(50% - 18px); |
|||
} |
|||
|
|||
.ele-admin-loading span { |
|||
width: 10px; |
|||
height: 10px; |
|||
margin: 4px; |
|||
border-radius: 50%; |
|||
background: #1890ff; |
|||
display: inline-block; |
|||
opacity: .9; |
|||
} |
|||
|
|||
.ele-admin-loading span:nth-child(2) { |
|||
opacity: .7; |
|||
} |
|||
|
|||
.ele-admin-loading span:nth-child(3) { |
|||
opacity: .5; |
|||
} |
|||
|
|||
.ele-admin-loading span:nth-child(4) { |
|||
opacity: .3; |
|||
} |
|||
|
|||
@keyframes loadingRotate { |
|||
to { |
|||
transform: rotate(405deg); |
|||
} |
|||
} |
|||
|
|||
#app > .ele-admin-loading { |
|||
position: fixed; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<noscript> |
|||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> |
|||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. |
|||
Please enable it to continue.</strong> |
|||
</noscript> |
|||
<div id="app"> |
|||
<div class="ele-admin-loading"></div> |
|||
<style> |
|||
.ele-admin-loading{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.ele-admin-loading:before{content:"";width:30px;height:30px;margin:0 auto;display:block;border-radius:50%;background:#409eff;animation:loading-bounce .3s cubic-bezier(0.05,0,0.2,1) infinite alternate}.ele-admin-loading:after{content:"";width:10px;height:2px;margin:0 auto;display:block;border-radius:50%;background:#BBB;animation:loading-shadow .3s cubic-bezier(0.05,0,0.2,1) infinite alternate}@keyframes loading-bounce{from{transform:translateY(0)}to{transform:translateY(-40px)}}@keyframes loading-shadow{from{transform:scale(1,1);opacity:1}to{transform:scale(3,2);opacity:.3}} |
|||
</style> |
|||
<div class="ele-admin-loading"> |
|||
<span></span> |
|||
<span></span> |
|||
<span></span> |
|||
<span></span> |
|||
</div> |
|||
</div> |
|||
<!-- built files will be auto injected --> |
|||
</body> |
|||
</body> |
|||
</html> |
|||
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,389 +1,389 @@ |
|||
tinymce.addI18n('zh_CN',{ |
|||
"Redo": "\u91cd\u505a", |
|||
"Undo": "\u64a4\u9500", |
|||
"Cut": "\u526a\u5207", |
|||
"Copy": "\u590d\u5236", |
|||
"Paste": "\u7c98\u8d34", |
|||
"Select all": "\u5168\u9009", |
|||
"New document": "\u65b0\u6587\u4ef6", |
|||
"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\u8fb9\u5bf9\u9f50", |
|||
"Align center": "\u4e2d\u95f4\u5bf9\u9f50", |
|||
"Align right": "\u53f3\u8fb9\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\u6253\u5f00\u526a\u8d34\u677f\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u7b49\u5feb\u6377\u952e\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\u5148\u683c\u5f0f\u5316\u7684", |
|||
"Div": "Div", |
|||
"Pre": "Pre", |
|||
"Code": "\u4ee3\u7801", |
|||
"Paragraph": "\u6bb5\u843d", |
|||
"Blockquote": "\u5f15\u6587\u533a\u5757", |
|||
"Inline": "\u6587\u672c", |
|||
"Blocks": "\u57fa\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", |
|||
"Fonts": "\u5b57\u4f53", |
|||
"Font Sizes": "\u5b57\u53f7", |
|||
"Class": "\u7c7b\u578b", |
|||
"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 characters...": "\u7279\u6b8a\u5b57\u7b26...", |
|||
"Source code": "\u6e90\u4ee3\u7801", |
|||
"Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b", |
|||
"Language": "\u8bed\u8a00", |
|||
"Code sample...": "\u793a\u4f8b\u4ee3\u7801...", |
|||
"Color Picker": "\u9009\u8272\u5668", |
|||
"R": "R", |
|||
"G": "G", |
|||
"B": "B", |
|||
"Left to right": "\u4ece\u5de6\u5230\u53f3", |
|||
"Right to left": "\u4ece\u53f3\u5230\u5de6", |
|||
"Emoticons...": "\u8868\u60c5\u7b26\u53f7...", |
|||
"Metadata and Document Properties": "\u5143\u6570\u636e\u548c\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\/Edit Link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", |
|||
"Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", |
|||
"Text to display": "\u663e\u793a\u6587\u5b57", |
|||
"Url": "\u5730\u5740", |
|||
"Open link in...": "\u94fe\u63a5\u6253\u5f00\u4f4d\u7f6e...", |
|||
"Current window": "\u5f53\u524d\u7a97\u53e3", |
|||
"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", |
|||
"Alternative source URL": "\u66ff\u4ee3\u6765\u6e90\u7f51\u5740", |
|||
"Media poster (Image URL)": "\u5c01\u9762(\u56fe\u7247\u5730\u5740)", |
|||
"Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:", |
|||
"Embed": "\u5185\u5d4c", |
|||
"Media...": "\u591a\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", |
|||
"Previous": "\u4e0a\u4e00\u4e2a", |
|||
"Next": "\u4e0b\u4e00\u4e2a", |
|||
"Find and replace...": "\u67e5\u627e\u5e76\u66ff\u6362...", |
|||
"Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.", |
|||
"Match case": "\u533a\u5206\u5927\u5c0f\u5199", |
|||
"Find whole words only": "\u5168\u5b57\u5339\u914d", |
|||
"Spell check": "\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", |
|||
"Show caption": "\u663e\u793a\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", |
|||
"Remove color": "\u79fb\u9664\u989c\u8272", |
|||
"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", |
|||
"Word count": "\u5b57\u6570", |
|||
"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", |
|||
"Image title": "\u56fe\u7247\u6807\u9898", |
|||
"Border width": "\u8fb9\u6846\u5bbd\u5ea6", |
|||
"Border style": "\u8fb9\u6846\u6837\u5f0f", |
|||
"Error": "\u9519\u8bef", |
|||
"Warn": "\u8b66\u544a", |
|||
"Valid": "\u6709\u6548", |
|||
"To open the popup, press Shift+Enter": "\u6309Shitf+Enter\u952e\u6253\u5f00\u5bf9\u8bdd\u6846", |
|||
"Rich Text Area. Press ALT-0 for help.": "\u7f16\u8f91\u533a\u3002\u6309Alt+0\u952e\u6253\u5f00\u5e2e\u52a9\u3002", |
|||
"System Font": "\u7cfb\u7edf\u5b57\u4f53", |
|||
"Failed to upload image: {0}": "\u56fe\u7247\u4e0a\u4f20\u5931\u8d25: {0}", |
|||
"Failed to load plugin: {0} from url {1}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25: {0} \u6765\u81ea\u94fe\u63a5 {1}", |
|||
"Failed to load plugin url: {0}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25 \u94fe\u63a5: {0}", |
|||
"Failed to initialize plugin: {0}": "\u63d2\u4ef6\u521d\u59cb\u5316\u5931\u8d25: {0}", |
|||
"example": "\u793a\u4f8b", |
|||
"Search": "\u641c\u7d22", |
|||
"All": "\u5168\u90e8", |
|||
"Currency": "\u8d27\u5e01", |
|||
"Text": "\u6587\u5b57", |
|||
"Quotations": "\u5f15\u7528", |
|||
"Mathematical": "\u6570\u5b66", |
|||
"Extended Latin": "\u62c9\u4e01\u8bed\u6269\u5145", |
|||
"Symbols": "\u7b26\u53f7", |
|||
"Arrows": "\u7bad\u5934", |
|||
"User Defined": "\u81ea\u5b9a\u4e49", |
|||
"dollar sign": "\u7f8e\u5143\u7b26\u53f7", |
|||
"currency sign": "\u8d27\u5e01\u7b26\u53f7", |
|||
"euro-currency sign": "\u6b27\u5143\u7b26\u53f7", |
|||
"colon sign": "\u5192\u53f7", |
|||
"cruzeiro sign": "\u514b\u9c81\u8d5b\u7f57\u5e01\u7b26\u53f7", |
|||
"french franc sign": "\u6cd5\u90ce\u7b26\u53f7", |
|||
"lira sign": "\u91cc\u62c9\u7b26\u53f7", |
|||
"mill sign": "\u5bc6\u5c14\u7b26\u53f7", |
|||
"naira sign": "\u5948\u62c9\u7b26\u53f7", |
|||
"peseta sign": "\u6bd4\u585e\u5854\u7b26\u53f7", |
|||
"rupee sign": "\u5362\u6bd4\u7b26\u53f7", |
|||
"won sign": "\u97e9\u5143\u7b26\u53f7", |
|||
"new sheqel sign": "\u65b0\u8c22\u514b\u5c14\u7b26\u53f7", |
|||
"dong sign": "\u8d8a\u5357\u76fe\u7b26\u53f7", |
|||
"kip sign": "\u8001\u631d\u57fa\u666e\u7b26\u53f7", |
|||
"tugrik sign": "\u56fe\u683c\u91cc\u514b\u7b26\u53f7", |
|||
"drachma sign": "\u5fb7\u62c9\u514b\u9a6c\u7b26\u53f7", |
|||
"german penny symbol": "\u5fb7\u56fd\u4fbf\u58eb\u7b26\u53f7", |
|||
"peso sign": "\u6bd4\u7d22\u7b26\u53f7", |
|||
"guarani sign": "\u74dc\u62c9\u5c3c\u7b26\u53f7", |
|||
"austral sign": "\u6fb3\u5143\u7b26\u53f7", |
|||
"hryvnia sign": "\u683c\u91cc\u592b\u5c3c\u4e9a\u7b26\u53f7", |
|||
"cedi sign": "\u585e\u5730\u7b26\u53f7", |
|||
"livre tournois sign": "\u91cc\u5f17\u5f17\u5c14\u7b26\u53f7", |
|||
"spesmilo sign": "spesmilo\u7b26\u53f7", |
|||
"tenge sign": "\u575a\u6208\u7b26\u53f7", |
|||
"indian rupee sign": "\u5370\u5ea6\u5362\u6bd4", |
|||
"turkish lira sign": "\u571f\u8033\u5176\u91cc\u62c9", |
|||
"nordic mark sign": "\u5317\u6b27\u9a6c\u514b", |
|||
"manat sign": "\u9a6c\u7eb3\u7279\u7b26\u53f7", |
|||
"ruble sign": "\u5362\u5e03\u7b26\u53f7", |
|||
"yen character": "\u65e5\u5143\u5b57\u6837", |
|||
"yuan character": "\u4eba\u6c11\u5e01\u5143\u5b57\u6837", |
|||
"yuan character, in hong kong and taiwan": "\u5143\u5b57\u6837\uff08\u6e2f\u53f0\u5730\u533a\uff09", |
|||
"yen\/yuan character variant one": "\u5143\u5b57\u6837\uff08\u5927\u5199\uff09", |
|||
"Loading emoticons...": "\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7...", |
|||
"Could not load emoticons": "\u4e0d\u80fd\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7", |
|||
"People": "\u4eba\u7c7b", |
|||
"Animals and Nature": "\u52a8\u7269\u548c\u81ea\u7136", |
|||
"Food and Drink": "\u98df\u7269\u548c\u996e\u54c1", |
|||
"Activity": "\u6d3b\u52a8", |
|||
"Travel and Places": "\u65c5\u6e38\u548c\u5730\u70b9", |
|||
"Objects": "\u7269\u4ef6", |
|||
"Flags": "\u65d7\u5e1c", |
|||
"Characters": "\u5b57\u7b26", |
|||
"Characters (no spaces)": "\u5b57\u7b26(\u65e0\u7a7a\u683c)", |
|||
"Error: Form submit field collision.": "\u9519\u8bef: \u8868\u5355\u63d0\u4ea4\u5b57\u6bb5\u51b2\u7a81\u3002", |
|||
"Error: No form element found.": "\u9519\u8bef: \u6ca1\u6709\u8868\u5355\u63a7\u4ef6\u3002", |
|||
"Update": "\u66f4\u65b0", |
|||
"Color swatch": "\u989c\u8272\u6837\u672c", |
|||
"Turquoise": "\u9752\u7eff\u8272", |
|||
"Green": "\u7eff\u8272", |
|||
"Blue": "\u84dd\u8272", |
|||
"Purple": "\u7d2b\u8272", |
|||
"Navy Blue": "\u6d77\u519b\u84dd", |
|||
"Dark Turquoise": "\u6df1\u84dd\u7eff\u8272", |
|||
"Dark Green": "\u6df1\u7eff\u8272", |
|||
"Medium Blue": "\u4e2d\u84dd\u8272", |
|||
"Medium Purple": "\u4e2d\u7d2b\u8272", |
|||
"Midnight Blue": "\u6df1\u84dd\u8272", |
|||
"Yellow": "\u9ec4\u8272", |
|||
"Orange": "\u6a59\u8272", |
|||
"Red": "\u7ea2\u8272", |
|||
"Light Gray": "\u6d45\u7070\u8272", |
|||
"Gray": "\u7070\u8272", |
|||
"Dark Yellow": "\u6697\u9ec4\u8272", |
|||
"Dark Orange": "\u6df1\u6a59\u8272", |
|||
"Dark Red": "\u6df1\u7ea2\u8272", |
|||
"Medium Gray": "\u4e2d\u7070\u8272", |
|||
"Dark Gray": "\u6df1\u7070\u8272", |
|||
"Black": "\u9ed1\u8272", |
|||
"White": "\u767d\u8272", |
|||
"Switch to or from fullscreen mode": "\u5207\u6362\u5168\u5c4f\u6a21\u5f0f", |
|||
"Open help dialog": "\u6253\u5f00\u5e2e\u52a9\u5bf9\u8bdd\u6846", |
|||
"history": "\u5386\u53f2", |
|||
"styles": "\u6837\u5f0f", |
|||
"formatting": "\u683c\u5f0f\u5316", |
|||
"alignment": "\u5bf9\u9f50", |
|||
"indentation": "\u7f29\u8fdb", |
|||
"permanent pen": "\u8bb0\u53f7\u7b14", |
|||
"comments": "\u5907\u6ce8", |
|||
"Anchor": "\u951a\u70b9", |
|||
"Special character": "\u7279\u6b8a\u7b26\u53f7", |
|||
"Code sample": "\u4ee3\u7801\u793a\u4f8b", |
|||
"Color": "\u989c\u8272", |
|||
"Emoticons": "\u8868\u60c5", |
|||
"Document properties": "\u6587\u6863\u5c5e\u6027", |
|||
"Image": "\u56fe\u7247", |
|||
"Insert link": "\u63d2\u5165\u94fe\u63a5", |
|||
"Target": "\u6253\u5f00\u65b9\u5f0f", |
|||
"Link": "\u94fe\u63a5", |
|||
"Poster": "\u5c01\u9762", |
|||
"Media": "\u5a92\u4f53", |
|||
"Print": "\u6253\u5370", |
|||
"Prev": "\u4e0a\u4e00\u4e2a", |
|||
"Find and replace": "\u67e5\u627e\u548c\u66ff\u6362", |
|||
"Whole words": "\u5168\u5b57\u5339\u914d", |
|||
"Spellcheck": "\u62fc\u5199\u68c0\u67e5", |
|||
"Caption": "\u6807\u9898", |
|||
"Insert template": "\u63d2\u5165\u6a21\u677f" |
|||
tinymce.addI18n('zh_CN', { |
|||
"Redo": "\u91cd\u505a", |
|||
"Undo": "\u64a4\u9500", |
|||
"Cut": "\u526a\u5207", |
|||
"Copy": "\u590d\u5236", |
|||
"Paste": "\u7c98\u8d34", |
|||
"Select all": "\u5168\u9009", |
|||
"New document": "\u65b0\u6587\u4ef6", |
|||
"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\u8fb9\u5bf9\u9f50", |
|||
"Align center": "\u4e2d\u95f4\u5bf9\u9f50", |
|||
"Align right": "\u53f3\u8fb9\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\u6253\u5f00\u526a\u8d34\u677f\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u7b49\u5feb\u6377\u952e\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\u5148\u683c\u5f0f\u5316\u7684", |
|||
"Div": "Div", |
|||
"Pre": "Pre", |
|||
"Code": "\u4ee3\u7801", |
|||
"Paragraph": "\u6bb5\u843d", |
|||
"Blockquote": "\u5f15\u6587\u533a\u5757", |
|||
"Inline": "\u6587\u672c", |
|||
"Blocks": "\u57fa\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", |
|||
"Fonts": "\u5b57\u4f53", |
|||
"Font Sizes": "\u5b57\u53f7", |
|||
"Class": "\u7c7b\u578b", |
|||
"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 characters...": "\u7279\u6b8a\u5b57\u7b26...", |
|||
"Source code": "\u6e90\u4ee3\u7801", |
|||
"Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b", |
|||
"Language": "\u8bed\u8a00", |
|||
"Code sample...": "\u793a\u4f8b\u4ee3\u7801...", |
|||
"Color Picker": "\u9009\u8272\u5668", |
|||
"R": "R", |
|||
"G": "G", |
|||
"B": "B", |
|||
"Left to right": "\u4ece\u5de6\u5230\u53f3", |
|||
"Right to left": "\u4ece\u53f3\u5230\u5de6", |
|||
"Emoticons...": "\u8868\u60c5\u7b26\u53f7...", |
|||
"Metadata and Document Properties": "\u5143\u6570\u636e\u548c\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\/Edit Link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", |
|||
"Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", |
|||
"Text to display": "\u663e\u793a\u6587\u5b57", |
|||
"Url": "\u5730\u5740", |
|||
"Open link in...": "\u94fe\u63a5\u6253\u5f00\u4f4d\u7f6e...", |
|||
"Current window": "\u5f53\u524d\u7a97\u53e3", |
|||
"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", |
|||
"Alternative source URL": "\u66ff\u4ee3\u6765\u6e90\u7f51\u5740", |
|||
"Media poster (Image URL)": "\u5c01\u9762(\u56fe\u7247\u5730\u5740)", |
|||
"Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:", |
|||
"Embed": "\u5185\u5d4c", |
|||
"Media...": "\u591a\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", |
|||
"Previous": "\u4e0a\u4e00\u4e2a", |
|||
"Next": "\u4e0b\u4e00\u4e2a", |
|||
"Find and replace...": "\u67e5\u627e\u5e76\u66ff\u6362...", |
|||
"Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.", |
|||
"Match case": "\u533a\u5206\u5927\u5c0f\u5199", |
|||
"Find whole words only": "\u5168\u5b57\u5339\u914d", |
|||
"Spell check": "\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", |
|||
"Show caption": "\u663e\u793a\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", |
|||
"Remove color": "\u79fb\u9664\u989c\u8272", |
|||
"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", |
|||
"Word count": "\u5b57\u6570", |
|||
"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", |
|||
"Image title": "\u56fe\u7247\u6807\u9898", |
|||
"Border width": "\u8fb9\u6846\u5bbd\u5ea6", |
|||
"Border style": "\u8fb9\u6846\u6837\u5f0f", |
|||
"Error": "\u9519\u8bef", |
|||
"Warn": "\u8b66\u544a", |
|||
"Valid": "\u6709\u6548", |
|||
"To open the popup, press Shift+Enter": "\u6309Shitf+Enter\u952e\u6253\u5f00\u5bf9\u8bdd\u6846", |
|||
"Rich Text Area. Press ALT-0 for help.": "\u7f16\u8f91\u533a\u3002\u6309Alt+0\u952e\u6253\u5f00\u5e2e\u52a9\u3002", |
|||
"System Font": "\u7cfb\u7edf\u5b57\u4f53", |
|||
"Failed to upload image: {0}": "\u56fe\u7247\u4e0a\u4f20\u5931\u8d25: {0}", |
|||
"Failed to load plugin: {0} from url {1}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25: {0} \u6765\u81ea\u94fe\u63a5 {1}", |
|||
"Failed to load plugin url: {0}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25 \u94fe\u63a5: {0}", |
|||
"Failed to initialize plugin: {0}": "\u63d2\u4ef6\u521d\u59cb\u5316\u5931\u8d25: {0}", |
|||
"example": "\u793a\u4f8b", |
|||
"Search": "\u641c\u7d22", |
|||
"All": "\u5168\u90e8", |
|||
"Currency": "\u8d27\u5e01", |
|||
"Text": "\u6587\u5b57", |
|||
"Quotations": "\u5f15\u7528", |
|||
"Mathematical": "\u6570\u5b66", |
|||
"Extended Latin": "\u62c9\u4e01\u8bed\u6269\u5145", |
|||
"Symbols": "\u7b26\u53f7", |
|||
"Arrows": "\u7bad\u5934", |
|||
"User Defined": "\u81ea\u5b9a\u4e49", |
|||
"dollar sign": "\u7f8e\u5143\u7b26\u53f7", |
|||
"currency sign": "\u8d27\u5e01\u7b26\u53f7", |
|||
"euro-currency sign": "\u6b27\u5143\u7b26\u53f7", |
|||
"colon sign": "\u5192\u53f7", |
|||
"cruzeiro sign": "\u514b\u9c81\u8d5b\u7f57\u5e01\u7b26\u53f7", |
|||
"french franc sign": "\u6cd5\u90ce\u7b26\u53f7", |
|||
"lira sign": "\u91cc\u62c9\u7b26\u53f7", |
|||
"mill sign": "\u5bc6\u5c14\u7b26\u53f7", |
|||
"naira sign": "\u5948\u62c9\u7b26\u53f7", |
|||
"peseta sign": "\u6bd4\u585e\u5854\u7b26\u53f7", |
|||
"rupee sign": "\u5362\u6bd4\u7b26\u53f7", |
|||
"won sign": "\u97e9\u5143\u7b26\u53f7", |
|||
"new sheqel sign": "\u65b0\u8c22\u514b\u5c14\u7b26\u53f7", |
|||
"dong sign": "\u8d8a\u5357\u76fe\u7b26\u53f7", |
|||
"kip sign": "\u8001\u631d\u57fa\u666e\u7b26\u53f7", |
|||
"tugrik sign": "\u56fe\u683c\u91cc\u514b\u7b26\u53f7", |
|||
"drachma sign": "\u5fb7\u62c9\u514b\u9a6c\u7b26\u53f7", |
|||
"german penny symbol": "\u5fb7\u56fd\u4fbf\u58eb\u7b26\u53f7", |
|||
"peso sign": "\u6bd4\u7d22\u7b26\u53f7", |
|||
"guarani sign": "\u74dc\u62c9\u5c3c\u7b26\u53f7", |
|||
"austral sign": "\u6fb3\u5143\u7b26\u53f7", |
|||
"hryvnia sign": "\u683c\u91cc\u592b\u5c3c\u4e9a\u7b26\u53f7", |
|||
"cedi sign": "\u585e\u5730\u7b26\u53f7", |
|||
"livre tournois sign": "\u91cc\u5f17\u5f17\u5c14\u7b26\u53f7", |
|||
"spesmilo sign": "spesmilo\u7b26\u53f7", |
|||
"tenge sign": "\u575a\u6208\u7b26\u53f7", |
|||
"indian rupee sign": "\u5370\u5ea6\u5362\u6bd4", |
|||
"turkish lira sign": "\u571f\u8033\u5176\u91cc\u62c9", |
|||
"nordic mark sign": "\u5317\u6b27\u9a6c\u514b", |
|||
"manat sign": "\u9a6c\u7eb3\u7279\u7b26\u53f7", |
|||
"ruble sign": "\u5362\u5e03\u7b26\u53f7", |
|||
"yen character": "\u65e5\u5143\u5b57\u6837", |
|||
"yuan character": "\u4eba\u6c11\u5e01\u5143\u5b57\u6837", |
|||
"yuan character, in hong kong and taiwan": "\u5143\u5b57\u6837\uff08\u6e2f\u53f0\u5730\u533a\uff09", |
|||
"yen\/yuan character variant one": "\u5143\u5b57\u6837\uff08\u5927\u5199\uff09", |
|||
"Loading emoticons...": "\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7...", |
|||
"Could not load emoticons": "\u4e0d\u80fd\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7", |
|||
"People": "\u4eba\u7c7b", |
|||
"Animals and Nature": "\u52a8\u7269\u548c\u81ea\u7136", |
|||
"Food and Drink": "\u98df\u7269\u548c\u996e\u54c1", |
|||
"Activity": "\u6d3b\u52a8", |
|||
"Travel and Places": "\u65c5\u6e38\u548c\u5730\u70b9", |
|||
"Objects": "\u7269\u4ef6", |
|||
"Flags": "\u65d7\u5e1c", |
|||
"Characters": "\u5b57\u7b26", |
|||
"Characters (no spaces)": "\u5b57\u7b26(\u65e0\u7a7a\u683c)", |
|||
"Error: Form submit field collision.": "\u9519\u8bef: \u8868\u5355\u63d0\u4ea4\u5b57\u6bb5\u51b2\u7a81\u3002", |
|||
"Error: No form element found.": "\u9519\u8bef: \u6ca1\u6709\u8868\u5355\u63a7\u4ef6\u3002", |
|||
"Update": "\u66f4\u65b0", |
|||
"Color swatch": "\u989c\u8272\u6837\u672c", |
|||
"Turquoise": "\u9752\u7eff\u8272", |
|||
"Green": "\u7eff\u8272", |
|||
"Blue": "\u84dd\u8272", |
|||
"Purple": "\u7d2b\u8272", |
|||
"Navy Blue": "\u6d77\u519b\u84dd", |
|||
"Dark Turquoise": "\u6df1\u84dd\u7eff\u8272", |
|||
"Dark Green": "\u6df1\u7eff\u8272", |
|||
"Medium Blue": "\u4e2d\u84dd\u8272", |
|||
"Medium Purple": "\u4e2d\u7d2b\u8272", |
|||
"Midnight Blue": "\u6df1\u84dd\u8272", |
|||
"Yellow": "\u9ec4\u8272", |
|||
"Orange": "\u6a59\u8272", |
|||
"Red": "\u7ea2\u8272", |
|||
"Light Gray": "\u6d45\u7070\u8272", |
|||
"Gray": "\u7070\u8272", |
|||
"Dark Yellow": "\u6697\u9ec4\u8272", |
|||
"Dark Orange": "\u6df1\u6a59\u8272", |
|||
"Dark Red": "\u6df1\u7ea2\u8272", |
|||
"Medium Gray": "\u4e2d\u7070\u8272", |
|||
"Dark Gray": "\u6df1\u7070\u8272", |
|||
"Black": "\u9ed1\u8272", |
|||
"White": "\u767d\u8272", |
|||
"Switch to or from fullscreen mode": "\u5207\u6362\u5168\u5c4f\u6a21\u5f0f", |
|||
"Open help dialog": "\u6253\u5f00\u5e2e\u52a9\u5bf9\u8bdd\u6846", |
|||
"history": "\u5386\u53f2", |
|||
"styles": "\u6837\u5f0f", |
|||
"formatting": "\u683c\u5f0f\u5316", |
|||
"alignment": "\u5bf9\u9f50", |
|||
"indentation": "\u7f29\u8fdb", |
|||
"permanent pen": "\u8bb0\u53f7\u7b14", |
|||
"comments": "\u5907\u6ce8", |
|||
"Anchor": "\u951a\u70b9", |
|||
"Special character": "\u7279\u6b8a\u7b26\u53f7", |
|||
"Code sample": "\u4ee3\u7801\u793a\u4f8b", |
|||
"Color": "\u989c\u8272", |
|||
"Emoticons": "\u8868\u60c5", |
|||
"Document properties": "\u6587\u6863\u5c5e\u6027", |
|||
"Image": "\u56fe\u7247", |
|||
"Insert link": "\u63d2\u5165\u94fe\u63a5", |
|||
"Target": "\u6253\u5f00\u65b9\u5f0f", |
|||
"Link": "\u94fe\u63a5", |
|||
"Poster": "\u5c01\u9762", |
|||
"Media": "\u5a92\u4f53", |
|||
"Print": "\u6253\u5370", |
|||
"Prev": "\u4e0a\u4e00\u4e2a", |
|||
"Find and replace": "\u67e5\u627e\u548c\u66ff\u6362", |
|||
"Whole words": "\u5168\u5b57\u5339\u914d", |
|||
"Spellcheck": "\u62fc\u5199\u68c0\u67e5", |
|||
"Caption": "\u6807\u9898", |
|||
"Insert template": "\u63d2\u5165\u6a21\u677f" |
|||
}); |
|||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -1,5 +1,15 @@ |
|||
<template> |
|||
<div id="app"> |
|||
<router-view/> |
|||
<router-view /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'App', |
|||
created() { |
|||
// 恢复主题 |
|||
this.$store.dispatch('theme/recoverTheme'); |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
@ -0,0 +1,53 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 获取支付笔数数据 |
|||
*/ |
|||
export async function getPayNumList() { |
|||
const res = await axios.get( |
|||
'https://cdn.eleadmin.com/20200610/analysis-pay-num.json' |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 获取销售量数据 |
|||
*/ |
|||
export async function getSaleroomList() { |
|||
const res = await axios.get( |
|||
'https://cdn.eleadmin.com/20200610/analysis-saleroom.json' |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 获取最近1小时访问情况数据 |
|||
*/ |
|||
export async function getVisitHourList() { |
|||
const res = await axios.get( |
|||
'https://cdn.eleadmin.com/20200610/analysis-visits.json' |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 获取词云数据 |
|||
*/ |
|||
export async function getWordCloudList() { |
|||
const res = await axios.get( |
|||
'https://cdn.eleadmin.com/20200610/analysis-hot-search.json' |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
import axios from '@/utils/request'; |
|||
const BASE_URL = process.env.BASE_URL; |
|||
|
|||
/** |
|||
* 获取中国地图geo数据 |
|||
*/ |
|||
export async function getChinaMapData() { |
|||
const res = await axios.get(BASE_URL + 'json/china-provinces.geo.json', { |
|||
baseURL: '' |
|||
}); |
|||
if (res.data) { |
|||
return res.data; |
|||
} |
|||
return Promise.reject(new Error('获取地图数据失败')); |
|||
} |
|||
|
|||
/** |
|||
* 获取用户分布数据 |
|||
*/ |
|||
export async function getUserCountList() { |
|||
const res = await axios.get( |
|||
'https://cdn.eleadmin.com/20200610/monitor-user-count.json' |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 获取用户浏览器分布数据 |
|||
*/ |
|||
export async function getBrowserCountList() { |
|||
const res = await axios.get( |
|||
'https://cdn.eleadmin.com/20200610/monitor-browser-count.json' |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 获取全部的班级数据 |
|||
*/ |
|||
export async function getAllClasses(params) { |
|||
const res = await axios.get( |
|||
'https://cdn.eleadmin.com/20200610/classes.json', |
|||
{ params } |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 获取案卷列表 |
|||
* @param params |
|||
*/ |
|||
export async function getPieceList(params) { |
|||
const res = await axios.get( |
|||
'https://cdn.eleadmin.com/20200610/document.json', |
|||
{ params } |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 获取卷内文件列表 |
|||
* @param params |
|||
*/ |
|||
export async function getArchiveList(params) { |
|||
const res = await axios.get( |
|||
'https://cdn.eleadmin.com/20200610/archive.json', |
|||
{ params } |
|||
); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
import request from '@/utils/request'; |
|||
|
|||
export async function pageUserScores() { |
|||
const res = await request.get( |
|||
'https://cdn.eleadmin.com/20200610/example-table-merge.json' |
|||
); |
|||
if (res.data.code === 0 && res.data.data) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 获取文件列表数据 |
|||
*/ |
|||
export async function getFileList({ directory, sort, order } = {}) { |
|||
const res = await axios.get( |
|||
'https://cdn.eleadmin.com/20200610/extension-files.json', |
|||
{ |
|||
params: { |
|||
directory, |
|||
sort, |
|||
order |
|||
} |
|||
} |
|||
); |
|||
if (res.data.code === 0) { |
|||
// 模拟按文件夹筛选
|
|||
let data = res.data.data; |
|||
if (directory) { |
|||
directory.split('/').forEach((d) => { |
|||
data = data.filter((t) => t.name === d)[0]?.data ?? []; |
|||
}); |
|||
} |
|||
// 模拟排序
|
|||
if (sort) { |
|||
data.sort((a, b) => { |
|||
if (a[sort] == b[sort]) { |
|||
return 0; |
|||
} |
|||
if (order === 'desc') { |
|||
return a[sort] < b[sort] ? 1 : -1; |
|||
} |
|||
return a[sort] < b[sort] ? -1 : 1; |
|||
}); |
|||
} |
|||
data.sort((a, b) => { |
|||
return b.isDirectory ?? false - a.isDirectory ?? false; |
|||
}); |
|||
return data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
/** |
|||
* 获取数据 |
|||
*/ |
|||
export async function queryList() { |
|||
const data = [ |
|||
{ |
|||
key: '1', |
|||
number: '00001', |
|||
name: 'John Brown', |
|||
department: '研发部' |
|||
}, |
|||
{ |
|||
key: '2', |
|||
number: '00002', |
|||
name: 'Jim Green', |
|||
department: '产品部' |
|||
}, |
|||
{ |
|||
key: '3', |
|||
number: '00003', |
|||
name: 'Joe Black', |
|||
department: '产品部' |
|||
} |
|||
]; |
|||
return data; |
|||
} |
|||
@ -0,0 +1,115 @@ |
|||
import request from '@/utils/request'; |
|||
|
|||
/** |
|||
* 获取当前登录的用户信息、菜单、权限、角色 |
|||
*/ |
|||
export async function getUserInfo() { |
|||
const res = await request.get('/auth/user'); |
|||
if (res.data.code === 0 && res.data.data) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 修改当前登录的用户密码 |
|||
*/ |
|||
export async function updatePassword(data) { |
|||
const res = await request.put('/auth/password', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message ?? '修改成功'; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 查询未读通知 |
|||
*/ |
|||
export async function getUnreadNotice() { |
|||
return { |
|||
notice: [ |
|||
{ |
|||
color: '#60B2FC', |
|||
icon: 'el-icon-s-comment', |
|||
title: '你收到了一封14份新周报', |
|||
time: '2020-07-27 18:30:18' |
|||
}, |
|||
{ |
|||
color: '#F5686F', |
|||
icon: 'el-icon-s-check', |
|||
title: '许经理同意了你的请假申请', |
|||
time: '2020-07-27 09:08:36' |
|||
}, |
|||
{ |
|||
color: '#7CD734', |
|||
icon: 'el-icon-video-camera', |
|||
title: '陈总邀请你参加视频会议', |
|||
time: '2020-07-26 18:30:01' |
|||
}, |
|||
{ |
|||
color: '#FAAD14', |
|||
icon: 'el-icon-s-claim', |
|||
title: '你推荐的刘诗雨已通过第三轮面试', |
|||
time: '2020-07-25 16:38:46' |
|||
}, |
|||
{ |
|||
color: '#2BCACD', |
|||
icon: 'el-icon-message-solid', |
|||
title: '你的6月加班奖金已发放', |
|||
time: '2020-07-25 11:03:31' |
|||
} |
|||
], |
|||
letter: [ |
|||
{ |
|||
avatar: |
|||
'https://cdn.eleadmin.com/20200609/c184eef391ae48dba87e3057e70238fb.jpg', |
|||
title: 'SunSmile 评论了你的日志', |
|||
content: '写的不错, 以后多多向你学习~', |
|||
time: '2020-07-27 18:30:18' |
|||
}, |
|||
{ |
|||
avatar: |
|||
'https://cdn.eleadmin.com/20200609/948344a2a77c47a7a7b332fe12ff749a.jpg', |
|||
title: '刘诗雨 点赞了你的日志', |
|||
content: '写的不错, 以后多多向你学习~', |
|||
time: '2020-07-27 09:08:36' |
|||
}, |
|||
{ |
|||
avatar: |
|||
'https://cdn.eleadmin.com/20200609/2d98970a51b34b6b859339c96b240dcd.jpg', |
|||
title: '酷酷的大叔 评论了你的周报', |
|||
content: '写的不错, 以后多多向你学习~', |
|||
time: '2020-07-26 18:30:01' |
|||
}, |
|||
{ |
|||
avatar: |
|||
'https://cdn.eleadmin.com/20200609/f6bc05af944a4f738b54128717952107.jpg', |
|||
title: 'Jasmine 点赞了你的周报', |
|||
content: '写的不错, 以后多多向你学习~', |
|||
time: '2020-07-25 11:03:31' |
|||
} |
|||
], |
|||
todo: [ |
|||
{ |
|||
status: 0, |
|||
title: '刘诗雨的请假审批', |
|||
description: '刘诗雨在 07-27 18:30 提交的请假申请' |
|||
}, |
|||
{ |
|||
status: 1, |
|||
title: '第三方代码紧急变更', |
|||
description: '需要在 2020-07-27 之前完成' |
|||
}, |
|||
{ |
|||
status: 2, |
|||
title: '信息安全考试', |
|||
description: '需要在 2020-07-26 18:30 前完成' |
|||
}, |
|||
{ |
|||
status: 2, |
|||
title: 'EleAdmin发布新版本', |
|||
description: '需要在 2020-07-25 11:03 前完成' |
|||
} |
|||
] |
|||
}; |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 获取列表数据 |
|||
*/ |
|||
export async function queryList(params) { |
|||
const res = await axios.get( |
|||
'https://cdn.eleadmin.com/20200610/list-demo-basic.json', |
|||
{ params } |
|||
); |
|||
if (res.data.code === 0) { |
|||
return { |
|||
list: res.data.data, |
|||
count: res.data.count |
|||
}; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
import axios from '@/utils/request'; |
|||
import { setToken } from '@/utils/token-util'; |
|||
|
|||
/** |
|||
* 登录 |
|||
*/ |
|||
export async function login(data) { |
|||
data.tenantId = 1; // 租户id
|
|||
const res = await axios.post('/login', data); |
|||
if (res.data.code === 0) { |
|||
setToken(res.data.data.access_token, data.remember); |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 获取验证码 |
|||
*/ |
|||
export async function getCaptcha() { |
|||
const res = await axios.get('/captcha'); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 分页查询字典数据 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function pageDictionaryData(params) { |
|||
const res = await axios.get('/system/dictionary-data/page', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 查询字典数据列表 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function listDictionaryData(params) { |
|||
const res = await axios.get('/system/dictionary-data', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 添加字典数据 |
|||
* @param data 字典数据信息 |
|||
*/ |
|||
export async function addDictionaryData(data) { |
|||
const res = await axios.post('/system/dictionary-data', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 修改字典数据 |
|||
* @param data 字典数据信息 |
|||
*/ |
|||
export async function updateDictionaryData(data) { |
|||
const res = await axios.put('/system/dictionary-data', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 删除字典数据 |
|||
* @param id 字典数据id |
|||
*/ |
|||
export async function removeDictionaryData(id) { |
|||
const res = await axios.delete('/system/dictionary-data/' + id); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 批量删除字典数据 |
|||
* @param data 字典数据id集合 |
|||
*/ |
|||
export async function removeDictionaryDataBatch(data) { |
|||
const res = await axios.delete('/system/dictionary-data/batch', { |
|||
data |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 查询字典列表 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function listDictionaries(params) { |
|||
const res = await axios.get('/system/dictionary', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 添加字典 |
|||
* @param data 字典信息 |
|||
*/ |
|||
export async function addDictionary(data) { |
|||
const res = await axios.post('/system/dictionary', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 修改字典 |
|||
* @param data 字典信息 |
|||
*/ |
|||
export async function updateDictionary(data) { |
|||
const res = await axios.put('/system/dictionary', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 删除字典 |
|||
* @param id 字典id |
|||
*/ |
|||
export async function removeDictionary(id) { |
|||
const res = await axios.delete('/system/dictionary/' + id); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 上传文件 |
|||
* @param file 文件 |
|||
*/ |
|||
export async function uploadFile(file) { |
|||
const formData = new FormData(); |
|||
formData.append('file', file); |
|||
const res = await axios.post('/file/upload', formData); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 分页查询文件上传记录 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function pageFiles(params) { |
|||
const res = await axios.get('/file/page', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 分页查询登录日志 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function pageLoginRecords(params) { |
|||
const res = await axios.get('/system/login-record/page', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 查询登录日志列表 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function listLoginRecords(params) { |
|||
const res = await axios.get('/system/login-record', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 查询菜单列表 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function listMenus(params) { |
|||
const res = await axios.get('/system/menu', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 添加菜单 |
|||
* @param data 菜单信息 |
|||
*/ |
|||
export async function addMenu(data) { |
|||
const res = await axios.post('/system/menu', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 修改菜单 |
|||
* @param data 菜单信息 |
|||
*/ |
|||
export async function updateMenu(data) { |
|||
const res = await axios.put('/system/menu', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 删除菜单 |
|||
* @param id 菜单id |
|||
*/ |
|||
export async function removeMenu(id) { |
|||
const res = await axios.delete('/system/menu/' + id); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 分页查询操作日志 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function pageOperationRecords(params) { |
|||
const res = await axios.get('/system/operation-record/page', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 查询操作日志列表 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function listOperationRecords(params) { |
|||
const res = await axios.get('/system/operation-record', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 分页查询机构 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function pageOrganizations(params) { |
|||
const res = await axios.get('/system/organization/page', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 查询机构列表 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function listOrganizations(params) { |
|||
const res = await axios.get('/system/organization', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 添加机构 |
|||
* @param data 机构信息 |
|||
*/ |
|||
export async function addOrganization(data) { |
|||
const res = await axios.post('/system/organization', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 修改机构 |
|||
* @param data 机构信息 |
|||
*/ |
|||
export async function updateOrganization(data) { |
|||
const res = await axios.put('/system/organization', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 删除机构 |
|||
* @param id 机构id |
|||
*/ |
|||
export async function removeOrganization(id) { |
|||
const res = await axios.delete('/system/organization/' + id); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,104 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 分页查询角色 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function pageRoles(params) { |
|||
const res = await axios.get('/system/role/page', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 查询角色列表 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function listRoles(params) { |
|||
const res = await axios.get('/system/role', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 添加角色 |
|||
* @param data 角色信息 |
|||
*/ |
|||
export async function addRole(data) { |
|||
const res = await axios.post('/system/role', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 修改角色 |
|||
* @param data 角色信息 |
|||
*/ |
|||
export async function updateRole(data) { |
|||
const res = await axios.put('/system/role', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 删除角色 |
|||
* @param id 角色id |
|||
*/ |
|||
export async function removeRole(id) { |
|||
const res = await axios.delete('/system/role/' + id); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 批量删除角色 |
|||
* @param ids 角色id集合 |
|||
*/ |
|||
export async function removeRoles(data) { |
|||
const res = await axios.delete('/system/role/batch', { |
|||
data |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 获取角色分配的菜单 |
|||
* @param roleId 角色id |
|||
*/ |
|||
export async function listRoleMenus(roleId) { |
|||
const res = await axios.get('/system/role-menu/' + roleId); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 修改角色菜单 |
|||
* @param roleId 角色id |
|||
* @param data 菜单id集合 |
|||
*/ |
|||
export async function updateRoleMenus(roleId, data) { |
|||
const res = await axios.put('/system/role-menu/' + roleId, data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,154 @@ |
|||
import axios from '@/utils/request'; |
|||
|
|||
/** |
|||
* 分页查询用户 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function pageUsers(params) { |
|||
const res = await axios.get('/system/user/page', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 查询用户列表 |
|||
* @param params 查询条件 |
|||
*/ |
|||
export async function listUsers(params) { |
|||
const res = await axios.get('/system/user', { |
|||
params |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 根据id查询用户 |
|||
* @param id 用户id |
|||
*/ |
|||
export async function getUser(id) { |
|||
const res = await axios.get('/system/user/' + id); |
|||
if (res.data.code === 0) { |
|||
return res.data.data; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 添加用户 |
|||
* @param data 用户信息 |
|||
*/ |
|||
export async function addUser(data) { |
|||
const res = await axios.post('/system/user', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 修改用户 |
|||
* @param data 用户信息 |
|||
*/ |
|||
export async function updateUser(data) { |
|||
const res = await axios.put('/system/user', data); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 删除用户 |
|||
* @param id 用户id |
|||
*/ |
|||
export async function removeUser(id) { |
|||
const res = await axios.delete('/system/user/' + id); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 批量删除用户 |
|||
* @param data 用户id集合 |
|||
*/ |
|||
export async function removeUsers(data) { |
|||
const res = await axios.delete('/system/user/batch', { |
|||
data |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 修改用户状态 |
|||
* @param userId 用户id |
|||
* @param status 状态 |
|||
*/ |
|||
export async function updateUserStatus(userId, status) { |
|||
const res = await axios.put('/system/user/status', { |
|||
userId, |
|||
status |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 重置用户密码 |
|||
* @param userId 用户id |
|||
* @param password 密码 |
|||
* @returns {Promise<string>} |
|||
*/ |
|||
export async function updateUserPassword(userId, password = '123456') { |
|||
const res = await axios.put('/system/user/password', { |
|||
userId, |
|||
password |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 导入用户 |
|||
* @param file excel文件 |
|||
*/ |
|||
export async function importUsers(file) { |
|||
const formData = new FormData(); |
|||
formData.append('file', file); |
|||
const res = await axios.post('/system/user/import', formData); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
|
|||
/** |
|||
* 检查用户是否存在 |
|||
* @param field 检查的字段 |
|||
* @param value 字段的值 |
|||
* @param id 修改时的id |
|||
*/ |
|||
export async function checkExistence(field, value, id) { |
|||
const res = await axios.get('/system/user/existence', { |
|||
params: { field, value, id } |
|||
}); |
|||
if (res.data.code === 0) { |
|||
return res.data.message; |
|||
} |
|||
return Promise.reject(new Error(res.data.message)); |
|||
} |
|||
@ -0,0 +1,223 @@ |
|||
/** |
|||
* 分页查询通知 |
|||
*/ |
|||
export async function pageNotices() { |
|||
return { |
|||
count: 10, |
|||
list: [ |
|||
{ |
|||
id: 21, |
|||
title: 'EleAdmin新版本发布,欢迎体验', |
|||
time: '2020-07-24 11:35', |
|||
status: 0 |
|||
}, |
|||
{ |
|||
id: 22, |
|||
title: 'EleAdmin新版本发布,欢迎体验', |
|||
time: '2020-07-24 11:35', |
|||
status: 0 |
|||
}, |
|||
{ |
|||
id: 23, |
|||
title: 'EleAdmin新版本发布,欢迎体验', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 24, |
|||
title: 'EleAdmin新版本发布,欢迎体验', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 25, |
|||
title: 'EleAdmin新版本发布,欢迎体验', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 26, |
|||
title: 'EleAdmin新版本发布,欢迎体验', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 27, |
|||
title: 'EleAdmin新版本发布,欢迎体验', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 28, |
|||
title: 'EleAdmin新版本发布,欢迎体验', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 29, |
|||
title: 'EleAdmin新版本发布,欢迎体验', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 30, |
|||
title: 'EleAdmin新版本发布,欢迎体验', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
} |
|||
] |
|||
}; |
|||
} |
|||
|
|||
/** |
|||
* 分页查询私信 |
|||
*/ |
|||
export async function pageLetters() { |
|||
return { |
|||
count: 10, |
|||
list: [ |
|||
{ |
|||
id: 11, |
|||
title: 'Jasmine给你发来了一条私信', |
|||
time: '2020-07-24 11:35', |
|||
status: 0 |
|||
}, |
|||
{ |
|||
id: 12, |
|||
title: 'Jasmine给你发来了一条私信', |
|||
time: '2020-07-24 11:35', |
|||
status: 0 |
|||
}, |
|||
{ |
|||
id: 13, |
|||
title: 'Jasmine给你发来了一条私信', |
|||
time: '2020-07-24 11:35', |
|||
status: 0 |
|||
}, |
|||
{ |
|||
id: 14, |
|||
title: 'Jasmine给你发来了一条私信', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 15, |
|||
title: 'Jasmine给你发来了一条私信', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 16, |
|||
title: 'Jasmine给你发来了一条私信', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 17, |
|||
title: 'Jasmine给你发来了一条私信', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 18, |
|||
title: 'Jasmine给你发来了一条私信', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 19, |
|||
title: 'Jasmine给你发来了一条私信', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 20, |
|||
title: 'Jasmine给你发来了一条私信', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
} |
|||
] |
|||
}; |
|||
} |
|||
|
|||
/** |
|||
* 分页查询代办 |
|||
*/ |
|||
export async function pageTodos() { |
|||
return { |
|||
count: 10, |
|||
list: [ |
|||
{ |
|||
id: 1, |
|||
title: '你有两条任务待完成,不要忘了哦~', |
|||
time: '2020-07-24 11:35', |
|||
status: 0 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
title: '你有两条任务待完成,不要忘了哦~', |
|||
time: '2020-07-24 11:35', |
|||
status: 0 |
|||
}, |
|||
{ |
|||
id: 3, |
|||
title: '你有两条任务待完成,不要忘了哦~', |
|||
time: '2020-07-24 11:35', |
|||
status: 0 |
|||
}, |
|||
{ |
|||
id: 4, |
|||
title: '你有两条任务待完成,不要忘了哦~', |
|||
time: '2020-07-24 11:35', |
|||
status: 0 |
|||
}, |
|||
{ |
|||
id: 5, |
|||
title: '你有两条任务待完成,不要忘了哦~', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 6, |
|||
title: '你有两条任务待完成,不要忘了哦~', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 7, |
|||
title: '你有两条任务待完成,不要忘了哦~', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 8, |
|||
title: '你有两条任务待完成,不要忘了哦~', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 9, |
|||
title: '你有两条任务待完成,不要忘了哦~', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
}, |
|||
{ |
|||
id: 10, |
|||
title: '你有两条任务待完成,不要忘了哦~', |
|||
time: '2020-07-24 11:35', |
|||
status: 1 |
|||
} |
|||
] |
|||
}; |
|||
} |
|||
|
|||
/** |
|||
* 查询未读数量 |
|||
*/ |
|||
export async function getUnReadNum() { |
|||
return { |
|||
notice: 2, |
|||
letter: 3, |
|||
todo: 4 |
|||
}; |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
/** 用于刷新的路由组件 */ |
|||
import { setRouteReload } from '@/utils/page-tab-util'; |
|||
|
|||
export default { |
|||
name: 'RedirectLayout', |
|||
created() { |
|||
const { params, query } = this.$route; |
|||
const from = Array.isArray(params.path) |
|||
? params.path.join('/') |
|||
: params.path; |
|||
const path = '/' + from; |
|||
setTimeout(() => { |
|||
setRouteReload(null).then(() => { |
|||
this.$router.replace({ path, query }); |
|||
}); |
|||
}, 100); |
|||
}, |
|||
render(h) { |
|||
return h('div'); |
|||
} |
|||
}; |
|||
@ -0,0 +1,128 @@ |
|||
<!-- 省市区选择组件 --> |
|||
<template> |
|||
<el-cascader |
|||
clearable |
|||
:value="value" |
|||
:options="regionsData" |
|||
:placeholder="placeholder" |
|||
popper-class="ele-pop-wrap-higher" |
|||
:props="props" |
|||
@input="updateValue" |
|||
/> |
|||
</template> |
|||
|
|||
<script> |
|||
import { getRegionsData } from './load-data'; |
|||
|
|||
export default { |
|||
name: 'RegionsSelect', |
|||
props: { |
|||
value: Array, |
|||
placeholder: String, |
|||
options: Array, |
|||
valueField: { |
|||
type: String, |
|||
validator: (val) => { |
|||
return !val || val === 'label'; |
|||
} |
|||
}, |
|||
type: { |
|||
type: String, |
|||
validator: (type) => { |
|||
return !type || ['provinceCity', 'province'].includes(type); |
|||
} |
|||
}, |
|||
props: Object |
|||
}, |
|||
data() { |
|||
return { |
|||
// 级联选择器数据 |
|||
regionsData: [] |
|||
}; |
|||
}, |
|||
methods: { |
|||
// 更新value |
|||
updateValue(value) { |
|||
this.$emit('input', value); |
|||
}, |
|||
// 级联选择器数据value处理 |
|||
formatData(data) { |
|||
if (this.valueField === 'label') { |
|||
return data.map((d) => { |
|||
const item = { |
|||
label: d.label, |
|||
value: d.label |
|||
}; |
|||
if (d.children) { |
|||
item.children = d.children.map((c) => { |
|||
const cItem = { |
|||
label: c.label, |
|||
value: c.label |
|||
}; |
|||
if (c.children) { |
|||
cItem.children = c.children.map((cc) => { |
|||
return { |
|||
label: cc.label, |
|||
value: cc.label |
|||
}; |
|||
}); |
|||
} |
|||
return cItem; |
|||
}); |
|||
} |
|||
return item; |
|||
}); |
|||
} else { |
|||
return data; |
|||
} |
|||
}, |
|||
// 省市区数据筛选 |
|||
filterData(data) { |
|||
if (this.type === 'provinceCity') { |
|||
return this.formatData( |
|||
data.map((d) => { |
|||
const item = { |
|||
label: d.label, |
|||
value: d.value |
|||
}; |
|||
if (d.children) { |
|||
item.children = d.children.map((c) => { |
|||
return { |
|||
label: c.label, |
|||
value: c.value |
|||
}; |
|||
}); |
|||
} |
|||
return item; |
|||
}) |
|||
); |
|||
} else if (this.type === 'province') { |
|||
return this.formatData( |
|||
data.map((d) => { |
|||
return { |
|||
label: d.label, |
|||
value: d.value |
|||
}; |
|||
}) |
|||
); |
|||
} else { |
|||
return this.formatData(data); |
|||
} |
|||
} |
|||
}, |
|||
watch: { |
|||
options: { |
|||
handler(options) { |
|||
this.regionsData = this.filterData(options ?? []); |
|||
if (!options) { |
|||
getRegionsData().then((data) => { |
|||
this.regionsData = this.filterData(data ?? []); |
|||
this.$emit('load-data-done', data); |
|||
}); |
|||
} |
|||
}, |
|||
immediate: true |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
@ -0,0 +1,24 @@ |
|||
import request from '@/utils/request'; |
|||
const BASE_URL = process.env.BASE_URL; |
|||
let reqPromise; |
|||
|
|||
/** |
|||
* 获取省市区数据 |
|||
*/ |
|||
export function getRegionsData() { |
|||
if (!reqPromise) { |
|||
reqPromise = new Promise((resolve, reject) => { |
|||
request |
|||
.get(BASE_URL + 'json/regions-data.json', { |
|||
baseURL: '' |
|||
}) |
|||
.then((res) => { |
|||
resolve(res.data ?? []); |
|||
}) |
|||
.catch((e) => { |
|||
reject(e); |
|||
}); |
|||
}); |
|||
} |
|||
return reqPromise; |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
<!-- router-view 结合 keep-alive 组件 --> |
|||
<template> |
|||
<keep-alive :include="include"> |
|||
<router-view /> |
|||
</keep-alive> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'RouterLayout', |
|||
computed: { |
|||
include() { |
|||
return this.$store.getters['theme/keepAliveInclude'] ?? []; |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
@ -0,0 +1,98 @@ |
|||
<!-- 二维码组件 --> |
|||
<template> |
|||
<div ref="root"></div> |
|||
</template> |
|||
|
|||
<script> |
|||
import QRCode from 'qrcodejs2'; |
|||
|
|||
export default { |
|||
name: 'VueQrCode', |
|||
props: { |
|||
text: String, |
|||
width: { |
|||
type: Number, |
|||
default: 256 |
|||
}, |
|||
height: { |
|||
type: Number, |
|||
default: 256 |
|||
}, |
|||
colorDark: { |
|||
type: String, |
|||
default: '#000000' |
|||
}, |
|||
colorLight: { |
|||
type: String, |
|||
default: '#ffffff' |
|||
}, |
|||
correctLevel: { |
|||
type: Number, |
|||
default: QRCode.CorrectLevel.H |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
instance: undefined |
|||
}; |
|||
}, |
|||
mounted() { |
|||
if (this.text) { |
|||
this.render(); |
|||
} |
|||
}, |
|||
methods: { |
|||
render() { |
|||
this.clear(); |
|||
this.instance = new QRCode(this.getEl(), { |
|||
text: this.text, |
|||
width: this.width, |
|||
height: this.height, |
|||
colorDark: this.colorDark, |
|||
colorLight: this.colorLight, |
|||
correctLevel: this.correctLevel |
|||
}); |
|||
}, |
|||
makeCode(value) { |
|||
if (this.instance) { |
|||
this.instance.makeCode(value); |
|||
} else { |
|||
this.render(); |
|||
} |
|||
}, |
|||
clear() { |
|||
this.instance?.clear(); |
|||
this.instance = undefined; |
|||
this.getEl().innerHTML = ''; |
|||
this.getEl().title = ''; |
|||
}, |
|||
getEl() { |
|||
return this.$refs.root; |
|||
} |
|||
}, |
|||
watch: { |
|||
text(text) { |
|||
if (text) { |
|||
this.makeCode(text); |
|||
} else { |
|||
this.clear(); |
|||
} |
|||
}, |
|||
width() { |
|||
this.render(); |
|||
}, |
|||
height() { |
|||
this.render(); |
|||
}, |
|||
colorDark() { |
|||
this.render(); |
|||
}, |
|||
colorLight() { |
|||
this.render(); |
|||
}, |
|||
correctLevel() { |
|||
this.render(); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
@ -1,79 +0,0 @@ |
|||
/** |
|||
* axios配置 |
|||
*/ |
|||
import Vue from 'vue'; |
|||
import VueAxios from 'vue-axios'; |
|||
import axios from 'axios'; |
|||
import store from '../store'; |
|||
import router from '../router'; |
|||
import setting from './setting'; |
|||
import {MessageBox} from 'element-ui'; |
|||
|
|||
Vue.use(VueAxios, axios); |
|||
|
|||
// 设置统一的url
|
|||
axios.defaults.baseURL = process.env.VUE_APP_API_BASE_URL; |
|||
|
|||
/* 请求拦截器 */ |
|||
axios.interceptors.request.use((config) => { |
|||
// 添加token到header
|
|||
let token = setting.takeToken(); |
|||
if (token) { |
|||
config.headers[setting.tokenHeaderName] = token; |
|||
} |
|||
return config; |
|||
}, function (error) { |
|||
return Promise.reject(error); |
|||
}); |
|||
|
|||
/* 响应拦截器 */ |
|||
axios.interceptors.response.use((res) => { |
|||
// 登录过期处理
|
|||
if (res.data.code === 40512) { |
|||
if (res.config.url === setting.menuUrl) { |
|||
goLogin(); |
|||
} else { |
|||
MessageBox.alert('登录状态已过期, 请退出重新登录!', '系统提示', { |
|||
confirmButtonText: '重新登录', |
|||
callback: (action) => { |
|||
if (action === 'confirm') { |
|||
goLogin(); |
|||
} |
|||
}, |
|||
beforeClose: () => { |
|||
MessageBox.close(); |
|||
} |
|||
}); |
|||
} |
|||
return Promise.reject(new Error(res.data.msg)); |
|||
} |
|||
// token自动续期
|
|||
let access_token = res.headers[setting.tokenHeaderName]; |
|||
if (access_token) { |
|||
setting.cacheToken(access_token); |
|||
} |
|||
return res; |
|||
}, (error) => { |
|||
return Promise.reject(error); |
|||
}); |
|||
|
|||
/** |
|||
* 跳转到登录页面 |
|||
*/ |
|||
function goLogin() { |
|||
store.dispatch('user/removeToken').then(() => { |
|||
const current = router.currentRoute; |
|||
if (current && current.path && current.path !== '/') { |
|||
router.push({ |
|||
path: '/login', |
|||
query: { |
|||
form: current.path |
|||
} |
|||
}).then(() => { |
|||
}); |
|||
} else { |
|||
router.push('/login').then(() => { |
|||
}); |
|||
} |
|||
}); |
|||
} |
|||
@ -1,134 +1,57 @@ |
|||
/** |
|||
* 项目统一配置 |
|||
*/ |
|||
export default { |
|||
// 路由白名单(不需要登录的)
|
|||
whiteList: ['/login', '/forget'], |
|||
// 不显示全局页脚的路由地址
|
|||
hideFooters: ['/system/dictionary', '/system/organization'], |
|||
// 需要缓存的组件名称
|
|||
keepAliveList: [], |
|||
// 菜单数据接口
|
|||
menuUrl: '/manager/permissMenu', |
|||
// 自定义解析接口菜单数据
|
|||
parseMenu: null, |
|||
// 自定义解析接口菜单每一个数据格式
|
|||
parseMenuItem: (item) => { |
|||
if (!item) { |
|||
return; |
|||
} |
|||
item.menuId = item.id; |
|||
item.title = item.name; |
|||
item.parentId = item.parent_id; |
|||
item.menuType = item.menu_type; |
|||
return item; |
|||
}, |
|||
// 直接指定菜单数据
|
|||
menus: null, |
|||
// 用户信息接口
|
|||
userUrl: '/manager/readPersional', |
|||
uploadImageUrl:'http://api.static.ahbmz.com/api/upload', |
|||
// 自定义解析接口用户信息
|
|||
parseUser(res) { |
|||
// 这里code和msg字段如果不一样可在这里修改
|
|||
let result = {code: res.code, msg: res.msg}; |
|||
if (res.data) { |
|||
// 这里只需要姓名和头像两个字段,如需缓存其它字段可在这里添加
|
|||
result.data = { |
|||
nickname: res.data.truename, |
|||
avatar: res.data.avatar |
|||
}; |
|||
// 下面是获取角色和权限列表,需要string数组类型
|
|||
if (res.data.roles) { |
|||
result.data.roles = res.data.roles.map(d => d.role_code); |
|||
} |
|||
if (res.data.authorities) { |
|||
result.data.authorities = res.data.authorities.map(d => d.authority); |
|||
} |
|||
} |
|||
return result; |
|||
}, |
|||
// token传递的header名称
|
|||
tokenHeaderName: 'Token', |
|||
// token存储的名称
|
|||
tokenStoreName: 'access_token', |
|||
// 获取缓存的token
|
|||
takeToken() { |
|||
let token = localStorage.getItem(this.tokenStoreName); |
|||
if (!token) { |
|||
token = sessionStorage.getItem(this.tokenStoreName); |
|||
} |
|||
return token; |
|||
}, |
|||
// 缓存token
|
|||
cacheToken(token, remember) { |
|||
localStorage.removeItem(this.tokenStoreName); |
|||
sessionStorage.removeItem(this.tokenStoreName); |
|||
if (token) { |
|||
if (remember) { |
|||
localStorage.setItem(this.tokenStoreName, token); |
|||
} else { |
|||
sessionStorage.setItem(this.tokenStoreName, token); |
|||
} |
|||
} |
|||
}, |
|||
// 用户信息存储的名称
|
|||
userStoreName: 'user', |
|||
// 获取缓存的用户信息
|
|||
takeUser() { |
|||
try { |
|||
return JSON.parse(localStorage.getItem(this.userStoreName)) || {}; |
|||
} catch (e) { |
|||
console.error(e); |
|||
} |
|||
return {}; |
|||
}, |
|||
// 缓存用户信息
|
|||
cacheUser(user) { |
|||
if (user) { |
|||
localStorage.setItem(this.userStoreName, JSON.stringify(user)); |
|||
} else { |
|||
localStorage.removeItem(this.userStoreName); |
|||
} |
|||
}, |
|||
// 主题配置存储的名称
|
|||
themeStoreName: 'theme', |
|||
// 首页tab显示标题, null会根据菜单自动获取
|
|||
homeTitle: '主页', |
|||
// 首页路径, null会自动获取
|
|||
homePath: null, |
|||
// 顶栏是否显示主题设置按钮
|
|||
showSetting: true, |
|||
// 侧边栏风格: 0亮色, 1暗色
|
|||
sideStyle: 0, |
|||
// 顶栏风格: 0亮色, 1暗色, 2主色
|
|||
headStyle: 2, |
|||
// 标签页风格: 0默认, 1圆点, 2卡片
|
|||
tabStyle: 0, |
|||
// 布局风格: 0默认, 1顶部菜单风格, 2混合菜单风格
|
|||
layoutStyle: 0, |
|||
// 是否固定侧栏
|
|||
fixedSidebar: true, |
|||
// 是否固定顶栏
|
|||
fixedHeader: false, |
|||
// 是否固定主体
|
|||
fixedBody: true, |
|||
// logo是否自适应宽度
|
|||
logoAutoSize: true, |
|||
// 内容区域宽度是否铺满
|
|||
bodyFull: true, |
|||
// 是否开启多标签
|
|||
showTabs: true, |
|||
// 侧栏是否多彩图标
|
|||
colorfulIcon: true, |
|||
// 侧边栏是否只保持一个子菜单展开
|
|||
sideUniqueOpen: true, |
|||
// 是否开启页脚
|
|||
showFooter: true, |
|||
// 是否是色弱模式
|
|||
weakMode: false, |
|||
// 是否是暗黑模式
|
|||
darkMode: false, |
|||
// 默认主题色
|
|||
color: null |
|||
} |
|||
// 接口地址
|
|||
export const API_BASE_URL = process.env.VUE_APP_API_BASE_URL; |
|||
|
|||
// 项目名称
|
|||
export const PROJECT_NAME = process.env.VUE_APP_NAME; |
|||
|
|||
// 不显示侧栏的路由
|
|||
export const HIDE_SIDEBARS = []; |
|||
|
|||
// 不显示页脚的路由
|
|||
export const HIDE_FOOTERS = [ |
|||
'/system/dictionary', |
|||
'/system/organization', |
|||
'/form/advanced', |
|||
'/example/choose' |
|||
]; |
|||
|
|||
// 页签同路由不同参数可重复打开的路由
|
|||
export const REPEATABLE_TABS = ['/system/user-info']; |
|||
|
|||
// 不需要登录的路由
|
|||
export const WHITE_LIST = ['/login', '/forget']; |
|||
|
|||
// 直接指定菜单数据
|
|||
export const USER_MENUS = null; |
|||
|
|||
// 首页名称, 为空则取第一个菜单的名称
|
|||
export const HOME_TITLE = null; |
|||
|
|||
// 首页路径, 为空则取第一个菜单的地址
|
|||
export const HOME_PATH = null; |
|||
|
|||
// 开启多页签是否缓存组件
|
|||
//export const TAB_KEEP_ALIVE = process.env.NODE_ENV !== 'development';
|
|||
export const TAB_KEEP_ALIVE = true; |
|||
|
|||
// token传递的header名称
|
|||
export const TOKEN_HEADER_NAME = 'Authorization'; |
|||
|
|||
// token存储的名称
|
|||
export const TOKEN_STORE_NAME = 'access_token'; |
|||
|
|||
// 主题配置存储的名称
|
|||
export const THEME_STORE_NAME = 'theme'; |
|||
|
|||
// i18n缓存的名称
|
|||
export const I18N_CACHE_NAME = 'i18n-lang'; |
|||
|
|||
// 刷新路由的路由地址
|
|||
export const REDIRECT_PATH = '/redirect'; |
|||
|
|||
// 高德地图key
|
|||
export const MAP_KEY = '006d995d433058322319fa797f2876f5'; |
|||
|
|||
// EleAdmin授权码
|
|||
export const LICENSE_CODE = |
|||
'dk9mcwJyetRWQlxWRiojIqJWdzJCLi4Wam2q5iojI0NWZRqL5Tip5JGr5Aqo5Re656mp5sWY5QmZ6Jyp5t9GZiwiI4+Y5tVGZiojIulWYp1GZhVGbl5ybpJCLi02bj5ibtFGRtEjI6ICZ2JCLiw2cnVkViojIu9WazJXZQfiAjL44SM0NW=='; |
|||
|
|||
@ -0,0 +1,29 @@ |
|||
/** |
|||
* 国际化配置 |
|||
*/ |
|||
import Vue from 'vue'; |
|||
import VueI18n from 'vue-i18n'; |
|||
import eleZhCNLocale from 'ele-admin/es/lang/zh-CN'; |
|||
import eleZhTWLocale from 'ele-admin/es/lang/zh-TW'; |
|||
import eleEnLocale from 'ele-admin/es/lang/en'; |
|||
import zhCNLocale from './lang/zh_CN'; |
|||
import zhTWLocale from './lang/zh_TW'; |
|||
import enLocale from './lang/en'; |
|||
import { I18N_CACHE_NAME } from '@/config/setting'; |
|||
|
|||
Vue.use(VueI18n); |
|||
|
|||
const messages = { |
|||
zh_CN: { ...eleZhCNLocale, ...zhCNLocale }, |
|||
zh_TW: { ...eleZhTWLocale, ...zhTWLocale }, |
|||
en: { ...eleEnLocale, ...enLocale } |
|||
}; |
|||
|
|||
const i18n = new VueI18n({ |
|||
messages: messages, |
|||
silentTranslationWarn: true, |
|||
// 默认语言
|
|||
locale: localStorage.getItem(I18N_CACHE_NAME) || 'zh_CN' |
|||
}); |
|||
|
|||
export default i18n; |
|||
@ -0,0 +1,186 @@ |
|||
/** |
|||
* 英语 |
|||
*/ |
|||
export default { |
|||
// 菜单路由
|
|||
route: { |
|||
dashboard: { |
|||
_name: 'Dashboard', |
|||
workplace: { _name: 'Workplace' }, |
|||
analysis: { _name: 'Analysis' }, |
|||
monitor: { _name: 'Monitor' } |
|||
}, |
|||
system: { |
|||
_name: 'System', |
|||
user: { |
|||
_name: 'User' |
|||
}, |
|||
role: { _name: 'Role' }, |
|||
menu: { _name: 'Menu' }, |
|||
dictionary: { _name: 'Dictionary' }, |
|||
organization: { _name: 'Organization' }, |
|||
loginRecord: { _name: 'LoginRecord' }, |
|||
operationRecord: { _name: 'OperationRecord' }, |
|||
userInfo: { _name: '' } |
|||
}, |
|||
form: { |
|||
_name: 'Form', |
|||
basic: { _name: 'Basic Form' }, |
|||
advanced: { _name: 'Advanced Form' }, |
|||
step: { _name: 'Step Form' } |
|||
}, |
|||
list: { |
|||
_name: 'List', |
|||
basic: { _name: 'Basic List' }, |
|||
advanced: { _name: 'Advanced List' }, |
|||
card: { |
|||
_name: 'Card List', |
|||
project: { _name: 'Project' }, |
|||
application: { _name: 'Application' }, |
|||
article: { _name: 'Article' } |
|||
} |
|||
}, |
|||
result: { |
|||
_name: 'Result', |
|||
success: { _name: 'Success' }, |
|||
fail: { _name: 'Fail' } |
|||
}, |
|||
exception: { |
|||
_name: 'Exception', |
|||
403: { _name: '403' }, |
|||
404: { _name: '404' }, |
|||
500: { _name: '500' } |
|||
}, |
|||
user: { |
|||
_name: 'User', |
|||
profile: { _name: 'Profile' }, |
|||
message: { _name: 'Message' } |
|||
}, |
|||
extension: { |
|||
_name: 'Extension', |
|||
icon: { _name: 'Icon' }, |
|||
file: { _name: 'File' }, |
|||
printer: { _name: 'Printer' }, |
|||
excel: { _name: 'Excel' }, |
|||
dragsort: { _name: 'DragSort' }, |
|||
message: { _name: 'Message' }, |
|||
map: { _name: 'Map' }, |
|||
player: { _name: 'Player' }, |
|||
editor: { _name: 'Editor' }, |
|||
tag: { _name: 'Tags' }, |
|||
colorPicker: { _name: 'ColorPicker' }, |
|||
regions: { _name: 'CitySelect' }, |
|||
countUp: { _name: 'CountUp' }, |
|||
empty: { _name: 'Empty' }, |
|||
steps: { _name: 'Steps' }, |
|||
menu: { _name: 'Menu' }, |
|||
treeSelect: { _name: 'TreeSelect' }, |
|||
tableSelect: { _name: 'TableSelect' }, |
|||
qrCode: { _name: 'QRCode' }, |
|||
dialog: { _name: 'DragDialog' } |
|||
}, |
|||
example: { |
|||
_name: 'Example', |
|||
table: { _name: 'ProTable' }, |
|||
menuBadge: { _name: 'MenuBadge' }, |
|||
document: { _name: 'Document' }, |
|||
choose: { _name: 'Choose' }, |
|||
eleadmin: { _name: 'IFrame' } |
|||
}, |
|||
'https://eleadminCom/goods/8': { _name: 'Authorization' } |
|||
}, |
|||
// 主框架
|
|||
layout: { |
|||
home: 'Home', |
|||
header: { |
|||
profile: 'Profile', |
|||
password: 'Password', |
|||
logout: 'SignOut' |
|||
}, |
|||
footer: { |
|||
website: 'Website', |
|||
document: 'Document', |
|||
authorization: 'Authorization', |
|||
copyright: 'Copyright © 2022 Wuhan EClouds Technology Co., Ltd' |
|||
}, |
|||
logout: { |
|||
title: 'Confirm', |
|||
message: 'Are you sure you want to log out?' |
|||
}, |
|||
setting: { |
|||
title: 'Theme Setting', |
|||
sideStyles: { |
|||
dark: 'Dark Sidebar', |
|||
light: 'Light Sidebar' |
|||
}, |
|||
headStyles: { |
|||
light: 'Light Header', |
|||
dark: 'Dark Header', |
|||
primary: 'Primary Header' |
|||
}, |
|||
layoutStyles: { |
|||
side: 'Side Menu Layout', |
|||
top: 'Top Menu Layout', |
|||
mix: 'Mix Menu Layout' |
|||
}, |
|||
colors: { |
|||
default: 'Daybreak Blue', |
|||
dust: 'Dust Blue', |
|||
sunset: 'Sunset Orange', |
|||
volcano: 'Volcano', |
|||
purple: 'Golden Purple', |
|||
cyan: 'Cyan', |
|||
green: 'Polar Green', |
|||
geekblue: 'Geek Blue' |
|||
}, |
|||
darkMode: 'Dark Mode', |
|||
layoutStyle: 'Navigation Mode', |
|||
sideMenuStyle: 'Sidebar Double Menu', |
|||
bodyFull: 'Body Fullscreen', |
|||
other: 'Other Setting', |
|||
fixedHeader: 'Fixed Header', |
|||
fixedSidebar: 'Fixed Sidebar', |
|||
fixedBody: 'Fixed Body', |
|||
logoAutoSize: 'Logo Adaptation', |
|||
colorfulIcon: 'Colorful Icon', |
|||
sideUniqueOpen: 'Menu Unique Open', |
|||
weakMode: 'Weak Mode', |
|||
showFooter: 'Show Footer', |
|||
showTabs: 'Show Tabs', |
|||
tabStyle: 'Tab Style', |
|||
tabStyles: { |
|||
default: 'Default', |
|||
dot: 'Dot', |
|||
card: 'Card' |
|||
}, |
|||
reset: 'Reset', |
|||
tips: 'It will remember your configuration the next time you open it.' |
|||
} |
|||
}, |
|||
// 登录界面
|
|||
login: { |
|||
title: 'User Login', |
|||
username: 'please input username', |
|||
password: 'please input password', |
|||
code: 'please input code', |
|||
remember: 'remember', |
|||
forget: 'forget', |
|||
login: 'login', |
|||
loading: 'loading' |
|||
}, |
|||
// 基础列表
|
|||
list: { |
|||
basic: { |
|||
table: { |
|||
username: 'Username', |
|||
nickname: 'Nickname', |
|||
organizationName: 'OrganizationName', |
|||
phone: 'Phone', |
|||
sexName: 'SexName', |
|||
createTime: 'CreateTime', |
|||
status: 'Status', |
|||
action: 'Action' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,187 @@ |
|||
/** |
|||
* 简体中文 |
|||
*/ |
|||
export default { |
|||
// 菜单路由
|
|||
route: { |
|||
dashboard: { |
|||
_name: 'Dashboard', |
|||
workplace: { _name: '工作台' }, |
|||
analysis: { _name: '分析页' }, |
|||
monitor: { _name: '监控页' } |
|||
}, |
|||
system: { |
|||
_name: '系统管理', |
|||
user: { |
|||
_name: '用户管理' |
|||
}, |
|||
role: { _name: '角色管理' }, |
|||
menu: { _name: '菜单管理' }, |
|||
dictionary: { _name: '字典管理' }, |
|||
organization: { _name: '机构管理' }, |
|||
loginRecord: { _name: '登录日志' }, |
|||
operationRecord: { _name: '操作日志' }, |
|||
userInfo: { _name: '' } |
|||
}, |
|||
form: { |
|||
_name: '表单页面', |
|||
basic: { _name: '基础表单' }, |
|||
advanced: { _name: '复杂表单' }, |
|||
step: { _name: '分步表单' } |
|||
}, |
|||
list: { |
|||
_name: '列表页面', |
|||
basic: { _name: '基础列表' }, |
|||
advanced: { _name: '复杂列表' }, |
|||
card: { |
|||
_name: '卡片列表', |
|||
project: { _name: '项目列表' }, |
|||
application: { _name: '应用列表' }, |
|||
article: { _name: '文章列表' } |
|||
} |
|||
}, |
|||
result: { |
|||
_name: '结果页面', |
|||
success: { _name: '成功页' }, |
|||
fail: { _name: '失败页' } |
|||
}, |
|||
exception: { |
|||
_name: '异常页面', |
|||
403: { _name: '403' }, |
|||
404: { _name: '404' }, |
|||
500: { _name: '500' } |
|||
}, |
|||
user: { |
|||
_name: '个人中心', |
|||
profile: { _name: '个人资料' }, |
|||
message: { _name: '我的消息' } |
|||
}, |
|||
extension: { |
|||
_name: '扩展组件', |
|||
icon: { _name: '图标扩展' }, |
|||
file: { _name: '文件列表' }, |
|||
printer: { _name: '打印插件' }, |
|||
excel: { _name: 'excel插件' }, |
|||
dragsort: { _name: '拖拽排序' }, |
|||
message: { _name: '消息提示' }, |
|||
map: { _name: '地图组件' }, |
|||
player: { _name: '视频播放' }, |
|||
editor: { _name: '富文本框' }, |
|||
tag: { _name: '标签组件' }, |
|||
colorPicker: { _name: '颜色选择' }, |
|||
regions: { _name: '城市选择' }, |
|||
countUp: { _name: '滚动数字' }, |
|||
empty: { _name: '空状态' }, |
|||
steps: { _name: '步骤条' }, |
|||
menu: { _name: '菜单导航' }, |
|||
treeSelect: { _name: '树形下拉' }, |
|||
tableSelect: { _name: '表格下拉' }, |
|||
qrCode: { _name: '二维码' }, |
|||
dialog: { _name: '拖拽弹窗' } |
|||
}, |
|||
example: { |
|||
_name: '常用实例', |
|||
table: { _name: '表格实例' }, |
|||
menuBadge: { _name: '菜单徽章' }, |
|||
document: { _name: '案卷调整' }, |
|||
choose: { _name: '批量选择' }, |
|||
eleadmin: { _name: '内嵌页面' } |
|||
}, |
|||
'https://eleadminCom/goods/8': { _name: '获取授权' } |
|||
}, |
|||
// 外层布局
|
|||
layout: { |
|||
home: '主页', |
|||
header: { |
|||
profile: '个人中心', |
|||
password: '修改密码', |
|||
logout: '退出登录' |
|||
}, |
|||
footer: { |
|||
website: '官网', |
|||
document: '文档', |
|||
authorization: '授权', |
|||
copyright: 'Copyright © 2022 武汉易云智科技有限公司' |
|||
}, |
|||
logout: { |
|||
title: '提示', |
|||
message: '确定要退出登录吗?' |
|||
}, |
|||
// 设置抽屉
|
|||
setting: { |
|||
title: '整体风格设置', |
|||
sideStyles: { |
|||
dark: '暗色侧边栏', |
|||
light: '亮色侧边栏' |
|||
}, |
|||
headStyles: { |
|||
light: '亮色顶栏', |
|||
dark: '暗色顶栏', |
|||
primary: '主色顶栏' |
|||
}, |
|||
layoutStyles: { |
|||
side: '左侧菜单布局', |
|||
top: '顶部菜单布局', |
|||
mix: '混合菜单布局' |
|||
}, |
|||
colors: { |
|||
default: '拂晓蓝', |
|||
dust: '薄暮', |
|||
sunset: '日暮', |
|||
volcano: '火山', |
|||
purple: '酱紫', |
|||
cyan: '明青', |
|||
green: '极光绿', |
|||
geekblue: '极客蓝' |
|||
}, |
|||
darkMode: '开启暗黑模式', |
|||
layoutStyle: '导航模式', |
|||
sideMenuStyle: '侧栏双排菜单', |
|||
bodyFull: '内容区域铺满', |
|||
other: '其它配置', |
|||
fixedHeader: '固定顶栏区域', |
|||
fixedSidebar: '固定侧栏区域', |
|||
fixedBody: '固定主体区域', |
|||
logoAutoSize: 'Logo宽度自动', |
|||
colorfulIcon: '侧栏彩色图标', |
|||
sideUniqueOpen: '侧栏排他展开', |
|||
weakMode: '开启色弱模式', |
|||
showFooter: '开启全局页脚', |
|||
showTabs: '开启多页签栏', |
|||
tabStyle: '页签显示风格', |
|||
tabStyles: { |
|||
default: '默认', |
|||
dot: '圆点', |
|||
card: '卡片' |
|||
}, |
|||
reset: '重置', |
|||
tips: '该功能可实时预览各种布局效果, 修改后会缓存在本地, 下次打开会记忆主题配置.' |
|||
} |
|||
}, |
|||
// 登录界面
|
|||
login: { |
|||
title: '用户登录', |
|||
username: '请输入登录账号', |
|||
password: '请输入登录密码', |
|||
code: '请输入验证码', |
|||
remember: '记住密码', |
|||
forget: '忘记密码', |
|||
login: '登录', |
|||
loading: '登录中' |
|||
}, |
|||
// 基础列表
|
|||
list: { |
|||
basic: { |
|||
table: { |
|||
username: '用户账号', |
|||
nickname: '用户名', |
|||
organizationName: '组织机构', |
|||
phone: '手机号', |
|||
sexName: '性别', |
|||
createTime: '创建时间', |
|||
status: '状态', |
|||
action: '操作' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,186 @@ |
|||
/** |
|||
* 繁体中文 |
|||
*/ |
|||
export default { |
|||
// 菜单路由
|
|||
route: { |
|||
dashboard: { |
|||
_name: 'Dashboard', |
|||
workplace: { _name: '工作臺' }, |
|||
analysis: { _name: '分析頁' }, |
|||
monitor: { _name: '監控頁' } |
|||
}, |
|||
system: { |
|||
_name: '系統管理', |
|||
user: { |
|||
_name: '用戶管理' |
|||
}, |
|||
role: { _name: '角色管理' }, |
|||
menu: { _name: '選單管理' }, |
|||
dictionary: { _name: '字典管理' }, |
|||
organization: { _name: '機构管理' }, |
|||
loginRecord: { _name: '登入日誌' }, |
|||
operationRecord: { _name: '操作日誌' }, |
|||
userInfo: { _name: '' } |
|||
}, |
|||
form: { |
|||
_name: '表單頁面', |
|||
basic: { _name: '基礎表單' }, |
|||
advanced: { _name: '複雜表單' }, |
|||
step: { _name: '分步表單' } |
|||
}, |
|||
list: { |
|||
_name: '清單頁面', |
|||
basic: { _name: '基礎清單' }, |
|||
advanced: { _name: '複雜清單' }, |
|||
card: { |
|||
_name: '卡片清單', |
|||
project: { _name: '項目清單' }, |
|||
application: { _name: '應用清單' }, |
|||
article: { _name: '文章清單' } |
|||
} |
|||
}, |
|||
result: { |
|||
_name: '結果頁面', |
|||
success: { _name: '成功頁' }, |
|||
fail: { _name: '失敗頁' } |
|||
}, |
|||
exception: { |
|||
_name: '异常頁面', |
|||
403: { _name: '403' }, |
|||
404: { _name: '404' }, |
|||
500: { _name: '500' } |
|||
}, |
|||
user: { |
|||
_name: '個人中心', |
|||
profile: { _name: '個人資料' }, |
|||
message: { _name: '我的消息' } |
|||
}, |
|||
extension: { |
|||
_name: '擴展組件', |
|||
icon: { _name: '圖標擴展' }, |
|||
file: { _name: '檔案清單' }, |
|||
printer: { _name: '列印挿件' }, |
|||
excel: { _name: 'excel挿件' }, |
|||
dragsort: { _name: '拖拽排序' }, |
|||
message: { _name: '消息提示' }, |
|||
map: { _name: '地圖組件' }, |
|||
player: { _name: '視頻播放' }, |
|||
editor: { _name: '富文本框' }, |
|||
tag: { _name: '標籤組件' }, |
|||
colorPicker: { _name: '顏色選擇' }, |
|||
regions: { _name: '城市選擇' }, |
|||
countUp: { _name: '滾動數字' }, |
|||
empty: { _name: '空狀態' }, |
|||
steps: { _name: '步驟條' }, |
|||
menu: { _name: '菜單導航' }, |
|||
treeSelect: { _name: '樹形下拉' }, |
|||
tableSelect: { _name: '表格下拉' }, |
|||
qrCode: { _name: '二維碼' }, |
|||
dialog: { _name: '拖拽彈窗' } |
|||
}, |
|||
example: { |
|||
_name: '常用實例', |
|||
table: { _name: '表格實例' }, |
|||
menuBadge: { _name: '菜單徽章' }, |
|||
document: { _name: '案卷調整' }, |
|||
choose: { _name: '批量選擇' }, |
|||
eleadmin: { _name: '內嵌頁面' } |
|||
}, |
|||
'https://eleadminCom/goods/8': { _name: '獲取授權' } |
|||
}, |
|||
// 主框架
|
|||
layout: { |
|||
home: '主頁', |
|||
header: { |
|||
profile: '個人中心', |
|||
password: '修改密碼', |
|||
logout: '安全登出' |
|||
}, |
|||
footer: { |
|||
website: '官網', |
|||
document: '檔案', |
|||
authorization: '授權', |
|||
copyright: 'Copyright © 2022 武漢易雲智科技有限公司' |
|||
}, |
|||
logout: { |
|||
title: '詢問', |
|||
message: '確定要登出嗎?' |
|||
}, |
|||
setting: { |
|||
title: '整體風格設定', |
|||
sideStyles: { |
|||
dark: '暗色側邊欄', |
|||
light: '亮色側邊欄' |
|||
}, |
|||
headStyles: { |
|||
light: '亮色頂欄', |
|||
dark: '暗色頂欄', |
|||
primary: '主色頂欄' |
|||
}, |
|||
layoutStyles: { |
|||
side: '左側選單佈局', |
|||
top: '頂部選單佈局', |
|||
mix: '混合選單佈局' |
|||
}, |
|||
colors: { |
|||
default: '拂曉藍', |
|||
dust: '薄暮', |
|||
sunset: '日暮', |
|||
volcano: '火山', |
|||
purple: '醬紫', |
|||
cyan: '明青', |
|||
green: '極光綠', |
|||
geekblue: '極客藍' |
|||
}, |
|||
darkMode: '開啟暗黑模式', |
|||
layoutStyle: '導航模式', |
|||
sideMenuStyle: '側欄雙排選單', |
|||
bodyFull: '內容區域鋪滿', |
|||
other: '其它配寘', |
|||
fixedHeader: '固定頂欄區域', |
|||
fixedSidebar: '固定側欄區域', |
|||
fixedBody: '固定主體區域', |
|||
logoAutoSize: 'Logo寬度自動', |
|||
colorfulIcon: '側欄彩色圖標', |
|||
sideUniqueOpen: '側欄排他展開', |
|||
weakMode: '開啟色弱模式', |
|||
showFooter: '開啟全域頁腳', |
|||
showTabs: '開啟多頁簽欄', |
|||
tabStyle: '頁簽顯示風格', |
|||
tabStyles: { |
|||
default: '默認', |
|||
dot: '圓點', |
|||
card: '卡片' |
|||
}, |
|||
reset: '重置', |
|||
tips: '該功能可實时預覽各種佈局效果,修改後會緩存在本地,下次打開會記憶主題配寘.' |
|||
} |
|||
}, |
|||
// 登录界面
|
|||
login: { |
|||
title: '用戶登錄', |
|||
username: '請輸入登入帳號', |
|||
password: '請輸入登入密碼', |
|||
code: '請輸入驗證碼', |
|||
remember: '記住密碼', |
|||
forget: '忘記密碼', |
|||
login: '登入', |
|||
loading: '登入中' |
|||
}, |
|||
// 基础列表
|
|||
list: { |
|||
basic: { |
|||
table: { |
|||
username: '用戶賬號', |
|||
nickname: '用戶名', |
|||
organizationName: '組織機構', |
|||
phone: '手機號', |
|||
sexName: '性別', |
|||
createTime: '創建時間', |
|||
status: '狀態', |
|||
action: '操作' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,278 @@ |
|||
<!-- 顶栏消息通知 --> |
|||
<template> |
|||
<el-popover |
|||
:width="330" |
|||
trigger="click" |
|||
v-model="visible" |
|||
class="ele-notice-group" |
|||
transition="el-zoom-in-top" |
|||
popper-class="ele-notice-pop" |
|||
> |
|||
<div slot="reference" class="ele-notice-group"> |
|||
<el-badge :value="unreadNum" :hidden="!unreadNum"> |
|||
<i class="el-icon-bell"></i> |
|||
</el-badge> |
|||
</div> |
|||
<el-tabs v-model="active"> |
|||
<el-tab-pane name="notice" :label="noticeTitle"> |
|||
<div class="ele-notice-list ele-scrollbar-mini"> |
|||
<div |
|||
v-for="(item, index) in notice" |
|||
:key="index" |
|||
class="ele-notice-item" |
|||
> |
|||
<div class="ele-cell ele-notice-item-wrapper"> |
|||
<i :class="[item.icon, 'ele-notice-item-icon']"></i> |
|||
<div class="ele-cell-content"> |
|||
<div class="ele-elip">{{ item.title }}</div> |
|||
<div class="ele-text-secondary ele-elip">{{ item.time }}</div> |
|||
</div> |
|||
</div> |
|||
<el-divider /> |
|||
</div> |
|||
</div> |
|||
<div v-if="notice.length" class="ele-cell ele-notice-actions"> |
|||
<div class="ele-cell-content" @click="clearNotice">清空通知</div> |
|||
<el-divider direction="vertical" class="line-color-light" /> |
|||
<router-link to="/user/message?type=notice" class="ele-cell-content"> |
|||
查看更多 |
|||
</router-link> |
|||
</div> |
|||
<ele-empty v-if="!notice.length" text="已查看所有通知" /> |
|||
</el-tab-pane> |
|||
<el-tab-pane name="letter" :label="letterTitle"> |
|||
<div class="ele-notice-list ele-scrollbar-mini"> |
|||
<div |
|||
v-for="(item, index) in letter" |
|||
:key="index" |
|||
class="ele-notice-item" |
|||
> |
|||
<div class="ele-cell ele-notice-item-wrapper ele-cell-align-top"> |
|||
<el-avatar :src="item.avatar" size="medium" /> |
|||
<div class="ele-cell-content"> |
|||
<div class="ele-elip">{{ item.title }}</div> |
|||
<div class="ele-text-secondary ele-elip"> |
|||
{{ item.content }} |
|||
</div> |
|||
<div class="ele-cell-desc ele-elip">{{ item.time }}</div> |
|||
</div> |
|||
</div> |
|||
<el-divider /> |
|||
</div> |
|||
</div> |
|||
<div v-if="letter.length" class="ele-cell ele-notice-actions"> |
|||
<div class="ele-cell-content" @click="clearLetter">清空私信</div> |
|||
<el-divider direction="vertical" class="line-color-light" /> |
|||
<router-link to="/user/message?type=letter" class="ele-cell-content"> |
|||
查看更多 |
|||
</router-link> |
|||
</div> |
|||
<ele-empty v-if="!letter.length" text="已读完所有私信" /> |
|||
</el-tab-pane> |
|||
<el-tab-pane :label="todoTitle" name="todo"> |
|||
<div class="ele-notice-list ele-scrollbar-mini"> |
|||
<div |
|||
v-for="(item, index) in todo" |
|||
:key="index" |
|||
class="ele-notice-item" |
|||
> |
|||
<div class="ele-notice-item-wrapper"> |
|||
<div class="ele-cell ele-cell-align-top"> |
|||
<div class="ele-cell-content ele-elip">{{ item.title }}</div> |
|||
<el-tag size="mini" :type="['info', 'danger', ''][item.status]"> |
|||
{{ ['未开始', '即将到期', '进行中'][item.status] }} |
|||
</el-tag> |
|||
</div> |
|||
<div class="ele-text-secondary ele-elip"> |
|||
{{ item.description }} |
|||
</div> |
|||
</div> |
|||
<el-divider /> |
|||
</div> |
|||
</div> |
|||
<div v-if="todo.length" class="ele-cell ele-notice-actions"> |
|||
<div class="ele-cell-content" @click="clearTodo">清空待办</div> |
|||
<el-divider direction="vertical" class="line-color-light" /> |
|||
<router-link to="/user/message?type=todo" class="ele-cell-content"> |
|||
查看更多 |
|||
</router-link> |
|||
</div> |
|||
<ele-empty v-if="!todo.length" text="已完成所有任务" /> |
|||
</el-tab-pane> |
|||
</el-tabs> |
|||
</el-popover> |
|||
</template> |
|||
|
|||
<script> |
|||
import { getUnreadNotice } from '@/api/layout'; |
|||
|
|||
export default { |
|||
name: 'HeaderNotice', |
|||
data() { |
|||
return { |
|||
// 是否显示 |
|||
visible: false, |
|||
// 选项卡选中 |
|||
active: 'notice', |
|||
// 通知数据 |
|||
notice: [], |
|||
// 私信数据 |
|||
letter: [], |
|||
// 待办数据 |
|||
todo: [] |
|||
}; |
|||
}, |
|||
computed: { |
|||
// 通知标题 |
|||
noticeTitle() { |
|||
return '通知' + (this.notice.length ? `(${this.notice.length})` : ''); |
|||
}, |
|||
// 私信标题 |
|||
letterTitle() { |
|||
return '私信' + (this.letter.length ? `(${this.letter.length})` : ''); |
|||
}, |
|||
// 待办标题 |
|||
todoTitle() { |
|||
return '待办' + (this.todo.length ? `(${this.todo.length})` : ''); |
|||
}, |
|||
// 未读数量 |
|||
unreadNum() { |
|||
return this.notice.length + this.letter.length + this.todo.length; |
|||
} |
|||
}, |
|||
created() { |
|||
this.query(); |
|||
}, |
|||
methods: { |
|||
/* 查询数据 */ |
|||
query() { |
|||
getUnreadNotice() |
|||
.then((result) => { |
|||
this.notice = result.notice; |
|||
this.letter = result.letter; |
|||
this.todo = result.todo; |
|||
}) |
|||
.catch((e) => { |
|||
this.$message.error(e.message); |
|||
}); |
|||
}, |
|||
/* 清空通知 */ |
|||
clearNotice() { |
|||
this.notice = []; |
|||
}, |
|||
/* 清空通知 */ |
|||
clearLetter() { |
|||
this.letter = []; |
|||
}, |
|||
/* 清空通知 */ |
|||
clearTodo() { |
|||
this.todo = []; |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.ele-notice-group { |
|||
display: block; |
|||
|
|||
.el-badge { |
|||
line-height: 1; |
|||
display: block; |
|||
} |
|||
} |
|||
|
|||
/* 消息通知pop */ |
|||
.ele-notice-pop { |
|||
padding: 0 !important; |
|||
|
|||
/* tab */ |
|||
.el-tabs__nav-scroll { |
|||
text-align: center; |
|||
} |
|||
|
|||
.el-tabs__nav { |
|||
float: none; |
|||
display: inline-block; |
|||
} |
|||
|
|||
.el-tabs__item { |
|||
height: 44px; |
|||
line-height: 44px; |
|||
padding: 0 20px !important; |
|||
} |
|||
|
|||
/* 空视图 */ |
|||
.ele-empty { |
|||
padding: 100px 0; |
|||
} |
|||
} |
|||
|
|||
/* 列表 */ |
|||
.ele-notice-list { |
|||
padding-top: 8px; |
|||
max-height: 360px; |
|||
overflow: auto; |
|||
} |
|||
|
|||
.ele-notice-item { |
|||
.ele-notice-item-wrapper { |
|||
padding: 12px 15px; |
|||
transition: background-color 0.2s; |
|||
cursor: pointer; |
|||
|
|||
&:hover { |
|||
background-color: hsla(0, 0%, 60%, 0.05); |
|||
} |
|||
} |
|||
|
|||
.ele-text-secondary { |
|||
margin-top: 5px; |
|||
font-size: 13px; |
|||
} |
|||
|
|||
.ele-cell-desc { |
|||
margin-top: 3px !important; |
|||
font-size: 12px !important; |
|||
} |
|||
} |
|||
|
|||
.ele-notice-item-icon { |
|||
width: 32px; |
|||
height: 32px; |
|||
line-height: 32px !important; |
|||
color: #fff; |
|||
font-size: 16px; |
|||
background-color: #60b2fc; |
|||
border-radius: 50%; |
|||
text-align: center; |
|||
|
|||
&.el-icon-s-check { |
|||
background-color: #f5686f; |
|||
} |
|||
|
|||
&.el-icon-video-camera { |
|||
background-color: #7cd734; |
|||
} |
|||
|
|||
&.el-icon-s-claim { |
|||
background-color: #faad14; |
|||
} |
|||
|
|||
&.el-icon-message-solid { |
|||
background-color: #2bcacd; |
|||
} |
|||
} |
|||
|
|||
/* 操作按钮 */ |
|||
.ele-notice-actions > .ele-cell-content { |
|||
line-height: 42px; |
|||
text-align: center; |
|||
cursor: pointer; |
|||
color: inherit; |
|||
|
|||
&:hover { |
|||
background-color: hsla(0, 0%, 60%, 0.05); |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,144 @@ |
|||
<!-- 顶栏右侧区域 --> |
|||
<template> |
|||
<div class="ele-admin-header-tool"> |
|||
<!-- 全屏切换 --> |
|||
<div |
|||
class="ele-admin-header-tool-item hidden-xs-only" |
|||
@click="toggleFullscreen" |
|||
> |
|||
<i v-if="fullscreen" class="el-icon-_screen-restore"></i> |
|||
<i v-else class="el-icon-_screen-full"></i> |
|||
</div> |
|||
<!-- 语言切换 --> |
|||
<div class="ele-admin-header-tool-item"> |
|||
<el-dropdown placement="bottom" @command="changeLanguage"> |
|||
<i class="el-icon-_language"></i> |
|||
<el-dropdown-menu slot="dropdown"> |
|||
<el-dropdown-item command="en"> |
|||
<span :class="{ 'ele-text-primary': language === 'en' }"> |
|||
English |
|||
</span> |
|||
</el-dropdown-item> |
|||
<el-dropdown-item command="zh_CN"> |
|||
<span :class="{ 'ele-text-primary': language === 'zh_CN' }"> |
|||
简体中文 |
|||
</span> |
|||
</el-dropdown-item> |
|||
<el-dropdown-item command="zh_TW"> |
|||
<span :class="{ 'ele-text-primary': language === 'zh_TW' }"> |
|||
繁體中文 |
|||
</span> |
|||
</el-dropdown-item> |
|||
</el-dropdown-menu> |
|||
</el-dropdown> |
|||
</div> |
|||
<!-- 消息通知 --> |
|||
<div class="ele-admin-header-tool-item"> |
|||
<header-notice /> |
|||
</div> |
|||
<!-- 用户信息 --> |
|||
<div class="ele-admin-header-tool-item"> |
|||
<el-dropdown @command="onUserDropClick"> |
|||
<div class="ele-admin-header-avatar"> |
|||
<el-avatar :src="loginUser.avatar" /> |
|||
<span class="hidden-xs-only">{{ loginUser.nickname }}</span> |
|||
<i class="el-icon-arrow-down"></i> |
|||
</div> |
|||
<el-dropdown-menu slot="dropdown"> |
|||
<el-dropdown-item command="profile" icon="el-icon-user"> |
|||
{{ $t('layout.header.profile') }} |
|||
</el-dropdown-item> |
|||
<el-dropdown-item command="password" icon="el-icon-key"> |
|||
{{ $t('layout.header.password') }} |
|||
</el-dropdown-item> |
|||
<el-dropdown-item |
|||
command="logout" |
|||
icon="el-icon-switch-button" |
|||
divided |
|||
> |
|||
{{ $t('layout.header.logout') }} |
|||
</el-dropdown-item> |
|||
</el-dropdown-menu> |
|||
</el-dropdown> |
|||
</div> |
|||
<!-- 主题设置 --> |
|||
<div class="ele-admin-header-tool-item" @click="openSetting"> |
|||
<i class="el-icon-_more"></i> |
|||
</div> |
|||
<!-- 修改密码弹窗 --> |
|||
<password-modal :visible.sync="passwordVisible" /> |
|||
<!-- 主题设置抽屉 --> |
|||
<setting-drawer :visible.sync="settingVisible" /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import HeaderNotice from './header-notice.vue'; |
|||
import PasswordModal from './password-modal.vue'; |
|||
import SettingDrawer from './setting-drawer.vue'; |
|||
import { logout } from '@/utils/page-tab-util'; |
|||
import { I18N_CACHE_NAME } from '@/config/setting'; |
|||
|
|||
export default { |
|||
name: 'HeaderTools', |
|||
components: { HeaderNotice, PasswordModal, SettingDrawer }, |
|||
props: { |
|||
// 是否是全屏 |
|||
fullscreen: Boolean |
|||
}, |
|||
data() { |
|||
return { |
|||
// 是否显示修改密码弹窗 |
|||
passwordVisible: false, |
|||
// 是否显示主题设置抽屉 |
|||
settingVisible: false |
|||
}; |
|||
}, |
|||
computed: { |
|||
// 当前用户信息 |
|||
loginUser() { |
|||
return this.$store.state.user.info; |
|||
}, |
|||
// 当前显示语言 |
|||
language() { |
|||
return this.$i18n.locale; |
|||
} |
|||
}, |
|||
methods: { |
|||
/* 用户信息下拉点击事件 */ |
|||
onUserDropClick(command) { |
|||
if (command === 'password') { |
|||
this.passwordVisible = true; |
|||
} else if (command === 'profile') { |
|||
if (this.$route.fullPath !== '/user/profile') { |
|||
this.$router.push('/user/profile'); |
|||
} |
|||
} else if (command === 'logout') { |
|||
// 退出登录 |
|||
this.$confirm( |
|||
this.$t('layout.logout.message'), |
|||
this.$t('layout.logout.title'), |
|||
{ type: 'warning' } |
|||
) |
|||
.then(() => { |
|||
logout(); |
|||
}) |
|||
.catch(() => {}); |
|||
} |
|||
}, |
|||
/* 全屏切换 */ |
|||
toggleFullscreen() { |
|||
this.$emit('fullscreen'); |
|||
}, |
|||
/* 打开设置抽屉 */ |
|||
openSetting() { |
|||
this.settingVisible = true; |
|||
}, |
|||
/* 切换语言 */ |
|||
changeLanguage(key) { |
|||
this.$i18n.locale = key; |
|||
localStorage.setItem(I18N_CACHE_NAME, key); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
@ -0,0 +1,35 @@ |
|||
<!-- 全局页脚 --> |
|||
<template> |
|||
<div class="ele-text-center" style="padding: 16px 0"> |
|||
<div> |
|||
<a target="_blank" class="ele-text-secondary" href="https://eleadmin.com"> |
|||
{{ $t('layout.footer.website') }} |
|||
</a> |
|||
<em></em> |
|||
<a |
|||
target="_blank" |
|||
class="ele-text-secondary" |
|||
href="https://eleadmin.com/doc/eleadmin/" |
|||
> |
|||
{{ $t('layout.footer.document') }} |
|||
</a> |
|||
<em></em> |
|||
<a |
|||
target="_blank" |
|||
class="ele-text-secondary" |
|||
href="https://eleadmin.com/goods/8" |
|||
> |
|||
{{ $t('layout.footer.authorization') }} |
|||
</a> |
|||
</div> |
|||
<div class="ele-text-secondary" style="margin-top: 8px"> |
|||
{{ $t('layout.footer.copyright') }} |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'PageFooter' |
|||
}; |
|||
</script> |
|||
@ -0,0 +1,137 @@ |
|||
<!-- 修改密码弹窗 --> |
|||
<template> |
|||
<ele-modal |
|||
width="420px" |
|||
title="修改密码" |
|||
:visible="visible" |
|||
:append-to-body="true" |
|||
:close-on-click-modal="true" |
|||
@update:visible="updateVisible" |
|||
@closed="onClose" |
|||
> |
|||
<el-form |
|||
ref="form" |
|||
:model="form" |
|||
:rules="rules" |
|||
label-width="82px" |
|||
@keyup.enter.native="save" |
|||
> |
|||
<el-form-item label="旧密码:" prop="oldPassword"> |
|||
<el-input |
|||
show-password |
|||
v-model="form.oldPassword" |
|||
placeholder="请输入旧密码" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item label="新密码:" prop="password"> |
|||
<el-input |
|||
show-password |
|||
v-model="form.password" |
|||
placeholder="请输入新密码" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item label="确认密码:" prop="password2"> |
|||
<el-input |
|||
show-password |
|||
v-model="form.password2" |
|||
placeholder="请再次输入新密码" |
|||
/> |
|||
</el-form-item> |
|||
</el-form> |
|||
<div slot="footer"> |
|||
<el-button @click="updateVisible(false)">取消</el-button> |
|||
<el-button type="primary" @click="save">确定</el-button> |
|||
</div> |
|||
</ele-modal> |
|||
</template> |
|||
|
|||
<script> |
|||
import { updatePassword } from '@/api/layout'; |
|||
|
|||
export default { |
|||
name: 'PasswordModal', |
|||
props: { |
|||
visible: Boolean |
|||
}, |
|||
data() { |
|||
return { |
|||
// 按钮loading |
|||
loading: false, |
|||
// 表单数据 |
|||
form: { |
|||
oldPassword: '', |
|||
password: '', |
|||
password2: '' |
|||
}, |
|||
// 表单验证 |
|||
rules: { |
|||
oldPassword: [ |
|||
{ |
|||
required: true, |
|||
message: '请输入旧密码', |
|||
trigger: 'blur' |
|||
} |
|||
], |
|||
password: [ |
|||
{ |
|||
required: true, |
|||
message: '请输入新密码', |
|||
trigger: 'blur' |
|||
} |
|||
], |
|||
password2: [ |
|||
{ |
|||
required: true, |
|||
trigger: 'blur', |
|||
validator: (_rule, value, callback) => { |
|||
if (!value) { |
|||
return callback(new Error('请再次输入新密码')); |
|||
} |
|||
if (value !== this.form.password) { |
|||
return callback(new Error('两次输入密码不一致')); |
|||
} |
|||
callback(); |
|||
} |
|||
} |
|||
] |
|||
} |
|||
}; |
|||
}, |
|||
methods: { |
|||
/* 修改visible */ |
|||
updateVisible(value) { |
|||
this.$emit('update:visible', value); |
|||
}, |
|||
/* 保存修改 */ |
|||
save() { |
|||
this.$refs['form'].validate((valid) => { |
|||
if (valid) { |
|||
this.loading = true; |
|||
updatePassword(this.form) |
|||
.then((msg) => { |
|||
this.loading = false; |
|||
this.$message.success(msg); |
|||
this.updateVisible(false); |
|||
}) |
|||
.catch((e) => { |
|||
this.loading = false; |
|||
this.$message.error(e.message); |
|||
}); |
|||
} else { |
|||
return false; |
|||
} |
|||
}); |
|||
}, |
|||
/* 关闭回调 */ |
|||
onClose() { |
|||
this.form = { |
|||
oldPassword: '', |
|||
password: '', |
|||
password2: '' |
|||
}; |
|||
this.$refs['form'].resetFields(); |
|||
this.loading = false; |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
@ -0,0 +1,627 @@ |
|||
<!-- 主题设置抽屉 --> |
|||
<template> |
|||
<el-drawer |
|||
size="300px" |
|||
:visible="visible" |
|||
:append-to-body="true" |
|||
:title="$t('layout.setting.title')" |
|||
@update:visible="updateVisible" |
|||
> |
|||
<div |
|||
:class="['ele-setting-wrapper', { 'ele-setting-dark': theme.darkMode }]" |
|||
> |
|||
<!-- 侧栏风格 --> |
|||
<div class="ele-setting-theme ele-text-primary"> |
|||
<el-tooltip |
|||
:content="$t('layout.setting.sideStyles.dark')" |
|||
placement="top" |
|||
> |
|||
<div |
|||
class="ele-bg-base ele-side-dark" |
|||
@click="updateSideStyle('dark')" |
|||
> |
|||
<i class="el-icon-check" v-if="theme.sideStyle === 'dark'"></i> |
|||
</div> |
|||
</el-tooltip> |
|||
<el-tooltip |
|||
:content="$t('layout.setting.sideStyles.light')" |
|||
placement="top" |
|||
> |
|||
<div class="ele-bg-base" @click="updateSideStyle('light')"> |
|||
<i class="el-icon-check" v-if="theme.sideStyle === 'light'"></i> |
|||
</div> |
|||
</el-tooltip> |
|||
</div> |
|||
<!-- 顶栏风格 --> |
|||
<div class="ele-setting-theme ele-text-primary"> |
|||
<el-tooltip |
|||
:content="$t('layout.setting.headStyles.light')" |
|||
placement="top" |
|||
> |
|||
<div |
|||
class="ele-bg-base ele-head-light" |
|||
@click="updateHeadStyle('light')" |
|||
> |
|||
<i class="el-icon-check" v-if="theme.headStyle === 'light'"></i> |
|||
</div> |
|||
</el-tooltip> |
|||
<el-tooltip |
|||
:content="$t('layout.setting.headStyles.dark')" |
|||
placement="top" |
|||
> |
|||
<div |
|||
class="ele-bg-base ele-head-dark" |
|||
@click="updateHeadStyle('dark')" |
|||
> |
|||
<i class="el-icon-check" v-if="theme.headStyle === 'dark'"></i> |
|||
</div> |
|||
</el-tooltip> |
|||
<el-tooltip |
|||
:content="$t('layout.setting.headStyles.primary')" |
|||
placement="top" |
|||
> |
|||
<div |
|||
class="ele-bg-base ele-head-primary" |
|||
@click="updateHeadStyle('primary')" |
|||
> |
|||
<div class="ele-bg-primary"></div> |
|||
<i class="el-icon-check" v-if="theme.headStyle === 'primary'"></i> |
|||
</div> |
|||
</el-tooltip> |
|||
</div> |
|||
<!-- 主题色 --> |
|||
<div class="ele-setting-colors"> |
|||
<el-tooltip |
|||
v-for="item in themes" |
|||
:key="item.name" |
|||
:content="$t('layout.setting.colors.' + item.name)" |
|||
placement="top" |
|||
> |
|||
<div |
|||
class="ele-setting-color-item" |
|||
:style="{ 'background-color': item.color || item.value }" |
|||
@click="updateColor(item.value)" |
|||
> |
|||
<i |
|||
class="el-icon-check" |
|||
v-if="item.value ? item.value === theme.color : !theme.color" |
|||
> |
|||
</i> |
|||
</div> |
|||
</el-tooltip> |
|||
<!-- 颜色选择器 --> |
|||
<el-color-picker |
|||
v-model="colorValue" |
|||
:predefine="predefineColors" |
|||
class="ele-setting-color-picker" |
|||
@change="updateColor" |
|||
/> |
|||
</div> |
|||
<!-- 暗黑模式 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.darkMode') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-switch :value="theme.darkMode" @change="updateDarkMode" /> |
|||
</div> |
|||
</div> |
|||
<el-divider /> |
|||
<!-- 导航布局 --> |
|||
<div class="ele-setting-title ele-text-secondary"> |
|||
{{ $t('layout.setting.layoutStyle') }} |
|||
</div> |
|||
<div class="ele-setting-theme ele-text-primary"> |
|||
<el-tooltip |
|||
:content="$t('layout.setting.layoutStyles.side')" |
|||
placement="top" |
|||
> |
|||
<div |
|||
class="ele-bg-base ele-side-dark" |
|||
@click="updateLayoutStyle('side')" |
|||
> |
|||
<i class="el-icon-check" v-if="theme.layoutStyle === 'side'"></i> |
|||
</div> |
|||
</el-tooltip> |
|||
<el-tooltip |
|||
:content="$t('layout.setting.layoutStyles.top')" |
|||
placement="top" |
|||
> |
|||
<div |
|||
class="ele-bg-base ele-head-dark" |
|||
@click="updateLayoutStyle('top')" |
|||
> |
|||
<i class="el-icon-check" v-if="theme.layoutStyle === 'top'"></i> |
|||
</div> |
|||
</el-tooltip> |
|||
<el-tooltip |
|||
:content="$t('layout.setting.layoutStyles.mix')" |
|||
placement="top" |
|||
> |
|||
<div |
|||
class="ele-bg-base ele-layout-mix" |
|||
@click="updateLayoutStyle('mix')" |
|||
> |
|||
<i class="el-icon-check" v-if="theme.layoutStyle === 'mix'"></i> |
|||
</div> |
|||
</el-tooltip> |
|||
</div> |
|||
<!-- 侧栏菜单布局 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.sideMenuStyle') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-switch |
|||
:value="theme.sideMenuStyle === 'mix'" |
|||
@change="updateSideMenuStyle" |
|||
/> |
|||
</div> |
|||
</div> |
|||
<!-- 内容区域铺满 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.bodyFull') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-switch :value="theme.bodyFull" @change="updateBodyFull" /> |
|||
</div> |
|||
</div> |
|||
<el-divider /> |
|||
<div class="ele-setting-title ele-text-secondary"> |
|||
{{ $t('layout.setting.other') }} |
|||
</div> |
|||
<!-- 固定顶栏 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.fixedHeader') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-switch :value="theme.fixedHeader" @change="updateFixedHeader" /> |
|||
</div> |
|||
</div> |
|||
<!-- 固定侧栏 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.fixedSidebar') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-switch :value="theme.fixedSidebar" @change="updateFixedSidebar" /> |
|||
</div> |
|||
</div> |
|||
<!-- 固定主体 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.fixedBody') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-switch :value="theme.fixedBody" @change="updateFixedBody" /> |
|||
</div> |
|||
</div> |
|||
<!-- LOGO自适应宽度 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.logoAutoSize') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-switch :value="theme.logoAutoSize" @change="updateLogoAutoSize" /> |
|||
</div> |
|||
</div> |
|||
<!-- 侧栏彩色图标 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.colorfulIcon') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-switch :value="theme.colorfulIcon" @change="updateColorfulIcon" /> |
|||
</div> |
|||
</div> |
|||
<!-- 侧栏排他展开 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.sideUniqueOpen') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-switch |
|||
:value="theme.sideUniqueOpen" |
|||
@change="updateSideUniqueOpen" |
|||
/> |
|||
</div> |
|||
</div> |
|||
<!-- 全局页脚 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.showFooter') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-switch :value="theme.showFooter" @change="updateShowFooter" /> |
|||
</div> |
|||
</div> |
|||
<!-- 色弱模式 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.weakMode') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-switch :value="theme.weakMode" @change="updateWeakMode" /> |
|||
</div> |
|||
</div> |
|||
<!-- 页签 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.showTabs') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-switch :value="theme.showTabs" @change="updateShowTabs" /> |
|||
</div> |
|||
</div> |
|||
<!-- 页签风格 --> |
|||
<div class="ele-setting-item"> |
|||
<div class="setting-item-title"> |
|||
{{ $t('layout.setting.tabStyle') }} |
|||
</div> |
|||
<div class="setting-item-control"> |
|||
<el-select |
|||
size="mini" |
|||
:value="theme.tabStyle" |
|||
@change="updateTabStyle" |
|||
> |
|||
<el-option |
|||
:label="$t('layout.setting.tabStyles.default')" |
|||
value="default" |
|||
/> |
|||
<el-option |
|||
:label="$t('layout.setting.tabStyles.dot')" |
|||
value="dot" |
|||
/> |
|||
<el-option |
|||
:label="$t('layout.setting.tabStyles.card')" |
|||
value="card" |
|||
/> |
|||
</el-select> |
|||
</div> |
|||
</div> |
|||
<el-divider /> |
|||
<!-- 提示 --> |
|||
<el-alert |
|||
type="warning" |
|||
:closable="false" |
|||
class="ele-alert-border" |
|||
:title="$t('layout.setting.tips')" |
|||
/> |
|||
<!-- 重置 --> |
|||
<div class="ele-setting-button-group"> |
|||
<el-button |
|||
size="small" |
|||
class="ele-fluid" |
|||
icon="el-icon-refresh-left" |
|||
@click="resetSetting" |
|||
> |
|||
{{ $t('layout.setting.reset') }} |
|||
</el-button> |
|||
</div> |
|||
</div> |
|||
</el-drawer> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapGetters } from 'vuex'; |
|||
import { messageLoading } from 'ele-admin'; |
|||
// 主题列表 |
|||
const themes = [ |
|||
{ |
|||
name: 'default', |
|||
color: '#1890ff' |
|||
}, |
|||
{ |
|||
name: 'dust', |
|||
value: '#5f80c7' |
|||
}, |
|||
{ |
|||
name: 'sunset', |
|||
value: '#faad14' |
|||
}, |
|||
{ |
|||
name: 'volcano', |
|||
value: '#f5686f' |
|||
}, |
|||
{ |
|||
name: 'purple', |
|||
value: '#9266f9' |
|||
}, |
|||
{ |
|||
name: 'green', |
|||
value: '#33cc99' |
|||
}, |
|||
{ |
|||
name: 'geekblue', |
|||
value: '#32a2d4' |
|||
} |
|||
]; |
|||
// 颜色选择器预设颜色 |
|||
const predefineColors = [ |
|||
'#f5222d', |
|||
'#fa541c', |
|||
'#fa8c16', |
|||
'#faad14', |
|||
'#a0d911', |
|||
'#52c41a', |
|||
'#13c2c2', |
|||
'#2f54eb', |
|||
'#722ed1', |
|||
'#eb2f96' |
|||
]; |
|||
|
|||
export default { |
|||
name: 'SettingDrawer', |
|||
props: { |
|||
// 是否显示, 支持.sync修饰 |
|||
visible: Boolean |
|||
}, |
|||
data() { |
|||
const color = this.$store.state.theme.color; |
|||
// 颜色选择器选中颜色 |
|||
const colorValue = |
|||
color && !themes.some((t) => t.value === color) ? color : undefined; |
|||
return { |
|||
themes, |
|||
predefineColors, |
|||
colorValue |
|||
}; |
|||
}, |
|||
computed: { |
|||
...mapGetters(['theme']) |
|||
}, |
|||
methods: { |
|||
updateVisible(value) { |
|||
this.$emit('update:visible', value); |
|||
}, |
|||
updateShowTabs(value) { |
|||
this.$store.dispatch('theme/setShowTabs', value); |
|||
}, |
|||
updateShowFooter(value) { |
|||
this.$store.dispatch('theme/setShowFooter', value); |
|||
}, |
|||
updateHeadStyle(value) { |
|||
this.$store.dispatch('theme/setHeadStyle', value); |
|||
}, |
|||
updateSideStyle(value) { |
|||
this.$store.dispatch('theme/setSideStyle', value); |
|||
}, |
|||
updateLayoutStyle(value) { |
|||
this.$store.dispatch('theme/setLayoutStyle', value); |
|||
}, |
|||
updateSideMenuStyle(value) { |
|||
this.$store.dispatch( |
|||
'theme/setSideMenuStyle', |
|||
value ? 'mix' : 'default' |
|||
); |
|||
}, |
|||
updateTabStyle(value) { |
|||
this.$store.dispatch('theme/setTabStyle', value); |
|||
}, |
|||
updateFixedHeader(value) { |
|||
this.$store.dispatch('theme/setFixedHeader', value); |
|||
}, |
|||
updateFixedSidebar(value) { |
|||
this.$store.dispatch('theme/setFixedSidebar', value); |
|||
}, |
|||
updateFixedBody(value) { |
|||
this.$store.dispatch('theme/setFixedBody', value); |
|||
}, |
|||
updateBodyFull(value) { |
|||
this.$store.dispatch('theme/setBodyFull', value); |
|||
}, |
|||
updateLogoAutoSize(value) { |
|||
this.$store.dispatch('theme/setLogoAutoSize', value); |
|||
}, |
|||
updateColorfulIcon(value) { |
|||
this.$store.dispatch('theme/setColorfulIcon', value); |
|||
}, |
|||
updateSideUniqueOpen(value) { |
|||
this.$store.dispatch('theme/setSideUniqueOpen', value); |
|||
}, |
|||
updateWeakMode(value) { |
|||
this.$store.dispatch('theme/setWeakMode', value); |
|||
}, |
|||
updateDarkMode(value) { |
|||
this.doWithLoading(() => |
|||
this.$store.dispatch('theme/setDarkMode', value) |
|||
); |
|||
}, |
|||
updateColor(value) { |
|||
this.colorValue = undefined; |
|||
this.doWithLoading(() => this.$store.dispatch('theme/setColor', value)); |
|||
}, |
|||
resetSetting() { |
|||
this.doWithLoading(() => this.$store.dispatch('theme/resetSetting')); |
|||
}, |
|||
doWithLoading(fun) { |
|||
const loading = messageLoading('正在加载主题..'); |
|||
fun() |
|||
.then(() => { |
|||
loading.close(); |
|||
}) |
|||
.catch((e) => { |
|||
loading.close(); |
|||
console.error(e); |
|||
this.$message.error('主题加载失败'); |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.ele-setting-wrapper { |
|||
padding: 20px 18px; |
|||
|
|||
.ele-setting-title { |
|||
font-size: 13px; |
|||
margin-bottom: 15px; |
|||
} |
|||
|
|||
/* 主题风格 */ |
|||
.ele-setting-theme > div { |
|||
width: 52px; |
|||
height: 36px; |
|||
line-height: 1; |
|||
font-size: 18px; |
|||
border-radius: 3px; |
|||
margin: 0 20px 30px 0; |
|||
padding: 14px 0 0 24px; |
|||
box-sizing: border-box; |
|||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15); |
|||
display: inline-block; |
|||
vertical-align: top; |
|||
position: relative; |
|||
overflow: hidden; |
|||
cursor: pointer; |
|||
transition: background-color 0.2s; |
|||
|
|||
&:before, |
|||
&:after, |
|||
& > .ele-bg-primary { |
|||
content: ''; |
|||
width: 100%; |
|||
height: 10px; |
|||
background: #fff; |
|||
position: absolute; |
|||
left: 0; |
|||
top: 0; |
|||
transition: background-color 0.2s; |
|||
} |
|||
|
|||
&:after { |
|||
width: 14px; |
|||
height: 100%; |
|||
} |
|||
|
|||
&.ele-side-dark:after, |
|||
&.ele-head-dark:before, |
|||
&.ele-layout-mix:before, |
|||
&.ele-layout-mix:after { |
|||
background: #001529; |
|||
} |
|||
|
|||
&.ele-head-light:before, |
|||
&.ele-head-dark:before, |
|||
& > .ele-bg-primary { |
|||
z-index: 1; |
|||
} |
|||
} |
|||
|
|||
/* 主题色选择 */ |
|||
.ele-setting-colors { |
|||
color: #fff; |
|||
margin-bottom: 20px; |
|||
|
|||
.ele-setting-color-item { |
|||
width: 20px; |
|||
height: 20px; |
|||
line-height: 22px; |
|||
border-radius: 2px; |
|||
margin: 8px 8px 0 0; |
|||
display: inline-block; |
|||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15); |
|||
vertical-align: top; |
|||
position: relative; |
|||
text-align: center; |
|||
cursor: pointer; |
|||
} |
|||
} |
|||
|
|||
/* 主题配置项 */ |
|||
.ele-setting-item { |
|||
display: flex; |
|||
align-items: center; |
|||
margin-bottom: 20px; |
|||
|
|||
.setting-item-title { |
|||
flex: 1; |
|||
line-height: 28px; |
|||
} |
|||
|
|||
.setting-item-control { |
|||
line-height: 1; |
|||
max-width: 95px; |
|||
} |
|||
} |
|||
|
|||
.el-divider { |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.el-alert + .ele-setting-button-group { |
|||
margin-top: 15px; |
|||
} |
|||
} |
|||
|
|||
/* 适配暗黑模式 */ |
|||
.ele-setting-dark .ele-setting-theme > div { |
|||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.55); |
|||
|
|||
&:before, |
|||
&:after, |
|||
& > .ele-bg-primary { |
|||
background: #1f1f1f; |
|||
} |
|||
|
|||
&.ele-side-dark:after, |
|||
&.ele-head-dark:before, |
|||
&.ele-layout-mix:before, |
|||
&.ele-layout-mix:after { |
|||
background: #262626; |
|||
} |
|||
} |
|||
|
|||
/* 颜色选择器 */ |
|||
.ele-setting-color-picker.el-color-picker { |
|||
height: auto; |
|||
margin-top: 8px; |
|||
|
|||
.el-color-picker__trigger { |
|||
padding: 0; |
|||
width: 20px; |
|||
height: 20px; |
|||
border: none; |
|||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15); |
|||
} |
|||
|
|||
.el-color-picker__color { |
|||
border: none; |
|||
} |
|||
|
|||
.el-color-picker__color-inner { |
|||
border-radius: 2px; |
|||
} |
|||
|
|||
.el-color-picker__empty { |
|||
background: conic-gradient( |
|||
from 90deg at 50% 50%, |
|||
rgb(255, 0, 0) -19.41deg, |
|||
rgb(255, 0, 0) 18.76deg, |
|||
rgb(255, 138, 0) 59.32deg, |
|||
rgb(255, 230, 0) 99.87deg, |
|||
rgb(20, 255, 0) 141.65deg, |
|||
rgb(0, 163, 255) 177.72deg, |
|||
rgb(5, 0, 255) 220.23deg, |
|||
rgb(173, 0, 255) 260.13deg, |
|||
rgb(255, 0, 199) 300.69deg, |
|||
rgb(255, 0, 0) 340.59deg, |
|||
rgb(255, 0, 0) 378.76deg |
|||
); |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
transform: none; |
|||
border-radius: 2px; |
|||
font-size: 0; |
|||
} |
|||
|
|||
.el-color-picker__icon { |
|||
font-size: 14px; |
|||
} |
|||
} |
|||
</style> |
|||
@ -1,33 +0,0 @@ |
|||
<!-- 页脚 --> |
|||
<template> |
|||
<div class="ele-text-center" style="padding: 16px 0;"> |
|||
<div> |
|||
<a |
|||
class="ele-text-secondary" |
|||
href="https://eleadmin.com" |
|||
target="_blank">官网 |
|||
</a> |
|||
<em/> |
|||
<a |
|||
class="ele-text-secondary" |
|||
href="https://eleadmin.com/doc/eleadmin/" |
|||
target="_blank">文档 |
|||
</a> |
|||
<em/> |
|||
<a |
|||
class="ele-text-secondary" |
|||
href="https://eleadmin.com/goods/8" |
|||
target="_blank">授权 |
|||
</a> |
|||
</div> |
|||
<div class="ele-text-secondary" style="margin-top: 8px;"> |
|||
Copyright © 2021 武汉易云智科技有限公司 |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'EleFooter' |
|||
} |
|||
</script> |
|||
@ -1,111 +0,0 @@ |
|||
<!-- 顶栏右侧区域按钮 --> |
|||
<template> |
|||
<div class="ele-admin-header-tool"> |
|||
<div |
|||
class="ele-admin-header-tool-item" |
|||
@click="toggleFullscreen"> |
|||
<i :class="isFullscreen?'el-icon-_screen-restore':'el-icon-_screen-full'"></i> |
|||
</div> |
|||
<!-- 消息通知 --> |
|||
<div class="ele-admin-header-tool-item"> |
|||
<ele-notice/> |
|||
</div> |
|||
<!-- 用户信息 --> |
|||
<div class="ele-admin-header-tool-item"> |
|||
<el-dropdown @command="onUserDropClick"> |
|||
<div class="ele-admin-header-avatar"> |
|||
<el-avatar :src="loginUser.avatar"/> |
|||
<span>{{ loginUser.nickname }}</span> |
|||
<i class="el-icon-arrow-down"></i> |
|||
</div> |
|||
<el-dropdown-menu slot="dropdown"> |
|||
<el-dropdown-item |
|||
command="user" |
|||
icon="el-icon-user">个人中心 |
|||
</el-dropdown-item> |
|||
<el-dropdown-item |
|||
command="password" |
|||
icon="el-icon-key">修改密码 |
|||
</el-dropdown-item> |
|||
<el-dropdown-item |
|||
command="logout" |
|||
icon="el-icon-switch-button" |
|||
divided>退出登录 |
|||
</el-dropdown-item> |
|||
</el-dropdown-menu> |
|||
</el-dropdown> |
|||
</div> |
|||
<!-- 主题设置 --> |
|||
<div |
|||
class="ele-admin-header-tool-item" |
|||
v-if="showSetting" |
|||
@click="openSetting"> |
|||
<i class="el-icon-_more"></i> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import EleNotice from './notice'; |
|||
|
|||
export default { |
|||
name: 'EleHeaderRight', |
|||
components: {EleNotice}, |
|||
props: { |
|||
// 是否显示打开设置抽屉按钮 |
|||
showSetting: { |
|||
type: Boolean, |
|||
default: true |
|||
} |
|||
}, |
|||
computed: { |
|||
// 当前登录用户信息 |
|||
loginUser() { |
|||
return this.$store.state.user.user; |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
// 是否全屏状态 |
|||
isFullscreen: false |
|||
}; |
|||
}, |
|||
methods: { |
|||
/* 个人信息下拉菜单点击 */ |
|||
onUserDropClick(command) { |
|||
if (command === 'user') { |
|||
if (this.$route.fullPath !== '/user/info') { |
|||
this.$router.push('/user/info'); |
|||
} |
|||
} else if (command === 'password') { |
|||
this.$emit('item-click', 'password'); |
|||
} else if (command === 'logout') { |
|||
// 退出登录 |
|||
this.$confirm( |
|||
'确定要退出登录吗?', |
|||
'提示', |
|||
{type: 'warning'} |
|||
).then(() => { |
|||
// 清除缓存的token |
|||
this.$store.dispatch('user/setToken').then(() => { |
|||
location.replace('/'); |
|||
}); |
|||
}).catch(() => { |
|||
}); |
|||
} |
|||
}, |
|||
/* 打开设置抽屉 */ |
|||
openSetting() { |
|||
this.$emit('item-click', 'setting'); |
|||
}, |
|||
/* 全屏切换 */ |
|||
toggleFullscreen() { |
|||
try { |
|||
this.isFullscreen = this.$util.toggleFullscreen(); |
|||
} catch (e) { |
|||
this.$message.error('您的浏览器不支持全屏模式'); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
@ -1,189 +1,262 @@ |
|||
<!-- 框架布局 --> |
|||
<template> |
|||
<ele-pro-layout |
|||
:menus="menus" |
|||
:tabs="theme.tabs" |
|||
:collapse="theme.collapse" |
|||
:side-nav-collapse="theme.sideNavCollapse" |
|||
:body-fullscreen="theme.bodyFullscreen" |
|||
:show-tabs="theme.showTabs" |
|||
:show-footer="theme.showFooter" |
|||
:head-style="theme.headStyle" |
|||
:side-style="theme.sideStyle" |
|||
:layout-style="theme.layoutStyle" |
|||
:side-menu-style="theme.sideMenuStyle" |
|||
:tab-style="theme.tabStyle" |
|||
:fixed-header="theme.fixedHeader" |
|||
:fixed-sidebar="theme.fixedSidebar" |
|||
:fixed-body="theme.fixedBody" |
|||
:layout-style="theme.layoutStyle" |
|||
:head-style="theme.headStyle" |
|||
:side-style="theme.sideStyle" |
|||
:body-full="theme.bodyFull" |
|||
:logo-auto-size="theme.logoAutoSize" |
|||
:colorful-icon="theme.colorfulIcon" |
|||
:side-unique-open="theme.sideUniqueOpen" |
|||
:show-tabs="theme.showTabs" |
|||
:tab-style="theme.tabStyle" |
|||
:body-full="theme.bodyFull" |
|||
:keep-alive-list="keepAliveList" |
|||
:project-name="PROJECT_NAME" |
|||
:hide-footers="HIDE_FOOTERS" |
|||
:hide-sidebars="HIDE_SIDEBARS" |
|||
:repeatable-tabs="REPEATABLE_TABS" |
|||
:home-title="homeTitle" |
|||
:project-name="projectName" |
|||
:tabs="user.tabs" |
|||
:menus="user.menus" |
|||
:need-setting="needSetting" |
|||
:show-setting.sync="showSetting" |
|||
:color="theme.color" |
|||
:dark-mode="theme.darkMode" |
|||
:weak-mode="theme.weakMode" |
|||
:show-content="showContent" |
|||
@update-collapse="updateCollapse" |
|||
@update-screen="updateScreen" |
|||
@tab-add="tabAdd" |
|||
@tab-remove="tabRemove" |
|||
@tab-remove-left="tabRemoveLeft" |
|||
@tab-remove-right="tabRemoveRight" |
|||
@tab-remove-other="tabRemoveOther" |
|||
@tab-remove-all="tabRemoveAll" |
|||
@change-color="changeColor" |
|||
@change-style="changeStyle"> |
|||
:locale="locale" |
|||
:i18n="i18n" |
|||
@update:collapse="updateCollapse" |
|||
@update:side-nav-collapse="updateSideNavCollapse" |
|||
@update:body-fullscreen="updateBodyFullscreen" |
|||
@tab-add="addPageTab" |
|||
@tab-remove="removePageTab" |
|||
@tab-remove-all="removeAllPageTab" |
|||
@tab-remove-left="removeLeftPageTab" |
|||
@tab-remove-right="removeRightPageTab" |
|||
@tab-remove-other="removeOtherPageTab" |
|||
@reload-page="reloadPageTab" |
|||
@logo-click="onLogoClick" |
|||
@screen-size-change="screenSizeChange" |
|||
@set-home-components="setHomeComponents" |
|||
> |
|||
<!-- 路由出口 --> |
|||
<router-layout /> |
|||
<!-- logo图标 --> |
|||
<template slot="logo"> |
|||
<img src="@/assets/logo.svg" alt="logo"/> |
|||
<img src="@/assets/logo.svg" alt="logo" /> |
|||
</template> |
|||
<!-- 顶栏右侧区域 --> |
|||
<template slot="right"> |
|||
<ele-header-right |
|||
:show-setting="needSetting" |
|||
@item-click="onItemClick"/> |
|||
<header-tools :fullscreen="fullscreen" @fullscreen="onFullscreen" /> |
|||
</template> |
|||
<!-- 全局页脚 --> |
|||
<template slot="footer"> |
|||
<page-footer /> |
|||
</template> |
|||
<!-- 自定义菜单标题增加徽章、小红点 --> |
|||
<template slot="title" slot-scope="{ title, item }"> |
|||
<span>{{ title }} </span> |
|||
<div v-if="item.meta && item.meta.badge" class="ele-menu-badge"> |
|||
<el-badge :value="item.meta.badge" :type="item.meta.badgeColor" /> |
|||
</div> |
|||
</template> |
|||
<template slot="top-title" slot-scope="{ title, item }"> |
|||
<span>{{ title }} </span> |
|||
<div v-if="item.meta && item.meta.badge" class="ele-menu-badge"> |
|||
<el-badge :value="item.meta.badge" :type="item.meta.badgeColor" /> |
|||
</div> |
|||
</template> |
|||
<template slot="nav-title" slot-scope="{ title, item }"> |
|||
<span>{{ title }} </span> |
|||
<div v-if="item.meta && item.meta.badge" class="ele-menu-badge"> |
|||
<el-badge :value="item.meta.badge" :type="item.meta.badgeColor" /> |
|||
</div> |
|||
</template> |
|||
<!-- 修改密码弹窗 --> |
|||
<ele-password :visible.sync="showPassword"/> |
|||
</ele-pro-layout> |
|||
</template> |
|||
|
|||
<script> |
|||
import {mapGetters} from 'vuex'; |
|||
import setting from '@/config/setting'; |
|||
import EleHeaderRight from './header-right'; |
|||
import ElePassword from './password'; |
|||
import { mapGetters } from 'vuex'; |
|||
import { toggleFullscreen, isFullscreen } from 'ele-admin'; |
|||
import RouterLayout from '@/components/RouterLayout/index.vue'; |
|||
import HeaderTools from './components/header-tools.vue'; |
|||
import PageFooter from './components/page-footer.vue'; |
|||
import { |
|||
PROJECT_NAME, |
|||
HIDE_SIDEBARS, |
|||
HIDE_FOOTERS, |
|||
REPEATABLE_TABS, |
|||
HOME_TITLE |
|||
} from '@/config/setting'; |
|||
import { |
|||
addPageTab, |
|||
removePageTab, |
|||
removeAllPageTab, |
|||
removeLeftPageTab, |
|||
removeRightPageTab, |
|||
removeOtherPageTab, |
|||
reloadPageTab, |
|||
setHomeComponents |
|||
} from '@/utils/page-tab-util'; |
|||
|
|||
export default { |
|||
export default { |
|||
name: 'EleLayout', |
|||
components: { |
|||
EleHeaderRight, |
|||
ElePassword |
|||
}, |
|||
computed: { |
|||
// 主页标题 |
|||
homeTitle() { |
|||
return setting.homeTitle; |
|||
}, |
|||
// 需要缓存的组件 |
|||
keepAliveList() { |
|||
return setting.keepAliveList; |
|||
}, |
|||
// 是否需要主题设置按钮 |
|||
needSetting() { |
|||
return setting.showSetting; |
|||
}, |
|||
...mapGetters(['theme', 'user']) |
|||
RouterLayout, |
|||
HeaderTools, |
|||
PageFooter |
|||
}, |
|||
data() { |
|||
return { |
|||
// 项目名 |
|||
projectName: process.env.VUE_APP_NAME, |
|||
// 是否显示修改密码弹窗 |
|||
showPassword: false, |
|||
// 是否显示主题设置抽屉 |
|||
showSetting: false, |
|||
// 是否显示主体部分, 如果你的首页用到了权限控制指令, 把这个改成false, 避免权限控制指令可能不生效 |
|||
showContent: true |
|||
PROJECT_NAME, |
|||
HIDE_SIDEBARS, |
|||
HIDE_FOOTERS, |
|||
REPEATABLE_TABS, |
|||
// 是否全屏 |
|||
fullscreen: false |
|||
}; |
|||
}, |
|||
mounted() { |
|||
// 获取用户信息 |
|||
this.getUserInfo(); |
|||
computed: { |
|||
// 当前语言 |
|||
locale() { |
|||
return this.$i18n.locale; |
|||
}, |
|||
methods: { |
|||
/* 获取当前用户信息 */ |
|||
getUserInfo() { |
|||
if (setting.userUrl) { |
|||
this.$http.get(setting.userUrl).then(res => { |
|||
let result; |
|||
if (setting.parseUser) { |
|||
result = setting.parseUser(res.data); |
|||
} else { |
|||
result = res.data; |
|||
} |
|||
if (res.data.code === 0) { |
|||
const user = result.data; |
|||
this.$store.dispatch('user/setUser', user); |
|||
this.$store.dispatch('user/setRoles', user ? user.roles : null); |
|||
this.$store.dispatch('user/setAuthorities', user ? user.authorities : null); |
|||
} else { |
|||
this.$message.error(res.data.msg); |
|||
} |
|||
// 在用户权限信息请求完成后再渲染主体部分, 以免权限控制指令不生效 |
|||
this.showContent = true; |
|||
}).catch(e => { |
|||
this.showContent = true; |
|||
this.$message.error(e.message); |
|||
}); |
|||
} |
|||
// 主页标题 |
|||
homeTitle() { |
|||
return HOME_TITLE ?? this.$t('layout.home'); |
|||
}, |
|||
/* 顶栏右侧点击 */ |
|||
onItemClick(key) { |
|||
if (key === 'password') { |
|||
this.showPassword = true; |
|||
} else if (key === 'setting') { |
|||
this.showSetting = true; |
|||
} |
|||
// 菜单数据 |
|||
menus() { |
|||
return this.$store.state.user.menus; |
|||
}, |
|||
// 主题状态 |
|||
...mapGetters(['theme']) |
|||
}, |
|||
/* 更新collapse */ |
|||
methods: { |
|||
updateCollapse(value) { |
|||
this.$store.dispatch('theme/set', { |
|||
key: 'collapse', |
|||
value: value |
|||
}); |
|||
this.$store.dispatch('theme/setCollapse', value); |
|||
}, |
|||
/* 更新屏幕尺寸 */ |
|||
updateScreen() { |
|||
this.$store.dispatch('theme/updateScreen'); |
|||
updateSideNavCollapse(value) { |
|||
this.$store.dispatch('theme/setSideNavCollapse', value); |
|||
}, |
|||
/* 切换主题色 */ |
|||
changeColor(value) { |
|||
const loading = this.$loading({ |
|||
lock: true, |
|||
background: 'transparent' |
|||
}); |
|||
this.$store.dispatch('theme/setColor', value).then(() => { |
|||
loading.close(); |
|||
}).catch(e => { |
|||
loading.close(); |
|||
console.error(e); |
|||
this.$message.error('主题加载失败'); |
|||
}); |
|||
updateBodyFullscreen(value) { |
|||
this.$store.dispatch('theme/setBodyFullscreen', value); |
|||
}, |
|||
/* 切换主题风格 */ |
|||
changeStyle(value) { |
|||
this.$store.dispatch('theme/set', value); |
|||
onLogoClick(isHome) { |
|||
isHome || this.$router.push('/'); |
|||
}, |
|||
/* 添加tab */ |
|||
tabAdd(value) { |
|||
this.$store.dispatch('user/tabAdd', value); |
|||
screenSizeChange() { |
|||
this.$store.dispatch('theme/updateScreenSize'); |
|||
this.fullscreen = isFullscreen(); |
|||
}, |
|||
/* 移除tab */ |
|||
tabRemove(obj) { |
|||
this.$store.dispatch('user/tabRemove', obj.name).then(last => { |
|||
if (obj.active === obj.name) { |
|||
this.$router.push(last === -1 ? '/' : this.user.tabs[last].path); |
|||
onFullscreen() { |
|||
try { |
|||
this.fullscreen = toggleFullscreen(); |
|||
} catch (e) { |
|||
this.$message.error('您的浏览器不支持全屏模式'); |
|||
} |
|||
}); |
|||
}, |
|||
/* 移除左边tab */ |
|||
tabRemoveLeft(value) { |
|||
this.$store.dispatch('user/tabRemoveLeft', value); |
|||
}, |
|||
/* 移除右边tab */ |
|||
tabRemoveRight(value) { |
|||
this.$store.dispatch('user/tabRemoveRight', value); |
|||
/* 菜单标题国际化 */ |
|||
i18n(_path, key) { |
|||
const k = 'route.' + key + '._name'; |
|||
const title = this.$t(k); |
|||
return title === k ? undefined : title; |
|||
}, |
|||
/* 移除其它tab */ |
|||
tabRemoveOther(value) { |
|||
this.$store.dispatch('user/tabRemoveOther', value); |
|||
}, |
|||
/* 移除全部tab */ |
|||
tabRemoveAll() { |
|||
this.$store.dispatch('user/tabRemoveAll'); |
|||
} |
|||
// |
|||
addPageTab, |
|||
removePageTab, |
|||
removeAllPageTab, |
|||
removeLeftPageTab, |
|||
removeRightPageTab, |
|||
removeOtherPageTab, |
|||
reloadPageTab, |
|||
setHomeComponents |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
// 侧栏菜单徽章样式,定位在右侧垂直居中并调小尺寸 |
|||
.ele-menu-badge { |
|||
position: absolute; |
|||
top: 50%; |
|||
right: 14px; |
|||
line-height: 1; |
|||
margin-top: -9px; |
|||
font-size: 0; |
|||
|
|||
.el-badge__content { |
|||
height: 18px; |
|||
line-height: 18px; |
|||
border-radius: 9px; |
|||
border: none; |
|||
min-width: 18px; |
|||
padding: 0 4px; |
|||
box-sizing: border-box; |
|||
} |
|||
} |
|||
|
|||
// 父级菜单标题中右侧多定位一点,避免与箭头重合 |
|||
.el-submenu > .el-submenu__title .ele-menu-badge { |
|||
right: 36px; |
|||
} |
|||
|
|||
// 折叠悬浮中样式调整 |
|||
.el-menu--popup { |
|||
.el-submenu > .el-submenu__title .ele-menu-badge { |
|||
right: 20px; |
|||
} |
|||
} |
|||
|
|||
// 侧栏折叠后样式调整 |
|||
.ele-admin-collapse .ele-admin-sidebar-menus > .el-menu { |
|||
& > .el-menu-item, |
|||
& > .el-submenu > .el-submenu__title { |
|||
.ele-menu-badge { |
|||
top: 6px; |
|||
right: 6px; |
|||
margin: 0; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 顶栏菜单标题中样式调整 |
|||
.ele-admin-header-nav.el-menu { |
|||
& > .el-menu-item, |
|||
& > .el-submenu > .el-submenu__title { |
|||
.ele-menu-badge { |
|||
position: static; |
|||
right: auto; |
|||
top: auto; |
|||
display: inline-block; |
|||
vertical-align: 6px; |
|||
margin: 0 0 0 2px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 双侧栏时一级侧栏菜单中样式调整,定位在右上角 |
|||
.ele-admin-sidebar-nav-menu > .el-menu { |
|||
& > .el-menu-item, |
|||
& > .el-submenu > .el-submenu__title { |
|||
.ele-menu-badge { |
|||
top: 2px; |
|||
right: 4px; |
|||
margin: 0; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 双侧栏时一级侧栏菜单折叠后样式调整 |
|||
.ele-admin-nav-collapse .ele-admin-sidebar-nav-menu > .el-menu { |
|||
& > .el-menu-item, |
|||
& > .el-submenu > .el-submenu__title { |
|||
.ele-menu-badge { |
|||
top: -2px; |
|||
right: -2px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
|
|||
@ -1,300 +0,0 @@ |
|||
<!-- 顶栏消息图标 --> |
|||
<template> |
|||
<el-popover |
|||
width="300" |
|||
v-model="visible" |
|||
trigger="click" |
|||
popper-class="ele-notice-pop" |
|||
transition="el-zoom-in-top" |
|||
class="ele-notice-group"> |
|||
<div |
|||
class="ele-notice-group" |
|||
slot="reference"> |
|||
<el-badge |
|||
:value="allNum" |
|||
:hidden="!allNum"> |
|||
<i class="el-icon-bell"></i> |
|||
</el-badge> |
|||
</div> |
|||
<el-tabs |
|||
v-model="active" |
|||
class="user-info-tabs"> |
|||
<el-tab-pane |
|||
:label="noticeLabel" |
|||
name="notice"> |
|||
<div class="ele-notice-list ele-scrollbar-mini"> |
|||
<div |
|||
v-for="(item,index) in notice" |
|||
:key="index" |
|||
class="ele-notice-item"> |
|||
<div class="ele-cell ele-notice-item-wrapper"> |
|||
<i :class="[item.icon,'ele-notice-item-icon']"></i> |
|||
<div class="ele-cell-content"> |
|||
<div class="ele-elip">{{ item.title }}</div> |
|||
<div class="ele-text-secondary ele-elip">{{ item.pub_time }}</div> |
|||
</div> |
|||
</div> |
|||
<el-divider/> |
|||
</div> |
|||
</div> |
|||
<div |
|||
v-if="notice.length" |
|||
class="ele-cell ele-notice-actions"> |
|||
<!-- <div--> |
|||
<!-- @click="clear(1)"--> |
|||
<!-- class="ele-cell-content">清空通知--> |
|||
<!-- </div>--> |
|||
<el-divider |
|||
direction="vertical" |
|||
class="line-color-light"/> |
|||
<div |
|||
@click="more(1)" |
|||
class="ele-cell-content">查看更多 |
|||
</div> |
|||
</div> |
|||
<ele-empty |
|||
v-if="!notice.length" |
|||
text="你已查看所有通知"/> |
|||
</el-tab-pane> |
|||
<el-tab-pane |
|||
:label="messageLabel" |
|||
name="message"> |
|||
<div class="ele-notice-list ele-scrollbar-mini"> |
|||
<div |
|||
v-for="(item,index) in message" |
|||
:key="index" |
|||
class="ele-notice-item"> |
|||
<div class="ele-cell ele-notice-item-wrapper ele-cell-align-top"> |
|||
<el-avatar |
|||
:src="item.avatar_str" |
|||
size="medium"/> |
|||
<div class="ele-cell-content"> |
|||
<div class="ele-elip">{{ item.title }}</div> |
|||
<div class="ele-text-secondary ele-elip">{{ item.content }}</div> |
|||
<div class="ele-cell-desc ele-elip">{{ item.pub_time }}</div> |
|||
</div> |
|||
</div> |
|||
<el-divider/> |
|||
</div> |
|||
</div> |
|||
<div |
|||
v-if="message.length" |
|||
class="ele-cell ele-notice-actions"> |
|||
<!-- <div--> |
|||
<!-- @click="clear(2)"--> |
|||
<!-- class="ele-cell-content">清空消息--> |
|||
<!-- </div>--> |
|||
<el-divider |
|||
direction="vertical" |
|||
class="line-color-light"/> |
|||
<div |
|||
@click="more(2)" |
|||
class="ele-cell-content">查看更多 |
|||
</div> |
|||
</div> |
|||
<ele-empty |
|||
v-if="!message.length" |
|||
text="你已读完所有私信"/> |
|||
</el-tab-pane> |
|||
</el-tabs> |
|||
</el-popover> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'EleNotice', |
|||
data() { |
|||
return { |
|||
visible: false, |
|||
active: 'notice', |
|||
notice: [ |
|||
|
|||
], |
|||
notice_count:0, |
|||
message: [ |
|||
|
|||
], |
|||
message_count:0, |
|||
}; |
|||
}, |
|||
|
|||
computed: { |
|||
|
|||
|
|||
// 通知标题 |
|||
noticeLabel() { |
|||
if (this.notice_count) { |
|||
return `通知(${this.notice_count})`; |
|||
} |
|||
return '通知'; |
|||
}, |
|||
// 私信标题 |
|||
messageLabel() { |
|||
if (this.message_count) { |
|||
return `私信(${this.message_count})`; |
|||
} |
|||
return '私信'; |
|||
}, |
|||
|
|||
// 所有消息数量 |
|||
allNum() { |
|||
return this.notice_count + this.message_count ; |
|||
} |
|||
}, |
|||
|
|||
mounted() { |
|||
// 获取用户信息 |
|||
this.getMessage(); |
|||
|
|||
setInterval(this.setM,60000) |
|||
}, |
|||
|
|||
methods: { |
|||
setM(){ |
|||
this.setMessage(); |
|||
this.getMessage(); |
|||
}, |
|||
getMessage(){ |
|||
this.$http.get('/manager/getMessage?type=99').then(res => { |
|||
if (res.data.code === 0) { |
|||
this.message = res.data.data.sx.list; |
|||
this.notice = res.data.data.gg.list; |
|||
this.message_count = res.data.data.sx.count; |
|||
this.notice_count = res.data.data.gg.count; |
|||
} |
|||
}) |
|||
}, |
|||
setMessage(){ |
|||
this.$http.get('/manager/setMessage?type=99').then(res => { |
|||
if (res.data.code === 0) { |
|||
this.message = res.data.data.sx.list; |
|||
this.notice = res.data.data.gg.list; |
|||
this.message_count = res.data.data.sx.count; |
|||
this.notice_count = res.data.data.gg.count; |
|||
} |
|||
}) |
|||
}, |
|||
|
|||
/* 清空消息 */ |
|||
clear(type) { |
|||
if (type === 1) { |
|||
this.notice = []; |
|||
} else if (type === 2) { |
|||
this.message = []; |
|||
} |
|||
}, |
|||
/* 查看更多 */ |
|||
more(type) { |
|||
console.log(type); |
|||
if (this.$route.path !== '/user/message') { |
|||
this.$router.push('/user/message'); |
|||
} |
|||
this.show = false; |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.ele-notice-group { |
|||
vertical-align: top !important; |
|||
display: inline-block; |
|||
|
|||
.el-badge { |
|||
line-height: normal; |
|||
} |
|||
} |
|||
|
|||
/* 消息通知pop */ |
|||
.ele-notice-pop { |
|||
margin: 0 !important; |
|||
padding: 0 !important; |
|||
|
|||
/* tab */ |
|||
.el-tabs__nav-scroll { |
|||
text-align: center; |
|||
} |
|||
|
|||
.el-tabs__nav { |
|||
float: none; |
|||
display: inline-block; |
|||
} |
|||
|
|||
.el-tabs__item { |
|||
padding: 0 20px; |
|||
} |
|||
|
|||
/* 空视图 */ |
|||
.ele-empty { |
|||
padding: 100px 0; |
|||
} |
|||
} |
|||
|
|||
/* 列表 */ |
|||
.ele-notice-list { |
|||
padding-top: 8px; |
|||
max-height: 360px; |
|||
overflow: auto; |
|||
} |
|||
|
|||
.ele-notice-item { |
|||
.ele-notice-item-wrapper { |
|||
padding: 12px 15px; |
|||
transition: background-color .2s; |
|||
cursor: pointer; |
|||
|
|||
&:hover { |
|||
background-color: hsla(0, 0%, 60%, .05); |
|||
} |
|||
} |
|||
|
|||
.ele-text-secondary { |
|||
margin-top: 5px; |
|||
font-size: 13px; |
|||
} |
|||
|
|||
.ele-cell-desc { |
|||
margin-top: 3px !important; |
|||
font-size: 12px !important; |
|||
} |
|||
} |
|||
|
|||
.ele-notice-item-icon { |
|||
width: 32px; |
|||
height: 32px; |
|||
line-height: 32px !important; |
|||
color: #FFF; |
|||
font-size: 16px; |
|||
background-color: #60B2FC; |
|||
border-radius: 50%; |
|||
text-align: center; |
|||
|
|||
|
|||
&.el-icon-s-check { |
|||
background-color: #F5686F; |
|||
} |
|||
|
|||
&.el-icon-video-camera { |
|||
background-color: #7CD734; |
|||
} |
|||
|
|||
&.el-icon-s-claim { |
|||
background-color: #FAAD14; |
|||
} |
|||
|
|||
&.el-icon-message-solid { |
|||
background-color: #2BCACD; |
|||
} |
|||
} |
|||
|
|||
/* 操作按钮 */ |
|||
.ele-notice-actions > .ele-cell-content { |
|||
line-height: 42px; |
|||
text-align: center; |
|||
cursor: pointer; |
|||
|
|||
&:hover { |
|||
background-color: hsla(0, 0%, 60%, .05); |
|||
} |
|||
} |
|||
</style> |
|||
@ -1,136 +0,0 @@ |
|||
<!-- 修改密码弹窗 --> |
|||
<template> |
|||
<el-dialog |
|||
:visible="visible" |
|||
title="修改密码" |
|||
width="400px" |
|||
@closed="onClose" |
|||
@update:visible="updateVisible" |
|||
:append-to-body="true" |
|||
:lock-scroll="false"> |
|||
<el-form |
|||
ref="form" |
|||
:model="form" |
|||
:rules="rules" |
|||
label-width="82px" |
|||
@keyup.enter.native="save"> |
|||
<el-form-item |
|||
label="旧密码:" |
|||
prop="old"> |
|||
<el-input |
|||
v-model="form.old" |
|||
placeholder="请输入旧密码" |
|||
show-password/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
label="新密码:" |
|||
prop="password"> |
|||
<el-input |
|||
v-model="form.password" |
|||
placeholder="请输入新密码" |
|||
show-password/> |
|||
</el-form-item> |
|||
<el-form-item |
|||
label="确认密码:" |
|||
prop="password2"> |
|||
<el-input |
|||
v-model="form.password2" |
|||
placeholder="请再次输入新密码" |
|||
show-password/> |
|||
</el-form-item> |
|||
</el-form> |
|||
<div slot="footer"> |
|||
<el-button |
|||
@click="cancel">取消 |
|||
</el-button> |
|||
<el-button |
|||
type="primary" |
|||
@click="save">确定 |
|||
</el-button> |
|||
</div> |
|||
</el-dialog> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'ElePassword', |
|||
props: { |
|||
visible: Boolean |
|||
}, |
|||
data() { |
|||
let rePswRule = (rule, value, callback) => { |
|||
if (!value) { |
|||
callback(new Error('请再次输入新密码')); |
|||
} else if (value !== this.form.password) { |
|||
callback(new Error('两次输入密码不一致')); |
|||
} else { |
|||
callback(); |
|||
} |
|||
}; |
|||
return { |
|||
// 表单数据 |
|||
form: { |
|||
old: '', |
|||
password: '', |
|||
password2: '' |
|||
}, |
|||
// 表单验证 |
|||
rules: { |
|||
old: [ |
|||
{required: true, message: '请输入旧密码', trigger: 'blur'} |
|||
], |
|||
password: [ |
|||
{required: true, message: '请输入新密码', trigger: 'blur'} |
|||
], |
|||
password2: [ |
|||
{validator: rePswRule, trigger: 'blur'} |
|||
] |
|||
}, |
|||
// 按钮loading |
|||
loading: false |
|||
}; |
|||
}, |
|||
methods: { |
|||
/* 保存修改 */ |
|||
save() { |
|||
this.$refs['form'].validate((valid) => { |
|||
if (valid) { |
|||
this.loading = true; |
|||
let formData = new FormData(); |
|||
formData.append('old_password', this.form.old); |
|||
formData.append('password', this.form.password); |
|||
formData.append('password2', this.form.password2); |
|||
this.$http.post('/manager/passwordEdit', formData).then(res => { |
|||
this.loading = false; |
|||
if (res.data.code === 0) { |
|||
this.$message({type: 'success', message: res.data.msg}); |
|||
this.cancel(); |
|||
} else { |
|||
this.$message.error(res.data.msg); |
|||
} |
|||
}).catch(e => { |
|||
this.loading = false; |
|||
this.$message.error(e.message); |
|||
}); |
|||
} else { |
|||
return false; |
|||
} |
|||
}); |
|||
}, |
|||
/* 取消 */ |
|||
cancel() { |
|||
this.updateVisible(false); |
|||
}, |
|||
/* 关闭回调 */ |
|||
onClose() { |
|||
this.form = {}; |
|||
this.$refs['form'].resetFields(); |
|||
this.loading = false; |
|||
}, |
|||
/* 修改visible */ |
|||
updateVisible(value) { |
|||
this.$emit('update:visible', value); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
@ -1,23 +1,33 @@ |
|||
/** 主入口js */ |
|||
import Vue from 'vue'; |
|||
import App from './App.vue'; |
|||
import router from './router'; |
|||
import store from './store'; |
|||
import setting from './config/setting'; |
|||
import permission from '@/utils/permission'; |
|||
import VueClipboard from 'vue-clipboard2'; |
|||
import './config/axios-config'; |
|||
import EleAdmin from 'ele-admin'; |
|||
import router from './router'; |
|||
import permission from './utils/permission'; |
|||
import './styles/index.scss'; |
|||
import EleAdmin from 'ele-admin'; |
|||
import VueClipboard from 'vue-clipboard2'; |
|||
import i18n from './i18n'; |
|||
import { MAP_KEY, LICENSE_CODE } from '@/config/setting'; |
|||
|
|||
Vue.config.productionTip = false; |
|||
Vue.prototype.$setting = setting; |
|||
Vue.use(EleAdmin, {size: 'medium'}); |
|||
|
|||
Vue.use(EleAdmin, { |
|||
response: { |
|||
dataName: 'list' |
|||
}, |
|||
mapKey: MAP_KEY, |
|||
license: LICENSE_CODE, |
|||
i18n: (key, value) => i18n.t(key, value) |
|||
}); |
|||
|
|||
Vue.use(permission); |
|||
|
|||
Vue.use(VueClipboard); |
|||
|
|||
new Vue({ |
|||
router, |
|||
store, |
|||
render: h => h(App) |
|||
i18n, |
|||
render: (h) => h(App) |
|||
}).$mount('#app'); |
|||
|
|||
@ -1,4 +1,7 @@ |
|||
/** |
|||
* vuex getter |
|||
*/ |
|||
export default { |
|||
theme: state => state.theme, |
|||
user: state => state.user |
|||
} |
|||
user: (state) => state.user, |
|||
theme: (state) => state.theme |
|||
}; |
|||
|
|||
@ -1,302 +1,506 @@ |
|||
/** |
|||
* 主题状态管理 license by http://eleadmin.com
|
|||
* 主题状态管理 |
|||
*/ |
|||
import setting from '@/config/setting'; |
|||
import { |
|||
screenWidth, |
|||
screenHeight, |
|||
contentWidth, |
|||
contentHeight |
|||
} from 'ele-admin'; |
|||
import { changeColor } from 'ele-admin/es/utils/theme-util'; |
|||
import { TAB_KEEP_ALIVE, THEME_STORE_NAME } from '@/config/setting'; |
|||
// state默认值
|
|||
const DEFAULT_STATE = Object.freeze({ |
|||
// 多页签数据
|
|||
tabs: [], |
|||
// 是否折叠侧边栏
|
|||
collapse: false, |
|||
// 是否折叠侧栏一级菜单
|
|||
sideNavCollapse: false, |
|||
// 内容区域是否全屏
|
|||
bodyFullscreen: false, |
|||
// 是否开启多页签
|
|||
showTabs: true, |
|||
// 是否开启页脚
|
|||
showFooter: true, |
|||
// 顶栏风格: light(亮色), dark(暗色), primary(主色)
|
|||
headStyle: 'light', |
|||
// 侧边栏风格: light(亮色), dark(暗色)
|
|||
sideStyle: 'dark', |
|||
// 布局风格: side(默认), top(顶栏菜单), mix(混合菜单)
|
|||
layoutStyle: 'side', |
|||
// 侧边栏菜单风格: default(默认), mix(双排菜单)
|
|||
sideMenuStyle: 'default', |
|||
// 标签页风格: default(默认), dot(圆点), card(卡片)
|
|||
tabStyle: 'default', |
|||
// 是否固定顶栏
|
|||
fixedHeader: false, |
|||
// 是否固定侧栏
|
|||
fixedSidebar: true, |
|||
// 是否固定主体
|
|||
fixedBody: true, |
|||
// 内容区域宽度铺满
|
|||
bodyFull: true, |
|||
// logo是否自适应宽度
|
|||
logoAutoSize: false, |
|||
// 侧栏是否彩色图标
|
|||
colorfulIcon: false, |
|||
// 侧栏是否只保持一个子菜单展开
|
|||
sideUniqueOpen: true, |
|||
// 是否是色弱模式
|
|||
weakMode: false, |
|||
// 是否是暗黑模式
|
|||
darkMode: false, |
|||
// 主题色
|
|||
color: null, |
|||
// 主页的组件
|
|||
homeComponents: [], |
|||
// 刷新路由时的参数
|
|||
routeReload: null, |
|||
// 屏幕宽度
|
|||
screenWidth: screenWidth(), |
|||
// 屏幕高度
|
|||
screenHeight: screenHeight(), |
|||
// 内容区域宽度
|
|||
contentWidth: contentWidth(), |
|||
// 内容区域高度
|
|||
contentHeight: contentHeight() |
|||
}); |
|||
// 延时操作定时器
|
|||
let disableTransitionTimer, updateContentSizeTimer; |
|||
const weakClass = 'ele-admin-weak'; |
|||
const disabledClass = 'ele-transition-disabled'; |
|||
|
|||
// 获取本地缓存配置
|
|||
let cache = {}; |
|||
try { |
|||
cache = JSON.parse(localStorage.getItem(setting.themeStoreName)) || {}; |
|||
} catch (e) { |
|||
/** |
|||
* 读取缓存配置 |
|||
*/ |
|||
function getCacheSetting() { |
|||
try { |
|||
const value = localStorage.getItem(THEME_STORE_NAME); |
|||
if (value) { |
|||
const cache = JSON.parse(value); |
|||
if (typeof cache === 'object' && cache !== null) { |
|||
return cache; |
|||
} |
|||
} |
|||
} catch (e) { |
|||
console.error(e); |
|||
} |
|||
return {}; |
|||
} |
|||
|
|||
// 获取缓存的主题配置和缓存的主题css
|
|||
const cacheTheme = getCache(cache, [ |
|||
'color', 'sideStyle', 'headStyle', |
|||
'tabStyle', 'layoutStyle', 'bodyFull', |
|||
'fixedHeader', 'fixedSidebar', 'fixedBody', |
|||
'showTabs', 'logoAutoSize', 'colorfulIcon', |
|||
'sideUniqueOpen', 'showFooter', 'weakMode', 'darkMode' |
|||
], setting); |
|||
/** |
|||
* 缓存配置 |
|||
*/ |
|||
function cacheSetting(key, value) { |
|||
const cache = getCacheSetting(); |
|||
if (cache[key] !== value) { |
|||
cache[key] = value; |
|||
localStorage.setItem(THEME_STORE_NAME, JSON.stringify(cache)); |
|||
} |
|||
} |
|||
|
|||
// 恢复色弱模式
|
|||
if (cacheTheme.weakMode) { |
|||
document.body.classList.add('ele-admin-weak'); |
|||
/** |
|||
* 切换色弱模式 |
|||
*/ |
|||
function changeWeakMode(weakMode) { |
|||
if (weakMode) { |
|||
document.body.classList.add(weakClass); |
|||
} else { |
|||
document.body.classList.remove(weakClass); |
|||
} |
|||
} |
|||
|
|||
// 恢复主题色
|
|||
window.onload = function () { |
|||
changeTheme(cacheTheme.color, cacheTheme.darkMode).catch(e => { |
|||
console.error(e); |
|||
/** |
|||
* 切换主题 |
|||
*/ |
|||
function changeTheme(value, dark) { |
|||
return new Promise((resolve, reject) => { |
|||
try { |
|||
changeColor(value, dark); |
|||
resolve(); |
|||
} catch (e) { |
|||
reject(e); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
// 获取屏幕宽度
|
|||
const screenWidth = document.documentElement.clientWidth || document.body.clientWidth, |
|||
screenHeight = document.documentElement.clientHeight || document.body.clientHeight; |
|||
/** |
|||
* 切换布局时禁用过渡动画 |
|||
*/ |
|||
function disableTransition() { |
|||
disableTransitionTimer && clearTimeout(disableTransitionTimer); |
|||
document.body.classList.add(disabledClass); |
|||
disableTransitionTimer = setTimeout(() => { |
|||
document.body.classList.remove(disabledClass); |
|||
}, 100); |
|||
} |
|||
|
|||
/** |
|||
* 获取含本地缓存的state值 |
|||
*/ |
|||
function getState() { |
|||
const state = Object.assign({}, DEFAULT_STATE); |
|||
const cache = getCacheSetting(); |
|||
Object.keys(state).forEach((key) => { |
|||
if (typeof cache[key] !== 'undefined') { |
|||
state[key] = cache[key]; |
|||
} |
|||
}); |
|||
return state; |
|||
} |
|||
|
|||
export default { |
|||
namespaced: true, |
|||
state: { |
|||
// 侧边栏风格: 0亮色, 1暗色
|
|||
sideStyle: cacheTheme.sideStyle, |
|||
// 顶栏风格: 0亮色, 1暗色, 2主色
|
|||
headStyle: cacheTheme.headStyle, |
|||
// 标签页风格: 0默认, 1圆点, 2卡片
|
|||
tabStyle: cacheTheme.tabStyle, |
|||
// 布局风格: 0默认, 1顶部菜单风格, 2混合菜单风格
|
|||
layoutStyle: cacheTheme.layoutStyle, |
|||
// 是否固定侧栏
|
|||
fixedSidebar: cacheTheme.fixedSidebar, |
|||
// 是否固定顶栏
|
|||
fixedHeader: cacheTheme.fixedHeader, |
|||
// 是否固定主体
|
|||
fixedBody: cacheTheme.fixedBody, |
|||
// 内容区域宽度铺满
|
|||
bodyFull: cacheTheme.bodyFull, |
|||
// 是否开启多标签
|
|||
showTabs: cacheTheme.showTabs, |
|||
// logo是否自适应宽度
|
|||
logoAutoSize: cacheTheme.logoAutoSize, |
|||
// 侧栏是否多彩图标
|
|||
colorfulIcon: cacheTheme.colorfulIcon, |
|||
// 侧边栏是否只保持一个子菜单展开
|
|||
sideUniqueOpen: cacheTheme.sideUniqueOpen, |
|||
// 是否开启页脚
|
|||
showFooter: cacheTheme.showFooter, |
|||
// 是否是色弱模式
|
|||
weakMode: cacheTheme.weakMode, |
|||
// 是否是暗黑模式
|
|||
darkMode: cacheTheme.darkMode, |
|||
// 主题色
|
|||
color: cacheTheme.color, |
|||
// 是否折叠侧边栏
|
|||
collapse: screenWidth < 992, |
|||
// 当前屏幕宽度
|
|||
screenWidth: screenWidth, |
|||
// 当前屏幕高度
|
|||
screenHeight: screenHeight |
|||
}, |
|||
mutations: { |
|||
SET: (state, obj) => { |
|||
state[obj.key] = obj.value; |
|||
// 开关色弱模式
|
|||
if ('weakMode' === obj.key) { |
|||
if (obj.value) { |
|||
document.body.classList.add('ele-admin-weak'); |
|||
} else { |
|||
document.body.classList.remove('ele-admin-weak'); |
|||
state: getState(), |
|||
getters: { |
|||
// 需要keep-alive的组件
|
|||
keepAliveInclude(state) { |
|||
if (!TAB_KEEP_ALIVE || !state.showTabs) { |
|||
return []; |
|||
} |
|||
const components = new Set(); |
|||
const { reloadPath, reloadHome } = state.routeReload || {}; |
|||
state.tabs?.forEach((t) => { |
|||
const isReload = reloadPath && reloadPath === t.fullPath; |
|||
if (!isReload && t.components) { |
|||
t.components.forEach((c) => { |
|||
if (typeof c === 'string' && c) { |
|||
components.add(c); |
|||
} |
|||
// 缓存修改的配置
|
|||
if (['collapse', 'screenWidth', 'screenHeight'].indexOf(obj.key) === -1) { |
|||
let temp = JSON.parse(localStorage.getItem(setting.themeStoreName) || '{}'); |
|||
temp[obj.key] = obj.value; |
|||
localStorage.setItem(setting.themeStoreName, JSON.stringify(temp)); |
|||
}); |
|||
} |
|||
}); |
|||
if (!reloadHome) { |
|||
state.homeComponents?.forEach((c) => { |
|||
if (typeof c === 'string' && c) { |
|||
components.add(c); |
|||
} |
|||
}); |
|||
} |
|||
return Array.from(components); |
|||
} |
|||
}, |
|||
mutations: { |
|||
SET(state, { key, value }) { |
|||
state[key] = value; |
|||
} |
|||
}, |
|||
actions: { |
|||
/** |
|||
* 修改配置 |
|||
* @param commit |
|||
* @param obj |
|||
*/ |
|||
set({commit}, obj) { |
|||
commit('SET', obj); |
|||
}, |
|||
/** |
|||
* 切换配置(boolean类型的配置) |
|||
* @param commit |
|||
* @param state |
|||
* @param key |
|||
*/ |
|||
toggle({commit, state}, key) { |
|||
commit('SET', {key: key, value: !state[key]}); |
|||
setTabs({ commit }, value) { |
|||
commit('SET', { key: 'tabs', value }); |
|||
//cacheSetting('tabs', value);
|
|||
}, |
|||
/** |
|||
* 更新屏幕尺寸 |
|||
* @param commit |
|||
* @param state |
|||
*/ |
|||
updateScreen({commit, state}) { |
|||
const w = document.documentElement.clientWidth || document.body.clientWidth, |
|||
h = document.documentElement.clientHeight || document.body.clientHeight; |
|||
if (w !== state.screenWidth) { |
|||
commit('SET', {key: 'screenWidth', value: w}); |
|||
} |
|||
if (h !== state.screenHeight) { |
|||
commit('SET', {key: 'screenHeight', value: h}); |
|||
} |
|||
setCollapse({ commit, dispatch }, value) { |
|||
commit('SET', { key: 'collapse', value }); |
|||
dispatch('delayUpdateContentSize', 800); |
|||
}, |
|||
/** |
|||
* 切换主题色 |
|||
* @param commit |
|||
* @param state |
|||
* @param color |
|||
* @returns {Promise<>} |
|||
*/ |
|||
setColor({commit, state}, color) { |
|||
setSideNavCollapse({ commit, dispatch }, value) { |
|||
commit('SET', { key: 'sideNavCollapse', value }); |
|||
dispatch('delayUpdateContentSize', 800); |
|||
}, |
|||
setBodyFullscreen({ commit, dispatch }, value) { |
|||
disableTransition(); |
|||
commit('SET', { key: 'bodyFullscreen', value }); |
|||
dispatch('delayUpdateContentSize', 800); |
|||
}, |
|||
setShowTabs({ commit, dispatch }, value) { |
|||
commit('SET', { key: 'showTabs', value }); |
|||
cacheSetting('showTabs', value); |
|||
dispatch('delayUpdateContentSize'); |
|||
}, |
|||
setShowFooter({ commit, dispatch }, value) { |
|||
commit('SET', { key: 'showFooter', value }); |
|||
cacheSetting('showFooter', value); |
|||
dispatch('delayUpdateContentSize'); |
|||
}, |
|||
setHeadStyle({ commit }, value) { |
|||
commit('SET', { key: 'headStyle', value }); |
|||
cacheSetting('headStyle', value); |
|||
}, |
|||
setSideStyle({ commit }, value) { |
|||
commit('SET', { key: 'sideStyle', value }); |
|||
cacheSetting('sideStyle', value); |
|||
}, |
|||
setLayoutStyle({ commit, dispatch }, value) { |
|||
disableTransition(); |
|||
commit('SET', { key: 'layoutStyle', value }); |
|||
cacheSetting('layoutStyle', value); |
|||
dispatch('delayUpdateContentSize'); |
|||
}, |
|||
setSideMenuStyle({ commit, dispatch }, value) { |
|||
disableTransition(); |
|||
commit('SET', { key: 'sideMenuStyle', value }); |
|||
cacheSetting('sideMenuStyle', value); |
|||
dispatch('delayUpdateContentSize'); |
|||
}, |
|||
setTabStyle({ commit }, value) { |
|||
commit('SET', { key: 'tabStyle', value }); |
|||
cacheSetting('tabStyle', value); |
|||
}, |
|||
setFixedHeader({ commit }, value) { |
|||
disableTransition(); |
|||
commit('SET', { key: 'fixedHeader', value }); |
|||
cacheSetting('fixedHeader', value); |
|||
}, |
|||
setFixedSidebar({ commit }, value) { |
|||
disableTransition(); |
|||
commit('SET', { key: 'fixedSidebar', value }); |
|||
cacheSetting('fixedSidebar', value); |
|||
}, |
|||
setFixedBody({ commit }, value) { |
|||
disableTransition(); |
|||
commit('SET', { key: 'fixedBody', value }); |
|||
cacheSetting('fixedBody', value); |
|||
}, |
|||
setBodyFull({ commit, dispatch }, value) { |
|||
commit('SET', { key: 'bodyFull', value }); |
|||
cacheSetting('bodyFull', value); |
|||
dispatch('delayUpdateContentSize'); |
|||
}, |
|||
setLogoAutoSize({ commit }, value) { |
|||
disableTransition(); |
|||
commit('SET', { key: 'logoAutoSize', value }); |
|||
cacheSetting('logoAutoSize', value); |
|||
}, |
|||
setColorfulIcon({ commit }, value) { |
|||
commit('SET', { key: 'colorfulIcon', value }); |
|||
cacheSetting('colorfulIcon', value); |
|||
}, |
|||
setSideUniqueOpen({ commit }, value) { |
|||
commit('SET', { key: 'sideUniqueOpen', value }); |
|||
cacheSetting('sideUniqueOpen', value); |
|||
}, |
|||
setWeakMode({ commit }, value) { |
|||
return new Promise((resolve) => { |
|||
changeWeakMode(value); |
|||
commit('SET', { key: 'weakMode', value }); |
|||
cacheSetting('weakMode', value); |
|||
resolve(); |
|||
}); |
|||
}, |
|||
setDarkMode({ commit, state }, value) { |
|||
return new Promise((resolve, reject) => { |
|||
changeTheme(color, state.darkMode).then(() => { |
|||
commit('SET', {key: 'color', value: color}); |
|||
return resolve(); |
|||
}).catch(e => { |
|||
changeTheme(state.color, value) |
|||
.then(() => { |
|||
commit('SET', { key: 'darkMode', value }); |
|||
cacheSetting('darkMode', value); |
|||
resolve(); |
|||
}) |
|||
.catch((e) => { |
|||
reject(e); |
|||
}); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取缓存配置项 |
|||
* @param cache 缓存数据 |
|||
* @param k 配置项 |
|||
* @param v 默认值 |
|||
*/ |
|||
function getCache(cache, k, v) { |
|||
if (Array.isArray(k)) { |
|||
let obj = {}; |
|||
k.forEach(t => { |
|||
obj[t] = (cache[t] === null || cache[t] === undefined) ? v[t] : cache[t]; |
|||
}, |
|||
setColor({ commit, state }, value) { |
|||
return new Promise((resolve, reject) => { |
|||
changeTheme(value, state.darkMode) |
|||
.then(() => { |
|||
commit('SET', { key: 'color', value }); |
|||
cacheSetting('color', value); |
|||
resolve(); |
|||
}) |
|||
.catch((e) => { |
|||
reject(e); |
|||
}); |
|||
return obj; |
|||
} else { |
|||
if (cache[k] === null || cache[k] === undefined) { |
|||
return v; |
|||
}); |
|||
}, |
|||
// 设置主页对应的组件
|
|||
setHomeComponents({ commit }, value) { |
|||
commit('SET', { key: 'homeComponents', value }); |
|||
}, |
|||
// 设置刷新路由信息
|
|||
setRouteReload({ commit }, value) { |
|||
commit('SET', { key: 'routeReload', value }); |
|||
}, |
|||
// 更新屏幕尺寸
|
|||
updateScreenSize({ commit, dispatch }) { |
|||
commit('SET', { key: 'screenWidth', value: screenWidth() }); |
|||
commit('SET', { key: 'screenHeight', value: screenHeight() }); |
|||
dispatch('updateContentSize'); |
|||
}, |
|||
// 更新内容区域尺寸
|
|||
updateContentSize({ commit }) { |
|||
commit('SET', { key: 'contentWidth', value: contentWidth() }); |
|||
commit('SET', { key: 'contentHeight', value: contentHeight() }); |
|||
}, |
|||
// 延时更新内容区域尺寸
|
|||
delayUpdateContentSize({ dispatch }, delay) { |
|||
updateContentSizeTimer && clearTimeout(updateContentSizeTimer); |
|||
updateContentSizeTimer = setTimeout(() => { |
|||
dispatch('updateContentSize'); |
|||
}, delay ?? 100); |
|||
}, |
|||
// 重置配置
|
|||
resetSetting({ commit, state }) { |
|||
return new Promise((resolve, reject) => { |
|||
disableTransition(); |
|||
[ |
|||
'showTabs', |
|||
'showFooter', |
|||
'headStyle', |
|||
'sideStyle', |
|||
'layoutStyle', |
|||
'sideMenuStyle', |
|||
'tabStyle', |
|||
'fixedHeader', |
|||
'fixedSidebar', |
|||
'fixedBody', |
|||
'bodyFull', |
|||
'logoAutoSize', |
|||
'colorfulIcon', |
|||
'sideUniqueOpen', |
|||
'weakMode', |
|||
'darkMode', |
|||
'color' |
|||
].forEach((key) => { |
|||
commit('SET', { key, value: DEFAULT_STATE[key] }); |
|||
}); |
|||
localStorage.removeItem(THEME_STORE_NAME); |
|||
changeWeakMode(state.weakMode); |
|||
changeTheme(state.color, state.darkMode) |
|||
.then(() => { |
|||
resolve(); |
|||
}) |
|||
.catch((e) => { |
|||
reject(e); |
|||
}); |
|||
}); |
|||
}, |
|||
// 恢复主题
|
|||
recoverTheme({ state }) { |
|||
// 恢复色弱模式
|
|||
if (state.weakMode) { |
|||
changeWeakMode(true); |
|||
} |
|||
return cache[k]; |
|||
// 恢复主题色
|
|||
if (state.color || state.darkMode) { |
|||
changeTheme(state.color, state.darkMode).catch((e) => { |
|||
console.error(e); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 切换主题 |
|||
* @param color 主题色 |
|||
* @param darkMode 是否是暗黑模式 |
|||
* @returns {Promise<>} |
|||
*/ |
|||
function changeTheme(color, darkMode) { |
|||
const version = process.env.VUE_APP_VERSION; |
|||
// 对应的css文件名
|
|||
let colorCss; |
|||
if (darkMode) { |
|||
if (color) { |
|||
colorCss = color + '-dark'; |
|||
} else { |
|||
colorCss = 'dark'; |
|||
}, |
|||
// 添加页签
|
|||
tabAdd({ dispatch, state }, data) { |
|||
if (Array.isArray(data)) { |
|||
data.forEach((d) => { |
|||
dispatch('tabAdd', d); |
|||
}); |
|||
return; |
|||
} |
|||
} else { |
|||
colorCss = color; |
|||
const i = state.tabs.findIndex((d) => d.key === data.key); |
|||
if (i === -1) { |
|||
dispatch('setTabs', state.tabs.concat([data])); |
|||
} else if (data.fullPath !== state.tabs[i].fullPath) { |
|||
dispatch( |
|||
'setTabs', |
|||
state.tabs |
|||
.slice(0, i) |
|||
.concat([data]) |
|||
.concat(state.tabs.slice(i + 1)) |
|||
); |
|||
} |
|||
// 获取缓存的主题css
|
|||
let themeCache = {}, |
|||
cacheStoreName = setting.themeStoreName + '-cache'; |
|||
if (window.eleThemeCache) { |
|||
themeCache = window.eleThemeCache; |
|||
} else { |
|||
try { |
|||
const localCache = JSON.parse(localStorage.getItem(cacheStoreName) || '{}'); |
|||
if (localCache && version === localCache.version && localCache.cache) { |
|||
themeCache = localCache.cache; |
|||
window.eleThemeCache = themeCache; |
|||
}, |
|||
// 关闭页签
|
|||
tabRemove({ dispatch, state }, key) { |
|||
return new Promise((resolve) => { |
|||
let index = -1; |
|||
let lastIndex = -1; |
|||
let last; |
|||
let lastPath; |
|||
for (let i = 0; i < state.tabs.length; i++) { |
|||
const t = state.tabs[i]; |
|||
if (t.closable && (t.key === key || t.fullPath === key)) { |
|||
index = i; |
|||
break; |
|||
} |
|||
} catch (e) { |
|||
console.error(e); |
|||
lastIndex = i; |
|||
last = state.tabs[i]; |
|||
lastPath = last.fullPath; |
|||
} |
|||
dispatch( |
|||
'setTabs', |
|||
state.tabs.filter((_d, i) => i !== index) |
|||
); |
|||
resolve({ lastIndex, lastPath, last }); |
|||
}); |
|||
}, |
|||
// 关闭全部页签
|
|||
tabRemoveAll({ dispatch, state }, active) { |
|||
return new Promise((resolve) => { |
|||
const tab = state.tabs.find((d) => d.key === active); |
|||
const stay = active ? !!(tab && tab.closable === false) : false; |
|||
dispatch( |
|||
'setTabs', |
|||
state.tabs.filter((d) => !d.closable) |
|||
); |
|||
resolve(stay); |
|||
}); |
|||
}, |
|||
// 关闭左侧页签
|
|||
tabRemoveLeft({ dispatch, state }, key) { |
|||
for (let i = 0; i < state.tabs.length; i++) { |
|||
if (state.tabs[i].key === key) { |
|||
dispatch( |
|||
'setTabs', |
|||
state.tabs |
|||
.filter((d, j) => !d.closable && j < i) |
|||
.concat(state.tabs.slice(i)) |
|||
); |
|||
break; |
|||
} |
|||
// 加载主题css
|
|||
return new Promise((resolve, reject) => { |
|||
// 恢复默认主题
|
|||
if (!colorCss) { |
|||
removeTheme(); |
|||
return resolve(); |
|||
} |
|||
// 主题css已经缓存过
|
|||
if (themeCache[colorCss]) { |
|||
removeTheme(); // 移除上次的主题
|
|||
let elem = document.createElement('style'); |
|||
elem.id = `ele-theme-${colorCss}`; |
|||
elem.setAttribute('type', 'text/css'); |
|||
elem.innerHTML = themeCache[colorCss]; |
|||
document.head.appendChild(elem); |
|||
return resolve(); |
|||
}, |
|||
// 关闭右侧页签
|
|||
tabRemoveRight({ dispatch, state }, key) { |
|||
for (let i = 0; i < state.tabs.length; i++) { |
|||
if (state.tabs[i].key === key) { |
|||
dispatch( |
|||
'setTabs', |
|||
state.tabs |
|||
.slice(0, i + 1) |
|||
.concat(state.tabs.filter((d, j) => !d.closable && j > i)) |
|||
); |
|||
break; |
|||
} |
|||
// 主题css的js模块已被加载过
|
|||
const oldElem = document.head.querySelector(`#ele-theme-${colorCss}-js`); |
|||
if (oldElem) { |
|||
removeTheme(); // 移除上次的主题
|
|||
let elem = document.createElement('link'); |
|||
elem.id = `ele-theme-${colorCss}`; |
|||
elem.setAttribute('type', 'text/css'); |
|||
elem.setAttribute('rel', 'stylesheet'); |
|||
elem.setAttribute('href', oldElem.getAttribute('ele-css')); |
|||
document.head.appendChild(elem); |
|||
return resolve(); |
|||
} |
|||
// 把head下面相关元素标记为非主题元素
|
|||
const nid = ':not([id^="ele-theme-"])', sel = `style${nid},link${nid},script${nid}`; |
|||
document.head.querySelectorAll(sel).forEach(elem => { |
|||
if (!elem.getAttribute('ele-theme')) { |
|||
elem.setAttribute('ele-theme', 'no'); |
|||
}, |
|||
// 关闭其它页签
|
|||
tabRemoveOther({ dispatch, state }, key) { |
|||
dispatch( |
|||
'setTabs', |
|||
state.tabs.filter((d) => !d.closable || d.key === key) |
|||
); |
|||
}, |
|||
// 修改页签
|
|||
tabSetItem({ dispatch, state }, data) { |
|||
let i = -1; |
|||
if (data.key) { |
|||
i = state.tabs.findIndex((d) => d.key === data.key); |
|||
} else if (data.fullPath) { |
|||
i = state.tabs.findIndex((d) => d.fullPath === data.fullPath); |
|||
} else if (data.path) { |
|||
i = state.tabs.findIndex((d) => d.path === data.path); |
|||
} |
|||
}); |
|||
// 加载主题css模块
|
|||
import(`@/styles/theme/${colorCss}.scss`).then(() => { |
|||
removeTheme(); // 移除上次的主题
|
|||
// 获取import之后的主题标签
|
|||
let elem = document.head.querySelectorAll('style:not([ele-theme="no"])'); |
|||
elem = elem.length ? elem[elem.length - 1] : null; |
|||
if (!elem) { |
|||
// 可能是style标签也可能是link标签
|
|||
elem = document.head.querySelectorAll('link:not([ele-theme="no"])'); |
|||
elem = elem.length ? elem[elem.length - 1] : null; |
|||
if (!elem) { |
|||
return reject(new Error('theme element not found.')); |
|||
if (i !== -1) { |
|||
const item = Object.assign({}, state.tabs[i]); |
|||
if (data.title) { |
|||
item.title = data.title; |
|||
} |
|||
// 再找到对应的主题js模块的标签
|
|||
const href = elem.getAttribute('href'), |
|||
uuid = href.substring(href.indexOf('chunk-'), href.indexOf('.')), |
|||
qs = `script[src^="/js/${uuid}"]:not([ele-theme="no"])`; |
|||
let node = document.head.querySelectorAll(qs); |
|||
if (node.length) { |
|||
node[node.length - 1].id = `ele-theme-${colorCss}-js`; |
|||
// 记录css地址
|
|||
node[node.length - 1].setAttribute('ele-css', href); |
|||
if (typeof data.closable === 'boolean') { |
|||
item.closable = data.closable; |
|||
} |
|||
if (data.components) { |
|||
item.components = data.components; |
|||
} |
|||
elem.id = `ele-theme-${colorCss}`; |
|||
// 缓存主题css
|
|||
if (elem.innerHTML) { |
|||
let cache = {}; |
|||
cache[colorCss] = elem.innerHTML; |
|||
try { |
|||
localStorage.setItem(cacheStoreName, JSON.stringify({ |
|||
version: version, |
|||
cache: cache |
|||
})); |
|||
} catch (e) { |
|||
console.error(e); |
|||
dispatch( |
|||
'setTabs', |
|||
state.tabs |
|||
.slice(0, i) |
|||
.concat([item]) |
|||
.concat(state.tabs.slice(i + 1)) |
|||
); |
|||
} |
|||
if (!window.eleThemeCache) { |
|||
window.eleThemeCache = {}; |
|||
} |
|||
window.eleThemeCache[colorCss] = cache[colorCss]; |
|||
} |
|||
return resolve(); |
|||
}).catch(e => { |
|||
reject(e); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 移除主题 |
|||
*/ |
|||
function removeTheme() { |
|||
const sel = 'style[id^="ele-theme-"],link[id^="ele-theme-"]'; |
|||
document.head.querySelectorAll(sel).forEach(elem => { |
|||
elem.parentNode.removeChild(elem); |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
@ -1,259 +1,91 @@ |
|||
/** |
|||
* 登录状态管理 |
|||
*/ |
|||
import axios from 'axios'; |
|||
import {util} from 'ele-admin'; |
|||
import setting from '@/config/setting'; |
|||
import { formatMenus, toTreeData, formatTreeData } from 'ele-admin'; |
|||
import { USER_MENUS } from '@/config/setting'; |
|||
import { getUserInfo } from '@/api/layout'; |
|||
|
|||
export default { |
|||
namespaced: true, |
|||
state: { |
|||
// 当前用户信息
|
|||
user: setting.takeUser(), |
|||
// 当前用户权限
|
|||
authorities: [], |
|||
// 当前用户角色
|
|||
roles: [], |
|||
// 当前用户的菜单
|
|||
// 当前登录用户信息
|
|||
info: null, |
|||
// 当前登录用户的菜单
|
|||
menus: null, |
|||
// 当前打开的选项卡
|
|||
tabs: [] |
|||
// 当前登录用户的权限
|
|||
authorities: [], |
|||
// 当前登录用户的角色
|
|||
roles: [] |
|||
}, |
|||
mutations: { |
|||
SET: (state, obj) => { |
|||
state[obj.key] = obj.value; |
|||
}, |
|||
SET_TOKEN: (state, obj) => { |
|||
setting.cacheToken(obj.token, obj.remember); |
|||
state.token = obj.token; |
|||
if (!obj.token) { |
|||
state.user = {}; |
|||
state.menus = null; |
|||
state.tabs = []; |
|||
setting.cacheUser(); |
|||
} |
|||
}, |
|||
TAB_PUSH(state, obj) { |
|||
if (!state.tabs.some(r => r.path === obj.path)) { |
|||
state.tabs.push(obj); |
|||
} |
|||
} |
|||
}, |
|||
actions: { |
|||
/** |
|||
* 缓存token |
|||
* @param commit |
|||
* @param token {String, {token: String, remember: String}} |
|||
*/ |
|||
setToken({commit}, token) { |
|||
let remember = true; |
|||
if (typeof token === 'object') { |
|||
remember = token.remember; |
|||
token = token.token; |
|||
} |
|||
commit('SET_TOKEN', {token: token, remember: remember}); |
|||
// 设置登录用户的信息
|
|||
setUserInfo(state, info) { |
|||
state.info = info; |
|||
}, |
|||
/** |
|||
* 移除token |
|||
* @param commit |
|||
*/ |
|||
removeToken({commit}) { |
|||
commit('SET_TOKEN', {}); |
|||
}, |
|||
/** |
|||
* 缓存用户信息 |
|||
* @param commit |
|||
* @param user {Object} 用户信息 |
|||
*/ |
|||
setUser({commit}, user) { |
|||
setting.cacheUser(user); |
|||
commit('SET', {key: 'user', value: user}); |
|||
}, |
|||
/** |
|||
* 设置用户权限 |
|||
* @param commit |
|||
* @param authorities {Array<String>} 权限 |
|||
*/ |
|||
setAuthorities({commit}, authorities) { |
|||
commit('SET', {key: 'authorities', value: authorities}); |
|||
}, |
|||
/** |
|||
* 设置用户角色 |
|||
* @param commit |
|||
* @param roles {Array<String>} 角色 |
|||
*/ |
|||
setRoles({commit}, roles) { |
|||
commit('SET', {key: 'roles', value: roles}); |
|||
}, |
|||
/** |
|||
* 设置用户菜单 |
|||
* @param commit |
|||
* @param menus {Array<Object>} 菜单 |
|||
*/ |
|||
setMenus({commit}, menus) { |
|||
commit('SET', {key: 'menus', value: menus}); |
|||
}, |
|||
/** |
|||
* 获取用户菜单路由 |
|||
* @param commit |
|||
* @returns {Promise<Object>} {menus: Array, home: String} |
|||
*/ |
|||
getMenus({commit}) { |
|||
return new Promise((resolve, reject) => { |
|||
if (!setting.menuUrl) { |
|||
let menus = setting.menus || []; |
|||
commit('SET', {key: 'menus', value: menus}); |
|||
return resolve({menus: menus}); |
|||
} |
|||
axios.get(setting.menuUrl).then(res => { |
|||
let result = setting.parseMenu ? setting.parseMenu(res.data) : res.data; |
|||
let menus = result.data, home = null; |
|||
if (!menus) { |
|||
return reject(new Error(result.msg)); |
|||
} |
|||
util.eachTreeData(menus, item => { |
|||
if (setting.parseMenuItem) { |
|||
item = setting.parseMenuItem(item); |
|||
} |
|||
item.meta = Object.assign({ |
|||
title: item.title, |
|||
icon: item.icon, |
|||
hide: item.hide, |
|||
active: item.active || item.uid, |
|||
hideFooter: item.hideFooter |
|||
}, item.meta); |
|||
if (!item.children || !item.children.length) { |
|||
if (!home && item.path && !( |
|||
item.path.startsWith('http://') || |
|||
item.path.startsWith('https://') || |
|||
item.path.startsWith('//') |
|||
)) { |
|||
home = item.path; |
|||
if (!setting.homeTitle) { |
|||
setting.homeTitle = item.title; |
|||
} |
|||
} |
|||
} else if (item.children[0].path) { |
|||
if (!item.redirect) { |
|||
item.redirect = item.children[0].path; |
|||
} |
|||
if (!item.path) { |
|||
const cp = item.children[0].path; |
|||
item.path = cp.substring(0, cp.lastIndexOf('/')); |
|||
} |
|||
} |
|||
}); |
|||
commit('SET', {key: 'menus', value: menus}); |
|||
resolve({menus: menus, home: home}); |
|||
}).catch(e => { |
|||
reject(e); |
|||
}); |
|||
}); |
|||
// 设置登录用户的菜单
|
|||
setMenus(state, menus) { |
|||
state.menus = menus; |
|||
}, |
|||
/** |
|||
* 添加新tab |
|||
* @param commit |
|||
* @param obj {{path: String, title: String}} tab信息 |
|||
*/ |
|||
tabAdd({commit}, obj) { |
|||
commit('TAB_PUSH', obj); |
|||
// 设置登录用户的权限
|
|||
setAuthorities(state, authorities) { |
|||
state.authorities = authorities; |
|||
}, |
|||
/** |
|||
* 关闭指定tab |
|||
* @param commit |
|||
* @param state |
|||
* @param path {String} tab路由 |
|||
* @returns {Promise<Number>} 前一个tab位置 |
|||
*/ |
|||
tabRemove({commit, state}, path) { |
|||
return new Promise((resolve) => { |
|||
let lastIndex = -1, lastPath, last; |
|||
for (let i = 0; i < state.tabs.length; i++) { |
|||
if (state.tabs[i].path === path) { |
|||
break; |
|||
} |
|||
lastIndex = i; |
|||
last = state.tabs[i]; |
|||
lastPath = last.path; |
|||
// 设置登录用户的角色
|
|||
setRoles(state, roles) { |
|||
state.roles = roles; |
|||
} |
|||
commit('SET', { |
|||
key: 'tabs', |
|||
value: state.tabs.filter(d => d.path !== path) |
|||
}); |
|||
resolve({ |
|||
lastIndex: lastIndex, |
|||
lastPath: lastPath, |
|||
last: last |
|||
}); |
|||
}); |
|||
}, |
|||
actions: { |
|||
/** |
|||
* 关闭所有tab |
|||
* @param commit |
|||
* 请求用户信息、权限、角色、菜单 |
|||
*/ |
|||
tabRemoveAll({commit}) { |
|||
commit('SET', {key: 'tabs', value: []}); |
|||
async fetchUserInfo({ commit }) { |
|||
const result = await getUserInfo(); |
|||
// 用户信息
|
|||
commit('setUserInfo', result); |
|||
// 用户权限
|
|||
const authorities = |
|||
result.authorities |
|||
?.filter((d) => !!d.authority) |
|||
?.map((d) => d.authority) ?? []; |
|||
commit('setAuthorities', authorities); |
|||
// 用户角色
|
|||
const roles = result.roles?.map((d) => d.roleCode) ?? []; |
|||
commit('setRoles', roles); |
|||
// 用户菜单, 过滤掉按钮类型并转为children形式
|
|||
const { menus, homePath } = formatMenus( |
|||
USER_MENUS ?? |
|||
toTreeData({ |
|||
data: result.authorities?.filter((d) => d.menuType === 0), |
|||
idField: 'menuId', |
|||
parentIdField: 'parentId' |
|||
}) |
|||
); |
|||
commit('setMenus', menus); |
|||
return { menus, homePath }; |
|||
}, |
|||
/** |
|||
* 关闭左侧tab |
|||
* @param commit |
|||
* @param state |
|||
* @param path {String} tab路由 |
|||
* 更新用户信息 |
|||
*/ |
|||
tabRemoveLeft({commit, state}, path) { |
|||
for (let i = 0; i < state.tabs.length; i++) { |
|||
if (state.tabs[i].path === path) { |
|||
commit('SET', { |
|||
key: 'tabs', |
|||
value: state.tabs.slice(i) |
|||
}); |
|||
break; |
|||
} |
|||
} |
|||
setInfo({ commit }, value) { |
|||
commit('setUserInfo', value); |
|||
}, |
|||
/** |
|||
* 关闭右侧tab |
|||
* @param commit |
|||
* @param state |
|||
* @param path {String} tab路由 |
|||
* 更新菜单的badge |
|||
*/ |
|||
tabRemoveRight({commit, state}, path) { |
|||
for (let i = 0; i < state.tabs.length; i++) { |
|||
if (state.tabs[i].path === path) { |
|||
commit('SET', { |
|||
key: 'tabs', |
|||
value: state.tabs.slice(0, i + 1) |
|||
setMenuBadge({ commit, state }, { path, value, color }) { |
|||
const menus = formatTreeData(state.menus, (m) => { |
|||
if (path === m.path) { |
|||
return Object.assign({}, m, { |
|||
meta: Object.assign({}, m.meta, { |
|||
badge: value, |
|||
badgeColor: color |
|||
}) |
|||
}); |
|||
break; |
|||
} |
|||
} |
|||
}, |
|||
/** |
|||
* 关闭其他tab |
|||
* @param commit |
|||
* @param state |
|||
* @param path {String} tab路由 |
|||
*/ |
|||
tabRemoveOther({commit, state}, path) { |
|||
commit('SET', { |
|||
key: 'tabs', |
|||
value: state.tabs.filter(d => d.path === path) |
|||
return m; |
|||
}); |
|||
}, |
|||
/** |
|||
* 修改指定tab标题 |
|||
* @param commit |
|||
* @param state |
|||
* @param obj {{path: String, title: String}} |
|||
*/ |
|||
tabSetTitle({commit, state}, obj) { |
|||
let i = state.tabs.findIndex(d => d.path === obj.path); |
|||
let tabs = state.tabs.slice(0, i).concat([ |
|||
Object.assign({}, state.tabs[i], { |
|||
title: obj.title |
|||
}) |
|||
]).concat(state.tabs.slice(i + 1)); |
|||
commit('SET', {key: 'tabs', value: tabs}); |
|||
commit('setMenus', menus); |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
@ -1,63 +1,9 @@ |
|||
/** 如果需要自己定义一些全局样式写在这里 */ |
|||
|
|||
$--ele-font-path: "~ele-admin/packages/style/fonts"; |
|||
|
|||
@import "./var.scss"; |
|||
@import "~ele-admin/packages/style/index.scss"; |
|||
|
|||
/* 异常页面 */ |
|||
.ele-exception { |
|||
margin: 145px 0; |
|||
|
|||
.ele-exception-img, |
|||
.ele-exception-content { |
|||
margin: 15px 30px; |
|||
display: inline-block; |
|||
vertical-align: middle; |
|||
} |
|||
|
|||
.ele-exception-content > h1 { |
|||
font-size: 72px; |
|||
font-weight: 600; |
|||
margin: 0 0 20px 0; |
|||
} |
|||
|
|||
&:not(.ele-exception-dark) .ele-exception-content > h1 { |
|||
color: #515A6E; |
|||
} |
|||
|
|||
.ele-exception-content > p { |
|||
font-size: 20px; |
|||
margin: 0 0 25px 0; |
|||
} |
|||
|
|||
&:not(.ele-exception-dark) .ele-exception-content > p { |
|||
color: #808695; |
|||
} |
|||
|
|||
&.ele-exception-dark .ele-exception-img { |
|||
opacity: .7; |
|||
} |
|||
} |
|||
|
|||
@media screen and (max-width: 768px) { |
|||
.ele-exception { |
|||
margin: 40px 0; |
|||
|
|||
.ele-exception-img { |
|||
margin: 0; |
|||
|
|||
img { |
|||
max-height: 200px; |
|||
} |
|||
} |
|||
|
|||
.ele-exception-content { |
|||
text-align: center; |
|||
} |
|||
} |
|||
} |
|||
//表格不对齐bug |
|||
.el-table th.gutter { |
|||
display: table-cell !important; |
|||
} |
|||
/** 全局样式 */ |
|||
// 如果需要覆盖更多样式变量请查看文档 |
|||
$--ele-font-path: '~ele-admin/es/style/fonts'; |
|||
// 如果不需要切换主题固定为夜间主题使用这个 |
|||
//@import "~ele-admin/es/style/themes/dark.scss"; |
|||
// 需要在线切换主题使用这个 |
|||
@import '~ele-admin/es/style/themes/dynamic.scss'; |
|||
// 全局引入样式 |
|||
@import '~ele-admin/es/style/index.scss'; |
|||
|
|||
@ -1,5 +0,0 @@ |
|||
/** 明青主题暗黑 */ |
|||
|
|||
$--color-primary: #2BCCCE; |
|||
|
|||
@import "./dark.scss"; |
|||
@ -1,6 +0,0 @@ |
|||
/** 明青主题 */ |
|||
|
|||
$--color-primary: #2BCCCE; |
|||
|
|||
@import "../var.scss"; |
|||
@import "~ele-admin/packages/style/themes/default.scss"; |
|||
@ -1,4 +0,0 @@ |
|||
/** 暗黑主题 */ |
|||
|
|||
@import "../var.scss"; |
|||
@import "~ele-admin/packages/style/themes/dark.scss"; |
|||
@ -1,5 +0,0 @@ |
|||
/** 薄暮主题暗黑 */ |
|||
|
|||
$--color-primary: #5F80C7; |
|||
|
|||
@import "./dark.scss"; |
|||
@ -1,6 +0,0 @@ |
|||
/** 薄暮主题 */ |
|||
|
|||
$--color-primary: #5F80C7; |
|||
|
|||
@import "../var.scss"; |
|||
@import "~ele-admin/packages/style/themes/default.scss"; |
|||
@ -1,5 +0,0 @@ |
|||
/** 极客蓝主题暗黑 */ |
|||
|
|||
$--color-primary: #32A2D4; |
|||
|
|||
@import "./dark.scss"; |
|||
@ -1,6 +0,0 @@ |
|||
/** 极客蓝主题 */ |
|||
|
|||
$--color-primary: #32A2D4; |
|||
|
|||
@import "../var.scss"; |
|||
@import "~ele-admin/packages/style/themes/default.scss"; |
|||
@ -1,5 +0,0 @@ |
|||
/** 极光绿主题暗黑 */ |
|||
|
|||
$--color-primary: #33CC99; |
|||
|
|||
@import "./dark.scss"; |
|||
@ -1,6 +0,0 @@ |
|||
/** 极光绿主题 */ |
|||
|
|||
$--color-primary: #33CC99; |
|||
|
|||
@import "../var.scss"; |
|||
@import "~ele-admin/packages/style/themes/default.scss"; |
|||
@ -1,5 +0,0 @@ |
|||
/** 酱紫主题暗黑 */ |
|||
|
|||
$--color-primary: #9266F9; |
|||
|
|||
@import "./dark.scss"; |
|||
@ -1,6 +0,0 @@ |
|||
/** 酱紫主题 */ |
|||
|
|||
$--color-primary: #9266F9; |
|||
|
|||
@import "../var.scss"; |
|||
@import "~ele-admin/packages/style/themes/default.scss"; |
|||
@ -1,5 +0,0 @@ |
|||
/** 日暮主题暗黑 */ |
|||
|
|||
$--color-primary: #FAAD14; |
|||
|
|||
@import "./dark.scss"; |
|||
@ -1,6 +0,0 @@ |
|||
/** 日暮主题 */ |
|||
|
|||
$--color-primary: #FAAD14; |
|||
|
|||
@import "../var.scss"; |
|||
@import "~ele-admin/packages/style/themes/default.scss"; |
|||
@ -1,5 +0,0 @@ |
|||
/** 火山主题暗黑 */ |
|||
|
|||
$--color-primary: #F5686F; |
|||
|
|||
@import "./dark.scss"; |
|||
@ -1,6 +0,0 @@ |
|||
/** 火山主题 */ |
|||
|
|||
$--color-primary: #F5686F; |
|||
|
|||
@import "../var.scss"; |
|||
@import "~ele-admin/packages/style/themes/default.scss"; |
|||
@ -1,2 +0,0 @@ |
|||
/** 如果需要覆盖框架样式变量写在这里 */ |
|||
$--sidebar-width: 220px; // 侧边栏宽度 |
|||
@ -0,0 +1,39 @@ |
|||
/** |
|||
* echarts混入 |
|||
*/ |
|||
import store from '@/store'; |
|||
import { THEME_KEY } from 'vue-echarts'; |
|||
import { ChartTheme } from 'ele-admin'; |
|||
|
|||
export function echartsMixin(refs) { |
|||
return { |
|||
provide: { |
|||
// 主题设置
|
|||
[THEME_KEY]: ChartTheme |
|||
}, |
|||
computed: { |
|||
// 内容区域宽度
|
|||
layoutContentWidth() { |
|||
return store?.state?.theme?.contentWidth; |
|||
} |
|||
}, |
|||
watch: { |
|||
// 监听内容区域宽度变化
|
|||
layoutContentWidth() { |
|||
this.resizeAllCharts(); |
|||
} |
|||
}, |
|||
// 适配keep-alive
|
|||
activated() { |
|||
this.resizeAllCharts(); |
|||
}, |
|||
methods: { |
|||
// 重置echarts尺寸
|
|||
resizeAllCharts() { |
|||
refs.forEach((ref) => { |
|||
this.$refs[ref]?.resize(); |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
@ -0,0 +1,128 @@ |
|||
/** |
|||
* 页签操作封装 |
|||
*/ |
|||
import store from '@/store'; |
|||
import router from '@/router'; |
|||
import { HOME_PATH, REDIRECT_PATH } from '@/config/setting'; |
|||
import { removeToken } from '@/utils/token-util'; |
|||
const BASE_URL = process.env.BASE_URL; |
|||
const HOME_ROUTE = HOME_PATH || '/'; |
|||
|
|||
/** |
|||
* 刷新当前路由 |
|||
*/ |
|||
export function reloadPageTab() { |
|||
const { path, fullPath, query, meta, matched } = router.currentRoute; |
|||
if (path.includes(REDIRECT_PATH)) { |
|||
return; |
|||
} |
|||
const { isHome } = meta; |
|||
setRouteReload({ |
|||
reloadHome: isHome, |
|||
reloadPath: isHome ? undefined : fullPath |
|||
}).then(() => { |
|||
router.replace({ |
|||
path: matched[matched.length - 2].path + REDIRECT_PATH + path, |
|||
query |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 关闭当前页签 |
|||
*/ |
|||
export function finishPageTab() { |
|||
const { fullPath } = router.currentRoute; |
|||
removePageTab({ key: fullPath, active: fullPath }); |
|||
} |
|||
|
|||
/** |
|||
* 关闭页签 |
|||
* @param key 页签的key |
|||
* @param active 选中页签的key |
|||
*/ |
|||
export function removePageTab({ key, active }) { |
|||
store.dispatch('theme/tabRemove', key).then(({ lastPath }) => { |
|||
if (active && key === active) { |
|||
router.push(lastPath || HOME_ROUTE); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 关闭全部页签 |
|||
*/ |
|||
export function removeAllPageTab(active) { |
|||
store.dispatch('theme/tabRemoveAll', active).then((stay) => { |
|||
if (!stay && active && active !== HOME_ROUTE) { |
|||
router.push(HOME_ROUTE); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 关闭左侧页签 |
|||
*/ |
|||
export function removeLeftPageTab(key) { |
|||
return store.dispatch('theme/tabRemoveLeft', key); |
|||
} |
|||
|
|||
/** |
|||
* 关闭右侧页签 |
|||
*/ |
|||
export function removeRightPageTab(key) { |
|||
return store.dispatch('theme/tabRemoveRight', key); |
|||
} |
|||
|
|||
/** |
|||
* 关闭其它页签 |
|||
*/ |
|||
export function removeOtherPageTab(key) { |
|||
return store.dispatch('theme/tabRemoveOther', key); |
|||
} |
|||
|
|||
/** |
|||
* 添加页签 |
|||
*/ |
|||
export function addPageTab(data) { |
|||
return store.dispatch('theme/tabAdd', data); |
|||
} |
|||
|
|||
/** |
|||
* 修改页签 |
|||
*/ |
|||
export function setPageTab(data) { |
|||
return store.dispatch('theme/tabSetItem', data); |
|||
} |
|||
|
|||
/** |
|||
* 设置主页的组件名称 |
|||
*/ |
|||
export function setHomeComponents(data) { |
|||
return store.dispatch('theme/setHomeComponents', data); |
|||
} |
|||
|
|||
/** |
|||
* 设置路由刷新信息 |
|||
*/ |
|||
export function setRouteReload(value) { |
|||
return store.dispatch('theme/setRouteReload', value); |
|||
} |
|||
|
|||
/** |
|||
* 退出登录 |
|||
* @param from 是否使用路由跳转 |
|||
* @param from 登录后跳转的地址 |
|||
*/ |
|||
export function logout(route, from) { |
|||
removeToken(); |
|||
if (route) { |
|||
router.push({ |
|||
path: '/login', |
|||
query: from ? { from } : undefined |
|||
}); |
|||
} else { |
|||
// 这样跳转避免再次登录重复注册动态路由
|
|||
location.replace(BASE_URL + 'login' + (from ? '?from=' + from : '')); |
|||
} |
|||
} |
|||
@ -1,128 +1,114 @@ |
|||
/** |
|||
* 权限、角色控制组件 |
|||
* 按钮级权限控制 |
|||
*/ |
|||
import store from '@/store'; |
|||
|
|||
/* 数组是否有某些值 */ |
|||
const arrayHas = function (array, value) { |
|||
if (!value) { |
|||
return true; |
|||
} |
|||
if (!array) { |
|||
return false; |
|||
} |
|||
if (Array.isArray(value)) { |
|||
for (let i = 0; i < value.length; i++) { |
|||
if (array.indexOf(value[i]) === -1) { |
|||
return false; |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
return array.indexOf(value) !== -1; |
|||
}; |
|||
|
|||
/* 数组是否有任意值 */ |
|||
const arrayHasAny = function (array, value) { |
|||
if (!value) { |
|||
return true; |
|||
} |
|||
if (!array) { |
|||
return false; |
|||
} |
|||
if (Array.isArray(value)) { |
|||
for (let i = 0; i < value.length; i++) { |
|||
if (array.indexOf(value[i]) !== -1) { |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
return array.indexOf(value) !== -1; |
|||
}; |
|||
|
|||
/** |
|||
* 是否有某些角色 |
|||
* @param value 角色字符或字符数组 |
|||
*/ |
|||
export function hasRole(value) { |
|||
return arrayHas(store.state.user?.roles, value); |
|||
} |
|||
|
|||
/** |
|||
* 是否有任意角色 |
|||
* @param value 角色字符或字符数组 |
|||
*/ |
|||
export function hasAnyRole(value) { |
|||
return arrayHasAny(store.state.user?.roles, value); |
|||
} |
|||
|
|||
/** |
|||
* 是否有某些权限 |
|||
* @param value 权限字符或字符数组 |
|||
*/ |
|||
export function hasPermission(value) { |
|||
return arrayHas(store.state.user?.authorities, value); |
|||
} |
|||
|
|||
/** |
|||
* 是否有任意权限 |
|||
* @param value 权限字符或字符数组 |
|||
*/ |
|||
export function hasAnyPermission(value) { |
|||
return arrayHasAny(store.state.user?.authorities, value); |
|||
} |
|||
|
|||
export default { |
|||
install(Vue) { |
|||
// 添加全局方法
|
|||
Vue.prototype.$hasRole = this.hasRole; |
|||
Vue.prototype.$hasAnyRole = this.hasAnyRole; |
|||
Vue.prototype.$hasPermission = this.hasPermission; |
|||
Vue.prototype.$hasAnyPermission = this.hasAnyPermission; |
|||
Vue.prototype.$hasRole = hasRole; |
|||
Vue.prototype.$hasAnyRole = hasAnyRole; |
|||
Vue.prototype.$hasPermission = hasPermission; |
|||
Vue.prototype.$hasAnyPermission = hasAnyPermission; |
|||
|
|||
// 添加自定义指令
|
|||
Vue.directive('role', { |
|||
inserted: (el, binding) => { |
|||
if (!this.hasRole(binding.value)) { |
|||
if (!hasRole(binding.value)) { |
|||
el.parentNode && el.parentNode.removeChild(el); |
|||
} |
|||
} |
|||
}); |
|||
Vue.directive('any-role', { |
|||
inserted: (el, binding) => { |
|||
if (!this.hasAnyRole(binding.value)) { |
|||
if (!hasAnyRole(binding.value)) { |
|||
el.parentNode && el.parentNode.removeChild(el); |
|||
} |
|||
} |
|||
}); |
|||
Vue.directive('permission', { |
|||
inserted: (el, binding) => { |
|||
if (!this.hasPermission(binding.value)) { |
|||
if (!hasPermission(binding.value)) { |
|||
el.parentNode && el.parentNode.removeChild(el); |
|||
} |
|||
} |
|||
}); |
|||
Vue.directive('any-permission', { |
|||
inserted: (el, binding) => { |
|||
if (!this.hasAnyPermission(binding.value)) { |
|||
if (!hasAnyPermission(binding.value)) { |
|||
el.parentNode && el.parentNode.removeChild(el); |
|||
} |
|||
} |
|||
}); |
|||
}, |
|||
/** |
|||
* 是否有某些角色 |
|||
* @param role {String, Array<String>} 角色字符或字符数组 |
|||
* @returns {boolean} |
|||
*/ |
|||
hasRole(role) { |
|||
const data = store.state.user ? store.state.user.roles : null; |
|||
return arrayHas(data, role); |
|||
}, |
|||
/** |
|||
* 是否有任意角色 |
|||
* @param role {String, Array<String>} 角色字符或字符数组 |
|||
* @returns {boolean} |
|||
*/ |
|||
hasAnyRole(role) { |
|||
const data = store.state.user ? store.state.user.roles : null; |
|||
return arrayHasAny(data, role); |
|||
}, |
|||
/** |
|||
* 是否有某些权限 |
|||
* @param auth {String, Array<String>} 权限字符或字符数组 |
|||
* @returns {boolean} |
|||
*/ |
|||
hasPermission(auth) { |
|||
const data = store.state.user ? store.state.user.authorities : null; |
|||
return arrayHas(data, auth); |
|||
}, |
|||
/** |
|||
* 是否有任意权限 |
|||
* @param auth {String, Array<String>} 权限字符或字符数组 |
|||
* @returns {boolean} |
|||
*/ |
|||
hasAnyPermission(auth) { |
|||
const data = store.state.user ? store.state.user.authorities : null; |
|||
return arrayHasAny(data, auth); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 数组是否有某些值 |
|||
* @param array {Array<String>} 数组 |
|||
* @param obj {String, Array<String>} 值 |
|||
* @returns {boolean} |
|||
*/ |
|||
function arrayHas(array, obj) { |
|||
if (!obj) { |
|||
return true; |
|||
} |
|||
if (!array) { |
|||
return false; |
|||
} |
|||
if (Array.isArray(obj)) { |
|||
for (let i = 0; i < obj.length; i++) { |
|||
if (array.indexOf(obj[i]) === -1) { |
|||
return false; |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
return array.indexOf(obj) !== -1; |
|||
} |
|||
|
|||
/** |
|||
* 数组是否有任意值 |
|||
* @param array {Array<String>} 数组 |
|||
* @param obj {String, Array<String>} 值 |
|||
* @returns {boolean} |
|||
*/ |
|||
function arrayHasAny(array, obj) { |
|||
if (!obj) { |
|||
return true; |
|||
} |
|||
if (!array) { |
|||
return false; |
|||
} |
|||
if (Array.isArray(obj)) { |
|||
for (let i = 0; i < obj.length; i++) { |
|||
if (array.indexOf(obj[i]) !== -1) { |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
return array.indexOf(obj) !== -1; |
|||
} |
|||
}; |
|||
|
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue