New file |
| | |
| | | # 告诉EditorConfig插件,这是根文件,不用继续往上查找 |
| | | root = true |
| | | |
| | | # 匹配全部文件 |
| | | [*] |
| | | # 设置字符集 |
| | | charset = utf-8 |
| | | # 缩进风格,可选space、tab |
| | | indent_style = space |
| | | # 缩进的空格数 |
| | | indent_size = 2 |
| | | # 结尾换行符,可选lf、cr、crlf |
| | | end_of_line = lf |
| | | # 在文件结尾插入新行 |
| | | insert_final_newline = true |
| | | # 删除一行中的前后空格 |
| | | trim_trailing_whitespace = true |
| | | |
| | | # 匹配md结尾的文件 |
| | | [*.md] |
| | | insert_final_newline = false |
| | | trim_trailing_whitespace = false |
New file |
| | |
| | | # 页面标题 |
| | | VUE_APP_TITLE = 档案管理系统 |
| | | |
| | | # 开发环境配置 |
| | | ENV = 'development' |
| | | |
| | | # 若依管理系统/开发环境 |
| | | VUE_APP_BASE_API = '/dev-api' |
| | | #VUE_APP_BASE_TRUE_API = 'https://www.bendudu.com:8080/' |
| | | #VUE_APP_BASE_OTHER_API = 'https://www.bendudu.com:8085/' |
| | | |
| | | # 路由懒加载 |
| | | VUE_CLI_BABEL_TRANSPILE_MODULES = true |
New file |
| | |
| | | # 页面标题 |
| | | VUE_APP_TITLE = 档案管理系统 |
| | | |
| | | # 生产环境配置 |
| | | ENV = 'production' |
| | | |
| | | # 若依管理系统/生产环境 |
| | | VUE_APP_BASE_API = '/prod-api' |
New file |
| | |
| | | # 页面标题 |
| | | VUE_APP_TITLE = 若依管理系统 |
| | | |
| | | BABEL_ENV = production |
| | | |
| | | NODE_ENV = production |
| | | |
| | | # 测试环境配置 |
| | | ENV = 'staging' |
| | | |
| | | # 若依管理系统/测试环境 |
| | | VUE_APP_BASE_API = '/stage-api' |
New file |
| | |
| | | module.exports = { |
| | | presets: [ |
| | | // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app |
| | | '@vue/cli-plugin-babel/preset' |
| | | ], |
| | | 'env': { |
| | | 'development': { |
| | | // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require(). |
| | | // This plugin can significantly increase the speed of hot updates, when you have a large number of pages. |
| | | 'plugins': ['dynamic-import-node'] |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | @echo off |
| | | echo. |
| | | echo [信息] 打包Web工程,生成dist文件。 |
| | | echo. |
| | | |
| | | %~d0 |
| | | cd %~dp0 |
| | | |
| | | cd .. |
| | | npm run build:prod |
| | | |
| | | pause |
New file |
| | |
| | | @echo off |
| | | echo. |
| | | echo [信息] 安装Web工程,生成node_modules文件。 |
| | | echo. |
| | | |
| | | %~d0 |
| | | cd %~dp0 |
| | | |
| | | cd .. |
| | | npm install --registry=https://registry.npmmirror.com |
| | | |
| | | pause |
New file |
| | |
| | | @echo off |
| | | echo. |
| | | echo [信息] 使用 Vue CLI 命令运行 Web 工程。 |
| | | echo. |
| | | |
| | | %~d0 |
| | | cd %~dp0 |
| | | |
| | | cd .. |
| | | npm run dev |
| | | |
| | | pause |
New file |
| | |
| | | const { run } = require('runjs') |
| | | const chalk = require('chalk') |
| | | const config = require('../vue.config.js') |
| | | const rawArgv = process.argv.slice(2) |
| | | const args = rawArgv.join(' ') |
| | | |
| | | if (process.env.npm_config_preview || rawArgv.includes('--preview')) { |
| | | const report = rawArgv.includes('--report') |
| | | |
| | | run(`vue-cli-service build ${args}`) |
| | | |
| | | const port = 9526 |
| | | const publicPath = config.publicPath |
| | | |
| | | var connect = require('connect') |
| | | var serveStatic = require('serve-static') |
| | | const app = connect() |
| | | |
| | | app.use( |
| | | publicPath, |
| | | serveStatic('./dist', { |
| | | index: ['index.html', '/'] |
| | | }) |
| | | ) |
| | | |
| | | app.listen(port, function () { |
| | | console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) |
| | | if (report) { |
| | | console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) |
| | | } |
| | | |
| | | }) |
| | | } else { |
| | | run(`vue-cli-service build ${args}`) |
| | | } |
New file |
| | |
| | | { |
| | | "name": "ruoyi", |
| | | "version": "3.9.0", |
| | | "description": "若依管理系统", |
| | | "author": "若依", |
| | | "license": "MIT", |
| | | "scripts": { |
| | | "dev": "vue-cli-service serve", |
| | | "build:prod": "vue-cli-service build", |
| | | "build:stage": "vue-cli-service build --mode staging", |
| | | "preview": "node build/index.js --preview" |
| | | }, |
| | | "keywords": [ |
| | | "vue", |
| | | "admin", |
| | | "dashboard", |
| | | "element-ui", |
| | | "boilerplate", |
| | | "admin-template", |
| | | "management-system" |
| | | ], |
| | | "repository": { |
| | | "type": "git", |
| | | "url": "https://gitee.com/y_project/RuoYi-Vue.git" |
| | | }, |
| | | "dependencies": { |
| | | "@riophae/vue-treeselect": "0.4.0", |
| | | "axios": "0.28.1", |
| | | "clipboard": "2.0.8", |
| | | "core-js": "3.37.1", |
| | | "echarts": "5.4.0", |
| | | "element-ui": "2.15.14", |
| | | "file-saver": "2.0.5", |
| | | "fuse.js": "6.4.3", |
| | | "highlight.js": "9.18.5", |
| | | "js-beautify": "1.13.0", |
| | | "js-cookie": "3.0.1", |
| | | "jsencrypt": "3.0.0-rc.1", |
| | | "nprogress": "0.2.0", |
| | | "quill": "2.0.2", |
| | | "screenfull": "5.0.2", |
| | | "sortablejs": "1.10.2", |
| | | "splitpanes": "2.4.1", |
| | | "vue": "2.6.12", |
| | | "vue-count-to": "1.0.13", |
| | | "vue-cropper": "0.5.5", |
| | | "vue-router": "3.4.9", |
| | | "vuedraggable": "2.24.3", |
| | | "vuex": "3.6.0" |
| | | }, |
| | | "devDependencies": { |
| | | "@vue/cli-plugin-babel": "4.4.6", |
| | | "@vue/cli-service": "4.4.6", |
| | | "babel-plugin-dynamic-import-node": "2.3.3", |
| | | "chalk": "4.1.0", |
| | | "compression-webpack-plugin": "6.1.2", |
| | | "connect": "3.6.6", |
| | | "sass": "1.32.13", |
| | | "sass-loader": "10.1.1", |
| | | "script-ext-html-webpack-plugin": "2.1.5", |
| | | "svg-sprite-loader": "5.1.1", |
| | | "vue-template-compiler": "2.6.12" |
| | | }, |
| | | "engines": { |
| | | "node": ">=8.9", |
| | | "npm": ">= 3.0.0" |
| | | }, |
| | | "browserslist": [ |
| | | "> 1%", |
| | | "last 2 versions" |
| | | ] |
| | | } |
New file |
| | |
| | | |
| | | <!DOCTYPE html> |
| | | <html lang="zh-CN"> |
| | | <head> |
| | | <meta charset="UTF-8" /> |
| | | <title>请升级您的浏览器</title> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" > |
| | | <meta name="renderer" content="webkit"> |
| | | <base target="_blank" /> |
| | | <style type="text/css"> |
| | | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0} |
| | | a{text-decoration:none;color:#0072c6;}a:hover{text-decoration:none;color:#004d8c;} |
| | | body{width:960px;margin:0 auto;padding:10px;font-size:14px;line-height:24px;color:#454545;font-family:'Microsoft YaHei UI','Microsoft YaHei',DengXian,SimSun,'Segoe UI',Tahoma,Helvetica,sans-serif;overflow-y:scroll} |
| | | h1{font-size:40px;line-height:80px;font-weight:100;margin-bottom:10px;} |
| | | h2{font-size:20px;line-height:25px;font-weight:100;margin:10px 0;} |
| | | em{color:red} |
| | | p{margin-bottom:10px;} |
| | | hr{margin:20px 0;border:0;border-top:1px solid #dadada} |
| | | span{display:block;font-size:12px;line-height:12px;} |
| | | .clean{clear:both;} |
| | | .browser{padding:10px 10px;} |
| | | .browser li{width:auto;padding:0 80px;margin-top:30px;height:34px;line-height:22px;float:left;list-style:none;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAADMCAYAAAAWCXEwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKTWlDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVN3WJP3Fj7f92UPVkLY8LGXbIEAIiOsCMgQWaIQkgBhhBASQMWFiApWFBURnEhVxILVCkidiOKgKLhnQYqIWotVXDjuH9yntX167+3t+9f7vOec5/zOec8PgBESJpHmomoAOVKFPDrYH49PSMTJvYACFUjgBCAQ5svCZwXFAADwA3l4fnSwP/wBr28AAgBw1S4kEsfh/4O6UCZXACCRAOAiEucLAZBSAMguVMgUAMgYALBTs2QKAJQAAGx5fEIiAKoNAOz0ST4FANipk9wXANiiHKkIAI0BAJkoRyQCQLsAYFWBUiwCwMIAoKxAIi4EwK4BgFm2MkcCgL0FAHaOWJAPQGAAgJlCLMwAIDgCAEMeE80DIEwDoDDSv+CpX3CFuEgBAMDLlc2XS9IzFLiV0Bp38vDg4iHiwmyxQmEXKRBmCeQinJebIxNI5wNMzgwAABr50cH+OD+Q5+bk4eZm52zv9MWi/mvwbyI+IfHf/ryMAgQAEE7P79pf5eXWA3DHAbB1v2upWwDaVgBo3/ldM9sJoFoK0Hr5i3k4/EAenqFQyDwdHAoLC+0lYqG9MOOLPv8z4W/gi372/EAe/tt68ABxmkCZrcCjg/1xYW52rlKO58sEQjFu9+cj/seFf/2OKdHiNLFcLBWK8ViJuFAiTcd5uVKRRCHJleIS6X8y8R+W/QmTdw0ArIZPwE62B7XLbMB+7gECiw5Y0nYAQH7zLYwaC5EAEGc0Mnn3AACTv/mPQCsBAM2XpOMAALzoGFyolBdMxggAAESggSqwQQcMwRSswA6cwR28wBcCYQZEQAwkwDwQQgbkgBwKoRiWQRlUwDrYBLWwAxqgEZrhELTBMTgN5+ASXIHrcBcGYBiewhi8hgkEQcgIE2EhOogRYo7YIs4IF5mOBCJhSDSSgKQg6YgUUSLFyHKkAqlCapFdSCPyLXIUOY1cQPqQ28ggMor8irxHMZSBslED1AJ1QLmoHxqKxqBz0XQ0D12AlqJr0Rq0Hj2AtqKn0UvodXQAfYqOY4DRMQ5mjNlhXIyHRWCJWBomxxZj5Vg1Vo81Yx1YN3YVG8CeYe8IJAKLgBPsCF6EEMJsgpCQR1hMWEOoJewjtBK6CFcJg4Qxwicik6hPtCV6EvnEeGI6sZBYRqwm7iEeIZ4lXicOE1+TSCQOyZLkTgohJZAySQtJa0jbSC2kU6Q+0hBpnEwm65Btyd7kCLKArCCXkbeQD5BPkvvJw+S3FDrFiOJMCaIkUqSUEko1ZT/lBKWfMkKZoKpRzame1AiqiDqfWkltoHZQL1OHqRM0dZolzZsWQ8ukLaPV0JppZ2n3aC/pdLoJ3YMeRZfQl9Jr6Afp5+mD9HcMDYYNg8dIYigZaxl7GacYtxkvmUymBdOXmchUMNcyG5lnmA+Yb1VYKvYqfBWRyhKVOpVWlX6V56pUVXNVP9V5qgtUq1UPq15WfaZGVbNQ46kJ1Bar1akdVbupNq7OUndSj1DPUV+jvl/9gvpjDbKGhUaghkijVGO3xhmNIRbGMmXxWELWclYD6yxrmE1iW7L57Ex2Bfsbdi97TFNDc6pmrGaRZp3mcc0BDsax4PA52ZxKziHODc57LQMtPy2x1mqtZq1+rTfaetq+2mLtcu0W7eva73VwnUCdLJ31Om0693UJuja6UbqFutt1z+o+02PreekJ9cr1Dund0Uf1bfSj9Rfq79bv0R83MDQINpAZbDE4Y/DMkGPoa5hpuNHwhOGoEctoupHEaKPRSaMnuCbuh2fjNXgXPmasbxxirDTeZdxrPGFiaTLbpMSkxeS+Kc2Ua5pmutG003TMzMgs3KzYrMnsjjnVnGueYb7ZvNv8jYWlRZzFSos2i8eW2pZ8ywWWTZb3rJhWPlZ5VvVW16xJ1lzrLOtt1ldsUBtXmwybOpvLtqitm63Edptt3xTiFI8p0in1U27aMez87ArsmuwG7Tn2YfYl9m32zx3MHBId1jt0O3xydHXMdmxwvOuk4TTDqcSpw+lXZxtnoXOd8zUXpkuQyxKXdpcXU22niqdun3rLleUa7rrStdP1o5u7m9yt2W3U3cw9xX2r+00umxvJXcM970H08PdY4nHM452nm6fC85DnL152Xlle+70eT7OcJp7WMG3I28Rb4L3Le2A6Pj1l+s7pAz7GPgKfep+Hvqa+It89viN+1n6Zfgf8nvs7+sv9j/i/4XnyFvFOBWABwQHlAb2BGoGzA2sDHwSZBKUHNQWNBbsGLww+FUIMCQ1ZH3KTb8AX8hv5YzPcZyya0RXKCJ0VWhv6MMwmTB7WEY6GzwjfEH5vpvlM6cy2CIjgR2yIuB9pGZkX+X0UKSoyqi7qUbRTdHF09yzWrORZ+2e9jvGPqYy5O9tqtnJ2Z6xqbFJsY+ybuIC4qriBeIf4RfGXEnQTJAntieTE2MQ9ieNzAudsmjOc5JpUlnRjruXcorkX5unOy553PFk1WZB8OIWYEpeyP+WDIEJQLxhP5aduTR0T8oSbhU9FvqKNolGxt7hKPJLmnVaV9jjdO31D+miGT0Z1xjMJT1IreZEZkrkj801WRNberM/ZcdktOZSclJyjUg1plrQr1zC3KLdPZisrkw3keeZtyhuTh8r35CP5c/PbFWyFTNGjtFKuUA4WTC+oK3hbGFt4uEi9SFrUM99m/ur5IwuCFny9kLBQuLCz2Lh4WfHgIr9FuxYji1MXdy4xXVK6ZHhp8NJ9y2jLspb9UOJYUlXyannc8o5Sg9KlpUMrglc0lamUycturvRauWMVYZVkVe9ql9VbVn8qF5VfrHCsqK74sEa45uJXTl/VfPV5bdra3kq3yu3rSOuk626s91m/r0q9akHV0IbwDa0b8Y3lG19tSt50oXpq9Y7NtM3KzQM1YTXtW8y2rNvyoTaj9nqdf13LVv2tq7e+2Sba1r/dd3vzDoMdFTve75TsvLUreFdrvUV99W7S7oLdjxpiG7q/5n7duEd3T8Wej3ulewf2Re/ranRvbNyvv7+yCW1SNo0eSDpw5ZuAb9qb7Zp3tXBaKg7CQeXBJ9+mfHvjUOihzsPcw83fmX+39QjrSHkr0jq/dawto22gPaG97+iMo50dXh1Hvrf/fu8x42N1xzWPV56gnSg98fnkgpPjp2Snnp1OPz3Umdx590z8mWtdUV29Z0PPnj8XdO5Mt1/3yfPe549d8Lxw9CL3Ytslt0utPa49R35w/eFIr1tv62X3y+1XPK509E3rO9Hv03/6asDVc9f41y5dn3m978bsG7duJt0cuCW69fh29u0XdwruTNxdeo94r/y+2v3qB/oP6n+0/rFlwG3g+GDAYM/DWQ/vDgmHnv6U/9OH4dJHzEfVI0YjjY+dHx8bDRq98mTOk+GnsqcTz8p+Vv9563Or59/94vtLz1j82PAL+YvPv655qfNy76uprzrHI8cfvM55PfGm/K3O233vuO+638e9H5ko/ED+UPPR+mPHp9BP9z7nfP78L/eE8/sl0p8zAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAC7ESURBVHja5Lx5dFRV1rBfgHwYRQQVtB26ZWhtabtfeUGxGxFbUGZF8RMHGkVbRkekVYiKisicVhE0gEwBokgDAhEMMSSQkAECwcxkrlRSqVTqJqnxzs/vj5t7qUyAvr9e37fWV2vtleSm6p6n9t5nn733OVU2RaUaEP5PiqJSbeMXPBTA5/Xhzk9Vnd9vo3HFx21E2LYJX9IRgh6npvyCe9uaqS4K4C3IpXHFx9S99CTuJ8Z0KLVjRlA7ZgTuJ8ZgXxmJL+kIlwAkXBQk6HFq9pWRVA8fSvXwodYgdS892a6EA1UNvouqwXdR99KTeAtyfz2IL+kI1cOHYh9wqwVwKWJqpXbMCOv19gG3Imzb1JF2OgZxfr/NukH4jcNVfyEAE8IU+4BbKet1PfaVke3BtA/i/H6b8aIBt7a4mWmaC0nr55vmqRp8F5V33Mm5LhHtwbQF8SUdsSDCb1I1+K42g1xIWgOYYh9wK+e6RCBs29QxSIWus37aJM51iWjx4so77mwD1d5AHQ1eecedlN9yuyVlva6nrNf14Q7cEmRn4W7u3T2E9ME3UX7L7W1uZg5Weced1s3sA2613ql5LXzQjuRclwjcT4wxTXQeRHC7GLdnHPeensiCVwa3e0PznZk3EbZtwluQa0kofz8NcVNxr++Ce30XnNuv61Bcu7viXt8Fvyu7JYipjfGHxzD+8Bh2j+7fAiZcC+Y0zPDIbCyD6DyV6DyVeDcIQR2C39J4oieNJ3oSOnkVcnZ35Ozu6MVdDHF0N6S4C43OqJYg/0ydzb27hzDx0FjuPT2R+asfa6OVsl7X40s6QoWus/CQk6fWZPHChhxe3lbMCxtyrN9TyxSQSwidvMoC0XK6tRGybPjSRmOuNUKVo4Zxe8YxIu4+Jh4ay/jDY7j39MQWWjnXJYLGFR9Toes8tSaLiavTrIHDxfxfapkCwW8hy9YuhCmhk1fR1FRnaCS1NM4yy8RDYy2tjIkZRXq/HtYsCnqc2sJDTkYsTrU00J6YkEJQR7M/eEGY0MmrcOenqjZA2JmyzTJLuJiOe65LBHUvPUmGR2bE4lQmrk7jqTVZHcrE1WkMWpRIdJ4KnpUXBCHLRl3e16EWIOEaMU00/vAY9na/gsYVH/NdgYe+8w9bMBeSQYsSWXjICcFvL2ga+dhlFwcJ10rjio/ZklprgbSWiavTWvzdd/5hXt5W/OtATC201sq9u4eQ+PVijmSW0nf+YQYtSmTQosR2gUYsTmXQokT6zj9saeRCpmkJ0hxD2gOZeGgsI+Lu45+ps7FXlFmDmDDtSd/5h+k7/zCpZQpa9cwOQciyIR+77LyzFhXlMyZmFOP2jLP8orVWRsTdR2ppHFtSa+k6ZZM1WHvSdcomwyxySceayO4OWTY88TdirygzUkWf18eL2//RQiutYcwYE/Q4tagDOUQ8uo6uUzbRZ3qMJV2nbCLi0XU8tSbrolNXzu6OfOyylgEN4NOkaO5acw/j9ozr0ET37h5imehIZimPL91rAfSZHsOQBfuISS7E7vaTETeX0MmrOoQInbwK+dhlNKWsahni0zPSuGvNPW1M1BrI1NrOwt0WkCn2ijJSS+MYt2ccuQk3oxd36RCi8URPY+HLT1VbgGiSzPsx71laCddMe2Yygf6ZOtuScXvG0XfJn/n8YL+LQnjibyQ34WZ8Xl/bfKSoKL+FVi4EYwKZcu/uIQzaPoExMaPQcrq1ADFX33AI1+6u1OV9HVI6ShU/TYqm75I/dwjTHtDEQ2MZt2ccg7ZPaGGScIDWEBlxc42UoSMQ00StYdoDCgcbtH0Cbx+8p40ZTIBwiFM7RmB3+y+exZvT2YRpDdR6ZoVrw1xRWwN44m/Euf06A6Ki7NLrmnDNmH7TEdSg7RP4/GA/yLK1GdwEKNzSk1M7RlDlqPl1JefOlG2MXTGmXaAxMaMsB/XE34h4tH+7ANlrB7T2iV8OAlDlqOH9mPcsIBPKlF3R16Ad7GwlxoVberYAKCrKv1ghfmkg5sPldLIzZVsLqLErxpC9doAlp3aMICNurlGyVpRdSAu/HqS1Q58rd1JUlI87P1UtKsrHXlGG3e1HCOoov+x2wiX3RxT+o49L1IgutXxVUCfDIxNfLraQDI+M3e3/NdCXbhohqBNfLrIsVzZqmoT6dmXG0SBLTrmJLxd/CVRLECXcDGFaSC1TmHE0yKg4B0P2uxiy38WoOAePHaptAfHYoVqG7HcxcGc5o+IcfFfgsbQUPoYoSa213BbE78oGucTSwpJTbobFFjNgbQHdvi6g8/Z6Om+vZ8h+VxsQE7T/97UMWFvA+Og0UvIryfDIZBQ4CeXvt8a5IAhAY/RImlJWUaHrPHaolhuXFXHN+8e58qNcbomq5P6t3xG973WePLzPgnnsUG0LiP7f1zJwZzk3LisyctfSOFxOJ4lfLzYToQubxu/KpmpWBFWzInguOokrP8ql7/zDRMxLpFfUabasHwlZNnITbmbgznI6b6+3Bu7/fa2lrW5fF9Ar6jQD1hYwLLaYx5fupdi+EiGok748koa4qa010xKkKWUV2UM7kd6vB7tH9yfpnUFkLzQiZOGWnmgHO9N4oie9ok5bA4YPbkqvqNNc8/5xIuYl8tSaLOLLRXambENXF+PxNJD0ziAanVHhYaEliH1lJD/1iqD0qSsIzu2M/N550TZ3QjvYmS3rR1qDtwdhgpgwnabGMj46zRjQsxJdXYw7P1X1pY0GuaRjkMKxPah5qxuV8y6nct7l1LzVDfdyo6miHexM+ou9mblwKfdv/Y77t37HNe8fbwMQDhIxL5FOU2PZklqLJjUYdU7wWxBuN+ricBAF0KQG6pcNovZpw0fCQao/MEBcu7tSOLYHjnu7EZzbmeDczqyfNokrP8ptMXi4XDnzAJ0n72TIgn1oUoMB4VlpgIjj24I0payi9KkrqHj+Ssth2wM5c38f8p68D2nbHKRtc3h86d42A/eZHsOVMw9Y0nXKJmxDvyS1NA70z8Gz0qh5hNvbzpr6ZYMofzyiBUwLkOVdjfR/eVcao0dSl/d1aHx0GhHzEi0TXDnzAJ2mxtJpaixdp2yypM/0GLrcs5D3Y94ztNDsK7qjuxmzDBBz2rYGqZoVQc1b3dr4yfppk+g8eWeLd91aAxGPrqPbyKV0G7mUiEfXMWdz+nmQ0Jsgn1AbT/SkMXrkeZC6vK9DpU9d0S5I5bzLqf6gq6UV7WBn5q9+zDJBuEQ8us4SE6LLPQvpcs9CjmSW4ndlo1XPNBxWLiE34WbSX+wNapEBEsrfT/njERSO7WGBmDA1b3Wj9KkrSO/Xg1WjBjJl/CT+8sQ8a0BT/eGDhwN0uWchXe94ia07YkE+oSLc3gxyQt2yfiSrRg0E+YRqgRSO7UHh2B4UT7ragqmcdznFk67mp14ROO7txpTxk7AN/bLFgN1GLsU29EvrejiACdG59xQjKgu3GzVP9UwIvcmCVwYb102NmBHVBDFNVDUrgjP39yF98E0E5xox5Dcj5lsDhwOYQObg4dK59xR2RV8D4njEo/0NIEd3dkVfgy9t9HkfMTWSO6pXG63kjupF8aSrqXj+SoJzO1M573KmjJ/Eb0bM5y9PzGPBK4Mp3GKUEFvWj+Q3I+a3AOjcewp/eWKesUQ0T1mz2att7oSU9+F5EE2SqXvpSbKHdrIGNmHCoapmRVgh33LezZ3QNncyloGDnVnwyuA2IFvWj0Q+dplREzu6Wy0r9/KubVvg9pWRpPfrwZn7+1haMSHCxdSM/J4RWWufjiC9Xw/m9PgtN9w0uo1JbrhpNI0njAXTrAIbT/TEvb4LjdEj2641vqQjpPfrQfrgm1qYKHxKlz51BbmjerFj4G2WtAYwtWDKglcGG2ZoXrldu43AWDUrAmnbnLaRVZMayHvyPn7qZThoa38pfeoKap+OIDi3M6tGDeSGm0a3GTT82g03jeaGm0bj3H4d8rHLrN0I93LDpDsG3kb68si2a425hfZTrwjSB9/UBiZcM+YM6ghoyvhJpL/Ym+yFhknc67tYQVF+z3gjc3r8Fuf32zpOFTMeHXpRGDNfMYF2j+7PqlEDWTVqIOkv9rZ8SNvcCff6LlTOu9yK1Okv9mZOj9+S8ehQNKmBDhs17vxU9adeES1gwoHKH49oFyhcwhfKynmXWzOu4vkryR7aieyhnQjl7+84QzNNJGzbxN7uV1gw7WmntYZaLw2mmNdrn44ge2gnztzfx9od7zBnDa9t0pdHtgsTDhRustaaCndwEyLj0aG481PVS9r3FSUJj6eBrConMZHvnodpntrh2gkHCgcLl/TBN7G3+xXGLMlIo0LXjU7ixeoaUZIQ3C7OlTtJya8kJvJddgy8DctvWgGFaylcHPd2Y2/3K5jT47esGjWQrTtiyapy4nI6jUrvUmpfUytFRfmkZ6SxdUcs66dNYsfA2ywNtQBrJeb/dgy8jZjId/kx4YgF4fP6Ln1L3uyhhWvnSGYpOw6lEBP5LuunTWLDAw+x4YGHrAi74YGHWD9tEuunTSIm8l227ohtAyBK0i8/pNDagTVJxuf1YXf7OVfuJKvKMF16RhrpGWkcySwlJb+SrCqn1awRgjqaJP9nO0b/Zxo1v+ahS0ZqKJ9QCX5rJMyhN42aRj6h/udB5BKjiAp+i64uNrJ2M0Vs3rUiy4aU92G42X49iCYZDZjUMoX4ctFIcILfGgVU6E0LwEyCxKP98aWNxpc2GvFof+RjlyHlfdjxWnOxh93tJya5kIWHnDx2qJbnopP4NCmaYvtKC0LL6WYkQps70RA3laaUVbjzU1V7RRn2ijK8BbkWUJsM7VIAog7k8MyuPKtD1AJA/9zQQpYN9/oubFk/kpkLl7J4a0KbtrdZa/vSRrfMWS8GcSSzlGd25TH5VIjptTpR9T5SS+OMsrHZD3RHd7SDnTm1YwSzY2KsTtL46DSei07iSGZpm/tKeR8a5gnf0+vI8zfE5zAstpjptTrvifBJeeZ5LTQDkGXDtbsr0fte59mjDmaWaUyv1ZlZpvH3XJlRcQ6Grj5OTHJhy/t7VhrpwMVAog7kMCrOwcs+nZWaccak2L7S0oLpC6d2jGDJiUyWN8E6FVZqsLwJ5ruwYO5O9jFoUSIb4nPOT+/gtxf3kZjkQobFFreAaHRGGZoQbm+hhWd25fHsUQevHilgbo7bAmoNM2S/i6Grj3Mks9Tolcgn1Hb39MzHuXInw9edZrJd4z3xPISuLrYgCrf0ZOuOWKLzVFLLFDIKmlfr5EJmHMxhfoWvDczkUyELxl5RduFUUZNkIvdm8+BpkZd9eocQPyYc6XDnocpRQ+TebObmuFmptdTK5FMhBqwt4K1vMi4cWTMKnIyKczDZrvFJeWaHEBdrbVc5aphxMIflTR1rJaPA2TFI1IEc7k72tZwdYRCLtyZc6h4MMcmF7WrlwRSRAWsLiNyb3T6Iz+vjmV15jIpztIHwxN/I7JgY4svFS47CHk9DG62Y5hm4s5zx0Wntb0CnlikMiy3m06ToFpFSO9iZnSnbeGZXHkcyS8kocF6SHMksZc7m9AuaJyW/si3IltRaZsfEGNM09KZVs2bEzWV5EyzLlXn1SEG7MuNgTruy5JS73dlzd7IvPMi1BIlJLmRnyjbLJFawar7ZHi5NdrSS9jRyd7KPXlGnzQDXyjSlcYY2mk1SuKUnS05kslI7f9M9/HKgdaoh74nn/cR02NV7M9t2A9A/t/qf2uZOvB/zHvNdxk3Mm0bV+36VzK8wxHTWVutPmEbkE6q1hjQ3/yefCvGeeB7k1SPGlLsUeeubDOtnezJnczpvfZPBuXJnGEjzAqSri9FyulG4pSf3b/3OCvErNQNmxsEczpU70ST5kuWXJc9yiZXemQ3du5N9TK/VedmnW1qZm+M+v3r+gpTS42nA42nA5XRa4vE0hFd8zSDBb63cInvtAAYtSuTuZB+T7ZoFYy7tz+zK6+igQZtHRoGTyL3ZLab4M7vyGB+dxpAF+1i8NaEliLmWyNndsa+MZPi60/T/vpaJhTKT7ZqllZWaoZW3vsnA42m4IMS5cifPRScxN8fNeyK87NOZXqszsdDITa55/3i4dgVb0OPUTG2IR/vjzk9Vt6Qau5R3J/uYWCi3MJEJM2dzOkcyS80Q3WKrPia50IIIX2cmnwrxYIpIr6jTPBed1Mo0apFgpv0NcVMR3C5ESWLO5nS6fV3Ag6fFdmHmV/iYcTCHyL3ZRB3IsSRybzbP7MpjfoWvXYj+39cyZME+c7aEgTQ36smy0RA31dostrv9DF193IIJ9xcTxgSam+O2xAQwg9fMMo2JhTIPnjYgBi1KbC+RPq8REyR8iT9X7rRgWptpvssYLBwqHGB6rc7fc2ULYsh+F4MWJbLjUErH09c8ytcaxNTMCxtyGLC2oIUDT6/VO5TJdkMLJsTAneUMWpTYNotvE0eaj3rKxy6zun2t69mdKdt4fOley4lN35ls11pIOIC51D8XnWQu9xcGUQCteibyscuM5n31TKNqD5fm1H9DfA7PRScxdPVxhsUWMyy22Dq4MGS/i2GxxQxfd9oC2HEopb1WVcdtCU2Sqcv7OmTWpGbRLOV9SCh/P0GPUwvPvDIKnMQkFxK5N5s5m9N5LjqJ56KTeOubDFbvzSQlv7LN1P5FxzZ8Xp918v8SWk5WsWStLbr0a5oLHRdY/+GjPP8vtq7+0yCiJOHz+hDcLlxOJ2bzxeV0Irhdlk/9x0B8Xh9VjhoEt6s5rZTaFU1qQHC7qHLU/PpZ05EGqhw1uJxO0CVESSIlv5KoAznM2ZxufTJgzuZ0og7kkJJfaR1mcjmdVDlqflkc6ahSs1eUWdMzJrmQQYsSrYMJNy4raiHmYQWzD2IC2SvKLpa/dAzi8/qsc6cZBU6GLNjHlTMPcEtUJVMSdd45qRGdp7KxDOvDPu+c1JhxNMgtUZVcOfMAQxbss0K7vaLsQqbq+GCtCbEhPodOU2O58qNcZhwNsrMK4t0Xlp1VMONokCs/yqXT1FgrE7sATPvbJK0hblxWxDsnNWugvc7zcqFry3JlbomqbANzSdskpk9kFDjpOmWTpQnzne6sMgbbWWWYY8kpN0tOuYnOU1v8z9TcOyc1blxWRNcpmwwz6dLFjxr7vD5rY+eO13YSMS+Rh/co1iAby4wBluXKLDnl5rsCD1lVxk7FdwUelpxysyxXbvHcjWUwYb9CxLxE7nhtp7X10spELUHMMiHqQA6dJ+9k8KYaJh1u6ZRLTrnZklrb+hS3lURtSa1lySm39fyNZTAlUWfwpho6T95p1rqtS5LzICapJsmWNkbEBpiSqLMs1/gY3DsntfAuT4tDlkrYtci92bxzUmNjmaG9KYk6I2IDbbTStsBqjhma1EBKfiVdp2xiwNoCHt6jMOmwxjsnNev46KWUkaIksfCQk2W5Mu+c1Jh0WGPCfoUBawvoOmWT1d4Miy3nQczIuXpvJp2mxjJ4Uw0T9hsg09KM6fhcdBIxyYWXJM9FJzHjaJBpaTDpsAEzeFMNnabGGhVec+RtA1LlqAFd4vGley0Q8wZTEnWmpWGdWX3sUC3PHnW0K+b/n0qoZ1oaTEszfCQc5PGle0GXwv0k7PxI87S9EMjMMo35rvMdILPDbErrzlA4iOmw4SBh0/iXgUxLg8mnQvw9V2Zmmdau/D1XtpoxpiYe3qPw8B6FW6IqreOCvwpkWhqMinMwaFEi46PTfrFMXG38HLr6OHe8ttPykXZNYzrr4q0JdJoay4C1BS2cdfCmGuZsTrd6Hv/T5ozZJ7no9L1xWZE1fU0bD193unXx3GESFZNcyIb4nDazaUN8Dh6PkTy1O307CmgT9itM2K9YWnkuOumi26wTV6dZR43NXOXKj3LpPHknEY+us0DaDWiWnwCr92bSdcomBm+q4eE9ShsThTXh2jRn5mxOZ/CmmjYzZkRsgE5TY40Q33bhu/iiF66VcJjh604TuTfbUnnk3myGrzttQZgzZtJhzQrvfabHWGNccNELnz2tfSUcJjxADVhbwIC1BdYsMyOp+fyH9yhWGnAks/TS0gDTV4qK8q2NxU5TY7klqrIFTDhQ6+gZ/hwzdoSbpKgo/9LPj5hnR8yUwEwVw810MRkRG7BSRXPpLyrKv/RUsT2YI5mlLZLnEbEBK1q2lhGxASt5vuO1nZY5ioryL5TJX7icENwuioryjV1rr4+oAzkMWbDvouXEkAX7iDqQg8/rQ5MaLgZxaQWWJslWSWkWWBkFzl9UYP2PvgjFPNrj8/osM/2YcIQfE46QnpFmfL7K7SLocWpBj1Mz6+D0jLQWzzPb3b/6aI8SVnCbvXTTVOZxno6kqCjfKlPNUH4pIP9XPGz/N319UFnrf2iKLGi6LmggqCBoIOi6JuiqIqCrgqIrgqyrgoYu6JpiiK4LKgigCpquCCEdQdVVAU0VdP2iMGW29tplmtbcQNQ1QEXXNDQdQGsWHZBbvdQsKkTQfaiaBJrc/PyLPpQ2zqqbL9U10GV0TUbTZUCyQAoaJPaVinx5RmbVKZnVWRpf56r8WKlQFww2Q4bf8VdMXwsEtfkdGb97xSAb8yRG7df4zYYQ3deEsK2WsK1UsK1U6LIqxJWfKQzcEODVw0GS7KbG1F8Pout6C7WuL5Dpv1PBtlLEFgWXfyHTY61Ery91rvkiwLWfB7h6jcxV/5LoskLF9gl0+tjLI7FesuuxzKnrHeqneQdL143Bjacj6wqg4ZFUph8JYvusCdsXIldvhGvXi/T+SuS6dQrXrZO4fp3Ib76UuH5NiD6fi1z/mcgNnwa5epWMbbHG1StEvsoSjbeoq2i60h6MYNN1XTAhNF1vdlBoVFSG7/Nh+1Ti2o1Brl8v03uDyDVfN3DDVz5u+FKh15cKvdbp9FoHvT5X6PW5wjVr4LrPda6NkugTJdL1EwXbIpkVx5sdGaXZ8S9gGgNIJ6ipPHgghO3TED23h+ixTafXZpmb1ofos0ml+9dw1VcaV3wapMvKIF1WSVz+qULPzxV6faZw9Wc613yq0Xt1iN9Ehei+WMG2QObz03JHDtxsGk07P2XRmZ/hx7ZG5rqtMjdubqTHFonrNov8doPMZRvA9pmPqz8X+MNWhb/tkrg/VuGWaJXLPmmk85Imen6m0+sz6BMlcsNqP9etVujysU63jwIcrwy1N6UFm6Zrgma4KKBxrE7lyq999PnaT58dcMNWjV5bFa7d6sP2lcj/+szP6/FNHK2SqQtpSKqIKItUN2psyJH52yYXtkV+uq9UuP5fMj1XqVy9WuWGFSE6LQgxbHMQv6kVXW92B12wKZouSEjGNNMVJvwgYdugcGOsym+2q/TZqnD9dh3bVz5u3h4guVJtnpJa808zkJlBMMS7SQG6vB/gimUKvVdK9Fmu0nu5zLXLZGzvaWzLDhggmoysqwYIKoKqG+rKqVO5douP62JUfvutxg2xCn1iZTpv0rgpRuF0XQAIgRJElSUURUWWZWRZRpFlgrIKeIEg7yaC7X2FXkslei+XDVkmY1sQ4pFNDaA3hwcdNF0XbGjNZwNQWXZaxrZV5XexMjftFLnpW4ne34rYNvjZUywBQUJqEEkMoEk6oqIgySqipCCKEt6Qis8fRNEaAB+TtijYInV6Lwtx7VKRPstkIj5S6PGBRGFtwFCgApquCDYFTQANXZeZkiARsVPnlu9kfhcr0/cbiYivA4w94DM0oet4VQVJUQiJGiFRIiTKBEMSAX+QhoBIvU/C1SQCfpIKGrl8kZerFitcu0Tkuk9ErlsiYXtDYuMpYyobE0gVbIouC6DiDsgMiwtx406Z/rs0+u6WGPCNSI8tIZbnSoCCEvITkBRkWSMUkAgEJbz+EE2+IA3eAPUNjTR6fNTWSni9PuoFN/d8KtBpkcg1n3jp82GQ3h/6sc33seAHb/P6pYOmCTY0VQCNEkHhrgMhfrdL5k/fafT/XqT/boU+sRI/2r0AhESFYFDCF1TwBSWa/CE8TQHcjQFcDX6cdQGq63w43PWU1AoEmup4emMjtvl+enzop/d7Aa57N4Btvo/Z37jCHBzBpuqaAHDOHWDo/iD99in8+XuZO/er/H6fxsB/h0irDgGqoYGAhOAL0eALUd/oo87TRK2nCUddI3anQKXTTUl1DUVVNXga6nh2mwvb6066L3Bz3btOekU2YXtd5MVNDmuVVtEFm6brAmiUu4OMPODnjv0idx+UGHpQ4q6DEnf928+h0iCg0egN0OgXqW8MUCd4cXm81LgbqHIJlDs9lFd5KK90U1hWQ3GlgLOqlrs/rsQ2q45rFjq57q0yukc6sL3iYc62akBDR0fRNcGmq5oAQYSAyuQEibsPhnjgkMYD8T4ePOTnv/ZrfJrtBTWE4A3ibvRTJ3hx1jdRXddApbOeMoebEruL3Ao3p8vqOVVSR1JuDZkFtbywvgDb0zl0eqmanm+Wct2bFdhmlvP2Po/hH6qIrmiCTdNUAVVElTVeyfTz10My435UGHNE5JGfJIYf1ZiV4kFo8uILBKirD+LwBHC43Dhq6ymurqfAUU9ORS05RSU0NHmQVRW/JCMqOho6354U6DEri04z8+nxWim2fxSx8ZgLEAlJCqoiCzZZUwVZVECDjUVNDD8s8sRRlSmJOs8mwbPHZJ466iO2yI8aDNJU56a8tpGqaicOZx2FVfWcLa8lq7CMBn8IHfAGZQKSik/SQAoBOjEZtdiezqTTS/l0fzmPrFIBNB9CUCcoSYJN0TTBKymgS5TXBXn8pwCTj8lMT1WZmarx+nGR2Rk680+GOFleh9/bgMtZR3V1HYWVLvJKajiTV0pVjRsV8IVEgrLaLApeERSCAAx5/xS2+48zZvlZAmKIQFMTHq+PppAi2DRdFQIyyKIfRImoMz6ePO7lpUyJl08r/PN0iMjTEh9kS6zNEUgp92GvaaDAXstZh4DLG0JoChAMyviDMn5Jxi/K+EISIVnFr0h4JWPZ33a8mNteSCI6vhpZbMDhaqChyYfHHxRsmhYURBECoRDoMvkukVfTFN7IlHk7W+aDXIlVOSHW5ob4qhi2F4v8WNLIiSov5wLgkVVERSUYMqa2LyTjF1UCkkpQ1vGLImJAxCsai2SdKFJQ6aG0ooqK+gBuVxOCTxBsuq4IkqQSFCVCkgyqzg8lXt5J9/H+WViVJ7G+KMSOEoVdJSp77DJxdRrH3Rq5goLDJyMERRqCIt6QbPiHqBAQFSRJJSCrhGSZJklDUs/nIefsNRRXe3DWefE0NjUf21BURFEiGDRWVH9I5Nu8Rt7Pk/lXocbWIpFvKzT2VSr8YJdIcEqk1Svke2TsPhV3SMYTEmkISngDCr6QTFBSCUkqQUnFL2kEJUNLflFF1aGuyUepow6HuxG34DdyVkVRkCQFUVLxBWR0ScEfFPmuuIG1hTIxpSr/rpA46FBIqJHJdGmcqVPJa1Co9MrUBiTcQQlPQKYhoNAUUvCJCn5JJSApBCTZEr8oEVJU/IpKiaOOmnov9Q1+QyOqqiErGqKiIYk6/mAATQ4QalRItPvZU+EnvkrmxxqJRJdIVp1KTr1GQaNChVei2idTE9BwBRTqAzKeoEyjKNMkKvglhaCkNAMZogAeX4DS6npcDQE8jYHmM0aajqLqyLJOSNbwSTJev0woEKCxyU9OdZCEkgAJ1UGSBYWsBo3cRihq0qj0KVT5ZBwBjdqQRn1IRhBVGiWVRlklqOiIikZQ1hAV4ytjJE2n0ummqt6LU/AjNAYEm64jaBqoqo6iaEiKhiirBESVhkAQr9eH0ChSUu3nVGkdGY4mUmt8ZLoC5DWoFDUplHpVKnw6VT6ZWn+IuqCEJ6TQEFINzUgSflXFJ8nUe304XALVdQ3UNwaob/TT5A0ZILoO4TCyrBKSZHxBGcEfxNPgpdETwO32U+ZoIKesnrPlHrLtbn6urCfPXk+B3U2R3cO5qgbOVTVQUilwrkKgtEqguLKe4sp6yhwNlNg9VLkEhKYgjd4QTX6RYFA+X2Dpuo6maaiqiqqqKIqGKKn4QwrekERjIIC70YenMUBjk0S9EKK23our3ovb48Xj8SI0BfD4ROq9IdyNQeoa/Lg8AZxuPzV1PuobRASfguAN0egP4Q1KBEMykqwKNkAxMnpDNM1oSxhQGrKiI6oqTapIkyTiDYUIiDLBkEwoICOGjHghKxqKqqCoEooqEVJFgkqIkBIiKIsEpBB+MYA/FMAXkgiICiHRmK2KoilWo6bZRIKu61bjRdd1QdEQVBVBkzRBlVRBFhVBVTRBUXRBknVB1hAUECQQNF0XUHVB13RB0XRBVDRBUjRBUTVBUlRBlBRBlGQhJGuCJOuCouiCpuqCqqpl/7Eemqor5HnS2Ja/hPezpvCP1PuYlfo3vvo5EnfA0baH9qs+CKZpBIIh7DUuyuw1lNprqHDU4mnwoqoamq5xyn2YVTkv8cKJO3n+TH+eTB7Ao/H9eSr+TnbmrfyfgdiddZzKKaK0yklhuYN6oWVfvabay+6Tu3gzaSJPpPZm9E9XMmnvH1n60wKSanZypuEg35WuZlrCMLb9vPSXgzicdWTkFLX7vya5Dq/spk62s8v1AW+cu53ns29kSd6z/Fi9mZ/L8tpqVFfZeHYxBe7MSwdJy85v8Xd1oJwDFRtZlTeTD88+wcKsMSzMGsv8rL8wNbMnc7LuJN6xg6AcsF6TW1xBkzfQct9P8pDrSkfT1QuDKKrKz8UV1t+V3kKi89/m1YyhvHlyMPOz/ouFZ4fwYe59fJAzjLfO3s66wuep8p7jbF0iUTkzOe76/rzZ6jxUVteGtch06gL2C4PIikJFtcv6e3/ZeuamDOHNU//NivwxfFY8jnXlE/iyYiKflz/Eh4WD2Gv/CL/YQIJjI2+dvJvXTt7FtJS+LPt5OvVBY383KEoUlFaGzSz5wqb5ubC0WSsyG3PfZUbKnXzw8wOsKX6EdWUT+NI+nq8cY1nrGMnikjuJd0Xhld1sr3iTt37+IyuLHmZN0WMszxnPzLSBvJnxMMWNPxv7vUITLrdw8VlzMswnNud+xD+O3cGy3LF8ce5R1pZN4IuKsXzlGM0X1SP4uPJ2jgpraJAcfFb+CJHnbuOz8pF8UT6OL0om8nnRJFblPcrLaXfxxolROHzGd2idq7xIHBEavTQFQwAcLNvMP5Lu5JOcsawpmsRnJROIKnuYtVWjWVP9Vz6q7McRz0pUTSa2Zh6LSgeytOJPfGa/j3UVY1lTMoFPz01kdcEjLM95hNmp/8UHmU+j6MYnlrJyz3UMknHW0IbDW8rLyfexIGs4nxU8zqqi8Xx07gGiKkfyheN+ltnvJEFYGdYOFWlUqjniWcGK8iFElQ1jTek4Pi2awOqCR1iZ9wgfnx3Hs4l9+aHc+BqH2voGRFFqC+JpaEKSjOR2Y84iZqX8majcx1ieN57Xc+/hvXPD+aziAZaX30VGY0yH0/1s00E+KR7KquL7+ezceFbnT2BFzkSW5Uzg7VP38UbKQ3hCdc1aKWoLktHsG06/nbnJ9/H+6VGsyJnIC9l38kreMNaUPsKSkkHsdy26aABMcK3lw4L/5l9FY1mdP56lOeP55Ox4Psh+mOeT7+BAyUZj17O8qiWIKMkUlNoBOFQaw4zkQSw+M5bZp+7in7mPsKnkFVade4DPSsfTJNVeFCSk+lhbPIVl+Q+wMnccS8+OY/GZsXxwZjTTj9/OkqwXACi3O/H5A+dBKhy1lFQac33t2bf5R/KdvJnxFxadnkSyYzuf5j3BssIR/Kt4DBvLp/NF2dOsqXiSNRVPsKbyCeNnxZN8XjaFz4ufJrr4Bf5V8Agr8h5iWc5YPs4ey4enR/P+6YeYnfZn3kh9CAUfqgz2Gtd5kLOFpZTYjUMHH516jmlJA3jjxHCO2XexteBtFpwZyqqC0awo+huLCv7Eu4W38V7x73mvtD/vl/Xl/bJ+vFfye94tuo2F+X/g3dw/szT/b6zIHcMnZ0fz0ZmHWXT6ISKzRvJq5mBeSh5MSeNZyzyyrBggWTlFlNsNssiMKYz9oQe7i/9FmmM/r6bezZKfx7Is5yGW5f+NFYUjWHXuflaXDmN12V+JKhtGVNkwVpX9lZXFw1lRNILl+Q/ySc6DfHRmFIuyRhF5ciRvZ/6NNzPvZ3baIJ5N+AM/1xsfXcg9V47XH2wLMidpFE/9eAcVQg7Lsp7j9fShfHTmIT4+M4rIrKG8ljGAeSf78eaZfszP7sc/z/bln9n9mH+mH29m9eO1jP7MPfF7ZibfxvSE3zP1UD+eiruVxw/cxIT9fRj+764Mje3M6bqjAOQVl+MPhgyQvHPllFQapnkhfgRf5y7haNV3PJvwe945+QDvnnyAf2bcQ0zR22S7fySzbj+Z7n2cdO/jZP1eTtbvI9O9j8y6fWS49pHm3Edq9T6OV+0luXIPRyt2k1C+i/jybzhYupUfSrfjV40wX1zhQNN0A8RR66bEbjjr5p+Xc9IRz9snJvJ88h94O/N+3s64j1dS7mJLXuT/v0e/vT6qa93nnVXXdXLOlRtJi6qSWLmL8Yd682rGvcxLG8qbJ4byRuoQXj56L+UNuRcdoDHk5kDJNvaXbuZA2Rb2l21hX9nX7C3byNaCKJKr4pqnbw3+QLBlQDttxn4dPsh4hseP3sjcjP/m5dRBvJYymNdTBjMtvh8rT865KMja0wsZvqsr4/f3ZNyBnjx88CpGxV3BiAM2bt5iY8PPKwz/KKlsG1lDooTgCRJAYPKR/jyb2pcZaQOZdfyPzDn+J145/l/MSfojU364lW05yzuE2F30FU/80JcZSQN5+fifmH38Tmam3MGM1Dt4LOE6pv90DyHFCGLZ+SXtL3pn88rJCR5hbPy1TEq6jqnJv2XGsduZdfwPzD52By8n/5FZSX9g8sGbeDflGU7VHMUTqKMhVM/Z2hMsSZ/JY3G38I/E25l77I/MOv4HZhy/nRkptzE1+Rbu+beNhMrvjLEKSi+cj0T+8AaPZfTi2eQ/8Gj89fz96C3MSB7AjOTfMzPpNmYn3c7MowN4/IdrmXKoPy8l3MtLP/2Fpw7fxiMHr+HFxH7MTrqNmUm/56XkAbyY3I/pyb/jr/tsRJ542hqnOGydaRdkxv6J/DXBxvflX/Fd0Rru2W3jmYTrmZnUnxlJ/ZhxtB+zjg5g1tH+vJBwM1Pjr+fZ+Ot5PuFmZiX2Y9ZR43kvJfXlpeR+PJ90M3/da2Nm4gME5MZ2c5F2QV5OeYA/7rZxrOYgANE/f8S933ViTFxXZiX1ZfbRvsxK7MusxFuZnXgrs8JkZuKtzEi8lZlHf8espL48Gd+Lu3fbeDVpLA1BY+kvc7T7ZTktQUQlyLQjg/nzv20cyo+zrsdX7OKR/bcybLeNp368hpd+uok5ib9lbuKtzfI75ib+jtmJv2PGT7fwfMJveOj7zty/O4JPs+YjKsYUdTc04Wloav/YRusLz/04lAeTIsgsPENewfnc0is1EH32Qx47MICH913F+O//F+O/t/H4wW7877gIHtnfhXHfd2Hs91cyZl9v3k19lgLPaev15TV1NDR6Oz4/0vrC26ceYVhcL45X/GB4d2Eljf7Q+cJI9pHqiGPVqVeZd+wRZicOZ0bCvbyS9DAfpD3PnnNfUuO3ny9NVI2T+eVI8oVPGrUB2ZsfzX1HehJTtMK6FgyJZOYW0+gXf1EIz8wro9LhvKTn2lrugkMoFOS5n/7C0APXYK8tb3GepMrh5HB8Cmknz5JbXEpBSQVlFbVU2N0UlVWRW1RK1s95/JCQzMkzPyPLMpqm4ff7CQQChEIhJElCURQ0TcPsVOm6fn6tCT+oUOkq4bGE27n/qzv4KeMIwVCQQCBAbV0ttXW1VFRWkJ19lrS0DJKSj5F4NInk5OOcPHmK/Px8amtrcbvd1NTU4HQ6cbvdNDU1WTCyLKOqaguYDmvfgNzE4bIYdpWv4UT5EezuMkQl9B877PT/DQC7cLwx8LR3hQAAAABJRU5ErkJggg==) no-repeat;padding-left:40px} |
| | | .browser .browser-firefox{background-position:0 -34px} |
| | | .browser .browser-ie{background-position:0 -68px;margin-left:0px} |
| | | .browser .browser-360{background-position:0 -170px;margin-left: -27px} |
| | | </style> |
| | | </head> |
| | | <body style="margin-top:50px"> |
| | | <h1>请升级您的浏览器,以便我们更好的为您提供服务!</h1> |
| | | <p>您正在使用 Internet Explorer 的早期版本(IE11以下版本或使用该内核的浏览器)。这意味着在升级浏览器前,您将无法访问此网站。</p> |
| | | <hr> |
| | | <h2>请注意:微软公司对Windows XP 及 Internet Explorer 早期版本的支持已经结束</h2> |
| | | <p>自 2016 年 1 月 12 日起,Microsoft 不再为 IE 11 以下版本提供相应支持和更新。没有关键的浏览器安全更新,您的电脑可能易受有害病毒、间谍软件和其他恶意软件的攻击,它们可以窃取或损害您的业务数据和信息。请参阅 <a href="https://www.microsoft.com/zh-cn/WindowsForBusiness/End-of-IE-support">微软对 Internet Explorer 早期版本的支持将于 2016 年 1 月 12 日结束的说明</a> 。</p> |
| | | <hr> |
| | | <h2>您可以选择更先进的浏览器</h2> |
| | | <p>推荐使用以下浏览器的最新版本。如果您的电脑已有以下浏览器的最新版本则直接使用该浏览器访问即可。</p> |
| | | <ul class="browser"> |
| | | <li class="browser-chrome"><a href="https://www.google.cn/chrome/browser/desktop/index.html?hl=zh-CN&standalone=1"> 谷歌浏览器<span>Google Chrome</span></a></li> |
| | | <li class="browser-firefox"><a href="https://www.mozilla.org/zh-CN/firefox/new/"> 火狐浏览器<span>Mozilla Firefox</span></a></li> |
| | | <li class="browser-ie"><a href="https://windows.microsoft.com/zh-cn/internet-explorer/download-ie"> IE 11 浏览器<span>Internet Explorer</span></a></li> |
| | | <li class="browser-360"><a href="http://se.360.cn/"> 360安全浏览器<span>360 Chrome</span></a></li> |
| | | <div class="clean"></div> |
| | | </ul> |
| | | <hr> |
| | | </body> |
| | | </html> |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html> |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
| | | <meta name="renderer" content="webkit"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> |
| | | <link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
| | | <title><%= webpackConfig.name %></title> |
| | | <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]--> |
| | | <style> |
| | | html, |
| | | body, |
| | | #app { |
| | | height: 100%; |
| | | margin: 0px; |
| | | padding: 0px; |
| | | } |
| | | .chromeframe { |
| | | margin: 0.2em 0; |
| | | background: #ccc; |
| | | color: #000; |
| | | padding: 0.2em 0; |
| | | } |
| | | |
| | | #loader-wrapper { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | z-index: 999999; |
| | | } |
| | | |
| | | #loader { |
| | | display: block; |
| | | position: relative; |
| | | left: 50%; |
| | | top: 50%; |
| | | width: 150px; |
| | | height: 150px; |
| | | margin: -75px 0 0 -75px; |
| | | border-radius: 50%; |
| | | border: 3px solid transparent; |
| | | border-top-color: #FFF; |
| | | -webkit-animation: spin 2s linear infinite; |
| | | -ms-animation: spin 2s linear infinite; |
| | | -moz-animation: spin 2s linear infinite; |
| | | -o-animation: spin 2s linear infinite; |
| | | animation: spin 2s linear infinite; |
| | | z-index: 1001; |
| | | } |
| | | |
| | | #loader:before { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 5px; |
| | | left: 5px; |
| | | right: 5px; |
| | | bottom: 5px; |
| | | border-radius: 50%; |
| | | border: 3px solid transparent; |
| | | border-top-color: #FFF; |
| | | -webkit-animation: spin 3s linear infinite; |
| | | -moz-animation: spin 3s linear infinite; |
| | | -o-animation: spin 3s linear infinite; |
| | | -ms-animation: spin 3s linear infinite; |
| | | animation: spin 3s linear infinite; |
| | | } |
| | | |
| | | #loader:after { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 15px; |
| | | left: 15px; |
| | | right: 15px; |
| | | bottom: 15px; |
| | | border-radius: 50%; |
| | | border: 3px solid transparent; |
| | | border-top-color: #FFF; |
| | | -moz-animation: spin 1.5s linear infinite; |
| | | -o-animation: spin 1.5s linear infinite; |
| | | -ms-animation: spin 1.5s linear infinite; |
| | | -webkit-animation: spin 1.5s linear infinite; |
| | | animation: spin 1.5s linear infinite; |
| | | } |
| | | |
| | | |
| | | @-webkit-keyframes spin { |
| | | 0% { |
| | | -webkit-transform: rotate(0deg); |
| | | -ms-transform: rotate(0deg); |
| | | transform: rotate(0deg); |
| | | } |
| | | 100% { |
| | | -webkit-transform: rotate(360deg); |
| | | -ms-transform: rotate(360deg); |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | @keyframes spin { |
| | | 0% { |
| | | -webkit-transform: rotate(0deg); |
| | | -ms-transform: rotate(0deg); |
| | | transform: rotate(0deg); |
| | | } |
| | | 100% { |
| | | -webkit-transform: rotate(360deg); |
| | | -ms-transform: rotate(360deg); |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | |
| | | #loader-wrapper .loader-section { |
| | | position: fixed; |
| | | top: 0; |
| | | width: 51%; |
| | | height: 100%; |
| | | background: #7171C6; |
| | | z-index: 1000; |
| | | -webkit-transform: translateX(0); |
| | | -ms-transform: translateX(0); |
| | | transform: translateX(0); |
| | | } |
| | | |
| | | #loader-wrapper .loader-section.section-left { |
| | | left: 0; |
| | | } |
| | | |
| | | #loader-wrapper .loader-section.section-right { |
| | | right: 0; |
| | | } |
| | | |
| | | |
| | | .loaded #loader-wrapper .loader-section.section-left { |
| | | -webkit-transform: translateX(-100%); |
| | | -ms-transform: translateX(-100%); |
| | | transform: translateX(-100%); |
| | | -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | } |
| | | |
| | | .loaded #loader-wrapper .loader-section.section-right { |
| | | -webkit-transform: translateX(100%); |
| | | -ms-transform: translateX(100%); |
| | | transform: translateX(100%); |
| | | -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
| | | } |
| | | |
| | | .loaded #loader { |
| | | opacity: 0; |
| | | -webkit-transition: all 0.3s ease-out; |
| | | transition: all 0.3s ease-out; |
| | | } |
| | | |
| | | .loaded #loader-wrapper { |
| | | visibility: hidden; |
| | | -webkit-transform: translateY(-100%); |
| | | -ms-transform: translateY(-100%); |
| | | transform: translateY(-100%); |
| | | -webkit-transition: all 0.3s 1s ease-out; |
| | | transition: all 0.3s 1s ease-out; |
| | | } |
| | | |
| | | .no-js #loader-wrapper { |
| | | display: none; |
| | | } |
| | | |
| | | .no-js h1 { |
| | | color: #222222; |
| | | } |
| | | |
| | | #loader-wrapper .load_title { |
| | | font-family: 'Open Sans'; |
| | | color: #FFF; |
| | | font-size: 19px; |
| | | width: 100%; |
| | | text-align: center; |
| | | z-index: 9999999999999; |
| | | position: absolute; |
| | | top: 60%; |
| | | opacity: 1; |
| | | line-height: 30px; |
| | | } |
| | | |
| | | #loader-wrapper .load_title span { |
| | | font-weight: normal; |
| | | font-style: italic; |
| | | font-size: 13px; |
| | | color: #FFF; |
| | | opacity: 0.5; |
| | | } |
| | | </style> |
| | | </head> |
| | | <body> |
| | | <div id="app"> |
| | | <div id="loader-wrapper"> |
| | | <div id="loader"></div> |
| | | <div class="loader-section section-left"></div> |
| | | <div class="loader-section section-right"></div> |
| | | <div class="load_title">正在加载系统资源,请耐心等待</div> |
| | | </div> |
| | | </div> |
| | | </body> |
| | | </html> |
New file |
| | |
| | | User-agent: * |
| | | Disallow: / |
New file |
| | |
| | | @charset "UTF-8";[class*=" el-icon-"],[class^=el-icon-]{font-family:element-icons!important;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;vertical-align:baseline;display:inline-block;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.el-icon-ice-cream-round:before{content:"\e6a0"}.el-icon-ice-cream-square:before{content:"\e6a3"}.el-icon-lollipop:before{content:"\e6a4"}.el-icon-potato-strips:before{content:"\e6a5"}.el-icon-milk-tea:before{content:"\e6a6"}.el-icon-ice-drink:before{content:"\e6a7"}.el-icon-ice-tea:before{content:"\e6a9"}.el-icon-coffee:before{content:"\e6aa"}.el-icon-orange:before{content:"\e6ab"}.el-icon-pear:before{content:"\e6ac"}.el-icon-apple:before{content:"\e6ad"}.el-icon-cherry:before{content:"\e6ae"}.el-icon-watermelon:before{content:"\e6af"}.el-icon-grape:before{content:"\e6b0"}.el-icon-refrigerator:before{content:"\e6b1"}.el-icon-goblet-square-full:before{content:"\e6b2"}.el-icon-goblet-square:before{content:"\e6b3"}.el-icon-goblet-full:before{content:"\e6b4"}.el-icon-goblet:before{content:"\e6b5"}.el-icon-cold-drink:before{content:"\e6b6"}.el-icon-coffee-cup:before{content:"\e6b8"}.el-icon-water-cup:before{content:"\e6b9"}.el-icon-hot-water:before{content:"\e6ba"}.el-icon-ice-cream:before{content:"\e6bb"}.el-icon-dessert:before{content:"\e6bc"}.el-icon-sugar:before{content:"\e6bd"}.el-icon-tableware:before{content:"\e6be"}.el-icon-burger:before{content:"\e6bf"}.el-icon-knife-fork:before{content:"\e6c1"}.el-icon-fork-spoon:before{content:"\e6c2"}.el-icon-chicken:before{content:"\e6c3"}.el-icon-food:before{content:"\e6c4"}.el-icon-dish-1:before{content:"\e6c5"}.el-icon-dish:before{content:"\e6c6"}.el-icon-moon-night:before{content:"\e6ee"}.el-icon-moon:before{content:"\e6f0"}.el-icon-cloudy-and-sunny:before{content:"\e6f1"}.el-icon-partly-cloudy:before{content:"\e6f2"}.el-icon-cloudy:before{content:"\e6f3"}.el-icon-sunny:before{content:"\e6f6"}.el-icon-sunset:before{content:"\e6f7"}.el-icon-sunrise-1:before{content:"\e6f8"}.el-icon-sunrise:before{content:"\e6f9"}.el-icon-heavy-rain:before{content:"\e6fa"}.el-icon-lightning:before{content:"\e6fb"}.el-icon-light-rain:before{content:"\e6fc"}.el-icon-wind-power:before{content:"\e6fd"}.el-icon-baseball:before{content:"\e712"}.el-icon-soccer:before{content:"\e713"}.el-icon-football:before{content:"\e715"}.el-icon-basketball:before{content:"\e716"}.el-icon-ship:before{content:"\e73f"}.el-icon-truck:before{content:"\e740"}.el-icon-bicycle:before{content:"\e741"}.el-icon-mobile-phone:before{content:"\e6d3"}.el-icon-service:before{content:"\e6d4"}.el-icon-key:before{content:"\e6e2"}.el-icon-unlock:before{content:"\e6e4"}.el-icon-lock:before{content:"\e6e5"}.el-icon-watch:before{content:"\e6fe"}.el-icon-watch-1:before{content:"\e6ff"}.el-icon-timer:before{content:"\e702"}.el-icon-alarm-clock:before{content:"\e703"}.el-icon-map-location:before{content:"\e704"}.el-icon-delete-location:before{content:"\e705"}.el-icon-add-location:before{content:"\e706"}.el-icon-location-information:before{content:"\e707"}.el-icon-location-outline:before{content:"\e708"}.el-icon-location:before{content:"\e79e"}.el-icon-place:before{content:"\e709"}.el-icon-discover:before{content:"\e70a"}.el-icon-first-aid-kit:before{content:"\e70b"}.el-icon-trophy-1:before{content:"\e70c"}.el-icon-trophy:before{content:"\e70d"}.el-icon-medal:before{content:"\e70e"}.el-icon-medal-1:before{content:"\e70f"}.el-icon-stopwatch:before{content:"\e710"}.el-icon-mic:before{content:"\e711"}.el-icon-copy-document:before{content:"\e718"}.el-icon-full-screen:before{content:"\e719"}.el-icon-switch-button:before{content:"\e71b"}.el-icon-aim:before{content:"\e71c"}.el-icon-crop:before{content:"\e71d"}.el-icon-odometer:before{content:"\e71e"}.el-icon-time:before{content:"\e71f"}.el-icon-bangzhu:before{content:"\e724"}.el-icon-close-notification:before{content:"\e726"}.el-icon-microphone:before{content:"\e727"}.el-icon-turn-off-microphone:before{content:"\e728"}.el-icon-position:before{content:"\e729"}.el-icon-postcard:before{content:"\e72a"}.el-icon-message:before{content:"\e72b"}.el-icon-chat-line-square:before{content:"\e72d"}.el-icon-chat-dot-square:before{content:"\e72e"}.el-icon-chat-dot-round:before{content:"\e72f"}.el-icon-chat-square:before{content:"\e730"}.el-icon-chat-line-round:before{content:"\e731"}.el-icon-chat-round:before{content:"\e732"}.el-icon-set-up:before{content:"\e733"}.el-icon-turn-off:before{content:"\e734"}.el-icon-open:before{content:"\e735"}.el-icon-connection:before{content:"\e736"}.el-icon-link:before{content:"\e737"}.el-icon-cpu:before{content:"\e738"}.el-icon-thumb:before{content:"\e739"}.el-icon-female:before{content:"\e73a"}.el-icon-male:before{content:"\e73b"}.el-icon-guide:before{content:"\e73c"}.el-icon-news:before{content:"\e73e"}.el-icon-price-tag:before{content:"\e744"}.el-icon-discount:before{content:"\e745"}.el-icon-wallet:before{content:"\e747"}.el-icon-coin:before{content:"\e748"}.el-icon-money:before{content:"\e749"}.el-icon-bank-card:before{content:"\e74a"}.el-icon-box:before{content:"\e74b"}.el-icon-present:before{content:"\e74c"}.el-icon-sell:before{content:"\e6d5"}.el-icon-sold-out:before{content:"\e6d6"}.el-icon-shopping-bag-2:before{content:"\e74d"}.el-icon-shopping-bag-1:before{content:"\e74e"}.el-icon-shopping-cart-2:before{content:"\e74f"}.el-icon-shopping-cart-1:before{content:"\e750"}.el-icon-shopping-cart-full:before{content:"\e751"}.el-icon-smoking:before{content:"\e752"}.el-icon-no-smoking:before{content:"\e753"}.el-icon-house:before{content:"\e754"}.el-icon-table-lamp:before{content:"\e755"}.el-icon-school:before{content:"\e756"}.el-icon-office-building:before{content:"\e757"}.el-icon-toilet-paper:before{content:"\e758"}.el-icon-notebook-2:before{content:"\e759"}.el-icon-notebook-1:before{content:"\e75a"}.el-icon-files:before{content:"\e75b"}.el-icon-collection:before{content:"\e75c"}.el-icon-receiving:before{content:"\e75d"}.el-icon-suitcase-1:before{content:"\e760"}.el-icon-suitcase:before{content:"\e761"}.el-icon-film:before{content:"\e763"}.el-icon-collection-tag:before{content:"\e765"}.el-icon-data-analysis:before{content:"\e766"}.el-icon-pie-chart:before{content:"\e767"}.el-icon-data-board:before{content:"\e768"}.el-icon-data-line:before{content:"\e76d"}.el-icon-reading:before{content:"\e769"}.el-icon-magic-stick:before{content:"\e76a"}.el-icon-coordinate:before{content:"\e76b"}.el-icon-mouse:before{content:"\e76c"}.el-icon-brush:before{content:"\e76e"}.el-icon-headset:before{content:"\e76f"}.el-icon-umbrella:before{content:"\e770"}.el-icon-scissors:before{content:"\e771"}.el-icon-mobile:before{content:"\e773"}.el-icon-attract:before{content:"\e774"}.el-icon-monitor:before{content:"\e775"}.el-icon-search:before{content:"\e778"}.el-icon-takeaway-box:before{content:"\e77a"}.el-icon-paperclip:before{content:"\e77d"}.el-icon-printer:before{content:"\e77e"}.el-icon-document-add:before{content:"\e782"}.el-icon-document:before{content:"\e785"}.el-icon-document-checked:before{content:"\e786"}.el-icon-document-copy:before{content:"\e787"}.el-icon-document-delete:before{content:"\e788"}.el-icon-document-remove:before{content:"\e789"}.el-icon-tickets:before{content:"\e78b"}.el-icon-folder-checked:before{content:"\e77f"}.el-icon-folder-delete:before{content:"\e780"}.el-icon-folder-remove:before{content:"\e781"}.el-icon-folder-add:before{content:"\e783"}.el-icon-folder-opened:before{content:"\e784"}.el-icon-folder:before{content:"\e78a"}.el-icon-edit-outline:before{content:"\e764"}.el-icon-edit:before{content:"\e78c"}.el-icon-date:before{content:"\e78e"}.el-icon-c-scale-to-original:before{content:"\e7c6"}.el-icon-view:before{content:"\e6ce"}.el-icon-loading:before{content:"\e6cf"}.el-icon-rank:before{content:"\e6d1"}.el-icon-sort-down:before{content:"\e7c4"}.el-icon-sort-up:before{content:"\e7c5"}.el-icon-sort:before{content:"\e6d2"}.el-icon-finished:before{content:"\e6cd"}.el-icon-refresh-left:before{content:"\e6c7"}.el-icon-refresh-right:before{content:"\e6c8"}.el-icon-refresh:before{content:"\e6d0"}.el-icon-video-play:before{content:"\e7c0"}.el-icon-video-pause:before{content:"\e7c1"}.el-icon-d-arrow-right:before{content:"\e6dc"}.el-icon-d-arrow-left:before{content:"\e6dd"}.el-icon-arrow-up:before{content:"\e6e1"}.el-icon-arrow-down:before{content:"\e6df"}.el-icon-arrow-right:before{content:"\e6e0"}.el-icon-arrow-left:before{content:"\e6de"}.el-icon-top-right:before{content:"\e6e7"}.el-icon-top-left:before{content:"\e6e8"}.el-icon-top:before{content:"\e6e6"}.el-icon-bottom:before{content:"\e6eb"}.el-icon-right:before{content:"\e6e9"}.el-icon-back:before{content:"\e6ea"}.el-icon-bottom-right:before{content:"\e6ec"}.el-icon-bottom-left:before{content:"\e6ed"}.el-icon-caret-top:before{content:"\e78f"}.el-icon-caret-bottom:before{content:"\e790"}.el-icon-caret-right:before{content:"\e791"}.el-icon-caret-left:before{content:"\e792"}.el-icon-d-caret:before{content:"\e79a"}.el-icon-share:before{content:"\e793"}.el-icon-menu:before{content:"\e798"}.el-icon-s-grid:before{content:"\e7a6"}.el-icon-s-check:before{content:"\e7a7"}.el-icon-s-data:before{content:"\e7a8"}.el-icon-s-opportunity:before{content:"\e7aa"}.el-icon-s-custom:before{content:"\e7ab"}.el-icon-s-claim:before{content:"\e7ad"}.el-icon-s-finance:before{content:"\e7ae"}.el-icon-s-comment:before{content:"\e7af"}.el-icon-s-flag:before{content:"\e7b0"}.el-icon-s-marketing:before{content:"\e7b1"}.el-icon-s-shop:before{content:"\e7b4"}.el-icon-s-open:before{content:"\e7b5"}.el-icon-s-management:before{content:"\e7b6"}.el-icon-s-ticket:before{content:"\e7b7"}.el-icon-s-release:before{content:"\e7b8"}.el-icon-s-home:before{content:"\e7b9"}.el-icon-s-promotion:before{content:"\e7ba"}.el-icon-s-operation:before{content:"\e7bb"}.el-icon-s-unfold:before{content:"\e7bc"}.el-icon-s-fold:before{content:"\e7a9"}.el-icon-s-platform:before{content:"\e7bd"}.el-icon-s-order:before{content:"\e7be"}.el-icon-s-cooperation:before{content:"\e7bf"}.el-icon-bell:before{content:"\e725"}.el-icon-message-solid:before{content:"\e799"}.el-icon-video-camera:before{content:"\e772"}.el-icon-video-camera-solid:before{content:"\e796"}.el-icon-camera:before{content:"\e779"}.el-icon-camera-solid:before{content:"\e79b"}.el-icon-download:before{content:"\e77c"}.el-icon-upload2:before{content:"\e77b"}.el-icon-upload:before{content:"\e7c3"}.el-icon-picture-outline-round:before{content:"\e75f"}.el-icon-picture-outline:before{content:"\e75e"}.el-icon-picture:before{content:"\e79f"}.el-icon-close:before{content:"\e6db"}.el-icon-check:before{content:"\e6da"}.el-icon-plus:before{content:"\e6d9"}.el-icon-minus:before{content:"\e6d8"}.el-icon-help:before{content:"\e73d"}.el-icon-s-help:before{content:"\e7b3"}.el-icon-circle-close:before{content:"\e78d"}.el-icon-circle-check:before{content:"\e720"}.el-icon-circle-plus-outline:before{content:"\e723"}.el-icon-remove-outline:before{content:"\e722"}.el-icon-zoom-out:before{content:"\e776"}.el-icon-zoom-in:before{content:"\e777"}.el-icon-error:before{content:"\e79d"}.el-icon-success:before{content:"\e79c"}.el-icon-circle-plus:before{content:"\e7a0"}.el-icon-remove:before{content:"\e7a2"}.el-icon-info:before{content:"\e7a1"}.el-icon-question:before{content:"\e7a4"}.el-icon-warning-outline:before{content:"\e6c9"}.el-icon-warning:before{content:"\e7a3"}.el-icon-goods:before{content:"\e7c2"}.el-icon-s-goods:before{content:"\e7b2"}.el-icon-star-off:before{content:"\e717"}.el-icon-star-on:before{content:"\e797"}.el-icon-more-outline:before{content:"\e6cc"}.el-icon-more:before{content:"\e794"}.el-icon-phone-outline:before{content:"\e6cb"}.el-icon-phone:before{content:"\e795"}.el-icon-user:before{content:"\e6e3"}.el-icon-user-solid:before{content:"\e7a5"}.el-icon-setting:before{content:"\e6ca"}.el-icon-s-tools:before{content:"\e7ac"}.el-icon-delete:before{content:"\e6d7"}.el-icon-delete-solid:before{content:"\e7c9"}.el-icon-eleme:before{content:"\e7c7"}.el-icon-platform-eleme:before{content:"\e7ca"}.el-icon-loading{-webkit-animation:rotating 2s linear infinite;animation:rotating 2s linear infinite}.el-icon--right{margin-left:5px}.el-icon--left{margin-right:5px}@-webkit-keyframes rotating{0%{-webkit-transform:rotateZ(0);transform:rotateZ(0)}100%{-webkit-transform:rotateZ(360deg);transform:rotateZ(360deg)}}@keyframes rotating{0%{-webkit-transform:rotateZ(0);transform:rotateZ(0)}100%{-webkit-transform:rotateZ(360deg);transform:rotateZ(360deg)}}.el-pagination{white-space:nowrap;padding:2px 5px;color:#303133;font-weight:700}.el-pagination::after,.el-pagination::before{display:table;content:""}.el-pagination::after{clear:both}.el-pagination button,.el-pagination span:not([class*=suffix]){display:inline-block;font-size:13px;min-width:35.5px;height:28px;line-height:28px;vertical-align:top;-webkit-box-sizing:border-box;box-sizing:border-box}.el-pagination .el-input__inner{text-align:center;-moz-appearance:textfield;line-height:normal}.el-pagination .el-input__suffix{right:0;-webkit-transform:scale(.8);transform:scale(.8)}.el-pagination .el-select .el-input{width:100px;margin:0 5px}.el-pagination .el-select .el-input .el-input__inner{padding-right:25px;border-radius:3px}.el-pagination button{border:none;padding:0 6px;background:0 0}.el-pagination button:focus{outline:0}.el-pagination button:hover{color:#409EFF}.el-pagination button:disabled{color:#C0C4CC;background-color:#FFF;cursor:not-allowed}.el-pagination .btn-next,.el-pagination .btn-prev{background:center center no-repeat #FFF;background-size:16px;cursor:pointer;margin:0;color:#303133}.el-pagination .btn-next .el-icon,.el-pagination .btn-prev .el-icon{display:block;font-size:12px;font-weight:700}.el-pagination .btn-prev{padding-right:12px}.el-pagination .btn-next{padding-left:12px}.el-pagination .el-pager li.disabled{color:#C0C4CC;cursor:not-allowed}.el-pager li,.el-pager li.btn-quicknext:hover,.el-pager li.btn-quickprev:hover{cursor:pointer}.el-pagination--small .btn-next,.el-pagination--small .btn-prev,.el-pagination--small .el-pager li,.el-pagination--small .el-pager li.btn-quicknext,.el-pagination--small .el-pager li.btn-quickprev,.el-pagination--small .el-pager li:last-child{border-color:transparent;font-size:12px;line-height:22px;height:22px;min-width:22px}.el-pagination--small .arrow.disabled{visibility:hidden}.el-pagination--small .more::before,.el-pagination--small li.more::before{line-height:24px}.el-pagination--small button,.el-pagination--small span:not([class*=suffix]){height:22px;line-height:22px}.el-pagination--small .el-pagination__editor,.el-pagination--small .el-pagination__editor.el-input .el-input__inner{height:22px}.el-pagination__sizes{margin:0 10px 0 0;font-weight:400;color:#606266}.el-pagination__sizes .el-input .el-input__inner{font-size:13px;padding-left:8px}.el-pagination__sizes .el-input .el-input__inner:hover{border-color:#409EFF}.el-pagination__total{margin-right:10px;font-weight:400;color:#606266}.el-pagination__jump{margin-left:24px;font-weight:400;color:#606266}.el-pagination__jump .el-input__inner{padding:0 3px}.el-pagination__rightwrapper{float:right}.el-pagination__editor{line-height:18px;padding:0 2px;height:28px;text-align:center;margin:0 2px;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:3px}.el-pager,.el-pagination.is-background .btn-next,.el-pagination.is-background .btn-prev{padding:0}.el-dialog,.el-pager li{-webkit-box-sizing:border-box}.el-pagination__editor.el-input{width:50px}.el-pagination__editor.el-input .el-input__inner{height:28px}.el-pagination__editor .el-input__inner::-webkit-inner-spin-button,.el-pagination__editor .el-input__inner::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.el-pagination.is-background .btn-next,.el-pagination.is-background .btn-prev,.el-pagination.is-background .el-pager li{margin:0 5px;background-color:#f4f4f5;color:#606266;min-width:30px;border-radius:2px}.el-pagination.is-background .btn-next.disabled,.el-pagination.is-background .btn-next:disabled,.el-pagination.is-background .btn-prev.disabled,.el-pagination.is-background .btn-prev:disabled,.el-pagination.is-background .el-pager li.disabled{color:#C0C4CC}.el-pagination.is-background .el-pager li:not(.disabled):hover{color:#409EFF}.el-pagination.is-background .el-pager li:not(.disabled).active{background-color:#409EFF;color:#FFF}.el-pagination.is-background.el-pagination--small .btn-next,.el-pagination.is-background.el-pagination--small .btn-prev,.el-pagination.is-background.el-pagination--small .el-pager li{margin:0 3px;min-width:22px}.el-pager,.el-pager li{vertical-align:top;margin:0;display:inline-block}.el-pager{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;list-style:none;font-size:0}.el-pager .more::before{line-height:30px}.el-pager li{padding:0 4px;background:#FFF;font-size:13px;min-width:35.5px;height:28px;line-height:28px;box-sizing:border-box;text-align:center}.el-pager li.btn-quicknext,.el-pager li.btn-quickprev{line-height:28px;color:#303133}.el-pager li.btn-quicknext.disabled,.el-pager li.btn-quickprev.disabled{color:#C0C4CC}.el-pager li.active+li{border-left:0}.el-pager li:hover{color:#409EFF}.el-pager li.active{color:#409EFF;cursor:default}@-webkit-keyframes v-modal-in{0%{opacity:0}}@-webkit-keyframes v-modal-out{100%{opacity:0}}.el-dialog{position:relative;margin:0 auto 50px;background:#FFF;border-radius:2px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.3);box-shadow:0 1px 3px rgba(0,0,0,.3);box-sizing:border-box;width:50%}.el-dialog.is-fullscreen{width:100%;margin-top:0;margin-bottom:0;height:100%;overflow:auto}.el-dialog__wrapper{position:fixed;top:0;right:0;bottom:0;left:0;overflow:auto;margin:0}.el-dialog__header{padding:20px 20px 10px}.el-dialog__headerbtn{position:absolute;top:20px;right:20px;padding:0;background:0 0;border:none;outline:0;cursor:pointer;font-size:16px}.el-dialog__headerbtn .el-dialog__close{color:#909399}.el-dialog__headerbtn:focus .el-dialog__close,.el-dialog__headerbtn:hover .el-dialog__close{color:#409EFF}.el-dialog__title{line-height:24px;font-size:18px;color:#303133}.el-dialog__body{padding:30px 20px;color:#606266;font-size:14px;word-break:break-all}.el-dialog__footer{padding:10px 20px 20px;text-align:right;-webkit-box-sizing:border-box;box-sizing:border-box}.el-dialog--center{text-align:center}.el-dialog--center .el-dialog__body{text-align:initial;padding:25px 25px 30px}.el-dialog--center .el-dialog__footer{text-align:inherit}.dialog-fade-enter-active{-webkit-animation:dialog-fade-in .3s;animation:dialog-fade-in .3s}.dialog-fade-leave-active{-webkit-animation:dialog-fade-out .3s;animation:dialog-fade-out .3s}@-webkit-keyframes dialog-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@keyframes dialog-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@-webkit-keyframes dialog-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes dialog-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.el-autocomplete{position:relative;display:inline-block}.el-autocomplete-suggestion{margin:5px 0;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:4px;border:1px solid #E4E7ED;-webkit-box-sizing:border-box;box-sizing:border-box;background-color:#FFF}.el-autocomplete-suggestion__wrap{max-height:280px;padding:10px 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-autocomplete-suggestion__list{margin:0;padding:0}.el-autocomplete-suggestion li{padding:0 20px;margin:0;line-height:34px;cursor:pointer;color:#606266;font-size:14px;list-style:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.el-autocomplete-suggestion li.highlighted,.el-autocomplete-suggestion li:hover{background-color:#F5F7FA}.el-autocomplete-suggestion li.divider{margin-top:6px;border-top:1px solid #000}.el-autocomplete-suggestion li.divider:last-child{margin-bottom:-6px}.el-autocomplete-suggestion.is-loading li{text-align:center;height:100px;line-height:100px;font-size:20px;color:#999}.el-autocomplete-suggestion.is-loading li::after{display:inline-block;content:"";height:100%;vertical-align:middle}.el-autocomplete-suggestion.is-loading li:hover{background-color:#FFF}.el-autocomplete-suggestion.is-loading .el-icon-loading{vertical-align:middle}.el-dropdown{display:inline-block;position:relative;color:#606266;font-size:14px}.el-dropdown .el-button-group{display:block}.el-dropdown .el-button-group .el-button{float:none}.el-dropdown .el-dropdown__caret-button{padding-left:5px;padding-right:5px;position:relative;border-left:none}.el-dropdown .el-dropdown__caret-button::before{content:'';position:absolute;display:block;width:1px;top:5px;bottom:5px;left:0;background:rgba(255,255,255,.5)}.el-dropdown .el-dropdown__caret-button.el-button--default::before{background:rgba(220,223,230,.5)}.el-dropdown .el-dropdown__caret-button:hover:not(.is-disabled)::before{top:0;bottom:0}.el-dropdown .el-dropdown__caret-button .el-dropdown__icon{padding-left:0}.el-dropdown__icon{font-size:12px;margin:0 3px}.el-dropdown .el-dropdown-selfdefine:focus:active,.el-dropdown .el-dropdown-selfdefine:focus:not(.focusing){outline-width:0}.el-dropdown [disabled]{cursor:not-allowed;color:#bbb}.el-dropdown-menu{position:absolute;top:0;left:0;z-index:10;padding:10px 0;margin:5px 0;background-color:#FFF;border:1px solid #EBEEF5;border-radius:4px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-dropdown-menu__item,.el-menu-item{font-size:14px;padding:0 20px;cursor:pointer}.el-dropdown-menu__item{list-style:none;line-height:36px;margin:0;color:#606266;outline:0}.el-dropdown-menu__item:focus,.el-dropdown-menu__item:not(.is-disabled):hover{background-color:#ecf5ff;color:#66b1ff}.el-dropdown-menu__item i{margin-right:5px}.el-dropdown-menu__item--divided{position:relative;margin-top:6px;border-top:1px solid #EBEEF5}.el-dropdown-menu__item--divided:before{content:'';height:6px;display:block;margin:0 -20px;background-color:#FFF}.el-dropdown-menu__item.is-disabled{cursor:default;color:#bbb;pointer-events:none}.el-dropdown-menu--medium{padding:6px 0}.el-dropdown-menu--medium .el-dropdown-menu__item{line-height:30px;padding:0 17px;font-size:14px}.el-dropdown-menu--medium .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:6px}.el-dropdown-menu--medium .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:6px;margin:0 -17px}.el-dropdown-menu--small{padding:6px 0}.el-dropdown-menu--small .el-dropdown-menu__item{line-height:27px;padding:0 15px;font-size:13px}.el-dropdown-menu--small .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:4px}.el-dropdown-menu--small .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:4px;margin:0 -15px}.el-dropdown-menu--mini{padding:3px 0}.el-dropdown-menu--mini .el-dropdown-menu__item{line-height:24px;padding:0 10px;font-size:12px}.el-dropdown-menu--mini .el-dropdown-menu__item.el-dropdown-menu__item--divided{margin-top:3px}.el-dropdown-menu--mini .el-dropdown-menu__item.el-dropdown-menu__item--divided:before{height:3px;margin:0 -10px}.el-menu{border-right:solid 1px #e6e6e6;list-style:none;position:relative;margin:0;padding-left:0;background-color:#FFF}.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus,.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,.el-menu--horizontal>.el-submenu .el-submenu__title:hover{background-color:#fff}.el-menu::after,.el-menu::before{display:table;content:""}.el-breadcrumb__item:last-child .el-breadcrumb__separator,.el-menu--collapse>.el-menu-item .el-submenu__icon-arrow,.el-menu--collapse>.el-submenu>.el-submenu__title .el-submenu__icon-arrow{display:none}.el-menu::after{clear:both}.el-menu.el-menu--horizontal{border-bottom:solid 1px #e6e6e6}.el-menu--horizontal{border-right:none}.el-menu--horizontal>.el-menu-item{float:left;height:60px;line-height:60px;margin:0;border-bottom:2px solid transparent;color:#909399}.el-menu--horizontal>.el-menu-item a,.el-menu--horizontal>.el-menu-item a:hover{color:inherit}.el-menu--horizontal>.el-submenu{float:left}.el-menu--horizontal>.el-submenu:focus,.el-menu--horizontal>.el-submenu:hover{outline:0}.el-menu--horizontal>.el-submenu:focus .el-submenu__title,.el-menu--horizontal>.el-submenu:hover .el-submenu__title{color:#303133}.el-menu--horizontal>.el-submenu.is-active .el-submenu__title{border-bottom:2px solid #409EFF;color:#303133}.el-menu--horizontal>.el-submenu .el-submenu__title{height:60px;line-height:60px;border-bottom:2px solid transparent;color:#909399}.el-menu--horizontal>.el-submenu .el-submenu__icon-arrow{position:static;vertical-align:middle;margin-left:8px;margin-top:-3px}.el-menu--collapse .el-submenu,.el-menu-item{position:relative}.el-menu--horizontal .el-menu .el-menu-item,.el-menu--horizontal .el-menu .el-submenu__title{background-color:#FFF;float:none;height:36px;line-height:36px;padding:0 10px;color:#909399}.el-menu--horizontal .el-menu .el-menu-item.is-active,.el-menu--horizontal .el-menu .el-submenu.is-active>.el-submenu__title{color:#303133}.el-menu--horizontal .el-menu-item:not(.is-disabled):focus,.el-menu--horizontal .el-menu-item:not(.is-disabled):hover{outline:0;color:#303133}.el-menu--horizontal>.el-menu-item.is-active{border-bottom:2px solid #409EFF;color:#303133}.el-menu--collapse{width:64px}.el-menu--collapse>.el-menu-item [class^=el-icon-],.el-menu--collapse>.el-submenu>.el-submenu__title [class^=el-icon-]{margin:0;vertical-align:middle;width:24px;text-align:center}.el-menu--collapse>.el-menu-item span,.el-menu--collapse>.el-submenu>.el-submenu__title span{height:0;width:0;overflow:hidden;visibility:hidden;display:inline-block}.el-menu-item,.el-submenu__title{height:56px;line-height:56px;list-style:none}.el-menu--collapse>.el-menu-item.is-active i{color:inherit}.el-menu--collapse .el-menu .el-submenu{min-width:200px}.el-menu--collapse .el-submenu .el-menu{position:absolute;margin-left:5px;top:0;left:100%;z-index:10;border:1px solid #E4E7ED;border-radius:2px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-menu--collapse .el-submenu.is-opened>.el-submenu__title .el-submenu__icon-arrow{-webkit-transform:none;transform:none}.el-menu--popup{z-index:100;min-width:200px;border:none;padding:5px 0;border-radius:2px;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-menu--popup-bottom-start{margin-top:5px}.el-menu--popup-right-start{margin-left:5px;margin-right:5px}.el-menu-item{color:#303133;-webkit-transition:border-color .3s,background-color .3s,color .3s;transition:border-color .3s,background-color .3s,color .3s;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}.el-radio-button__inner,.el-submenu__title{-webkit-box-sizing:border-box;position:relative;white-space:nowrap}.el-menu-item *{vertical-align:middle}.el-menu-item i{color:#909399}.el-menu-item:focus,.el-menu-item:hover{outline:0;background-color:#ecf5ff}.el-menu-item.is-disabled{opacity:.25;cursor:not-allowed;background:0 0!important}.el-menu-item [class^=el-icon-]{margin-right:5px;width:24px;text-align:center;font-size:18px;vertical-align:middle}.el-menu-item.is-active{color:#409EFF}.el-menu-item.is-active i{color:inherit}.el-submenu{list-style:none;margin:0;padding-left:0}.el-submenu__title{font-size:14px;color:#303133;padding:0 20px;cursor:pointer;-webkit-transition:border-color .3s,background-color .3s,color .3s;transition:border-color .3s,background-color .3s,color .3s;box-sizing:border-box}.el-submenu__title *{vertical-align:middle}.el-submenu__title i{color:#909399}.el-submenu__title:focus,.el-submenu__title:hover{outline:0;background-color:#ecf5ff}.el-submenu__title.is-disabled{opacity:.25;cursor:not-allowed;background:0 0!important}.el-submenu__title:hover{background-color:#ecf5ff}.el-submenu .el-menu{border:none}.el-submenu .el-menu-item{height:50px;line-height:50px;padding:0 45px;min-width:200px}.el-submenu__icon-arrow{position:absolute;top:50%;right:20px;margin-top:-7px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-size:12px}.el-submenu.is-active .el-submenu__title{border-bottom-color:#409EFF}.el-submenu.is-opened>.el-submenu__title .el-submenu__icon-arrow{-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg)}.el-submenu.is-disabled .el-menu-item,.el-submenu.is-disabled .el-submenu__title{opacity:.25;cursor:not-allowed;background:0 0!important}.el-submenu [class^=el-icon-]{vertical-align:middle;margin-right:5px;width:24px;text-align:center;font-size:18px}.el-menu-item-group>ul{padding:0}.el-menu-item-group__title{padding:7px 0 7px 20px;line-height:normal;font-size:12px;color:#909399}.el-radio-button__inner,.el-radio-group{display:inline-block;line-height:1;vertical-align:middle}.horizontal-collapse-transition .el-submenu__title .el-submenu__icon-arrow{-webkit-transition:.2s;transition:.2s;opacity:0}.el-radio-group{font-size:0}.el-radio-button{position:relative;display:inline-block;outline:0}.el-radio-button__inner{background:#FFF;border:1px solid #DCDFE6;font-weight:500;border-left:0;color:#606266;-webkit-appearance:none;text-align:center;box-sizing:border-box;outline:0;margin:0;cursor:pointer;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);padding:12px 20px;font-size:14px;border-radius:0}.el-radio-button__inner.is-round{padding:12px 20px}.el-radio-button__inner:hover{color:#409EFF}.el-radio-button__inner [class*=el-icon-]{line-height:.9}.el-radio-button__inner [class*=el-icon-]+span{margin-left:5px}.el-radio-button:first-child .el-radio-button__inner{border-left:1px solid #DCDFE6;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.el-radio-button__orig-radio{opacity:0;outline:0;position:absolute;z-index:-1}.el-radio-button__orig-radio:checked+.el-radio-button__inner{color:#FFF;background-color:#409EFF;border-color:#409EFF;-webkit-box-shadow:-1px 0 0 0 #409EFF;box-shadow:-1px 0 0 0 #409EFF}.el-radio-button__orig-radio:disabled+.el-radio-button__inner{color:#C0C4CC;cursor:not-allowed;background-image:none;background-color:#FFF;border-color:#EBEEF5;-webkit-box-shadow:none;box-shadow:none}.el-radio-button__orig-radio:disabled:checked+.el-radio-button__inner{background-color:#F2F6FC}.el-radio-button:last-child .el-radio-button__inner{border-radius:0 4px 4px 0}.el-radio-button:first-child:last-child .el-radio-button__inner{border-radius:4px}.el-radio-button--medium .el-radio-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.el-radio-button--medium .el-radio-button__inner.is-round{padding:10px 20px}.el-radio-button--small .el-radio-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.el-radio-button--small .el-radio-button__inner.is-round{padding:9px 15px}.el-radio-button--mini .el-radio-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.el-radio-button--mini .el-radio-button__inner.is-round{padding:7px 15px}.el-radio-button:focus:not(.is-focus):not(:active):not(.is-disabled){-webkit-box-shadow:0 0 2px 2px #409EFF;box-shadow:0 0 2px 2px #409EFF}.el-picker-panel,.el-popover,.el-select-dropdown,.el-table-filter,.el-time-panel{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-switch{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;position:relative;font-size:14px;line-height:20px;height:20px;vertical-align:middle}.el-switch__core,.el-switch__label{display:inline-block;cursor:pointer}.el-switch.is-disabled .el-switch__core,.el-switch.is-disabled .el-switch__label{cursor:not-allowed}.el-switch__label{-webkit-transition:.2s;transition:.2s;height:20px;font-size:14px;font-weight:500;vertical-align:middle;color:#303133}.el-switch__label.is-active{color:#409EFF}.el-switch__label--left{margin-right:10px}.el-switch__label--right{margin-left:10px}.el-switch__label *{line-height:1;font-size:14px;display:inline-block}.el-switch__input{position:absolute;width:0;height:0;opacity:0;margin:0}.el-switch__core{margin:0;position:relative;width:40px;height:20px;border:1px solid #DCDFE6;outline:0;border-radius:10px;-webkit-box-sizing:border-box;box-sizing:border-box;background:#DCDFE6;-webkit-transition:border-color .3s,background-color .3s;transition:border-color .3s,background-color .3s;vertical-align:middle}.el-input__prefix,.el-input__suffix{-webkit-transition:all .3s;color:#C0C4CC}.el-switch__core:after{content:"";position:absolute;top:1px;left:1px;border-radius:100%;-webkit-transition:all .3s;transition:all .3s;width:16px;height:16px;background-color:#FFF}.el-switch.is-checked .el-switch__core{border-color:#409EFF;background-color:#409EFF}.el-switch.is-checked .el-switch__core::after{left:100%;margin-left:-17px}.el-switch.is-disabled{opacity:.6}.el-switch--wide .el-switch__label.el-switch__label--left span{left:10px}.el-switch--wide .el-switch__label.el-switch__label--right span{right:10px}.el-switch .label-fade-enter,.el-switch .label-fade-leave-active{opacity:0}.el-select-dropdown{position:absolute;z-index:1001;border:1px solid #E4E7ED;border-radius:4px;background-color:#FFF;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-box-sizing:border-box;box-sizing:border-box;margin:5px 0}.el-select-dropdown.is-multiple .el-select-dropdown__item{padding-right:40px}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected{color:#409EFF;background-color:#FFF}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected.hover{background-color:#F5F7FA}.el-select-dropdown.is-multiple .el-select-dropdown__item.selected::after{position:absolute;right:20px;font-family:element-icons;content:"\e6da";font-size:12px;font-weight:700;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.el-select-dropdown .el-scrollbar.is-empty .el-select-dropdown__list{padding:0}.el-select-dropdown__empty{padding:10px 0;margin:0;text-align:center;color:#999;font-size:14px}.el-select-dropdown__wrap{max-height:274px}.el-select-dropdown__list{list-style:none;padding:6px 0;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-select-dropdown__item{font-size:14px;padding:0 20px;position:relative;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#606266;height:34px;line-height:34px;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:pointer}.el-select-dropdown__item.is-disabled{color:#C0C4CC;cursor:not-allowed}.el-select-dropdown__item.is-disabled:hover{background-color:#FFF}.el-select-dropdown__item.hover,.el-select-dropdown__item:hover{background-color:#F5F7FA}.el-select-dropdown__item.selected{color:#409EFF;font-weight:700}.el-select-group{margin:0;padding:0}.el-select-group__wrap{position:relative;list-style:none;margin:0;padding:0}.el-select-group__wrap:not(:last-of-type){padding-bottom:24px}.el-select-group__wrap:not(:last-of-type)::after{content:'';position:absolute;display:block;left:20px;right:20px;bottom:12px;height:1px;background:#E4E7ED}.el-select-group__title{padding-left:20px;font-size:12px;color:#909399;line-height:30px}.el-select-group .el-select-dropdown__item{padding-left:20px}.el-select{display:inline-block;position:relative}.el-select .el-select__tags>span{display:contents}.el-select:hover .el-input__inner{border-color:#C0C4CC}.el-select .el-input__inner{cursor:pointer;padding-right:35px}.el-select .el-input__inner:focus{border-color:#409EFF}.el-select .el-input .el-select__caret{color:#C0C4CC;font-size:14px;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg);cursor:pointer}.el-select .el-input .el-select__caret.is-reverse{-webkit-transform:rotateZ(0);transform:rotateZ(0)}.el-select .el-input .el-select__caret.is-show-close{font-size:14px;text-align:center;-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg);border-radius:100%;color:#C0C4CC;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.el-select .el-input .el-select__caret.is-show-close:hover{color:#909399}.el-select .el-input.is-disabled .el-input__inner{cursor:not-allowed}.el-select .el-input.is-disabled .el-input__inner:hover{border-color:#E4E7ED}.el-range-editor.is-active,.el-range-editor.is-active:hover,.el-select .el-input.is-focus .el-input__inner{border-color:#409EFF}.el-select>.el-input{display:block}.el-select__input{border:none;outline:0;padding:0;margin-left:15px;color:#666;font-size:14px;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:28px;background-color:transparent}.el-select__input.is-mini{height:14px}.el-select__close{cursor:pointer;position:absolute;top:8px;z-index:1000;right:25px;color:#C0C4CC;line-height:18px;font-size:14px}.el-select__close:hover{color:#909399}.el-select__tags{position:absolute;line-height:normal;white-space:normal;z-index:1;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-wrap:wrap;flex-wrap:wrap}.el-select__tags-text{overflow:hidden;text-overflow:ellipsis}.el-select .el-tag{-webkit-box-sizing:border-box;box-sizing:border-box;border-color:transparent;margin:2px 0 2px 6px;background-color:#f0f2f5;display:-webkit-box;display:-ms-flexbox;display:flex;max-width:100%;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-select .el-tag__close.el-icon-close{background-color:#C0C4CC;top:0;color:#FFF;-ms-flex-negative:0;flex-shrink:0}.el-select .el-tag__close.el-icon-close:hover{background-color:#909399}.el-table,.el-table__expanded-cell{background-color:#FFF}.el-select .el-tag__close.el-icon-close::before{display:block;-webkit-transform:translate(0,.5px);transform:translate(0,.5px)}.el-table{position:relative;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-flex:1;-ms-flex:1;flex:1;width:100%;max-width:100%;font-size:14px;color:#606266}.el-table__empty-block{min-height:60px;text-align:center;width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-table__empty-text{line-height:60px;width:50%;color:#909399}.el-table__expand-column .cell{padding:0;text-align:center}.el-table__expand-icon{position:relative;cursor:pointer;color:#666;font-size:12px;-webkit-transition:-webkit-transform .2s ease-in-out;transition:-webkit-transform .2s ease-in-out;transition:transform .2s ease-in-out;transition:transform .2s ease-in-out,-webkit-transform .2s ease-in-out;height:20px}.el-table__expand-icon--expanded{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-table__expand-icon>.el-icon{position:absolute;left:50%;top:50%;margin-left:-5px;margin-top:-5px}.el-table__expanded-cell[class*=cell]{padding:20px 50px}.el-table__expanded-cell:hover{background-color:transparent!important}.el-table__placeholder{display:inline-block;width:20px}.el-table__append-wrapper{overflow:hidden}.el-table--fit{border-right:0;border-bottom:0}.el-table--fit .el-table__cell.gutter{border-right-width:1px}.el-table--scrollable-x .el-table__body-wrapper{overflow-x:auto}.el-table--scrollable-y .el-table__body-wrapper{overflow-y:auto}.el-table thead{color:#909399;font-weight:500}.el-table thead.is-group th.el-table__cell{background:#F5F7FA}.el-table .el-table__cell{padding:12px 0;min-width:0;-webkit-box-sizing:border-box;box-sizing:border-box;text-overflow:ellipsis;vertical-align:middle;position:relative;text-align:left}.el-table .el-table__cell.is-center{text-align:center}.el-table .el-table__cell.is-right{text-align:right}.el-table .el-table__cell.gutter{width:15px;border-right-width:0;border-bottom-width:0;padding:0}.el-table .el-table__cell.is-hidden>*{visibility:hidden}.el-table--medium .el-table__cell{padding:10px 0}.el-table--small{font-size:12px}.el-table--small .el-table__cell{padding:8px 0}.el-table--mini{font-size:12px}.el-table--mini .el-table__cell{padding:6px 0}.el-table tr{background-color:#FFF}.el-table tr input[type=checkbox]{margin:0}.el-table td.el-table__cell,.el-table th.el-table__cell.is-leaf{border-bottom:1px solid #EBEEF5}.el-table th.el-table__cell.is-sortable{cursor:pointer}.el-table th.el-table__cell{overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#FFF}.el-table th.el-table__cell>.cell{display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;vertical-align:middle;padding-left:10px;padding-right:10px;width:100%}.el-table th.el-table__cell>.cell.highlight{color:#409EFF}.el-table th.el-table__cell.required>div::before{display:inline-block;content:"";width:8px;height:8px;border-radius:50%;background:#ff4d51;margin-right:5px;vertical-align:middle}.el-table td.el-table__cell div{-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-table td,.el-table .cell,.el-table-filter{-webkit-box-sizing:border-box}.el-table td.el-table__cell.gutter{width:0}.el-table .cell{box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;white-space:normal;word-break:break-all;line-height:23px;padding-left:10px;padding-right:10px}.el-table .cell.el-tooltip{white-space:nowrap;min-width:50px}.el-table--border,.el-table--group{border:1px solid #EBEEF5}.el-table--border::after,.el-table--group::after,.el-table::before{content:'';position:absolute;background-color:#EBEEF5;z-index:1}.el-table--border::after,.el-table--group::after{top:0;right:0;width:1px;height:100%}.el-table::before{left:0;bottom:0;width:100%;height:1px}.el-table--border{border-right:none;border-bottom:none}.el-table--border.el-loading-parent--relative{border-color:transparent}.el-table--border .el-table__cell,.el-table__body-wrapper .el-table--border.is-scrolling-left~.el-table__fixed{border-right:1px solid #EBEEF5}.el-table--border .el-table__cell:first-child .cell{padding-left:10px}.el-table--border th.el-table__cell.gutter:last-of-type{border-bottom:1px solid #EBEEF5;border-bottom-width:1px}.el-table--border th.el-table__cell,.el-table__fixed-right-patch{border-bottom:1px solid #EBEEF5}.el-table--hidden{visibility:hidden}.el-table__fixed,.el-table__fixed-right{position:absolute;top:0;left:0;overflow-x:hidden;overflow-y:hidden;-webkit-box-shadow:0 0 10px rgba(0,0,0,.12);box-shadow:0 0 10px rgba(0,0,0,.12)}.el-table__fixed-right::before,.el-table__fixed::before{content:'';position:absolute;left:0;bottom:0;width:100%;height:1px;background-color:#EBEEF5;z-index:4}.el-table__fixed-right-patch{position:absolute;top:-1px;right:0;background-color:#FFF}.el-table__fixed-right{top:0;left:auto;right:0}.el-table__fixed-right .el-table__fixed-body-wrapper,.el-table__fixed-right .el-table__fixed-footer-wrapper,.el-table__fixed-right .el-table__fixed-header-wrapper{left:auto;right:0}.el-table__fixed-header-wrapper{position:absolute;left:0;top:0;z-index:3}.el-table__fixed-footer-wrapper{position:absolute;left:0;bottom:0;z-index:3}.el-table__fixed-footer-wrapper tbody td.el-table__cell{border-top:1px solid #EBEEF5;background-color:#F5F7FA;color:#606266}.el-table__fixed-body-wrapper{position:absolute;left:0;top:37px;overflow:hidden;z-index:3}.el-table__body-wrapper,.el-table__footer-wrapper,.el-table__header-wrapper{width:100%}.el-table__footer-wrapper{margin-top:-1px}.el-table__footer-wrapper td.el-table__cell{border-top:1px solid #EBEEF5}.el-table__body,.el-table__footer,.el-table__header{table-layout:fixed;border-collapse:separate}.el-table__footer-wrapper,.el-table__header-wrapper{overflow:hidden}.el-table__footer-wrapper tbody td.el-table__cell,.el-table__header-wrapper tbody td.el-table__cell{background-color:#F5F7FA;color:#606266}.el-table__body-wrapper{overflow:hidden;position:relative}.el-table__body-wrapper.is-scrolling-left~.el-table__fixed,.el-table__body-wrapper.is-scrolling-none~.el-table__fixed,.el-table__body-wrapper.is-scrolling-none~.el-table__fixed-right,.el-table__body-wrapper.is-scrolling-right~.el-table__fixed-right{-webkit-box-shadow:none;box-shadow:none}.el-table__body-wrapper .el-table--border.is-scrolling-right~.el-table__fixed-right{border-left:1px solid #EBEEF5}.el-table .caret-wrapper{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:34px;width:24px;vertical-align:middle;cursor:pointer;overflow:initial;position:relative}.el-table .sort-caret{width:0;height:0;border:5px solid transparent;position:absolute;left:7px}.el-table .sort-caret.ascending{border-bottom-color:#C0C4CC;top:5px}.el-table .sort-caret.descending{border-top-color:#C0C4CC;bottom:7px}.el-table .ascending .sort-caret.ascending{border-bottom-color:#409EFF}.el-table .descending .sort-caret.descending{border-top-color:#409EFF}.el-table .hidden-columns{visibility:hidden;position:absolute;z-index:-1}.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell{background:#FAFAFA}.el-table--striped .el-table__body tr.el-table__row--striped.current-row td.el-table__cell,.el-table--striped .el-table__body tr.el-table__row--striped.selection-row td.el-table__cell{background-color:#ecf5ff}.el-table__body tr.hover-row.current-row>td.el-table__cell,.el-table__body tr.hover-row.el-table__row--striped.current-row>td.el-table__cell,.el-table__body tr.hover-row.el-table__row--striped.selection-row>td.el-table__cell,.el-table__body tr.hover-row.el-table__row--striped>td.el-table__cell,.el-table__body tr.hover-row.selection-row>td.el-table__cell,.el-table__body tr.hover-row>td.el-table__cell{background-color:#F5F7FA}.el-table__body tr.current-row>td.el-table__cell,.el-table__body tr.selection-row>td.el-table__cell{background-color:#ecf5ff}.el-table__column-resize-proxy{position:absolute;left:200px;top:0;bottom:0;width:0;border-left:1px solid #EBEEF5;z-index:10}.el-table__column-filter-trigger{display:inline-block;line-height:34px;cursor:pointer}.el-table__column-filter-trigger i{color:#909399;font-size:12px;-webkit-transform:scale(.75);transform:scale(.75)}.el-table--enable-row-transition .el-table__body td.el-table__cell{-webkit-transition:background-color .25s ease;transition:background-color .25s ease}.el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell{background-color:#F5F7FA}.el-table--fluid-height .el-table__fixed,.el-table--fluid-height .el-table__fixed-right{bottom:0;overflow:hidden}.el-table [class*=el-table__row--level] .el-table__expand-icon{display:inline-block;width:20px;line-height:20px;height:20px;text-align:center;margin-right:3px}.el-table-column--selection .cell{padding-left:14px;padding-right:14px}.el-table-filter{border:1px solid #EBEEF5;border-radius:2px;background-color:#FFF;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-sizing:border-box;margin:2px 0}.el-table-filter__list{padding:5px 0;margin:0;list-style:none;min-width:100px}.el-table-filter__list-item{line-height:36px;padding:0 10px;cursor:pointer;font-size:14px}.el-table-filter__list-item:hover{background-color:#ecf5ff;color:#66b1ff}.el-table-filter__list-item.is-active{background-color:#409EFF;color:#FFF}.el-table-filter__content{min-width:100px}.el-table-filter__bottom{border-top:1px solid #EBEEF5;padding:8px}.el-table-filter__bottom button{background:0 0;border:none;color:#606266;cursor:pointer;font-size:13px;padding:0 3px}.el-date-table td.in-range div,.el-date-table td.in-range div:hover,.el-date-table.is-week-mode .el-date-table__row.current div,.el-date-table.is-week-mode .el-date-table__row:hover div{background-color:#F2F6FC}.el-table-filter__bottom button:hover{color:#409EFF}.el-table-filter__bottom button:focus{outline:0}.el-table-filter__bottom button.is-disabled{color:#C0C4CC;cursor:not-allowed}.el-table-filter__wrap{max-height:280px}.el-table-filter__checkbox-group{padding:10px}.el-table-filter__checkbox-group label.el-checkbox{display:block;margin-right:5px;margin-bottom:8px;margin-left:5px}.el-table-filter__checkbox-group .el-checkbox:last-child{margin-bottom:0}.el-date-table{font-size:12px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.el-date-table.is-week-mode .el-date-table__row:hover td.available:hover{color:#606266}.el-date-table.is-week-mode .el-date-table__row:hover td:first-child div{margin-left:5px;border-top-left-radius:15px;border-bottom-left-radius:15px}.el-date-table.is-week-mode .el-date-table__row:hover td:last-child div{margin-right:5px;border-top-right-radius:15px;border-bottom-right-radius:15px}.el-date-table td{width:32px;height:30px;padding:4px 0;box-sizing:border-box;text-align:center;cursor:pointer;position:relative}.el-date-table td div{height:30px;padding:3px 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-table td span{width:24px;height:24px;display:block;margin:0 auto;line-height:24px;position:absolute;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);border-radius:50%}.el-date-table td.next-month,.el-date-table td.prev-month{color:#C0C4CC}.el-date-table td.today{position:relative}.el-date-table td.today span{color:#409EFF;font-weight:700}.el-date-table td.today.end-date span,.el-date-table td.today.start-date span{color:#FFF}.el-date-table td.available:hover{color:#409EFF}.el-date-table td.current:not(.disabled) span{color:#FFF;background-color:#409EFF}.el-date-table td.end-date div,.el-date-table td.start-date div{color:#FFF}.el-date-table td.end-date span,.el-date-table td.start-date span{background-color:#409EFF}.el-date-table td.start-date div{margin-left:5px;border-top-left-radius:15px;border-bottom-left-radius:15px}.el-date-table td.end-date div{margin-right:5px;border-top-right-radius:15px;border-bottom-right-radius:15px}.el-date-table td.disabled div{background-color:#F5F7FA;opacity:1;cursor:not-allowed;color:#C0C4CC}.el-date-table td.selected div{margin-left:5px;margin-right:5px;background-color:#F2F6FC;border-radius:15px}.el-date-table td.selected div:hover{background-color:#F2F6FC}.el-date-table td.selected span{background-color:#409EFF;color:#FFF;border-radius:15px}.el-date-table td.week{font-size:80%;color:#606266}.el-month-table,.el-year-table{font-size:12px;border-collapse:collapse}.el-date-table th{padding:5px;color:#606266;font-weight:400;border-bottom:solid 1px #EBEEF5}.el-month-table{margin:-1px}.el-month-table td{text-align:center;padding:8px 0;cursor:pointer}.el-month-table td div{height:48px;padding:6px 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-month-table td.today .cell{color:#409EFF;font-weight:700}.el-month-table td.today.end-date .cell,.el-month-table td.today.start-date .cell{color:#FFF}.el-month-table td.disabled .cell{background-color:#F5F7FA;cursor:not-allowed;color:#C0C4CC}.el-month-table td.disabled .cell:hover{color:#C0C4CC}.el-month-table td .cell{width:60px;height:36px;display:block;line-height:36px;color:#606266;margin:0 auto;border-radius:18px}.el-month-table td .cell:hover{color:#409EFF}.el-month-table td.in-range div,.el-month-table td.in-range div:hover{background-color:#F2F6FC}.el-month-table td.end-date div,.el-month-table td.start-date div{color:#FFF}.el-month-table td.end-date .cell,.el-month-table td.start-date .cell{color:#FFF;background-color:#409EFF}.el-month-table td.start-date div{border-top-left-radius:24px;border-bottom-left-radius:24px}.el-month-table td.end-date div{border-top-right-radius:24px;border-bottom-right-radius:24px}.el-month-table td.current:not(.disabled) .cell{color:#409EFF}.el-year-table{margin:-1px}.el-year-table .el-icon{color:#303133}.el-year-table td{text-align:center;padding:20px 3px;cursor:pointer}.el-year-table td.today .cell{color:#409EFF;font-weight:700}.el-year-table td.disabled .cell{background-color:#F5F7FA;cursor:not-allowed;color:#C0C4CC}.el-year-table td.disabled .cell:hover{color:#C0C4CC}.el-year-table td .cell{width:48px;height:32px;display:block;line-height:32px;color:#606266;margin:0 auto}.el-year-table td .cell:hover,.el-year-table td.current:not(.disabled) .cell{color:#409EFF}.el-date-range-picker{width:646px}.el-date-range-picker.has-sidebar{width:756px}.el-date-range-picker table{table-layout:fixed;width:100%}.el-date-range-picker .el-picker-panel__body{min-width:513px}.el-date-range-picker .el-picker-panel__content{margin:0}.el-date-range-picker__header{position:relative;text-align:center;height:28px}.el-date-range-picker__header [class*=arrow-left]{float:left}.el-date-range-picker__header [class*=arrow-right]{float:right}.el-date-range-picker__header div{font-size:16px;font-weight:500;margin-right:50px}.el-date-range-picker__content{float:left;width:50%;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:16px}.el-date-range-picker__content.is-left{border-right:1px solid #e4e4e4}.el-date-range-picker__content .el-date-range-picker__header div{margin-left:50px;margin-right:50px}.el-date-range-picker__editors-wrap{-webkit-box-sizing:border-box;box-sizing:border-box;display:table-cell}.el-date-range-picker__editors-wrap.is-right{text-align:right}.el-date-range-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-range-picker__time-header>.el-icon-arrow-right{font-size:20px;vertical-align:middle;display:table-cell;color:#303133}.el-date-range-picker__time-picker-wrap{position:relative;display:table-cell;padding:0 5px}.el-date-range-picker__time-picker-wrap .el-picker-panel{position:absolute;top:13px;right:0;z-index:1;background:#FFF}.el-date-picker{width:322px}.el-date-picker.has-sidebar.has-time{width:434px}.el-date-picker.has-sidebar{width:438px}.el-date-picker.has-time .el-picker-panel__body-wrapper{position:relative}.el-date-picker .el-picker-panel__content{width:292px}.el-date-picker table{table-layout:fixed;width:100%}.el-date-picker__editor-wrap{position:relative;display:table-cell;padding:0 5px}.el-date-picker__time-header{position:relative;border-bottom:1px solid #e4e4e4;font-size:12px;padding:8px 5px 5px;display:table;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.el-date-picker__header{margin:12px;text-align:center}.el-date-picker__header--bordered{margin-bottom:0;padding-bottom:12px;border-bottom:solid 1px #EBEEF5}.el-date-picker__header--bordered+.el-picker-panel__content{margin-top:0}.el-date-picker__header-label{font-size:16px;font-weight:500;padding:0 5px;line-height:22px;text-align:center;cursor:pointer;color:#606266}.el-date-picker__header-label.active,.el-date-picker__header-label:hover{color:#409EFF}.el-date-picker__prev-btn{float:left}.el-date-picker__next-btn{float:right}.el-date-picker__time-wrap{padding:10px;text-align:center}.el-date-picker__time-label{float:left;cursor:pointer;line-height:30px;margin-left:10px}.time-select{margin:5px 0;min-width:0}.time-select .el-picker-panel__content{max-height:200px;margin:0}.time-select-item{padding:8px 10px;font-size:14px;line-height:20px}.time-select-item.selected:not(.disabled){color:#409EFF;font-weight:700}.time-select-item.disabled{color:#E4E7ED;cursor:not-allowed}.time-select-item:hover{background-color:#F5F7FA;font-weight:700;cursor:pointer}.el-date-editor{position:relative;display:inline-block;text-align:left}.el-date-editor.el-input,.el-date-editor.el-input__inner{width:220px}.el-date-editor--monthrange.el-input,.el-date-editor--monthrange.el-input__inner{width:300px}.el-date-editor--daterange.el-input,.el-date-editor--daterange.el-input__inner,.el-date-editor--timerange.el-input,.el-date-editor--timerange.el-input__inner{width:350px}.el-date-editor--datetimerange.el-input,.el-date-editor--datetimerange.el-input__inner{width:400px}.el-date-editor--dates .el-input__inner{text-overflow:ellipsis;white-space:nowrap}.el-date-editor .el-icon-circle-close{cursor:pointer}.el-date-editor .el-range__icon{font-size:14px;margin-left:-5px;color:#C0C4CC;float:left;line-height:32px}.el-date-editor .el-range-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;outline:0;display:inline-block;height:100%;margin:0;padding:0;width:39%;text-align:center;font-size:14px;color:#606266}.el-date-editor .el-range-input::-webkit-input-placeholder{color:#C0C4CC}.el-date-editor .el-range-input:-ms-input-placeholder{color:#C0C4CC}.el-date-editor .el-range-input::-ms-input-placeholder{color:#C0C4CC}.el-date-editor .el-range-input::placeholder{color:#C0C4CC}.el-date-editor .el-range-separator{display:inline-block;height:100%;padding:0 5px;margin:0;text-align:center;line-height:32px;font-size:14px;width:5%;color:#303133}.el-date-editor .el-range__close-icon{font-size:14px;color:#C0C4CC;width:25px;display:inline-block;float:right;line-height:32px}.el-range-editor.el-input__inner{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:3px 10px}.el-range-editor .el-range-input{line-height:1}.el-range-editor--medium.el-input__inner{height:36px}.el-range-editor--medium .el-range-separator{line-height:28px;font-size:14px}.el-range-editor--medium .el-range-input{font-size:14px}.el-range-editor--medium .el-range__close-icon,.el-range-editor--medium .el-range__icon{line-height:28px}.el-range-editor--small.el-input__inner{height:32px}.el-range-editor--small .el-range-separator{line-height:24px;font-size:13px}.el-range-editor--small .el-range-input{font-size:13px}.el-range-editor--small .el-range__close-icon,.el-range-editor--small .el-range__icon{line-height:24px}.el-range-editor--mini.el-input__inner{height:28px}.el-range-editor--mini .el-range-separator{line-height:20px;font-size:12px}.el-range-editor--mini .el-range-input{font-size:12px}.el-range-editor--mini .el-range__close-icon,.el-range-editor--mini .el-range__icon{line-height:20px}.el-range-editor.is-disabled{background-color:#F5F7FA;border-color:#E4E7ED;color:#C0C4CC;cursor:not-allowed}.el-range-editor.is-disabled:focus,.el-range-editor.is-disabled:hover{border-color:#E4E7ED}.el-range-editor.is-disabled input{background-color:#F5F7FA;color:#C0C4CC;cursor:not-allowed}.el-range-editor.is-disabled input::-webkit-input-placeholder{color:#C0C4CC}.el-range-editor.is-disabled input:-ms-input-placeholder{color:#C0C4CC}.el-range-editor.is-disabled input::-ms-input-placeholder{color:#C0C4CC}.el-range-editor.is-disabled input::placeholder{color:#C0C4CC}.el-range-editor.is-disabled .el-range-separator{color:#C0C4CC}.el-picker-panel{color:#606266;border:1px solid #E4E7ED;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);background:#FFF;border-radius:4px;line-height:30px;margin:5px 0}.el-picker-panel__body-wrapper::after,.el-picker-panel__body::after{content:"";display:table;clear:both}.el-picker-panel__content{position:relative;margin:15px}.el-picker-panel__footer{border-top:1px solid #e4e4e4;padding:4px;text-align:right;background-color:#FFF;position:relative;font-size:0}.el-picker-panel__shortcut{display:block;width:100%;border:0;background-color:transparent;line-height:28px;font-size:14px;color:#606266;padding-left:12px;text-align:left;outline:0;cursor:pointer}.el-picker-panel__shortcut:hover{color:#409EFF}.el-picker-panel__shortcut.active{background-color:#e6f1fe;color:#409EFF}.el-picker-panel__btn{border:1px solid #dcdcdc;color:#333;line-height:24px;border-radius:2px;padding:0 20px;cursor:pointer;background-color:transparent;outline:0;font-size:12px}.el-picker-panel__btn[disabled]{color:#ccc;cursor:not-allowed}.el-picker-panel__icon-btn{font-size:12px;color:#303133;border:0;background:0 0;cursor:pointer;outline:0;margin-top:8px}.el-picker-panel__icon-btn:hover{color:#409EFF}.el-picker-panel__icon-btn.is-disabled{color:#bbb}.el-picker-panel__icon-btn.is-disabled:hover{cursor:not-allowed}.el-picker-panel__link-btn{vertical-align:middle}.el-picker-panel [slot=sidebar],.el-picker-panel__sidebar{position:absolute;top:0;bottom:0;width:110px;border-right:1px solid #e4e4e4;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;background-color:#FFF;overflow:auto}.el-picker-panel [slot=sidebar]+.el-picker-panel__body,.el-picker-panel__sidebar+.el-picker-panel__body{margin-left:110px}.el-time-spinner.has-seconds .el-time-spinner__wrapper{width:33.3%}.el-time-spinner__wrapper{max-height:190px;overflow:auto;display:inline-block;width:50%;vertical-align:top;position:relative}.el-time-spinner__wrapper .el-scrollbar__wrap:not(.el-scrollbar__wrap--hidden-default){padding-bottom:15px}.el-time-spinner__input.el-input .el-input__inner,.el-time-spinner__list{padding:0;text-align:center}.el-time-spinner__wrapper.is-arrow{-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;overflow:hidden}.el-time-spinner__wrapper.is-arrow .el-time-spinner__list{-webkit-transform:translateY(-32px);transform:translateY(-32px)}.el-time-spinner__wrapper.is-arrow .el-time-spinner__item:hover:not(.disabled):not(.active){background:#FFF;cursor:default}.el-time-spinner__arrow{font-size:12px;color:#909399;position:absolute;left:0;width:100%;z-index:1;text-align:center;height:30px;line-height:30px;cursor:pointer}.el-time-spinner__arrow:hover{color:#409EFF}.el-time-spinner__arrow.el-icon-arrow-up{top:10px}.el-time-spinner__arrow.el-icon-arrow-down{bottom:10px}.el-time-spinner__input.el-input{width:70%}.el-time-spinner__list{margin:0;list-style:none}.el-time-spinner__list::after,.el-time-spinner__list::before{content:'';display:block;width:100%;height:80px}.el-time-spinner__item{height:32px;line-height:32px;font-size:12px;color:#606266}.el-time-spinner__item:hover:not(.disabled):not(.active){background:#F5F7FA;cursor:pointer}.el-time-spinner__item.active:not(.disabled){color:#303133;font-weight:700}.el-time-spinner__item.disabled{color:#C0C4CC;cursor:not-allowed}.el-time-panel{margin:5px 0;border:1px solid #E4E7ED;background-color:#FFF;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);border-radius:2px;position:absolute;width:180px;left:0;z-index:1000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-box-sizing:content-box;box-sizing:content-box}.el-time-panel__content{font-size:0;position:relative;overflow:hidden}.el-time-panel__content::after,.el-time-panel__content::before{content:"";top:50%;position:absolute;margin-top:-15px;height:32px;z-index:-1;left:0;right:0;-webkit-box-sizing:border-box;box-sizing:border-box;padding-top:6px;text-align:left;border-top:1px solid #E4E7ED;border-bottom:1px solid #E4E7ED}.el-time-panel__content::after{left:50%;margin-left:12%;margin-right:12%}.el-time-panel__content::before{padding-left:50%;margin-right:12%;margin-left:12%}.el-time-panel__content.has-seconds::after{left:calc(100% / 3 * 2)}.el-time-panel__content.has-seconds::before{padding-left:calc(100% / 3)}.el-time-panel__footer{border-top:1px solid #e4e4e4;padding:4px;height:36px;line-height:25px;text-align:right;-webkit-box-sizing:border-box;box-sizing:border-box}.el-time-panel__btn{border:none;line-height:28px;padding:0 5px;margin:0 5px;cursor:pointer;background-color:transparent;outline:0;font-size:12px;color:#303133}.el-time-panel__btn.confirm{font-weight:800;color:#409EFF}.el-time-range-picker{width:354px;overflow:visible}.el-time-range-picker__content{position:relative;text-align:center;padding:10px}.el-time-range-picker__cell{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:4px 7px 7px;width:50%;display:inline-block}.el-time-range-picker__header{margin-bottom:5px;text-align:center;font-size:14px}.el-time-range-picker__body{border-radius:2px;border:1px solid #E4E7ED}.el-popover{position:absolute;background:#FFF;min-width:150px;border-radius:4px;border:1px solid #EBEEF5;padding:12px;z-index:2000;color:#606266;line-height:1.4;text-align:justify;font-size:14px;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);word-break:break-all}.el-card.is-always-shadow,.el-card.is-hover-shadow:focus,.el-card.is-hover-shadow:hover,.el-cascader__dropdown,.el-color-picker__panel,.el-message-box,.el-notification{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-popover--plain{padding:18px 20px}.el-popover__title{color:#303133;font-size:16px;line-height:1;margin-bottom:12px}.el-popover:focus,.el-popover:focus:active,.el-popover__reference:focus:hover,.el-popover__reference:focus:not(.focusing){outline-width:0}.v-modal-enter{-webkit-animation:v-modal-in .2s ease;animation:v-modal-in .2s ease}.v-modal-leave{-webkit-animation:v-modal-out .2s ease forwards;animation:v-modal-out .2s ease forwards}@keyframes v-modal-in{0%{opacity:0}}@keyframes v-modal-out{100%{opacity:0}}.v-modal{position:fixed;left:0;top:0;width:100%;height:100%;opacity:.5;background:#000}.el-popup-parent--hidden{overflow:hidden}.el-message-box{display:inline-block;width:420px;padding-bottom:10px;vertical-align:middle;background-color:#FFF;border-radius:4px;border:1px solid #EBEEF5;font-size:18px;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);text-align:left;overflow:hidden;-webkit-backface-visibility:hidden;backface-visibility:hidden}.el-message-box__wrapper{position:fixed;top:0;bottom:0;left:0;right:0;text-align:center}.el-message-box__wrapper::after{content:"";display:inline-block;height:100%;width:0;vertical-align:middle}.el-message-box__header{position:relative;padding:15px 15px 10px}.el-message-box__title{padding-left:0;margin-bottom:0;font-size:18px;line-height:1;color:#303133}.el-message-box__headerbtn{position:absolute;top:15px;right:15px;padding:0;border:none;outline:0;background:0 0;font-size:16px;cursor:pointer}.el-form-item.is-error .el-input__inner,.el-form-item.is-error .el-input__inner:focus,.el-form-item.is-error .el-textarea__inner,.el-form-item.is-error .el-textarea__inner:focus,.el-message-box__input input.invalid,.el-message-box__input input.invalid:focus{border-color:#F56C6C}.el-message-box__headerbtn .el-message-box__close{color:#909399}.el-message-box__headerbtn:focus .el-message-box__close,.el-message-box__headerbtn:hover .el-message-box__close{color:#409EFF}.el-message-box__content{padding:10px 15px;color:#606266;font-size:14px}.el-message-box__container{position:relative}.el-message-box__input{padding-top:15px}.el-message-box__status{position:absolute;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);font-size:24px!important}.el-message-box__status::before{padding-left:1px}.el-message-box__status+.el-message-box__message{padding-left:36px;padding-right:12px}.el-message-box__status.el-icon-success{color:#67C23A}.el-message-box__status.el-icon-info{color:#909399}.el-message-box__status.el-icon-warning{color:#E6A23C}.el-message-box__status.el-icon-error{color:#F56C6C}.el-message-box__message{margin:0}.el-message-box__message p{margin:0;line-height:24px}.el-message-box__errormsg{color:#F56C6C;font-size:12px;min-height:18px;margin-top:2px}.el-message-box__btns{padding:5px 15px 0;text-align:right}.el-message-box__btns button:nth-child(2){margin-left:10px}.el-message-box__btns-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.el-message-box--center{padding-bottom:30px}.el-message-box--center .el-message-box__header{padding-top:30px}.el-message-box--center .el-message-box__title{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-message-box--center .el-message-box__status{position:relative;top:auto;padding-right:5px;text-align:center;-webkit-transform:translateY(-1px);transform:translateY(-1px)}.el-message-box--center .el-message-box__message{margin-left:0}.el-message-box--center .el-message-box__btns,.el-message-box--center .el-message-box__content{text-align:center}.el-message-box--center .el-message-box__content{padding-left:27px;padding-right:27px}.msgbox-fade-enter-active{-webkit-animation:msgbox-fade-in .3s;animation:msgbox-fade-in .3s}.msgbox-fade-leave-active{-webkit-animation:msgbox-fade-out .3s;animation:msgbox-fade-out .3s}@-webkit-keyframes msgbox-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@keyframes msgbox-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@-webkit-keyframes msgbox-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes msgbox-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.el-breadcrumb{font-size:14px;line-height:1}.el-breadcrumb::after,.el-breadcrumb::before{display:table;content:""}.el-breadcrumb::after{clear:both}.el-breadcrumb__separator{margin:0 9px;font-weight:700;color:#C0C4CC}.el-breadcrumb__separator[class*=icon]{margin:0 6px;font-weight:400}.el-breadcrumb__item{float:left}.el-breadcrumb__inner{color:#606266}.el-breadcrumb__inner a,.el-breadcrumb__inner.is-link{font-weight:700;text-decoration:none;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1);color:#303133}.el-breadcrumb__inner a:hover,.el-breadcrumb__inner.is-link:hover{color:#409EFF;cursor:pointer}.el-breadcrumb__item:last-child .el-breadcrumb__inner,.el-breadcrumb__item:last-child .el-breadcrumb__inner a,.el-breadcrumb__item:last-child .el-breadcrumb__inner a:hover,.el-breadcrumb__item:last-child .el-breadcrumb__inner:hover{font-weight:400;color:#606266;cursor:text}.el-form--label-left .el-form-item__label{text-align:left}.el-form--label-top .el-form-item__label{float:none;display:inline-block;text-align:left;padding:0 0 10px}.el-form--inline .el-form-item{display:inline-block;margin-right:10px;vertical-align:top}.el-form--inline .el-form-item__label{float:none;display:inline-block}.el-form--inline .el-form-item__content{display:inline-block;vertical-align:top}.el-form--inline.el-form--label-top .el-form-item__content{display:block}.el-form-item{margin-bottom:22px}.el-form-item::after,.el-form-item::before{display:table;content:""}.el-form-item::after{clear:both}.el-form-item .el-form-item{margin-bottom:0}.el-form-item--mini.el-form-item,.el-form-item--small.el-form-item{margin-bottom:18px}.el-form-item .el-input__validateIcon{display:none}.el-form-item--medium .el-form-item__content,.el-form-item--medium .el-form-item__label{line-height:36px}.el-form-item--small .el-form-item__content,.el-form-item--small .el-form-item__label{line-height:32px}.el-form-item--small .el-form-item__error{padding-top:2px}.el-form-item--mini .el-form-item__content,.el-form-item--mini .el-form-item__label{line-height:28px}.el-form-item--mini .el-form-item__error{padding-top:1px}.el-form-item__label-wrap{float:left}.el-form-item__label-wrap .el-form-item__label{display:inline-block;float:none}.el-form-item__label{text-align:right;vertical-align:middle;float:left;font-size:14px;color:#606266;line-height:40px;padding:0 12px 0 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-form-item__content{line-height:40px;position:relative;font-size:14px}.el-form-item__content::after,.el-form-item__content::before{display:table;content:""}.el-form-item__content::after{clear:both}.el-form-item__content .el-input-group{vertical-align:top}.el-form-item__error{color:#F56C6C;font-size:12px;line-height:1;padding-top:4px;position:absolute;top:100%;left:0}.el-form-item__error--inline{position:relative;top:auto;left:auto;display:inline-block;margin-left:10px}.el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap>.el-form-item__label:before,.el-form-item.is-required:not(.is-no-asterisk)>.el-form-item__label:before{content:'*';color:#F56C6C;margin-right:4px}.el-form-item.is-error .el-input-group__append .el-input__inner,.el-form-item.is-error .el-input-group__prepend .el-input__inner{border-color:transparent}.el-form-item.is-error .el-input__validateIcon{color:#F56C6C}.el-form-item--feedback .el-input__validateIcon{display:inline-block}.el-tabs__header{padding:0;position:relative;margin:0 0 15px}.el-tabs__active-bar{position:absolute;bottom:0;left:0;height:2px;background-color:#409EFF;z-index:1;-webkit-transition:-webkit-transform .3s cubic-bezier(.645,.045,.355,1);transition:-webkit-transform .3s cubic-bezier(.645,.045,.355,1);transition:transform .3s cubic-bezier(.645,.045,.355,1);transition:transform .3s cubic-bezier(.645,.045,.355,1),-webkit-transform .3s cubic-bezier(.645,.045,.355,1);list-style:none}.el-tabs__new-tab{float:right;border:1px solid #d3dce6;height:18px;width:18px;line-height:18px;margin:12px 0 9px 10px;border-radius:3px;text-align:center;font-size:12px;color:#d3dce6;cursor:pointer;-webkit-transition:all .15s;transition:all .15s}.el-tabs__new-tab .el-icon-plus{-webkit-transform:scale(.8,.8);transform:scale(.8,.8)}.el-tabs__new-tab:hover{color:#409EFF}.el-tabs__nav-wrap{overflow:hidden;margin-bottom:-1px;position:relative}.el-tabs__nav-wrap::after{content:"";position:absolute;left:0;bottom:0;width:100%;height:2px;background-color:#E4E7ED;z-index:1}.el-tabs__nav-wrap.is-scrollable{padding:0 20px;-webkit-box-sizing:border-box;box-sizing:border-box}.el-tabs__nav-scroll{overflow:hidden}.el-tabs__nav-next,.el-tabs__nav-prev{position:absolute;cursor:pointer;line-height:44px;font-size:12px;color:#909399}.el-tabs__nav-next{right:0}.el-tabs__nav-prev{left:0}.el-tabs__nav{white-space:nowrap;position:relative;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;float:left;z-index:2}.el-tabs__nav.is-stretch{min-width:100%;display:-webkit-box;display:-ms-flexbox;display:flex}.el-tabs__nav.is-stretch>*{-webkit-box-flex:1;-ms-flex:1;flex:1;text-align:center}.el-tabs__item{padding:0 20px;height:40px;-webkit-box-sizing:border-box;box-sizing:border-box;line-height:40px;display:inline-block;list-style:none;font-size:14px;font-weight:500;color:#303133;position:relative}.el-tabs__item:focus,.el-tabs__item:focus:active{outline:0}.el-tabs__item:focus.is-active.is-focus:not(:active){-webkit-box-shadow:0 0 2px 2px #409EFF inset;box-shadow:0 0 2px 2px #409EFF inset;border-radius:3px}.el-tabs__item .el-icon-close{border-radius:50%;text-align:center;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);margin-left:5px}.el-tabs__item .el-icon-close:before{-webkit-transform:scale(.9);transform:scale(.9);display:inline-block}.el-tabs--card>.el-tabs__header .el-tabs__active-bar,.el-tabs--left.el-tabs--card .el-tabs__active-bar.is-left,.el-tabs--right.el-tabs--card .el-tabs__active-bar.is-right{display:none}.el-tabs__item .el-icon-close:hover{background-color:#C0C4CC;color:#FFF}.el-tabs__item.is-active{color:#409EFF}.el-tabs__item:hover{color:#409EFF;cursor:pointer}.el-tabs__item.is-disabled{color:#C0C4CC;cursor:default}.el-tabs__content{overflow:hidden;position:relative}.el-tabs--card>.el-tabs__header{border-bottom:1px solid #E4E7ED}.el-tabs--card>.el-tabs__header .el-tabs__nav-wrap::after{content:none}.el-tabs--card>.el-tabs__header .el-tabs__nav{border:1px solid #E4E7ED;border-bottom:none;border-radius:4px 4px 0 0;-webkit-box-sizing:border-box;box-sizing:border-box}.el-tabs--card>.el-tabs__header .el-tabs__item .el-icon-close{position:relative;font-size:12px;width:0;height:14px;vertical-align:middle;line-height:15px;overflow:hidden;top:-1px;right:-2px;-webkit-transform-origin:100% 50%;transform-origin:100% 50%}.el-tabs--card>.el-tabs__header .el-tabs__item{border-bottom:1px solid transparent;border-left:1px solid #E4E7ED;-webkit-transition:color .3s cubic-bezier(.645,.045,.355,1),padding .3s cubic-bezier(.645,.045,.355,1);transition:color .3s cubic-bezier(.645,.045,.355,1),padding .3s cubic-bezier(.645,.045,.355,1)}.el-tabs--card>.el-tabs__header .el-tabs__item:first-child{border-left:none}.el-tabs--card>.el-tabs__header .el-tabs__item.is-closable:hover{padding-left:13px;padding-right:13px}.el-tabs--card>.el-tabs__header .el-tabs__item.is-closable:hover .el-icon-close{width:14px}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active{border-bottom-color:#FFF}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active.is-closable{padding-left:20px;padding-right:20px}.el-tabs--card>.el-tabs__header .el-tabs__item.is-active.is-closable .el-icon-close{width:14px}.el-tabs--border-card{background:#FFF;border:1px solid #DCDFE6;-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04);box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04)}.el-tabs--border-card>.el-tabs__content{padding:15px}.el-tabs--border-card>.el-tabs__header{background-color:#F5F7FA;border-bottom:1px solid #E4E7ED;margin:0}.el-tabs--border-card>.el-tabs__header .el-tabs__nav-wrap::after{content:none}.el-tabs--border-card>.el-tabs__header .el-tabs__item{-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);border:1px solid transparent;margin-top:-1px;color:#909399}.el-tabs--border-card>.el-tabs__header .el-tabs__item+.el-tabs__item,.el-tabs--border-card>.el-tabs__header .el-tabs__item:first-child{margin-left:-1px}.el-col-offset-0,.el-tabs--border-card>.el-tabs__header .is-scrollable .el-tabs__item:first-child{margin-left:0}.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active{color:#409EFF;background-color:#FFF;border-right-color:#DCDFE6;border-left-color:#DCDFE6}.el-tabs--border-card>.el-tabs__header .el-tabs__item:not(.is-disabled):hover{color:#409EFF}.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-disabled{color:#C0C4CC}.el-tabs--bottom .el-tabs__item.is-bottom:nth-child(2),.el-tabs--bottom .el-tabs__item.is-top:nth-child(2),.el-tabs--top .el-tabs__item.is-bottom:nth-child(2),.el-tabs--top .el-tabs__item.is-top:nth-child(2){padding-left:0}.el-tabs--bottom .el-tabs__item.is-bottom:last-child,.el-tabs--bottom .el-tabs__item.is-top:last-child,.el-tabs--top .el-tabs__item.is-bottom:last-child,.el-tabs--top .el-tabs__item.is-top:last-child{padding-right:0}.el-cascader-menu:last-child .el-cascader-node,.el-tabs--bottom .el-tabs--left>.el-tabs__header .el-tabs__item:last-child,.el-tabs--bottom .el-tabs--right>.el-tabs__header .el-tabs__item:last-child,.el-tabs--bottom.el-tabs--border-card>.el-tabs__header .el-tabs__item:last-child,.el-tabs--bottom.el-tabs--card>.el-tabs__header .el-tabs__item:last-child,.el-tabs--top .el-tabs--left>.el-tabs__header .el-tabs__item:last-child,.el-tabs--top .el-tabs--right>.el-tabs__header .el-tabs__item:last-child,.el-tabs--top.el-tabs--border-card>.el-tabs__header .el-tabs__item:last-child,.el-tabs--top.el-tabs--card>.el-tabs__header .el-tabs__item:last-child{padding-right:20px}.el-tabs--bottom .el-tabs--left>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--bottom .el-tabs--right>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--bottom.el-tabs--border-card>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--bottom.el-tabs--card>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--top .el-tabs--left>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--top .el-tabs--right>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--top.el-tabs--border-card>.el-tabs__header .el-tabs__item:nth-child(2),.el-tabs--top.el-tabs--card>.el-tabs__header .el-tabs__item:nth-child(2){padding-left:20px}.el-tabs--bottom .el-tabs__header.is-bottom{margin-bottom:0;margin-top:10px}.el-tabs--bottom.el-tabs--border-card .el-tabs__header.is-bottom{border-bottom:0;border-top:1px solid #DCDFE6}.el-tabs--bottom.el-tabs--border-card .el-tabs__nav-wrap.is-bottom{margin-top:-1px;margin-bottom:0}.el-tabs--bottom.el-tabs--border-card .el-tabs__item.is-bottom:not(.is-active){border:1px solid transparent}.el-tabs--bottom.el-tabs--border-card .el-tabs__item.is-bottom{margin:0 -1px -1px}.el-tabs--left,.el-tabs--right{overflow:hidden}.el-tabs--left .el-tabs__header.is-left,.el-tabs--left .el-tabs__header.is-right,.el-tabs--left .el-tabs__nav-scroll,.el-tabs--left .el-tabs__nav-wrap.is-left,.el-tabs--left .el-tabs__nav-wrap.is-right,.el-tabs--right .el-tabs__header.is-left,.el-tabs--right .el-tabs__header.is-right,.el-tabs--right .el-tabs__nav-scroll,.el-tabs--right .el-tabs__nav-wrap.is-left,.el-tabs--right .el-tabs__nav-wrap.is-right{height:100%}.el-tabs--left .el-tabs__active-bar.is-left,.el-tabs--left .el-tabs__active-bar.is-right,.el-tabs--right .el-tabs__active-bar.is-left,.el-tabs--right .el-tabs__active-bar.is-right{top:0;bottom:auto;width:2px;height:auto}.el-tabs--left .el-tabs__nav-wrap.is-left,.el-tabs--left .el-tabs__nav-wrap.is-right,.el-tabs--right .el-tabs__nav-wrap.is-left,.el-tabs--right .el-tabs__nav-wrap.is-right{margin-bottom:0}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-next,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev{height:30px;line-height:30px;width:100%;text-align:center;cursor:pointer}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-next i,.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev i,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-next i,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev i,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-next i,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev i,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-next i,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev i{-webkit-transform:rotateZ(90deg);transform:rotateZ(90deg)}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-prev,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-prev{left:auto;top:0}.el-tabs--left .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--left .el-tabs__nav-wrap.is-right>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-left>.el-tabs__nav-next,.el-tabs--right .el-tabs__nav-wrap.is-right>.el-tabs__nav-next{right:auto;bottom:0}.el-tabs--left .el-tabs__active-bar.is-left,.el-tabs--left .el-tabs__nav-wrap.is-left::after{right:0;left:auto}.el-tabs--left .el-tabs__nav-wrap.is-left.is-scrollable,.el-tabs--left .el-tabs__nav-wrap.is-right.is-scrollable,.el-tabs--right .el-tabs__nav-wrap.is-left.is-scrollable,.el-tabs--right .el-tabs__nav-wrap.is-right.is-scrollable{padding:30px 0}.el-tabs--left .el-tabs__nav-wrap.is-left::after,.el-tabs--left .el-tabs__nav-wrap.is-right::after,.el-tabs--right .el-tabs__nav-wrap.is-left::after,.el-tabs--right .el-tabs__nav-wrap.is-right::after{height:100%;width:2px;bottom:auto;top:0}.el-tabs--left .el-tabs__nav.is-left,.el-tabs--left .el-tabs__nav.is-right,.el-tabs--right .el-tabs__nav.is-left,.el-tabs--right .el-tabs__nav.is-right{float:none}.el-tabs--left .el-tabs__item.is-left,.el-tabs--left .el-tabs__item.is-right,.el-tabs--right .el-tabs__item.is-left,.el-tabs--right .el-tabs__item.is-right{display:block}.el-tabs--left .el-tabs__header.is-left{float:left;margin-bottom:0;margin-right:10px}.el-button-group>.el-button:not(:last-child),.el-tabs--left .el-tabs__nav-wrap.is-left{margin-right:-1px}.el-tabs--left .el-tabs__item.is-left{text-align:right}.el-tabs--left.el-tabs--card .el-tabs__item.is-left{border-left:none;border-right:1px solid #E4E7ED;border-bottom:none;border-top:1px solid #E4E7ED;text-align:left}.el-tabs--left.el-tabs--card .el-tabs__item.is-left:first-child{border-right:1px solid #E4E7ED;border-top:none}.el-tabs--left.el-tabs--card .el-tabs__item.is-left.is-active{border:1px solid #E4E7ED;border-right-color:#fff;border-left:none;border-bottom:none}.el-tabs--left.el-tabs--card .el-tabs__item.is-left.is-active:first-child{border-top:none}.el-tabs--left.el-tabs--card .el-tabs__item.is-left.is-active:last-child{border-bottom:none}.el-tabs--left.el-tabs--card .el-tabs__nav{border-radius:4px 0 0 4px;border-bottom:1px solid #E4E7ED;border-right:none}.el-tabs--left.el-tabs--card .el-tabs__new-tab{float:none}.el-tabs--left.el-tabs--border-card .el-tabs__header.is-left{border-right:1px solid #dfe4ed}.el-tabs--left.el-tabs--border-card .el-tabs__item.is-left{border:1px solid transparent;margin:-1px 0 -1px -1px}.el-tabs--left.el-tabs--border-card .el-tabs__item.is-left.is-active{border-color:#d1dbe5 transparent}.el-tabs--right .el-tabs__header.is-right{float:right;margin-bottom:0;margin-left:10px}.el-tabs--right .el-tabs__nav-wrap.is-right{margin-left:-1px}.el-tabs--right .el-tabs__nav-wrap.is-right::after{left:0;right:auto}.el-tabs--right .el-tabs__active-bar.is-right{left:0}.el-tabs--right.el-tabs--card .el-tabs__item.is-right{border-bottom:none;border-top:1px solid #E4E7ED}.el-tabs--right.el-tabs--card .el-tabs__item.is-right:first-child{border-left:1px solid #E4E7ED;border-top:none}.el-tabs--right.el-tabs--card .el-tabs__item.is-right.is-active{border:1px solid #E4E7ED;border-left-color:#fff;border-right:none;border-bottom:none}.el-tabs--right.el-tabs--card .el-tabs__item.is-right.is-active:first-child{border-top:none}.el-tabs--right.el-tabs--card .el-tabs__item.is-right.is-active:last-child{border-bottom:none}.el-tabs--right.el-tabs--card .el-tabs__nav{border-radius:0 4px 4px 0;border-bottom:1px solid #E4E7ED;border-left:none}.el-tabs--right.el-tabs--border-card .el-tabs__header.is-right{border-left:1px solid #dfe4ed}.el-tabs--right.el-tabs--border-card .el-tabs__item.is-right{border:1px solid transparent;margin:-1px -1px -1px 0}.el-tabs--right.el-tabs--border-card .el-tabs__item.is-right.is-active{border-color:#d1dbe5 transparent}.slideInLeft-transition,.slideInRight-transition{display:inline-block}.slideInRight-enter{-webkit-animation:slideInRight-enter .3s;animation:slideInRight-enter .3s}.slideInRight-leave{position:absolute;left:0;right:0;-webkit-animation:slideInRight-leave .3s;animation:slideInRight-leave .3s}.slideInLeft-enter{-webkit-animation:slideInLeft-enter .3s;animation:slideInLeft-enter .3s}.slideInLeft-leave{position:absolute;left:0;right:0;-webkit-animation:slideInLeft-leave .3s;animation:slideInLeft-leave .3s}@-webkit-keyframes slideInRight-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInRight-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes slideInRight-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%);opacity:0}}@keyframes slideInRight-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(100%);transform:translateX(100%);opacity:0}}@-webkit-keyframes slideInLeft-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes slideInLeft-enter{0%{opacity:0;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes slideInLeft-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%);opacity:0}}@keyframes slideInLeft-leave{0%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(0);transform:translateX(0);opacity:1}100%{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:translateX(-100%);transform:translateX(-100%);opacity:0}}.el-tree{position:relative;cursor:default;background:#FFF;color:#606266}.el-tree__empty-block{position:relative;min-height:60px;text-align:center;width:100%;height:100%}.el-tree__empty-text{position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);color:#909399;font-size:14px}.el-tree__drop-indicator{position:absolute;left:0;right:0;height:1px;background-color:#409EFF}.el-tree-node{white-space:nowrap;outline:0}.el-tree-node:focus>.el-tree-node__content{background-color:#F5F7FA}.el-tree-node.is-drop-inner>.el-tree-node__content .el-tree-node__label{background-color:#409EFF;color:#fff}.el-tree-node__content:hover,.el-upload-list__item:hover{background-color:#F5F7FA}.el-tree-node__content{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:26px;cursor:pointer}.el-tree-node__content>.el-tree-node__expand-icon{padding:6px}.el-tree-node__content>label.el-checkbox{margin-right:8px}.el-tree.is-dragging .el-tree-node__content{cursor:move}.el-tree.is-dragging .el-tree-node__content *{pointer-events:none}.el-tree.is-dragging.is-drop-not-allow .el-tree-node__content{cursor:not-allowed}.el-tree-node__expand-icon{cursor:pointer;color:#C0C4CC;font-size:12px;-webkit-transform:rotate(0);transform:rotate(0);-webkit-transition:-webkit-transform .3s ease-in-out;transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;transition:transform .3s ease-in-out,-webkit-transform .3s ease-in-out}.el-tree-node__expand-icon.expanded{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-tree-node__expand-icon.is-leaf{color:transparent;cursor:default}.el-tree-node__label{font-size:14px}.el-tree-node__loading-icon{margin-right:8px;font-size:14px;color:#C0C4CC}.el-tree-node>.el-tree-node__children{overflow:hidden;background-color:transparent}.el-tree-node.is-expanded>.el-tree-node__children{display:block}.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content{background-color:#f0f7ff}.el-alert{width:100%;padding:8px 16px;margin:0;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;position:relative;background-color:#FFF;overflow:hidden;opacity:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-transition:opacity .2s;transition:opacity .2s}.el-alert.is-light .el-alert__closebtn{color:#C0C4CC}.el-alert.is-dark .el-alert__closebtn,.el-alert.is-dark .el-alert__description{color:#FFF}.el-alert.is-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-alert--success.is-light{background-color:#f0f9eb;color:#67C23A}.el-alert--success.is-light .el-alert__description{color:#67C23A}.el-alert--success.is-dark{background-color:#67C23A;color:#FFF}.el-alert--info.is-light{background-color:#f4f4f5;color:#909399}.el-alert--info.is-dark{background-color:#909399;color:#FFF}.el-alert--info .el-alert__description{color:#909399}.el-alert--warning.is-light{background-color:#fdf6ec;color:#E6A23C}.el-alert--warning.is-light .el-alert__description{color:#E6A23C}.el-alert--warning.is-dark{background-color:#E6A23C;color:#FFF}.el-alert--error.is-light{background-color:#fef0f0;color:#F56C6C}.el-alert--error.is-light .el-alert__description{color:#F56C6C}.el-alert--error.is-dark{background-color:#F56C6C;color:#FFF}.el-alert__content{display:table-cell;padding:0 8px}.el-alert__icon{font-size:16px;width:16px}.el-alert__icon.is-big{font-size:28px;width:28px}.el-alert__title{font-size:13px;line-height:18px}.el-alert__title.is-bold{font-weight:700}.el-alert .el-alert__description{font-size:12px;margin:5px 0 0}.el-alert__closebtn{font-size:12px;opacity:1;position:absolute;top:12px;right:15px;cursor:pointer}.el-alert-fade-enter,.el-alert-fade-leave-active,.el-loading-fade-enter,.el-loading-fade-leave-active,.el-notification-fade-leave-active,.el-upload iframe{opacity:0}.el-carousel__arrow--right,.el-notification.right{right:16px}.el-alert__closebtn.is-customed{font-style:normal;font-size:13px;top:9px}.el-notification{display:-webkit-box;display:-ms-flexbox;display:flex;width:330px;padding:14px 26px 14px 13px;border-radius:8px;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #EBEEF5;position:fixed;background-color:#FFF;box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-transition:opacity .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;transition:opacity .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;transition:opacity .3s,transform .3s,left .3s,right .3s,top .4s,bottom .3s;transition:opacity .3s,transform .3s,left .3s,right .3s,top .4s,bottom .3s,-webkit-transform .3s;overflow:hidden}.el-notification.left{left:16px}.el-notification__group{margin-left:13px;margin-right:8px}.el-notification__title{font-weight:700;font-size:16px;color:#303133;margin:0}.el-notification__content{font-size:14px;line-height:21px;margin:6px 0 0;color:#606266;text-align:justify}.el-notification__content p{margin:0}.el-notification__icon{height:24px;width:24px;font-size:24px}.el-notification__closeBtn{position:absolute;top:18px;right:15px;cursor:pointer;color:#909399;font-size:16px}.el-notification__closeBtn:hover{color:#606266}.el-notification .el-icon-success{color:#67C23A}.el-notification .el-icon-error{color:#F56C6C}.el-notification .el-icon-info{color:#909399}.el-notification .el-icon-warning{color:#E6A23C}.el-notification-fade-enter.right{right:0;-webkit-transform:translateX(100%);transform:translateX(100%)}.el-notification-fade-enter.left{left:0;-webkit-transform:translateX(-100%);transform:translateX(-100%)}.el-input-number{position:relative;display:inline-block;width:180px;line-height:38px}.el-input-number .el-input{display:block}.el-input-number .el-input__inner{-webkit-appearance:none;padding-left:50px;padding-right:50px;text-align:center}.el-input-number__decrease,.el-input-number__increase{position:absolute;z-index:1;top:1px;width:40px;height:auto;text-align:center;background:#F5F7FA;color:#606266;cursor:pointer;font-size:13px}.el-input-number__decrease:hover,.el-input-number__increase:hover{color:#409EFF}.el-input-number__decrease:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled),.el-input-number__increase:hover:not(.is-disabled)~.el-input .el-input__inner:not(.is-disabled){border-color:#409EFF}.el-input-number__decrease.is-disabled,.el-input-number__increase.is-disabled{color:#C0C4CC;cursor:not-allowed}.el-input-number__increase{right:1px;border-radius:0 4px 4px 0;border-left:1px solid #DCDFE6}.el-input-number__decrease{left:1px;border-radius:4px 0 0 4px;border-right:1px solid #DCDFE6}.el-input-number.is-disabled .el-input-number__decrease,.el-input-number.is-disabled .el-input-number__increase{border-color:#E4E7ED;color:#E4E7ED}.el-input-number.is-disabled .el-input-number__decrease:hover,.el-input-number.is-disabled .el-input-number__increase:hover{color:#E4E7ED;cursor:not-allowed}.el-input-number--medium{width:200px;line-height:34px}.el-input-number--medium .el-input-number__decrease,.el-input-number--medium .el-input-number__increase{width:36px;font-size:14px}.el-input-number--medium .el-input__inner{padding-left:43px;padding-right:43px}.el-input-number--small{width:130px;line-height:30px}.el-input-number--small .el-input-number__decrease,.el-input-number--small .el-input-number__increase{width:32px;font-size:13px}.el-input-number--small .el-input-number__decrease [class*=el-icon],.el-input-number--small .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.9);transform:scale(.9)}.el-input-number--small .el-input__inner{padding-left:39px;padding-right:39px}.el-input-number--mini{width:130px;line-height:26px}.el-input-number--mini .el-input-number__decrease,.el-input-number--mini .el-input-number__increase{width:28px;font-size:12px}.el-input-number--mini .el-input-number__decrease [class*=el-icon],.el-input-number--mini .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.8);transform:scale(.8)}.el-input-number--mini .el-input__inner{padding-left:35px;padding-right:35px}.el-input-number.is-without-controls .el-input__inner{padding-left:15px;padding-right:15px}.el-input-number.is-controls-right .el-input__inner{padding-left:15px;padding-right:50px}.el-input-number.is-controls-right .el-input-number__decrease,.el-input-number.is-controls-right .el-input-number__increase{height:auto;line-height:19px}.el-input-number.is-controls-right .el-input-number__decrease [class*=el-icon],.el-input-number.is-controls-right .el-input-number__increase [class*=el-icon]{-webkit-transform:scale(.8);transform:scale(.8)}.el-input-number.is-controls-right .el-input-number__increase{border-radius:0 4px 0 0;border-bottom:1px solid #DCDFE6}.el-input-number.is-controls-right .el-input-number__decrease{right:1px;bottom:1px;top:auto;left:auto;border-right:none;border-left:1px solid #DCDFE6;border-radius:0 0 4px}.el-input-number.is-controls-right[class*=medium] [class*=decrease],.el-input-number.is-controls-right[class*=medium] [class*=increase]{line-height:17px}.el-input-number.is-controls-right[class*=small] [class*=decrease],.el-input-number.is-controls-right[class*=small] [class*=increase]{line-height:15px}.el-input-number.is-controls-right[class*=mini] [class*=decrease],.el-input-number.is-controls-right[class*=mini] [class*=increase]{line-height:13px}.el-tooltip:focus:hover,.el-tooltip:focus:not(.focusing){outline-width:0}.el-tooltip__popper{position:absolute;border-radius:4px;padding:10px;z-index:2000;font-size:12px;line-height:1.2;min-width:10px;word-wrap:break-word}.el-tooltip__popper .popper__arrow,.el-tooltip__popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-tooltip__popper .popper__arrow{border-width:6px}.el-tooltip__popper .popper__arrow::after{content:" ";border-width:5px}.el-button-group::after,.el-button-group::before,.el-color-dropdown__main-wrapper::after,.el-link.is-underline:hover:after,.el-page-header__left::after,.el-progress-bar__inner::after,.el-row::after,.el-row::before,.el-slider::after,.el-slider::before,.el-slider__button-wrapper::after,.el-transfer-panel .el-transfer-panel__footer::after,.el-upload-cover::after,.el-upload-list--picture-card .el-upload-list__item-actions::after{content:""}.el-tooltip__popper[x-placement^=top]{margin-bottom:12px}.el-tooltip__popper[x-placement^=top] .popper__arrow{bottom:-6px;border-top-color:#303133;border-bottom-width:0}.el-tooltip__popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-5px;border-top-color:#303133;border-bottom-width:0}.el-tooltip__popper[x-placement^=bottom]{margin-top:12px}.el-tooltip__popper[x-placement^=bottom] .popper__arrow{top:-6px;border-top-width:0;border-bottom-color:#303133}.el-tooltip__popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-5px;border-top-width:0;border-bottom-color:#303133}.el-tooltip__popper[x-placement^=right]{margin-left:12px}.el-tooltip__popper[x-placement^=right] .popper__arrow{left:-6px;border-right-color:#303133;border-left-width:0}.el-tooltip__popper[x-placement^=right] .popper__arrow::after{bottom:-5px;left:1px;border-right-color:#303133;border-left-width:0}.el-tooltip__popper[x-placement^=left]{margin-right:12px}.el-tooltip__popper[x-placement^=left] .popper__arrow{right:-6px;border-right-width:0;border-left-color:#303133}.el-tooltip__popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-5px;margin-left:-5px;border-right-width:0;border-left-color:#303133}.el-tooltip__popper.is-dark{background:#303133;color:#FFF}.el-tooltip__popper.is-light{background:#FFF;border:1px solid #303133}.el-tooltip__popper.is-light[x-placement^=top] .popper__arrow{border-top-color:#303133}.el-tooltip__popper.is-light[x-placement^=top] .popper__arrow::after{border-top-color:#FFF}.el-tooltip__popper.is-light[x-placement^=bottom] .popper__arrow{border-bottom-color:#303133}.el-tooltip__popper.is-light[x-placement^=bottom] .popper__arrow::after{border-bottom-color:#FFF}.el-tooltip__popper.is-light[x-placement^=left] .popper__arrow{border-left-color:#303133}.el-tooltip__popper.is-light[x-placement^=left] .popper__arrow::after{border-left-color:#FFF}.el-tooltip__popper.is-light[x-placement^=right] .popper__arrow{border-right-color:#303133}.el-tooltip__popper.is-light[x-placement^=right] .popper__arrow::after{border-right-color:#FFF}.el-slider::after,.el-slider::before{display:table}.el-slider__button-wrapper .el-tooltip,.el-slider__button-wrapper::after{display:inline-block;vertical-align:middle}.el-slider::after{clear:both}.el-slider__runway{width:100%;height:6px;margin:16px 0;background-color:#E4E7ED;border-radius:3px;position:relative;cursor:pointer;vertical-align:middle}.el-slider__runway.show-input{margin-right:160px;width:auto}.el-slider__runway.disabled{cursor:default}.el-slider__runway.disabled .el-slider__bar{background-color:#C0C4CC}.el-slider__runway.disabled .el-slider__button{border-color:#C0C4CC}.el-slider__runway.disabled .el-slider__button-wrapper.dragging,.el-slider__runway.disabled .el-slider__button-wrapper.hover,.el-slider__runway.disabled .el-slider__button-wrapper:hover{cursor:not-allowed}.el-slider__runway.disabled .el-slider__button.dragging,.el-slider__runway.disabled .el-slider__button.hover,.el-slider__runway.disabled .el-slider__button:hover{-webkit-transform:scale(1);transform:scale(1);cursor:not-allowed}.el-slider__button-wrapper,.el-slider__stop{-webkit-transform:translateX(-50%);position:absolute}.el-slider__input{float:right;margin-top:3px;width:130px}.el-slider__input.el-input-number--mini{margin-top:5px}.el-slider__input.el-input-number--medium{margin-top:0}.el-slider__input.el-input-number--large{margin-top:-2px}.el-slider__bar{height:6px;background-color:#409EFF;border-top-left-radius:3px;border-bottom-left-radius:3px;position:absolute}.el-slider__button-wrapper{height:36px;width:36px;z-index:1001;top:-15px;transform:translateX(-50%);background-color:transparent;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;line-height:normal}.el-image-viewer__btn,.el-slider__button,.el-step__icon-inner{-moz-user-select:none;-ms-user-select:none}.el-slider__button-wrapper::after{height:100%}.el-slider__button-wrapper.hover,.el-slider__button-wrapper:hover{cursor:-webkit-grab;cursor:grab}.el-slider__button-wrapper.dragging{cursor:-webkit-grabbing;cursor:grabbing}.el-slider__button{width:16px;height:16px;border:2px solid #409EFF;background-color:#FFF;border-radius:50%;-webkit-transition:.2s;transition:.2s;-webkit-user-select:none;user-select:none}.el-slider__button.dragging,.el-slider__button.hover,.el-slider__button:hover{-webkit-transform:scale(1.2);transform:scale(1.2)}.el-slider__button.hover,.el-slider__button:hover{cursor:-webkit-grab;cursor:grab}.el-slider__button.dragging{cursor:-webkit-grabbing;cursor:grabbing}.el-slider__stop{height:6px;width:6px;border-radius:100%;background-color:#FFF;transform:translateX(-50%)}.el-slider__marks{top:0;left:12px;width:18px;height:100%}.el-slider__marks-text{position:absolute;-webkit-transform:translateX(-50%);transform:translateX(-50%);font-size:14px;color:#909399;margin-top:15px}.el-slider.is-vertical{position:relative}.el-slider.is-vertical .el-slider__runway{width:6px;height:100%;margin:0 16px}.el-slider.is-vertical .el-slider__bar{width:6px;height:auto;border-radius:0 0 3px 3px}.el-slider.is-vertical .el-slider__button-wrapper{top:auto;left:-15px;-webkit-transform:translateY(50%);transform:translateY(50%)}.el-slider.is-vertical .el-slider__stop{-webkit-transform:translateY(50%);transform:translateY(50%)}.el-slider.is-vertical.el-slider--with-input{padding-bottom:58px}.el-slider.is-vertical.el-slider--with-input .el-slider__input{overflow:visible;float:none;position:absolute;bottom:22px;width:36px;margin-top:15px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input__inner{text-align:center;padding-left:5px;padding-right:5px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__decrease,.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase{top:32px;margin-top:-1px;border:1px solid #DCDFE6;line-height:20px;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__decrease{width:18px;right:18px;border-bottom-left-radius:4px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase{width:19px;border-bottom-right-radius:4px}.el-slider.is-vertical.el-slider--with-input .el-slider__input .el-input-number__increase~.el-input .el-input__inner{border-bottom-left-radius:0;border-bottom-right-radius:0}.el-slider.is-vertical.el-slider--with-input .el-slider__input:hover .el-input-number__decrease,.el-slider.is-vertical.el-slider--with-input .el-slider__input:hover .el-input-number__increase{border-color:#C0C4CC}.el-slider.is-vertical.el-slider--with-input .el-slider__input:active .el-input-number__decrease,.el-slider.is-vertical.el-slider--with-input .el-slider__input:active .el-input-number__increase{border-color:#409EFF}.el-slider.is-vertical .el-slider__marks-text{margin-top:0;left:15px;-webkit-transform:translateY(50%);transform:translateY(50%)}.el-loading-parent--relative{position:relative!important}.el-loading-parent--hidden{overflow:hidden!important}.el-loading-mask{position:absolute;z-index:2000;background-color:rgba(255,255,255,.9);margin:0;top:0;right:0;bottom:0;left:0;-webkit-transition:opacity .3s;transition:opacity .3s}.el-loading-mask.is-fullscreen{position:fixed}.el-loading-mask.is-fullscreen .el-loading-spinner{margin-top:-25px}.el-loading-mask.is-fullscreen .el-loading-spinner .circular{height:50px;width:50px}.el-loading-spinner{top:50%;margin-top:-21px;width:100%;text-align:center;position:absolute}.el-col-pull-0,.el-col-pull-1,.el-col-pull-10,.el-col-pull-11,.el-col-pull-12,.el-col-pull-13,.el-col-pull-14,.el-col-pull-15,.el-col-pull-16,.el-col-pull-17,.el-col-pull-18,.el-col-pull-19,.el-col-pull-2,.el-col-pull-20,.el-col-pull-21,.el-col-pull-22,.el-col-pull-23,.el-col-pull-24,.el-col-pull-3,.el-col-pull-4,.el-col-pull-5,.el-col-pull-6,.el-col-pull-7,.el-col-pull-8,.el-col-pull-9,.el-col-push-0,.el-col-push-1,.el-col-push-10,.el-col-push-11,.el-col-push-12,.el-col-push-13,.el-col-push-14,.el-col-push-15,.el-col-push-16,.el-col-push-17,.el-col-push-18,.el-col-push-19,.el-col-push-2,.el-col-push-20,.el-col-push-21,.el-col-push-22,.el-col-push-23,.el-col-push-24,.el-col-push-3,.el-col-push-4,.el-col-push-5,.el-col-push-6,.el-col-push-7,.el-col-push-8,.el-col-push-9,.el-row,.el-upload-dragger,.el-upload-list__item{position:relative}.el-loading-spinner .el-loading-text{color:#409EFF;margin:3px 0;font-size:14px}.el-loading-spinner .circular{height:42px;width:42px;-webkit-animation:loading-rotate 2s linear infinite;animation:loading-rotate 2s linear infinite}.el-loading-spinner .path{-webkit-animation:loading-dash 1.5s ease-in-out infinite;animation:loading-dash 1.5s ease-in-out infinite;stroke-dasharray:90,150;stroke-dashoffset:0;stroke-width:2;stroke:#409EFF;stroke-linecap:round}.el-loading-spinner i{color:#409EFF}@-webkit-keyframes loading-rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loading-rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes loading-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40px}100%{stroke-dasharray:90,150;stroke-dashoffset:-120px}}@keyframes loading-dash{0%{stroke-dasharray:1,200;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-40px}100%{stroke-dasharray:90,150;stroke-dashoffset:-120px}}.el-row{-webkit-box-sizing:border-box;box-sizing:border-box}.el-row::after,.el-row::before{display:table}.el-row::after{clear:both}.el-row--flex{display:-webkit-box;display:-ms-flexbox;display:flex}.el-col-0,.el-row--flex:after,.el-row--flex:before{display:none}.el-row--flex.is-justify-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-row--flex.is-justify-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.el-row--flex.is-justify-space-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.el-row--flex.is-justify-space-around{-ms-flex-pack:distribute;justify-content:space-around}.el-row--flex.is-align-top{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.el-row--flex.is-align-middle{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-row--flex.is-align-bottom{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}[class*=el-col-]{float:left;-webkit-box-sizing:border-box;box-sizing:border-box}.el-col-0{width:0%}.el-col-pull-0{right:0}.el-col-push-0{left:0}.el-col-1{width:4.16667%}.el-col-offset-1{margin-left:4.16667%}.el-col-pull-1{right:4.16667%}.el-col-push-1{left:4.16667%}.el-col-2{width:8.33333%}.el-col-offset-2{margin-left:8.33333%}.el-col-pull-2{right:8.33333%}.el-col-push-2{left:8.33333%}.el-col-3{width:12.5%}.el-col-offset-3{margin-left:12.5%}.el-col-pull-3{right:12.5%}.el-col-push-3{left:12.5%}.el-col-4{width:16.66667%}.el-col-offset-4{margin-left:16.66667%}.el-col-pull-4{right:16.66667%}.el-col-push-4{left:16.66667%}.el-col-5{width:20.83333%}.el-col-offset-5{margin-left:20.83333%}.el-col-pull-5{right:20.83333%}.el-col-push-5{left:20.83333%}.el-col-6{width:25%}.el-col-offset-6{margin-left:25%}.el-col-pull-6{right:25%}.el-col-push-6{left:25%}.el-col-7{width:29.16667%}.el-col-offset-7{margin-left:29.16667%}.el-col-pull-7{right:29.16667%}.el-col-push-7{left:29.16667%}.el-col-8{width:33.33333%}.el-col-offset-8{margin-left:33.33333%}.el-col-pull-8{right:33.33333%}.el-col-push-8{left:33.33333%}.el-col-9{width:37.5%}.el-col-offset-9{margin-left:37.5%}.el-col-pull-9{right:37.5%}.el-col-push-9{left:37.5%}.el-col-10{width:41.66667%}.el-col-offset-10{margin-left:41.66667%}.el-col-pull-10{right:41.66667%}.el-col-push-10{left:41.66667%}.el-col-11{width:45.83333%}.el-col-offset-11{margin-left:45.83333%}.el-col-pull-11{right:45.83333%}.el-col-push-11{left:45.83333%}.el-col-12{width:50%}.el-col-offset-12{margin-left:50%}.el-col-pull-12{right:50%}.el-col-push-12{left:50%}.el-col-13{width:54.16667%}.el-col-offset-13{margin-left:54.16667%}.el-col-pull-13{right:54.16667%}.el-col-push-13{left:54.16667%}.el-col-14{width:58.33333%}.el-col-offset-14{margin-left:58.33333%}.el-col-pull-14{right:58.33333%}.el-col-push-14{left:58.33333%}.el-col-15{width:62.5%}.el-col-offset-15{margin-left:62.5%}.el-col-pull-15{right:62.5%}.el-col-push-15{left:62.5%}.el-col-16{width:66.66667%}.el-col-offset-16{margin-left:66.66667%}.el-col-pull-16{right:66.66667%}.el-col-push-16{left:66.66667%}.el-col-17{width:70.83333%}.el-col-offset-17{margin-left:70.83333%}.el-col-pull-17{right:70.83333%}.el-col-push-17{left:70.83333%}.el-col-18{width:75%}.el-col-offset-18{margin-left:75%}.el-col-pull-18{right:75%}.el-col-push-18{left:75%}.el-col-19{width:79.16667%}.el-col-offset-19{margin-left:79.16667%}.el-col-pull-19{right:79.16667%}.el-col-push-19{left:79.16667%}.el-col-20{width:83.33333%}.el-col-offset-20{margin-left:83.33333%}.el-col-pull-20{right:83.33333%}.el-col-push-20{left:83.33333%}.el-col-21{width:87.5%}.el-col-offset-21{margin-left:87.5%}.el-col-pull-21{right:87.5%}.el-col-push-21{left:87.5%}.el-col-22{width:91.66667%}.el-col-offset-22{margin-left:91.66667%}.el-col-pull-22{right:91.66667%}.el-col-push-22{left:91.66667%}.el-col-23{width:95.83333%}.el-col-offset-23{margin-left:95.83333%}.el-col-pull-23{right:95.83333%}.el-col-push-23{left:95.83333%}.el-col-24{width:100%}.el-col-offset-24{margin-left:100%}.el-col-pull-24{right:100%}.el-col-push-24{left:100%}@media only screen and (max-width:767px){.el-col-xs-0{display:none;width:0%}.el-col-xs-offset-0{margin-left:0}.el-col-xs-pull-0{position:relative;right:0}.el-col-xs-push-0{position:relative;left:0}.el-col-xs-1{width:4.16667%}.el-col-xs-offset-1{margin-left:4.16667%}.el-col-xs-pull-1{position:relative;right:4.16667%}.el-col-xs-push-1{position:relative;left:4.16667%}.el-col-xs-2{width:8.33333%}.el-col-xs-offset-2{margin-left:8.33333%}.el-col-xs-pull-2{position:relative;right:8.33333%}.el-col-xs-push-2{position:relative;left:8.33333%}.el-col-xs-3{width:12.5%}.el-col-xs-offset-3{margin-left:12.5%}.el-col-xs-pull-3{position:relative;right:12.5%}.el-col-xs-push-3{position:relative;left:12.5%}.el-col-xs-4{width:16.66667%}.el-col-xs-offset-4{margin-left:16.66667%}.el-col-xs-pull-4{position:relative;right:16.66667%}.el-col-xs-push-4{position:relative;left:16.66667%}.el-col-xs-5{width:20.83333%}.el-col-xs-offset-5{margin-left:20.83333%}.el-col-xs-pull-5{position:relative;right:20.83333%}.el-col-xs-push-5{position:relative;left:20.83333%}.el-col-xs-6{width:25%}.el-col-xs-offset-6{margin-left:25%}.el-col-xs-pull-6{position:relative;right:25%}.el-col-xs-push-6{position:relative;left:25%}.el-col-xs-7{width:29.16667%}.el-col-xs-offset-7{margin-left:29.16667%}.el-col-xs-pull-7{position:relative;right:29.16667%}.el-col-xs-push-7{position:relative;left:29.16667%}.el-col-xs-8{width:33.33333%}.el-col-xs-offset-8{margin-left:33.33333%}.el-col-xs-pull-8{position:relative;right:33.33333%}.el-col-xs-push-8{position:relative;left:33.33333%}.el-col-xs-9{width:37.5%}.el-col-xs-offset-9{margin-left:37.5%}.el-col-xs-pull-9{position:relative;right:37.5%}.el-col-xs-push-9{position:relative;left:37.5%}.el-col-xs-10{width:41.66667%}.el-col-xs-offset-10{margin-left:41.66667%}.el-col-xs-pull-10{position:relative;right:41.66667%}.el-col-xs-push-10{position:relative;left:41.66667%}.el-col-xs-11{width:45.83333%}.el-col-xs-offset-11{margin-left:45.83333%}.el-col-xs-pull-11{position:relative;right:45.83333%}.el-col-xs-push-11{position:relative;left:45.83333%}.el-col-xs-12{width:50%}.el-col-xs-offset-12{margin-left:50%}.el-col-xs-pull-12{position:relative;right:50%}.el-col-xs-push-12{position:relative;left:50%}.el-col-xs-13{width:54.16667%}.el-col-xs-offset-13{margin-left:54.16667%}.el-col-xs-pull-13{position:relative;right:54.16667%}.el-col-xs-push-13{position:relative;left:54.16667%}.el-col-xs-14{width:58.33333%}.el-col-xs-offset-14{margin-left:58.33333%}.el-col-xs-pull-14{position:relative;right:58.33333%}.el-col-xs-push-14{position:relative;left:58.33333%}.el-col-xs-15{width:62.5%}.el-col-xs-offset-15{margin-left:62.5%}.el-col-xs-pull-15{position:relative;right:62.5%}.el-col-xs-push-15{position:relative;left:62.5%}.el-col-xs-16{width:66.66667%}.el-col-xs-offset-16{margin-left:66.66667%}.el-col-xs-pull-16{position:relative;right:66.66667%}.el-col-xs-push-16{position:relative;left:66.66667%}.el-col-xs-17{width:70.83333%}.el-col-xs-offset-17{margin-left:70.83333%}.el-col-xs-pull-17{position:relative;right:70.83333%}.el-col-xs-push-17{position:relative;left:70.83333%}.el-col-xs-18{width:75%}.el-col-xs-offset-18{margin-left:75%}.el-col-xs-pull-18{position:relative;right:75%}.el-col-xs-push-18{position:relative;left:75%}.el-col-xs-19{width:79.16667%}.el-col-xs-offset-19{margin-left:79.16667%}.el-col-xs-pull-19{position:relative;right:79.16667%}.el-col-xs-push-19{position:relative;left:79.16667%}.el-col-xs-20{width:83.33333%}.el-col-xs-offset-20{margin-left:83.33333%}.el-col-xs-pull-20{position:relative;right:83.33333%}.el-col-xs-push-20{position:relative;left:83.33333%}.el-col-xs-21{width:87.5%}.el-col-xs-offset-21{margin-left:87.5%}.el-col-xs-pull-21{position:relative;right:87.5%}.el-col-xs-push-21{position:relative;left:87.5%}.el-col-xs-22{width:91.66667%}.el-col-xs-offset-22{margin-left:91.66667%}.el-col-xs-pull-22{position:relative;right:91.66667%}.el-col-xs-push-22{position:relative;left:91.66667%}.el-col-xs-23{width:95.83333%}.el-col-xs-offset-23{margin-left:95.83333%}.el-col-xs-pull-23{position:relative;right:95.83333%}.el-col-xs-push-23{position:relative;left:95.83333%}.el-col-xs-24{width:100%}.el-col-xs-offset-24{margin-left:100%}.el-col-xs-pull-24{position:relative;right:100%}.el-col-xs-push-24{position:relative;left:100%}}@media only screen and (min-width:768px){.el-col-sm-0{display:none;width:0%}.el-col-sm-offset-0{margin-left:0}.el-col-sm-pull-0{position:relative;right:0}.el-col-sm-push-0{position:relative;left:0}.el-col-sm-1{width:4.16667%}.el-col-sm-offset-1{margin-left:4.16667%}.el-col-sm-pull-1{position:relative;right:4.16667%}.el-col-sm-push-1{position:relative;left:4.16667%}.el-col-sm-2{width:8.33333%}.el-col-sm-offset-2{margin-left:8.33333%}.el-col-sm-pull-2{position:relative;right:8.33333%}.el-col-sm-push-2{position:relative;left:8.33333%}.el-col-sm-3{width:12.5%}.el-col-sm-offset-3{margin-left:12.5%}.el-col-sm-pull-3{position:relative;right:12.5%}.el-col-sm-push-3{position:relative;left:12.5%}.el-col-sm-4{width:16.66667%}.el-col-sm-offset-4{margin-left:16.66667%}.el-col-sm-pull-4{position:relative;right:16.66667%}.el-col-sm-push-4{position:relative;left:16.66667%}.el-col-sm-5{width:20.83333%}.el-col-sm-offset-5{margin-left:20.83333%}.el-col-sm-pull-5{position:relative;right:20.83333%}.el-col-sm-push-5{position:relative;left:20.83333%}.el-col-sm-6{width:25%}.el-col-sm-offset-6{margin-left:25%}.el-col-sm-pull-6{position:relative;right:25%}.el-col-sm-push-6{position:relative;left:25%}.el-col-sm-7{width:29.16667%}.el-col-sm-offset-7{margin-left:29.16667%}.el-col-sm-pull-7{position:relative;right:29.16667%}.el-col-sm-push-7{position:relative;left:29.16667%}.el-col-sm-8{width:33.33333%}.el-col-sm-offset-8{margin-left:33.33333%}.el-col-sm-pull-8{position:relative;right:33.33333%}.el-col-sm-push-8{position:relative;left:33.33333%}.el-col-sm-9{width:37.5%}.el-col-sm-offset-9{margin-left:37.5%}.el-col-sm-pull-9{position:relative;right:37.5%}.el-col-sm-push-9{position:relative;left:37.5%}.el-col-sm-10{width:41.66667%}.el-col-sm-offset-10{margin-left:41.66667%}.el-col-sm-pull-10{position:relative;right:41.66667%}.el-col-sm-push-10{position:relative;left:41.66667%}.el-col-sm-11{width:45.83333%}.el-col-sm-offset-11{margin-left:45.83333%}.el-col-sm-pull-11{position:relative;right:45.83333%}.el-col-sm-push-11{position:relative;left:45.83333%}.el-col-sm-12{width:50%}.el-col-sm-offset-12{margin-left:50%}.el-col-sm-pull-12{position:relative;right:50%}.el-col-sm-push-12{position:relative;left:50%}.el-col-sm-13{width:54.16667%}.el-col-sm-offset-13{margin-left:54.16667%}.el-col-sm-pull-13{position:relative;right:54.16667%}.el-col-sm-push-13{position:relative;left:54.16667%}.el-col-sm-14{width:58.33333%}.el-col-sm-offset-14{margin-left:58.33333%}.el-col-sm-pull-14{position:relative;right:58.33333%}.el-col-sm-push-14{position:relative;left:58.33333%}.el-col-sm-15{width:62.5%}.el-col-sm-offset-15{margin-left:62.5%}.el-col-sm-pull-15{position:relative;right:62.5%}.el-col-sm-push-15{position:relative;left:62.5%}.el-col-sm-16{width:66.66667%}.el-col-sm-offset-16{margin-left:66.66667%}.el-col-sm-pull-16{position:relative;right:66.66667%}.el-col-sm-push-16{position:relative;left:66.66667%}.el-col-sm-17{width:70.83333%}.el-col-sm-offset-17{margin-left:70.83333%}.el-col-sm-pull-17{position:relative;right:70.83333%}.el-col-sm-push-17{position:relative;left:70.83333%}.el-col-sm-18{width:75%}.el-col-sm-offset-18{margin-left:75%}.el-col-sm-pull-18{position:relative;right:75%}.el-col-sm-push-18{position:relative;left:75%}.el-col-sm-19{width:79.16667%}.el-col-sm-offset-19{margin-left:79.16667%}.el-col-sm-pull-19{position:relative;right:79.16667%}.el-col-sm-push-19{position:relative;left:79.16667%}.el-col-sm-20{width:83.33333%}.el-col-sm-offset-20{margin-left:83.33333%}.el-col-sm-pull-20{position:relative;right:83.33333%}.el-col-sm-push-20{position:relative;left:83.33333%}.el-col-sm-21{width:87.5%}.el-col-sm-offset-21{margin-left:87.5%}.el-col-sm-pull-21{position:relative;right:87.5%}.el-col-sm-push-21{position:relative;left:87.5%}.el-col-sm-22{width:91.66667%}.el-col-sm-offset-22{margin-left:91.66667%}.el-col-sm-pull-22{position:relative;right:91.66667%}.el-col-sm-push-22{position:relative;left:91.66667%}.el-col-sm-23{width:95.83333%}.el-col-sm-offset-23{margin-left:95.83333%}.el-col-sm-pull-23{position:relative;right:95.83333%}.el-col-sm-push-23{position:relative;left:95.83333%}.el-col-sm-24{width:100%}.el-col-sm-offset-24{margin-left:100%}.el-col-sm-pull-24{position:relative;right:100%}.el-col-sm-push-24{position:relative;left:100%}}@media only screen and (min-width:992px){.el-col-md-0{display:none;width:0%}.el-col-md-offset-0{margin-left:0}.el-col-md-pull-0{position:relative;right:0}.el-col-md-push-0{position:relative;left:0}.el-col-md-1{width:4.16667%}.el-col-md-offset-1{margin-left:4.16667%}.el-col-md-pull-1{position:relative;right:4.16667%}.el-col-md-push-1{position:relative;left:4.16667%}.el-col-md-2{width:8.33333%}.el-col-md-offset-2{margin-left:8.33333%}.el-col-md-pull-2{position:relative;right:8.33333%}.el-col-md-push-2{position:relative;left:8.33333%}.el-col-md-3{width:12.5%}.el-col-md-offset-3{margin-left:12.5%}.el-col-md-pull-3{position:relative;right:12.5%}.el-col-md-push-3{position:relative;left:12.5%}.el-col-md-4{width:16.66667%}.el-col-md-offset-4{margin-left:16.66667%}.el-col-md-pull-4{position:relative;right:16.66667%}.el-col-md-push-4{position:relative;left:16.66667%}.el-col-md-5{width:20.83333%}.el-col-md-offset-5{margin-left:20.83333%}.el-col-md-pull-5{position:relative;right:20.83333%}.el-col-md-push-5{position:relative;left:20.83333%}.el-col-md-6{width:25%}.el-col-md-offset-6{margin-left:25%}.el-col-md-pull-6{position:relative;right:25%}.el-col-md-push-6{position:relative;left:25%}.el-col-md-7{width:29.16667%}.el-col-md-offset-7{margin-left:29.16667%}.el-col-md-pull-7{position:relative;right:29.16667%}.el-col-md-push-7{position:relative;left:29.16667%}.el-col-md-8{width:33.33333%}.el-col-md-offset-8{margin-left:33.33333%}.el-col-md-pull-8{position:relative;right:33.33333%}.el-col-md-push-8{position:relative;left:33.33333%}.el-col-md-9{width:37.5%}.el-col-md-offset-9{margin-left:37.5%}.el-col-md-pull-9{position:relative;right:37.5%}.el-col-md-push-9{position:relative;left:37.5%}.el-col-md-10{width:41.66667%}.el-col-md-offset-10{margin-left:41.66667%}.el-col-md-pull-10{position:relative;right:41.66667%}.el-col-md-push-10{position:relative;left:41.66667%}.el-col-md-11{width:45.83333%}.el-col-md-offset-11{margin-left:45.83333%}.el-col-md-pull-11{position:relative;right:45.83333%}.el-col-md-push-11{position:relative;left:45.83333%}.el-col-md-12{width:50%}.el-col-md-offset-12{margin-left:50%}.el-col-md-pull-12{position:relative;right:50%}.el-col-md-push-12{position:relative;left:50%}.el-col-md-13{width:54.16667%}.el-col-md-offset-13{margin-left:54.16667%}.el-col-md-pull-13{position:relative;right:54.16667%}.el-col-md-push-13{position:relative;left:54.16667%}.el-col-md-14{width:58.33333%}.el-col-md-offset-14{margin-left:58.33333%}.el-col-md-pull-14{position:relative;right:58.33333%}.el-col-md-push-14{position:relative;left:58.33333%}.el-col-md-15{width:62.5%}.el-col-md-offset-15{margin-left:62.5%}.el-col-md-pull-15{position:relative;right:62.5%}.el-col-md-push-15{position:relative;left:62.5%}.el-col-md-16{width:66.66667%}.el-col-md-offset-16{margin-left:66.66667%}.el-col-md-pull-16{position:relative;right:66.66667%}.el-col-md-push-16{position:relative;left:66.66667%}.el-col-md-17{width:70.83333%}.el-col-md-offset-17{margin-left:70.83333%}.el-col-md-pull-17{position:relative;right:70.83333%}.el-col-md-push-17{position:relative;left:70.83333%}.el-col-md-18{width:75%}.el-col-md-offset-18{margin-left:75%}.el-col-md-pull-18{position:relative;right:75%}.el-col-md-push-18{position:relative;left:75%}.el-col-md-19{width:79.16667%}.el-col-md-offset-19{margin-left:79.16667%}.el-col-md-pull-19{position:relative;right:79.16667%}.el-col-md-push-19{position:relative;left:79.16667%}.el-col-md-20{width:83.33333%}.el-col-md-offset-20{margin-left:83.33333%}.el-col-md-pull-20{position:relative;right:83.33333%}.el-col-md-push-20{position:relative;left:83.33333%}.el-col-md-21{width:87.5%}.el-col-md-offset-21{margin-left:87.5%}.el-col-md-pull-21{position:relative;right:87.5%}.el-col-md-push-21{position:relative;left:87.5%}.el-col-md-22{width:91.66667%}.el-col-md-offset-22{margin-left:91.66667%}.el-col-md-pull-22{position:relative;right:91.66667%}.el-col-md-push-22{position:relative;left:91.66667%}.el-col-md-23{width:95.83333%}.el-col-md-offset-23{margin-left:95.83333%}.el-col-md-pull-23{position:relative;right:95.83333%}.el-col-md-push-23{position:relative;left:95.83333%}.el-col-md-24{width:100%}.el-col-md-offset-24{margin-left:100%}.el-col-md-pull-24{position:relative;right:100%}.el-col-md-push-24{position:relative;left:100%}}@media only screen and (min-width:1200px){.el-col-lg-0{display:none;width:0%}.el-col-lg-offset-0{margin-left:0}.el-col-lg-pull-0{position:relative;right:0}.el-col-lg-push-0{position:relative;left:0}.el-col-lg-1{width:4.16667%}.el-col-lg-offset-1{margin-left:4.16667%}.el-col-lg-pull-1{position:relative;right:4.16667%}.el-col-lg-push-1{position:relative;left:4.16667%}.el-col-lg-2{width:8.33333%}.el-col-lg-offset-2{margin-left:8.33333%}.el-col-lg-pull-2{position:relative;right:8.33333%}.el-col-lg-push-2{position:relative;left:8.33333%}.el-col-lg-3{width:12.5%}.el-col-lg-offset-3{margin-left:12.5%}.el-col-lg-pull-3{position:relative;right:12.5%}.el-col-lg-push-3{position:relative;left:12.5%}.el-col-lg-4{width:16.66667%}.el-col-lg-offset-4{margin-left:16.66667%}.el-col-lg-pull-4{position:relative;right:16.66667%}.el-col-lg-push-4{position:relative;left:16.66667%}.el-col-lg-5{width:20.83333%}.el-col-lg-offset-5{margin-left:20.83333%}.el-col-lg-pull-5{position:relative;right:20.83333%}.el-col-lg-push-5{position:relative;left:20.83333%}.el-col-lg-6{width:25%}.el-col-lg-offset-6{margin-left:25%}.el-col-lg-pull-6{position:relative;right:25%}.el-col-lg-push-6{position:relative;left:25%}.el-col-lg-7{width:29.16667%}.el-col-lg-offset-7{margin-left:29.16667%}.el-col-lg-pull-7{position:relative;right:29.16667%}.el-col-lg-push-7{position:relative;left:29.16667%}.el-col-lg-8{width:33.33333%}.el-col-lg-offset-8{margin-left:33.33333%}.el-col-lg-pull-8{position:relative;right:33.33333%}.el-col-lg-push-8{position:relative;left:33.33333%}.el-col-lg-9{width:37.5%}.el-col-lg-offset-9{margin-left:37.5%}.el-col-lg-pull-9{position:relative;right:37.5%}.el-col-lg-push-9{position:relative;left:37.5%}.el-col-lg-10{width:41.66667%}.el-col-lg-offset-10{margin-left:41.66667%}.el-col-lg-pull-10{position:relative;right:41.66667%}.el-col-lg-push-10{position:relative;left:41.66667%}.el-col-lg-11{width:45.83333%}.el-col-lg-offset-11{margin-left:45.83333%}.el-col-lg-pull-11{position:relative;right:45.83333%}.el-col-lg-push-11{position:relative;left:45.83333%}.el-col-lg-12{width:50%}.el-col-lg-offset-12{margin-left:50%}.el-col-lg-pull-12{position:relative;right:50%}.el-col-lg-push-12{position:relative;left:50%}.el-col-lg-13{width:54.16667%}.el-col-lg-offset-13{margin-left:54.16667%}.el-col-lg-pull-13{position:relative;right:54.16667%}.el-col-lg-push-13{position:relative;left:54.16667%}.el-col-lg-14{width:58.33333%}.el-col-lg-offset-14{margin-left:58.33333%}.el-col-lg-pull-14{position:relative;right:58.33333%}.el-col-lg-push-14{position:relative;left:58.33333%}.el-col-lg-15{width:62.5%}.el-col-lg-offset-15{margin-left:62.5%}.el-col-lg-pull-15{position:relative;right:62.5%}.el-col-lg-push-15{position:relative;left:62.5%}.el-col-lg-16{width:66.66667%}.el-col-lg-offset-16{margin-left:66.66667%}.el-col-lg-pull-16{position:relative;right:66.66667%}.el-col-lg-push-16{position:relative;left:66.66667%}.el-col-lg-17{width:70.83333%}.el-col-lg-offset-17{margin-left:70.83333%}.el-col-lg-pull-17{position:relative;right:70.83333%}.el-col-lg-push-17{position:relative;left:70.83333%}.el-col-lg-18{width:75%}.el-col-lg-offset-18{margin-left:75%}.el-col-lg-pull-18{position:relative;right:75%}.el-col-lg-push-18{position:relative;left:75%}.el-col-lg-19{width:79.16667%}.el-col-lg-offset-19{margin-left:79.16667%}.el-col-lg-pull-19{position:relative;right:79.16667%}.el-col-lg-push-19{position:relative;left:79.16667%}.el-col-lg-20{width:83.33333%}.el-col-lg-offset-20{margin-left:83.33333%}.el-col-lg-pull-20{position:relative;right:83.33333%}.el-col-lg-push-20{position:relative;left:83.33333%}.el-col-lg-21{width:87.5%}.el-col-lg-offset-21{margin-left:87.5%}.el-col-lg-pull-21{position:relative;right:87.5%}.el-col-lg-push-21{position:relative;left:87.5%}.el-col-lg-22{width:91.66667%}.el-col-lg-offset-22{margin-left:91.66667%}.el-col-lg-pull-22{position:relative;right:91.66667%}.el-col-lg-push-22{position:relative;left:91.66667%}.el-col-lg-23{width:95.83333%}.el-col-lg-offset-23{margin-left:95.83333%}.el-col-lg-pull-23{position:relative;right:95.83333%}.el-col-lg-push-23{position:relative;left:95.83333%}.el-col-lg-24{width:100%}.el-col-lg-offset-24{margin-left:100%}.el-col-lg-pull-24{position:relative;right:100%}.el-col-lg-push-24{position:relative;left:100%}}@media only screen and (min-width:1920px){.el-col-xl-0{display:none;width:0%}.el-col-xl-offset-0{margin-left:0}.el-col-xl-pull-0{position:relative;right:0}.el-col-xl-push-0{position:relative;left:0}.el-col-xl-1{width:4.16667%}.el-col-xl-offset-1{margin-left:4.16667%}.el-col-xl-pull-1{position:relative;right:4.16667%}.el-col-xl-push-1{position:relative;left:4.16667%}.el-col-xl-2{width:8.33333%}.el-col-xl-offset-2{margin-left:8.33333%}.el-col-xl-pull-2{position:relative;right:8.33333%}.el-col-xl-push-2{position:relative;left:8.33333%}.el-col-xl-3{width:12.5%}.el-col-xl-offset-3{margin-left:12.5%}.el-col-xl-pull-3{position:relative;right:12.5%}.el-col-xl-push-3{position:relative;left:12.5%}.el-col-xl-4{width:16.66667%}.el-col-xl-offset-4{margin-left:16.66667%}.el-col-xl-pull-4{position:relative;right:16.66667%}.el-col-xl-push-4{position:relative;left:16.66667%}.el-col-xl-5{width:20.83333%}.el-col-xl-offset-5{margin-left:20.83333%}.el-col-xl-pull-5{position:relative;right:20.83333%}.el-col-xl-push-5{position:relative;left:20.83333%}.el-col-xl-6{width:25%}.el-col-xl-offset-6{margin-left:25%}.el-col-xl-pull-6{position:relative;right:25%}.el-col-xl-push-6{position:relative;left:25%}.el-col-xl-7{width:29.16667%}.el-col-xl-offset-7{margin-left:29.16667%}.el-col-xl-pull-7{position:relative;right:29.16667%}.el-col-xl-push-7{position:relative;left:29.16667%}.el-col-xl-8{width:33.33333%}.el-col-xl-offset-8{margin-left:33.33333%}.el-col-xl-pull-8{position:relative;right:33.33333%}.el-col-xl-push-8{position:relative;left:33.33333%}.el-col-xl-9{width:37.5%}.el-col-xl-offset-9{margin-left:37.5%}.el-col-xl-pull-9{position:relative;right:37.5%}.el-col-xl-push-9{position:relative;left:37.5%}.el-col-xl-10{width:41.66667%}.el-col-xl-offset-10{margin-left:41.66667%}.el-col-xl-pull-10{position:relative;right:41.66667%}.el-col-xl-push-10{position:relative;left:41.66667%}.el-col-xl-11{width:45.83333%}.el-col-xl-offset-11{margin-left:45.83333%}.el-col-xl-pull-11{position:relative;right:45.83333%}.el-col-xl-push-11{position:relative;left:45.83333%}.el-col-xl-12{width:50%}.el-col-xl-offset-12{margin-left:50%}.el-col-xl-pull-12{position:relative;right:50%}.el-col-xl-push-12{position:relative;left:50%}.el-col-xl-13{width:54.16667%}.el-col-xl-offset-13{margin-left:54.16667%}.el-col-xl-pull-13{position:relative;right:54.16667%}.el-col-xl-push-13{position:relative;left:54.16667%}.el-col-xl-14{width:58.33333%}.el-col-xl-offset-14{margin-left:58.33333%}.el-col-xl-pull-14{position:relative;right:58.33333%}.el-col-xl-push-14{position:relative;left:58.33333%}.el-col-xl-15{width:62.5%}.el-col-xl-offset-15{margin-left:62.5%}.el-col-xl-pull-15{position:relative;right:62.5%}.el-col-xl-push-15{position:relative;left:62.5%}.el-col-xl-16{width:66.66667%}.el-col-xl-offset-16{margin-left:66.66667%}.el-col-xl-pull-16{position:relative;right:66.66667%}.el-col-xl-push-16{position:relative;left:66.66667%}.el-col-xl-17{width:70.83333%}.el-col-xl-offset-17{margin-left:70.83333%}.el-col-xl-pull-17{position:relative;right:70.83333%}.el-col-xl-push-17{position:relative;left:70.83333%}.el-col-xl-18{width:75%}.el-col-xl-offset-18{margin-left:75%}.el-col-xl-pull-18{position:relative;right:75%}.el-col-xl-push-18{position:relative;left:75%}.el-col-xl-19{width:79.16667%}.el-col-xl-offset-19{margin-left:79.16667%}.el-col-xl-pull-19{position:relative;right:79.16667%}.el-col-xl-push-19{position:relative;left:79.16667%}.el-col-xl-20{width:83.33333%}.el-col-xl-offset-20{margin-left:83.33333%}.el-col-xl-pull-20{position:relative;right:83.33333%}.el-col-xl-push-20{position:relative;left:83.33333%}.el-col-xl-21{width:87.5%}.el-col-xl-offset-21{margin-left:87.5%}.el-col-xl-pull-21{position:relative;right:87.5%}.el-col-xl-push-21{position:relative;left:87.5%}.el-col-xl-22{width:91.66667%}.el-col-xl-offset-22{margin-left:91.66667%}.el-col-xl-pull-22{position:relative;right:91.66667%}.el-col-xl-push-22{position:relative;left:91.66667%}.el-col-xl-23{width:95.83333%}.el-col-xl-offset-23{margin-left:95.83333%}.el-col-xl-pull-23{position:relative;right:95.83333%}.el-col-xl-push-23{position:relative;left:95.83333%}.el-col-xl-24{width:100%}.el-col-xl-offset-24{margin-left:100%}.el-col-xl-pull-24{position:relative;right:100%}.el-col-xl-push-24{position:relative;left:100%}}@-webkit-keyframes progress{0%{background-position:0 0}100%{background-position:32px 0}}.el-upload{display:inline-block;text-align:center;cursor:pointer;outline:0}.el-upload__input{display:none}.el-upload__tip{font-size:12px;color:#606266;margin-top:7px}.el-upload iframe{position:absolute;z-index:-1;top:0;left:0;filter:alpha(opacity=0)}.el-upload--picture-card{background-color:#fbfdff;border:1px dashed #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:148px;height:148px;cursor:pointer;line-height:146px;vertical-align:top}.el-upload--picture-card i{font-size:28px;color:#8c939d}.el-upload--picture-card:hover,.el-upload:focus{border-color:#409EFF;color:#409EFF}.el-upload:focus .el-upload-dragger{border-color:#409EFF}.el-upload-dragger{background-color:#fff;border:1px dashed #d9d9d9;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:360px;height:180px;text-align:center;cursor:pointer;overflow:hidden}.el-upload-dragger .el-icon-upload{font-size:67px;color:#C0C4CC;margin:40px 0 16px;line-height:50px}.el-upload-dragger+.el-upload__tip{text-align:center}.el-upload-dragger~.el-upload__files{border-top:1px solid #DCDFE6;margin-top:7px;padding-top:5px}.el-upload-dragger .el-upload__text{color:#606266;font-size:14px;text-align:center}.el-upload-dragger .el-upload__text em{color:#409EFF;font-style:normal}.el-upload-dragger:hover{border-color:#409EFF}.el-upload-dragger.is-dragover{background-color:rgba(32,159,255,.06);border:2px dashed #409EFF}.el-upload-list{margin:0;padding:0;list-style:none}.el-upload-list__item{-webkit-transition:all .5s cubic-bezier(.55,0,.1,1);transition:all .5s cubic-bezier(.55,0,.1,1);font-size:14px;color:#606266;line-height:1.8;margin-top:5px;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;width:100%}.el-upload-list__item .el-progress{position:absolute;top:20px;width:100%}.el-upload-list__item .el-progress__text{position:absolute;right:0;top:-13px}.el-upload-list__item .el-progress-bar{margin-right:0;padding-right:0}.el-upload-list__item:first-child{margin-top:10px}.el-upload-list__item .el-icon-upload-success{color:#67C23A}.el-upload-list__item .el-icon-close{display:none;position:absolute;top:5px;right:5px;cursor:pointer;opacity:.75;color:#606266}.el-upload-list__item .el-icon-close:hover{opacity:1}.el-upload-list__item .el-icon-close-tip{display:none;position:absolute;top:5px;right:5px;font-size:12px;cursor:pointer;opacity:1;color:#409EFF}.el-upload-list__item:hover .el-icon-close{display:inline-block}.el-upload-list__item:hover .el-progress__text{display:none}.el-upload-list__item.is-success .el-upload-list__item-status-label{display:block}.el-upload-list__item.is-success .el-upload-list__item-name:focus,.el-upload-list__item.is-success .el-upload-list__item-name:hover{color:#409EFF;cursor:pointer}.el-upload-list__item.is-success:focus:not(:hover) .el-icon-close-tip{display:inline-block}.el-upload-list__item.is-success:active,.el-upload-list__item.is-success:not(.focusing):focus{outline-width:0}.el-upload-list__item.is-success:active .el-icon-close-tip,.el-upload-list__item.is-success:focus .el-upload-list__item-status-label,.el-upload-list__item.is-success:hover .el-upload-list__item-status-label,.el-upload-list__item.is-success:not(.focusing):focus .el-icon-close-tip{display:none}.el-upload-list.is-disabled .el-upload-list__item:hover .el-upload-list__item-status-label{display:block}.el-upload-list__item-name{color:#606266;display:block;margin-right:40px;overflow:hidden;padding-left:4px;text-overflow:ellipsis;-webkit-transition:color .3s;transition:color .3s;white-space:nowrap}.el-upload-list__item-name [class^=el-icon]{height:100%;margin-right:7px;color:#909399;line-height:inherit}.el-upload-list__item-status-label{position:absolute;right:5px;top:0;line-height:inherit;display:none}.el-upload-list__item-delete{position:absolute;right:10px;top:0;font-size:12px;color:#606266;display:none}.el-upload-list__item-delete:hover{color:#409EFF}.el-upload-list--picture-card{margin:0;display:inline;vertical-align:top}.el-upload-list--picture-card .el-upload-list__item{overflow:hidden;background-color:#fff;border:1px solid #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;width:148px;height:148px;margin:0 8px 8px 0;display:inline-block}.el-upload-list--picture-card .el-upload-list__item .el-icon-check,.el-upload-list--picture-card .el-upload-list__item .el-icon-circle-check{color:#FFF}.el-upload-list--picture-card .el-upload-list__item .el-icon-close,.el-upload-list--picture-card .el-upload-list__item:hover .el-upload-list__item-status-label{display:none}.el-upload-list--picture-card .el-upload-list__item:hover .el-progress__text{display:block}.el-upload-list--picture-card .el-upload-list__item-name{display:none}.el-upload-list--picture-card .el-upload-list__item-thumbnail{width:100%;height:100%}.el-upload-list--picture-card .el-upload-list__item-status-label{position:absolute;right:-15px;top:-6px;width:40px;height:24px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 0 1pc 1px rgba(0,0,0,.2);box-shadow:0 0 1pc 1px rgba(0,0,0,.2)}.el-upload-list--picture-card .el-upload-list__item-status-label i{font-size:12px;margin-top:11px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.el-upload-list--picture-card .el-upload-list__item-actions{position:absolute;width:100%;height:100%;left:0;top:0;cursor:default;text-align:center;color:#fff;opacity:0;font-size:20px;background-color:rgba(0,0,0,.5);-webkit-transition:opacity .3s;transition:opacity .3s}.el-upload-list--picture-card .el-upload-list__item-actions::after{display:inline-block;height:100%;vertical-align:middle}.el-upload-list--picture-card .el-upload-list__item-actions span{display:none;cursor:pointer}.el-upload-list--picture-card .el-upload-list__item-actions span+span{margin-left:15px}.el-upload-list--picture-card .el-upload-list__item-actions .el-upload-list__item-delete{position:static;font-size:inherit;color:inherit}.el-upload-list--picture-card .el-upload-list__item-actions:hover{opacity:1}.el-upload-list--picture-card .el-upload-list__item-actions:hover span{display:inline-block}.el-upload-list--picture-card .el-progress{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);bottom:auto;width:126px}.el-upload-list--picture-card .el-progress .el-progress__text{top:50%}.el-upload-list--picture .el-upload-list__item{overflow:hidden;z-index:0;background-color:#fff;border:1px solid #c0ccda;border-radius:6px;-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:10px;padding:10px 10px 10px 90px;height:92px}.el-upload-list--picture .el-upload-list__item .el-icon-check,.el-upload-list--picture .el-upload-list__item .el-icon-circle-check{color:#FFF}.el-upload-list--picture .el-upload-list__item:hover .el-upload-list__item-status-label{background:0 0;-webkit-box-shadow:none;box-shadow:none;top:-2px;right:-12px}.el-upload-list--picture .el-upload-list__item:hover .el-progress__text{display:block}.el-upload-list--picture .el-upload-list__item.is-success .el-upload-list__item-name{line-height:70px;margin-top:0}.el-upload-list--picture .el-upload-list__item.is-success .el-upload-list__item-name i{display:none}.el-upload-list--picture .el-upload-list__item-thumbnail{vertical-align:middle;display:inline-block;width:70px;height:70px;float:left;position:relative;z-index:1;margin-left:-80px;background-color:#FFF}.el-upload-list--picture .el-upload-list__item-name{display:block;margin-top:20px}.el-upload-list--picture .el-upload-list__item-name i{font-size:70px;line-height:1;position:absolute;left:9px;top:10px}.el-upload-list--picture .el-upload-list__item-status-label{position:absolute;right:-17px;top:-7px;width:46px;height:26px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 1px 1px #ccc;box-shadow:0 1px 1px #ccc}.el-upload-list--picture .el-upload-list__item-status-label i{font-size:12px;margin-top:12px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.el-upload-list--picture .el-progress{position:relative;top:-7px}.el-upload-cover{position:absolute;left:0;top:0;width:100%;height:100%;overflow:hidden;z-index:10;cursor:default}.el-upload-cover::after{display:inline-block;height:100%;vertical-align:middle}.el-upload-cover img{display:block;width:100%;height:100%}.el-upload-cover__label{position:absolute;right:-15px;top:-6px;width:40px;height:24px;background:#13ce66;text-align:center;-webkit-transform:rotate(45deg);transform:rotate(45deg);-webkit-box-shadow:0 0 1pc 1px rgba(0,0,0,.2);box-shadow:0 0 1pc 1px rgba(0,0,0,.2)}.el-upload-cover__label i{font-size:12px;margin-top:11px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);color:#fff}.el-upload-cover__progress{display:inline-block;vertical-align:middle;position:static;width:243px}.el-upload-cover__progress+.el-upload__inner{opacity:0}.el-upload-cover__content{position:absolute;top:0;left:0;width:100%;height:100%}.el-upload-cover__interact{position:absolute;bottom:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.72);text-align:center}.el-upload-cover__interact .btn{display:inline-block;color:#FFF;font-size:14px;cursor:pointer;vertical-align:middle;-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);margin-top:60px}.el-upload-cover__interact .btn span{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.el-upload-cover__interact .btn:not(:first-child){margin-left:35px}.el-upload-cover__interact .btn:hover{-webkit-transform:translateY(-13px);transform:translateY(-13px)}.el-upload-cover__interact .btn:hover span{opacity:1}.el-upload-cover__interact .btn i{color:#FFF;display:block;font-size:24px;line-height:inherit;margin:0 auto 5px}.el-upload-cover__title{position:absolute;bottom:0;left:0;background-color:#FFF;height:36px;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:400;text-align:left;padding:0 10px;margin:0;line-height:36px;font-size:14px;color:#303133}.el-upload-cover+.el-upload__inner{opacity:0;position:relative;z-index:1}.el-progress{position:relative;line-height:1}.el-progress__text{font-size:14px;color:#606266;display:inline-block;vertical-align:middle;margin-left:10px;line-height:1}.el-progress__text i{vertical-align:middle;display:block}.el-progress--circle,.el-progress--dashboard{display:inline-block}.el-progress--circle .el-progress__text,.el-progress--dashboard .el-progress__text{position:absolute;top:50%;left:0;width:100%;text-align:center;margin:0;-webkit-transform:translate(0,-50%);transform:translate(0,-50%)}.el-progress--circle .el-progress__text i,.el-progress--dashboard .el-progress__text i{vertical-align:middle;display:inline-block}.el-progress--without-text .el-progress__text{display:none}.el-progress--without-text .el-progress-bar{padding-right:0;margin-right:0;display:block}.el-progress--text-inside .el-progress-bar{padding-right:0;margin-right:0}.el-progress.is-success .el-progress-bar__inner{background-color:#67C23A}.el-progress.is-success .el-progress__text{color:#67C23A}.el-progress.is-warning .el-progress-bar__inner{background-color:#E6A23C}.el-badge__content,.el-progress.is-exception .el-progress-bar__inner{background-color:#F56C6C}.el-progress.is-warning .el-progress__text{color:#E6A23C}.el-progress.is-exception .el-progress__text{color:#F56C6C}.el-progress-bar{padding-right:50px;display:inline-block;vertical-align:middle;width:100%;margin-right:-55px;-webkit-box-sizing:border-box;box-sizing:border-box}.el-card__header,.el-message,.el-step__icon{-webkit-box-sizing:border-box}.el-progress-bar__outer{height:6px;border-radius:100px;background-color:#EBEEF5;overflow:hidden;position:relative;vertical-align:middle}.el-progress-bar__inner{position:absolute;left:0;top:0;height:100%;background-color:#409EFF;text-align:right;border-radius:100px;line-height:1;white-space:nowrap;-webkit-transition:width .6s ease;transition:width .6s ease}.el-progress-bar__inner::after{display:inline-block;height:100%;vertical-align:middle}.el-progress-bar__innerText{display:inline-block;vertical-align:middle;color:#FFF;font-size:12px;margin:0 5px}@keyframes progress{0%{background-position:0 0}100%{background-position:32px 0}}.el-time-spinner{width:100%;white-space:nowrap}.el-spinner{display:inline-block;vertical-align:middle}.el-spinner-inner{-webkit-animation:rotate 2s linear infinite;animation:rotate 2s linear infinite;width:50px;height:50px}.el-spinner-inner .path{stroke:#ececec;stroke-linecap:round;-webkit-animation:dash 1.5s ease-in-out infinite;animation:dash 1.5s ease-in-out infinite}@-webkit-keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}100%{stroke-dasharray:90,150;stroke-dashoffset:-124}}@keyframes dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}100%{stroke-dasharray:90,150;stroke-dashoffset:-124}}.el-message{min-width:380px;box-sizing:border-box;border-radius:4px;border-width:1px;border-style:solid;border-color:#EBEEF5;position:fixed;left:50%;top:20px;-webkit-transform:translateX(-50%);transform:translateX(-50%);background-color:#edf2fc;-webkit-transition:opacity .3s,top .4s,-webkit-transform .4s;transition:opacity .3s,top .4s,-webkit-transform .4s;transition:opacity .3s,transform .4s,top .4s;transition:opacity .3s,transform .4s,top .4s,-webkit-transform .4s;overflow:hidden;padding:15px 15px 15px 20px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-message.is-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-message.is-closable .el-message__content{padding-right:16px}.el-message p{margin:0}.el-message--info .el-message__content{color:#909399}.el-message--success{background-color:#f0f9eb;border-color:#e1f3d8}.el-message--success .el-message__content{color:#67C23A}.el-message--warning{background-color:#fdf6ec;border-color:#faecd8}.el-message--warning .el-message__content{color:#E6A23C}.el-message--error{background-color:#fef0f0;border-color:#fde2e2}.el-message--error .el-message__content{color:#F56C6C}.el-message__icon{margin-right:10px}.el-message__content{padding:0;font-size:14px;line-height:1}.el-message__content:focus{outline-width:0}.el-message__closeBtn{position:absolute;top:50%;right:15px;-webkit-transform:translateY(-50%);transform:translateY(-50%);cursor:pointer;color:#C0C4CC;font-size:16px}.el-message__closeBtn:focus{outline-width:0}.el-message__closeBtn:hover{color:#909399}.el-message .el-icon-success{color:#67C23A}.el-message .el-icon-error{color:#F56C6C}.el-message .el-icon-info{color:#909399}.el-message .el-icon-warning{color:#E6A23C}.el-message-fade-enter,.el-message-fade-leave-active{opacity:0;-webkit-transform:translate(-50%,-100%);transform:translate(-50%,-100%)}.el-badge{position:relative;vertical-align:middle;display:inline-block}.el-badge__content{border-radius:10px;color:#FFF;display:inline-block;font-size:12px;height:18px;line-height:18px;padding:0 6px;text-align:center;white-space:nowrap;border:1px solid #FFF}.el-badge__content.is-fixed{position:absolute;top:0;right:10px;-webkit-transform:translateY(-50%) translateX(100%);transform:translateY(-50%) translateX(100%)}.el-rate__icon,.el-rate__item{position:relative;display:inline-block}.el-badge__content.is-fixed.is-dot{right:5px}.el-badge__content.is-dot{height:8px;width:8px;padding:0;right:0;border-radius:50%}.el-badge__content--primary{background-color:#409EFF}.el-badge__content--success{background-color:#67C23A}.el-badge__content--warning{background-color:#E6A23C}.el-badge__content--info{background-color:#909399}.el-badge__content--danger{background-color:#F56C6C}.el-card{border-radius:4px;border:1px solid #EBEEF5;background-color:#FFF;overflow:hidden;color:#303133;-webkit-transition:.3s;transition:.3s}.el-card.is-always-shadow,.el-card.is-hover-shadow:focus,.el-card.is-hover-shadow:hover{box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-card__header{padding:18px 20px;border-bottom:1px solid #EBEEF5;box-sizing:border-box}.el-card__body,.el-main{padding:20px}.el-rate{height:20px;line-height:1}.el-rate:active,.el-rate:focus{outline-width:0}.el-rate__item{font-size:0;vertical-align:middle}.el-rate__icon{font-size:18px;margin-right:6px;color:#C0C4CC;-webkit-transition:.3s;transition:.3s}.el-rate__decimal,.el-rate__icon .path2{position:absolute;top:0;left:0}.el-rate__icon.hover{-webkit-transform:scale(1.15);transform:scale(1.15)}.el-rate__decimal{display:inline-block;overflow:hidden}.el-step.is-vertical,.el-steps{display:-webkit-box;display:-ms-flexbox}.el-rate__text{font-size:14px;vertical-align:middle}.el-steps{display:flex}.el-steps--simple{padding:13px 8%;border-radius:4px;background:#F5F7FA}.el-steps--horizontal{white-space:nowrap}.el-steps--vertical{height:100%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-flow:column;flex-flow:column}.el-step{position:relative;-ms-flex-negative:1;flex-shrink:1}.el-step:last-of-type .el-step__line{display:none}.el-step:last-of-type.is-flex{-ms-flex-preferred-size:auto!important;flex-basis:auto!important;-ms-flex-negative:0;flex-shrink:0;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.el-step:last-of-type .el-step__description,.el-step:last-of-type .el-step__main{padding-right:0}.el-step__head{position:relative;width:100%}.el-step__head.is-process{color:#303133;border-color:#303133}.el-step__head.is-wait{color:#C0C4CC;border-color:#C0C4CC}.el-step__head.is-success{color:#67C23A;border-color:#67C23A}.el-step__head.is-error{color:#F56C6C;border-color:#F56C6C}.el-step__head.is-finish{color:#409EFF;border-color:#409EFF}.el-step__icon{position:relative;z-index:1;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:24px;height:24px;font-size:14px;box-sizing:border-box;background:#FFF;-webkit-transition:.15s ease-out;transition:.15s ease-out}.el-step.is-horizontal,.el-step__icon-inner{display:inline-block}.el-step__icon.is-text{border-radius:50%;border:2px solid;border-color:inherit}.el-step__icon.is-icon{width:40px}.el-step__icon-inner{-webkit-user-select:none;user-select:none;text-align:center;font-weight:700;line-height:1;color:inherit}.el-step__icon-inner[class*=el-icon]:not(.is-status){font-size:25px;font-weight:400}.el-step__icon-inner.is-status{-webkit-transform:translateY(1px);transform:translateY(1px)}.el-step__line{position:absolute;border-color:inherit;background-color:#C0C4CC}.el-step__line-inner{display:block;border-width:1px;border-style:solid;border-color:inherit;-webkit-transition:.15s ease-out;transition:.15s ease-out;-webkit-box-sizing:border-box;box-sizing:border-box;width:0;height:0}.el-step__main{white-space:normal;text-align:left}.el-step__title{font-size:16px;line-height:38px}.el-step__title.is-process{font-weight:700;color:#303133}.el-step__title.is-wait{color:#C0C4CC}.el-step__title.is-success{color:#67C23A}.el-step__title.is-error{color:#F56C6C}.el-step__title.is-finish{color:#409EFF}.el-step__description{padding-right:10%;margin-top:-5px;font-size:12px;line-height:20px;font-weight:400}.el-step__description.is-process{color:#303133}.el-step__description.is-wait{color:#C0C4CC}.el-step__description.is-success{color:#67C23A}.el-step__description.is-error{color:#F56C6C}.el-step__description.is-finish{color:#409EFF}.el-step.is-horizontal .el-step__line{height:2px;top:11px;left:0;right:0}.el-step.is-vertical{display:flex}.el-step.is-vertical .el-step__head{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;width:24px}.el-step.is-vertical .el-step__main{padding-left:10px;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.el-step.is-vertical .el-step__title{line-height:24px;padding-bottom:8px}.el-step.is-vertical .el-step__line{width:2px;top:0;bottom:0;left:11px}.el-step.is-vertical .el-step__icon.is-icon{width:24px}.el-step.is-center .el-step__head,.el-step.is-center .el-step__main{text-align:center}.el-step.is-center .el-step__description{padding-left:20%;padding-right:20%}.el-step.is-center .el-step__line{left:50%;right:-50%}.el-step.is-simple{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-step.is-simple .el-step__head{width:auto;font-size:0;padding-right:10px}.el-step.is-simple .el-step__icon{background:0 0;width:16px;height:16px;font-size:12px}.el-step.is-simple .el-step__icon-inner[class*=el-icon]:not(.is-status){font-size:18px}.el-step.is-simple .el-step__icon-inner.is-status{-webkit-transform:scale(.8) translateY(1px);transform:scale(.8) translateY(1px)}.el-step.is-simple .el-step__main{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.el-step.is-simple .el-step__title{font-size:16px;line-height:20px}.el-step.is-simple:not(:last-of-type) .el-step__title{max-width:50%;word-break:break-all}.el-step.is-simple .el-step__arrow{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.el-step.is-simple .el-step__arrow::after,.el-step.is-simple .el-step__arrow::before{content:'';display:inline-block;position:absolute;height:15px;width:1px;background:#C0C4CC}.el-step.is-simple .el-step__arrow::before{-webkit-transform:rotate(-45deg) translateY(-4px);transform:rotate(-45deg) translateY(-4px);-webkit-transform-origin:0 0;transform-origin:0 0}.el-step.is-simple .el-step__arrow::after{-webkit-transform:rotate(45deg) translateY(4px);transform:rotate(45deg) translateY(4px);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}.el-step.is-simple:last-of-type .el-step__arrow{display:none}.el-carousel{position:relative}.el-carousel--horizontal{overflow-x:hidden}.el-carousel--vertical{overflow-y:hidden}.el-carousel__container{position:relative;height:300px}.el-carousel__arrow{border:none;outline:0;padding:0;margin:0;height:36px;width:36px;cursor:pointer;-webkit-transition:.3s;transition:.3s;border-radius:50%;background-color:rgba(31,45,61,.11);color:#FFF;position:absolute;top:50%;z-index:10;-webkit-transform:translateY(-50%);transform:translateY(-50%);text-align:center;font-size:12px}.el-carousel__arrow--left{left:16px}.el-carousel__arrow:hover{background-color:rgba(31,45,61,.23)}.el-carousel__arrow i{cursor:pointer}.el-carousel__indicators{position:absolute;list-style:none;margin:0;padding:0;z-index:2}.el-carousel__indicators--horizontal{bottom:0;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.el-carousel__indicators--vertical{right:0;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-carousel__indicators--outside{bottom:26px;text-align:center;position:static;-webkit-transform:none;transform:none}.el-carousel__indicators--outside .el-carousel__indicator:hover button{opacity:.64}.el-carousel__indicators--outside button{background-color:#C0C4CC;opacity:.24}.el-carousel__indicators--labels{left:0;right:0;-webkit-transform:none;transform:none;text-align:center}.el-carousel__indicators--labels .el-carousel__button{height:auto;width:auto;padding:2px 18px;font-size:12px}.el-carousel__indicators--labels .el-carousel__indicator{padding:6px 4px}.el-carousel__indicator{background-color:transparent;cursor:pointer}.el-carousel__indicator:hover button{opacity:.72}.el-carousel__indicator--horizontal{display:inline-block;padding:12px 4px}.el-carousel__indicator--vertical{padding:4px 12px}.el-carousel__indicator--vertical .el-carousel__button{width:2px;height:15px}.el-carousel__indicator.is-active button{opacity:1}.el-carousel__button{display:block;opacity:.48;width:30px;height:2px;background-color:#FFF;border:none;outline:0;padding:0;margin:0;cursor:pointer;-webkit-transition:.3s;transition:.3s}.el-carousel__item,.el-carousel__mask{height:100%;position:absolute;top:0;left:0}.carousel-arrow-left-enter,.carousel-arrow-left-leave-active{-webkit-transform:translateY(-50%) translateX(-10px);transform:translateY(-50%) translateX(-10px);opacity:0}.carousel-arrow-right-enter,.carousel-arrow-right-leave-active{-webkit-transform:translateY(-50%) translateX(10px);transform:translateY(-50%) translateX(10px);opacity:0}.el-carousel__item{width:100%;display:inline-block;overflow:hidden;z-index:0}.el-carousel__item.is-active{z-index:2}.el-carousel__item.is-animating{-webkit-transition:-webkit-transform .4s ease-in-out;transition:-webkit-transform .4s ease-in-out;transition:transform .4s ease-in-out;transition:transform .4s ease-in-out,-webkit-transform .4s ease-in-out}.el-carousel__item--card{width:50%;-webkit-transition:-webkit-transform .4s ease-in-out;transition:-webkit-transform .4s ease-in-out;transition:transform .4s ease-in-out;transition:transform .4s ease-in-out,-webkit-transform .4s ease-in-out}.el-carousel__item--card.is-in-stage{cursor:pointer;z-index:1}.el-carousel__item--card.is-in-stage.is-hover .el-carousel__mask,.el-carousel__item--card.is-in-stage:hover .el-carousel__mask{opacity:.12}.el-carousel__item--card.is-active{z-index:2}.el-carousel__mask{width:100%;background-color:#FFF;opacity:.24;-webkit-transition:.2s;transition:.2s}.fade-in-linear-enter-active,.fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.fade-in-linear-enter,.fade-in-linear-leave,.fade-in-linear-leave-active{opacity:0}.el-fade-in-linear-enter-active,.el-fade-in-linear-leave-active{-webkit-transition:opacity .2s linear;transition:opacity .2s linear}.el-fade-in-linear-enter,.el-fade-in-linear-leave,.el-fade-in-linear-leave-active{opacity:0}.el-fade-in-enter-active,.el-fade-in-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.el-fade-in-enter,.el-fade-in-leave-active{opacity:0}.el-zoom-in-center-enter-active,.el-zoom-in-center-leave-active{-webkit-transition:all .3s cubic-bezier(.55,0,.1,1);transition:all .3s cubic-bezier(.55,0,.1,1)}.el-zoom-in-center-enter,.el-zoom-in-center-leave-active{opacity:0;-webkit-transform:scaleX(0);transform:scaleX(0)}.el-zoom-in-top-enter-active,.el-zoom-in-top-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center top;transform-origin:center top}.el-zoom-in-top-enter,.el-zoom-in-top-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.el-zoom-in-bottom-enter-active,.el-zoom-in-bottom-leave-active{opacity:1;-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:center bottom;transform-origin:center bottom}.el-zoom-in-bottom-enter,.el-zoom-in-bottom-leave-active{opacity:0;-webkit-transform:scaleY(0);transform:scaleY(0)}.el-zoom-in-left-enter-active,.el-zoom-in-left-leave-active{opacity:1;-webkit-transform:scale(1,1);transform:scale(1,1);-webkit-transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1);transition:transform .3s cubic-bezier(.23,1,.32,1),opacity .3s cubic-bezier(.23,1,.32,1),-webkit-transform .3s cubic-bezier(.23,1,.32,1);-webkit-transform-origin:top left;transform-origin:top left}.el-zoom-in-left-enter,.el-zoom-in-left-leave-active{opacity:0;-webkit-transform:scale(.45,.45);transform:scale(.45,.45)}.collapse-transition{-webkit-transition:.3s height ease-in-out,.3s padding-top ease-in-out,.3s padding-bottom ease-in-out;transition:.3s height ease-in-out,.3s padding-top ease-in-out,.3s padding-bottom ease-in-out}.horizontal-collapse-transition{-webkit-transition:.3s width ease-in-out,.3s padding-left ease-in-out,.3s padding-right ease-in-out;transition:.3s width ease-in-out,.3s padding-left ease-in-out,.3s padding-right ease-in-out}.el-list-enter-active,.el-list-leave-active{-webkit-transition:all 1s;transition:all 1s}.el-list-enter,.el-list-leave-active{opacity:0;-webkit-transform:translateY(-30px);transform:translateY(-30px)}.el-opacity-transition{-webkit-transition:opacity .3s cubic-bezier(.55,0,.1,1);transition:opacity .3s cubic-bezier(.55,0,.1,1)}.el-collapse{border-top:1px solid #EBEEF5;border-bottom:1px solid #EBEEF5}.el-collapse-item.is-disabled .el-collapse-item__header{color:#bbb;cursor:not-allowed}.el-collapse-item__header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:48px;line-height:48px;background-color:#FFF;color:#303133;cursor:pointer;border-bottom:1px solid #EBEEF5;font-size:13px;font-weight:500;-webkit-transition:border-bottom-color .3s;transition:border-bottom-color .3s;outline:0}.el-collapse-item__arrow{margin:0 8px 0 auto;-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-weight:300}.el-collapse-item__arrow.is-active{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.el-collapse-item__header.focusing:focus:not(:hover){color:#409EFF}.el-collapse-item__header.is-active{border-bottom-color:transparent}.el-collapse-item__wrap{will-change:height;background-color:#FFF;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;border-bottom:1px solid #EBEEF5}.el-cascader__search-input,.el-cascader__tags,.el-tag{-webkit-box-sizing:border-box}.el-collapse-item__content{padding-bottom:25px;font-size:13px;color:#303133;line-height:1.769230769230769}.el-collapse-item:last-child{margin-bottom:-1px}.el-popper .popper__arrow,.el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-cascader,.el-tag{display:inline-block}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03));filter:drop-shadow(0 2px 12px rgba(0, 0, 0, .03))}.el-popper .popper__arrow::after{content:" ";border-width:6px}.el-popper[x-placement^=top]{margin-bottom:12px}.el-popper[x-placement^=top] .popper__arrow{bottom:-6px;left:50%;margin-right:3px;border-top-color:#EBEEF5;border-bottom-width:0}.el-popper[x-placement^=top] .popper__arrow::after{bottom:1px;margin-left:-6px;border-top-color:#FFF;border-bottom-width:0}.el-popper[x-placement^=bottom]{margin-top:12px}.el-popper[x-placement^=bottom] .popper__arrow{top:-6px;left:50%;margin-right:3px;border-top-width:0;border-bottom-color:#EBEEF5}.el-popper[x-placement^=bottom] .popper__arrow::after{top:1px;margin-left:-6px;border-top-width:0;border-bottom-color:#FFF}.el-popper[x-placement^=right]{margin-left:12px}.el-popper[x-placement^=right] .popper__arrow{top:50%;left:-6px;margin-bottom:3px;border-right-color:#EBEEF5;border-left-width:0}.el-popper[x-placement^=right] .popper__arrow::after{bottom:-6px;left:1px;border-right-color:#FFF;border-left-width:0}.el-popper[x-placement^=left]{margin-right:12px}.el-popper[x-placement^=left] .popper__arrow{top:50%;right:-6px;margin-bottom:3px;border-right-width:0;border-left-color:#EBEEF5}.el-popper[x-placement^=left] .popper__arrow::after{right:1px;bottom:-6px;margin-left:-6px;border-right-width:0;border-left-color:#FFF}.el-tag{background-color:#ecf5ff;border-color:#d9ecff;height:32px;padding:0 10px;line-height:30px;font-size:12px;color:#409EFF;border-width:1px;border-style:solid;border-radius:4px;box-sizing:border-box;white-space:nowrap}.el-tag.is-hit{border-color:#409EFF}.el-tag .el-tag__close{color:#409eff}.el-tag .el-tag__close:hover{color:#FFF;background-color:#409eff}.el-tag.el-tag--info{background-color:#f4f4f5;border-color:#e9e9eb;color:#909399}.el-tag.el-tag--info.is-hit{border-color:#909399}.el-tag.el-tag--info .el-tag__close{color:#909399}.el-tag.el-tag--info .el-tag__close:hover{color:#FFF;background-color:#909399}.el-tag.el-tag--success{background-color:#f0f9eb;border-color:#e1f3d8;color:#67c23a}.el-tag.el-tag--success.is-hit{border-color:#67C23A}.el-tag.el-tag--success .el-tag__close{color:#67c23a}.el-tag.el-tag--success .el-tag__close:hover{color:#FFF;background-color:#67c23a}.el-tag.el-tag--warning{background-color:#fdf6ec;border-color:#faecd8;color:#e6a23c}.el-tag.el-tag--warning.is-hit{border-color:#E6A23C}.el-tag.el-tag--warning .el-tag__close{color:#e6a23c}.el-tag.el-tag--warning .el-tag__close:hover{color:#FFF;background-color:#e6a23c}.el-tag.el-tag--danger{background-color:#fef0f0;border-color:#fde2e2;color:#f56c6c}.el-tag.el-tag--danger.is-hit{border-color:#F56C6C}.el-tag.el-tag--danger .el-tag__close{color:#f56c6c}.el-tag.el-tag--danger .el-tag__close:hover{color:#FFF;background-color:#f56c6c}.el-tag .el-icon-close{border-radius:50%;text-align:center;position:relative;cursor:pointer;font-size:12px;height:16px;width:16px;line-height:16px;vertical-align:middle;top:-1px;right:-5px}.el-tag .el-icon-close::before{display:block}.el-tag--dark{background-color:#409eff;border-color:#409eff;color:#fff}.el-tag--dark.is-hit{border-color:#409EFF}.el-tag--dark .el-tag__close{color:#fff}.el-tag--dark .el-tag__close:hover{color:#FFF;background-color:#66b1ff}.el-tag--dark.el-tag--info{background-color:#909399;border-color:#909399;color:#fff}.el-tag--dark.el-tag--info.is-hit{border-color:#909399}.el-tag--dark.el-tag--info .el-tag__close{color:#fff}.el-tag--dark.el-tag--info .el-tag__close:hover{color:#FFF;background-color:#a6a9ad}.el-tag--dark.el-tag--success{background-color:#67c23a;border-color:#67c23a;color:#fff}.el-tag--dark.el-tag--success.is-hit{border-color:#67C23A}.el-tag--dark.el-tag--success .el-tag__close{color:#fff}.el-tag--dark.el-tag--success .el-tag__close:hover{color:#FFF;background-color:#85ce61}.el-tag--dark.el-tag--warning{background-color:#e6a23c;border-color:#e6a23c;color:#fff}.el-tag--dark.el-tag--warning.is-hit{border-color:#E6A23C}.el-tag--dark.el-tag--warning .el-tag__close{color:#fff}.el-tag--dark.el-tag--warning .el-tag__close:hover{color:#FFF;background-color:#ebb563}.el-tag--dark.el-tag--danger{background-color:#f56c6c;border-color:#f56c6c;color:#fff}.el-tag--dark.el-tag--danger.is-hit{border-color:#F56C6C}.el-tag--dark.el-tag--danger .el-tag__close{color:#fff}.el-tag--dark.el-tag--danger .el-tag__close:hover{color:#FFF;background-color:#f78989}.el-tag--plain{background-color:#fff;border-color:#b3d8ff;color:#409eff}.el-tag--plain.is-hit{border-color:#409EFF}.el-tag--plain .el-tag__close{color:#409eff}.el-tag--plain .el-tag__close:hover{color:#FFF;background-color:#409eff}.el-tag--plain.el-tag--info{background-color:#fff;border-color:#d3d4d6;color:#909399}.el-tag--plain.el-tag--info.is-hit{border-color:#909399}.el-tag--plain.el-tag--info .el-tag__close{color:#909399}.el-tag--plain.el-tag--info .el-tag__close:hover{color:#FFF;background-color:#909399}.el-tag--plain.el-tag--success{background-color:#fff;border-color:#c2e7b0;color:#67c23a}.el-tag--plain.el-tag--success.is-hit{border-color:#67C23A}.el-tag--plain.el-tag--success .el-tag__close{color:#67c23a}.el-tag--plain.el-tag--success .el-tag__close:hover{color:#FFF;background-color:#67c23a}.el-tag--plain.el-tag--warning{background-color:#fff;border-color:#f5dab1;color:#e6a23c}.el-tag--plain.el-tag--warning.is-hit{border-color:#E6A23C}.el-tag--plain.el-tag--warning .el-tag__close{color:#e6a23c}.el-tag--plain.el-tag--warning .el-tag__close:hover{color:#FFF;background-color:#e6a23c}.el-tag--plain.el-tag--danger{background-color:#fff;border-color:#fbc4c4;color:#f56c6c}.el-tag--plain.el-tag--danger.is-hit{border-color:#F56C6C}.el-tag--plain.el-tag--danger .el-tag__close{color:#f56c6c}.el-tag--plain.el-tag--danger .el-tag__close:hover{color:#FFF;background-color:#f56c6c}.el-tag--medium{height:28px;line-height:26px}.el-tag--medium .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.el-tag--small{height:24px;padding:0 8px;line-height:22px}.el-tag--small .el-icon-close{-webkit-transform:scale(.8);transform:scale(.8)}.el-tag--mini{height:20px;padding:0 5px;line-height:19px}.el-tag--mini .el-icon-close{margin-left:-3px;-webkit-transform:scale(.7);transform:scale(.7)}.el-cascader{position:relative;font-size:14px;line-height:40px}.el-cascader:not(.is-disabled):hover .el-input__inner{cursor:pointer;border-color:#C0C4CC}.el-cascader .el-input .el-input__inner:focus,.el-cascader .el-input.is-focus .el-input__inner{border-color:#409EFF}.el-cascader .el-input{cursor:pointer}.el-cascader .el-input .el-input__inner{text-overflow:ellipsis}.el-cascader .el-input .el-icon-arrow-down{-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;font-size:14px}.el-cascader .el-input .el-icon-arrow-down.is-reverse{-webkit-transform:rotateZ(180deg);transform:rotateZ(180deg)}.el-cascader .el-input .el-icon-circle-close:hover{color:#909399}.el-cascader--medium{font-size:14px;line-height:36px}.el-cascader--small{font-size:13px;line-height:32px}.el-cascader--mini{font-size:12px;line-height:28px}.el-cascader.is-disabled .el-cascader__label{z-index:2;color:#C0C4CC}.el-cascader__dropdown{margin:5px 0;font-size:14px;background:#FFF;border:1px solid #E4E7ED;border-radius:4px;box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-cascader__tags{position:absolute;left:0;right:30px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;line-height:normal;text-align:left;box-sizing:border-box}.el-cascader__tags .el-tag{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;max-width:100%;margin:2px 0 2px 6px;text-overflow:ellipsis;background:#f0f2f5}.el-cascader__tags .el-tag:not(.is-hit){border-color:transparent}.el-cascader__tags .el-tag>span{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:hidden;text-overflow:ellipsis}.el-cascader__tags .el-tag .el-icon-close{-webkit-box-flex:0;-ms-flex:none;flex:none;background-color:#C0C4CC;color:#FFF}.el-cascader__tags .el-tag .el-icon-close:hover{background-color:#909399}.el-cascader__suggestion-panel{border-radius:4px}.el-cascader__suggestion-list{max-height:204px;margin:0;padding:6px 0;font-size:14px;color:#606266;text-align:center}.el-cascader__suggestion-item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:34px;padding:0 15px;text-align:left;outline:0;cursor:pointer}.el-cascader__suggestion-item:focus,.el-cascader__suggestion-item:hover{background:#F5F7FA}.el-cascader__suggestion-item.is-checked{color:#409EFF;font-weight:700}.el-cascader__suggestion-item>span{margin-right:10px}.el-cascader__empty-text{margin:10px 0;color:#C0C4CC}.el-cascader__search-input{-webkit-box-flex:1;-ms-flex:1;flex:1;height:24px;min-width:60px;margin:2px 0 2px 15px;padding:0;color:#606266;border:none;outline:0;box-sizing:border-box}.el-cascader__search-input::-webkit-input-placeholder{color:#C0C4CC}.el-cascader__search-input:-ms-input-placeholder{color:#C0C4CC}.el-cascader__search-input::-ms-input-placeholder{color:#C0C4CC}.el-cascader__search-input::placeholder{color:#C0C4CC}.el-color-predefine{display:-webkit-box;display:-ms-flexbox;display:flex;font-size:12px;margin-top:8px;width:280px}.el-color-predefine__colors{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-wrap:wrap;flex-wrap:wrap}.el-color-predefine__color-selector{margin:0 0 8px 8px;width:20px;height:20px;border-radius:4px;cursor:pointer}.el-color-predefine__color-selector:nth-child(10n+1){margin-left:0}.el-color-predefine__color-selector.selected{-webkit-box-shadow:0 0 3px 2px #409EFF;box-shadow:0 0 3px 2px #409EFF}.el-color-predefine__color-selector>div{display:-webkit-box;display:-ms-flexbox;display:flex;height:100%;border-radius:3px}.el-color-predefine__color-selector.is-alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.el-color-hue-slider{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;width:280px;height:12px;background-color:red;padding:0 2px}.el-color-hue-slider__bar{position:relative;background:-webkit-gradient(linear,left top,right top,from(red),color-stop(17%,#ff0),color-stop(33%,#0f0),color-stop(50%,#0ff),color-stop(67%,#00f),color-stop(83%,#f0f),to(red));background:linear-gradient(to right,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);height:100%}.el-color-hue-slider__thumb{position:absolute;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;left:0;top:0;width:4px;height:100%;border-radius:1px;background:#fff;border:1px solid #f0f0f0;-webkit-box-shadow:0 0 2px rgba(0,0,0,.6);box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.el-color-hue-slider.is-vertical{width:12px;height:180px;padding:2px 0}.el-color-hue-slider.is-vertical .el-color-hue-slider__bar{background:-webkit-gradient(linear,left top,left bottom,from(red),color-stop(17%,#ff0),color-stop(33%,#0f0),color-stop(50%,#0ff),color-stop(67%,#00f),color-stop(83%,#f0f),to(red));background:linear-gradient(to bottom,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%)}.el-color-hue-slider.is-vertical .el-color-hue-slider__thumb{left:0;top:0;width:100%;height:4px}.el-color-svpanel{position:relative;width:280px;height:180px}.el-color-svpanel__black,.el-color-svpanel__white{position:absolute;top:0;left:0;right:0;bottom:0}.el-color-svpanel__white{background:-webkit-gradient(linear,left top,right top,from(#fff),to(rgba(255,255,255,0)));background:linear-gradient(to right,#fff,rgba(255,255,255,0))}.el-color-svpanel__black{background:-webkit-gradient(linear,left bottom,left top,from(#000),to(rgba(0,0,0,0)));background:linear-gradient(to top,#000,rgba(0,0,0,0))}.el-color-svpanel__cursor{position:absolute}.el-color-svpanel__cursor>div{cursor:head;width:4px;height:4px;-webkit-box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px rgba(0,0,0,.3),0 0 1px 2px rgba(0,0,0,.4);border-radius:50%;-webkit-transform:translate(-2px,-2px);transform:translate(-2px,-2px)}.el-color-alpha-slider{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;width:280px;height:12px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.el-color-alpha-slider__bar{position:relative;background:-webkit-gradient(linear,left top,right top,from(rgba(255,255,255,0)),to(white));background:linear-gradient(to right,rgba(255,255,255,0) 0,#fff 100%);height:100%}.el-color-alpha-slider__thumb{position:absolute;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;left:0;top:0;width:4px;height:100%;border-radius:1px;background:#fff;border:1px solid #f0f0f0;-webkit-box-shadow:0 0 2px rgba(0,0,0,.6);box-shadow:0 0 2px rgba(0,0,0,.6);z-index:1}.el-color-alpha-slider.is-vertical{width:20px;height:180px}.el-color-alpha-slider.is-vertical .el-color-alpha-slider__bar{background:-webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0)),to(white));background:linear-gradient(to bottom,rgba(255,255,255,0) 0,#fff 100%)}.el-color-alpha-slider.is-vertical .el-color-alpha-slider__thumb{left:0;top:0;width:100%;height:4px}.el-color-dropdown{width:300px}.el-color-dropdown__main-wrapper{margin-bottom:6px}.el-color-dropdown__main-wrapper::after{display:table;clear:both}.el-color-dropdown__btns{margin-top:6px;text-align:right}.el-color-dropdown__value{float:left;line-height:26px;font-size:12px;color:#000;width:160px}.el-color-dropdown__btn{border:1px solid #dcdcdc;color:#333;line-height:24px;border-radius:2px;padding:0 20px;cursor:pointer;background-color:transparent;outline:0;font-size:12px}.el-color-dropdown__btn[disabled]{color:#ccc;cursor:not-allowed}.el-color-dropdown__btn:hover{color:#409EFF;border-color:#409EFF}.el-color-dropdown__link-btn{cursor:pointer;color:#409EFF;text-decoration:none;padding:15px;font-size:12px}.el-color-dropdown__link-btn:hover{color:tint(#409EFF,20%)}.el-color-picker{display:inline-block;position:relative;line-height:normal;height:40px}.el-color-picker.is-disabled .el-color-picker__trigger{cursor:not-allowed}.el-color-picker--medium{height:36px}.el-color-picker--medium .el-color-picker__trigger{height:36px;width:36px}.el-color-picker--medium .el-color-picker__mask{height:34px;width:34px}.el-color-picker--small{height:32px}.el-color-picker--small .el-color-picker__trigger{height:32px;width:32px}.el-color-picker--small .el-color-picker__mask{height:30px;width:30px}.el-color-picker--small .el-color-picker__empty,.el-color-picker--small .el-color-picker__icon{-webkit-transform:translate3d(-50%,-50%,0) scale(.8);transform:translate3d(-50%,-50%,0) scale(.8)}.el-color-picker--mini{height:28px}.el-color-picker--mini .el-color-picker__trigger{height:28px;width:28px}.el-color-picker--mini .el-color-picker__mask{height:26px;width:26px}.el-color-picker--mini .el-color-picker__empty,.el-color-picker--mini .el-color-picker__icon{-webkit-transform:translate3d(-50%,-50%,0) scale(.8);transform:translate3d(-50%,-50%,0) scale(.8)}.el-color-picker__mask{height:38px;width:38px;border-radius:4px;position:absolute;top:1px;left:1px;z-index:1;cursor:not-allowed;background-color:rgba(255,255,255,.7)}.el-color-picker__trigger{display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;height:40px;width:40px;padding:4px;border:1px solid #e6e6e6;border-radius:4px;font-size:0;position:relative;cursor:pointer}.el-color-picker__color{position:relative;display:block;-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #999;border-radius:2px;width:100%;height:100%;text-align:center}.el-color-picker__icon,.el-input,.el-textarea{display:inline-block;width:100%}.el-color-picker__color.is-alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.el-color-picker__color-inner{position:absolute;left:0;top:0;right:0;bottom:0}.el-color-picker__empty{font-size:12px;color:#999;position:absolute;top:50%;left:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}.el-color-picker__icon{position:absolute;top:50%;left:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0);color:#FFF;text-align:center;font-size:12px}.el-input__prefix,.el-input__suffix{position:absolute;top:0;text-align:center}.el-color-picker__panel{position:absolute;z-index:10;padding:6px;-webkit-box-sizing:content-box;box-sizing:content-box;background-color:#FFF;border:1px solid #EBEEF5;border-radius:4px;box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-input__inner,.el-textarea__inner,.el-transfer-panel{-webkit-box-sizing:border-box}.el-textarea{position:relative;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;box-sizing:border-box;width:100%;font-size:inherit;color:#606266;background-color:#FFF;background-image:none;border:1px solid #DCDFE6;border-radius:4px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.el-textarea__inner::-webkit-input-placeholder{color:#C0C4CC}.el-textarea__inner:-ms-input-placeholder{color:#C0C4CC}.el-textarea__inner::-ms-input-placeholder{color:#C0C4CC}.el-textarea__inner::placeholder{color:#C0C4CC}.el-textarea__inner:hover{border-color:#C0C4CC}.el-textarea__inner:focus{outline:0;border-color:#409EFF}.el-textarea .el-input__count{color:#909399;background:#FFF;position:absolute;font-size:12px;bottom:5px;right:10px}.el-textarea.is-disabled .el-textarea__inner{background-color:#F5F7FA;border-color:#E4E7ED;color:#C0C4CC;cursor:not-allowed}.el-textarea.is-disabled .el-textarea__inner::-webkit-input-placeholder{color:#C0C4CC}.el-textarea.is-disabled .el-textarea__inner:-ms-input-placeholder{color:#C0C4CC}.el-textarea.is-disabled .el-textarea__inner::-ms-input-placeholder{color:#C0C4CC}.el-textarea.is-disabled .el-textarea__inner::placeholder{color:#C0C4CC}.el-textarea.is-exceed .el-textarea__inner{border-color:#F56C6C}.el-textarea.is-exceed .el-input__count{color:#F56C6C}.el-input{position:relative;font-size:14px}.el-input::-webkit-scrollbar{z-index:11;width:6px}.el-input::-webkit-scrollbar:horizontal{height:6px}.el-input::-webkit-scrollbar-thumb{border-radius:5px;width:6px;background:#b4bccc}.el-input::-webkit-scrollbar-corner{background:#fff}.el-input::-webkit-scrollbar-track{background:#fff}.el-input::-webkit-scrollbar-track-piece{background:#fff;width:6px}.el-input .el-input__clear{color:#C0C4CC;font-size:14px;cursor:pointer;-webkit-transition:color .2s cubic-bezier(.645,.045,.355,1);transition:color .2s cubic-bezier(.645,.045,.355,1)}.el-input .el-input__clear:hover{color:#909399}.el-input .el-input__count{height:100%;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#909399;font-size:12px}.el-input-group__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input,.el-input__inner{font-size:inherit}.el-input .el-input__count .el-input__count-inner{background:#FFF;line-height:initial;display:inline-block;padding:0 5px}.el-input__inner{-webkit-appearance:none;background-color:#FFF;background-image:none;border-radius:4px;border:1px solid #DCDFE6;box-sizing:border-box;color:#606266;display:inline-block;height:40px;line-height:40px;outline:0;padding:0 15px;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}.el-input__inner::-ms-reveal{display:none}.el-input__inner::-webkit-input-placeholder{color:#C0C4CC}.el-input__inner:-ms-input-placeholder{color:#C0C4CC}.el-input__inner::-ms-input-placeholder{color:#C0C4CC}.el-input__inner::placeholder{color:#C0C4CC}.el-input__inner:hover{border-color:#C0C4CC}.el-input.is-active .el-input__inner,.el-input__inner:focus{border-color:#409EFF;outline:0}.el-input__suffix{height:100%;right:5px;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{height:100%;left:5px;transition:all .3s}.el-input__icon{height:100%;width:25px;text-align:center;-webkit-transition:all .3s;transition:all .3s;line-height:40px}.el-input__icon:after{content:'';height:100%;width:0;display:inline-block;vertical-align:middle}.el-input__validateIcon{pointer-events:none}.el-input.is-disabled .el-input__inner{background-color:#F5F7FA;border-color:#E4E7ED;color:#C0C4CC;cursor:not-allowed}.el-input.is-disabled .el-input__inner::-webkit-input-placeholder{color:#C0C4CC}.el-input.is-disabled .el-input__inner:-ms-input-placeholder{color:#C0C4CC}.el-input.is-disabled .el-input__inner::-ms-input-placeholder{color:#C0C4CC}.el-input.is-disabled .el-input__inner::placeholder{color:#C0C4CC}.el-input.is-disabled .el-input__icon{cursor:not-allowed}.el-image-viewer__btn,.el-image__preview,.el-link,.el-transfer-panel__filter .el-icon-circle-close{cursor:pointer}.el-input.is-exceed .el-input__inner{border-color:#F56C6C}.el-input.is-exceed .el-input__suffix .el-input__count{color:#F56C6C}.el-input--suffix .el-input__inner{padding-right:30px}.el-input--prefix .el-input__inner{padding-left:30px}.el-input--medium{font-size:14px}.el-input--medium .el-input__inner{height:36px;line-height:36px}.el-input--medium .el-input__icon{line-height:36px}.el-input--small{font-size:13px}.el-input--small .el-input__inner{height:32px;line-height:32px}.el-input--small .el-input__icon{line-height:32px}.el-input--mini{font-size:12px}.el-input--mini .el-input__inner{height:28px;line-height:28px}.el-input--mini .el-input__icon{line-height:28px}.el-input-group{line-height:normal;display:inline-table;width:100%;border-collapse:separate;border-spacing:0}.el-input-group>.el-input__inner{vertical-align:middle;display:table-cell}.el-input-group__append,.el-input-group__prepend{background-color:#F5F7FA;color:#909399;vertical-align:middle;display:table-cell;position:relative;border:1px solid #DCDFE6;border-radius:4px;padding:0 20px;width:1px;white-space:nowrap}.el-input-group--append .el-input__inner,.el-input-group__prepend{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append:focus,.el-input-group__prepend:focus{outline:0}.el-input-group__append .el-button,.el-input-group__append .el-select,.el-input-group__prepend .el-button,.el-input-group__prepend .el-select{display:inline-block;margin:-10px -20px}.el-input-group__append button.el-button,.el-input-group__append div.el-select .el-input__inner,.el-input-group__append div.el-select:hover .el-input__inner,.el-input-group__prepend button.el-button,.el-input-group__prepend div.el-select .el-input__inner,.el-input-group__prepend div.el-select:hover .el-input__inner{border-color:transparent;background-color:transparent;color:inherit;border-top:0;border-bottom:0}.el-input-group__prepend{border-right:0}.el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner,.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.el-input__inner::-ms-clear{display:none;width:0;height:0}.el-transfer{font-size:14px}.el-transfer__buttons{display:inline-block;vertical-align:middle;padding:0 30px}.el-transfer__button{display:block;margin:0 auto;padding:10px;border-radius:50%;color:#FFF;background-color:#409EFF;font-size:0}.el-button-group>.el-button+.el-button,.el-transfer-panel__item+.el-transfer-panel__item,.el-transfer__button [class*=el-icon-]+span{margin-left:0}.el-divider__text,.el-image__error,.el-link,.el-timeline,.el-transfer__button i,.el-transfer__button span{font-size:14px}.el-transfer__button.is-with-texts{border-radius:4px}.el-transfer__button.is-disabled,.el-transfer__button.is-disabled:hover{border:1px solid #DCDFE6;background-color:#F5F7FA;color:#C0C4CC}.el-transfer__button:first-child{margin-bottom:10px}.el-transfer__button:nth-child(2){margin:0}.el-transfer-panel{border:1px solid #EBEEF5;border-radius:4px;overflow:hidden;background:#FFF;display:inline-block;vertical-align:middle;width:200px;max-height:100%;box-sizing:border-box;position:relative}.el-transfer-panel__body{height:246px}.el-transfer-panel__body.is-with-footer{padding-bottom:40px}.el-transfer-panel__list{margin:0;padding:6px 0;list-style:none;height:246px;overflow:auto;-webkit-box-sizing:border-box;box-sizing:border-box}.el-transfer-panel__list.is-filterable{height:194px;padding-top:0}.el-transfer-panel__item{height:30px;line-height:30px;padding-left:15px;display:block!important}.el-transfer-panel__item.el-checkbox{color:#606266}.el-transfer-panel__item:hover{color:#409EFF}.el-transfer-panel__item.el-checkbox .el-checkbox__label{width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block;-webkit-box-sizing:border-box;box-sizing:border-box;padding-left:24px;line-height:30px}.el-transfer-panel__item .el-checkbox__input{position:absolute;top:8px}.el-transfer-panel__filter{text-align:center;margin:15px;-webkit-box-sizing:border-box;box-sizing:border-box;display:block;width:auto}.el-transfer-panel__filter .el-input__inner{height:32px;width:100%;font-size:12px;display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:16px;padding-right:10px;padding-left:30px}.el-transfer-panel__filter .el-input__icon{margin-left:5px}.el-transfer-panel .el-transfer-panel__header{height:40px;line-height:40px;background:#F5F7FA;margin:0;padding-left:15px;border-bottom:1px solid #EBEEF5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#000}.el-container,.el-header{-webkit-box-sizing:border-box}.el-transfer-panel .el-transfer-panel__header .el-checkbox{display:block;line-height:40px}.el-transfer-panel .el-transfer-panel__header .el-checkbox .el-checkbox__label{font-size:16px;color:#303133;font-weight:400}.el-transfer-panel .el-transfer-panel__header .el-checkbox .el-checkbox__label span{position:absolute;right:15px;color:#909399;font-size:12px;font-weight:400}.el-transfer-panel .el-transfer-panel__footer{height:40px;background:#FFF;margin:0;padding:0;border-top:1px solid #EBEEF5;position:absolute;bottom:0;left:0;width:100%;z-index:1}.el-transfer-panel .el-transfer-panel__footer::after{display:inline-block;height:100%;vertical-align:middle}.el-container,.el-timeline-item__node{display:-webkit-box;display:-ms-flexbox}.el-transfer-panel .el-transfer-panel__footer .el-checkbox{padding-left:20px;color:#606266}.el-transfer-panel .el-transfer-panel__empty{margin:0;height:30px;line-height:30px;padding:6px 15px 0;color:#909399;text-align:center}.el-transfer-panel .el-checkbox__label{padding-left:8px}.el-transfer-panel .el-checkbox__inner{height:14px;width:14px;border-radius:3px}.el-transfer-panel .el-checkbox__inner::after{height:6px;width:3px;left:4px}.el-container{display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-preferred-size:auto;flex-basis:auto;box-sizing:border-box;min-width:0}.el-container.is-vertical,.el-drawer,.el-empty,.el-result{-webkit-box-orient:vertical;-webkit-box-direction:normal}.el-container.is-vertical{-ms-flex-direction:column;flex-direction:column}.el-header{padding:0 20px;box-sizing:border-box;-ms-flex-negative:0;flex-shrink:0}.el-aside{overflow:auto;-webkit-box-sizing:border-box;box-sizing:border-box;-ms-flex-negative:0;flex-shrink:0}.el-main{display:block;-webkit-box-flex:1;-ms-flex:1;flex:1;-ms-flex-preferred-size:auto;flex-basis:auto;overflow:auto;-webkit-box-sizing:border-box;box-sizing:border-box}.el-footer{padding:0 20px;-webkit-box-sizing:border-box;box-sizing:border-box;-ms-flex-negative:0;flex-shrink:0}.el-timeline{margin:0;list-style:none}.el-timeline .el-timeline-item:last-child .el-timeline-item__tail{display:none}.el-timeline-item{position:relative;padding-bottom:20px}.el-timeline-item__wrapper{position:relative;padding-left:28px;top:-3px}.el-timeline-item__tail{position:absolute;left:4px;height:100%;border-left:2px solid #E4E7ED}.el-timeline-item__icon{color:#FFF;font-size:13px}.el-timeline-item__node{position:absolute;background-color:#E4E7ED;border-radius:50%;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-image__error,.el-timeline-item__dot{display:-webkit-box;display:-ms-flexbox}.el-timeline-item__node--normal{left:-1px;width:12px;height:12px}.el-timeline-item__node--large{left:-2px;width:14px;height:14px}.el-timeline-item__node--primary{background-color:#409EFF}.el-timeline-item__node--success{background-color:#67C23A}.el-timeline-item__node--warning{background-color:#E6A23C}.el-timeline-item__node--danger{background-color:#F56C6C}.el-timeline-item__node--info{background-color:#909399}.el-timeline-item__dot{position:absolute;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-timeline-item__content{color:#303133}.el-timeline-item__timestamp{color:#909399;line-height:1;font-size:13px}.el-timeline-item__timestamp.is-top{margin-bottom:8px;padding-top:4px}.el-timeline-item__timestamp.is-bottom{margin-top:8px}.el-link{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;vertical-align:middle;position:relative;text-decoration:none;outline:0;padding:0;font-weight:500}.el-link.is-underline:hover:after{position:absolute;left:0;right:0;height:0;bottom:0;border-bottom:1px solid #409EFF}.el-link.el-link--default:after,.el-link.el-link--primary.is-underline:hover:after,.el-link.el-link--primary:after{border-color:#409EFF}.el-link.is-disabled{cursor:not-allowed}.el-link [class*=el-icon-]+span{margin-left:5px}.el-link.el-link--default{color:#606266}.el-link.el-link--default:hover{color:#409EFF}.el-link.el-link--default.is-disabled{color:#C0C4CC}.el-link.el-link--primary{color:#409EFF}.el-link.el-link--primary:hover{color:#66b1ff}.el-link.el-link--primary.is-disabled{color:#a0cfff}.el-link.el-link--danger.is-underline:hover:after,.el-link.el-link--danger:after{border-color:#F56C6C}.el-link.el-link--danger{color:#F56C6C}.el-link.el-link--danger:hover{color:#f78989}.el-link.el-link--danger.is-disabled{color:#fab6b6}.el-link.el-link--success.is-underline:hover:after,.el-link.el-link--success:after{border-color:#67C23A}.el-link.el-link--success{color:#67C23A}.el-link.el-link--success:hover{color:#85ce61}.el-link.el-link--success.is-disabled{color:#b3e19d}.el-link.el-link--warning.is-underline:hover:after,.el-link.el-link--warning:after{border-color:#E6A23C}.el-link.el-link--warning{color:#E6A23C}.el-link.el-link--warning:hover{color:#ebb563}.el-link.el-link--warning.is-disabled{color:#f3d19e}.el-link.el-link--info.is-underline:hover:after,.el-link.el-link--info:after{border-color:#909399}.el-link.el-link--info{color:#909399}.el-link.el-link--info:hover{color:#a6a9ad}.el-link.el-link--info.is-disabled{color:#c8c9cc}.el-divider{background-color:#DCDFE6;position:relative}.el-divider--horizontal{display:block;height:1px;width:100%;margin:24px 0}.el-divider--vertical{display:inline-block;width:1px;height:1em;margin:0 8px;vertical-align:middle;position:relative}.el-divider__text{position:absolute;background-color:#FFF;padding:0 20px;font-weight:500;color:#303133}.el-image__error,.el-image__placeholder{background:#F5F7FA}.el-divider__text.is-left{left:20px;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-divider__text.is-center{left:50%;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%)}.el-divider__text.is-right{right:20px;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.el-image__error,.el-image__inner,.el-image__placeholder{width:100%;height:100%}.el-image{position:relative;display:inline-block;overflow:hidden}.el-image__inner{vertical-align:top}.el-image__inner--center{position:relative;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);display:block}.el-image__error{display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#C0C4CC;vertical-align:middle}.el-image-viewer__wrapper{position:fixed;top:0;right:0;bottom:0;left:0}.el-image-viewer__btn{position:absolute;z-index:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;border-radius:50%;opacity:.8;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-user-select:none;user-select:none}.el-button,.el-checkbox,.el-checkbox-button__inner,.el-empty__image img,.el-radio{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.el-image-viewer__close{top:40px;right:40px;width:40px;height:40px;font-size:24px;color:#fff;background-color:#606266}.el-image-viewer__canvas{width:100%;height:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-image-viewer__actions{left:50%;bottom:30px;-webkit-transform:translateX(-50%);transform:translateX(-50%);width:282px;height:44px;padding:0 23px;background-color:#606266;border-color:#fff;border-radius:22px}.el-image-viewer__actions__inner{width:100%;height:100%;text-align:justify;cursor:default;font-size:23px;color:#fff;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-pack:distribute;justify-content:space-around}.el-image-viewer__next,.el-image-viewer__prev{width:44px;height:44px;font-size:24px;color:#fff;background-color:#606266;border-color:#fff;top:50%}.el-image-viewer__prev{-webkit-transform:translateY(-50%);transform:translateY(-50%);left:40px}.el-image-viewer__next{-webkit-transform:translateY(-50%);transform:translateY(-50%);right:40px;text-indent:2px}.el-image-viewer__mask{position:absolute;width:100%;height:100%;top:0;left:0;opacity:.5;background:#000}.viewer-fade-enter-active{-webkit-animation:viewer-fade-in .3s;animation:viewer-fade-in .3s}.viewer-fade-leave-active{-webkit-animation:viewer-fade-out .3s;animation:viewer-fade-out .3s}@-webkit-keyframes viewer-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@keyframes viewer-fade-in{0%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}}@-webkit-keyframes viewer-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}@keyframes viewer-fade-out{0%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}100%{-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0);opacity:0}}.el-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#FFF;border:1px solid #DCDFE6;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:.1s;transition:.1s;font-weight:500;padding:12px 20px;font-size:14px;border-radius:4px}.el-button+.el-button,.el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.el-button:focus,.el-button:hover{color:#409EFF;border-color:#c6e2ff;background-color:#ecf5ff}.el-button:active{color:#3a8ee6;border-color:#3a8ee6;outline:0}.el-button::-moz-focus-inner{border:0}.el-button [class*=el-icon-]+span{margin-left:5px}.el-button.is-plain:focus,.el-button.is-plain:hover{background:#FFF;border-color:#409EFF;color:#409EFF}.el-button.is-active,.el-button.is-plain:active{color:#3a8ee6;border-color:#3a8ee6}.el-button.is-plain:active{background:#FFF;outline:0}.el-button.is-disabled,.el-button.is-disabled:focus,.el-button.is-disabled:hover{color:#C0C4CC;cursor:not-allowed;background-image:none;background-color:#FFF;border-color:#EBEEF5}.el-button.is-disabled.el-button--text{background-color:transparent}.el-button.is-disabled.is-plain,.el-button.is-disabled.is-plain:focus,.el-button.is-disabled.is-plain:hover{background-color:#FFF;border-color:#EBEEF5;color:#C0C4CC}.el-button.is-loading{position:relative;pointer-events:none}.el-button.is-loading:before{pointer-events:none;content:'';position:absolute;left:-1px;top:-1px;right:-1px;bottom:-1px;border-radius:inherit;background-color:rgba(255,255,255,.35)}.el-button.is-round{border-radius:20px;padding:12px 23px}.el-button.is-circle{border-radius:50%;padding:12px}.el-button--primary{color:#FFF;background-color:#409EFF;border-color:#409EFF}.el-button--primary:focus,.el-button--primary:hover{background:#66b1ff;border-color:#66b1ff;color:#FFF}.el-button--primary.is-active,.el-button--primary:active{background:#3a8ee6;border-color:#3a8ee6;color:#FFF}.el-button--primary:active{outline:0}.el-button--primary.is-disabled,.el-button--primary.is-disabled:active,.el-button--primary.is-disabled:focus,.el-button--primary.is-disabled:hover{color:#FFF;background-color:#a0cfff;border-color:#a0cfff}.el-button--primary.is-plain{color:#409EFF;background:#ecf5ff;border-color:#b3d8ff}.el-button--primary.is-plain:focus,.el-button--primary.is-plain:hover{background:#409EFF;border-color:#409EFF;color:#FFF}.el-button--primary.is-plain:active{background:#3a8ee6;border-color:#3a8ee6;color:#FFF;outline:0}.el-button--primary.is-plain.is-disabled,.el-button--primary.is-plain.is-disabled:active,.el-button--primary.is-plain.is-disabled:focus,.el-button--primary.is-plain.is-disabled:hover{color:#8cc5ff;background-color:#ecf5ff;border-color:#d9ecff}.el-button--success{color:#FFF;background-color:#67C23A;border-color:#67C23A}.el-button--success:focus,.el-button--success:hover{background:#85ce61;border-color:#85ce61;color:#FFF}.el-button--success.is-active,.el-button--success:active{background:#5daf34;border-color:#5daf34;color:#FFF}.el-button--success:active{outline:0}.el-button--success.is-disabled,.el-button--success.is-disabled:active,.el-button--success.is-disabled:focus,.el-button--success.is-disabled:hover{color:#FFF;background-color:#b3e19d;border-color:#b3e19d}.el-button--success.is-plain{color:#67C23A;background:#f0f9eb;border-color:#c2e7b0}.el-button--success.is-plain:focus,.el-button--success.is-plain:hover{background:#67C23A;border-color:#67C23A;color:#FFF}.el-button--success.is-plain:active{background:#5daf34;border-color:#5daf34;color:#FFF;outline:0}.el-button--success.is-plain.is-disabled,.el-button--success.is-plain.is-disabled:active,.el-button--success.is-plain.is-disabled:focus,.el-button--success.is-plain.is-disabled:hover{color:#a4da89;background-color:#f0f9eb;border-color:#e1f3d8}.el-button--warning{color:#FFF;background-color:#E6A23C;border-color:#E6A23C}.el-button--warning:focus,.el-button--warning:hover{background:#ebb563;border-color:#ebb563;color:#FFF}.el-button--warning.is-active,.el-button--warning:active{background:#cf9236;border-color:#cf9236;color:#FFF}.el-button--warning:active{outline:0}.el-button--warning.is-disabled,.el-button--warning.is-disabled:active,.el-button--warning.is-disabled:focus,.el-button--warning.is-disabled:hover{color:#FFF;background-color:#f3d19e;border-color:#f3d19e}.el-button--warning.is-plain{color:#E6A23C;background:#fdf6ec;border-color:#f5dab1}.el-button--warning.is-plain:focus,.el-button--warning.is-plain:hover{background:#E6A23C;border-color:#E6A23C;color:#FFF}.el-button--warning.is-plain:active{background:#cf9236;border-color:#cf9236;color:#FFF;outline:0}.el-button--warning.is-plain.is-disabled,.el-button--warning.is-plain.is-disabled:active,.el-button--warning.is-plain.is-disabled:focus,.el-button--warning.is-plain.is-disabled:hover{color:#f0c78a;background-color:#fdf6ec;border-color:#faecd8}.el-button--danger{color:#FFF;background-color:#F56C6C;border-color:#F56C6C}.el-button--danger:focus,.el-button--danger:hover{background:#f78989;border-color:#f78989;color:#FFF}.el-button--danger.is-active,.el-button--danger:active{background:#dd6161;border-color:#dd6161;color:#FFF}.el-button--danger:active{outline:0}.el-button--danger.is-disabled,.el-button--danger.is-disabled:active,.el-button--danger.is-disabled:focus,.el-button--danger.is-disabled:hover{color:#FFF;background-color:#fab6b6;border-color:#fab6b6}.el-button--danger.is-plain{color:#F56C6C;background:#fef0f0;border-color:#fbc4c4}.el-button--danger.is-plain:focus,.el-button--danger.is-plain:hover{background:#F56C6C;border-color:#F56C6C;color:#FFF}.el-button--danger.is-plain:active{background:#dd6161;border-color:#dd6161;color:#FFF;outline:0}.el-button--danger.is-plain.is-disabled,.el-button--danger.is-plain.is-disabled:active,.el-button--danger.is-plain.is-disabled:focus,.el-button--danger.is-plain.is-disabled:hover{color:#f9a7a7;background-color:#fef0f0;border-color:#fde2e2}.el-button--info{color:#FFF;background-color:#909399;border-color:#909399}.el-button--info:focus,.el-button--info:hover{background:#a6a9ad;border-color:#a6a9ad;color:#FFF}.el-button--info.is-active,.el-button--info:active{background:#82848a;border-color:#82848a;color:#FFF}.el-button--info:active{outline:0}.el-button--info.is-disabled,.el-button--info.is-disabled:active,.el-button--info.is-disabled:focus,.el-button--info.is-disabled:hover{color:#FFF;background-color:#c8c9cc;border-color:#c8c9cc}.el-button--info.is-plain{color:#909399;background:#f4f4f5;border-color:#d3d4d6}.el-button--info.is-plain:focus,.el-button--info.is-plain:hover{background:#909399;border-color:#909399;color:#FFF}.el-button--info.is-plain:active{background:#82848a;border-color:#82848a;color:#FFF;outline:0}.el-button--info.is-plain.is-disabled,.el-button--info.is-plain.is-disabled:active,.el-button--info.is-plain.is-disabled:focus,.el-button--info.is-plain.is-disabled:hover{color:#bcbec2;background-color:#f4f4f5;border-color:#e9e9eb}.el-button--medium{padding:10px 20px;font-size:14px;border-radius:4px}.el-button--medium.is-round{padding:10px 20px}.el-button--medium.is-circle{padding:10px}.el-button--small{padding:9px 15px;font-size:12px;border-radius:3px}.el-button--small.is-round{padding:9px 15px}.el-button--small.is-circle{padding:9px}.el-button--mini,.el-button--mini.is-round{padding:7px 15px}.el-button--mini{font-size:12px;border-radius:3px}.el-button--mini.is-circle{padding:7px}.el-button--text{border-color:transparent;color:#409EFF;background:0 0;padding-left:0;padding-right:0}.el-button--text:focus,.el-button--text:hover{color:#66b1ff;border-color:transparent;background-color:transparent}.el-button--text:active{color:#3a8ee6;border-color:transparent;background-color:transparent}.el-button--text.is-disabled,.el-button--text.is-disabled:focus,.el-button--text.is-disabled:hover{border-color:transparent}.el-button-group .el-button--danger:last-child,.el-button-group .el-button--danger:not(:first-child):not(:last-child),.el-button-group .el-button--info:last-child,.el-button-group .el-button--info:not(:first-child):not(:last-child),.el-button-group .el-button--primary:last-child,.el-button-group .el-button--primary:not(:first-child):not(:last-child),.el-button-group .el-button--success:last-child,.el-button-group .el-button--success:not(:first-child):not(:last-child),.el-button-group .el-button--warning:last-child,.el-button-group .el-button--warning:not(:first-child):not(:last-child),.el-button-group>.el-dropdown>.el-button{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:first-child,.el-button-group .el-button--danger:not(:first-child):not(:last-child),.el-button-group .el-button--info:first-child,.el-button-group .el-button--info:not(:first-child):not(:last-child),.el-button-group .el-button--primary:first-child,.el-button-group .el-button--primary:not(:first-child):not(:last-child),.el-button-group .el-button--success:first-child,.el-button-group .el-button--success:not(:first-child):not(:last-child),.el-button-group .el-button--warning:first-child,.el-button-group .el-button--warning:not(:first-child):not(:last-child){border-right-color:rgba(255,255,255,.5)}.el-button-group{display:inline-block;vertical-align:middle}.el-button-group::after,.el-button-group::before{display:table}.el-button-group::after{clear:both}.el-button-group>.el-button{float:left;position:relative}.el-button-group>.el-button.is-disabled{z-index:1}.el-button-group>.el-button:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.el-button-group>.el-button:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.el-button-group>.el-button:first-child:last-child{border-radius:4px}.el-button-group>.el-button:first-child:last-child.is-round{border-radius:20px}.el-button-group>.el-button:first-child:last-child.is-circle{border-radius:50%}.el-button-group>.el-button:not(:first-child):not(:last-child){border-radius:0}.el-button-group>.el-button.is-active,.el-button-group>.el-button:not(.is-disabled):active,.el-button-group>.el-button:not(.is-disabled):focus,.el-button-group>.el-button:not(.is-disabled):hover{z-index:1}.el-button-group>.el-dropdown>.el-button{border-top-left-radius:0;border-bottom-left-radius:0}.el-calendar{background-color:#fff}.el-calendar__header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:12px 20px;border-bottom:1px solid #EBEEF5}.el-backtop,.el-page-header{display:-webkit-box;display:-ms-flexbox}.el-calendar__title{color:#000;-ms-flex-item-align:center;align-self:center}.el-calendar__body{padding:12px 20px 35px}.el-calendar-table{table-layout:fixed;width:100%}.el-calendar-table thead th{padding:12px 0;color:#606266;font-weight:400}.el-calendar-table:not(.is-range) td.next,.el-calendar-table:not(.is-range) td.prev{color:#C0C4CC}.el-backtop,.el-calendar-table td.is-today{color:#409EFF}.el-calendar-table td{border-bottom:1px solid #EBEEF5;border-right:1px solid #EBEEF5;vertical-align:top;-webkit-transition:background-color .2s ease;transition:background-color .2s ease}.el-calendar-table td.is-selected{background-color:#F2F8FE}.el-calendar-table tr:first-child td{border-top:1px solid #EBEEF5}.el-calendar-table tr td:first-child{border-left:1px solid #EBEEF5}.el-calendar-table tr.el-calendar-table__row--hide-border td{border-top:none}.el-calendar-table .el-calendar-day{-webkit-box-sizing:border-box;box-sizing:border-box;padding:8px;height:85px}.el-calendar-table .el-calendar-day:hover{cursor:pointer;background-color:#F2F8FE}.el-backtop{position:fixed;background-color:#FFF;width:40px;height:40px;border-radius:50%;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;font-size:20px;-webkit-box-shadow:0 0 6px rgba(0,0,0,.12);box-shadow:0 0 6px rgba(0,0,0,.12);cursor:pointer;z-index:5}.el-backtop:hover{background-color:#F2F6FC}.el-page-header{display:flex;line-height:24px}.el-page-header__left{display:-webkit-box;display:-ms-flexbox;display:flex;cursor:pointer;margin-right:40px;position:relative}.el-page-header__left::after{position:absolute;width:1px;height:16px;right:-20px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);background-color:#DCDFE6}.el-checkbox,.el-checkbox__input{display:inline-block;position:relative;white-space:nowrap}.el-page-header__left .el-icon-back{font-size:18px;margin-right:6px;-ms-flex-item-align:center;align-self:center}.el-page-header__title{font-size:14px;font-weight:500}.el-page-header__content{font-size:18px;color:#303133}.el-checkbox{color:#606266;font-weight:500;font-size:14px;cursor:pointer;user-select:none;margin-right:30px}.el-checkbox.is-bordered{padding:9px 20px 9px 10px;border-radius:4px;border:1px solid #DCDFE6;-webkit-box-sizing:border-box;box-sizing:border-box;line-height:normal;height:40px}.el-checkbox.is-bordered.is-checked{border-color:#409EFF}.el-checkbox.is-bordered.is-disabled{border-color:#EBEEF5;cursor:not-allowed}.el-checkbox.is-bordered.el-checkbox--medium{padding:7px 20px 7px 10px;border-radius:4px;height:36px}.el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__label{line-height:17px;font-size:14px}.el-checkbox.is-bordered.el-checkbox--medium .el-checkbox__inner{height:14px;width:14px}.el-checkbox.is-bordered.el-checkbox--small{padding:5px 15px 5px 10px;border-radius:3px;height:32px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__label{line-height:15px;font-size:12px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner{height:12px;width:12px}.el-checkbox.is-bordered.el-checkbox--small .el-checkbox__inner::after{height:6px;width:2px}.el-checkbox.is-bordered.el-checkbox--mini{padding:3px 15px 3px 10px;border-radius:3px;height:28px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__label{line-height:12px;font-size:12px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner{height:12px;width:12px}.el-checkbox.is-bordered.el-checkbox--mini .el-checkbox__inner::after{height:6px;width:2px}.el-checkbox__input{cursor:pointer;outline:0;line-height:1;vertical-align:middle}.el-checkbox__input.is-disabled .el-checkbox__inner{background-color:#edf2fc;border-color:#DCDFE6;cursor:not-allowed}.el-checkbox__input.is-disabled .el-checkbox__inner::after{cursor:not-allowed;border-color:#C0C4CC}.el-checkbox__input.is-disabled .el-checkbox__inner+.el-checkbox__label{cursor:not-allowed}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{background-color:#F2F6FC;border-color:#DCDFE6}.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner::after{border-color:#C0C4CC}.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner{background-color:#F2F6FC;border-color:#DCDFE6}.el-checkbox__input.is-disabled.is-indeterminate .el-checkbox__inner::before{background-color:#C0C4CC;border-color:#C0C4CC}.el-checkbox__input.is-checked .el-checkbox__inner,.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#409EFF;border-color:#409EFF}.el-checkbox__input.is-disabled+span.el-checkbox__label{color:#C0C4CC;cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner::after{-webkit-transform:rotate(45deg) scaleY(1);transform:rotate(45deg) scaleY(1)}.el-checkbox__input.is-checked+.el-checkbox__label{color:#409EFF}.el-checkbox__input.is-focus .el-checkbox__inner{border-color:#409EFF}.el-checkbox__input.is-indeterminate .el-checkbox__inner::before{content:'';position:absolute;display:block;background-color:#FFF;height:2px;-webkit-transform:scale(.5);transform:scale(.5);left:0;right:0;top:5px}.el-checkbox__input.is-indeterminate .el-checkbox__inner::after{display:none}.el-checkbox__inner{display:inline-block;position:relative;border:1px solid #DCDFE6;border-radius:2px;-webkit-box-sizing:border-box;box-sizing:border-box;width:14px;height:14px;background-color:#FFF;z-index:1;-webkit-transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46);transition:border-color .25s cubic-bezier(.71,-.46,.29,1.46),background-color .25s cubic-bezier(.71,-.46,.29,1.46)}.el-checkbox__inner:hover{border-color:#409EFF}.el-checkbox__inner::after{-webkit-box-sizing:content-box;box-sizing:content-box;content:"";border:1px solid #FFF;border-left:0;border-top:0;height:7px;left:4px;position:absolute;top:1px;-webkit-transform:rotate(45deg) scaleY(0);transform:rotate(45deg) scaleY(0);width:3px;-webkit-transition:-webkit-transform .15s ease-in .05s;transition:-webkit-transform .15s ease-in .05s;transition:transform .15s ease-in .05s;transition:transform .15s ease-in .05s,-webkit-transform .15s ease-in .05s;-webkit-transform-origin:center;transform-origin:center}.el-checkbox__original{opacity:0;outline:0;position:absolute;margin:0;width:0;height:0;z-index:-1}.el-checkbox-button,.el-checkbox-button__inner{display:inline-block;position:relative}.el-checkbox__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.el-checkbox:last-of-type{margin-right:0}.el-checkbox-button__inner{line-height:1;font-weight:500;white-space:nowrap;vertical-align:middle;cursor:pointer;background:#FFF;border:1px solid #DCDFE6;border-left:0;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;-webkit-transition:all .3s cubic-bezier(.645,.045,.355,1);transition:all .3s cubic-bezier(.645,.045,.355,1);padding:12px 20px;font-size:14px;border-radius:0}.el-checkbox-button__inner.is-round{padding:12px 20px}.el-checkbox-button__inner:hover{color:#409EFF}.el-checkbox-button__inner [class*=el-icon-]{line-height:.9}.el-checkbox-button__inner [class*=el-icon-]+span{margin-left:5px}.el-checkbox-button__original{opacity:0;outline:0;position:absolute;margin:0;z-index:-1}.el-radio,.el-radio__inner,.el-radio__input{position:relative;display:inline-block}.el-checkbox-button.is-checked .el-checkbox-button__inner{color:#FFF;background-color:#409EFF;border-color:#409EFF;-webkit-box-shadow:-1px 0 0 0 #8cc5ff;box-shadow:-1px 0 0 0 #8cc5ff}.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner{border-left-color:#409EFF}.el-checkbox-button.is-disabled .el-checkbox-button__inner{color:#C0C4CC;cursor:not-allowed;background-image:none;background-color:#FFF;border-color:#EBEEF5;-webkit-box-shadow:none;box-shadow:none}.el-checkbox-button.is-disabled:first-child .el-checkbox-button__inner{border-left-color:#EBEEF5}.el-checkbox-button:first-child .el-checkbox-button__inner{border-left:1px solid #DCDFE6;border-radius:4px 0 0 4px;-webkit-box-shadow:none!important;box-shadow:none!important}.el-checkbox-button.is-focus .el-checkbox-button__inner{border-color:#409EFF}.el-checkbox-button:last-child .el-checkbox-button__inner{border-radius:0 4px 4px 0}.el-checkbox-button--medium .el-checkbox-button__inner{padding:10px 20px;font-size:14px;border-radius:0}.el-checkbox-button--medium .el-checkbox-button__inner.is-round{padding:10px 20px}.el-checkbox-button--small .el-checkbox-button__inner{padding:9px 15px;font-size:12px;border-radius:0}.el-checkbox-button--small .el-checkbox-button__inner.is-round{padding:9px 15px}.el-checkbox-button--mini .el-checkbox-button__inner{padding:7px 15px;font-size:12px;border-radius:0}.el-checkbox-button--mini .el-checkbox-button__inner.is-round{padding:7px 15px}.el-checkbox-group{font-size:0}.el-avatar,.el-cascader-panel,.el-radio,.el-radio--medium.is-bordered .el-radio__label,.el-radio__label{font-size:14px}.el-radio{color:#606266;font-weight:500;line-height:1;cursor:pointer;white-space:nowrap;outline:0;margin-right:30px}.el-cascader-node>.el-radio,.el-radio:last-child{margin-right:0}.el-radio.is-bordered{padding:12px 20px 0 10px;border-radius:4px;border:1px solid #DCDFE6;-webkit-box-sizing:border-box;box-sizing:border-box;height:40px}.el-cascader-menu,.el-cascader-menu__list,.el-radio__inner{-webkit-box-sizing:border-box}.el-radio.is-bordered.is-checked{border-color:#409EFF}.el-radio.is-bordered.is-disabled{cursor:not-allowed;border-color:#EBEEF5}.el-radio__input.is-disabled .el-radio__inner,.el-radio__input.is-disabled.is-checked .el-radio__inner{background-color:#F5F7FA;border-color:#E4E7ED}.el-radio.is-bordered+.el-radio.is-bordered{margin-left:10px}.el-radio--medium.is-bordered{padding:10px 20px 0 10px;border-radius:4px;height:36px}.el-radio--mini.is-bordered .el-radio__label,.el-radio--small.is-bordered .el-radio__label{font-size:12px}.el-radio--medium.is-bordered .el-radio__inner{height:14px;width:14px}.el-radio--small.is-bordered{padding:8px 15px 0 10px;border-radius:3px;height:32px}.el-radio--small.is-bordered .el-radio__inner{height:12px;width:12px}.el-radio--mini.is-bordered{padding:6px 15px 0 10px;border-radius:3px;height:28px}.el-radio--mini.is-bordered .el-radio__inner{height:12px;width:12px}.el-radio__input{white-space:nowrap;cursor:pointer;outline:0;line-height:1;vertical-align:middle}.el-radio__input.is-disabled .el-radio__inner{cursor:not-allowed}.el-radio__input.is-disabled .el-radio__inner::after{cursor:not-allowed;background-color:#F5F7FA}.el-radio__input.is-disabled .el-radio__inner+.el-radio__label{cursor:not-allowed}.el-radio__input.is-disabled.is-checked .el-radio__inner::after{background-color:#C0C4CC}.el-radio__input.is-disabled+span.el-radio__label{color:#C0C4CC;cursor:not-allowed}.el-radio__input.is-checked .el-radio__inner{border-color:#409EFF;background:#409EFF}.el-radio__input.is-checked .el-radio__inner::after{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}.el-radio__input.is-checked+.el-radio__label{color:#409EFF}.el-radio__input.is-focus .el-radio__inner{border-color:#409EFF}.el-radio__inner{border:1px solid #DCDFE6;border-radius:100%;width:14px;height:14px;background-color:#FFF;cursor:pointer;box-sizing:border-box}.el-radio__inner:hover{border-color:#409EFF}.el-radio__inner::after{width:4px;height:4px;border-radius:100%;background-color:#FFF;content:"";position:absolute;left:50%;top:50%;-webkit-transform:translate(-50%,-50%) scale(0);transform:translate(-50%,-50%) scale(0);-webkit-transition:-webkit-transform .15s ease-in;transition:-webkit-transform .15s ease-in;transition:transform .15s ease-in;transition:transform .15s ease-in,-webkit-transform .15s ease-in}.el-radio__original{opacity:0;outline:0;position:absolute;z-index:-1;top:0;left:0;right:0;bottom:0;margin:0}.el-radio:focus:not(.is-focus):not(:active):not(.is-disabled) .el-radio__inner{-webkit-box-shadow:0 0 2px 2px #409EFF;box-shadow:0 0 2px 2px #409EFF}.el-radio__label{padding-left:10px}.el-scrollbar{overflow:hidden;position:relative}.el-scrollbar:active>.el-scrollbar__bar,.el-scrollbar:focus>.el-scrollbar__bar,.el-scrollbar:hover>.el-scrollbar__bar{opacity:1;-webkit-transition:opacity 340ms ease-out;transition:opacity 340ms ease-out}.el-scrollbar__wrap{overflow:scroll;height:100%}.el-scrollbar__wrap--hidden-default{scrollbar-width:none}.el-scrollbar__wrap--hidden-default::-webkit-scrollbar{width:0;height:0}.el-scrollbar__thumb{position:relative;display:block;width:0;height:0;cursor:pointer;border-radius:inherit;background-color:rgba(144,147,153,.3);-webkit-transition:.3s background-color;transition:.3s background-color}.el-scrollbar__thumb:hover{background-color:rgba(144,147,153,.5)}.el-scrollbar__bar{position:absolute;right:2px;bottom:2px;z-index:1;border-radius:4px;opacity:0;-webkit-transition:opacity 120ms ease-out;transition:opacity 120ms ease-out}.el-scrollbar__bar.is-vertical{width:6px;top:2px}.el-scrollbar__bar.is-vertical>div{width:100%}.el-scrollbar__bar.is-horizontal{height:6px;left:2px}.el-scrollbar__bar.is-horizontal>div{height:100%}.el-cascader-panel{display:-webkit-box;display:-ms-flexbox;display:flex;border-radius:4px}.el-cascader-panel.is-bordered{border:1px solid #E4E7ED;border-radius:4px}.el-cascader-menu{min-width:180px;box-sizing:border-box;color:#606266;border-right:solid 1px #E4E7ED}.el-cascader-menu:last-child{border-right:none}.el-cascader-menu__wrap{height:204px}.el-cascader-menu__list{position:relative;min-height:100%;margin:0;padding:6px 0;list-style:none;box-sizing:border-box}.el-cascader-menu__hover-zone{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none}.el-cascader-menu__empty-text{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);text-align:center;color:#C0C4CC}.el-cascader-node{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:0 30px 0 20px;height:34px;line-height:34px;outline:0}.el-cascader-node.is-selectable.in-active-path{color:#606266}.el-cascader-node.in-active-path,.el-cascader-node.is-active,.el-cascader-node.is-selectable.in-checked-path{color:#409EFF;font-weight:700}.el-cascader-node:not(.is-disabled){cursor:pointer}.el-cascader-node:not(.is-disabled):focus,.el-cascader-node:not(.is-disabled):hover{background:#F5F7FA}.el-cascader-node.is-disabled{color:#C0C4CC;cursor:not-allowed}.el-cascader-node__prefix{position:absolute;left:10px}.el-cascader-node__postfix{position:absolute;right:10px}.el-cascader-node__label{-webkit-box-flex:1;-ms-flex:1;flex:1;padding:0 10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.el-cascader-node>.el-radio .el-radio__label{padding-left:0}.el-avatar{display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;overflow:hidden;color:#fff;background:#C0C4CC;width:40px;height:40px;line-height:40px}.el-drawer,.el-drawer__body>*{-webkit-box-sizing:border-box}.el-avatar>img{display:block;height:100%;vertical-align:middle}.el-empty__image img,.el-empty__image svg{vertical-align:top;height:100%;width:100%}.el-avatar--circle{border-radius:50%}.el-avatar--square{border-radius:4px}.el-avatar--icon{font-size:18px}.el-avatar--large{width:40px;height:40px;line-height:40px}.el-avatar--medium{width:36px;height:36px;line-height:36px}.el-avatar--small{width:28px;height:28px;line-height:28px}@-webkit-keyframes el-drawer-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes el-drawer-fade-in{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes rtl-drawer-in{0%{-webkit-transform:translate(100%,0);transform:translate(100%,0)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@keyframes rtl-drawer-in{0%{-webkit-transform:translate(100%,0);transform:translate(100%,0)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@-webkit-keyframes rtl-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(100%,0);transform:translate(100%,0)}}@keyframes rtl-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(100%,0);transform:translate(100%,0)}}@-webkit-keyframes ltr-drawer-in{0%{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@keyframes ltr-drawer-in{0%{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@-webkit-keyframes ltr-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}}@keyframes ltr-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}}@-webkit-keyframes ttb-drawer-in{0%{-webkit-transform:translate(0,-100%);transform:translate(0,-100%)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@keyframes ttb-drawer-in{0%{-webkit-transform:translate(0,-100%);transform:translate(0,-100%)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@-webkit-keyframes ttb-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(0,-100%);transform:translate(0,-100%)}}@keyframes ttb-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(0,-100%);transform:translate(0,-100%)}}@-webkit-keyframes btt-drawer-in{0%{-webkit-transform:translate(0,100%);transform:translate(0,100%)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@keyframes btt-drawer-in{0%{-webkit-transform:translate(0,100%);transform:translate(0,100%)}100%{-webkit-transform:translate(0,0);transform:translate(0,0)}}@-webkit-keyframes btt-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(0,100%);transform:translate(0,100%)}}@keyframes btt-drawer-out{0%{-webkit-transform:translate(0,0);transform:translate(0,0)}100%{-webkit-transform:translate(0,100%);transform:translate(0,100%)}}.el-drawer{position:absolute;box-sizing:border-box;background-color:#FFF;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-webkit-box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);box-shadow:0 8px 10px -5px rgba(0,0,0,.2),0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12);overflow:hidden;outline:0}.el-drawer.rtl{-webkit-animation:rtl-drawer-out .3s;animation:rtl-drawer-out .3s;right:0}.el-drawer__open .el-drawer.rtl{-webkit-animation:rtl-drawer-in .3s 1ms;animation:rtl-drawer-in .3s 1ms}.el-drawer.ltr{-webkit-animation:ltr-drawer-out .3s;animation:ltr-drawer-out .3s;left:0}.el-drawer__open .el-drawer.ltr{-webkit-animation:ltr-drawer-in .3s 1ms;animation:ltr-drawer-in .3s 1ms}.el-drawer.ttb{-webkit-animation:ttb-drawer-out .3s;animation:ttb-drawer-out .3s;top:0}.el-drawer__open .el-drawer.ttb{-webkit-animation:ttb-drawer-in .3s 1ms;animation:ttb-drawer-in .3s 1ms}.el-drawer.btt{-webkit-animation:btt-drawer-out .3s;animation:btt-drawer-out .3s;bottom:0}.el-drawer__open .el-drawer.btt{-webkit-animation:btt-drawer-in .3s 1ms;animation:btt-drawer-in .3s 1ms}.el-drawer__wrapper{position:fixed;top:0;right:0;bottom:0;left:0;overflow:hidden;margin:0}.el-drawer__header{-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#72767b;display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:32px;padding:20px 20px 0}.el-drawer__header>:first-child{-webkit-box-flex:1;-ms-flex:1;flex:1}.el-drawer__title{margin:0;-webkit-box-flex:1;-ms-flex:1;flex:1;line-height:inherit;font-size:1rem}.el-drawer__close-btn{border:none;cursor:pointer;font-size:20px;color:inherit;background-color:transparent}.el-drawer__body{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:auto}.el-drawer__body>*{box-sizing:border-box}.el-drawer.ltr,.el-drawer.rtl{height:100%;top:0;bottom:0}.el-drawer.btt,.el-drawer.ttb{width:100%;left:0;right:0}.el-drawer__container{position:relative;left:0;right:0;top:0;bottom:0;height:100%;width:100%}.el-drawer-fade-enter-active{-webkit-animation:el-drawer-fade-in .3s;animation:el-drawer-fade-in .3s}.el-drawer-fade-leave-active{animation:el-drawer-fade-in .3s reverse}.el-statistic{width:100%;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;color:#000;font-variant:tabular-nums;list-style:none;-webkit-font-feature-settings:"tnum";font-feature-settings:"tnum";text-align:center}.el-statistic .head{margin-bottom:4px;color:#606266;font-size:13px}.el-statistic .con{font-family:Sans-serif;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:#303133}.el-statistic .con .number{font-size:20px;padding:0 4px}.el-statistic .con span{display:inline-block;margin:0;line-height:100%}.el-popconfirm__main,.el-skeleton__image{display:-ms-flexbox;-webkit-box-align:center;display:-webkit-box}.el-popconfirm__main{display:flex;-ms-flex-align:center;align-items:center}.el-popconfirm__icon{margin-right:5px}.el-popconfirm__action{text-align:right;margin:0}@-webkit-keyframes el-skeleton-loading{0%{background-position:100% 50%}100%{background-position:0 50%}}@keyframes el-skeleton-loading{0%{background-position:100% 50%}100%{background-position:0 50%}}.el-skeleton{width:100%}.el-skeleton__first-line,.el-skeleton__paragraph{height:16px;margin-top:16px;background:#f2f2f2}.el-skeleton.is-animated .el-skeleton__item{background:-webkit-gradient(linear,left top,right top,color-stop(25%,#f2f2f2),color-stop(37%,#e6e6e6),color-stop(63%,#f2f2f2));background:linear-gradient(90deg,#f2f2f2 25%,#e6e6e6 37%,#f2f2f2 63%);background-size:400% 100%;-webkit-animation:el-skeleton-loading 1.4s ease infinite;animation:el-skeleton-loading 1.4s ease infinite}.el-skeleton__item{background:#f2f2f2;display:inline-block;height:16px;border-radius:4px;width:100%}.el-skeleton__circle{border-radius:50%;width:36px;height:36px;line-height:36px}.el-skeleton__circle--lg{width:40px;height:40px;line-height:40px}.el-skeleton__circle--md{width:28px;height:28px;line-height:28px}.el-skeleton__button{height:40px;width:64px;border-radius:4px}.el-skeleton__p{width:100%}.el-skeleton__p.is-last{width:61%}.el-skeleton__p.is-first{width:33%}.el-skeleton__text{width:100%;height:13px}.el-skeleton__caption{height:12px}.el-skeleton__h1{height:20px}.el-skeleton__h3{height:18px}.el-skeleton__h5{height:16px}.el-skeleton__image{width:unset;display:flex;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;border-radius:0}.el-skeleton__image svg{fill:#DCDDE0;width:22%;height:22%}.el-empty{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-direction:column;flex-direction:column;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;padding:40px 0}.el-empty__image{width:160px}.el-empty__image img{user-select:none;-o-object-fit:contain;object-fit:contain}.el-empty__image svg{fill:#DCDDE0}.el-empty__description{margin-top:20px}.el-empty__description p{margin:0;font-size:14px;color:#909399}.el-empty__bottom,.el-result__title{margin-top:20px}.el-descriptions{-webkit-box-sizing:border-box;box-sizing:border-box;font-size:14px;color:#303133}.el-descriptions__header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:20px}.el-descriptions__title{font-size:16px;font-weight:700}.el-descriptions--mini,.el-descriptions--small{font-size:12px}.el-descriptions__body{color:#606266;background-color:#FFF}.el-descriptions__body .el-descriptions__table{border-collapse:collapse;width:100%;table-layout:fixed}.el-descriptions__body .el-descriptions__table .el-descriptions-item__cell{-webkit-box-sizing:border-box;box-sizing:border-box;text-align:left;font-weight:400;line-height:1.5}.el-descriptions__body .el-descriptions__table .el-descriptions-item__cell.is-left{text-align:left}.el-descriptions__body .el-descriptions__table .el-descriptions-item__cell.is-center{text-align:center}.el-descriptions__body .el-descriptions__table .el-descriptions-item__cell.is-right{text-align:right}.el-descriptions .is-bordered{table-layout:auto}.el-descriptions .is-bordered .el-descriptions-item__cell{border:1px solid #EBEEF5;padding:12px 10px}.el-descriptions :not(.is-bordered) .el-descriptions-item__cell{padding-bottom:12px}.el-descriptions--medium.is-bordered .el-descriptions-item__cell{padding:10px}.el-descriptions--medium:not(.is-bordered) .el-descriptions-item__cell{padding-bottom:10px}.el-descriptions--small.is-bordered .el-descriptions-item__cell{padding:8px 10px}.el-descriptions--small:not(.is-bordered) .el-descriptions-item__cell{padding-bottom:8px}.el-descriptions--mini.is-bordered .el-descriptions-item__cell{padding:6px 10px}.el-descriptions--mini:not(.is-bordered) .el-descriptions-item__cell{padding-bottom:6px}.el-descriptions-item{vertical-align:top}.el-descriptions-item__container{display:-webkit-box;display:-ms-flexbox;display:flex}.el-descriptions-item__container .el-descriptions-item__content,.el-descriptions-item__container .el-descriptions-item__label{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.el-descriptions-item__container .el-descriptions-item__content{-webkit-box-flex:1;-ms-flex:1;flex:1}.el-descriptions-item__label.has-colon::after{content:':';position:relative;top:-.5px}.el-descriptions-item__label.is-bordered-label{font-weight:700;color:#909399;background:#fafafa}.el-descriptions-item__label:not(.is-bordered-label){margin-right:10px}.el-descriptions-item__content{word-break:break-word;overflow-wrap:break-word}.el-result{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-direction:column;flex-direction:column;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;padding:40px 30px}.el-result__icon svg{width:64px;height:64px}.el-result__title p{margin:0;font-size:20px;color:#303133;line-height:1.3}.el-result__subtitle{margin-top:10px}.el-result__subtitle p{margin:0;font-size:14px;color:#606266;line-height:1.3}.el-result__extra{margin-top:30px }.el-result .icon-success{fill:#67C23A}.el-result .icon-error{fill:#F56C6C}.el-result .icon-info{fill:#909399}.el-result .icon-warning{fill:#E6A23C} |
New file |
| | |
| | | <template> |
| | | <div id="app"> |
| | | <router-view /> |
| | | <theme-picker /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import ThemePicker from "@/components/ThemePicker" |
| | | |
| | | export default { |
| | | name: "App", |
| | | components: { ThemePicker } |
| | | } |
| | | </script> |
| | | <style scoped> |
| | | #app .theme-picker { |
| | | display: none; |
| | | } |
| | | </style> |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 登录方法 |
| | | export function login(username, password, code, uuid) { |
| | | const data = { |
| | | username, |
| | | password, |
| | | code, |
| | | uuid |
| | | } |
| | | return request({ |
| | | url: '/login', |
| | | headers: { |
| | | isToken: false, |
| | | repeatSubmit: false |
| | | }, |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 注册方法 |
| | | export function register(data) { |
| | | return request({ |
| | | url: '/register', |
| | | headers: { |
| | | isToken: false |
| | | }, |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 获取用户详细信息 |
| | | export function getInfo() { |
| | | return request({ |
| | | url: '/getInfo', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 退出方法 |
| | | export function logout() { |
| | | return request({ |
| | | url: '/logout', |
| | | method: 'post' |
| | | }) |
| | | } |
| | | |
| | | // 获取验证码 |
| | | export function getCodeImg() { |
| | | return request({ |
| | | url: '/captchaImage', |
| | | headers: { |
| | | isToken: false |
| | | }, |
| | | method: 'get', |
| | | timeout: 20000 |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 获取路由 |
| | | export const getRouters = () => { |
| | | return request({ |
| | | url: '/getRouters', |
| | | method: 'get' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询缓存详细 |
| | | export function getCache() { |
| | | return request({ |
| | | url: '/monitor/cache', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 查询缓存名称列表 |
| | | export function listCacheName() { |
| | | return request({ |
| | | url: '/monitor/cache/getNames', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 查询缓存键名列表 |
| | | export function listCacheKey(cacheName) { |
| | | return request({ |
| | | url: '/monitor/cache/getKeys/' + cacheName, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 查询缓存内容 |
| | | export function getCacheValue(cacheName, cacheKey) { |
| | | return request({ |
| | | url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 清理指定名称缓存 |
| | | export function clearCacheName(cacheName) { |
| | | return request({ |
| | | url: '/monitor/cache/clearCacheName/' + cacheName, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // 清理指定键名缓存 |
| | | export function clearCacheKey(cacheKey) { |
| | | return request({ |
| | | url: '/monitor/cache/clearCacheKey/' + cacheKey, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // 清理全部缓存 |
| | | export function clearCacheAll() { |
| | | return request({ |
| | | url: '/monitor/cache/clearCacheAll', |
| | | method: 'delete' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询定时任务调度列表 |
| | | export function listJob(query) { |
| | | return request({ |
| | | url: '/monitor/job/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询定时任务调度详细 |
| | | export function getJob(jobId) { |
| | | return request({ |
| | | url: '/monitor/job/' + jobId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 新增定时任务调度 |
| | | export function addJob(data) { |
| | | return request({ |
| | | url: '/monitor/job', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 修改定时任务调度 |
| | | export function updateJob(data) { |
| | | return request({ |
| | | url: '/monitor/job', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 删除定时任务调度 |
| | | export function delJob(jobId) { |
| | | return request({ |
| | | url: '/monitor/job/' + jobId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // 任务状态修改 |
| | | export function changeJobStatus(jobId, status) { |
| | | const data = { |
| | | jobId, |
| | | status |
| | | } |
| | | return request({ |
| | | url: '/monitor/job/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | |
| | | // 定时任务立即执行一次 |
| | | export function runJob(jobId, jobGroup) { |
| | | const data = { |
| | | jobId, |
| | | jobGroup |
| | | } |
| | | return request({ |
| | | url: '/monitor/job/run', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询调度日志列表 |
| | | export function listJobLog(query) { |
| | | return request({ |
| | | url: '/monitor/jobLog/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 删除调度日志 |
| | | export function delJobLog(jobLogId) { |
| | | return request({ |
| | | url: '/monitor/jobLog/' + jobLogId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // 清空调度日志 |
| | | export function cleanJobLog() { |
| | | return request({ |
| | | url: '/monitor/jobLog/clean', |
| | | method: 'delete' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询登录日志列表 |
| | | export function list(query) { |
| | | return request({ |
| | | url: '/monitor/logininfor/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 删除登录日志 |
| | | export function delLogininfor(infoId) { |
| | | return request({ |
| | | url: '/monitor/logininfor/' + infoId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // 解锁用户登录状态 |
| | | export function unlockLogininfor(userName) { |
| | | return request({ |
| | | url: '/monitor/logininfor/unlock/' + userName, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 清空登录日志 |
| | | export function cleanLogininfor() { |
| | | return request({ |
| | | url: '/monitor/logininfor/clean', |
| | | method: 'delete' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询在线用户列表 |
| | | export function list(query) { |
| | | return request({ |
| | | url: '/monitor/online/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 强退用户 |
| | | export function forceLogout(tokenId) { |
| | | return request({ |
| | | url: '/monitor/online/' + tokenId, |
| | | method: 'delete' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询操作日志列表 |
| | | export function list(query) { |
| | | return request({ |
| | | url: '/monitor/operlog/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 删除操作日志 |
| | | export function delOperlog(operId) { |
| | | return request({ |
| | | url: '/monitor/operlog/' + operId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // 清空操作日志 |
| | | export function cleanOperlog() { |
| | | return request({ |
| | | url: '/monitor/operlog/clean', |
| | | method: 'delete' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 获取服务信息 |
| | | export function getServer() { |
| | | return request({ |
| | | url: '/monitor/server', |
| | | method: 'get' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询参数列表 |
| | | export function listConfig(query) { |
| | | return request({ |
| | | url: '/system/config/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询参数详细 |
| | | export function getConfig(configId) { |
| | | return request({ |
| | | url: '/system/config/' + configId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 根据参数键名查询参数值 |
| | | export function getConfigKey(configKey) { |
| | | return request({ |
| | | url: '/system/config/configKey/' + configKey, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 新增参数配置 |
| | | export function addConfig(data) { |
| | | return request({ |
| | | url: '/system/config', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 修改参数配置 |
| | | export function updateConfig(data) { |
| | | return request({ |
| | | url: '/system/config', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 删除参数配置 |
| | | export function delConfig(configId) { |
| | | return request({ |
| | | url: '/system/config/' + configId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // 刷新参数缓存 |
| | | export function refreshCache() { |
| | | return request({ |
| | | url: '/system/config/refreshCache', |
| | | method: 'delete' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询部门列表 |
| | | export function listDept(query) { |
| | | return request({ |
| | | url: '/system/dept/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询部门列表(排除节点) |
| | | export function listDeptExcludeChild(deptId) { |
| | | return request({ |
| | | url: '/system/dept/list/exclude/' + deptId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 查询部门详细 |
| | | export function getDept(deptId) { |
| | | return request({ |
| | | url: '/system/dept/' + deptId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 新增部门 |
| | | export function addDept(data) { |
| | | return request({ |
| | | url: '/system/dept', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 修改部门 |
| | | export function updateDept(data) { |
| | | return request({ |
| | | url: '/system/dept', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 删除部门 |
| | | export function delDept(deptId) { |
| | | return request({ |
| | | url: '/system/dept/' + deptId, |
| | | method: 'delete' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询字典数据列表 |
| | | export function listData(query) { |
| | | return request({ |
| | | url: '/system/dict/data/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询字典数据详细 |
| | | export function getData(dictCode) { |
| | | return request({ |
| | | url: '/system/dict/data/' + dictCode, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 根据字典类型查询字典数据信息 |
| | | export function getDicts(dictType) { |
| | | return request({ |
| | | url: '/system/dict/data/type/' + dictType, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 新增字典数据 |
| | | export function addData(data) { |
| | | return request({ |
| | | url: '/system/dict/data', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 修改字典数据 |
| | | export function updateData(data) { |
| | | return request({ |
| | | url: '/system/dict/data', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 删除字典数据 |
| | | export function delData(dictCode) { |
| | | return request({ |
| | | url: '/system/dict/data/' + dictCode, |
| | | method: 'delete' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询字典类型列表 |
| | | export function listType(query) { |
| | | return request({ |
| | | url: '/system/dict/type/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询字典类型详细 |
| | | export function getType(dictId) { |
| | | return request({ |
| | | url: '/system/dict/type/' + dictId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 新增字典类型 |
| | | export function addType(data) { |
| | | return request({ |
| | | url: '/system/dict/type', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 修改字典类型 |
| | | export function updateType(data) { |
| | | return request({ |
| | | url: '/system/dict/type', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 删除字典类型 |
| | | export function delType(dictId) { |
| | | return request({ |
| | | url: '/system/dict/type/' + dictId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // 刷新字典缓存 |
| | | export function refreshCache() { |
| | | return request({ |
| | | url: '/system/dict/type/refreshCache', |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // 获取字典选择框列表 |
| | | export function optionselect() { |
| | | return request({ |
| | | url: '/system/dict/type/optionselect', |
| | | method: 'get' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询菜单列表 |
| | | export function listMenu(query) { |
| | | return request({ |
| | | url: '/system/menu/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询菜单详细 |
| | | export function getMenu(menuId) { |
| | | return request({ |
| | | url: '/system/menu/' + menuId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 查询菜单下拉树结构 |
| | | export function treeselect() { |
| | | return request({ |
| | | url: '/system/menu/treeselect', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 根据角色ID查询菜单下拉树结构 |
| | | export function roleMenuTreeselect(roleId) { |
| | | return request({ |
| | | url: '/system/menu/roleMenuTreeselect/' + roleId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 新增菜单 |
| | | export function addMenu(data) { |
| | | return request({ |
| | | url: '/system/menu', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 修改菜单 |
| | | export function updateMenu(data) { |
| | | return request({ |
| | | url: '/system/menu', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 删除菜单 |
| | | export function delMenu(menuId) { |
| | | return request({ |
| | | url: '/system/menu/' + menuId, |
| | | method: 'delete' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询公告列表 |
| | | export function listNotice(query) { |
| | | return request({ |
| | | url: '/system/notice/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询公告详细 |
| | | export function getNotice(noticeId) { |
| | | return request({ |
| | | url: '/system/notice/' + noticeId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 新增公告 |
| | | export function addNotice(data) { |
| | | return request({ |
| | | url: '/system/notice', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 修改公告 |
| | | export function updateNotice(data) { |
| | | return request({ |
| | | url: '/system/notice', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 删除公告 |
| | | export function delNotice(noticeId) { |
| | | return request({ |
| | | url: '/system/notice/' + noticeId, |
| | | method: 'delete' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询岗位列表 |
| | | export function listPost(query) { |
| | | return request({ |
| | | url: '/system/post/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询岗位详细 |
| | | export function getPost(postId) { |
| | | return request({ |
| | | url: '/system/post/' + postId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 新增岗位 |
| | | export function addPost(data) { |
| | | return request({ |
| | | url: '/system/post', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 修改岗位 |
| | | export function updatePost(data) { |
| | | return request({ |
| | | url: '/system/post', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 删除岗位 |
| | | export function delPost(postId) { |
| | | return request({ |
| | | url: '/system/post/' + postId, |
| | | method: 'delete' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询档案记录列表 |
| | | export function listRecords(query) { |
| | | return request({ |
| | | url: '/system/records/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询档案记录详细 |
| | | export function getRecords(id) { |
| | | return request({ |
| | | url: '/system/records/' + id, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 新增档案记录 |
| | | export function addRecords(data) { |
| | | return request({ |
| | | url: '/system/records', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 修改档案记录 |
| | | export function updateRecords(data) { |
| | | return request({ |
| | | url: '/system/records', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 删除档案记录 |
| | | export function delRecords(id) { |
| | | return request({ |
| | | url: '/system/records/' + id, |
| | | method: 'delete' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询角色列表 |
| | | export function listRole(query) { |
| | | return request({ |
| | | url: '/system/role/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询角色详细 |
| | | export function getRole(roleId) { |
| | | return request({ |
| | | url: '/system/role/' + roleId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 新增角色 |
| | | export function addRole(data) { |
| | | return request({ |
| | | url: '/system/role', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 修改角色 |
| | | export function updateRole(data) { |
| | | return request({ |
| | | url: '/system/role', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 角色数据权限 |
| | | export function dataScope(data) { |
| | | return request({ |
| | | url: '/system/role/dataScope', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 角色状态修改 |
| | | export function changeRoleStatus(roleId, status) { |
| | | const data = { |
| | | roleId, |
| | | status |
| | | } |
| | | return request({ |
| | | url: '/system/role/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 删除角色 |
| | | export function delRole(roleId) { |
| | | return request({ |
| | | url: '/system/role/' + roleId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | // 查询角色已授权用户列表 |
| | | export function UserRoleIdList(query) { |
| | | return request({ |
| | | url: '/system/role/listUserByRoleId', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | // 查询角色已授权用户列表 |
| | | export function allocatedUserList(query) { |
| | | return request({ |
| | | url: '/system/role/authUser/allocatedList', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询角色未授权用户列表 |
| | | export function unallocatedUserList(query) { |
| | | return request({ |
| | | url: '/system/role/authUser/unallocatedList', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 取消用户授权角色 |
| | | export function authUserCancel(data) { |
| | | return request({ |
| | | url: '/system/role/authUser/cancel', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 批量取消用户授权角色 |
| | | export function authUserCancelAll(data) { |
| | | return request({ |
| | | url: '/system/role/authUser/cancelAll', |
| | | method: 'put', |
| | | params: data |
| | | }) |
| | | } |
| | | |
| | | // 授权用户选择 |
| | | export function authUserSelectAll(data) { |
| | | return request({ |
| | | url: '/system/role/authUser/selectAll', |
| | | method: 'put', |
| | | params: data |
| | | }) |
| | | } |
| | | |
| | | // 根据角色ID查询部门树结构 |
| | | export function deptTreeSelect(roleId) { |
| | | return request({ |
| | | url: '/system/role/deptTree/' + roleId, |
| | | method: 'get' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | import { parseStrEmpty } from "@/utils/ruoyi"; |
| | | |
| | | // 查询用户列表 |
| | | export function listUser(query) { |
| | | return request({ |
| | | url: '/system/user/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询用户详细 |
| | | export function getUser(userId) { |
| | | return request({ |
| | | url: '/system/user/' + parseStrEmpty(userId), |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 新增用户 |
| | | export function addUser(data) { |
| | | return request({ |
| | | url: '/system/user', |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 修改用户 |
| | | export function updateUser(data) { |
| | | return request({ |
| | | url: '/system/user', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 删除用户 |
| | | export function delUser(userId) { |
| | | return request({ |
| | | url: '/system/user/' + userId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // 用户密码重置 |
| | | export function resetUserPwd(userId, password) { |
| | | const data = { |
| | | userId, |
| | | password |
| | | } |
| | | return request({ |
| | | url: '/system/user/resetPwd', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 用户状态修改 |
| | | export function changeUserStatus(userId, status) { |
| | | const data = { |
| | | userId, |
| | | status |
| | | } |
| | | return request({ |
| | | url: '/system/user/changeStatus', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 查询用户个人信息 |
| | | export function getUserProfile() { |
| | | return request({ |
| | | url: '/system/user/profile', |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 修改用户个人信息 |
| | | export function updateUserProfile(data) { |
| | | return request({ |
| | | url: '/system/user/profile', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 用户密码重置 |
| | | export function updateUserPwd(oldPassword, newPassword) { |
| | | const data = { |
| | | oldPassword, |
| | | newPassword |
| | | } |
| | | return request({ |
| | | url: '/system/user/profile/updatePwd', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 用户头像上传 |
| | | export function uploadAvatar(data) { |
| | | return request({ |
| | | url: '/system/user/profile/avatar', |
| | | method: 'post', |
| | | headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 查询授权角色 |
| | | export function getAuthRole(userId) { |
| | | return request({ |
| | | url: '/system/user/authRole/' + userId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 保存授权角色 |
| | | export function updateAuthRole(data) { |
| | | return request({ |
| | | url: '/system/user/authRole', |
| | | method: 'put', |
| | | params: data |
| | | }) |
| | | } |
| | | |
| | | // 查询部门下拉树结构 |
| | | export function deptTreeSelect() { |
| | | return request({ |
| | | url: '/system/user/deptTree', |
| | | method: 'get' |
| | | }) |
| | | } |
New file |
| | |
| | | import request from '@/utils/request' |
| | | |
| | | // 查询生成表数据 |
| | | export function listTable(query) { |
| | | return request({ |
| | | url: '/tool/gen/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | // 查询db数据库列表 |
| | | export function listDbTable(query) { |
| | | return request({ |
| | | url: '/tool/gen/db/list', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | | |
| | | // 查询表详细信息 |
| | | export function getGenTable(tableId) { |
| | | return request({ |
| | | url: '/tool/gen/' + tableId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 修改代码生成信息 |
| | | export function updateGenTable(data) { |
| | | return request({ |
| | | url: '/tool/gen', |
| | | method: 'put', |
| | | data: data |
| | | }) |
| | | } |
| | | |
| | | // 导入表 |
| | | export function importTable(data) { |
| | | return request({ |
| | | url: '/tool/gen/importTable', |
| | | method: 'post', |
| | | params: data |
| | | }) |
| | | } |
| | | |
| | | // 创建表 |
| | | export function createTable(data) { |
| | | return request({ |
| | | url: '/tool/gen/createTable', |
| | | method: 'post', |
| | | params: data |
| | | }) |
| | | } |
| | | |
| | | // 预览生成代码 |
| | | export function previewTable(tableId) { |
| | | return request({ |
| | | url: '/tool/gen/preview/' + tableId, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 删除表数据 |
| | | export function delTable(tableId) { |
| | | return request({ |
| | | url: '/tool/gen/' + tableId, |
| | | method: 'delete' |
| | | }) |
| | | } |
| | | |
| | | // 生成代码(自定义路径) |
| | | export function genCode(tableName) { |
| | | return request({ |
| | | url: '/tool/gen/genCode/' + tableName, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | // 同步数据库 |
| | | export function synchDb(tableName) { |
| | | return request({ |
| | | url: '/tool/gen/synchDb/' + tableName, |
| | | method: 'get' |
| | | }) |
| | | } |
New file |
| | |
| | | import Vue from 'vue' |
| | | import SvgIcon from '@/components/SvgIcon'// svg component |
| | | |
| | | // register globally |
| | | Vue.component('svg-icon', SvgIcon) |
| | | |
| | | const req = require.context('./svg', false, /\.svg$/) |
| | | const requireAll = requireContext => requireContext.keys().map(requireContext) |
| | | requireAll(req) |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M121.718 73.272v9.953c3.957-7.584 6.199-16.05 6.199-24.995C127.917 26.079 99.273 0 63.958 0 28.644 0 0 26.079 0 58.23c0 .403.028.806.028 1.21l22.97-25.953h13.34l-19.76 27.187h6.42V53.77l13.728-19.477v49.361H22.998V73.272H2.158c5.951 20.284 23.608 36.208 45.998 41.399-1.44 3.3-5.618 11.263-12.565 12.674-8.607 1.764 23.358.428 46.163-13.178 17.519-4.611 31.938-15.849 39.77-30.513h-13.506V73.272H85.02V59.464l22.998-25.977h13.008l-19.429 27.187h6.421v-7.433l13.727-19.402v39.433h-.027zm-78.24 2.822a10.516 10.516 0 0 1-.996-4.535V44.548c0-1.613.332-3.124.996-4.535a11.66 11.66 0 0 1 2.713-3.68c1.134-1.032 2.49-1.864 4.04-2.468 1.55-.605 3.21-.908 4.982-.908h11.292c1.77 0 3.431.303 4.981.908 1.522.604 2.85 1.41 3.986 2.418l-12.26 16.303v-2.898a1.96 1.96 0 0 0-.665-1.512c-.443-.403-.996-.604-1.66-.604-.665 0-1.218.201-1.661.604a1.96 1.96 0 0 0-.664 1.512v9.071L44.364 77.606a10.556 10.556 0 0 1-.886-1.512zm35.73-4.535c0 1.613-.332 3.124-.997 4.535a11.66 11.66 0 0 1-2.712 3.68c-1.134 1.032-2.49 1.864-4.04 2.469-1.55.604-3.21.907-4.982.907H55.185c-1.77 0-3.431-.303-4.981-.907-1.55-.605-2.906-1.437-4.041-2.47a12.49 12.49 0 0 1-1.384-1.512l13.727-18.217v6.375c0 .605.222 1.109.665 1.512.442.403.996.604 1.66.604.664 0 1.218-.201 1.66-.604a1.96 1.96 0 0 0 .665-1.512V53.87L75.97 36.838c.913.932 1.66 1.99 2.214 3.175.664 1.41.996 2.922.996 4.535v27.011h.028z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M127.88 73.143c0 1.412-.506 2.635-1.518 3.669-1.011 1.033-2.209 1.55-3.592 1.55h-17.887c0 9.296-1.783 17.178-5.35 23.645l16.609 17.044c1.011 1.034 1.517 2.257 1.517 3.67 0 1.412-.506 2.635-1.517 3.668-.958 1.033-2.155 1.55-3.593 1.55-1.438 0-2.635-.517-3.593-1.55l-15.811-16.063a15.49 15.49 0 0 1-1.196 1.06c-.532.434-1.65 1.208-3.353 2.322a50.104 50.104 0 0 1-5.192 2.974c-1.758.87-3.94 1.658-6.546 2.364-2.607.706-5.189 1.06-7.748 1.06V47.044H58.89v73.062c-2.716 0-5.417-.367-8.106-1.102-2.688-.734-5.003-1.631-6.945-2.692a66.769 66.769 0 0 1-5.268-3.179c-1.571-1.057-2.73-1.94-3.476-2.65L33.9 109.34l-14.611 16.877c-1.066 1.14-2.344 1.711-3.833 1.711-1.277 0-2.422-.434-3.434-1.304-1.012-.978-1.557-2.187-1.635-3.627-.079-1.44.333-2.705 1.236-3.794l16.129-18.51c-3.087-6.197-4.63-13.644-4.63-22.342H5.235c-1.383 0-2.58-.517-3.592-1.55S.125 74.545.125 73.132c0-1.412.506-2.635 1.518-3.668 1.012-1.034 2.21-1.55 3.592-1.55h17.887V43.939L9.308 29.833c-1.012-1.033-1.517-2.256-1.517-3.669 0-1.412.505-2.635 1.517-3.668 1.012-1.034 2.21-1.55 3.593-1.55s2.58.516 3.593 1.55l13.813 14.106h67.396l13.814-14.106c1.012-1.034 2.21-1.55 3.592-1.55 1.384 0 2.581.516 3.593 1.55 1.012 1.033 1.518 2.256 1.518 3.668 0 1.413-.506 2.636-1.518 3.67l-13.814 14.105v23.975h17.887c1.383 0 2.58.516 3.593 1.55 1.011 1.033 1.517 2.256 1.517 3.668l-.005.01zM89.552 26.175H38.448c0-7.23 2.489-13.386 7.466-18.469C50.892 2.623 56.92.082 64 .082c7.08 0 13.108 2.541 18.086 7.624 4.977 5.083 7.466 11.24 7.466 18.469z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1568899741379" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2054" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M960 591.424V368.96c0-0.288 0.16-0.512 0.16-0.768S960 367.68 960 367.424V192a32 32 0 0 0-32-32H96a32 32 0 0 0-32 32v175.424c0 0.288-0.16 0.512-0.16 0.768s0.16 0.48 0.16 0.768v222.464c0 0.288-0.16 0.512-0.16 0.768s0.16 0.48 0.16 0.768V864a32 32 0 0 0 32 32h832a32 32 0 0 0 32-32v-271.04c0-0.288 0.16-0.512 0.16-0.768S960 591.68 960 591.424z m-560-31.232v-160H608v160h-208z m208 64V832h-208v-207.808H608z m-480-224h208v160H128v-160z m544 0h224v160h-224v-160zM896 224v112.192H128V224h768zM128 624.192h208V832H128v-207.808zM672 832v-207.808h224V832h-224z" p-id="2055"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1588670460195" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1314" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M230.4 307.712c13.824 0 25.088-11.264 25.088-25.088 0-100.352 81.92-182.272 182.272-182.272s182.272 81.408 182.272 182.272c0 13.824 11.264 25.088 25.088 25.088s25.088-11.264 24.576-25.088c0-127.488-103.936-231.936-231.936-231.936S205.824 154.624 205.824 282.624c-0.512 14.336 10.752 25.088 24.576 25.088z m564.736 234.496c-11.264 0-21.504 2.048-31.232 6.144 0-44.544-40.448-81.92-88.064-81.92-14.848 0-28.16 3.584-39.936 10.24-13.824-28.16-44.544-48.128-78.848-48.128-12.288 0-24.576 2.56-35.328 7.68V284.16c0-45.568-37.888-81.92-84.48-81.92s-84.48 36.864-84.48 81.92v348.672l-69.12-112.64c-18.432-28.16-58.368-36.864-91.136-19.968-26.624 14.336-46.592 47.104-30.208 88.064 3.072 8.192 76.8 205.312 171.52 311.296 0 0 28.16 24.576 43.008 58.88 4.096 9.728 13.312 15.36 22.528 15.36 3.072 0 6.656-0.512 9.728-2.048 12.288-5.12 18.432-19.968 12.8-32.256-19.456-44.544-53.76-74.752-53.76-74.752C281.6 768 209.408 573.44 208.384 570.88c-5.12-12.8-2.56-20.992 7.168-26.112 9.216-4.608 21.504-4.608 26.112 2.56l113.152 184.32c4.096 8.704 12.8 14.336 22.528 14.336 13.824 0 25.088-10.752 25.088-25.088V284.16c0-17.92 15.36-32.256 34.816-32.256s34.816 14.336 34.816 32.256v284.16c0 13.824 10.24 25.088 24.576 25.088 13.824 0 25.088-11.264 25.088-25.088v-57.344c0-17.92 15.36-32.768 34.816-32.768 19.968 0 37.376 15.36 37.376 32.768v95.232c0 7.168 3.072 13.312 7.68 17.92 4.608 4.608 10.752 7.168 17.92 7.168 13.824 0 24.576-11.264 24.576-25.088V547.84c0-18.432 13.824-32.256 32.256-32.256 20.48 0 38.912 15.36 38.912 32.256v95.232c0 13.824 11.264 25.088 25.088 25.088s24.576-11.264 25.088-25.088v-18.944c0-18.944 12.8-32.256 30.72-32.256 18.432 0 22.528 18.944 22.528 31.744 0 1.024-11.776 99.84-50.688 173.056-30.72 58.368-45.056 112.128-51.2 146.944-2.56 13.312 6.656 26.112 19.968 28.672 1.536 0 3.072 0.512 4.608 0.512 11.776 0 22.016-8.192 24.064-20.48 5.632-31.232 18.432-79.36 46.08-132.608 43.52-81.92 55.808-186.88 56.32-193.536-0.512-50.688-29.696-83.968-72.704-83.968z"></path></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1576153230908" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="971" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M772.87036133 734.06115723c-43.34106445 0-80.00793458 27.93273926-93.76831055 66.57714843H475.90991211c-56.60705567 0-102.66723633-46.06018067-102.66723633-102.66723633V600.82446289h305.859375c13.76037598 38.64440918 50.42724609 66.57714844 93.76831055 66.57714844 55.12390137 0 99.94812012-44.82421875 99.94812012-99.94812012S827.9942627 467.50537109 772.87036133 467.50537109c-43.34106445 0-80.00793458 27.93273926-93.76831055 66.57714844H373.24267578V401.01062011h321.92687989c55.12390137 0 99.94812012-44.82421875 99.94812011-99.94812011V190.07312011C795.11767578 134.94921875 750.29345703 90.125 695.16955567 90.125H251.12963867C196.0057373 90.125 151.18151855 134.94921875 151.18151855 190.07312011V301.0625c0 55.12390137 44.82421875 99.94812012 99.94812012 99.94812012h55.53588867v296.96044921c0 93.35632325 75.97045898 169.32678223 169.32678224 169.32678223h203.19213866c13.76037598 38.64440918 50.42724609 66.57714844 93.76831055 66.57714844 55.12390137 0 99.94812012-44.82421875 99.94812012-99.94812012s-44.90661622-99.86572266-100.03051758-99.86572265z m0-199.89624024c18.37463379 0 33.28857422 14.91394043 33.28857422 33.28857423s-14.91394043 33.28857422-33.28857422 33.28857421-33.28857422-14.91394043-33.28857422-33.28857421 14.91394043-33.28857422 33.28857422-33.28857422zM217.75866699 301.0625V190.07312011c0-18.37463379 14.91394043-33.28857422 33.28857423-33.28857421h444.03991698c18.37463379 0 33.28857422 14.91394043 33.28857422 33.28857422V301.0625c0 18.37463379-14.91394043 33.28857422-33.28857422 33.28857422H251.12963867c-18.37463379 0-33.37097168-14.91394043-33.37097168-33.28857422z m555.11169434 566.23535156c-18.37463379 0-33.28857422-14.91394043-33.28857422-33.28857422 0-18.37463379 14.91394043-33.28857422 33.28857422-33.28857422s33.28857422 14.91394043 33.28857422 33.28857422c0.08239747 18.29223633-14.91394043 33.28857422-33.28857422 33.28857422z" p-id="972"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h36.571V128H0V54.857zM91.429 27.43H128V128H91.429V27.429zM45.714 0h36.572v128H45.714V0z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575982282951" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="902" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M828.40625 90.125H195.59375C137.375 90.125 90.125 137.375 90.125 195.59375v632.8125c0 58.21875 47.25 105.46875 105.46875 105.46875h632.8125c58.21875 0 105.46875-47.25 105.46875-105.46875V195.59375c0-58.21875-47.25-105.46875-105.46875-105.46875z m52.734375 738.28125c0 29.16-23.57015625 52.734375-52.734375 52.734375H195.59375c-29.109375 0-52.734375-23.574375-52.734375-52.734375V195.59375c0-29.109375 23.625-52.734375 52.734375-52.734375h632.8125c29.16 0 52.734375 23.625 52.734375 52.734375v632.8125z" p-id="903"></path><path d="M421.52890625 709.55984375a36.28125 36.28125 0 0 1-27.55265625-12.66890625L205.17453125 476.613125a36.28546875 36.28546875 0 0 1 55.10109375-47.22890625l164.986875 192.4846875 342.16171875-298.48078125a36.2896875 36.2896875 0 0 1 47.70984375 54.68765625L445.3859375 700.6203125a36.3234375 36.3234375 0 0 1-23.85703125 8.93953125z" p-id="904"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.857 118.857h64V73.143H89.143c-1.902 0-3.52-.668-4.855-2.002-1.335-1.335-2.002-2.954-2.002-4.855V36.57H54.857v82.286zM73.143 16v-4.571a2.2 2.2 0 0 0-.677-1.61 2.198 2.198 0 0 0-1.609-.676H20.571c-.621 0-1.158.225-1.609.676a2.198 2.198 0 0 0-.676 1.61V16a2.2 2.2 0 0 0 .676 1.61c.451.45.988.676 1.61.676h50.285c.622 0 1.158-.226 1.61-.677.45-.45.676-.987.676-1.609zm18.286 48h21.357L91.43 42.642V64zM128 73.143v48c0 1.902-.667 3.52-2.002 4.855-1.335 1.335-2.953 2.002-4.855 2.002H52.57c-1.901 0-3.52-.667-4.854-2.002-1.335-1.335-2.003-2.953-2.003-4.855v-11.429H6.857c-1.902 0-3.52-.667-4.855-2.002C.667 106.377 0 104.759 0 102.857v-96c0-1.902.667-3.52 2.002-4.855C3.337.667 4.955 0 6.857 0h77.714c1.902 0 3.52.667 4.855 2.002 1.335 1.335 2.003 2.953 2.003 4.855V30.29c1 .622 1.856 1.29 2.569 2.003l29.147 29.147c1.335 1.335 2.478 3.145 3.429 5.43.95 2.287 1.426 4.383 1.426 6.291v-.018z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1546567861908" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2422" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M318.577778 819.2L17.066667 512l301.511111-307.2 45.511111 45.511111L96.711111 512l267.377778 261.688889zM705.422222 819.2l-45.511111-45.511111L927.288889 512l-267.377778-261.688889 45.511111-45.511111L1006.933333 512zM540.785778 221.866667l55.751111 11.150222L483.157333 802.133333l-55.751111-11.093333z" p-id="2423"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577252187056" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2508" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M747.59340925 691.12859384c11.51396329 0.25305413 22.43746719-0.21087818 40.74171707-1.51832482 29.35428085-2.10878421 35.84933734-2.36183835 46.47761114-0.8856895 24.71495444 3.37405491 41.12129828 21.76265671 32.47528161 47.95376084-85.57447632 258.19957947-442.00123984 249.76444099-628.67084683 50.73735554-153.47733892-159.33976008-153.09775772-414.41833795 0.92786545-573.42069196 159.71934128-162.67163983 424.03439521-166.59397897 565.78689185 0.63263534 80.38686649 94.81095318 108.34934958 169.16669549 89.11723508 230.57450162-15.01454608 47.99593598-50.61082928 77.68762207-119.77896259 114.63352789-4.89237973 2.65706845-29.35428085 15.52065436-35.84933652 19.02123633-46.94154346 25.30541465-63.51659033 41.20565021-62.20914449 58.45550757 2.95229856 39.13904114 24.16667102 52.7196135 70.98168823 53.81618115z m44.41100207 50.10472101c-19.82257471 1.43397372-32.05352527 1.940082-45.63409763 1.6448519-70.34905207-1.60267593-115.98314969-30.91478165-121.38163769-101.64341492-3.45840683-46.05585397 24.7571304-73.13264758 89.24376132-107.96976837 6.7902866-3.66928501 31.37871396-16.57504688 36.06021551-19.06341229 57.69634516-30.83042972 85.15271997-53.73183005 94.76877722-84.47790866 12.77923398-40.78389304-9.10994898-98.94417051-79.24812286-181.6507002-121.17075953-142.97559219-350.14258521-139.60153647-489.2380134 2.06660824-134.49827774 138.84237405-134.79350784 362.12048163-0.42175717 501.637667 158.53842169 168.99799328 451.9968783 181.18676788 534.57688175-11.80919339-4.68150156 0.2952301-10.71262573 0.67481131-18.72600705 1.26527069z" p-id="2509"></path><path d="M346.03865637 637.18588562a78.82636652 78.82636652 0 0 0 78.32025825-79.29029883c0-43.69401562-35.005823-79.29029883-78.32025825-79.29029882a78.82636652 78.82636652 0 0 0-78.36243338 79.29029882c0 43.69401562 35.005823 79.29029883 78.36243338 79.29029883z m0-51.7495729a27.07679361 27.07679361 0 0 1-26.5706845-27.54072593c0-15.30977536 11.97789643-27.54072593 26.5706845-27.54072592 14.55061295 0 26.57068533 12.23095057 26.57068533 27.54072592a27.07679361 27.07679361 0 0 1-26.57068533 27.54072593zM475.7289063 807.11174353a78.82636652 78.82636652 0 0 0 78.3624334-79.29029882c0-43.69401562-34.96364785-79.29029883-78.32025825-79.29029883a78.82636652 78.82636652 0 0 0-78.32025742 79.29029883c0 43.69401562 34.96364785 79.29029883 78.32025742 79.29029882z m0-51.74957208a27.07679361 27.07679361 0 0 1-26.57068532-27.54072674c0-15.30977536 12.06224753-27.54072593 26.57068532-27.54072593 14.59278892 0 26.57068533 12.23095057 26.57068453 27.54072593a27.07679361 27.07679361 0 0 1-26.57068453 27.54072674zM601.24376214 377.21492718a78.82636652 78.82636652 0 0 0 78.32025742-79.29029883c0-43.69401562-34.96364785-79.29029883-78.32025742-79.29029882a78.82636652 78.82636652 0 0 0-78.32025823 79.29029883c0 43.69401562 34.96364785 79.29029883 78.32025824 79.29029883z m1e-8-51.74957208a27.07679361 27.07679361 0 0 1-26.57068534-27.54072675c0-15.30977536 11.97789643-27.54072593 26.57068534-27.54072591 14.55061295 0 26.57068533 12.23095057 26.57068451 27.54072592a27.07679361 27.07679361 0 0 1-26.57068451 27.54072674zM378.80916809 433.85687983a78.82636652 78.82636652 0 0 0 78.32025824-79.29029883c0-43.69401562-34.96364785-79.29029883-78.32025824-79.29029802a78.82636652 78.82636652 0 0 0-78.32025742 79.29029802c0 43.69401562 34.96364785 79.29029883 78.32025742 79.29029883z m0-51.74957209a27.07679361 27.07679361 0 0 1-26.57068451-27.54072674c0-15.30977536 11.97789643-27.54072593 26.57068451-27.54072593 14.55061295 0 26.57068533 12.23095057 26.57068533 27.54072593a27.07679361 27.07679361 0 0 1-26.57068533 27.54072674z" p-id="2510"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575804206892" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3145" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M826.56 470.016c-32.896 0-64.384 12.288-89.984 35.52l0-104.96c0-62.208-50.496-112.832-112.64-113.088L623.936 287.04 519.552 287.104C541.824 262.72 554.56 230.72 554.56 197.12c0-73.536-59.904-133.44-133.504-133.44-73.472 0-133.376 59.904-133.376 133.44 0 32.896 12.224 64.256 35.52 89.984L175.232 287.104l0 0.576C113.728 288.704 64 338.88 64 400.576l0.32 0 0.32 116.48C60.864 544.896 70.592 577.728 100.8 588.48c12.736 4.608 37.632 7.488 60.864-25.28 12.992-18.368 34.24-29.248 56.64-29.248 38.336 0 69.504 31.104 69.504 69.312 0 38.4-31.168 69.504-69.504 69.504-22.656 0-44.032-11.264-57.344-30.4C138.688 610.112 112.576 615.36 102.464 619.136c-29.824 10.752-39.104 43.776-38.144 67.392l0 160.384L64 846.912C64 909.248 114.752 960 177.216 960l446.272 0c62.4 0 113.152-50.752 113.152-113.152l0-145.024c24.384 22.272 56.384 35.008 89.984 35.008 73.536 0 133.44-59.904 133.44-133.504C960 529.92 900.096 470.016 826.56 470.016zM826.56 672.896c-22.72 0-44.032-11.264-57.344-30.4-22.272-32.384-48.448-27.136-58.56-23.36-29.824 10.752-39.04 43.776-38.08 67.392l0 160.384c0 27.136-22.016 49.152-49.152 49.152L177.216 896.064C150.08 896 128 873.984 128 846.848l0.32 0 0-145.024c24.384 22.272 56.384 35.008 89.984 35.008 73.6 0 133.504-59.904 133.504-133.504 0-73.472-59.904-133.376-133.504-133.376-32.896 0-64.32 12.288-89.984 35.52l0-104.96L128 400.512c0-27.072 22.08-49.152 49.216-49.152L177.216 351.04 334.656 350.72c3.776 0.512 7.616 0.832 11.52 0.832 24.896 0 50.752-10.816 60.032-37.056 4.544-12.736 7.424-37.568-25.344-60.736C362.624 240.768 351.68 219.52 351.68 197.12c0-38.272 31.104-69.44 69.376-69.44 38.336 0 69.504 31.168 69.504 69.44 0 22.72-11.264 44.032-30.528 57.472C427.968 276.736 433.088 302.784 436.8 313.024c10.752 29.888 43.072 39.232 67.392 38.08l119.232 0 0 0.384c27.136 0 49.152 22.08 49.152 49.152l0.256 116.48c-3.776 27.84 6.016 60.736 36.224 71.488 12.736 4.608 37.632 7.488 60.8-25.28 13.056-18.368 34.24-29.248 56.704-29.248C864.832 534.016 896 565.12 896 603.392 896 641.728 864.832 672.896 826.56 672.896z" p-id="3146"></path></svg> |
New file |
| | |
| | | <svg width="128" height="100" xmlns="http://www.w3.org/2000/svg"><path d="M27.429 63.638c0-2.508-.893-4.65-2.679-6.424-1.786-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.465 2.662-1.785 1.774-2.678 3.916-2.678 6.424 0 2.508.893 4.65 2.678 6.424 1.786 1.775 3.94 2.662 6.465 2.662 2.524 0 4.678-.887 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm13.714-31.801c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM71.714 65.98l7.215-27.116c.285-1.23.107-2.378-.536-3.443-.643-1.064-1.56-1.762-2.75-2.094-1.19-.33-2.333-.177-3.429.462-1.095.639-1.81 1.573-2.143 2.804l-7.214 27.116c-2.857.237-5.405 1.266-7.643 3.088-2.238 1.822-3.738 4.152-4.5 6.992-.952 3.644-.476 7.098 1.429 10.364 1.905 3.265 4.69 5.37 8.357 6.317 3.667.947 7.143.474 10.429-1.42 3.285-1.892 5.404-4.66 6.357-8.305.762-2.84.619-5.607-.429-8.305-1.047-2.697-2.762-4.85-5.143-6.46zm47.143-2.342c0-2.508-.893-4.65-2.678-6.424-1.786-1.775-3.94-2.662-6.465-2.662-2.524 0-4.678.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.786 1.775 3.94 2.662 6.464 2.662 2.524 0 4.679-.887 6.465-2.662 1.785-1.775 2.678-3.916 2.678-6.424zm-45.714-45.43c0-2.509-.893-4.65-2.679-6.425C68.68 10.01 66.524 9.122 64 9.122c-2.524 0-4.679.887-6.464 2.661-1.786 1.775-2.679 3.916-2.679 6.425 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zm32 13.629c0-2.508-.893-4.65-2.679-6.424-1.785-1.775-3.94-2.662-6.464-2.662-2.524 0-4.679.887-6.464 2.662-1.786 1.774-2.679 3.916-2.679 6.424 0 2.508.893 4.65 2.679 6.424 1.785 1.774 3.94 2.662 6.464 2.662 2.524 0 4.679-.888 6.464-2.662 1.786-1.775 2.679-3.916 2.679-6.424zM128 63.638c0 12.351-3.357 23.78-10.071 34.286-.905 1.372-2.19 2.058-3.858 2.058H13.93c-1.667 0-2.953-.686-3.858-2.058C3.357 87.465 0 76.037 0 63.638c0-8.613 1.69-16.847 5.071-24.703C8.452 31.08 13 24.312 18.714 18.634c5.715-5.68 12.524-10.199 20.429-13.559C47.048 1.715 55.333.035 64 .035c8.667 0 16.952 1.68 24.857 5.04 7.905 3.36 14.714 7.88 20.429 13.559 5.714 5.678 10.262 12.446 13.643 20.301 3.38 7.856 5.071 16.09 5.071 24.703z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1579774833889" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1376" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M887.466667 192.853333h-100.693334V119.466667c0-10.24-6.826667-17.066667-17.066666-17.066667s-17.066667 6.826667-17.066667 17.066667v73.386666H303.786667V119.466667c0-10.24-6.826667-17.066667-17.066667-17.066667s-17.066667 6.826667-17.066667 17.066667v73.386666H168.96c-46.08 0-85.333333 37.546667-85.333333 85.333334V836.266667c0 46.08 37.546667 85.333333 85.333333 85.333333H887.466667c46.08 0 85.333333-37.546667 85.333333-85.333333V278.186667c0-47.786667-37.546667-85.333333-85.333333-85.333334z m-718.506667 34.133334h100.693333v66.56c0 10.24 6.826667 17.066667 17.066667 17.066666s17.066667-6.826667 17.066667-17.066666v-66.56h450.56v66.56c0 10.24 6.826667 17.066667 17.066666 17.066666s17.066667-6.826667 17.066667-17.066666v-66.56H887.466667c27.306667 0 51.2 22.186667 51.2 51.2v88.746666H117.76v-88.746666c0-29.013333 22.186667-51.2 51.2-51.2zM887.466667 887.466667H168.96c-27.306667 0-51.2-22.186667-51.2-51.2V401.066667H938.666667V836.266667c0 27.306667-22.186667 51.2-51.2 51.2z" p-id="1377"></path><path d="M858.453333 493.226667H327.68c-10.24 0-17.066667 6.826667-17.066667 17.066666v114.346667h-116.053333c-10.24 0-17.066667 6.826667-17.066667 17.066667v133.12c0 10.24 6.826667 17.066667 17.066667 17.066666H460.8c10.24 0 17.066667-6.826667 17.066667-17.066666v-114.346667h380.586666c10.24 0 17.066667-6.826667 17.066667-17.066667v-133.12c0-10.24-6.826667-17.066667-17.066667-17.066666z m-413.013333 34.133333v97.28h-98.986667v-97.28h98.986667z m-230.4 131.413333h98.986667v98.986667h-98.986667v-98.986667z m131.413333 97.28v-97.28h98.986667v97.28h-98.986667z m133.12-228.693333h97.28v98.986667h-97.28v-98.986667z m131.413334 0h98.986666v98.986667h-98.986666v-98.986667z m230.4 97.28h-98.986667v-98.986667h98.986667v98.986667z" p-id="1378"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577186573535" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1068" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M479.85714249 608.42857168h64.28571502c19.28571417 0 32.14285751-12.85714249 32.14285664-32.14285751s-12.85714249-32.14285751-32.14285664-32.14285664h-64.28571504c-19.28571417 0-32.14285751 12.85714249-32.14285664 32.14285662s12.85714249 32.14285751 32.14285664 32.14285753z m-2e-8 122.14285665h64.28571504c19.28571417 0 32.14285751-12.85714249 32.14285664-32.14285665s-12.85714249-32.14285751-32.14285664-32.14285751h-64.28571504c-19.28571417 0-32.14285751 12.85714249-32.14285664 32.14285751s12.85714249 32.14285751 32.14285664 32.14285664z m353.57142921-559.28571416h-128.57142921v-32.14285664c0-19.28571417-12.85714249-32.14285751-32.14285664-32.14285753s-32.14285751 12.85714249-32.14285751 32.14285753v32.14285664h-257.14285665v-32.14285664c0-19.28571417-12.85714249-32.14285751-32.14285752-32.14285753s-32.14285751 12.85714249-32.14285664 32.14285753v32.14285664h-128.57142919c-70.71428585 0-128.57142832 57.85714249-128.57142832 122.14285751v501.42857081c0 70.71428585 57.85714249 128.57142832 128.57142832 122.14285751h642.85714335c70.71428585 0 128.57142832-57.85714249 128.57142833-122.14285751v-501.42857081c0-70.71428585-57.85714249-122.14285753-128.57142833-122.14285751z m64.28571415 623.57142832c0 32.14285751-32.14285751 64.28571415-64.28571416 64.28571504h-642.85714335c-32.14285751 0-64.28571415-25.71428583-64.28571417-64.28571504v-372.85714249h771.42857168v372.85714249z m0-437.14285664h-771.42857168v-64.28571417c0-32.14285751 32.14285751-64.28571415 64.28571417-64.28571415h128.57142919v32.14285664c0 19.28571417 12.85714249 32.14285751 32.14285664 32.14285751s32.14285751-12.85714249 32.14285753-32.14285751v-32.14285664h257.14285665v32.14285664c0 19.28571417 12.85714249 32.14285751 32.1428575 32.14285751s32.14285751-12.85714249 32.14285664-32.14285751v-32.14285664h128.57142921c32.14285751 0 64.28571415 25.71428583 64.28571415 64.28571415v64.28571417z m-610.71428583 372.85714247h64.28571415c19.28571417 0 32.14285751-12.85714249 32.14285753-32.14285664s-12.85714249-32.14285751-32.14285753-32.14285751h-64.28571415c-19.28571417 0-32.14285751 12.85714249-32.14285751 32.14285751s12.85714249 32.14285751 32.14285751 32.14285665z m385.71428583-122.14285664h64.28571417c19.28571417 0 32.14285751-12.85714249 32.14285751-32.14285751s-12.85714249-32.14285751-32.14285751-32.14285664h-64.28571415c-19.28571417 0-32.14285751 12.85714249-32.14285753 32.14285664s12.85714249 32.14285751 32.14285753 32.14285751z m-385.71428583 0h64.28571415c19.28571417 0 32.14285751-12.85714249 32.14285753-32.14285751s-12.85714249-32.14285751-32.14285753-32.14285664h-64.28571415c-19.28571417 0-32.14285751 12.85714249-32.14285751 32.14285664s12.85714249 32.14285751 32.14285751 32.14285751z m385.71428583 122.14285665h64.28571417c19.28571417 0 32.14285751-12.85714249 32.14285751-32.14285665s-12.85714249-32.14285751-32.14285751-32.14285751h-64.28571415c-19.28571417 0-32.14285751 12.85714249-32.14285753 32.14285751s12.85714249 32.14285751 32.14285753 32.14285665z" p-id="1069"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566035680909" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3601" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M1002.0848 744.672l-33.568 10.368c0.96 7.264 2.144 14.304 2.144 21.76 0 7.328-1.184 14.432-2.368 21.568l33.792 10.56c7.936 2.24 14.496 7.616 18.336 14.752 3.84 7.328 4.672 15.808 1.952 23.552-5.376 16-23.168 24.672-39.936 19.68l-34.176-10.624c-7.136 12.8-15.776 24.672-26.208 35.2l20.8 27.488a28.96 28.96 0 0 1 5.824 22.816 29.696 29.696 0 0 1-12.704 19.616 32.544 32.544 0 0 1-44.416-6.752l-20.8-27.552c-13.696 6.56-28.192 11.2-43.008 13.888v33.632c0 16.736-14.112 30.432-31.648 30.432-17.6 0-31.872-13.696-31.872-30.432v-33.632a167.616 167.616 0 0 1-42.88-13.888l-20.928 27.552c-10.72 13.76-30.08 16.64-44.288 6.752a29.632 29.632 0 0 1-12.704-19.616 29.28 29.28 0 0 1 5.696-22.816l20.896-27.808a166.72 166.72 0 0 1-27.008-34.688l-33.376 10.432c-16.8 5.184-34.56-3.552-39.936-19.616a29.824 29.824 0 0 1 20.224-38.24l33.472-10.432c-0.8-7.264-2.016-14.304-2.016-21.824 0-7.36 1.184-14.496 2.304-21.632l-33.792-10.368c-16.672-5.376-25.632-22.496-20.224-38.432 5.376-16 23.136-24.672 39.936-19.68l34.016 10.752c7.328-12.672 15.84-24.8 26.336-35.328l-20.8-27.552a29.44 29.44 0 0 1 6.944-42.432 32.704 32.704 0 0 1 44.384 6.752l20.832 27.616c13.696-6.432 28.224-11.2 43.104-13.952v-33.568c0-16.736 14.048-30.432 31.648-30.432 17.536 0 31.808 13.568 31.808 30.432v33.504c15.072 2.688 29.344 7.808 42.848 14.016l20.992-27.616a32.48 32.48 0 0 1 44.224-6.752 29.568 29.568 0 0 1 7.136 42.432l-21.024 27.808c10.432 10.432 19.872 21.888 27.04 34.752l33.376-10.432c16.768-5.12 34.56 3.68 39.936 19.68 5.536 15.936-3.712 33.056-20.32 38.304z m-206.016-74.432c-61.344 0-111.136 47.808-111.136 106.56 0 58.88 49.792 106.496 111.136 106.496 61.312 0 111.104-47.616 111.104-106.496 0-58.752-49.792-106.56-111.104-106.56z" p-id="3602"></path><path d="M802.7888 57.152h-76.448c0-22.08-21.024-38.24-42.848-38.24H39.3968a39.68 39.68 0 0 0-39.36 40.032v795.616s41.888 120.192 110.752 120.192H673.2848a227.488 227.488 0 0 1-107.04-97.44H117.6368s-40.608-13.696-40.608-41.248l470.304-0.256 1.664 3.36a227.68 227.68 0 0 1-12.64-73.632c0-60.576 24-118.624 66.88-161.44a228.352 228.352 0 0 1 123.552-63.392l-3.2 0.288 2.144-424.672h38.208l0.576 421.024c27.04 0 52.672 4.8 76.64 13.344V101.536c0.032 0-6.304-44.384-38.368-44.384zM149.7648 514.336H72.3888v-77.408H149.7648v77.408z m0-144.32H72.3888v-77.44H149.7648v77.44z m0-137.248H72.3888v-77.44H149.7648v77.44z m501.856 281.568H206.0848v-77.408h445.536v77.408z m0-144.32H206.0848v-77.44h445.536v77.44z m0-137.248H206.0848v-77.44h445.536v77.44z" p-id="3603"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M71.984 44.815H115.9L71.984 9.642v35.173zM16.094.05h63.875l47.906 38.37v76.74c0 3.392-1.682 6.645-4.677 9.044-2.995 2.399-7.056 3.746-11.292 3.746H16.094c-4.236 0-8.297-1.347-11.292-3.746-2.995-2.399-4.677-5.652-4.677-9.044V12.84C.125 5.742 7.23.05 16.094.05zm71.86 102.32V89.58h-71.86v12.79h71.86zm23.952-25.58V64H16.094v12.79h95.812z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1569915748289" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3062" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M768.35456 416a256 256 0 1 0-512 0 192 192 0 1 0 0 384v64a256 256 0 0 1-58.88-505.216 320.128 320.128 0 0 1 629.76 0A256.128 256.128 0 0 1 768.35456 864v-64a192 192 0 0 0 0-384z m-512 384h64v64H256.35456v-64z m448 0h64v64h-64v-64z" fill="#333333" p-id="3063"></path><path d="M539.04256 845.248V512.192a32.448 32.448 0 0 0-32-32.192c-17.664 0-32 14.912-32 32.192v333.056l-36.096-36.096a32.192 32.192 0 0 0-45.056 0.192 31.616 31.616 0 0 0-0.192 45.056l90.88 90.944a31.36 31.36 0 0 0 22.528 9.088 30.08 30.08 0 0 0 22.4-9.088l90.88-90.88a32.192 32.192 0 0 0-0.192-45.12 31.616 31.616 0 0 0-45.056-0.192l-36.096 36.096z" fill="#333333" p-id="3064"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M73.137 29.08h-9.209 29.7L63.886.093 34.373 29.08h20.49v27.035H27.238v17.948h27.625v27.133h18.274V74.063h27.41V56.115h-27.41V29.08zm-9.245 98.827l27.518-26.711H36.59l27.302 26.71zM.042 64.982l27.196 27.029V38.167L.042 64.982zm100.505-26.815V92.01l27.41-27.029-27.41-26.815z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566036347051" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5853" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M832 128H192a64.19 64.19 0 0 0-64 64v640a64.19 64.19 0 0 0 64 64h640a64.19 64.19 0 0 0 64-64V192a64.19 64.19 0 0 0-64-64z m0 703.89l-0.11 0.11H192.11l-0.11-0.11V768h640zM832 544H720L605.6 696.54 442.18 435.07 333.25 544H192v-64h114.75l147.07-147.07L610.4 583.46 688 480h144z m0-288H192v-63.89l0.11-0.11h639.78l0.11 0.11z" p-id="5854"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M106.133 67.2a4.797 4.797 0 0 0-4.8 4.8c0 .187.014.36.027.533h-.027V118.4H9.6V26.667h50.133c2.654 0 4.8-2.147 4.8-4.8 0-2.654-2.146-4.8-4.8-4.8H9.6a9.594 9.594 0 0 0-9.6 9.6V118.4c0 5.307 4.293 9.6 9.6 9.6h91.733c5.307 0 9.6-4.293 9.6-9.6V72.533h-.026c.013-.173.026-.346.026-.533 0-2.653-2.146-4.8-4.8-4.8z"/><path d="M125.16 13.373L114.587 2.8c-3.747-3.747-9.854-3.72-13.6.027l-52.96 52.96a4.264 4.264 0 0 0-.907 1.36L33.813 88.533c-.746 1.76-.226 3.534.907 4.68 1.133 1.147 2.92 1.667 4.693.92l31.4-13.293c.507-.213.96-.52 1.36-.907l52.96-52.96c3.747-3.746 3.774-9.853.027-13.6zM66.107 72.4l-18.32 7.76 7.76-18.32L92.72 24.667l10.56 10.56L66.107 72.4zm52.226-52.227l-8.266 8.267-10.56-10.56 8.266-8.267.027-.026 10.56 10.56-.027.026z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M88.883 119.565c-7.284 0-19.434 2.495-21.333 8.25v.127c-4.232.13-5.222 0-7.108 0-1.895-5.76-14.045-8.256-21.333-8.256H0V0h42.523c9.179 0 17.109 5.47 21.47 13.551C68.352 5.475 76.295 0 85.478 0H128v119.57l-39.113-.005h-.004zM60.442 24.763c0-9.651-8.978-16.507-17.777-16.507H7.108V111.43H39.11c7.054-.14 18.177.082 21.333 6.12v-4.628c-.134-5.722-.004-13.522 0-13.832V27.413l.004-2.655-.004.005zm60.442-16.517h-35.55c-8.802 0-17.78 6.856-17.78 16.493v74.259c.004.32.138 8.115 0 13.813v4.627c3.155-6.022 14.279-6.26 21.333-6.114h32V8.25l-.003-.005z"/></svg> |
New file |
| | |
| | | <svg width="128" height="96" xmlns="http://www.w3.org/2000/svg"><path d="M64.125 56.975L120.188.912A12.476 12.476 0 0 0 115.5 0h-103c-1.588 0-3.113.3-4.513.838l56.138 56.137z"/><path d="M64.125 68.287l-62.3-62.3A12.42 12.42 0 0 0 0 12.5v71C0 90.4 5.6 96 12.5 96h103c6.9 0 12.5-5.6 12.5-12.5v-71a12.47 12.47 0 0 0-1.737-6.35L64.125 68.287z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1746590936918" class="icon" viewBox="0 0 1194 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5378" xmlns:xlink="http://www.w3.org/1999/xlink" width="233.203125" height="200"><path d="M1151.9144 325.11999969V89.12a57.04000031 57.04000031 0 0 0-28.8-49.44 58.15999969 58.15999969 0 0 0-57.76000031 0 57.04000031 57.04000031 0 0 0-28.8 49.44v235.99999969c0.24 84.31999969-33.6 152.56000031-94.08 212.00000062-60.07999969 59.83999969-141.84 80.64-227.04 80.4H225.91440031L388.07439969 457.11999969a56.80000031 56.80000031 0 0 0 12.40000031-62.16 57.76000031 57.76000031 0 0 0-94.00000031-18.63999938L48.8744 631.20000031a56.88 56.88 0 0 0 0 80.79999938l264.96 262.56a58.08 58.08 0 0 0 96.55999969-25.59999938 56.80000031 56.80000031 0 0 0-14.95999969-55.2L232.07439969 731.67999969h483.44000062c116.56000031 0 226.15999969-32.08000031 308.64-113.76 82.15999969-80.80000031 128.23999969-178.15999969 127.83999938-292.87999969" p-id="5379"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M96.258 57.462h31.421C124.794 27.323 100.426 2.956 70.287.07v31.422a32.856 32.856 0 0 1 25.971 25.97zm-38.796-25.97V.07C27.323 2.956 2.956 27.323.07 57.462h31.422a32.856 32.856 0 0 1 25.97-25.97zm12.825 64.766v31.421c30.46-2.885 54.507-27.253 57.713-57.712H96.579c-2.886 13.466-13.146 23.726-26.292 26.291zM31.492 70.287H.07c2.886 30.46 27.253 54.507 57.713 57.713V96.579c-13.466-2.886-23.726-13.146-26.291-26.292z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.208 16.576v8.384h38.72v5.376h-38.72v8.704h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.576h38.72v5.376h-38.72v8.512h38.72v5.376h-38.72v11.136H128v-94.72H78.208zM0 114.368L72.128 128V0L0 13.632v100.736z"/><path d="M28.672 82.56h-11.2l14.784-23.488-14.08-22.592h11.52l8.192 14.976 8.448-14.976h11.136l-14.08 22.208L58.368 82.56H46.656l-8.768-15.68z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M49.217 41.329l-.136-35.24c-.06-2.715-2.302-4.345-5.022-4.405h-3.65c-2.712-.06-4.866 2.303-4.806 5.016l.152 19.164-24.151-23.79a6.698 6.698 0 0 0-9.499 0 6.76 6.76 0 0 0 0 9.526l23.93 23.713-18.345.074c-2.712-.069-5.228 1.813-5.64 5.02v3.462c.069 2.721 2.31 4.97 5.022 5.03l35.028-.207c.052.005.087.025.133.025l2.457.054a4.626 4.626 0 0 0 3.436-1.38c.88-.874 1.205-2.096 1.169-3.462l-.262-2.465c0-.048.182-.081.182-.136h.002zm52.523 51.212l18.32-.073c2.713.06 5.224-1.609 5.64-4.815v-3.462c-.068-2.722-2.317-4.97-5.021-5.04l-34.58.21c-.053 0-.086-.021-.138-.021l-2.451-.06a4.64 4.64 0 0 0-3.445 1.381c-.885.868-1.201 2.094-1.174 3.46l.27 2.46c.005.06-.177.095-.177.141l.141 34.697c.069 2.713 2.31 4.338 5.022 4.397l3.45.006c2.705.062 4.867-2.31 4.8-5.026l-.153-18.752 24.151 23.946a6.69 6.69 0 0 0 9.494 0 6.747 6.747 0 0 0 0-9.523L101.74 92.54v.001zM48.125 80.662a4.636 4.636 0 0 0-3.437-1.382l-2.457.06c-.05 0-.082.022-.137.022l-35.025-.21c-2.712.07-4.957 2.318-5.022 5.04v3.462c.409 3.206 2.925 4.874 5.633 4.814l18.554.06-24.132 23.928c-2.62 2.626-2.62 6.89 0 9.524a6.694 6.694 0 0 0 9.496 0l24.155-23.79-.155 18.866c-.06 2.722 2.094 5.093 4.801 5.025h3.65c2.72-.069 4.962-1.685 5.022-4.406l.141-34.956c0-.05-.182-.082-.182-.136l.262-2.46c.03-1.366-.286-2.592-1.166-3.46h-.001zM80.08 47.397a4.62 4.62 0 0 0 3.443 1.374l2.45-.054c.055 0 .088-.02.143-.028l35.08.21c2.712-.062 4.953-2.312 5.021-5.033l.009-3.463c-.417-3.211-2.937-5.084-5.64-5.025l-18.615-.073 23.917-23.715c2.63-2.623 2.63-6.879.008-9.513a6.691 6.691 0 0 0-9.494 0L92.251 26.016l.155-19.312c.065-2.713-2.097-5.085-4.802-5.025h-3.45c-2.713.069-4.954 1.693-5.022 4.406l-.139 35.247c0 .054.18.088.18.136l-.267 2.465c-.028 1.366.288 2.588 1.174 3.463v.001z"/></svg> |
New file |
| | |
| | | <svg class="icon" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><defs><style/></defs><path d="M512 128q69.675 0 135.51 21.163t115.498 54.997 93.483 74.837 73.685 82.006 51.67 74.837 32.17 54.827L1024 512q-2.347 4.992-6.315 13.483T998.87 560.17t-31.658 51.669-44.331 59.99-56.832 64.34-69.504 60.16-82.347 51.5-94.848 34.687T512 896q-69.675 0-135.51-21.163t-115.498-54.826-93.483-74.326-73.685-81.493-51.67-74.496-32.17-54.997L0 513.707q2.347-4.992 6.315-13.483t18.816-34.816 31.658-51.84 44.331-60.33 56.832-64.683 69.504-60.331 82.347-51.84 94.848-34.816T512 128.085zm0 85.333q-46.677 0-91.648 12.331t-81.152 31.83-70.656 47.146-59.648 54.485-48.853 57.686-37.675 52.821-26.325 43.99q12.33 21.674 26.325 43.52t37.675 52.351 48.853 57.003 59.648 53.845T339.2 767.02t81.152 31.488T512 810.667t91.648-12.331 81.152-31.659 70.656-46.848 59.648-54.186 48.853-57.344 37.675-52.651T927.957 512q-12.33-21.675-26.325-43.648t-37.675-52.65-48.853-57.345-59.648-54.186-70.656-46.848-81.152-31.659T512 213.334zm0 128q70.656 0 120.661 50.006T682.667 512 632.66 632.661 512 682.667 391.339 632.66 341.333 512t50.006-120.661T512 341.333zm0 85.334q-35.328 0-60.33 25.002T426.666 512t25.002 60.33T512 597.334t60.33-25.002T597.334 512t-25.002-60.33T512 426.666z"/></svg> |
New file |
| | |
| | | <svg width="128" height="64" xmlns="http://www.w3.org/2000/svg"><path d="M127.072 7.994c1.37-2.208.914-5.152-.914-6.87-2.056-1.717-4.797-1.226-6.396.982-.229.245-25.586 32.382-55.74 32.382-29.24 0-55.74-32.382-55.968-32.627-1.6-1.963-4.57-2.208-6.397-.49C-.17 3.086-.399 6.275 1.2 8.238c.457.736 5.94 7.36 14.62 14.72L4.17 35.96c-1.828 1.963-1.6 5.152.228 6.87.457.98 1.6 1.471 2.742 1.471s2.284-.49 3.198-1.472l12.564-13.983c5.94 4.416 13.021 8.587 20.788 11.53l-4.797 17.418c-.685 2.699.686 5.397 3.198 6.133h1.37c2.057 0 3.884-1.472 4.341-3.68L52.6 42.83c3.655.736 7.538 1.227 11.422 1.227 3.883 0 7.767-.49 11.422-1.227l4.797 17.173c.457 2.208 2.513 3.68 4.34 3.68.457 0 .914 0 1.143-.246 2.513-.736 3.883-3.434 3.198-6.133l-4.797-17.172c7.767-2.944 14.848-7.114 20.788-11.53l12.336 13.738c.913.981 2.056 1.472 3.198 1.472s2.284-.49 3.198-1.472c1.828-1.963 1.828-4.906.228-6.87l-11.65-13.001c9.366-7.36 14.849-14.474 14.849-14.474z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.068 23.784c-1.02 0-1.877-.32-2.572-.96a8.588 8.588 0 0 1-1.738-2.237 11.524 11.524 0 0 1-1.042-2.621c-.232-.895-.348-1.641-.348-2.238V0h.278c.834 0 1.622.085 2.363.256.742.17 1.645.575 2.711 1.214 1.066.64 2.363 1.535 3.892 2.686 1.53 1.15 3.453 2.664 5.77 4.54 2.502 2.045 4.494 3.771 5.977 5.178 1.483 1.406 2.618 2.6 3.406 3.58.787.98 1.274 1.812 1.46 2.494.185.682.277 1.278.277 1.79v2.046H84.068zM127.3 84.01c.278.682.464 1.535.556 2.558.093 1.023-.37 2.003-1.39 2.94-.463.427-.88.832-1.25 1.215-.372.384-.696.704-.974.96a6.69 6.69 0 0 1-.973.767l-11.816-10.741a44.331 44.331 0 0 0 1.877-1.535 31.028 31.028 0 0 1 1.737-1.406c1.112-.938 2.317-1.343 3.615-1.215 1.297.128 2.363.405 3.197.83.927.427 1.923 1.173 2.989 2.239 1.065 1.065 1.876 2.195 2.432 3.388zM78.23 95.902c2.038 0 3.752-.511 5.143-1.534l-26.969 25.83H18.037c-1.761 0-3.684-.47-5.77-1.407a24.549 24.549 0 0 1-5.838-3.709 21.373 21.373 0 0 1-4.518-5.306c-1.204-2.003-1.807-4.07-1.807-6.202V16.495c0-1.79.44-3.665 1.32-5.626A18.41 18.41 0 0 1 5.04 5.562a21.798 21.798 0 0 1 5.213-3.964C12.198.533 14.237 0 16.37 0h53.24v15.984c0 1.62.278 3.367.834 5.242a16.704 16.704 0 0 0 2.572 5.179c1.159 1.577 2.665 2.898 4.518 3.964 1.853 1.066 4.078 1.598 6.673 1.598h20.295v42.325L85.458 92.45c1.02-1.364 1.529-2.856 1.529-4.476 0-2.216-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1c-2.409 0-4.448.789-6.116 2.366-1.668 1.577-2.502 3.474-2.502 5.69 0 2.217.834 4.092 2.502 5.626 1.668 1.535 3.707 2.302 6.117 2.302h52.13zM26.1 47.951c-2.41 0-4.449.789-6.117 2.366-1.668 1.577-2.502 3.473-2.502 5.69 0 2.216.834 4.092 2.502 5.626 1.668 1.534 3.707 2.302 6.117 2.302h52.13c2.409 0 4.47-.768 6.185-2.302 1.715-1.534 2.572-3.41 2.572-5.626 0-2.217-.857-4.113-2.572-5.69-1.714-1.577-3.776-2.366-6.186-2.366H26.1zm52.407 64.063l1.807-1.663 3.476-3.196a479.75 479.75 0 0 0 4.587-4.284 500.757 500.757 0 0 1 5.004-4.667c3.985-3.666 8.48-7.758 13.485-12.276l11.677 10.741-13.485 12.404-5.004 4.603-4.587 4.22a179.46 179.46 0 0 0-3.267 3.068c-.88.853-1.367 1.322-1.46 1.407-.463.341-.973.703-1.529 1.087-.556.383-1.112.703-1.668.959-.556.256-1.413.575-2.572.959a83.5 83.5 0 0 1-3.545 1.087 72.2 72.2 0 0 1-3.475.895c-1.112.256-1.946.426-2.502.511-1.112.17-1.854.043-2.224-.383-.371-.426-.464-1.151-.278-2.174.092-.511.278-1.279.556-2.302.278-1.023.602-2.067.973-3.132l1.042-3.005c.325-.938.58-1.577.765-1.918a10.157 10.157 0 0 1 2.224-2.941z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M38.47 52L52 38.462l-23.648-23.67L43.209 0H.035L0 43.137l14.757-14.865L38.47 52zm74.773 47.726L89.526 76 76 89.536l23.648 23.672L84.795 128h43.174L128 84.863l-14.757 14.863zM89.538 52l23.668-23.648L128 43.207V.038L84.866 0 99.73 14.76 76 38.472 89.538 52zM38.46 76L14.792 99.651 0 84.794v43.173l43.137.033-14.865-14.757L52 89.53 38.46 76z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1581238998885" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4187" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M511.542857 14.057143C228.914286 13.942857 0 242.742857 0 525.142857 0 748.457143 143.2 938.285714 342.628571 1008c26.857143 6.742857 22.742857-12.342857 22.742858-25.371429v-88.571428c-155.085714 18.171429-161.371429-84.457143-171.771429-101.6C172.571429 756.571429 122.857143 747.428571 137.714286 730.285714c35.314286-18.171429 71.314286 4.571429 113.028571 66.171429 30.171429 44.685714 89.028571 37.142857 118.857143 29.714286 6.514286-26.857143 20.457143-50.857143 39.657143-69.485715-160.685714-28.8-227.657143-126.857143-227.657143-243.428571 0-56.571429 18.628571-108.571429 55.2-150.514286-23.314286-69.142857 2.171429-128.342857 5.6-137.142857 66.4-5.942857 135.428571 47.542857 140.8 51.771429 37.714286-10.171429 80.8-15.542857 129.028571-15.542858 48.457143 0 91.657143 5.6 129.714286 15.885715 12.914286-9.828571 76.914286-55.771429 138.628572-50.171429 3.314286 8.8 28.228571 66.628571 6.285714 134.857143 37.028571 42.057143 55.885714 94.514286 55.885714 151.2 0 116.8-67.428571 214.971429-228.571428 243.314286a145.714286 145.714286 0 0 1 43.542857 104v128.571428c0.914286 10.285714 0 20.457143 17.142857 20.457143 202.4-68.228571 348.114286-259.428571 348.114286-484.685714 0-282.514286-229.028571-511.2-511.428572-511.2z" p-id="4188"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M1.482 70.131l36.204 16.18 69.932-65.485-61.38 70.594 46.435 18.735c1.119.425 2.397-.17 2.797-1.363v-.085L127.998.047 1.322 65.874c-1.12.597-1.519 1.959-1.04 3.151.32.511.72.937 1.2 1.107zm44.676 57.821L64.22 107.26l-18.062-7.834v28.527z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.147.062a13 13 0 0 1 4.94.945c1.55.63 2.907 1.526 4.069 2.688a13.148 13.148 0 0 1 2.761 4.069c.678 1.55 1.017 3.245 1.017 5.086v102.3c0 3.681-1.187 6.733-3.56 9.155-2.373 2.422-5.352 3.633-8.937 3.633H12.992c-3.875 0-7-1.26-9.373-3.779-2.373-2.518-3.56-5.667-3.56-9.445V12.704c0-3.39 1.163-6.345 3.488-8.863C5.872 1.32 8.972.062 12.847.062h102.3zM81.434 109.047c1.744 0 3.003-.412 3.778-1.235.775-.824 1.163-1.914 1.163-3.27 0-1.26-.388-2.325-1.163-3.197-.775-.872-2.034-1.307-3.778-1.307H72.57c.097-.194.145-.485.145-.872V27.09h9.01c1.743 0 2.954-.436 3.633-1.308.678-.872 1.017-1.938 1.017-3.197 0-1.26-.34-2.325-1.017-3.197-.679-.872-1.89-1.308-3.633-1.308H46.268c-1.743 0-2.954.436-3.632 1.308-.678.872-1.018 1.938-1.018 3.197 0 1.26.34 2.325 1.018 3.197.678.872 1.889 1.308 3.632 1.308h8.138v72.075c0 .193.024.339.073.436.048.096.072.242.072.436H46.56c-1.744 0-3.003.435-3.778 1.307-.775.872-1.163 1.938-1.163 3.197 0 1.356.388 2.446 1.163 3.27.775.823 2.034 1.235 3.778 1.235h34.875z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575802859706" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3102" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M896 224H128c-35.2 0-64 28.8-64 64v448c0 35.2 28.8 64 64 64h768c35.2 0 64-28.8 64-64V288c0-35.2-28.8-64-64-64z m0 480c0 19.2-12.8 32-32 32H160c-19.2 0-32-12.8-32-32V320c0-19.2 12.8-32 32-32h704c19.2 0 32 12.8 32 32v384z" p-id="3103"></path><path d="M224 352c-19.2 0-32 12.8-32 32v256c0 16 12.8 32 32 32s32-12.8 32-32V384c0-16-12.8-32-32-32z" p-id="3104"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M83.287 103.01c-1.57-3.84-6.778-10.414-15.447-19.548-2.327-2.444-2.182-4.306-1.338-9.862v-.64c.553-3.81 1.513-6.05 14.313-8.087 6.516-1.018 8.203 1.57 10.589 5.178l.785 1.193a12.625 12.625 0 0 0 6.43 5.207c1.134.524 2.53 1.164 4.421 2.24 4.596 2.53 4.596 5.41 4.596 11.753v.727a26.91 26.91 0 0 1-5.178 17.454 59.055 59.055 0 0 1-19.025 11.026c3.49-6.546.814-14.313 0-16.553l-.146-.087zM64 5.12a58.502 58.502 0 0 1 25.484 5.818 54.313 54.313 0 0 0-12.859 10.327c-.93 1.28-1.716 2.473-2.472 3.579-2.444 3.694-3.637 5.352-5.818 5.614a25.105 25.105 0 0 1-4.219 0c-4.276-.29-10.094-.64-11.956 4.422-1.193 3.23-1.396 11.956 2.444 16.495.66 1.077.778 2.4.32 3.578a7.01 7.01 0 0 1-2.066 3.229 18.938 18.938 0 0 1-2.909-2.91 18.91 18.91 0 0 0-8.32-6.603c-1.25-.349-2.647-.64-3.985-.93-3.782-.786-8.03-1.688-9.019-3.812a14.895 14.895 0 0 1-.727-5.818 21.935 21.935 0 0 0-1.396-9.25 8.873 8.873 0 0 0-5.557-4.946A58.705 58.705 0 0 1 64 5.12zM0 64c0 35.346 28.654 64 64 64 35.346 0 64-28.654 64-64 0-35.346-28.654-64-64-64C28.654 0 0 28.654 0 64z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566036191400" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5472" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M934.912 1016.832H192c-14.336 0-25.6-11.264-25.6-25.6v-189.44c0-14.336 11.264-25.6 25.6-25.6s25.6 11.264 25.6 25.6v163.84h691.712V64H217.6v148.48c0 14.336-11.264 25.6-25.6 25.6s-25.6-11.264-25.6-25.6v-174.08c0-14.336 11.264-25.6 25.6-25.6h742.912c14.336 0 25.6 11.264 25.6 25.6v952.832c0 14.336-11.264 25.6-25.6 25.6z" p-id="5473"></path><path d="M232.96 371.2h-117.76c-14.336 0-25.6-11.264-25.6-25.6s11.264-25.6 25.6-25.6h117.76c14.336 0 25.6 11.264 25.6 25.6s-11.264 25.6-25.6 25.6zM232.96 540.16h-117.76c-14.336 0-25.6-11.264-25.6-25.6s11.264-25.6 25.6-25.6h117.76c14.336 0 25.6 11.264 25.6 25.6s-11.264 25.6-25.6 25.6zM232.96 698.88h-117.76c-14.336 0-25.6-11.264-25.6-25.6s11.264-25.6 25.6-25.6h117.76c14.336 0 25.6 11.264 25.6 25.6s-11.264 25.6-25.6 25.6zM574.464 762.88c-134.144 0-243.2-109.056-243.2-243.2S440.32 276.48 574.464 276.48s243.2 109.056 243.2 243.2-109.056 243.2-243.2 243.2z m0-435.2c-105.984 0-192 86.016-192 192S468.48 711.68 574.464 711.68s192-86.016 192-192S680.448 327.68 574.464 327.68z" p-id="5474"></path><path d="M663.04 545.28h-87.04c-14.336 0-25.6-11.264-25.6-25.6s11.264-25.6 25.6-25.6h87.04c14.336 0 25.6 11.264 25.6 25.6s-11.264 25.6-25.6 25.6z" p-id="5475"></path><path d="M576 545.28c-14.336 0-25.6-11.264-25.6-25.6v-87.04c0-14.336 11.264-25.6 25.6-25.6s25.6 11.264 25.6 25.6v87.04c0 14.336-11.264 25.6-25.6 25.6z" p-id="5476"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M84.742 36.8c2.398 7.2 5.595 12.8 11.19 18.4 4.795-4.8 7.992-11.2 10.39-18.4h-21.58zm-52.748 40h20.78l-10.39-28-10.39 28z"/><path d="M111.916 0H16.009C7.218 0 .025 7.2.025 16v96c0 8.8 7.193 16 15.984 16h95.907c8.791 0 15.984-7.2 15.984-16V16c0-8.8-6.394-16-15.984-16zM72.754 103.2c-1.598 1.6-3.197 1.6-4.795 1.6-.8 0-2.398 0-3.197-.8-.8-.8-1.599 0-1.599-.8s-.799-1.6-1.598-3.2c-.8-1.6-.8-2.4-1.599-4l-3.196-8.8H28.797L25.6 96c-1.598 3.2-2.398 5.6-3.197 7.2-.8 1.6-2.398 1.6-4.795 1.6-1.599 0-3.197-.8-4.796-1.6-1.598-1.6-2.397-2.4-2.397-4 0-.8 0-1.6.799-3.2.8-1.6.8-2.4 1.598-4l17.583-44.8c.8-1.6.8-3.2 1.599-4.8.799-1.6 1.598-3.2 2.397-4 .8-.8 1.599-2.4 3.197-3.2 1.599-.8 3.197-.8 4.796-.8 1.598 0 3.196 0 4.795.8 1.598.8 2.398 1.6 3.197 3.2.799.8 1.598 2.4 2.397 4 .8 1.6 1.599 3.2 2.398 5.6l17.583 44c1.598 3.2 2.398 5.6 2.398 7.2-.8.8-1.599 2.4-2.398 4zM116.711 72c-8.791-3.2-15.185-7.2-20.78-12-5.594 5.6-12.787 9.6-21.579 12l-2.397-4c8.791-2.4 15.984-5.6 21.579-11.2C87.939 51.2 83.144 44 81.545 36h-7.992v-3.2h21.58c-1.6-2.4-3.198-5.6-4.796-8l2.397-.8c1.599 2.4 3.997 5.6 5.595 8.8h19.98v4h-7.992c-2.397 8-6.393 15.2-11.189 20 5.595 4.8 11.988 8.8 20.78 11.2l-3.197 4z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M115.625 127.937H.063V12.375h57.781v12.374H12.438v90.813h90.813V70.156h12.374z"/><path d="M116.426 2.821l8.753 8.753-56.734 56.734-8.753-8.745z"/><path d="M127.893 37.982h-12.375V12.375H88.706V0h39.187z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M1.585 12.087c0 6.616 3.974 11.98 8.877 11.98 4.902 0 8.877-5.364 8.877-11.98 0-6.616-3.975-11.98-8.877-11.98-4.903 0-8.877 5.364-8.877 11.98zM125.86.107H35.613c-1.268 0-2.114 1.426-2.114 2.852v18.255c0 1.712 1.057 2.853 2.114 2.853h90.247c1.268 0 2.114-1.426 2.114-2.853V2.96c0-1.711-1.057-2.852-2.114-2.852zM.106 62.86c0 6.615 3.974 11.979 8.876 11.979 4.903 0 8.877-5.364 8.877-11.98 0-6.616-3.974-11.98-8.877-11.98-4.902 0-8.876 5.364-8.876 11.98zM124.17 50.88H33.921c-1.268 0-2.114 1.425-2.114 2.851v18.256c0 1.711 1.057 2.852 2.114 2.852h90.247c1.268 0 2.114-1.426 2.114-2.852V53.73c0-1.426-.846-2.852-2.114-2.852zM.106 115.913c0 6.616 3.974 11.98 8.876 11.98 4.903 0 8.877-5.364 8.877-11.98 0-6.616-3.974-11.98-8.877-11.98-4.902 0-8.876 5.364-8.876 11.98zm124.064-11.98H33.921c-1.268 0-2.114 1.426-2.114 2.853v18.255c0 1.711 1.057 2.852 2.114 2.852h90.247c1.268 0 2.114-1.426 2.114-2.852v-18.255c0-1.427-.846-2.853-2.114-2.853z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M119.88 49.674h-7.987V39.52C111.893 17.738 90.45.08 63.996.08 37.543.08 16.1 17.738 16.1 39.52v10.154H8.113c-4.408 0-7.987 2.94-7.987 6.577v65.13c0 3.637 3.57 6.577 7.987 6.577H119.88c4.407 0 7.987-2.94 7.987-6.577v-65.13c-.008-3.636-3.58-6.577-7.987-6.577zm-23.953 0H32.065V39.52c0-14.524 14.301-26.295 31.931-26.295 17.63 0 31.932 11.777 31.932 26.295v10.153z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566035943711" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4805" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M208.736 566.336H64.384v59.328h144.352v-59.328z m0-336.096H165.44V74.592c0-7.968 4.896-14.848 10.464-14.848h502.016V0.448H175.936c-38.72 1.248-69.248 34.368-68.192 74.144v155.648H64.384V289.6h144.352V230.24z m0 168.096H64.384v59.328h144.352v-59.328z m714.656 76.576h-57.76v474.496c0 7.936-4.896 14.848-10.464 14.848H175.936c-5.568 0-10.464-6.912-10.464-14.848v-155.68h43.296v-59.296H64.384v59.296h43.328v155.68c-1.024 39.776 29.472 72.896 68.192 74.144h679.232c38.72-1.184 69.248-34.368 68.256-74.144V474.912z m14.944-290.336l-83.072-85.312a71.264 71.264 0 0 0-52.544-21.728 71.52 71.52 0 0 0-51.616 23.872L386.528 507.264a30.496 30.496 0 0 0-6.176 10.72L308.16 740.512a30.016 30.016 0 0 0 6.976 30.24c7.712 7.968 19.2 10.752 29.568 7.2l216.544-74.112a28.736 28.736 0 0 0 12.128-7.936L940.448 287.456a75.552 75.552 0 0 0-2.112-102.88z m-557.12 518.272l39.104-120.64 78.336 80.416-117.44 40.224z m170.048-70.016l-103.552-106.016 200.16-222.4 103.52 106.304-200.128 222.112zM897.952 247.072l-0.256 0.224-107.136 119.168-103.52-106.528 106.432-118.624a14.144 14.144 0 0 1 10.304-4.736 13.44 13.44 0 0 1 10.464 4.288l83.264 85.696c5.472 5.6 5.664 14.72 0.448 20.512z" p-id="4806"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566036016814" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5261" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M896 128h-85.333333a42.666667 42.666667 0 0 0 0 85.333333h42.666666v640H170.666667V213.333333h42.666666a42.666667 42.666667 0 0 0 0-85.333333H128a42.666667 42.666667 0 0 0-42.666667 42.666667v725.333333a42.666667 42.666667 0 0 0 42.666667 42.666667h768a42.666667 42.666667 0 0 0 42.666667-42.666667V170.666667a42.666667 42.666667 0 0 0-42.666667-42.666667z" p-id="5262"></path><path d="M341.333333 298.666667a42.666667 42.666667 0 0 0 42.666667-42.666667V128a42.666667 42.666667 0 0 0-85.333333 0v128a42.666667 42.666667 0 0 0 42.666666 42.666667zM512 298.666667a42.666667 42.666667 0 0 0 42.666667-42.666667V128a42.666667 42.666667 0 0 0-85.333334 0v128a42.666667 42.666667 0 0 0 42.666667 42.666667zM682.666667 298.666667a42.666667 42.666667 0 0 0 42.666666-42.666667V128a42.666667 42.666667 0 0 0-85.333333 0v128a42.666667 42.666667 0 0 0 42.666667 42.666667zM341.333333 768a42.666667 42.666667 0 0 0 42.666667-42.666667 128 128 0 0 1 256 0 42.666667 42.666667 0 0 0 85.333333 0 213.333333 213.333333 0 0 0-107.52-184.32A128 128 0 0 0 640 469.333333a128 128 0 0 0-256 0 128 128 0 0 0 22.186667 71.68A213.333333 213.333333 0 0 0 298.666667 725.333333a42.666667 42.666667 0 0 0 42.666666 42.666667z m128-298.666667a42.666667 42.666667 0 1 1 42.666667 42.666667 42.666667 42.666667 0 0 1-42.666667-42.666667z" p-id="5263"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 20.967v59.59c0 11.59 8.537 20.966 19.075 20.966h28.613l1 26.477L76.8 101.523h32.125c10.538 0 19.075-9.377 19.075-20.966v-59.59C128 9.377 119.463 0 108.925 0h-89.85C8.538 0 0 9.377 0 20.967zm82.325 33.1c0-5.524 4.013-9.935 9.037-9.935 5.026 0 9.038 4.41 9.038 9.934 0 5.524-4.025 9.934-9.038 9.934-5.024 0-9.037-4.41-9.037-9.934zm-27.613 0c0-5.524 4.013-9.935 9.038-9.935s9.037 4.41 9.037 9.934c0 5.524-4.025 9.934-9.037 9.934-5.025 0-9.038-4.41-9.038-9.934zm-27.1 0c0-5.524 4.013-9.935 9.038-9.935s9.038 4.41 9.038 9.934c0 5.524-4.026 9.934-9.05 9.934-5.013 0-9.025-4.41-9.025-9.934z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M54.122 127.892v-28.68H7.513V87.274h46.609v-12.4H7.513v-12.86h38.003L.099 0h22.6l32.556 45.07c3.617 5.144 6.44 9.611 8.487 13.385 1.788-3.05 4.89-7.779 9.301-14.186L103.93 0h24.01L82.385 62.013h38.34v12.862h-46.41v12.4h46.41v11.937h-46.41v28.68H54.123z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1543827393750" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4695" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: rbicon; src: url("chrome-extension://dipiagiiohfljcicegpgffpbnjmgjcnf/fonts/rbicon.woff2") format("woff2"); font-weight: normal; font-style: normal; } |
| | | </style></defs><path d="M64 64V640H896V64H64zM0 0h960v704H0V0z" p-id="4696"></path><path d="M192 896H768v64H192zM448 640H512v256h-64z" p-id="4697"></path><path d="M479.232 561.604267l309.9904-348.330667-47.803733-42.5472-259.566934 291.669333L303.957333 240.008533 163.208533 438.6048l52.224 37.009067 91.6224-129.28z" p-id="4698"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1746760911144" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12537" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M395.21211 182.914448c0 62.669318 49.541323 113.472378 110.642936 113.472378 61.093427 0 110.652146-50.80306 110.65214601-113.472378 0-62.685691-49.559742-113.487727-110.65214601-113.487727C444.75241 69.426721 395.21211 120.22978 395.21211 182.914448zM395.21211 523.34693101c0 62.668295 49.541323 113.487727 110.642936 113.48772699 61.093427 0 110.652146-50.820456 110.652146-113.487727 0-62.669318-49.559742-113.472378-110.652146-113.472378C444.75241 409.874553 395.21211 460.67761301 395.21211 523.34693101zM395.21211 841.084529c0 62.686714 49.541323 113.488751 110.642936 113.488751 61.093427 0 110.652146-50.80203599 110.65214601-113.488751 0-62.669318-49.559742-113.471354-110.65214601-113.471354C444.75241 727.614198 395.21211 778.416234 395.21211 841.084529z" p-id="12538"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.002 9.2c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-5.043-3.58-9.132-7.997-9.132S.002 4.157.002 9.2zM31.997.066h95.981V18.33H31.997V.066zm0 45.669c0 5.044 3.58 9.132 7.998 9.132 4.417 0 7.997-4.088 7.997-9.132 0-3.263-1.524-6.278-3.998-7.91-2.475-1.63-5.524-1.63-7.998 0-2.475 1.632-4 4.647-4 7.91zM63.992 36.6h63.986v18.265H63.992V36.6zm-31.995 82.2c0 5.043 3.58 9.132 7.998 9.132 4.417 0 7.997-4.089 7.997-9.132 0-5.044-3.58-9.133-7.997-9.133s-7.998 4.089-7.998 9.133zm31.995-9.131h63.986v18.265H63.992V109.67zm0-27.404c0 5.044 3.58 9.133 7.998 9.133 4.417 0 7.997-4.089 7.997-9.133 0-3.263-1.524-6.277-3.998-7.909-2.475-1.631-5.524-1.631-7.998 0-2.475 1.632-4 4.646-4 7.91zm31.995-9.13h31.991V91.4H95.987V73.135z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575802851180" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2867" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M279.272727 791.272727h512a46.545455 46.545455 0 0 1 0 93.090909H279.272727a46.545455 46.545455 0 0 1 0-93.090909z m33.838546-617.984V651.636364H193.722182V395.170909c0-37.003636-0.884364-59.298909-2.653091-66.746182a24.948364 24.948364 0 0 0-14.615273-16.989091c-8.005818-3.863273-25.786182-5.771636-53.341091-5.771636h-11.822545v-55.854545c57.716364-12.381091 101.562182-37.888 131.490909-76.520728h70.283636z m303.709091 396.8V651.636364H354.164364v-68.235637c77.777455-127.255273 124.043636-206.010182 138.705454-236.218182 14.661818-30.254545 22.016-53.853091 22.016-70.74909 0-13.032727-2.234182-22.714182-6.656-29.137455-4.421818-6.376727-11.170909-9.588364-20.247273-9.588364a22.248727 22.248727 0 0 0-20.200727 10.612364c-4.468364 7.121455-6.656 21.178182-6.656 42.263273v45.521454H354.164364v-17.454545c0-26.763636 1.396364-47.941818 4.142545-63.348364 2.746182-15.499636 9.541818-30.72 20.386909-45.661091 10.798545-14.987636 24.901818-26.298182 42.216727-33.978182 17.361455-7.68 38.167273-11.543273 62.37091-11.543272 47.476364 0 83.316364 11.776 107.706181 35.328 24.296727 23.552 36.445091 53.341091 36.445091 89.367272 0 27.368727-6.842182 56.32-20.48 86.853819-13.730909 30.533818-54.039273 95.325091-121.018182 194.420363h130.885819z m270.615272-189.393454c18.152727 6.097455 31.650909 16.104727 40.494546 29.975272 8.843636 13.917091 13.312 46.452364 13.312 97.652364 0 38.027636-4.328727 67.490909-13.032727 88.529455-8.657455 20.945455-23.598545 36.910545-44.869819 47.848727-21.271273 10.938182-48.593455 16.384-81.873454 16.384-37.794909 0-67.490909-6.330182-89.088-19.083636-21.550545-12.660364-35.746909-28.253091-42.542546-46.638546-6.795636-18.432-10.193455-50.362182-10.193454-95.883636v-37.841455h119.389091v77.730909c0 20.666182 1.210182 33.838545 3.723636 39.424 2.420364 5.585455 7.912727 8.424727 16.337455 8.424728 9.309091 0 15.36-3.537455 18.338909-10.612364 2.932364-7.121455 4.421818-25.6 4.421818-55.575273v-33.047273c0-18.338909-2.048-31.744-6.190546-40.215272a30.72 30.72 0 0 0-18.338909-16.709818c-8.052364-2.653091-23.738182-4.189091-46.964363-4.561455V357.050182c28.392727 0 45.893818-1.070545 52.596363-3.258182a22.946909 22.946909 0 0 0 14.475637-14.149818c2.932364-7.307636 4.421818-18.711273 4.421818-34.257455v-26.624c0-16.756364-1.722182-27.741091-5.12-33.047272-3.490909-5.352727-8.843636-8.005818-16.151273-8.005819-8.285091 0-13.963636 2.792727-16.989091 8.378182-3.025455 5.632-4.561455 17.640727-4.561454 35.933091v39.284364h-119.389091v-40.773818c0-45.661091 10.472727-76.567273 31.325091-92.625455 20.898909-16.058182 54.085818-24.064 99.607272-24.064 56.878545 0 95.511273 11.170909 115.805091 33.373091 20.293818 22.248727 30.394182 53.201455 30.394182 92.765091 0 26.810182-3.630545 46.173091-10.891636 58.088727-7.307636 11.915636-20.107636 22.807273-38.446546 32.628364z" p-id="2868"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1568899557259" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="535" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M356.246145 681.56286c-68.156286-41.949414-107.246583-103.84102-107.246583-169.805384 0-65.966411 39.090297-127.860063 107.246583-169.809477 12.046361-7.414877 15.800871-23.190165 8.385994-35.236526-7.413853-12.046361-23.191188-15.801894-35.236526-8.387018-39.640836 24.399713-72.539106 56.044434-95.137801 91.515297-23.86657 37.461193-36.481889 79.620385-36.481889 121.917724 0 42.297338 12.615319 84.454484 36.481889 121.914654 22.598694 35.469839 55.496965 67.11456 95.137801 91.51325 4.185322 2.576685 8.821923 3.804652 13.400195 3.804652 8.598842 0 16.998139-4.329609 21.836331-12.190647C372.047016 704.752002 368.291482 688.976714 356.246145 681.56286zM263.943926 754.580874c-92.603071-61.111846-145.713686-149.623739-145.713686-242.840794 0-93.195565 53.094242-181.682899 145.667637-242.774279 11.805884-7.79043 15.061021-23.677259 7.269567-35.483142-7.79043-11.805884-23.677259-15.062044-35.483142-7.269567C128.487861 296.954249 67.006602 401.024489 67.006602 511.74008c0 110.73708 61.496609 214.830857 168.721703 285.593504 4.343935 2.867304 9.240455 4.238534 14.08274 4.238534 8.317433 0 16.476253-4.046153 21.400403-11.507078C279.003923 778.258133 275.748786 762.372328 263.943926 754.580874zM788.660552 226.213092c-11.80486-7.791453-27.692712-4.536316-35.483142 7.269567-7.79043 11.805884-4.536316 27.692712 7.269567 35.483142 92.575442 61.092403 145.670707 149.579737 145.670707 242.774279 0 93.216032-53.111638 181.727924-145.715733 242.840794-11.805884 7.79043-15.059997 23.678282-7.269567 35.484166 4.925173 7.461949 13.081946 11.507078 21.400403 11.507078 4.841262 0 9.739828-1.37123 14.083763-4.238534 107.22714-70.761624 168.724773-174.857447 168.724773-285.593504C957.341323 401.025513 895.860063 296.955272 788.660552 226.213092zM790.090111 633.67213c23.865547-37.459147 36.480866-79.617315 36.480866-121.914654 0-42.298362-12.615319-84.45653-36.480866-121.917724-22.598694-35.470863-55.496965-67.115584-95.139847-91.515297-12.047384-7.413853-27.821649-3.659343-35.236526 8.387018-7.414877 12.045337-3.659343 27.821649 8.385994 35.236526 68.156286 41.949414 107.247606 103.842043 107.247606 169.809477 0 65.964364-39.090297 127.85597-107.247606 169.804361-12.045337 7.414877-15.800871 23.190165-8.385994 35.237549 4.838192 7.861038 13.236466 12.190647 21.835308 12.190647 4.579295 0 9.215896-1.227967 13.400195-3.804652C734.591099 700.786691 767.490394 669.142993 790.090111 633.67213zM567.129086 518.274914c24.12342-17.150612 39.887452-45.305859 39.887452-77.07133 0-52.128241-42.452881-94.538143-94.634334-94.538143-52.18043 0-94.633311 42.408879-94.633311 94.538143 0 31.695886 15.696494 59.797921 39.730886 76.958766-49.875944 21.128203-84.917018 70.234621-84.917018 127.301338 0 2.366907 0.061398 4.762467 0.182149 7.119141l1.249457 24.296359 276.373515 0 1.238201-24.308639c0.119727-2.358721 0.181125-4.750187 0.181125-7.106862C651.786185 588.497255 616.865861 539.465538 567.129086 518.274914zM512.381182 397.889079c23.937179 0 43.411719 19.430538 43.411719 43.314505 0 23.882943-19.47454 43.313481-43.411719 43.313481-23.936155 0-43.409672-19.430538-43.409672-43.313481C468.971509 417.320641 488.445026 397.889079 512.381182 397.889079zM426.08884 625.656573c9.119705-38.542828 44.254923-67.337641 86.085634-67.337641s76.966952 28.794813 86.085634 67.337641L426.08884 625.656573z" p-id="536"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575802846045" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2750" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M868.593046 403.832442c-30.081109-28.844955-70.037123-44.753273-112.624057-44.753273L265.949606 359.079168c-42.554188 0-82.510202 15.908318-112.469538 44.690852-30.236652 28.782533-46.857191 67.222007-46.857191 108.198258l0 294.079782c0 40.977273 16.619516 79.414701 46.702672 108.136859 29.959336 28.844955 70.069869 44.814672 112.624057 44.814672l490.019383 0c42.585911 0 82.696444-15.969717 112.624057-44.814672 30.082132-28.844955 46.579875-67.222007 46.579875-108.136859L915.172921 511.968278C915.171897 471.053426 898.675178 432.677397 868.593046 403.832442zM841.821309 806.049083c0 22.098297-8.882298 42.772152-25.099654 58.306964-16.154935 15.661701-37.81935 24.203238-60.752666 24.203238L265.949606 888.559285c-22.934339 0-44.567032-8.54256-60.877509-24.264637-16.186657-15.474436-25.067932-36.148291-25.067932-58.246589L180.004165 511.968278c0-22.035876 8.881274-42.772152 25.192775-58.307987 16.186657-15.536858 37.81935-24.139793 60.753689-24.139793l490.019383 0c22.933315 0 44.597731 8.602935 60.752666 24.139793 16.21838 15.535835 25.099654 36.272112 25.099654 58.307987L841.822332 806.049083zM510.974136 135.440715c114.914216 0 208.318536 89.75214 208.318536 200.055338l73.350588 0c0-149.113109-126.366036-270.496667-281.669124-270.496667-155.333788 0-281.699824 121.383558-281.699824 270.496667l73.350588 0C302.623877 225.193879 396.059919 135.440715 510.974136 135.440715zM474.299865 747.244792l73.350588 0L547.650453 629.576859l-73.350588 0L474.299865 747.244792z" p-id="2751"></path></svg> |
New file |
| | |
| | | <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="128" height="128"><path d="M869.073 277.307H657.111V65.344l211.962 211.963zm-238.232 26.27V65.344l-476.498-.054v416.957h714.73v-178.67H630.841zm-335.836 360.57c-5.07-3.064-10.944-5.133-17.61-6.201-6.67-1.064-13.603-1.6-20.81-1.6h-48.821v85.641h48.822c7.206 0 14.14-.532 20.81-1.6 6.665-1.065 12.54-3.133 17.609-6.202 5.064-3.063 9.134-7.406 12.208-13.007 3.065-5.602 4.6-12.937 4.6-22.011 0-9.07-1.535-16.408-4.6-22.01-3.074-5.603-7.144-9.94-12.208-13.01zM35.82 541.805v416.904h952.358V541.805H35.821zm331.421 191.179c-3.6 11.071-9.343 20.879-17.209 29.413-7.874 8.542-18.078 15.408-30.617 20.61-12.544 5.206-27.747 7.807-45.621 7.807h-66.036v102.45h-62.831V607.517h128.867c17.874 0 33.077 2.6 45.62 7.802 12.541 5.207 22.745 12.076 30.618 20.615 7.866 8.538 13.604 18.277 17.21 29.212 3.6 10.943 5.401 22.278 5.401 34.018 0 11.477-1.8 22.752-5.402 33.819zM644.9 806.417c-5.343 17.61-13.408 32.818-24.212 45.627-10.807 12.803-24.283 22.879-40.423 30.213-16.146 7.343-35.155 11.007-57.03 11.007h-123.26V607.518h123.26c18.41 0 35.552 2.941 51.428 8.808 15.873 5.869 29.618 14.671 41.22 26.412 11.608 11.744 20.674 26.411 27.217 44.02 6.535 17.61 9.803 38.288 9.803 62.035 0 20.81-2.67 40.02-8.003 57.624zm245.362-146.07h-138.07v66.03h119.66v48.829h-119.66v118.058h-62.83V607.518h200.9v52.829h-.001zm-318.2 25.611c-6.402-8.266-14.877-14.604-25.412-19.01-10.544-4.402-23.551-6.602-39.019-6.602h-44.825v180.088h56.029c9.07 0 17.872-1.463 26.415-4.401 8.535-2.932 16.14-7.802 22.812-14.609 6.665-6.8 12.007-15.667 16.007-26.61 4.003-10.94 6.003-24.275 6.003-40.021 0-14.408-1.4-27.416-4.202-39.019-2.8-11.607-7.406-21.542-13.808-29.816zm0 0"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M104.185 95.254c8.161 7.574 13.145 17.441 13.145 28.28 0 1.508-.098 2.998-.285 4.466h-10.784c.238-1.465.403-2.948.403-4.465 0-8.983-4.36-17.115-11.419-23.216C86 104.66 75.355 107.162 64 107.162c-11.344 0-21.98-2.495-31.22-6.83-7.064 6.099-11.444 14.218-11.444 23.203 0 1.517.165 3 .403 4.465H10.955a35.444 35.444 0 0 1-.285-4.465c0-10.838 4.974-20.713 13.127-28.291C9.294 85.42.003 70.417.003 53.58.003 23.99 28.656.001 64 .001s63.997 23.988 63.997 53.58c0 16.842-9.299 31.85-23.812 41.673zM64 36.867c-29.454 0-53.33-10.077-53.33 15.342 0 25.418 23.876 46.023 53.33 46.023 29.454 0 53.33-20.605 53.33-46.023 0-25.419-23.876-15.342-53.33-15.342zm24.888 25.644c-3.927 0-7.111-2.665-7.111-5.953 0-3.288 3.184-5.954 7.11-5.954 3.928 0 7.111 2.666 7.111 5.954s-3.183 5.953-7.11 5.953zm-3.556 16.372c0 4.11-9.55 7.442-21.332 7.442-11.781 0-21.332-3.332-21.332-7.442 0-1.06.656-2.064 1.8-2.976 3.295 2.626 10.79 4.465 19.532 4.465 8.743 0 16.237-1.84 19.531-4.465 1.145.912 1.801 1.916 1.801 2.976zm-46.22-16.372c-3.927 0-7.11-2.665-7.11-5.953 0-3.288 3.183-5.954 7.11-5.954 3.927 0 7.111 2.666 7.111 5.954s-3.184 5.953-7.11 5.953z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M95.648 118.762c0 5.035-3.563 9.121-7.979 9.121H7.98c-4.416 0-7.979-4.086-7.979-9.121C0 100.519 15.408 83.47 31.152 76.75c-9.099-6.43-15.216-17.863-15.216-30.987v-9.128c0-20.16 14.293-36.518 31.893-36.518s31.894 16.358 31.894 36.518v9.122c0 13.137-6.123 24.556-15.216 30.993 15.738 6.726 31.141 23.769 31.141 42.012z"/><path d="M106.032 118.252h15.867c3.376 0 6.101-3.125 6.101-6.972 0-13.957-11.787-26.984-23.819-32.123 6.955-4.919 11.638-13.66 11.638-23.704v-6.985c0-15.416-10.928-27.926-24.39-27.926-1.674 0-3.306.193-4.89.561 1.936 4.713 3.018 9.974 3.018 15.526v9.121c0 13.137-3.056 23.111-11.066 30.993 14.842 4.41 27.312 23.42 27.541 41.509z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1567417214476" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2266" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M761.503029 2.90619 242.121921 2.90619c-32.405037 0-58.932204 26.060539-58.932204 58.527998l0 902.302287c0 32.156374 26.217105 58.216913 58.932204 58.216913l519.381108 0c32.344662 0 58.591443-26.060539 58.591443-58.216913L820.094472 61.123103C820.094472 28.966729 793.847691 2.90619 761.503029 2.90619M452.878996 61.123103l98.147344 0c6.780427 0 12.31549 5.536087 12.31549 12.253068 0 6.748704-5.535063 12.253068-12.31549 12.253068l-98.147344 0c-6.779404 0-12.345166-5.504364-12.345166-12.253068C440.532807 66.659189 446.099592 61.123103 452.878996 61.123103M501.641583 980.593398c-29.636994 0-53.987588-23.946388-53.987588-53.677527 0-29.356608 24.039509-53.614082 53.987588-53.614082 29.91738 0 53.987588 23.883967 53.987588 53.614082C555.629171 956.647009 531.559986 980.593398 501.641583 980.593398M766.35657 803.142893c0 16.23373-13.186324 29.107945-29.233811 29.107945l-470.618521 0c-16.35755 0-29.325909-13.186324-29.325909-29.107945L237.178329 163.500794c0-16.232706 13.279445-29.138644 29.325909-29.138644l470.246037 0c16.420995 0 29.357632 13.1853 29.357632 29.138644l0 639.642099L766.35657 803.142893zM766.35657 803.142893" p-id="2267"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566035724641" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3998" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M136.4 434.3h77.7c21.5 0 38.9-17.4 38.9-38.9s-17.4-38.9-38.9-38.9h-77.7c-21.5 0-38.9 17.4-38.9 38.9s17.4 38.9 38.9 38.9zM252.9 628.6c0-21.5-17.4-38.9-38.9-38.9h-77.7c-21.5 0-38.9 17.4-38.9 38.9s17.4 38.9 38.9 38.9H214c21.5-0.1 38.9-17.5 38.9-38.9z" p-id="3999"></path><path d="M874.7 97.5H227c-28.6 0-51.8 23.2-51.8 51.8v194.3h38.9c28.6 0 51.8 23.2 51.8 51.8 0 28.6-23.2 51.8-51.8 51.8h-38.9v129.5h38.9c28.6 0 51.8 23.2 51.8 51.8 0 28.6-23.2 51.8-51.8 51.8h-38.9v194.3c0 28.6 23.2 51.8 51.8 51.8h647.7c28.6 0 51.8-23.2 51.8-51.8V149.3c0-28.6-23.2-51.8-51.8-51.8z m-311.3 723c-15.6 0-146.7-71.6-146.7-91 0-19.4 102-368.6 102-368.6l-83.6-104s-12.3-23.1 24.6-23.1h208.9c36.9 0 18.4 23.1 18.4 23.1l-79 104s102 351.3 102 368.6c0.1 17.3-131 91-146.6 91z m169.2-253.6l-27.9 40.2-74.5-240 103.4 171.7c4.6 7.9 4.2 20.6-1 28.1z" p-id="4000"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M18.448 57.545l-.244-.744-.198-.968-.132-.53v-2.181l.236-.859.24-.908.317-.953.428-1.06.561-1.103.794-1.104v-.773l.077-.724.123-.984.34-1.106.313-1.194.25-.548.289-.511.371-.569.405-.423v-2.73l.234-1.407.236-1.633.42-1.955.577-2.035.43-1.118.426-1.217.468-1.135.559-1.216.57-1.332.655-1.247.737-1.331.929-1.33.43-.762.457-.624.995-1.406 1.025-1.403 1.163-1.444 1.246-1.405 1.352-1.384 1.41-1.423 1.708-1.536 1.083-.934 1.322-1.008 1.34-.89 1.448-.855 1.392-.76 1.57-.63 1.667-.775 1.657-.532 1.653-.552 1.787-.548 1.785-.417 1.876-.347L59.128.68l1.879-.245 1.876-.252 2.002-.106h5.912l1.97.243 1.981.231 2.019.207 1.874.441 1.979.413 1.857.475 2.035.53 1.862.646 1.782.738 1.904.78 1.736.853 1.689.95 1.655 1.044 1.425.971.662.548.693.401 1.323 1.1 1.115 1.064 1.112 1.1 1.083 1.214.894 1.178 1.064 1.217.74 1.306.752 1.162.798 1.352.661 1.175 1.113 2.489.546 1.286.428 1.192.428 1.294.384 1.217.267 1.047.347 1.231.607 2.198.388 1.924.253 1.861.217 1.497.342 2.28.077.362.274.41.737 1.18.473.8.42.832.534.892.472 1.07.307 1.093.334 1.2.252 1.232.115.605.106.746v.648l-.106.643v.8l-.192.774-.35 1.5-.403.76-.299.852v.213l.142.264.4.623 1.746 2.53 1.377 1.9.66 1.267.889 1.389.774 1.52.893 1.627.894 1.828 1.006 2.069.567 1.268.518 1.239.447 1.307.44 1.175.336 1.235.342 1.16.432 2.261.343 2.31.235 2.05v2.891l-.158 1.025-.226 1.768-.308 1.59-.48 1.44-.18.588-.336.707-.28.493-.375.607-.33.383-.42.494-.375.4-.401.34-.48.207-.432.207-.355.114h-.543l-.346-.114-.66-.32-.302-.212-.317-.223-.347-.304-.35-.342-.579-.63-.684-.89-.539-.917-.538-.734-.526-.855-.741-1.517-.833-1.579-.098-.055h-.138l-.338.247-.196.415-.326.516-.567 1.533-.856 2.182-1.096 2.626-.824 1.308-.864 1.366-1.027 1.536-1.09 1.503-.557.68-.676.743-1.555 1.497.136.135.21.214.777.446 3.235 1.524 1.41.779 1.347.756 1.332.953 1.187.982.574.443.432.511.445.593.367.643.198.533.242.64.105.554.115.647-.115.433v.44l-.105.454-.242.415-.092.325-.22.394-.587.784-.543.627-.42.47-.35.348-.893.638-1.01.556-1.077.532-1.155.511-1.287.495-.693.207-.608.167-1.496.342-1.545.325-1.552.323-1.689.27-1.74.072-1.785.21h-5.539l-1.998-.114-1.86-.168-2.005-.27-1.99-.209-2.095-.286-2.03-.495-1.981-.374-1.968-.552-2.019-.707-1.98-.585-1.044-.342-.927-.323-.586-.223-.582-.12h-1.647l-1.904-.131-.962-.096-1.24-.135-.795.705-1.085.665-1.471.701-1.628.875-.99.475-1.033.376-2.281.914-1.24.305-1.3.343-1.803.344-1.13.086-1.193.1-1.246.135-1.45.053h-5.926l-3.346-.053-3.25-.321-1.644-.23-1.589-.23-1.546-.227-1.547-.305-1.442-.456-1.434-.325-1.294-.51-1.223-.474-1.142-.533-.99-.583-.984-.71-.336-.343-.44-.415-.334-.362-.3-.417-.278-.415-.215-.42-.311-.89-.109-.46-.138-.51v-.473l.138-.533v-.53l.109-.53v-1.069l.052-.564.259-.647.215-.646.39-.779.286-.3.236-.348.615-.738.49-.38.464-.266.428-.338.676-.21.543-.324.676-.341.77-.227.775-.231.897-.192.85-.11 1.008-.13 1.093-.081.284-.092h.063l.137-.115v-.13l-.2-.266-.58-.27-1.45-1.231-.975-.761-1.127-.967-1.136-1.082-1.181-1.382-1.36-1.558-.508-.843-.672-.87-.58-1.007-.522-1.1-.704-1.047-.459-1.194-.547-1.192-.546-1.33-.397-1.273-.378-1.575-.112-.057h-.115l-.059-.113h-.14l-.23.113-.114.057-.158.264-.057.321-.119.286-.206.477-.664 1.157-.345.701-.546.612-.58.736-.641.816-.677.724-.795.701-.734.658-.814.524-.89.546-.855.325-1.008.247-.99.095h-.233l-.228-.095-.18-.384-.29-.188-.38-.912-.237-.493-.255-.707-.21-.734-.113-.724-.313-1.648-.12-.972v-3.185l.12-2.379.196-1.214.23-1.252.21-1.347.374-1.254.42-1.443.431-1.407.578-1.448.545-1.38.754-1.4.699-1.52.855-1.425 1.006-1.538 1.023-1.382 1.069-1.538.891-1.071 1.142-1.227 1.202-1.237.56-.59.678-.662.985-.836 1.012-.853 1.647-1.446 1.242-.889z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1581238842264" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1409" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M512 0C229.233778 0 0 229.233778 0 512s229.233778 512 512 512 512-229.233778 512-512A512 512 0 0 0 512 0z m0 938.666667C276.366222 938.666667 85.333333 747.633778 85.333333 512 85.333333 276.366222 276.366222 85.333333 512 85.333333c235.633778 0 426.666667 191.032889 426.666667 426.666667a426.666667 426.666667 0 0 1-426.666667 426.666667z m0-717.653334a170.666667 170.666667 0 0 0-170.666667 170.666667 42.666667 42.666667 0 0 0 85.333334 0 85.333333 85.333333 0 1 1 85.333333 85.333333 42.666667 42.666667 0 0 0-42.666667 42.666667v111.36a42.666667 42.666667 0 0 0 85.333334 0v-74.24A170.666667 170.666667 0 0 0 512 221.013333z m-42.666667 542.293334a42.666667 42.666667 0 1 0 85.333334 0 42.666667 42.666667 0 0 0-85.333334 0z" p-id="1410"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575966775973" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="879" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M507.39346659 71.84873358c241.53533667 0 437.39770766 195.85422109 437.39770767 437.37442191 0 241.53766571-195.86237099 437.38955776-437.39770767 437.38955776-241.50040803 0-437.34997219-195.85189205-437.34997219-437.38955776C70.0434944 267.70295467 265.89189347 71.84873358 507.39346659 71.84873358L507.39346659 71.84873358zM507.39346659 282.81899805c-125.00686734 0-226.37039389 101.38914133-226.37039388 226.41813048 0 125.01268821 101.36352768 226.39717262 226.37039388 226.39717262 125.04295993 0 226.42395136-101.38448441 226.42395136-226.39717262C733.81625401 384.20813938 632.43642653 282.81899805 507.39346659 282.81899805L507.39346659 282.81899805zM507.39346659 120.78172615c-214.46664192 0-388.42047261 173.95150279-388.4204726 388.44026539 0 214.51204949 173.95499463 388.46122325 388.4204726 388.46122325 214.52369237 0 388.46005817-173.94800981 388.46005818-388.46122325C895.85236082 294.73322894 721.91715897 120.78172615 507.39346659 120.78172615z" p-id="880"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577246781606" class="icon" viewBox="0 0 1069 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1098" xmlns:xlink="http://www.w3.org/1999/xlink" width="84.5595703125" height="81"><defs><style type="text/css"></style></defs><path d="M633.72929961 378.02038203l9.49872568 18.68789795 20.78025469 2.79745225 206.61592412 27.33248408a11.46496817 11.46496817 0 0 1 6.6095543 19.47324902l-147.2675168 147.35350284-14.89299345 14.89299345 3.8006376 20.68280244 37.84585956 204.89044571a11.46496817 11.46496817 0 0 1-16.4808914 12.2961788L554.68980898 751.84713388l-18.68789794-9.49299345-18.48726123 9.99171915-183.23885392 99.34968163a11.46496817 11.46496817 0 0 1-16.78471347-11.8662416l32.5433127-205.79617881 3.29617793-20.78598692-15.19108243-14.49172002-151.03375839-143.48407587a11.46496817 11.46496817 0 0 1 6.09936328-19.63949062l205.79617881-32.63503185 20.78598691-3.2961788L428.87898125 380.72038203 518.59235674 192.64331182a11.46496817 11.46496817 0 0 1 20.56815264-0.26369385l94.56879023 185.63503183zM496.64840732 85.52038203l-121.75796162 254.98089229L95.76433145 384.76178369A34.3949045 34.3949045 0 0 0 77.46050938 443.66879023l204.87324901 194.66369385-44.16879023 279.1146498a34.3949045 34.3949045 0 0 0 50.36560489 35.61592325l248.4-134.67898038 251.84522285 128.27579591a34.3949045 34.3949045 0 0 0 49.43694287-36.89426777l-51.30573223-277.85350284 199.73120977-199.90891758a34.3949045 34.3949045 0 0 0-19.82866201-58.40827998l-280.11783428-37.03184736L558.32993633 84.71210205a34.3949045 34.3949045 0 0 0-61.68152901 0.80254775z" p-id="1099"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1656035183065" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3395" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); } |
| | | </style></defs><path d="M958.88 730.06H65.12c-18.28 0-33.12-14.82-33.12-33.12V68.91c0-18.29 14.83-33.12 33.12-33.12h893.77c18.28 0 33.12 14.82 33.12 33.12v628.03c-0.01 18.3-14.84 33.12-33.13 33.12zM98.23 663.83h827.53v-561.8H98.23v561.8z" p-id="3396"></path><path d="M512 954.55c-18.28 0-33.12-14.82-33.12-33.12V733.92c0-18.29 14.83-33.12 33.12-33.12s33.12 14.82 33.12 33.12v187.51c0 18.3-14.84 33.12-33.12 33.12z" p-id="3397"></path><path d="M762.01 988.21H261.99c-18.28 0-33.12-14.82-33.12-33.12 0-18.29 14.83-33.12 33.12-33.12h500.03c18.28 0 33.12 14.82 33.12 33.12-0.01 18.29-14.84 33.12-33.13 33.12zM514.74 578.55c-21.63 0-43.31-3.87-64.21-11.65-45.95-17.13-82.49-51.13-102.86-95.74-5.07-11.08-0.19-24.19 10.89-29.26 11.08-5.09 24.19-0.18 29.26 10.91 15.5 33.88 43.25 59.7 78.14 72.71 34.93 12.99 72.79 11.64 106.66-3.85 33.22-15.17 58.8-42.26 72.03-76.3 4.42-11.37 17.21-17.01 28.57-12.58 11.36 4.42 16.99 17.22 12.57 28.58-17.42 44.82-51.1 80.5-94.82 100.47-24.34 11.12-50.25 16.71-76.23 16.71z" p-id="3398"></path><path d="M325.27 528.78c-1.66 0-3.34-0.18-5.02-0.57-11.88-2.77-19.28-14.63-16.49-26.51l18.84-81c1.34-5.82 5-10.84 10.13-13.92 5.09-3.09 11.3-3.96 17.03-2.41l80.51 21.43c11.79 3.14 18.8 15.23 15.67 27.02-3.15 11.79-15.42 18.75-27.02 15.65l-58.49-15.57-13.69 58.81c-2.37 10.2-11.45 17.07-21.47 17.07zM360.8 351.01c-2.65 0-5.37-0.49-8-1.51-11.36-4.41-16.99-17.21-12.59-28.57 17.4-44.79 51.06-80.47 94.8-100.48 92.15-42.06 201.25-1.39 243.31 90.68 5.07 11.08 0.19 24.19-10.89 29.26-11.13 5.07-24.19 0.17-29.26-10.91-31.97-69.91-114.9-100.82-184.79-68.86-33.22 15.19-58.8 42.28-71.99 76.29-3.41 8.74-11.75 14.1-20.59 14.1z" p-id="3399"></path><path d="M684.68 376.74c-1.47 0-2.95-0.15-4.42-0.44l-81.61-16.68c-11.94-2.45-19.64-14.11-17.21-26.06 2.44-11.96 14.1-19.64 26.04-17.22l59.29 12.12 10.23-59.5c2.05-12 13.52-20.19 25.48-18.01 12.03 2.06 20.09 13.48 18.02 25.5l-14.08 81.96a22.089 22.089 0 0 1-9.29 14.49c-3.7 2.51-8.03 3.84-12.45 3.84z" p-id="3400"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1605865043777" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="856" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M1023.786667 611.84c-0.426667 9.770667-13.354667 20.693333-39.893334 34.56-54.613333 28.458667-337.749333 144.896-397.994666 176.298667-60.288 31.402667-93.738667 31.104-141.354667 8.32-47.616-22.741333-348.842667-144.469333-403.114667-170.368-27.093333-12.970667-40.917333-23.893333-41.386666-34.218667v103.509333c0 10.325333 14.250667 21.290667 41.386666 34.261334 54.272 25.941333 355.541333 147.626667 403.114667 170.368 47.616 22.784 81.066667 23.082667 141.354667-8.362667 60.245333-31.402667 343.338667-147.797333 397.994666-176.298667 27.776-14.464 40.106667-25.728 40.106667-35.925333v-102.058667l-0.213333-0.085333z m0-168.746667c-0.512 9.770667-13.397333 20.650667-39.893334 34.517334-54.613333 28.458667-337.749333 144.896-397.994666 176.298666-60.288 31.402667-93.738667 31.104-141.354667 8.362667-47.616-22.741333-348.842667-144.469333-403.114667-170.410667-27.093333-12.928-40.917333-23.893333-41.386666-34.176v103.509334c0 10.325333 14.250667 21.248 41.386666 34.218666 54.272 25.941333 355.498667 147.626667 403.114667 170.368 47.616 22.784 81.066667 23.082667 141.354667-8.32 60.245333-31.402667 343.338667-147.84 397.994666-176.298666 27.776-14.506667 40.106667-25.770667 40.106667-35.968v-102.058667l-0.256-0.042667z m0-175.018666c0.469333-10.410667-13.141333-19.541333-40.533334-29.610667-53.248-19.498667-334.634667-131.498667-388.522666-151.253333-53.888-19.712-75.818667-18.901333-139.093334 3.84C392.234667 113.706667 92.629333 231.253333 39.338667 252.074667c-26.666667 10.496-39.68 20.181333-39.253334 30.506666V386.133333c0 10.325333 14.250667 21.248 41.386667 34.218667 54.272 25.941333 355.498667 147.669333 403.114667 170.410667 47.616 22.741333 81.066667 23.04 141.354666-8.362667 60.245333-31.402667 343.338667-147.84 397.994667-176.298667 27.776-14.506667 40.106667-25.770667 40.106667-35.968V268.074667h-0.341334zM366.677333 366.08l237.269334-36.437333-71.68 105.088-165.546667-68.650667z m524.8-94.634667l-140.330666 55.466667-15.232 5.973333-140.245334-55.466666 155.392-61.44 140.373334 55.466666z m-411.989333-101.674666l-22.954667-42.325334 71.594667 27.989334 67.498667-22.101334-18.261334 43.733334 68.778667 25.770666-88.704 9.216-19.882667 47.786667-32.085333-53.290667-102.4-9.216 76.416-27.562666z m-176.768 59.733333c70.058667 0 126.805333 21.973333 126.805333 49.109333s-56.746667 49.152-126.805333 49.152-126.848-22.058667-126.848-49.152c0-27.136 56.789333-49.152 126.848-49.152z" p-id="857"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1579339929870" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1182" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M152 854.856875h325.7146875V237.715625H134.856875v600q0 6.99375 5.0746875 12.0684375T152 854.856875z m737.143125-17.1421875v-600H546.284375v617.1421875H872q6.99375 0 12.0684375-5.07375t5.0746875-12.0684375z m68.5715625-651.429375V837.715625q0 35.3821875-25.16625 60.5484375T872 923.4284375H152q-35.383125 0-60.5484375-25.1653125T66.284375 837.7146875V186.284375q0-35.3821875 25.16625-60.5484375T152 100.5715625h720q35.383125 0 60.5484375 25.1653125t25.16625 60.5484375z" p-id="1183"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M124.884 109.812L94.256 79.166c-.357-.357-.757-.629-1.129-.914a50.366 50.366 0 0 0 8.186-27.59C101.327 22.689 78.656 0 50.67 0 22.685 0 0 22.688 0 50.663c0 27.989 22.685 50.663 50.656 50.663 10.186 0 19.643-3.03 27.6-8.201.286.385.557.771.9 1.114l30.628 30.632a10.633 10.633 0 0 0 7.543 3.129c2.728 0 5.457-1.043 7.543-3.115 4.171-4.157 4.171-10.915.014-15.073M50.671 85.338C31.557 85.338 16 69.78 16 50.663c0-19.102 15.557-34.661 34.67-34.661 19.115 0 34.657 15.559 34.657 34.675 0 19.102-15.557 34.661-34.656 34.661"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575803481213" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="804" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M62 511.97954521C62 263.86590869 263.90681826 62 511.97954521 62s449.97954521 201.825 449.97954521 449.97954521c0 248.19545479-201.90681826 449.97954521-449.97954521 449.97954521C263.90681826 962 62 760.175 62 511.97954521M901.98636348 511.97954521c0-215.24318174-175.00909131-390.41590869-390.00681827-390.41590869-215.03863652 0-389.96590869 175.17272695-389.96590868 390.41590869 0 215.28409131 175.00909131 390.45681826 389.96590868 390.45681826C727.01818174 902.47727305 901.98636348 727.30454521 901.98636348 511.97954521M264.17272695 430.28409131c0-5.76818174 2.12727305-11.51590869 6.64772696-15.87272696 8.71363652-8.75454521 22.88863652-8.75454521 31.725 0l209.4340913 208.22727305L721.45454521 414.53409131c8.75454521-8.71363652 22.97045479-8.71363652 31.90909132 0 8.71363652 8.75454521 8.71363652 22.88863652 0 31.60227304L511.97954521 685.74090869 270.71818174 446.01363653C266.27954521 441.77954521 264.17272695 436.05227305 264.17272695 430.28409131" p-id="805"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1547360688278" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M890 120H134a70 70 0 0 0-70 70v500a70 70 0 0 0 70 70h756a70 70 0 0 0 70-70V190a70 70 0 0 0-70-70z m-10 520a40 40 0 0 1-40 40H712V448a40 40 0 0 0-80 0v232h-80V368a40 40 0 0 0-80 0v312h-80V512a40 40 0 0 0-80 0v168H184a40 40 0 0 1-40-40V240a40 40 0 0 1 40-40h656a40 40 0 0 1 40 40zM696 824H328a40 40 0 0 0 0 80h368a40 40 0 0 0 0-80z" p-id="6718"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M42.913 101.36c1.642 0 3.198.332 4.667.996a12.28 12.28 0 0 1 3.89 2.772c1.123 1.184 1.987 2.582 2.592 4.193.605 1.612.908 3.318.908 5.118 0 1.8-.303 3.507-.908 5.118-.605 1.611-1.469 3.01-2.593 4.194a13.3 13.3 0 0 1-3.889 2.843 10.582 10.582 0 0 1-4.667 1.066c-1.729 0-3.306-.355-4.732-1.066a13.604 13.604 0 0 1-3.825-2.843c-1.123-1.185-1.988-2.583-2.593-4.194a14.437 14.437 0 0 1-.907-5.118c0-1.8.302-3.506.907-5.118.605-1.61 1.47-3.009 2.593-4.193a12.515 12.515 0 0 1 3.825-2.772c1.426-.664 3.003-.996 4.732-.996zm53.932.285c1.643 0 3.22.331 4.733.995a11.386 11.386 0 0 1 3.889 2.772c1.08 1.185 1.945 2.583 2.593 4.194.648 1.61.972 3.317.972 5.118 0 1.8-.324 3.506-.972 5.117-.648 1.611-1.513 3.01-2.593 4.194a12.253 12.253 0 0 1-3.89 2.843 11 11 0 0 1-4.732 1.066 10.58 10.58 0 0 1-4.667-1.066 12.478 12.478 0 0 1-3.824-2.843c-1.08-1.185-1.945-2.583-2.593-4.194a13.581 13.581 0 0 1-.973-5.117c0-1.801.325-3.507.973-5.118.648-1.611 1.512-3.01 2.593-4.194a11.559 11.559 0 0 1 3.824-2.772 11.212 11.212 0 0 1 4.667-.995zm21.781-80.747c2.42 0 4.3.355 5.64 1.066 1.34.71 2.29 1.587 2.852 2.63a6.427 6.427 0 0 1 .778 3.34c-.044 1.185-.195 2.204-.454 3.057-.26.853-.8 2.606-1.62 5.26a589.268 589.268 0 0 1-2.788 8.743 1236.373 1236.373 0 0 0-3.047 9.453c-.994 3.128-1.75 5.592-2.269 7.393-1.123 3.79-2.55 6.42-4.278 7.89-1.728 1.469-3.846 2.203-6.352 2.203H39.023l1.945 12.795h65.342c4.148 0 6.223 1.943 6.223 5.828 0 1.896-.41 3.53-1.232 4.905-.821 1.374-2.442 2.061-4.862 2.061H38.505c-1.729 0-3.176-.426-4.343-1.28-1.167-.852-2.14-1.966-2.917-3.34a21.277 21.277 0 0 1-1.88-4.478 44.128 44.128 0 0 1-1.102-4.55c-.087-.568-.324-1.942-.713-4.122-.39-2.18-.865-4.904-1.426-8.174l-1.88-10.947c-.692-4.027-1.383-8.079-2.075-12.154-1.642-9.572-3.5-20.234-5.574-31.986H6.87c-1.296 0-2.377-.356-3.24-1.067a9.024 9.024 0 0 1-2.14-2.558 10.416 10.416 0 0 1-1.167-3.2C.108 8.53 0 7.488 0 6.54c0-1.896.583-3.46 1.75-4.69C2.917.615 4.494 0 6.482 0h13.095c1.728 0 3.111.284 4.148.853 1.037.569 1.858 1.28 2.463 2.132a8.548 8.548 0 0 1 1.297 2.701c.26.948.475 1.754.648 2.417.173.758.346 1.825.519 3.199.173 1.374.345 2.772.518 4.193.26 1.706.519 3.507.778 5.403h88.678z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M0 54.857h54.796v18.286H36.531V128H18.265V73.143H0V54.857zm127.857-36.571H91.935V128H72.456V18.286H36.534V0h91.326l-.003 18.286z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M31.652 93.206h33.401c1.44 2.418 3.077 4.663 4.93 6.692h-38.33v-6.692zm0-10.586h28.914a44.8 44.8 0 0 1-1.264-6.688h-27.65v6.688zm0-17.27H59.39c.288-2.286.714-4.532 1.34-6.687H31.65v6.687h.003zm53.913 44.84v5.85c0 2.798-2.095 5.075-4.667 5.075h-70.07c-2.576 0-4.663-2.277-4.663-5.075V31.26l23.22-20.96v22.25H17.16v6.688h18.39V6.688h45.348c2.576 0 4.667 2.277 4.667 5.066v20.009c1.987-.675 4.053-1.128 6.17-1.445v-18.56C91.738 5.28 86.874 0 80.902 0H31.15L0 28.118v87.917c0 6.48 4.859 11.759 10.832 11.759h70.07c5.974 0 10.837-5.27 10.837-11.759v-4.41c-2.117-.312-4.183-.765-6.17-1.435h-.004zM23.279 58.667h-7.96v6.688h7.96v-6.688zm-7.956 41.23h7.96v-6.691h-7.96v6.692zm7.956-23.96h-7.96v6.687h7.96v-6.688zm89.718-15.042l-4.896-4.07-12.447 17.613-11.19-9.305-3.762 5.311 16.091 13.38 16.204-22.929zM128 70.978c0-18.632-13.97-33.782-31.147-33.782-17.168 0-31.135 15.155-31.135 33.782 0 18.628 13.97 33.783 31.135 33.783 17.172 0 31.143-15.15 31.143-33.783H128zm-6.17 0c0 14.933-11.203 27.1-24.981 27.1-13.77 0-24.987-12.158-24.987-27.1 0-14.941 11.195-27.099 24.987-27.099 13.778 0 24.982 12.158 24.982 27.1z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577185310368" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1238" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M951.453125 476.84375H523.671875a131.8359375 131.8359375 0 0 0-254.1796875 0H72.546875v70.3125h196.9453125a131.8359375 131.8359375 0 0 0 254.1796875 0H951.453125z" p-id="1239"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M70.66 4.328l14.01 29.693c1.088 2.29 3.177 3.882 5.603 4.25l31.347 4.76c6.087.926 8.528 8.756 4.117 13.247L103.05 79.395c-1.75 1.78-2.544 4.352-2.132 6.867l5.352 32.641c1.043 6.337-5.33 11.182-10.778 8.19l-28.039-15.409a7.13 7.13 0 0 0-6.91 0l-28.039 15.41c-5.448 2.99-11.821-1.854-10.777-8.19l5.352-32.642c.415-2.515-.387-5.088-2.136-6.867L2.264 56.278C-2.146 51.787.286 43.957 6.38 43.031l31.343-4.76c2.419-.368 4.51-1.96 5.595-4.25L57.334 4.328c2.728-5.77 10.605-5.77 13.325 0z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1566036776944" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6463" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M64 223.995345h168.001164v47.997673c0 26.428509 18.878836 47.997673 41.984 47.997673h140.036654c23.095855 0 41.984-21.569164 41.984-47.997673v-47.997673h504.003491a32.004655 32.004655 0 0 0 0-64.009309H455.996509V111.988364c0-26.428509-18.878836-47.997673-41.984-47.997673H273.985164c-23.095855 0-41.984 21.569164-41.984 47.997673v47.997672H64a32.004655 32.004655 0 0 0 0 64.009309zM288.004655 128h111.997672V256H288.004655V128zM960 479.995345H791.998836v-47.997672c0-26.372655-18.878836-47.997673-41.984-47.997673H609.978182c-23.095855 0-41.984 21.634327-41.984 47.997673v47.997672H64a32.004655 32.004655 0 0 0 0 64.00931h504.003491v47.997672c0 26.363345 18.878836 47.997673 41.984 47.997673h140.036654c23.095855 0 41.984-21.634327 41.984-47.997673v-47.997672h168.001164a32.004655 32.004655 0 1 0-0.009309-64.00931zM735.995345 576H623.997673v-128h111.997672v128zM960 800.293236v-0.288581H455.996509v-47.997673c0-26.363345-18.878836-47.997673-41.984-47.997673H274.050327c-23.105164 0-41.984 21.634327-41.984 47.997673v47.997673H64v0.288581a32.004655 32.004655 0 0 0 0 64.009309c0.986764 0 1.917673-0.195491 2.885818-0.288581h165.115346v47.997672c0 26.363345 18.878836 47.997673 41.984 47.997673h140.036654c23.095855 0 41.984-21.634327 41.984-47.997673v-47.997672h501.108364c0.968145 0.093091 1.899055 0.288582 2.895127 0.288581a32.004655 32.004655 0 1 0-0.009309-64.009309zM400.002327 896H288.004655V768h111.997672v128z" fill="" p-id="6464"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1576042673958" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1110" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M692 792H332c-150 0-270-120-270-270s120-270 270-270h360c150 0 270 120 270 270 0 147-120 270-270 270zM332 312c-117 0-210 93-210 210s93 210 210 210h360c117 0 210-93 210-210s-93-210-210-210H332z" p-id="1111"></path><path d="M341 522m-150 0a150 150 0 1 0 300 0 150 150 0 1 0-300 0Z" p-id="1112"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1543827724451" class="icon" style="" viewBox="0 0 1084 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10233" xmlns:xlink="http://www.w3.org/1999/xlink" width="211.71875" height="200"><defs><style type="text/css">@font-face { font-family: rbicon; src: url("chrome-extension://dipiagiiohfljcicegpgffpbnjmgjcnf/fonts/rbicon.woff2") format("woff2"); font-weight: normal; font-style: normal; } |
| | | </style></defs><path d="M1080.09609 434.500756c-4.216302-23.731757-26.9241-47.945376-50.595623-53.185637l-17.648235-4.095836a175.940257 175.940257 0 0 1-101.612877-80.832531 177.807476 177.807476 0 0 1-18.732427-129.801867l5.541425-16.684509c7.10748-23.129428-2.108151-54.992624-20.599646-70.833873 0 0-16.624276-14.094495-63.244529-41.199293-46.800951-26.984332-66.858502-34.513443-66.858502-34.513443-22.76803-8.372371-54.631227-0.361397-71.255503 17.407304l-12.287509 13.251234a173.470708 173.470708 0 0 1-120.465769 48.065842A174.13327 174.13327 0 0 1 421.329029 33.590675L409.583617 20.761071C393.140039 2.99237 361.096144-4.898138 338.267881 3.353767c0 0-20.358715 7.529111-67.099434 34.513443-46.800951 27.34573-63.244529 41.440225-63.244529 41.440225-18.431263 15.66055-27.646894 47.222582-20.539413 70.592941l5.059562 16.865207a178.048407 178.048407 0 0 1-18.672194 129.621169 174.916297 174.916297 0 0 1-102.275439 81.073463l-17.045906 3.854904c-23.310126 5.42096-46.258856 29.333415-50.595623 53.185637 0 0-3.854905 21.382674-3.854905 75.712737 0 54.330062 3.854905 75.712736 3.854905 75.712736 4.216302 23.972688 26.9241 47.945376 50.595623 53.185637l16.624276 3.854905a174.253736 174.253736 0 0 1 102.395904 81.314394c23.310126 40.837896 28.911785 87.337683 18.732427 129.801867l-4.81863 16.443578c-7.10748 23.129428 2.108151 54.992624 20.599646 70.833872 0 0 16.624276 14.094495 63.244529 41.199293 46.800951 27.104798 66.918735 34.513443 66.918735 34.513443 22.707798 8.372371 54.631227 0.361397 71.255503-17.407303l11.624947-12.588673a175.096996 175.096996 0 0 1 242.256662 0.120465l11.624947 12.648906c16.383345 17.708468 48.427239 25.598976 71.255503 17.347071 0 0 20.358715-7.529111 67.159666-34.513443 46.740719-27.104798 63.124063-41.199293 63.124064-41.199293 18.491496-15.600317 27.707127-47.463513 20.599646-70.833873l-5.059562-17.106139a176.723284 176.723284 0 0 1 18.672194-129.139305 176.060722 176.060722 0 0 1 102.395904-81.314394l16.68451-3.854905c23.310126-5.42096 46.258856-29.333415 50.595623-53.185637 0 0 3.854905-21.382674 3.854904-75.712737-0.240932-54.330062-4.095836-75.833202-4.095836-75.833202z m-537.819428 293.334149c-119.261112 0-216.175824-97.336342-216.175824-217.621412a216.657687 216.657687 0 0 1 216.236057-217.320249c119.200879 0 216.115591 97.276109 216.11559 217.56118-0.240932 120.044139-96.974945 217.320248-216.175823 217.320249z" p-id="10234"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.921.052H49.08c-1.865 0-3.198 1.599-3.198 3.464v6.661c0 1.865 1.6 3.464 3.198 3.464h29.84c1.865 0 3.198-1.599 3.198-3.464V3.516C82.385 1.65 80.786.052 78.92.052zm45.563 0H94.642c-1.865 0-3.464 1.599-3.464 3.464v6.661c0 1.865 1.599 3.464 3.464 3.464h29.842c1.865-.266 3.464-1.599 3.464-3.464V3.516c0-1.865-1.599-3.464-3.464-3.464zm0 22.382H40.02c-1.866 0-3.464-1.599-3.464-3.464V3.516c0-1.865-1.599-3.464-3.464-3.464H3.516C1.65.052.052 1.651.052 3.516V124.75c0 1.598 1.599 3.197 3.464 3.197h120.968c1.865 0 3.464-1.599 3.464-3.464V25.898c0-1.865-1.599-3.464-3.464-3.464z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/><path d="M.006.064h127.988v31.104H.006V.064zm0 38.016h38.396v41.472H.006V38.08zm0 48.384h38.396v41.472H.006V86.464zM44.802 38.08h38.396v41.472H44.802V38.08zm0 48.384h38.396v41.472H44.802V86.464zM89.598 38.08h38.396v41.472H89.598zm0 48.384h38.396v41.472H89.598z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1575802855098" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2984" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M896 160H128c-35.2 0-64 28.8-64 64v576c0 35.2 28.8 64 64 64h768c35.2 0 64-28.8 64-64V224c0-35.2-28.8-64-64-64z m0 608c0 16-12.8 32-32 32H160c-19.2 0-32-12.8-32-32V256c0-16 12.8-32 32-32h704c19.2 0 32 12.8 32 32v512z" p-id="2985"></path><path d="M224 288c-19.2 0-32 12.8-32 32v256c0 16 12.8 32 32 32s32-12.8 32-32V320c0-16-12.8-32-32-32z m608 480c19.2 0 32-12.8 32-32V608L704 768h128z" p-id="2986"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M125.5 36.984L95.336 2.83C93.735 1.018 91.565 0 89.3 0c-2.263 0-4.433 1.018-6.033 2.83l-3.786 4.286c-1.6 1.812-3.77 2.83-6.032 2.831H54.553c-2.263 0-4.434-1.018-6.033-2.83L44.734 2.83C43.134 1.018 40.964 0 38.701 0c-2.263 0-4.434 1.018-6.034 2.83L2.5 36.984C.9 38.796 0 41.254 0 43.815c0 2.562.899 5.02 2.5 6.831L14.565 64.31c2.178 2.468 5.367 3.403 8.33 2.444 1.35-.435 2.709.592 2.709 2.18v49.407c0 5.313 3.84 9.66 8.532 9.66h59.726c4.693 0 8.532-4.347 8.532-9.66V68.934c0-1.59 1.36-2.616 2.71-2.181 2.962.96 6.15.024 8.329-2.444L125.5 50.646c1.6-1.811 2.499-4.269 2.499-6.83 0-2.563-.899-5.02-2.5-6.832z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1579774825624" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1248" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M498.595712 482.290351 345.420077 482.290351l0 57.307194 210.477712 0L555.897789 274.196942l-57.301054 0L498.596735 482.290351zM498.595712 482.290351" p-id="1249"></path><path d="M577.685002 644.98478l379.879913 0 0 57.302077L577.685002 702.286858 577.685002 644.98478 577.685002 644.98478zM577.685002 644.98478" p-id="1250"></path><path d="M577.685002 773.764795l379.879913 0 0 57.307194L577.685002 831.071989 577.685002 773.764795 577.685002 773.764795zM577.685002 773.764795" p-id="1251"></path><path d="M577.685002 902.549927l379.879913 0 0 57.307194L577.685002 959.857121 577.685002 902.549927 577.685002 902.549927zM577.685002 902.549927" p-id="1252"></path><path d="M102.523001 382.290823c4.450359 2.615571 9.470699 3.954055 14.530948 3.954055 2.969635 0 5.952572-0.461511 8.836249-1.394766l190.809767-61.886489c15.052834-4.882194 23.297612-21.040199 18.415418-36.08894-4.882194-15.052834-21.040199-23.297612-36.093033-18.415418L175.676092 308.458257c15.994276-26.115797 35.170011-50.537 57.370639-72.743768 73.767074-73.767074 171.845857-114.388237 276.16783-114.388237 104.32095 0 202.39564 40.622186 276.16169 114.388237s114.393353 171.845857 114.393353 276.16783c0 26.427906-2.615571 52.449559-7.709589 77.780481l58.302871 0c4.464685-25.499767 6.708795-51.470255 6.708795-77.780481 0-60.449767-11.845793-119.102608-35.204803-174.336584-22.559808-53.334719-54.850236-101.226472-95.968725-142.349055-41.122583-41.122583-89.017406-73.408917-142.348032-95.968725C628.317169 75.866898 569.659211 64.021106 509.215584 64.021106c-60.448744 0-119.106702 11.845793-174.336584 35.207873-53.334719 22.559808-101.230566 54.846142-142.349055 95.968725-23.980157 23.980157-44.934398 50.278103-62.727647 78.601172l-20.738323-105.655342c-3.043313-15.527648-18.105357-25.642007-33.631982-22.599717-15.527648 3.048429-25.64303 18.105357-22.599717 33.637098l36.102243 183.932126C90.51348 371.153158 95.460142 378.13313 102.523001 382.290823L102.523001 382.290823zM102.523001 382.290823" p-id="1253"></path><path d="M126.020158 587.9416 67.768453 587.9416c5.759167 33.679054 15.368012 66.544579 28.789697 98.278327 22.559808 53.333696 54.850236 101.225449 95.971795 142.348032 41.122583 41.122583 89.014336 73.408917 142.349055 95.968725 54.112432 22.88829 111.517863 34.71157 170.668031 35.18229L505.547031 902.395408c-102.94972-0.941442-199.594851-41.445948-272.499277-114.349351C177.545672 732.543975 140.810003 663.275355 126.020158 587.9416L126.020158 587.9416zM126.020158 587.9416" p-id="1254"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577099827399" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1008" xmlns:xlink="http://www.w3.org/1999/xlink" width="81" height="81"><defs><style type="text/css"></style></defs><path d="M520 559h204c17.673 0 32 14.327 32 32 0 17.673-14.327 32-32 32H488c-17.673 0-32-14.327-32-32 0-0.167 0.001-0.334 0.004-0.5a32.65 32.65 0 0 1-0.004-0.5V277c0-17.673 14.327-32 32-32 17.673 0 32 14.327 32 32v282z m-8 401C264.576 960 64 759.424 64 512S264.576 64 512 64s448 200.576 448 448-200.576 448-448 448z m0-64c212.077 0 384-171.923 384-384S724.077 128 512 128 128 299.923 128 512s171.923 384 384 384z" p-id="1009"></path></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1553828490559" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1684" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M898.831744 900.517641 103.816972 900.517641c-36.002982 0-65.363683-29.286-65.363683-65.313541l0-554.949184c0-36.041868 29.361725-65.326844 65.363683-65.326844l795.015795 0c36.002982 0 65.198931 29.284977 65.198931 65.326844l0 554.949184C964.030675 871.231641 934.834726 900.517641 898.831744 900.517641L898.831744 900.517641zM103.816972 255.593236c-13.576203 0-24.711821 11.085476-24.711821 24.662703l0 554.949184c0 13.576203 11.136641 24.662703 24.711821 24.662703l795.015795 0c13.577227 0 24.547069-11.086499 24.547069-24.662703l0-554.949184c0-13.577227-10.970866-24.662703-24.547069-24.662703L103.816972 255.593236 103.816972 255.593236zM664.346245 251.774257c-11.161201 0-20.332071-9.080819-20.332071-20.332071l0-101.278661c0-13.576203-11.047614-24.623817-24.699542-24.623817L383.181611 105.539708c-13.576203 0-24.712845 11.04659-24.712845 24.623817l0 101.278661c0 11.252275-9.041934 20.332071-20.332071 20.332071-11.20111 0-20.319791-9.080819-20.319791-20.332071l0-101.278661c0-35.989679 29.323862-65.275679 65.364707-65.275679l236.133022 0c36.06745 0 65.402569 29.284977 65.402569 65.275679l0 101.278661C684.717202 242.694461 675.636383 251.774257 664.346245 251.774257L664.346245 251.774257zM413.233044 521.725502 75.694471 521.725502c-11.163247 0-20.333094-9.117658-20.333094-20.35663 0-11.252275 9.169847-20.332071 20.333094-20.332071l337.538573 0c11.277858 0 20.319791 9.080819 20.319791 20.332071C433.552835 512.607844 424.510902 521.725502 413.233044 521.725502L413.233044 521.725502zM912.894018 521.725502 575.367725 521.725502c-11.213389 0-20.332071-9.117658-20.332071-20.35663 0-11.252275 9.118682-20.332071 20.332071-20.332071l337.526293 0c11.290137 0 20.332071 9.080819 20.332071 20.332071C933.226089 512.607844 924.184155 521.725502 912.894018 521.725502L912.894018 521.725502zM557.56322 634.217552 445.085496 634.217552c-11.213389 0-20.332071-9.079796-20.332071-20.331048l0-168.763658c0-11.251252 9.118682-20.332071 20.332071-20.332071l112.478747 0c11.290137 0 20.370956 9.080819 20.370956 20.332071l0 168.763658C577.934177 625.137757 568.853357 634.217552 557.56322 634.217552L557.56322 634.217552zM465.417567 593.514525l71.827909 0L537.245476 465.454918l-71.827909 0L465.417567 593.514525 465.417567 593.514525z" p-id="1685"></path></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M44.8 0h79.543C126.78 0 128 1.422 128 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H44.8c-2.438 0-3.657-1.422-3.657-4.267V4.267C41.143 1.422 42.362 0 44.8 0zm22.857 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 80 64 78.578 64 75.733V52.267C64 49.422 65.219 48 67.657 48zm0 48h56.686c2.438 0 3.657 1.422 3.657 4.267v23.466c0 2.845-1.219 4.267-3.657 4.267H67.657C65.22 128 64 126.578 64 123.733v-23.466C64 97.422 65.219 96 67.657 96zM50.286 68.267c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V32h6.4c2.02 0 3.658-1.91 3.658-4.267V4.267C27.429 1.91 25.79 0 23.77 0H3.657C1.637 0 0 1.91 0 4.267v23.466C0 30.09 1.637 32 3.657 32h6.4v80c0 2.356 1.638 4.267 3.657 4.267h36.572c2.02 0 3.657-1.91 3.657-4.267 0-2.356-1.638-4.267-3.657-4.267H17.37V68.267h32.915z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M126.713 90.023c.858.985 1.287 2.134 1.287 3.447v29.553c0 1.423-.429 2.6-1.287 3.53-.858.93-1.907 1.395-3.146 1.395H97.824c-1.145 0-2.146-.465-3.004-1.395-.858-.93-1.287-2.107-1.287-3.53V93.47c0-.875.19-1.696.572-2.462.382-.766.906-1.368 1.573-1.806a3.84 3.84 0 0 1 2.146-.657h9.725V69.007a3.84 3.84 0 0 0-.43-1.806 3.569 3.569 0 0 0-1.143-1.313 2.714 2.714 0 0 0-1.573-.492h-36.47v23.149h9.725c1.144 0 2.145.492 3.004 1.478.858.985 1.287 2.134 1.287 3.447v29.553c0 .876-.191 1.696-.573 2.463-.38.766-.905 1.368-1.573 1.806a3.84 3.84 0 0 1-2.145.656H51.915a3.84 3.84 0 0 1-2.145-.656c-.668-.438-1.216-1.04-1.645-1.806a4.96 4.96 0 0 1-.644-2.463V93.47c0-1.313.43-2.462 1.288-3.447.858-.986 1.907-1.478 3.146-1.478h9.582v-23.15h-37.9c-.953 0-1.74.356-2.359 1.068-.62.711-.93 1.56-.93 2.544v19.538h9.726c1.239 0 2.264.492 3.074 1.478.81.985 1.216 2.134 1.216 3.447v29.553c0 1.423-.405 2.6-1.216 3.53-.81.93-1.835 1.395-3.074 1.395H4.29c-.476 0-.93-.082-1.358-.246a4.1 4.1 0 0 1-1.144-.657 4.658 4.658 0 0 1-.93-1.067 5.186 5.186 0 0 1-.643-1.395 5.566 5.566 0 0 1-.215-1.56V93.47c0-.437.048-.875.143-1.313a3.95 3.95 0 0 1 .429-1.15c.19-.328.429-.656.715-.984.286-.329.572-.602.858-.821.286-.22.62-.383 1.001-.493.382-.11.763-.164 1.144-.164h9.726V61.619c0-.985.31-1.833.93-2.544.619-.712 1.358-1.068 2.216-1.068h44.335V39.62h-9.582c-1.24 0-2.288-.492-3.146-1.477a5.09 5.09 0 0 1-1.287-3.448V5.14c0-1.423.429-2.627 1.287-3.612.858-.985 1.907-1.477 3.146-1.477h25.743c.763 0 1.478.246 2.145.739a5.17 5.17 0 0 1 1.573 1.888c.382.766.573 1.587.573 2.462v29.553c0 1.313-.43 2.463-1.287 3.448-.859.985-1.86 1.477-3.004 1.477h-9.725v18.389h42.762c.954 0 1.74.355 2.36 1.067.62.711.93 1.56.93 2.545v26.925h9.582c1.239 0 2.288.492 3.146 1.478z"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1577540289643" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7922" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M530.944 458.24l4.8 3.456 122.176 106.816a32 32 0 0 1-37.44 51.584l-4.672-3.392L546.56 556.16v280.704a32 32 0 0 1-26.24 31.488l-5.76 0.512a32 32 0 0 1-31.424-26.24l-0.512-5.76-0.064-280.704-69.12 60.48a32 32 0 0 1-40.96 0.896l-4.16-3.968a32 32 0 0 1-0.96-40.96l4.032-4.16 122.176-106.816a32 32 0 0 1 37.312-3.456zM497.92 128c128.128 0 239.168 82.304 275.52 199.04 123.968 11.264 221.312 113.088 221.312 237.44 0 128.128-103.68 232.96-234.88 238.272h-5.888l-35.52 0.192a32 32 0 0 1-0.192-64l35.264-0.128 4.672-0.064c96.384-3.84 172.544-80.896 172.544-174.272 0-96.128-80.512-174.464-179.584-174.464h-1.984a32 32 0 0 1-32-25.28C695.872 264.96 604.736 192 497.92 192 381.824 192 285.44 277.76 274.816 388.48a32 32 0 0 1-28.352 28.8c-83.968 9.152-147.84 78.208-147.84 159.552l0.192 7.936c3.84 85.76 77.056 154.112 166.592 154.112h45.632a32 32 0 0 1 0 64h-45.632C142.016 802.944 40.32 708.032 34.88 586.88l-0.192-9.28c0-106.88 76.352-197.184 179.968-219.904C239.488 226.112 357.76 128 497.856 128z" p-id="7923"></path></svg> |
New file |
| | |
| | | <svg width="130" height="130" xmlns="http://www.w3.org/2000/svg"><path d="M63.444 64.996c20.633 0 37.359-14.308 37.359-31.953 0-17.649-16.726-31.952-37.359-31.952-20.631 0-37.36 14.303-37.358 31.952 0 17.645 16.727 31.953 37.359 31.953zM80.57 75.65H49.434c-26.652 0-48.26 18.477-48.26 41.27v2.664c0 9.316 21.608 9.325 48.26 9.325H80.57c26.649 0 48.256-.344 48.256-9.325v-2.663c0-22.794-21.605-41.271-48.256-41.271z" stroke="#979797"/></svg> |
New file |
| | |
| | | <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1569580729849" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1939" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M513.3 958.5c-142.2 0-397.9-222.1-401.6-440.5V268c1.7-39.6 31.7-72.3 71.1-77.3 49-4.6 97.1-16.5 142.7-35.3 47.8-14 91.9-38.3 129.4-71.1 30.3-24.4 72.9-26.3 105.3-4.6 39.9 30.7 83.8 55.9 130.5 74.6 48.6 14.7 98.2 25.9 148.4 33.7 38.5 7.6 67.1 40.3 69.5 79.5 3.3 84.9 2.5 169.9-2.6 254.7-33.7 281.6-253.7 436.4-392.7 436.3z m-0.1-813.7c-7.2-0.2-14.3 2-20 6.4-39.7 35.2-86.8 61.1-137.7 75.7-46.8 19.2-96.2 31-146.6 35.2-11 3.2-18.8 13-19.5 24.4v230.1c3.5 180.3 223.3 361 323.9 361s287.3-120.2 317.6-360.5c7.3-142.7 0-228.6 0-229.6-1.3-13.3-11-24.3-24-27.3-49.6-7.7-98.6-19-146.5-33.7-46.3-19.5-89.7-45.3-129-76.7-5.8-3.8-12.7-5.5-19.5-4.9l1.3-0.1z" fill="#C6CCDA" p-id="1940"></path><path d="M750.1 428L490.7 673.2c-11.7 11.1-29.5 12.9-43.1 4.2l-6.8-5.8-141.2-149.4c-9.3-9.3-12.7-22.9-9-35.5 3.8-12.6 14.1-22.1 27-24.8 12.9-2.7 26.1 1.9 34.6 11.9L469 597.5l233.7-221c14.6-12.8 36.8-11.6 49.9 2.7 13.2 14.2 11.5 35.3-2.5 48.8" fill="#C6CCDA" p-id="1941"></path></svg> |
New file |
| | |
| | | <svg width="128" height="110" xmlns="http://www.w3.org/2000/svg"><path d="M86.635 33.334c1.467 0 2.917.113 4.358.283C87.078 14.392 67.58.111 45.321.111 20.44.111.055 17.987.055 40.687c0 13.104 6.781 23.863 18.115 32.209l-4.527 14.352 15.82-8.364c5.666 1.182 10.207 2.395 15.858 2.395 1.42 0 2.829-.073 4.227-.189-.886-3.19-1.398-6.53-1.398-9.996 0-20.845 16.98-37.76 38.485-37.76zm-24.34-12.936c3.407 0 5.665 2.363 5.665 5.954 0 3.576-2.258 5.97-5.666 5.97-3.392 0-6.795-2.395-6.795-5.97 0-3.591 3.403-5.954 6.795-5.954zM30.616 32.323c-3.393 0-6.818-2.395-6.818-5.971 0-3.591 3.425-5.954 6.818-5.954 3.392 0 5.65 2.363 5.65 5.954 0 3.576-2.258 5.97-5.65 5.97z"/><path d="M127.945 70.52c0-19.075-18.108-34.623-38.448-34.623-21.537 0-38.5 15.548-38.5 34.623 0 19.108 16.963 34.622 38.5 34.622 4.508 0 9.058-1.2 13.584-2.395l12.414 7.167-3.404-11.923c9.087-7.184 15.854-16.712 15.854-27.471zm-50.928-5.97c-2.254 0-4.53-2.362-4.53-4.773 0-2.378 2.276-4.771 4.53-4.771 3.422 0 5.665 2.393 5.665 4.771 0 2.41-2.243 4.773-5.665 4.773zm24.897 0c-2.24 0-4.498-2.362-4.498-4.773 0-2.378 2.258-4.771 4.498-4.771 3.392 0 5.665 2.393 5.665 4.771 0 2.41-2.273 4.773-5.665 4.773z"/></svg> |
New file |
| | |
| | | <svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M78.527 116.793c.178.008.348.024.527.024h40.233c4.711-.005 8.53-3.677 8.534-8.21V18.895c-.004-4.532-3.823-8.204-8.534-8.209H79.054c-.179 0-.353.016-.527.024V0L0 10.082v107.406l78.527 10.342v-11.037zm0-101.362c.174-.024.348-.052.527-.052h40.233c2.018 0 3.659 1.578 3.659 3.52v89.713c-.003 1.942-1.64 3.517-3.659 3.519H79.054c-.179 0-.353-.028-.527-.052V15.431zM30.262 75.757l-18.721-.46V72.37l11.3-16.673v-.148l-10.266.164v-4.51l17.504-.44v3.264L18.696 70.76v.144l11.566.176v4.678zm9.419.231l-5.823-.144V50.671l5.823-.144v25.461zm22.255-11.632c-2.168 1.922-5.353 2.76-9.02 2.736-.702.004-1.402-.04-2.097-.131v9.303l-5.997-.148V50.743c1.852-.352 4.473-.647 8.218-.743 3.838-.096 6.608.539 8.48 1.913 1.807 1.306 3.032 3.5 3.032 6.112s-.926 4.833-2.612 6.331h-.004zM53.36 54.45c-.856-.01-1.71.083-2.541.275v7.682c.523.116 1.167.152 2.06.152 3.301-.004 5.36-1.614 5.36-4.314 0-2.425-1.772-3.843-4.875-3.791l-.004-.004zm39.847-37.066h9.564v3.795h-9.564v-3.795zm-9.568 5.68h9.564v3.8h-9.564v-3.8zm9.568 6.216h9.564v3.799h-9.564V29.28zm0 12h9.564v3.794h-9.564V41.28zm-9.568-6.096h9.564v3.795h-9.564v-3.795zm9.472 47.064c2.512 0 4.921-.96 6.697-2.67 1.776-1.708 2.773-4.026 2.772-6.442l-1.748-15.263c0-5.033-2.492-9.112-7.725-9.112-5.232 0-7.72 4.079-7.72 9.112l-1.752 15.263c-.001 2.417.996 4.735 2.773 6.444 1.777 1.71 4.187 2.669 6.7 2.668h.003zm-3.135-16.75h6.27v12.743h-6.27V65.5z"/></svg> |
New file |
| | |
| | | # replace default config |
| | | |
| | | # multipass: true |
| | | # full: true |
| | | |
| | | plugins: |
| | | |
| | | # - name |
| | | # |
| | | # or: |
| | | # - name: false |
| | | # - name: true |
| | | # |
| | | # or: |
| | | # - name: |
| | | # param1: 1 |
| | | # param2: 2 |
| | | |
| | | - removeAttrs: |
| | | attrs: |
| | | - 'fill' |
| | | - 'fill-rule' |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1" |
| | | xmlns="http://www.w3.org/2000/svg" |
| | | xmlns:xlink="http://www.w3.org/1999/xlink"> |
| | | <defs> |
| | | <filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox" id="filter-1"> |
| | | <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> |
| | | <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> |
| | | <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix> |
| | | <feMerge> |
| | | <feMergeNode in="shadowMatrixOuter1"></feMergeNode> |
| | | <feMergeNode in="SourceGraphic"></feMergeNode> |
| | | </feMerge> |
| | | </filter> |
| | | <rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect> |
| | | <filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox" id="filter-4"> |
| | | <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> |
| | | <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> |
| | | <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix> |
| | | </filter> |
| | | </defs> |
| | | <g id="配置面板" width="48" height="40" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> |
| | | <g id="setting-copy-2" width="48" height="40" transform="translate(-1190.000000, -136.000000)"> |
| | | <g id="Group-8" width="48" height="40" transform="translate(1167.000000, 0.000000)"> |
| | | <g id="Group-5-Copy-5" filter="url(#filter-1)" transform="translate(25.000000, 137.000000)"> |
| | | <mask id="mask-3" fill="white"> |
| | | <use xlink:href="#path-2"></use> |
| | | </mask> |
| | | <g id="Rectangle-18"> |
| | | <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use> |
| | | <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use> |
| | | </g> |
| | | <rect id="Rectangle-11" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="48" height="10"></rect> |
| | | <rect id="Rectangle-18" fill="#303648" mask="url(#mask-3)" x="0" y="0" width="16" height="40"></rect> |
| | | </g> |
| | | </g> |
| | | </g> |
| | | </g> |
| | | </svg> |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <svg width="52px" height="45px" viewBox="0 0 52 45" version="1.1" |
| | | xmlns="http://www.w3.org/2000/svg" |
| | | xmlns:xlink="http://www.w3.org/1999/xlink"> |
| | | <defs> |
| | | <filter x="-9.4%" y="-6.2%" width="118.8%" height="122.5%" filterUnits="objectBoundingBox" id="filter-1"> |
| | | <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> |
| | | <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> |
| | | <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix> |
| | | <feMerge> |
| | | <feMergeNode in="shadowMatrixOuter1"></feMergeNode> |
| | | <feMergeNode in="SourceGraphic"></feMergeNode> |
| | | </feMerge> |
| | | </filter> |
| | | <rect id="path-2" x="0" y="0" width="48" height="40" rx="4"></rect> |
| | | <filter x="-4.2%" y="-2.5%" width="108.3%" height="110.0%" filterUnits="objectBoundingBox" id="filter-4"> |
| | | <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> |
| | | <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> |
| | | <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix> |
| | | </filter> |
| | | </defs> |
| | | <g id="配置面板" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> |
| | | <g id="setting-copy-2" transform="translate(-1254.000000, -136.000000)"> |
| | | <g id="Group-8" transform="translate(1167.000000, 0.000000)"> |
| | | <g id="Group-5" filter="url(#filter-1)" transform="translate(89.000000, 137.000000)"> |
| | | <mask id="mask-3" fill="white"> |
| | | <use xlink:href="#path-2"></use> |
| | | </mask> |
| | | <g id="Rectangle-18"> |
| | | <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use> |
| | | <use fill="#F0F2F5" fill-rule="evenodd" xlink:href="#path-2"></use> |
| | | </g> |
| | | <rect id="Rectangle-18" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="16" height="40"></rect> |
| | | <rect id="Rectangle-11" fill="#FFFFFF" mask="url(#mask-3)" x="0" y="0" width="48" height="10"></rect> |
| | | </g> |
| | | </g> |
| | | </g> |
| | | </g> |
| | | </svg> |
New file |
| | |
| | | @import './variables.scss'; |
| | | |
| | | @mixin colorBtn($color) { |
| | | background: $color; |
| | | |
| | | &:hover { |
| | | color: $color; |
| | | |
| | | &:before, |
| | | &:after { |
| | | background: $color; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .blue-btn { |
| | | @include colorBtn($blue) |
| | | } |
| | | |
| | | .light-blue-btn { |
| | | @include colorBtn($light-blue) |
| | | } |
| | | |
| | | .red-btn { |
| | | @include colorBtn($red) |
| | | } |
| | | |
| | | .pink-btn { |
| | | @include colorBtn($pink) |
| | | } |
| | | |
| | | .green-btn { |
| | | @include colorBtn($green) |
| | | } |
| | | |
| | | .tiffany-btn { |
| | | @include colorBtn($tiffany) |
| | | } |
| | | |
| | | .yellow-btn { |
| | | @include colorBtn($yellow) |
| | | } |
| | | |
| | | .pan-btn { |
| | | font-size: 14px; |
| | | color: #fff; |
| | | padding: 14px 36px; |
| | | border-radius: 8px; |
| | | border: none; |
| | | outline: none; |
| | | transition: 600ms ease all; |
| | | position: relative; |
| | | display: inline-block; |
| | | |
| | | &:hover { |
| | | background: #fff; |
| | | |
| | | &:before, |
| | | &:after { |
| | | width: 100%; |
| | | transition: 600ms ease all; |
| | | } |
| | | } |
| | | |
| | | &:before, |
| | | &:after { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | height: 2px; |
| | | width: 0; |
| | | transition: 400ms ease all; |
| | | } |
| | | |
| | | &::after { |
| | | right: inherit; |
| | | top: inherit; |
| | | left: 0; |
| | | bottom: 0; |
| | | } |
| | | } |
| | | |
| | | .custom-button { |
| | | display: inline-block; |
| | | line-height: 1; |
| | | white-space: nowrap; |
| | | cursor: pointer; |
| | | background: #fff; |
| | | color: #fff; |
| | | -webkit-appearance: none; |
| | | text-align: center; |
| | | box-sizing: border-box; |
| | | outline: 0; |
| | | margin: 0; |
| | | padding: 10px 15px; |
| | | font-size: 14px; |
| | | border-radius: 4px; |
| | | } |
New file |
| | |
| | | // cover some element-ui styles |
| | | |
| | | .el-breadcrumb__inner, |
| | | .el-breadcrumb__inner a { |
| | | font-weight: 400 !important; |
| | | } |
| | | |
| | | .el-upload { |
| | | input[type="file"] { |
| | | display: none !important; |
| | | } |
| | | } |
| | | |
| | | .el-upload__input { |
| | | display: none; |
| | | } |
| | | |
| | | .cell { |
| | | .el-tag { |
| | | margin-right: 0px; |
| | | } |
| | | } |
| | | |
| | | .small-padding { |
| | | .cell { |
| | | padding-left: 5px; |
| | | padding-right: 5px; |
| | | } |
| | | } |
| | | |
| | | .fixed-width { |
| | | .el-button--mini { |
| | | padding: 7px 10px; |
| | | width: 60px; |
| | | } |
| | | } |
| | | |
| | | .status-col { |
| | | .cell { |
| | | padding: 0 10px; |
| | | text-align: center; |
| | | |
| | | .el-tag { |
| | | margin-right: 0px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // to fixed https://github.com/ElemeFE/element/issues/2461 |
| | | .el-dialog { |
| | | transform: none; |
| | | left: 0; |
| | | position: relative; |
| | | margin: 0 auto; |
| | | } |
| | | |
| | | // refine element ui upload |
| | | .upload-container { |
| | | .el-upload { |
| | | width: 100%; |
| | | |
| | | .el-upload-dragger { |
| | | width: 100%; |
| | | height: 200px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // dropdown |
| | | .el-dropdown-menu { |
| | | a { |
| | | display: block |
| | | } |
| | | } |
| | | |
| | | // fix date-picker ui bug in filter-item |
| | | .el-range-editor.el-input__inner { |
| | | display: inline-flex !important; |
| | | } |
| | | |
| | | // to fix el-date-picker css style |
| | | .el-range-separator { |
| | | box-sizing: content-box; |
| | | } |
| | | |
| | | .el-menu--collapse |
| | | > div |
| | | > .el-submenu |
| | | > .el-submenu__title |
| | | .el-submenu__icon-arrow { |
| | | display: none; |
| | | } |
New file |
| | |
| | | /** |
| | | * I think element-ui's default theme color is too light for long-term use. |
| | | * So I modified the default color and you can modify it to your liking. |
| | | **/ |
| | | |
| | | /* theme color */ |
| | | $--color-primary: #1890ff; |
| | | $--color-success: #13ce66; |
| | | $--color-warning: #ffba00; |
| | | $--color-danger: #ff4949; |
| | | // $--color-info: #1E1E1E; |
| | | |
| | | $--button-font-weight: 400; |
| | | |
| | | // $--color-text-regular: #1f2d3d; |
| | | |
| | | $--border-color-light: #dfe4ed; |
| | | $--border-color-lighter: #e6ebf5; |
| | | |
| | | $--table-border: 1px solid #dfe6ec; |
| | | |
| | | /* icon font path, required */ |
| | | $--font-path: '~element-ui/lib/theme-chalk/fonts'; |
| | | |
| | | @import "~element-ui/packages/theme-chalk/src/index"; |
| | | |
| | | // the :export directive is the magic sauce for webpack |
| | | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass |
| | | :export { |
| | | theme: $--color-primary; |
| | | } |
New file |
| | |
| | | @import './variables.scss'; |
| | | @import './mixin.scss'; |
| | | @import './transition.scss'; |
| | | @import './element-ui.scss'; |
| | | @import './sidebar.scss'; |
| | | @import './btn.scss'; |
| | | |
| | | body { |
| | | height: 100%; |
| | | -moz-osx-font-smoothing: grayscale; |
| | | -webkit-font-smoothing: antialiased; |
| | | text-rendering: optimizeLegibility; |
| | | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; |
| | | } |
| | | |
| | | label { |
| | | font-weight: 700; |
| | | } |
| | | |
| | | html { |
| | | height: 100%; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | #app { |
| | | height: 100%; |
| | | } |
| | | |
| | | *, |
| | | *:before, |
| | | *:after { |
| | | box-sizing: inherit; |
| | | } |
| | | |
| | | .no-padding { |
| | | padding: 0px !important; |
| | | } |
| | | |
| | | .padding-content { |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | a:focus, |
| | | a:active { |
| | | outline: none; |
| | | } |
| | | |
| | | a, |
| | | a:focus, |
| | | a:hover { |
| | | cursor: pointer; |
| | | color: inherit; |
| | | text-decoration: none; |
| | | } |
| | | |
| | | div:focus { |
| | | outline: none; |
| | | } |
| | | |
| | | .fr { |
| | | float: right; |
| | | } |
| | | |
| | | .fl { |
| | | float: left; |
| | | } |
| | | |
| | | .pr-5 { |
| | | padding-right: 5px; |
| | | } |
| | | |
| | | .pl-5 { |
| | | padding-left: 5px; |
| | | } |
| | | |
| | | .block { |
| | | display: block; |
| | | } |
| | | |
| | | .pointer { |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .inlineBlock { |
| | | display: block; |
| | | } |
| | | |
| | | .clearfix { |
| | | &:after { |
| | | visibility: hidden; |
| | | display: block; |
| | | font-size: 0; |
| | | content: " "; |
| | | clear: both; |
| | | height: 0; |
| | | } |
| | | } |
| | | |
| | | aside { |
| | | background: #eef1f6; |
| | | padding: 8px 24px; |
| | | margin-bottom: 20px; |
| | | border-radius: 2px; |
| | | display: block; |
| | | line-height: 32px; |
| | | font-size: 16px; |
| | | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; |
| | | color: #2c3e50; |
| | | -webkit-font-smoothing: antialiased; |
| | | -moz-osx-font-smoothing: grayscale; |
| | | |
| | | a { |
| | | color: #337ab7; |
| | | cursor: pointer; |
| | | |
| | | &:hover { |
| | | color: rgb(32, 160, 255); |
| | | } |
| | | } |
| | | } |
| | | |
| | | //main-container全局样式 |
| | | .app-container { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .components-container { |
| | | margin: 30px 50px; |
| | | position: relative; |
| | | } |
| | | |
| | | .text-center { |
| | | text-align: center |
| | | } |
| | | |
| | | .sub-navbar { |
| | | height: 50px; |
| | | line-height: 50px; |
| | | position: relative; |
| | | width: 100%; |
| | | text-align: right; |
| | | padding-right: 20px; |
| | | transition: 600ms ease position; |
| | | background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); |
| | | |
| | | .subtitle { |
| | | font-size: 20px; |
| | | color: #fff; |
| | | } |
| | | |
| | | &.draft { |
| | | background: #d0d0d0; |
| | | } |
| | | |
| | | &.deleted { |
| | | background: #d0d0d0; |
| | | } |
| | | } |
| | | |
| | | .link-type, |
| | | .link-type:focus { |
| | | color: #337ab7; |
| | | cursor: pointer; |
| | | |
| | | &:hover { |
| | | color: rgb(32, 160, 255); |
| | | } |
| | | } |
| | | |
| | | .filter-container { |
| | | padding-bottom: 10px; |
| | | |
| | | .filter-item { |
| | | display: inline-block; |
| | | vertical-align: middle; |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
New file |
| | |
| | | @mixin clearfix { |
| | | &:after { |
| | | content: ""; |
| | | display: table; |
| | | clear: both; |
| | | } |
| | | } |
| | | |
| | | @mixin scrollBar { |
| | | &::-webkit-scrollbar-track-piece { |
| | | background: #d3dce6; |
| | | } |
| | | |
| | | &::-webkit-scrollbar { |
| | | width: 6px; |
| | | } |
| | | |
| | | &::-webkit-scrollbar-thumb { |
| | | background: #99a9bf; |
| | | border-radius: 20px; |
| | | } |
| | | } |
| | | |
| | | @mixin relative { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | @mixin pct($pct) { |
| | | width: #{$pct}; |
| | | position: relative; |
| | | margin: 0 auto; |
| | | } |
| | | |
| | | @mixin triangle($width, $height, $color, $direction) { |
| | | $width: $width/2; |
| | | $color-border-style: $height solid $color; |
| | | $transparent-border-style: $width solid transparent; |
| | | height: 0; |
| | | width: 0; |
| | | |
| | | @if $direction==up { |
| | | border-bottom: $color-border-style; |
| | | border-left: $transparent-border-style; |
| | | border-right: $transparent-border-style; |
| | | } |
| | | |
| | | @else if $direction==right { |
| | | border-left: $color-border-style; |
| | | border-top: $transparent-border-style; |
| | | border-bottom: $transparent-border-style; |
| | | } |
| | | |
| | | @else if $direction==down { |
| | | border-top: $color-border-style; |
| | | border-left: $transparent-border-style; |
| | | border-right: $transparent-border-style; |
| | | } |
| | | |
| | | @else if $direction==left { |
| | | border-right: $color-border-style; |
| | | border-top: $transparent-border-style; |
| | | border-bottom: $transparent-border-style; |
| | | } |
| | | } |
New file |
| | |
| | | /** |
| | | * 通用css样式布局处理 |
| | | * Copyright (c) 2019 ruoyi |
| | | */ |
| | | |
| | | /** 基础通用 **/ |
| | | .pt5 { |
| | | padding-top: 5px; |
| | | } |
| | | |
| | | .pr5 { |
| | | padding-right: 5px; |
| | | } |
| | | |
| | | .pb5 { |
| | | padding-bottom: 5px; |
| | | } |
| | | |
| | | .mt5 { |
| | | margin-top: 5px; |
| | | } |
| | | |
| | | .mr5 { |
| | | margin-right: 5px; |
| | | } |
| | | |
| | | .mb5 { |
| | | margin-bottom: 5px; |
| | | } |
| | | |
| | | .mb8 { |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .ml5 { |
| | | margin-left: 5px; |
| | | } |
| | | |
| | | .mt10 { |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | .mr10 { |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | .mb10 { |
| | | margin-bottom: 10px; |
| | | } |
| | | .ml10 { |
| | | margin-left: 10px; |
| | | } |
| | | |
| | | .mt20 { |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | .mr20 { |
| | | margin-right: 20px; |
| | | } |
| | | |
| | | .mb20 { |
| | | margin-bottom: 20px; |
| | | } |
| | | .ml20 { |
| | | margin-left: 20px; |
| | | } |
| | | |
| | | .h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 { |
| | | font-family: inherit; |
| | | font-weight: 500; |
| | | line-height: 1.1; |
| | | color: inherit; |
| | | } |
| | | |
| | | .el-message-box__status + .el-message-box__message{ |
| | | word-break: break-word; |
| | | } |
| | | |
| | | .el-dialog:not(.is-fullscreen) { |
| | | margin-top: 6vh !important; |
| | | } |
| | | |
| | | .el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body { |
| | | overflow: auto; |
| | | overflow-x: hidden; |
| | | max-height: 70vh; |
| | | padding: 10px 20px 0; |
| | | } |
| | | |
| | | .el-table { |
| | | .el-table__header-wrapper, .el-table__fixed-header-wrapper { |
| | | th { |
| | | word-break: break-word; |
| | | background-color: #f8f8f9; |
| | | color: #515a6e; |
| | | height: 40px; |
| | | font-size: 13px; |
| | | } |
| | | } |
| | | |
| | | .el-table__body-wrapper { |
| | | .el-button [class*="el-icon-"] + span { |
| | | margin-left: 1px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** 表单布局 **/ |
| | | .form-header { |
| | | font-size: 15px; |
| | | color: #6379bb; |
| | | border-bottom: 1px solid #ddd; |
| | | margin: 8px 10px 25px 10px; |
| | | padding-bottom: 5px |
| | | } |
| | | |
| | | /** 表格布局 **/ |
| | | .pagination-container { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | /* tree border */ |
| | | .tree-border { |
| | | margin-top: 5px; |
| | | border: 1px solid #e5e6e7; |
| | | background: #FFFFFF none; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | @media (max-width: 768px) { |
| | | .pagination-container .el-pagination > .el-pagination__jump { |
| | | display: none !important; |
| | | } |
| | | .pagination-container .el-pagination > .el-pagination__sizes { |
| | | display: none !important; |
| | | } |
| | | } |
| | | |
| | | .el-table .fixed-width .el-button--mini { |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | | width: inherit; |
| | | } |
| | | |
| | | /** 表格更多操作下拉样式 */ |
| | | .el-table .el-dropdown-link,.el-table .el-dropdown-selfdefine { |
| | | cursor: pointer; |
| | | margin-left: 5px; |
| | | } |
| | | |
| | | .el-table .el-dropdown, .el-icon-arrow-down { |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .el-tree-node__content > .el-checkbox { |
| | | margin-right: 8px; |
| | | } |
| | | |
| | | .list-group-striped > .list-group-item { |
| | | border-left: 0; |
| | | border-right: 0; |
| | | border-radius: 0; |
| | | padding-left: 0; |
| | | padding-right: 0; |
| | | } |
| | | |
| | | .list-group { |
| | | padding-left: 0px; |
| | | list-style: none; |
| | | } |
| | | |
| | | .list-group-item { |
| | | border-bottom: 1px solid #e7eaec; |
| | | border-top: 1px solid #e7eaec; |
| | | margin-bottom: -1px; |
| | | padding: 11px 0px; |
| | | font-size: 13px; |
| | | } |
| | | |
| | | .pull-right { |
| | | float: right !important; |
| | | } |
| | | |
| | | .el-card__header { |
| | | padding: 14px 15px 7px; |
| | | min-height: 40px; |
| | | } |
| | | |
| | | .el-card__body { |
| | | padding: 15px 20px 20px 20px; |
| | | } |
| | | |
| | | .card-box { |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | /* button color */ |
| | | .el-button--cyan.is-active, |
| | | .el-button--cyan:active { |
| | | background: #20B2AA; |
| | | border-color: #20B2AA; |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | .el-button--cyan:focus, |
| | | .el-button--cyan:hover { |
| | | background: #48D1CC; |
| | | border-color: #48D1CC; |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | .el-button--cyan { |
| | | background-color: #20B2AA; |
| | | border-color: #20B2AA; |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | /* text color */ |
| | | .text-navy { |
| | | color: #1ab394; |
| | | } |
| | | |
| | | .text-primary { |
| | | color: inherit; |
| | | } |
| | | |
| | | .text-success { |
| | | color: #1c84c6; |
| | | } |
| | | |
| | | .text-info { |
| | | color: #23c6c8; |
| | | } |
| | | |
| | | .text-warning { |
| | | color: #f8ac59; |
| | | } |
| | | |
| | | .text-danger { |
| | | color: #ed5565; |
| | | } |
| | | |
| | | .text-muted { |
| | | color: #888888; |
| | | } |
| | | |
| | | /* image */ |
| | | .img-circle { |
| | | border-radius: 50%; |
| | | } |
| | | |
| | | .img-lg { |
| | | width: 120px; |
| | | height: 120px; |
| | | } |
| | | |
| | | .avatar-upload-preview { |
| | | position: relative; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | width: 200px; |
| | | height: 200px; |
| | | border-radius: 50%; |
| | | box-shadow: 0 0 4px #ccc; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | /* 拖拽列样式 */ |
| | | .sortable-ghost { |
| | | opacity: .8; |
| | | color: #fff !important; |
| | | background: #42b983 !important; |
| | | } |
| | | |
| | | .top-right-btn { |
| | | position: relative; |
| | | float: right; |
| | | } |
| | | |
| | | /* 分割面板样式 */ |
| | | .splitpanes.default-theme .splitpanes__pane { |
| | | background-color: #fff!important; |
| | | } |
New file |
| | |
| | | #app { |
| | | |
| | | .main-container { |
| | | height: 100%; |
| | | transition: margin-left .28s; |
| | | margin-left: $base-sidebar-width; |
| | | position: relative; |
| | | } |
| | | |
| | | .sidebarHide { |
| | | margin-left: 0!important; |
| | | } |
| | | |
| | | .sidebar-container { |
| | | -webkit-transition: width .28s; |
| | | transition: width 0.28s; |
| | | width: $base-sidebar-width !important; |
| | | background-color: $base-menu-background; |
| | | height: 100%; |
| | | position: fixed; |
| | | font-size: 0px; |
| | | top: 0; |
| | | bottom: 0; |
| | | left: 0; |
| | | z-index: 1001; |
| | | overflow: hidden; |
| | | -webkit-box-shadow: 2px 0 6px rgba(0,21,41,.35); |
| | | box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1); |
| | | |
| | | // reset element-ui css |
| | | .horizontal-collapse-transition { |
| | | transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; |
| | | } |
| | | |
| | | .scrollbar-wrapper { |
| | | overflow-x: hidden !important; |
| | | } |
| | | |
| | | .el-scrollbar__bar.is-vertical { |
| | | right: 0px; |
| | | } |
| | | |
| | | .el-scrollbar { |
| | | height: 100%; |
| | | } |
| | | |
| | | &.has-logo { |
| | | .el-scrollbar { |
| | | height: calc(100% - 50px); |
| | | } |
| | | } |
| | | |
| | | .is-horizontal { |
| | | display: none; |
| | | } |
| | | |
| | | a { |
| | | display: inline-block; |
| | | width: 100%; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .svg-icon { |
| | | margin-right: 16px; |
| | | } |
| | | |
| | | .el-menu { |
| | | border: none; |
| | | height: 100%; |
| | | width: 100% !important; |
| | | } |
| | | |
| | | .el-menu-item, .el-submenu__title { |
| | | overflow: hidden !important; |
| | | text-overflow: ellipsis !important; |
| | | white-space: nowrap !important; |
| | | } |
| | | |
| | | // menu hover |
| | | .submenu-title-noDropdown, |
| | | .el-submenu__title { |
| | | &:hover { |
| | | background-color: rgba(0, 0, 0, 0.06) !important; |
| | | } |
| | | } |
| | | |
| | | & .theme-dark .is-active > .el-submenu__title { |
| | | color: $base-menu-color-active !important; |
| | | } |
| | | |
| | | & .nest-menu .el-submenu>.el-submenu__title, |
| | | & .el-submenu .el-menu-item { |
| | | min-width: $base-sidebar-width !important; |
| | | |
| | | &:hover { |
| | | background-color: rgba(0, 0, 0, 0.06) !important; |
| | | } |
| | | } |
| | | |
| | | & .theme-dark .nest-menu .el-submenu>.el-submenu__title, |
| | | & .theme-dark .el-submenu .el-menu-item { |
| | | background-color: $base-sub-menu-background !important; |
| | | |
| | | &:hover { |
| | | background-color: $base-sub-menu-hover !important; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .hideSidebar { |
| | | .sidebar-container { |
| | | width: 54px !important; |
| | | } |
| | | |
| | | .main-container { |
| | | margin-left: 54px; |
| | | } |
| | | |
| | | .submenu-title-noDropdown { |
| | | padding: 0 !important; |
| | | position: relative; |
| | | |
| | | .el-tooltip { |
| | | padding: 0 !important; |
| | | |
| | | .svg-icon { |
| | | margin-left: 20px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-submenu { |
| | | overflow: hidden; |
| | | |
| | | &>.el-submenu__title { |
| | | padding: 0 !important; |
| | | |
| | | .svg-icon { |
| | | margin-left: 20px; |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | .el-menu--collapse { |
| | | .el-submenu { |
| | | &>.el-submenu__title { |
| | | &>span { |
| | | height: 0; |
| | | width: 0; |
| | | overflow: hidden; |
| | | visibility: hidden; |
| | | display: inline-block; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .el-menu--collapse .el-menu .el-submenu { |
| | | min-width: $base-sidebar-width !important; |
| | | } |
| | | |
| | | // mobile responsive |
| | | .mobile { |
| | | .main-container { |
| | | margin-left: 0px; |
| | | } |
| | | |
| | | .sidebar-container { |
| | | transition: transform .28s; |
| | | width: $base-sidebar-width !important; |
| | | } |
| | | |
| | | &.hideSidebar { |
| | | .sidebar-container { |
| | | pointer-events: none; |
| | | transition-duration: 0.3s; |
| | | transform: translate3d(-$base-sidebar-width, 0, 0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | .withoutAnimation { |
| | | |
| | | .main-container, |
| | | .sidebar-container { |
| | | transition: none; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // when menu collapsed |
| | | .el-menu--vertical { |
| | | &>.el-menu { |
| | | .svg-icon { |
| | | margin-right: 16px; |
| | | } |
| | | } |
| | | |
| | | .nest-menu .el-submenu>.el-submenu__title, |
| | | .el-menu-item { |
| | | &:hover { |
| | | // you can use $subMenuHover |
| | | background-color: rgba(0, 0, 0, 0.06) !important; |
| | | } |
| | | } |
| | | |
| | | // the scroll bar appears when the subMenu is too long |
| | | >.el-menu--popup { |
| | | max-height: 100vh; |
| | | overflow-y: auto; |
| | | |
| | | &::-webkit-scrollbar-track-piece { |
| | | background: #d3dce6; |
| | | } |
| | | |
| | | &::-webkit-scrollbar { |
| | | width: 6px; |
| | | } |
| | | |
| | | &::-webkit-scrollbar-thumb { |
| | | background: #99a9bf; |
| | | border-radius: 20px; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | // global transition css |
| | | |
| | | /* fade */ |
| | | .fade-enter-active, |
| | | .fade-leave-active { |
| | | transition: opacity 0.28s; |
| | | } |
| | | |
| | | .fade-enter, |
| | | .fade-leave-active { |
| | | opacity: 0; |
| | | } |
| | | |
| | | /* fade-transform */ |
| | | .fade-transform--move, |
| | | .fade-transform-leave-active, |
| | | .fade-transform-enter-active { |
| | | transition: all .5s; |
| | | } |
| | | |
| | | .fade-transform-enter { |
| | | opacity: 0; |
| | | transform: translateX(-30px); |
| | | } |
| | | |
| | | .fade-transform-leave-to { |
| | | opacity: 0; |
| | | transform: translateX(30px); |
| | | } |
| | | |
| | | /* breadcrumb transition */ |
| | | .breadcrumb-enter-active, |
| | | .breadcrumb-leave-active { |
| | | transition: all .5s; |
| | | } |
| | | |
| | | .breadcrumb-enter, |
| | | .breadcrumb-leave-active { |
| | | opacity: 0; |
| | | transform: translateX(20px); |
| | | } |
| | | |
| | | .breadcrumb-move { |
| | | transition: all .5s; |
| | | } |
| | | |
| | | .breadcrumb-leave-active { |
| | | position: absolute; |
| | | } |
New file |
| | |
| | | // base color |
| | | $blue:#324157; |
| | | $light-blue:#3A71A8; |
| | | $red:#C03639; |
| | | $pink: #E65D6E; |
| | | $green: #30B08F; |
| | | $tiffany: #4AB7BD; |
| | | $yellow:#FEC171; |
| | | $panGreen: #30B08F; |
| | | |
| | | // 默认菜单主题风格 |
| | | $base-menu-color:#bfcbd9; |
| | | $base-menu-color-active:#f4f4f5; |
| | | $base-menu-background:#304156; |
| | | $base-logo-title-color: #ffffff; |
| | | |
| | | $base-menu-light-color:rgba(0,0,0,.70); |
| | | $base-menu-light-background:#ffffff; |
| | | $base-logo-light-title-color: #001529; |
| | | |
| | | $base-sub-menu-background:#1f2d3d; |
| | | $base-sub-menu-hover:#001528; |
| | | |
| | | // 自定义暗色菜单风格 |
| | | /** |
| | | $base-menu-color:hsla(0,0%,100%,.65); |
| | | $base-menu-color-active:#fff; |
| | | $base-menu-background:#001529; |
| | | $base-logo-title-color: #ffffff; |
| | | |
| | | $base-menu-light-color:rgba(0,0,0,.70); |
| | | $base-menu-light-background:#ffffff; |
| | | $base-logo-light-title-color: #001529; |
| | | |
| | | $base-sub-menu-background:#000c17; |
| | | $base-sub-menu-hover:#001528; |
| | | */ |
| | | |
| | | $base-sidebar-width: 200px; |
| | | |
| | | // the :export directive is the magic sauce for webpack |
| | | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass |
| | | :export { |
| | | menuColor: $base-menu-color; |
| | | menuLightColor: $base-menu-light-color; |
| | | menuColorActive: $base-menu-color-active; |
| | | menuBackground: $base-menu-background; |
| | | menuLightBackground: $base-menu-light-background; |
| | | subMenuBackground: $base-sub-menu-background; |
| | | subMenuHover: $base-sub-menu-hover; |
| | | sideBarWidth: $base-sidebar-width; |
| | | logoTitleColor: $base-logo-title-color; |
| | | logoLightTitleColor: $base-logo-light-title-color |
| | | } |
New file |
| | |
| | | <template> |
| | | <el-breadcrumb class="app-breadcrumb" separator="/"> |
| | | <transition-group name="breadcrumb"> |
| | | <el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path"> |
| | | <span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span> |
| | | <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a> |
| | | </el-breadcrumb-item> |
| | | </transition-group> |
| | | </el-breadcrumb> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | levelList: null |
| | | } |
| | | }, |
| | | watch: { |
| | | $route(route) { |
| | | // if you go to the redirect page, do not update the breadcrumbs |
| | | if (route.path.startsWith('/redirect/')) { |
| | | return |
| | | } |
| | | this.getBreadcrumb() |
| | | } |
| | | }, |
| | | created() { |
| | | this.getBreadcrumb() |
| | | }, |
| | | methods: { |
| | | getBreadcrumb() { |
| | | // only show routes with meta.title |
| | | let matched = [] |
| | | const router = this.$route |
| | | const pathNum = this.findPathNum(router.path) |
| | | // multi-level menu |
| | | if (pathNum > 2) { |
| | | const reg = /\/\w+/gi |
| | | const pathList = router.path.match(reg).map((item, index) => { |
| | | if (index !== 0) item = item.slice(1) |
| | | return item |
| | | }) |
| | | this.getMatched(pathList, this.$store.getters.defaultRoutes, matched) |
| | | } else { |
| | | matched = router.matched.filter(item => item.meta && item.meta.title) |
| | | } |
| | | // 判断是否为首页 |
| | | if (!this.isDashboard(matched[0])) { |
| | | matched = [{ path: "/index", meta: { title: "首页" } }].concat(matched) |
| | | } |
| | | this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) |
| | | }, |
| | | findPathNum(str, char = "/") { |
| | | let index = str.indexOf(char) |
| | | let num = 0 |
| | | while (index !== -1) { |
| | | num++ |
| | | index = str.indexOf(char, index + 1) |
| | | } |
| | | return num |
| | | }, |
| | | getMatched(pathList, routeList, matched) { |
| | | let data = routeList.find(item => item.path == pathList[0] || (item.name += '').toLowerCase() == pathList[0]) |
| | | if (data) { |
| | | matched.push(data) |
| | | if (data.children && pathList.length) { |
| | | pathList.shift() |
| | | this.getMatched(pathList, data.children, matched) |
| | | } |
| | | } |
| | | }, |
| | | isDashboard(route) { |
| | | const name = route && route.name |
| | | if (!name) { |
| | | return false |
| | | } |
| | | return name.trim() === 'Index' |
| | | }, |
| | | handleLink(item) { |
| | | const { redirect, path } = item |
| | | if (redirect) { |
| | | this.$router.push(redirect) |
| | | return |
| | | } |
| | | this.$router.push(path) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .app-breadcrumb.el-breadcrumb { |
| | | display: inline-block; |
| | | font-size: 14px; |
| | | line-height: 50px; |
| | | margin-left: 8px; |
| | | .no-redirect { |
| | | color: #97a8be; |
| | | cursor: text; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-form size="small"> |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="1"> |
| | | 日,允许的通配符[, - * ? / L W] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="2"> |
| | | 不指定 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="3"> |
| | | 周期从 |
| | | <el-input-number v-model='cycle01' :min="1" :max="30" /> - |
| | | <el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 2" :max="31" /> 日 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="4"> |
| | | 从 |
| | | <el-input-number v-model='average01' :min="1" :max="30" /> 号开始,每 |
| | | <el-input-number v-model='average02' :min="1" :max="31 - average01 || 1" /> 日执行一次 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="5"> |
| | | 每月 |
| | | <el-input-number v-model='workday' :min="1" :max="31" /> 号最近的那个工作日 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="6"> |
| | | 本月最后一天 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="7"> |
| | | 指定 |
| | | <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> |
| | | <el-option v-for="item in 31" :key="item" :value="item">{{item}}</el-option> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | radioValue: 1, |
| | | workday: 1, |
| | | cycle01: 1, |
| | | cycle02: 2, |
| | | average01: 1, |
| | | average02: 1, |
| | | checkboxList: [], |
| | | checkNum: this.$options.propsData.check |
| | | } |
| | | }, |
| | | name: 'crontab-day', |
| | | props: ['check', 'cron'], |
| | | methods: { |
| | | // 单选按钮值变化时 |
| | | radioChange() { |
| | | ('day rachange') |
| | | if (this.radioValue !== 2 && this.cron.week !== '?') { |
| | | this.$emit('update', 'week', '?', 'day') |
| | | } |
| | | |
| | | switch (this.radioValue) { |
| | | case 1: |
| | | this.$emit('update', 'day', '*') |
| | | break |
| | | case 2: |
| | | this.$emit('update', 'day', '?') |
| | | break |
| | | case 3: |
| | | this.$emit('update', 'day', this.cycleTotal) |
| | | break |
| | | case 4: |
| | | this.$emit('update', 'day', this.averageTotal) |
| | | break |
| | | case 5: |
| | | this.$emit('update', 'day', this.workday + 'W') |
| | | break |
| | | case 6: |
| | | this.$emit('update', 'day', 'L') |
| | | break |
| | | case 7: |
| | | this.$emit('update', 'day', this.checkboxString) |
| | | break |
| | | } |
| | | ('day rachange end') |
| | | }, |
| | | // 周期两个值变化时 |
| | | cycleChange() { |
| | | if (this.radioValue == '3') { |
| | | this.$emit('update', 'day', this.cycleTotal) |
| | | } |
| | | }, |
| | | // 平均两个值变化时 |
| | | averageChange() { |
| | | if (this.radioValue == '4') { |
| | | this.$emit('update', 'day', this.averageTotal) |
| | | } |
| | | }, |
| | | // 最近工作日值变化时 |
| | | workdayChange() { |
| | | if (this.radioValue == '5') { |
| | | this.$emit('update', 'day', this.workdayCheck + 'W') |
| | | } |
| | | }, |
| | | // checkbox值变化时 |
| | | checkboxChange() { |
| | | if (this.radioValue == '7') { |
| | | this.$emit('update', 'day', this.checkboxString) |
| | | } |
| | | } |
| | | }, |
| | | watch: { |
| | | 'radioValue': 'radioChange', |
| | | 'cycleTotal': 'cycleChange', |
| | | 'averageTotal': 'averageChange', |
| | | 'workdayCheck': 'workdayChange', |
| | | 'checkboxString': 'checkboxChange', |
| | | }, |
| | | computed: { |
| | | // 计算两个周期值 |
| | | cycleTotal: function () { |
| | | const cycle01 = this.checkNum(this.cycle01, 1, 30) |
| | | const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 31, 31) |
| | | return cycle01 + '-' + cycle02 |
| | | }, |
| | | // 计算平均用到的值 |
| | | averageTotal: function () { |
| | | const average01 = this.checkNum(this.average01, 1, 30) |
| | | const average02 = this.checkNum(this.average02, 1, 31 - average01 || 0) |
| | | return average01 + '/' + average02 |
| | | }, |
| | | // 计算工作日格式 |
| | | workdayCheck: function () { |
| | | const workday = this.checkNum(this.workday, 1, 31) |
| | | return workday |
| | | }, |
| | | // 计算勾选的checkbox值合集 |
| | | checkboxString: function () { |
| | | let str = this.checkboxList.join() |
| | | return str == '' ? '*' : str |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <el-form size="small"> |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="1"> |
| | | 小时,允许的通配符[, - * /] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="2"> |
| | | 周期从 |
| | | <el-input-number v-model='cycle01' :min="0" :max="22" /> - |
| | | <el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="23" /> 小时 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="3"> |
| | | 从 |
| | | <el-input-number v-model='average01' :min="0" :max="22" /> 小时开始,每 |
| | | <el-input-number v-model='average02' :min="1" :max="23 - average01 || 0" /> 小时执行一次 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="4"> |
| | | 指定 |
| | | <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> |
| | | <el-option v-for="item in 24" :key="item" :value="item-1">{{item-1}}</el-option> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | radioValue: 1, |
| | | cycle01: 0, |
| | | cycle02: 1, |
| | | average01: 0, |
| | | average02: 1, |
| | | checkboxList: [], |
| | | checkNum: this.$options.propsData.check |
| | | } |
| | | }, |
| | | name: 'crontab-hour', |
| | | props: ['check', 'cron'], |
| | | methods: { |
| | | // 单选按钮值变化时 |
| | | radioChange() { |
| | | if (this.cron.min === '*') { |
| | | this.$emit('update', 'min', '0', 'hour') |
| | | } |
| | | if (this.cron.second === '*') { |
| | | this.$emit('update', 'second', '0', 'hour') |
| | | } |
| | | switch (this.radioValue) { |
| | | case 1: |
| | | this.$emit('update', 'hour', '*') |
| | | break |
| | | case 2: |
| | | this.$emit('update', 'hour', this.cycleTotal) |
| | | break |
| | | case 3: |
| | | this.$emit('update', 'hour', this.averageTotal) |
| | | break |
| | | case 4: |
| | | this.$emit('update', 'hour', this.checkboxString) |
| | | break |
| | | } |
| | | }, |
| | | // 周期两个值变化时 |
| | | cycleChange() { |
| | | if (this.radioValue == '2') { |
| | | this.$emit('update', 'hour', this.cycleTotal) |
| | | } |
| | | }, |
| | | // 平均两个值变化时 |
| | | averageChange() { |
| | | if (this.radioValue == '3') { |
| | | this.$emit('update', 'hour', this.averageTotal) |
| | | } |
| | | }, |
| | | // checkbox值变化时 |
| | | checkboxChange() { |
| | | if (this.radioValue == '4') { |
| | | this.$emit('update', 'hour', this.checkboxString) |
| | | } |
| | | } |
| | | }, |
| | | watch: { |
| | | 'radioValue': 'radioChange', |
| | | 'cycleTotal': 'cycleChange', |
| | | 'averageTotal': 'averageChange', |
| | | 'checkboxString': 'checkboxChange' |
| | | }, |
| | | computed: { |
| | | // 计算两个周期值 |
| | | cycleTotal: function () { |
| | | const cycle01 = this.checkNum(this.cycle01, 0, 22) |
| | | const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 23) |
| | | return cycle01 + '-' + cycle02 |
| | | }, |
| | | // 计算平均用到的值 |
| | | averageTotal: function () { |
| | | const average01 = this.checkNum(this.average01, 0, 22) |
| | | const average02 = this.checkNum(this.average02, 1, 23 - average01 || 0) |
| | | return average01 + '/' + average02 |
| | | }, |
| | | // 计算勾选的checkbox值合集 |
| | | checkboxString: function () { |
| | | let str = this.checkboxList.join() |
| | | return str == '' ? '*' : str |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div> |
| | | <el-tabs type="border-card"> |
| | | <el-tab-pane label="秒" v-if="shouldHide('second')"> |
| | | <CrontabSecond |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronsecond" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="分钟" v-if="shouldHide('min')"> |
| | | <CrontabMin |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronmin" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="小时" v-if="shouldHide('hour')"> |
| | | <CrontabHour |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronhour" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="日" v-if="shouldHide('day')"> |
| | | <CrontabDay |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronday" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="月" v-if="shouldHide('month')"> |
| | | <CrontabMonth |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronmonth" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="周" v-if="shouldHide('week')"> |
| | | <CrontabWeek |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronweek" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="年" v-if="shouldHide('year')"> |
| | | <CrontabYear |
| | | @update="updateCrontabValue" |
| | | :check="checkNumber" |
| | | :cron="crontabValueObj" |
| | | ref="cronyear" |
| | | /> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | |
| | | <div class="popup-main"> |
| | | <div class="popup-result"> |
| | | <p class="title">时间表达式</p> |
| | | <table> |
| | | <thead> |
| | | <th v-for="item of tabTitles" width="40" :key="item">{{item}}</th> |
| | | <th>Cron 表达式</th> |
| | | </thead> |
| | | <tbody> |
| | | <td> |
| | | <span>{{crontabValueObj.second}}</span> |
| | | </td> |
| | | <td> |
| | | <span>{{crontabValueObj.min}}</span> |
| | | </td> |
| | | <td> |
| | | <span>{{crontabValueObj.hour}}</span> |
| | | </td> |
| | | <td> |
| | | <span>{{crontabValueObj.day}}</span> |
| | | </td> |
| | | <td> |
| | | <span>{{crontabValueObj.month}}</span> |
| | | </td> |
| | | <td> |
| | | <span>{{crontabValueObj.week}}</span> |
| | | </td> |
| | | <td> |
| | | <span>{{crontabValueObj.year}}</span> |
| | | </td> |
| | | <td> |
| | | <span>{{crontabValueString}}</span> |
| | | </td> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | <CrontabResult :ex="crontabValueString"></CrontabResult> |
| | | |
| | | <div class="pop_btn"> |
| | | <el-button size="small" type="primary" @click="submitFill">确定</el-button> |
| | | <el-button size="small" type="warning" @click="clearCron">重置</el-button> |
| | | <el-button size="small" @click="hidePopup">取消</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import CrontabSecond from "./second.vue" |
| | | import CrontabMin from "./min.vue" |
| | | import CrontabHour from "./hour.vue" |
| | | import CrontabDay from "./day.vue" |
| | | import CrontabMonth from "./month.vue" |
| | | import CrontabWeek from "./week.vue" |
| | | import CrontabYear from "./year.vue" |
| | | import CrontabResult from "./result.vue" |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"], |
| | | tabActive: 0, |
| | | myindex: 0, |
| | | crontabValueObj: { |
| | | second: "*", |
| | | min: "*", |
| | | hour: "*", |
| | | day: "*", |
| | | month: "*", |
| | | week: "?", |
| | | year: "", |
| | | }, |
| | | } |
| | | }, |
| | | name: "vcrontab", |
| | | props: ["expression", "hideComponent"], |
| | | methods: { |
| | | shouldHide(key) { |
| | | if (this.hideComponent && this.hideComponent.includes(key)) return false |
| | | return true |
| | | }, |
| | | resolveExp() { |
| | | // 反解析 表达式 |
| | | if (this.expression) { |
| | | let arr = this.expression.split(" ") |
| | | if (arr.length >= 6) { |
| | | //6 位以上是合法表达式 |
| | | let obj = { |
| | | second: arr[0], |
| | | min: arr[1], |
| | | hour: arr[2], |
| | | day: arr[3], |
| | | month: arr[4], |
| | | week: arr[5], |
| | | year: arr[6] ? arr[6] : "", |
| | | } |
| | | this.crontabValueObj = { |
| | | ...obj, |
| | | } |
| | | for (let i in obj) { |
| | | if (obj[i]) this.changeRadio(i, obj[i]) |
| | | } |
| | | } |
| | | } else { |
| | | // 没有传入的表达式 则还原 |
| | | this.clearCron() |
| | | } |
| | | }, |
| | | // tab切换值 |
| | | tabCheck(index) { |
| | | this.tabActive = index |
| | | }, |
| | | // 由子组件触发,更改表达式组成的字段值 |
| | | updateCrontabValue(name, value, from) { |
| | | "updateCrontabValue", name, value, from |
| | | this.crontabValueObj[name] = value |
| | | if (from && from !== name) { |
| | | console.log(`来自组件 ${from} 改变了 ${name} ${value}`) |
| | | this.changeRadio(name, value) |
| | | } |
| | | }, |
| | | // 赋值到组件 |
| | | changeRadio(name, value) { |
| | | let arr = ["second", "min", "hour", "month"], |
| | | refName = "cron" + name, |
| | | insValue |
| | | |
| | | if (!this.$refs[refName]) return |
| | | |
| | | if (arr.includes(name)) { |
| | | if (value === "*") { |
| | | insValue = 1 |
| | | } else if (value.indexOf("-") > -1) { |
| | | let indexArr = value.split("-") |
| | | isNaN(indexArr[0]) |
| | | ? (this.$refs[refName].cycle01 = 0) |
| | | : (this.$refs[refName].cycle01 = indexArr[0]) |
| | | this.$refs[refName].cycle02 = indexArr[1] |
| | | insValue = 2 |
| | | } else if (value.indexOf("/") > -1) { |
| | | let indexArr = value.split("/") |
| | | isNaN(indexArr[0]) |
| | | ? (this.$refs[refName].average01 = 0) |
| | | : (this.$refs[refName].average01 = indexArr[0]) |
| | | this.$refs[refName].average02 = indexArr[1] |
| | | insValue = 3 |
| | | } else { |
| | | insValue = 4 |
| | | this.$refs[refName].checkboxList = value.split(",") |
| | | } |
| | | } else if (name == "day") { |
| | | if (value === "*") { |
| | | insValue = 1 |
| | | } else if (value == "?") { |
| | | insValue = 2 |
| | | } else if (value.indexOf("-") > -1) { |
| | | let indexArr = value.split("-") |
| | | isNaN(indexArr[0]) |
| | | ? (this.$refs[refName].cycle01 = 0) |
| | | : (this.$refs[refName].cycle01 = indexArr[0]) |
| | | this.$refs[refName].cycle02 = indexArr[1] |
| | | insValue = 3 |
| | | } else if (value.indexOf("/") > -1) { |
| | | let indexArr = value.split("/") |
| | | isNaN(indexArr[0]) |
| | | ? (this.$refs[refName].average01 = 0) |
| | | : (this.$refs[refName].average01 = indexArr[0]) |
| | | this.$refs[refName].average02 = indexArr[1] |
| | | insValue = 4 |
| | | } else if (value.indexOf("W") > -1) { |
| | | let indexArr = value.split("W") |
| | | isNaN(indexArr[0]) |
| | | ? (this.$refs[refName].workday = 0) |
| | | : (this.$refs[refName].workday = indexArr[0]) |
| | | insValue = 5 |
| | | } else if (value === "L") { |
| | | insValue = 6 |
| | | } else { |
| | | this.$refs[refName].checkboxList = value.split(",") |
| | | insValue = 7 |
| | | } |
| | | } else if (name == "week") { |
| | | if (value === "*") { |
| | | insValue = 1 |
| | | } else if (value == "?") { |
| | | insValue = 2 |
| | | } else if (value.indexOf("-") > -1) { |
| | | let indexArr = value.split("-") |
| | | isNaN(indexArr[0]) |
| | | ? (this.$refs[refName].cycle01 = 0) |
| | | : (this.$refs[refName].cycle01 = indexArr[0]) |
| | | this.$refs[refName].cycle02 = indexArr[1] |
| | | insValue = 3 |
| | | } else if (value.indexOf("#") > -1) { |
| | | let indexArr = value.split("#") |
| | | isNaN(indexArr[0]) |
| | | ? (this.$refs[refName].average01 = 1) |
| | | : (this.$refs[refName].average01 = indexArr[0]) |
| | | this.$refs[refName].average02 = indexArr[1] |
| | | insValue = 4 |
| | | } else if (value.indexOf("L") > -1) { |
| | | let indexArr = value.split("L") |
| | | isNaN(indexArr[0]) |
| | | ? (this.$refs[refName].weekday = 1) |
| | | : (this.$refs[refName].weekday = indexArr[0]) |
| | | insValue = 5 |
| | | } else { |
| | | this.$refs[refName].checkboxList = value.split(",") |
| | | insValue = 6 |
| | | } |
| | | } else if (name == "year") { |
| | | if (value == "") { |
| | | insValue = 1 |
| | | } else if (value == "*") { |
| | | insValue = 2 |
| | | } else if (value.indexOf("-") > -1) { |
| | | insValue = 3 |
| | | } else if (value.indexOf("/") > -1) { |
| | | insValue = 4 |
| | | } else { |
| | | this.$refs[refName].checkboxList = value.split(",") |
| | | insValue = 5 |
| | | } |
| | | } |
| | | this.$refs[refName].radioValue = insValue |
| | | }, |
| | | // 表单选项的子组件校验数字格式(通过-props传递) |
| | | checkNumber(value, minLimit, maxLimit) { |
| | | // 检查必须为整数 |
| | | value = Math.floor(value) |
| | | if (value < minLimit) { |
| | | value = minLimit |
| | | } else if (value > maxLimit) { |
| | | value = maxLimit |
| | | } |
| | | return value |
| | | }, |
| | | // 隐藏弹窗 |
| | | hidePopup() { |
| | | this.$emit("hide") |
| | | }, |
| | | // 填充表达式 |
| | | submitFill() { |
| | | this.$emit("fill", this.crontabValueString) |
| | | this.hidePopup() |
| | | }, |
| | | clearCron() { |
| | | // 还原选择项 |
| | | ("准备还原") |
| | | this.crontabValueObj = { |
| | | second: "*", |
| | | min: "*", |
| | | hour: "*", |
| | | day: "*", |
| | | month: "*", |
| | | week: "?", |
| | | year: "", |
| | | } |
| | | for (let j in this.crontabValueObj) { |
| | | this.changeRadio(j, this.crontabValueObj[j]) |
| | | } |
| | | }, |
| | | }, |
| | | computed: { |
| | | crontabValueString: function() { |
| | | let obj = this.crontabValueObj |
| | | let str = |
| | | obj.second + |
| | | " " + |
| | | obj.min + |
| | | " " + |
| | | obj.hour + |
| | | " " + |
| | | obj.day + |
| | | " " + |
| | | obj.month + |
| | | " " + |
| | | obj.week + |
| | | (obj.year == "" ? "" : " " + obj.year) |
| | | return str |
| | | }, |
| | | }, |
| | | components: { |
| | | CrontabSecond, |
| | | CrontabMin, |
| | | CrontabHour, |
| | | CrontabDay, |
| | | CrontabMonth, |
| | | CrontabWeek, |
| | | CrontabYear, |
| | | CrontabResult, |
| | | }, |
| | | watch: { |
| | | expression: "resolveExp", |
| | | hideComponent(value) { |
| | | // 隐藏部分组件 |
| | | }, |
| | | }, |
| | | mounted: function() { |
| | | this.resolveExp() |
| | | }, |
| | | } |
| | | </script> |
| | | <style scoped> |
| | | .pop_btn { |
| | | text-align: center; |
| | | margin-top: 20px; |
| | | } |
| | | .popup-main { |
| | | position: relative; |
| | | margin: 10px auto; |
| | | background: #fff; |
| | | border-radius: 5px; |
| | | font-size: 12px; |
| | | overflow: hidden; |
| | | } |
| | | .popup-title { |
| | | overflow: hidden; |
| | | line-height: 34px; |
| | | padding-top: 6px; |
| | | background: #f2f2f2; |
| | | } |
| | | .popup-result { |
| | | box-sizing: border-box; |
| | | line-height: 24px; |
| | | margin: 25px auto; |
| | | padding: 15px 10px 10px; |
| | | border: 1px solid #ccc; |
| | | position: relative; |
| | | } |
| | | .popup-result .title { |
| | | position: absolute; |
| | | top: -28px; |
| | | left: 50%; |
| | | width: 140px; |
| | | font-size: 14px; |
| | | margin-left: -70px; |
| | | text-align: center; |
| | | line-height: 30px; |
| | | background: #fff; |
| | | } |
| | | .popup-result table { |
| | | text-align: center; |
| | | width: 100%; |
| | | margin: 0 auto; |
| | | } |
| | | .popup-result table span { |
| | | display: block; |
| | | width: 100%; |
| | | font-family: arial; |
| | | line-height: 30px; |
| | | height: 30px; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | border: 1px solid #e8e8e8; |
| | | } |
| | | .popup-result-scroll { |
| | | font-size: 12px; |
| | | line-height: 24px; |
| | | height: 10em; |
| | | overflow-y: auto; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-form size="small"> |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="1"> |
| | | 分钟,允许的通配符[, - * /] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="2"> |
| | | 周期从 |
| | | <el-input-number v-model='cycle01' :min="0" :max="58" /> - |
| | | <el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> 分钟 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="3"> |
| | | 从 |
| | | <el-input-number v-model='average01' :min="0" :max="58" /> 分钟开始,每 |
| | | <el-input-number v-model='average02' :min="1" :max="59 - average01 || 0" /> 分钟执行一次 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="4"> |
| | | 指定 |
| | | <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> |
| | | <el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | radioValue: 1, |
| | | cycle01: 1, |
| | | cycle02: 2, |
| | | average01: 0, |
| | | average02: 1, |
| | | checkboxList: [], |
| | | checkNum: this.$options.propsData.check |
| | | } |
| | | }, |
| | | name: 'crontab-min', |
| | | props: ['check', 'cron'], |
| | | methods: { |
| | | // 单选按钮值变化时 |
| | | radioChange() { |
| | | switch (this.radioValue) { |
| | | case 1: |
| | | this.$emit('update', 'min', '*', 'min') |
| | | break |
| | | case 2: |
| | | this.$emit('update', 'min', this.cycleTotal, 'min') |
| | | break |
| | | case 3: |
| | | this.$emit('update', 'min', this.averageTotal, 'min') |
| | | break |
| | | case 4: |
| | | this.$emit('update', 'min', this.checkboxString, 'min') |
| | | break |
| | | } |
| | | }, |
| | | // 周期两个值变化时 |
| | | cycleChange() { |
| | | if (this.radioValue == '2') { |
| | | this.$emit('update', 'min', this.cycleTotal, 'min') |
| | | } |
| | | }, |
| | | // 平均两个值变化时 |
| | | averageChange() { |
| | | if (this.radioValue == '3') { |
| | | this.$emit('update', 'min', this.averageTotal, 'min') |
| | | } |
| | | }, |
| | | // checkbox值变化时 |
| | | checkboxChange() { |
| | | if (this.radioValue == '4') { |
| | | this.$emit('update', 'min', this.checkboxString, 'min') |
| | | } |
| | | }, |
| | | |
| | | }, |
| | | watch: { |
| | | 'radioValue': 'radioChange', |
| | | 'cycleTotal': 'cycleChange', |
| | | 'averageTotal': 'averageChange', |
| | | 'checkboxString': 'checkboxChange', |
| | | }, |
| | | computed: { |
| | | // 计算两个周期值 |
| | | cycleTotal: function () { |
| | | const cycle01 = this.checkNum(this.cycle01, 0, 58) |
| | | const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59) |
| | | return cycle01 + '-' + cycle02 |
| | | }, |
| | | // 计算平均用到的值 |
| | | averageTotal: function () { |
| | | const average01 = this.checkNum(this.average01, 0, 58) |
| | | const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0) |
| | | return average01 + '/' + average02 |
| | | }, |
| | | // 计算勾选的checkbox值合集 |
| | | checkboxString: function () { |
| | | let str = this.checkboxList.join() |
| | | return str == '' ? '*' : str |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <el-form size='small'> |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="1"> |
| | | 月,允许的通配符[, - * /] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="2"> |
| | | 周期从 |
| | | <el-input-number v-model='cycle01' :min="1" :max="11" /> - |
| | | <el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 2" :max="12" /> 月 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="3"> |
| | | 从 |
| | | <el-input-number v-model='average01' :min="1" :max="11" /> 月开始,每 |
| | | <el-input-number v-model='average02' :min="1" :max="12 - average01 || 0" /> 月月执行一次 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="4"> |
| | | 指定 |
| | | <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> |
| | | <el-option v-for="item in 12" :key="item" :value="item">{{item}}</el-option> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | radioValue: 1, |
| | | cycle01: 1, |
| | | cycle02: 2, |
| | | average01: 1, |
| | | average02: 1, |
| | | checkboxList: [], |
| | | checkNum: this.check |
| | | } |
| | | }, |
| | | name: 'crontab-month', |
| | | props: ['check', 'cron'], |
| | | methods: { |
| | | // 单选按钮值变化时 |
| | | radioChange() { |
| | | switch (this.radioValue) { |
| | | case 1: |
| | | this.$emit('update', 'month', '*') |
| | | break |
| | | case 2: |
| | | this.$emit('update', 'month', this.cycleTotal) |
| | | break |
| | | case 3: |
| | | this.$emit('update', 'month', this.averageTotal) |
| | | break |
| | | case 4: |
| | | this.$emit('update', 'month', this.checkboxString) |
| | | break |
| | | } |
| | | }, |
| | | // 周期两个值变化时 |
| | | cycleChange() { |
| | | if (this.radioValue == '2') { |
| | | this.$emit('update', 'month', this.cycleTotal) |
| | | } |
| | | }, |
| | | // 平均两个值变化时 |
| | | averageChange() { |
| | | if (this.radioValue == '3') { |
| | | this.$emit('update', 'month', this.averageTotal) |
| | | } |
| | | }, |
| | | // checkbox值变化时 |
| | | checkboxChange() { |
| | | if (this.radioValue == '4') { |
| | | this.$emit('update', 'month', this.checkboxString) |
| | | } |
| | | } |
| | | }, |
| | | watch: { |
| | | 'radioValue': 'radioChange', |
| | | 'cycleTotal': 'cycleChange', |
| | | 'averageTotal': 'averageChange', |
| | | 'checkboxString': 'checkboxChange' |
| | | }, |
| | | computed: { |
| | | // 计算两个周期值 |
| | | cycleTotal: function () { |
| | | const cycle01 = this.checkNum(this.cycle01, 1, 11) |
| | | const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 12) |
| | | return cycle01 + '-' + cycle02 |
| | | }, |
| | | // 计算平均用到的值 |
| | | averageTotal: function () { |
| | | const average01 = this.checkNum(this.average01, 1, 11) |
| | | const average02 = this.checkNum(this.average02, 1, 12 - average01 || 0) |
| | | return average01 + '/' + average02 |
| | | }, |
| | | // 计算勾选的checkbox值合集 |
| | | checkboxString: function () { |
| | | let str = this.checkboxList.join() |
| | | return str == '' ? '*' : str |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="popup-result"> |
| | | <p class="title">最近5次运行时间</p> |
| | | <ul class="popup-result-scroll"> |
| | | <template v-if='isShow'> |
| | | <li v-for='item in resultList' :key="item">{{item}}</li> |
| | | </template> |
| | | <li v-else>计算结果中...</li> |
| | | </ul> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | dayRule: '', |
| | | dayRuleSup: '', |
| | | dateArr: [], |
| | | resultList: [], |
| | | isShow: false |
| | | } |
| | | }, |
| | | name: 'crontab-result', |
| | | methods: { |
| | | // 表达式值变化时,开始去计算结果 |
| | | expressionChange() { |
| | | |
| | | // 计算开始-隐藏结果 |
| | | this.isShow = false |
| | | // 获取规则数组[0秒、1分、2时、3日、4月、5星期、6年] |
| | | let ruleArr = this.$options.propsData.ex.split(' ') |
| | | // 用于记录进入循环的次数 |
| | | let nums = 0 |
| | | // 用于暂时存符号时间规则结果的数组 |
| | | let resultArr = [] |
| | | // 获取当前时间精确至[年、月、日、时、分、秒] |
| | | let nTime = new Date() |
| | | let nYear = nTime.getFullYear() |
| | | let nMonth = nTime.getMonth() + 1 |
| | | let nDay = nTime.getDate() |
| | | let nHour = nTime.getHours() |
| | | let nMin = nTime.getMinutes() |
| | | let nSecond = nTime.getSeconds() |
| | | // 根据规则获取到近100年可能年数组、月数组等等 |
| | | this.getSecondArr(ruleArr[0]) |
| | | this.getMinArr(ruleArr[1]) |
| | | this.getHourArr(ruleArr[2]) |
| | | this.getDayArr(ruleArr[3]) |
| | | this.getMonthArr(ruleArr[4]) |
| | | this.getWeekArr(ruleArr[5]) |
| | | this.getYearArr(ruleArr[6], nYear) |
| | | // 将获取到的数组赋值-方便使用 |
| | | let sDate = this.dateArr[0] |
| | | let mDate = this.dateArr[1] |
| | | let hDate = this.dateArr[2] |
| | | let DDate = this.dateArr[3] |
| | | let MDate = this.dateArr[4] |
| | | let YDate = this.dateArr[5] |
| | | // 获取当前时间在数组中的索引 |
| | | let sIdx = this.getIndex(sDate, nSecond) |
| | | let mIdx = this.getIndex(mDate, nMin) |
| | | let hIdx = this.getIndex(hDate, nHour) |
| | | let DIdx = this.getIndex(DDate, nDay) |
| | | let MIdx = this.getIndex(MDate, nMonth) |
| | | let YIdx = this.getIndex(YDate, nYear) |
| | | // 重置月日时分秒的函数(后面用的比较多) |
| | | const resetSecond = function () { |
| | | sIdx = 0 |
| | | nSecond = sDate[sIdx] |
| | | } |
| | | const resetMin = function () { |
| | | mIdx = 0 |
| | | nMin = mDate[mIdx] |
| | | resetSecond() |
| | | } |
| | | const resetHour = function () { |
| | | hIdx = 0 |
| | | nHour = hDate[hIdx] |
| | | resetMin() |
| | | } |
| | | const resetDay = function () { |
| | | DIdx = 0 |
| | | nDay = DDate[DIdx] |
| | | resetHour() |
| | | } |
| | | const resetMonth = function () { |
| | | MIdx = 0 |
| | | nMonth = MDate[MIdx] |
| | | resetDay() |
| | | } |
| | | // 如果当前年份不为数组中当前值 |
| | | if (nYear !== YDate[YIdx]) { |
| | | resetMonth() |
| | | } |
| | | // 如果当前月份不为数组中当前值 |
| | | if (nMonth !== MDate[MIdx]) { |
| | | resetDay() |
| | | } |
| | | // 如果当前“日”不为数组中当前值 |
| | | if (nDay !== DDate[DIdx]) { |
| | | resetHour() |
| | | } |
| | | // 如果当前“时”不为数组中当前值 |
| | | if (nHour !== hDate[hIdx]) { |
| | | resetMin() |
| | | } |
| | | // 如果当前“分”不为数组中当前值 |
| | | if (nMin !== mDate[mIdx]) { |
| | | resetSecond() |
| | | } |
| | | |
| | | // 循环年份数组 |
| | | goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) { |
| | | let YY = YDate[Yi] |
| | | // 如果到达最大值时 |
| | | if (nMonth > MDate[MDate.length - 1]) { |
| | | resetMonth() |
| | | continue |
| | | } |
| | | // 循环月份数组 |
| | | goMonth: for (let Mi = MIdx; Mi < MDate.length; Mi++) { |
| | | // 赋值、方便后面运算 |
| | | let MM = MDate[Mi]; |
| | | MM = MM < 10 ? '0' + MM : MM |
| | | // 如果到达最大值时 |
| | | if (nDay > DDate[DDate.length - 1]) { |
| | | resetDay() |
| | | if (Mi == MDate.length - 1) { |
| | | resetMonth() |
| | | continue goYear |
| | | } |
| | | continue |
| | | } |
| | | // 循环日期数组 |
| | | goDay: for (let Di = DIdx; Di < DDate.length; Di++) { |
| | | // 赋值、方便后面运算 |
| | | let DD = DDate[Di] |
| | | let thisDD = DD < 10 ? '0' + DD : DD |
| | | |
| | | // 如果到达最大值时 |
| | | if (nHour > hDate[hDate.length - 1]) { |
| | | resetHour() |
| | | if (Di == DDate.length - 1) { |
| | | resetDay() |
| | | if (Mi == MDate.length - 1) { |
| | | resetMonth() |
| | | continue goYear |
| | | } |
| | | continue goMonth |
| | | } |
| | | continue |
| | | } |
| | | |
| | | // 判断日期的合法性,不合法的话也是跳出当前循环 |
| | | if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && this.dayRule !== 'workDay' && this.dayRule !== 'lastWeek' && this.dayRule !== 'lastDay') { |
| | | resetDay() |
| | | continue goMonth |
| | | } |
| | | // 如果日期规则中有值时 |
| | | if (this.dayRule == 'lastDay') { |
| | | // 如果不是合法日期则需要将前将日期调到合法日期即月末最后一天 |
| | | |
| | | if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | DD-- |
| | | thisDD = DD < 10 ? '0' + DD : DD |
| | | } |
| | | } |
| | | } else if (this.dayRule == 'workDay') { |
| | | // 校验并调整如果是2月30号这种日期传进来时需调整至正常月底 |
| | | if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | DD-- |
| | | thisDD = DD < 10 ? '0' + DD : DD |
| | | } |
| | | } |
| | | // 获取达到条件的日期是星期X |
| | | let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week') |
| | | // 当星期日时 |
| | | if (thisWeek == 1) { |
| | | // 先找下一个日,并判断是否为月底 |
| | | DD++ |
| | | thisDD = DD < 10 ? '0' + DD : DD |
| | | // 判断下一日已经不是合法日期 |
| | | if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | DD -= 3 |
| | | } |
| | | } else if (thisWeek == 7) { |
| | | // 当星期6时只需判断不是1号就可进行操作 |
| | | if (this.dayRuleSup !== 1) { |
| | | DD-- |
| | | } else { |
| | | DD += 2 |
| | | } |
| | | } |
| | | } else if (this.dayRule == 'weekDay') { |
| | | // 如果指定了是星期几 |
| | | // 获取当前日期是属于星期几 |
| | | let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week') |
| | | // 校验当前星期是否在星期池(dayRuleSup)中 |
| | | if (this.dayRuleSup.indexOf(thisWeek) < 0) { |
| | | // 如果到达最大值时 |
| | | if (Di == DDate.length - 1) { |
| | | resetDay() |
| | | if (Mi == MDate.length - 1) { |
| | | resetMonth() |
| | | continue goYear |
| | | } |
| | | continue goMonth |
| | | } |
| | | continue |
| | | } |
| | | } else if (this.dayRule == 'assWeek') { |
| | | // 如果指定了是第几周的星期几 |
| | | // 获取每月1号是属于星期几 |
| | | let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week') |
| | | if (this.dayRuleSup[1] >= thisWeek) { |
| | | DD = (this.dayRuleSup[0] - 1) * 7 + this.dayRuleSup[1] - thisWeek + 1 |
| | | } else { |
| | | DD = this.dayRuleSup[0] * 7 + this.dayRuleSup[1] - thisWeek + 1 |
| | | } |
| | | } else if (this.dayRule == 'lastWeek') { |
| | | // 如果指定了每月最后一个星期几 |
| | | // 校验并调整如果是2月30号这种日期传进来时需调整至正常月底 |
| | | if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) { |
| | | DD-- |
| | | thisDD = DD < 10 ? '0' + DD : DD |
| | | } |
| | | } |
| | | // 获取月末最后一天是星期几 |
| | | let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week') |
| | | // 找到要求中最近的那个星期几 |
| | | if (this.dayRuleSup < thisWeek) { |
| | | DD -= thisWeek - this.dayRuleSup |
| | | } else if (this.dayRuleSup > thisWeek) { |
| | | DD -= 7 - (this.dayRuleSup - thisWeek) |
| | | } |
| | | } |
| | | // 判断时间值是否小于10置换成“05”这种格式 |
| | | DD = DD < 10 ? '0' + DD : DD |
| | | |
| | | // 循环“时”数组 |
| | | goHour: for (let hi = hIdx; hi < hDate.length; hi++) { |
| | | let hh = hDate[hi] < 10 ? '0' + hDate[hi] : hDate[hi] |
| | | |
| | | // 如果到达最大值时 |
| | | if (nMin > mDate[mDate.length - 1]) { |
| | | resetMin() |
| | | if (hi == hDate.length - 1) { |
| | | resetHour() |
| | | if (Di == DDate.length - 1) { |
| | | resetDay() |
| | | if (Mi == MDate.length - 1) { |
| | | resetMonth() |
| | | continue goYear |
| | | } |
| | | continue goMonth |
| | | } |
| | | continue goDay |
| | | } |
| | | continue |
| | | } |
| | | // 循环"分"数组 |
| | | goMin: for (let mi = mIdx; mi < mDate.length; mi++) { |
| | | let mm = mDate[mi] < 10 ? '0' + mDate[mi] : mDate[mi] |
| | | |
| | | // 如果到达最大值时 |
| | | if (nSecond > sDate[sDate.length - 1]) { |
| | | resetSecond() |
| | | if (mi == mDate.length - 1) { |
| | | resetMin() |
| | | if (hi == hDate.length - 1) { |
| | | resetHour() |
| | | if (Di == DDate.length - 1) { |
| | | resetDay() |
| | | if (Mi == MDate.length - 1) { |
| | | resetMonth() |
| | | continue goYear |
| | | } |
| | | continue goMonth |
| | | } |
| | | continue goDay |
| | | } |
| | | continue goHour |
| | | } |
| | | continue |
| | | } |
| | | // 循环"秒"数组 |
| | | goSecond: for (let si = sIdx; si <= sDate.length - 1; si++) { |
| | | let ss = sDate[si] < 10 ? '0' + sDate[si] : sDate[si] |
| | | // 添加当前时间(时间合法性在日期循环时已经判断) |
| | | if (MM !== '00' && DD !== '00') { |
| | | resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss) |
| | | nums++ |
| | | } |
| | | // 如果条数满了就退出循环 |
| | | if (nums == 5) break goYear |
| | | // 如果到达最大值时 |
| | | if (si == sDate.length - 1) { |
| | | resetSecond() |
| | | if (mi == mDate.length - 1) { |
| | | resetMin() |
| | | if (hi == hDate.length - 1) { |
| | | resetHour() |
| | | if (Di == DDate.length - 1) { |
| | | resetDay() |
| | | if (Mi == MDate.length - 1) { |
| | | resetMonth() |
| | | continue goYear |
| | | } |
| | | continue goMonth |
| | | } |
| | | continue goDay |
| | | } |
| | | continue goHour |
| | | } |
| | | continue goMin |
| | | } |
| | | } //goSecond |
| | | } //goMin |
| | | }//goHour |
| | | }//goDay |
| | | }//goMonth |
| | | } |
| | | // 判断100年内的结果条数 |
| | | if (resultArr.length == 0) { |
| | | this.resultList = ['没有达到条件的结果!'] |
| | | } else { |
| | | this.resultList = resultArr |
| | | if (resultArr.length !== 5) { |
| | | this.resultList.push('最近100年内只有上面' + resultArr.length + '条结果!') |
| | | } |
| | | } |
| | | // 计算完成-显示结果 |
| | | this.isShow = true |
| | | |
| | | |
| | | }, |
| | | // 用于计算某位数字在数组中的索引 |
| | | getIndex(arr, value) { |
| | | if (value <= arr[0] || value > arr[arr.length - 1]) { |
| | | return 0 |
| | | } else { |
| | | for (let i = 0; i < arr.length - 1; i++) { |
| | | if (value > arr[i] && value <= arr[i + 1]) { |
| | | return i + 1 |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | // 获取"年"数组 |
| | | getYearArr(rule, year) { |
| | | this.dateArr[5] = this.getOrderArr(year, year + 100) |
| | | if (rule !== undefined) { |
| | | if (rule.indexOf('-') >= 0) { |
| | | this.dateArr[5] = this.getCycleArr(rule, year + 100, false) |
| | | } else if (rule.indexOf('/') >= 0) { |
| | | this.dateArr[5] = this.getAverageArr(rule, year + 100) |
| | | } else if (rule !== '*') { |
| | | this.dateArr[5] = this.getAssignArr(rule) |
| | | } |
| | | } |
| | | }, |
| | | // 获取"月"数组 |
| | | getMonthArr(rule) { |
| | | this.dateArr[4] = this.getOrderArr(1, 12) |
| | | if (rule.indexOf('-') >= 0) { |
| | | this.dateArr[4] = this.getCycleArr(rule, 12, false) |
| | | } else if (rule.indexOf('/') >= 0) { |
| | | this.dateArr[4] = this.getAverageArr(rule, 12) |
| | | } else if (rule !== '*') { |
| | | this.dateArr[4] = this.getAssignArr(rule) |
| | | } |
| | | }, |
| | | // 获取"日"数组-主要为日期规则 |
| | | getWeekArr(rule) { |
| | | // 只有当日期规则的两个值均为“”时则表达日期是有选项的 |
| | | if (this.dayRule == '' && this.dayRuleSup == '') { |
| | | if (rule.indexOf('-') >= 0) { |
| | | this.dayRule = 'weekDay' |
| | | this.dayRuleSup = this.getCycleArr(rule, 7, false) |
| | | } else if (rule.indexOf('#') >= 0) { |
| | | this.dayRule = 'assWeek' |
| | | let matchRule = rule.match(/[0-9]{1}/g) |
| | | this.dayRuleSup = [Number(matchRule[1]), Number(matchRule[0])] |
| | | this.dateArr[3] = [1] |
| | | if (this.dayRuleSup[1] == 7) { |
| | | this.dayRuleSup[1] = 0 |
| | | } |
| | | } else if (rule.indexOf('L') >= 0) { |
| | | this.dayRule = 'lastWeek' |
| | | this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]) |
| | | this.dateArr[3] = [31] |
| | | if (this.dayRuleSup == 7) { |
| | | this.dayRuleSup = 0 |
| | | } |
| | | } else if (rule !== '*' && rule !== '?') { |
| | | this.dayRule = 'weekDay' |
| | | this.dayRuleSup = this.getAssignArr(rule) |
| | | } |
| | | } |
| | | }, |
| | | // 获取"日"数组-少量为日期规则 |
| | | getDayArr(rule) { |
| | | this.dateArr[3] = this.getOrderArr(1, 31) |
| | | this.dayRule = '' |
| | | this.dayRuleSup = '' |
| | | if (rule.indexOf('-') >= 0) { |
| | | this.dateArr[3] = this.getCycleArr(rule, 31, false) |
| | | this.dayRuleSup = 'null' |
| | | } else if (rule.indexOf('/') >= 0) { |
| | | this.dateArr[3] = this.getAverageArr(rule, 31) |
| | | this.dayRuleSup = 'null' |
| | | } else if (rule.indexOf('W') >= 0) { |
| | | this.dayRule = 'workDay' |
| | | this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]) |
| | | this.dateArr[3] = [this.dayRuleSup] |
| | | } else if (rule.indexOf('L') >= 0) { |
| | | this.dayRule = 'lastDay' |
| | | this.dayRuleSup = 'null' |
| | | this.dateArr[3] = [31] |
| | | } else if (rule !== '*' && rule !== '?') { |
| | | this.dateArr[3] = this.getAssignArr(rule) |
| | | this.dayRuleSup = 'null' |
| | | } else if (rule == '*') { |
| | | this.dayRuleSup = 'null' |
| | | } |
| | | }, |
| | | // 获取"时"数组 |
| | | getHourArr(rule) { |
| | | this.dateArr[2] = this.getOrderArr(0, 23) |
| | | if (rule.indexOf('-') >= 0) { |
| | | this.dateArr[2] = this.getCycleArr(rule, 24, true) |
| | | } else if (rule.indexOf('/') >= 0) { |
| | | this.dateArr[2] = this.getAverageArr(rule, 23) |
| | | } else if (rule !== '*') { |
| | | this.dateArr[2] = this.getAssignArr(rule) |
| | | } |
| | | }, |
| | | // 获取"分"数组 |
| | | getMinArr(rule) { |
| | | this.dateArr[1] = this.getOrderArr(0, 59) |
| | | if (rule.indexOf('-') >= 0) { |
| | | this.dateArr[1] = this.getCycleArr(rule, 60, true) |
| | | } else if (rule.indexOf('/') >= 0) { |
| | | this.dateArr[1] = this.getAverageArr(rule, 59) |
| | | } else if (rule !== '*') { |
| | | this.dateArr[1] = this.getAssignArr(rule) |
| | | } |
| | | }, |
| | | // 获取"秒"数组 |
| | | getSecondArr(rule) { |
| | | this.dateArr[0] = this.getOrderArr(0, 59) |
| | | if (rule.indexOf('-') >= 0) { |
| | | this.dateArr[0] = this.getCycleArr(rule, 60, true) |
| | | } else if (rule.indexOf('/') >= 0) { |
| | | this.dateArr[0] = this.getAverageArr(rule, 59) |
| | | } else if (rule !== '*') { |
| | | this.dateArr[0] = this.getAssignArr(rule) |
| | | } |
| | | }, |
| | | // 根据传进来的min-max返回一个顺序的数组 |
| | | getOrderArr(min, max) { |
| | | let arr = [] |
| | | for (let i = min; i <= max; i++) { |
| | | arr.push(i) |
| | | } |
| | | return arr |
| | | }, |
| | | // 根据规则中指定的零散值返回一个数组 |
| | | getAssignArr(rule) { |
| | | let arr = [] |
| | | let assiginArr = rule.split(',') |
| | | for (let i = 0; i < assiginArr.length; i++) { |
| | | arr[i] = Number(assiginArr[i]) |
| | | } |
| | | arr.sort(this.compare) |
| | | return arr |
| | | }, |
| | | // 根据一定算术规则计算返回一个数组 |
| | | getAverageArr(rule, limit) { |
| | | let arr = [] |
| | | let agArr = rule.split('/') |
| | | let min = Number(agArr[0]) |
| | | let step = Number(agArr[1]) |
| | | while (min <= limit) { |
| | | arr.push(min) |
| | | min += step |
| | | } |
| | | return arr |
| | | }, |
| | | // 根据规则返回一个具有周期性的数组 |
| | | getCycleArr(rule, limit, status) { |
| | | // status--表示是否从0开始(则从1开始) |
| | | let arr = [] |
| | | let cycleArr = rule.split('-') |
| | | let min = Number(cycleArr[0]) |
| | | let max = Number(cycleArr[1]) |
| | | if (min > max) { |
| | | max += limit |
| | | } |
| | | for (let i = min; i <= max; i++) { |
| | | let add = 0 |
| | | if (status == false && i % limit == 0) { |
| | | add = limit |
| | | } |
| | | arr.push(Math.round(i % limit + add)) |
| | | } |
| | | arr.sort(this.compare) |
| | | return arr |
| | | }, |
| | | // 比较数字大小(用于Array.sort) |
| | | compare(value1, value2) { |
| | | if (value2 - value1 > 0) { |
| | | return -1 |
| | | } else { |
| | | return 1 |
| | | } |
| | | }, |
| | | // 格式化日期格式如:2017-9-19 18:04:33 |
| | | formatDate(value, type) { |
| | | // 计算日期相关值 |
| | | let time = typeof value == 'number' ? new Date(value) : value |
| | | let Y = time.getFullYear() |
| | | let M = time.getMonth() + 1 |
| | | let D = time.getDate() |
| | | let h = time.getHours() |
| | | let m = time.getMinutes() |
| | | let s = time.getSeconds() |
| | | let week = time.getDay() |
| | | // 如果传递了type的话 |
| | | if (type == undefined) { |
| | | return Y + '-' + (M < 10 ? '0' + M : M) + '-' + (D < 10 ? '0' + D : D) + ' ' + (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s) |
| | | } else if (type == 'week') { |
| | | // 在quartz中 1为星期日 |
| | | return week + 1 |
| | | } |
| | | }, |
| | | // 检查日期是否存在 |
| | | checkDate(value) { |
| | | let time = new Date(value) |
| | | let format = this.formatDate(time) |
| | | return value === format |
| | | } |
| | | }, |
| | | watch: { |
| | | 'ex': 'expressionChange' |
| | | }, |
| | | props: ['ex'], |
| | | mounted: function () { |
| | | // 初始化 获取一次结果 |
| | | this.expressionChange() |
| | | } |
| | | } |
| | | |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <el-form size="small"> |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="1"> |
| | | 秒,允许的通配符[, - * /] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="2"> |
| | | 周期从 |
| | | <el-input-number v-model='cycle01' :min="0" :max="58" /> - |
| | | <el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> 秒 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="3"> |
| | | 从 |
| | | <el-input-number v-model='average01' :min="0" :max="58" /> 秒开始,每 |
| | | <el-input-number v-model='average02' :min="1" :max="59 - average01 || 0" /> 秒执行一次 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="4"> |
| | | 指定 |
| | | <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> |
| | | <el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | radioValue: 1, |
| | | cycle01: 1, |
| | | cycle02: 2, |
| | | average01: 0, |
| | | average02: 1, |
| | | checkboxList: [], |
| | | checkNum: this.$options.propsData.check |
| | | } |
| | | }, |
| | | name: 'crontab-second', |
| | | props: ['check', 'radioParent'], |
| | | methods: { |
| | | // 单选按钮值变化时 |
| | | radioChange() { |
| | | switch (this.radioValue) { |
| | | case 1: |
| | | this.$emit('update', 'second', '*', 'second') |
| | | break |
| | | case 2: |
| | | this.$emit('update', 'second', this.cycleTotal) |
| | | break |
| | | case 3: |
| | | this.$emit('update', 'second', this.averageTotal) |
| | | break |
| | | case 4: |
| | | this.$emit('update', 'second', this.checkboxString) |
| | | break |
| | | } |
| | | }, |
| | | // 周期两个值变化时 |
| | | cycleChange() { |
| | | if (this.radioValue == '2') { |
| | | this.$emit('update', 'second', this.cycleTotal) |
| | | } |
| | | }, |
| | | // 平均两个值变化时 |
| | | averageChange() { |
| | | if (this.radioValue == '3') { |
| | | this.$emit('update', 'second', this.averageTotal) |
| | | } |
| | | }, |
| | | // checkbox值变化时 |
| | | checkboxChange() { |
| | | if (this.radioValue == '4') { |
| | | this.$emit('update', 'second', this.checkboxString) |
| | | } |
| | | } |
| | | }, |
| | | watch: { |
| | | 'radioValue': 'radioChange', |
| | | 'cycleTotal': 'cycleChange', |
| | | 'averageTotal': 'averageChange', |
| | | 'checkboxString': 'checkboxChange', |
| | | radioParent() { |
| | | this.radioValue = this.radioParent |
| | | } |
| | | }, |
| | | computed: { |
| | | // 计算两个周期值 |
| | | cycleTotal: function () { |
| | | const cycle01 = this.checkNum(this.cycle01, 0, 58) |
| | | const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59) |
| | | return cycle01 + '-' + cycle02 |
| | | }, |
| | | // 计算平均用到的值 |
| | | averageTotal: function () { |
| | | const average01 = this.checkNum(this.average01, 0, 58) |
| | | const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0) |
| | | return average01 + '/' + average02 |
| | | }, |
| | | // 计算勾选的checkbox值合集 |
| | | checkboxString: function () { |
| | | let str = this.checkboxList.join() |
| | | return str == '' ? '*' : str |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <el-form size='small'> |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="1"> |
| | | 周,允许的通配符[, - * ? / L #] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="2"> |
| | | 不指定 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="3"> |
| | | 周期从星期 |
| | | <el-select clearable v-model="cycle01"> |
| | | <el-option |
| | | v-for="(item,index) of weekList" |
| | | :key="index" |
| | | :label="item.value" |
| | | :value="item.key" |
| | | :disabled="item.key === 1" |
| | | >{{item.value}}</el-option> |
| | | </el-select> |
| | | - |
| | | <el-select clearable v-model="cycle02"> |
| | | <el-option |
| | | v-for="(item,index) of weekList" |
| | | :key="index" |
| | | :label="item.value" |
| | | :value="item.key" |
| | | :disabled="item.key < cycle01 && item.key !== 1" |
| | | >{{item.value}}</el-option> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="4"> |
| | | 第 |
| | | <el-input-number v-model='average01' :min="1" :max="4" /> 周的星期 |
| | | <el-select clearable v-model="average02"> |
| | | <el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key">{{item.value}}</el-option> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="5"> |
| | | 本月最后一个星期 |
| | | <el-select clearable v-model="weekday"> |
| | | <el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key">{{item.value}}</el-option> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio v-model='radioValue' :label="6"> |
| | | 指定 |
| | | <el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%"> |
| | | <el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="String(item.key)">{{item.value}}</el-option> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | </el-form> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | radioValue: 2, |
| | | weekday: 2, |
| | | cycle01: 2, |
| | | cycle02: 3, |
| | | average01: 1, |
| | | average02: 2, |
| | | checkboxList: [], |
| | | weekList: [ |
| | | { |
| | | key: 2, |
| | | value: '星期一' |
| | | }, |
| | | { |
| | | key: 3, |
| | | value: '星期二' |
| | | }, |
| | | { |
| | | key: 4, |
| | | value: '星期三' |
| | | }, |
| | | { |
| | | key: 5, |
| | | value: '星期四' |
| | | }, |
| | | { |
| | | key: 6, |
| | | value: '星期五' |
| | | }, |
| | | { |
| | | key: 7, |
| | | value: '星期六' |
| | | }, |
| | | { |
| | | key: 1, |
| | | value: '星期日' |
| | | } |
| | | ], |
| | | checkNum: this.$options.propsData.check |
| | | } |
| | | }, |
| | | name: 'crontab-week', |
| | | props: ['check', 'cron'], |
| | | methods: { |
| | | // 单选按钮值变化时 |
| | | radioChange() { |
| | | if (this.radioValue !== 2 && this.cron.day !== '?') { |
| | | this.$emit('update', 'day', '?', 'week') |
| | | } |
| | | switch (this.radioValue) { |
| | | case 1: |
| | | this.$emit('update', 'week', '*') |
| | | break |
| | | case 2: |
| | | this.$emit('update', 'week', '?') |
| | | break |
| | | case 3: |
| | | this.$emit('update', 'week', this.cycleTotal) |
| | | break |
| | | case 4: |
| | | this.$emit('update', 'week', this.averageTotal) |
| | | break |
| | | case 5: |
| | | this.$emit('update', 'week', this.weekdayCheck + 'L') |
| | | break |
| | | case 6: |
| | | this.$emit('update', 'week', this.checkboxString) |
| | | break |
| | | } |
| | | }, |
| | | |
| | | // 周期两个值变化时 |
| | | cycleChange() { |
| | | if (this.radioValue == '3') { |
| | | this.$emit('update', 'week', this.cycleTotal) |
| | | } |
| | | }, |
| | | // 平均两个值变化时 |
| | | averageChange() { |
| | | if (this.radioValue == '4') { |
| | | this.$emit('update', 'week', this.averageTotal) |
| | | } |
| | | }, |
| | | // 最近工作日值变化时 |
| | | weekdayChange() { |
| | | if (this.radioValue == '5') { |
| | | this.$emit('update', 'week', this.weekday + 'L') |
| | | } |
| | | }, |
| | | // checkbox值变化时 |
| | | checkboxChange() { |
| | | if (this.radioValue == '6') { |
| | | this.$emit('update', 'week', this.checkboxString) |
| | | } |
| | | }, |
| | | }, |
| | | watch: { |
| | | 'radioValue': 'radioChange', |
| | | 'cycleTotal': 'cycleChange', |
| | | 'averageTotal': 'averageChange', |
| | | 'weekdayCheck': 'weekdayChange', |
| | | 'checkboxString': 'checkboxChange', |
| | | }, |
| | | computed: { |
| | | // 计算两个周期值 |
| | | cycleTotal: function () { |
| | | this.cycle01 = this.checkNum(this.cycle01, 1, 7) |
| | | this.cycle02 = this.checkNum(this.cycle02, 1, 7) |
| | | return this.cycle01 + '-' + this.cycle02 |
| | | }, |
| | | // 计算平均用到的值 |
| | | averageTotal: function () { |
| | | this.average01 = this.checkNum(this.average01, 1, 4) |
| | | this.average02 = this.checkNum(this.average02, 1, 7) |
| | | return this.average02 + '#' + this.average01 |
| | | }, |
| | | // 最近的工作日(格式) |
| | | weekdayCheck: function () { |
| | | this.weekday = this.checkNum(this.weekday, 1, 7) |
| | | return this.weekday |
| | | }, |
| | | // 计算勾选的checkbox值合集 |
| | | checkboxString: function () { |
| | | let str = this.checkboxList.join() |
| | | return str == '' ? '*' : str |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <el-form size="small"> |
| | | <el-form-item> |
| | | <el-radio :label="1" v-model='radioValue'> |
| | | 不填,允许的通配符[, - * /] |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio :label="2" v-model='radioValue'> |
| | | 每年 |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio :label="3" v-model='radioValue'> |
| | | 周期从 |
| | | <el-input-number v-model='cycle01' :min='fullYear' :max="2098" /> - |
| | | <el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : fullYear + 1" :max="2099" /> |
| | | </el-radio> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio :label="4" v-model='radioValue'> |
| | | 从 |
| | | <el-input-number v-model='average01' :min='fullYear' :max="2098"/> 年开始,每 |
| | | <el-input-number v-model='average02' :min="1" :max="2099 - average01 || fullYear" /> 年执行一次 |
| | | </el-radio> |
| | | |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-radio :label="5" v-model='radioValue'> |
| | | 指定 |
| | | <el-select clearable v-model="checkboxList" placeholder="可多选" multiple> |
| | | <el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item -1 + fullYear" /> |
| | | </el-select> |
| | | </el-radio> |
| | | </el-form-item> |
| | | </el-form> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | fullYear: 0, |
| | | radioValue: 1, |
| | | cycle01: 0, |
| | | cycle02: 0, |
| | | average01: 0, |
| | | average02: 1, |
| | | checkboxList: [], |
| | | checkNum: this.$options.propsData.check |
| | | } |
| | | }, |
| | | name: 'crontab-year', |
| | | props: ['check', 'month', 'cron'], |
| | | methods: { |
| | | // 单选按钮值变化时 |
| | | radioChange() { |
| | | switch (this.radioValue) { |
| | | case 1: |
| | | this.$emit('update', 'year', '') |
| | | break |
| | | case 2: |
| | | this.$emit('update', 'year', '*') |
| | | break |
| | | case 3: |
| | | this.$emit('update', 'year', this.cycleTotal) |
| | | break |
| | | case 4: |
| | | this.$emit('update', 'year', this.averageTotal) |
| | | break |
| | | case 5: |
| | | this.$emit('update', 'year', this.checkboxString) |
| | | break |
| | | } |
| | | }, |
| | | // 周期两个值变化时 |
| | | cycleChange() { |
| | | if (this.radioValue == '3') { |
| | | this.$emit('update', 'year', this.cycleTotal) |
| | | } |
| | | }, |
| | | // 平均两个值变化时 |
| | | averageChange() { |
| | | if (this.radioValue == '4') { |
| | | this.$emit('update', 'year', this.averageTotal) |
| | | } |
| | | }, |
| | | // checkbox值变化时 |
| | | checkboxChange() { |
| | | if (this.radioValue == '5') { |
| | | this.$emit('update', 'year', this.checkboxString) |
| | | } |
| | | } |
| | | }, |
| | | watch: { |
| | | 'radioValue': 'radioChange', |
| | | 'cycleTotal': 'cycleChange', |
| | | 'averageTotal': 'averageChange', |
| | | 'checkboxString': 'checkboxChange' |
| | | }, |
| | | computed: { |
| | | // 计算两个周期值 |
| | | cycleTotal: function () { |
| | | const cycle01 = this.checkNum(this.cycle01, this.fullYear, 2098) |
| | | const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : this.fullYear + 1, 2099) |
| | | return cycle01 + '-' + cycle02 |
| | | }, |
| | | // 计算平均用到的值 |
| | | averageTotal: function () { |
| | | const average01 = this.checkNum(this.average01, this.fullYear, 2098) |
| | | const average02 = this.checkNum(this.average02, 1, 2099 - average01 || this.fullYear) |
| | | return average01 + '/' + average02 |
| | | }, |
| | | // 计算勾选的checkbox值合集 |
| | | checkboxString: function () { |
| | | let str = this.checkboxList.join() |
| | | return str |
| | | } |
| | | }, |
| | | mounted: function () { |
| | | // 仅获取当前年份 |
| | | this.fullYear = Number(new Date().getFullYear()) |
| | | this.cycle01 = this.fullYear |
| | | this.average01 = this.fullYear |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | import Vue from 'vue' |
| | | import store from '@/store' |
| | | import DataDict from '@/utils/dict' |
| | | import { getDicts as getDicts } from '@/api/system/dict/data' |
| | | |
| | | function searchDictByKey(dict, key) { |
| | | if (key == null && key == "") { |
| | | return null |
| | | } |
| | | try { |
| | | for (let i = 0; i < dict.length; i++) { |
| | | if (dict[i].key == key) { |
| | | return dict[i].value |
| | | } |
| | | } |
| | | } catch (e) { |
| | | return null |
| | | } |
| | | } |
| | | |
| | | function install() { |
| | | Vue.use(DataDict, { |
| | | metas: { |
| | | '*': { |
| | | labelField: 'dictLabel', |
| | | valueField: 'dictValue', |
| | | request(dictMeta) { |
| | | const storeDict = searchDictByKey(store.getters.dict, dictMeta.type) |
| | | if (storeDict) { |
| | | return new Promise(resolve => { resolve(storeDict) }) |
| | | } else { |
| | | return new Promise((resolve, reject) => { |
| | | getDicts(dictMeta.type).then(res => { |
| | | store.dispatch('dict/setDict', { key: dictMeta.type, value: res.data }) |
| | | resolve(res.data) |
| | | }).catch(error => { |
| | | reject(error) |
| | | }) |
| | | }) |
| | | } |
| | | }, |
| | | }, |
| | | }, |
| | | }) |
| | | } |
| | | |
| | | export default { |
| | | install, |
| | | } |
New file |
| | |
| | | <template> |
| | | <div> |
| | | <template v-for="(item, index) in options"> |
| | | <template v-if="values.includes(item.value)"> |
| | | <span |
| | | v-if="(item.raw.listClass == 'default' || item.raw.listClass == '') && (item.raw.cssClass == '' || item.raw.cssClass == null)" |
| | | :key="item.value" |
| | | :index="index" |
| | | :class="item.raw.cssClass" |
| | | >{{ item.label + ' ' }}</span |
| | | > |
| | | <el-tag |
| | | v-else |
| | | :disable-transitions="true" |
| | | :key="item.value" |
| | | :index="index" |
| | | :type="item.raw.listClass == 'primary' ? '' : item.raw.listClass" |
| | | :class="item.raw.cssClass" |
| | | > |
| | | {{ item.label + ' ' }} |
| | | </el-tag> |
| | | </template> |
| | | </template> |
| | | <template v-if="unmatch && showValue"> |
| | | {{ unmatchArray | handleArray }} |
| | | </template> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: "DictTag", |
| | | props: { |
| | | options: { |
| | | type: Array, |
| | | default: null, |
| | | }, |
| | | value: [Number, String, Array], |
| | | // 当未找到匹配的数据时,显示value |
| | | showValue: { |
| | | type: Boolean, |
| | | default: true, |
| | | }, |
| | | separator: { |
| | | type: String, |
| | | default: "," |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | unmatchArray: [], // 记录未匹配的项 |
| | | } |
| | | }, |
| | | computed: { |
| | | values() { |
| | | if (this.value === null || typeof this.value === 'undefined' || this.value === '') return [] |
| | | return Array.isArray(this.value) ? this.value.map(item => '' + item) : String(this.value).split(this.separator) |
| | | }, |
| | | unmatch() { |
| | | this.unmatchArray = [] |
| | | // 没有value不显示 |
| | | if (this.value === null || typeof this.value === 'undefined' || this.value === '' || this.options.length === 0) return false |
| | | // 传入值为数组 |
| | | let unmatch = false // 添加一个标志来判断是否有未匹配项 |
| | | this.values.forEach(item => { |
| | | if (!this.options.some(v => v.value === item)) { |
| | | this.unmatchArray.push(item) |
| | | unmatch = true // 如果有未匹配项,将标志设置为true |
| | | } |
| | | }) |
| | | return unmatch // 返回标志的值 |
| | | }, |
| | | |
| | | }, |
| | | filters: { |
| | | handleArray(array) { |
| | | if (array.length === 0) return '' |
| | | return array.reduce((pre, cur) => { |
| | | return pre + ' ' + cur |
| | | }) |
| | | }, |
| | | } |
| | | } |
| | | </script> |
| | | <style scoped> |
| | | .el-tag + .el-tag { |
| | | margin-left: 10px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div> |
| | | <el-upload |
| | | :action="uploadUrl" |
| | | :before-upload="handleBeforeUpload" |
| | | :on-success="handleUploadSuccess" |
| | | :on-error="handleUploadError" |
| | | name="file" |
| | | :show-file-list="false" |
| | | :headers="headers" |
| | | style="display: none" |
| | | ref="upload" |
| | | v-if="this.type == 'url'" |
| | | > |
| | | </el-upload> |
| | | <div class="editor" ref="editor" :style="styles"></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import axios from "axios" |
| | | import Quill from "quill" |
| | | import "quill/dist/quill.core.css" |
| | | import "quill/dist/quill.snow.css" |
| | | import "quill/dist/quill.bubble.css" |
| | | import { getToken } from "@/utils/auth" |
| | | |
| | | export default { |
| | | name: "Editor", |
| | | props: { |
| | | /* 编辑器的内容 */ |
| | | value: { |
| | | type: String, |
| | | default: "", |
| | | }, |
| | | /* 高度 */ |
| | | height: { |
| | | type: Number, |
| | | default: null, |
| | | }, |
| | | /* 最小高度 */ |
| | | minHeight: { |
| | | type: Number, |
| | | default: null, |
| | | }, |
| | | /* 只读 */ |
| | | readOnly: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | /* 上传文件大小限制(MB) */ |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5, |
| | | }, |
| | | /* 类型(base64格式、url格式) */ |
| | | type: { |
| | | type: String, |
| | | default: "url", |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | uploadUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址 |
| | | headers: { |
| | | Authorization: "Bearer " + getToken() |
| | | }, |
| | | Quill: null, |
| | | currentValue: "", |
| | | options: { |
| | | theme: "snow", |
| | | bounds: document.body, |
| | | debug: "warn", |
| | | modules: { |
| | | // 工具栏配置 |
| | | toolbar: [ |
| | | ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线 |
| | | ["blockquote", "code-block"], // 引用 代码块 |
| | | [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表 |
| | | [{ indent: "-1" }, { indent: "+1" }], // 缩进 |
| | | [{ size: ["small", false, "large", "huge"] }], // 字体大小 |
| | | [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题 |
| | | [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色 |
| | | [{ align: [] }], // 对齐方式 |
| | | ["clean"], // 清除文本格式 |
| | | ["link", "image", "video"] // 链接、图片、视频 |
| | | ], |
| | | }, |
| | | placeholder: "请输入内容", |
| | | readOnly: this.readOnly, |
| | | }, |
| | | } |
| | | }, |
| | | computed: { |
| | | styles() { |
| | | let style = {} |
| | | if (this.minHeight) { |
| | | style.minHeight = `${this.minHeight}px` |
| | | } |
| | | if (this.height) { |
| | | style.height = `${this.height}px` |
| | | } |
| | | return style |
| | | } |
| | | }, |
| | | watch: { |
| | | value: { |
| | | handler(val) { |
| | | if (val !== this.currentValue) { |
| | | this.currentValue = val === null ? "" : val |
| | | if (this.Quill) { |
| | | this.Quill.clipboard.dangerouslyPasteHTML(this.currentValue) |
| | | } |
| | | } |
| | | }, |
| | | immediate: true, |
| | | }, |
| | | }, |
| | | mounted() { |
| | | this.init() |
| | | }, |
| | | beforeDestroy() { |
| | | this.Quill = null |
| | | }, |
| | | methods: { |
| | | init() { |
| | | const editor = this.$refs.editor |
| | | this.Quill = new Quill(editor, this.options) |
| | | // 如果设置了上传地址则自定义图片上传事件 |
| | | if (this.type == 'url') { |
| | | let toolbar = this.Quill.getModule("toolbar") |
| | | toolbar.addHandler("image", (value) => { |
| | | if (value) { |
| | | this.$refs.upload.$children[0].$refs.input.click() |
| | | } else { |
| | | this.quill.format("image", false) |
| | | } |
| | | }) |
| | | this.Quill.root.addEventListener('paste', this.handlePasteCapture, true) |
| | | } |
| | | this.Quill.clipboard.dangerouslyPasteHTML(this.currentValue) |
| | | this.Quill.on("text-change", (delta, oldDelta, source) => { |
| | | const html = this.$refs.editor.children[0].innerHTML |
| | | const text = this.Quill.getText() |
| | | const quill = this.Quill |
| | | this.currentValue = html |
| | | this.$emit("input", html) |
| | | this.$emit("on-change", { html, text, quill }) |
| | | }) |
| | | this.Quill.on("text-change", (delta, oldDelta, source) => { |
| | | this.$emit("on-text-change", delta, oldDelta, source) |
| | | }) |
| | | this.Quill.on("selection-change", (range, oldRange, source) => { |
| | | this.$emit("on-selection-change", range, oldRange, source) |
| | | }) |
| | | this.Quill.on("editor-change", (eventName, ...args) => { |
| | | this.$emit("on-editor-change", eventName, ...args) |
| | | }) |
| | | }, |
| | | // 上传前校检格式和大小 |
| | | handleBeforeUpload(file) { |
| | | const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"] |
| | | const isJPG = type.includes(file.type) |
| | | // 检验文件格式 |
| | | if (!isJPG) { |
| | | this.$message.error(`图片格式错误!`) |
| | | return false |
| | | } |
| | | // 校检文件大小 |
| | | if (this.fileSize) { |
| | | const isLt = file.size / 1024 / 1024 < this.fileSize |
| | | if (!isLt) { |
| | | this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`) |
| | | return false |
| | | } |
| | | } |
| | | return true |
| | | }, |
| | | handleUploadSuccess(res, file) { |
| | | // 如果上传成功 |
| | | if (res.code == 200) { |
| | | // 获取富文本组件实例 |
| | | let quill = this.Quill |
| | | // 获取光标所在位置 |
| | | let length = quill.getSelection().index |
| | | // 插入图片 res.url为服务器返回的图片地址 |
| | | quill.insertEmbed(length, "image", process.env.VUE_APP_BASE_API + res.fileName) |
| | | // 调整光标到最后 |
| | | quill.setSelection(length + 1) |
| | | } else { |
| | | this.$message.error("图片插入失败") |
| | | } |
| | | }, |
| | | handleUploadError() { |
| | | this.$message.error("图片插入失败") |
| | | }, |
| | | // 复制粘贴图片处理 |
| | | handlePasteCapture(e) { |
| | | const clipboard = e.clipboardData || window.clipboardData |
| | | if (clipboard && clipboard.items) { |
| | | for (let i = 0; i < clipboard.items.length; i++) { |
| | | const item = clipboard.items[i] |
| | | if (item.type.indexOf('image') !== -1) { |
| | | e.preventDefault() |
| | | const file = item.getAsFile() |
| | | this.insertImage(file) |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | insertImage(file) { |
| | | const formData = new FormData() |
| | | formData.append("file", file) |
| | | axios.post(this.uploadUrl, formData, { headers: { "Content-Type": "multipart/form-data", Authorization: this.headers.Authorization } }).then(res => { |
| | | this.handleUploadSuccess(res.data) |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | .editor, .ql-toolbar { |
| | | white-space: pre-wrap !important; |
| | | line-height: normal !important; |
| | | } |
| | | .quill-img { |
| | | display: none; |
| | | } |
| | | .ql-snow .ql-tooltip[data-mode="link"]::before { |
| | | content: "请输入链接地址:"; |
| | | } |
| | | .ql-snow .ql-tooltip.ql-editing a.ql-action::after { |
| | | border-right: 0px; |
| | | content: "保存"; |
| | | padding-right: 0px; |
| | | } |
| | | .ql-snow .ql-tooltip[data-mode="video"]::before { |
| | | content: "请输入视频地址:"; |
| | | } |
| | | .ql-snow .ql-picker.ql-size .ql-picker-label::before, |
| | | .ql-snow .ql-picker.ql-size .ql-picker-item::before { |
| | | content: "14px"; |
| | | } |
| | | .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before, |
| | | .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before { |
| | | content: "10px"; |
| | | } |
| | | .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before, |
| | | .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before { |
| | | content: "18px"; |
| | | } |
| | | .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before, |
| | | .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before { |
| | | content: "32px"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item::before { |
| | | content: "文本"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before { |
| | | content: "标题1"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before { |
| | | content: "标题2"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before { |
| | | content: "标题3"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before { |
| | | content: "标题4"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before { |
| | | content: "标题5"; |
| | | } |
| | | .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before, |
| | | .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before { |
| | | content: "标题6"; |
| | | } |
| | | .ql-snow .ql-picker.ql-font .ql-picker-label::before, |
| | | .ql-snow .ql-picker.ql-font .ql-picker-item::before { |
| | | content: "标准字体"; |
| | | } |
| | | .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before, |
| | | .ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before { |
| | | content: "衬线字体"; |
| | | } |
| | | .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before, |
| | | .ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before { |
| | | content: "等宽字体"; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="upload-file"> |
| | | <el-upload |
| | | multiple |
| | | :action="uploadFileUrl" |
| | | :before-upload="handleBeforeUpload" |
| | | :file-list="fileList" |
| | | :data="data" |
| | | :limit="limit" |
| | | :on-error="handleUploadError" |
| | | :on-exceed="handleExceed" |
| | | :on-success="handleUploadSuccess" |
| | | :show-file-list="false" |
| | | :headers="headers" |
| | | class="upload-file-uploader" |
| | | ref="fileUpload" |
| | | v-if="!disabled" |
| | | > |
| | | <!-- 上传按钮 --> |
| | | <el-button size="mini" type="primary">选取文件</el-button> |
| | | <!-- 上传提示 --> |
| | | <div class="el-upload__tip" slot="tip" v-if="showTip"> |
| | | 请上传 |
| | | <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template> |
| | | <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template> |
| | | 的文件 |
| | | </div> |
| | | </el-upload> |
| | | |
| | | <!-- 文件列表 --> |
| | | <transition-group ref="uploadFileList" class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul"> |
| | | <li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList"> |
| | | <el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank"> |
| | | <span class="el-icon-document"> {{ getFileName(file.name) }} </span> |
| | | </el-link> |
| | | <div class="ele-upload-list__item-content-action"> |
| | | <el-link :underline="false" @click="handleDelete(index)" type="danger" v-if="!disabled">删除</el-link> |
| | | </div> |
| | | </li> |
| | | </transition-group> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getToken } from "@/utils/auth" |
| | | import Sortable from 'sortablejs' |
| | | |
| | | export default { |
| | | name: "FileUpload", |
| | | props: { |
| | | // 值 |
| | | value: [String, Object, Array], |
| | | // 上传接口地址 |
| | | action: { |
| | | type: String, |
| | | default: "/common/upload" |
| | | }, |
| | | // 上传携带的参数 |
| | | data: { |
| | | type: Object |
| | | }, |
| | | // 数量限制 |
| | | limit: { |
| | | type: Number, |
| | | default: 5 |
| | | }, |
| | | // 大小限制(MB) |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5 |
| | | }, |
| | | // 文件类型, 例如['png', 'jpg', 'jpeg'] |
| | | fileType: { |
| | | type: Array, |
| | | default: () => ["doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "pdf"] |
| | | }, |
| | | // 是否显示提示 |
| | | isShowTip: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 禁用组件(仅查看文件) |
| | | disabled: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 拖动排序 |
| | | drag: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | number: 0, |
| | | uploadList: [], |
| | | baseUrl: process.env.VUE_APP_BASE_API, |
| | | uploadFileUrl: process.env.VUE_APP_BASE_API + this.action, // 上传文件服务器地址 |
| | | headers: { |
| | | Authorization: "Bearer " + getToken(), |
| | | }, |
| | | fileList: [] |
| | | } |
| | | }, |
| | | mounted() { |
| | | if (this.drag && !this.disabled) { |
| | | this.$nextTick(() => { |
| | | const element = this.$refs.uploadFileList?.$el || this.$refs.uploadFileList |
| | | Sortable.create(element, { |
| | | ghostClass: 'file-upload-darg', |
| | | onEnd: (evt) => { |
| | | const movedItem = this.fileList.splice(evt.oldIndex, 1)[0] |
| | | this.fileList.splice(evt.newIndex, 0, movedItem) |
| | | this.$emit("input", this.listToString(this.fileList)) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | }, |
| | | watch: { |
| | | value: { |
| | | handler(val) { |
| | | if (val) { |
| | | let temp = 1 |
| | | // 首先将值转为数组 |
| | | const list = Array.isArray(val) ? val : this.value.split(',') |
| | | // 然后将数组转为对象数组 |
| | | this.fileList = list.map(item => { |
| | | if (typeof item === "string") { |
| | | item = { name: item, url: item } |
| | | } |
| | | item.uid = item.uid || new Date().getTime() + temp++ |
| | | return item |
| | | }) |
| | | } else { |
| | | this.fileList = [] |
| | | return [] |
| | | } |
| | | }, |
| | | deep: true, |
| | | immediate: true |
| | | } |
| | | }, |
| | | computed: { |
| | | // 是否显示提示 |
| | | showTip() { |
| | | return this.isShowTip && (this.fileType || this.fileSize) |
| | | }, |
| | | }, |
| | | methods: { |
| | | // 上传前校检格式和大小 |
| | | handleBeforeUpload(file) { |
| | | // 校检文件类型 |
| | | if (this.fileType) { |
| | | const fileName = file.name.split('.') |
| | | const fileExt = fileName[fileName.length - 1] |
| | | const isTypeOk = this.fileType.indexOf(fileExt) >= 0 |
| | | if (!isTypeOk) { |
| | | this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}格式文件!`) |
| | | return false |
| | | } |
| | | } |
| | | // 校检文件名是否包含特殊字符 |
| | | if (file.name.includes(',')) { |
| | | this.$modal.msgError('文件名不正确,不能包含英文逗号!') |
| | | return false |
| | | } |
| | | // 校检文件大小 |
| | | if (this.fileSize) { |
| | | const isLt = file.size / 1024 / 1024 < this.fileSize |
| | | if (!isLt) { |
| | | this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`) |
| | | return false |
| | | } |
| | | } |
| | | this.$modal.loading("正在上传文件,请稍候...") |
| | | this.number++ |
| | | return true |
| | | }, |
| | | // 文件个数超出 |
| | | handleExceed() { |
| | | this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`) |
| | | }, |
| | | // 上传失败 |
| | | handleUploadError(err) { |
| | | this.$modal.msgError("上传文件失败,请重试") |
| | | this.$modal.closeLoading() |
| | | }, |
| | | // 上传成功回调 |
| | | handleUploadSuccess(res, file) { |
| | | if (res.code === 200) { |
| | | this.uploadList.push({ name: res.fileName, url: res.fileName }) |
| | | this.uploadedSuccessfully() |
| | | } else { |
| | | this.number-- |
| | | this.$modal.closeLoading() |
| | | this.$modal.msgError(res.msg) |
| | | this.$refs.fileUpload.handleRemove(file) |
| | | this.uploadedSuccessfully() |
| | | } |
| | | }, |
| | | // 删除文件 |
| | | handleDelete(index) { |
| | | this.fileList.splice(index, 1) |
| | | this.$emit("input", this.listToString(this.fileList)) |
| | | }, |
| | | // 上传结束处理 |
| | | uploadedSuccessfully() { |
| | | if (this.number > 0 && this.uploadList.length === this.number) { |
| | | this.fileList = this.fileList.concat(this.uploadList) |
| | | this.uploadList = [] |
| | | this.number = 0 |
| | | this.$emit("input", this.listToString(this.fileList)) |
| | | this.$modal.closeLoading() |
| | | } |
| | | }, |
| | | // 获取文件名称 |
| | | getFileName(name) { |
| | | // 如果是url那么取最后的名字 如果不是直接返回 |
| | | if (name.lastIndexOf("/") > -1) { |
| | | return name.slice(name.lastIndexOf("/") + 1) |
| | | } else { |
| | | return name |
| | | } |
| | | }, |
| | | // 对象转成指定字符串分隔 |
| | | listToString(list, separator) { |
| | | let strs = "" |
| | | separator = separator || "," |
| | | for (let i in list) { |
| | | strs += list[i].url + separator |
| | | } |
| | | return strs != '' ? strs.substr(0, strs.length - 1) : '' |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .file-upload-darg { |
| | | opacity: 0.5; |
| | | background: #c8ebfb; |
| | | } |
| | | .upload-file-uploader { |
| | | margin-bottom: 5px; |
| | | } |
| | | .upload-file-list .el-upload-list__item { |
| | | border: 1px solid #e4e7ed; |
| | | line-height: 2; |
| | | margin-bottom: 10px; |
| | | position: relative; |
| | | } |
| | | .upload-file-list .ele-upload-list__item-content { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | color: inherit; |
| | | } |
| | | .ele-upload-list__item-content-action .el-link { |
| | | margin-right: 10px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div style="padding: 0 15px;" @click="toggleClick"> |
| | | <svg |
| | | :class="{'is-active':isActive}" |
| | | class="hamburger" |
| | | viewBox="0 0 1024 1024" |
| | | xmlns="http://www.w3.org/2000/svg" |
| | | width="64" |
| | | height="64" |
| | | > |
| | | <path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" /> |
| | | </svg> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'Hamburger', |
| | | props: { |
| | | isActive: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }, |
| | | methods: { |
| | | toggleClick() { |
| | | this.$emit('toggleClick') |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .hamburger { |
| | | display: inline-block; |
| | | vertical-align: middle; |
| | | width: 20px; |
| | | height: 20px; |
| | | } |
| | | |
| | | .hamburger.is-active { |
| | | transform: rotate(180deg); |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="header-search"> |
| | | <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" /> |
| | | <el-dialog |
| | | :visible.sync="show" |
| | | width="600px" |
| | | @close="close" |
| | | :show-close="false" |
| | | append-to-body |
| | | > |
| | | <el-input |
| | | v-model="search" |
| | | ref="headerSearchSelectRef" |
| | | size="large" |
| | | @input="querySearch" |
| | | prefix-icon="el-icon-search" |
| | | placeholder="菜单搜索,支持标题、URL模糊查询" |
| | | clearable |
| | | @keyup.enter.native="selectActiveResult" |
| | | @keydown.up.native="navigateResult('up')" |
| | | @keydown.down.native="navigateResult('down')" |
| | | > |
| | | </el-input> |
| | | <el-scrollbar wrap-class="right-scrollbar-wrapper"> |
| | | <div class="result-wrap"> |
| | | <div class="search-item" v-for="(item, index) in options" :key="item.path" :style="activeStyle(index)" @mouseenter="activeIndex = index" @mouseleave="activeIndex = -1"> |
| | | <div class="left"> |
| | | <svg-icon class="menu-icon" :icon-class="item.icon" /> |
| | | </div> |
| | | <div class="search-info" @click="change(item)"> |
| | | <div class="menu-title"> |
| | | {{ item.title.join(" / ") }} |
| | | </div> |
| | | <div class="menu-path"> |
| | | {{ item.path }} |
| | | </div> |
| | | </div> |
| | | <svg-icon icon-class="enter" v-show="index === activeIndex"/> |
| | | </div> |
| | | </div> |
| | | </el-scrollbar> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import Fuse from 'fuse.js/dist/fuse.min.js' |
| | | import path from 'path' |
| | | import { isHttp } from '@/utils/validate' |
| | | |
| | | export default { |
| | | name: 'HeaderSearch', |
| | | data() { |
| | | return { |
| | | search: '', |
| | | options: [], |
| | | searchPool: [], |
| | | activeIndex: -1, |
| | | show: false, |
| | | fuse: undefined |
| | | } |
| | | }, |
| | | computed: { |
| | | theme() { |
| | | return this.$store.state.settings.theme |
| | | }, |
| | | routes() { |
| | | return this.$store.getters.defaultRoutes |
| | | } |
| | | }, |
| | | watch: { |
| | | routes() { |
| | | this.searchPool = this.generateRoutes(this.routes) |
| | | }, |
| | | searchPool(list) { |
| | | this.initFuse(list) |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.searchPool = this.generateRoutes(this.routes) |
| | | }, |
| | | methods: { |
| | | click() { |
| | | this.show = !this.show |
| | | if (this.show) { |
| | | this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.focus() |
| | | this.options = this.searchPool |
| | | } |
| | | }, |
| | | close() { |
| | | this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.blur() |
| | | this.search = '' |
| | | this.options = [] |
| | | this.show = false |
| | | this.activeIndex = -1 |
| | | }, |
| | | change(val) { |
| | | const path = val.path |
| | | const query = val.query |
| | | if(isHttp(val.path)) { |
| | | // http(s):// 路径新窗口打开 |
| | | const pindex = path.indexOf("http") |
| | | window.open(path.substr(pindex, path.length), "_blank") |
| | | } else { |
| | | if (query) { |
| | | this.$router.push({ path: path, query: JSON.parse(query) }) |
| | | } else { |
| | | this.$router.push(path) |
| | | } |
| | | } |
| | | this.search = '' |
| | | this.options = [] |
| | | this.$nextTick(() => { |
| | | this.show = false |
| | | }) |
| | | }, |
| | | initFuse(list) { |
| | | this.fuse = new Fuse(list, { |
| | | shouldSort: true, |
| | | threshold: 0.4, |
| | | location: 0, |
| | | distance: 100, |
| | | minMatchCharLength: 1, |
| | | keys: [{ |
| | | name: 'title', |
| | | weight: 0.7 |
| | | }, { |
| | | name: 'path', |
| | | weight: 0.3 |
| | | }] |
| | | }) |
| | | }, |
| | | // Filter out the routes that can be displayed in the sidebar |
| | | // And generate the internationalized title |
| | | generateRoutes(routes, basePath = '/', prefixTitle = []) { |
| | | let res = [] |
| | | |
| | | for (const router of routes) { |
| | | // skip hidden router |
| | | if (router.hidden) { continue } |
| | | |
| | | const data = { |
| | | path: !isHttp(router.path) ? path.resolve(basePath, router.path) : router.path, |
| | | title: [...prefixTitle], |
| | | icon: '' |
| | | } |
| | | |
| | | if (router.meta && router.meta.title) { |
| | | data.title = [...data.title, router.meta.title] |
| | | data.icon = router.meta.icon |
| | | |
| | | if (router.redirect !== 'noRedirect') { |
| | | // only push the routes with title |
| | | // special case: need to exclude parent router without redirect |
| | | res.push(data) |
| | | } |
| | | } |
| | | |
| | | if (router.query) { |
| | | data.query = router.query |
| | | } |
| | | |
| | | // recursive child routes |
| | | if (router.children) { |
| | | const tempRoutes = this.generateRoutes(router.children, data.path, data.title) |
| | | if (tempRoutes.length >= 1) { |
| | | res = [...res, ...tempRoutes] |
| | | } |
| | | } |
| | | } |
| | | return res |
| | | }, |
| | | querySearch(query) { |
| | | this.activeIndex = -1 |
| | | if (query !== '') { |
| | | this.options = this.fuse.search(query).map((item) => item.item) ?? this.searchPool |
| | | } else { |
| | | this.options = this.searchPool |
| | | } |
| | | }, |
| | | activeStyle(index) { |
| | | if (index !== this.activeIndex) return {} |
| | | return { |
| | | "background-color": this.theme, |
| | | "color": "#fff" |
| | | } |
| | | }, |
| | | navigateResult(direction) { |
| | | if (direction === "up") { |
| | | this.activeIndex = this.activeIndex <= 0 ? this.options.length - 1 : this.activeIndex - 1 |
| | | } else if (direction === "down") { |
| | | this.activeIndex = this.activeIndex >= this.options.length - 1 ? 0 : this.activeIndex + 1 |
| | | } |
| | | }, |
| | | selectActiveResult() { |
| | | if (this.options.length > 0 && this.activeIndex >= 0) { |
| | | this.change(this.options[this.activeIndex]) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | ::v-deep { |
| | | .el-dialog__header { |
| | | padding: 0 !important; |
| | | } |
| | | } |
| | | |
| | | .header-search { |
| | | .search-icon { |
| | | cursor: pointer; |
| | | font-size: 18px; |
| | | vertical-align: middle; |
| | | } |
| | | } |
| | | |
| | | .result-wrap { |
| | | height: 280px; |
| | | margin: 6px 0; |
| | | |
| | | .search-item { |
| | | display: flex; |
| | | height: 48px; |
| | | align-items: center; |
| | | padding-right: 10px; |
| | | |
| | | .left { |
| | | width: 60px; |
| | | text-align: center; |
| | | |
| | | .menu-icon { |
| | | width: 18px; |
| | | height: 18px; |
| | | } |
| | | } |
| | | |
| | | .search-info { |
| | | padding-left: 5px; |
| | | margin-top: 10px; |
| | | width: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: flex-start; |
| | | flex: 1; |
| | | |
| | | .menu-title, |
| | | .menu-path { |
| | | height: 20px; |
| | | } |
| | | .menu-path { |
| | | color: #ccc; |
| | | font-size: 10px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .search-item:hover { |
| | | cursor: pointer; |
| | | } |
| | | } |
| | | </style> |
| | | |
New file |
| | |
| | | <!-- @author zhengjie --> |
| | | <template> |
| | | <div class="icon-body"> |
| | | <el-input v-model="name" class="icon-search" clearable placeholder="请输入图标名称" @clear="filterIcons" @input="filterIcons"> |
| | | <i slot="suffix" class="el-icon-search el-input__icon" /> |
| | | </el-input> |
| | | <div class="icon-list"> |
| | | <div class="list-container"> |
| | | <div v-for="(item, index) in iconList" class="icon-item-wrapper" :key="index" @click="selectedIcon(item)"> |
| | | <div :class="['icon-item', { active: activeIcon === item }]"> |
| | | <svg-icon :icon-class="item" class-name="icon" style="height: 25px;width: 16px;"/> |
| | | <span>{{ item }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import icons from './requireIcons' |
| | | export default { |
| | | name: 'IconSelect', |
| | | props: { |
| | | activeIcon: { |
| | | type: String |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | name: '', |
| | | iconList: icons |
| | | } |
| | | }, |
| | | methods: { |
| | | filterIcons() { |
| | | this.iconList = icons |
| | | if (this.name) { |
| | | this.iconList = this.iconList.filter(item => item.includes(this.name)) |
| | | } |
| | | }, |
| | | selectedIcon(name) { |
| | | this.$emit('selected', name) |
| | | document.body.click() |
| | | }, |
| | | reset() { |
| | | this.name = '' |
| | | this.iconList = icons |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style rel="stylesheet/scss" lang="scss" scoped> |
| | | .icon-body { |
| | | width: 100%; |
| | | padding: 10px; |
| | | .icon-search { |
| | | position: relative; |
| | | margin-bottom: 5px; |
| | | } |
| | | .icon-list { |
| | | height: 200px; |
| | | overflow: auto; |
| | | .list-container { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | .icon-item-wrapper { |
| | | width: calc(100% / 3); |
| | | height: 25px; |
| | | line-height: 25px; |
| | | cursor: pointer; |
| | | display: flex; |
| | | .icon-item { |
| | | display: flex; |
| | | max-width: 100%; |
| | | height: 100%; |
| | | padding: 0 5px; |
| | | &:hover { |
| | | background: #ececec; |
| | | border-radius: 5px; |
| | | } |
| | | .icon { |
| | | flex-shrink: 0; |
| | | } |
| | | span { |
| | | display: inline-block; |
| | | vertical-align: -0.15em; |
| | | fill: currentColor; |
| | | padding-left: 2px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | | .icon-item.active { |
| | | background: #ececec; |
| | | border-radius: 5px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | |
| | | const req = require.context('../../assets/icons/svg', false, /\.svg$/) |
| | | const requireAll = requireContext => requireContext.keys() |
| | | |
| | | const re = /\.\/(.*)\.svg/ |
| | | |
| | | const icons = requireAll(req).map(i => { |
| | | return i.match(re)[1] |
| | | }) |
| | | |
| | | export default icons |
New file |
| | |
| | | <template> |
| | | <el-image |
| | | :src="`${realSrc}`" |
| | | fit="cover" |
| | | :style="`width:${realWidth};height:${realHeight};`" |
| | | :preview-src-list="realSrcList" |
| | | > |
| | | <div slot="error" class="image-slot"> |
| | | <i class="el-icon-picture-outline"></i> |
| | | </div> |
| | | </el-image> |
| | | </template> |
| | | |
| | | <script> |
| | | import { isExternal } from "@/utils/validate" |
| | | |
| | | export default { |
| | | name: "ImagePreview", |
| | | props: { |
| | | src: { |
| | | type: String, |
| | | default: "" |
| | | }, |
| | | width: { |
| | | type: [Number, String], |
| | | default: "" |
| | | }, |
| | | height: { |
| | | type: [Number, String], |
| | | default: "" |
| | | } |
| | | }, |
| | | computed: { |
| | | realSrc() { |
| | | if (!this.src) { |
| | | return |
| | | } |
| | | let real_src = this.src.split(",")[0] |
| | | if (isExternal(real_src)) { |
| | | return real_src |
| | | } |
| | | return process.env.VUE_APP_BASE_API + real_src |
| | | }, |
| | | realSrcList() { |
| | | if (!this.src) { |
| | | return |
| | | } |
| | | let real_src_list = this.src.split(",") |
| | | let srcList = [] |
| | | real_src_list.forEach(item => { |
| | | if (isExternal(item)) { |
| | | return srcList.push(item) |
| | | } |
| | | return srcList.push(process.env.VUE_APP_BASE_API + item) |
| | | }) |
| | | return srcList |
| | | }, |
| | | realWidth() { |
| | | return typeof this.width == "string" ? this.width : `${this.width}px` |
| | | }, |
| | | realHeight() { |
| | | return typeof this.height == "string" ? this.height : `${this.height}px` |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .el-image { |
| | | border-radius: 5px; |
| | | background-color: #ebeef5; |
| | | box-shadow: 0 0 5px 1px #ccc; |
| | | ::v-deep .el-image__inner { |
| | | transition: all 0.3s; |
| | | cursor: pointer; |
| | | &:hover { |
| | | transform: scale(1.2); |
| | | } |
| | | } |
| | | ::v-deep .image-slot { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | width: 100%; |
| | | height: 100%; |
| | | color: #909399; |
| | | font-size: 30px; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="component-upload-image"> |
| | | <el-upload |
| | | multiple |
| | | :disabled="disabled" |
| | | :action="uploadImgUrl" |
| | | list-type="picture-card" |
| | | :on-success="handleUploadSuccess" |
| | | :before-upload="handleBeforeUpload" |
| | | :data="data" |
| | | :limit="limit" |
| | | :on-error="handleUploadError" |
| | | :on-exceed="handleExceed" |
| | | ref="imageUpload" |
| | | :on-remove="handleDelete" |
| | | :show-file-list="true" |
| | | :headers="headers" |
| | | :file-list="fileList" |
| | | :on-preview="handlePictureCardPreview" |
| | | :class="{hide: this.fileList.length >= this.limit}" |
| | | > |
| | | <i class="el-icon-plus"></i> |
| | | </el-upload> |
| | | |
| | | <!-- 上传提示 --> |
| | | <div class="el-upload__tip" slot="tip" v-if="showTip && !disabled"> |
| | | 请上传 |
| | | <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template> |
| | | <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template> |
| | | 的文件 |
| | | </div> |
| | | |
| | | <el-dialog |
| | | :visible.sync="dialogVisible" |
| | | title="预览" |
| | | width="800" |
| | | append-to-body |
| | | > |
| | | <img |
| | | :src="dialogImageUrl" |
| | | style="display: block; max-width: 100%; margin: 0 auto" |
| | | /> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getToken } from "@/utils/auth" |
| | | import { isExternal } from "@/utils/validate" |
| | | import Sortable from 'sortablejs' |
| | | |
| | | export default { |
| | | props: { |
| | | value: [String, Object, Array], |
| | | // 上传接口地址 |
| | | action: { |
| | | type: String, |
| | | default: "/common/upload" |
| | | }, |
| | | // 上传携带的参数 |
| | | data: { |
| | | type: Object |
| | | }, |
| | | // 图片数量限制 |
| | | limit: { |
| | | type: Number, |
| | | default: 5 |
| | | }, |
| | | // 大小限制(MB) |
| | | fileSize: { |
| | | type: Number, |
| | | default: 5 |
| | | }, |
| | | // 文件类型, 例如['png', 'jpg', 'jpeg'] |
| | | fileType: { |
| | | type: Array, |
| | | default: () => ["png", "jpg", "jpeg"] |
| | | }, |
| | | // 是否显示提示 |
| | | isShowTip: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | // 禁用组件(仅查看图片) |
| | | disabled: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 拖动排序 |
| | | drag: { |
| | | type: Boolean, |
| | | default: true |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | number: 0, |
| | | uploadList: [], |
| | | dialogImageUrl: "", |
| | | dialogVisible: false, |
| | | hideUpload: false, |
| | | baseUrl: process.env.VUE_APP_BASE_API, |
| | | uploadImgUrl: process.env.VUE_APP_BASE_API + this.action, // 上传的图片服务器地址 |
| | | headers: { |
| | | Authorization: "Bearer " + getToken(), |
| | | }, |
| | | fileList: [] |
| | | } |
| | | }, |
| | | mounted() { |
| | | if (this.drag && !this.disabled) { |
| | | this.$nextTick(() => { |
| | | const element = this.$refs.imageUpload?.$el?.querySelector('.el-upload-list') |
| | | Sortable.create(element, { |
| | | onEnd: (evt) => { |
| | | const movedItem = this.fileList.splice(evt.oldIndex, 1)[0] |
| | | this.fileList.splice(evt.newIndex, 0, movedItem) |
| | | this.$emit("input", this.listToString(this.fileList)) |
| | | } |
| | | }) |
| | | }) |
| | | } |
| | | }, |
| | | watch: { |
| | | value: { |
| | | handler(val) { |
| | | if (val) { |
| | | // 首先将值转为数组 |
| | | const list = Array.isArray(val) ? val : this.value.split(',') |
| | | // 然后将数组转为对象数组 |
| | | this.fileList = list.map(item => { |
| | | if (typeof item === "string") { |
| | | if (item.indexOf(this.baseUrl) === -1 && !isExternal(item)) { |
| | | item = { name: this.baseUrl + item, url: this.baseUrl + item } |
| | | } else { |
| | | item = { name: item, url: item } |
| | | } |
| | | } |
| | | return item |
| | | }) |
| | | } else { |
| | | this.fileList = [] |
| | | return [] |
| | | } |
| | | }, |
| | | deep: true, |
| | | immediate: true |
| | | } |
| | | }, |
| | | computed: { |
| | | // 是否显示提示 |
| | | showTip() { |
| | | return this.isShowTip && (this.fileType || this.fileSize) |
| | | }, |
| | | }, |
| | | methods: { |
| | | // 上传前loading加载 |
| | | handleBeforeUpload(file) { |
| | | let isImg = false |
| | | if (this.fileType.length) { |
| | | let fileExtension = "" |
| | | if (file.name.lastIndexOf(".") > -1) { |
| | | fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1) |
| | | } |
| | | isImg = this.fileType.some(type => { |
| | | if (file.type.indexOf(type) > -1) return true |
| | | if (fileExtension && fileExtension.indexOf(type) > -1) return true |
| | | return false |
| | | }) |
| | | } else { |
| | | isImg = file.type.indexOf("image") > -1 |
| | | } |
| | | |
| | | if (!isImg) { |
| | | this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}图片格式文件!`) |
| | | return false |
| | | } |
| | | if (file.name.includes(',')) { |
| | | this.$modal.msgError('文件名不正确,不能包含英文逗号!') |
| | | return false |
| | | } |
| | | if (this.fileSize) { |
| | | const isLt = file.size / 1024 / 1024 < this.fileSize |
| | | if (!isLt) { |
| | | this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`) |
| | | return false |
| | | } |
| | | } |
| | | this.$modal.loading("正在上传图片,请稍候...") |
| | | this.number++ |
| | | }, |
| | | // 文件个数超出 |
| | | handleExceed() { |
| | | this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`) |
| | | }, |
| | | // 上传成功回调 |
| | | handleUploadSuccess(res, file) { |
| | | if (res.code === 200) { |
| | | this.uploadList.push({ name: res.fileName, url: res.fileName }) |
| | | this.uploadedSuccessfully() |
| | | } else { |
| | | this.number-- |
| | | this.$modal.closeLoading() |
| | | this.$modal.msgError(res.msg) |
| | | this.$refs.imageUpload.handleRemove(file) |
| | | this.uploadedSuccessfully() |
| | | } |
| | | }, |
| | | // 删除图片 |
| | | handleDelete(file) { |
| | | const findex = this.fileList.map(f => f.name).indexOf(file.name) |
| | | if (findex > -1) { |
| | | this.fileList.splice(findex, 1) |
| | | this.$emit("input", this.listToString(this.fileList)) |
| | | } |
| | | }, |
| | | // 上传失败 |
| | | handleUploadError() { |
| | | this.$modal.msgError("上传图片失败,请重试") |
| | | this.$modal.closeLoading() |
| | | }, |
| | | // 上传结束处理 |
| | | uploadedSuccessfully() { |
| | | if (this.number > 0 && this.uploadList.length === this.number) { |
| | | this.fileList = this.fileList.concat(this.uploadList) |
| | | this.uploadList = [] |
| | | this.number = 0 |
| | | this.$emit("input", this.listToString(this.fileList)) |
| | | this.$modal.closeLoading() |
| | | } |
| | | }, |
| | | // 预览 |
| | | handlePictureCardPreview(file) { |
| | | this.dialogImageUrl = file.url |
| | | this.dialogVisible = true |
| | | }, |
| | | // 对象转成指定字符串分隔 |
| | | listToString(list, separator) { |
| | | let strs = "" |
| | | separator = separator || "," |
| | | for (let i in list) { |
| | | if (list[i].url) { |
| | | strs += list[i].url.replace(this.baseUrl, "") + separator |
| | | } |
| | | } |
| | | return strs != '' ? strs.substr(0, strs.length - 1) : '' |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style scoped lang="scss"> |
| | | // .el-upload--picture-card 控制加号部分 |
| | | ::v-deep.hide .el-upload--picture-card { |
| | | display: none; |
| | | } |
| | | |
| | | ::v-deep .el-upload-list--picture-card.is-disabled + .el-upload--picture-card { |
| | | display: none !important; |
| | | } |
| | | |
| | | // 去掉动画效果 |
| | | ::v-deep .el-list-enter-active, |
| | | ::v-deep .el-list-leave-active { |
| | | transition: all 0s; |
| | | } |
| | | |
| | | ::v-deep .el-list-enter, .el-list-leave-active { |
| | | opacity: 0; |
| | | transform: translateY(0); |
| | | } |
| | | </style> |
| | | |
New file |
| | |
| | | <template> |
| | | <div :class="{'hidden':hidden}" class="pagination-container"> |
| | | <el-pagination |
| | | :background="background" |
| | | :current-page.sync="currentPage" |
| | | :page-size.sync="pageSize" |
| | | :layout="layout" |
| | | :page-sizes="pageSizes" |
| | | :pager-count="pagerCount" |
| | | :total="total" |
| | | v-bind="$attrs" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { scrollTo } from '@/utils/scroll-to' |
| | | |
| | | export default { |
| | | name: 'Pagination', |
| | | props: { |
| | | total: { |
| | | required: true, |
| | | type: Number |
| | | }, |
| | | page: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | limit: { |
| | | type: Number, |
| | | default: 20 |
| | | }, |
| | | pageSizes: { |
| | | type: Array, |
| | | default() { |
| | | return [10, 20, 30, 50] |
| | | } |
| | | }, |
| | | // 移动端页码按钮的数量端默认值5 |
| | | pagerCount: { |
| | | type: Number, |
| | | default: document.body.clientWidth < 992 ? 5 : 7 |
| | | }, |
| | | layout: { |
| | | type: String, |
| | | default: 'total, sizes, prev, pager, next, jumper' |
| | | }, |
| | | background: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | autoScroll: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | hidden: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | } |
| | | }, |
| | | computed: { |
| | | currentPage: { |
| | | get() { |
| | | return this.page |
| | | }, |
| | | set(val) { |
| | | this.$emit('update:page', val) |
| | | } |
| | | }, |
| | | pageSize: { |
| | | get() { |
| | | return this.limit |
| | | }, |
| | | set(val) { |
| | | this.$emit('update:limit', val) |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | handleSizeChange(val) { |
| | | if (this.currentPage * val > this.total) { |
| | | this.currentPage = 1 |
| | | } |
| | | this.$emit('pagination', { page: this.currentPage, limit: val }) |
| | | if (this.autoScroll) { |
| | | scrollTo(0, 800) |
| | | } |
| | | }, |
| | | handleCurrentChange(val) { |
| | | this.$emit('pagination', { page: val, limit: this.pageSize }) |
| | | if (this.autoScroll) { |
| | | scrollTo(0, 800) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .pagination-container { |
| | | background: #fff; |
| | | } |
| | | .pagination-container.hidden { |
| | | display: none; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div :style="{zIndex:zIndex,height:height,width:width}" class="pan-item"> |
| | | <div class="pan-info"> |
| | | <div class="pan-info-roles-container"> |
| | | <slot /> |
| | | </div> |
| | | </div> |
| | | <div :style="{backgroundImage: `url(${image})`}" class="pan-thumb"></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'PanThumb', |
| | | props: { |
| | | image: { |
| | | type: String, |
| | | required: true |
| | | }, |
| | | zIndex: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | width: { |
| | | type: String, |
| | | default: '150px' |
| | | }, |
| | | height: { |
| | | type: String, |
| | | default: '150px' |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .pan-item { |
| | | width: 200px; |
| | | height: 200px; |
| | | border-radius: 50%; |
| | | display: inline-block; |
| | | position: relative; |
| | | cursor: default; |
| | | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); |
| | | } |
| | | |
| | | .pan-info-roles-container { |
| | | padding: 20px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .pan-thumb { |
| | | width: 100%; |
| | | height: 100%; |
| | | background-position: center center; |
| | | background-size: cover; |
| | | border-radius: 50%; |
| | | overflow: hidden; |
| | | position: absolute; |
| | | transform-origin: 95% 40%; |
| | | transition: all 0.3s ease-in-out; |
| | | } |
| | | |
| | | /* .pan-thumb:after { |
| | | content: ''; |
| | | width: 8px; |
| | | height: 8px; |
| | | position: absolute; |
| | | border-radius: 50%; |
| | | top: 40%; |
| | | left: 95%; |
| | | margin: -4px 0 0 -4px; |
| | | background: radial-gradient(ellipse at center, rgba(14, 14, 14, 1) 0%, rgba(125, 126, 125, 1) 100%); |
| | | box-shadow: 0 0 1px rgba(255, 255, 255, 0.9); |
| | | } */ |
| | | |
| | | .pan-info { |
| | | position: absolute; |
| | | width: inherit; |
| | | height: inherit; |
| | | border-radius: 50%; |
| | | overflow: hidden; |
| | | box-shadow: inset 0 0 0 5px rgba(0, 0, 0, 0.05); |
| | | } |
| | | |
| | | .pan-info h3 { |
| | | color: #fff; |
| | | text-transform: uppercase; |
| | | position: relative; |
| | | letter-spacing: 2px; |
| | | font-size: 18px; |
| | | margin: 0 60px; |
| | | padding: 22px 0 0 0; |
| | | height: 85px; |
| | | font-family: 'Open Sans', Arial, sans-serif; |
| | | text-shadow: 0 0 1px #fff, 0 1px 2px rgba(0, 0, 0, 0.3); |
| | | } |
| | | |
| | | .pan-info p { |
| | | color: #fff; |
| | | padding: 10px 5px; |
| | | font-style: italic; |
| | | margin: 0 30px; |
| | | font-size: 12px; |
| | | border-top: 1px solid rgba(255, 255, 255, 0.5); |
| | | } |
| | | |
| | | .pan-info p a { |
| | | display: block; |
| | | color: #333; |
| | | width: 80px; |
| | | height: 80px; |
| | | background: rgba(255, 255, 255, 0.3); |
| | | border-radius: 50%; |
| | | color: #fff; |
| | | font-style: normal; |
| | | font-weight: 700; |
| | | text-transform: uppercase; |
| | | font-size: 9px; |
| | | letter-spacing: 1px; |
| | | padding-top: 24px; |
| | | margin: 7px auto 0; |
| | | font-family: 'Open Sans', Arial, sans-serif; |
| | | opacity: 0; |
| | | transition: transform 0.3s ease-in-out 0.2s, opacity 0.3s ease-in-out 0.2s, background 0.2s linear 0s; |
| | | transform: translateX(60px) rotate(90deg); |
| | | } |
| | | |
| | | .pan-info p a:hover { |
| | | background: rgba(255, 255, 255, 0.5); |
| | | } |
| | | |
| | | .pan-item:hover .pan-thumb { |
| | | transform: rotate(-110deg); |
| | | } |
| | | |
| | | .pan-item:hover .pan-info p a { |
| | | opacity: 1; |
| | | transform: translateX(0px) rotate(0deg); |
| | | } |
| | | </style> |
New file |
| | |
| | | <template > |
| | | <router-view /> |
| | | </template> |
New file |
| | |
| | | <template> |
| | | <div class="top-right-btn" :style="style"> |
| | | <el-row> |
| | | <el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search"> |
| | | <el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()" /> |
| | | </el-tooltip> |
| | | <el-tooltip class="item" effect="dark" content="刷新" placement="top"> |
| | | <el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" /> |
| | | </el-tooltip> |
| | | <el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns"> |
| | | <el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" v-if="showColumnsType == 'transfer'"/> |
| | | <el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px" v-if="showColumnsType == 'checkbox'"> |
| | | <el-button size="mini" circle icon="el-icon-menu" /> |
| | | <el-dropdown-menu slot="dropdown"> |
| | | <!-- 全选/反选 按钮 --> |
| | | <el-dropdown-item> |
| | | <el-checkbox :indeterminate="isIndeterminate" v-model="isChecked" @change="toggleCheckAll"> 列展示 </el-checkbox> |
| | | </el-dropdown-item> |
| | | <div class="check-line"></div> |
| | | <template v-for="item in columns"> |
| | | <el-dropdown-item :key="item.key"> |
| | | <el-checkbox v-model="item.visible" @change="checkboxChange($event, item.label)" :label="item.label" /> |
| | | </el-dropdown-item> |
| | | </template> |
| | | </el-dropdown-menu> |
| | | </el-dropdown> |
| | | </el-tooltip> |
| | | </el-row> |
| | | <el-dialog :title="title" :visible.sync="open" append-to-body> |
| | | <el-transfer |
| | | :titles="['显示', '隐藏']" |
| | | v-model="value" |
| | | :data="columns" |
| | | @change="dataChange" |
| | | ></el-transfer> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | <script> |
| | | export default { |
| | | name: "RightToolbar", |
| | | data() { |
| | | return { |
| | | // 显隐数据 |
| | | value: [], |
| | | // 弹出层标题 |
| | | title: "显示/隐藏", |
| | | // 是否显示弹出层 |
| | | open: false |
| | | } |
| | | }, |
| | | props: { |
| | | /* 是否显示检索条件 */ |
| | | showSearch: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | /* 显隐列信息 */ |
| | | columns: { |
| | | type: Array |
| | | }, |
| | | /* 是否显示检索图标 */ |
| | | search: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | /* 显隐列类型(transfer穿梭框、checkbox复选框) */ |
| | | showColumnsType: { |
| | | type: String, |
| | | default: "checkbox" |
| | | }, |
| | | /* 右外边距 */ |
| | | gutter: { |
| | | type: Number, |
| | | default: 10 |
| | | }, |
| | | }, |
| | | computed: { |
| | | style() { |
| | | const ret = {} |
| | | if (this.gutter) { |
| | | ret.marginRight = `${this.gutter / 2}px` |
| | | } |
| | | return ret |
| | | }, |
| | | isChecked: { |
| | | get() { |
| | | return this.columns.every((col) => col.visible) |
| | | }, |
| | | set() {} |
| | | }, |
| | | isIndeterminate() { |
| | | return this.columns.some((col) => col.visible) && !this.isChecked |
| | | } |
| | | }, |
| | | created() { |
| | | if (this.showColumnsType == 'transfer') { |
| | | // 显隐列初始默认隐藏列 |
| | | for (let item in this.columns) { |
| | | if (this.columns[item].visible === false) { |
| | | this.value.push(parseInt(item)) |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | // 搜索 |
| | | toggleSearch() { |
| | | this.$emit("update:showSearch", !this.showSearch) |
| | | }, |
| | | // 刷新 |
| | | refresh() { |
| | | this.$emit("queryTable") |
| | | }, |
| | | // 右侧列表元素变化 |
| | | dataChange(data) { |
| | | for (let item in this.columns) { |
| | | const key = this.columns[item].key |
| | | this.columns[item].visible = !data.includes(key) |
| | | } |
| | | }, |
| | | // 打开显隐列dialog |
| | | showColumn() { |
| | | this.open = true |
| | | }, |
| | | // 单勾选 |
| | | checkboxChange(event, label) { |
| | | this.columns.filter(item => item.label == label)[0].visible = event |
| | | }, |
| | | // 切换全选/反选 |
| | | toggleCheckAll() { |
| | | const newValue = !this.isChecked |
| | | this.columns.forEach((col) => (col.visible = newValue)) |
| | | } |
| | | }, |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | ::v-deep .el-transfer__button { |
| | | border-radius: 50%; |
| | | padding: 12px; |
| | | display: block; |
| | | margin-left: 0px; |
| | | } |
| | | ::v-deep .el-transfer__button:first-child { |
| | | margin-bottom: 10px; |
| | | } |
| | | .check-line { |
| | | width: 90%; |
| | | height: 1px; |
| | | background-color: #ccc; |
| | | margin: 3px auto; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div> |
| | | <svg-icon icon-class="question" @click="goto" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'RuoYiDoc', |
| | | data() { |
| | | return { |
| | | url: 'http://doc.ruoyi.vip/ruoyi-vue' |
| | | } |
| | | }, |
| | | methods: { |
| | | goto() { |
| | | window.open(this.url) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div> |
| | | <svg-icon icon-class="github" @click="goto" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'RuoYiGit', |
| | | data() { |
| | | return { |
| | | url: 'https://gitee.com/y_project/RuoYi-Vue' |
| | | } |
| | | }, |
| | | methods: { |
| | | goto() { |
| | | window.open(this.url) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div> |
| | | <svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" @click="click" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import screenfull from 'screenfull' |
| | | |
| | | export default { |
| | | name: 'Screenfull', |
| | | data() { |
| | | return { |
| | | isFullscreen: false |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.init() |
| | | }, |
| | | beforeDestroy() { |
| | | this.destroy() |
| | | }, |
| | | methods: { |
| | | click() { |
| | | if (!screenfull.isEnabled) { |
| | | this.$message({ message: '你的浏览器不支持全屏', type: 'warning' }) |
| | | return false |
| | | } |
| | | screenfull.toggle() |
| | | }, |
| | | change() { |
| | | this.isFullscreen = screenfull.isFullscreen |
| | | }, |
| | | init() { |
| | | if (screenfull.isEnabled) { |
| | | screenfull.on('change', this.change) |
| | | } |
| | | }, |
| | | destroy() { |
| | | if (screenfull.isEnabled) { |
| | | screenfull.off('change', this.change) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .screenfull-svg { |
| | | display: inline-block; |
| | | cursor: pointer; |
| | | fill: #5a5e66;; |
| | | width: 20px; |
| | | height: 20px; |
| | | vertical-align: 10px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-dropdown trigger="click" @command="handleSetSize"> |
| | | <div> |
| | | <svg-icon class-name="size-icon" icon-class="size" /> |
| | | </div> |
| | | <el-dropdown-menu slot="dropdown"> |
| | | <el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size===item.value" :command="item.value"> |
| | | {{ item.label }} |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </el-dropdown> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | sizeOptions: [ |
| | | { label: 'Default', value: 'default' }, |
| | | { label: 'Medium', value: 'medium' }, |
| | | { label: 'Small', value: 'small' }, |
| | | { label: 'Mini', value: 'mini' } |
| | | ] |
| | | } |
| | | }, |
| | | computed: { |
| | | size() { |
| | | return this.$store.getters.size |
| | | } |
| | | }, |
| | | methods: { |
| | | handleSetSize(size) { |
| | | this.$ELEMENT.size = size |
| | | this.$store.dispatch('app/setSize', size) |
| | | this.refreshView() |
| | | this.$message({ |
| | | message: 'Switch Size Success', |
| | | type: 'success' |
| | | }) |
| | | }, |
| | | refreshView() { |
| | | // In order to make the cached page re-rendered |
| | | this.$store.dispatch('tagsView/delAllCachedViews', this.$route) |
| | | |
| | | const { fullPath } = this.$route |
| | | |
| | | this.$nextTick(() => { |
| | | this.$router.replace({ |
| | | path: '/redirect' + fullPath |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" /> |
| | | <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners"> |
| | | <use :xlink:href="iconName" /> |
| | | </svg> |
| | | </template> |
| | | |
| | | <script> |
| | | import { isExternal } from '@/utils/validate' |
| | | |
| | | export default { |
| | | name: 'SvgIcon', |
| | | props: { |
| | | iconClass: { |
| | | type: String, |
| | | required: true |
| | | }, |
| | | className: { |
| | | type: String, |
| | | default: '' |
| | | } |
| | | }, |
| | | computed: { |
| | | isExternal() { |
| | | return isExternal(this.iconClass) |
| | | }, |
| | | iconName() { |
| | | return `#icon-${this.iconClass}` |
| | | }, |
| | | svgClass() { |
| | | if (this.className) { |
| | | return 'svg-icon ' + this.className |
| | | } else { |
| | | return 'svg-icon' |
| | | } |
| | | }, |
| | | styleExternalIcon() { |
| | | return { |
| | | mask: `url(${this.iconClass}) no-repeat 50% 50%`, |
| | | '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%` |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .svg-icon { |
| | | width: 1em; |
| | | height: 1em; |
| | | vertical-align: -0.15em; |
| | | fill: currentColor; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .svg-external-icon { |
| | | background-color: currentColor; |
| | | mask-size: cover!important; |
| | | display: inline-block; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-color-picker |
| | | v-model="theme" |
| | | :predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]" |
| | | class="theme-picker" |
| | | popper-class="theme-picker-dropdown" |
| | | /> |
| | | </template> |
| | | |
| | | <script> |
| | | const ORIGINAL_THEME = '#409EFF' // default color |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | chalk: '', // content of theme-chalk css |
| | | theme: '' |
| | | } |
| | | }, |
| | | computed: { |
| | | defaultTheme() { |
| | | return this.$store.state.settings.theme |
| | | } |
| | | }, |
| | | watch: { |
| | | defaultTheme: { |
| | | handler: function(val, oldVal) { |
| | | this.theme = val |
| | | }, |
| | | immediate: true |
| | | }, |
| | | async theme(val) { |
| | | await this.setTheme(val) |
| | | } |
| | | }, |
| | | created() { |
| | | if(this.defaultTheme !== ORIGINAL_THEME) { |
| | | this.setTheme(this.defaultTheme) |
| | | } |
| | | }, |
| | | methods: { |
| | | async setTheme(val) { |
| | | const oldVal = this.chalk ? this.theme : ORIGINAL_THEME |
| | | if (typeof val !== 'string') return |
| | | const themeCluster = this.getThemeCluster(val.replace('#', '')) |
| | | const originalCluster = this.getThemeCluster(oldVal.replace('#', '')) |
| | | |
| | | const getHandler = (variable, id) => { |
| | | return () => { |
| | | const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', '')) |
| | | const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster) |
| | | |
| | | let styleTag = document.getElementById(id) |
| | | if (!styleTag) { |
| | | styleTag = document.createElement('style') |
| | | styleTag.setAttribute('id', id) |
| | | document.head.appendChild(styleTag) |
| | | } |
| | | styleTag.innerText = newStyle |
| | | } |
| | | } |
| | | |
| | | if (!this.chalk) { |
| | | const url = `/styles/theme-chalk/index.css` |
| | | await this.getCSSString(url, 'chalk') |
| | | } |
| | | |
| | | const chalkHandler = getHandler('chalk', 'chalk-style') |
| | | chalkHandler() |
| | | |
| | | const styles = [].slice.call(document.querySelectorAll('style')) |
| | | .filter(style => { |
| | | const text = style.innerText |
| | | return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text) |
| | | }) |
| | | styles.forEach(style => { |
| | | const { innerText } = style |
| | | if (typeof innerText !== 'string') return |
| | | style.innerText = this.updateStyle(innerText, originalCluster, themeCluster) |
| | | }) |
| | | |
| | | this.$emit('change', val) |
| | | }, |
| | | |
| | | updateStyle(style, oldCluster, newCluster) { |
| | | let newStyle = style |
| | | oldCluster.forEach((color, index) => { |
| | | newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index]) |
| | | }) |
| | | return newStyle |
| | | }, |
| | | |
| | | getCSSString(url, variable) { |
| | | return new Promise(resolve => { |
| | | const xhr = new XMLHttpRequest() |
| | | xhr.onreadystatechange = () => { |
| | | if (xhr.readyState === 4 && xhr.status === 200) { |
| | | this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '') |
| | | resolve() |
| | | } |
| | | } |
| | | xhr.open('GET', url) |
| | | xhr.send() |
| | | }) |
| | | }, |
| | | |
| | | getThemeCluster(theme) { |
| | | const tintColor = (color, tint) => { |
| | | let red = parseInt(color.slice(0, 2), 16) |
| | | let green = parseInt(color.slice(2, 4), 16) |
| | | let blue = parseInt(color.slice(4, 6), 16) |
| | | |
| | | if (tint === 0) { // when primary color is in its rgb space |
| | | return [red, green, blue].join(',') |
| | | } else { |
| | | red += Math.round(tint * (255 - red)) |
| | | green += Math.round(tint * (255 - green)) |
| | | blue += Math.round(tint * (255 - blue)) |
| | | |
| | | red = red.toString(16) |
| | | green = green.toString(16) |
| | | blue = blue.toString(16) |
| | | |
| | | return `#${red}${green}${blue}` |
| | | } |
| | | } |
| | | |
| | | const shadeColor = (color, shade) => { |
| | | let red = parseInt(color.slice(0, 2), 16) |
| | | let green = parseInt(color.slice(2, 4), 16) |
| | | let blue = parseInt(color.slice(4, 6), 16) |
| | | |
| | | red = Math.round((1 - shade) * red) |
| | | green = Math.round((1 - shade) * green) |
| | | blue = Math.round((1 - shade) * blue) |
| | | |
| | | red = red.toString(16) |
| | | green = green.toString(16) |
| | | blue = blue.toString(16) |
| | | |
| | | return `#${red}${green}${blue}` |
| | | } |
| | | |
| | | const clusters = [theme] |
| | | for (let i = 0; i <= 9; i++) { |
| | | clusters.push(tintColor(theme, Number((i / 10).toFixed(2)))) |
| | | } |
| | | clusters.push(shadeColor(theme, 0.1)) |
| | | return clusters |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | .theme-message, |
| | | .theme-picker-dropdown { |
| | | z-index: 99999 !important; |
| | | } |
| | | |
| | | .theme-picker .el-color-picker__trigger { |
| | | height: 26px !important; |
| | | width: 26px !important; |
| | | padding: 2px; |
| | | } |
| | | |
| | | .theme-picker-dropdown .el-color-dropdown__link-btn { |
| | | display: none; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-menu |
| | | :default-active="activeMenu" |
| | | mode="horizontal" |
| | | @select="handleSelect" |
| | | > |
| | | <template v-for="(item, index) in topMenus"> |
| | | <el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber"> |
| | | <svg-icon |
| | | v-if="item.meta && item.meta.icon && item.meta.icon !== '#'" |
| | | :icon-class="item.meta.icon"/> |
| | | {{ item.meta.title }} |
| | | </el-menu-item> |
| | | </template> |
| | | |
| | | <!-- 顶部菜单超出数量折叠 --> |
| | | <el-submenu :style="{'--theme': theme}" index="more" :key="visibleNumber" v-if="topMenus.length > visibleNumber"> |
| | | <template slot="title">更多菜单</template> |
| | | <template v-for="(item, index) in topMenus"> |
| | | <el-menu-item |
| | | :index="item.path" |
| | | :key="index" |
| | | v-if="index >= visibleNumber"> |
| | | <svg-icon |
| | | v-if="item.meta && item.meta.icon && item.meta.icon !== '#'" |
| | | :icon-class="item.meta.icon"/> |
| | | {{ item.meta.title }} |
| | | </el-menu-item> |
| | | </template> |
| | | </el-submenu> |
| | | </el-menu> |
| | | </template> |
| | | |
| | | <script> |
| | | import { constantRoutes } from "@/router" |
| | | import { isHttp } from "@/utils/validate" |
| | | |
| | | // 隐藏侧边栏路由 |
| | | const hideList = ['/index', '/user/profile'] |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | // 顶部栏初始数 |
| | | visibleNumber: 5, |
| | | // 当前激活菜单的 index |
| | | currentIndex: undefined |
| | | } |
| | | }, |
| | | computed: { |
| | | theme() { |
| | | return this.$store.state.settings.theme |
| | | }, |
| | | // 顶部显示菜单 |
| | | topMenus() { |
| | | let topMenus = [] |
| | | this.routers.map((menu) => { |
| | | if (menu.hidden !== true) { |
| | | // 兼容顶部栏一级菜单内部跳转 |
| | | if (menu.path === '/' && menu.children) { |
| | | topMenus.push(menu.children[0]) |
| | | } else { |
| | | topMenus.push(menu) |
| | | } |
| | | } |
| | | }) |
| | | return topMenus |
| | | }, |
| | | // 所有的路由信息 |
| | | routers() { |
| | | return this.$store.state.permission.topbarRouters |
| | | }, |
| | | // 设置子路由 |
| | | childrenMenus() { |
| | | var childrenMenus = [] |
| | | this.routers.map((router) => { |
| | | for (var item in router.children) { |
| | | if (router.children[item].parentPath === undefined) { |
| | | if(router.path === "/") { |
| | | router.children[item].path = "/" + router.children[item].path |
| | | } else { |
| | | if(!isHttp(router.children[item].path)) { |
| | | router.children[item].path = router.path + "/" + router.children[item].path |
| | | } |
| | | } |
| | | router.children[item].parentPath = router.path |
| | | } |
| | | childrenMenus.push(router.children[item]) |
| | | } |
| | | }) |
| | | return constantRoutes.concat(childrenMenus) |
| | | }, |
| | | // 默认激活的菜单 |
| | | activeMenu() { |
| | | const path = this.$route.path |
| | | let activePath = path |
| | | if (path !== undefined && path.lastIndexOf("/") > 0 && hideList.indexOf(path) === -1) { |
| | | const tmpPath = path.substring(1, path.length) |
| | | if (!this.$route.meta.link) { |
| | | activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/")) |
| | | this.$store.dispatch('app/toggleSideBarHide', false) |
| | | } |
| | | } else if(!this.$route.children) { |
| | | activePath = path |
| | | this.$store.dispatch('app/toggleSideBarHide', true) |
| | | } |
| | | this.activeRoutes(activePath) |
| | | return activePath |
| | | }, |
| | | }, |
| | | beforeMount() { |
| | | window.addEventListener('resize', this.setVisibleNumber) |
| | | }, |
| | | beforeDestroy() { |
| | | window.removeEventListener('resize', this.setVisibleNumber) |
| | | }, |
| | | mounted() { |
| | | this.setVisibleNumber() |
| | | }, |
| | | methods: { |
| | | // 根据宽度计算设置显示栏数 |
| | | setVisibleNumber() { |
| | | const width = document.body.getBoundingClientRect().width / 3 |
| | | this.visibleNumber = parseInt(width / 85) |
| | | }, |
| | | // 菜单选择事件 |
| | | handleSelect(key, keyPath) { |
| | | this.currentIndex = key |
| | | const route = this.routers.find(item => item.path === key) |
| | | if (isHttp(key)) { |
| | | // http(s):// 路径新窗口打开 |
| | | window.open(key, "_blank") |
| | | } else if (!route || !route.children) { |
| | | // 没有子路由路径内部打开 |
| | | const routeMenu = this.childrenMenus.find(item => item.path === key) |
| | | if (routeMenu && routeMenu.query) { |
| | | let query = JSON.parse(routeMenu.query) |
| | | this.$router.push({ path: key, query: query }) |
| | | } else { |
| | | this.$router.push({ path: key }) |
| | | } |
| | | this.$store.dispatch('app/toggleSideBarHide', true) |
| | | } else { |
| | | // 显示左侧联动菜单 |
| | | this.activeRoutes(key) |
| | | this.$store.dispatch('app/toggleSideBarHide', false) |
| | | } |
| | | }, |
| | | // 当前激活的路由 |
| | | activeRoutes(key) { |
| | | var routes = [] |
| | | if (this.childrenMenus && this.childrenMenus.length > 0) { |
| | | this.childrenMenus.map((item) => { |
| | | if (key == item.parentPath || (key == "index" && "" == item.path)) { |
| | | routes.push(item) |
| | | } |
| | | }) |
| | | } |
| | | if(routes.length > 0) { |
| | | this.$store.commit("SET_SIDEBAR_ROUTERS", routes) |
| | | } else { |
| | | this.$store.dispatch('app/toggleSideBarHide', true) |
| | | } |
| | | } |
| | | }, |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .topmenu-container.el-menu--horizontal > .el-menu-item { |
| | | float: left; |
| | | height: 50px !important; |
| | | line-height: 50px !important; |
| | | color: #999093 !important; |
| | | padding: 0 5px !important; |
| | | margin: 0 10px !important; |
| | | } |
| | | |
| | | .topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-submenu.is-active .el-submenu__title { |
| | | border-bottom: 2px solid #{'var(--theme)'} !important; |
| | | color: #303133; |
| | | } |
| | | |
| | | /* submenu item */ |
| | | .topmenu-container.el-menu--horizontal > .el-submenu .el-submenu__title { |
| | | float: left; |
| | | height: 50px !important; |
| | | line-height: 50px !important; |
| | | color: #999093 !important; |
| | | padding: 0 5px !important; |
| | | margin: 0 10px !important; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div v-loading="loading" :style="'height:' + height"> |
| | | <iframe |
| | | :src="src" |
| | | frameborder="no" |
| | | style="width: 100%; height: 100%" |
| | | scrolling="auto" |
| | | /> |
| | | </div> |
| | | </template> |
| | | <script> |
| | | export default { |
| | | props: { |
| | | src: { |
| | | type: String, |
| | | required: true |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | height: document.documentElement.clientHeight - 94.5 + "px;", |
| | | loading: true, |
| | | url: this.src |
| | | } |
| | | }, |
| | | mounted: function () { |
| | | setTimeout(() => { |
| | | this.loading = false |
| | | }, 300) |
| | | const that = this |
| | | window.onresize = function temp() { |
| | | that.height = document.documentElement.clientHeight - 94.5 + "px;" |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | /** |
| | | * v-dialogDrag 弹窗拖拽 |
| | | * Copyright (c) 2019 ruoyi |
| | | */ |
| | | |
| | | export default { |
| | | bind(el, binding, vnode, oldVnode) { |
| | | const value = binding.value |
| | | if (value == false) return |
| | | // 获取拖拽内容头部 |
| | | const dialogHeaderEl = el.querySelector('.el-dialog__header') |
| | | const dragDom = el.querySelector('.el-dialog') |
| | | dialogHeaderEl.style.cursor = 'move' |
| | | // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null) |
| | | const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null) |
| | | dragDom.style.position = 'absolute' |
| | | dragDom.style.marginTop = 0 |
| | | let width = dragDom.style.width |
| | | if (width.includes('%')) { |
| | | width = +document.body.clientWidth * (+width.replace(/\%/g, '') / 100) |
| | | } else { |
| | | width = +width.replace(/\px/g, '') |
| | | } |
| | | dragDom.style.left = `${(document.body.clientWidth - width) / 2}px` |
| | | // 鼠标按下事件 |
| | | dialogHeaderEl.onmousedown = (e) => { |
| | | // 鼠标按下,计算当前元素距离可视区的距离 (鼠标点击位置距离可视窗口的距离) |
| | | const disX = e.clientX - dialogHeaderEl.offsetLeft |
| | | const disY = e.clientY - dialogHeaderEl.offsetTop |
| | | |
| | | // 获取到的值带px 正则匹配替换 |
| | | let styL, styT |
| | | |
| | | // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px |
| | | if (sty.left.includes('%')) { |
| | | styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100) |
| | | styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100) |
| | | } else { |
| | | styL = +sty.left.replace(/\px/g, '') |
| | | styT = +sty.top.replace(/\px/g, '') |
| | | } |
| | | |
| | | // 鼠标拖拽事件 |
| | | document.onmousemove = function (e) { |
| | | // 通过事件委托,计算移动的距离 (开始拖拽至结束拖拽的距离) |
| | | const l = e.clientX - disX |
| | | const t = e.clientY - disY |
| | | |
| | | let finallyL = l + styL |
| | | let finallyT = t + styT |
| | | |
| | | // 移动当前元素 |
| | | dragDom.style.left = `${finallyL}px` |
| | | dragDom.style.top = `${finallyT}px` |
| | | |
| | | } |
| | | |
| | | document.onmouseup = function (e) { |
| | | document.onmousemove = null |
| | | document.onmouseup = null |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /** |
| | | * v-dialogDragWidth 可拖动弹窗高度(右下角) |
| | | * Copyright (c) 2019 ruoyi |
| | | */ |
| | | |
| | | export default { |
| | | bind(el) { |
| | | const dragDom = el.querySelector('.el-dialog') |
| | | const lineEl = document.createElement('div') |
| | | lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;' |
| | | lineEl.addEventListener('mousedown', |
| | | function(e) { |
| | | // 鼠标按下,计算当前元素距离可视区的距离 |
| | | const disX = e.clientX - el.offsetLeft |
| | | const disY = e.clientY - el.offsetTop |
| | | // 当前宽度 高度 |
| | | const curWidth = dragDom.offsetWidth |
| | | const curHeight = dragDom.offsetHeight |
| | | document.onmousemove = function(e) { |
| | | e.preventDefault() // 移动时禁用默认事件 |
| | | // 通过事件委托,计算移动的距离 |
| | | const xl = e.clientX - disX |
| | | const yl = e.clientY - disY |
| | | dragDom.style.width = `${curWidth + xl}px` |
| | | dragDom.style.height = `${curHeight + yl}px` |
| | | } |
| | | document.onmouseup = function(e) { |
| | | document.onmousemove = null |
| | | document.onmouseup = null |
| | | } |
| | | }, false) |
| | | dragDom.appendChild(lineEl) |
| | | } |
| | | } |
New file |
| | |
| | | /** |
| | | * v-dialogDragWidth 可拖动弹窗宽度(右侧边) |
| | | * Copyright (c) 2019 ruoyi |
| | | */ |
| | | |
| | | export default { |
| | | bind(el) { |
| | | const dragDom = el.querySelector('.el-dialog') |
| | | const lineEl = document.createElement('div') |
| | | lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;' |
| | | lineEl.addEventListener('mousedown', |
| | | function (e) { |
| | | // 鼠标按下,计算当前元素距离可视区的距离 |
| | | const disX = e.clientX - el.offsetLeft |
| | | // 当前宽度 |
| | | const curWidth = dragDom.offsetWidth |
| | | document.onmousemove = function (e) { |
| | | e.preventDefault() // 移动时禁用默认事件 |
| | | // 通过事件委托,计算移动的距离 |
| | | const l = e.clientX - disX |
| | | dragDom.style.width = `${curWidth + l}px` |
| | | } |
| | | document.onmouseup = function (e) { |
| | | document.onmousemove = null |
| | | document.onmouseup = null |
| | | } |
| | | }, false) |
| | | dragDom.appendChild(lineEl) |
| | | } |
| | | } |
New file |
| | |
| | | import hasRole from './permission/hasRole' |
| | | import hasPermi from './permission/hasPermi' |
| | | import dialogDrag from './dialog/drag' |
| | | import dialogDragWidth from './dialog/dragWidth' |
| | | import dialogDragHeight from './dialog/dragHeight' |
| | | import clipboard from './module/clipboard' |
| | | |
| | | const install = function(Vue) { |
| | | Vue.directive('hasRole', hasRole) |
| | | Vue.directive('hasPermi', hasPermi) |
| | | Vue.directive('clipboard', clipboard) |
| | | Vue.directive('dialogDrag', dialogDrag) |
| | | Vue.directive('dialogDragWidth', dialogDragWidth) |
| | | Vue.directive('dialogDragHeight', dialogDragHeight) |
| | | } |
| | | |
| | | if (window.Vue) { |
| | | window['hasRole'] = hasRole |
| | | window['hasPermi'] = hasPermi |
| | | Vue.use(install) |
| | | } |
| | | |
| | | export default install |
New file |
| | |
| | | /** |
| | | * v-clipboard 文字复制剪贴 |
| | | * Copyright (c) 2021 ruoyi |
| | | */ |
| | | |
| | | import Clipboard from 'clipboard' |
| | | export default { |
| | | bind(el, binding, vnode) { |
| | | switch (binding.arg) { |
| | | case 'success': |
| | | el._vClipBoard_success = binding.value |
| | | break |
| | | case 'error': |
| | | el._vClipBoard_error = binding.value |
| | | break |
| | | default: { |
| | | const clipboard = new Clipboard(el, { |
| | | text: () => binding.value, |
| | | action: () => binding.arg === 'cut' ? 'cut' : 'copy' |
| | | }) |
| | | clipboard.on('success', e => { |
| | | const callback = el._vClipBoard_success |
| | | callback && callback(e) |
| | | }) |
| | | clipboard.on('error', e => { |
| | | const callback = el._vClipBoard_error |
| | | callback && callback(e) |
| | | }) |
| | | el._vClipBoard = clipboard |
| | | } |
| | | } |
| | | }, |
| | | update(el, binding) { |
| | | if (binding.arg === 'success') { |
| | | el._vClipBoard_success = binding.value |
| | | } else if (binding.arg === 'error') { |
| | | el._vClipBoard_error = binding.value |
| | | } else { |
| | | el._vClipBoard.text = function () { return binding.value } |
| | | el._vClipBoard.action = () => binding.arg === 'cut' ? 'cut' : 'copy' |
| | | } |
| | | }, |
| | | unbind(el, binding) { |
| | | if (!el._vClipboard) return |
| | | if (binding.arg === 'success') { |
| | | delete el._vClipBoard_success |
| | | } else if (binding.arg === 'error') { |
| | | delete el._vClipBoard_error |
| | | } else { |
| | | el._vClipBoard.destroy() |
| | | delete el._vClipBoard |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /** |
| | | * v-hasPermi 操作权限处理 |
| | | * Copyright (c) 2019 ruoyi |
| | | */ |
| | | |
| | | import store from '@/store' |
| | | |
| | | export default { |
| | | inserted(el, binding, vnode) { |
| | | const { value } = binding |
| | | const all_permission = "*:*:*" |
| | | const permissions = store.getters && store.getters.permissions |
| | | |
| | | if (value && value instanceof Array && value.length > 0) { |
| | | const permissionFlag = value |
| | | |
| | | const hasPermissions = permissions.some(permission => { |
| | | return all_permission === permission || permissionFlag.includes(permission) |
| | | }) |
| | | |
| | | if (!hasPermissions) { |
| | | el.parentNode && el.parentNode.removeChild(el) |
| | | } |
| | | } else { |
| | | throw new Error(`请设置操作权限标签值`) |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | /** |
| | | * v-hasRole 角色权限处理 |
| | | * Copyright (c) 2019 ruoyi |
| | | */ |
| | | |
| | | import store from '@/store' |
| | | |
| | | export default { |
| | | inserted(el, binding, vnode) { |
| | | const { value } = binding |
| | | const super_admin = "admin" |
| | | const roles = store.getters && store.getters.roles |
| | | |
| | | if (value && value instanceof Array && value.length > 0) { |
| | | const roleFlag = value |
| | | |
| | | const hasRole = roles.some(role => { |
| | | return super_admin === role || roleFlag.includes(role) |
| | | }) |
| | | |
| | | if (!hasRole) { |
| | | el.parentNode && el.parentNode.removeChild(el) |
| | | } |
| | | } else { |
| | | throw new Error(`请设置角色权限标签值"`) |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | <template> |
| | | <section class="app-main"> |
| | | <transition name="fade-transform" mode="out-in"> |
| | | <keep-alive :include="cachedViews"> |
| | | <router-view v-if="!$route.meta.link" :key="key" /> |
| | | </keep-alive> |
| | | </transition> |
| | | <iframe-toggle /> |
| | | <copyright /> |
| | | </section> |
| | | </template> |
| | | |
| | | <script> |
| | | import copyright from "./Copyright/index" |
| | | import iframeToggle from "./IframeToggle/index" |
| | | |
| | | export default { |
| | | name: 'AppMain', |
| | | components: { iframeToggle, copyright }, |
| | | computed: { |
| | | cachedViews() { |
| | | return this.$store.state.tagsView.cachedViews |
| | | }, |
| | | key() { |
| | | return this.$route.path |
| | | } |
| | | }, |
| | | watch: { |
| | | $route() { |
| | | this.addIframe() |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.addIframe() |
| | | }, |
| | | methods: { |
| | | addIframe() { |
| | | const { name } = this.$route |
| | | if (name && this.$route.meta.link) { |
| | | this.$store.dispatch('tagsView/addIframeView', this.$route) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .app-main { |
| | | /* 50= navbar 50 */ |
| | | min-height: calc(100vh - 50px); |
| | | width: 100%; |
| | | position: relative; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .app-main:has(.copyright) { |
| | | padding-bottom: 36px; |
| | | } |
| | | |
| | | .fixed-header + .app-main { |
| | | padding-top: 50px; |
| | | } |
| | | |
| | | .hasTagsView { |
| | | .app-main { |
| | | /* 84 = navbar + tags-view = 50 + 34 */ |
| | | min-height: calc(100vh - 84px); |
| | | } |
| | | |
| | | .fixed-header + .app-main { |
| | | padding-top: 84px; |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | <style lang="scss"> |
| | | // fix css style bug in open el-dialog |
| | | .el-popup-parent--hidden { |
| | | .fixed-header { |
| | | padding-right: 6px; |
| | | } |
| | | } |
| | | |
| | | ::-webkit-scrollbar { |
| | | width: 6px; |
| | | height: 6px; |
| | | } |
| | | |
| | | ::-webkit-scrollbar-track { |
| | | background-color: #f1f1f1; |
| | | } |
| | | |
| | | ::-webkit-scrollbar-thumb { |
| | | background-color: #c0c0c0; |
| | | border-radius: 3px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <footer v-if="visible" class="copyright"> |
| | | <span>{{ content }}</span> |
| | | </footer> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | computed: { |
| | | visible() { |
| | | return this.$store.state.settings.footerVisible |
| | | }, |
| | | content() { |
| | | return this.$store.state.settings.footerContent |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .copyright { |
| | | position: fixed; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | height: 36px; |
| | | padding: 10px 20px; |
| | | text-align: right; |
| | | background-color: #f8f8f8; |
| | | color: #666; |
| | | font-size: 14px; |
| | | border-top: 1px solid #e7e7e7; |
| | | z-index: 999; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <transition-group name="fade-transform" mode="out-in"> |
| | | <inner-link |
| | | v-for="(item, index) in iframeViews" |
| | | :key="item.path" |
| | | :iframeId="'iframe' + index" |
| | | v-show="$route.path === item.path" |
| | | :src="iframeUrl(item.meta.link, item.query)" |
| | | ></inner-link> |
| | | </transition-group> |
| | | </template> |
| | | |
| | | <script> |
| | | import InnerLink from "../InnerLink/index" |
| | | |
| | | export default { |
| | | components: { InnerLink }, |
| | | computed: { |
| | | iframeViews() { |
| | | return this.$store.state.tagsView.iframeViews |
| | | } |
| | | }, |
| | | methods: { |
| | | iframeUrl(url, query) { |
| | | if (Object.keys(query).length > 0) { |
| | | let params = Object.keys(query).map((key) => key + "=" + query[key]).join("&") |
| | | return url + "?" + params |
| | | } |
| | | return url |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div :style="'height:' + height" v-loading="loading" element-loading-text="正在加载页面,请稍候!"> |
| | | <iframe |
| | | :id="iframeId" |
| | | style="width: 100%; height: 100%" |
| | | :src="src" |
| | | frameborder="no" |
| | | ></iframe> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | props: { |
| | | src: { |
| | | type: String, |
| | | default: "/" |
| | | }, |
| | | iframeId: { |
| | | type: String |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | loading: false, |
| | | height: document.documentElement.clientHeight - 94.5 + "px;" |
| | | } |
| | | }, |
| | | mounted() { |
| | | var _this = this |
| | | const iframeId = ("#" + this.iframeId).replace(/\//g, "\\/") |
| | | const iframe = document.querySelector(iframeId) |
| | | // iframe页面loading控制 |
| | | if (iframe.attachEvent) { |
| | | this.loading = true |
| | | iframe.attachEvent("onload", function () { |
| | | _this.loading = false |
| | | }) |
| | | } else { |
| | | this.loading = true |
| | | iframe.onload = function () { |
| | | _this.loading = false |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="navbar"> |
| | | <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> |
| | | |
| | | <breadcrumb v-if="!topNav" id="breadcrumb-container" class="breadcrumb-container" /> |
| | | <top-nav v-if="topNav" id="topmenu-container" class="topmenu-container" /> |
| | | |
| | | <div class="right-menu"> |
| | | <template v-if="device!=='mobile'"> |
| | | <search id="header-search" class="right-menu-item" /> |
| | | |
| | | <el-tooltip content="源码地址" effect="dark" placement="bottom"> |
| | | <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | | |
| | | <el-tooltip content="文档地址" effect="dark" placement="bottom"> |
| | | <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | | |
| | | <screenfull id="screenfull" class="right-menu-item hover-effect" /> |
| | | |
| | | <el-tooltip content="布局大小" effect="dark" placement="bottom"> |
| | | <size-select id="size-select" class="right-menu-item hover-effect" /> |
| | | </el-tooltip> |
| | | |
| | | </template> |
| | | |
| | | <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="hover"> |
| | | <div class="avatar-wrapper"> |
| | | <img :src="avatar" class="user-avatar"> |
| | | <span class="user-nickname"> {{ nickName }} </span> |
| | | </div> |
| | | <el-dropdown-menu slot="dropdown"> |
| | | <router-link to="/user/profile"> |
| | | <el-dropdown-item>个人中心</el-dropdown-item> |
| | | </router-link> |
| | | <el-dropdown-item divided @click.native="logout"> |
| | | <span>退出登录</span> |
| | | </el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </el-dropdown> |
| | | |
| | | <div class="right-menu-item hover-effect setting" @click="setLayout" v-if="setting"> |
| | | <svg-icon icon-class="more-up" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapGetters } from 'vuex' |
| | | import Breadcrumb from '@/components/Breadcrumb' |
| | | import TopNav from '@/components/TopNav' |
| | | import Hamburger from '@/components/Hamburger' |
| | | import Screenfull from '@/components/Screenfull' |
| | | import SizeSelect from '@/components/SizeSelect' |
| | | import Search from '@/components/HeaderSearch' |
| | | import RuoYiGit from '@/components/RuoYi/Git' |
| | | import RuoYiDoc from '@/components/RuoYi/Doc' |
| | | |
| | | export default { |
| | | emits: ['setLayout'], |
| | | components: { |
| | | Breadcrumb, |
| | | TopNav, |
| | | Hamburger, |
| | | Screenfull, |
| | | SizeSelect, |
| | | Search, |
| | | RuoYiGit, |
| | | RuoYiDoc |
| | | }, |
| | | computed: { |
| | | ...mapGetters([ |
| | | 'sidebar', |
| | | 'avatar', |
| | | 'device', |
| | | 'nickName' |
| | | ]), |
| | | setting: { |
| | | get() { |
| | | return this.$store.state.settings.showSettings |
| | | } |
| | | }, |
| | | topNav: { |
| | | get() { |
| | | return this.$store.state.settings.topNav |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | toggleSideBar() { |
| | | this.$store.dispatch('app/toggleSideBar') |
| | | }, |
| | | setLayout(event) { |
| | | this.$emit('setLayout') |
| | | }, |
| | | logout() { |
| | | this.$confirm('确定注销并退出系统吗?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | this.$store.dispatch('LogOut').then(() => { |
| | | location.href = '/index' |
| | | }) |
| | | }).catch(() => {}) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .navbar { |
| | | height: 50px; |
| | | overflow: hidden; |
| | | position: relative; |
| | | background: #fff; |
| | | box-shadow: 0 1px 4px rgba(0,21,41,.08); |
| | | |
| | | .hamburger-container { |
| | | line-height: 46px; |
| | | height: 100%; |
| | | float: left; |
| | | cursor: pointer; |
| | | transition: background .3s; |
| | | -webkit-tap-highlight-color:transparent; |
| | | |
| | | &:hover { |
| | | background: rgba(0, 0, 0, .025) |
| | | } |
| | | } |
| | | |
| | | .breadcrumb-container { |
| | | float: left; |
| | | } |
| | | |
| | | .topmenu-container { |
| | | position: absolute; |
| | | left: 50px; |
| | | } |
| | | |
| | | .errLog-container { |
| | | display: inline-block; |
| | | vertical-align: top; |
| | | } |
| | | |
| | | .right-menu { |
| | | float: right; |
| | | height: 100%; |
| | | line-height: 50px; |
| | | |
| | | &:focus { |
| | | outline: none; |
| | | } |
| | | |
| | | .right-menu-item { |
| | | display: inline-block; |
| | | padding: 0 8px; |
| | | height: 100%; |
| | | font-size: 18px; |
| | | color: #5a5e66; |
| | | vertical-align: text-bottom; |
| | | |
| | | &.hover-effect { |
| | | cursor: pointer; |
| | | transition: background .3s; |
| | | |
| | | &:hover { |
| | | background: rgba(0, 0, 0, .025) |
| | | } |
| | | } |
| | | } |
| | | |
| | | .avatar-container { |
| | | margin-right: 0px; |
| | | padding-right: 0px; |
| | | |
| | | .avatar-wrapper { |
| | | margin-top: 10px; |
| | | position: relative; |
| | | |
| | | .user-avatar { |
| | | cursor: pointer; |
| | | width: 30px; |
| | | height: 30px; |
| | | border-radius: 50%; |
| | | } |
| | | |
| | | .user-nickname{ |
| | | position: relative; |
| | | bottom: 10px; |
| | | font-size: 14px; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .el-icon-caret-bottom { |
| | | cursor: pointer; |
| | | position: absolute; |
| | | right: -20px; |
| | | top: 25px; |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-drawer size="280px" :visible="showSettings" :with-header="false" :append-to-body="true" :before-close="closeSetting" :lock-scroll="false"> |
| | | <div class="drawer-container"> |
| | | <div> |
| | | <div class="setting-drawer-content"> |
| | | <div class="setting-drawer-title"> |
| | | <h3 class="drawer-title">主题风格设置</h3> |
| | | </div> |
| | | <div class="setting-drawer-block-checbox"> |
| | | <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')"> |
| | | <img src="@/assets/images/dark.svg" alt="dark"> |
| | | <div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;"> |
| | | <i aria-label="图标: check" class="anticon anticon-check"> |
| | | <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class=""> |
| | | <path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/> |
| | | </svg> |
| | | </i> |
| | | </div> |
| | | </div> |
| | | <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')"> |
| | | <img src="@/assets/images/light.svg" alt="light"> |
| | | <div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;"> |
| | | <i aria-label="图标: check" class="anticon anticon-check"> |
| | | <svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class=""> |
| | | <path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"/> |
| | | </svg> |
| | | </i> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>主题颜色</span> |
| | | <theme-picker style="float: right;height: 26px;margin: -3px 8px 0 0;" @change="themeChange" /> |
| | | </div> |
| | | </div> |
| | | |
| | | <el-divider/> |
| | | |
| | | <h3 class="drawer-title">系统布局配置</h3> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>开启 TopNav</span> |
| | | <el-switch v-model="topNav" class="drawer-switch" /> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>开启 Tags-Views</span> |
| | | <el-switch v-model="tagsView" class="drawer-switch" /> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>显示页签图标</span> |
| | | <el-switch v-model="tagsIcon" :disabled="!tagsView" class="drawer-switch" /> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>固定 Header</span> |
| | | <el-switch v-model="fixedHeader" class="drawer-switch" /> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>显示 Logo</span> |
| | | <el-switch v-model="sidebarLogo" class="drawer-switch" /> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>动态标题</span> |
| | | <el-switch v-model="dynamicTitle" class="drawer-switch" /> |
| | | </div> |
| | | |
| | | <div class="drawer-item"> |
| | | <span>底部版权</span> |
| | | <el-switch v-model="footerVisible" class="drawer-switch" /> |
| | | </div> |
| | | |
| | | <el-divider/> |
| | | |
| | | <el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting">保存配置</el-button> |
| | | <el-button size="small" plain icon="el-icon-refresh" @click="resetSetting">重置配置</el-button> |
| | | </div> |
| | | </div> |
| | | </el-drawer> |
| | | </template> |
| | | |
| | | <script> |
| | | import ThemePicker from '@/components/ThemePicker' |
| | | |
| | | export default { |
| | | components: { ThemePicker }, |
| | | expose: ['openSetting'], |
| | | data() { |
| | | return { |
| | | theme: this.$store.state.settings.theme, |
| | | sideTheme: this.$store.state.settings.sideTheme, |
| | | showSettings: false |
| | | } |
| | | }, |
| | | computed: { |
| | | fixedHeader: { |
| | | get() { |
| | | return this.$store.state.settings.fixedHeader |
| | | }, |
| | | set(val) { |
| | | this.$store.dispatch('settings/changeSetting', { |
| | | key: 'fixedHeader', |
| | | value: val |
| | | }) |
| | | } |
| | | }, |
| | | topNav: { |
| | | get() { |
| | | return this.$store.state.settings.topNav |
| | | }, |
| | | set(val) { |
| | | this.$store.dispatch('settings/changeSetting', { |
| | | key: 'topNav', |
| | | value: val |
| | | }) |
| | | if (!val) { |
| | | this.$store.dispatch('app/toggleSideBarHide', false) |
| | | this.$store.commit("SET_SIDEBAR_ROUTERS", this.$store.state.permission.defaultRoutes) |
| | | } |
| | | } |
| | | }, |
| | | tagsView: { |
| | | get() { |
| | | return this.$store.state.settings.tagsView |
| | | }, |
| | | set(val) { |
| | | this.$store.dispatch('settings/changeSetting', { |
| | | key: 'tagsView', |
| | | value: val |
| | | }) |
| | | } |
| | | }, |
| | | tagsIcon: { |
| | | get() { |
| | | return this.$store.state.settings.tagsIcon |
| | | }, |
| | | set(val) { |
| | | this.$store.dispatch('settings/changeSetting', { |
| | | key: 'tagsIcon', |
| | | value: val |
| | | }) |
| | | } |
| | | }, |
| | | sidebarLogo: { |
| | | get() { |
| | | return this.$store.state.settings.sidebarLogo |
| | | }, |
| | | set(val) { |
| | | this.$store.dispatch('settings/changeSetting', { |
| | | key: 'sidebarLogo', |
| | | value: val |
| | | }) |
| | | } |
| | | }, |
| | | dynamicTitle: { |
| | | get() { |
| | | return this.$store.state.settings.dynamicTitle |
| | | }, |
| | | set(val) { |
| | | this.$store.dispatch('settings/changeSetting', { |
| | | key: 'dynamicTitle', |
| | | value: val |
| | | }) |
| | | this.$store.dispatch('settings/setTitle', this.$store.state.settings.title) |
| | | } |
| | | }, |
| | | footerVisible: { |
| | | get() { |
| | | return this.$store.state.settings.footerVisible |
| | | }, |
| | | set(val) { |
| | | this.$store.dispatch('settings/changeSetting', { |
| | | key: 'footerVisible', |
| | | value: val |
| | | }) |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | themeChange(val) { |
| | | this.$store.dispatch('settings/changeSetting', { |
| | | key: 'theme', |
| | | value: val |
| | | }) |
| | | this.theme = val |
| | | }, |
| | | handleTheme(val) { |
| | | this.$store.dispatch('settings/changeSetting', { |
| | | key: 'sideTheme', |
| | | value: val |
| | | }) |
| | | this.sideTheme = val |
| | | }, |
| | | openSetting() { |
| | | this.showSettings = true |
| | | }, |
| | | closeSetting(){ |
| | | this.showSettings = false |
| | | }, |
| | | saveSetting() { |
| | | this.$modal.loading("正在保存到本地,请稍候...") |
| | | this.$cache.local.set( |
| | | "layout-setting", |
| | | `{ |
| | | "topNav":${this.topNav}, |
| | | "tagsView":${this.tagsView}, |
| | | "tagsIcon":${this.tagsIcon}, |
| | | "fixedHeader":${this.fixedHeader}, |
| | | "sidebarLogo":${this.sidebarLogo}, |
| | | "dynamicTitle":${this.dynamicTitle}, |
| | | "footerVisible":${this.footerVisible}, |
| | | "sideTheme":"${this.sideTheme}", |
| | | "theme":"${this.theme}" |
| | | }` |
| | | ) |
| | | setTimeout(this.$modal.closeLoading(), 1000) |
| | | }, |
| | | resetSetting() { |
| | | this.$modal.loading("正在清除设置缓存并刷新,请稍候...") |
| | | this.$cache.local.remove("layout-setting") |
| | | setTimeout("window.location.reload()", 1000) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .setting-drawer-content { |
| | | .setting-drawer-title { |
| | | margin-bottom: 12px; |
| | | color: rgba(0, 0, 0, .85); |
| | | font-size: 14px; |
| | | line-height: 22px; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .setting-drawer-block-checbox { |
| | | display: flex; |
| | | justify-content: flex-start; |
| | | align-items: center; |
| | | margin-top: 10px; |
| | | margin-bottom: 20px; |
| | | |
| | | .setting-drawer-block-checbox-item { |
| | | position: relative; |
| | | margin-right: 16px; |
| | | border-radius: 2px; |
| | | cursor: pointer; |
| | | |
| | | img { |
| | | width: 48px; |
| | | height: 48px; |
| | | } |
| | | |
| | | .setting-drawer-block-checbox-selectIcon { |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | padding-top: 15px; |
| | | padding-left: 24px; |
| | | color: #1890ff; |
| | | font-weight: 700; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .drawer-container { |
| | | padding: 20px; |
| | | font-size: 14px; |
| | | line-height: 1.5; |
| | | word-wrap: break-word; |
| | | |
| | | .drawer-title { |
| | | margin-bottom: 12px; |
| | | color: rgba(0, 0, 0, .85); |
| | | font-size: 14px; |
| | | line-height: 22px; |
| | | } |
| | | |
| | | .drawer-item { |
| | | color: rgba(0, 0, 0, .65); |
| | | font-size: 14px; |
| | | padding: 12px 0; |
| | | } |
| | | |
| | | .drawer-switch { |
| | | float: right |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | export default { |
| | | computed: { |
| | | device() { |
| | | return this.$store.state.app.device |
| | | } |
| | | }, |
| | | mounted() { |
| | | // In order to fix the click on menu on the ios device will trigger the mouseleave bug |
| | | this.fixBugIniOS() |
| | | }, |
| | | methods: { |
| | | fixBugIniOS() { |
| | | const $subMenu = this.$refs.subMenu |
| | | if ($subMenu) { |
| | | const handleMouseleave = $subMenu.handleMouseleave |
| | | $subMenu.handleMouseleave = (e) => { |
| | | if (this.device === 'mobile') { |
| | | return |
| | | } |
| | | handleMouseleave(e) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | <script> |
| | | export default { |
| | | name: 'MenuItem', |
| | | functional: true, |
| | | props: { |
| | | icon: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | title: { |
| | | type: String, |
| | | default: '' |
| | | } |
| | | }, |
| | | render(h, context) { |
| | | const { icon, title } = context.props |
| | | const vnodes = [] |
| | | |
| | | if (icon) { |
| | | vnodes.push(<svg-icon icon-class={icon}/>) |
| | | } |
| | | |
| | | if (title) { |
| | | if (title.length > 5) { |
| | | vnodes.push(<span slot='title' title={(title)}>{(title)}</span>) |
| | | } else { |
| | | vnodes.push(<span slot='title'>{(title)}</span>) |
| | | } |
| | | } |
| | | return vnodes |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <component :is="type" v-bind="linkProps(to)"> |
| | | <slot /> |
| | | </component> |
| | | </template> |
| | | |
| | | <script> |
| | | import { isExternal } from '@/utils/validate' |
| | | |
| | | export default { |
| | | props: { |
| | | to: { |
| | | type: [String, Object], |
| | | required: true |
| | | } |
| | | }, |
| | | computed: { |
| | | isExternal() { |
| | | return isExternal(this.to) |
| | | }, |
| | | type() { |
| | | if (this.isExternal) { |
| | | return 'a' |
| | | } |
| | | return 'router-link' |
| | | } |
| | | }, |
| | | methods: { |
| | | linkProps(to) { |
| | | if (this.isExternal) { |
| | | return { |
| | | href: to, |
| | | target: '_blank', |
| | | rel: 'noopener' |
| | | } |
| | | } |
| | | return { |
| | | to: to |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="sidebar-logo-container" :class="{'collapse':collapse}" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }"> |
| | | <transition name="sidebarLogoFade"> |
| | | <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/"> |
| | | <img v-if="logo" :src="logo" class="sidebar-logo" /> |
| | | <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1> |
| | | </router-link> |
| | | <router-link v-else key="expand" class="sidebar-logo-link" to="/"> |
| | | <img v-if="logo" :src="logo" class="sidebar-logo" /> |
| | | <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1> |
| | | </router-link> |
| | | </transition> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import logoImg from '@/assets/logo/logo.png' |
| | | import variables from '@/assets/styles/variables.scss' |
| | | |
| | | export default { |
| | | name: 'SidebarLogo', |
| | | props: { |
| | | collapse: { |
| | | type: Boolean, |
| | | required: true |
| | | } |
| | | }, |
| | | computed: { |
| | | variables() { |
| | | return variables |
| | | }, |
| | | sideTheme() { |
| | | return this.$store.state.settings.sideTheme |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | title: process.env.VUE_APP_TITLE, |
| | | logo: logoImg |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .sidebarLogoFade-enter-active { |
| | | transition: opacity 1.5s; |
| | | } |
| | | |
| | | .sidebarLogoFade-enter, |
| | | .sidebarLogoFade-leave-to { |
| | | opacity: 0; |
| | | } |
| | | |
| | | .sidebar-logo-container { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 50px; |
| | | line-height: 50px; |
| | | background: #2b2f3a; |
| | | text-align: center; |
| | | overflow: hidden; |
| | | |
| | | & .sidebar-logo-link { |
| | | height: 100%; |
| | | width: 100%; |
| | | |
| | | & .sidebar-logo { |
| | | width: 32px; |
| | | height: 32px; |
| | | vertical-align: middle; |
| | | margin-right: 12px; |
| | | } |
| | | |
| | | & .sidebar-title { |
| | | display: inline-block; |
| | | margin: 0; |
| | | color: #fff; |
| | | font-weight: 600; |
| | | line-height: 50px; |
| | | font-size: 14px; |
| | | font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif; |
| | | vertical-align: middle; |
| | | } |
| | | } |
| | | |
| | | &.collapse { |
| | | .sidebar-logo { |
| | | margin-right: 0px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div v-if="!item.hidden"> |
| | | <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"> |
| | | <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path, onlyOneChild.query)"> |
| | | <el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}"> |
| | | <item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" /> |
| | | </el-menu-item> |
| | | </app-link> |
| | | </template> |
| | | |
| | | <el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body> |
| | | <template slot="title"> |
| | | <item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" /> |
| | | </template> |
| | | <sidebar-item |
| | | v-for="(child, index) in item.children" |
| | | :key="child.path + index" |
| | | :is-nest="true" |
| | | :item="child" |
| | | :base-path="resolvePath(child.path)" |
| | | class="nest-menu" |
| | | /> |
| | | </el-submenu> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import path from 'path' |
| | | import { isExternal } from '@/utils/validate' |
| | | import Item from './Item' |
| | | import AppLink from './Link' |
| | | import FixiOSBug from './FixiOSBug' |
| | | |
| | | export default { |
| | | name: 'SidebarItem', |
| | | components: { Item, AppLink }, |
| | | mixins: [FixiOSBug], |
| | | props: { |
| | | // route object |
| | | item: { |
| | | type: Object, |
| | | required: true |
| | | }, |
| | | isNest: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | basePath: { |
| | | type: String, |
| | | default: '' |
| | | } |
| | | }, |
| | | data() { |
| | | this.onlyOneChild = null |
| | | return {} |
| | | }, |
| | | methods: { |
| | | hasOneShowingChild(children = [], parent) { |
| | | if (!children) { |
| | | children = [] |
| | | } |
| | | const showingChildren = children.filter(item => { |
| | | if (item.hidden) { |
| | | return false |
| | | } |
| | | // Temp set(will be used if only has one showing child) |
| | | this.onlyOneChild = item |
| | | return true |
| | | }) |
| | | |
| | | // When there is only one child router, the child router is displayed by default |
| | | if (showingChildren.length === 1) { |
| | | return true |
| | | } |
| | | |
| | | // Show parent if there are no child router to display |
| | | if (showingChildren.length === 0) { |
| | | this.onlyOneChild = { ... parent, path: '', noShowingChildren: true } |
| | | return true |
| | | } |
| | | |
| | | return false |
| | | }, |
| | | resolvePath(routePath, routeQuery) { |
| | | if (isExternal(routePath)) { |
| | | return routePath |
| | | } |
| | | if (isExternal(this.basePath)) { |
| | | return this.basePath |
| | | } |
| | | if (routeQuery) { |
| | | let query = JSON.parse(routeQuery) |
| | | return { path: path.resolve(this.basePath, routePath), query: query } |
| | | } |
| | | return path.resolve(this.basePath, routePath) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div :class="{'has-logo':showLogo}" :style="{ backgroundColor: settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }"> |
| | | <logo v-if="showLogo" :collapse="isCollapse" /> |
| | | <el-scrollbar :class="settings.sideTheme" wrap-class="scrollbar-wrapper"> |
| | | <el-menu |
| | | :default-active="activeMenu" |
| | | :collapse="isCollapse" |
| | | :background-color="settings.sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground" |
| | | :text-color="settings.sideTheme === 'theme-dark' ? variables.menuColor : variables.menuLightColor" |
| | | :unique-opened="true" |
| | | :active-text-color="settings.theme" |
| | | :collapse-transition="false" |
| | | mode="vertical" |
| | | > |
| | | <sidebar-item |
| | | v-for="(route, index) in sidebarRouters" |
| | | :key="route.path + index" |
| | | :item="route" |
| | | :base-path="route.path" |
| | | /> |
| | | </el-menu> |
| | | </el-scrollbar> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapGetters, mapState } from "vuex" |
| | | import Logo from "./Logo" |
| | | import SidebarItem from "./SidebarItem" |
| | | import variables from "@/assets/styles/variables.scss" |
| | | |
| | | export default { |
| | | components: { SidebarItem, Logo }, |
| | | computed: { |
| | | ...mapState(["settings"]), |
| | | ...mapGetters(["sidebarRouters", "sidebar"]), |
| | | activeMenu() { |
| | | const route = this.$route |
| | | const { meta, path } = route |
| | | // if set path, the sidebar will highlight the path you set |
| | | if (meta.activeMenu) { |
| | | return meta.activeMenu |
| | | } |
| | | return path |
| | | }, |
| | | showLogo() { |
| | | return this.$store.state.settings.sidebarLogo |
| | | }, |
| | | variables() { |
| | | return variables |
| | | }, |
| | | isCollapse() { |
| | | return !this.sidebar.opened |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <el-scrollbar ref="scrollContainer" :vertical="false" class="scroll-container" @wheel.native.prevent="handleScroll"> |
| | | <slot /> |
| | | </el-scrollbar> |
| | | </template> |
| | | |
| | | <script> |
| | | const tagAndTagSpacing = 4 // tagAndTagSpacing |
| | | |
| | | export default { |
| | | name: 'ScrollPane', |
| | | data() { |
| | | return { |
| | | left: 0 |
| | | } |
| | | }, |
| | | computed: { |
| | | scrollWrapper() { |
| | | return this.$refs.scrollContainer.$refs.wrap |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.scrollWrapper.addEventListener('scroll', this.emitScroll, true) |
| | | }, |
| | | beforeDestroy() { |
| | | this.scrollWrapper.removeEventListener('scroll', this.emitScroll) |
| | | }, |
| | | methods: { |
| | | handleScroll(e) { |
| | | const eventDelta = e.wheelDelta || -e.deltaY * 40 |
| | | const $scrollWrapper = this.scrollWrapper |
| | | $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4 |
| | | }, |
| | | emitScroll() { |
| | | this.$emit('scroll') |
| | | }, |
| | | moveToTarget(currentTag) { |
| | | const $container = this.$refs.scrollContainer.$el |
| | | const $containerWidth = $container.offsetWidth |
| | | const $scrollWrapper = this.scrollWrapper |
| | | const tagList = this.$parent.$refs.tag |
| | | |
| | | let firstTag = null |
| | | let lastTag = null |
| | | |
| | | // find first tag and last tag |
| | | if (tagList.length > 0) { |
| | | firstTag = tagList[0] |
| | | lastTag = tagList[tagList.length - 1] |
| | | } |
| | | |
| | | if (firstTag === currentTag) { |
| | | $scrollWrapper.scrollLeft = 0 |
| | | } else if (lastTag === currentTag) { |
| | | $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth |
| | | } else { |
| | | // find preTag and nextTag |
| | | const currentIndex = tagList.findIndex(item => item === currentTag) |
| | | const prevTag = tagList[currentIndex - 1] |
| | | const nextTag = tagList[currentIndex + 1] |
| | | |
| | | // the tag's offsetLeft after of nextTag |
| | | const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing |
| | | |
| | | // the tag's offsetLeft before of prevTag |
| | | const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing |
| | | |
| | | if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) { |
| | | $scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth |
| | | } else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) { |
| | | $scrollWrapper.scrollLeft = beforePrevTagOffsetLeft |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .scroll-container { |
| | | white-space: nowrap; |
| | | position: relative; |
| | | overflow: hidden; |
| | | width: 100%; |
| | | ::v-deep { |
| | | .el-scrollbar__bar { |
| | | bottom: 0px; |
| | | } |
| | | .el-scrollbar__wrap { |
| | | height: 49px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div id="tags-view-container" class="tags-view-container"> |
| | | <scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll"> |
| | | <router-link |
| | | v-for="tag in visitedViews" |
| | | ref="tag" |
| | | :key="tag.path" |
| | | :class="{ 'active': isActive(tag), 'has-icon': tagsIcon }" |
| | | :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }" |
| | | tag="span" |
| | | class="tags-view-item" |
| | | :style="activeStyle(tag)" |
| | | @click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''" |
| | | @contextmenu.prevent.native="openMenu(tag,$event)" |
| | | > |
| | | <svg-icon v-if="tagsIcon && tag.meta && tag.meta.icon && tag.meta.icon !== '#'" :icon-class="tag.meta.icon" /> |
| | | {{ tag.title }} |
| | | <span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" /> |
| | | </router-link> |
| | | </scroll-pane> |
| | | <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu"> |
| | | <li @click="refreshSelectedTag(selectedTag)"><i class="el-icon-refresh-right"></i> 刷新页面</li> |
| | | <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)"><i class="el-icon-close"></i> 关闭当前</li> |
| | | <li @click="closeOthersTags"><i class="el-icon-circle-close"></i> 关闭其他</li> |
| | | <li v-if="!isFirstView()" @click="closeLeftTags"><i class="el-icon-back"></i> 关闭左侧</li> |
| | | <li v-if="!isLastView()" @click="closeRightTags"><i class="el-icon-right"></i> 关闭右侧</li> |
| | | <li @click="closeAllTags(selectedTag)"><i class="el-icon-circle-close"></i> 全部关闭</li> |
| | | </ul> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import ScrollPane from './ScrollPane' |
| | | import path from 'path' |
| | | |
| | | export default { |
| | | components: { ScrollPane }, |
| | | data() { |
| | | return { |
| | | visible: false, |
| | | top: 0, |
| | | left: 0, |
| | | selectedTag: {}, |
| | | affixTags: [] |
| | | } |
| | | }, |
| | | computed: { |
| | | visitedViews() { |
| | | return this.$store.state.tagsView.visitedViews |
| | | }, |
| | | routes() { |
| | | return this.$store.state.permission.routes |
| | | }, |
| | | theme() { |
| | | return this.$store.state.settings.theme |
| | | }, |
| | | tagsIcon() { |
| | | return this.$store.state.settings.tagsIcon |
| | | } |
| | | }, |
| | | watch: { |
| | | $route() { |
| | | this.addTags() |
| | | this.moveToCurrentTag() |
| | | }, |
| | | visible(value) { |
| | | if (value) { |
| | | document.body.addEventListener('click', this.closeMenu) |
| | | } else { |
| | | document.body.removeEventListener('click', this.closeMenu) |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.initTags() |
| | | this.addTags() |
| | | }, |
| | | methods: { |
| | | isActive(route) { |
| | | return route.path === this.$route.path |
| | | }, |
| | | activeStyle(tag) { |
| | | if (!this.isActive(tag)) return {} |
| | | return { |
| | | "background-color": this.theme, |
| | | "border-color": this.theme |
| | | } |
| | | }, |
| | | isAffix(tag) { |
| | | return tag.meta && tag.meta.affix |
| | | }, |
| | | isFirstView() { |
| | | try { |
| | | return this.selectedTag.fullPath === '/index' || this.selectedTag.fullPath === this.visitedViews[1].fullPath |
| | | } catch (err) { |
| | | return false |
| | | } |
| | | }, |
| | | isLastView() { |
| | | try { |
| | | return this.selectedTag.fullPath === this.visitedViews[this.visitedViews.length - 1].fullPath |
| | | } catch (err) { |
| | | return false |
| | | } |
| | | }, |
| | | filterAffixTags(routes, basePath = '/') { |
| | | let tags = [] |
| | | routes.forEach(route => { |
| | | if (route.meta && route.meta.affix) { |
| | | const tagPath = path.resolve(basePath, route.path) |
| | | tags.push({ |
| | | fullPath: tagPath, |
| | | path: tagPath, |
| | | name: route.name, |
| | | meta: { ...route.meta } |
| | | }) |
| | | } |
| | | if (route.children) { |
| | | const tempTags = this.filterAffixTags(route.children, route.path) |
| | | if (tempTags.length >= 1) { |
| | | tags = [...tags, ...tempTags] |
| | | } |
| | | } |
| | | }) |
| | | return tags |
| | | }, |
| | | initTags() { |
| | | const affixTags = this.affixTags = this.filterAffixTags(this.routes) |
| | | for (const tag of affixTags) { |
| | | // Must have tag name |
| | | if (tag.name) { |
| | | this.$store.dispatch('tagsView/addVisitedView', tag) |
| | | } |
| | | } |
| | | }, |
| | | addTags() { |
| | | const { name } = this.$route |
| | | if (name) { |
| | | this.$store.dispatch('tagsView/addView', this.$route) |
| | | } |
| | | }, |
| | | moveToCurrentTag() { |
| | | const tags = this.$refs.tag |
| | | this.$nextTick(() => { |
| | | for (const tag of tags) { |
| | | if (tag.to.path === this.$route.path) { |
| | | this.$refs.scrollPane.moveToTarget(tag) |
| | | // when query is different then update |
| | | if (tag.to.fullPath !== this.$route.fullPath) { |
| | | this.$store.dispatch('tagsView/updateVisitedView', this.$route) |
| | | } |
| | | break |
| | | } |
| | | } |
| | | }) |
| | | }, |
| | | refreshSelectedTag(view) { |
| | | this.$tab.refreshPage(view) |
| | | if (this.$route.meta.link) { |
| | | this.$store.dispatch('tagsView/delIframeView', this.$route) |
| | | } |
| | | }, |
| | | closeSelectedTag(view) { |
| | | this.$tab.closePage(view).then(({ visitedViews }) => { |
| | | if (this.isActive(view)) { |
| | | this.toLastView(visitedViews, view) |
| | | } |
| | | }) |
| | | }, |
| | | closeRightTags() { |
| | | this.$tab.closeRightPage(this.selectedTag).then(visitedViews => { |
| | | if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) { |
| | | this.toLastView(visitedViews) |
| | | } |
| | | }) |
| | | }, |
| | | closeLeftTags() { |
| | | this.$tab.closeLeftPage(this.selectedTag).then(visitedViews => { |
| | | if (!visitedViews.find(i => i.fullPath === this.$route.fullPath)) { |
| | | this.toLastView(visitedViews) |
| | | } |
| | | }) |
| | | }, |
| | | closeOthersTags() { |
| | | this.$router.push(this.selectedTag.fullPath).catch(()=>{}) |
| | | this.$tab.closeOtherPage(this.selectedTag).then(() => { |
| | | this.moveToCurrentTag() |
| | | }) |
| | | }, |
| | | closeAllTags(view) { |
| | | this.$tab.closeAllPage().then(({ visitedViews }) => { |
| | | if (this.affixTags.some(tag => tag.path === this.$route.path)) { |
| | | return |
| | | } |
| | | this.toLastView(visitedViews, view) |
| | | }) |
| | | }, |
| | | toLastView(visitedViews, view) { |
| | | const latestView = visitedViews.slice(-1)[0] |
| | | if (latestView) { |
| | | this.$router.push(latestView.fullPath) |
| | | } else { |
| | | // now the default is to redirect to the home page if there is no tags-view, |
| | | // you can adjust it according to your needs. |
| | | if (view.name === 'Dashboard') { |
| | | // to reload home page |
| | | this.$router.replace({ path: '/redirect' + view.fullPath }) |
| | | } else { |
| | | this.$router.push('/') |
| | | } |
| | | } |
| | | }, |
| | | openMenu(tag, e) { |
| | | const menuMinWidth = 105 |
| | | const offsetLeft = this.$el.getBoundingClientRect().left // container margin left |
| | | const offsetWidth = this.$el.offsetWidth // container width |
| | | const maxLeft = offsetWidth - menuMinWidth // left boundary |
| | | const left = e.clientX - offsetLeft + 15 // 15: margin right |
| | | |
| | | if (left > maxLeft) { |
| | | this.left = maxLeft |
| | | } else { |
| | | this.left = left |
| | | } |
| | | |
| | | this.top = e.clientY |
| | | this.visible = true |
| | | this.selectedTag = tag |
| | | }, |
| | | closeMenu() { |
| | | this.visible = false |
| | | }, |
| | | handleScroll() { |
| | | this.closeMenu() |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .tags-view-container { |
| | | height: 34px; |
| | | width: 100%; |
| | | background: #fff; |
| | | border-bottom: 1px solid #d8dce5; |
| | | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04); |
| | | .tags-view-wrapper { |
| | | .tags-view-item { |
| | | display: inline-block; |
| | | position: relative; |
| | | cursor: pointer; |
| | | height: 26px; |
| | | line-height: 26px; |
| | | border: 1px solid #d8dce5; |
| | | color: #495060; |
| | | background: #fff; |
| | | padding: 0 8px; |
| | | font-size: 12px; |
| | | margin-left: 5px; |
| | | margin-top: 4px; |
| | | &:first-of-type { |
| | | margin-left: 15px; |
| | | } |
| | | &:last-of-type { |
| | | margin-right: 15px; |
| | | } |
| | | &.active { |
| | | background-color: #42b983; |
| | | color: #fff; |
| | | border-color: #42b983; |
| | | &::before { |
| | | content: ''; |
| | | background: #fff; |
| | | display: inline-block; |
| | | width: 8px; |
| | | height: 8px; |
| | | border-radius: 50%; |
| | | position: relative; |
| | | margin-right: 2px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .tags-view-item.active.has-icon::before { |
| | | content: none !important; |
| | | } |
| | | |
| | | .contextmenu { |
| | | margin: 0; |
| | | background: #fff; |
| | | z-index: 3000; |
| | | position: absolute; |
| | | list-style-type: none; |
| | | padding: 5px 0; |
| | | border-radius: 4px; |
| | | font-size: 12px; |
| | | font-weight: 400; |
| | | color: #333; |
| | | box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3); |
| | | li { |
| | | margin: 0; |
| | | padding: 7px 16px; |
| | | cursor: pointer; |
| | | &:hover { |
| | | background: #eee; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | <style lang="scss"> |
| | | //reset element css of el-icon-close |
| | | .tags-view-wrapper { |
| | | .tags-view-item { |
| | | .el-icon-close { |
| | | width: 16px; |
| | | height: 16px; |
| | | vertical-align: 2px; |
| | | border-radius: 50%; |
| | | text-align: center; |
| | | transition: all .3s cubic-bezier(.645, .045, .355, 1); |
| | | transform-origin: 100% 50%; |
| | | &:before { |
| | | transform: scale(.6); |
| | | display: inline-block; |
| | | vertical-align: -3px; |
| | | } |
| | | &:hover { |
| | | background-color: #b4bccc; |
| | | color: #fff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | export { default as AppMain } from './AppMain' |
| | | export { default as Navbar } from './Navbar' |
| | | export { default as Settings } from './Settings' |
| | | export { default as Sidebar } from './Sidebar/index.vue' |
| | | export { default as TagsView } from './TagsView/index.vue' |
New file |
| | |
| | | <template> |
| | | <div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}"> |
| | | <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/> |
| | | <sidebar v-if="!sidebar.hide" class="sidebar-container"/> |
| | | <div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container"> |
| | | <div :class="{'fixed-header':fixedHeader}"> |
| | | <navbar @setLayout="setLayout"/> |
| | | <tags-view v-if="needTagsView"/> |
| | | </div> |
| | | <app-main/> |
| | | <settings ref="settingRef"/> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components' |
| | | import ResizeMixin from './mixin/ResizeHandler' |
| | | import { mapState } from 'vuex' |
| | | import variables from '@/assets/styles/variables.scss' |
| | | |
| | | export default { |
| | | name: 'Layout', |
| | | components: { |
| | | AppMain, |
| | | Navbar, |
| | | Settings, |
| | | Sidebar, |
| | | TagsView |
| | | }, |
| | | mixins: [ResizeMixin], |
| | | computed: { |
| | | ...mapState({ |
| | | theme: state => state.settings.theme, |
| | | sideTheme: state => state.settings.sideTheme, |
| | | sidebar: state => state.app.sidebar, |
| | | device: state => state.app.device, |
| | | needTagsView: state => state.settings.tagsView, |
| | | fixedHeader: state => state.settings.fixedHeader |
| | | }), |
| | | classObj() { |
| | | return { |
| | | hideSidebar: !this.sidebar.opened, |
| | | openSidebar: this.sidebar.opened, |
| | | withoutAnimation: this.sidebar.withoutAnimation, |
| | | mobile: this.device === 'mobile' |
| | | } |
| | | }, |
| | | variables() { |
| | | return variables |
| | | } |
| | | }, |
| | | methods: { |
| | | handleClickOutside() { |
| | | this.$store.dispatch('app/closeSideBar', { withoutAnimation: false }) |
| | | }, |
| | | setLayout() { |
| | | this.$refs.settingRef.openSetting() |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import "~@/assets/styles/mixin.scss"; |
| | | @import "~@/assets/styles/variables.scss"; |
| | | |
| | | .app-wrapper { |
| | | @include clearfix; |
| | | position: relative; |
| | | height: 100%; |
| | | width: 100%; |
| | | |
| | | &.mobile.openSidebar { |
| | | position: fixed; |
| | | top: 0; |
| | | } |
| | | } |
| | | |
| | | .drawer-bg { |
| | | background: #000; |
| | | opacity: 0.3; |
| | | width: 100%; |
| | | top: 0; |
| | | height: 100%; |
| | | position: absolute; |
| | | z-index: 999; |
| | | } |
| | | |
| | | .fixed-header { |
| | | position: fixed; |
| | | top: 0; |
| | | right: 0; |
| | | z-index: 9; |
| | | width: calc(100% - #{$base-sidebar-width}); |
| | | transition: width 0.28s; |
| | | } |
| | | |
| | | .hideSidebar .fixed-header { |
| | | width: calc(100% - 54px); |
| | | } |
| | | |
| | | .sidebarHide .fixed-header { |
| | | width: 100%; |
| | | } |
| | | |
| | | .mobile .fixed-header { |
| | | width: 100%; |
| | | } |
| | | </style> |
New file |
| | |
| | | import store from '@/store' |
| | | |
| | | const { body } = document |
| | | const WIDTH = 992 // refer to Bootstrap's responsive design |
| | | |
| | | export default { |
| | | watch: { |
| | | $route(route) { |
| | | if (this.device === 'mobile' && this.sidebar.opened) { |
| | | store.dispatch('app/closeSideBar', { withoutAnimation: false }) |
| | | } |
| | | } |
| | | }, |
| | | beforeMount() { |
| | | window.addEventListener('resize', this.$_resizeHandler) |
| | | }, |
| | | beforeDestroy() { |
| | | window.removeEventListener('resize', this.$_resizeHandler) |
| | | }, |
| | | mounted() { |
| | | const isMobile = this.$_isMobile() |
| | | if (isMobile) { |
| | | store.dispatch('app/toggleDevice', 'mobile') |
| | | store.dispatch('app/closeSideBar', { withoutAnimation: true }) |
| | | } |
| | | }, |
| | | methods: { |
| | | // use $_ for mixins properties |
| | | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential |
| | | $_isMobile() { |
| | | const rect = body.getBoundingClientRect() |
| | | return rect.width - 1 < WIDTH |
| | | }, |
| | | $_resizeHandler() { |
| | | if (!document.hidden) { |
| | | const isMobile = this.$_isMobile() |
| | | store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop') |
| | | |
| | | if (isMobile) { |
| | | store.dispatch('app/closeSideBar', { withoutAnimation: true }) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | import Vue from 'vue' |
| | | |
| | | import Cookies from 'js-cookie' |
| | | |
| | | import Element from 'element-ui' |
| | | import './assets/styles/element-variables.scss' |
| | | |
| | | import '@/assets/styles/index.scss' // global css |
| | | import '@/assets/styles/ruoyi.scss' // ruoyi css |
| | | import App from './App' |
| | | import store from './store' |
| | | import router from './router' |
| | | import directive from './directive' // directive |
| | | import plugins from './plugins' // plugins |
| | | import { download } from '@/utils/request' |
| | | |
| | | import './assets/icons' // icon |
| | | import './permission' // permission control |
| | | import { getDicts } from "@/api/system/dict/data" |
| | | import { getConfigKey } from "@/api/system/config" |
| | | import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi" |
| | | // 分页组件 |
| | | import Pagination from "@/components/Pagination" |
| | | // 自定义表格工具组件 |
| | | import RightToolbar from "@/components/RightToolbar" |
| | | // 富文本组件 |
| | | import Editor from "@/components/Editor" |
| | | // 文件上传组件 |
| | | import FileUpload from "@/components/FileUpload" |
| | | // 图片上传组件 |
| | | import ImageUpload from "@/components/ImageUpload" |
| | | // 图片预览组件 |
| | | import ImagePreview from "@/components/ImagePreview" |
| | | // 字典标签组件 |
| | | import DictTag from '@/components/DictTag' |
| | | // 字典数据组件 |
| | | import DictData from '@/components/DictData' |
| | | |
| | | // 全局方法挂载 |
| | | Vue.prototype.getDicts = getDicts |
| | | Vue.prototype.getConfigKey = getConfigKey |
| | | Vue.prototype.parseTime = parseTime |
| | | Vue.prototype.resetForm = resetForm |
| | | Vue.prototype.addDateRange = addDateRange |
| | | Vue.prototype.selectDictLabel = selectDictLabel |
| | | Vue.prototype.selectDictLabels = selectDictLabels |
| | | Vue.prototype.download = download |
| | | Vue.prototype.handleTree = handleTree |
| | | |
| | | // 全局组件挂载 |
| | | Vue.component('DictTag', DictTag) |
| | | Vue.component('Pagination', Pagination) |
| | | Vue.component('RightToolbar', RightToolbar) |
| | | Vue.component('Editor', Editor) |
| | | Vue.component('FileUpload', FileUpload) |
| | | Vue.component('ImageUpload', ImageUpload) |
| | | Vue.component('ImagePreview', ImagePreview) |
| | | |
| | | Vue.use(directive) |
| | | Vue.use(plugins) |
| | | DictData.install() |
| | | |
| | | /** |
| | | * If you don't want to use mock-server |
| | | * you want to use MockJs for mock api |
| | | * you can execute: mockXHR() |
| | | * |
| | | * Currently MockJs will be used in the production environment, |
| | | * please remove it before going online! ! ! |
| | | */ |
| | | |
| | | Vue.use(Element, { |
| | | size: Cookies.get('size') || 'medium' // set element-ui default size |
| | | }) |
| | | |
| | | Vue.config.productionTip = false |
| | | |
| | | new Vue({ |
| | | el: '#app', |
| | | router, |
| | | store, |
| | | render: h => h(App) |
| | | }) |
New file |
| | |
| | | import router from './router' |
| | | import store from './store' |
| | | import { Message } from 'element-ui' |
| | | import NProgress from 'nprogress' |
| | | import 'nprogress/nprogress.css' |
| | | import { getToken } from '@/utils/auth' |
| | | import { isPathMatch } from '@/utils/validate' |
| | | import { isRelogin } from '@/utils/request' |
| | | |
| | | NProgress.configure({ showSpinner: false }) |
| | | |
| | | const whiteList = ['/login', '/register'] |
| | | |
| | | const isWhiteList = (path) => { |
| | | return whiteList.some(pattern => isPathMatch(pattern, path)) |
| | | } |
| | | |
| | | router.beforeEach((to, from, next) => { |
| | | NProgress.start() |
| | | if (getToken()) { |
| | | to.meta.title && store.dispatch('settings/setTitle', to.meta.title) |
| | | /* has token*/ |
| | | if (to.path === '/login') { |
| | | next({ path: '/' }) |
| | | NProgress.done() |
| | | } else if (isWhiteList(to.path)) { |
| | | next() |
| | | } else { |
| | | if (store.getters.roles.length === 0) { |
| | | isRelogin.show = true |
| | | // 判断当前用户是否已拉取完user_info信息 |
| | | store.dispatch('GetInfo').then(() => { |
| | | isRelogin.show = false |
| | | store.dispatch('GenerateRoutes').then(accessRoutes => { |
| | | // 根据roles权限生成可访问的路由表 |
| | | router.addRoutes(accessRoutes) // 动态添加可访问路由表 |
| | | next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 |
| | | }) |
| | | }).catch(err => { |
| | | store.dispatch('LogOut').then(() => { |
| | | Message.error(err) |
| | | next({ path: '/' }) |
| | | }) |
| | | }) |
| | | } else { |
| | | next() |
| | | } |
| | | } |
| | | } else { |
| | | // 没有token |
| | | if (isWhiteList(to.path)) { |
| | | // 在免登录白名单,直接进入 |
| | | next() |
| | | } else { |
| | | next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页 |
| | | NProgress.done() |
| | | } |
| | | } |
| | | }) |
| | | |
| | | router.afterEach(() => { |
| | | NProgress.done() |
| | | }) |
New file |
| | |
| | | import store from '@/store' |
| | | |
| | | function authPermission(permission) { |
| | | const all_permission = "*:*:*" |
| | | const permissions = store.getters && store.getters.permissions |
| | | if (permission && permission.length > 0) { |
| | | return permissions.some(v => { |
| | | return all_permission === v || v === permission |
| | | }) |
| | | } else { |
| | | return false |
| | | } |
| | | } |
| | | |
| | | function authRole(role) { |
| | | const super_admin = "admin" |
| | | const roles = store.getters && store.getters.roles |
| | | if (role && role.length > 0) { |
| | | return roles.some(v => { |
| | | return super_admin === v || v === role |
| | | }) |
| | | } else { |
| | | return false |
| | | } |
| | | } |
| | | |
| | | export default { |
| | | // 验证用户是否具备某权限 |
| | | hasPermi(permission) { |
| | | return authPermission(permission) |
| | | }, |
| | | // 验证用户是否含有指定权限,只需包含其中一个 |
| | | hasPermiOr(permissions) { |
| | | return permissions.some(item => { |
| | | return authPermission(item) |
| | | }) |
| | | }, |
| | | // 验证用户是否含有指定权限,必须全部拥有 |
| | | hasPermiAnd(permissions) { |
| | | return permissions.every(item => { |
| | | return authPermission(item) |
| | | }) |
| | | }, |
| | | // 验证用户是否具备某角色 |
| | | hasRole(role) { |
| | | return authRole(role) |
| | | }, |
| | | // 验证用户是否含有指定角色,只需包含其中一个 |
| | | hasRoleOr(roles) { |
| | | return roles.some(item => { |
| | | return authRole(item) |
| | | }) |
| | | }, |
| | | // 验证用户是否含有指定角色,必须全部拥有 |
| | | hasRoleAnd(roles) { |
| | | return roles.every(item => { |
| | | return authRole(item) |
| | | }) |
| | | } |
| | | } |
New file |
| | |
| | | const sessionCache = { |
| | | set (key, value) { |
| | | if (!sessionStorage) { |
| | | return |
| | | } |
| | | if (key != null && value != null) { |
| | | sessionStorage.setItem(key, value) |
| | | } |
| | | }, |
| | | get (key) { |
| | | if (!sessionStorage) { |
| | | return null |
| | | } |
| | | if (key == null) { |
| | | return null |
| | | } |
| | | return sessionStorage.getItem(key) |
| | | }, |
| | | setJSON (key, jsonValue) { |
| | | if (jsonValue != null) { |
| | | this.set(key, JSON.stringify(jsonValue)) |
| | | } |
| | | }, |
| | | getJSON (key) { |
| | | const value = this.get(key) |
| | | if (value != null) { |
| | | return JSON.parse(value) |
| | | } |
| | | return null |
| | | }, |
| | | remove (key) { |
| | | sessionStorage.removeItem(key) |
| | | } |
| | | } |
| | | const localCache = { |
| | | set (key, value) { |
| | | if (!localStorage) { |
| | | return |
| | | } |
| | | if (key != null && value != null) { |
| | | localStorage.setItem(key, value) |
| | | } |
| | | }, |
| | | get (key) { |
| | | if (!localStorage) { |
| | | return null |
| | | } |
| | | if (key == null) { |
| | | return null |
| | | } |
| | | return localStorage.getItem(key) |
| | | }, |
| | | setJSON (key, jsonValue) { |
| | | if (jsonValue != null) { |
| | | this.set(key, JSON.stringify(jsonValue)) |
| | | } |
| | | }, |
| | | getJSON (key) { |
| | | const value = this.get(key) |
| | | if (value != null) { |
| | | return JSON.parse(value) |
| | | } |
| | | return null |
| | | }, |
| | | remove (key) { |
| | | localStorage.removeItem(key) |
| | | } |
| | | } |
| | | |
| | | export default { |
| | | /** |
| | | * 会话级缓存 |
| | | */ |
| | | session: sessionCache, |
| | | /** |
| | | * 本地缓存 |
| | | */ |
| | | local: localCache |
| | | } |
New file |
| | |
| | | import axios from 'axios' |
| | | import {Loading, Message} from 'element-ui' |
| | | import { saveAs } from 'file-saver' |
| | | import { getToken } from '@/utils/auth' |
| | | import errorCode from '@/utils/errorCode' |
| | | import { blobValidate } from "@/utils/ruoyi" |
| | | |
| | | const baseURL = process.env.VUE_APP_BASE_API |
| | | let downloadLoadingInstance |
| | | |
| | | export default { |
| | | name(name, isDelete = true) { |
| | | var url = baseURL + "/common/download?fileName=" + encodeURIComponent(name) + "&delete=" + isDelete |
| | | axios({ |
| | | method: 'get', |
| | | url: url, |
| | | responseType: 'blob', |
| | | headers: { 'Authorization': 'Bearer ' + getToken() } |
| | | }).then((res) => { |
| | | const isBlob = blobValidate(res.data) |
| | | if (isBlob) { |
| | | const blob = new Blob([res.data]) |
| | | this.saveAs(blob, decodeURIComponent(res.headers['download-filename'])) |
| | | } else { |
| | | this.printErrMsg(res.data) |
| | | } |
| | | }) |
| | | }, |
| | | resource(resource) { |
| | | var url = baseURL + "/common/download/resource?resource=" + encodeURIComponent(resource) |
| | | axios({ |
| | | method: 'get', |
| | | url: url, |
| | | responseType: 'blob', |
| | | headers: { 'Authorization': 'Bearer ' + getToken() } |
| | | }).then((res) => { |
| | | const isBlob = blobValidate(res.data) |
| | | if (isBlob) { |
| | | const blob = new Blob([res.data]) |
| | | this.saveAs(blob, decodeURIComponent(res.headers['download-filename'])) |
| | | } else { |
| | | this.printErrMsg(res.data) |
| | | } |
| | | }) |
| | | }, |
| | | zip(url, name) { |
| | | var url = baseURL + url |
| | | downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }) |
| | | axios({ |
| | | method: 'get', |
| | | url: url, |
| | | responseType: 'blob', |
| | | headers: { 'Authorization': 'Bearer ' + getToken() } |
| | | }).then((res) => { |
| | | const isBlob = blobValidate(res.data) |
| | | if (isBlob) { |
| | | const blob = new Blob([res.data], { type: 'application/zip' }) |
| | | this.saveAs(blob, name) |
| | | } else { |
| | | this.printErrMsg(res.data) |
| | | } |
| | | downloadLoadingInstance.close() |
| | | }).catch((r) => { |
| | | console.error(r) |
| | | Message.error('下载文件出现错误,请联系管理员!') |
| | | downloadLoadingInstance.close() |
| | | }) |
| | | }, |
| | | saveAs(text, name, opts) { |
| | | saveAs(text, name, opts) |
| | | }, |
| | | async printErrMsg(data) { |
| | | const resText = await data.text() |
| | | const rspObj = JSON.parse(resText) |
| | | const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] |
| | | Message.error(errMsg) |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | import tab from './tab' |
| | | import auth from './auth' |
| | | import cache from './cache' |
| | | import modal from './modal' |
| | | import download from './download' |
| | | |
| | | export default { |
| | | install(Vue) { |
| | | // 页签操作 |
| | | Vue.prototype.$tab = tab |
| | | // 认证对象 |
| | | Vue.prototype.$auth = auth |
| | | // 缓存对象 |
| | | Vue.prototype.$cache = cache |
| | | // 模态框对象 |
| | | Vue.prototype.$modal = modal |
| | | // 下载文件 |
| | | Vue.prototype.$download = download |
| | | } |
| | | } |
New file |
| | |
| | | import { Message, MessageBox, Notification, Loading } from 'element-ui' |
| | | |
| | | let loadingInstance |
| | | |
| | | export default { |
| | | // 消息提示 |
| | | msg(content) { |
| | | Message.info(content) |
| | | }, |
| | | // 错误消息 |
| | | msgError(content) { |
| | | Message.error(content) |
| | | }, |
| | | // 成功消息 |
| | | msgSuccess(content) { |
| | | Message.success(content) |
| | | }, |
| | | // 警告消息 |
| | | msgWarning(content) { |
| | | Message.warning(content) |
| | | }, |
| | | // 弹出提示 |
| | | alert(content) { |
| | | MessageBox.alert(content, "系统提示") |
| | | }, |
| | | // 错误提示 |
| | | alertError(content) { |
| | | MessageBox.alert(content, "系统提示", { type: 'error' }) |
| | | }, |
| | | // 成功提示 |
| | | alertSuccess(content) { |
| | | MessageBox.alert(content, "系统提示", { type: 'success' }) |
| | | }, |
| | | // 警告提示 |
| | | alertWarning(content) { |
| | | MessageBox.alert(content, "系统提示", { type: 'warning' }) |
| | | }, |
| | | // 通知提示 |
| | | notify(content) { |
| | | Notification.info(content) |
| | | }, |
| | | // 错误通知 |
| | | notifyError(content) { |
| | | Notification.error(content) |
| | | }, |
| | | // 成功通知 |
| | | notifySuccess(content) { |
| | | Notification.success(content) |
| | | }, |
| | | // 警告通知 |
| | | notifyWarning(content) { |
| | | Notification.warning(content) |
| | | }, |
| | | // 确认窗体 |
| | | confirm(content) { |
| | | return MessageBox.confirm(content, "系统提示", { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: "warning", |
| | | }) |
| | | }, |
| | | // 提交内容 |
| | | prompt(content) { |
| | | return MessageBox.prompt(content, "系统提示", { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: "warning", |
| | | }) |
| | | }, |
| | | // 打开遮罩层 |
| | | loading(content) { |
| | | loadingInstance = Loading.service({ |
| | | lock: true, |
| | | text: content, |
| | | spinner: "el-icon-loading", |
| | | background: "rgba(0, 0, 0, 0.7)", |
| | | }) |
| | | }, |
| | | // 关闭遮罩层 |
| | | closeLoading() { |
| | | loadingInstance.close() |
| | | } |
| | | } |
New file |
| | |
| | | import store from '@/store' |
| | | import router from '@/router' |
| | | |
| | | export default { |
| | | // 刷新当前tab页签 |
| | | refreshPage(obj) { |
| | | const { path, query, matched } = router.currentRoute |
| | | if (obj === undefined) { |
| | | matched.forEach((m) => { |
| | | if (m.components && m.components.default && m.components.default.name) { |
| | | if (!['Layout', 'ParentView'].includes(m.components.default.name)) { |
| | | obj = { name: m.components.default.name, path: path, query: query } |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | return store.dispatch('tagsView/delCachedView', obj).then(() => { |
| | | const { path, query } = obj |
| | | router.replace({ |
| | | path: '/redirect' + path, |
| | | query: query |
| | | }) |
| | | }) |
| | | }, |
| | | // 关闭当前tab页签,打开新页签 |
| | | closeOpenPage(obj) { |
| | | store.dispatch("tagsView/delView", router.currentRoute) |
| | | if (obj !== undefined) { |
| | | return router.push(obj) |
| | | } |
| | | }, |
| | | // 关闭指定tab页签 |
| | | closePage(obj) { |
| | | if (obj === undefined) { |
| | | return store.dispatch('tagsView/delView', router.currentRoute).then(({ visitedViews }) => { |
| | | const latestView = visitedViews.slice(-1)[0] |
| | | if (latestView) { |
| | | return router.push(latestView.fullPath) |
| | | } |
| | | return router.push('/') |
| | | }) |
| | | } |
| | | return store.dispatch('tagsView/delView', obj) |
| | | }, |
| | | // 关闭所有tab页签 |
| | | closeAllPage() { |
| | | return store.dispatch('tagsView/delAllViews') |
| | | }, |
| | | // 关闭左侧tab页签 |
| | | closeLeftPage(obj) { |
| | | return store.dispatch('tagsView/delLeftTags', obj || router.currentRoute) |
| | | }, |
| | | // 关闭右侧tab页签 |
| | | closeRightPage(obj) { |
| | | return store.dispatch('tagsView/delRightTags', obj || router.currentRoute) |
| | | }, |
| | | // 关闭其他tab页签 |
| | | closeOtherPage(obj) { |
| | | return store.dispatch('tagsView/delOthersViews', obj || router.currentRoute) |
| | | }, |
| | | // 添加tab页签 |
| | | openPage(title, url, params) { |
| | | const obj = { path: url, meta: { title: title } } |
| | | store.dispatch('tagsView/addView', obj) |
| | | return router.push({ path: url, query: params }) |
| | | }, |
| | | // 修改tab页签 |
| | | updatePage(obj) { |
| | | return store.dispatch('tagsView/updateVisitedView', obj) |
| | | } |
| | | } |
New file |
| | |
| | | import Vue from 'vue' |
| | | import Router from 'vue-router' |
| | | |
| | | Vue.use(Router) |
| | | |
| | | /* Layout */ |
| | | import Layout from '@/layout' |
| | | |
| | | /** |
| | | * Note: 路由配置项 |
| | | * |
| | | * hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1 |
| | | * alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 |
| | | * // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面 |
| | | * // 若你想不管路由下面的 children 声明的个数都显示你的根路由 |
| | | * // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由 |
| | | * redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 |
| | | * name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题 |
| | | * query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数 |
| | | * roles: ['admin', 'common'] // 访问路由的角色权限 |
| | | * permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限 |
| | | * meta : { |
| | | noCache: true // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false) |
| | | title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 |
| | | icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg |
| | | breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示 |
| | | activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。 |
| | | } |
| | | */ |
| | | |
| | | // 公共路由 |
| | | export const constantRoutes = [ |
| | | { |
| | | path: '/redirect', |
| | | component: Layout, |
| | | hidden: true, |
| | | children: [ |
| | | { |
| | | path: '/redirect/:path(.*)', |
| | | component: () => import('@/views/redirect') |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/login', |
| | | component: () => import('@/views/login'), |
| | | hidden: true |
| | | }, |
| | | { |
| | | path: '/register', |
| | | component: () => import('@/views/register'), |
| | | hidden: true |
| | | }, |
| | | { |
| | | path: '/404', |
| | | component: () => import('@/views/error/404'), |
| | | hidden: true |
| | | }, |
| | | { |
| | | path: '/401', |
| | | component: () => import('@/views/error/401'), |
| | | hidden: true |
| | | }, |
| | | |
| | | { |
| | | path: '', |
| | | component: Layout, |
| | | redirect: 'index', |
| | | children: [ |
| | | { |
| | | path: 'index', |
| | | component: () => import('@/views/index'), |
| | | name: 'Index', |
| | | meta: { title: '首页', icon: 'dashboard', affix: true } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/user', |
| | | component: Layout, |
| | | hidden: true, |
| | | redirect: 'noredirect', |
| | | children: [ |
| | | { |
| | | path: 'profile', |
| | | component: () => import('@/views/system/user/profile/index'), |
| | | name: 'Profile', |
| | | meta: { title: '个人中心', icon: 'user' } |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | |
| | | // 动态路由,基于用户权限动态去加载 |
| | | export const dynamicRoutes = [ |
| | | { |
| | | path: '/system/user-auth', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:user:edit'], |
| | | children: [ |
| | | { |
| | | path: 'role/:userId(\\d+)', |
| | | component: () => import('@/views/system/user/authRole'), |
| | | name: 'AuthRole', |
| | | meta: { title: '分配角色', activeMenu: '/system/user' } |
| | | } |
| | | ] |
| | | }, |
| | | //案卷管理 |
| | | { |
| | | path: '/archiveManager/infoManagerAu', |
| | | component: Layout, |
| | | // permissions: [], |
| | | hidden: true, |
| | | permissions: ['system:records:edit'], |
| | | children: [ |
| | | { |
| | | path: 'user/:roleId(\\d+)', |
| | | component: () => import('@/views/archiveManager/arMAutoUser'), |
| | | name: 'AuthUser127', |
| | | meta: { title: '分配用户', activeMenu: '/archiveManager/infoManager' } |
| | | } |
| | | ] |
| | | }, |
| | | //案卷分配用户 |
| | | // { |
| | | // path: '/archiveManager/infoAuthManager', |
| | | // component: Layout, |
| | | // // permissions: [], |
| | | // hidden: true, |
| | | // // permissions: ['familymodel:doctor:info'], |
| | | // children: [ |
| | | // { |
| | | // path: 'user/:roleId(\\d+)', |
| | | // component: () => import('@/views/archiveManager/arMAutoUser'), |
| | | // name: 'AuthUser1', |
| | | // meta: { title: '分配用户', activeMenu: '/archiveManager/infoManager' } |
| | | // } |
| | | // ] |
| | | // }, |
| | | { |
| | | path: '/system/role-auth', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:role:edit'], |
| | | children: [ |
| | | { |
| | | path: 'user/:roleId(\\d+)', |
| | | component: () => import('@/views/system/role/authUser'), |
| | | name: 'AuthUser', |
| | | meta: { title: '分配用户', activeMenu: '/system/role' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/system/dict-data', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['system:dict:list'], |
| | | children: [ |
| | | { |
| | | path: 'index/:dictId(\\d+)', |
| | | component: () => import('@/views/system/dict/data'), |
| | | name: 'Data', |
| | | meta: { title: '字典数据', activeMenu: '/system/dict' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/monitor/job-log', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['monitor:job:list'], |
| | | children: [ |
| | | { |
| | | path: 'index/:jobId(\\d+)', |
| | | component: () => import('@/views/monitor/job/log'), |
| | | name: 'JobLog', |
| | | meta: { title: '调度日志', activeMenu: '/monitor/job' } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/tool/gen-edit', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['tool:gen:edit'], |
| | | children: [ |
| | | { |
| | | path: 'index/:tableId(\\d+)', |
| | | component: () => import('@/views/tool/gen/editTable'), |
| | | name: 'GenEdit', |
| | | meta: { title: '修改生成配置', activeMenu: '/tool/gen' } |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | |
| | | // 防止连续点击多次路由报错 |
| | | let routerPush = Router.prototype.push |
| | | let routerReplace = Router.prototype.replace |
| | | // push |
| | | Router.prototype.push = function push(location) { |
| | | return routerPush.call(this, location).catch(err => err) |
| | | } |
| | | // replace |
| | | Router.prototype.replace = function push(location) { |
| | | return routerReplace.call(this, location).catch(err => err) |
| | | } |
| | | |
| | | export default new Router({ |
| | | mode: 'history', // 去掉url中的# |
| | | scrollBehavior: () => ({ y: 0 }), |
| | | routes: constantRoutes |
| | | }) |
New file |
| | |
| | | module.exports = { |
| | | /** |
| | | * 网页标题 |
| | | */ |
| | | title: process.env.VUE_APP_TITLE, |
| | | |
| | | /** |
| | | * 侧边栏主题 深色主题theme-dark,浅色主题theme-light |
| | | */ |
| | | sideTheme: 'theme-dark', |
| | | |
| | | /** |
| | | * 系统布局配置 |
| | | */ |
| | | showSettings: true, |
| | | |
| | | /** |
| | | * 是否显示顶部导航 |
| | | */ |
| | | topNav: false, |
| | | |
| | | /** |
| | | * 是否显示 tagsView |
| | | */ |
| | | tagsView: true, |
| | | |
| | | /** |
| | | * 显示页签图标 |
| | | */ |
| | | tagsIcon: false, |
| | | |
| | | /** |
| | | * 是否固定头部 |
| | | */ |
| | | fixedHeader: false, |
| | | |
| | | /** |
| | | * 是否显示logo |
| | | */ |
| | | sidebarLogo: true, |
| | | |
| | | /** |
| | | * 是否显示动态标题 |
| | | */ |
| | | dynamicTitle: false, |
| | | |
| | | /** |
| | | * 是否显示底部版权 |
| | | */ |
| | | footerVisible: false, |
| | | |
| | | /** |
| | | * 底部版权文本内容 |
| | | */ |
| | | footerContent: 'Copyright © 2018-2025 RuoYi. All Rights Reserved.' |
| | | } |
New file |
| | |
| | | const getters = { |
| | | sidebar: state => state.app.sidebar, |
| | | size: state => state.app.size, |
| | | device: state => state.app.device, |
| | | dict: state => state.dict.dict, |
| | | visitedViews: state => state.tagsView.visitedViews, |
| | | cachedViews: state => state.tagsView.cachedViews, |
| | | token: state => state.user.token, |
| | | avatar: state => state.user.avatar, |
| | | id: state => state.user.id, |
| | | name: state => state.user.name, |
| | | nickName: state => state.user.nickName, |
| | | introduction: state => state.user.introduction, |
| | | roles: state => state.user.roles, |
| | | permissions: state => state.user.permissions, |
| | | permission_routes: state => state.permission.routes, |
| | | topbarRouters: state => state.permission.topbarRouters, |
| | | defaultRoutes: state => state.permission.defaultRoutes, |
| | | sidebarRouters: state => state.permission.sidebarRouters |
| | | } |
| | | export default getters |
New file |
| | |
| | | import Vue from 'vue' |
| | | import Vuex from 'vuex' |
| | | import app from './modules/app' |
| | | import dict from './modules/dict' |
| | | import user from './modules/user' |
| | | import tagsView from './modules/tagsView' |
| | | import permission from './modules/permission' |
| | | import settings from './modules/settings' |
| | | import getters from './getters' |
| | | |
| | | Vue.use(Vuex) |
| | | |
| | | const store = new Vuex.Store({ |
| | | modules: { |
| | | app, |
| | | dict, |
| | | user, |
| | | tagsView, |
| | | permission, |
| | | settings |
| | | }, |
| | | getters |
| | | }) |
| | | |
| | | export default store |
New file |
| | |
| | | import Cookies from 'js-cookie' |
| | | |
| | | const state = { |
| | | sidebar: { |
| | | opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, |
| | | withoutAnimation: false, |
| | | hide: false |
| | | }, |
| | | device: 'desktop', |
| | | size: Cookies.get('size') || 'medium' |
| | | } |
| | | |
| | | const mutations = { |
| | | TOGGLE_SIDEBAR: state => { |
| | | if (state.sidebar.hide) { |
| | | return false |
| | | } |
| | | state.sidebar.opened = !state.sidebar.opened |
| | | state.sidebar.withoutAnimation = false |
| | | if (state.sidebar.opened) { |
| | | Cookies.set('sidebarStatus', 1) |
| | | } else { |
| | | Cookies.set('sidebarStatus', 0) |
| | | } |
| | | }, |
| | | CLOSE_SIDEBAR: (state, withoutAnimation) => { |
| | | Cookies.set('sidebarStatus', 0) |
| | | state.sidebar.opened = false |
| | | state.sidebar.withoutAnimation = withoutAnimation |
| | | }, |
| | | TOGGLE_DEVICE: (state, device) => { |
| | | state.device = device |
| | | }, |
| | | SET_SIZE: (state, size) => { |
| | | state.size = size |
| | | Cookies.set('size', size) |
| | | }, |
| | | SET_SIDEBAR_HIDE: (state, status) => { |
| | | state.sidebar.hide = status |
| | | } |
| | | } |
| | | |
| | | const actions = { |
| | | toggleSideBar({ commit }) { |
| | | commit('TOGGLE_SIDEBAR') |
| | | }, |
| | | closeSideBar({ commit }, { withoutAnimation }) { |
| | | commit('CLOSE_SIDEBAR', withoutAnimation) |
| | | }, |
| | | toggleDevice({ commit }, device) { |
| | | commit('TOGGLE_DEVICE', device) |
| | | }, |
| | | setSize({ commit }, size) { |
| | | commit('SET_SIZE', size) |
| | | }, |
| | | toggleSideBarHide({ commit }, status) { |
| | | commit('SET_SIDEBAR_HIDE', status) |
| | | } |
| | | } |
| | | |
| | | export default { |
| | | namespaced: true, |
| | | state, |
| | | mutations, |
| | | actions |
| | | } |
New file |
| | |
| | | const state = { |
| | | dict: new Array() |
| | | } |
| | | const mutations = { |
| | | SET_DICT: (state, { key, value }) => { |
| | | if (key !== null && key !== "") { |
| | | state.dict.push({ |
| | | key: key, |
| | | value: value |
| | | }) |
| | | } |
| | | }, |
| | | REMOVE_DICT: (state, key) => { |
| | | try { |
| | | for (let i = 0; i < state.dict.length; i++) { |
| | | if (state.dict[i].key == key) { |
| | | state.dict.splice(i, 1) |
| | | return true |
| | | } |
| | | } |
| | | } catch (e) { |
| | | } |
| | | }, |
| | | CLEAN_DICT: (state) => { |
| | | state.dict = new Array() |
| | | } |
| | | } |
| | | |
| | | const actions = { |
| | | // 设置字典 |
| | | setDict({ commit }, data) { |
| | | commit('SET_DICT', data) |
| | | }, |
| | | // 删除字典 |
| | | removeDict({ commit }, key) { |
| | | commit('REMOVE_DICT', key) |
| | | }, |
| | | // 清空字典 |
| | | cleanDict({ commit }) { |
| | | commit('CLEAN_DICT') |
| | | } |
| | | } |
| | | |
| | | export default { |
| | | namespaced: true, |
| | | state, |
| | | mutations, |
| | | actions |
| | | } |
| | | |
New file |
| | |
| | | import auth from '@/plugins/auth' |
| | | import router, { constantRoutes, dynamicRoutes } from '@/router' |
| | | import { getRouters } from '@/api/menu' |
| | | import Layout from '@/layout/index' |
| | | import ParentView from '@/components/ParentView' |
| | | import InnerLink from '@/layout/components/InnerLink' |
| | | |
| | | const permission = { |
| | | state: { |
| | | routes: [], |
| | | addRoutes: [], |
| | | defaultRoutes: [], |
| | | topbarRouters: [], |
| | | sidebarRouters: [] |
| | | }, |
| | | mutations: { |
| | | SET_ROUTES: (state, routes) => { |
| | | state.addRoutes = routes |
| | | state.routes = constantRoutes.concat(routes) |
| | | }, |
| | | SET_DEFAULT_ROUTES: (state, routes) => { |
| | | state.defaultRoutes = constantRoutes.concat(routes) |
| | | }, |
| | | SET_TOPBAR_ROUTES: (state, routes) => { |
| | | state.topbarRouters = routes |
| | | }, |
| | | SET_SIDEBAR_ROUTERS: (state, routes) => { |
| | | state.sidebarRouters = routes |
| | | }, |
| | | }, |
| | | actions: { |
| | | // 生成路由 |
| | | GenerateRoutes({ commit }) { |
| | | return new Promise(resolve => { |
| | | // 向后端请求路由数据 |
| | | getRouters().then(res => { |
| | | const sdata = JSON.parse(JSON.stringify(res.data)) |
| | | const rdata = JSON.parse(JSON.stringify(res.data)) |
| | | const sidebarRoutes = filterAsyncRouter(sdata) |
| | | const rewriteRoutes = filterAsyncRouter(rdata, false, true) |
| | | const asyncRoutes = filterDynamicRoutes(dynamicRoutes) |
| | | rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) |
| | | router.addRoutes(asyncRoutes) |
| | | commit('SET_ROUTES', rewriteRoutes) |
| | | commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes)) |
| | | commit('SET_DEFAULT_ROUTES', sidebarRoutes) |
| | | commit('SET_TOPBAR_ROUTES', sidebarRoutes) |
| | | resolve(rewriteRoutes) |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 遍历后台传来的路由字符串,转换为组件对象 |
| | | function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) { |
| | | return asyncRouterMap.filter(route => { |
| | | if (type && route.children) { |
| | | route.children = filterChildren(route.children) |
| | | } |
| | | if (route.component) { |
| | | // Layout ParentView 组件特殊处理 |
| | | if (route.component === 'Layout') { |
| | | route.component = Layout |
| | | } else if (route.component === 'ParentView') { |
| | | route.component = ParentView |
| | | } else if (route.component === 'InnerLink') { |
| | | route.component = InnerLink |
| | | } else { |
| | | route.component = loadView(route.component) |
| | | } |
| | | } |
| | | if (route.children != null && route.children && route.children.length) { |
| | | route.children = filterAsyncRouter(route.children, route, type) |
| | | } else { |
| | | delete route['children'] |
| | | delete route['redirect'] |
| | | } |
| | | return true |
| | | }) |
| | | } |
| | | |
| | | function filterChildren(childrenMap, lastRouter = false) { |
| | | var children = [] |
| | | childrenMap.forEach(el => { |
| | | el.path = lastRouter ? lastRouter.path + '/' + el.path : el.path |
| | | if (el.children && el.children.length && el.component === 'ParentView') { |
| | | children = children.concat(filterChildren(el.children, el)) |
| | | } else { |
| | | children.push(el) |
| | | } |
| | | }) |
| | | return children |
| | | } |
| | | |
| | | // 动态路由遍历,验证是否具备权限 |
| | | export function filterDynamicRoutes(routes) { |
| | | const res = [] |
| | | routes.forEach(route => { |
| | | if (route.permissions) { |
| | | if (auth.hasPermiOr(route.permissions)) { |
| | | res.push(route) |
| | | } |
| | | } else if (route.roles) { |
| | | if (auth.hasRoleOr(route.roles)) { |
| | | res.push(route) |
| | | } |
| | | } |
| | | }) |
| | | return res |
| | | } |
| | | |
| | | export const loadView = (view) => { |
| | | if (process.env.NODE_ENV === 'development') { |
| | | return (resolve) => require([`@/views/${view}`], resolve) |
| | | } else { |
| | | // 使用 import 实现生产环境的路由懒加载 |
| | | return () => import(`@/views/${view}`) |
| | | } |
| | | } |
| | | |
| | | export default permission |
New file |
| | |
| | | import defaultSettings from '@/settings' |
| | | import { useDynamicTitle } from '@/utils/dynamicTitle' |
| | | |
| | | const { sideTheme, showSettings, topNav, tagsView, tagsIcon, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings |
| | | |
| | | const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '' |
| | | const state = { |
| | | title: '', |
| | | theme: storageSetting.theme || '#409EFF', |
| | | sideTheme: storageSetting.sideTheme || sideTheme, |
| | | showSettings: showSettings, |
| | | topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav, |
| | | tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView, |
| | | tagsIcon: storageSetting.tagsIcon === undefined ? tagsIcon : storageSetting.tagsIcon, |
| | | fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, |
| | | sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo, |
| | | dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle, |
| | | footerVisible: storageSetting.footerVisible === undefined ? footerVisible : storageSetting.footerVisible, |
| | | footerContent: footerContent |
| | | } |
| | | const mutations = { |
| | | CHANGE_SETTING: (state, { key, value }) => { |
| | | if (state.hasOwnProperty(key)) { |
| | | state[key] = value |
| | | } |
| | | } |
| | | } |
| | | |
| | | const actions = { |
| | | // 修改布局设置 |
| | | changeSetting({ commit }, data) { |
| | | commit('CHANGE_SETTING', data) |
| | | }, |
| | | // 设置网页标题 |
| | | setTitle({ commit }, title) { |
| | | state.title = title |
| | | useDynamicTitle() |
| | | } |
| | | } |
| | | |
| | | export default { |
| | | namespaced: true, |
| | | state, |
| | | mutations, |
| | | actions |
| | | } |
| | | |
New file |
| | |
| | | const state = { |
| | | visitedViews: [], |
| | | cachedViews: [], |
| | | iframeViews: [] |
| | | } |
| | | |
| | | const mutations = { |
| | | ADD_IFRAME_VIEW: (state, view) => { |
| | | if (state.iframeViews.some(v => v.path === view.path)) return |
| | | state.iframeViews.push( |
| | | Object.assign({}, view, { |
| | | title: view.meta.title || 'no-name' |
| | | }) |
| | | ) |
| | | }, |
| | | ADD_VISITED_VIEW: (state, view) => { |
| | | if (state.visitedViews.some(v => v.path === view.path)) return |
| | | state.visitedViews.push( |
| | | Object.assign({}, view, { |
| | | title: view.meta.title || 'no-name' |
| | | }) |
| | | ) |
| | | }, |
| | | ADD_CACHED_VIEW: (state, view) => { |
| | | if (state.cachedViews.includes(view.name)) return |
| | | if (view.meta && !view.meta.noCache) { |
| | | state.cachedViews.push(view.name) |
| | | } |
| | | }, |
| | | DEL_VISITED_VIEW: (state, view) => { |
| | | for (const [i, v] of state.visitedViews.entries()) { |
| | | if (v.path === view.path) { |
| | | state.visitedViews.splice(i, 1) |
| | | break |
| | | } |
| | | } |
| | | state.iframeViews = state.iframeViews.filter(item => item.path !== view.path) |
| | | }, |
| | | DEL_IFRAME_VIEW: (state, view) => { |
| | | state.iframeViews = state.iframeViews.filter(item => item.path !== view.path) |
| | | }, |
| | | DEL_CACHED_VIEW: (state, view) => { |
| | | const index = state.cachedViews.indexOf(view.name) |
| | | index > -1 && state.cachedViews.splice(index, 1) |
| | | }, |
| | | |
| | | DEL_OTHERS_VISITED_VIEWS: (state, view) => { |
| | | state.visitedViews = state.visitedViews.filter(v => { |
| | | return v.meta.affix || v.path === view.path |
| | | }) |
| | | state.iframeViews = state.iframeViews.filter(item => item.path === view.path) |
| | | }, |
| | | DEL_OTHERS_CACHED_VIEWS: (state, view) => { |
| | | const index = state.cachedViews.indexOf(view.name) |
| | | if (index > -1) { |
| | | state.cachedViews = state.cachedViews.slice(index, index + 1) |
| | | } else { |
| | | state.cachedViews = [] |
| | | } |
| | | }, |
| | | DEL_ALL_VISITED_VIEWS: state => { |
| | | // keep affix tags |
| | | const affixTags = state.visitedViews.filter(tag => tag.meta.affix) |
| | | state.visitedViews = affixTags |
| | | state.iframeViews = [] |
| | | }, |
| | | DEL_ALL_CACHED_VIEWS: state => { |
| | | state.cachedViews = [] |
| | | }, |
| | | UPDATE_VISITED_VIEW: (state, view) => { |
| | | for (let v of state.visitedViews) { |
| | | if (v.path === view.path) { |
| | | v = Object.assign(v, view) |
| | | break |
| | | } |
| | | } |
| | | }, |
| | | DEL_RIGHT_VIEWS: (state, view) => { |
| | | const index = state.visitedViews.findIndex(v => v.path === view.path) |
| | | if (index === -1) { |
| | | return |
| | | } |
| | | state.visitedViews = state.visitedViews.filter((item, idx) => { |
| | | if (idx <= index || (item.meta && item.meta.affix)) { |
| | | return true |
| | | } |
| | | const i = state.cachedViews.indexOf(item.name) |
| | | if (i > -1) { |
| | | state.cachedViews.splice(i, 1) |
| | | } |
| | | if(item.meta.link) { |
| | | const fi = state.iframeViews.findIndex(v => v.path === item.path) |
| | | state.iframeViews.splice(fi, 1) |
| | | } |
| | | return false |
| | | }) |
| | | }, |
| | | DEL_LEFT_VIEWS: (state, view) => { |
| | | const index = state.visitedViews.findIndex(v => v.path === view.path) |
| | | if (index === -1) { |
| | | return |
| | | } |
| | | state.visitedViews = state.visitedViews.filter((item, idx) => { |
| | | if (idx >= index || (item.meta && item.meta.affix)) { |
| | | return true |
| | | } |
| | | const i = state.cachedViews.indexOf(item.name) |
| | | if (i > -1) { |
| | | state.cachedViews.splice(i, 1) |
| | | } |
| | | if(item.meta.link) { |
| | | const fi = state.iframeViews.findIndex(v => v.path === item.path) |
| | | state.iframeViews.splice(fi, 1) |
| | | } |
| | | return false |
| | | }) |
| | | } |
| | | } |
| | | |
| | | const actions = { |
| | | addView({ dispatch }, view) { |
| | | dispatch('addVisitedView', view) |
| | | dispatch('addCachedView', view) |
| | | }, |
| | | addIframeView({ commit }, view) { |
| | | commit('ADD_IFRAME_VIEW', view) |
| | | }, |
| | | addVisitedView({ commit }, view) { |
| | | commit('ADD_VISITED_VIEW', view) |
| | | }, |
| | | addCachedView({ commit }, view) { |
| | | commit('ADD_CACHED_VIEW', view) |
| | | }, |
| | | delView({ dispatch, state }, view) { |
| | | return new Promise(resolve => { |
| | | dispatch('delVisitedView', view) |
| | | dispatch('delCachedView', view) |
| | | resolve({ |
| | | visitedViews: [...state.visitedViews], |
| | | cachedViews: [...state.cachedViews] |
| | | }) |
| | | }) |
| | | }, |
| | | delVisitedView({ commit, state }, view) { |
| | | return new Promise(resolve => { |
| | | commit('DEL_VISITED_VIEW', view) |
| | | resolve([...state.visitedViews]) |
| | | }) |
| | | }, |
| | | delIframeView({ commit, state }, view) { |
| | | return new Promise(resolve => { |
| | | commit('DEL_IFRAME_VIEW', view) |
| | | resolve([...state.iframeViews]) |
| | | }) |
| | | }, |
| | | delCachedView({ commit, state }, view) { |
| | | return new Promise(resolve => { |
| | | commit('DEL_CACHED_VIEW', view) |
| | | resolve([...state.cachedViews]) |
| | | }) |
| | | }, |
| | | delOthersViews({ dispatch, state }, view) { |
| | | return new Promise(resolve => { |
| | | dispatch('delOthersVisitedViews', view) |
| | | dispatch('delOthersCachedViews', view) |
| | | resolve({ |
| | | visitedViews: [...state.visitedViews], |
| | | cachedViews: [...state.cachedViews] |
| | | }) |
| | | }) |
| | | }, |
| | | delOthersVisitedViews({ commit, state }, view) { |
| | | return new Promise(resolve => { |
| | | commit('DEL_OTHERS_VISITED_VIEWS', view) |
| | | resolve([...state.visitedViews]) |
| | | }) |
| | | }, |
| | | delOthersCachedViews({ commit, state }, view) { |
| | | return new Promise(resolve => { |
| | | commit('DEL_OTHERS_CACHED_VIEWS', view) |
| | | resolve([...state.cachedViews]) |
| | | }) |
| | | }, |
| | | delAllViews({ dispatch, state }, view) { |
| | | return new Promise(resolve => { |
| | | dispatch('delAllVisitedViews', view) |
| | | dispatch('delAllCachedViews', view) |
| | | resolve({ |
| | | visitedViews: [...state.visitedViews], |
| | | cachedViews: [...state.cachedViews] |
| | | }) |
| | | }) |
| | | }, |
| | | delAllVisitedViews({ commit, state }) { |
| | | return new Promise(resolve => { |
| | | commit('DEL_ALL_VISITED_VIEWS') |
| | | resolve([...state.visitedViews]) |
| | | }) |
| | | }, |
| | | delAllCachedViews({ commit, state }) { |
| | | return new Promise(resolve => { |
| | | commit('DEL_ALL_CACHED_VIEWS') |
| | | resolve([...state.cachedViews]) |
| | | }) |
| | | }, |
| | | updateVisitedView({ commit }, view) { |
| | | commit('UPDATE_VISITED_VIEW', view) |
| | | }, |
| | | delRightTags({ commit }, view) { |
| | | return new Promise(resolve => { |
| | | commit('DEL_RIGHT_VIEWS', view) |
| | | resolve([...state.visitedViews]) |
| | | }) |
| | | }, |
| | | delLeftTags({ commit }, view) { |
| | | return new Promise(resolve => { |
| | | commit('DEL_LEFT_VIEWS', view) |
| | | resolve([...state.visitedViews]) |
| | | }) |
| | | }, |
| | | } |
| | | |
| | | export default { |
| | | namespaced: true, |
| | | state, |
| | | mutations, |
| | | actions |
| | | } |
New file |
| | |
| | | import router from '@/router' |
| | | import { MessageBox, } from 'element-ui' |
| | | import { login, logout, getInfo } from '@/api/login' |
| | | import { getToken, setToken, removeToken } from '@/utils/auth' |
| | | import { isHttp, isEmpty } from "@/utils/validate" |
| | | import defAva from '@/assets/images/profile.jpg' |
| | | |
| | | const user = { |
| | | state: { |
| | | token: getToken(), |
| | | id: '', |
| | | name: '', |
| | | nickName: '', |
| | | avatar: '', |
| | | roles: [], |
| | | permissions: [] |
| | | }, |
| | | |
| | | mutations: { |
| | | SET_TOKEN: (state, token) => { |
| | | state.token = token |
| | | }, |
| | | SET_ID: (state, id) => { |
| | | state.id = id |
| | | }, |
| | | SET_NAME: (state, name) => { |
| | | state.name = name |
| | | }, |
| | | SET_NICK_NAME: (state, nickName) => { |
| | | state.nickName = nickName |
| | | }, |
| | | SET_AVATAR: (state, avatar) => { |
| | | state.avatar = avatar |
| | | }, |
| | | SET_ROLES: (state, roles) => { |
| | | state.roles = roles |
| | | }, |
| | | SET_PERMISSIONS: (state, permissions) => { |
| | | state.permissions = permissions |
| | | } |
| | | }, |
| | | |
| | | actions: { |
| | | // 登录 |
| | | Login({ commit }, userInfo) { |
| | | const username = userInfo.username.trim() |
| | | const password = userInfo.password |
| | | const code = userInfo.code |
| | | const uuid = userInfo.uuid |
| | | return new Promise((resolve, reject) => { |
| | | login(username, password, code, uuid).then(res => { |
| | | setToken(res.token) |
| | | commit('SET_TOKEN', res.token) |
| | | resolve() |
| | | }).catch(error => { |
| | | reject(error) |
| | | }) |
| | | }) |
| | | }, |
| | | |
| | | // 获取用户信息 |
| | | GetInfo({ commit, state }) { |
| | | return new Promise((resolve, reject) => { |
| | | getInfo().then(res => { |
| | | const user = res.user |
| | | let avatar = user.avatar || "" |
| | | if (!isHttp(avatar)) { |
| | | avatar = (isEmpty(avatar)) ? defAva : process.env.VUE_APP_BASE_API + avatar |
| | | } |
| | | if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组 |
| | | commit('SET_ROLES', res.roles) |
| | | commit('SET_PERMISSIONS', res.permissions) |
| | | } else { |
| | | commit('SET_ROLES', ['ROLE_DEFAULT']) |
| | | } |
| | | commit('SET_ID', user.userId) |
| | | commit('SET_NAME', user.userName) |
| | | commit('SET_NICK_NAME', user.nickName) |
| | | commit('SET_AVATAR', avatar) |
| | | /* 初始密码提示 */ |
| | | if(res.isDefaultModifyPwd) { |
| | | MessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { |
| | | router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } }) |
| | | }).catch(() => {}) |
| | | } |
| | | /* 过期密码提示 */ |
| | | if(!res.isDefaultModifyPwd && res.isPasswordExpired) { |
| | | MessageBox.confirm('您的密码已过期,请尽快修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { |
| | | router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } }) |
| | | }).catch(() => {}) |
| | | } |
| | | resolve(res) |
| | | }).catch(error => { |
| | | reject(error) |
| | | }) |
| | | }) |
| | | }, |
| | | |
| | | // 退出系统 |
| | | LogOut({ commit, state }) { |
| | | return new Promise((resolve, reject) => { |
| | | logout(state.token).then(() => { |
| | | commit('SET_TOKEN', '') |
| | | commit('SET_ROLES', []) |
| | | commit('SET_PERMISSIONS', []) |
| | | removeToken() |
| | | resolve() |
| | | }).catch(error => { |
| | | reject(error) |
| | | }) |
| | | }) |
| | | }, |
| | | |
| | | // 前端 登出 |
| | | FedLogOut({ commit }) { |
| | | return new Promise(resolve => { |
| | | commit('SET_TOKEN', '') |
| | | removeToken() |
| | | resolve() |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | |
| | | export default user |
New file |
| | |
| | | import Cookies from 'js-cookie' |
| | | |
| | | const TokenKey = 'Admin-Token' |
| | | |
| | | export function getToken() { |
| | | return Cookies.get(TokenKey) |
| | | } |
| | | |
| | | export function setToken(token) { |
| | | return Cookies.set(TokenKey, token) |
| | | } |
| | | |
| | | export function removeToken() { |
| | | return Cookies.remove(TokenKey) |
| | | } |
New file |
| | |
| | | import Vue from 'vue' |
| | | import { mergeRecursive } from "@/utils/ruoyi" |
| | | import DictMeta from './DictMeta' |
| | | import DictData from './DictData' |
| | | |
| | | const DEFAULT_DICT_OPTIONS = { |
| | | types: [], |
| | | } |
| | | |
| | | /** |
| | | * @classdesc 字典 |
| | | * @property {Object} label 标签对象,内部属性名为字典类型名称 |
| | | * @property {Object} dict 字段数组,内部属性名为字典类型名称 |
| | | * @property {Array.<DictMeta>} _dictMetas 字典元数据数组 |
| | | */ |
| | | export default class Dict { |
| | | constructor() { |
| | | this.owner = null |
| | | this.label = {} |
| | | this.type = {} |
| | | } |
| | | |
| | | init(options) { |
| | | if (options instanceof Array) { |
| | | options = { types: options } |
| | | } |
| | | const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options) |
| | | if (opts.types === undefined) { |
| | | throw new Error('need dict types') |
| | | } |
| | | const ps = [] |
| | | this._dictMetas = opts.types.map(t => DictMeta.parse(t)) |
| | | this._dictMetas.forEach(dictMeta => { |
| | | const type = dictMeta.type |
| | | Vue.set(this.label, type, {}) |
| | | Vue.set(this.type, type, []) |
| | | if (dictMeta.lazy) { |
| | | return |
| | | } |
| | | ps.push(loadDict(this, dictMeta)) |
| | | }) |
| | | return Promise.all(ps) |
| | | } |
| | | |
| | | /** |
| | | * 重新加载字典 |
| | | * @param {String} type 字典类型 |
| | | */ |
| | | reloadDict(type) { |
| | | const dictMeta = this._dictMetas.find(e => e.type === type) |
| | | if (dictMeta === undefined) { |
| | | return Promise.reject(`the dict meta of ${type} was not found`) |
| | | } |
| | | return loadDict(this, dictMeta) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 加载字典 |
| | | * @param {Dict} dict 字典 |
| | | * @param {DictMeta} dictMeta 字典元数据 |
| | | * @returns {Promise} |
| | | */ |
| | | function loadDict(dict, dictMeta) { |
| | | return dictMeta.request(dictMeta) |
| | | .then(response => { |
| | | const type = dictMeta.type |
| | | let dicts = dictMeta.responseConverter(response, dictMeta) |
| | | if (!(dicts instanceof Array)) { |
| | | console.error('the return of responseConverter must be Array.<DictData>') |
| | | dicts = [] |
| | | } else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) { |
| | | console.error('the type of elements in dicts must be DictData') |
| | | dicts = [] |
| | | } |
| | | dict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts) |
| | | dicts.forEach(d => { |
| | | Vue.set(dict.label[type], d.value, d.label) |
| | | }) |
| | | return dicts |
| | | }) |
| | | } |
New file |
| | |
| | | import DictOptions from './DictOptions' |
| | | import DictData from './DictData' |
| | | |
| | | export default function(dict, dictMeta) { |
| | | const label = determineDictField(dict, dictMeta.labelField, ...DictOptions.DEFAULT_LABEL_FIELDS) |
| | | const value = determineDictField(dict, dictMeta.valueField, ...DictOptions.DEFAULT_VALUE_FIELDS) |
| | | return new DictData(dict[label], dict[value], dict) |
| | | } |
| | | |
| | | /** |
| | | * 确定字典字段 |
| | | * @param {DictData} dict |
| | | * @param {...String} fields |
| | | */ |
| | | function determineDictField(dict, ...fields) { |
| | | return fields.find(f => Object.prototype.hasOwnProperty.call(dict, f)) |
| | | } |
New file |
| | |
| | | /** |
| | | * @classdesc 字典数据 |
| | | * @property {String} label 标签 |
| | | * @property {*} value 标签 |
| | | * @property {Object} raw 原始数据 |
| | | */ |
| | | export default class DictData { |
| | | constructor(label, value, raw) { |
| | | this.label = label |
| | | this.value = value |
| | | this.raw = raw |
| | | } |
| | | } |
New file |
| | |
| | | import { mergeRecursive } from "@/utils/ruoyi" |
| | | import DictOptions from './DictOptions' |
| | | |
| | | /** |
| | | * @classdesc 字典元数据 |
| | | * @property {String} type 类型 |
| | | * @property {Function} request 请求 |
| | | * @property {String} label 标签字段 |
| | | * @property {String} value 值字段 |
| | | */ |
| | | export default class DictMeta { |
| | | constructor(options) { |
| | | this.type = options.type |
| | | this.request = options.request |
| | | this.responseConverter = options.responseConverter |
| | | this.labelField = options.labelField |
| | | this.valueField = options.valueField |
| | | this.lazy = options.lazy === true |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 解析字典元数据 |
| | | * @param {Object} options |
| | | * @returns {DictMeta} |
| | | */ |
| | | DictMeta.parse= function(options) { |
| | | let opts = null |
| | | if (typeof options === 'string') { |
| | | opts = DictOptions.metas[options] || {} |
| | | opts.type = options |
| | | } else if (typeof options === 'object') { |
| | | opts = options |
| | | } |
| | | opts = mergeRecursive(DictOptions.metas['*'], opts) |
| | | return new DictMeta(opts) |
| | | } |
New file |
| | |
| | | import { mergeRecursive } from "@/utils/ruoyi" |
| | | import dictConverter from './DictConverter' |
| | | |
| | | export const options = { |
| | | metas: { |
| | | '*': { |
| | | /** |
| | | * 字典请求,方法签名为function(dictMeta: DictMeta): Promise |
| | | */ |
| | | request: (dictMeta) => { |
| | | console.log(`load dict ${dictMeta.type}`) |
| | | return Promise.resolve([]) |
| | | }, |
| | | /** |
| | | * 字典响应数据转换器,方法签名为function(response: Object, dictMeta: DictMeta): DictData |
| | | */ |
| | | responseConverter, |
| | | labelField: 'label', |
| | | valueField: 'value', |
| | | }, |
| | | }, |
| | | /** |
| | | * 默认标签字段 |
| | | */ |
| | | DEFAULT_LABEL_FIELDS: ['label', 'name', 'title'], |
| | | /** |
| | | * 默认值字段 |
| | | */ |
| | | DEFAULT_VALUE_FIELDS: ['value', 'id', 'uid', 'key'], |
| | | } |
| | | |
| | | /** |
| | | * 映射字典 |
| | | * @param {Object} response 字典数据 |
| | | * @param {DictMeta} dictMeta 字典元数据 |
| | | * @returns {DictData} |
| | | */ |
| | | function responseConverter(response, dictMeta) { |
| | | const dicts = response.content instanceof Array ? response.content : response |
| | | if (dicts === undefined) { |
| | | console.warn(`no dict data of "${dictMeta.type}" found in the response`) |
| | | return [] |
| | | } |
| | | return dicts.map(d => dictConverter(d, dictMeta)) |
| | | } |
| | | |
| | | export function mergeOptions(src) { |
| | | mergeRecursive(options, src) |
| | | } |
| | | |
| | | export default options |
New file |
| | |
| | | import Dict from './Dict' |
| | | import { mergeOptions } from './DictOptions' |
| | | |
| | | export default function(Vue, options) { |
| | | mergeOptions(options) |
| | | Vue.mixin({ |
| | | data() { |
| | | if (this.$options === undefined || this.$options.dicts === undefined || this.$options.dicts === null) { |
| | | return {} |
| | | } |
| | | const dict = new Dict() |
| | | dict.owner = this |
| | | return { |
| | | dict |
| | | } |
| | | }, |
| | | created() { |
| | | if (!(this.dict instanceof Dict)) { |
| | | return |
| | | } |
| | | options.onCreated && options.onCreated(this.dict) |
| | | this.dict.init(this.$options.dicts).then(() => { |
| | | options.onReady && options.onReady(this.dict) |
| | | this.$nextTick(() => { |
| | | this.$emit('dictReady', this.dict) |
| | | if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) { |
| | | this.$options.methods.onDictReady.call(this, this.dict) |
| | | } |
| | | }) |
| | | }) |
| | | }, |
| | | }) |
| | | } |
New file |
| | |
| | | import store from '@/store' |
| | | import defaultSettings from '@/settings' |
| | | |
| | | /** |
| | | * 动态修改标题 |
| | | */ |
| | | export function useDynamicTitle() { |
| | | if (store.state.settings.dynamicTitle) { |
| | | document.title = store.state.settings.title + ' - ' + defaultSettings.title |
| | | } else { |
| | | document.title = defaultSettings.title |
| | | } |
| | | } |
New file |
| | |
| | | export default { |
| | | '401': '认证失败,无法访问系统资源', |
| | | '403': '当前操作没有权限', |
| | | '404': '访问资源不存在', |
| | | 'default': '系统未知错误,请反馈给管理员' |
| | | } |
New file |
| | |
| | | export const formConf = { |
| | | formRef: 'elForm', |
| | | formModel: 'formData', |
| | | size: 'medium', |
| | | labelPosition: 'right', |
| | | labelWidth: 100, |
| | | formRules: 'rules', |
| | | gutter: 15, |
| | | disabled: false, |
| | | span: 24, |
| | | formBtns: true |
| | | } |
| | | |
| | | export const inputComponents = [ |
| | | { |
| | | label: '单行文本', |
| | | tag: 'el-input', |
| | | tagIcon: 'input', |
| | | placeholder: '请输入', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | clearable: true, |
| | | prepend: '', |
| | | append: '', |
| | | 'prefix-icon': '', |
| | | 'suffix-icon': '', |
| | | maxlength: null, |
| | | 'show-word-limit': false, |
| | | readonly: false, |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/input' |
| | | }, |
| | | { |
| | | label: '多行文本', |
| | | tag: 'el-input', |
| | | tagIcon: 'textarea', |
| | | type: 'textarea', |
| | | placeholder: '请输入', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | autosize: { |
| | | minRows: 4, |
| | | maxRows: 4 |
| | | }, |
| | | style: { width: '100%' }, |
| | | maxlength: null, |
| | | 'show-word-limit': false, |
| | | readonly: false, |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/input' |
| | | }, |
| | | { |
| | | label: '密码', |
| | | tag: 'el-input', |
| | | tagIcon: 'password', |
| | | placeholder: '请输入', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | 'show-password': true, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | clearable: true, |
| | | prepend: '', |
| | | append: '', |
| | | 'prefix-icon': '', |
| | | 'suffix-icon': '', |
| | | maxlength: null, |
| | | 'show-word-limit': false, |
| | | readonly: false, |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/input' |
| | | }, |
| | | { |
| | | label: '计数器', |
| | | tag: 'el-input-number', |
| | | tagIcon: 'number', |
| | | placeholder: '', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | min: undefined, |
| | | max: undefined, |
| | | step: undefined, |
| | | 'step-strictly': false, |
| | | precision: undefined, |
| | | 'controls-position': '', |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/input-number' |
| | | } |
| | | ] |
| | | |
| | | export const selectComponents = [ |
| | | { |
| | | label: '下拉选择', |
| | | tag: 'el-select', |
| | | tagIcon: 'select', |
| | | placeholder: '请选择', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | clearable: true, |
| | | disabled: false, |
| | | required: true, |
| | | filterable: false, |
| | | multiple: false, |
| | | options: [{ |
| | | label: '选项一', |
| | | value: 1 |
| | | }, { |
| | | label: '选项二', |
| | | value: 2 |
| | | }], |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/select' |
| | | }, |
| | | { |
| | | label: '级联选择', |
| | | tag: 'el-cascader', |
| | | tagIcon: 'cascader', |
| | | placeholder: '请选择', |
| | | defaultValue: [], |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | props: { |
| | | props: { |
| | | multiple: false |
| | | } |
| | | }, |
| | | 'show-all-levels': true, |
| | | disabled: false, |
| | | clearable: true, |
| | | filterable: false, |
| | | required: true, |
| | | options: [{ |
| | | id: 1, |
| | | value: 1, |
| | | label: '选项1', |
| | | children: [{ |
| | | id: 2, |
| | | value: 2, |
| | | label: '选项1-1' |
| | | }] |
| | | }], |
| | | dataType: 'dynamic', |
| | | labelKey: 'label', |
| | | valueKey: 'value', |
| | | childrenKey: 'children', |
| | | separator: '/', |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/cascader' |
| | | }, |
| | | { |
| | | label: '单选框组', |
| | | tag: 'el-radio-group', |
| | | tagIcon: 'radio', |
| | | defaultValue: undefined, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: {}, |
| | | optionType: 'default', |
| | | border: false, |
| | | size: 'medium', |
| | | disabled: false, |
| | | required: true, |
| | | options: [{ |
| | | label: '选项一', |
| | | value: 1 |
| | | }, { |
| | | label: '选项二', |
| | | value: 2 |
| | | }], |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/radio' |
| | | }, |
| | | { |
| | | label: '多选框组', |
| | | tag: 'el-checkbox-group', |
| | | tagIcon: 'checkbox', |
| | | defaultValue: [], |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: {}, |
| | | optionType: 'default', |
| | | border: false, |
| | | size: 'medium', |
| | | disabled: false, |
| | | required: true, |
| | | options: [{ |
| | | label: '选项一', |
| | | value: 1 |
| | | }, { |
| | | label: '选项二', |
| | | value: 2 |
| | | }], |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/checkbox' |
| | | }, |
| | | { |
| | | label: '开关', |
| | | tag: 'el-switch', |
| | | tagIcon: 'switch', |
| | | defaultValue: false, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: {}, |
| | | disabled: false, |
| | | required: true, |
| | | 'active-text': '', |
| | | 'inactive-text': '', |
| | | 'active-color': null, |
| | | 'inactive-color': null, |
| | | 'active-value': true, |
| | | 'inactive-value': false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/switch' |
| | | }, |
| | | { |
| | | label: '滑块', |
| | | tag: 'el-slider', |
| | | tagIcon: 'slider', |
| | | defaultValue: null, |
| | | span: 24, |
| | | labelWidth: null, |
| | | disabled: false, |
| | | required: true, |
| | | min: 0, |
| | | max: 100, |
| | | step: 1, |
| | | 'show-stops': false, |
| | | range: false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/slider' |
| | | }, |
| | | { |
| | | label: '时间选择', |
| | | tag: 'el-time-picker', |
| | | tagIcon: 'time', |
| | | placeholder: '请选择', |
| | | defaultValue: null, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | disabled: false, |
| | | clearable: true, |
| | | required: true, |
| | | 'picker-options': { |
| | | selectableRange: '00:00:00-23:59:59' |
| | | }, |
| | | format: 'HH:mm:ss', |
| | | 'value-format': 'HH:mm:ss', |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/time-picker' |
| | | }, |
| | | { |
| | | label: '时间范围', |
| | | tag: 'el-time-picker', |
| | | tagIcon: 'time-range', |
| | | defaultValue: null, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | disabled: false, |
| | | clearable: true, |
| | | required: true, |
| | | 'is-range': true, |
| | | 'range-separator': '至', |
| | | 'start-placeholder': '开始时间', |
| | | 'end-placeholder': '结束时间', |
| | | format: 'HH:mm:ss', |
| | | 'value-format': 'HH:mm:ss', |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/time-picker' |
| | | }, |
| | | { |
| | | label: '日期选择', |
| | | tag: 'el-date-picker', |
| | | tagIcon: 'date', |
| | | placeholder: '请选择', |
| | | defaultValue: null, |
| | | type: 'date', |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | disabled: false, |
| | | clearable: true, |
| | | required: true, |
| | | format: 'yyyy-MM-dd', |
| | | 'value-format': 'yyyy-MM-dd', |
| | | readonly: false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/date-picker' |
| | | }, |
| | | { |
| | | label: '日期范围', |
| | | tag: 'el-date-picker', |
| | | tagIcon: 'date-range', |
| | | defaultValue: null, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: { width: '100%' }, |
| | | type: 'daterange', |
| | | 'range-separator': '至', |
| | | 'start-placeholder': '开始日期', |
| | | 'end-placeholder': '结束日期', |
| | | disabled: false, |
| | | clearable: true, |
| | | required: true, |
| | | format: 'yyyy-MM-dd', |
| | | 'value-format': 'yyyy-MM-dd', |
| | | readonly: false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/date-picker' |
| | | }, |
| | | { |
| | | label: '评分', |
| | | tag: 'el-rate', |
| | | tagIcon: 'rate', |
| | | defaultValue: 0, |
| | | span: 24, |
| | | labelWidth: null, |
| | | style: {}, |
| | | max: 5, |
| | | 'allow-half': false, |
| | | 'show-text': false, |
| | | 'show-score': false, |
| | | disabled: false, |
| | | required: true, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/rate' |
| | | }, |
| | | { |
| | | label: '颜色选择', |
| | | tag: 'el-color-picker', |
| | | tagIcon: 'color', |
| | | defaultValue: null, |
| | | labelWidth: null, |
| | | 'show-alpha': false, |
| | | 'color-format': '', |
| | | disabled: false, |
| | | required: true, |
| | | size: 'medium', |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/color-picker' |
| | | }, |
| | | { |
| | | label: '上传', |
| | | tag: 'el-upload', |
| | | tagIcon: 'upload', |
| | | action: 'https://jsonplaceholder.typicode.com/posts/', |
| | | defaultValue: null, |
| | | labelWidth: null, |
| | | disabled: false, |
| | | required: true, |
| | | accept: '', |
| | | name: 'file', |
| | | 'auto-upload': true, |
| | | showTip: false, |
| | | buttonText: '点击上传', |
| | | fileSize: 2, |
| | | sizeUnit: 'MB', |
| | | 'list-type': 'text', |
| | | multiple: false, |
| | | regList: [], |
| | | changeTag: true, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/upload' |
| | | } |
| | | ] |
| | | |
| | | export const layoutComponents = [ |
| | | { |
| | | layout: 'rowFormItem', |
| | | tagIcon: 'row', |
| | | type: 'default', |
| | | justify: 'start', |
| | | align: 'top', |
| | | label: '行容器', |
| | | layoutTree: true, |
| | | children: [], |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/layout' |
| | | }, |
| | | { |
| | | layout: 'colFormItem', |
| | | label: '按钮', |
| | | changeTag: true, |
| | | labelWidth: null, |
| | | tag: 'el-button', |
| | | tagIcon: 'button', |
| | | span: 24, |
| | | default: '主要按钮', |
| | | type: 'primary', |
| | | icon: 'el-icon-search', |
| | | size: 'medium', |
| | | disabled: false, |
| | | document: 'https://element.eleme.cn/#/zh-CN/component/button' |
| | | } |
| | | ] |
| | | |
| | | // 组件rule的触发方式,无触发方式的组件不生成rule |
| | | export const trigger = { |
| | | 'el-input': 'blur', |
| | | 'el-input-number': 'blur', |
| | | 'el-select': 'change', |
| | | 'el-radio-group': 'change', |
| | | 'el-checkbox-group': 'change', |
| | | 'el-cascader': 'change', |
| | | 'el-time-picker': 'change', |
| | | 'el-date-picker': 'change', |
| | | 'el-rate': 'change' |
| | | } |
New file |
| | |
| | | const styles = { |
| | | 'el-rate': '.el-rate{display: inline-block; vertical-align: text-top;}', |
| | | 'el-upload': '.el-upload__tip{line-height: 1.2;}' |
| | | } |
| | | |
| | | function addCss(cssList, el) { |
| | | const css = styles[el.tag] |
| | | css && cssList.indexOf(css) === -1 && cssList.push(css) |
| | | if (el.children) { |
| | | el.children.forEach(el2 => addCss(cssList, el2)) |
| | | } |
| | | } |
| | | |
| | | export function makeUpCss(conf) { |
| | | const cssList = [] |
| | | conf.fields.forEach(el => addCss(cssList, el)) |
| | | return cssList.join('\n') |
| | | } |
New file |
| | |
| | | export default [ |
| | | { |
| | | layout: 'colFormItem', |
| | | tagIcon: 'input', |
| | | label: '手机号', |
| | | vModel: 'mobile', |
| | | formId: 6, |
| | | tag: 'el-input', |
| | | placeholder: '请输入手机号', |
| | | defaultValue: '', |
| | | span: 24, |
| | | style: { width: '100%' }, |
| | | clearable: true, |
| | | prepend: '', |
| | | append: '', |
| | | 'prefix-icon': 'el-icon-mobile', |
| | | 'suffix-icon': '', |
| | | maxlength: 11, |
| | | 'show-word-limit': true, |
| | | readonly: false, |
| | | disabled: false, |
| | | required: true, |
| | | changeTag: true, |
| | | regList: [{ |
| | | pattern: '/^1(3|4|5|7|8|9)\\d{9}$/', |
| | | message: '手机号格式错误' |
| | | }] |
| | | } |
| | | ] |
New file |
| | |
| | | import { trigger } from './config' |
| | | |
| | | let confGlobal |
| | | let someSpanIsNot24 |
| | | |
| | | export function dialogWrapper(str) { |
| | | return `<el-dialog v-bind="$attrs" v-on="$listeners" @open="onOpen" @close="onClose" title="Dialog Title"> |
| | | ${str} |
| | | <div slot="footer"> |
| | | <el-button @click="close">取消</el-button> |
| | | <el-button type="primary" @click="handleConfirm">确定</el-button> |
| | | </div> |
| | | </el-dialog>` |
| | | } |
| | | |
| | | export function vueTemplate(str) { |
| | | return `<template> |
| | | <div> |
| | | ${str} |
| | | </div> |
| | | </template>` |
| | | } |
| | | |
| | | export function vueScript(str) { |
| | | return `<script> |
| | | ${str} |
| | | </script>` |
| | | } |
| | | |
| | | export function cssStyle(cssStr) { |
| | | return `<style> |
| | | ${cssStr} |
| | | </style>` |
| | | } |
| | | |
| | | function buildFormTemplate(conf, child, type) { |
| | | let labelPosition = '' |
| | | if (conf.labelPosition !== 'right') { |
| | | labelPosition = `label-position="${conf.labelPosition}"` |
| | | } |
| | | const disabled = conf.disabled ? `:disabled="${conf.disabled}"` : '' |
| | | let str = `<el-form ref="${conf.formRef}" :model="${conf.formModel}" :rules="${conf.formRules}" size="${conf.size}" ${disabled} label-width="${conf.labelWidth}px" ${labelPosition}> |
| | | ${child} |
| | | ${buildFromBtns(conf, type)} |
| | | </el-form>` |
| | | if (someSpanIsNot24) { |
| | | str = `<el-row :gutter="${conf.gutter}"> |
| | | ${str} |
| | | </el-row>` |
| | | } |
| | | return str |
| | | } |
| | | |
| | | function buildFromBtns(conf, type) { |
| | | let str = '' |
| | | if (conf.formBtns && type === 'file') { |
| | | str = `<el-form-item size="large"> |
| | | <el-button type="primary" @click="submitForm">提交</el-button> |
| | | <el-button @click="resetForm">重置</el-button> |
| | | </el-form-item>` |
| | | if (someSpanIsNot24) { |
| | | str = `<el-col :span="24"> |
| | | ${str} |
| | | </el-col>` |
| | | } |
| | | } |
| | | return str |
| | | } |
| | | |
| | | // span不为24的用el-col包裹 |
| | | function colWrapper(element, str) { |
| | | if (someSpanIsNot24 || element.span !== 24) { |
| | | return `<el-col :span="${element.span}"> |
| | | ${str} |
| | | </el-col>` |
| | | } |
| | | return str |
| | | } |
| | | |
| | | const layouts = { |
| | | colFormItem(element) { |
| | | let labelWidth = '' |
| | | if (element.labelWidth && element.labelWidth !== confGlobal.labelWidth) { |
| | | labelWidth = `label-width="${element.labelWidth}px"` |
| | | } |
| | | const required = !trigger[element.tag] && element.required ? 'required' : '' |
| | | const tagDom = tags[element.tag] ? tags[element.tag](element) : null |
| | | let str = `<el-form-item ${labelWidth} label="${element.label}" prop="${element.vModel}" ${required}> |
| | | ${tagDom} |
| | | </el-form-item>` |
| | | str = colWrapper(element, str) |
| | | return str |
| | | }, |
| | | rowFormItem(element) { |
| | | const type = element.type === 'default' ? '' : `type="${element.type}"` |
| | | const justify = element.type === 'default' ? '' : `justify="${element.justify}"` |
| | | const align = element.type === 'default' ? '' : `align="${element.align}"` |
| | | const gutter = element.gutter ? `gutter="${element.gutter}"` : '' |
| | | const children = element.children.map(el => layouts[el.layout](el)) |
| | | let str = `<el-row ${type} ${justify} ${align} ${gutter}> |
| | | ${children.join('\n')} |
| | | </el-row>` |
| | | str = colWrapper(element, str) |
| | | return str |
| | | } |
| | | } |
| | | |
| | | const tags = { |
| | | 'el-button': el => { |
| | | const { |
| | | tag, disabled |
| | | } = attrBuilder(el) |
| | | const type = el.type ? `type="${el.type}"` : '' |
| | | const icon = el.icon ? `icon="${el.icon}"` : '' |
| | | const size = el.size ? `size="${el.size}"` : '' |
| | | let child = buildElButtonChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // 换行 |
| | | return `<${el.tag} ${type} ${icon} ${size} ${disabled}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-input': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const maxlength = el.maxlength ? `:maxlength="${el.maxlength}"` : '' |
| | | const showWordLimit = el['show-word-limit'] ? 'show-word-limit' : '' |
| | | const readonly = el.readonly ? 'readonly' : '' |
| | | const prefixIcon = el['prefix-icon'] ? `prefix-icon='${el['prefix-icon']}'` : '' |
| | | const suffixIcon = el['suffix-icon'] ? `suffix-icon='${el['suffix-icon']}'` : '' |
| | | const showPassword = el['show-password'] ? 'show-password' : '' |
| | | const type = el.type ? `type="${el.type}"` : '' |
| | | const autosize = el.autosize && el.autosize.minRows |
| | | ? `:autosize="{minRows: ${el.autosize.minRows}, maxRows: ${el.autosize.maxRows}}"` |
| | | : '' |
| | | let child = buildElInputChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // 换行 |
| | | return `<${el.tag} ${vModel} ${type} ${placeholder} ${maxlength} ${showWordLimit} ${readonly} ${disabled} ${clearable} ${prefixIcon} ${suffixIcon} ${showPassword} ${autosize} ${width}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-input-number': el => { |
| | | const { disabled, vModel, placeholder } = attrBuilder(el) |
| | | const controlsPosition = el['controls-position'] ? `controls-position=${el['controls-position']}` : '' |
| | | const min = el.min ? `:min='${el.min}'` : '' |
| | | const max = el.max ? `:max='${el.max}'` : '' |
| | | const step = el.step ? `:step='${el.step}'` : '' |
| | | const stepStrictly = el['step-strictly'] ? 'step-strictly' : '' |
| | | const precision = el.precision ? `:precision='${el.precision}'` : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${placeholder} ${step} ${stepStrictly} ${precision} ${controlsPosition} ${min} ${max} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-select': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const filterable = el.filterable ? 'filterable' : '' |
| | | const multiple = el.multiple ? 'multiple' : '' |
| | | let child = buildElSelectChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // 换行 |
| | | return `<${el.tag} ${vModel} ${placeholder} ${disabled} ${multiple} ${filterable} ${clearable} ${width}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-radio-group': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const size = `size="${el.size}"` |
| | | let child = buildElRadioGroupChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // 换行 |
| | | return `<${el.tag} ${vModel} ${size} ${disabled}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-checkbox-group': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const size = `size="${el.size}"` |
| | | const min = el.min ? `:min="${el.min}"` : '' |
| | | const max = el.max ? `:max="${el.max}"` : '' |
| | | let child = buildElCheckboxGroupChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // 换行 |
| | | return `<${el.tag} ${vModel} ${min} ${max} ${size} ${disabled}>${child}</${el.tag}>` |
| | | }, |
| | | 'el-switch': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const activeText = el['active-text'] ? `active-text="${el['active-text']}"` : '' |
| | | const inactiveText = el['inactive-text'] ? `inactive-text="${el['inactive-text']}"` : '' |
| | | const activeColor = el['active-color'] ? `active-color="${el['active-color']}"` : '' |
| | | const inactiveColor = el['inactive-color'] ? `inactive-color="${el['inactive-color']}"` : '' |
| | | const activeValue = el['active-value'] !== true ? `:active-value='${JSON.stringify(el['active-value'])}'` : '' |
| | | const inactiveValue = el['inactive-value'] !== false ? `:inactive-value='${JSON.stringify(el['inactive-value'])}'` : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${activeText} ${inactiveText} ${activeColor} ${inactiveColor} ${activeValue} ${inactiveValue} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-cascader': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const options = el.options ? `:options="${el.vModel}Options"` : '' |
| | | const props = el.props ? `:props="${el.vModel}Props"` : '' |
| | | const showAllLevels = el['show-all-levels'] ? '' : ':show-all-levels="false"' |
| | | const filterable = el.filterable ? 'filterable' : '' |
| | | const separator = el.separator === '/' ? '' : `separator="${el.separator}"` |
| | | |
| | | return `<${el.tag} ${vModel} ${options} ${props} ${width} ${showAllLevels} ${placeholder} ${separator} ${filterable} ${clearable} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-slider': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const min = el.min ? `:min='${el.min}'` : '' |
| | | const max = el.max ? `:max='${el.max}'` : '' |
| | | const step = el.step ? `:step='${el.step}'` : '' |
| | | const range = el.range ? 'range' : '' |
| | | const showStops = el['show-stops'] ? `:show-stops="${el['show-stops']}"` : '' |
| | | |
| | | return `<${el.tag} ${min} ${max} ${step} ${vModel} ${range} ${showStops} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-time-picker': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' |
| | | const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' |
| | | const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' |
| | | const isRange = el['is-range'] ? 'is-range' : '' |
| | | const format = el.format ? `format="${el.format}"` : '' |
| | | const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' |
| | | const pickerOptions = el['picker-options'] ? `:picker-options='${JSON.stringify(el['picker-options'])}'` : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${isRange} ${format} ${valueFormat} ${pickerOptions} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-date-picker': el => { |
| | | const { |
| | | disabled, vModel, clearable, placeholder, width |
| | | } = attrBuilder(el) |
| | | const startPlaceholder = el['start-placeholder'] ? `start-placeholder="${el['start-placeholder']}"` : '' |
| | | const endPlaceholder = el['end-placeholder'] ? `end-placeholder="${el['end-placeholder']}"` : '' |
| | | const rangeSeparator = el['range-separator'] ? `range-separator="${el['range-separator']}"` : '' |
| | | const format = el.format ? `format="${el.format}"` : '' |
| | | const valueFormat = el['value-format'] ? `value-format="${el['value-format']}"` : '' |
| | | const type = el.type === 'date' ? '' : `type="${el.type}"` |
| | | const readonly = el.readonly ? 'readonly' : '' |
| | | |
| | | return `<${el.tag} ${type} ${vModel} ${format} ${valueFormat} ${width} ${placeholder} ${startPlaceholder} ${endPlaceholder} ${rangeSeparator} ${clearable} ${readonly} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-rate': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const max = el.max ? `:max='${el.max}'` : '' |
| | | const allowHalf = el['allow-half'] ? 'allow-half' : '' |
| | | const showText = el['show-text'] ? 'show-text' : '' |
| | | const showScore = el['show-score'] ? 'show-score' : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${allowHalf} ${showText} ${showScore} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-color-picker': el => { |
| | | const { disabled, vModel } = attrBuilder(el) |
| | | const size = `size="${el.size}"` |
| | | const showAlpha = el['show-alpha'] ? 'show-alpha' : '' |
| | | const colorFormat = el['color-format'] ? `color-format="${el['color-format']}"` : '' |
| | | |
| | | return `<${el.tag} ${vModel} ${size} ${showAlpha} ${colorFormat} ${disabled}></${el.tag}>` |
| | | }, |
| | | 'el-upload': el => { |
| | | const disabled = el.disabled ? ':disabled=\'true\'' : '' |
| | | const action = el.action ? `:action="${el.vModel}Action"` : '' |
| | | const multiple = el.multiple ? 'multiple' : '' |
| | | const listType = el['list-type'] !== 'text' ? `list-type="${el['list-type']}"` : '' |
| | | const accept = el.accept ? `accept="${el.accept}"` : '' |
| | | const name = el.name !== 'file' ? `name="${el.name}"` : '' |
| | | const autoUpload = el['auto-upload'] === false ? ':auto-upload="false"' : '' |
| | | const beforeUpload = `:before-upload="${el.vModel}BeforeUpload"` |
| | | const fileList = `:file-list="${el.vModel}fileList"` |
| | | const ref = `ref="${el.vModel}"` |
| | | let child = buildElUploadChild(el) |
| | | |
| | | if (child) child = `\n${child}\n` // 换行 |
| | | return `<${el.tag} ${ref} ${fileList} ${action} ${autoUpload} ${multiple} ${beforeUpload} ${listType} ${accept} ${name} ${disabled}>${child}</${el.tag}>` |
| | | } |
| | | } |
| | | |
| | | function attrBuilder(el) { |
| | | return { |
| | | vModel: `v-model="${confGlobal.formModel}.${el.vModel}"`, |
| | | clearable: el.clearable ? 'clearable' : '', |
| | | placeholder: el.placeholder ? `placeholder="${el.placeholder}"` : '', |
| | | width: el.style && el.style.width ? ':style="{width: \'100%\'}"' : '', |
| | | disabled: el.disabled ? ':disabled=\'true\'' : '' |
| | | } |
| | | } |
| | | |
| | | // el-buttin 子级 |
| | | function buildElButtonChild(conf) { |
| | | const children = [] |
| | | if (conf.default) { |
| | | children.push(conf.default) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | // el-input innerHTML |
| | | function buildElInputChild(conf) { |
| | | const children = [] |
| | | if (conf.prepend) { |
| | | children.push(`<template slot="prepend">${conf.prepend}</template>`) |
| | | } |
| | | if (conf.append) { |
| | | children.push(`<template slot="append">${conf.append}</template>`) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | function buildElSelectChild(conf) { |
| | | const children = [] |
| | | if (conf.options && conf.options.length) { |
| | | children.push(`<el-option v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.label" :value="item.value" :disabled="item.disabled"></el-option>`) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | function buildElRadioGroupChild(conf) { |
| | | const children = [] |
| | | if (conf.options && conf.options.length) { |
| | | const tag = conf.optionType === 'button' ? 'el-radio-button' : 'el-radio' |
| | | const border = conf.border ? 'border' : '' |
| | | children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | function buildElCheckboxGroupChild(conf) { |
| | | const children = [] |
| | | if (conf.options && conf.options.length) { |
| | | const tag = conf.optionType === 'button' ? 'el-checkbox-button' : 'el-checkbox' |
| | | const border = conf.border ? 'border' : '' |
| | | children.push(`<${tag} v-for="(item, index) in ${conf.vModel}Options" :key="index" :label="item.value" :disabled="item.disabled" ${border}>{{item.label}}</${tag}>`) |
| | | } |
| | | return children.join('\n') |
| | | } |
| | | |
| | | function buildElUploadChild(conf) { |
| | | const list = [] |
| | | if (conf['list-type'] === 'picture-card') list.push('<i class="el-icon-plus"></i>') |
| | | else list.push(`<el-button size="small" type="primary" icon="el-icon-upload">${conf.buttonText}</el-button>`) |
| | | if (conf.showTip) list.push(`<div slot="tip" class="el-upload__tip">只能上传不超过 ${conf.fileSize}${conf.sizeUnit} 的${conf.accept}文件</div>`) |
| | | return list.join('\n') |
| | | } |
| | | |
| | | export function makeUpHtml(conf, type) { |
| | | const htmlList = [] |
| | | confGlobal = conf |
| | | someSpanIsNot24 = conf.fields.some(item => item.span !== 24) |
| | | conf.fields.forEach(el => { |
| | | htmlList.push(layouts[el.layout](el)) |
| | | }) |
| | | const htmlStr = htmlList.join('\n') |
| | | |
| | | let temp = buildFormTemplate(conf, htmlStr, type) |
| | | if (type === 'dialog') { |
| | | temp = dialogWrapper(temp) |
| | | } |
| | | confGlobal = null |
| | | return temp |
| | | } |
New file |
| | |
| | | ["platform-eleme","eleme","delete-solid","delete","s-tools","setting","user-solid","user","phone","phone-outline","more","more-outline","star-on","star-off","s-goods","goods","warning","warning-outline","question","info","remove","circle-plus","success","error","zoom-in","zoom-out","remove-outline","circle-plus-outline","circle-check","circle-close","s-help","help","minus","plus","check","close","picture","picture-outline","picture-outline-round","upload","upload2","download","camera-solid","camera","video-camera-solid","video-camera","message-solid","bell","s-cooperation","s-order","s-platform","s-fold","s-unfold","s-operation","s-promotion","s-home","s-release","s-ticket","s-management","s-open","s-shop","s-marketing","s-flag","s-comment","s-finance","s-claim","s-custom","s-opportunity","s-data","s-check","s-grid","menu","share","d-caret","caret-left","caret-right","caret-bottom","caret-top","bottom-left","bottom-right","back","right","bottom","top","top-left","top-right","arrow-left","arrow-right","arrow-down","arrow-up","d-arrow-left","d-arrow-right","video-pause","video-play","refresh","refresh-right","refresh-left","finished","sort","sort-up","sort-down","rank","loading","view","c-scale-to-original","date","edit","edit-outline","folder","folder-opened","folder-add","folder-remove","folder-delete","folder-checked","tickets","document-remove","document-delete","document-copy","document-checked","document","document-add","printer","paperclip","takeaway-box","search","monitor","attract","mobile","scissors","umbrella","headset","brush","mouse","coordinate","magic-stick","reading","data-line","data-board","pie-chart","data-analysis","collection-tag","film","suitcase","suitcase-1","receiving","collection","files","notebook-1","notebook-2","toilet-paper","office-building","school","table-lamp","house","no-smoking","smoking","shopping-cart-full","shopping-cart-1","shopping-cart-2","shopping-bag-1","shopping-bag-2","sold-out","sell","present","box","bank-card","money","coin","wallet","discount","price-tag","news","guide","male","female","thumb","cpu","link","connection","open","turn-off","set-up","chat-round","chat-line-round","chat-square","chat-dot-round","chat-dot-square","chat-line-square","message","postcard","position","turn-off-microphone","microphone","close-notification","bangzhu","time","odometer","crop","aim","switch-button","full-screen","copy-document","mic","stopwatch","medal-1","medal","trophy","trophy-1","first-aid-kit","discover","place","location","location-outline","location-information","add-location","delete-location","map-location","alarm-clock","timer","watch-1","watch","lock","unlock","key","service","mobile-phone","bicycle","truck","ship","basketball","football","soccer","baseball","wind-power","light-rain","lightning","heavy-rain","sunrise","sunrise-1","sunset","sunny","cloudy","partly-cloudy","cloudy-and-sunny","moon","moon-night","dish","dish-1","food","chicken","fork-spoon","knife-fork","burger","tableware","sugar","dessert","ice-cream","hot-water","water-cup","coffee-cup","cold-drink","goblet","goblet-full","goblet-square","goblet-square-full","refrigerator","grape","watermelon","cherry","apple","pear","orange","coffee","ice-tea","ice-drink","milk-tea","potato-strips","lollipop","ice-cream-square","ice-cream-round"] |
New file |
| | |
| | | import { exportDefault, titleCase } from '@/utils/index' |
| | | import { trigger } from './config' |
| | | |
| | | const units = { |
| | | KB: '1024', |
| | | MB: '1024 / 1024', |
| | | GB: '1024 / 1024 / 1024' |
| | | } |
| | | let confGlobal |
| | | const inheritAttrs = { |
| | | file: '', |
| | | dialog: 'inheritAttrs: false,' |
| | | } |
| | | |
| | | |
| | | export function makeUpJs(conf, type) { |
| | | confGlobal = conf = JSON.parse(JSON.stringify(conf)) |
| | | const dataList = [] |
| | | const ruleList = [] |
| | | const optionsList = [] |
| | | const propsList = [] |
| | | const methodList = mixinMethod(type) |
| | | const uploadVarList = [] |
| | | |
| | | conf.fields.forEach(el => { |
| | | buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) |
| | | }) |
| | | |
| | | const script = buildexport( |
| | | conf, |
| | | type, |
| | | dataList.join('\n'), |
| | | ruleList.join('\n'), |
| | | optionsList.join('\n'), |
| | | uploadVarList.join('\n'), |
| | | propsList.join('\n'), |
| | | methodList.join('\n') |
| | | ) |
| | | confGlobal = null |
| | | return script |
| | | } |
| | | |
| | | function buildAttributes(el, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) { |
| | | buildData(el, dataList) |
| | | buildRules(el, ruleList) |
| | | |
| | | if (el.options && el.options.length) { |
| | | buildOptions(el, optionsList) |
| | | if (el.dataType === 'dynamic') { |
| | | const model = `${el.vModel}Options` |
| | | const options = titleCase(model) |
| | | buildOptionMethod(`get${options}`, model, methodList) |
| | | } |
| | | } |
| | | |
| | | if (el.props && el.props.props) { |
| | | buildProps(el, propsList) |
| | | } |
| | | |
| | | if (el.action && el.tag === 'el-upload') { |
| | | uploadVarList.push( |
| | | `${el.vModel}Action: '${el.action}', |
| | | ${el.vModel}fileList: [],` |
| | | ) |
| | | methodList.push(buildBeforeUpload(el)) |
| | | if (!el['auto-upload']) { |
| | | methodList.push(buildSubmitUpload(el)) |
| | | } |
| | | } |
| | | |
| | | if (el.children) { |
| | | el.children.forEach(el2 => { |
| | | buildAttributes(el2, dataList, ruleList, optionsList, methodList, propsList, uploadVarList) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | function mixinMethod(type) { |
| | | const list = []; const |
| | | minxins = { |
| | | file: confGlobal.formBtns ? { |
| | | submitForm: `submitForm() { |
| | | this.$refs['${confGlobal.formRef}'].validate(valid => { |
| | | if(!valid) return |
| | | // TODO 提交表单 |
| | | }) |
| | | },`, |
| | | resetForm: `resetForm() { |
| | | this.$refs['${confGlobal.formRef}'].resetFields() |
| | | },` |
| | | } : null, |
| | | dialog: { |
| | | onOpen: 'onOpen() {},', |
| | | onClose: `onClose() { |
| | | this.$refs['${confGlobal.formRef}'].resetFields() |
| | | },`, |
| | | close: `close() { |
| | | this.$emit('update:visible', false) |
| | | },`, |
| | | handleConfirm: `handleConfirm() { |
| | | this.$refs['${confGlobal.formRef}'].validate(valid => { |
| | | if(!valid) return |
| | | this.close() |
| | | }) |
| | | },` |
| | | } |
| | | } |
| | | |
| | | const methods = minxins[type] |
| | | if (methods) { |
| | | Object.keys(methods).forEach(key => { |
| | | list.push(methods[key]) |
| | | }) |
| | | } |
| | | |
| | | return list |
| | | } |
| | | |
| | | function buildData(conf, dataList) { |
| | | if (conf.vModel === undefined) return |
| | | let defaultValue |
| | | if (typeof (conf.defaultValue) === 'string' && !conf.multiple) { |
| | | defaultValue = `'${conf.defaultValue}'` |
| | | } else { |
| | | defaultValue = `${JSON.stringify(conf.defaultValue)}` |
| | | } |
| | | dataList.push(`${conf.vModel}: ${defaultValue},`) |
| | | } |
| | | |
| | | function buildRules(conf, ruleList) { |
| | | if (conf.vModel === undefined) return |
| | | const rules = [] |
| | | if (trigger[conf.tag]) { |
| | | if (conf.required) { |
| | | const type = Array.isArray(conf.defaultValue) ? 'type: \'array\',' : '' |
| | | let message = Array.isArray(conf.defaultValue) ? `请至少选择一个${conf.vModel}` : conf.placeholder |
| | | if (message === undefined) message = `${conf.label}不能为空` |
| | | rules.push(`{ required: true, ${type} message: '${message}', trigger: '${trigger[conf.tag]}' }`) |
| | | } |
| | | if (conf.regList && Array.isArray(conf.regList)) { |
| | | conf.regList.forEach(item => { |
| | | if (item.pattern) { |
| | | rules.push(`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${trigger[conf.tag]}' }`) |
| | | } |
| | | }) |
| | | } |
| | | ruleList.push(`${conf.vModel}: [${rules.join(',')}],`) |
| | | } |
| | | } |
| | | |
| | | function buildOptions(conf, optionsList) { |
| | | if (conf.vModel === undefined) return |
| | | if (conf.dataType === 'dynamic') { conf.options = [] } |
| | | const str = `${conf.vModel}Options: ${JSON.stringify(conf.options)},` |
| | | optionsList.push(str) |
| | | } |
| | | |
| | | function buildProps(conf, propsList) { |
| | | if (conf.dataType === 'dynamic') { |
| | | conf.valueKey !== 'value' && (conf.props.props.value = conf.valueKey) |
| | | conf.labelKey !== 'label' && (conf.props.props.label = conf.labelKey) |
| | | conf.childrenKey !== 'children' && (conf.props.props.children = conf.childrenKey) |
| | | } |
| | | const str = `${conf.vModel}Props: ${JSON.stringify(conf.props.props)},` |
| | | propsList.push(str) |
| | | } |
| | | |
| | | function buildBeforeUpload(conf) { |
| | | const unitNum = units[conf.sizeUnit]; let rightSizeCode = ''; let acceptCode = ''; const |
| | | returnList = [] |
| | | if (conf.fileSize) { |
| | | rightSizeCode = `let isRightSize = file.size / ${unitNum} < ${conf.fileSize} |
| | | if(!isRightSize){ |
| | | this.$message.error('文件大小超过 ${conf.fileSize}${conf.sizeUnit}') |
| | | }` |
| | | returnList.push('isRightSize') |
| | | } |
| | | if (conf.accept) { |
| | | acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type) |
| | | if(!isAccept){ |
| | | this.$message.error('应该选择${conf.accept}类型的文件') |
| | | }` |
| | | returnList.push('isAccept') |
| | | } |
| | | const str = `${conf.vModel}BeforeUpload(file) { |
| | | ${rightSizeCode} |
| | | ${acceptCode} |
| | | return ${returnList.join('&&')} |
| | | },` |
| | | return returnList.length ? str : '' |
| | | } |
| | | |
| | | function buildSubmitUpload(conf) { |
| | | const str = `submitUpload() { |
| | | this.$refs['${conf.vModel}'].submit() |
| | | },` |
| | | return str |
| | | } |
| | | |
| | | function buildOptionMethod(methodName, model, methodList) { |
| | | const str = `${methodName}() { |
| | | // TODO 发起请求获取数据 |
| | | this.${model} |
| | | },` |
| | | methodList.push(str) |
| | | } |
| | | |
| | | function buildexport(conf, type, data, rules, selectOptions, uploadVar, props, methods) { |
| | | const str = `${exportDefault}{ |
| | | ${inheritAttrs[type]} |
| | | components: {}, |
| | | props: [], |
| | | data () { |
| | | return { |
| | | ${conf.formModel}: { |
| | | ${data} |
| | | }, |
| | | ${conf.formRules}: { |
| | | ${rules} |
| | | }, |
| | | ${uploadVar} |
| | | ${selectOptions} |
| | | ${props} |
| | | } |
| | | }, |
| | | computed: {}, |
| | | watch: {}, |
| | | created () {}, |
| | | mounted () {}, |
| | | methods: { |
| | | ${methods} |
| | | } |
| | | }` |
| | | return str |
| | | } |
New file |
| | |
| | | import { makeMap } from '@/utils/index' |
| | | |
| | | // 参考https://github.com/vuejs/vue/blob/v2.6.10/src/platforms/web/server/util.js |
| | | const isAttr = makeMap( |
| | | 'accept,accept-charset,accesskey,action,align,alt,async,autocomplete,' |
| | | + 'autofocus,autoplay,autosave,bgcolor,border,buffered,challenge,charset,' |
| | | + 'checked,cite,class,code,codebase,color,cols,colspan,content,http-equiv,' |
| | | + 'name,contenteditable,contextmenu,controls,coords,data,datetime,default,' |
| | | + 'defer,dir,dirname,disabled,download,draggable,dropzone,enctype,method,for,' |
| | | + 'form,formaction,headers,height,hidden,high,href,hreflang,http-equiv,' |
| | | + 'icon,id,ismap,itemprop,keytype,kind,label,lang,language,list,loop,low,' |
| | | + 'manifest,max,maxlength,media,method,GET,POST,min,multiple,email,file,' |
| | | + 'muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,' |
| | | + 'preload,radiogroup,readonly,rel,required,reversed,rows,rowspan,sandbox,' |
| | | + 'scope,scoped,seamless,selected,shape,size,type,text,password,sizes,span,' |
| | | + 'spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,' |
| | | + 'target,title,type,usemap,value,width,wrap' |
| | | ) |
| | | |
| | | function vModel(self, dataObject, defaultValue) { |
| | | dataObject.props.value = defaultValue |
| | | |
| | | dataObject.on.input = val => { |
| | | self.$emit('input', val) |
| | | } |
| | | } |
| | | |
| | | const componentChild = { |
| | | 'el-button': { |
| | | default(h, conf, key) { |
| | | return conf[key] |
| | | }, |
| | | }, |
| | | 'el-input': { |
| | | prepend(h, conf, key) { |
| | | return <template slot="prepend">{conf[key]}</template> |
| | | }, |
| | | append(h, conf, key) { |
| | | return <template slot="append">{conf[key]}</template> |
| | | } |
| | | }, |
| | | 'el-select': { |
| | | options(h, conf, key) { |
| | | const list = [] |
| | | conf.options.forEach(item => { |
| | | list.push(<el-option label={item.label} value={item.value} disabled={item.disabled}></el-option>) |
| | | }) |
| | | return list |
| | | } |
| | | }, |
| | | 'el-radio-group': { |
| | | options(h, conf, key) { |
| | | const list = [] |
| | | conf.options.forEach(item => { |
| | | if (conf.optionType === 'button') list.push(<el-radio-button label={item.value}>{item.label}</el-radio-button>) |
| | | else list.push(<el-radio label={item.value} border={conf.border}>{item.label}</el-radio>) |
| | | }) |
| | | return list |
| | | } |
| | | }, |
| | | 'el-checkbox-group': { |
| | | options(h, conf, key) { |
| | | const list = [] |
| | | conf.options.forEach(item => { |
| | | if (conf.optionType === 'button') { |
| | | list.push(<el-checkbox-button label={item.value}>{item.label}</el-checkbox-button>) |
| | | } else { |
| | | list.push(<el-checkbox label={item.value} border={conf.border}>{item.label}</el-checkbox>) |
| | | } |
| | | }) |
| | | return list |
| | | } |
| | | }, |
| | | 'el-upload': { |
| | | 'list-type': (h, conf, key) => { |
| | | const list = [] |
| | | if (conf['list-type'] === 'picture-card') { |
| | | list.push(<i class="el-icon-plus"></i>) |
| | | } else { |
| | | list.push(<el-button size="small" type="primary" icon="el-icon-upload">{conf.buttonText}</el-button>) |
| | | } |
| | | if (conf.showTip) { |
| | | list.push(<div slot="tip" class="el-upload__tip">只能上传不超过 {conf.fileSize}{conf.sizeUnit} 的{conf.accept}文件</div>) |
| | | } |
| | | return list |
| | | } |
| | | } |
| | | } |
| | | |
| | | export default { |
| | | render(h) { |
| | | const dataObject = { |
| | | attrs: {}, |
| | | props: {}, |
| | | on: {}, |
| | | style: {} |
| | | } |
| | | const confClone = JSON.parse(JSON.stringify(this.conf)) |
| | | const children = [] |
| | | |
| | | const childObjs = componentChild[confClone.tag] |
| | | if (childObjs) { |
| | | Object.keys(childObjs).forEach(key => { |
| | | const childFunc = childObjs[key] |
| | | if (confClone[key]) { |
| | | children.push(childFunc(h, confClone, key)) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | Object.keys(confClone).forEach(key => { |
| | | const val = confClone[key] |
| | | if (key === 'vModel') { |
| | | vModel(this, dataObject, confClone.defaultValue) |
| | | } else if (dataObject[key]) { |
| | | dataObject[key] = val |
| | | } else if (!isAttr(key)) { |
| | | dataObject.props[key] = val |
| | | } else { |
| | | dataObject.attrs[key] = val |
| | | } |
| | | }) |
| | | return h(this.conf.tag, dataObject, children) |
| | | }, |
| | | props: ['conf'] |
| | | } |
New file |
| | |
| | | import { parseTime } from './ruoyi' |
| | | |
| | | /** |
| | | * 表格时间格式化 |
| | | */ |
| | | export function formatDate(cellValue) { |
| | | if (cellValue == null || cellValue == "") return "" |
| | | var date = new Date(cellValue) |
| | | var year = date.getFullYear() |
| | | var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 |
| | | var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() |
| | | var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() |
| | | var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() |
| | | var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() |
| | | return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds |
| | | } |
| | | |
| | | /** |
| | | * @param {number} time |
| | | * @param {string} option |
| | | * @returns {string} |
| | | */ |
| | | export function formatTime(time, option) { |
| | | if (('' + time).length === 10) { |
| | | time = parseInt(time) * 1000 |
| | | } else { |
| | | time = +time |
| | | } |
| | | const d = new Date(time) |
| | | const now = Date.now() |
| | | |
| | | const diff = (now - d) / 1000 |
| | | |
| | | if (diff < 30) { |
| | | return '刚刚' |
| | | } else if (diff < 3600) { |
| | | // less 1 hour |
| | | return Math.ceil(diff / 60) + '分钟前' |
| | | } else if (diff < 3600 * 24) { |
| | | return Math.ceil(diff / 3600) + '小时前' |
| | | } else if (diff < 3600 * 24 * 2) { |
| | | return '1天前' |
| | | } |
| | | if (option) { |
| | | return parseTime(time, option) |
| | | } else { |
| | | return ( |
| | | d.getMonth() + |
| | | 1 + |
| | | '月' + |
| | | d.getDate() + |
| | | '日' + |
| | | d.getHours() + |
| | | '时' + |
| | | d.getMinutes() + |
| | | '分' |
| | | ) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @param {string} url |
| | | * @returns {Object} |
| | | */ |
| | | export function getQueryObject(url) { |
| | | url = url == null ? window.location.href : url |
| | | const search = url.substring(url.lastIndexOf('?') + 1) |
| | | const obj = {} |
| | | const reg = /([^?&=]+)=([^?&=]*)/g |
| | | search.replace(reg, (rs, $1, $2) => { |
| | | const name = decodeURIComponent($1) |
| | | let val = decodeURIComponent($2) |
| | | val = String(val) |
| | | obj[name] = val |
| | | return rs |
| | | }) |
| | | return obj |
| | | } |
| | | |
| | | /** |
| | | * @param {string} input value |
| | | * @returns {number} output value |
| | | */ |
| | | export function byteLength(str) { |
| | | // returns the byte length of an utf8 string |
| | | let s = str.length |
| | | for (var i = str.length - 1; i >= 0; i--) { |
| | | const code = str.charCodeAt(i) |
| | | if (code > 0x7f && code <= 0x7ff) s++ |
| | | else if (code > 0x7ff && code <= 0xffff) s += 2 |
| | | if (code >= 0xDC00 && code <= 0xDFFF) i-- |
| | | } |
| | | return s |
| | | } |
| | | |
| | | /** |
| | | * @param {Array} actual |
| | | * @returns {Array} |
| | | */ |
| | | export function cleanArray(actual) { |
| | | const newArray = [] |
| | | for (let i = 0; i < actual.length; i++) { |
| | | if (actual[i]) { |
| | | newArray.push(actual[i]) |
| | | } |
| | | } |
| | | return newArray |
| | | } |
| | | |
| | | /** |
| | | * @param {Object} json |
| | | * @returns {Array} |
| | | */ |
| | | export function param(json) { |
| | | if (!json) return '' |
| | | return cleanArray( |
| | | Object.keys(json).map(key => { |
| | | if (json[key] === undefined) return '' |
| | | return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]) |
| | | }) |
| | | ).join('&') |
| | | } |
| | | |
| | | /** |
| | | * @param {string} url |
| | | * @returns {Object} |
| | | */ |
| | | export function param2Obj(url) { |
| | | const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') |
| | | if (!search) { |
| | | return {} |
| | | } |
| | | const obj = {} |
| | | const searchArr = search.split('&') |
| | | searchArr.forEach(v => { |
| | | const index = v.indexOf('=') |
| | | if (index !== -1) { |
| | | const name = v.substring(0, index) |
| | | const val = v.substring(index + 1, v.length) |
| | | obj[name] = val |
| | | } |
| | | }) |
| | | return obj |
| | | } |
| | | |
| | | /** |
| | | * @param {string} val |
| | | * @returns {string} |
| | | */ |
| | | export function html2Text(val) { |
| | | const div = document.createElement('div') |
| | | div.innerHTML = val |
| | | return div.textContent || div.innerText |
| | | } |
| | | |
| | | /** |
| | | * Merges two objects, giving the last one precedence |
| | | * @param {Object} target |
| | | * @param {(Object|Array)} source |
| | | * @returns {Object} |
| | | */ |
| | | export function objectMerge(target, source) { |
| | | if (typeof target !== 'object') { |
| | | target = {} |
| | | } |
| | | if (Array.isArray(source)) { |
| | | return source.slice() |
| | | } |
| | | Object.keys(source).forEach(property => { |
| | | const sourceProperty = source[property] |
| | | if (typeof sourceProperty === 'object') { |
| | | target[property] = objectMerge(target[property], sourceProperty) |
| | | } else { |
| | | target[property] = sourceProperty |
| | | } |
| | | }) |
| | | return target |
| | | } |
| | | |
| | | /** |
| | | * @param {HTMLElement} element |
| | | * @param {string} className |
| | | */ |
| | | export function toggleClass(element, className) { |
| | | if (!element || !className) { |
| | | return |
| | | } |
| | | let classString = element.className |
| | | const nameIndex = classString.indexOf(className) |
| | | if (nameIndex === -1) { |
| | | classString += '' + className |
| | | } else { |
| | | classString = |
| | | classString.substr(0, nameIndex) + |
| | | classString.substr(nameIndex + className.length) |
| | | } |
| | | element.className = classString |
| | | } |
| | | |
| | | /** |
| | | * @param {string} type |
| | | * @returns {Date} |
| | | */ |
| | | export function getTime(type) { |
| | | if (type === 'start') { |
| | | return new Date().getTime() - 3600 * 1000 * 24 * 90 |
| | | } else { |
| | | return new Date(new Date().toDateString()) |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * @param {Function} func |
| | | * @param {number} wait |
| | | * @param {boolean} immediate |
| | | * @return {*} |
| | | */ |
| | | export function debounce(func, wait, immediate) { |
| | | let timeout, args, context, timestamp, result |
| | | |
| | | const later = function() { |
| | | // 据上一次触发时间间隔 |
| | | const last = +new Date() - timestamp |
| | | |
| | | // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait |
| | | if (last < wait && last > 0) { |
| | | timeout = setTimeout(later, wait - last) |
| | | } else { |
| | | timeout = null |
| | | // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 |
| | | if (!immediate) { |
| | | result = func.apply(context, args) |
| | | if (!timeout) context = args = null |
| | | } |
| | | } |
| | | } |
| | | |
| | | return function(...args) { |
| | | context = this |
| | | timestamp = +new Date() |
| | | const callNow = immediate && !timeout |
| | | // 如果延时不存在,重新设定延时 |
| | | if (!timeout) timeout = setTimeout(later, wait) |
| | | if (callNow) { |
| | | result = func.apply(context, args) |
| | | context = args = null |
| | | } |
| | | |
| | | return result |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * This is just a simple version of deep copy |
| | | * Has a lot of edge cases bug |
| | | * If you want to use a perfect deep copy, use lodash's _.cloneDeep |
| | | * @param {Object} source |
| | | * @returns {Object} |
| | | */ |
| | | export function deepClone(source) { |
| | | if (!source && typeof source !== 'object') { |
| | | throw new Error('error arguments', 'deepClone') |
| | | } |
| | | const targetObj = source.constructor === Array ? [] : {} |
| | | Object.keys(source).forEach(keys => { |
| | | if (source[keys] && typeof source[keys] === 'object') { |
| | | targetObj[keys] = deepClone(source[keys]) |
| | | } else { |
| | | targetObj[keys] = source[keys] |
| | | } |
| | | }) |
| | | return targetObj |
| | | } |
| | | |
| | | /** |
| | | * @param {Array} arr |
| | | * @returns {Array} |
| | | */ |
| | | export function uniqueArr(arr) { |
| | | return Array.from(new Set(arr)) |
| | | } |
| | | |
| | | /** |
| | | * @returns {string} |
| | | */ |
| | | export function createUniqueString() { |
| | | const timestamp = +new Date() + '' |
| | | const randomNum = parseInt((1 + Math.random()) * 65536) + '' |
| | | return (+(randomNum + timestamp)).toString(32) |
| | | } |
| | | |
| | | /** |
| | | * Check if an element has a class |
| | | * @param {HTMLElement} elm |
| | | * @param {string} cls |
| | | * @returns {boolean} |
| | | */ |
| | | export function hasClass(ele, cls) { |
| | | return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) |
| | | } |
| | | |
| | | /** |
| | | * Add class to element |
| | | * @param {HTMLElement} elm |
| | | * @param {string} cls |
| | | */ |
| | | export function addClass(ele, cls) { |
| | | if (!hasClass(ele, cls)) ele.className += ' ' + cls |
| | | } |
| | | |
| | | /** |
| | | * Remove class from element |
| | | * @param {HTMLElement} elm |
| | | * @param {string} cls |
| | | */ |
| | | export function removeClass(ele, cls) { |
| | | if (hasClass(ele, cls)) { |
| | | const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)') |
| | | ele.className = ele.className.replace(reg, ' ') |
| | | } |
| | | } |
| | | |
| | | export function makeMap(str, expectsLowerCase) { |
| | | const map = Object.create(null) |
| | | const list = str.split(',') |
| | | for (let i = 0; i < list.length; i++) { |
| | | map[list[i]] = true |
| | | } |
| | | return expectsLowerCase |
| | | ? val => map[val.toLowerCase()] |
| | | : val => map[val] |
| | | } |
| | | |
| | | export const exportDefault = 'export default ' |
| | | |
| | | export const beautifierConf = { |
| | | html: { |
| | | indent_size: '2', |
| | | indent_char: ' ', |
| | | max_preserve_newlines: '-1', |
| | | preserve_newlines: false, |
| | | keep_array_indentation: false, |
| | | break_chained_methods: false, |
| | | indent_scripts: 'separate', |
| | | brace_style: 'end-expand', |
| | | space_before_conditional: true, |
| | | unescape_strings: false, |
| | | jslint_happy: false, |
| | | end_with_newline: true, |
| | | wrap_line_length: '110', |
| | | indent_inner_html: true, |
| | | comma_first: false, |
| | | e4x: true, |
| | | indent_empty_lines: true |
| | | }, |
| | | js: { |
| | | indent_size: '2', |
| | | indent_char: ' ', |
| | | max_preserve_newlines: '-1', |
| | | preserve_newlines: false, |
| | | keep_array_indentation: false, |
| | | break_chained_methods: false, |
| | | indent_scripts: 'normal', |
| | | brace_style: 'end-expand', |
| | | space_before_conditional: true, |
| | | unescape_strings: false, |
| | | jslint_happy: true, |
| | | end_with_newline: true, |
| | | wrap_line_length: '110', |
| | | indent_inner_html: true, |
| | | comma_first: false, |
| | | e4x: true, |
| | | indent_empty_lines: true |
| | | } |
| | | } |
| | | |
| | | // 首字母大小 |
| | | export function titleCase(str) { |
| | | return str.replace(/( |^)[a-z]/g, L => L.toUpperCase()) |
| | | } |
| | | |
| | | // 下划转驼峰 |
| | | export function camelCase(str) { |
| | | return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase()) |
| | | } |
| | | |
| | | export function isNumberStr(str) { |
| | | return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str) |
| | | } |
| | | |
New file |
| | |
| | | import JSEncrypt from 'jsencrypt/bin/jsencrypt.min' |
| | | |
| | | // 密钥对生成 http://web.chacuo.net/netrsakeypair |
| | | |
| | | const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' + |
| | | 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==' |
| | | |
| | | const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' + |
| | | '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' + |
| | | 'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' + |
| | | 'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' + |
| | | 'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' + |
| | | 'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' + |
| | | 'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' + |
| | | 'UP8iWi1Qw0Y=' |
| | | |
| | | // 加密 |
| | | export function encrypt(txt) { |
| | | const encryptor = new JSEncrypt() |
| | | encryptor.setPublicKey(publicKey) // 设置公钥 |
| | | return encryptor.encrypt(txt) // 对数据进行加密 |
| | | } |
| | | |
| | | // 解密 |
| | | export function decrypt(txt) { |
| | | const encryptor = new JSEncrypt() |
| | | encryptor.setPrivateKey(privateKey) // 设置私钥 |
| | | return encryptor.decrypt(txt) // 对数据进行解密 |
| | | } |
| | | |
New file |
| | |
| | | import store from '@/store' |
| | | |
| | | /** |
| | | * 字符权限校验 |
| | | * @param {Array} value 校验值 |
| | | * @returns {Boolean} |
| | | */ |
| | | export function checkPermi(value) { |
| | | if (value && value instanceof Array && value.length > 0) { |
| | | const permissions = store.getters && store.getters.permissions |
| | | const permissionDatas = value |
| | | const all_permission = "*:*:*" |
| | | |
| | | const hasPermission = permissions.some(permission => { |
| | | return all_permission === permission || permissionDatas.includes(permission) |
| | | }) |
| | | |
| | | return hasPermission |
| | | |
| | | } else { |
| | | console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`) |
| | | return false |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 角色权限校验 |
| | | * @param {Array} value 校验值 |
| | | * @returns {Boolean} |
| | | */ |
| | | export function checkRole(value) { |
| | | if (value && value instanceof Array && value.length > 0) { |
| | | const roles = store.getters && store.getters.roles |
| | | const permissionRoles = value |
| | | const super_admin = "admin" |
| | | |
| | | const hasRole = roles.some(role => { |
| | | return super_admin === role || permissionRoles.includes(role) |
| | | }) |
| | | |
| | | return hasRole |
| | | |
| | | } else { |
| | | console.error(`need roles! Like checkRole="['admin','editor']"`) |
| | | return false |
| | | } |
| | | } |
New file |
| | |
| | | import axios from 'axios' |
| | | import { Notification, MessageBox, Message, Loading } from 'element-ui' |
| | | import store from '@/store' |
| | | import { getToken } from '@/utils/auth' |
| | | import errorCode from '@/utils/errorCode' |
| | | import { tansParams, blobValidate } from "@/utils/ruoyi" |
| | | import cache from '@/plugins/cache' |
| | | import { saveAs } from 'file-saver' |
| | | |
| | | let downloadLoadingInstance |
| | | // 是否显示重新登录 |
| | | export let isRelogin = { show: false } |
| | | |
| | | axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' |
| | | // 创建axios实例 |
| | | const service = axios.create({ |
| | | // axios中请求配置有baseURL选项,表示请求URL公共部分 |
| | | baseURL: process.env.VUE_APP_BASE_API, |
| | | // 超时 |
| | | timeout: 10000 |
| | | }) |
| | | |
| | | // request拦截器 |
| | | service.interceptors.request.use(config => { |
| | | // 是否需要设置 token |
| | | const isToken = (config.headers || {}).isToken === false |
| | | // 是否需要防止数据重复提交 |
| | | const isRepeatSubmit = (config.headers || {}).repeatSubmit === false |
| | | if (getToken() && !isToken) { |
| | | config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 |
| | | } |
| | | // get请求映射params参数 |
| | | if (config.method === 'get' && config.params) { |
| | | let url = config.url + '?' + tansParams(config.params) |
| | | url = url.slice(0, -1) |
| | | config.params = {} |
| | | config.url = url |
| | | } |
| | | if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { |
| | | const requestObj = { |
| | | url: config.url, |
| | | data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, |
| | | time: new Date().getTime() |
| | | } |
| | | const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小 |
| | | const limitSize = 5 * 1024 * 1024 // 限制存放数据5M |
| | | if (requestSize >= limitSize) { |
| | | console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。') |
| | | return config |
| | | } |
| | | const sessionObj = cache.session.getJSON('sessionObj') |
| | | if (sessionObj === undefined || sessionObj === null || sessionObj === '') { |
| | | cache.session.setJSON('sessionObj', requestObj) |
| | | } else { |
| | | const s_url = sessionObj.url // 请求地址 |
| | | const s_data = sessionObj.data // 请求数据 |
| | | const s_time = sessionObj.time // 请求时间 |
| | | const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交 |
| | | if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { |
| | | const message = '数据正在处理,请勿重复提交' |
| | | console.warn(`[${s_url}]: ` + message) |
| | | return Promise.reject(new Error(message)) |
| | | } else { |
| | | cache.session.setJSON('sessionObj', requestObj) |
| | | } |
| | | } |
| | | } |
| | | return config |
| | | }, error => { |
| | | console.log(error) |
| | | Promise.reject(error) |
| | | }) |
| | | |
| | | // 响应拦截器 |
| | | service.interceptors.response.use(res => { |
| | | // 未设置状态码则默认成功状态 |
| | | const code = res.data.code || 200 |
| | | // 获取错误信息 |
| | | const msg = errorCode[code] || res.data.msg || errorCode['default'] |
| | | // 二进制数据则直接返回 |
| | | if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { |
| | | return res.data |
| | | } |
| | | if (code === 401) { |
| | | if (!isRelogin.show) { |
| | | isRelogin.show = true |
| | | MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { |
| | | isRelogin.show = false |
| | | store.dispatch('LogOut').then(() => { |
| | | location.href = '/index' |
| | | }) |
| | | }).catch(() => { |
| | | isRelogin.show = false |
| | | }) |
| | | } |
| | | return Promise.reject('无效的会话,或者会话已过期,请重新登录。') |
| | | } else if (code === 500) { |
| | | Message({ message: msg, type: 'error' }) |
| | | return Promise.reject(new Error(msg)) |
| | | } else if (code === 601) { |
| | | Message({ message: msg, type: 'warning' }) |
| | | return Promise.reject('error') |
| | | } else if (code !== 200) { |
| | | Notification.error({ title: msg }) |
| | | return Promise.reject('error') |
| | | } else { |
| | | return res.data |
| | | } |
| | | }, |
| | | error => { |
| | | console.log('err' + error) |
| | | let { message } = error |
| | | if (message == "Network Error") { |
| | | message = "后端接口连接异常" |
| | | } else if (message.includes("timeout")) { |
| | | message = "系统接口请求超时" |
| | | } else if (message.includes("Request failed with status code")) { |
| | | message = "系统接口" + message.substr(message.length - 3) + "异常" |
| | | } |
| | | Message({ message: message, type: 'error', duration: 5 * 1000 }) |
| | | return Promise.reject(error) |
| | | } |
| | | ) |
| | | |
| | | // 通用下载方法 |
| | | export function download(url, params, filename, config) { |
| | | downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }) |
| | | return service.post(url, params, { |
| | | transformRequest: [(params) => { return tansParams(params) }], |
| | | headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, |
| | | responseType: 'blob', |
| | | ...config |
| | | }).then(async (data) => { |
| | | const isBlob = blobValidate(data) |
| | | if (isBlob) { |
| | | const blob = new Blob([data]) |
| | | saveAs(blob, filename) |
| | | } else { |
| | | const resText = await data.text() |
| | | const rspObj = JSON.parse(resText) |
| | | const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] |
| | | Message.error(errMsg) |
| | | } |
| | | downloadLoadingInstance.close() |
| | | }).catch((r) => { |
| | | console.error(r) |
| | | Message.error('下载文件出现错误,请联系管理员!') |
| | | downloadLoadingInstance.close() |
| | | }) |
| | | } |
| | | |
| | | export default service |
New file |
| | |
| | | /** |
| | | * 通用js方法封装处理 |
| | | * Copyright (c) 2019 ruoyi |
| | | */ |
| | | |
| | | // 日期格式化 |
| | | export function parseTime(time, pattern) { |
| | | if (arguments.length === 0 || !time) { |
| | | return null |
| | | } |
| | | const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}' |
| | | let date |
| | | if (typeof time === 'object') { |
| | | date = time |
| | | } else { |
| | | if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { |
| | | time = parseInt(time) |
| | | } else if (typeof time === 'string') { |
| | | time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '') |
| | | } |
| | | if ((typeof time === 'number') && (time.toString().length === 10)) { |
| | | time = time * 1000 |
| | | } |
| | | date = new Date(time) |
| | | } |
| | | const formatObj = { |
| | | y: date.getFullYear(), |
| | | m: date.getMonth() + 1, |
| | | d: date.getDate(), |
| | | h: date.getHours(), |
| | | i: date.getMinutes(), |
| | | s: date.getSeconds(), |
| | | a: date.getDay() |
| | | } |
| | | const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { |
| | | let value = formatObj[key] |
| | | // Note: getDay() returns 0 on Sunday |
| | | if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] } |
| | | if (result.length > 0 && value < 10) { |
| | | value = '0' + value |
| | | } |
| | | return value || 0 |
| | | }) |
| | | return time_str |
| | | } |
| | | |
| | | // 表单重置 |
| | | export function resetForm(refName) { |
| | | if (this.$refs[refName]) { |
| | | this.$refs[refName].resetFields() |
| | | } |
| | | } |
| | | |
| | | // 添加日期范围 |
| | | export function addDateRange(params, dateRange, propName) { |
| | | let search = params |
| | | search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {} |
| | | dateRange = Array.isArray(dateRange) ? dateRange : [] |
| | | if (typeof (propName) === 'undefined') { |
| | | search.params['beginTime'] = dateRange[0] |
| | | search.params['endTime'] = dateRange[1] |
| | | } else { |
| | | search.params['begin' + propName] = dateRange[0] |
| | | search.params['end' + propName] = dateRange[1] |
| | | } |
| | | return search |
| | | } |
| | | |
| | | // 回显数据字典 |
| | | export function selectDictLabel(datas, value) { |
| | | if (value === undefined) { |
| | | return "" |
| | | } |
| | | var actions = [] |
| | | Object.keys(datas).some((key) => { |
| | | if (datas[key].value == ('' + value)) { |
| | | actions.push(datas[key].label) |
| | | return true |
| | | } |
| | | }) |
| | | if (actions.length === 0) { |
| | | actions.push(value) |
| | | } |
| | | return actions.join('') |
| | | } |
| | | |
| | | // 回显数据字典(字符串、数组) |
| | | export function selectDictLabels(datas, value, separator) { |
| | | if (value === undefined || value.length ===0) { |
| | | return "" |
| | | } |
| | | if (Array.isArray(value)) { |
| | | value = value.join(",") |
| | | } |
| | | var actions = [] |
| | | var currentSeparator = undefined === separator ? "," : separator |
| | | var temp = value.split(currentSeparator) |
| | | Object.keys(value.split(currentSeparator)).some((val) => { |
| | | var match = false |
| | | Object.keys(datas).some((key) => { |
| | | if (datas[key].value == ('' + temp[val])) { |
| | | actions.push(datas[key].label + currentSeparator) |
| | | match = true |
| | | } |
| | | }) |
| | | if (!match) { |
| | | actions.push(temp[val] + currentSeparator) |
| | | } |
| | | }) |
| | | return actions.join('').substring(0, actions.join('').length - 1) |
| | | } |
| | | |
| | | // 字符串格式化(%s ) |
| | | export function sprintf(str) { |
| | | var args = arguments, flag = true, i = 1 |
| | | str = str.replace(/%s/g, function () { |
| | | var arg = args[i++] |
| | | if (typeof arg === 'undefined') { |
| | | flag = false |
| | | return '' |
| | | } |
| | | return arg |
| | | }) |
| | | return flag ? str : '' |
| | | } |
| | | |
| | | // 转换字符串,undefined,null等转化为"" |
| | | export function parseStrEmpty(str) { |
| | | if (!str || str == "undefined" || str == "null") { |
| | | return "" |
| | | } |
| | | return str |
| | | } |
| | | |
| | | // 数据合并 |
| | | export function mergeRecursive(source, target) { |
| | | for (var p in target) { |
| | | try { |
| | | if (target[p].constructor == Object) { |
| | | source[p] = mergeRecursive(source[p], target[p]) |
| | | } else { |
| | | source[p] = target[p] |
| | | } |
| | | } catch (e) { |
| | | source[p] = target[p] |
| | | } |
| | | } |
| | | return source |
| | | } |
| | | |
| | | /** |
| | | * 构造树型结构数据 |
| | | * @param {*} data 数据源 |
| | | * @param {*} id id字段 默认 'id' |
| | | * @param {*} parentId 父节点字段 默认 'parentId' |
| | | * @param {*} children 孩子节点字段 默认 'children' |
| | | */ |
| | | export function handleTree(data, id, parentId, children) { |
| | | let config = { |
| | | id: id || 'id', |
| | | parentId: parentId || 'parentId', |
| | | childrenList: children || 'children' |
| | | } |
| | | |
| | | var childrenListMap = {} |
| | | var tree = [] |
| | | for (let d of data) { |
| | | let id = d[config.id] |
| | | childrenListMap[id] = d |
| | | if (!d[config.childrenList]) { |
| | | d[config.childrenList] = [] |
| | | } |
| | | } |
| | | |
| | | for (let d of data) { |
| | | let parentId = d[config.parentId] |
| | | let parentObj = childrenListMap[parentId] |
| | | if (!parentObj) { |
| | | tree.push(d) |
| | | } else { |
| | | parentObj[config.childrenList].push(d) |
| | | } |
| | | } |
| | | return tree |
| | | } |
| | | |
| | | /** |
| | | * 参数处理 |
| | | * @param {*} params 参数 |
| | | */ |
| | | export function tansParams(params) { |
| | | let result = '' |
| | | for (const propName of Object.keys(params)) { |
| | | const value = params[propName] |
| | | var part = encodeURIComponent(propName) + "=" |
| | | if (value !== null && value !== "" && typeof (value) !== "undefined") { |
| | | if (typeof value === 'object') { |
| | | for (const key of Object.keys(value)) { |
| | | if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') { |
| | | let params = propName + '[' + key + ']' |
| | | var subPart = encodeURIComponent(params) + "=" |
| | | result += subPart + encodeURIComponent(value[key]) + "&" |
| | | } |
| | | } |
| | | } else { |
| | | result += part + encodeURIComponent(value) + "&" |
| | | } |
| | | } |
| | | } |
| | | return result |
| | | } |
| | | |
| | | // 返回项目路径 |
| | | export function getNormalPath(p) { |
| | | if (p.length === 0 || !p || p == 'undefined') { |
| | | return p |
| | | } |
| | | let res = p.replace('//', '/') |
| | | if (res[res.length - 1] === '/') { |
| | | return res.slice(0, res.length - 1) |
| | | } |
| | | return res |
| | | } |
| | | |
| | | // 验证是否为blob格式 |
| | | export function blobValidate(data) { |
| | | return data.type !== 'application/json' |
| | | } |
New file |
| | |
| | | Math.easeInOutQuad = function(t, b, c, d) { |
| | | t /= d / 2 |
| | | if (t < 1) { |
| | | return c / 2 * t * t + b |
| | | } |
| | | t-- |
| | | return -c / 2 * (t * (t - 2) - 1) + b |
| | | } |
| | | |
| | | // requestAnimationFrame for Smart Animating http://goo.gl/sx5sts |
| | | var requestAnimFrame = (function() { |
| | | return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) } |
| | | })() |
| | | |
| | | /** |
| | | * Because it's so fucking difficult to detect the scrolling element, just move them all |
| | | * @param {number} amount |
| | | */ |
| | | function move(amount) { |
| | | document.documentElement.scrollTop = amount |
| | | document.body.parentNode.scrollTop = amount |
| | | document.body.scrollTop = amount |
| | | } |
| | | |
| | | function position() { |
| | | return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop |
| | | } |
| | | |
| | | /** |
| | | * @param {number} to |
| | | * @param {number} duration |
| | | * @param {Function} callback |
| | | */ |
| | | export function scrollTo(to, duration, callback) { |
| | | const start = position() |
| | | const change = to - start |
| | | const increment = 20 |
| | | let currentTime = 0 |
| | | duration = (typeof (duration) === 'undefined') ? 500 : duration |
| | | var animateScroll = function() { |
| | | // increment the time |
| | | currentTime += increment |
| | | // find the value with the quadratic in-out easing function |
| | | var val = Math.easeInOutQuad(currentTime, start, change, duration) |
| | | // move the document.body |
| | | move(val) |
| | | // do the animation unless its over |
| | | if (currentTime < duration) { |
| | | requestAnimFrame(animateScroll) |
| | | } else { |
| | | if (callback && typeof (callback) === 'function') { |
| | | // the animation is done so lets callback |
| | | callback() |
| | | } |
| | | } |
| | | } |
| | | animateScroll() |
| | | } |
New file |
| | |
| | | /** |
| | | * 路径匹配器 |
| | | * @param {string} pattern |
| | | * @param {string} path |
| | | * @returns {Boolean} |
| | | */ |
| | | export function isPathMatch(pattern, path) { |
| | | const regexPattern = pattern.replace(/\//g, '\\/').replace(/\*\*/g, '.*').replace(/\*/g, '[^\\/]*') |
| | | const regex = new RegExp(`^${regexPattern}$`) |
| | | return regex.test(path) |
| | | } |
| | | |
| | | /** |
| | | * 判断value字符串是否为空 |
| | | * @param {string} value |
| | | * @returns {Boolean} |
| | | */ |
| | | export function isEmpty(value) { |
| | | if (value == null || value == "" || value == undefined || value == "undefined") { |
| | | return true |
| | | } |
| | | return false |
| | | } |
| | | |
| | | /** |
| | | * 判断url是否是http或https |
| | | * @param {string} url |
| | | * @returns {Boolean} |
| | | */ |
| | | export function isHttp(url) { |
| | | return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1 |
| | | } |
| | | |
| | | /** |
| | | * 判断path是否为外链 |
| | | * @param {string} path |
| | | * @returns {Boolean} |
| | | */ |
| | | export function isExternal(path) { |
| | | return /^(https?:|mailto:|tel:)/.test(path) |
| | | } |
| | | |
| | | /** |
| | | * @param {string} str |
| | | * @returns {Boolean} |
| | | */ |
| | | export function validUsername(str) { |
| | | const valid_map = ['admin', 'editor'] |
| | | return valid_map.indexOf(str.trim()) >= 0 |
| | | } |
| | | |
| | | /** |
| | | * @param {string} url |
| | | * @returns {Boolean} |
| | | */ |
| | | export function validURL(url) { |
| | | const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ |
| | | return reg.test(url) |
| | | } |
| | | |
| | | /** |
| | | * @param {string} str |
| | | * @returns {Boolean} |
| | | */ |
| | | export function validLowerCase(str) { |
| | | const reg = /^[a-z]+$/ |
| | | return reg.test(str) |
| | | } |
| | | |
| | | /** |
| | | * @param {string} str |
| | | * @returns {Boolean} |
| | | */ |
| | | export function validUpperCase(str) { |
| | | const reg = /^[A-Z]+$/ |
| | | return reg.test(str) |
| | | } |
| | | |
| | | /** |
| | | * @param {string} str |
| | | * @returns {Boolean} |
| | | */ |
| | | export function validAlphabets(str) { |
| | | const reg = /^[A-Za-z]+$/ |
| | | return reg.test(str) |
| | | } |
| | | |
| | | /** |
| | | * @param {string} email |
| | | * @returns {Boolean} |
| | | */ |
| | | export function validEmail(email) { |
| | | const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ |
| | | return reg.test(email) |
| | | } |
| | | |
| | | /** |
| | | * @param {string} str |
| | | * @returns {Boolean} |
| | | */ |
| | | export function isString(str) { |
| | | return typeof str === 'string' || str instanceof String |
| | | } |
| | | |
| | | /** |
| | | * @param {Array} arg |
| | | * @returns {Boolean} |
| | | */ |
| | | export function isArray(arg) { |
| | | if (typeof Array.isArray === 'undefined') { |
| | | return Object.prototype.toString.call(arg) === '[object Array]' |
| | | } |
| | | return Array.isArray(arg) |
| | | } |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"> |
| | | <el-form-item label="用户名称" prop="userName"> |
| | | <el-input |
| | | v-model="queryParams.userName" |
| | | placeholder="请输入用户名称" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="手机号码" prop="phonenumber"> |
| | | <el-input |
| | | v-model="queryParams.phonenumber" |
| | | placeholder="请输入手机号码" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="el-icon-plus" |
| | | size="mini" |
| | | @click="openSelectUser" |
| | | v-hasPermi="['system:role:add']" |
| | | >给案卷分配录入员</el-button> |
| | | </el-col> |
| | | <!-- <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-circle-close" |
| | | size="mini" |
| | | :disabled="multiple" |
| | | @click="cancelAuthUserAll" |
| | | v-hasPermi="['system:role:remove']" |
| | | >批量取消授权</el-button> |
| | | </el-col> --> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-close" |
| | | size="mini" |
| | | @click="handleClose" |
| | | >关闭</el-button> |
| | | </el-col> |
| | | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="用户名称" prop="userName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="用户昵称" prop="nickName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="邮箱" prop="email" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="状态" align="center" prop="status"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-circle-close" |
| | | @click="cancelAuthUser(scope.row)" |
| | | v-hasPermi="['system:role:remove']" |
| | | >取消授权</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | <select-user ref="select" :roleId="queryParams.roleId" @ok="handleQuery" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import {UserRoleIdList, allocatedUserList, authUserCancel, authUserCancelAll } from "@/api/system/role" |
| | | import selectUser from "./seleUser" |
| | | |
| | | export default { |
| | | name: "AuthUser1", |
| | | dicts: ['sys_normal_disable'], |
| | | components: { selectUser }, |
| | | data() { |
| | | return { |
| | | // 遮罩层 |
| | | loading: true, |
| | | // 选中用户组 |
| | | userIds: [], |
| | | // 非多个禁用 |
| | | multiple: true, |
| | | // 显示搜索条件 |
| | | showSearch: true, |
| | | // 总条数 |
| | | total: 0, |
| | | // 用户表格数据 |
| | | userList: [], |
| | | // 查询参数 |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | roleId: undefined, |
| | | userName: undefined, |
| | | phonenumber: undefined |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | const roleId = this.$route.params && this.$route.params.roleId |
| | | if (roleId) { |
| | | this.queryParams.roleId = roleId |
| | | this.getList() |
| | | } |
| | | }, |
| | | methods: { |
| | | /** 查询授权用户列表 */ |
| | | getList() { |
| | | this.loading = true |
| | | console.log(this.queryParams) |
| | | console.log("------------") |
| | | UserRoleIdList(this.queryParams).then(response => { |
| | | this.userList = response.rows |
| | | this.total = response.total |
| | | this.loading = false |
| | | } |
| | | ) |
| | | }, |
| | | // 返回按钮 |
| | | handleClose() { |
| | | const obj = { path: "/system/role" } |
| | | this.$tab.closeOpenPage(obj) |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.resetForm("queryForm") |
| | | this.handleQuery() |
| | | }, |
| | | // 多选框选中数据 |
| | | handleSelectionChange(selection) { |
| | | this.userIds = selection.map(item => item.userId) |
| | | this.multiple = !selection.length |
| | | }, |
| | | /** 打开授权用户表弹窗 */ |
| | | openSelectUser() { |
| | | this.$refs.select.show() |
| | | }, |
| | | /** 取消授权按钮操作 */ |
| | | cancelAuthUser(row) { |
| | | const roleId = this.queryParams.roleId |
| | | this.$modal.confirm('确认要取消该用户"' + row.userName + '"角色吗?').then(function() { |
| | | return authUserCancel({ userId: row.userId, roleId: roleId }) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("取消授权成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 批量取消授权按钮操作 */ |
| | | cancelAuthUserAll(row) { |
| | | const roleId = this.queryParams.roleId |
| | | const userIds = this.userIds.join(",") |
| | | this.$modal.confirm('是否取消选中用户授权数据项?').then(function() { |
| | | return authUserCancelAll({ roleId: roleId, userIds: userIds }) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("取消授权成功") |
| | | }).catch(() => {}) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="档案号" prop="recordId"> |
| | | <el-input |
| | | v-model="queryParams.recordId" |
| | | placeholder="请输入档案号" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="发文号" prop="inquiryNumber"> |
| | | <el-input |
| | | v-model="queryParams.inquiryNumber" |
| | | placeholder="请输入发文号" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="案卷题名" prop="caseTitle"> |
| | | <el-input |
| | | v-model="queryParams.caseTitle" |
| | | placeholder="请输入案卷题名" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="公开属性" prop="publicAttribute"> |
| | | <el-input |
| | | v-model="queryParams.publicAttribute" |
| | | placeholder="请输入公开属性" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="编制单位" prop="preparationUnit"> |
| | | <el-input |
| | | v-model="queryParams.preparationUnit" |
| | | placeholder="请输入编制单位" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="编制日期" prop="preparationDate"> |
| | | <el-date-picker clearable |
| | | v-model="queryParams.preparationDate" |
| | | type="date" |
| | | value-format="yyyy-MM-dd" |
| | | placeholder="请选择编制日期"> |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item label="保管期限" prop="retentionPeriod"> |
| | | <el-input |
| | | v-model="queryParams.retentionPeriod" |
| | | placeholder="请输入保管期限" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="密级" prop="securityClassification"> |
| | | <el-input |
| | | v-model="queryParams.securityClassification" |
| | | placeholder="请输入密级" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="案卷页数" prop="pageCount"> |
| | | <el-input |
| | | v-model="queryParams.pageCount" |
| | | placeholder="请输入案卷页数" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="立案号" prop="filingNumber"> |
| | | <el-input |
| | | v-model="queryParams.filingNumber" |
| | | placeholder="请输入立案号" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="建设单位" prop="constructionUnit"> |
| | | <el-input |
| | | v-model="queryParams.constructionUnit" |
| | | placeholder="请输入建设单位" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="建设地址" prop="constructionAddress"> |
| | | <el-input |
| | | v-model="queryParams.constructionAddress" |
| | | placeholder="请输入建设地址" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="建设项目名称" prop="projectName"> |
| | | <el-input |
| | | v-model="queryParams.projectName" |
| | | placeholder="请输入建设项目名称" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="项目编号" prop="projectNumber"> |
| | | <el-input |
| | | v-model="queryParams.projectNumber" |
| | | placeholder="请输入项目编号" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="扫描加工公司" prop="scanningCompany"> |
| | | <el-input |
| | | v-model="queryParams.scanningCompany" |
| | | placeholder="请输入扫描加工公司" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="档案管(室)号" prop="archiveRoomNumber"> |
| | | <el-input |
| | | v-model="queryParams.archiveRoomNumber" |
| | | placeholder="请输入档案管(室)号" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="缩微号" prop="microfilmNumber"> |
| | | <el-input |
| | | v-model="queryParams.microfilmNumber" |
| | | placeholder="请输入缩微号" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="历史相关发文号" prop="historicalReferenceNumber"> |
| | | <el-input |
| | | v-model="queryParams.historicalReferenceNumber" |
| | | placeholder="请输入历史相关发文号" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="el-icon-plus" |
| | | size="mini" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:records:add']" |
| | | >新增</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="el-icon-edit" |
| | | size="mini" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['system:records:edit']" |
| | | >修改</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-delete" |
| | | size="mini" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['system:records:remove']" |
| | | >删除</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-download" |
| | | size="mini" |
| | | @click="handleExport" |
| | | v-hasPermi="['system:records:export']" |
| | | >导出</el-button> |
| | | </el-col> |
| | | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="recordsList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <!-- <el-table-column label="${comment}" align="center" prop="id" /> --> |
| | | <el-table-column label="档案号" align="center" prop="recordId" /> |
| | | <el-table-column label="发文号" align="center" prop="inquiryNumber" /> |
| | | <el-table-column label="案卷题名" align="center" prop="caseTitle" /> |
| | | <el-table-column label="公开属性" align="center" prop="publicAttribute" /> |
| | | <el-table-column label="编制单位" align="center" prop="preparationUnit" /> |
| | | <el-table-column label="编制日期" align="center" prop="preparationDate" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.preparationDate, '{y}-{m}-{d}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="保管期限" align="center" prop="retentionPeriod" /> |
| | | <el-table-column label="密级" align="center" prop="securityClassification" /> |
| | | <el-table-column label="案卷页数" align="center" prop="pageCount" /> |
| | | <el-table-column label="立案号" align="center" prop="filingNumber" /> |
| | | <el-table-column label="建设单位" align="center" prop="constructionUnit" /> |
| | | <el-table-column label="建设地址" align="center" prop="constructionAddress" /> |
| | | <el-table-column label="建设项目名称" align="center" prop="projectName" /> |
| | | <el-table-column label="项目编号" align="center" prop="projectNumber" /> |
| | | <el-table-column label="扫描加工公司" align="center" prop="scanningCompany" /> |
| | | <el-table-column label="档案管(室)号" align="center" prop="archiveRoomNumber" /> |
| | | <el-table-column label="缩微号" align="center" prop="microfilmNumber" /> |
| | | <el-table-column label="备注" align="center" prop="remarks" /> |
| | | <el-table-column label="历史相关发文号" align="center" prop="historicalReferenceNumber" /> |
| | | <el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | v-if="amio" |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleUpdate(scope.row)" |
| | | v-hasPermi="['system:records:edit']" |
| | | >案卷详细信息管理</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleUpdate(scope.row)" |
| | | v-hasPermi="['system:records:edit']" |
| | | >修改</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleDelete(scope.row)" |
| | | v-hasPermi="['system:records:remove']" |
| | | >删除</el-button> |
| | | <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)"> |
| | | <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button> |
| | | <el-dropdown-menu slot="dropdown"> |
| | | |
| | | <el-dropdown-item command="handleAuthUser" icon="el-icon-user" |
| | | >分配用户</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </el-dropdown> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- 添加或修改档案记录对话框 --> |
| | | <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body> |
| | | <el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="档案号" prop="recordId"> |
| | | <el-input v-model="form.recordId" placeholder="请输入档案号" /> |
| | | </el-form-item> |
| | | <el-form-item label="发文号" prop="inquiryNumber"> |
| | | <el-input v-model="form.inquiryNumber" placeholder="请输入发问号" /> |
| | | </el-form-item> |
| | | <div v-if="vis"> |
| | | <el-form-item label="案卷题名" prop="caseTitle"> |
| | | <el-input v-model="form.caseTitle" placeholder="请输入案卷题名" /> |
| | | </el-form-item> |
| | | <el-form-item label="公开属性" prop="publicAttribute"> |
| | | <el-input v-model="form.publicAttribute" placeholder="请输入公开属性" /> |
| | | </el-form-item> |
| | | <el-form-item label="编制单位" prop="preparationUnit"> |
| | | <el-input v-model="form.preparationUnit" placeholder="请输入编制单位" /> |
| | | </el-form-item> |
| | | <el-form-item label="编制日期" prop="preparationDate"> |
| | | <el-date-picker clearable |
| | | v-model="form.preparationDate" |
| | | type="date" |
| | | value-format="yyyy-MM-dd" |
| | | placeholder="请选择编制日期"> |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item label="保管期限" prop="retentionPeriod"> |
| | | <el-input v-model="form.retentionPeriod" placeholder="请输入保管期限" /> |
| | | </el-form-item> |
| | | <el-form-item label="密级" prop="securityClassification"> |
| | | <el-input v-model="form.securityClassification" placeholder="请输入密级" /> |
| | | </el-form-item> |
| | | <el-form-item label="案卷页数" prop="pageCount"> |
| | | <el-input v-model="form.pageCount" placeholder="请输入案卷页数" /> |
| | | </el-form-item> |
| | | <el-form-item label="立案号" prop="filingNumber"> |
| | | <el-input v-model="form.filingNumber" placeholder="请输入立案号" /> |
| | | </el-form-item> |
| | | <el-form-item label="建设单位" prop="constructionUnit"> |
| | | <el-input v-model="form.constructionUnit" placeholder="请输入建设单位" /> |
| | | </el-form-item> |
| | | <el-form-item label="建设地址" prop="constructionAddress"> |
| | | <el-input v-model="form.constructionAddress" placeholder="请输入建设地址" /> |
| | | </el-form-item> |
| | | <el-form-item label="建设项目名称" prop="projectName"> |
| | | <el-input v-model="form.projectName" placeholder="请输入建设项目名称" /> |
| | | </el-form-item> |
| | | <el-form-item label="项目编号" prop="projectNumber"> |
| | | <el-input v-model="form.projectNumber" placeholder="请输入项目编号" /> |
| | | </el-form-item> |
| | | <el-form-item label="扫描加工公司" prop="scanningCompany"> |
| | | <el-input v-model="form.scanningCompany" placeholder="请输入扫描加工公司" /> |
| | | </el-form-item> |
| | | <el-form-item label="档案管(室)号" prop="archiveRoomNumber"> |
| | | <el-input v-model="form.archiveRoomNumber" placeholder="请输入档案管(室)号" /> |
| | | </el-form-item> |
| | | <el-form-item label="缩微号" prop="microfilmNumber"> |
| | | <el-input v-model="form.microfilmNumber" placeholder="请输入缩微号" /> |
| | | </el-form-item> |
| | | <el-form-item label="备注" prop="remarks"> |
| | | <el-input v-model="form.remarks" type="textarea" placeholder="请输入内容" /> |
| | | </el-form-item> |
| | | <el-form-item label="历史相关发文号" prop="historicalReferenceNumber"> |
| | | <el-input v-model="form.historicalReferenceNumber" placeholder="请输入历史相关发文号" /> |
| | | </el-form-item> |
| | | </div> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确 定</el-button> |
| | | <el-button @click="cancel">取 消</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { listRecords, getRecords, delRecords, addRecords, updateRecords } from "@/api/system/records" |
| | | |
| | | export default { |
| | | name: "Records", |
| | | data() { |
| | | return { |
| | | amio: false, |
| | | vis: false, |
| | | // 遮罩层 |
| | | loading: true, |
| | | // 选中数组 |
| | | ids: [], |
| | | // 非单个禁用 |
| | | single: true, |
| | | // 非多个禁用 |
| | | multiple: true, |
| | | // 显示搜索条件 |
| | | showSearch: true, |
| | | // 总条数 |
| | | total: 0, |
| | | // 档案记录表格数据 |
| | | recordsList: [], |
| | | // 弹出层标题 |
| | | title: "", |
| | | // 是否显示弹出层 |
| | | open: false, |
| | | // 查询参数 |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | recordId: null, |
| | | inquiryNumber: null, |
| | | caseTitle: null, |
| | | publicAttribute: null, |
| | | preparationUnit: null, |
| | | preparationDate: null, |
| | | retentionPeriod: null, |
| | | securityClassification: null, |
| | | pageCount: null, |
| | | filingNumber: null, |
| | | constructionUnit: null, |
| | | constructionAddress: null, |
| | | projectName: null, |
| | | projectNumber: null, |
| | | scanningCompany: null, |
| | | archiveRoomNumber: null, |
| | | microfilmNumber: null, |
| | | remarks: null, |
| | | historicalReferenceNumber: null |
| | | }, |
| | | // 表单参数 |
| | | form: {}, |
| | | // 表单校验 |
| | | rules: { |
| | | recordId: [ |
| | | { required: true, message: "档案号不能为空", trigger: "blur" } |
| | | ], |
| | | inquiryNumber: [ |
| | | { required: true, message: "发问号不能为空", trigger: "blur" } |
| | | ], |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | }, |
| | | methods: { |
| | | /** 查询档案记录列表 */ |
| | | getList() { |
| | | this.loading = true |
| | | console.log(this.queryParams) |
| | | console.log("--------------") |
| | | listRecords(this.queryParams).then(response => { |
| | | |
| | | console.log(response) |
| | | this.recordsList = response.data.data |
| | | this.total = response.data.total |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | // 取消按钮 |
| | | cancel() { |
| | | this.open = false |
| | | this.reset() |
| | | }, |
| | | // 表单重置 |
| | | reset() { |
| | | this.form = { |
| | | id: null, |
| | | recordId: null, |
| | | inquiryNumber: null, |
| | | caseTitle: null, |
| | | publicAttribute: null, |
| | | preparationUnit: null, |
| | | preparationDate: null, |
| | | retentionPeriod: null, |
| | | securityClassification: null, |
| | | pageCount: null, |
| | | filingNumber: null, |
| | | constructionUnit: null, |
| | | constructionAddress: null, |
| | | projectName: null, |
| | | projectNumber: null, |
| | | scanningCompany: null, |
| | | archiveRoomNumber: null, |
| | | microfilmNumber: null, |
| | | remarks: null, |
| | | historicalReferenceNumber: null |
| | | } |
| | | this.resetForm("form") |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.resetForm("queryForm") |
| | | this.handleQuery() |
| | | }, |
| | | // 多选框选中数据 |
| | | handleSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.id) |
| | | this.single = selection.length!==1 |
| | | this.multiple = !selection.length |
| | | }, |
| | | /** 新增按钮操作 */ |
| | | handleAdd() { |
| | | this.reset() |
| | | this.open = true |
| | | this.vis = false; |
| | | this.title = "添加档案记录" |
| | | }, |
| | | /** 修改按钮操作 */ |
| | | handleUpdate(row) { |
| | | this.reset() |
| | | this.vis = true; |
| | | const id = row.id || this.ids |
| | | getRecords(id).then(response => { |
| | | console.log(response) |
| | | console.log("----=============--------------") |
| | | this.form = response.data |
| | | this.open = true |
| | | this.title = "修改档案记录" |
| | | }) |
| | | }, |
| | | /** 提交按钮 */ |
| | | submitForm() { |
| | | this.$refs["form"].validate(valid => { |
| | | if (valid) { |
| | | if (this.form.id != null) { |
| | | updateRecords(this.form).then(response => { |
| | | this.$modal.msgSuccess("修改成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } else { |
| | | addRecords(this.form).then(response => { |
| | | this.$modal.msgSuccess("新增成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | }, |
| | | // 更多操作触发 |
| | | handleCommand(command, row) { |
| | | switch (command) { |
| | | case "handleDataScope": |
| | | this.handleDataScope(row) |
| | | break |
| | | case "handleAuthUser": |
| | | this.handleAuthUser(row) |
| | | break |
| | | default: |
| | | break |
| | | } |
| | | }, |
| | | /** 分配用户操作 */ |
| | | handleAuthUser: function(row) { |
| | | const roleId = 2 |
| | | alert(roleId) |
| | | this.$router.push("/archiveManager/infoManagerAu/user/" + roleId) |
| | | }, |
| | | /** 删除按钮操作 */ |
| | | handleDelete(row) { |
| | | const ids = row.id || this.ids |
| | | this.$modal.confirm('是否确认删除档案记录编号为"' + ids + '"的数据项?').then(function() { |
| | | return delRecords(ids) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("删除成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 导出按钮操作 */ |
| | | handleExport() { |
| | | this.download('system/records/export', { |
| | | ...this.queryParams |
| | | }, `records_${new Date().getTime()}.xlsx`) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <!-- 授权用户 --> |
| | | <el-dialog title="选择用户" :visible.sync="visible" width="800px" top="5vh" append-to-body> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true"> |
| | | <el-form-item label="用户名称" prop="userName"> |
| | | <el-input |
| | | v-model="queryParams.userName" |
| | | placeholder="请输入用户名称" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="手机号码" prop="phonenumber"> |
| | | <el-input |
| | | v-model="queryParams.phonenumber" |
| | | placeholder="请输入手机号码" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-row> |
| | | <el-table @row-click="clickRow" ref="table" :data="userList" @selection-change="handleSelectionChange" height="260px"> |
| | | <el-table-column type="selection" width="55"></el-table-column> |
| | | <el-table-column label="用户名称" prop="userName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="用户昵称" prop="nickName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="邮箱" prop="email" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="手机" prop="phonenumber" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="状态" align="center" prop="status"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | </el-row> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSelectUser">确 定</el-button> |
| | | <el-button @click="visible = false">取 消</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script> |
| | | import { UserRoleIdList,unallocatedUserList, authUserSelectAll } from "@/api/system/role" |
| | | export default { |
| | | dicts: ['sys_normal_disable'], |
| | | props: { |
| | | // 角色编号 |
| | | roleId: { |
| | | type: [Number, String] |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | // 遮罩层 |
| | | visible: false, |
| | | // 选中数组值 |
| | | userIds: [], |
| | | // 总条数 |
| | | total: 0, |
| | | // 未授权用户数据 |
| | | userList: [], |
| | | // 查询参数 |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | roleId: undefined, |
| | | userName: undefined, |
| | | phonenumber: undefined |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | // 显示弹框 |
| | | show() { |
| | | this.queryParams.roleId = this.roleId |
| | | this.getList() |
| | | this.visible = true |
| | | }, |
| | | clickRow(row) { |
| | | this.$refs.table.toggleRowSelection(row) |
| | | }, |
| | | // 多选框选中数据 |
| | | handleSelectionChange(selection) { |
| | | this.userIds = selection.map(item => item.userId) |
| | | }, |
| | | // 查询表数据 |
| | | getList() { |
| | | UserRoleIdList(this.queryParams).then(res => { |
| | | this.userList = res.rows |
| | | this.total = res.total |
| | | }) |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.resetForm("queryForm") |
| | | this.handleQuery() |
| | | }, |
| | | /** 选择授权用户操作 */ |
| | | handleSelectUser() { |
| | | const roleId = this.queryParams.roleId |
| | | const userIds = this.userIds.join(",") |
| | | if (userIds == "") { |
| | | this.$modal.msgError("请选择要分配的用户") |
| | | return |
| | | } |
| | | authUserSelectAll({ roleId: roleId, userIds: userIds }).then(res => { |
| | | this.$modal.msgSuccess(res.msg) |
| | | this.visible = false |
| | | this.$emit("ok") |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div :class="className" :style="{height:height,width:width}" /> |
| | | </template> |
| | | |
| | | <script> |
| | | import * as echarts from 'echarts' |
| | | require('echarts/theme/macarons') // echarts theme |
| | | import resize from './mixins/resize' |
| | | |
| | | const animationDuration = 6000 |
| | | |
| | | export default { |
| | | mixins: [resize], |
| | | props: { |
| | | className: { |
| | | type: String, |
| | | default: 'chart' |
| | | }, |
| | | width: { |
| | | type: String, |
| | | default: '100%' |
| | | }, |
| | | height: { |
| | | type: String, |
| | | default: '300px' |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | chart: null |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.$nextTick(() => { |
| | | this.initChart() |
| | | }) |
| | | }, |
| | | beforeDestroy() { |
| | | if (!this.chart) { |
| | | return |
| | | } |
| | | this.chart.dispose() |
| | | this.chart = null |
| | | }, |
| | | methods: { |
| | | initChart() { |
| | | this.chart = echarts.init(this.$el, 'macarons') |
| | | |
| | | this.chart.setOption({ |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { // 坐标轴指示器,坐标轴触发有效 |
| | | type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' |
| | | } |
| | | }, |
| | | grid: { |
| | | top: 10, |
| | | left: '2%', |
| | | right: '2%', |
| | | bottom: '3%', |
| | | containLabel: true |
| | | }, |
| | | xAxis: [{ |
| | | type: 'category', |
| | | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], |
| | | axisTick: { |
| | | alignWithLabel: true |
| | | } |
| | | }], |
| | | yAxis: [{ |
| | | type: 'value', |
| | | axisTick: { |
| | | show: false |
| | | } |
| | | }], |
| | | series: [{ |
| | | name: 'pageA', |
| | | type: 'bar', |
| | | stack: 'vistors', |
| | | barWidth: '60%', |
| | | data: [79, 52, 200, 334, 390, 330, 220], |
| | | animationDuration |
| | | }, { |
| | | name: 'pageB', |
| | | type: 'bar', |
| | | stack: 'vistors', |
| | | barWidth: '60%', |
| | | data: [80, 52, 200, 334, 390, 330, 220], |
| | | animationDuration |
| | | }, { |
| | | name: 'pageC', |
| | | type: 'bar', |
| | | stack: 'vistors', |
| | | barWidth: '60%', |
| | | data: [30, 52, 200, 334, 390, 330, 220], |
| | | animationDuration |
| | | }] |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div :class="className" :style="{height:height,width:width}" /> |
| | | </template> |
| | | |
| | | <script> |
| | | import * as echarts from 'echarts' |
| | | require('echarts/theme/macarons') // echarts theme |
| | | import resize from './mixins/resize' |
| | | |
| | | export default { |
| | | mixins: [resize], |
| | | props: { |
| | | className: { |
| | | type: String, |
| | | default: 'chart' |
| | | }, |
| | | width: { |
| | | type: String, |
| | | default: '100%' |
| | | }, |
| | | height: { |
| | | type: String, |
| | | default: '350px' |
| | | }, |
| | | autoResize: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | chartData: { |
| | | type: Object, |
| | | required: true |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | chart: null |
| | | } |
| | | }, |
| | | watch: { |
| | | chartData: { |
| | | deep: true, |
| | | handler(val) { |
| | | this.setOptions(val) |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.$nextTick(() => { |
| | | this.initChart() |
| | | }) |
| | | }, |
| | | beforeDestroy() { |
| | | if (!this.chart) { |
| | | return |
| | | } |
| | | this.chart.dispose() |
| | | this.chart = null |
| | | }, |
| | | methods: { |
| | | initChart() { |
| | | this.chart = echarts.init(this.$el, 'macarons') |
| | | this.setOptions(this.chartData) |
| | | }, |
| | | setOptions({ expectedData, actualData } = {}) { |
| | | this.chart.setOption({ |
| | | xAxis: { |
| | | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], |
| | | boundaryGap: false, |
| | | axisTick: { |
| | | show: false |
| | | } |
| | | }, |
| | | grid: { |
| | | left: 10, |
| | | right: 10, |
| | | bottom: 20, |
| | | top: 30, |
| | | containLabel: true |
| | | }, |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { |
| | | type: 'cross' |
| | | }, |
| | | padding: [5, 10] |
| | | }, |
| | | yAxis: { |
| | | axisTick: { |
| | | show: false |
| | | } |
| | | }, |
| | | legend: { |
| | | data: ['expected', 'actual'] |
| | | }, |
| | | series: [{ |
| | | name: 'expected', itemStyle: { |
| | | normal: { |
| | | color: '#FF005A', |
| | | lineStyle: { |
| | | color: '#FF005A', |
| | | width: 2 |
| | | } |
| | | } |
| | | }, |
| | | smooth: true, |
| | | type: 'line', |
| | | data: expectedData, |
| | | animationDuration: 2800, |
| | | animationEasing: 'cubicInOut' |
| | | }, |
| | | { |
| | | name: 'actual', |
| | | smooth: true, |
| | | type: 'line', |
| | | itemStyle: { |
| | | normal: { |
| | | color: '#3888fa', |
| | | lineStyle: { |
| | | color: '#3888fa', |
| | | width: 2 |
| | | }, |
| | | areaStyle: { |
| | | color: '#f3f8ff' |
| | | } |
| | | } |
| | | }, |
| | | data: actualData, |
| | | animationDuration: 2800, |
| | | animationEasing: 'quadraticOut' |
| | | }] |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <el-row :gutter="40" class="panel-group"> |
| | | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> |
| | | <div class="card-panel" @click="handleSetLineChartData('newVisitis')"> |
| | | <div class="card-panel-icon-wrapper icon-people"> |
| | | <svg-icon icon-class="peoples" class-name="card-panel-icon" /> |
| | | </div> |
| | | <div class="card-panel-description"> |
| | | <div class="card-panel-text"> |
| | | 访客 |
| | | </div> |
| | | <count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" /> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> |
| | | <div class="card-panel" @click="handleSetLineChartData('messages')"> |
| | | <div class="card-panel-icon-wrapper icon-message"> |
| | | <svg-icon icon-class="message" class-name="card-panel-icon" /> |
| | | </div> |
| | | <div class="card-panel-description"> |
| | | <div class="card-panel-text"> |
| | | 消息 |
| | | </div> |
| | | <count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" /> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> |
| | | <div class="card-panel" @click="handleSetLineChartData('purchases')"> |
| | | <div class="card-panel-icon-wrapper icon-money"> |
| | | <svg-icon icon-class="money" class-name="card-panel-icon" /> |
| | | </div> |
| | | <div class="card-panel-description"> |
| | | <div class="card-panel-text"> |
| | | 金额 |
| | | </div> |
| | | <count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" /> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> |
| | | <div class="card-panel" @click="handleSetLineChartData('shoppings')"> |
| | | <div class="card-panel-icon-wrapper icon-shopping"> |
| | | <svg-icon icon-class="shopping" class-name="card-panel-icon" /> |
| | | </div> |
| | | <div class="card-panel-description"> |
| | | <div class="card-panel-text"> |
| | | 订单 |
| | | </div> |
| | | <count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" /> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <script> |
| | | import CountTo from 'vue-count-to' |
| | | |
| | | export default { |
| | | components: { |
| | | CountTo |
| | | }, |
| | | methods: { |
| | | handleSetLineChartData(type) { |
| | | this.$emit('handleSetLineChartData', type) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .panel-group { |
| | | margin-top: 18px; |
| | | |
| | | .card-panel-col { |
| | | margin-bottom: 32px; |
| | | } |
| | | |
| | | .card-panel { |
| | | height: 108px; |
| | | cursor: pointer; |
| | | font-size: 12px; |
| | | position: relative; |
| | | overflow: hidden; |
| | | color: #666; |
| | | background: #fff; |
| | | box-shadow: 4px 4px 40px rgba(0, 0, 0, .05); |
| | | border-color: rgba(0, 0, 0, .05); |
| | | |
| | | &:hover { |
| | | .card-panel-icon-wrapper { |
| | | color: #fff; |
| | | } |
| | | |
| | | .icon-people { |
| | | background: #40c9c6; |
| | | } |
| | | |
| | | .icon-message { |
| | | background: #36a3f7; |
| | | } |
| | | |
| | | .icon-money { |
| | | background: #f4516c; |
| | | } |
| | | |
| | | .icon-shopping { |
| | | background: #34bfa3 |
| | | } |
| | | } |
| | | |
| | | .icon-people { |
| | | color: #40c9c6; |
| | | } |
| | | |
| | | .icon-message { |
| | | color: #36a3f7; |
| | | } |
| | | |
| | | .icon-money { |
| | | color: #f4516c; |
| | | } |
| | | |
| | | .icon-shopping { |
| | | color: #34bfa3 |
| | | } |
| | | |
| | | .card-panel-icon-wrapper { |
| | | float: left; |
| | | margin: 14px 0 0 14px; |
| | | padding: 16px; |
| | | transition: all 0.38s ease-out; |
| | | border-radius: 6px; |
| | | } |
| | | |
| | | .card-panel-icon { |
| | | float: left; |
| | | font-size: 48px; |
| | | } |
| | | |
| | | .card-panel-description { |
| | | float: right; |
| | | font-weight: bold; |
| | | margin: 26px; |
| | | margin-left: 0px; |
| | | |
| | | .card-panel-text { |
| | | line-height: 18px; |
| | | color: rgba(0, 0, 0, 0.45); |
| | | font-size: 16px; |
| | | margin-bottom: 12px; |
| | | } |
| | | |
| | | .card-panel-num { |
| | | font-size: 20px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | @media (max-width:550px) { |
| | | .card-panel-description { |
| | | display: none; |
| | | } |
| | | |
| | | .card-panel-icon-wrapper { |
| | | float: none !important; |
| | | width: 100%; |
| | | height: 100%; |
| | | margin: 0 !important; |
| | | |
| | | .svg-icon { |
| | | display: block; |
| | | margin: 14px auto !important; |
| | | float: none !important; |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div :class="className" :style="{height:height,width:width}" /> |
| | | </template> |
| | | |
| | | <script> |
| | | import * as echarts from 'echarts' |
| | | require('echarts/theme/macarons') // echarts theme |
| | | import resize from './mixins/resize' |
| | | |
| | | export default { |
| | | mixins: [resize], |
| | | props: { |
| | | className: { |
| | | type: String, |
| | | default: 'chart' |
| | | }, |
| | | width: { |
| | | type: String, |
| | | default: '100%' |
| | | }, |
| | | height: { |
| | | type: String, |
| | | default: '300px' |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | chart: null |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.$nextTick(() => { |
| | | this.initChart() |
| | | }) |
| | | }, |
| | | beforeDestroy() { |
| | | if (!this.chart) { |
| | | return |
| | | } |
| | | this.chart.dispose() |
| | | this.chart = null |
| | | }, |
| | | methods: { |
| | | initChart() { |
| | | this.chart = echarts.init(this.$el, 'macarons') |
| | | |
| | | this.chart.setOption({ |
| | | tooltip: { |
| | | trigger: 'item', |
| | | formatter: '{a} <br/>{b} : {c} ({d}%)' |
| | | }, |
| | | legend: { |
| | | left: 'center', |
| | | bottom: '10', |
| | | data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts'] |
| | | }, |
| | | series: [ |
| | | { |
| | | name: 'WEEKLY WRITE ARTICLES', |
| | | type: 'pie', |
| | | roseType: 'radius', |
| | | radius: [15, 95], |
| | | center: ['50%', '38%'], |
| | | data: [ |
| | | { value: 320, name: 'Industries' }, |
| | | { value: 240, name: 'Technology' }, |
| | | { value: 149, name: 'Forex' }, |
| | | { value: 100, name: 'Gold' }, |
| | | { value: 59, name: 'Forecasts' } |
| | | ], |
| | | animationEasing: 'cubicInOut', |
| | | animationDuration: 2600 |
| | | } |
| | | ] |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div :class="className" :style="{height:height,width:width}" /> |
| | | </template> |
| | | |
| | | <script> |
| | | import * as echarts from 'echarts' |
| | | require('echarts/theme/macarons') // echarts theme |
| | | import resize from './mixins/resize' |
| | | |
| | | const animationDuration = 3000 |
| | | |
| | | export default { |
| | | mixins: [resize], |
| | | props: { |
| | | className: { |
| | | type: String, |
| | | default: 'chart' |
| | | }, |
| | | width: { |
| | | type: String, |
| | | default: '100%' |
| | | }, |
| | | height: { |
| | | type: String, |
| | | default: '300px' |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | chart: null |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.$nextTick(() => { |
| | | this.initChart() |
| | | }) |
| | | }, |
| | | beforeDestroy() { |
| | | if (!this.chart) { |
| | | return |
| | | } |
| | | this.chart.dispose() |
| | | this.chart = null |
| | | }, |
| | | methods: { |
| | | initChart() { |
| | | this.chart = echarts.init(this.$el, 'macarons') |
| | | |
| | | this.chart.setOption({ |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | axisPointer: { // 坐标轴指示器,坐标轴触发有效 |
| | | type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' |
| | | } |
| | | }, |
| | | radar: { |
| | | radius: '66%', |
| | | center: ['50%', '42%'], |
| | | splitNumber: 8, |
| | | splitArea: { |
| | | areaStyle: { |
| | | color: 'rgba(127,95,132,.3)', |
| | | opacity: 1, |
| | | shadowBlur: 45, |
| | | shadowColor: 'rgba(0,0,0,.5)', |
| | | shadowOffsetX: 0, |
| | | shadowOffsetY: 15 |
| | | } |
| | | }, |
| | | indicator: [ |
| | | { name: 'Sales', max: 10000 }, |
| | | { name: 'Administration', max: 20000 }, |
| | | { name: 'Information Techology', max: 20000 }, |
| | | { name: 'Customer Support', max: 20000 }, |
| | | { name: 'Development', max: 20000 }, |
| | | { name: 'Marketing', max: 20000 } |
| | | ] |
| | | }, |
| | | legend: { |
| | | left: 'center', |
| | | bottom: '10', |
| | | data: ['Allocated Budget', 'Expected Spending', 'Actual Spending'] |
| | | }, |
| | | series: [{ |
| | | type: 'radar', |
| | | symbolSize: 0, |
| | | areaStyle: { |
| | | normal: { |
| | | shadowBlur: 13, |
| | | shadowColor: 'rgba(0,0,0,.2)', |
| | | shadowOffsetX: 0, |
| | | shadowOffsetY: 10, |
| | | opacity: 1 |
| | | } |
| | | }, |
| | | data: [ |
| | | { |
| | | value: [5000, 7000, 12000, 11000, 15000, 14000], |
| | | name: 'Allocated Budget' |
| | | }, |
| | | { |
| | | value: [4000, 9000, 15000, 15000, 13000, 11000], |
| | | name: 'Expected Spending' |
| | | }, |
| | | { |
| | | value: [5500, 11000, 12000, 15000, 12000, 12000], |
| | | name: 'Actual Spending' |
| | | } |
| | | ], |
| | | animationDuration: animationDuration |
| | | }] |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | import { debounce } from '@/utils' |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | $_sidebarElm: null, |
| | | $_resizeHandler: null |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.initListener() |
| | | }, |
| | | activated() { |
| | | if (!this.$_resizeHandler) { |
| | | // avoid duplication init |
| | | this.initListener() |
| | | } |
| | | |
| | | // when keep-alive chart activated, auto resize |
| | | this.resize() |
| | | }, |
| | | beforeDestroy() { |
| | | this.destroyListener() |
| | | }, |
| | | deactivated() { |
| | | this.destroyListener() |
| | | }, |
| | | methods: { |
| | | // use $_ for mixins properties |
| | | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential |
| | | $_sidebarResizeHandler(e) { |
| | | if (e.propertyName === 'width') { |
| | | this.$_resizeHandler() |
| | | } |
| | | }, |
| | | initListener() { |
| | | this.$_resizeHandler = debounce(() => { |
| | | this.resize() |
| | | }, 100) |
| | | window.addEventListener('resize', this.$_resizeHandler) |
| | | |
| | | this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0] |
| | | this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler) |
| | | }, |
| | | destroyListener() { |
| | | window.removeEventListener('resize', this.$_resizeHandler) |
| | | this.$_resizeHandler = null |
| | | |
| | | this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler) |
| | | }, |
| | | resize() { |
| | | const { chart } = this |
| | | chart && chart.resize() |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | <template> |
| | | <div class="errPage-container"> |
| | | <el-button icon="arrow-left" class="pan-back-btn" @click="back"> |
| | | 返回 |
| | | </el-button> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <h1 class="text-jumbo text-ginormous"> |
| | | 401错误! |
| | | </h1> |
| | | <h2>您没有访问权限!</h2> |
| | | <h6>对不起,您没有访问权限,请不要进行非法操作!您可以返回主页面</h6> |
| | | <ul class="list-unstyled"> |
| | | <li class="link-type"> |
| | | <router-link to="/"> |
| | | 回首页 |
| | | </router-link> |
| | | </li> |
| | | </ul> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <img :src="errGif" width="313" height="428" alt="Girl has dropped her ice cream."> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import errGif from '@/assets/401_images/401.gif' |
| | | |
| | | export default { |
| | | name: 'Page401', |
| | | data() { |
| | | return { |
| | | errGif: errGif + '?' + +new Date() |
| | | } |
| | | }, |
| | | methods: { |
| | | back() { |
| | | if (this.$route.query.noGoBack) { |
| | | this.$router.push({ path: '/' }) |
| | | } else { |
| | | this.$router.go(-1) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .errPage-container { |
| | | width: 800px; |
| | | max-width: 100%; |
| | | margin: 100px auto; |
| | | .pan-back-btn { |
| | | background: #008489; |
| | | color: #fff; |
| | | border: none!important; |
| | | } |
| | | .pan-gif { |
| | | margin: 0 auto; |
| | | display: block; |
| | | } |
| | | .pan-img { |
| | | display: block; |
| | | margin: 0 auto; |
| | | width: 100%; |
| | | } |
| | | .text-jumbo { |
| | | font-size: 60px; |
| | | font-weight: 700; |
| | | color: #484848; |
| | | } |
| | | .list-unstyled { |
| | | font-size: 14px; |
| | | li { |
| | | padding-bottom: 5px; |
| | | } |
| | | a { |
| | | color: #008489; |
| | | text-decoration: none; |
| | | &:hover { |
| | | text-decoration: underline; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="wscn-http404-container"> |
| | | <div class="wscn-http404"> |
| | | <div class="pic-404"> |
| | | <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404"> |
| | | <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404"> |
| | | <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404"> |
| | | <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404"> |
| | | </div> |
| | | <div class="bullshit"> |
| | | <div class="bullshit__oops"> |
| | | 404错误! |
| | | </div> |
| | | <div class="bullshit__headline"> |
| | | {{ message }} |
| | | </div> |
| | | <div class="bullshit__info"> |
| | | 对不起,您正在寻找的页面不存在。尝试检查URL的错误,然后按浏览器上的刷新按钮或尝试在我们的应用程序中找到其他内容。 |
| | | </div> |
| | | <router-link to="/" class="bullshit__return-home"> |
| | | 返回首页 |
| | | </router-link> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | |
| | | export default { |
| | | name: 'Page404', |
| | | computed: { |
| | | message() { |
| | | return '找不到网页!' |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .wscn-http404-container{ |
| | | transform: translate(-50%,-50%); |
| | | position: absolute; |
| | | top: 40%; |
| | | left: 50%; |
| | | } |
| | | .wscn-http404 { |
| | | position: relative; |
| | | width: 1200px; |
| | | padding: 0 50px; |
| | | overflow: hidden; |
| | | .pic-404 { |
| | | position: relative; |
| | | float: left; |
| | | width: 600px; |
| | | overflow: hidden; |
| | | &__parent { |
| | | width: 100%; |
| | | } |
| | | &__child { |
| | | position: absolute; |
| | | &.left { |
| | | width: 80px; |
| | | top: 17px; |
| | | left: 220px; |
| | | opacity: 0; |
| | | animation-name: cloudLeft; |
| | | animation-duration: 2s; |
| | | animation-timing-function: linear; |
| | | animation-fill-mode: forwards; |
| | | animation-delay: 1s; |
| | | } |
| | | &.mid { |
| | | width: 46px; |
| | | top: 10px; |
| | | left: 420px; |
| | | opacity: 0; |
| | | animation-name: cloudMid; |
| | | animation-duration: 2s; |
| | | animation-timing-function: linear; |
| | | animation-fill-mode: forwards; |
| | | animation-delay: 1.2s; |
| | | } |
| | | &.right { |
| | | width: 62px; |
| | | top: 100px; |
| | | left: 500px; |
| | | opacity: 0; |
| | | animation-name: cloudRight; |
| | | animation-duration: 2s; |
| | | animation-timing-function: linear; |
| | | animation-fill-mode: forwards; |
| | | animation-delay: 1s; |
| | | } |
| | | @keyframes cloudLeft { |
| | | 0% { |
| | | top: 17px; |
| | | left: 220px; |
| | | opacity: 0; |
| | | } |
| | | 20% { |
| | | top: 33px; |
| | | left: 188px; |
| | | opacity: 1; |
| | | } |
| | | 80% { |
| | | top: 81px; |
| | | left: 92px; |
| | | opacity: 1; |
| | | } |
| | | 100% { |
| | | top: 97px; |
| | | left: 60px; |
| | | opacity: 0; |
| | | } |
| | | } |
| | | @keyframes cloudMid { |
| | | 0% { |
| | | top: 10px; |
| | | left: 420px; |
| | | opacity: 0; |
| | | } |
| | | 20% { |
| | | top: 40px; |
| | | left: 360px; |
| | | opacity: 1; |
| | | } |
| | | 70% { |
| | | top: 130px; |
| | | left: 180px; |
| | | opacity: 1; |
| | | } |
| | | 100% { |
| | | top: 160px; |
| | | left: 120px; |
| | | opacity: 0; |
| | | } |
| | | } |
| | | @keyframes cloudRight { |
| | | 0% { |
| | | top: 100px; |
| | | left: 500px; |
| | | opacity: 0; |
| | | } |
| | | 20% { |
| | | top: 120px; |
| | | left: 460px; |
| | | opacity: 1; |
| | | } |
| | | 80% { |
| | | top: 180px; |
| | | left: 340px; |
| | | opacity: 1; |
| | | } |
| | | 100% { |
| | | top: 200px; |
| | | left: 300px; |
| | | opacity: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | .bullshit { |
| | | position: relative; |
| | | float: left; |
| | | width: 300px; |
| | | padding: 30px 0; |
| | | overflow: hidden; |
| | | &__oops { |
| | | font-size: 32px; |
| | | font-weight: bold; |
| | | line-height: 40px; |
| | | color: #1482f0; |
| | | opacity: 0; |
| | | margin-bottom: 20px; |
| | | animation-name: slideUp; |
| | | animation-duration: 0.5s; |
| | | animation-fill-mode: forwards; |
| | | } |
| | | &__headline { |
| | | font-size: 20px; |
| | | line-height: 24px; |
| | | color: #222; |
| | | font-weight: bold; |
| | | opacity: 0; |
| | | margin-bottom: 10px; |
| | | animation-name: slideUp; |
| | | animation-duration: 0.5s; |
| | | animation-delay: 0.1s; |
| | | animation-fill-mode: forwards; |
| | | } |
| | | &__info { |
| | | font-size: 13px; |
| | | line-height: 21px; |
| | | color: grey; |
| | | opacity: 0; |
| | | margin-bottom: 30px; |
| | | animation-name: slideUp; |
| | | animation-duration: 0.5s; |
| | | animation-delay: 0.2s; |
| | | animation-fill-mode: forwards; |
| | | } |
| | | &__return-home { |
| | | display: block; |
| | | float: left; |
| | | width: 110px; |
| | | height: 36px; |
| | | background: #1482f0; |
| | | border-radius: 100px; |
| | | text-align: center; |
| | | color: #ffffff; |
| | | opacity: 0; |
| | | font-size: 14px; |
| | | line-height: 36px; |
| | | cursor: pointer; |
| | | animation-name: slideUp; |
| | | animation-duration: 0.5s; |
| | | animation-delay: 0.3s; |
| | | animation-fill-mode: forwards; |
| | | } |
| | | @keyframes slideUp { |
| | | 0% { |
| | | transform: translateY(60px); |
| | | opacity: 0; |
| | | } |
| | | 100% { |
| | | transform: translateY(0); |
| | | opacity: 1; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="app-container home"> |
| | | |
| | | |
| | | <h1>档案管理系统</h1> |
| | | |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: "Index", |
| | | data() { |
| | | return { |
| | | // 版本号 |
| | | version: "3.9.0" |
| | | } |
| | | }, |
| | | methods: { |
| | | goTarget(href) { |
| | | window.open(href, "_blank") |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .home { |
| | | blockquote { |
| | | padding: 10px 20px; |
| | | margin: 0 0 20px; |
| | | font-size: 17.5px; |
| | | border-left: 5px solid #eee; |
| | | } |
| | | hr { |
| | | margin-top: 20px; |
| | | margin-bottom: 20px; |
| | | border: 0; |
| | | border-top: 1px solid #eee; |
| | | } |
| | | .col-item { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | ul { |
| | | padding: 0; |
| | | margin: 0; |
| | | } |
| | | |
| | | font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif; |
| | | font-size: 13px; |
| | | color: #676a6c; |
| | | overflow-x: hidden; |
| | | |
| | | ul { |
| | | list-style-type: none; |
| | | } |
| | | |
| | | h4 { |
| | | margin-top: 0px; |
| | | } |
| | | |
| | | h2 { |
| | | margin-top: 10px; |
| | | font-size: 26px; |
| | | font-weight: 100; |
| | | } |
| | | |
| | | p { |
| | | margin-top: 10px; |
| | | |
| | | b { |
| | | font-weight: 700; |
| | | } |
| | | } |
| | | |
| | | .update-log { |
| | | ol { |
| | | display: block; |
| | | list-style-type: decimal; |
| | | margin-block-start: 1em; |
| | | margin-block-end: 1em; |
| | | margin-inline-start: 0; |
| | | margin-inline-end: 0; |
| | | padding-inline-start: 40px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | | |
New file |
| | |
| | | <template> |
| | | <div class="dashboard-editor-container"> |
| | | |
| | | <panel-group @handleSetLineChartData="handleSetLineChartData" /> |
| | | |
| | | <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;"> |
| | | <line-chart :chart-data="lineChartData" /> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="32"> |
| | | <el-col :xs="24" :sm="24" :lg="8"> |
| | | <div class="chart-wrapper"> |
| | | <raddar-chart /> |
| | | </div> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="24" :lg="8"> |
| | | <div class="chart-wrapper"> |
| | | <pie-chart /> |
| | | </div> |
| | | </el-col> |
| | | <el-col :xs="24" :sm="24" :lg="8"> |
| | | <div class="chart-wrapper"> |
| | | <bar-chart /> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import PanelGroup from './dashboard/PanelGroup' |
| | | import LineChart from './dashboard/LineChart' |
| | | import RaddarChart from './dashboard/RaddarChart' |
| | | import PieChart from './dashboard/PieChart' |
| | | import BarChart from './dashboard/BarChart' |
| | | |
| | | const lineChartData = { |
| | | newVisitis: { |
| | | expectedData: [100, 120, 161, 134, 105, 160, 165], |
| | | actualData: [120, 82, 91, 154, 162, 140, 145] |
| | | }, |
| | | messages: { |
| | | expectedData: [200, 192, 120, 144, 160, 130, 140], |
| | | actualData: [180, 160, 151, 106, 145, 150, 130] |
| | | }, |
| | | purchases: { |
| | | expectedData: [80, 100, 121, 104, 105, 90, 100], |
| | | actualData: [120, 90, 100, 138, 142, 130, 130] |
| | | }, |
| | | shoppings: { |
| | | expectedData: [130, 140, 141, 142, 145, 150, 160], |
| | | actualData: [120, 82, 91, 154, 162, 140, 130] |
| | | } |
| | | } |
| | | |
| | | export default { |
| | | name: 'Index', |
| | | components: { |
| | | PanelGroup, |
| | | LineChart, |
| | | RaddarChart, |
| | | PieChart, |
| | | BarChart |
| | | }, |
| | | data() { |
| | | return { |
| | | lineChartData: lineChartData.newVisitis |
| | | } |
| | | }, |
| | | methods: { |
| | | handleSetLineChartData(type) { |
| | | this.lineChartData = lineChartData[type] |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .dashboard-editor-container { |
| | | padding: 32px; |
| | | background-color: rgb(240, 242, 245); |
| | | position: relative; |
| | | |
| | | .chart-wrapper { |
| | | background: #fff; |
| | | padding: 16px 16px 0; |
| | | margin-bottom: 32px; |
| | | } |
| | | } |
| | | |
| | | @media (max-width:1024px) { |
| | | .chart-wrapper { |
| | | padding: 8px; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="login"> |
| | | <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> |
| | | <h3 class="title">{{title}}</h3> |
| | | <el-form-item prop="username"> |
| | | <el-input |
| | | v-model="loginForm.username" |
| | | type="text" |
| | | auto-complete="off" |
| | | placeholder="账号" |
| | | > |
| | | <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="password"> |
| | | <el-input |
| | | v-model="loginForm.password" |
| | | type="password" |
| | | auto-complete="off" |
| | | placeholder="密码" |
| | | @keyup.enter.native="handleLogin" |
| | | > |
| | | <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="code" v-if="captchaEnabled"> |
| | | <el-input |
| | | v-model="loginForm.code" |
| | | auto-complete="off" |
| | | placeholder="验证码" |
| | | style="width: 63%" |
| | | @keyup.enter.native="handleLogin" |
| | | > |
| | | <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" /> |
| | | </el-input> |
| | | <div class="login-code"> |
| | | <img :src="codeUrl" @click="getCode" class="login-code-img"/> |
| | | </div> |
| | | </el-form-item> |
| | | <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox> |
| | | <el-form-item style="width:100%;"> |
| | | <el-button |
| | | :loading="loading" |
| | | size="medium" |
| | | type="primary" |
| | | style="width:100%;" |
| | | @click.native.prevent="handleLogin" |
| | | > |
| | | <span v-if="!loading">登 录</span> |
| | | <span v-else>登 录 中...</span> |
| | | </el-button> |
| | | <div style="float: right;" v-if="register"> |
| | | <router-link class="link-type" :to="'/register'">立即注册</router-link> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- 底部 --> |
| | | <div class="el-login-footer"> |
| | | <span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getCodeImg } from "@/api/login" |
| | | import Cookies from "js-cookie" |
| | | import { encrypt, decrypt } from '@/utils/jsencrypt' |
| | | |
| | | export default { |
| | | name: "Login", |
| | | data() { |
| | | return { |
| | | title: process.env.VUE_APP_TITLE, |
| | | codeUrl: "", |
| | | loginForm: { |
| | | username: "admin", |
| | | password: "admin123", |
| | | rememberMe: false, |
| | | code: "", |
| | | uuid: "" |
| | | }, |
| | | loginRules: { |
| | | username: [ |
| | | { required: true, trigger: "blur", message: "请输入您的账号" } |
| | | ], |
| | | password: [ |
| | | { required: true, trigger: "blur", message: "请输入您的密码" } |
| | | ], |
| | | code: [{ required: true, trigger: "change", message: "请输入验证码" }] |
| | | }, |
| | | loading: false, |
| | | // 验证码开关 |
| | | captchaEnabled: true, |
| | | // 注册开关 |
| | | register: false, |
| | | redirect: undefined |
| | | } |
| | | }, |
| | | watch: { |
| | | $route: { |
| | | handler: function(route) { |
| | | this.redirect = route.query && route.query.redirect |
| | | }, |
| | | immediate: true |
| | | } |
| | | }, |
| | | created() { |
| | | this.getCode() |
| | | this.getCookie() |
| | | }, |
| | | methods: { |
| | | getCode() { |
| | | getCodeImg().then(res => { |
| | | this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled |
| | | if (this.captchaEnabled) { |
| | | this.codeUrl = "data:image/gif;base64," + res.img |
| | | this.loginForm.uuid = res.uuid |
| | | } |
| | | }) |
| | | }, |
| | | getCookie() { |
| | | const username = Cookies.get("username") |
| | | const password = Cookies.get("password") |
| | | const rememberMe = Cookies.get('rememberMe') |
| | | this.loginForm = { |
| | | username: username === undefined ? this.loginForm.username : username, |
| | | password: password === undefined ? this.loginForm.password : decrypt(password), |
| | | rememberMe: rememberMe === undefined ? false : Boolean(rememberMe) |
| | | } |
| | | }, |
| | | handleLogin() { |
| | | this.$refs.loginForm.validate(valid => { |
| | | if (valid) { |
| | | this.loading = true |
| | | if (this.loginForm.rememberMe) { |
| | | Cookies.set("username", this.loginForm.username, { expires: 30 }) |
| | | Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 }) |
| | | Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 }) |
| | | } else { |
| | | Cookies.remove("username") |
| | | Cookies.remove("password") |
| | | Cookies.remove('rememberMe') |
| | | } |
| | | this.$store.dispatch("Login", this.loginForm).then(() => { |
| | | this.$router.push({ path: this.redirect || "/" }).catch(()=>{}) |
| | | }).catch(() => { |
| | | this.loading = false |
| | | if (this.captchaEnabled) { |
| | | this.getCode() |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style rel="stylesheet/scss" lang="scss"> |
| | | .login { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | height: 100%; |
| | | background-image: url("../assets/images/login-background.jpg"); |
| | | background-size: cover; |
| | | } |
| | | .title { |
| | | margin: 0px auto 30px auto; |
| | | text-align: center; |
| | | color: #707070; |
| | | } |
| | | |
| | | .login-form { |
| | | border-radius: 6px; |
| | | background: #ffffff; |
| | | width: 400px; |
| | | padding: 25px 25px 5px 25px; |
| | | z-index: 1; |
| | | .el-input { |
| | | height: 38px; |
| | | input { |
| | | height: 38px; |
| | | } |
| | | } |
| | | .input-icon { |
| | | height: 39px; |
| | | width: 14px; |
| | | margin-left: 2px; |
| | | } |
| | | } |
| | | .login-tip { |
| | | font-size: 13px; |
| | | text-align: center; |
| | | color: #bfbfbf; |
| | | } |
| | | .login-code { |
| | | width: 33%; |
| | | height: 38px; |
| | | float: right; |
| | | img { |
| | | cursor: pointer; |
| | | vertical-align: middle; |
| | | } |
| | | } |
| | | .el-login-footer { |
| | | height: 40px; |
| | | line-height: 40px; |
| | | position: fixed; |
| | | bottom: 0; |
| | | width: 100%; |
| | | text-align: center; |
| | | color: #fff; |
| | | font-family: Arial; |
| | | font-size: 12px; |
| | | letter-spacing: 1px; |
| | | } |
| | | .login-code-img { |
| | | height: 38px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="24" class="card-box"> |
| | | <el-card> |
| | | <div slot="header"><span><i class="el-icon-monitor"></i> 基本信息</span></div> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table cellspacing="0" style="width: 100%"> |
| | | <tbody> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">Redis版本</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.redis_version }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">运行模式</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.redis_mode == "standalone" ? "单机" : "集群" }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">端口</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.tcp_port }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">客户端数</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.connected_clients }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">运行时间(天)</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.uptime_in_days }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">使用内存</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.used_memory_human }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">使用CPU</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">内存配置</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.maxmemory_human }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">AOF是否开启</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.aof_enabled == "0" ? "否" : "是" }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">RDB是否成功</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.rdb_last_bgsave_status }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">Key数量</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.dbSize">{{ cache.dbSize }} </div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">网络入口/出口</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps</div></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <div slot="header"><span><i class="el-icon-pie-chart"></i> 命令统计</span></div> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <div ref="commandstats" style="height: 420px" /> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <div slot="header"><span><i class="el-icon-odometer"></i> 内存信息</span></div> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <div ref="usedmemory" style="height: 420px" /> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getCache } from "@/api/monitor/cache" |
| | | import * as echarts from "echarts" |
| | | |
| | | export default { |
| | | name: "Cache", |
| | | data() { |
| | | return { |
| | | // 统计命令信息 |
| | | commandstats: null, |
| | | // 使用内存 |
| | | usedmemory: null, |
| | | // cache信息 |
| | | cache: [] |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | this.openLoading() |
| | | }, |
| | | methods: { |
| | | /** 查缓存询信息 */ |
| | | getList() { |
| | | getCache().then((response) => { |
| | | this.cache = response.data |
| | | this.$modal.closeLoading() |
| | | |
| | | this.commandstats = echarts.init(this.$refs.commandstats, "macarons") |
| | | this.commandstats.setOption({ |
| | | tooltip: { |
| | | trigger: "item", |
| | | formatter: "{a} <br/>{b} : {c} ({d}%)", |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "命令", |
| | | type: "pie", |
| | | roseType: "radius", |
| | | radius: [15, 95], |
| | | center: ["50%", "38%"], |
| | | data: response.data.commandStats, |
| | | animationEasing: "cubicInOut", |
| | | animationDuration: 1000, |
| | | } |
| | | ] |
| | | }) |
| | | this.usedmemory = echarts.init(this.$refs.usedmemory, "macarons") |
| | | this.usedmemory.setOption({ |
| | | tooltip: { |
| | | formatter: "{b} <br/>{a} : " + this.cache.info.used_memory_human, |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "峰值", |
| | | type: "gauge", |
| | | min: 0, |
| | | max: 1000, |
| | | detail: { |
| | | formatter: this.cache.info.used_memory_human, |
| | | }, |
| | | data: [ |
| | | { |
| | | value: parseFloat(this.cache.info.used_memory_human), |
| | | name: "内存消耗", |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | }) |
| | | window.addEventListener("resize", () => { |
| | | this.commandstats.resize() |
| | | this.usedmemory.resize() |
| | | }) |
| | | }) |
| | | }, |
| | | // 打开加载层 |
| | | openLoading() { |
| | | this.$modal.loading("正在加载缓存监控数据,请稍候!") |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="8"> |
| | | <el-card style="height: calc(100vh - 125px)"> |
| | | <div slot="header"> |
| | | <span><i class="el-icon-collection"></i> 缓存列表</span> |
| | | <el-button |
| | | style="float: right; padding: 3px 0" |
| | | type="text" |
| | | icon="el-icon-refresh-right" |
| | | @click="refreshCacheNames()" |
| | | ></el-button> |
| | | </div> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="cacheNames" |
| | | :height="tableHeight" |
| | | highlight-current-row |
| | | @row-click="getCacheKeys" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column |
| | | label="序号" |
| | | width="60" |
| | | type="index" |
| | | ></el-table-column> |
| | | |
| | | <el-table-column |
| | | label="缓存名称" |
| | | align="center" |
| | | prop="cacheName" |
| | | :show-overflow-tooltip="true" |
| | | :formatter="nameFormatter" |
| | | ></el-table-column> |
| | | |
| | | <el-table-column |
| | | label="备注" |
| | | align="center" |
| | | prop="remark" |
| | | :show-overflow-tooltip="true" |
| | | /> |
| | | <el-table-column |
| | | label="操作" |
| | | width="60" |
| | | align="center" |
| | | class-name="small-padding fixed-width" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleClearCacheName(scope.row)" |
| | | ></el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <el-card style="height: calc(100vh - 125px)"> |
| | | <div slot="header"> |
| | | <span><i class="el-icon-key"></i> 键名列表</span> |
| | | <el-button |
| | | style="float: right; padding: 3px 0" |
| | | type="text" |
| | | icon="el-icon-refresh-right" |
| | | @click="refreshCacheKeys()" |
| | | ></el-button> |
| | | </div> |
| | | <el-table |
| | | v-loading="subLoading" |
| | | :data="cacheKeys" |
| | | :height="tableHeight" |
| | | highlight-current-row |
| | | @row-click="handleCacheValue" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column |
| | | label="序号" |
| | | width="60" |
| | | type="index" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | label="缓存键名" |
| | | align="center" |
| | | :show-overflow-tooltip="true" |
| | | :formatter="keyFormatter" |
| | | > |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="操作" |
| | | width="60" |
| | | align="center" |
| | | class-name="small-padding fixed-width" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleClearCacheKey(scope.row)" |
| | | ></el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <el-card :bordered="false" style="height: calc(100vh - 125px)"> |
| | | <div slot="header"> |
| | | <span><i class="el-icon-document"></i> 缓存内容</span> |
| | | <el-button |
| | | style="float: right; padding: 3px 0" |
| | | type="text" |
| | | icon="el-icon-refresh-right" |
| | | @click="handleClearCacheAll()" |
| | | >清理全部</el-button |
| | | > |
| | | </div> |
| | | <el-form :model="cacheForm"> |
| | | <el-row :gutter="32"> |
| | | <el-col :offset="1" :span="22"> |
| | | <el-form-item label="缓存名称:" prop="cacheName"> |
| | | <el-input v-model="cacheForm.cacheName" :readOnly="true" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :offset="1" :span="22"> |
| | | <el-form-item label="缓存键名:" prop="cacheKey"> |
| | | <el-input v-model="cacheForm.cacheKey" :readOnly="true" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :offset="1" :span="22"> |
| | | <el-form-item label="缓存内容:" prop="cacheValue"> |
| | | <el-input |
| | | v-model="cacheForm.cacheValue" |
| | | type="textarea" |
| | | :rows="8" |
| | | :readOnly="true" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { listCacheName, listCacheKey, getCacheValue, clearCacheName, clearCacheKey, clearCacheAll } from "@/api/monitor/cache" |
| | | |
| | | export default { |
| | | name: "CacheList", |
| | | data() { |
| | | return { |
| | | cacheNames: [], |
| | | cacheKeys: [], |
| | | cacheForm: {}, |
| | | loading: true, |
| | | subLoading: false, |
| | | nowCacheName: "", |
| | | tableHeight: window.innerHeight - 200 |
| | | } |
| | | }, |
| | | created() { |
| | | this.getCacheNames() |
| | | }, |
| | | methods: { |
| | | /** 查询缓存名称列表 */ |
| | | getCacheNames() { |
| | | this.loading = true |
| | | listCacheName().then(response => { |
| | | this.cacheNames = response.data |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | /** 刷新缓存名称列表 */ |
| | | refreshCacheNames() { |
| | | this.getCacheNames() |
| | | this.$modal.msgSuccess("刷新缓存列表成功") |
| | | }, |
| | | /** 清理指定名称缓存 */ |
| | | handleClearCacheName(row) { |
| | | clearCacheName(row.cacheName).then(response => { |
| | | this.$modal.msgSuccess("清理缓存名称[" + row.cacheName + "]成功") |
| | | this.getCacheKeys() |
| | | }) |
| | | }, |
| | | /** 查询缓存键名列表 */ |
| | | getCacheKeys(row) { |
| | | const cacheName = row !== undefined ? row.cacheName : this.nowCacheName |
| | | if (cacheName === "") { |
| | | return |
| | | } |
| | | this.subLoading = true |
| | | listCacheKey(cacheName).then(response => { |
| | | this.cacheKeys = response.data |
| | | this.subLoading = false |
| | | this.nowCacheName = cacheName |
| | | }) |
| | | }, |
| | | /** 刷新缓存键名列表 */ |
| | | refreshCacheKeys() { |
| | | this.getCacheKeys() |
| | | this.$modal.msgSuccess("刷新键名列表成功") |
| | | }, |
| | | /** 清理指定键名缓存 */ |
| | | handleClearCacheKey(cacheKey) { |
| | | clearCacheKey(cacheKey).then(response => { |
| | | this.$modal.msgSuccess("清理缓存键名[" + cacheKey + "]成功") |
| | | this.getCacheKeys() |
| | | }) |
| | | }, |
| | | /** 列表前缀去除 */ |
| | | nameFormatter(row) { |
| | | return row.cacheName.replace(":", "") |
| | | }, |
| | | /** 键名前缀去除 */ |
| | | keyFormatter(cacheKey) { |
| | | return cacheKey.replace(this.nowCacheName, "") |
| | | }, |
| | | /** 查询缓存内容详细 */ |
| | | handleCacheValue(cacheKey) { |
| | | getCacheValue(this.nowCacheName, cacheKey).then(response => { |
| | | this.cacheForm = response.data |
| | | }) |
| | | }, |
| | | /** 清理全部缓存 */ |
| | | handleClearCacheAll() { |
| | | clearCacheAll().then(response => { |
| | | this.$modal.msgSuccess("清理全部缓存成功") |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <i-frame :src="url" /> |
| | | </template> |
| | | <script> |
| | | import iFrame from "@/components/iFrame/index" |
| | | export default { |
| | | name: "Druid", |
| | | components: { iFrame }, |
| | | data() { |
| | | return { |
| | | url: process.env.VUE_APP_BASE_API + "/druid/login.html" |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="任务名称" prop="jobName"> |
| | | <el-input |
| | | v-model="queryParams.jobName" |
| | | placeholder="请输入任务名称" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="任务组名" prop="jobGroup"> |
| | | <el-select v-model="queryParams.jobGroup" placeholder="请选择任务组名" clearable> |
| | | <el-option |
| | | v-for="dict in dict.type.sys_job_group" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="任务状态" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="请选择任务状态" clearable> |
| | | <el-option |
| | | v-for="dict in dict.type.sys_job_status" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="el-icon-plus" |
| | | size="mini" |
| | | @click="handleAdd" |
| | | v-hasPermi="['monitor:job:add']" |
| | | >新增</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="el-icon-edit" |
| | | size="mini" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['monitor:job:edit']" |
| | | >修改</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-delete" |
| | | size="mini" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['monitor:job:remove']" |
| | | >删除</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-download" |
| | | size="mini" |
| | | @click="handleExport" |
| | | v-hasPermi="['monitor:job:export']" |
| | | >导出</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="info" |
| | | plain |
| | | icon="el-icon-s-operation" |
| | | size="mini" |
| | | @click="handleJobLog" |
| | | v-hasPermi="['monitor:job:query']" |
| | | >日志</el-button> |
| | | </el-col> |
| | | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="任务编号" width="100" align="center" prop="jobId" /> |
| | | <el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="任务组名" align="center" prop="jobGroup"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="cron执行表达式" align="center" prop="cronExpression" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="状态" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-switch |
| | | v-model="scope.row.status" |
| | | active-value="0" |
| | | inactive-value="1" |
| | | @change="handleStatusChange(scope.row)" |
| | | ></el-switch> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleUpdate(scope.row)" |
| | | v-hasPermi="['monitor:job:edit']" |
| | | >修改</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleDelete(scope.row)" |
| | | v-hasPermi="['monitor:job:remove']" |
| | | >删除</el-button> |
| | | <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['monitor:job:changeStatus', 'monitor:job:query']"> |
| | | <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button> |
| | | <el-dropdown-menu slot="dropdown"> |
| | | <el-dropdown-item command="handleRun" icon="el-icon-caret-right" |
| | | v-hasPermi="['monitor:job:changeStatus']">执行一次</el-dropdown-item> |
| | | <el-dropdown-item command="handleView" icon="el-icon-view" |
| | | v-hasPermi="['monitor:job:query']">任务详细</el-dropdown-item> |
| | | <el-dropdown-item command="handleJobLog" icon="el-icon-s-operation" |
| | | v-hasPermi="['monitor:job:query']">调度日志</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </el-dropdown> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- 添加或修改定时任务对话框 --> |
| | | <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body> |
| | | <el-form ref="form" :model="form" :rules="rules" label-width="120px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="任务名称" prop="jobName"> |
| | | <el-input v-model="form.jobName" placeholder="请输入任务名称" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="任务分组" prop="jobGroup"> |
| | | <el-select v-model="form.jobGroup" placeholder="请选择任务分组"> |
| | | <el-option |
| | | v-for="dict in dict.type.sys_job_group" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item prop="invokeTarget"> |
| | | <span slot="label"> |
| | | 调用方法 |
| | | <el-tooltip placement="top"> |
| | | <div slot="content"> |
| | | Bean调用示例:ryTask.ryParams('ry') |
| | | <br />Class类调用示例:com.ruoyi.quartz.task.RyTask.ryParams('ry') |
| | | <br />参数说明:支持字符串,布尔类型,长整型,浮点型,整型 |
| | | </div> |
| | | <i class="el-icon-question"></i> |
| | | </el-tooltip> |
| | | </span> |
| | | <el-input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="cron表达式" prop="cronExpression"> |
| | | <el-input v-model="form.cronExpression" placeholder="请输入cron执行表达式"> |
| | | <template slot="append"> |
| | | <el-button type="primary" @click="handleShowCron"> |
| | | 生成表达式 |
| | | <i class="el-icon-time el-icon--right"></i> |
| | | </el-button> |
| | | </template> |
| | | </el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24" v-if="form.jobId !== undefined"> |
| | | <el-form-item label="状态"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in dict.type.sys_job_status" |
| | | :key="dict.value" |
| | | :label="dict.value" |
| | | >{{dict.label}}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="执行策略" prop="misfirePolicy"> |
| | | <el-radio-group v-model="form.misfirePolicy" size="small"> |
| | | <el-radio-button label="1">立即执行</el-radio-button> |
| | | <el-radio-button label="2">执行一次</el-radio-button> |
| | | <el-radio-button label="3">放弃执行</el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="是否并发" prop="concurrent"> |
| | | <el-radio-group v-model="form.concurrent" size="small"> |
| | | <el-radio-button label="0">允许</el-radio-button> |
| | | <el-radio-button label="1">禁止</el-radio-button> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确 定</el-button> |
| | | <el-button @click="cancel">取 消</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | <el-dialog title="Cron表达式生成器" :visible.sync="openCron" append-to-body destroy-on-close class="scrollbar"> |
| | | <crontab @hide="openCron=false" @fill="crontabFill" :expression="expression"></crontab> |
| | | </el-dialog> |
| | | |
| | | <!-- 任务日志详细 --> |
| | | <el-dialog title="任务详细" :visible.sync="openView" width="700px" append-to-body> |
| | | <el-form ref="form" :model="form" label-width="120px" size="mini"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="任务编号:">{{ form.jobId }}</el-form-item> |
| | | <el-form-item label="任务名称:">{{ form.jobName }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="任务分组:">{{ jobGroupFormat(form) }}</el-form-item> |
| | | <el-form-item label="创建时间:">{{ form.createTime }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="cron表达式:">{{ form.cronExpression }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="下次执行时间:">{{ parseTime(form.nextValidTime) }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="调用目标方法:">{{ form.invokeTarget }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="任务状态:"> |
| | | <div v-if="form.status == 0">正常</div> |
| | | <div v-else-if="form.status == 1">暂停</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="是否并发:"> |
| | | <div v-if="form.concurrent == 0">允许</div> |
| | | <div v-else-if="form.concurrent == 1">禁止</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="执行策略:"> |
| | | <div v-if="form.misfirePolicy == 0">默认策略</div> |
| | | <div v-else-if="form.misfirePolicy == 1">立即执行</div> |
| | | <div v-else-if="form.misfirePolicy == 2">执行一次</div> |
| | | <div v-else-if="form.misfirePolicy == 3">放弃执行</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="openView = false">关 闭</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { listJob, getJob, delJob, addJob, updateJob, runJob, changeJobStatus } from "@/api/monitor/job" |
| | | import Crontab from '@/components/Crontab' |
| | | |
| | | export default { |
| | | components: { Crontab }, |
| | | name: "Job", |
| | | dicts: ['sys_job_group', 'sys_job_status'], |
| | | data() { |
| | | return { |
| | | // 遮罩层 |
| | | loading: true, |
| | | // 选中数组 |
| | | ids: [], |
| | | // 非单个禁用 |
| | | single: true, |
| | | // 非多个禁用 |
| | | multiple: true, |
| | | // 显示搜索条件 |
| | | showSearch: true, |
| | | // 总条数 |
| | | total: 0, |
| | | // 定时任务表格数据 |
| | | jobList: [], |
| | | // 弹出层标题 |
| | | title: "", |
| | | // 是否显示弹出层 |
| | | open: false, |
| | | // 是否显示详细弹出层 |
| | | openView: false, |
| | | // 是否显示Cron表达式弹出层 |
| | | openCron: false, |
| | | // 传入的表达式 |
| | | expression: "", |
| | | // 查询参数 |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | jobName: undefined, |
| | | jobGroup: undefined, |
| | | status: undefined |
| | | }, |
| | | // 表单参数 |
| | | form: {}, |
| | | // 表单校验 |
| | | rules: { |
| | | jobName: [ |
| | | { required: true, message: "任务名称不能为空", trigger: "blur" } |
| | | ], |
| | | invokeTarget: [ |
| | | { required: true, message: "调用目标字符串不能为空", trigger: "blur" } |
| | | ], |
| | | cronExpression: [ |
| | | { required: true, message: "cron执行表达式不能为空", trigger: "blur" } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | }, |
| | | methods: { |
| | | /** 查询定时任务列表 */ |
| | | getList() { |
| | | this.loading = true |
| | | listJob(this.queryParams).then(response => { |
| | | this.jobList = response.rows |
| | | this.total = response.total |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | // 任务组名字典翻译 |
| | | jobGroupFormat(row, column) { |
| | | return this.selectDictLabel(this.dict.type.sys_job_group, row.jobGroup) |
| | | }, |
| | | // 取消按钮 |
| | | cancel() { |
| | | this.open = false |
| | | this.reset() |
| | | }, |
| | | // 表单重置 |
| | | reset() { |
| | | this.form = { |
| | | jobId: undefined, |
| | | jobName: undefined, |
| | | jobGroup: undefined, |
| | | invokeTarget: undefined, |
| | | cronExpression: undefined, |
| | | misfirePolicy: 1, |
| | | concurrent: 1, |
| | | status: "0" |
| | | } |
| | | this.resetForm("form") |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.resetForm("queryForm") |
| | | this.handleQuery() |
| | | }, |
| | | // 多选框选中数据 |
| | | handleSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.jobId) |
| | | this.single = selection.length != 1 |
| | | this.multiple = !selection.length |
| | | }, |
| | | // 更多操作触发 |
| | | handleCommand(command, row) { |
| | | switch (command) { |
| | | case "handleRun": |
| | | this.handleRun(row) |
| | | break |
| | | case "handleView": |
| | | this.handleView(row) |
| | | break |
| | | case "handleJobLog": |
| | | this.handleJobLog(row) |
| | | break |
| | | default: |
| | | break |
| | | } |
| | | }, |
| | | // 任务状态修改 |
| | | handleStatusChange(row) { |
| | | let text = row.status === "0" ? "启用" : "停用" |
| | | this.$modal.confirm('确认要"' + text + '""' + row.jobName + '"任务吗?').then(function() { |
| | | return changeJobStatus(row.jobId, row.status) |
| | | }).then(() => { |
| | | this.$modal.msgSuccess(text + "成功") |
| | | }).catch(function() { |
| | | row.status = row.status === "0" ? "1" : "0" |
| | | }) |
| | | }, |
| | | /* 立即执行一次 */ |
| | | handleRun(row) { |
| | | this.$modal.confirm('确认要立即执行一次"' + row.jobName + '"任务吗?').then(function() { |
| | | return runJob(row.jobId, row.jobGroup) |
| | | }).then(() => { |
| | | this.$modal.msgSuccess("执行成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 任务详细信息 */ |
| | | handleView(row) { |
| | | getJob(row.jobId).then(response => { |
| | | this.form = response.data |
| | | this.openView = true |
| | | }) |
| | | }, |
| | | /** cron表达式按钮操作 */ |
| | | handleShowCron() { |
| | | this.expression = this.form.cronExpression |
| | | this.openCron = true |
| | | }, |
| | | /** 确定后回传值 */ |
| | | crontabFill(value) { |
| | | this.form.cronExpression = value |
| | | }, |
| | | /** 任务日志列表查询 */ |
| | | handleJobLog(row) { |
| | | const jobId = row.jobId || 0 |
| | | this.$router.push('/monitor/job-log/index/' + jobId) |
| | | }, |
| | | /** 新增按钮操作 */ |
| | | handleAdd() { |
| | | this.reset() |
| | | this.open = true |
| | | this.title = "添加任务" |
| | | }, |
| | | /** 修改按钮操作 */ |
| | | handleUpdate(row) { |
| | | this.reset() |
| | | const jobId = row.jobId || this.ids |
| | | getJob(jobId).then(response => { |
| | | this.form = response.data |
| | | this.open = true |
| | | this.title = "修改任务" |
| | | }) |
| | | }, |
| | | /** 提交按钮 */ |
| | | submitForm: function() { |
| | | this.$refs["form"].validate(valid => { |
| | | if (valid) { |
| | | if (this.form.jobId != undefined) { |
| | | updateJob(this.form).then(response => { |
| | | this.$modal.msgSuccess("修改成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } else { |
| | | addJob(this.form).then(response => { |
| | | this.$modal.msgSuccess("新增成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | }, |
| | | /** 删除按钮操作 */ |
| | | handleDelete(row) { |
| | | const jobIds = row.jobId || this.ids |
| | | this.$modal.confirm('是否确认删除定时任务编号为"' + jobIds + '"的数据项?').then(function() { |
| | | return delJob(jobIds) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("删除成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 导出按钮操作 */ |
| | | handleExport() { |
| | | this.download('monitor/job/export', { |
| | | ...this.queryParams |
| | | }, `job_${new Date().getTime()}.xlsx`) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="任务名称" prop="jobName"> |
| | | <el-input |
| | | v-model="queryParams.jobName" |
| | | placeholder="请输入任务名称" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="任务组名" prop="jobGroup"> |
| | | <el-select |
| | | v-model="queryParams.jobGroup" |
| | | placeholder="请选择任务组名" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_job_group" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="执行状态" prop="status"> |
| | | <el-select |
| | | v-model="queryParams.status" |
| | | placeholder="请选择执行状态" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_common_status" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="执行时间"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | style="width: 240px" |
| | | value-format="yyyy-MM-dd" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-delete" |
| | | size="mini" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['monitor:job:remove']" |
| | | >删除</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-delete" |
| | | size="mini" |
| | | @click="handleClean" |
| | | v-hasPermi="['monitor:job:remove']" |
| | | >清空</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-download" |
| | | size="mini" |
| | | @click="handleExport" |
| | | v-hasPermi="['monitor:job:export']" |
| | | >导出</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-close" |
| | | size="mini" |
| | | @click="handleClose" |
| | | >关闭</el-button> |
| | | </el-col> |
| | | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="jobLogList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="日志编号" width="80" align="center" prop="jobLogId" /> |
| | | <el-table-column label="任务名称" align="center" prop="jobName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="任务组名" align="center" prop="jobGroup" :show-overflow-tooltip="true"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_job_group" :value="scope.row.jobGroup"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="调用目标字符串" align="center" prop="invokeTarget" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="日志信息" align="center" prop="jobMessage" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="执行状态" align="center" prop="status"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_common_status" :value="scope.row.status"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="执行时间" align="center" prop="createTime" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-view" |
| | | @click="handleView(scope.row)" |
| | | v-hasPermi="['monitor:job:query']" |
| | | >详细</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- 调度日志详细 --> |
| | | <el-dialog title="调度日志详细" :visible.sync="open" width="700px" append-to-body> |
| | | <el-form ref="form" :model="form" label-width="100px" size="mini"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="日志序号:">{{ form.jobLogId }}</el-form-item> |
| | | <el-form-item label="任务名称:">{{ form.jobName }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="任务分组:">{{ form.jobGroup }}</el-form-item> |
| | | <el-form-item label="执行时间:">{{ form.createTime }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="调用方法:">{{ form.invokeTarget }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="日志信息:">{{ form.jobMessage }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="执行状态:"> |
| | | <div v-if="form.status == 0">正常</div> |
| | | <div v-else-if="form.status == 1">失败</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="异常信息:" v-if="form.status == 1">{{ form.exceptionInfo }}</el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="open = false">关 闭</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getJob} from "@/api/monitor/job" |
| | | import { listJobLog, delJobLog, cleanJobLog } from "@/api/monitor/jobLog" |
| | | |
| | | export default { |
| | | name: "JobLog", |
| | | dicts: ['sys_common_status', 'sys_job_group'], |
| | | data() { |
| | | return { |
| | | // 遮罩层 |
| | | loading: true, |
| | | // 选中数组 |
| | | ids: [], |
| | | // 非多个禁用 |
| | | multiple: true, |
| | | // 显示搜索条件 |
| | | showSearch: true, |
| | | // 总条数 |
| | | total: 0, |
| | | // 调度日志表格数据 |
| | | jobLogList: [], |
| | | // 是否显示弹出层 |
| | | open: false, |
| | | // 日期范围 |
| | | dateRange: [], |
| | | // 表单参数 |
| | | form: {}, |
| | | // 查询参数 |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | jobName: undefined, |
| | | jobGroup: undefined, |
| | | status: undefined |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | const jobId = this.$route.params && this.$route.params.jobId |
| | | if (jobId !== undefined && jobId != 0) { |
| | | getJob(jobId).then(response => { |
| | | this.queryParams.jobName = response.data.jobName |
| | | this.queryParams.jobGroup = response.data.jobGroup |
| | | this.getList() |
| | | }) |
| | | } else { |
| | | this.getList() |
| | | } |
| | | }, |
| | | methods: { |
| | | /** 查询调度日志列表 */ |
| | | getList() { |
| | | this.loading = true |
| | | listJobLog(this.addDateRange(this.queryParams, this.dateRange)).then(response => { |
| | | this.jobLogList = response.rows |
| | | this.total = response.total |
| | | this.loading = false |
| | | } |
| | | ) |
| | | }, |
| | | // 返回按钮 |
| | | handleClose() { |
| | | const obj = { path: "/monitor/job" } |
| | | this.$tab.closeOpenPage(obj) |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.dateRange = [] |
| | | this.resetForm("queryForm") |
| | | this.handleQuery() |
| | | }, |
| | | // 多选框选中数据 |
| | | handleSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.jobLogId) |
| | | this.multiple = !selection.length |
| | | }, |
| | | /** 详细按钮操作 */ |
| | | handleView(row) { |
| | | this.open = true |
| | | this.form = row |
| | | }, |
| | | /** 删除按钮操作 */ |
| | | handleDelete(row) { |
| | | const jobLogIds = this.ids |
| | | this.$modal.confirm('是否确认删除调度日志编号为"' + jobLogIds + '"的数据项?').then(function() { |
| | | return delJobLog(jobLogIds) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("删除成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 清空按钮操作 */ |
| | | handleClean() { |
| | | this.$modal.confirm('是否确认清空所有调度日志数据项?').then(function() { |
| | | return cleanJobLog() |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("清空成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 导出按钮操作 */ |
| | | handleExport() { |
| | | this.download('/monitor/jobLog/export', { |
| | | ...this.queryParams |
| | | }, `log_${new Date().getTime()}.xlsx`) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="登录地址" prop="ipaddr"> |
| | | <el-input |
| | | v-model="queryParams.ipaddr" |
| | | placeholder="请输入登录地址" |
| | | clearable |
| | | style="width: 240px;" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="用户名称" prop="userName"> |
| | | <el-input |
| | | v-model="queryParams.userName" |
| | | placeholder="请输入用户名称" |
| | | clearable |
| | | style="width: 240px;" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="状态" prop="status"> |
| | | <el-select |
| | | v-model="queryParams.status" |
| | | placeholder="登录状态" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_common_status" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="登录时间"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | style="width: 240px" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | :default-time="['00:00:00', '23:59:59']" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-delete" |
| | | size="mini" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['monitor:logininfor:remove']" |
| | | >删除</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-delete" |
| | | size="mini" |
| | | @click="handleClean" |
| | | v-hasPermi="['monitor:logininfor:remove']" |
| | | >清空</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="el-icon-unlock" |
| | | size="mini" |
| | | :disabled="single" |
| | | @click="handleUnlock" |
| | | v-hasPermi="['monitor:logininfor:unlock']" |
| | | >解锁</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-download" |
| | | size="mini" |
| | | @click="handleExport" |
| | | v-hasPermi="['monitor:logininfor:export']" |
| | | >导出</el-button> |
| | | </el-col> |
| | | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table ref="tables" v-loading="loading" :data="list" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="访问编号" align="center" prop="infoId" /> |
| | | <el-table-column label="用户名称" align="center" prop="userName" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" /> |
| | | <el-table-column label="登录地址" align="center" prop="ipaddr" width="130" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="登录地点" align="center" prop="loginLocation" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="浏览器" align="center" prop="browser" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="操作系统" align="center" prop="os" /> |
| | | <el-table-column label="登录状态" align="center" prop="status"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_common_status" :value="scope.row.status"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作信息" align="center" prop="msg" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="登录日期" align="center" prop="loginTime" sortable="custom" :sort-orders="['descending', 'ascending']" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.loginTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { list, delLogininfor, cleanLogininfor, unlockLogininfor } from "@/api/monitor/logininfor" |
| | | |
| | | export default { |
| | | name: "Logininfor", |
| | | dicts: ['sys_common_status'], |
| | | data() { |
| | | return { |
| | | // 遮罩层 |
| | | loading: true, |
| | | // 选中数组 |
| | | ids: [], |
| | | // 非单个禁用 |
| | | single: true, |
| | | // 非多个禁用 |
| | | multiple: true, |
| | | // 选择用户名 |
| | | selectName: "", |
| | | // 显示搜索条件 |
| | | showSearch: true, |
| | | // 总条数 |
| | | total: 0, |
| | | // 表格数据 |
| | | list: [], |
| | | // 日期范围 |
| | | dateRange: [], |
| | | // 默认排序 |
| | | defaultSort: { prop: "loginTime", order: "descending" }, |
| | | // 查询参数 |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | ipaddr: undefined, |
| | | userName: undefined, |
| | | status: undefined |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | }, |
| | | methods: { |
| | | /** 查询登录日志列表 */ |
| | | getList() { |
| | | this.loading = true |
| | | list(this.addDateRange(this.queryParams, this.dateRange)).then(response => { |
| | | this.list = response.rows |
| | | this.total = response.total |
| | | this.loading = false |
| | | } |
| | | ) |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.dateRange = [] |
| | | this.resetForm("queryForm") |
| | | this.queryParams.pageNum = 1 |
| | | this.$refs.tables.sort(this.defaultSort.prop, this.defaultSort.order) |
| | | }, |
| | | /** 多选框选中数据 */ |
| | | handleSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.infoId) |
| | | this.single = selection.length!=1 |
| | | this.multiple = !selection.length |
| | | this.selectName = selection.map(item => item.userName) |
| | | }, |
| | | /** 排序触发事件 */ |
| | | handleSortChange(column, prop, order) { |
| | | this.queryParams.orderByColumn = column.prop |
| | | this.queryParams.isAsc = column.order |
| | | this.getList() |
| | | }, |
| | | /** 删除按钮操作 */ |
| | | handleDelete(row) { |
| | | const infoIds = row.infoId || this.ids |
| | | this.$modal.confirm('是否确认删除访问编号为"' + infoIds + '"的数据项?').then(function() { |
| | | return delLogininfor(infoIds) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("删除成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 清空按钮操作 */ |
| | | handleClean() { |
| | | this.$modal.confirm('是否确认清空所有登录日志数据项?').then(function() { |
| | | return cleanLogininfor() |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("清空成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 解锁按钮操作 */ |
| | | handleUnlock() { |
| | | const username = this.selectName |
| | | this.$modal.confirm('是否确认解锁用户"' + username + '"数据项?').then(function() { |
| | | return unlockLogininfor(username) |
| | | }).then(() => { |
| | | this.$modal.msgSuccess("用户" + username + "解锁成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 导出按钮操作 */ |
| | | handleExport() { |
| | | this.download('monitor/logininfor/export', { |
| | | ...this.queryParams |
| | | }, `logininfor_${new Date().getTime()}.xlsx`) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px"> |
| | | <el-form-item label="登录地址" prop="ipaddr"> |
| | | <el-input |
| | | v-model="queryParams.ipaddr" |
| | | placeholder="请输入登录地址" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="用户名称" prop="userName"> |
| | | <el-input |
| | | v-model="queryParams.userName" |
| | | placeholder="请输入用户名称" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | |
| | | </el-form> |
| | | <el-table |
| | | v-loading="loading" |
| | | :data="list.slice((pageNum-1)*pageSize,pageNum*pageSize)" |
| | | style="width: 100%;" |
| | | > |
| | | <el-table-column label="序号" type="index" align="center"> |
| | | <template slot-scope="scope"> |
| | | <span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="会话编号" align="center" prop="tokenId" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="登录名称" align="center" prop="userName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="部门名称" align="center" prop="deptName" /> |
| | | <el-table-column label="主机" align="center" prop="ipaddr" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="登录地点" align="center" prop="loginLocation" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="浏览器" align="center" prop="browser" /> |
| | | <el-table-column label="操作系统" align="center" prop="os" /> |
| | | <el-table-column label="登录时间" align="center" prop="loginTime" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.loginTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleForceLogout(scope.row)" |
| | | v-hasPermi="['monitor:online:forceLogout']" |
| | | >强退</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination v-show="total>0" :total="total" :page.sync="pageNum" :limit.sync="pageSize" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { list, forceLogout } from "@/api/monitor/online" |
| | | |
| | | export default { |
| | | name: "Online", |
| | | data() { |
| | | return { |
| | | // 遮罩层 |
| | | loading: true, |
| | | // 总条数 |
| | | total: 0, |
| | | // 表格数据 |
| | | list: [], |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | // 查询参数 |
| | | queryParams: { |
| | | ipaddr: undefined, |
| | | userName: undefined |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | }, |
| | | methods: { |
| | | /** 查询登录日志列表 */ |
| | | getList() { |
| | | this.loading = true |
| | | list(this.queryParams).then(response => { |
| | | this.list = response.rows |
| | | this.total = response.total |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.resetForm("queryForm") |
| | | this.handleQuery() |
| | | }, |
| | | /** 强退按钮操作 */ |
| | | handleForceLogout(row) { |
| | | this.$modal.confirm('是否确认强退名称为"' + row.userName + '"的用户?').then(function() { |
| | | return forceLogout(row.tokenId) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("强退成功") |
| | | }).catch(() => {}) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="操作地址" prop="operIp"> |
| | | <el-input |
| | | v-model="queryParams.operIp" |
| | | placeholder="请输入操作地址" |
| | | clearable |
| | | style="width: 240px;" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="系统模块" prop="title"> |
| | | <el-input |
| | | v-model="queryParams.title" |
| | | placeholder="请输入系统模块" |
| | | clearable |
| | | style="width: 240px;" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="操作人员" prop="operName"> |
| | | <el-input |
| | | v-model="queryParams.operName" |
| | | placeholder="请输入操作人员" |
| | | clearable |
| | | style="width: 240px;" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="类型" prop="businessType"> |
| | | <el-select |
| | | v-model="queryParams.businessType" |
| | | placeholder="操作类型" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_oper_type" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="状态" prop="status"> |
| | | <el-select |
| | | v-model="queryParams.status" |
| | | placeholder="操作状态" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_common_status" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="操作时间"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | style="width: 240px" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | :default-time="['00:00:00', '23:59:59']" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-delete" |
| | | size="mini" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['monitor:operlog:remove']" |
| | | >删除</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-delete" |
| | | size="mini" |
| | | @click="handleClean" |
| | | v-hasPermi="['monitor:operlog:remove']" |
| | | >清空</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-download" |
| | | size="mini" |
| | | @click="handleExport" |
| | | v-hasPermi="['monitor:operlog:export']" |
| | | >导出</el-button> |
| | | </el-col> |
| | | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table ref="tables" v-loading="loading" :data="list" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange"> |
| | | <el-table-column type="selection" width="50" align="center" /> |
| | | <el-table-column label="日志编号" align="center" prop="operId" /> |
| | | <el-table-column label="系统模块" align="center" prop="title" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="操作类型" align="center" prop="businessType"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_oper_type" :value="scope.row.businessType"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作人员" align="center" prop="operName" width="110" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" /> |
| | | <el-table-column label="操作地址" align="center" prop="operIp" width="130" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="操作地点" align="center" prop="operLocation" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="操作状态" align="center" prop="status"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_common_status" :value="scope.row.status"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作日期" align="center" prop="operTime" width="160" sortable="custom" :sort-orders="['descending', 'ascending']"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.operTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="消耗时间" align="center" prop="costTime" width="110" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ scope.row.costTime }}毫秒</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-view" |
| | | @click="handleView(scope.row,scope.index)" |
| | | v-hasPermi="['monitor:operlog:query']" |
| | | >详细</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- 操作日志详细 --> |
| | | <el-dialog title="操作日志详细" :visible.sync="open" width="800px" append-to-body> |
| | | <el-form ref="form" :model="form" label-width="100px" size="mini"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="操作模块:">{{ form.title }} / {{ typeFormat(form) }}</el-form-item> |
| | | <el-form-item |
| | | label="登录信息:" |
| | | >{{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="请求地址:">{{ form.operUrl }}</el-form-item> |
| | | <el-form-item label="请求方式:">{{ form.requestMethod }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="操作方法:">{{ form.method }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="请求参数:">{{ form.operParam }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="返回参数:">{{ form.jsonResult }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="操作状态:"> |
| | | <div v-if="form.status === 0">正常</div> |
| | | <div v-else-if="form.status === 1">失败</div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="消耗时间:">{{ form.costTime }}毫秒</el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="操作时间:">{{ parseTime(form.operTime) }}</el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="异常信息:" v-if="form.status === 1">{{ form.errorMsg }}</el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="open = false">关 闭</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { list, delOperlog, cleanOperlog } from "@/api/monitor/operlog" |
| | | |
| | | export default { |
| | | name: "Operlog", |
| | | dicts: ['sys_oper_type', 'sys_common_status'], |
| | | data() { |
| | | return { |
| | | // 遮罩层 |
| | | loading: true, |
| | | // 选中数组 |
| | | ids: [], |
| | | // 非多个禁用 |
| | | multiple: true, |
| | | // 显示搜索条件 |
| | | showSearch: true, |
| | | // 总条数 |
| | | total: 0, |
| | | // 表格数据 |
| | | list: [], |
| | | // 是否显示弹出层 |
| | | open: false, |
| | | // 日期范围 |
| | | dateRange: [], |
| | | // 默认排序 |
| | | defaultSort: { prop: "operTime", order: "descending" }, |
| | | // 表单参数 |
| | | form: {}, |
| | | // 查询参数 |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | operIp: undefined, |
| | | title: undefined, |
| | | operName: undefined, |
| | | businessType: undefined, |
| | | status: undefined |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | }, |
| | | methods: { |
| | | /** 查询登录日志 */ |
| | | getList() { |
| | | this.loading = true |
| | | list(this.addDateRange(this.queryParams, this.dateRange)).then( response => { |
| | | this.list = response.rows |
| | | this.total = response.total |
| | | this.loading = false |
| | | } |
| | | ) |
| | | }, |
| | | // 操作日志类型字典翻译 |
| | | typeFormat(row, column) { |
| | | return this.selectDictLabel(this.dict.type.sys_oper_type, row.businessType) |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.dateRange = [] |
| | | this.resetForm("queryForm") |
| | | this.queryParams.pageNum = 1 |
| | | this.$refs.tables.sort(this.defaultSort.prop, this.defaultSort.order) |
| | | }, |
| | | /** 多选框选中数据 */ |
| | | handleSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.operId) |
| | | this.multiple = !selection.length |
| | | }, |
| | | /** 排序触发事件 */ |
| | | handleSortChange(column, prop, order) { |
| | | this.queryParams.orderByColumn = column.prop |
| | | this.queryParams.isAsc = column.order |
| | | this.getList() |
| | | }, |
| | | /** 详细按钮操作 */ |
| | | handleView(row) { |
| | | this.open = true |
| | | this.form = row |
| | | }, |
| | | /** 删除按钮操作 */ |
| | | handleDelete(row) { |
| | | const operIds = row.operId || this.ids |
| | | this.$modal.confirm('是否确认删除日志编号为"' + operIds + '"的数据项?').then(function() { |
| | | return delOperlog(operIds) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("删除成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 清空按钮操作 */ |
| | | handleClean() { |
| | | this.$modal.confirm('是否确认清空所有操作日志数据项?').then(function() { |
| | | return cleanOperlog() |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("清空成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 导出按钮操作 */ |
| | | handleExport() { |
| | | this.download('monitor/operlog/export', { |
| | | ...this.queryParams |
| | | }, `operlog_${new Date().getTime()}.xlsx`) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-row :gutter="10"> |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <div slot="header"><span><i class="el-icon-cpu"></i> CPU</span></div> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table cellspacing="0" style="width: 100%;"> |
| | | <thead> |
| | | <tr> |
| | | <th class="el-table__cell is-leaf"><div class="cell">属性</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">值</div></th> |
| | | </tr> |
| | | </thead> |
| | | <tbody> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">核心数</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.cpuNum }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">用户使用率</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.used }}%</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">系统使用率</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.sys }}%</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">当前空闲率</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.free }}%</div></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="12" class="card-box"> |
| | | <el-card> |
| | | <div slot="header"><span><i class="el-icon-tickets"></i> 内存</span></div> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table cellspacing="0" style="width: 100%;"> |
| | | <thead> |
| | | <tr> |
| | | <th class="el-table__cell is-leaf"><div class="cell">属性</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">内存</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">JVM</div></th> |
| | | </tr> |
| | | </thead> |
| | | <tbody> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">总内存</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem">{{ server.mem.total }}G</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.total }}M</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">已用内存</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem">{{ server.mem.used}}G</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.used}}M</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">剩余内存</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem">{{ server.mem.free }}G</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.free }}M</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">使用率</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem" :class="{'text-danger': server.mem.usage > 80}">{{ server.mem.usage }}%</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm" :class="{'text-danger': server.jvm.usage > 80}">{{ server.jvm.usage }}%</div></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="24" class="card-box"> |
| | | <el-card> |
| | | <div slot="header"> |
| | | <span><i class="el-icon-monitor"></i> 服务器信息</span> |
| | | </div> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table cellspacing="0" style="width: 100%;"> |
| | | <tbody> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">服务器名称</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.computerName }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">操作系统</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.osName }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">服务器IP</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.computerIp }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">系统架构</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.osArch }}</div></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="24" class="card-box"> |
| | | <el-card> |
| | | <div slot="header"> |
| | | <span><i class="el-icon-coffee-cup"></i> Java虚拟机信息</span> |
| | | </div> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table cellspacing="0" style="width: 100%;table-layout:fixed;"> |
| | | <tbody> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">Java名称</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.name }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">Java版本</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.version }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td class="el-table__cell is-leaf"><div class="cell">启动时间</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.startTime }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">运行时长</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.runTime }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td colspan="1" class="el-table__cell is-leaf"><div class="cell">安装路径</div></td> |
| | | <td colspan="3" class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.home }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td colspan="1" class="el-table__cell is-leaf"><div class="cell">项目路径</div></td> |
| | | <td colspan="3" class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.userDir }}</div></td> |
| | | </tr> |
| | | <tr> |
| | | <td colspan="1" class="el-table__cell is-leaf"><div class="cell">运行参数</div></td> |
| | | <td colspan="3" class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.inputArgs }}</div></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="24" class="card-box"> |
| | | <el-card> |
| | | <div slot="header"> |
| | | <span><i class="el-icon-receiving"></i> 磁盘状态</span> |
| | | </div> |
| | | <div class="el-table el-table--enable-row-hover el-table--medium"> |
| | | <table cellspacing="0" style="width: 100%;"> |
| | | <thead> |
| | | <tr> |
| | | <th class="el-table__cell el-table__cell is-leaf"><div class="cell">盘符路径</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">文件系统</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">盘符类型</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">总大小</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">可用大小</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">已用大小</div></th> |
| | | <th class="el-table__cell is-leaf"><div class="cell">已用百分比</div></th> |
| | | </tr> |
| | | </thead> |
| | | <tbody v-if="server.sysFiles"> |
| | | <tr v-for="(sysFile, index) in server.sysFiles" :key="index"> |
| | | <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.dirName }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.sysTypeName }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.typeName }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.total }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.free }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.used }}</div></td> |
| | | <td class="el-table__cell is-leaf"><div class="cell" :class="{'text-danger': sysFile.usage > 80}">{{ sysFile.usage }}%</div></td> |
| | | </tr> |
| | | </tbody> |
| | | </table> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getServer } from "@/api/monitor/server" |
| | | |
| | | export default { |
| | | name: "Server", |
| | | data() { |
| | | return { |
| | | // 服务器信息 |
| | | server: [] |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | this.openLoading() |
| | | }, |
| | | methods: { |
| | | /** 查询服务器信息 */ |
| | | getList() { |
| | | getServer().then(response => { |
| | | this.server = response.data |
| | | this.$modal.closeLoading() |
| | | }) |
| | | }, |
| | | // 打开加载层 |
| | | openLoading() { |
| | | this.$modal.loading("正在加载服务监控数据,请稍候!") |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <script> |
| | | export default { |
| | | created() { |
| | | const { params, query } = this.$route |
| | | const { path } = params |
| | | this.$router.replace({ path: '/' + path, query }) |
| | | }, |
| | | render: function(h) { |
| | | return h() // avoid warning message |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="register"> |
| | | <el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form"> |
| | | <h3 class="title">{{title}}</h3> |
| | | <el-form-item prop="username"> |
| | | <el-input v-model="registerForm.username" type="text" auto-complete="off" placeholder="账号"> |
| | | <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="password"> |
| | | <el-input |
| | | v-model="registerForm.password" |
| | | type="password" |
| | | auto-complete="off" |
| | | placeholder="密码" |
| | | @keyup.enter.native="handleRegister" |
| | | > |
| | | <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="confirmPassword"> |
| | | <el-input |
| | | v-model="registerForm.confirmPassword" |
| | | type="password" |
| | | auto-complete="off" |
| | | placeholder="确认密码" |
| | | @keyup.enter.native="handleRegister" |
| | | > |
| | | <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> |
| | | </el-input> |
| | | </el-form-item> |
| | | <el-form-item prop="code" v-if="captchaEnabled"> |
| | | <el-input |
| | | v-model="registerForm.code" |
| | | auto-complete="off" |
| | | placeholder="验证码" |
| | | style="width: 63%" |
| | | @keyup.enter.native="handleRegister" |
| | | > |
| | | <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" /> |
| | | </el-input> |
| | | <div class="register-code"> |
| | | <img :src="codeUrl" @click="getCode" class="register-code-img"/> |
| | | </div> |
| | | </el-form-item> |
| | | <el-form-item style="width:100%;"> |
| | | <el-button |
| | | :loading="loading" |
| | | size="medium" |
| | | type="primary" |
| | | style="width:100%;" |
| | | @click.native.prevent="handleRegister" |
| | | > |
| | | <span v-if="!loading">注 册</span> |
| | | <span v-else>注 册 中...</span> |
| | | </el-button> |
| | | <div style="float: right;"> |
| | | <router-link class="link-type" :to="'/login'">使用已有账户登录</router-link> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- 底部 --> |
| | | <div class="el-register-footer"> |
| | | <span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getCodeImg, register } from "@/api/login" |
| | | |
| | | export default { |
| | | name: "Register", |
| | | data() { |
| | | const equalToPassword = (rule, value, callback) => { |
| | | if (this.registerForm.password !== value) { |
| | | callback(new Error("两次输入的密码不一致")) |
| | | } else { |
| | | callback() |
| | | } |
| | | } |
| | | return { |
| | | title: process.env.VUE_APP_TITLE, |
| | | codeUrl: "", |
| | | registerForm: { |
| | | username: "", |
| | | password: "", |
| | | confirmPassword: "", |
| | | code: "", |
| | | uuid: "" |
| | | }, |
| | | registerRules: { |
| | | username: [ |
| | | { required: true, trigger: "blur", message: "请输入您的账号" }, |
| | | { min: 2, max: 20, message: '用户账号长度必须介于 2 和 20 之间', trigger: 'blur' } |
| | | ], |
| | | password: [ |
| | | { required: true, trigger: "blur", message: "请输入您的密码" }, |
| | | { min: 5, max: 20, message: "用户密码长度必须介于 5 和 20 之间", trigger: "blur" }, |
| | | { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" } |
| | | ], |
| | | confirmPassword: [ |
| | | { required: true, trigger: "blur", message: "请再次输入您的密码" }, |
| | | { required: true, validator: equalToPassword, trigger: "blur" } |
| | | ], |
| | | code: [{ required: true, trigger: "change", message: "请输入验证码" }] |
| | | }, |
| | | loading: false, |
| | | captchaEnabled: true |
| | | } |
| | | }, |
| | | created() { |
| | | this.getCode() |
| | | }, |
| | | methods: { |
| | | getCode() { |
| | | getCodeImg().then(res => { |
| | | this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled |
| | | if (this.captchaEnabled) { |
| | | this.codeUrl = "data:image/gif;base64," + res.img |
| | | this.registerForm.uuid = res.uuid |
| | | } |
| | | }) |
| | | }, |
| | | handleRegister() { |
| | | this.$refs.registerForm.validate(valid => { |
| | | if (valid) { |
| | | this.loading = true |
| | | register(this.registerForm).then(res => { |
| | | const username = this.registerForm.username |
| | | this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', { |
| | | dangerouslyUseHTMLString: true, |
| | | type: 'success' |
| | | }).then(() => { |
| | | this.$router.push("/login") |
| | | }).catch(() => {}) |
| | | }).catch(() => { |
| | | this.loading = false |
| | | if (this.captchaEnabled) { |
| | | this.getCode() |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style rel="stylesheet/scss" lang="scss"> |
| | | .register { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | height: 100%; |
| | | background-image: url("../assets/images/login-background.jpg"); |
| | | background-size: cover; |
| | | } |
| | | .title { |
| | | margin: 0px auto 30px auto; |
| | | text-align: center; |
| | | color: #707070; |
| | | } |
| | | |
| | | .register-form { |
| | | border-radius: 6px; |
| | | background: #ffffff; |
| | | width: 400px; |
| | | padding: 25px 25px 5px 25px; |
| | | .el-input { |
| | | height: 38px; |
| | | input { |
| | | height: 38px; |
| | | } |
| | | } |
| | | .input-icon { |
| | | height: 39px; |
| | | width: 14px; |
| | | margin-left: 2px; |
| | | } |
| | | } |
| | | .register-tip { |
| | | font-size: 13px; |
| | | text-align: center; |
| | | color: #bfbfbf; |
| | | } |
| | | .register-code { |
| | | width: 33%; |
| | | height: 38px; |
| | | float: right; |
| | | img { |
| | | cursor: pointer; |
| | | vertical-align: middle; |
| | | } |
| | | } |
| | | .el-register-footer { |
| | | height: 40px; |
| | | line-height: 40px; |
| | | position: fixed; |
| | | bottom: 0; |
| | | width: 100%; |
| | | text-align: center; |
| | | color: #fff; |
| | | font-family: Arial; |
| | | font-size: 12px; |
| | | letter-spacing: 1px; |
| | | } |
| | | .register-code-img { |
| | | height: 38px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="参数名称" prop="configName"> |
| | | <el-input |
| | | v-model="queryParams.configName" |
| | | placeholder="请输入参数名称" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="参数键名" prop="configKey"> |
| | | <el-input |
| | | v-model="queryParams.configKey" |
| | | placeholder="请输入参数键名" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="系统内置" prop="configType"> |
| | | <el-select v-model="queryParams.configType" placeholder="系统内置" clearable> |
| | | <el-option |
| | | v-for="dict in dict.type.sys_yes_no" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="创建时间"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | style="width: 240px" |
| | | value-format="yyyy-MM-dd" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="el-icon-plus" |
| | | size="mini" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:config:add']" |
| | | >新增</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="el-icon-edit" |
| | | size="mini" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['system:config:edit']" |
| | | >修改</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-delete" |
| | | size="mini" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['system:config:remove']" |
| | | >删除</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-download" |
| | | size="mini" |
| | | @click="handleExport" |
| | | v-hasPermi="['system:config:export']" |
| | | >导出</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-refresh" |
| | | size="mini" |
| | | @click="handleRefreshCache" |
| | | v-hasPermi="['system:config:remove']" |
| | | >刷新缓存</el-button> |
| | | </el-col> |
| | | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="参数主键" align="center" prop="configId" /> |
| | | <el-table-column label="参数名称" align="center" prop="configName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="参数键名" align="center" prop="configKey" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="参数键值" align="center" prop="configValue" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="系统内置" align="center" prop="configType"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_yes_no" :value="scope.row.configType"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleUpdate(scope.row)" |
| | | v-hasPermi="['system:config:edit']" |
| | | >修改</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleDelete(scope.row)" |
| | | v-hasPermi="['system:config:remove']" |
| | | >删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- 添加或修改参数配置对话框 --> |
| | | <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> |
| | | <el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="参数名称" prop="configName"> |
| | | <el-input v-model="form.configName" placeholder="请输入参数名称" /> |
| | | </el-form-item> |
| | | <el-form-item label="参数键名" prop="configKey"> |
| | | <el-input v-model="form.configKey" placeholder="请输入参数键名" /> |
| | | </el-form-item> |
| | | <el-form-item label="参数键值" prop="configValue"> |
| | | <el-input v-model="form.configValue" type="textarea" placeholder="请输入参数键值" /> |
| | | </el-form-item> |
| | | <el-form-item label="系统内置" prop="configType"> |
| | | <el-radio-group v-model="form.configType"> |
| | | <el-radio |
| | | v-for="dict in dict.type.sys_yes_no" |
| | | :key="dict.value" |
| | | :label="dict.value" |
| | | >{{dict.label}}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="备注" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确 定</el-button> |
| | | <el-button @click="cancel">取 消</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { listConfig, getConfig, delConfig, addConfig, updateConfig, refreshCache } from "@/api/system/config" |
| | | |
| | | export default { |
| | | name: "Config", |
| | | dicts: ['sys_yes_no'], |
| | | data() { |
| | | return { |
| | | // 遮罩层 |
| | | loading: true, |
| | | // 选中数组 |
| | | ids: [], |
| | | // 非单个禁用 |
| | | single: true, |
| | | // 非多个禁用 |
| | | multiple: true, |
| | | // 显示搜索条件 |
| | | showSearch: true, |
| | | // 总条数 |
| | | total: 0, |
| | | // 参数表格数据 |
| | | configList: [], |
| | | // 弹出层标题 |
| | | title: "", |
| | | // 是否显示弹出层 |
| | | open: false, |
| | | // 日期范围 |
| | | dateRange: [], |
| | | // 查询参数 |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | configName: undefined, |
| | | configKey: undefined, |
| | | configType: undefined |
| | | }, |
| | | // 表单参数 |
| | | form: {}, |
| | | // 表单校验 |
| | | rules: { |
| | | configName: [ |
| | | { required: true, message: "参数名称不能为空", trigger: "blur" } |
| | | ], |
| | | configKey: [ |
| | | { required: true, message: "参数键名不能为空", trigger: "blur" } |
| | | ], |
| | | configValue: [ |
| | | { required: true, message: "参数键值不能为空", trigger: "blur" } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | }, |
| | | methods: { |
| | | /** 查询参数列表 */ |
| | | getList() { |
| | | this.loading = true |
| | | listConfig(this.addDateRange(this.queryParams, this.dateRange)).then(response => { |
| | | this.configList = response.rows |
| | | this.total = response.total |
| | | this.loading = false |
| | | } |
| | | ) |
| | | }, |
| | | // 取消按钮 |
| | | cancel() { |
| | | this.open = false |
| | | this.reset() |
| | | }, |
| | | // 表单重置 |
| | | reset() { |
| | | this.form = { |
| | | configId: undefined, |
| | | configName: undefined, |
| | | configKey: undefined, |
| | | configValue: undefined, |
| | | configType: "Y", |
| | | remark: undefined |
| | | } |
| | | this.resetForm("form") |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.dateRange = [] |
| | | this.resetForm("queryForm") |
| | | this.handleQuery() |
| | | }, |
| | | /** 新增按钮操作 */ |
| | | handleAdd() { |
| | | this.reset() |
| | | this.open = true |
| | | this.title = "添加参数" |
| | | }, |
| | | // 多选框选中数据 |
| | | handleSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.configId) |
| | | this.single = selection.length!=1 |
| | | this.multiple = !selection.length |
| | | }, |
| | | /** 修改按钮操作 */ |
| | | handleUpdate(row) { |
| | | this.reset() |
| | | const configId = row.configId || this.ids |
| | | getConfig(configId).then(response => { |
| | | this.form = response.data |
| | | this.open = true |
| | | this.title = "修改参数" |
| | | }) |
| | | }, |
| | | /** 提交按钮 */ |
| | | submitForm: function() { |
| | | this.$refs["form"].validate(valid => { |
| | | if (valid) { |
| | | if (this.form.configId != undefined) { |
| | | updateConfig(this.form).then(response => { |
| | | this.$modal.msgSuccess("修改成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } else { |
| | | addConfig(this.form).then(response => { |
| | | this.$modal.msgSuccess("新增成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | }, |
| | | /** 删除按钮操作 */ |
| | | handleDelete(row) { |
| | | const configIds = row.configId || this.ids |
| | | this.$modal.confirm('是否确认删除参数编号为"' + configIds + '"的数据项?').then(function() { |
| | | return delConfig(configIds) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("删除成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 导出按钮操作 */ |
| | | handleExport() { |
| | | this.download('system/config/export', { |
| | | ...this.queryParams |
| | | }, `config_${new Date().getTime()}.xlsx`) |
| | | }, |
| | | /** 刷新缓存按钮操作 */ |
| | | handleRefreshCache() { |
| | | refreshCache().then(() => { |
| | | this.$modal.msgSuccess("刷新成功") |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"> |
| | | <el-form-item label="部门名称" prop="deptName"> |
| | | <el-input |
| | | v-model="queryParams.deptName" |
| | | placeholder="请输入部门名称" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="状态" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="部门状态" clearable> |
| | | <el-option |
| | | v-for="dict in dict.type.sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="el-icon-plus" |
| | | size="mini" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:dept:add']" |
| | | >新增</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="info" |
| | | plain |
| | | icon="el-icon-sort" |
| | | size="mini" |
| | | @click="toggleExpandAll" |
| | | >展开/折叠</el-button> |
| | | </el-col> |
| | | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table |
| | | v-if="refreshTable" |
| | | v-loading="loading" |
| | | :data="deptList" |
| | | row-key="deptId" |
| | | :default-expand-all="isExpandAll" |
| | | :tree-props="{children: 'children', hasChildren: 'hasChildren'}" |
| | | > |
| | | <el-table-column prop="deptName" label="部门名称" width="260"></el-table-column> |
| | | <el-table-column prop="orderNum" label="排序" width="200"></el-table-column> |
| | | <el-table-column prop="status" label="状态" width="100"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="创建时间" align="center" prop="createTime" width="200"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleUpdate(scope.row)" |
| | | v-hasPermi="['system:dept:edit']" |
| | | >修改</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-plus" |
| | | @click="handleAdd(scope.row)" |
| | | v-hasPermi="['system:dept:add']" |
| | | >新增</el-button> |
| | | <el-button |
| | | v-if="scope.row.parentId != 0" |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleDelete(scope.row)" |
| | | v-hasPermi="['system:dept:remove']" |
| | | >删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- 添加或修改部门对话框 --> |
| | | <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body> |
| | | <el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
| | | <el-row> |
| | | <el-col :span="24" v-if="form.parentId !== 0"> |
| | | <el-form-item label="上级部门" prop="parentId"> |
| | | <treeselect v-model="form.parentId" :options="deptOptions" :normalizer="normalizer" placeholder="选择上级部门" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="部门名称" prop="deptName"> |
| | | <el-input v-model="form.deptName" placeholder="请输入部门名称" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="显示排序" prop="orderNum"> |
| | | <el-input-number v-model="form.orderNum" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="负责人" prop="leader"> |
| | | <el-input v-model="form.leader" placeholder="请输入负责人" maxlength="20" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="联系电话" prop="phone"> |
| | | <el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="邮箱" prop="email"> |
| | | <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="部门状态"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in dict.type.sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.value" |
| | | >{{dict.label}}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确 定</el-button> |
| | | <el-button @click="cancel">取 消</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept" |
| | | import Treeselect from "@riophae/vue-treeselect" |
| | | import "@riophae/vue-treeselect/dist/vue-treeselect.css" |
| | | |
| | | export default { |
| | | name: "Dept", |
| | | dicts: ['sys_normal_disable'], |
| | | components: { Treeselect }, |
| | | data() { |
| | | return { |
| | | // 遮罩层 |
| | | loading: true, |
| | | // 显示搜索条件 |
| | | showSearch: true, |
| | | // 表格树数据 |
| | | deptList: [], |
| | | // 部门树选项 |
| | | deptOptions: [], |
| | | // 弹出层标题 |
| | | title: "", |
| | | // 是否显示弹出层 |
| | | open: false, |
| | | // 是否展开,默认全部展开 |
| | | isExpandAll: true, |
| | | // 重新渲染表格状态 |
| | | refreshTable: true, |
| | | // 查询参数 |
| | | queryParams: { |
| | | deptName: undefined, |
| | | status: undefined |
| | | }, |
| | | // 表单参数 |
| | | form: {}, |
| | | // 表单校验 |
| | | rules: { |
| | | parentId: [ |
| | | { required: true, message: "上级部门不能为空", trigger: "blur" } |
| | | ], |
| | | deptName: [ |
| | | { required: true, message: "部门名称不能为空", trigger: "blur" } |
| | | ], |
| | | orderNum: [ |
| | | { required: true, message: "显示排序不能为空", trigger: "blur" } |
| | | ], |
| | | email: [ |
| | | { |
| | | type: "email", |
| | | message: "请输入正确的邮箱地址", |
| | | trigger: ["blur", "change"] |
| | | } |
| | | ], |
| | | phone: [ |
| | | { |
| | | pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, |
| | | message: "请输入正确的手机号码", |
| | | trigger: "blur" |
| | | } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | }, |
| | | methods: { |
| | | /** 查询部门列表 */ |
| | | getList() { |
| | | this.loading = true |
| | | listDept(this.queryParams).then(response => { |
| | | this.deptList = this.handleTree(response.data, "deptId") |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | /** 转换部门数据结构 */ |
| | | normalizer(node) { |
| | | if (node.children && !node.children.length) { |
| | | delete node.children |
| | | } |
| | | return { |
| | | id: node.deptId, |
| | | label: node.deptName, |
| | | children: node.children |
| | | } |
| | | }, |
| | | // 取消按钮 |
| | | cancel() { |
| | | this.open = false |
| | | this.reset() |
| | | }, |
| | | // 表单重置 |
| | | reset() { |
| | | this.form = { |
| | | deptId: undefined, |
| | | parentId: undefined, |
| | | deptName: undefined, |
| | | orderNum: undefined, |
| | | leader: undefined, |
| | | phone: undefined, |
| | | email: undefined, |
| | | status: "0" |
| | | } |
| | | this.resetForm("form") |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.getList() |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.resetForm("queryForm") |
| | | this.handleQuery() |
| | | }, |
| | | /** 新增按钮操作 */ |
| | | handleAdd(row) { |
| | | this.reset() |
| | | if (row != undefined) { |
| | | this.form.parentId = row.deptId |
| | | } |
| | | this.open = true |
| | | this.title = "添加部门" |
| | | listDept().then(response => { |
| | | this.deptOptions = this.handleTree(response.data, "deptId") |
| | | }) |
| | | }, |
| | | /** 展开/折叠操作 */ |
| | | toggleExpandAll() { |
| | | this.refreshTable = false |
| | | this.isExpandAll = !this.isExpandAll |
| | | this.$nextTick(() => { |
| | | this.refreshTable = true |
| | | }) |
| | | }, |
| | | /** 修改按钮操作 */ |
| | | handleUpdate(row) { |
| | | this.reset() |
| | | getDept(row.deptId).then(response => { |
| | | this.form = response.data |
| | | this.open = true |
| | | this.title = "修改部门" |
| | | listDeptExcludeChild(row.deptId).then(response => { |
| | | this.deptOptions = this.handleTree(response.data, "deptId") |
| | | if (this.deptOptions.length == 0) { |
| | | const noResultsOptions = { deptId: this.form.parentId, deptName: this.form.parentName, children: [] } |
| | | this.deptOptions.push(noResultsOptions) |
| | | } |
| | | }) |
| | | }) |
| | | }, |
| | | /** 提交按钮 */ |
| | | submitForm: function() { |
| | | this.$refs["form"].validate(valid => { |
| | | if (valid) { |
| | | if (this.form.deptId != undefined) { |
| | | updateDept(this.form).then(response => { |
| | | this.$modal.msgSuccess("修改成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } else { |
| | | addDept(this.form).then(response => { |
| | | this.$modal.msgSuccess("新增成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | }, |
| | | /** 删除按钮操作 */ |
| | | handleDelete(row) { |
| | | this.$modal.confirm('是否确认删除名称为"' + row.deptName + '"的数据项?').then(function() { |
| | | return delDept(row.deptId) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("删除成功") |
| | | }).catch(() => {}) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="字典名称" prop="dictType"> |
| | | <el-select v-model="queryParams.dictType"> |
| | | <el-option |
| | | v-for="item in typeOptions" |
| | | :key="item.dictId" |
| | | :label="item.dictName" |
| | | :value="item.dictType" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="字典标签" prop="dictLabel"> |
| | | <el-input |
| | | v-model="queryParams.dictLabel" |
| | | placeholder="请输入字典标签" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="状态" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="数据状态" clearable> |
| | | <el-option |
| | | v-for="dict in dict.type.sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="el-icon-plus" |
| | | size="mini" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:dict:add']" |
| | | >新增</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="el-icon-edit" |
| | | size="mini" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['system:dict:edit']" |
| | | >修改</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-delete" |
| | | size="mini" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['system:dict:remove']" |
| | | >删除</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-download" |
| | | size="mini" |
| | | @click="handleExport" |
| | | v-hasPermi="['system:dict:export']" |
| | | >导出</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-close" |
| | | size="mini" |
| | | @click="handleClose" |
| | | >关闭</el-button> |
| | | </el-col> |
| | | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="字典编码" align="center" prop="dictCode" /> |
| | | <el-table-column label="字典标签" align="center" prop="dictLabel"> |
| | | <template slot-scope="scope"> |
| | | <span v-if="(scope.row.listClass == '' || scope.row.listClass == 'default') && (scope.row.cssClass == '' || scope.row.cssClass == null)">{{ scope.row.dictLabel }}</span> |
| | | <el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass" :class="scope.row.cssClass">{{ scope.row.dictLabel }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="字典键值" align="center" prop="dictValue" /> |
| | | <el-table-column label="字典排序" align="center" prop="dictSort" /> |
| | | <el-table-column label="状态" align="center" prop="status"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleUpdate(scope.row)" |
| | | v-hasPermi="['system:dict:edit']" |
| | | >修改</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleDelete(scope.row)" |
| | | v-hasPermi="['system:dict:remove']" |
| | | >删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- 添加或修改参数配置对话框 --> |
| | | <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> |
| | | <el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="字典类型"> |
| | | <el-input v-model="form.dictType" :disabled="true" /> |
| | | </el-form-item> |
| | | <el-form-item label="数据标签" prop="dictLabel"> |
| | | <el-input v-model="form.dictLabel" placeholder="请输入数据标签" /> |
| | | </el-form-item> |
| | | <el-form-item label="数据键值" prop="dictValue"> |
| | | <el-input v-model="form.dictValue" placeholder="请输入数据键值" /> |
| | | </el-form-item> |
| | | <el-form-item label="样式属性" prop="cssClass"> |
| | | <el-input v-model="form.cssClass" placeholder="请输入样式属性" /> |
| | | </el-form-item> |
| | | <el-form-item label="显示排序" prop="dictSort"> |
| | | <el-input-number v-model="form.dictSort" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | <el-form-item label="回显样式" prop="listClass"> |
| | | <el-select v-model="form.listClass"> |
| | | <el-option |
| | | v-for="item in listClassOptions" |
| | | :key="item.value" |
| | | :label="item.label + '(' + item.value + ')'" |
| | | :value="item.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="状态" prop="status"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in dict.type.sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.value" |
| | | >{{dict.label}}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="备注" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确 定</el-button> |
| | | <el-button @click="cancel">取 消</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { listData, getData, delData, addData, updateData } from "@/api/system/dict/data" |
| | | import { optionselect as getDictOptionselect, getType } from "@/api/system/dict/type" |
| | | |
| | | export default { |
| | | name: "Data", |
| | | dicts: ['sys_normal_disable'], |
| | | data() { |
| | | return { |
| | | // 遮罩层 |
| | | loading: true, |
| | | // 选中数组 |
| | | ids: [], |
| | | // 非单个禁用 |
| | | single: true, |
| | | // 非多个禁用 |
| | | multiple: true, |
| | | // 显示搜索条件 |
| | | showSearch: true, |
| | | // 总条数 |
| | | total: 0, |
| | | // 字典表格数据 |
| | | dataList: [], |
| | | // 默认字典类型 |
| | | defaultDictType: "", |
| | | // 弹出层标题 |
| | | title: "", |
| | | // 是否显示弹出层 |
| | | open: false, |
| | | // 数据标签回显样式 |
| | | listClassOptions: [ |
| | | { |
| | | value: "default", |
| | | label: "默认" |
| | | }, |
| | | { |
| | | value: "primary", |
| | | label: "主要" |
| | | }, |
| | | { |
| | | value: "success", |
| | | label: "成功" |
| | | }, |
| | | { |
| | | value: "info", |
| | | label: "信息" |
| | | }, |
| | | { |
| | | value: "warning", |
| | | label: "警告" |
| | | }, |
| | | { |
| | | value: "danger", |
| | | label: "危险" |
| | | } |
| | | ], |
| | | // 类型数据字典 |
| | | typeOptions: [], |
| | | // 查询参数 |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | dictType: undefined, |
| | | dictLabel: undefined, |
| | | status: undefined |
| | | }, |
| | | // 表单参数 |
| | | form: {}, |
| | | // 表单校验 |
| | | rules: { |
| | | dictLabel: [ |
| | | { required: true, message: "数据标签不能为空", trigger: "blur" } |
| | | ], |
| | | dictValue: [ |
| | | { required: true, message: "数据键值不能为空", trigger: "blur" } |
| | | ], |
| | | dictSort: [ |
| | | { required: true, message: "数据顺序不能为空", trigger: "blur" } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | const dictId = this.$route.params && this.$route.params.dictId |
| | | this.getType(dictId) |
| | | this.getTypeList() |
| | | }, |
| | | methods: { |
| | | /** 查询字典类型详细 */ |
| | | getType(dictId) { |
| | | getType(dictId).then(response => { |
| | | this.queryParams.dictType = response.data.dictType |
| | | this.defaultDictType = response.data.dictType |
| | | this.getList() |
| | | }) |
| | | }, |
| | | /** 查询字典类型列表 */ |
| | | getTypeList() { |
| | | getDictOptionselect().then(response => { |
| | | this.typeOptions = response.data |
| | | }) |
| | | }, |
| | | /** 查询字典数据列表 */ |
| | | getList() { |
| | | this.loading = true |
| | | listData(this.queryParams).then(response => { |
| | | this.dataList = response.rows |
| | | this.total = response.total |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | // 取消按钮 |
| | | cancel() { |
| | | this.open = false |
| | | this.reset() |
| | | }, |
| | | // 表单重置 |
| | | reset() { |
| | | this.form = { |
| | | dictCode: undefined, |
| | | dictLabel: undefined, |
| | | dictValue: undefined, |
| | | cssClass: undefined, |
| | | listClass: 'default', |
| | | dictSort: 0, |
| | | status: "0", |
| | | remark: undefined |
| | | } |
| | | this.resetForm("form") |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | /** 返回按钮操作 */ |
| | | handleClose() { |
| | | const obj = { path: "/system/dict" } |
| | | this.$tab.closeOpenPage(obj) |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.resetForm("queryForm") |
| | | this.queryParams.dictType = this.defaultDictType |
| | | this.handleQuery() |
| | | }, |
| | | /** 新增按钮操作 */ |
| | | handleAdd() { |
| | | this.reset() |
| | | this.open = true |
| | | this.title = "添加字典数据" |
| | | this.form.dictType = this.queryParams.dictType |
| | | }, |
| | | // 多选框选中数据 |
| | | handleSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.dictCode) |
| | | this.single = selection.length!=1 |
| | | this.multiple = !selection.length |
| | | }, |
| | | /** 修改按钮操作 */ |
| | | handleUpdate(row) { |
| | | this.reset() |
| | | const dictCode = row.dictCode || this.ids |
| | | getData(dictCode).then(response => { |
| | | this.form = response.data |
| | | this.open = true |
| | | this.title = "修改字典数据" |
| | | }) |
| | | }, |
| | | /** 提交按钮 */ |
| | | submitForm: function() { |
| | | this.$refs["form"].validate(valid => { |
| | | if (valid) { |
| | | if (this.form.dictCode != undefined) { |
| | | updateData(this.form).then(response => { |
| | | this.$store.dispatch('dict/removeDict', this.queryParams.dictType) |
| | | this.$modal.msgSuccess("修改成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } else { |
| | | addData(this.form).then(response => { |
| | | this.$store.dispatch('dict/removeDict', this.queryParams.dictType) |
| | | this.$modal.msgSuccess("新增成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | }, |
| | | /** 删除按钮操作 */ |
| | | handleDelete(row) { |
| | | const dictCodes = row.dictCode || this.ids |
| | | this.$modal.confirm('是否确认删除字典编码为"' + dictCodes + '"的数据项?').then(function() { |
| | | return delData(dictCodes) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("删除成功") |
| | | this.$store.dispatch('dict/removeDict', this.queryParams.dictType) |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 导出按钮操作 */ |
| | | handleExport() { |
| | | this.download('system/dict/data/export', { |
| | | ...this.queryParams |
| | | }, `data_${new Date().getTime()}.xlsx`) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> |
| | | <el-form-item label="字典名称" prop="dictName"> |
| | | <el-input |
| | | v-model="queryParams.dictName" |
| | | placeholder="请输入字典名称" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="字典类型" prop="dictType"> |
| | | <el-input |
| | | v-model="queryParams.dictType" |
| | | placeholder="请输入字典类型" |
| | | clearable |
| | | style="width: 240px" |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="状态" prop="status"> |
| | | <el-select |
| | | v-model="queryParams.status" |
| | | placeholder="字典状态" |
| | | clearable |
| | | style="width: 240px" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="创建时间"> |
| | | <el-date-picker |
| | | v-model="dateRange" |
| | | style="width: 240px" |
| | | value-format="yyyy-MM-dd" |
| | | type="daterange" |
| | | range-separator="-" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | ></el-date-picker> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="el-icon-plus" |
| | | size="mini" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:dict:add']" |
| | | >新增</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="el-icon-edit" |
| | | size="mini" |
| | | :disabled="single" |
| | | @click="handleUpdate" |
| | | v-hasPermi="['system:dict:edit']" |
| | | >修改</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-delete" |
| | | size="mini" |
| | | :disabled="multiple" |
| | | @click="handleDelete" |
| | | v-hasPermi="['system:dict:remove']" |
| | | >删除</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="warning" |
| | | plain |
| | | icon="el-icon-download" |
| | | size="mini" |
| | | @click="handleExport" |
| | | v-hasPermi="['system:dict:export']" |
| | | >导出</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-refresh" |
| | | size="mini" |
| | | @click="handleRefreshCache" |
| | | v-hasPermi="['system:dict:remove']" |
| | | >刷新缓存</el-button> |
| | | </el-col> |
| | | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column label="字典编号" align="center" prop="dictId" /> |
| | | <el-table-column label="字典名称" align="center" prop="dictName" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="字典类型" align="center" :show-overflow-tooltip="true"> |
| | | <template slot-scope="scope"> |
| | | <router-link :to="'/system/dict-data/index/' + scope.row.dictId" class="link-type"> |
| | | <span>{{ scope.row.dictType }}</span> |
| | | </router-link> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="状态" align="center" prop="status"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" /> |
| | | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleUpdate(scope.row)" |
| | | v-hasPermi="['system:dict:edit']" |
| | | >修改</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleDelete(scope.row)" |
| | | v-hasPermi="['system:dict:remove']" |
| | | >删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <pagination |
| | | v-show="total>0" |
| | | :total="total" |
| | | :page.sync="queryParams.pageNum" |
| | | :limit.sync="queryParams.pageSize" |
| | | @pagination="getList" |
| | | /> |
| | | |
| | | <!-- 添加或修改参数配置对话框 --> |
| | | <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> |
| | | <el-form ref="form" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="字典名称" prop="dictName"> |
| | | <el-input v-model="form.dictName" placeholder="请输入字典名称" /> |
| | | </el-form-item> |
| | | <el-form-item label="字典类型" prop="dictType"> |
| | | <el-input v-model="form.dictType" placeholder="请输入字典类型" /> |
| | | </el-form-item> |
| | | <el-form-item label="状态" prop="status"> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in dict.type.sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.value" |
| | | >{{dict.label}}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="备注" prop="remark"> |
| | | <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确 定</el-button> |
| | | <el-button @click="cancel">取 消</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { listType, getType, delType, addType, updateType, refreshCache } from "@/api/system/dict/type" |
| | | |
| | | export default { |
| | | name: "Dict", |
| | | dicts: ['sys_normal_disable'], |
| | | data() { |
| | | return { |
| | | // 遮罩层 |
| | | loading: true, |
| | | // 选中数组 |
| | | ids: [], |
| | | // 非单个禁用 |
| | | single: true, |
| | | // 非多个禁用 |
| | | multiple: true, |
| | | // 显示搜索条件 |
| | | showSearch: true, |
| | | // 总条数 |
| | | total: 0, |
| | | // 字典表格数据 |
| | | typeList: [], |
| | | // 弹出层标题 |
| | | title: "", |
| | | // 是否显示弹出层 |
| | | open: false, |
| | | // 日期范围 |
| | | dateRange: [], |
| | | // 查询参数 |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | dictName: undefined, |
| | | dictType: undefined, |
| | | status: undefined |
| | | }, |
| | | // 表单参数 |
| | | form: {}, |
| | | // 表单校验 |
| | | rules: { |
| | | dictName: [ |
| | | { required: true, message: "字典名称不能为空", trigger: "blur" } |
| | | ], |
| | | dictType: [ |
| | | { required: true, message: "字典类型不能为空", trigger: "blur" } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | }, |
| | | methods: { |
| | | /** 查询字典类型列表 */ |
| | | getList() { |
| | | this.loading = true |
| | | listType(this.addDateRange(this.queryParams, this.dateRange)).then(response => { |
| | | this.typeList = response.rows |
| | | this.total = response.total |
| | | this.loading = false |
| | | } |
| | | ) |
| | | }, |
| | | // 取消按钮 |
| | | cancel() { |
| | | this.open = false |
| | | this.reset() |
| | | }, |
| | | // 表单重置 |
| | | reset() { |
| | | this.form = { |
| | | dictId: undefined, |
| | | dictName: undefined, |
| | | dictType: undefined, |
| | | status: "0", |
| | | remark: undefined |
| | | } |
| | | this.resetForm("form") |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.queryParams.pageNum = 1 |
| | | this.getList() |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.dateRange = [] |
| | | this.resetForm("queryForm") |
| | | this.handleQuery() |
| | | }, |
| | | /** 新增按钮操作 */ |
| | | handleAdd() { |
| | | this.reset() |
| | | this.open = true |
| | | this.title = "添加字典类型" |
| | | }, |
| | | // 多选框选中数据 |
| | | handleSelectionChange(selection) { |
| | | this.ids = selection.map(item => item.dictId) |
| | | this.single = selection.length!=1 |
| | | this.multiple = !selection.length |
| | | }, |
| | | /** 修改按钮操作 */ |
| | | handleUpdate(row) { |
| | | this.reset() |
| | | const dictId = row.dictId || this.ids |
| | | getType(dictId).then(response => { |
| | | this.form = response.data |
| | | this.open = true |
| | | this.title = "修改字典类型" |
| | | }) |
| | | }, |
| | | /** 提交按钮 */ |
| | | submitForm: function() { |
| | | this.$refs["form"].validate(valid => { |
| | | if (valid) { |
| | | if (this.form.dictId != undefined) { |
| | | updateType(this.form).then(response => { |
| | | this.$modal.msgSuccess("修改成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } else { |
| | | addType(this.form).then(response => { |
| | | this.$modal.msgSuccess("新增成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | }, |
| | | /** 删除按钮操作 */ |
| | | handleDelete(row) { |
| | | const dictIds = row.dictId || this.ids |
| | | this.$modal.confirm('是否确认删除字典编号为"' + dictIds + '"的数据项?').then(function() { |
| | | return delType(dictIds) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("删除成功") |
| | | }).catch(() => {}) |
| | | }, |
| | | /** 导出按钮操作 */ |
| | | handleExport() { |
| | | this.download('system/dict/type/export', { |
| | | ...this.queryParams |
| | | }, `type_${new Date().getTime()}.xlsx`) |
| | | }, |
| | | /** 刷新缓存按钮操作 */ |
| | | handleRefreshCache() { |
| | | refreshCache().then(() => { |
| | | this.$modal.msgSuccess("刷新成功") |
| | | this.$store.dispatch('dict/cleanDict') |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"> |
| | | <el-form-item label="菜单名称" prop="menuName"> |
| | | <el-input |
| | | v-model="queryParams.menuName" |
| | | placeholder="请输入菜单名称" |
| | | clearable |
| | | @keyup.enter.native="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="状态" prop="status"> |
| | | <el-select v-model="queryParams.status" placeholder="菜单状态" clearable> |
| | | <el-option |
| | | v-for="dict in dict.type.sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="primary" |
| | | plain |
| | | icon="el-icon-plus" |
| | | size="mini" |
| | | @click="handleAdd" |
| | | v-hasPermi="['system:menu:add']" |
| | | >新增</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | type="info" |
| | | plain |
| | | icon="el-icon-sort" |
| | | size="mini" |
| | | @click="toggleExpandAll" |
| | | >展开/折叠</el-button> |
| | | </el-col> |
| | | <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | |
| | | <el-table |
| | | v-if="refreshTable" |
| | | v-loading="loading" |
| | | :data="menuList" |
| | | row-key="menuId" |
| | | :default-expand-all="isExpandAll" |
| | | :tree-props="{children: 'children', hasChildren: 'hasChildren'}" |
| | | > |
| | | <el-table-column prop="menuName" label="菜单名称" :show-overflow-tooltip="true" width="160"></el-table-column> |
| | | <el-table-column prop="icon" label="图标" align="center" width="100"> |
| | | <template slot-scope="scope"> |
| | | <svg-icon :icon-class="scope.row.icon" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="orderNum" label="排序" width="60"></el-table-column> |
| | | <el-table-column prop="perms" label="权限标识" :show-overflow-tooltip="true"></el-table-column> |
| | | <el-table-column prop="component" label="组件路径" :show-overflow-tooltip="true"></el-table-column> |
| | | <el-table-column prop="status" label="状态" width="80"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_normal_disable" :value="scope.row.status"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="创建时间" align="center" prop="createTime"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-edit" |
| | | @click="handleUpdate(scope.row)" |
| | | v-hasPermi="['system:menu:edit']" |
| | | >修改</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-plus" |
| | | @click="handleAdd(scope.row)" |
| | | v-hasPermi="['system:menu:add']" |
| | | >新增</el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | @click="handleDelete(scope.row)" |
| | | v-hasPermi="['system:menu:remove']" |
| | | >删除</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- 添加或修改菜单对话框 --> |
| | | <el-dialog :title="title" :visible.sync="open" width="680px" append-to-body> |
| | | <el-form ref="form" :model="form" :rules="rules" label-width="100px"> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="上级菜单" prop="parentId"> |
| | | <treeselect |
| | | v-model="form.parentId" |
| | | :options="menuOptions" |
| | | :normalizer="normalizer" |
| | | :show-count="true" |
| | | placeholder="选择上级菜单" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="24"> |
| | | <el-form-item label="菜单类型" prop="menuType"> |
| | | <el-radio-group v-model="form.menuType"> |
| | | <el-radio label="M">目录</el-radio> |
| | | <el-radio label="C">菜单</el-radio> |
| | | <el-radio label="F">按钮</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12" v-if="form.menuType != 'F'"> |
| | | <el-form-item label="菜单图标" prop="icon"> |
| | | <el-popover |
| | | placement="bottom-start" |
| | | width="460" |
| | | trigger="click" |
| | | @show="$refs['iconSelect'].reset()" |
| | | > |
| | | <IconSelect ref="iconSelect" @selected="selected" :active-icon="form.icon" /> |
| | | <el-input slot="reference" v-model="form.icon" placeholder="点击选择图标" readonly> |
| | | <svg-icon |
| | | v-if="form.icon" |
| | | slot="prefix" |
| | | :icon-class="form.icon" |
| | | style="width: 25px;" |
| | | /> |
| | | <i v-else slot="prefix" class="el-icon-search el-input__icon" /> |
| | | </el-input> |
| | | </el-popover> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="显示排序" prop="orderNum"> |
| | | <el-input-number v-model="form.orderNum" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-form-item label="菜单名称" prop="menuName"> |
| | | <el-input v-model="form.menuName" placeholder="请输入菜单名称" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType == 'C'"> |
| | | <el-form-item prop="routeName"> |
| | | <el-input v-model="form.routeName" placeholder="请输入路由名称" /> |
| | | <span slot="label"> |
| | | <el-tooltip content="默认不填则和路由地址相同:如地址为:`user`,则名称为`User`(注意:为避免名字的冲突,特殊情况下请自定义,保证唯一性)" placement="top"> |
| | | <i class="el-icon-question"></i> |
| | | </el-tooltip> |
| | | 路由名称 |
| | | </span> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12" v-if="form.menuType != 'F'"> |
| | | <el-form-item prop="isFrame"> |
| | | <span slot="label"> |
| | | <el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top"> |
| | | <i class="el-icon-question"></i> |
| | | </el-tooltip> |
| | | 是否外链 |
| | | </span> |
| | | <el-radio-group v-model="form.isFrame"> |
| | | <el-radio label="0">是</el-radio> |
| | | <el-radio label="1">否</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType != 'F'"> |
| | | <el-form-item prop="path"> |
| | | <span slot="label"> |
| | | <el-tooltip content="访问的路由地址,如:`user`,如外网地址需内链访问则以`http(s)://`开头" placement="top"> |
| | | <i class="el-icon-question"></i> |
| | | </el-tooltip> |
| | | 路由地址 |
| | | </span> |
| | | <el-input v-model="form.path" placeholder="请输入路由地址" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12" v-if="form.menuType == 'C'"> |
| | | <el-form-item prop="component"> |
| | | <span slot="label"> |
| | | <el-tooltip content="访问的组件路径,如:`system/user/index`,默认在`views`目录下" placement="top"> |
| | | <i class="el-icon-question"></i> |
| | | </el-tooltip> |
| | | 组件路径 |
| | | </span> |
| | | <el-input v-model="form.component" placeholder="请输入组件路径" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType != 'M'"> |
| | | <el-form-item prop="perms"> |
| | | <el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="100" /> |
| | | <span slot="label"> |
| | | <el-tooltip content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top"> |
| | | <i class="el-icon-question"></i> |
| | | </el-tooltip> |
| | | 权限字符 |
| | | </span> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12" v-if="form.menuType == 'C'"> |
| | | <el-form-item prop="query"> |
| | | <el-input v-model="form.query" placeholder="请输入路由参数" maxlength="255" /> |
| | | <span slot="label"> |
| | | <el-tooltip content='访问路由的默认传递参数,如:`{"id": 1, "name": "ry"}`' placement="top"> |
| | | <i class="el-icon-question"></i> |
| | | </el-tooltip> |
| | | 路由参数 |
| | | </span> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12" v-if="form.menuType == 'C'"> |
| | | <el-form-item prop="isCache"> |
| | | <span slot="label"> |
| | | <el-tooltip content="选择是则会被`keep-alive`缓存,需要匹配组件的`name`和地址保持一致" placement="top"> |
| | | <i class="el-icon-question"></i> |
| | | </el-tooltip> |
| | | 是否缓存 |
| | | </span> |
| | | <el-radio-group v-model="form.isCache"> |
| | | <el-radio label="0">缓存</el-radio> |
| | | <el-radio label="1">不缓存</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="12" v-if="form.menuType != 'F'"> |
| | | <el-form-item prop="visible"> |
| | | <span slot="label"> |
| | | <el-tooltip content="选择隐藏则路由将不会出现在侧边栏,但仍然可以访问" placement="top"> |
| | | <i class="el-icon-question"></i> |
| | | </el-tooltip> |
| | | 显示状态 |
| | | </span> |
| | | <el-radio-group v-model="form.visible"> |
| | | <el-radio |
| | | v-for="dict in dict.type.sys_show_hide" |
| | | :key="dict.value" |
| | | :label="dict.value" |
| | | >{{dict.label}}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item prop="status"> |
| | | <span slot="label"> |
| | | <el-tooltip content="选择停用则路由将不会出现在侧边栏,也不能被访问" placement="top"> |
| | | <i class="el-icon-question"></i> |
| | | </el-tooltip> |
| | | 菜单状态 |
| | | </span> |
| | | <el-radio-group v-model="form.status"> |
| | | <el-radio |
| | | v-for="dict in dict.type.sys_normal_disable" |
| | | :key="dict.value" |
| | | :label="dict.value" |
| | | >{{dict.label}}</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确 定</el-button> |
| | | <el-button @click="cancel">取 消</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { listMenu, getMenu, delMenu, addMenu, updateMenu } from "@/api/system/menu" |
| | | import Treeselect from "@riophae/vue-treeselect" |
| | | import "@riophae/vue-treeselect/dist/vue-treeselect.css" |
| | | import IconSelect from "@/components/IconSelect" |
| | | |
| | | export default { |
| | | name: "Menu", |
| | | dicts: ['sys_show_hide', 'sys_normal_disable'], |
| | | components: { Treeselect, IconSelect }, |
| | | data() { |
| | | return { |
| | | // 遮罩层 |
| | | loading: true, |
| | | // 显示搜索条件 |
| | | showSearch: true, |
| | | // 菜单表格树数据 |
| | | menuList: [], |
| | | // 菜单树选项 |
| | | menuOptions: [], |
| | | // 弹出层标题 |
| | | title: "", |
| | | // 是否显示弹出层 |
| | | open: false, |
| | | // 是否展开,默认全部折叠 |
| | | isExpandAll: false, |
| | | // 重新渲染表格状态 |
| | | refreshTable: true, |
| | | // 查询参数 |
| | | queryParams: { |
| | | menuName: undefined, |
| | | visible: undefined |
| | | }, |
| | | // 表单参数 |
| | | form: {}, |
| | | // 表单校验 |
| | | rules: { |
| | | menuName: [ |
| | | { required: true, message: "菜单名称不能为空", trigger: "blur" } |
| | | ], |
| | | orderNum: [ |
| | | { required: true, message: "菜单顺序不能为空", trigger: "blur" } |
| | | ], |
| | | path: [ |
| | | { required: true, message: "路由地址不能为空", trigger: "blur" } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | created() { |
| | | this.getList() |
| | | }, |
| | | methods: { |
| | | // 选择图标 |
| | | selected(name) { |
| | | this.form.icon = name |
| | | }, |
| | | /** 查询菜单列表 */ |
| | | getList() { |
| | | this.loading = true |
| | | listMenu(this.queryParams).then(response => { |
| | | this.menuList = this.handleTree(response.data, "menuId") |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | /** 转换菜单数据结构 */ |
| | | normalizer(node) { |
| | | if (node.children && !node.children.length) { |
| | | delete node.children |
| | | } |
| | | return { |
| | | id: node.menuId, |
| | | label: node.menuName, |
| | | children: node.children |
| | | } |
| | | }, |
| | | /** 查询菜单下拉树结构 */ |
| | | getTreeselect() { |
| | | listMenu().then(response => { |
| | | this.menuOptions = [] |
| | | const menu = { menuId: 0, menuName: '主类目', children: [] } |
| | | menu.children = this.handleTree(response.data, "menuId") |
| | | this.menuOptions.push(menu) |
| | | }) |
| | | }, |
| | | // 取消按钮 |
| | | cancel() { |
| | | this.open = false |
| | | this.reset() |
| | | }, |
| | | // 表单重置 |
| | | reset() { |
| | | this.form = { |
| | | menuId: undefined, |
| | | parentId: 0, |
| | | menuName: undefined, |
| | | icon: undefined, |
| | | menuType: "M", |
| | | orderNum: undefined, |
| | | isFrame: "1", |
| | | isCache: "0", |
| | | visible: "0", |
| | | status: "0" |
| | | } |
| | | this.resetForm("form") |
| | | }, |
| | | /** 搜索按钮操作 */ |
| | | handleQuery() { |
| | | this.getList() |
| | | }, |
| | | /** 重置按钮操作 */ |
| | | resetQuery() { |
| | | this.resetForm("queryForm") |
| | | this.handleQuery() |
| | | }, |
| | | /** 新增按钮操作 */ |
| | | handleAdd(row) { |
| | | this.reset() |
| | | this.getTreeselect() |
| | | if (row != null && row.menuId) { |
| | | this.form.parentId = row.menuId |
| | | } else { |
| | | this.form.parentId = 0 |
| | | } |
| | | this.open = true |
| | | this.title = "添加菜单" |
| | | }, |
| | | /** 展开/折叠操作 */ |
| | | toggleExpandAll() { |
| | | this.refreshTable = false |
| | | this.isExpandAll = !this.isExpandAll |
| | | this.$nextTick(() => { |
| | | this.refreshTable = true |
| | | }) |
| | | }, |
| | | /** 修改按钮操作 */ |
| | | handleUpdate(row) { |
| | | this.reset() |
| | | this.getTreeselect() |
| | | getMenu(row.menuId).then(response => { |
| | | this.form = response.data |
| | | this.open = true |
| | | this.title = "修改菜单" |
| | | }) |
| | | }, |
| | | /** 提交按钮 */ |
| | | submitForm: function() { |
| | | this.$refs["form"].validate(valid => { |
| | | if (valid) { |
| | | if (this.form.menuId != undefined) { |
| | | updateMenu(this.form).then(response => { |
| | | this.$modal.msgSuccess("修改成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } else { |
| | | addMenu(this.form).then(response => { |
| | | this.$modal.msgSuccess("新增成功") |
| | | this.open = false |
| | | this.getList() |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | }, |
| | | /** 删除按钮操作 */ |
| | | handleDelete(row) { |
| | | this.$modal.confirm('是否确认删除名称为"' + row.menuName + '"的数据项?').then(function() { |
| | | return delMenu(row.menuId) |
| | | }).then(() => { |
| | | this.getList() |
| | | this.$modal.msgSuccess("删除成功") |
| | | }).catch(() => {}) |
| | | } |
| | | } |
| | | } |
| | | </script> |
src/views/system/notice/index.vue
src/views/system/post/index.vue
src/views/system/role/authUser.vue
src/views/system/role/index.vue
src/views/system/role/selectUser.vue
src/views/system/user/authRole.vue
src/views/system/user/index.vue
src/views/system/user/profile/index.vue
src/views/system/user/profile/resetPwd.vue
src/views/system/user/profile/userAvatar.vue
src/views/system/user/profile/userInfo.vue
src/views/tool/build/CodeTypeDialog.vue
src/views/tool/build/DraggableItem.vue
src/views/tool/build/IconsDialog.vue
src/views/tool/build/RightPanel.vue
src/views/tool/build/TreeNodeDialog.vue
src/views/tool/build/index.vue
src/views/tool/gen/basicInfoForm.vue
src/views/tool/gen/createTable.vue
src/views/tool/gen/editTable.vue
src/views/tool/gen/genInfoForm.vue
src/views/tool/gen/importTable.vue
src/views/tool/gen/index.vue
src/views/tool/swagger/index.vue
vue.config.js |