From d4c810f9803aa13d806724a5f4f71fe85abac38e Mon Sep 17 00:00:00 2001 From: suerprisePlus <15810472099@163.com> Date: 星期四, 30 五月 2024 16:42:16 +0800 Subject: [PATCH] 代码初始化 --- src/assets/icons/svg/iot.svg | 1 src/assets/styles/index.scss | 211 src/assets/icons/svg/eye.svg | 1 src/assets/icons/svg/listener.svg | 1 src/views/components/icons/index.vue | 87 src/layout/index.vue | 111 src/views/system/user/authRole.vue | 117 src/api/iot/protocol.js | 44 src/api/system/notice.js | 44 src/assets/icons/svg/cascader.svg | 1 src/views/tool/build/CodeTypeDialog.vue | 106 src/views/dashboard/BarChart.vue | 102 src/assets/icons/svg/tool.svg | 1 src/api/login.js | 107 src/assets/icons/svg/radio.svg | 1 src/assets/401_images/401.gif | 0 src/utils/generator/config.js | 438 src/utils/generator/html.js | 359 src/assets/bigScreen/css/theme/fonts/element-icons.woff | 0 src/components/SizeSelect/index.vue | 56 bin/run-web.bat | 12 src/assets/icons/svg/wifi_3.svg | 1 src/utils/dict/DictData.js | 13 src/views/iot/platform/index.vue | 338 src/api/tool/gen.js | 76 src/assets/styles/element-variables.scss | 31 src/assets/bigScreen/css/theme/fonts/element-icons.ttf | 0 src/api/iot/tool.js | 50 src/assets/icons/svg/time.svg | 1 src/components/TopNav/index.vue | 185 src/directive/permission/hasPermi.js | 28 src/assets/icons/svg/category.svg | 1 src/assets/icons/svg/upload.svg | 1 src/assets/logo/logo.gif | 0 src/api/iot/category.js | 52 src/assets/icons/svg/theme.svg | 1 src/assets/icons/svg/subscribe.svg | 1 src/views/iot/device/running-status.vue | 946 + src/assets/icons/svg/guide.svg | 1 src/views/error/401.vue | 88 src/views/tool/gen/editTable.vue | 234 src/views/tool/gen/importTable.vue | 120 src/assets/icons/svg/job.svg | 1 src/api/iot/runstatus.js | 29 src/assets/icons/svg/wifi_2.svg | 1 src/assets/icons/svg/checkbox.svg | 1 public/index.html | 229 src/assets/icons/svg/channel.svg | 1 src/views/system/dept/index.vue | 340 src/views/iot/template/parameter.vue | 440 src/utils/generator/render.js | 126 src/assets/images/video.png | 0 src/plugins/download.js | 72 src/assets/icons/svg/language.svg | 1 src/assets/icons/svg/github.svg | 1 src/views/dashboard/PieChart.vue | 79 src/assets/icons/svg/videotape.svg | 1 src/assets/styles/btn.scss | 99 src/views/dashboard/mixins/resize.js | 56 src/assets/bigScreen/img/zuo_xuxian.png | 0 src/assets/icons/svg/row.svg | 1 src/assets/icons/svg/link.svg | 1 src/utils/generator/icon.json | 1 src/views/iot/protocol/index.vue | 234 src/assets/icons/svg/druid.svg | 1 src/views/register.vue | 329 .prettierignore | 4 src/layout/components/Sidebar/Logo.vue | 92 bin/package.bat | 12 src/assets/icons/svg/input.svg | 1 src/assets/icons/svg/validCode.svg | 1 src/assets/icons/svg/icon.svg | 1 src/api/iot/deviceuser.js | 63 src/views/tool/gen/basicInfoForm.vue | 60 src/assets/icons/svg/rate.svg | 1 src/components/Pagination/index.vue | 114 src/utils/bigScreen/drawMixin.js | 75 src/assets/icons/svg/phone.svg | 1 src/assets/icons/svg/size.svg | 1 src/assets/icons/svg/system.svg | 2 src/views/bigScreen/components/reacquire/reacquire.vue | 63 src/views/iot/product/index.vue | 302 src/api/iot/model.js | 78 src/assets/images/dark.svg | 39 src/api/monitor/job.js | 71 src/assets/icons/svg/authenticate.svg | 1 src/views/iot/product/product-select-template.vue | 125 src/components/RuoYi/Git/index.vue | 21 src/plugins/tab.js | 67 src/assets/images/phone.png | 0 src/utils/errorCode.js | 6 src/components/HeaderSearch/index.vue | 189 src/assets/icons/svg/international.svg | 1 src/components/RightPanel/index.vue | 106 src/views/monitor/job/index.vue | 513 src/assets/icons/svg/pdf.svg | 1 src/components/RightToolbar/index.vue | 104 src/views/monitor/online/index.vue | 122 src/assets/icons/svg/wifi_1.svg | 1 src/views/tool/swagger/index.vue | 15 src/views/tool/gen/genInfoForm.vue | 299 src/assets/icons/svg/search.svg | 1 src/layout/components/IframeToggle/index.vue | 24 src/assets/bigScreen/iconfont/iconfont.woff | 0 package.json | 106 src/components/IconSelect/requireIcons.js | 11 .prettierrc.js | 10 src/components/Crontab/index.vue | 430 src/views/iot/product/product-edit.vue | 560 vue.config.js | 131 src/assets/icons/svg/shopping.svg | 1 src/views/bigScreen/indexs/right-center.vue | 121 src/views/iot/device/user-list.vue | 194 src/assets/icons/svg/button.svg | 1 src/api/iot/functionLog.js | 44 src/assets/icons/svg/peoples.svg | 1 src/store/modules/settings.js | 42 src/assets/bigScreen/css/variable.scss | 50 src/assets/icons/svg/tab.svg | 1 src/assets/icons/svg/online.svg | 1 src/assets/bigScreen/css/public.scss | 156 src/views/monitor/job/log.vue | 295 src/components/ImageUpload/index.vue | 226 src/views/dashboard/PanelGroup.vue | 181 src/api/iot/netty.js | 36 src/assets/icons/svg/404.svg | 1 src/store/modules/user.js | 109 src/api/iot/news.js | 44 src/store/index.js | 25 src/api/system/dict/data.js | 52 src/utils/generator/drawingDefalut.js | 29 src/assets/icons/svg/tree-table.svg | 1 src/views/iot/device/index.vue | 509 src/assets/icons/svg/documentation.svg | 1 src/api/iot/log.js | 44 src/layout/components/Sidebar/Link.vue | 43 src/assets/icons/svg/ota.svg | 1 src/assets/images/gateway.png | 0 src/assets/bigScreen/css/theme/index.css | 1 src/assets/icons/svg/group.svg | 1 src/components/ParentView/index.vue | 3 src/plugins/index.js | 20 src/api/iot/device.js | 146 src/assets/icons/svg/client.svg | 1 src/utils/index.js | 425 src/api/monitor/cache.js | 57 src/assets/icons/svg/scene.svg | 1 src/views/iot/device/device-timer.vue | 780 + src/directive/module/clipboard.js | 54 src/assets/icons/svg/disconnect.svg | 1 src/assets/icons/svg/people.svg | 1 src/views/monitor/cache/list.vue | 241 src/api/iot/deviceLog.js | 62 src/views/iot/device/device-log.vue | 306 src/lib/types.js | 46 src/views/redirect.vue | 12 src/components/Crontab/month.vue | 114 src/utils/map.js | 28 src/views/system/menu/index.vue | 453 src/directive/index.js | 23 src/lib/index.js | 9 src/assets/icons/svg/server.svg | 1 src/assets/icons/svg/log-a.svg | 2 src/layout/components/Sidebar/index.vue | 57 src/api/system/user.js | 149 src/assets/icons/svg/table.svg | 1 src/assets/styles/sidebar.scss | 227 src/views/bigScreen/components/item-wrap/item-wrap.vue | 90 src/assets/styles/element-ui.scss | 92 src/utils/dict/DictConverter.js | 17 src/assets/icons/svg/cloud.svg | 1 src/assets/icons/svg/video.svg | 1 src/assets/icons/svg/redis-list.svg | 2 src/assets/icons/svg/star.svg | 1 src/assets/icons/svg/code.svg | 1 src/assets/bigScreen/img/top.png | 0 src/assets/icons/svg/wifi_0.svg | 1 src/views/bigScreen/indexs/right-bottom.vue | 99 src/views/bigScreen/indexs/left-bottom.vue | 100 src/views/index.vue | 877 + src/assets/icons/svg/fullscreen.svg | 1 src/assets/icons/index.js | 9 src/assets/icons/svg/dashboard.svg | 1 src/views/system/user/profile/userAvatar.vue | 187 src/assets/bigScreen/img/titles/you.png | 0 src/components/Screenfull/index.vue | 57 src/views/index_v1.vue | 98 src/assets/icons/svg/date.svg | 1 src/api/system/dept.js | 52 src/assets/images/zlm-logo.png | 0 src/views/system/role/authUser.vue | 199 src/assets/icons/svg/connect.svg | 1 public/favicon.ico | 0 .editorconfig | 22 src/assets/icons/svg/nested.svg | 1 src/components/PanThumb/index.vue | 142 src/views/tool/build/index.vue | 783 + src/permission.js | 56 src/assets/icons/svg/monitor.svg | 2 src/utils/scroll-to.js | 58 src/views/bigScreen/components/echart/index.vue | 65 src/views/system/user/profile/index.vue | 212 src/assets/styles/transition.scss | 53 src/assets/icons/svg/time-range.svg | 1 README.md | 30 src/plugins/modal.js | 83 src/views/bigScreen/setting.vue | 105 src/main.js | 126 src/components/DictData/index.js | 49 src/layout/components/TagsView/ScrollPane.vue | 94 src/assets/bigScreen/css/modules/reset.scss | 200 src/layout/components/index.js | 5 src/views/iot/device/device-edit.vue | 932 + src/views/tool/build/RightPanel.vue | 946 + src/layout/components/Navbar.vue | 200 src/api/iot/platform.js | 68 src/assets/icons/svg/share.svg | 2 src/assets/bigScreen/img/xiezuo.png | 0 src/layout/components/Sidebar/SidebarItem.vue | 100 public/html/ie.html | 46 src/assets/bigScreen/iconfont/iconfont.woff2 | 0 src/assets/icons/svg/redis.svg | 1 src/components/DictTag/index.vue | 58 src/assets/icons/svg/swagger.svg | 1 src/store/modules/permission.js | 133 src/utils/validate.js | 114 src/utils/permission.js | 51 src/store/modules/dict.js | 50 src/views/dashboard/LineChart.vue | 135 src/api/system/post.js | 44 src/assets/icons/svg/tree.svg | 1 src/views/iot/device/device-monitor.vue | 296 src/directive/permission/hasRole.js | 28 src/views/components/icons/element-icons.js | 3 src/api/iot/salve.js | 53 src/assets/icons/svg/select.svg | 1 src/views/iot/log/index.vue | 391 src/assets/icons/svg/component.svg | 1 src/assets/images/phone.jpg | 0 src/assets/icons/svg/clipboard.svg | 1 src/assets/icons/svg/download.svg | 1 src/assets/images/light.svg | 39 src/utils/generator/drawingDefault.js | 29 public/robots.txt | 2 src/views/monitor/operlog/index.vue | 305 src/views/tool/build/IconsDialog.vue | 123 src/assets/icons/svg/model.svg | 1 src/views/tool/build/DraggableItem.vue | 100 src/api/monitor/jobLog.js | 26 src/api/iot/group.js | 61 src/views/monitor/cache/index.vue | 146 src/assets/icons/svg/subscribe1.svg | 1 src/views/error/404.vue | 233 src/directive/dialog/dragHeight.js | 34 src/settings.js | 44 src/assets/icons/svg/alert.svg | 1 src/assets/icons/svg/live.svg | 1 src/assets/icons/svg/user.svg | 1 src/components/Breadcrumb/index.vue | 74 .env.development | 20 src/assets/icons/svg/form.svg | 1 src/store/modules/tagsView.js | 228 src/views/iot/newsCategory/index.vue | 250 src/assets/icons/svg/mq.svg | 1 src/views/bigScreen/indexs/left-center.vue | 152 src/assets/icons/svg/chart.svg | 1 src/assets/icons/svg/switch.svg | 1 src/assets/styles/mixin.scss | 66 src/api/iot/clientDetails.js | 44 src/views/system/role/index.vue | 606 src/assets/icons/svg/firmware.svg | 1 src/assets/icons/svg/log.svg | 1 src/utils/ruoyi.js | 239 src/views/bigScreen/components/message/message.vue | 67 src/lib/dd-moment.js | 93 src/assets/icons/svg/date-range.svg | 1 src/views/monitor/server/index.vue | 207 src/views/system/dict/data.vue | 402 src/views/iot/template/index.vue | 889 + src/views/iot/device/device-user.vue | 348 src/api/iot/temp.js | 62 src/directive/dialog/drag.js | 64 src/views/bigScreen/components/echart/theme.json | 490 src/api/iot/product.js | 78 src/assets/icons/svg/start.svg | 1 src/layout/mixin/ResizeHandler.js | 45 src/assets/icons/svg/qq.svg | 1 src/views/bigScreen/components/message/message.js | 49 src/views/iot/device/product-list.vue | 156 src/assets/icons/svg/qrcode.svg | 1 babel.config.js | 13 src/utils/busEvent.js | 5 src/views/system/user/profile/userInfo.vue | 75 src/components/iFrame/index.vue | 36 src/components/ThemePicker/index.vue | 173 src/components/RuoYi/Doc/index.vue | 21 src/plugins/auth.js | 60 src/assets/icons/svg/dict.svg | 1 src/utils/mqttTool.js | 152 src/views/iot/product/product-authorize.vue | 515 src/assets/icons/svg/wechat.svg | 1 .eslintrc.js | 210 src/assets/bigScreen/img/xieyou.png | 0 src/api/iot/newsCategory.js | 52 src/assets/images/weChat.png | 0 src/views/iot/product/product-things-model.vue | 984 + src/assets/icons/svg/number.svg | 1 src/assets/bigScreen/img/titles/zuo.png | 0 src/assets/icons/svg/exit-fullscreen.svg | 1 src/router/index.js | 203 src/layout/components/Sidebar/FixiOSBug.js | 25 src/lib/currency.js | 431 src/assets/icons/svg/money.svg | 1 src/components/FileUpload/index.vue | 215 src/views/system/dict/index.vue | 347 src/assets/404_images/404.png | 0 src/api/monitor/online.js | 18 src/components/Crontab/year.vue | 131 .gitignore | 22 src/utils/generator/css.js | 18 src/views/monitor/druid/index.vue | 15 src/views/system/role/selectUser.vue | 138 src/assets/icons/svg/small.svg | 1 src/assets/icons/svg/education.svg | 1 src/assets/icons/svg/arrow-left.svg | 1 src/views/bigScreen/indexs/center-bottom.vue | 176 src/assets/404_images/404_cloud.png | 0 src/components/SvgIcon/index.vue | 61 src/assets/icons/svg/topic.svg | 1 src/components/Crontab/day.vue | 161 src/views/bigScreen/indexs/right-top.vue | 125 src/api/monitor/server.js | 9 src/components/IconSelect/index.vue | 68 src/views/system/user/index.vue | 670 src/views/login.vue | 403 src/views/iot/device/device-statistic.vue | 225 src/assets/bigScreen/img/headers/juxing2.png | 0 src/App.vue | 31 src/views/iot/device/device-functionlog.vue | 222 src/assets/bigScreen/img/headers/juxing1.png | 0 src/assets/icons/svg/message.svg | 1 src/assets/icons/svg/receiver.svg | 1 src/utils/dict/Dict.js | 82 src/assets/icons/svg/drag.svg | 1 src/assets/icons/svg/textarea.svg | 1 src/assets/icons/svgo.yml | 22 src/views/iot/clientDetails/index.vue | 292 src/views/monitor/logininfor/index.vue | 245 src/api/iot/deviceJob.js | 71 src/assets/styles/ruoyi.scss | 292 src/assets/icons/svg/event-a.svg | 2 src/assets/images/qq.png | 0 src/assets/icons/svg/list.svg | 1 src/assets/icons/svg/plugin.svg | 1 src/views/iot/news/index.vue | 443 src/assets/icons/svg/device.svg | 1 src/assets/bigScreen/css/index.scss | 361 src/assets/icons/svg/eye-open.svg | 1 src/api/system/menu.js | 60 src/views/bigScreen/indexs/index.vue | 141 src/api/tool/ossDetail.js | 44 src/components/Hamburger/index.vue | 44 src/views/tool/gen/index.vue | 337 src/assets/icons/svg/product.svg | 1 src/api/iot/template.js | 53 src/assets/icons/svg/password.svg | 1 src/components/ImagePreview/index.vue | 90 src/assets/bigScreen/iconfont/iconfont.css | 23 src/assets/icons/svg/question.svg | 1 src/assets/icons/svg/zip.svg | 1 src/components/Crontab/hour.vue | 114 src/components/Crontab/result.vue | 559 src/assets/icons/svg/edit.svg | 1 src/api/iot/authorize.js | 52 src/components/Editor/index.vue | 272 public/logo.png | 0 src/api/monitor/logininfor.js | 34 src/directive/dialog/dragWidth.js | 30 src/assets/icons/svg/skill.svg | 1 src/views/bigScreen/indexs/center-map.vue | 392 src/api/tool/ossConfig.js | 44 src/store/modules/app.js | 66 src/assets/icons/svg/excel.svg | 1 src/assets/styles/variables.scss | 54 src/assets/images/profile.jpg | 0 src/views/iot/category/index.vue | 275 src/layout/components/TagsView/index.vue | 332 src/assets/images/product.png | 0 src/utils/request.js | 146 src/views/iot/business/index.vue | 19 src/assets/bigScreen/img/guang.png | 0 src/views/system/user/profile/resetPwd.vue | 87 src/layout/components/AppMain.vue | 61 .eslintignore | 9 src/assets/icons/svg/post.svg | 1 src/components/Crontab/second.vue | 117 src/assets/icons/svg/build.svg | 1 src/api/system/config.js | 60 src/views/iot/netty/mqtt.vue | 346 src/utils/auth.js | 28 src/views/bigScreen/home.vue | 96 src/views/bigScreen/indexs/left-top.vue | 75 src/views/dashboard/RaddarChart.vue | 116 src/assets/icons/svg/zhifubao.svg | 2 src/layout/components/InnerLink/index.vue | 47 src/api/system/dict/type.js | 60 src/store/getters.js | 19 src/api/iot/eventLog.js | 45 src/assets/bigScreen/iconfont/iconfont.ttf | 0 src/utils/dict/index.js | 33 src/views/system/post/index.vue | 309 src/assets/icons/svg/example.svg | 1 src/utils/generator/js.js | 236 src/layout/components/Sidebar/Item.vue | 33 src/assets/images/orange.svg | 39 src/assets/icons/svg/logininfor.svg | 1 .env.production | 14 src/views/system/notice/index.vue | 312 src/layout/components/Settings/index.vue | 260 bin/build.bat | 12 src/assets/icons/svg/lock.svg | 1 src/assets/icons/svg/wifi_4.svg | 1 src/views/bigScreen/home.scss | 266 src/views/system/config/index.vue | 343 src/views/iot/group/index.vue | 289 src/api/system/role.js | 119 src/assets/bigScreen/css/webfont/index.css | 18 src/views/iot/netty/clients.vue | 324 src/assets/icons/svg/monitor-a.svg | 2 src/assets/images/code.jpg | 0 src/utils/jsencrypt.js | 30 src/components/Crontab/min.vue | 116 src/assets/icons/svg/live1.svg | 1 src/views/iot/group/device-list.vue | 191 .env.staging | 17 src/assets/icons/svg/bug.svg | 1 src/views/tool/build/TreeNodeDialog.vue | 149 src/api/monitor/operlog.js | 26 src/assets/icons/svg/email.svg | 1 src/utils/dict/DictOptions.js | 51 src/assets/icons/svg/color.svg | 1 src/assets/icons/svg/slider.svg | 1 src/assets/logo/logo.png | 0 src/api/menu.js | 9 src/views/components/icons/svg-icons.js | 10 src/assets/bigScreen/css/modules/variables.scss | 98 src/utils/dict/DictMeta.js | 38 src/components/Codemirror/index.vue | 128 src/plugins/cache.js | 77 src/views/iot/product/product-app.vue | 129 src/api/iot/point.js | 62 src/assets/icons/svg/big.svg | 1 src/components/Crontab/week.vue | 202 src/assets/icons/svg/stop.svg | 1 src/utils/bigScreen/index.js | 58 455 files changed, 44,890 insertions(+), 2 deletions(-) diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7034f9b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +# 鍛婅瘔EditorConfig鎻掍欢锛岃繖鏄牴鏂囦欢锛屼笉鐢ㄧ户缁線涓婃煡鎵� +root = true + +# 鍖归厤鍏ㄩ儴鏂囦欢 +[*] +# 璁剧疆瀛楃闆� +charset = utf-8 +# 缂╄繘椋庢牸锛屽彲閫塻pace銆乼ab +indent_style = space +# 缂╄繘鐨勭┖鏍兼暟 +indent_size = 2 +# 缁撳熬鎹㈣绗︼紝鍙�塴f銆乧r銆乧rlf +end_of_line = lf +# 鍦ㄦ枃浠剁粨灏炬彃鍏ユ柊琛� +insert_final_newline = true +# 鍒犻櫎涓�琛屼腑鐨勫墠鍚庣┖鏍� +trim_trailing_whitespace = true + +# 鍖归厤md缁撳熬鐨勬枃浠� +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..35e3852 --- /dev/null +++ b/.env.development @@ -0,0 +1,20 @@ +# 椤甸潰鏍囬 +VUE_APP_TITLE = 娉扮憺宸ヤ笟鏁板瓧瀛敓绠$悊骞冲彴 + +# 寮�鍙戠幆澧冮厤缃� +ENV = 'development' + +# 寮�鍙戠幆澧� +VUE_APP_BASE_API = '/dev-api' + +# 璺敱鎳掑姞杞� +VUE_CLI_BABEL_TRANSPILE_MODULES = true + +# 鍚庣鎺ュ彛鍦板潃 +VUE_APP_SERVER_API_URL = 'http://192.168.11.14:8080' + +# Mqtt娑堟伅鏈嶅姟鍣ㄨ繛鎺ュ湴鍧� +VUE_APP_MQTT_SERVER_URL = 'ws://101.201.75.67:8083/mqtt' + +# 鐧惧害鍦板浘AK +VUE_APP_BAI_DU_AK = 'nAtaBg9FYzav6c8P9rF9qzsWZfT8O0PD' diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..425ab61 --- /dev/null +++ b/.env.production @@ -0,0 +1,14 @@ +# 椤甸潰鏍囬 +VUE_APP_TITLE = FastBee鐗╄仈缃� + +# 鐢熶骇鐜閰嶇疆 +ENV = 'production' + +# 鐢熶骇鐜 +VUE_APP_BASE_API = '/prod-api' + +# Mqtt娑堟伅鏈嶅姟鍣ㄨ繛鎺ュ湴鍧�,浣跨敤绌哄瓧绗︿覆鍒欎細鑷姩鑾峰彇鏈嶅姟鍣ㄥ湴鍧� +VUE_APP_MQTT_SERVER_URL = '' + +# 鐧惧害鍦板浘AK +VUE_APP_BAI_DU_AK = 'nAtaBg9FYzav6c8P9rF9qzsWZfT8O0PD' diff --git a/.env.staging b/.env.staging new file mode 100644 index 0000000..43f1d14 --- /dev/null +++ b/.env.staging @@ -0,0 +1,17 @@ +# 椤甸潰鏍囬 +VUE_APP_TITLE = 娉扮憺宸ヤ笟鏁板瓧瀛敓绠$悊骞冲彴 + +NODE_ENV = production + +# 娴嬭瘯鐜閰嶇疆 +ENV = 'staging' + +# 娴嬭瘯鐜 +VUE_APP_BASE_API = '/stage-api' + +# Mqtt娑堟伅鏈嶅姟鍣ㄨ繛鎺ュ湴鍧� +VUE_APP_MQTT_SERVER_URL = 'ws://localhost:8083/mqtt' + +# 鐧惧害鍦板浘AK +VUE_APP_BAI_DU_AK = 'nAtaBg9FYzav6c8P9rF9qzsWZXXXXXX' + diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..53b6e62 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,9 @@ +# 蹇界暐build鐩綍涓嬬被鍨嬩负js鐨勬枃浠剁殑璇硶妫�鏌� +build/*.js +# 蹇界暐src/assets鐩綍涓嬫枃浠剁殑璇硶妫�鏌� +src/assets +# 蹇界暐public鐩綍涓嬫枃浠剁殑璇硶妫�鏌� +public +# 蹇界暐褰撳墠鐩綍涓嬩负js鐨勬枃浠剁殑璇硶妫�鏌� +*.js +*.vue diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..49652e2 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,210 @@ + +/** + * + * 瑙勫垯璇存槑瑙� https://cn.eslint.org/docs/rules/ + * eslint-plugin-vue 瑙勫垯瑙� https://github.com/vuejs/eslint-plugin-vue + * + * "off" 鎴� 0 - 鍏抽棴瑙勫垯 + * "warn" 鎴� 1 - 寮�鍚鍒欙紝浣跨敤璀﹀憡绾у埆鐨勯敊璇細warn (涓嶄細瀵艰嚧绋嬪簭閫�鍑�) + * "error" 鎴� 2 - 寮�鍚鍒欙紝浣跨敤閿欒绾у埆鐨勯敊璇細error (褰撹瑙﹀彂鐨勬椂鍊欙紝绋嬪簭浼氶��鍑�) + * + */ +module.exports = { + root: true, + parserOptions: { + parser: 'babel-eslint', + sourceType: 'module' + }, + env: { + browser: true, + node: true, + es6: true, + }, + extends: ['plugin:vue/recommended', 'eslint:recommended'], + + // add your custom rules here + rules: { + 'vue/max-attributes-per-line': [2, { + 'singleline': 10, + 'multiline': { + 'max': 1, + 'allowFirstLine': false + } + }], + 'vue/html-self-closing': 'off', + 'vue/singleline-html-element-content-newline': 'off', + 'vue/multiline-html-element-content-newline': 'off', + 'vue/no-template-shadow': "off", + 'vue/name-property-casing': ['error', 'PascalCase'], + 'vue/no-v-html': 'off', + 'accessor-pairs': 2, + 'arrow-spacing': [2, { + 'before': true, + 'after': true + }], + 'block-spacing': [2, 'always'], + 'brace-style': [2, '1tbs', { + 'allowSingleLine': true + }], + 'camelcase': [0, { + 'properties': 'always' + }], + 'comma-dangle': [2, 'always-multiline'], + 'comma-spacing': [2, { + 'before': false, + 'after': true + }], + 'comma-style': [2, 'last'], + 'constructor-super': 2, + 'curly': [2, 'multi-line'], + 'dot-location': [2, 'property'], + 'eol-last': 2, + 'eqeqeq': ["error", "always", {"null": "ignore"}], + 'generator-star-spacing': [2, { + 'before': true, + 'after': true + }], + 'handle-callback-err': [2, '^(err|error)$'], + 'indent': [2, 2, { + 'SwitchCase': 1 + }], + 'jsx-quotes': [2, 'prefer-single'], + 'key-spacing': [2, { + 'beforeColon': false, + 'afterColon': true + }], + 'keyword-spacing': [2, { + 'before': true, + 'after': true + }], + 'new-cap': [2, { + 'newIsCap': true, + 'capIsNew': false + }], + 'new-parens': 2, + 'no-array-constructor': 2, + 'no-caller': 2, + 'no-console': 'off', + 'no-class-assign': 2, + 'no-cond-assign': 2, + 'no-const-assign': 2, + 'no-control-regex': 0, + 'no-delete-var': 2, + 'no-dupe-args': 2, + 'no-dupe-class-members': 2, + 'no-dupe-keys': 2, + 'no-duplicate-case': 2, + 'no-empty-character-class': 2, + 'no-empty-pattern': 2, + 'no-eval': 2, + 'no-ex-assign': 2, + 'no-extend-native': 2, + 'no-extra-bind': 2, + 'no-extra-boolean-cast': 2, + 'no-extra-parens': [2, 'functions'], + 'no-fallthrough': 2, + 'no-floating-decimal': 2, + 'no-func-assign': 2, + 'no-implied-eval': 2, + 'no-inner-declarations': [2, 'functions'], + 'no-invalid-regexp': 2, + 'no-irregular-whitespace': 2, + 'no-iterator': 2, + 'no-label-var': 2, + 'no-labels': [2, { + 'allowLoop': false, + 'allowSwitch': false + }], + 'no-lone-blocks': 2, + 'no-mixed-spaces-and-tabs': 2, + 'no-multi-spaces': 2, + 'no-multi-str': 2, + 'no-multiple-empty-lines': [2, { + 'max': 1 + }], + 'no-native-reassign': 2, + 'no-negated-in-lhs': 2, + 'no-new-object': 2, + 'no-new-require': 2, + 'no-new-symbol': 2, + 'no-new-wrappers': 2, + 'no-obj-calls': 2, + 'no-octal': 2, + 'no-octal-escape': 2, + 'no-path-concat': 2, + 'no-proto': 2, + 'no-redeclare': 2, + 'no-regex-spaces': 2, + 'no-return-assign': [2, 'except-parens'], + 'no-self-assign': 2, + 'no-self-compare': 2, + 'no-sequences': 2, + 'no-shadow-restricted-names': 2, + 'no-spaced-func': 2, + 'no-sparse-arrays': 2, + 'no-this-before-super': 2, + 'no-throw-literal': 2, + 'no-trailing-spaces': 2, + 'no-undef': 2, + 'no-undef-init': 2, + 'no-unexpected-multiline': 2, + 'no-unmodified-loop-condition': 2, + 'no-unneeded-ternary': [2, { + 'defaultAssignment': false + }], + 'no-unreachable': 2, + 'no-unsafe-finally': 2, + 'no-unused-vars': [2, { + 'vars': 'all', + 'args': 'none' + }], + 'no-useless-call': 2, + 'no-useless-computed-key': 2, + 'no-useless-constructor': 2, + 'no-useless-escape': 0, + 'no-whitespace-before-property': 2, + 'no-with': 2, + 'one-var': [2, { + 'initialized': 'never' + }], + 'operator-linebreak': [2, 'after', { + 'overrides': { + '?': 'before', + ':': 'before' + } + }], + 'padded-blocks': [2, 'never'], + 'quotes': [2, 'single', { + 'avoidEscape': true, + 'allowTemplateLiterals': true + }], + 'semi': [2, 'always'], + 'semi-spacing': [2, { + 'before': false, + 'after': true + }], + 'space-before-blocks': [2, 'always'], + 'space-before-function-paren': 0, + 'space-in-parens': [2, 'never'], + 'space-infix-ops': 2, + 'space-unary-ops': [2, { + 'words': true, + 'nonwords': false + }], + 'spaced-comment': [2, 'always', { + 'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ','] + }], + 'template-curly-spacing': [2, 'never'], + 'use-isnan': 2, + 'valid-typeof': 2, + 'wrap-iife': [2, 'any'], + 'yield-star-spacing': [2, 'both'], + 'yoda': [2, 'never'], + 'prefer-const': 2, + 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, + 'object-curly-spacing': [2, 'always', { + objectsInObjects: false + }], + 'array-bracket-spacing': [2, 'never'] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..16161ad --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +.DS_Store +node_modules/ +dist/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +**/*.log + +tests/**/coverage/ +tests/e2e/reports +selenium-debug.log + +# Editor directories and files +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.local + +package-lock.json +yarn.lock diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..b06eb49 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +.eslintrc.js +/dist/ +/node_modules/** +/public/* \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..fda9ffe --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,10 @@ +module.exports = { + printWidth: 220, + singleQuote: true, // 浣跨敤鍗曞紩鍙疯�屼笉鏄弻寮曞彿 + semi: true, // 鍙ュ熬鏄惁鍔�; + proseWrap: 'preserve', + tabWidth: 4, + trailingComma: 'es5', // 鍦ㄥ璞℃垨鏁扮粍鏈�鍚庝竴涓厓绱犲悗闈㈡槸鍚﹀姞閫楀彿锛堝湪ES5涓姞灏鹃�楀彿锛� + bracketSpacing: true, // 鍦ㄥ璞★紝鏁扮粍鎷彿涓庢枃瀛椾箣闂村姞绌烘牸 "{ foo: bar }" + htmlWhitespaceSensitivity: 'ignore', // > 涓嶄贡鎹㈣ +}; diff --git a/README.md b/README.md index 802ada7..00c0ab8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,30 @@ -## TerraD +## 寮�鍙� -鐗╄仈缃戞劅鐭ュ钩鍙� +```bash +# 鍏嬮殕椤圭洰 +git clone https://gitee.com/y_project/RuoYi-Vue +# 杩涘叆椤圭洰鐩綍 +cd ruoyi-ui + +# 瀹夎渚濊禆 +npm install + +# 寤鸿涓嶈鐩存帴浣跨敤 cnpm 瀹夎渚濊禆锛屼細鏈夊悇绉嶈寮傜殑 bug銆傚彲浠ラ�氳繃濡備笅鎿嶄綔瑙e喅 npm 涓嬭浇閫熷害鎱㈢殑闂 +npm install --registry=https://registry.npmmirror.com + +# 鍚姩鏈嶅姟 +npm run dev +``` + +娴忚鍣ㄨ闂� http://localhost:80 + +## 鍙戝竷 + +```bash +# 鏋勫缓娴嬭瘯鐜 +npm run build:stage + +# 鏋勫缓鐢熶骇鐜 +npm run build:prod +``` \ No newline at end of file diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..b99f001 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,13 @@ +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'] + } + } +} diff --git a/bin/build.bat b/bin/build.bat new file mode 100644 index 0000000..dda590d --- /dev/null +++ b/bin/build.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [信息] 打包Web工程,生成dist文件。 +echo. + +%~d0 +cd %~dp0 + +cd .. +npm run build:prod + +pause \ No newline at end of file diff --git a/bin/package.bat b/bin/package.bat new file mode 100644 index 0000000..0e5bc0f --- /dev/null +++ b/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [信息] 安装Web工程,生成node_modules文件。 +echo. + +%~d0 +cd %~dp0 + +cd .. +npm install --registry=https://registry.npmmirror.com + +pause \ No newline at end of file diff --git a/bin/run-web.bat b/bin/run-web.bat new file mode 100644 index 0000000..d30deae --- /dev/null +++ b/bin/run-web.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [信息] 使用 Vue CLI 命令运行 Web 工程。 +echo. + +%~d0 +cd %~dp0 + +cd .. +npm run dev + +pause \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..34422a5 --- /dev/null +++ b/package.json @@ -0,0 +1,106 @@ +{ + "name": "fastbee", + "version": "3.8.5", + "description": "FastBee鐗╄仈缃戝钩鍙�", + "author": "kerwincui", + "license": "AGPL3.0", + "scripts": { + "dev": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --open", + "build:prod": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build --report", + "build:stage": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build --mode staging", + "preview": "set NODE_OPTIONS=--openssl-legacy-provider && node build/index.js --preview", + "lint": "eslint --ext .js,.vue src" +}, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "src/**/*.{js,vue}": [ + "eslint --fix", + "git add" + ] + }, + "keywords": [ + "vue", + "admin", + "dashboard", + "element-ui", + "boilerplate", + "admin-template", + "management-system" + ], + "repository": { + "type": "git", + "url": "https://gitee.com/y_project/RuoYi-Vue.git" + }, + "dependencies": { + "@easydarwin/easywasmplayer": "^4.0.7", + "@jiaminghi/data-view": "^2.10.0", + "@riophae/vue-treeselect": "0.4.0", + "axios": "0.24.0", + "clipboard": "2.0.8", + "codemirror": "^5.65.2", + "core-js": "3.25.3", + "echarts": "5.4.0", + "element-china-area-data": "^4.1.1", + "element-ui": "2.15.10", + "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", + "jshint": "^2.13.4", + "jsonlint": "^1.6.3", + "moment": "^2.29.4", + "mqtt": "^4.3.3", + "nprogress": "0.2.0", + "quill": "1.3.7", + "screenfull": "5.0.2", + "script-loader": "^0.7.2", + "sortablejs": "1.10.2", + "sql-formatter": "^4.0.2", + "vue": "2.6.12", + "vue-clipboard2": "^0.3.3", + "vue-codemirror": "^4.0.6", + "vue-count-to": "1.0.13", + "vue-cropper": "0.5.5", + "vue-easytable": "^2.14.0", + "vue-json-viewer": "^2.2.21", + "vue-meta": "2.4.0", + "vue-qr": "^4.0.9", + "vue-router": "3.4.9", + "vue-seamless-scroll": "^1.1.23", + "vuedraggable": "2.24.3", + "vuex": "3.6.0" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "4.4.6", + "@vue/cli-plugin-eslint": "4.4.6", + "@vue/cli-service": "4.4.6", + "babel-eslint": "10.1.0", + "babel-plugin-dynamic-import-node": "^2.3.3", + "chalk": "4.1.0", + "compression-webpack-plugin": "5.0.2", + "connect": "3.6.6", + "eslint": "^7.28.0", + "eslint-plugin-vue": "7.2.0", + "lint-staged": "10.5.3", + "runjs": "4.4.2", + "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" + ] +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..18c5b52 --- /dev/null +++ b/public/favicon.ico Binary files differ diff --git a/public/html/ie.html b/public/html/ie.html new file mode 100644 index 0000000..052ffcd --- /dev/null +++ b/public/html/ie.html @@ -0,0 +1,46 @@ + +<!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>璇锋敞鎰忥細寰蒋鍏徃瀵筗indows XP 鍙� Internet Explorer 鏃╂湡鐗堟湰鐨勬敮鎸佸凡缁忕粨鏉�</h2> +<p>鑷� 2016 骞� 1 鏈� 12 鏃ヨ捣锛孧icrosoft 涓嶅啀涓� 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> \ No newline at end of file diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..e1ec1a2 --- /dev/null +++ b/public/index.html @@ -0,0 +1,229 @@ +<!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 %>logo.png"> + + <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; + } + + img { + max-width: 100%; + } + + /* 娓呴櫎鍦板浘LOGO */ + /* .BMap_cpyCtrl { + display: none!important; + } + + .anchorBL { + display: none!important; + } */ + </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">姝e湪鍔犺浇绯荤粺璧勬簮锛岃鑰愬績绛夊緟</div> + </div> + </div> +</body> +</html> diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..fefb48e --- /dev/null +++ b/public/logo.png Binary files differ diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..77470cb --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..ad8aca7 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,31 @@ +<template> + <div id="app" style="background-color:#0e2e87" v-if="$route.meta.bigScreen"> + <router-view /> + </div> + <div id="app" v-else> + <router-view /> + <theme-picker /> + </div> +</template> + +<script> +import ThemePicker from "@/components/ThemePicker"; + +export default { + name: "App", + components: { ThemePicker }, + metaInfo() { + return { + title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title, + titleTemplate: title => { + return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE + } + } + } +}; +</script> +<style scoped> +#app .theme-picker { + display: none; +} +</style> diff --git a/src/api/iot/authorize.js b/src/api/iot/authorize.js new file mode 100644 index 0000000..e7f2806 --- /dev/null +++ b/src/api/iot/authorize.js @@ -0,0 +1,52 @@ +import request from '@/utils/request' + +// 鏌ヨ浜у搧鎺堟潈鐮佸垪琛� +export function listAuthorize(query) { + return request({ + url: '/iot/authorize/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ浜у搧鎺堟潈鐮佽缁� +export function getAuthorize(authorizeId) { + return request({ + url: '/iot/authorize/' + authorizeId, + method: 'get' + }) +} + +// 鏂板浜у搧鎺堟潈鐮� +export function addAuthorize(data) { + return request({ + url: '/iot/authorize', + method: 'post', + data: data + }) +} + +//鏍规嵁鏁伴噺鎵归噺鏂板浜у搧鎺堟潈鐮� +export function addProductAuthorizeByNum(data) { + return request({ + url: '/iot/authorize/addProductAuthorizeByNum', + method: 'post', + data: data + }) +} +// 淇敼浜у搧鎺堟潈鐮� +export function updateAuthorize(data) { + return request({ + url: '/iot/authorize', + method: 'put', + data: data + }) +} + +// 鍒犻櫎浜у搧鎺堟潈鐮� +export function delAuthorize(authorizeId) { + return request({ + url: '/iot/authorize/' + authorizeId, + method: 'delete' + }) +} diff --git a/src/api/iot/category.js b/src/api/iot/category.js new file mode 100644 index 0000000..311fa61 --- /dev/null +++ b/src/api/iot/category.js @@ -0,0 +1,52 @@ +import request from '@/utils/request' + +// 鏌ヨ浜у搧鍒嗙被鍒楄〃 +export function listCategory(query) { + return request({ + url: '/iot/category/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ浜у搧绠�鐭垎绫诲垪琛� +export function listShortCategory() { + return request({ + url: '/iot/category/shortlist', + method: 'get', + }) +} + +// 鏌ヨ浜у搧鍒嗙被璇︾粏 +export function getCategory(categoryId) { + return request({ + url: '/iot/category/' + categoryId, + method: 'get' + }) +} + +// 鏂板浜у搧鍒嗙被 +export function addCategory(data) { + return request({ + url: '/iot/category', + method: 'post', + data: data + }) +} + +// 淇敼浜у搧鍒嗙被 +export function updateCategory(data) { + return request({ + url: '/iot/category', + method: 'put', + data: data + }) +} + +// 鍒犻櫎浜у搧鍒嗙被 +export function delCategory(categoryId) { + return request({ + url: '/iot/category/' + categoryId, + method: 'delete' + }) +} diff --git a/src/api/iot/clientDetails.js b/src/api/iot/clientDetails.js new file mode 100644 index 0000000..33d84ec --- /dev/null +++ b/src/api/iot/clientDetails.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 鏌ヨ浜戜簯瀵规帴鍒楄〃 +export function listClientDetails(query) { + return request({ + url: '/iot/clientDetails/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ浜戜簯瀵规帴璇︾粏 +export function getClientDetails(clientId) { + return request({ + url: '/iot/clientDetails/' + clientId, + method: 'get' + }) +} + +// 鏂板浜戜簯瀵规帴 +export function addClientDetails(data) { + return request({ + url: '/iot/clientDetails', + method: 'post', + data: data + }) +} + +// 淇敼浜戜簯瀵规帴 +export function updateClientDetails(data) { + return request({ + url: '/iot/clientDetails', + method: 'put', + data: data + }) +} + +// 鍒犻櫎浜戜簯瀵规帴 +export function delClientDetails(clientId) { + return request({ + url: '/iot/clientDetails/' + clientId, + method: 'delete' + }) +} diff --git a/src/api/iot/device.js b/src/api/iot/device.js new file mode 100644 index 0000000..f49c294 --- /dev/null +++ b/src/api/iot/device.js @@ -0,0 +1,146 @@ +import request from '@/utils/request'; + +// 鏌ヨ璁惧鍒楄〃 +export function listDevice(query) { + return request({ + url: '/iot/device/list', + method: 'get', + params: query, + }); +} + +// 鏌ヨ鏈巿鏉冭澶囧垪琛� +export function listUnAuthDevice(query) { + return request({ + url: '/iot/device/unAuthlist', + method: 'get', + params: query, + }); +} + +// 鏌ヨ鍒嗙粍鍙坊鍔犺澶囧垎椤靛垪琛� +export function listDeviceByGroup(query) { + return request({ + url: '/iot/device/listByGroup', + method: 'get', + params: query, + }); +} + +// 鏌ヨ璁惧绠�鐭垪琛� +export function listDeviceShort(query) { + return request({ + url: '/iot/device/shortList', + method: 'get', + params: query, + }); +} + +// 鏌ヨ鎵�鏈夎澶囩畝鐭垪琛� +export function listAllDeviceShort() { + return request({ + url: '/iot/device/all', + method: 'get', + }); +} + +// 鏌ヨ璁惧璇︾粏 +export function getDevice(deviceId) { + return request({ + url: '/iot/device/' + deviceId, + method: 'get', + }); +} + +// 璁惧鏁版嵁鍚屾 +export function deviceSynchronization(serialNumber) { + return request({ + url: '/iot/device/synchronization/' + serialNumber, + method: 'get', + }); +} + +// 鏍规嵁璁惧缂栧彿鏌ヨ璁惧璇︾粏 +export function getDeviceBySerialNumber(serialNumber) { + return request({ + url: '/iot/device/getDeviceBySerialNumber/' + serialNumber, + method: 'get', + }); +} + +// 鏌ヨ璁惧缁熻淇℃伅 +export function getDeviceStatistic() { + return request({ + url: '/iot/device/statistic', + method: 'get', + }); +} + +// 鏌ヨ璁惧杩愯鐘舵�佽缁� +export function getDeviceRunningStatus(params) { + return request({ + url: '/iot/device/runningStatus', + method: 'get', + params: params, + }); +} + +// 鏌ヨ璁惧鐗╂ā鍨嬬殑鍊� +export function getDeviceThingsModelValue(deviceId) { + return request({ + url: '/iot/device/thingsModelValue/' + deviceId, + method: 'get', + }); +} + +// 鏂板璁惧 +export function addDevice(data) { + return request({ + url: '/iot/device', + method: 'post', + data: data, + }); +} + +// 淇敼璁惧 +export function updateDevice(data) { + return request({ + url: '/iot/device', + method: 'put', + data: data, + }); +} + +// 鍒犻櫎璁惧 +export function delDevice(deviceId) { + return request({ + url: '/iot/device/' + deviceId, + method: 'delete', + }); +} + +// 鐢熸垚璁惧缂栧彿 +export function generatorDeviceNum(params) { + return request({ + url: '/iot/device/generator', + method: 'get', + params: params, + }); +} + +export function getGwDevCode(params) { + return request({ + url: '/iot/device/gwDevCount', + method: 'get', + params: params, + }); +} + +//mqtt杩炴帴鍙傛暟鏌ョ湅 +export function getMqttConnect(params) { + return request({ + url: '/iot/device/getMqttConnectData', + method: 'get', + params: params, + }); +} diff --git a/src/api/iot/deviceJob.js b/src/api/iot/deviceJob.js new file mode 100644 index 0000000..26167fa --- /dev/null +++ b/src/api/iot/deviceJob.js @@ -0,0 +1,71 @@ +import request from '@/utils/request' + +// 鏌ヨ瀹氭椂浠诲姟璋冨害鍒楄〃 +export function listJob(query) { + return request({ + url: '/iot/job/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ瀹氭椂浠诲姟璋冨害璇︾粏 +export function getJob(jobId) { + return request({ + url: '/iot/job/' + jobId, + method: 'get' + }) +} + +// 鏂板瀹氭椂浠诲姟璋冨害 +export function addJob(data) { + return request({ + url: '/iot/job', + method: 'post', + data: data + }) +} + +// 淇敼瀹氭椂浠诲姟璋冨害 +export function updateJob(data) { + return request({ + url: '/iot/job', + method: 'put', + data: data + }) +} + +// 鍒犻櫎瀹氭椂浠诲姟璋冨害 +export function delJob(jobId) { + return request({ + url: '/iot/job/' + jobId, + method: 'delete' + }) +} + +// 浠诲姟鐘舵�佷慨鏀� +export function changeJobStatus(jobId, status) { + const data = { + jobId, + status + } + return request({ + url: '/iot/job/changeStatus', + method: 'put', + data: data + }) +} + + +// 瀹氭椂浠诲姟绔嬪嵆鎵ц涓�娆� +export function runJob(jobId, jobGroup) { + const data = { + jobId, + jobGroup + } + return request({ + url: '/iot/job/run', + method: 'put', + data: data + }) +} \ No newline at end of file diff --git a/src/api/iot/deviceLog.js b/src/api/iot/deviceLog.js new file mode 100644 index 0000000..c78e90b --- /dev/null +++ b/src/api/iot/deviceLog.js @@ -0,0 +1,62 @@ +import request from '@/utils/request' + +// 鏌ヨ璁惧鏃ュ織鍒楄〃 +export function listDeviceLog(query) { + return request({ + url: '/iot/deviceLog/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ璁惧鐩戞祴鏁版嵁 +export function listMonitor(query) { + return request({ + url: '/iot/deviceLog/monitor', + method: 'get', + params: query + }) +} + +// 鏌ヨ璁惧鐩戞祴鏁版嵁 +export function listHistory(query) { + return request({ + url: '/iot/deviceLog/history', + method: 'get', + params: query + }) +} + +// 鏌ヨ璁惧鏃ュ織璇︾粏 +export function getDeviceLog(logId) { + return request({ + url: '/iot/deviceLog/' + logId, + method: 'get' + }) +} + +// 鏂板璁惧鏃ュ織 +export function addDeviceLog(data) { + return request({ + url: '/iot/deviceLog', + method: 'post', + data: data + }) +} + +// 淇敼璁惧鏃ュ織 +export function updateDeviceLog(data) { + return request({ + url: '/iot/deviceLog', + method: 'put', + data: data + }) +} + +// 鍒犻櫎璁惧鏃ュ織 +export function delDeviceLog(logId) { + return request({ + url: '/iot/deviceLog/' + logId, + method: 'delete' + }) +} diff --git a/src/api/iot/deviceuser.js b/src/api/iot/deviceuser.js new file mode 100644 index 0000000..ccce58f --- /dev/null +++ b/src/api/iot/deviceuser.js @@ -0,0 +1,63 @@ +import request from '@/utils/request'; + +// 鏌ヨ璁惧鐢ㄦ埛鍒楄〃 +export function listDeviceUser(query) { + return request({ + url: '/iot/deviceUser/list', + method: 'get', + params: query, + }); +} + +// 鏌ヨ璁惧鐢ㄦ埛璇︾粏 +export function getDeviceUser(deviceId, userId) { + return request({ + url: '/iot/deviceUser/' + deviceId + '/' + userId, + method: 'get', + }); +} + +// 鏌ヨ鐢ㄦ埛 +export function shareUser(query) { + return request({ + url: '/iot/deviceUser/shareUser', + method: 'get', + params: query, + }); +} + +// 鏂板璁惧鐢ㄦ埛 +export function addDeviceUser(data) { + return request({ + url: '/iot/deviceUser', + method: 'post', + data: data, + }); +} + +// 鏂板澶氫釜璁惧鐢ㄦ埛 +export function addDeviceUsers(data) { + return request({ + url: '/iot/deviceUser/addDeviceUsers', + method: 'post', + data: data, + }); +} + +// 淇敼璁惧鐢ㄦ埛 +export function updateDeviceUser(data) { + return request({ + url: '/iot/deviceUser', + method: 'put', + data: data, + }); +} + +// 鍒犻櫎璁惧鐢ㄦ埛 +export function delDeviceUser(device) { + return request({ + url: '/iot/deviceUser', + method: 'delete', + data: device, + }); +} diff --git a/src/api/iot/eventLog.js b/src/api/iot/eventLog.js new file mode 100644 index 0000000..8485d33 --- /dev/null +++ b/src/api/iot/eventLog.js @@ -0,0 +1,45 @@ +import request from '@/utils/request' + + +// 鏌ヨ浜嬩欢鏃ュ織鍒楄〃 +export function listEventLog(query) { + return request({ + url: '/iot/event/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ浜嬩欢鏃ュ織璇︾粏 +export function getEventLog(logId) { + return request({ + url: '/iot/event/' + logId, + method: 'get' + }) +} + +// 鏂板浜嬩欢鏃ュ織 +export function addEventLog(data) { + return request({ + url: '/iot/event', + method: 'post', + data: data + }) +} + +// 淇敼浜嬩欢鏃ュ織 +export function updateEventLog(data) { + return request({ + url: '/iot/event', + method: 'put', + data: data + }) +} + +// 鍒犻櫎浜嬩欢鏃ュ織 +export function delLog(logId) { + return request({ + url: '/iot/event/' + logId, + method: 'delete' + }) +} diff --git a/src/api/iot/functionLog.js b/src/api/iot/functionLog.js new file mode 100644 index 0000000..e283abd --- /dev/null +++ b/src/api/iot/functionLog.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 鏌ヨ璁惧鏈嶅姟涓嬪彂鏃ュ織鍒楄〃 +export function listLog(query) { + return request({ + url: '/iot/log/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ璁惧鏈嶅姟涓嬪彂鏃ュ織璇︾粏 +export function getLog(id) { + return request({ + url: '/iot/log/' + id, + method: 'get' + }) +} + +// 鏂板璁惧鏈嶅姟涓嬪彂鏃ュ織 +export function addLog(data) { + return request({ + url: '/iot/log', + method: 'post', + data: data + }) +} + +// 淇敼璁惧鏈嶅姟涓嬪彂鏃ュ織 +export function updateLog(data) { + return request({ + url: '/iot/log', + method: 'put', + data: data + }) +} + +// 鍒犻櫎璁惧鏈嶅姟涓嬪彂鏃ュ織 +export function delLog(id) { + return request({ + url: '/iot/log/' + id, + method: 'delete' + }) +} diff --git a/src/api/iot/group.js b/src/api/iot/group.js new file mode 100644 index 0000000..4ca9b35 --- /dev/null +++ b/src/api/iot/group.js @@ -0,0 +1,61 @@ +import request from '@/utils/request' + +// 鏌ヨ璁惧鍒嗙粍鍒楄〃 +export function listGroup(query) { + return request({ + url: '/iot/group/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ璁惧鍒嗙粍璇︾粏 +export function getGroup(groupId) { + return request({ + url: '/iot/group/' + groupId, + method: 'get' + }) +} + +// 鏌ヨ鍒嗙粍涓嬬殑鍏宠仈璁惧ID鏁扮粍 +export function getDeviceIds(groupId) { + return request({ + url: '/iot/group/getDeviceIds/' + groupId, + method: 'get' + }) +} + +// 鏂板璁惧鍒嗙粍 +export function addGroup(data) { + return request({ + url: '/iot/group', + method: 'post', + data: data + }) +} + +// 淇敼璁惧鍒嗙粍 +export function updateGroup(data) { + return request({ + url: '/iot/group', + method: 'put', + data: data + }) +} + +// 鏇存柊鍒嗙粍涓嬬殑璁惧 +export function updateDeviceGroups(data) { + return request({ + url: '/iot/group/updateDeviceGroups', + method: 'put', + data: data + }) +} + +// 鍒犻櫎璁惧鍒嗙粍 +export function delGroup(groupId) { + return request({ + url: '/iot/group/' + groupId, + method: 'delete' + }) +} diff --git a/src/api/iot/log.js b/src/api/iot/log.js new file mode 100644 index 0000000..07559da --- /dev/null +++ b/src/api/iot/log.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 鏌ヨ璁惧鏃ュ織鍒楄〃 +export function listLog(query) { + return request({ + url: '/iot/log/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ璁惧鏃ュ織璇︾粏 +export function getLog(deviceLogId) { + return request({ + url: '/iot/log/' + deviceLogId, + method: 'get' + }) +} + +// 鏂板璁惧鏃ュ織 +export function addLog(data) { + return request({ + url: '/iot/log', + method: 'post', + data: data + }) +} + +// 淇敼璁惧鏃ュ織 +export function updateLog(data) { + return request({ + url: '/iot/log', + method: 'put', + data: data + }) +} + +// 鍒犻櫎璁惧鏃ュ織 +export function delLog(deviceLogId) { + return request({ + url: '/iot/log/' + deviceLogId, + method: 'delete' + }) +} diff --git a/src/api/iot/model.js b/src/api/iot/model.js new file mode 100644 index 0000000..ebc7902 --- /dev/null +++ b/src/api/iot/model.js @@ -0,0 +1,78 @@ +import request from '@/utils/request'; + +// 鏌ヨ鐗╂ā鍨嬪垪琛� +export function listModel(query) { + return request({ + url: '/iot/model/list', + method: 'get', + params: query, + }); +} + +// 鏌ヨ鐗╂ā鍨嬭缁� +export function getModel(modelId) { + return request({ + url: '/iot/model/' + modelId, + method: 'get', + }); +} + +// 鏌ヨ鐗╂ā鍨嬪搴斿垎浜澶囩敤鎴锋潈闄愬垪琛� +export function permListModel(productId) { + return request({ + url: '/iot/model/permList/' + productId, + method: 'get', + }); +} + +// 鏂板鐗╂ā鍨� +export function addModel(data) { + return request({ + url: '/iot/model', + method: 'post', + data: data, + }); +} + +// 瀵煎叆閫氱敤鐗╂ā鍨� +export function importModel(data) { + return request({ + url: '/iot/model/import', + method: 'post', + data: data, + }); +} + +// 淇敼鐗╂ā鍨� +export function updateModel(data) { + return request({ + url: '/iot/model', + method: 'put', + data: data, + }); +} + +// 鍒犻櫎鐗╂ā鍨� +export function delModel(modelId) { + return request({ + url: '/iot/model/' + modelId, + method: 'delete', + }); +} + +// 鏍规嵁浜у搧ID鑾峰彇缂撳瓨鐨勭墿妯″瀷 +export function cacheJsonThingsModel(productId) { + return request({ + url: '/iot/model/cache/' + productId, + method: 'get', + }); +} + +// 鍚屾閲囬泦鐐规ā鏉垮埌浜у搧鐗╂ā鍨� +export function synchron(data) { + return request({ + url: '/iot/model/synchron', + method: 'post', + data: data, + }); +} diff --git a/src/api/iot/netty.js b/src/api/iot/netty.js new file mode 100644 index 0000000..5c1eb93 --- /dev/null +++ b/src/api/iot/netty.js @@ -0,0 +1,36 @@ +import request from '@/utils/request' + +// 闆嗙兢涓嬫墍鏈夊鎴风鍒楄〃 +export function listNettyMqttClient(query) { + return request({ + url: '/iot/mqtt/clients', + method: 'get', + params: query + }) +} + +export function clientOut(query) { + return request({ + url: '/iot/mqtt/client/out', + method: 'get', + params: query + }) +} + + +export function getNettyMqttStats() { + return request({ + url: '/bashBoard/stats', + method: 'get', + }) +} + + +export function statisticNettyMqtt(query) { + return request({ + url: '/bashBoard/metrics', + method: 'get', + params: query + }) +} + diff --git a/src/api/iot/news.js b/src/api/iot/news.js new file mode 100644 index 0000000..a89013c --- /dev/null +++ b/src/api/iot/news.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 鏌ヨ鏂伴椈璧勮鍒楄〃 +export function listNews(query) { + return request({ + url: '/iot/news/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ鏂伴椈璧勮璇︾粏 +export function getNews(newsId) { + return request({ + url: '/iot/news/' + newsId, + method: 'get' + }) +} + +// 鏂板鏂伴椈璧勮 +export function addNews(data) { + return request({ + url: '/iot/news', + method: 'post', + data: data + }) +} + +// 淇敼鏂伴椈璧勮 +export function updateNews(data) { + return request({ + url: '/iot/news', + method: 'put', + data: data + }) +} + +// 鍒犻櫎鏂伴椈璧勮 +export function delNews(newsId) { + return request({ + url: '/iot/news/' + newsId, + method: 'delete' + }) +} diff --git a/src/api/iot/newsCategory.js b/src/api/iot/newsCategory.js new file mode 100644 index 0000000..988b044 --- /dev/null +++ b/src/api/iot/newsCategory.js @@ -0,0 +1,52 @@ +import request from '@/utils/request' + +// 鏌ヨ鏂伴椈鍒嗙被鍒楄〃 +export function listNewsCategory(query) { + return request({ + url: '/iot/newsCategory/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ浜у搧绠�鐭垎绫诲垪琛� +export function listShortNewsCategory() { + return request({ + url: '/iot/newsCategory/newsCategoryShortList', + method: 'get', + }) +} + +// 鏌ヨ鏂伴椈鍒嗙被璇︾粏 +export function getNewsCategory(categoryId) { + return request({ + url: '/iot/newsCategory/' + categoryId, + method: 'get' + }) +} + +// 鏂板鏂伴椈鍒嗙被 +export function addNewsCategory(data) { + return request({ + url: '/iot/newsCategory', + method: 'post', + data: data + }) +} + +// 淇敼鏂伴椈鍒嗙被 +export function updateNewsCategory(data) { + return request({ + url: '/iot/newsCategory', + method: 'put', + data: data + }) +} + +// 鍒犻櫎鏂伴椈鍒嗙被 +export function delNewsCategory(categoryId) { + return request({ + url: '/iot/newsCategory/' + categoryId, + method: 'delete' + }) +} diff --git a/src/api/iot/platform.js b/src/api/iot/platform.js new file mode 100644 index 0000000..834c3da --- /dev/null +++ b/src/api/iot/platform.js @@ -0,0 +1,68 @@ +import request from '@/utils/request' + +// 鏌ヨ绗笁鏂圭櫥褰曞钩鍙版帶鍒跺垪琛� +export function listPlatform(query) { + return request({ + url: '/iot/platform/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ绗笁鏂圭櫥褰曞钩鍙版帶鍒惰缁� +export function getPlatform(socialPlatformId) { + return request({ + url: '/iot/platform/' + socialPlatformId, + method: 'get' + }) +} + +// 鏂板绗笁鏂圭櫥褰曞钩鍙版帶鍒� +export function addPlatform(data) { + return request({ + url: '/iot/platform', + method: 'post', + data: data + }) +} + +// 淇敼绗笁鏂圭櫥褰曞钩鍙版帶鍒� +export function updatePlatform(data) { + return request({ + url: '/iot/platform', + method: 'put', + data: data + }) +} + +// 鍒犻櫎绗笁鏂圭櫥褰曞钩鍙版帶鍒� +export function delPlatform(socialPlatformId) { + return request({ + url: '/iot/platform/' + socialPlatformId, + method: 'delete' + }) +} + +//瑙i櫎缁戝畾 +export function unbind(socialUserId){ + return request({ + url: '/iot/social/unbind/' + socialUserId, + method: 'get' + }) +} + +//缁戝畾璺宠浆 +export function bind(platform){ + return request({ + url: '/iot/social/bind/' + platform, + method: 'get' + }) +} + +//缁戝畾 +export function bindUser(bindId){ + return request({ + url: '/iot/social/bindId/' + bindId, + method: 'get' + }) +} diff --git a/src/api/iot/point.js b/src/api/iot/point.js new file mode 100644 index 0000000..6a453f1 --- /dev/null +++ b/src/api/iot/point.js @@ -0,0 +1,62 @@ +import request from '@/utils/request' + +// 鏌ヨ鍙橀噺妯℃澘浠庢満閲囬泦鐐瑰垪琛� +export function listPoint(query) { + return request({ + url: '/iot/point/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ鍙橀噺妯℃澘浠庢満閲囬泦鐐硅缁� +export function getPoint(id) { + return request({ + url: '/iot/point/' + id, + method: 'get' + }) +} + +// 鏂板鍙橀噺妯℃澘浠庢満閲囬泦鐐� +export function addPoint(data) { + return request({ + url: '/iot/point', + method: 'post', + data: data + }) +} + +// 淇敼鍙橀噺妯℃澘浠庢満閲囬泦鐐� +export function updatePoint(data) { + return request({ + url: '/iot/point', + method: 'put', + data: data + }) +} + +// 鍒犻櫎鍙橀噺妯℃澘浠庢満閲囬泦鐐� +export function delPoint(id) { + return request({ + url: '/iot/point/' + id, + method: 'delete' + }) +} + +//鏍规嵁浠庢満id鍒犻櫎閲囬泦鐐规暟鎹� +export function delBySlaveId(data){ + return request({ + url: '/iot/point/delBySlaveId', + method: 'delete', + data: data, + + }) +} +//.. +export function selectByTemp(query){ + return request({ + url: '/iot/point/getPoints', + method: 'get', + params: query + }) +} diff --git a/src/api/iot/product.js b/src/api/iot/product.js new file mode 100644 index 0000000..80142fd --- /dev/null +++ b/src/api/iot/product.js @@ -0,0 +1,78 @@ +import request from '@/utils/request' + +// 鏌ヨ浜у搧鍒楄〃 +export function listProduct(query) { + return request({ + url: '/iot/product/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ浜у搧鍒楄〃 +export function listShortProduct() { + return request({ + url: '/iot/product/shortList', + method: 'get', + }) +} + +// 鏌ヨ浜у搧璇︾粏 +export function getProduct(productId) { + return request({ + url: '/iot/product/' + productId, + method: 'get' + }) +} + +// 鏂板浜у搧 +export function addProduct(data) { + return request({ + url: '/iot/product', + method: 'post', + data: data + }) +} + +// 淇敼浜у搧 +export function updateProduct(data) { + return request({ + url: '/iot/product', + method: 'put', + data: data + }) +} + +// 鑾峰彇浜у搧涓嬭澶囩殑鏁伴噺 +export function deviceCount(productId) { + return request({ + url: '/iot/product/deviceCount/' + productId, + method: 'get' + }) +} + +// 鏇存柊浜у搧鐘舵�� +export function changeProductStatus(data) { + return request({ + url: '/iot/product/status/', + method: 'put', + data:data + }) +} + +// 鍒犻櫎浜у搧 +export function delProduct(productId) { + return request({ + url: '/iot/product/' + productId, + method: 'delete' + }) +} + +// 鏍规嵁閲囬泦鐐规ā鏉縤d鏌ヨ鎵�鏈変骇鍝� +export function selectByTempleId(params) { + return request({ + url: '/iot/product/queryByTemplateId', + method: 'get', + params: params + }) +} diff --git a/src/api/iot/protocol.js b/src/api/iot/protocol.js new file mode 100644 index 0000000..551ec45 --- /dev/null +++ b/src/api/iot/protocol.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 鏌ヨ鍗忚鍒楄〃 +export function listProtocol(query) { + return request({ + url: '/iot/protocol/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ鍗忚璇︾粏 +export function getProtocol(id) { + return request({ + url: '/iot/protocol/' + id, + method: 'get' + }) +} + +// 鏂板鍗忚 +export function addProtocol(data) { + return request({ + url: '/iot/protocol', + method: 'post', + data: data + }) +} + +// 淇敼鍗忚 +export function updateProtocol(data) { + return request({ + url: '/iot/protocol', + method: 'put', + data: data + }) +} + +// 鍒犻櫎鍗忚 +export function delProtocol(id) { + return request({ + url: '/iot/protocol/' + id, + method: 'delete' + }) +} diff --git a/src/api/iot/runstatus.js b/src/api/iot/runstatus.js new file mode 100644 index 0000000..67a479e --- /dev/null +++ b/src/api/iot/runstatus.js @@ -0,0 +1,29 @@ +import request from '@/utils/request' + +//鏌ヨ璁惧瀹炴椂鏁版嵁 +export function runStatus(params) { + return request({ + url: '/iot/runtime/runState', + method: 'get', + params: params, + }) +} + + +//鏌ヨ璁惧瀹炴椂鏁版嵁 +export function serviceInvoke(data) { + return request({ + url: '/iot/runtime/service/invoke', + method: 'post', + data: data, + }) +} + +//鏌ヨ璁惧鏈嶅姟涓嬪彂鏃ュ織 +export function funcLog(params) { + return request({ + url: '/iot/runtime/funcLog', + method: 'get', + params: params, + }) +} diff --git a/src/api/iot/salve.js b/src/api/iot/salve.js new file mode 100644 index 0000000..ccb6260 --- /dev/null +++ b/src/api/iot/salve.js @@ -0,0 +1,53 @@ +import request from '@/utils/request' + +// 鏌ヨ鍙橀噺妯℃澘璁惧浠庢満鍒楄〃 +export function listSalve(query) { + return request({ + url: '/iot/salve/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ鍙橀噺妯℃澘璁惧浠庢満璇︾粏 +export function getSalve(id) { + return request({ + url: '/iot/salve/' + id, + method: 'get' + }) +} + +// 鏂板鍙橀噺妯℃澘璁惧浠庢満 +export function addSalve(data) { + return request({ + url: '/iot/salve', + method: 'post', + data: data + }) +} + +// 淇敼鍙橀噺妯℃澘璁惧浠庢満 +export function updateSalve(data) { + return request({ + url: '/iot/salve', + method: 'put', + data: data + }) +} + +// 鍒犻櫎鍙橀噺妯℃澘璁惧浠庢満 +export function delSalve(id) { + return request({ + url: '/iot/salve/' + id, + method: 'delete' + }) +} + +//鏍规嵁浜у搧id鏌ヨ浠庢満鍒楄〃 +export function listByPid(params){ + return request({ + url: "/iot/salve/listByPId", + method: 'get', + params: params, + }) +} diff --git a/src/api/iot/temp.js b/src/api/iot/temp.js new file mode 100644 index 0000000..98dcf02 --- /dev/null +++ b/src/api/iot/temp.js @@ -0,0 +1,62 @@ +import request from '@/utils/request' + +// 鏌ヨ璁惧閲囬泦鍙橀噺妯℃澘鍒楄〃 +export function listTemp(query) { + return request({ + url: '/iot/temp/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ璁惧閲囬泦鍙橀噺妯℃澘璇︾粏 +export function getTemp(templateId) { + return request({ + url: '/iot/temp/' + templateId, + method: 'get' + }) +} + +// 鏂板璁惧閲囬泦鍙橀噺妯℃澘 +export function addTemp(data) { + return request({ + url: '/iot/temp', + method: 'post', + data: data + }) +} + +// 淇敼璁惧閲囬泦鍙橀噺妯℃澘 +export function updateTemp(data) { + return request({ + url: '/iot/temp', + method: 'put', + data: data + }) +} + +// 鍒犻櫎璁惧閲囬泦鍙橀噺妯℃澘 +export function delTemp(templateId) { + return request({ + url: '/iot/temp/' + templateId, + method: 'delete' + }) +} + + +//鏍规嵁浜у搧鏌ヨ閲囬泦鐐瑰叧鑱� +export function getDeviceTemp(params){ + return request({ + url: '/iot/temp/getTemp' , + method: 'get', + params: params, + }) +} + +export function getTempByPId(params){ + return request({ + url: '/iot/temp/getTempByPid', + method: 'get', + params: params, + }) +} diff --git a/src/api/iot/template.js b/src/api/iot/template.js new file mode 100644 index 0000000..fe13a97 --- /dev/null +++ b/src/api/iot/template.js @@ -0,0 +1,53 @@ +import request from '@/utils/request' + +// 鏌ヨ閫氱敤鐗╂ā鍨嬪垪琛� +export function listTemplate(query) { + return request({ + url: '/iot/template/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ閫氱敤鐗╂ā鍨嬭缁� +export function getTemplate(templateId) { + return request({ + url: '/iot/template/' + templateId, + method: 'get' + }) +} + +// 鏂板閫氱敤鐗╂ā鍨� +export function addTemplate(data) { + return request({ + url: '/iot/template', + method: 'post', + data: data + }) +} + +// 淇敼閫氱敤鐗╂ā鍨� +export function updateTemplate(data) { + return request({ + url: '/iot/template', + method: 'put', + data: data + }) +} + +// 鍒犻櫎閫氱敤鐗╂ā鍨� +export function delTemplate(templateId) { + return request({ + url: '/iot/template/' + templateId, + method: 'delete' + }) +} + +// 鏌ヨ閫氱敤鐗╂ā鍨嬭缁� +export function getAllPoints(params) { + return request({ + url: '/iot/template/getPoints', + method: 'get', + params: params, + }) +} diff --git a/src/api/iot/tool.js b/src/api/iot/tool.js new file mode 100644 index 0000000..6476290 --- /dev/null +++ b/src/api/iot/tool.js @@ -0,0 +1,50 @@ +import request from '@/utils/request' +import axios from 'axios' +import { Message } from 'element-ui' +import { saveAs } from 'file-saver' +import { getToken } from '@/utils/auth' +import { blobValidate } from "@/utils/ruoyi"; + +const baseURL = process.env.VUE_APP_BASE_API; + +// 娉ㄥ唽鏂规硶 +export function register(data) { + return request({ + url: '/iot/tool/register', + headers: { + isToken: false + }, + method: 'post', + data: data + }) +} + +// 鏌ヨ鐢ㄦ埛鍒楄〃 +export function listUser(query) { + return request({ + url: '/iot/tool/userList', + method: 'get', + params: query + }) +} + +// 鑾峰彇鎵�鏈変笅鍙戠殑topic +export function getTopics(params){ + return request({ + url: '/iot/tool/getTopics', + method: 'get', + params: params, + }) +} + +// 鑾峰彇鎵�鏈変笅鍙戠殑topic +export function decode(params){ + return request({ + url: '/iot/tool/decode', + method: 'get', + params: params, + }) +} + + + diff --git a/src/api/login.js b/src/api/login.js new file mode 100644 index 0000000..7df3a39 --- /dev/null +++ b/src/api/login.js @@ -0,0 +1,107 @@ +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, + }, + 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', + }); +} + +// 妫�鏌indID +export function checkBindId(bindId) { + return request({ + url: '/auth/checkBindId/' + bindId, + method: 'get', + }); +} + +// 寰俊缁戝畾鑾峰彇缁撴灉淇℃伅 +export function getWxBindMsg(wxBindMsgId) { + return request({ + url: '/wechat/getWxBindMsg?wxBindMsgId=' + wxBindMsgId, + 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, + }); +} +// 寰俊鐧诲綍鐩存帴璺宠浆鐧诲綍 +export function socialLogin(loginId) { + return request({ + url: '/auth/login/' + loginId, + method: 'get', + }); +} + +// 寰俊鐧诲綍缁戝畾鐧诲綍 +export function bindLogin(data) { + return request({ + url: '/auth/bind/login', + headers: { + isToken: false, + }, + method: 'post', + data: data, + }); +} + +// 涓夋柟鐧诲綍娉ㄥ唽缁戝畾 +export function bindRegister(data) { + return request({ + url: '/auth/bind/register', + headers: { + isToken: false, + }, + method: 'post', + timeout: 20000, + data: data, + }); +} diff --git a/src/api/menu.js b/src/api/menu.js new file mode 100644 index 0000000..faef101 --- /dev/null +++ b/src/api/menu.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +// 鑾峰彇璺敱 +export const getRouters = () => { + return request({ + url: '/getRouters', + method: 'get' + }) +} \ No newline at end of file diff --git a/src/api/monitor/cache.js b/src/api/monitor/cache.js new file mode 100644 index 0000000..72c5f6a --- /dev/null +++ b/src/api/monitor/cache.js @@ -0,0 +1,57 @@ +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' + }) +} diff --git a/src/api/monitor/job.js b/src/api/monitor/job.js new file mode 100644 index 0000000..3815569 --- /dev/null +++ b/src/api/monitor/job.js @@ -0,0 +1,71 @@ +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 + }) +} \ No newline at end of file diff --git a/src/api/monitor/jobLog.js b/src/api/monitor/jobLog.js new file mode 100644 index 0000000..6e0be61 --- /dev/null +++ b/src/api/monitor/jobLog.js @@ -0,0 +1,26 @@ +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' + }) +} diff --git a/src/api/monitor/logininfor.js b/src/api/monitor/logininfor.js new file mode 100644 index 0000000..4d112b7 --- /dev/null +++ b/src/api/monitor/logininfor.js @@ -0,0 +1,34 @@ +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' + }) +} + +// 瑙i攣鐢ㄦ埛鐧诲綍鐘舵�� +export function unlockLogininfor(userName) { + return request({ + url: '/monitor/logininfor/unlock/' + userName, + method: 'get' + }) +} + +// 娓呯┖鐧诲綍鏃ュ織 +export function cleanLogininfor() { + return request({ + url: '/monitor/logininfor/clean', + method: 'delete' + }) +} diff --git a/src/api/monitor/online.js b/src/api/monitor/online.js new file mode 100644 index 0000000..bd22137 --- /dev/null +++ b/src/api/monitor/online.js @@ -0,0 +1,18 @@ +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' + }) +} diff --git a/src/api/monitor/operlog.js b/src/api/monitor/operlog.js new file mode 100644 index 0000000..a04bca8 --- /dev/null +++ b/src/api/monitor/operlog.js @@ -0,0 +1,26 @@ +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' + }) +} diff --git a/src/api/monitor/server.js b/src/api/monitor/server.js new file mode 100644 index 0000000..e1f9ca2 --- /dev/null +++ b/src/api/monitor/server.js @@ -0,0 +1,9 @@ +import request from '@/utils/request' + +// 鑾峰彇鏈嶅姟淇℃伅 +export function getServer() { + return request({ + url: '/monitor/server', + method: 'get' + }) +} \ No newline at end of file diff --git a/src/api/system/config.js b/src/api/system/config.js new file mode 100644 index 0000000..a404d82 --- /dev/null +++ b/src/api/system/config.js @@ -0,0 +1,60 @@ +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' + }) +} diff --git a/src/api/system/dept.js b/src/api/system/dept.js new file mode 100644 index 0000000..fc943cd --- /dev/null +++ b/src/api/system/dept.js @@ -0,0 +1,52 @@ +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' + }) +} \ No newline at end of file diff --git a/src/api/system/dict/data.js b/src/api/system/dict/data.js new file mode 100644 index 0000000..6c9eb79 --- /dev/null +++ b/src/api/system/dict/data.js @@ -0,0 +1,52 @@ +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' + }) +} diff --git a/src/api/system/dict/type.js b/src/api/system/dict/type.js new file mode 100644 index 0000000..a7a6e01 --- /dev/null +++ b/src/api/system/dict/type.js @@ -0,0 +1,60 @@ +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' + }) +} \ No newline at end of file diff --git a/src/api/system/menu.js b/src/api/system/menu.js new file mode 100644 index 0000000..f6415c6 --- /dev/null +++ b/src/api/system/menu.js @@ -0,0 +1,60 @@ +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' + }) +} \ No newline at end of file diff --git a/src/api/system/notice.js b/src/api/system/notice.js new file mode 100644 index 0000000..c274ea5 --- /dev/null +++ b/src/api/system/notice.js @@ -0,0 +1,44 @@ +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' + }) +} \ No newline at end of file diff --git a/src/api/system/post.js b/src/api/system/post.js new file mode 100644 index 0000000..1a8e9ca --- /dev/null +++ b/src/api/system/post.js @@ -0,0 +1,44 @@ +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' + }) +} diff --git a/src/api/system/role.js b/src/api/system/role.js new file mode 100644 index 0000000..f13e6f4 --- /dev/null +++ b/src/api/system/role.js @@ -0,0 +1,119 @@ +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 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' + }) +} diff --git a/src/api/system/user.js b/src/api/system/user.js new file mode 100644 index 0000000..1043af5 --- /dev/null +++ b/src/api/system/user.js @@ -0,0 +1,149 @@ +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 getLoginParam() { + return request({ + url: '/wechat/getWxBindQr', + method: 'get', + }); +} +// 瑙i櫎缁戝畾 +export function secureBind(data) { + return request({ + url: '/wechat/cancelBind', + method: 'post', + 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', + params: data + }) +} + +// 鐢ㄦ埛澶村儚涓婁紶 +export function uploadAvatar(data) { + return request({ + url: '/system/user/profile/avatar', + method: 'post', + 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' + }) +} diff --git a/src/api/tool/gen.js b/src/api/tool/gen.js new file mode 100644 index 0000000..4506927 --- /dev/null +++ b/src/api/tool/gen.js @@ -0,0 +1,76 @@ +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' + }) +} + +// 淇敼浠g爜鐢熸垚淇℃伅 +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 + }) +} + +// 棰勮鐢熸垚浠g爜 +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' + }) +} + +// 鐢熸垚浠g爜锛堣嚜瀹氫箟璺緞锛� +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' + }) +} diff --git a/src/api/tool/ossConfig.js b/src/api/tool/ossConfig.js new file mode 100644 index 0000000..1b9eaa7 --- /dev/null +++ b/src/api/tool/ossConfig.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 鏌ヨ鏂囦欢瀛樺偍閰嶇疆鍒楄〃 +export function listOssConfig(query) { + return request({ + url: '/oss/ossConfig/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ鏂囦欢瀛樺偍閰嶇疆璇︾粏 +export function getOssConfig(id) { + return request({ + url: '/oss/ossConfig/' + id, + method: 'get' + }) +} + +// 鏂板鏂囦欢瀛樺偍閰嶇疆 +export function addOssConfig(data) { + return request({ + url: '/oss/ossConfig', + method: 'post', + data: data + }) +} + +// 淇敼鏂囦欢瀛樺偍閰嶇疆 +export function updateOssConfig(data) { + return request({ + url: '/oss/ossConfig', + method: 'put', + data: data + }) +} + +// 鍒犻櫎鏂囦欢瀛樺偍閰嶇疆 +export function delOssConfig(id) { + return request({ + url: '/oss/ossConfig/' + id, + method: 'delete' + }) +} diff --git a/src/api/tool/ossDetail.js b/src/api/tool/ossDetail.js new file mode 100644 index 0000000..55c3111 --- /dev/null +++ b/src/api/tool/ossDetail.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 鏌ヨ鏂囦欢璁板綍鍒楄〃 +export function listOssDetail(query) { + return request({ + url: '/oss/OssDetail/list', + method: 'get', + params: query + }) +} + +// 鏌ヨ鏂囦欢璁板綍璇︾粏 +export function getOssDetail(id) { + return request({ + url: '/oss/OssDetail/' + id, + method: 'get' + }) +} + +// 鏂板鏂囦欢璁板綍 +export function addOssDetail(data) { + return request({ + url: '/oss/OssDetail', + method: 'post', + data: data + }) +} + +// 淇敼鏂囦欢璁板綍 +export function updateOssDetail(data) { + return request({ + url: '/oss/OssDetail', + method: 'put', + data: data + }) +} + +// 鍒犻櫎鏂囦欢璁板綍 +export function delOssDetail(id) { + return request({ + url: '/oss/OssDetail/' + id, + method: 'delete' + }) +} diff --git a/src/assets/401_images/401.gif b/src/assets/401_images/401.gif new file mode 100644 index 0000000..cd6e0d9 --- /dev/null +++ b/src/assets/401_images/401.gif Binary files differ diff --git a/src/assets/404_images/404.png b/src/assets/404_images/404.png new file mode 100644 index 0000000..3d8e230 --- /dev/null +++ b/src/assets/404_images/404.png Binary files differ diff --git a/src/assets/404_images/404_cloud.png b/src/assets/404_images/404_cloud.png new file mode 100644 index 0000000..c6281d0 --- /dev/null +++ b/src/assets/404_images/404_cloud.png Binary files differ diff --git a/src/assets/bigScreen/css/index.scss b/src/assets/bigScreen/css/index.scss new file mode 100644 index 0000000..0bc1560 --- /dev/null +++ b/src/assets/bigScreen/css/index.scss @@ -0,0 +1,361 @@ +@import "./modules/reset.scss"; +@import "./modules/variables.scss"; +// @import './theme/index.css'; +// @import '../iconfont//iconfont.css'; + +[class*=" blq-icon-"], +[class^=blq-icon-] { + font-family: iconfont !important; + speak: none; + font-style: normal; + font-weight: 400; + font-variant: normal; + text-transform: none; + line-height: 1; + vertical-align: middle; + display: inline-block; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale +} + +*, +:after, +:before { + box-sizing: content-box; +} + +.clearfix { + &::after { + content: ""; + display: table; + height: 0; + line-height: 0; + visibility: hidden; + clear: both; + } +} + +.contents { + width: 100%; + display: flex; + min-height: calc(100% - 60px); + justify-content: space-between; +} + +.beautify-scroll-def { + overflow-y: auto; + + &::-webkit-scrollbar-thumb { + //婊氬姩鏉$殑璁剧疆 + background-color: rgba(14, 59, 150, 0); + background-clip: padding-box; + border-radius: 4px; + } + + &:hover { + &::-webkit-scrollbar-thumb { + //婊氬姩鏉$殑璁剧疆 + background-color: rgba(14, 59, 150, 0.5); + background-clip: padding-box; + border-radius: 4px; + } + } + + &::-webkit-scrollbar-track-piece { + //婊氬姩鏉″嚬妲界殑棰滆壊锛岃繕鍙互璁剧疆杈规灞炴�� + background-color: transparent; + } + + &::-webkit-scrollbar { + //婊氬姩鏉$殑瀹藉害 + width: 8px; + height: 8px; + } + + + + &::-webkit-scrollbar-thumb:hover { + background-color: rgba(14, 59, 150, .8); + } +} + + +.orderNum { + // min-width: 22px; + // height: 22px; + // background: #00b8ff; + // border-radius: 50%; + // text-align: center; + // line-height: 22px; + // font-size: 13px; + // font-weight: 900; + // color: #0f2854; + color: #00b8ff; +} + +.yh-big-input { + width: 253px; + height: 14px; + background: transparent; + border: 1px solid rgba(255, 255, 255, .53); + border-radius: 4px; + color: #fff; + padding: 6px 10px; + font-size: 14px; + transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1); + + &:focus { + outline: none; + border-color: #31abe3; + } +} + +.yh-big-el-input { + width: 253px; + font-size: 14px; + + .el-input__inner { + padding: 6px 10px; + border: 1px solid rgba(255, 255, 255, .53); + background-color: transparent; + font-size: 14px; + line-height: 1; + color: #fff; + &:hover{ + border-color: rgba(255, 255, 255, .8); + } + &:focus { + outline: none; + border-color: #31abe3; + } + + } + +} + +.yh-big-button { + width: 53px; + height: 26px; + background: #00b1d6; + border-radius: 4px; + // border-color: #00b1d6; + border-width: 1px; + border: none; + cursor: pointer; + color: #fff; + font-size: 15px; + + &:hover, + &:focus { + // border-color: #0597b4; + background: #0597b4; + } +} + + +//娴姩 +.float-r { + float: right; +} + +//娴姩 +.float-l { + float: left; +} + +// 瀛椾綋鍔犵矖 +.fw-b { + font-weight: bold; +} + +//鏂囩珷涓�琛屾樉绀猴紝澶氫綑鐪佺暐鍙锋樉绀� +.title-item { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +//琛ㄦ牸鏍峰紡閲嶇疆 +.ve-table { + $border-color: #525371; + // $border-color: rgba(255, 255, 255, .43); + box-sizing: border-box; + + .ve-table-container { + &::-webkit-scrollbar-track-piece { + //婊氬姩鏉″嚬妲界殑棰滆壊锛岃繕鍙互璁剧疆杈规灞炴�� + background-color: transparent; + } + + &::-webkit-scrollbar { + //婊氬姩鏉$殑瀹藉害 + width: 8px; + height: 8px; + } + + &::-webkit-scrollbar-thumb { + //婊氬姩鏉$殑璁剧疆 + background-color: rgba(14, 59, 150, 0.5); + background-clip: padding-box; + border-radius: 4px; + } + + &::-webkit-scrollbar-thumb:hover { + background-color: rgba(14, 59, 150, .8); + } + + .ve-table-content { + &::after { + content: ""; + position: absolute; + top: 0; + right: 0px; + width: 1px; + height: 100%; + background-color: $border-color; + z-index: 20; + + } + } + + } + + &.ve-table-border-around { + border-color: $border-color; + } + + .ve-table-container table.ve-table-content thead.ve-table-header tr.ve-table-header-tr { + height: 34px; + box-sizing: border-box; + + th.ve-table-header-th { + background: #04004E; + color: #FFF; + border-color: $border-color; + box-sizing: border-box; + line-height: 1; + } + } + + .ve-table-container table.ve-table-content tbody.ve-table-body { + + tr.ve-table-body-tr td.ve-table-body-td, + tr.ve-table-expand-tr td.ve-table-body-td, + tr.ve-table-body-tr td.ve-table-expand-td, + tr.ve-table-expand-tr td.ve-table-expand-td { + background: transparent; + color: #FFF; + border-color: $border-color; + box-sizing: border-box; + } + + tr.ve-table-body-tr, + tr.ve-table-expand-tr { + height: 34px; + box-sizing: border-box; + } + + &.ve-table-row-hover tr.ve-table-body-tr:hover td { + background-color: rgba(0, 0, 0, .22); + box-sizing: border-box; + } + } + + + + .ve-table-container .ve-table-border-x th, + .ve-table-container .ve-table-border-x td { + border-color: $border-color; + box-sizing: border-box; + } + +} + + + +//棰滆壊 +@each $colorkey, +$color in $colors { + .text-#{$colorkey} { + color: $color; + } + + .bg-#{$colorkey} { + background-color: $color; + } +} + +//瀵归綈 +@each $var in (left, center, right) { + .text-#{$var} { + text-align: $var !important; + } +} + +//flex +@each $key, +$value in $flex-jc { + .jc-#{$key} { + justify-content: $value; + } +} + +@each $key, +$value in $flex-ai { + .ai-#{$key} { + align-items: $value; + } +} + +//瀛椾綋 +@each $fontkey, +$fontvalue in $font-sizes { + .fs-#{$fontkey} { + font-size: $fontvalue * $base-font-size; + } +} + +//.mt-1 => margin top +//spacing + +@each $typekey, +$type in $spacing-types { + + //.m-1 + @each $sizekey, + $size in $spacing-sizes { + .#{$typekey}-#{$sizekey} { + #{$type}: $size * $spacing-base-size; + } + } + + //.mx-1 + @each $sizekey, + $size in $spacing-sizes { + .#{$typekey}x-#{$sizekey} { + #{$type}-left: $size * $spacing-base-size; + #{$type}-right: $size * $spacing-base-size; + } + + .#{$typekey}y-#{$sizekey} { + #{$type}-top: $size * $spacing-base-size; + #{$type}-bottom: $size * $spacing-base-size; + } + } + + //.mt-1 + @each $directionkey, + $direction in $spacing-directions { + + @each $sizekey, + $size in $spacing-sizes { + .#{$typekey}#{$directionkey}-#{$sizekey} { + #{$type}-#{$direction}: $size * $spacing-base-size; + } + } + } + + .#{$typekey} { + #{$type}: 0; + } +} \ No newline at end of file diff --git a/src/assets/bigScreen/css/modules/reset.scss b/src/assets/bigScreen/css/modules/reset.scss new file mode 100644 index 0000000..3c38101 --- /dev/null +++ b/src/assets/bigScreen/css/modules/reset.scss @@ -0,0 +1,200 @@ +/** + * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/) + * http://cssreset.com + */ +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, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video, +input { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font-weight: normal; + vertical-align: baseline; +} + +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +menu, +nav, +section { + display: block; +} + +body { + line-height: 1; +} + +blockquote, +q { + quotes: none; +} + +blockquote:before, +blockquote:after, +q:before, +q:after { + content: none; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +/* custom */ + +a { + color: #7e8c8d; + -webkit-backface-visibility: hidden; + text-decoration: none; +} + +li { + list-style: none; +} + +body { + -webkit-text-size-adjust: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +.olControlScaleLineBottom { + display: none; +} + +.olControlScaleLineTop { + color: #000 !important; + border-bottom: solid 3px #000 !important; + border-left: solid 2px #000 !important; + border-right: solid 2px #000 !important; + background-color: rgba(255, 255, 255, .4); + font-size: 10px; + text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff; +} + +.olControlScaleLine { + z-index: 900 !important; +} +/*娓呴櫎娴姩*/ +.clearfix:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} +.clearfix {display: inline-block;} +/* 鐐瑰嚮鎼滅储妗嗚幏鍙栫劍鐐� placeholder娑堝け-寮�濮� */ +/* WebKit browsers */ + +// input:focus::-webkit-input-placeholder { +// color: transparent; +// } + + +// /* Mozilla Firefox 4 to 18 */ + +// input:focus:-moz-placeholder { +// color: transparent; +// } + + +// /* Mozilla Firefox 19+ */ + +// input:focus::-moz-placeholder { +// color: transparent; +// } + + +// /* Internet Explorer 10+ */ + +// input:focus:-ms-input-placeholder { +// color: transparent; +// } + +/* 鐐瑰嚮鎼滅储妗嗚幏鍙栫劍鐐� placeholder娑堝け-缁撴潫 */ diff --git a/src/assets/bigScreen/css/modules/variables.scss b/src/assets/bigScreen/css/modules/variables.scss new file mode 100644 index 0000000..e36162c --- /dev/null +++ b/src/assets/bigScreen/css/modules/variables.scss @@ -0,0 +1,98 @@ +// 棰滆壊 +$colors: ( + "primary": #1A5CD7, + "info-1": #4394e4, + "info": #4b67af, + "white": #ffffff, + "light": #f9f9f9, + "grey-1": #999999, + "grey": #666666, + "dark-1": #5f5f5f, + "dark": #222222, + "black-1": #171823, + "black": #000000, + "icon": #5cd9e8 +); + +// 瀛椾綋澶у皬 +$base-font-size: 0.2rem; +$font-sizes: ( + xxs: 0.1, + //8px + xs: 0.125, + //10px + sm: 0.2875, + //12px + md: 0.1625, + //13px + lg: 0.175, + //14px + xl: 0.2, + //16px + xxl: 0.225, + //18px + xxxl: 0.25 //20px,,,, +); + +// 瀹介珮 +.w-100 { + width: 100%; +} +.h-100 { + height: 100%; +} + +//flex +.flex { + display: flex; +} +.flex-column { + flex-direction: column; +} +.flex-wrap { + flex-wrap: wrap; +} +.flex-nowrap { + flex-wrap: nowrap; +} +$flex-jc: ( + start: flex-start, + end: flex-end, + center: center, + between: space-between, + around: space-around, + evenly: space-evenly, +); + +$flex-ai: ( + start: flex-start, + end: flex-end, + center: center, + stretch: stretch, +); + +.flex-1 { + flex: 1; +} + +//.mt-1 => margin top +//spacing +$spacing-types: ( + m: margin, + p: padding, +); +$spacing-directions: ( + t: top, + r: right, + b: bottom, + l: left, +); +$spacing-base-size: 0.5rem; +$spacing-sizes: ( + 0: 0, + 1: 0.5, + 2: 1, + 3: 1.5, + 4: 2, + 5: 2.5, +); diff --git a/src/assets/bigScreen/css/public.scss b/src/assets/bigScreen/css/public.scss new file mode 100644 index 0000000..719c7b6 --- /dev/null +++ b/src/assets/bigScreen/css/public.scss @@ -0,0 +1,156 @@ +.flex { + display: flex; +} + +.flex-direction { + flex-direction: column; +} + +.flex-wrap { + flex-wrap: wrap; +} + +.align-start { + align-items: flex-start; +} + +.align-end { + align-items: flex-end; +} + +.align-center { + align-items: center; +} + +.align-stretch { + align-items: stretch; +} + +.self-start { + align-self: flex-start; +} + +.self-center { + align-self: flex-center; +} + +.self-end { + align-self: flex-end; +} + +.self-stretch { + align-self: stretch; +} + +.align-stretch { + align-items: stretch; +} + +.justify-start { + justify-content: flex-start; +} + +.justify-end { + justify-content: flex-end; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.justify-around { + justify-content: space-around; +} +@for $i from 0 through 12 { + .rdx-flex-#{$i} { + flex: $i; + } +} + +@for $i from 9 to 50 { + .rdx-font-#{$i} { + font-size: $i + px; + } +} + +@for $i from 2 to 50 { + .rdx-radius-#{$i} { + border-radius: $i + px; + } +} +@for $i from 10 to 50 { + .rdx-line-height-#{$i} { + line-height: $i + px; + } +} + +// 瀹氫箟鍐呭杈硅窛锛屽巻閬�1-80 +@for $i from 0 through 80 { + // 鍙鍙屾暟鍜岃兘琚�5闄ゅ敖鐨勬暟 + @if $i % 2 == 0 or $i % 5 == 0 { + // 寰楀嚭锛歶-margin-30鎴栬�卽-m-30 + .rdx-m-#{$i} { + margin: $i + px !important; + } + // 寰楀嚭锛歶-padding-30鎴栬�卽-p-30 + .rdx-p-#{$i} { + padding: $i + px !important; + } + + @each $short, $long in l left, t top, r right, b bottom { + // 缂╁啓鐗堬紝缁撴灉濡傦細 u-m-l-30 + // 瀹氫箟澶栬竟璺� + .rdx-m-#{$short}-#{$i} { + margin-#{$long}: $i + px !important; + } + + // 瀹氫箟鍐呰竟璺� + .rdx-p-#{$short}-#{$i} { + padding-#{$long}: $i + px !important; + } + + //鑷畾涔夊乏鍙冲唴杈硅窛 + .rdx-p-lr-#{$i} { + padding-left:$i + px !important; + padding-right:$i + px !important; + } + //鑷畾涔変笂涓嬪唴杈硅窛 + .rdx-p-tb-#{$i} { + padding-top:$i + px !important; + padding-bottom:$i + px !important; + } + } + } +} +i{font-style: normal;} +.position-re{position: relative;} +.position-ab{position: absolute; z-index: 9;} +.position-fixed{position: fixed; background: rgba(92, 116, 143, 0.45); width: 100%; height: 100%; left: 0px; top: 0px; z-index: 10;} +.round{border-radius: 50%;} +.font-strong{font-weight: bold;} +// .color-del{color:$del-color} +// .color-primary{color: $primary-color;} +.color-remark{color: #666666;} +.color-9{color: #999999;} +.color-green{color: #38a800;} +.bg-white{background-color: white;} +.line-bottom{border-bottom: 1px solid #eeeeee;} +.button-pointer{cursor: pointer;} +.box-shadow-item{box-shadow: 0px 0px 4px 0px rgba(45, 45, 46, 0.1);} +.search-form .search-form-item label {text-align: right; padding-right: 6px;} + + +.break-all{ + word-break: break-all; +} +.blocks{ + width: 100%; + height: 100%; +} +.cursor-pointer{ + cursor: pointer; +} diff --git a/src/assets/bigScreen/css/theme/fonts/element-icons.ttf b/src/assets/bigScreen/css/theme/fonts/element-icons.ttf new file mode 100644 index 0000000..91b74de --- /dev/null +++ b/src/assets/bigScreen/css/theme/fonts/element-icons.ttf Binary files differ diff --git a/src/assets/bigScreen/css/theme/fonts/element-icons.woff b/src/assets/bigScreen/css/theme/fonts/element-icons.woff new file mode 100644 index 0000000..02b9a25 --- /dev/null +++ b/src/assets/bigScreen/css/theme/fonts/element-icons.woff Binary files differ diff --git a/src/assets/bigScreen/css/theme/index.css b/src/assets/bigScreen/css/theme/index.css new file mode 100644 index 0000000..ec735b2 --- /dev/null +++ b/src/assets/bigScreen/css/theme/index.css @@ -0,0 +1 @@ +@charset "UTF-8";.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)}@font-face{font-family:element-icons;src:url("fonts/element-icons.woff") format("woff"),url("fonts/element-icons.ttf") format("truetype");font-weight:400;font-display:"auto";font-style:normal}[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-popper .popper__arrow,.el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0,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-select-dropdown{position:absolute;z-index:1001;border:solid 1px #e4e7ed;border-radius:4px;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);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:#1890ff;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-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;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::-moz-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:#1890ff}.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::-moz-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;display:inline-block;width:100%}.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 .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;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;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::-moz-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__inner:focus{outline:0;border-color:#1890ff}.el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;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-active .el-input__inner{outline:0;border-color:#1890ff}.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::-moz-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-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: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__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.el-tag{background-color:#e8f4ff;border-color:#d1e9ff;color:#1890ff;display:inline-block;height:32px;padding:0 10px;line-height:30px;font-size:12px;color:#1890ff;border-width:1px;border-style:solid;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}.el-tag.is-hit{border-color:#1890ff}.el-tag .el-tag__close{color:#1890ff}.el-tag .el-tag__close:hover{color:#fff;background-color:#1890ff}.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:#1890ff;border-color:#1890ff;color:#fff}.el-tag--dark.is-hit{border-color:#1890ff}.el-tag--dark .el-tag__close{color:#fff}.el-tag--dark .el-tag__close:hover{color:#fff;background-color:#46a6ff}.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:#a3d3ff;color:#1890ff}.el-tag--plain.is-hit{border-color:#1890ff}.el-tag--plain .el-tag__close{color:#1890ff}.el-tag--plain .el-tag__close:hover{color:#fff;background-color:#1890ff}.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-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:#1890ff;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-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-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:#1890ff}.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-select .el-input.is-focus .el-input__inner{border-color:#1890ff}.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-select .el-tag__close.el-icon-close::before{display:block;-webkit-transform:translate(0,.5px);transform:translate(0,.5px)}.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:#1890ff}.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;background-size:16px;background-color:#fff;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-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{height:22px}.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:#1890ff}.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-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-prev.disabled,.el-pagination.is-background .el-pager li.disabled{color:#c0c4cc}.el-pagination.is-background .btn-next,.el-pagination.is-background .btn-prev{padding:0}.el-pagination.is-background .btn-next:disabled,.el-pagination.is-background .btn-prev:disabled{color:#c0c4cc}.el-pagination.is-background .el-pager li:not(.disabled):hover{color:#1890ff}.el-pagination.is-background .el-pager li:not(.disabled).active{background-color:#1890ff;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{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;list-style:none;display:inline-block;vertical-align:top;font-size:0;padding:0;margin:0}.el-pager .more::before{line-height:30px}.el-pager li{padding:0 4px;background:#fff;vertical-align:top;display:inline-block;font-size:13px;min-width:35.5px;height:28px;line-height:28px;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;margin:0}.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.btn-quickprev:hover{cursor:pointer}.el-pager li.btn-quicknext:hover{cursor:pointer}.el-pager li.active+li{border-left:0}.el-pager li:hover{color:#1890ff}.el-pager li.active{color:#1890ff;cursor:default}.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}@-webkit-keyframes v-modal-in{0%{opacity:0}}@keyframes v-modal-in{0%{opacity:0}}@-webkit-keyframes v-modal-out{100%{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-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);-webkit-box-sizing:border-box;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;padding-bottom: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:#1890ff}.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:20px;padding-top:10px;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-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;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::-moz-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:#1890ff}.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::-moz-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;display:inline-block;width:100%}.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 .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;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;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::-moz-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__inner:focus{outline:0;border-color:#1890ff}.el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;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-active .el-input__inner{outline:0;border-color:#1890ff}.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::-moz-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-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: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__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.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-popper .popper__arrow,.el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0,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-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:hover{background-color:#f5f7fa}.el-autocomplete-suggestion li.highlighted{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-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#fff;border:1px solid #dcdfe6;border-color:#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;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:4px}.el-button+.el-button{margin-left:10px}.el-button.is-round{padding:12px 20px}.el-button:focus,.el-button:hover{color:#1890ff;border-color:#badeff;background-color:#e8f4ff}.el-button:active{color:#1682e6;border-color:#1682e6;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:#1890ff;color:#1890ff}.el-button.is-plain:active{background:#fff;border-color:#1682e6;color:#1682e6;outline:0}.el-button.is-active{color:#1682e6;border-color:#1682e6}.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:#1890ff;border-color:#1890ff}.el-button--primary:focus,.el-button--primary:hover{background:#46a6ff;border-color:#46a6ff;color:#fff}.el-button--primary:active{background:#1682e6;border-color:#1682e6;color:#fff;outline:0}.el-button--primary.is-active{background:#1682e6;border-color:#1682e6;color:#fff}.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:#8cc8ff;border-color:#8cc8ff}.el-button--primary.is-plain{color:#1890ff;background:#e8f4ff;border-color:#a3d3ff}.el-button--primary.is-plain:focus,.el-button--primary.is-plain:hover{background:#1890ff;border-color:#1890ff;color:#fff}.el-button--primary.is-plain:active{background:#1682e6;border-color:#1682e6;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:#74bcff;background-color:#e8f4ff;border-color:#d1e9ff}.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:active{background:#5daf34;border-color:#5daf34;color:#fff;outline:0}.el-button--success.is-active{background:#5daf34;border-color:#5daf34;color:#fff}.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:active{background:#cf9236;border-color:#cf9236;color:#fff;outline:0}.el-button--warning.is-active{background:#cf9236;border-color:#cf9236;color:#fff}.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:active{background:#dd6161;border-color:#dd6161;color:#fff;outline:0}.el-button--danger.is-active{background:#dd6161;border-color:#dd6161;color:#fff}.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:active{background:#82848a;border-color:#82848a;color:#fff;outline:0}.el-button--info.is-active{background:#82848a;border-color:#82848a;color:#fff}.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{padding:7px 15px;font-size:12px;border-radius:3px}.el-button--mini.is-round{padding:7px 15px}.el-button--mini.is-circle{padding:7px}.el-button--text{border-color:transparent;color:#1890ff;background:0 0;padding-left:0;padding-right:0}.el-button--text:focus,.el-button--text:hover{color:#46a6ff;border-color:transparent;background-color:transparent}.el-button--text:active{color:#1682e6;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{display:inline-block;vertical-align:middle}.el-button-group::after,.el-button-group::before{display:table;content:""}.el-button-group::after{clear:both}.el-button-group>.el-button{float:left;position:relative}.el-button-group>.el-button+.el-button{margin-left:0}.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-top-right-radius:4px;border-bottom-right-radius:4px;border-top-left-radius:4px;border-bottom-left-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:not(:last-child){margin-right:-1px}.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-button.is-active{z-index:1}.el-button-group>.el-dropdown>.el-button{border-top-left-radius:0;border-bottom-left-radius:0;border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-popper .popper__arrow,.el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0,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-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{list-style:none;line-height:36px;padding:0 20px;margin:0;font-size:14px;color:#606266;cursor:pointer;outline:0}.el-dropdown-menu__item:focus,.el-dropdown-menu__item:not(.is-disabled):hover{background-color:#e8f4ff;color:#46a6ff}.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}.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-menu{border-right:solid 1px #e6e6e6;list-style:none;position:relative;margin:0;padding-left:0;background-color:#fff}.el-menu::after,.el-menu::before{display:table;content:""}.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-menu-item:not(.is-disabled):focus,.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover{background-color:#fff}.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 #1890ff;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__title:hover{background-color:#fff}.el-menu--horizontal>.el-submenu .el-submenu__icon-arrow{position:static;vertical-align:middle;margin-left:8px;margin-top:-3px}.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 #1890ff;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 .el-submenu__icon-arrow,.el-menu--collapse>.el-submenu>.el-submenu__title .el-submenu__icon-arrow{display:none}.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--collapse>.el-menu-item.is-active i{color:inherit}.el-menu--collapse .el-menu .el-submenu{min-width:200px}.el-menu--collapse .el-submenu{position:relative}.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{height:56px;line-height:56px;font-size:14px;color:#303133;padding:0 20px;list-style:none;cursor:pointer;position:relative;-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-menu-item *{vertical-align:middle}.el-menu-item i{color:#909399}.el-menu-item:focus,.el-menu-item:hover{outline:0;background-color:#e8f4ff}.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:#1890ff}.el-menu-item.is-active i{color:inherit}.el-submenu{list-style:none;margin:0;padding-left:0}.el-submenu__title{height:56px;line-height:56px;font-size:14px;color:#303133;padding:0 20px;list-style:none;cursor:pointer;position:relative;-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-submenu__title *{vertical-align:middle}.el-submenu__title i{color:#909399}.el-submenu__title:focus,.el-submenu__title:hover{outline:0;background-color:#e8f4ff}.el-submenu__title.is-disabled{opacity:.25;cursor:not-allowed;background:0 0!important}.el-submenu__title:hover{background-color:#e8f4ff}.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:#1890ff}.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}.horizontal-collapse-transition .el-submenu__title .el-submenu__icon-arrow{-webkit-transition:.2s;transition:.2s;opacity:0}.el-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;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::-moz-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:#1890ff}.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::-moz-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;display:inline-block;width:100%}.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 .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;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;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::-moz-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__inner:focus{outline:0;border-color:#1890ff}.el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;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-active .el-input__inner{outline:0;border-color:#1890ff}.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::-moz-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-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: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__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.el-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;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::-moz-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:#1890ff}.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::-moz-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;display:inline-block;width:100%}.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 .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;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;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::-moz-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__inner:focus{outline:0;border-color:#1890ff}.el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;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-active .el-input__inner{outline:0;border-color:#1890ff}.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::-moz-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-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: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__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.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:#1890ff}.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:#1890ff}.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 0}.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-radio{color:#606266;font-weight:500;line-height:1;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;outline:0;font-size:14px;margin-right:30px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.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-radio.is-bordered.is-checked{border-color:#1890ff}.el-radio.is-bordered.is-disabled{cursor:not-allowed;border-color:#ebeef5}.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--medium.is-bordered .el-radio__label{font-size:14px}.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__label{font-size:12px}.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__label{font-size:12px}.el-radio--mini.is-bordered .el-radio__inner{height:12px;width:12px}.el-radio:last-child{margin-right:0}.el-radio__input{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;vertical-align:middle}.el-radio__input.is-disabled .el-radio__inner{background-color:#f5f7fa;border-color:#e4e7ed;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{background-color:#f5f7fa;border-color:#e4e7ed}.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:#1890ff;background:#1890ff}.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:#1890ff}.el-radio__input.is-focus .el-radio__inner{border-color:#1890ff}.el-radio__inner{border:1px solid #dcdfe6;border-radius:100%;width:14px;height:14px;background-color:#fff;position:relative;cursor:pointer;display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box}.el-radio__inner:hover{border-color:#1890ff}.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 #1890ff;box-shadow:0 0 2px 2px #1890ff}.el-radio__label{font-size:14px;padding-left:10px}.el-radio-group{display:inline-block;line-height:1;vertical-align:middle;font-size:0}.el-radio-button{position:relative;display:inline-block;outline:0}.el-radio-button__inner{display:inline-block;line-height:1;white-space:nowrap;vertical-align:middle;background:#fff;border:1px solid #dcdfe6;font-weight:500;border-left:0;color:#606266;-webkit-appearance:none;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;outline:0;margin:0;position:relative;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:#1890ff}.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:#1890ff;border-color:#1890ff;-webkit-box-shadow:-1px 0 0 0 #1890ff;box-shadow:-1px 0 0 0 #1890ff}.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 #1890ff;box-shadow:0 0 2px 2px #1890ff}.el-checkbox{color:#606266;font-weight:500;font-size:14px;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;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:#1890ff}.el-checkbox.is-bordered.is-disabled{border-color:#ebeef5;cursor:not-allowed}.el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.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{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;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-disabled+span.el-checkbox__label{color:#c0c4cc;cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.el-checkbox__input.is-focus .el-checkbox__inner{border-color:#1890ff}.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.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 50ms;transition:-webkit-transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms,-webkit-transform .15s ease-in 50ms;-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__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.el-checkbox:last-of-type{margin-right:0}.el-checkbox-button{position:relative;display:inline-block}.el-checkbox-button__inner{display:inline-block;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;position:relative;-webkit-transition:all .3s cubic-bezier(.645, .045, .355, 1);transition:all .3s cubic-bezier(.645, .045, .355, 1);-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:0}.el-checkbox-button__inner.is-round{padding:12px 20px}.el-checkbox-button__inner:hover{color:#1890ff}.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-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#1890ff;border-color:#1890ff;-webkit-box-shadow:-1px 0 0 0 #74bcff;box-shadow:-1px 0 0 0 #74bcff}.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner{border-left-color:#1890ff}.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:#1890ff}.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-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.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;display:inline-block;font-size:14px;font-weight:500;cursor:pointer;vertical-align:middle;color:#303133}.el-switch__label.is-active{color:#1890ff}.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;display:inline-block;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;cursor:pointer;-webkit-transition:border-color .3s,background-color .3s;transition:border-color .3s,background-color .3s;vertical-align:middle}.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:#1890ff;background-color:#1890ff}.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-popper .popper__arrow,.el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0,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-select-dropdown{position:absolute;z-index:1001;border:solid 1px #e4e7ed;border-radius:4px;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);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:#1890ff;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-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;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::-moz-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:#1890ff}.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::-moz-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;display:inline-block;width:100%}.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 .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;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;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::-moz-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__inner:focus{outline:0;border-color:#1890ff}.el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;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-active .el-input__inner{outline:0;border-color:#1890ff}.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::-moz-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-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: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__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.el-tag{background-color:#e8f4ff;border-color:#d1e9ff;color:#1890ff;display:inline-block;height:32px;padding:0 10px;line-height:30px;font-size:12px;color:#1890ff;border-width:1px;border-style:solid;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}.el-tag.is-hit{border-color:#1890ff}.el-tag .el-tag__close{color:#1890ff}.el-tag .el-tag__close:hover{color:#fff;background-color:#1890ff}.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:#1890ff;border-color:#1890ff;color:#fff}.el-tag--dark.is-hit{border-color:#1890ff}.el-tag--dark .el-tag__close{color:#fff}.el-tag--dark .el-tag__close:hover{color:#fff;background-color:#46a6ff}.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:#a3d3ff;color:#1890ff}.el-tag--plain.is-hit{border-color:#1890ff}.el-tag--plain .el-tag__close{color:#1890ff}.el-tag--plain .el-tag__close:hover{color:#fff;background-color:#1890ff}.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-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:#1890ff;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-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-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:#1890ff}.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-select .el-input.is-focus .el-input__inner{border-color:#1890ff}.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-select .el-tag__close.el-icon-close::before{display:block;-webkit-transform:translate(0,.5px);transform:translate(0,.5px)}.el-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#fff;border:1px solid #dcdfe6;border-color:#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;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:4px}.el-button+.el-button{margin-left:10px}.el-button.is-round{padding:12px 20px}.el-button:focus,.el-button:hover{color:#1890ff;border-color:#badeff;background-color:#e8f4ff}.el-button:active{color:#1682e6;border-color:#1682e6;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:#1890ff;color:#1890ff}.el-button.is-plain:active{background:#fff;border-color:#1682e6;color:#1682e6;outline:0}.el-button.is-active{color:#1682e6;border-color:#1682e6}.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:#1890ff;border-color:#1890ff}.el-button--primary:focus,.el-button--primary:hover{background:#46a6ff;border-color:#46a6ff;color:#fff}.el-button--primary:active{background:#1682e6;border-color:#1682e6;color:#fff;outline:0}.el-button--primary.is-active{background:#1682e6;border-color:#1682e6;color:#fff}.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:#8cc8ff;border-color:#8cc8ff}.el-button--primary.is-plain{color:#1890ff;background:#e8f4ff;border-color:#a3d3ff}.el-button--primary.is-plain:focus,.el-button--primary.is-plain:hover{background:#1890ff;border-color:#1890ff;color:#fff}.el-button--primary.is-plain:active{background:#1682e6;border-color:#1682e6;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:#74bcff;background-color:#e8f4ff;border-color:#d1e9ff}.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:active{background:#5daf34;border-color:#5daf34;color:#fff;outline:0}.el-button--success.is-active{background:#5daf34;border-color:#5daf34;color:#fff}.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:active{background:#cf9236;border-color:#cf9236;color:#fff;outline:0}.el-button--warning.is-active{background:#cf9236;border-color:#cf9236;color:#fff}.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:active{background:#dd6161;border-color:#dd6161;color:#fff;outline:0}.el-button--danger.is-active{background:#dd6161;border-color:#dd6161;color:#fff}.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:active{background:#82848a;border-color:#82848a;color:#fff;outline:0}.el-button--info.is-active{background:#82848a;border-color:#82848a;color:#fff}.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{padding:7px 15px;font-size:12px;border-radius:3px}.el-button--mini.is-round{padding:7px 15px}.el-button--mini.is-circle{padding:7px}.el-button--text{border-color:transparent;color:#1890ff;background:0 0;padding-left:0;padding-right:0}.el-button--text:focus,.el-button--text:hover{color:#46a6ff;border-color:transparent;background-color:transparent}.el-button--text:active{color:#1682e6;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{display:inline-block;vertical-align:middle}.el-button-group::after,.el-button-group::before{display:table;content:""}.el-button-group::after{clear:both}.el-button-group>.el-button{float:left;position:relative}.el-button-group>.el-button+.el-button{margin-left:0}.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-top-right-radius:4px;border-bottom-right-radius:4px;border-top-left-radius:4px;border-bottom-left-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:not(:last-child){margin-right:-1px}.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-button.is-active{z-index:1}.el-button-group>.el-dropdown>.el-button{border-top-left-radius:0;border-bottom-left-radius:0;border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-checkbox{color:#606266;font-weight:500;font-size:14px;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;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:#1890ff}.el-checkbox.is-bordered.is-disabled{border-color:#ebeef5;cursor:not-allowed}.el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.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{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;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-disabled+span.el-checkbox__label{color:#c0c4cc;cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.el-checkbox__input.is-focus .el-checkbox__inner{border-color:#1890ff}.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.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 50ms;transition:-webkit-transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms,-webkit-transform .15s ease-in 50ms;-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__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.el-checkbox:last-of-type{margin-right:0}.el-checkbox-button{position:relative;display:inline-block}.el-checkbox-button__inner{display:inline-block;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;position:relative;-webkit-transition:all .3s cubic-bezier(.645, .045, .355, 1);transition:all .3s cubic-bezier(.645, .045, .355, 1);-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:0}.el-checkbox-button__inner.is-round{padding:12px 20px}.el-checkbox-button__inner:hover{color:#1890ff}.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-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#1890ff;border-color:#1890ff;-webkit-box-shadow:-1px 0 0 0 #74bcff;box-shadow:-1px 0 0 0 #74bcff}.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner{border-left-color:#1890ff}.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:#1890ff}.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-tag{background-color:#e8f4ff;border-color:#d1e9ff;color:#1890ff;display:inline-block;height:32px;padding:0 10px;line-height:30px;font-size:12px;color:#1890ff;border-width:1px;border-style:solid;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}.el-tag.is-hit{border-color:#1890ff}.el-tag .el-tag__close{color:#1890ff}.el-tag .el-tag__close:hover{color:#fff;background-color:#1890ff}.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:#1890ff;border-color:#1890ff;color:#fff}.el-tag--dark.is-hit{border-color:#1890ff}.el-tag--dark .el-tag__close{color:#fff}.el-tag--dark .el-tag__close:hover{color:#fff;background-color:#46a6ff}.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:#a3d3ff;color:#1890ff}.el-tag--plain.is-hit{border-color:#1890ff}.el-tag--plain .el-tag__close{color:#1890ff}.el-tag--plain .el-tag__close:hover{color:#fff;background-color:#1890ff}.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-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-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-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%;background-color:#fff;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{background-color:#fff}.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:#1890ff}.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-table td.el-table__cell.gutter{width:0}.el-table .cell{-webkit-box-sizing:border-box;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{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{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;border-bottom:1px solid #ebeef5}.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-none~.el-table__fixed,.el-table__body-wrapper.is-scrolling-none~.el-table__fixed-right{-webkit-box-shadow:none;box-shadow:none}.el-table__body-wrapper.is-scrolling-left~.el-table__fixed{-webkit-box-shadow:none;box-shadow:none}.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__body-wrapper .el-table--border.is-scrolling-left~.el-table__fixed{border-right: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:solid 5px 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:#1890ff}.el-table .descending .sort-caret.descending{border-top-color:#1890ff}.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{background-color:#e8f4ff}.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>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{background-color:#e8f4ff}.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-checkbox{color:#606266;font-weight:500;font-size:14px;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;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:#1890ff}.el-checkbox.is-bordered.is-disabled{border-color:#ebeef5;cursor:not-allowed}.el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.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{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;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-disabled+span.el-checkbox__label{color:#c0c4cc;cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.el-checkbox__input.is-focus .el-checkbox__inner{border-color:#1890ff}.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.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 50ms;transition:-webkit-transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms,-webkit-transform .15s ease-in 50ms;-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__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.el-checkbox:last-of-type{margin-right:0}.el-checkbox-button{position:relative;display:inline-block}.el-checkbox-button__inner{display:inline-block;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;position:relative;-webkit-transition:all .3s cubic-bezier(.645, .045, .355, 1);transition:all .3s cubic-bezier(.645, .045, .355, 1);-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:0}.el-checkbox-button__inner.is-round{padding:12px 20px}.el-checkbox-button__inner:hover{color:#1890ff}.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-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#1890ff;border-color:#1890ff;-webkit-box-shadow:-1px 0 0 0 #74bcff;box-shadow:-1px 0 0 0 #74bcff}.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner{border-left-color:#1890ff}.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:#1890ff}.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-tag{background-color:#e8f4ff;border-color:#d1e9ff;color:#1890ff;display:inline-block;height:32px;padding:0 10px;line-height:30px;font-size:12px;color:#1890ff;border-width:1px;border-style:solid;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}.el-tag.is-hit{border-color:#1890ff}.el-tag .el-tag__close{color:#1890ff}.el-tag .el-tag__close:hover{color:#fff;background-color:#1890ff}.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:#1890ff;border-color:#1890ff;color:#fff}.el-tag--dark.is-hit{border-color:#1890ff}.el-tag--dark .el-tag__close{color:#fff}.el-tag--dark .el-tag__close:hover{color:#fff;background-color:#46a6ff}.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:#a3d3ff;color:#1890ff}.el-tag--plain.is-hit{border-color:#1890ff}.el-tag--plain .el-tag__close{color:#1890ff}.el-tag--plain .el-tag__close:hover{color:#fff;background-color:#1890ff}.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-table-column--selection .cell{padding-left:14px;padding-right:14px}.el-table-filter{border:solid 1px #ebeef5;border-radius:2px;background-color:#fff;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);-webkit-box-sizing:border-box;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:#e8f4ff;color:#46a6ff}.el-table-filter__list-item.is-active{background-color:#1890ff;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-table-filter__bottom button:hover{color:#1890ff}.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 div{background-color:#f2f6fc}.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.is-week-mode .el-date-table__row.current div{background-color:#f2f6fc}.el-date-table td{width:32px;height:30px;padding:4px 0;-webkit-box-sizing:border-box;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:#1890ff;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:#1890ff}.el-date-table td.in-range div{background-color:#f2f6fc}.el-date-table td.in-range div:hover{background-color:#f2f6fc}.el-date-table td.current:not(.disabled) span{color:#fff;background-color:#1890ff}.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:#1890ff}.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:#1890ff;color:#fff;border-radius:15px}.el-date-table td.week{font-size:80%;color:#606266}.el-date-table th{padding:5px;color:#606266;font-weight:400;border-bottom:solid 1px #ebeef5}.el-month-table{font-size:12px;margin:-1px;border-collapse:collapse}.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:#1890ff;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:#1890ff}.el-month-table td.in-range div{background-color:#f2f6fc}.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:#1890ff}.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:#1890ff}.el-year-table{font-size:12px;margin:-1px;border-collapse:collapse}.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:#1890ff;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{color:#1890ff}.el-year-table td.current:not(.disabled) .cell{color:#1890ff}.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__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:#1890ff}.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__input.el-input .el-input__inner{padding:0;text-align:center}.el-time-spinner__list{padding:0;margin:0;list-style:none;text-align:center}.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}.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-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::-moz-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.is-active{border-color:#1890ff}.el-range-editor.is-active:hover{border-color:#1890ff}.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::-moz-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;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);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:#1890ff}.el-picker-panel__shortcut.active{background-color:#e6f1fe;color:#1890ff}.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:#1890ff}.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-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 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:hover{color:#1890ff}.el-date-picker__header-label.active{color:#1890ff}.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}.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 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-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-time-panel{margin:5px 0;border:solid 1px #e4e7ed;background-color:#fff;-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: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:66.6666666667%}.el-time-panel__content.has-seconds::before{padding-left:33.3333333333%}.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:#1890ff}.el-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;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::-moz-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:#1890ff}.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::-moz-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;display:inline-block;width:100%}.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 .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;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;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::-moz-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__inner:focus{outline:0;border-color:#1890ff}.el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;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-active .el-input__inner{outline:0;border-color:#1890ff}.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::-moz-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-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: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__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.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-popper .popper__arrow,.el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0,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}.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-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::-moz-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.is-active{border-color:#1890ff}.el-range-editor.is-active:hover{border-color:#1890ff}.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::-moz-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;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);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:#1890ff}.el-picker-panel__shortcut.active{background-color:#e6f1fe;color:#1890ff}.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:#1890ff}.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-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 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:hover{color:#1890ff}.el-date-picker__header-label.active{color:#1890ff}.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}.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-popper .popper__arrow,.el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0,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}.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:#1890ff;font-weight:700}.time-select-item.disabled{color:#e4e7ed;cursor:not-allowed}.time-select-item:hover{background-color:#f5f7fa;font-weight:700;cursor:pointer}.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-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::-moz-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.is-active{border-color:#1890ff}.el-range-editor.is-active:hover{border-color:#1890ff}.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::-moz-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;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);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:#1890ff}.el-picker-panel__shortcut.active{background-color:#e6f1fe;color:#1890ff}.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:#1890ff}.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__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:#1890ff}.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__input.el-input .el-input__inner{padding:0;text-align:center}.el-time-spinner__list{padding:0;margin:0;list-style:none;text-align:center}.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:solid 1px #e4e7ed;background-color:#fff;-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: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:66.6666666667%}.el-time-panel__content.has-seconds::before{padding-left:33.3333333333%}.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:#1890ff}.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-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;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::-moz-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:#1890ff}.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::-moz-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;display:inline-block;width:100%}.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 .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;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;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::-moz-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__inner:focus{outline:0;border-color:#1890ff}.el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;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-active .el-input__inner{outline:0;border-color:#1890ff}.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::-moz-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-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: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__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.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-popper .popper__arrow,.el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0,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-popper .popper__arrow,.el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0,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-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;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1);word-break:break-all}.el-popover--plain{padding:18px 20px}.el-popover__title{color:#303133;font-size:16px;line-height:1;margin-bottom:12px}.el-popover__reference:focus:hover,.el-popover__reference:focus:not(.focusing){outline-width:0}.el-popover:focus,.el-popover:focus:active{outline-width:0}.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-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}.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-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#fff;border:1px solid #dcdfe6;border-color:#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;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:4px}.el-button+.el-button{margin-left:10px}.el-button.is-round{padding:12px 20px}.el-button:focus,.el-button:hover{color:#1890ff;border-color:#badeff;background-color:#e8f4ff}.el-button:active{color:#1682e6;border-color:#1682e6;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:#1890ff;color:#1890ff}.el-button.is-plain:active{background:#fff;border-color:#1682e6;color:#1682e6;outline:0}.el-button.is-active{color:#1682e6;border-color:#1682e6}.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:#1890ff;border-color:#1890ff}.el-button--primary:focus,.el-button--primary:hover{background:#46a6ff;border-color:#46a6ff;color:#fff}.el-button--primary:active{background:#1682e6;border-color:#1682e6;color:#fff;outline:0}.el-button--primary.is-active{background:#1682e6;border-color:#1682e6;color:#fff}.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:#8cc8ff;border-color:#8cc8ff}.el-button--primary.is-plain{color:#1890ff;background:#e8f4ff;border-color:#a3d3ff}.el-button--primary.is-plain:focus,.el-button--primary.is-plain:hover{background:#1890ff;border-color:#1890ff;color:#fff}.el-button--primary.is-plain:active{background:#1682e6;border-color:#1682e6;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:#74bcff;background-color:#e8f4ff;border-color:#d1e9ff}.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:active{background:#5daf34;border-color:#5daf34;color:#fff;outline:0}.el-button--success.is-active{background:#5daf34;border-color:#5daf34;color:#fff}.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:active{background:#cf9236;border-color:#cf9236;color:#fff;outline:0}.el-button--warning.is-active{background:#cf9236;border-color:#cf9236;color:#fff}.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:active{background:#dd6161;border-color:#dd6161;color:#fff;outline:0}.el-button--danger.is-active{background:#dd6161;border-color:#dd6161;color:#fff}.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:active{background:#82848a;border-color:#82848a;color:#fff;outline:0}.el-button--info.is-active{background:#82848a;border-color:#82848a;color:#fff}.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{padding:7px 15px;font-size:12px;border-radius:3px}.el-button--mini.is-round{padding:7px 15px}.el-button--mini.is-circle{padding:7px}.el-button--text{border-color:transparent;color:#1890ff;background:0 0;padding-left:0;padding-right:0}.el-button--text:focus,.el-button--text:hover{color:#46a6ff;border-color:transparent;background-color:transparent}.el-button--text:active{color:#1682e6;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{display:inline-block;vertical-align:middle}.el-button-group::after,.el-button-group::before{display:table;content:""}.el-button-group::after{clear:both}.el-button-group>.el-button{float:left;position:relative}.el-button-group>.el-button+.el-button{margin-left:0}.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-top-right-radius:4px;border-bottom-right-radius:4px;border-top-left-radius:4px;border-bottom-left-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:not(:last-child){margin-right:-1px}.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-button.is-active{z-index:1}.el-button-group>.el-dropdown>.el-button{border-top-left-radius:0;border-bottom-left-radius:0;border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;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::-moz-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:#1890ff}.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::-moz-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;display:inline-block;width:100%}.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 .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;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;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::-moz-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__inner:focus{outline:0;border-color:#1890ff}.el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;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-active .el-input__inner{outline:0;border-color:#1890ff}.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::-moz-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-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: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__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.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;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);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;padding-bottom: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-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:#1890ff}.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__input input.invalid{border-color:#f56c6c}.el-message-box__input input.invalid:focus{border-color:#f56c6c}.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:#1890ff;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-breadcrumb__item:last-child .el-breadcrumb__separator{display:none}.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 0}.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 .el-input__validateIcon{display:none}.el-form-item--medium .el-form-item__label{line-height:36px}.el-form-item--medium .el-form-item__content{line-height:36px}.el-form-item--small .el-form-item__label{line-height:32px}.el-form-item--small .el-form-item__content{line-height:32px}.el-form-item--small.el-form-item{margin-bottom:18px}.el-form-item--small .el-form-item__error{padding-top:2px}.el-form-item--mini .el-form-item__label{line-height:28px}.el-form-item--mini .el-form-item__content{line-height:28px}.el-form-item--mini.el-form-item{margin-bottom:18px}.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__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{border-color:#f56c6c}.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:#1890ff;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:#1890ff}.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 #1890ff inset;box-shadow:0 0 2px 2px #1890ff 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__item .el-icon-close:hover{background-color:#c0c4cc;color:#fff}.el-tabs__item.is-active{color:#1890ff}.el-tabs__item:hover{color:#1890ff;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__active-bar{display:none}.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:first-child{margin-left:-1px}.el-tabs--border-card>.el-tabs__header .el-tabs__item+.el-tabs__item{margin-left:-1px}.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-active{color:#1890ff;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:#1890ff}.el-tabs--border-card>.el-tabs__header .el-tabs__item.is-disabled{color:#c0c4cc}.el-tabs--border-card>.el-tabs__header .is-scrollable .el-tabs__item:first-child{margin-left:0}.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-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--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__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 -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__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-tabs--left .el-tabs__nav-wrap.is-left{margin-right:-1px}.el-tabs--left .el-tabs__nav-wrap.is-left::after{left:auto;right:0}.el-tabs--left .el-tabs__active-bar.is-left{right:0;left:auto}.el-tabs--left .el-tabs__item.is-left{text-align:right}.el-tabs--left.el-tabs--card .el-tabs__active-bar.is-left{display:none}.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:transparent;border-top-color:#d1dbe5;border-bottom-color:#d1dbe5}.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__active-bar.is-right{display:none}.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:transparent;border-top-color:#d1dbe5;border-bottom-color:#d1dbe5}.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-tag{background-color:#e8f4ff;border-color:#d1e9ff;color:#1890ff;display:inline-block;height:32px;padding:0 10px;line-height:30px;font-size:12px;color:#1890ff;border-width:1px;border-style:solid;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}.el-tag.is-hit{border-color:#1890ff}.el-tag .el-tag__close{color:#1890ff}.el-tag .el-tag__close:hover{color:#fff;background-color:#1890ff}.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:#1890ff;border-color:#1890ff;color:#fff}.el-tag--dark.is-hit{border-color:#1890ff}.el-tag--dark .el-tag__close{color:#fff}.el-tag--dark .el-tag__close:hover{color:#fff;background-color:#46a6ff}.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:#a3d3ff;color:#1890ff}.el-tag--plain.is-hit{border-color:#1890ff}.el-tag--plain .el-tag__close{color:#1890ff}.el-tag--plain .el-tag__close:hover{color:#fff;background-color:#1890ff}.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)}.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-checkbox{color:#606266;font-weight:500;font-size:14px;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;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:#1890ff}.el-checkbox.is-bordered.is-disabled{border-color:#ebeef5;cursor:not-allowed}.el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.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{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;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-disabled+span.el-checkbox__label{color:#c0c4cc;cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.el-checkbox__input.is-focus .el-checkbox__inner{border-color:#1890ff}.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.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 50ms;transition:-webkit-transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms,-webkit-transform .15s ease-in 50ms;-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__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.el-checkbox:last-of-type{margin-right:0}.el-checkbox-button{position:relative;display:inline-block}.el-checkbox-button__inner{display:inline-block;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;position:relative;-webkit-transition:all .3s cubic-bezier(.645, .045, .355, 1);transition:all .3s cubic-bezier(.645, .045, .355, 1);-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:0}.el-checkbox-button__inner.is-round{padding:12px 20px}.el-checkbox-button__inner:hover{color:#1890ff}.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-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#1890ff;border-color:#1890ff;-webkit-box-shadow:-1px 0 0 0 #74bcff;box-shadow:-1px 0 0 0 #74bcff}.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner{border-left-color:#1890ff}.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:#1890ff}.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-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:#1890ff}.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:#1890ff;color:#fff}.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-node__content:hover{background-color:#f5f7fa}.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:#edf6ff}.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{color:#fff}.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 0}.el-alert__closebtn{font-size:12px;opacity:1;position:absolute;top:12px;right:15px;cursor:pointer}.el-alert__closebtn.is-customed{font-style:normal;font-size:13px;top:9px}.el-alert-fade-enter,.el-alert-fade-leave-active{opacity:0}.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;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);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.right{right:16px}.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 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-notification-fade-leave-active{opacity:0}.el-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;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::-moz-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:#1890ff}.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::-moz-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;display:inline-block;width:100%}.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 .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;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;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::-moz-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__inner:focus{outline:0;border-color:#1890ff}.el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;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-active .el-input__inner{outline:0;border-color:#1890ff}.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::-moz-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-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: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__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.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:#1890ff}.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:#1890ff}.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 0}.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-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;content:""}.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.hover,.el-slider__runway.disabled .el-slider__button-wrapper:hover{cursor:not-allowed}.el-slider__runway.disabled .el-slider__button-wrapper.dragging{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)}.el-slider__runway.disabled .el-slider__button.hover,.el-slider__runway.disabled .el-slider__button:hover{cursor:not-allowed}.el-slider__runway.disabled .el-slider__button.dragging{cursor:not-allowed}.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:#1890ff;border-top-left-radius:3px;border-bottom-left-radius:3px;position:absolute}.el-slider__button-wrapper{height:36px;width:36px;position:absolute;z-index:1001;top:-15px;-webkit-transform:translateX(-50%);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-slider__button-wrapper::after{display:inline-block;content:"";height:100%;vertical-align:middle}.el-slider__button-wrapper .el-tooltip{vertical-align:middle;display:inline-block}.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:solid 2px #1890ff;background-color:#fff;border-radius:50%;-webkit-transition:.2s;transition:.2s;-webkit-user-select:none;-moz-user-select:none;-ms-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{position:absolute;height:6px;width:6px;border-radius:100%;background-color:#fff;-webkit-transform:translateX(-50%);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:#1890ff}.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-loading-spinner .el-loading-text{color:#1890ff;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:#1890FF;stroke-linecap:round}.el-loading-spinner i{color:#1890ff}.el-loading-fade-enter,.el-loading-fade-leave-active{opacity:0}@-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{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box}.el-row::after,.el-row::before{display:table;content:""}.el-row::after{clear:both}.el-row--flex{display:-webkit-box;display:-ms-flexbox;display:flex}.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{display:none}.el-col-0{width:0%}.el-col-offset-0{margin-left:0}.el-col-pull-0{position:relative;right:0}.el-col-push-0{position:relative;left:0}.el-col-1{width:4.1666666667%}.el-col-offset-1{margin-left:4.1666666667%}.el-col-pull-1{position:relative;right:4.1666666667%}.el-col-push-1{position:relative;left:4.1666666667%}.el-col-2{width:8.3333333333%}.el-col-offset-2{margin-left:8.3333333333%}.el-col-pull-2{position:relative;right:8.3333333333%}.el-col-push-2{position:relative;left:8.3333333333%}.el-col-3{width:12.5%}.el-col-offset-3{margin-left:12.5%}.el-col-pull-3{position:relative;right:12.5%}.el-col-push-3{position:relative;left:12.5%}.el-col-4{width:16.6666666667%}.el-col-offset-4{margin-left:16.6666666667%}.el-col-pull-4{position:relative;right:16.6666666667%}.el-col-push-4{position:relative;left:16.6666666667%}.el-col-5{width:20.8333333333%}.el-col-offset-5{margin-left:20.8333333333%}.el-col-pull-5{position:relative;right:20.8333333333%}.el-col-push-5{position:relative;left:20.8333333333%}.el-col-6{width:25%}.el-col-offset-6{margin-left:25%}.el-col-pull-6{position:relative;right:25%}.el-col-push-6{position:relative;left:25%}.el-col-7{width:29.1666666667%}.el-col-offset-7{margin-left:29.1666666667%}.el-col-pull-7{position:relative;right:29.1666666667%}.el-col-push-7{position:relative;left:29.1666666667%}.el-col-8{width:33.3333333333%}.el-col-offset-8{margin-left:33.3333333333%}.el-col-pull-8{position:relative;right:33.3333333333%}.el-col-push-8{position:relative;left:33.3333333333%}.el-col-9{width:37.5%}.el-col-offset-9{margin-left:37.5%}.el-col-pull-9{position:relative;right:37.5%}.el-col-push-9{position:relative;left:37.5%}.el-col-10{width:41.6666666667%}.el-col-offset-10{margin-left:41.6666666667%}.el-col-pull-10{position:relative;right:41.6666666667%}.el-col-push-10{position:relative;left:41.6666666667%}.el-col-11{width:45.8333333333%}.el-col-offset-11{margin-left:45.8333333333%}.el-col-pull-11{position:relative;right:45.8333333333%}.el-col-push-11{position:relative;left:45.8333333333%}.el-col-12{width:50%}.el-col-offset-12{margin-left:50%}.el-col-pull-12{position:relative;right:50%}.el-col-push-12{position:relative;left:50%}.el-col-13{width:54.1666666667%}.el-col-offset-13{margin-left:54.1666666667%}.el-col-pull-13{position:relative;right:54.1666666667%}.el-col-push-13{position:relative;left:54.1666666667%}.el-col-14{width:58.3333333333%}.el-col-offset-14{margin-left:58.3333333333%}.el-col-pull-14{position:relative;right:58.3333333333%}.el-col-push-14{position:relative;left:58.3333333333%}.el-col-15{width:62.5%}.el-col-offset-15{margin-left:62.5%}.el-col-pull-15{position:relative;right:62.5%}.el-col-push-15{position:relative;left:62.5%}.el-col-16{width:66.6666666667%}.el-col-offset-16{margin-left:66.6666666667%}.el-col-pull-16{position:relative;right:66.6666666667%}.el-col-push-16{position:relative;left:66.6666666667%}.el-col-17{width:70.8333333333%}.el-col-offset-17{margin-left:70.8333333333%}.el-col-pull-17{position:relative;right:70.8333333333%}.el-col-push-17{position:relative;left:70.8333333333%}.el-col-18{width:75%}.el-col-offset-18{margin-left:75%}.el-col-pull-18{position:relative;right:75%}.el-col-push-18{position:relative;left:75%}.el-col-19{width:79.1666666667%}.el-col-offset-19{margin-left:79.1666666667%}.el-col-pull-19{position:relative;right:79.1666666667%}.el-col-push-19{position:relative;left:79.1666666667%}.el-col-20{width:83.3333333333%}.el-col-offset-20{margin-left:83.3333333333%}.el-col-pull-20{position:relative;right:83.3333333333%}.el-col-push-20{position:relative;left:83.3333333333%}.el-col-21{width:87.5%}.el-col-offset-21{margin-left:87.5%}.el-col-pull-21{position:relative;right:87.5%}.el-col-push-21{position:relative;left:87.5%}.el-col-22{width:91.6666666667%}.el-col-offset-22{margin-left:91.6666666667%}.el-col-pull-22{position:relative;right:91.6666666667%}.el-col-push-22{position:relative;left:91.6666666667%}.el-col-23{width:95.8333333333%}.el-col-offset-23{margin-left:95.8333333333%}.el-col-pull-23{position:relative;right:95.8333333333%}.el-col-push-23{position:relative;left:95.8333333333%}.el-col-24{width:100%}.el-col-offset-24{margin-left:100%}.el-col-pull-24{position:relative;right:100%}.el-col-push-24{position:relative;left:100%}@media only screen and (max-width:767px){.el-col-xs-0{display:none}.el-col-xs-0{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.1666666667%}.el-col-xs-offset-1{margin-left:4.1666666667%}.el-col-xs-pull-1{position:relative;right:4.1666666667%}.el-col-xs-push-1{position:relative;left:4.1666666667%}.el-col-xs-2{width:8.3333333333%}.el-col-xs-offset-2{margin-left:8.3333333333%}.el-col-xs-pull-2{position:relative;right:8.3333333333%}.el-col-xs-push-2{position:relative;left:8.3333333333%}.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.6666666667%}.el-col-xs-offset-4{margin-left:16.6666666667%}.el-col-xs-pull-4{position:relative;right:16.6666666667%}.el-col-xs-push-4{position:relative;left:16.6666666667%}.el-col-xs-5{width:20.8333333333%}.el-col-xs-offset-5{margin-left:20.8333333333%}.el-col-xs-pull-5{position:relative;right:20.8333333333%}.el-col-xs-push-5{position:relative;left:20.8333333333%}.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.1666666667%}.el-col-xs-offset-7{margin-left:29.1666666667%}.el-col-xs-pull-7{position:relative;right:29.1666666667%}.el-col-xs-push-7{position:relative;left:29.1666666667%}.el-col-xs-8{width:33.3333333333%}.el-col-xs-offset-8{margin-left:33.3333333333%}.el-col-xs-pull-8{position:relative;right:33.3333333333%}.el-col-xs-push-8{position:relative;left:33.3333333333%}.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.6666666667%}.el-col-xs-offset-10{margin-left:41.6666666667%}.el-col-xs-pull-10{position:relative;right:41.6666666667%}.el-col-xs-push-10{position:relative;left:41.6666666667%}.el-col-xs-11{width:45.8333333333%}.el-col-xs-offset-11{margin-left:45.8333333333%}.el-col-xs-pull-11{position:relative;right:45.8333333333%}.el-col-xs-push-11{position:relative;left:45.8333333333%}.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.1666666667%}.el-col-xs-offset-13{margin-left:54.1666666667%}.el-col-xs-pull-13{position:relative;right:54.1666666667%}.el-col-xs-push-13{position:relative;left:54.1666666667%}.el-col-xs-14{width:58.3333333333%}.el-col-xs-offset-14{margin-left:58.3333333333%}.el-col-xs-pull-14{position:relative;right:58.3333333333%}.el-col-xs-push-14{position:relative;left:58.3333333333%}.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.6666666667%}.el-col-xs-offset-16{margin-left:66.6666666667%}.el-col-xs-pull-16{position:relative;right:66.6666666667%}.el-col-xs-push-16{position:relative;left:66.6666666667%}.el-col-xs-17{width:70.8333333333%}.el-col-xs-offset-17{margin-left:70.8333333333%}.el-col-xs-pull-17{position:relative;right:70.8333333333%}.el-col-xs-push-17{position:relative;left:70.8333333333%}.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.1666666667%}.el-col-xs-offset-19{margin-left:79.1666666667%}.el-col-xs-pull-19{position:relative;right:79.1666666667%}.el-col-xs-push-19{position:relative;left:79.1666666667%}.el-col-xs-20{width:83.3333333333%}.el-col-xs-offset-20{margin-left:83.3333333333%}.el-col-xs-pull-20{position:relative;right:83.3333333333%}.el-col-xs-push-20{position:relative;left:83.3333333333%}.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.6666666667%}.el-col-xs-offset-22{margin-left:91.6666666667%}.el-col-xs-pull-22{position:relative;right:91.6666666667%}.el-col-xs-push-22{position:relative;left:91.6666666667%}.el-col-xs-23{width:95.8333333333%}.el-col-xs-offset-23{margin-left:95.8333333333%}.el-col-xs-pull-23{position:relative;right:95.8333333333%}.el-col-xs-push-23{position:relative;left:95.8333333333%}.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}.el-col-sm-0{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.1666666667%}.el-col-sm-offset-1{margin-left:4.1666666667%}.el-col-sm-pull-1{position:relative;right:4.1666666667%}.el-col-sm-push-1{position:relative;left:4.1666666667%}.el-col-sm-2{width:8.3333333333%}.el-col-sm-offset-2{margin-left:8.3333333333%}.el-col-sm-pull-2{position:relative;right:8.3333333333%}.el-col-sm-push-2{position:relative;left:8.3333333333%}.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.6666666667%}.el-col-sm-offset-4{margin-left:16.6666666667%}.el-col-sm-pull-4{position:relative;right:16.6666666667%}.el-col-sm-push-4{position:relative;left:16.6666666667%}.el-col-sm-5{width:20.8333333333%}.el-col-sm-offset-5{margin-left:20.8333333333%}.el-col-sm-pull-5{position:relative;right:20.8333333333%}.el-col-sm-push-5{position:relative;left:20.8333333333%}.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.1666666667%}.el-col-sm-offset-7{margin-left:29.1666666667%}.el-col-sm-pull-7{position:relative;right:29.1666666667%}.el-col-sm-push-7{position:relative;left:29.1666666667%}.el-col-sm-8{width:33.3333333333%}.el-col-sm-offset-8{margin-left:33.3333333333%}.el-col-sm-pull-8{position:relative;right:33.3333333333%}.el-col-sm-push-8{position:relative;left:33.3333333333%}.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.6666666667%}.el-col-sm-offset-10{margin-left:41.6666666667%}.el-col-sm-pull-10{position:relative;right:41.6666666667%}.el-col-sm-push-10{position:relative;left:41.6666666667%}.el-col-sm-11{width:45.8333333333%}.el-col-sm-offset-11{margin-left:45.8333333333%}.el-col-sm-pull-11{position:relative;right:45.8333333333%}.el-col-sm-push-11{position:relative;left:45.8333333333%}.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.1666666667%}.el-col-sm-offset-13{margin-left:54.1666666667%}.el-col-sm-pull-13{position:relative;right:54.1666666667%}.el-col-sm-push-13{position:relative;left:54.1666666667%}.el-col-sm-14{width:58.3333333333%}.el-col-sm-offset-14{margin-left:58.3333333333%}.el-col-sm-pull-14{position:relative;right:58.3333333333%}.el-col-sm-push-14{position:relative;left:58.3333333333%}.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.6666666667%}.el-col-sm-offset-16{margin-left:66.6666666667%}.el-col-sm-pull-16{position:relative;right:66.6666666667%}.el-col-sm-push-16{position:relative;left:66.6666666667%}.el-col-sm-17{width:70.8333333333%}.el-col-sm-offset-17{margin-left:70.8333333333%}.el-col-sm-pull-17{position:relative;right:70.8333333333%}.el-col-sm-push-17{position:relative;left:70.8333333333%}.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.1666666667%}.el-col-sm-offset-19{margin-left:79.1666666667%}.el-col-sm-pull-19{position:relative;right:79.1666666667%}.el-col-sm-push-19{position:relative;left:79.1666666667%}.el-col-sm-20{width:83.3333333333%}.el-col-sm-offset-20{margin-left:83.3333333333%}.el-col-sm-pull-20{position:relative;right:83.3333333333%}.el-col-sm-push-20{position:relative;left:83.3333333333%}.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.6666666667%}.el-col-sm-offset-22{margin-left:91.6666666667%}.el-col-sm-pull-22{position:relative;right:91.6666666667%}.el-col-sm-push-22{position:relative;left:91.6666666667%}.el-col-sm-23{width:95.8333333333%}.el-col-sm-offset-23{margin-left:95.8333333333%}.el-col-sm-pull-23{position:relative;right:95.8333333333%}.el-col-sm-push-23{position:relative;left:95.8333333333%}.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}.el-col-md-0{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.1666666667%}.el-col-md-offset-1{margin-left:4.1666666667%}.el-col-md-pull-1{position:relative;right:4.1666666667%}.el-col-md-push-1{position:relative;left:4.1666666667%}.el-col-md-2{width:8.3333333333%}.el-col-md-offset-2{margin-left:8.3333333333%}.el-col-md-pull-2{position:relative;right:8.3333333333%}.el-col-md-push-2{position:relative;left:8.3333333333%}.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.6666666667%}.el-col-md-offset-4{margin-left:16.6666666667%}.el-col-md-pull-4{position:relative;right:16.6666666667%}.el-col-md-push-4{position:relative;left:16.6666666667%}.el-col-md-5{width:20.8333333333%}.el-col-md-offset-5{margin-left:20.8333333333%}.el-col-md-pull-5{position:relative;right:20.8333333333%}.el-col-md-push-5{position:relative;left:20.8333333333%}.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.1666666667%}.el-col-md-offset-7{margin-left:29.1666666667%}.el-col-md-pull-7{position:relative;right:29.1666666667%}.el-col-md-push-7{position:relative;left:29.1666666667%}.el-col-md-8{width:33.3333333333%}.el-col-md-offset-8{margin-left:33.3333333333%}.el-col-md-pull-8{position:relative;right:33.3333333333%}.el-col-md-push-8{position:relative;left:33.3333333333%}.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.6666666667%}.el-col-md-offset-10{margin-left:41.6666666667%}.el-col-md-pull-10{position:relative;right:41.6666666667%}.el-col-md-push-10{position:relative;left:41.6666666667%}.el-col-md-11{width:45.8333333333%}.el-col-md-offset-11{margin-left:45.8333333333%}.el-col-md-pull-11{position:relative;right:45.8333333333%}.el-col-md-push-11{position:relative;left:45.8333333333%}.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.1666666667%}.el-col-md-offset-13{margin-left:54.1666666667%}.el-col-md-pull-13{position:relative;right:54.1666666667%}.el-col-md-push-13{position:relative;left:54.1666666667%}.el-col-md-14{width:58.3333333333%}.el-col-md-offset-14{margin-left:58.3333333333%}.el-col-md-pull-14{position:relative;right:58.3333333333%}.el-col-md-push-14{position:relative;left:58.3333333333%}.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.6666666667%}.el-col-md-offset-16{margin-left:66.6666666667%}.el-col-md-pull-16{position:relative;right:66.6666666667%}.el-col-md-push-16{position:relative;left:66.6666666667%}.el-col-md-17{width:70.8333333333%}.el-col-md-offset-17{margin-left:70.8333333333%}.el-col-md-pull-17{position:relative;right:70.8333333333%}.el-col-md-push-17{position:relative;left:70.8333333333%}.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.1666666667%}.el-col-md-offset-19{margin-left:79.1666666667%}.el-col-md-pull-19{position:relative;right:79.1666666667%}.el-col-md-push-19{position:relative;left:79.1666666667%}.el-col-md-20{width:83.3333333333%}.el-col-md-offset-20{margin-left:83.3333333333%}.el-col-md-pull-20{position:relative;right:83.3333333333%}.el-col-md-push-20{position:relative;left:83.3333333333%}.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.6666666667%}.el-col-md-offset-22{margin-left:91.6666666667%}.el-col-md-pull-22{position:relative;right:91.6666666667%}.el-col-md-push-22{position:relative;left:91.6666666667%}.el-col-md-23{width:95.8333333333%}.el-col-md-offset-23{margin-left:95.8333333333%}.el-col-md-pull-23{position:relative;right:95.8333333333%}.el-col-md-push-23{position:relative;left:95.8333333333%}.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}.el-col-lg-0{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.1666666667%}.el-col-lg-offset-1{margin-left:4.1666666667%}.el-col-lg-pull-1{position:relative;right:4.1666666667%}.el-col-lg-push-1{position:relative;left:4.1666666667%}.el-col-lg-2{width:8.3333333333%}.el-col-lg-offset-2{margin-left:8.3333333333%}.el-col-lg-pull-2{position:relative;right:8.3333333333%}.el-col-lg-push-2{position:relative;left:8.3333333333%}.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.6666666667%}.el-col-lg-offset-4{margin-left:16.6666666667%}.el-col-lg-pull-4{position:relative;right:16.6666666667%}.el-col-lg-push-4{position:relative;left:16.6666666667%}.el-col-lg-5{width:20.8333333333%}.el-col-lg-offset-5{margin-left:20.8333333333%}.el-col-lg-pull-5{position:relative;right:20.8333333333%}.el-col-lg-push-5{position:relative;left:20.8333333333%}.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.1666666667%}.el-col-lg-offset-7{margin-left:29.1666666667%}.el-col-lg-pull-7{position:relative;right:29.1666666667%}.el-col-lg-push-7{position:relative;left:29.1666666667%}.el-col-lg-8{width:33.3333333333%}.el-col-lg-offset-8{margin-left:33.3333333333%}.el-col-lg-pull-8{position:relative;right:33.3333333333%}.el-col-lg-push-8{position:relative;left:33.3333333333%}.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.6666666667%}.el-col-lg-offset-10{margin-left:41.6666666667%}.el-col-lg-pull-10{position:relative;right:41.6666666667%}.el-col-lg-push-10{position:relative;left:41.6666666667%}.el-col-lg-11{width:45.8333333333%}.el-col-lg-offset-11{margin-left:45.8333333333%}.el-col-lg-pull-11{position:relative;right:45.8333333333%}.el-col-lg-push-11{position:relative;left:45.8333333333%}.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.1666666667%}.el-col-lg-offset-13{margin-left:54.1666666667%}.el-col-lg-pull-13{position:relative;right:54.1666666667%}.el-col-lg-push-13{position:relative;left:54.1666666667%}.el-col-lg-14{width:58.3333333333%}.el-col-lg-offset-14{margin-left:58.3333333333%}.el-col-lg-pull-14{position:relative;right:58.3333333333%}.el-col-lg-push-14{position:relative;left:58.3333333333%}.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.6666666667%}.el-col-lg-offset-16{margin-left:66.6666666667%}.el-col-lg-pull-16{position:relative;right:66.6666666667%}.el-col-lg-push-16{position:relative;left:66.6666666667%}.el-col-lg-17{width:70.8333333333%}.el-col-lg-offset-17{margin-left:70.8333333333%}.el-col-lg-pull-17{position:relative;right:70.8333333333%}.el-col-lg-push-17{position:relative;left:70.8333333333%}.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.1666666667%}.el-col-lg-offset-19{margin-left:79.1666666667%}.el-col-lg-pull-19{position:relative;right:79.1666666667%}.el-col-lg-push-19{position:relative;left:79.1666666667%}.el-col-lg-20{width:83.3333333333%}.el-col-lg-offset-20{margin-left:83.3333333333%}.el-col-lg-pull-20{position:relative;right:83.3333333333%}.el-col-lg-push-20{position:relative;left:83.3333333333%}.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.6666666667%}.el-col-lg-offset-22{margin-left:91.6666666667%}.el-col-lg-pull-22{position:relative;right:91.6666666667%}.el-col-lg-push-22{position:relative;left:91.6666666667%}.el-col-lg-23{width:95.8333333333%}.el-col-lg-offset-23{margin-left:95.8333333333%}.el-col-lg-pull-23{position:relative;right:95.8333333333%}.el-col-lg-push-23{position:relative;left:95.8333333333%}.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}.el-col-xl-0{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.1666666667%}.el-col-xl-offset-1{margin-left:4.1666666667%}.el-col-xl-pull-1{position:relative;right:4.1666666667%}.el-col-xl-push-1{position:relative;left:4.1666666667%}.el-col-xl-2{width:8.3333333333%}.el-col-xl-offset-2{margin-left:8.3333333333%}.el-col-xl-pull-2{position:relative;right:8.3333333333%}.el-col-xl-push-2{position:relative;left:8.3333333333%}.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.6666666667%}.el-col-xl-offset-4{margin-left:16.6666666667%}.el-col-xl-pull-4{position:relative;right:16.6666666667%}.el-col-xl-push-4{position:relative;left:16.6666666667%}.el-col-xl-5{width:20.8333333333%}.el-col-xl-offset-5{margin-left:20.8333333333%}.el-col-xl-pull-5{position:relative;right:20.8333333333%}.el-col-xl-push-5{position:relative;left:20.8333333333%}.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.1666666667%}.el-col-xl-offset-7{margin-left:29.1666666667%}.el-col-xl-pull-7{position:relative;right:29.1666666667%}.el-col-xl-push-7{position:relative;left:29.1666666667%}.el-col-xl-8{width:33.3333333333%}.el-col-xl-offset-8{margin-left:33.3333333333%}.el-col-xl-pull-8{position:relative;right:33.3333333333%}.el-col-xl-push-8{position:relative;left:33.3333333333%}.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.6666666667%}.el-col-xl-offset-10{margin-left:41.6666666667%}.el-col-xl-pull-10{position:relative;right:41.6666666667%}.el-col-xl-push-10{position:relative;left:41.6666666667%}.el-col-xl-11{width:45.8333333333%}.el-col-xl-offset-11{margin-left:45.8333333333%}.el-col-xl-pull-11{position:relative;right:45.8333333333%}.el-col-xl-push-11{position:relative;left:45.8333333333%}.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.1666666667%}.el-col-xl-offset-13{margin-left:54.1666666667%}.el-col-xl-pull-13{position:relative;right:54.1666666667%}.el-col-xl-push-13{position:relative;left:54.1666666667%}.el-col-xl-14{width:58.3333333333%}.el-col-xl-offset-14{margin-left:58.3333333333%}.el-col-xl-pull-14{position:relative;right:58.3333333333%}.el-col-xl-push-14{position:relative;left:58.3333333333%}.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.6666666667%}.el-col-xl-offset-16{margin-left:66.6666666667%}.el-col-xl-pull-16{position:relative;right:66.6666666667%}.el-col-xl-push-16{position:relative;left:66.6666666667%}.el-col-xl-17{width:70.8333333333%}.el-col-xl-offset-17{margin-left:70.8333333333%}.el-col-xl-pull-17{position:relative;right:70.8333333333%}.el-col-xl-push-17{position:relative;left:70.8333333333%}.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.1666666667%}.el-col-xl-offset-19{margin-left:79.1666666667%}.el-col-xl-pull-19{position:relative;right:79.1666666667%}.el-col-xl-push-19{position:relative;left:79.1666666667%}.el-col-xl-20{width:83.3333333333%}.el-col-xl-offset-20{margin-left:83.3333333333%}.el-col-xl-pull-20{position:relative;right:83.3333333333%}.el-col-xl-push-20{position:relative;left:83.3333333333%}.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.6666666667%}.el-col-xl-offset-22{margin-left:91.6666666667%}.el-col-xl-pull-22{position:relative;right:91.6666666667%}.el-col-xl-push-22{position:relative;left:91.6666666667%}.el-col-xl-23{width:95.8333333333%}.el-col-xl-offset-23{margin-left:95.8333333333%}.el-col-xl-pull-23{position:relative;right:95.8333333333%}.el-col-xl-push-23{position:relative;left:95.8333333333%}.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%}}.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-progress.is-warning .el-progress__text{color:#e6a23c}.el-progress.is-exception .el-progress-bar__inner{background-color:#f56c6c}.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-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:#1890ff;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;content:"";height:100%;vertical-align:middle}.el-progress-bar__innerText{display:inline-block;vertical-align:middle;color:#fff;font-size:12px;margin:0 5px}@-webkit-keyframes progress{0%{background-position:0 0}100%{background-position:32px 0}}@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;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{border-color:#1890ff;color:#1890ff}.el-upload:focus{border-color:#1890ff;color:#1890ff}.el-upload:focus .el-upload-dragger{border-color:#1890ff}.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;position:relative;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:#1890ff;font-style:normal}.el-upload-dragger:hover{border-color:#1890ff}.el-upload-dragger.is-dragover{background-color:rgba(32,159,255,.06);border:2px dashed #1890ff}.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;position:relative;-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:#1890ff}.el-upload-list__item:hover{background-color:#f5f7fa}.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:#1890ff;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:not(.focusing):focus .el-icon-close-tip{display:none}.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{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:#1890ff}.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{display:none}.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;content:"";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;content:"";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 i{margin-top:0}.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-progress.is-warning .el-progress__text{color:#e6a23c}.el-progress.is-exception .el-progress-bar__inner{background-color:#f56c6c}.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-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:#1890ff;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;content:"";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;-webkit-box-sizing:border-box;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{background-color:#f56c6c;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-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:#1890ff}.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{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-card.is-hover-shadow:focus,.el-card.is-hover-shadow:hover{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-card__header{padding:18px 20px;border-bottom:1px solid #ebeef5;-webkit-box-sizing:border-box;box-sizing:border-box}.el-card__body{padding:20px}.el-rate{height:20px;line-height:1}.el-rate:active,.el-rate:focus{outline-width:0}.el-rate__item{display:inline-block;position:relative;font-size:0;vertical-align:middle}.el-rate__icon{position:relative;display:inline-block;font-size:18px;margin-right:6px;color:#c0c4cc;-webkit-transition:.3s;transition:.3s}.el-rate__icon.hover{-webkit-transform:scale(1.15);transform:scale(1.15)}.el-rate__icon .path2{position:absolute;left:0;top:0}.el-rate__decimal{position:absolute;top:0;left:0;display:inline-block;overflow:hidden}.el-rate__text{font-size:14px;vertical-align:middle}.el-steps{display:-webkit-box;display:-ms-flexbox;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:#1890ff;border-color:#1890ff}.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;-webkit-box-sizing:border-box;box-sizing:border-box;background:#fff;-webkit-transition:.15s ease-out;transition:.15s ease-out}.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{display:inline-block;-webkit-user-select:none;-moz-user-select:none;-ms-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:#1890ff}.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:#1890ff}.el-step.is-horizontal{display:inline-block}.el-step.is-horizontal .el-step__line{height:2px;top:11px;left:0;right:0}.el-step.is-vertical{display:-webkit-box;display:-ms-flexbox;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{text-align:center}.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--right{right: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}.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-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-carousel__item{position:absolute;top:0;left:0;width:100%;height: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{position:absolute;width:100%;height:100%;top:0;left:0;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:#1890ff}.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-collapse-item__content{padding-bottom:25px;font-size:13px;color:#303133;line-height:1.7692307692}.el-collapse-item:last-child{margin-bottom:-1px}.el-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;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::-moz-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:#1890ff}.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::-moz-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;display:inline-block;width:100%}.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 .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;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;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::-moz-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__inner:focus{outline:0;border-color:#1890ff}.el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;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-active .el-input__inner{outline:0;border-color:#1890ff}.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::-moz-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-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: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__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.el-popper .popper__arrow,.el-popper .popper__arrow::after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.el-popper .popper__arrow{border-width:6px;-webkit-filter:drop-shadow(0 2px 12px rgba(0,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:#e8f4ff;border-color:#d1e9ff;color:#1890ff;display:inline-block;height:32px;padding:0 10px;line-height:30px;font-size:12px;color:#1890ff;border-width:1px;border-style:solid;border-radius:4px;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:nowrap}.el-tag.is-hit{border-color:#1890ff}.el-tag .el-tag__close{color:#1890ff}.el-tag .el-tag__close:hover{color:#fff;background-color:#1890ff}.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:#1890ff;border-color:#1890ff;color:#fff}.el-tag--dark.is-hit{border-color:#1890ff}.el-tag--dark .el-tag__close{color:#fff}.el-tag--dark .el-tag__close:hover{color:#fff;background-color:#46a6ff}.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:#a3d3ff;color:#1890ff}.el-tag--plain.is-hit{border-color:#1890ff}.el-tag--plain .el-tag__close{color:#1890ff}.el-tag--plain .el-tag__close:hover{color:#fff;background-color:#1890ff}.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-checkbox{color:#606266;font-weight:500;font-size:14px;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;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:#1890ff}.el-checkbox.is-bordered.is-disabled{border-color:#ebeef5;cursor:not-allowed}.el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.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{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;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-disabled+span.el-checkbox__label{color:#c0c4cc;cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.el-checkbox__input.is-focus .el-checkbox__inner{border-color:#1890ff}.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.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 50ms;transition:-webkit-transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms,-webkit-transform .15s ease-in 50ms;-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__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.el-checkbox:last-of-type{margin-right:0}.el-checkbox-button{position:relative;display:inline-block}.el-checkbox-button__inner{display:inline-block;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;position:relative;-webkit-transition:all .3s cubic-bezier(.645, .045, .355, 1);transition:all .3s cubic-bezier(.645, .045, .355, 1);-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:0}.el-checkbox-button__inner.is-round{padding:12px 20px}.el-checkbox-button__inner:hover{color:#1890ff}.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-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#1890ff;border-color:#1890ff;-webkit-box-shadow:-1px 0 0 0 #74bcff;box-shadow:-1px 0 0 0 #74bcff}.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner{border-left-color:#1890ff}.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:#1890ff}.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-radio{color:#606266;font-weight:500;line-height:1;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;outline:0;font-size:14px;margin-right:30px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.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-radio.is-bordered.is-checked{border-color:#1890ff}.el-radio.is-bordered.is-disabled{cursor:not-allowed;border-color:#ebeef5}.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--medium.is-bordered .el-radio__label{font-size:14px}.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__label{font-size:12px}.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__label{font-size:12px}.el-radio--mini.is-bordered .el-radio__inner{height:12px;width:12px}.el-radio:last-child{margin-right:0}.el-radio__input{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;vertical-align:middle}.el-radio__input.is-disabled .el-radio__inner{background-color:#f5f7fa;border-color:#e4e7ed;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{background-color:#f5f7fa;border-color:#e4e7ed}.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:#1890ff;background:#1890ff}.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:#1890ff}.el-radio__input.is-focus .el-radio__inner{border-color:#1890ff}.el-radio__inner{border:1px solid #dcdfe6;border-radius:100%;width:14px;height:14px;background-color:#fff;position:relative;cursor:pointer;display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box}.el-radio__inner:hover{border-color:#1890ff}.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 #1890ff;box-shadow:0 0 2px 2px #1890ff}.el-radio__label{font-size:14px;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;font-size:14px}.el-cascader-panel.is-bordered{border:solid 1px #e4e7ed;border-radius:4px}.el-cascader-menu{min-width:180px;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;border-right:solid 1px #e4e7ed}.el-cascader-menu:last-child{border-right:none}.el-cascader-menu:last-child .el-cascader-node{padding-right:20px}.el-cascader-menu__wrap{height:204px}.el-cascader-menu__list{position:relative;min-height:100%;margin:0;padding:6px 0;list-style:none;-webkit-box-sizing:border-box;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:#1890ff;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{margin-right:0}.el-cascader-node>.el-radio .el-radio__label{padding-left:0}.el-cascader{display:inline-block;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{cursor:pointer}.el-cascader .el-input .el-input__inner{text-overflow:ellipsis}.el-cascader .el-input .el-input__inner:focus{border-color:#1890ff}.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 .el-input.is-focus .el-input__inner{border-color:#1890ff}.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:solid 1px #e4e7ed;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-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;-webkit-box-sizing:border-box;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:#1890ff;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;-webkit-box-sizing:border-box;box-sizing:border-box}.el-cascader__search-input::-webkit-input-placeholder{color:#c0c4cc}.el-cascader__search-input::-moz-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 #1890ff;box-shadow:0 0 3px 2px #1890ff}.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{content:"";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:#1890ff;border-color:#1890ff}.el-color-dropdown__link-btn{cursor:pointer;color:#1890ff;text-decoration:none;padding:15px;font-size:12px}.el-color-dropdown__link-btn:hover{color:tint(#1890ff,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__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{display:inline-block;position:absolute;width:100%;top:50%;left:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0);color:#fff;text-align:center;font-size:12px}.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;-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.el-textarea{position:relative;display:inline-block;width:100%;vertical-align:bottom;font-size:14px}.el-textarea__inner{display:block;resize:vertical;padding:5px 15px;line-height:1.5;-webkit-box-sizing:border-box;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::-moz-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:#1890ff}.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::-moz-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;display:inline-block;width:100%}.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 .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;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;display:inline-block;font-size:inherit;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::-moz-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__inner:focus{outline:0;border-color:#1890ff}.el-input__suffix{position:absolute;height:100%;right:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;transition:all .3s;pointer-events:none}.el-input__suffix-inner{pointer-events:all}.el-input__prefix{position:absolute;height:100%;left:5px;top:0;text-align:center;color:#c0c4cc;-webkit-transition:all .3s;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-active .el-input__inner{outline:0;border-color:#1890ff}.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::-moz-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-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: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__append .el-button,.el-input-group__append .el-input,.el-input-group__prepend .el-button,.el-input-group__prepend .el-input{font-size:inherit}.el-input-group__prepend{border-right:0;border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group__append{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-input__inner{border-top-left-radius:0;border-bottom-left-radius:0}.el-input-group--prepend .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input-group--append .el-input__inner{border-top-right-radius:0;border-bottom-right-radius:0}.el-input-group--append .el-select .el-input.is-focus .el-input__inner{border-color:transparent}.el-input__inner::-ms-clear{display:none;width:0;height:0}.el-button{display:inline-block;line-height:1;white-space:nowrap;cursor:pointer;background:#fff;border:1px solid #dcdfe6;border-color:#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;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:4px}.el-button+.el-button{margin-left:10px}.el-button.is-round{padding:12px 20px}.el-button:focus,.el-button:hover{color:#1890ff;border-color:#badeff;background-color:#e8f4ff}.el-button:active{color:#1682e6;border-color:#1682e6;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:#1890ff;color:#1890ff}.el-button.is-plain:active{background:#fff;border-color:#1682e6;color:#1682e6;outline:0}.el-button.is-active{color:#1682e6;border-color:#1682e6}.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:#1890ff;border-color:#1890ff}.el-button--primary:focus,.el-button--primary:hover{background:#46a6ff;border-color:#46a6ff;color:#fff}.el-button--primary:active{background:#1682e6;border-color:#1682e6;color:#fff;outline:0}.el-button--primary.is-active{background:#1682e6;border-color:#1682e6;color:#fff}.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:#8cc8ff;border-color:#8cc8ff}.el-button--primary.is-plain{color:#1890ff;background:#e8f4ff;border-color:#a3d3ff}.el-button--primary.is-plain:focus,.el-button--primary.is-plain:hover{background:#1890ff;border-color:#1890ff;color:#fff}.el-button--primary.is-plain:active{background:#1682e6;border-color:#1682e6;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:#74bcff;background-color:#e8f4ff;border-color:#d1e9ff}.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:active{background:#5daf34;border-color:#5daf34;color:#fff;outline:0}.el-button--success.is-active{background:#5daf34;border-color:#5daf34;color:#fff}.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:active{background:#cf9236;border-color:#cf9236;color:#fff;outline:0}.el-button--warning.is-active{background:#cf9236;border-color:#cf9236;color:#fff}.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:active{background:#dd6161;border-color:#dd6161;color:#fff;outline:0}.el-button--danger.is-active{background:#dd6161;border-color:#dd6161;color:#fff}.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:active{background:#82848a;border-color:#82848a;color:#fff;outline:0}.el-button--info.is-active{background:#82848a;border-color:#82848a;color:#fff}.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{padding:7px 15px;font-size:12px;border-radius:3px}.el-button--mini.is-round{padding:7px 15px}.el-button--mini.is-circle{padding:7px}.el-button--text{border-color:transparent;color:#1890ff;background:0 0;padding-left:0;padding-right:0}.el-button--text:focus,.el-button--text:hover{color:#46a6ff;border-color:transparent;background-color:transparent}.el-button--text:active{color:#1682e6;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{display:inline-block;vertical-align:middle}.el-button-group::after,.el-button-group::before{display:table;content:""}.el-button-group::after{clear:both}.el-button-group>.el-button{float:left;position:relative}.el-button-group>.el-button+.el-button{margin-left:0}.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-top-right-radius:4px;border-bottom-right-radius:4px;border-top-left-radius:4px;border-bottom-left-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:not(:last-child){margin-right:-1px}.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-button.is-active{z-index:1}.el-button-group>.el-dropdown>.el-button{border-top-left-radius:0;border-bottom-left-radius:0;border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-checkbox{color:#606266;font-weight:500;font-size:14px;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;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:#1890ff}.el-checkbox.is-bordered.is-disabled{border-color:#ebeef5;cursor:not-allowed}.el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.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{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;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-disabled+span.el-checkbox__label{color:#c0c4cc;cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.el-checkbox__input.is-focus .el-checkbox__inner{border-color:#1890ff}.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.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 50ms;transition:-webkit-transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms,-webkit-transform .15s ease-in 50ms;-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__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.el-checkbox:last-of-type{margin-right:0}.el-checkbox-button{position:relative;display:inline-block}.el-checkbox-button__inner{display:inline-block;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;position:relative;-webkit-transition:all .3s cubic-bezier(.645, .045, .355, 1);transition:all .3s cubic-bezier(.645, .045, .355, 1);-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:0}.el-checkbox-button__inner.is-round{padding:12px 20px}.el-checkbox-button__inner:hover{color:#1890ff}.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-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#1890ff;border-color:#1890ff;-webkit-box-shadow:-1px 0 0 0 #74bcff;box-shadow:-1px 0 0 0 #74bcff}.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner{border-left-color:#1890ff}.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:#1890ff}.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-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:#1890ff;font-size:0}.el-transfer__button.is-with-texts{border-radius:4px}.el-transfer__button.is-disabled{border:1px solid #dcdfe6;background-color:#f5f7fa;color:#c0c4cc}.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__button i,.el-transfer__button span{font-size:14px}.el-transfer__button [class*=el-icon-]+span{margin-left: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%;-webkit-box-sizing:border-box;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-transfer-panel__item{margin-left:0}.el-transfer-panel__item.el-checkbox{color:#606266}.el-transfer-panel__item:hover{color:#1890ff}.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__filter .el-icon-circle-close{cursor:pointer}.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-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;content:"";height:100%;vertical-align:middle}.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:-webkit-box;display:-ms-flexbox;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;-webkit-box-sizing:border-box;box-sizing:border-box;min-width:0}.el-container.is-vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.el-header{padding:0 20px;-webkit-box-sizing:border-box;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;padding:20px}.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;font-size:14px;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:-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-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:#1890ff}.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:-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-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;cursor:pointer;padding:0;font-size:14px;font-weight:500}.el-link.is-underline:hover:after{content:"";position:absolute;left:0;right:0;height:0;bottom:0;border-bottom:1px solid #1890ff}.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:#1890ff}.el-link.el-link--default:after{border-color:#1890ff}.el-link.el-link--default.is-disabled{color:#c0c4cc}.el-link.el-link--primary{color:#1890ff}.el-link.el-link--primary:hover{color:#46a6ff}.el-link.el-link--primary:after{border-color:#1890ff}.el-link.el-link--primary.is-disabled{color:#8cc8ff}.el-link.el-link--primary.is-underline:hover:after{border-color:#1890ff}.el-link.el-link--danger{color:#f56c6c}.el-link.el-link--danger:hover{color:#f78989}.el-link.el-link--danger:after{border-color:#f56c6c}.el-link.el-link--danger.is-disabled{color:#fab6b6}.el-link.el-link--danger.is-underline:hover:after{border-color:#f56c6c}.el-link.el-link--success{color:#67c23a}.el-link.el-link--success:hover{color:#85ce61}.el-link.el-link--success:after{border-color:#67c23a}.el-link.el-link--success.is-disabled{color:#b3e19d}.el-link.el-link--success.is-underline:hover:after{border-color:#67c23a}.el-link.el-link--warning{color:#e6a23c}.el-link.el-link--warning:hover{color:#ebb563}.el-link.el-link--warning:after{border-color:#e6a23c}.el-link.el-link--warning.is-disabled{color:#f3d19e}.el-link.el-link--warning.is-underline:hover:after{border-color:#e6a23c}.el-link.el-link--info{color:#909399}.el-link.el-link--info:hover{color:#a6a9ad}.el-link.el-link--info:after{border-color:#909399}.el-link.el-link--info.is-disabled{color:#c8c9cc}.el-link.el-link--info.is-underline:hover:after{border-color:#909399}.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;font-size:14px}.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__placeholder{background:#f5f7fa}.el-image__error{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;font-size:14px;background:#f5f7fa;color:#c0c4cc;vertical-align:middle}.el-image__preview{cursor:pointer}.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;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;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__prev{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);width:44px;height:44px;font-size:24px;color:#fff;background-color:#606266;border-color:#fff;left:40px}.el-image-viewer__next{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);width:44px;height:44px;font-size:24px;color:#fff;background-color:#606266;border-color:#fff;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;border-color:#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;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:4px}.el-button+.el-button{margin-left:10px}.el-button.is-round{padding:12px 20px}.el-button:focus,.el-button:hover{color:#1890ff;border-color:#badeff;background-color:#e8f4ff}.el-button:active{color:#1682e6;border-color:#1682e6;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:#1890ff;color:#1890ff}.el-button.is-plain:active{background:#fff;border-color:#1682e6;color:#1682e6;outline:0}.el-button.is-active{color:#1682e6;border-color:#1682e6}.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:#1890ff;border-color:#1890ff}.el-button--primary:focus,.el-button--primary:hover{background:#46a6ff;border-color:#46a6ff;color:#fff}.el-button--primary:active{background:#1682e6;border-color:#1682e6;color:#fff;outline:0}.el-button--primary.is-active{background:#1682e6;border-color:#1682e6;color:#fff}.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:#8cc8ff;border-color:#8cc8ff}.el-button--primary.is-plain{color:#1890ff;background:#e8f4ff;border-color:#a3d3ff}.el-button--primary.is-plain:focus,.el-button--primary.is-plain:hover{background:#1890ff;border-color:#1890ff;color:#fff}.el-button--primary.is-plain:active{background:#1682e6;border-color:#1682e6;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:#74bcff;background-color:#e8f4ff;border-color:#d1e9ff}.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:active{background:#5daf34;border-color:#5daf34;color:#fff;outline:0}.el-button--success.is-active{background:#5daf34;border-color:#5daf34;color:#fff}.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:active{background:#cf9236;border-color:#cf9236;color:#fff;outline:0}.el-button--warning.is-active{background:#cf9236;border-color:#cf9236;color:#fff}.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:active{background:#dd6161;border-color:#dd6161;color:#fff;outline:0}.el-button--danger.is-active{background:#dd6161;border-color:#dd6161;color:#fff}.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:active{background:#82848a;border-color:#82848a;color:#fff;outline:0}.el-button--info.is-active{background:#82848a;border-color:#82848a;color:#fff}.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{padding:7px 15px;font-size:12px;border-radius:3px}.el-button--mini.is-round{padding:7px 15px}.el-button--mini.is-circle{padding:7px}.el-button--text{border-color:transparent;color:#1890ff;background:0 0;padding-left:0;padding-right:0}.el-button--text:focus,.el-button--text:hover{color:#46a6ff;border-color:transparent;background-color:transparent}.el-button--text:active{color:#1682e6;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{display:inline-block;vertical-align:middle}.el-button-group::after,.el-button-group::before{display:table;content:""}.el-button-group::after{clear:both}.el-button-group>.el-button{float:left;position:relative}.el-button-group>.el-button+.el-button{margin-left:0}.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-top-right-radius:4px;border-bottom-right-radius:4px;border-top-left-radius:4px;border-bottom-left-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:not(:last-child){margin-right:-1px}.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-button.is-active{z-index:1}.el-button-group>.el-dropdown>.el-button{border-top-left-radius:0;border-bottom-left-radius:0;border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--primary:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--success:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--warning:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--danger:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:first-child{border-right-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:last-child{border-left-color:rgba(255,255,255,.5)}.el-button-group .el-button--info:not(:first-child):not(:last-child){border-left-color:rgba(255,255,255,.5);border-right-color:rgba(255,255,255,.5)}.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-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-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 td.is-today{color:#1890ff}.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%;color:#1890ff;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;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:-webkit-box;display:-ms-flexbox;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{content:"";position:absolute;width:1px;height:16px;right:-20px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%);background-color:#dcdfe6}.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;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;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:#1890ff}.el-checkbox.is-bordered.is-disabled{border-color:#ebeef5;cursor:not-allowed}.el-checkbox.is-bordered+.el-checkbox.is-bordered{margin-left:10px}.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{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;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-disabled+span.el-checkbox__label{color:#c0c4cc;cursor:not-allowed}.el-checkbox__input.is-checked .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.el-checkbox__input.is-focus .el-checkbox__inner{border-color:#1890ff}.el-checkbox__input.is-indeterminate .el-checkbox__inner{background-color:#1890ff;border-color:#1890ff}.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:#1890ff}.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 50ms;transition:-webkit-transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms;transition:transform .15s ease-in 50ms,-webkit-transform .15s ease-in 50ms;-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__label{display:inline-block;padding-left:10px;line-height:19px;font-size:14px}.el-checkbox:last-of-type{margin-right:0}.el-checkbox-button{position:relative;display:inline-block}.el-checkbox-button__inner{display:inline-block;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;position:relative;-webkit-transition:all .3s cubic-bezier(.645, .045, .355, 1);transition:all .3s cubic-bezier(.645, .045, .355, 1);-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;padding:12px 20px;font-size:14px;border-radius:0}.el-checkbox-button__inner.is-round{padding:12px 20px}.el-checkbox-button__inner:hover{color:#1890ff}.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-checkbox-button.is-checked .el-checkbox-button__inner{color:#fff;background-color:#1890ff;border-color:#1890ff;-webkit-box-shadow:-1px 0 0 0 #74bcff;box-shadow:-1px 0 0 0 #74bcff}.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner{border-left-color:#1890ff}.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:#1890ff}.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-radio{color:#606266;font-weight:500;line-height:1;position:relative;cursor:pointer;display:inline-block;white-space:nowrap;outline:0;font-size:14px;margin-right:30px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.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-radio.is-bordered.is-checked{border-color:#1890ff}.el-radio.is-bordered.is-disabled{cursor:not-allowed;border-color:#ebeef5}.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--medium.is-bordered .el-radio__label{font-size:14px}.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__label{font-size:12px}.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__label{font-size:12px}.el-radio--mini.is-bordered .el-radio__inner{height:12px;width:12px}.el-radio:last-child{margin-right:0}.el-radio__input{white-space:nowrap;cursor:pointer;outline:0;display:inline-block;line-height:1;position:relative;vertical-align:middle}.el-radio__input.is-disabled .el-radio__inner{background-color:#f5f7fa;border-color:#e4e7ed;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{background-color:#f5f7fa;border-color:#e4e7ed}.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:#1890ff;background:#1890ff}.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:#1890ff}.el-radio__input.is-focus .el-radio__inner{border-color:#1890ff}.el-radio__inner{border:1px solid #dcdfe6;border-radius:100%;width:14px;height:14px;background-color:#fff;position:relative;cursor:pointer;display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box}.el-radio__inner:hover{border-color:#1890ff}.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 #1890ff;box-shadow:0 0 2px 2px #1890ff}.el-radio__label{font-size:14px;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;font-size:14px}.el-cascader-panel.is-bordered{border:solid 1px #e4e7ed;border-radius:4px}.el-cascader-menu{min-width:180px;-webkit-box-sizing:border-box;box-sizing:border-box;color:#606266;border-right:solid 1px #e4e7ed}.el-cascader-menu:last-child{border-right:none}.el-cascader-menu:last-child .el-cascader-node{padding-right:20px}.el-cascader-menu__wrap{height:204px}.el-cascader-menu__list{position:relative;min-height:100%;margin:0;padding:6px 0;list-style:none;-webkit-box-sizing:border-box;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:#1890ff;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{margin-right:0}.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;font-size:14px}.el-avatar>img{display:block;height:100%;vertical-align:middle}.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;-webkit-box-sizing:border-box;box-sizing:border-box;background-color:#fff;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-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}.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}.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}.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}.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;padding-bottom: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>*{-webkit-box-sizing:border-box;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.ltr{left:0}.el-drawer.rtl{right:0}.el-drawer.ttb{top:0}.el-drawer.btt{bottom: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-popconfirm__main{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.el-popconfirm__icon{margin-right:5px}.el-popconfirm__action{text-align:right;margin:0}.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:-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:0}.el-skeleton__image svg{fill:#DCDDE0;width:22%;height:22%}@-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{height:16px;margin-top:16px;background:#f2f2f2}.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:-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: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;-webkit-box-orient:vertical;-webkit-box-direction:normal;-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{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:100%;height:100%;vertical-align:top;-o-object-fit:contain;object-fit:contain}.el-empty__image svg{fill:#DCDDE0;width:100%;height:100%;vertical-align:top}.el-empty__description{margin-top:20px}.el-empty__description p{margin:0;font-size:14px;color:#909399}.el-empty__bottom{margin-top:20px}.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-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__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{font-size:12px}.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{font-size:12px}.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;-webkit-box-orient:vertical;-webkit-box-direction:normal;-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{margin-top:20px}.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} \ No newline at end of file diff --git a/src/assets/bigScreen/css/variable.scss b/src/assets/bigScreen/css/variable.scss new file mode 100644 index 0000000..6541052 --- /dev/null +++ b/src/assets/bigScreen/css/variable.scss @@ -0,0 +1,50 @@ +// 棰滆壊 +$primary-color: #1890ff; +$primary-color-hl: rgb(41, 52, 67); +$default-color: #006569; +$link: #1890ff; +$active-color: rgb(0, 101, 105); +$del-color: #ff1839; +$content-background: #f3f5fa; +$table-header-background: #d8eaff; + +$primary-color-rgba: rgba($color: $primary-color, + $alpha: 0.1, +); +//琛ㄦ牸涓婇潰button鎸夐挳棰滆壊 +$table-header-button: #18d1ff; +// 闃村奖 +$primary-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), +0 0 6px rgba(0, 0, 0, 0.04); +$primary-shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1); +$baidu-shadow: 1px 2px 1px rgba(0, 0, 0, 0.15); +$gaode-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2), +0 2px 6px 0 rgba(0, 0, 0, 0.19); + +// box-shadow: 0 2px 6px 0 rgb(114 124 245 / 50%); + +$primary-border: $primary-color solid 1px; + +$tool-top: 20px; + +//header 鐨勯珮搴� +$index-height: 60px; +$index-content-height: calc(100% - 60px); +$index-tags-height: 36px; +// 瀹藉害渚ц竟鏍� +$aside-width: 200px; +$content-padding: 16px; + +$default-zindex: 99; + +/*鏂囨湰鏍煎紡鍖栵紝瓒呭嚭鑼冨洿锛屾樉绀虹渷鐣ュ彿*/ +@mixin text-overflow($num: 1) { + word-break: break-all; + text-overflow: ellipsis; + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: $num; + -webkit-box-orient: vertical; +} + + diff --git a/src/assets/bigScreen/css/webfont/index.css b/src/assets/bigScreen/css/webfont/index.css new file mode 100644 index 0000000..e1f0487 --- /dev/null +++ b/src/assets/bigScreen/css/webfont/index.css @@ -0,0 +1,18 @@ +/* @font-face { + font-family: 'webfont'; + font-display: swap; + src: url('//at.alicdn.com/t/webfont_c14qx7m7htb.eot'); + src: + url('//at.alicdn.com/t/webfont_c14qx7m7htb.woff2') format('woff2'), + url('//at.alicdn.com/t/webfont_c14qx7m7htb.woff') format('woff'), + + + } + +.number-font{ + font-family:"webfont" !important; + font-size:16px;font-style:normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + -moz-osx-font-smoothing: grayscale; +} */ \ No newline at end of file diff --git a/src/assets/bigScreen/iconfont/iconfont.css b/src/assets/bigScreen/iconfont/iconfont.css new file mode 100644 index 0000000..f043473 --- /dev/null +++ b/src/assets/bigScreen/iconfont/iconfont.css @@ -0,0 +1,23 @@ +@font-face { + font-family: "iconfont"; /* Project id 2995337 */ + src: url('iconfont.woff2?t=1638871675242') format('woff2'), + url('iconfont.woff?t=1638871675242') format('woff'), + url('iconfont.ttf?t=1638871675242') format('truetype'); +} + +/* .iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} */ + +.blq-icon-shezhi01:before { + content: "\e610"; +} + +.blq-icon-shezhi02:before { + content: "\e611"; +} + diff --git a/src/assets/bigScreen/iconfont/iconfont.ttf b/src/assets/bigScreen/iconfont/iconfont.ttf new file mode 100644 index 0000000..4846ee3 --- /dev/null +++ b/src/assets/bigScreen/iconfont/iconfont.ttf Binary files differ diff --git a/src/assets/bigScreen/iconfont/iconfont.woff b/src/assets/bigScreen/iconfont/iconfont.woff new file mode 100644 index 0000000..a4600dc --- /dev/null +++ b/src/assets/bigScreen/iconfont/iconfont.woff Binary files differ diff --git a/src/assets/bigScreen/iconfont/iconfont.woff2 b/src/assets/bigScreen/iconfont/iconfont.woff2 new file mode 100644 index 0000000..8154396 --- /dev/null +++ b/src/assets/bigScreen/iconfont/iconfont.woff2 Binary files differ diff --git a/src/assets/bigScreen/img/guang.png b/src/assets/bigScreen/img/guang.png new file mode 100644 index 0000000..3c49e9d --- /dev/null +++ b/src/assets/bigScreen/img/guang.png Binary files differ diff --git a/src/assets/bigScreen/img/headers/juxing1.png b/src/assets/bigScreen/img/headers/juxing1.png new file mode 100644 index 0000000..36d901a --- /dev/null +++ b/src/assets/bigScreen/img/headers/juxing1.png Binary files differ diff --git a/src/assets/bigScreen/img/headers/juxing2.png b/src/assets/bigScreen/img/headers/juxing2.png new file mode 100644 index 0000000..5c99bd7 --- /dev/null +++ b/src/assets/bigScreen/img/headers/juxing2.png Binary files differ diff --git a/src/assets/bigScreen/img/titles/you.png b/src/assets/bigScreen/img/titles/you.png new file mode 100644 index 0000000..3877b31 --- /dev/null +++ b/src/assets/bigScreen/img/titles/you.png Binary files differ diff --git a/src/assets/bigScreen/img/titles/zuo.png b/src/assets/bigScreen/img/titles/zuo.png new file mode 100644 index 0000000..b3b355d --- /dev/null +++ b/src/assets/bigScreen/img/titles/zuo.png Binary files differ diff --git a/src/assets/bigScreen/img/top.png b/src/assets/bigScreen/img/top.png new file mode 100644 index 0000000..8c0be6b --- /dev/null +++ b/src/assets/bigScreen/img/top.png Binary files differ diff --git a/src/assets/bigScreen/img/xieyou.png b/src/assets/bigScreen/img/xieyou.png new file mode 100644 index 0000000..1744fae --- /dev/null +++ b/src/assets/bigScreen/img/xieyou.png Binary files differ diff --git a/src/assets/bigScreen/img/xiezuo.png b/src/assets/bigScreen/img/xiezuo.png new file mode 100644 index 0000000..272249d --- /dev/null +++ b/src/assets/bigScreen/img/xiezuo.png Binary files differ diff --git a/src/assets/bigScreen/img/zuo_xuxian.png b/src/assets/bigScreen/img/zuo_xuxian.png new file mode 100644 index 0000000..e54d037 --- /dev/null +++ b/src/assets/bigScreen/img/zuo_xuxian.png Binary files differ diff --git a/src/assets/icons/index.js b/src/assets/icons/index.js new file mode 100644 index 0000000..2c6b309 --- /dev/null +++ b/src/assets/icons/index.js @@ -0,0 +1,9 @@ +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) diff --git a/src/assets/icons/svg/404.svg b/src/assets/icons/svg/404.svg new file mode 100644 index 0000000..6df5019 --- /dev/null +++ b/src/assets/icons/svg/404.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/alert.svg b/src/assets/icons/svg/alert.svg new file mode 100644 index 0000000..c4c365e --- /dev/null +++ b/src/assets/icons/svg/alert.svg @@ -0,0 +1 @@ +<?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="1640533950169" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19899" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M793.6 819.2a51.2 51.2 0 1 1 0 102.4h-614.4a51.2 51.2 0 0 1 0-102.4h614.4z m-307.2-563.2a307.2 307.2 0 0 1 307.2 307.2v204.8h-614.4v-204.8a307.2 307.2 0 0 1 307.2-307.2z m51.2 102.4l-153.6 153.6H460.8l-25.6 153.6 153.6-153.6-76.8-0.0512L537.6 358.4zM138.1376 232.448l4.096 2.2528 76.8 51.2a25.6 25.6 0 0 1-24.3712 44.8l-4.096-2.2016-76.8-51.2a25.6 25.6 0 0 1 24.3712-44.8z m727.9616 9.3696a25.6 25.6 0 0 1-3.4816 32.5632l-3.584 2.9184-76.8 51.2-4.096 2.2016a25.6 25.6 0 0 1-27.9552-41.8816l3.584-2.9184 76.8-51.2 4.096-2.2016a25.6 25.6 0 0 1 31.4368 9.3184zM300.032 110.2336l2.8672 3.584 51.2 76.8a25.6 25.6 0 0 1-39.68 32l-2.9184-3.584-51.2-76.8a25.6 25.6 0 0 1 39.7312-32.0512z m405.3504-3.5328a25.6 25.6 0 0 1 9.3184 31.4368l-2.2016 4.096-51.2 76.8-2.8672 3.584a25.6 25.6 0 0 1-41.984-27.9552l2.2528-4.096 51.2-76.8 2.9184-3.584a25.6 25.6 0 0 1 32.5632-3.4816zM486.4 51.2a25.6 25.6 0 0 1 25.1904 20.992L512 76.8v102.4a25.6 25.6 0 0 1-50.7904 4.608L460.8 179.2v-102.4a25.6 25.6 0 0 1 25.6-25.6z" p-id="19900"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/arrow-left.svg b/src/assets/icons/svg/arrow-left.svg new file mode 100644 index 0000000..d093665 --- /dev/null +++ b/src/assets/icons/svg/arrow-left.svg @@ -0,0 +1 @@ +<?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="1696736330576" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6319" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512.42 920.16c-88.25 0-176.5-6.43-264.14-19.28l-0.26-0.04c-30.68-4.81-61.57-21.45-86.98-46.85-25.41-25.41-42.05-56.3-46.85-86.98l-0.04-0.26a1818.793 1818.793 0 0 1 0-528.28l0.04-0.26c4.81-30.68 21.44-61.57 46.85-86.98 25.41-25.41 56.3-42.05 86.98-46.85l0.26-0.04a1818.793 1818.793 0 0 1 528.28 0l0.26 0.04c30.68 4.81 61.57 21.44 86.98 46.85s42.05 56.3 46.85 86.98l0.04 0.26a1818.793 1818.793 0 0 1 0 528.28l-0.04 0.26c-4.81 30.68-21.44 61.57-46.85 86.98-25.41 25.41-56.3 42.05-86.98 46.85l-0.26 0.04a1820.45 1820.45 0 0 1-264.14 19.28z m-256.03-73.69c169.89 24.91 342.15 24.91 512.05 0 39.74-6.3 81.56-48.12 87.86-87.86 24.9-169.87 24.9-342.16 0-512.03-6.3-39.75-48.12-81.57-87.86-87.86a1764.188 1764.188 0 0 0-512.03 0c-39.74 6.3-81.57 48.12-87.86 87.86a1764.188 1764.188 0 0 0 0 512.03c6.28 39.74 48.1 81.56 87.84 87.86z" fill="#64A0CF" p-id="6320"></path><path d="M626.33 337.19L416.49 547.03c-10.19 10.19-26.72 10.19-36.92 0l-12.58-12.58c-10.19-10.19-10.19-26.72 0-36.92l209.84-209.84c10.19-10.19 26.72-10.19 36.92 0l12.58 12.58c10.19 10.19 10.19 26.72 0 36.92z" fill="#9EEFD9" p-id="6321"></path><path d="M627.01 731.07l-12.58 12.58c-10.19 10.19-26.72 10.19-36.92 0L367.67 533.81c-10.19-10.19-10.19-26.72 0-36.92l12.58-12.58c10.19-10.19 26.72-10.19 36.92 0l209.84 209.84c10.19 10.2 10.19 26.72 0 36.92z" fill="#9EEFD9" p-id="6322"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/authenticate.svg b/src/assets/icons/svg/authenticate.svg new file mode 100644 index 0000000..87125e0 --- /dev/null +++ b/src/assets/icons/svg/authenticate.svg @@ -0,0 +1 @@ +<?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="1646631871952" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22032" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M581.616221 423.19292q-46.215929 19.030088-84.729204 50.746903t-66.60531 72.495575-43.497345 89.260177-15.40531 101.946903q0 47.122124 12.233628 90.166372t33.982301 81.104425l-24.467257 0q-26.279646 0-61.168142-1.812389t-72.042478-4.984071-73.854867-7.249558-66.60531-8.60885-50.746903-9.061947-26.279646-9.061947q-9.968142-7.249558-14.952212-44.856637t4.077876-96.509735q3.624779-22.654867 14.952212-37.153982t27.638938-24.920354 36.247788-16.764602 40.778761-12.233628 40.325664-12.686726 35.79469-16.764602q19.030088-11.780531 29.451327-23.107965t14.952212-22.20177 4.530973-22.654867-0.906195-26.279646q-1.812389-20.842478-14.499115-33.076106t-28.092035-24.920354q-7.249558-6.343363-13.139823-17.670796t-10.421239-23.107965q-4.530973-13.59292-9.061947-28.092035-6.343363-1.812389-12.686726-6.343363-5.437168-4.530973-11.780531-12.686726t-10.874336-23.561062-3.624779-28.092035 5.437168-22.654867q3.624779-9.968142 11.780531-19.030088 0-34.435398 3.624779-68.870796 3.624779-28.99823 12.686726-62.527434t28.092035-59.80885q18.123894-25.373451 38.966372-41.231858t43.497345-24.920354 44.856637-12.233628 43.044248-3.171681q26.279646 0 52.106195 5.890265t48.481416 15.858407 40.325664 22.654867 27.638938 25.373451q23.561062 28.99823 34.435398 63.886726t15.40531 66.60531q4.530973 36.247788 4.530973 73.40177 6.343363 4.530973 9.968142 11.780531 3.624779 6.343363 5.890265 16.311504t0.453097 24.467257q-1.812389 19.936283-7.702655 31.263717t-13.139823 17.670796q-8.155752 7.249558-17.217699 9.968142-1.812389 5.437168-3.624779 11.780531l-4.530973 12.686726q-1.812389 6.343363-4.530973 13.59292zM711.202061 452.19115q58.902655 0 111.00885 22.654867t90.619469 61.621239 61.168142 91.072566 22.654867 111.00885-22.654867 111.00885-61.168142 91.072566-90.619469 61.168142-111.00885 22.20177q-59.80885 0-111.915044-22.20177t-90.619469-61.168142-61.168142-91.072566-22.654867-111.00885 22.654867-111.00885 61.168142-91.072566 90.619469-61.621239 111.915044-22.654867zM877.941884 682.364602q5.437168-18.123894-4.984071-33.076106t-27.638938-21.295575-34.435398-0.906195-25.373451 28.092035q-4.530973 15.40531-8.60885 28.545133t-8.155752 27.638938-9.968142 31.263717-14.952212 38.513274q-9.061947 23.561062-25.826549 22.20177t-25.826549-19.483186q-9.968142-18.123894-18.576991-38.966372t-16.764602-40.778761-14.499115-36.247788-10.874336-26.279646q-7.249558-14.499115-24.014159-16.311504t-32.623009 4.984071-26.279646 21.295575-3.171681 31.716814q6.343363 18.123894 14.499115 40.778761t17.217699 46.215929 17.217699 46.215929 14.499115 38.966372q13.59292 34.435398 41.231858 51.653097t57.99646 18.123894 57.99646-13.59292 40.325664-43.497345q9.968142-23.561062 20.389381-49.387611t19.936283-50.293805 17.670796-47.122124 13.59292-38.966372z" p-id="22033"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/big.svg b/src/assets/icons/svg/big.svg new file mode 100644 index 0000000..f3dd9ca --- /dev/null +++ b/src/assets/icons/svg/big.svg @@ -0,0 +1 @@ +<?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="1676963808794" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11069" width="128" height="128" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M885.1 962.6H139.5c-42.2 0-76.6-34.3-76.6-76.6V140.4c0-42.2 34.3-76.6 76.6-76.6h745.6c42.2 0 76.6 34.3 76.6 76.6V886c-0.1 42.2-34.4 76.6-76.6 76.6zM139.5 110.5c-16.5 0-30 13.4-30 30V886c0 16.5 13.4 30 30 30h745.6c16.5 0 30-13.4 30-30V140.4c0-16.5-13.4-30-30-30H139.5z" fill="#1890ff" p-id="11070"></path><path d="M745.3 536.5h-466c-12.9 0-23.3-10.4-23.3-23.3s10.4-23.3 23.3-23.3h466c12.9 0 23.3 10.4 23.3 23.3s-10.4 23.3-23.3 23.3z" fill="#1890ff" p-id="11071"></path><path d="M512.3 769.5c-12.9 0-23.3-10.4-23.3-23.3v-466c0-12.9 10.4-23.3 23.3-23.3s23.3 10.4 23.3 23.3v466c0 12.9-10.4 23.3-23.3 23.3z" fill="#1890ff" p-id="11072"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/bug.svg b/src/assets/icons/svg/bug.svg new file mode 100644 index 0000000..05a150d --- /dev/null +++ b/src/assets/icons/svg/bug.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/build.svg b/src/assets/icons/svg/build.svg new file mode 100644 index 0000000..97c4688 --- /dev/null +++ b/src/assets/icons/svg/build.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/button.svg b/src/assets/icons/svg/button.svg new file mode 100644 index 0000000..904fddc --- /dev/null +++ b/src/assets/icons/svg/button.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/cascader.svg b/src/assets/icons/svg/cascader.svg new file mode 100644 index 0000000..e256024 --- /dev/null +++ b/src/assets/icons/svg/cascader.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/category.svg b/src/assets/icons/svg/category.svg new file mode 100644 index 0000000..42986df --- /dev/null +++ b/src/assets/icons/svg/category.svg @@ -0,0 +1 @@ +<?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="1640528385068" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10352" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M874.7 615.6h-50.2V486.1c0-10.7-8.7-19.4-19.4-19.4H531.4v-58.3h84.2c28.6 0 51.8-23.2 51.8-51.8V149.3c0-28.6-23.2-51.8-51.8-51.8H408.4c-28.6 0-51.8 23.2-51.8 51.8v207.2c0 28.6 23.2 51.8 51.8 51.8h84.2v58.3H219c-10.7 0-19.4 8.7-19.4 19.4v129.5h-50.3c-28.6 0-51.8 23.2-51.8 51.8v207.2c0 28.6 23.2 51.8 51.8 51.8h207.2c28.6 0 51.8-23.2 51.8-51.8V667.4c0-28.6-23.2-51.8-51.8-51.8H238.4V505.5h547.3v110.1H667.4c-28.6 0-51.8 23.2-51.8 51.8v207.2c0 28.6 23.2 51.8 51.8 51.8h207.2c28.6 0 51.8-23.2 51.8-51.8V667.4c0.1-28.6-23.1-51.8-51.7-51.8z" p-id="10353"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/channel.svg b/src/assets/icons/svg/channel.svg new file mode 100644 index 0000000..2ef1877 --- /dev/null +++ b/src/assets/icons/svg/channel.svg @@ -0,0 +1 @@ +<?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="1667669082784" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14339" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M853.333333 682.666667a128 128 0 0 0-73.813333 23.893333l-104.533333-61.866667A159.573333 159.573333 0 0 0 682.666667 597.333333a170.666667 170.666667 0 0 0-128-164.693333V333.653333a128 128 0 1 0-85.333334 0v98.986667A170.666667 170.666667 0 0 0 341.333333 597.333333c0.170667 16.085333 2.730667 32.042667 7.68 47.36l-104.533333 61.866667A128 128 0 0 0 170.666667 682.666667a128 128 0 1 0 128 128 128 128 0 0 0-5.12-34.133334l98.133333-58.453333a170.666667 170.666667 0 0 0 240.64 0l98.133333 58.453333A128 128 0 1 0 853.333333 682.666667zM170.666667 853.333333a42.666667 42.666667 0 1 1 0-85.333333 42.666667 42.666667 0 0 1 0 85.333333z m341.333333-682.666666a42.666667 42.666667 0 1 1 0 85.333333 42.666667 42.666667 0 0 1 0-85.333333z m0 512a85.333333 85.333333 0 1 1 0-170.666667 85.333333 85.333333 0 0 1 0 170.666667z m341.333333 170.666666a42.666667 42.666667 0 1 1 0-85.333333 42.666667 42.666667 0 0 1 0 85.333333z" p-id="14340"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/chart.svg b/src/assets/icons/svg/chart.svg new file mode 100644 index 0000000..27728fb --- /dev/null +++ b/src/assets/icons/svg/chart.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/checkbox.svg b/src/assets/icons/svg/checkbox.svg new file mode 100644 index 0000000..013fd3a --- /dev/null +++ b/src/assets/icons/svg/checkbox.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/client.svg b/src/assets/icons/svg/client.svg new file mode 100644 index 0000000..a8a9f9c --- /dev/null +++ b/src/assets/icons/svg/client.svg @@ -0,0 +1 @@ +<?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="1646373006802" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="18419" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M928 543.8h-95.8c-17.6 0-32 14.4-32 32v255.9c0 17.6 14.4 32 32 32H928c17.6 0 32-14.4 32-32V575.8c0-17.6-14.4-32-32-32zM871.8 841c0-5.8 4.7-10.5 10.5-10.5s10.5 4.7 10.5 10.5-4.7 10.5-10.5 10.5-10.5-4.7-10.5-10.5z m77.8-25.7h-139V587.4h139v227.9z" fill="#dbdbdb" p-id="18420"></path><path d="M800.7 448.2a32.2 32.1 0 1 0 64.4 0 32.2 32.1 0 1 0-64.4 0Z" fill="#dbdbdb" p-id="18421"></path><path d="M800.7 317.4v2.4c0 17.7 14.4 32.1 32.2 32.1s32.2-14.4 32.2-32.1c0-0.8 0-1.6-0.1-2.4h0.1V191.3c0-35.2-28.8-64-64-64H128.3c-35.2 0-64 28.8-64 64V640c0 35.2 28.8 64 64 64h302.1v127.7h-155c-17.6 0-32 14.4-32 32s14.4 32 32 32H657c17.5 0 31.9-14.4 32-32 0-17.6-14.4-32-32-32H498V704h206.7v-0.1c17.7-0.2 31.9-14.4 31.9-32.1 0-17.6-14.3-31.9-31.9-32.1H160.8c-17.6 0-32-14.4-32-32V223.8c0-17.6 14.4-32 32-32h607.9c17.6 0 32 14.4 32 32v93.6z" fill="#dbdbdb" p-id="18422"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/clipboard.svg b/src/assets/icons/svg/clipboard.svg new file mode 100644 index 0000000..90923ff --- /dev/null +++ b/src/assets/icons/svg/clipboard.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/cloud.svg b/src/assets/icons/svg/cloud.svg new file mode 100644 index 0000000..9fa24c8 --- /dev/null +++ b/src/assets/icons/svg/cloud.svg @@ -0,0 +1 @@ +<?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="1644243464391" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2162" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M811.4 368.9C765.6 248 648.9 162 512.2 162S258.8 247.9 213 368.8C126.9 391.5 63.5 470.2 64 563.6 64.6 668 145.6 752.9 247.6 762c4.7 0.4 8.7-3.3 8.7-8v-60.4c0-4-3-7.4-7-7.9-27-3.4-52.5-15.2-72.1-34.5-24-23.5-37.2-55.1-37.2-88.6 0-28 9.1-54.4 26.2-76.4 16.7-21.4 40.2-36.9 66.1-43.7l37.9-10 13.9-36.7c8.6-22.8 20.6-44.2 35.7-63.5 14.9-19.2 32.6-36 52.4-50 41.1-28.9 89.5-44.2 140-44.2s98.9 15.3 140 44.3c19.9 14 37.5 30.8 52.4 50 15.1 19.3 27.1 40.7 35.7 63.5l13.8 36.6 37.8 10c54.2 14.4 92.1 63.7 92.1 120 0 33.6-13.2 65.1-37.2 88.6-19.5 19.2-44.9 31.1-71.9 34.5-4 0.5-6.9 3.9-6.9 7.9V754c0 4.7 4.1 8.4 8.8 8 101.7-9.2 182.5-94 183.2-198.2 0.6-93.4-62.7-172.1-148.6-194.9z" p-id="2163" fill="#dbdbdb"></path><path d="M376.9 656.4c1.8-33.5 15.7-64.7 39.5-88.6 25.4-25.5 60-39.8 96-39.8 36.2 0 70.3 14.1 96 39.8 1.4 1.4 2.7 2.8 4.1 4.3l-25 19.6c-5.3 4.1-3.5 12.5 3 14.1l98.2 24c5 1.2 9.9-2.6 9.9-7.7l0.5-101.3c0-6.7-7.6-10.5-12.9-6.3L663 532.7c-36.6-42-90.4-68.6-150.5-68.6-107.4 0-195 85.1-199.4 191.7-0.2 4.5 3.4 8.3 8 8.3H369c4.2-0.1 7.7-3.4 7.9-7.7zM703 664h-47.9c-4.2 0-7.7 3.3-8 7.6-1.8 33.5-15.7 64.7-39.5 88.6-25.4 25.5-60 39.8-96 39.8-36.2 0-70.3-14.1-96-39.8-1.4-1.4-2.7-2.8-4.1-4.3l25-19.6c5.3-4.1 3.5-12.5-3-14.1l-98.2-24c-5-1.2-9.9 2.6-9.9 7.7l-0.4 101.4c0 6.7 7.6 10.5 12.9 6.3l23.2-18.2c36.6 42 90.4 68.6 150.5 68.6 107.4 0 195-85.1 199.4-191.7 0.2-4.5-3.4-8.3-8-8.3z" p-id="2164" fill="#dbdbdb"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/code.svg b/src/assets/icons/svg/code.svg new file mode 100644 index 0000000..ed4d23c --- /dev/null +++ b/src/assets/icons/svg/code.svg @@ -0,0 +1 @@ +<?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" fill="#bfbfbf" p-id="2423"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/color.svg b/src/assets/icons/svg/color.svg new file mode 100644 index 0000000..44a81aa --- /dev/null +++ b/src/assets/icons/svg/color.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/component.svg b/src/assets/icons/svg/component.svg new file mode 100644 index 0000000..29c3458 --- /dev/null +++ b/src/assets/icons/svg/component.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/connect.svg b/src/assets/icons/svg/connect.svg new file mode 100644 index 0000000..edd1f2f --- /dev/null +++ b/src/assets/icons/svg/connect.svg @@ -0,0 +1 @@ +<?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="1646632012192" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="23210" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M512 0a512 512 0 1 0 512 512A512 512 0 0 0 512 0z m-58.006042 771.609265a88.169184 88.169184 0 0 1-121.941591 25.780463L216.040282 721.852971a88.426989 88.426989 0 0 1-25.780463-121.941591l150.042296-232.02417a88.684794 88.684794 0 0 1 122.199396-25.780463l116.012084 75.021148a88.426989 88.426989 0 0 1 25.780463 122.199396l-25.780463-16.757301a57.490433 57.490433 0 0 0-17.015106-79.661631l-116.012084-75.021149a57.748238 57.748238 0 0 0-79.661632 17.015106l-150.042296 232.024169A58.006042 58.006042 0 0 0 232.024169 696.072508l116.269889 74.763343a57.490433 57.490433 0 0 0 79.661632-16.757301L482.868077 670.292044l25.780463 16.499497z m380.004028-395.472306l-149.784492 232.024169a88.169184 88.169184 0 0 1-74.247734 40.475327 87.137966 87.137966 0 0 1-47.693857-14.179255l-116.269889-75.536757a88.942598 88.942598 0 0 1-38.41289-55.685801 87.653575 87.653575 0 0 1 12.116818-66.513595l25.780463 16.757301a58.006042 58.006042 0 0 0-7.21853 43.311179 56.717019 56.717019 0 0 0 25.780463 36.350453l116.012085 75.278953a58.006042 58.006042 0 0 0 79.661631-17.272911l149.784492-232.024169a57.748238 57.748238 0 0 0-16.757301-79.661631l-117.558913-74.763344a57.748238 57.748238 0 0 0-79.661631 17.015106L541.389728 305.756294l-25.780463-16.499496L569.748238 206.243706a88.426989 88.426989 0 0 1 122.199395-25.780463l116.012085 75.021148a88.169184 88.169184 0 0 1 25.780463 122.199396z" p-id="23211"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/dashboard.svg b/src/assets/icons/svg/dashboard.svg new file mode 100644 index 0000000..5317d37 --- /dev/null +++ b/src/assets/icons/svg/dashboard.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/date-range.svg b/src/assets/icons/svg/date-range.svg new file mode 100644 index 0000000..fda571e --- /dev/null +++ b/src/assets/icons/svg/date-range.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/date.svg b/src/assets/icons/svg/date.svg new file mode 100644 index 0000000..52dc73e --- /dev/null +++ b/src/assets/icons/svg/date.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/device.svg b/src/assets/icons/svg/device.svg new file mode 100644 index 0000000..032ac5a --- /dev/null +++ b/src/assets/icons/svg/device.svg @@ -0,0 +1 @@ +<?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="1640528598588" class="icon" viewBox="0 0 1280 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16798" xmlns:xlink="http://www.w3.org/1999/xlink" width="160" height="128"><defs><style type="text/css"></style></defs><path d="M153.64583333 62h984.375C1176.87083362 62 1208.33333333 93.5 1208.33333333 132.3125v205.49999971c0 38.85000029-31.5 70.35000029-70.3125 70.35000029H153.64583333A70.3125 70.3125 0 0 1 83.33333333 337.85V132.3125C83.33333333 93.46249971 114.83333333 62 153.64583333 62z m104.92499971 138.44999971a34.61249971 34.61249971 0 0 0 0 69.22500029h212.02500058a34.61249971 34.61249971 0 0 0 0-69.22500029H258.57083304zM153.64583333 615.87500029h984.375c38.85000029 0 70.3125 31.5 70.3125 70.3125v205.5375C1208.33333333 930.53750029 1176.83333333 962 1138.02083333 962H153.64583333A70.3125 70.3125 0 0 1 83.33333333 891.6875v-205.49999971c0-38.85000029 31.5-70.35000029 70.3125-70.35000029z m104.92499971 138.4875a34.61249971 34.61249971 0 1 0 0 69.22499942h212.02500058a34.61249971 34.61249971 0 1 0 0-69.22499942H258.57083304z" p-id="16799"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/dict.svg b/src/assets/icons/svg/dict.svg new file mode 100644 index 0000000..4849377 --- /dev/null +++ b/src/assets/icons/svg/dict.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/disconnect.svg b/src/assets/icons/svg/disconnect.svg new file mode 100644 index 0000000..19a01b2 --- /dev/null +++ b/src/assets/icons/svg/disconnect.svg @@ -0,0 +1 @@ +<?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="1646372768874" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14319" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M317.103 429.404c11.571-11.54 30.262-11.654 41.966-0.256l237.208 231.007c11.946 11.637 12.058 30.801 0.247 42.582l-95.872 95.626c-77.416 77.416-192.408 92.605-270.707 38.009L120.038 946.246c-11.676 11.672-30.606 11.672-42.281 0-11.49-11.487-11.673-29.998-0.547-41.708l0.547-0.562 109.67-109.64c-55.967-78.326-41.111-194.39 36.848-272.35z m21.35 63.133l-71.916 71.723-1.883 1.912c-61.82 63.543-67.918 156.28-16.193 208.005 52.247 52.247 146.34 45.498 209.949-18.11l74.42-74.23-194.377-189.3z m613.79-422.783c11.49 11.487 11.673 29.998 0.547 41.708l-0.547 0.562-109.11 109.084c57.203 78.339 42.65 195.365-35.795 273.81L714.51 587.5c-11.57 11.54-30.261 11.655-41.966 0.256L626.8 543.208l-18.078 18.075c-11.676 11.673-30.606 11.673-42.281 0-11.49-11.487-11.673-29.998-0.548-41.708l0.548-0.561 17.524-17.521-61.698-60.085-20.092 20.087c-11.675 11.672-30.605 11.672-42.28 0-11.49-11.487-11.673-29.998-0.548-41.708l0.547-0.562 19.538-19.532-44.096-42.943c-11.826-11.52-12.054-30.42-0.598-42.227l0.351-0.355 95.872-95.626c76.927-76.927 190.955-92.411 269.218-39.036L909.962 69.754c11.676-11.672 30.606-11.672 42.281 0z m-169.09 172.973c-52.248-52.247-146.34-45.498-209.95 18.111l-74.42 74.231 194.377 189.3 71.937-71.748 1.862-1.889c61.82-63.543 67.918-156.28 16.193-208.005z" fill="#ffffff" p-id="14320"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/documentation.svg b/src/assets/icons/svg/documentation.svg new file mode 100644 index 0000000..7043122 --- /dev/null +++ b/src/assets/icons/svg/documentation.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/download.svg b/src/assets/icons/svg/download.svg new file mode 100644 index 0000000..c896951 --- /dev/null +++ b/src/assets/icons/svg/download.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/drag.svg b/src/assets/icons/svg/drag.svg new file mode 100644 index 0000000..4185d3c --- /dev/null +++ b/src/assets/icons/svg/drag.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/druid.svg b/src/assets/icons/svg/druid.svg new file mode 100644 index 0000000..a2b4b4e --- /dev/null +++ b/src/assets/icons/svg/druid.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/edit.svg b/src/assets/icons/svg/edit.svg new file mode 100644 index 0000000..d26101f --- /dev/null +++ b/src/assets/icons/svg/edit.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/education.svg b/src/assets/icons/svg/education.svg new file mode 100644 index 0000000..7bfb01d --- /dev/null +++ b/src/assets/icons/svg/education.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/email.svg b/src/assets/icons/svg/email.svg new file mode 100644 index 0000000..74d25e2 --- /dev/null +++ b/src/assets/icons/svg/email.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/event-a.svg b/src/assets/icons/svg/event-a.svg new file mode 100644 index 0000000..7faf66a --- /dev/null +++ b/src/assets/icons/svg/event-a.svg @@ -0,0 +1,2 @@ +<?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="1654508296100" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19419" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><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="M942.102 904.571c-21.954 35.544-57.556 55.418-99.308 55.418H181.195c-41.752 0-77.35-19.874-99.3-55.418-21.945-35.544-23.78-76.303-5.111-113.685l330.8-662.296c20.324-40.686 58.976-64.597 104.411-64.597 45.448 0 84.095 23.91 104.411 64.597L947.21 790.886c18.673 37.382 16.838 78.142-5.108 113.685zM608 448H416c-17.673 0-32 14.327-32 32 0 17.673 14.327 32 32 32h192c17.673 0 32-14.327 32-32 0-17.673-14.327-32-32-32z m32 128H384c-17.673 0-32 14.327-32 32s14.327 32 32 32h256c17.673 0 32-14.327 32-32s-14.327-32-32-32z m32 128H352c-17.673 0-32 14.327-32 32s14.327 32 32 32h320c17.673 0 32-14.327 32-32s-14.327-32-32-32z" p-id="19420"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/example.svg b/src/assets/icons/svg/example.svg new file mode 100644 index 0000000..46f42b5 --- /dev/null +++ b/src/assets/icons/svg/example.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/excel.svg b/src/assets/icons/svg/excel.svg new file mode 100644 index 0000000..74d97b8 --- /dev/null +++ b/src/assets/icons/svg/excel.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/exit-fullscreen.svg b/src/assets/icons/svg/exit-fullscreen.svg new file mode 100644 index 0000000..485c128 --- /dev/null +++ b/src/assets/icons/svg/exit-fullscreen.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/eye-open.svg b/src/assets/icons/svg/eye-open.svg new file mode 100644 index 0000000..88dcc98 --- /dev/null +++ b/src/assets/icons/svg/eye-open.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/eye.svg b/src/assets/icons/svg/eye.svg new file mode 100644 index 0000000..16ed2d8 --- /dev/null +++ b/src/assets/icons/svg/eye.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/firmware.svg b/src/assets/icons/svg/firmware.svg new file mode 100644 index 0000000..2803430 --- /dev/null +++ b/src/assets/icons/svg/firmware.svg @@ -0,0 +1 @@ +<?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="1640533920219" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="17700" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M534.656 361.408C528.864 355.6 520.848 352 512 352s-16.864 3.6-22.656 9.408l-127.952 127.952a32 32 0 1 0 45.248 45.248L480 461.248V640a32 32 0 1 0 64 0V461.248l73.36 73.36a32 32 0 1 0 45.232-45.264l-127.936-127.936z" p-id="17701"></path><path d="M928 576h-32v-128h32a32 32 0 0 0 0-64h-32v-32c0-123.52-100.48-224-224-224h-32V96a32 32 0 0 0-64 0v32h-128V96a32 32 0 0 0-64 0v32h-32C228.48 128 128 228.48 128 352v32H96a32 32 0 0 0 0 64h32v128H96a32 32 0 0 0 0 64h32v32c0 123.52 100.48 224 224 224h32v32a32 32 0 0 0 64 0v-32h128v32a32 32 0 0 0 64 0v-32h32c123.52 0 224-100.48 224-224v-32h32a32 32 0 0 0 0-64z m-96 96c0 88.224-71.776 160-160 160H352c-88.224 0-160-71.776-160-160V352c0-88.224 71.776-160 160-160h320c88.224 0 160 71.776 160 160v320z" p-id="17702"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/form.svg b/src/assets/icons/svg/form.svg new file mode 100644 index 0000000..dcbaa18 --- /dev/null +++ b/src/assets/icons/svg/form.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/fullscreen.svg b/src/assets/icons/svg/fullscreen.svg new file mode 100644 index 0000000..0e86b6f --- /dev/null +++ b/src/assets/icons/svg/fullscreen.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/github.svg b/src/assets/icons/svg/github.svg new file mode 100644 index 0000000..db0a0d4 --- /dev/null +++ b/src/assets/icons/svg/github.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/group.svg b/src/assets/icons/svg/group.svg new file mode 100644 index 0000000..240f968 --- /dev/null +++ b/src/assets/icons/svg/group.svg @@ -0,0 +1 @@ +<?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="1640528461166" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12217" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M107.52 209.92h89.088c25.6 0 46.08-20.48 46.08-46.08s-20.48-46.08-46.08-46.08h-89.088c-55.296 0-100.352 45.056-100.352 100.352v586.752c0 55.296 45.056 100.352 100.352 100.352h89.088c25.6 0 46.08-20.48 46.08-46.08s-20.48-46.08-46.08-46.08h-89.088c-5.12 0-8.192-4.096-8.192-8.192V558.08h97.28c25.6 0 46.08-20.48 46.08-46.08s-20.48-46.08-46.08-46.08H99.328V218.112c0-4.096 3.072-8.192 8.192-8.192zM974.848 389.12H345.088c-23.552 0-43.008 19.456-43.008 43.008v160.768c0 23.552 19.456 43.008 43.008 43.008h628.736c23.552 0 43.008-19.456 43.008-43.008V432.128c0-23.552-18.432-43.008-41.984-43.008zM422.912 543.744c0 9.216-8.192 16.384-18.432 16.384h-1.024-1.024c-9.216 0-16.384-7.168-16.384-16.384v-63.488c0-9.216 7.168-16.384 16.384-16.384h2.048c10.24 0 18.432 7.168 18.432 16.384v63.488z m512-23.552c0 22.528-17.408 39.936-39.936 39.936H547.84c-22.528 0-39.936-17.408-39.936-39.936v-16.384c0-22.528 17.408-39.936 39.936-39.936h347.136c22.528 0 39.936 17.408 39.936 39.936v16.384zM974.848 33.792H345.088c-23.552 0-43.008 19.456-43.008 43.008v160.768c0 23.552 19.456 43.008 43.008 43.008h628.736c23.552 0 43.008-19.456 43.008-43.008V75.776c0-23.552-18.432-41.984-41.984-41.984zM422.912 188.416c0 9.216-8.192 16.384-18.432 16.384h-1.024-1.024c-9.216 0-16.384-7.168-16.384-16.384v-63.488c0-9.216 7.168-16.384 16.384-16.384h2.048c10.24 0 18.432 7.168 18.432 16.384v63.488z m512-23.552c0 22.528-17.408 39.936-39.936 39.936H547.84c-22.528 0-39.936-17.408-39.936-39.936v-16.384c0-22.528 17.408-39.936 39.936-39.936h347.136c22.528 0 39.936 17.408 39.936 39.936v16.384zM974.848 745.472H345.088c-23.552 0-43.008 19.456-43.008 43.008v160.768c0 23.552 19.456 43.008 43.008 43.008h628.736c23.552 0 43.008-19.456 43.008-43.008V787.456c0-23.552-18.432-41.984-41.984-41.984zM422.912 900.096c0 9.216-8.192 16.384-18.432 16.384h-1.024-1.024c-9.216 0-16.384-7.168-16.384-16.384v-63.488c0-9.216 7.168-16.384 16.384-16.384h2.048c10.24 0 18.432 7.168 18.432 16.384v63.488z m512-23.552c0 22.528-17.408 39.936-39.936 39.936H547.84c-22.528 0-39.936-17.408-39.936-39.936V860.16c0-22.528 17.408-39.936 39.936-39.936h347.136c22.528 0 39.936 17.408 39.936 39.936v16.384z" p-id="12218"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/guide.svg b/src/assets/icons/svg/guide.svg new file mode 100644 index 0000000..b271001 --- /dev/null +++ b/src/assets/icons/svg/guide.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/icon.svg b/src/assets/icons/svg/icon.svg new file mode 100644 index 0000000..82be8ee --- /dev/null +++ b/src/assets/icons/svg/icon.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/input.svg b/src/assets/icons/svg/input.svg new file mode 100644 index 0000000..ab91381 --- /dev/null +++ b/src/assets/icons/svg/input.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/international.svg b/src/assets/icons/svg/international.svg new file mode 100644 index 0000000..e9b56ee --- /dev/null +++ b/src/assets/icons/svg/international.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/iot.svg b/src/assets/icons/svg/iot.svg new file mode 100644 index 0000000..e3ab00d --- /dev/null +++ b/src/assets/icons/svg/iot.svg @@ -0,0 +1 @@ +<?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="1621330831603" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="27504" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M532.038 0.41c-72.843-2.902-147.462 9.781-219.07 40.003-71.612 30.223-132.753 74.836-181.491 129.051 72.432-1.391 145.775-16.28 216.488-46.125C418.679 93.494 480.512 51.335 532.038 0.41zM441.627 345.266c140.577-59.33 256.27-153.169 341.414-267.521a514.78 514.78 0 0 0-132.678-58.566 690.967 690.967 0 0 1-37.939 42.388c-64.186 66.02-140.084 117.793-225.586 153.878-85.501 36.086-175.545 54.347-267.624 54.274a690.536 690.536 0 0 1-56.838-2.386 514.877 514.877 0 0 0-50.598 135.916c141.329 18.772 289.272 1.346 429.849-57.983z" p-id="27505"></path><path d="M535.289 567.192c169.034-71.339 310.196-181.335 417.572-315.38-25.017-42.507-55.54-80.322-90.25-112.904a928.479 928.479 0 0 1-77.503 90.688c-86.659 89.14-189.144 159.047-304.608 207.777-115.463 48.729-237.044 73.388-361.367 73.29A929.085 929.085 0 0 1 0.091 502.928a508.255 508.255 0 0 0 17.933 143.423c170.947 16.582 348.231-7.821 517.265-79.159z" p-id="27506"></path><path d="M998.663 353.31a1163.002 1163.002 0 0 1-40.869 44.315c-109.135 112.26-238.211 200.3-383.632 261.674-145.423 61.376-298.545 92.431-455.112 92.308a1159.323 1159.323 0 0 1-60.26-1.633c28.541 54.499 65.835 101.974 109.398 141.4 154.353-5.572 310.229-38.724 460.763-102.255 150.535-63.533 283.03-152.085 394.704-258.787 2.141-58.714-5.854-118.554-24.992-177.022zM305.351 980.291c124.479 54.902 270.44 60.368 405.675 3.294 135.234-57.073 233.14-165.464 280.646-292.949-98.29 77.292-206.657 141.131-323.847 190.59-117.19 49.456-238.526 82.564-362.474 99.065z" p-id="27507"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/job.svg b/src/assets/icons/svg/job.svg new file mode 100644 index 0000000..2a93a25 --- /dev/null +++ b/src/assets/icons/svg/job.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/language.svg b/src/assets/icons/svg/language.svg new file mode 100644 index 0000000..0082b57 --- /dev/null +++ b/src/assets/icons/svg/language.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/link.svg b/src/assets/icons/svg/link.svg new file mode 100644 index 0000000..48197ba --- /dev/null +++ b/src/assets/icons/svg/link.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/list.svg b/src/assets/icons/svg/list.svg new file mode 100644 index 0000000..20259ed --- /dev/null +++ b/src/assets/icons/svg/list.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/listener.svg b/src/assets/icons/svg/listener.svg new file mode 100644 index 0000000..afad0b8 --- /dev/null +++ b/src/assets/icons/svg/listener.svg @@ -0,0 +1 @@ +<?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="1646373053806" class="icon" viewBox="0 0 1264 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19028" xmlns:xlink="http://www.w3.org/1999/xlink" width="158" height="128"><defs><style type="text/css"></style></defs><path d="M1135.230625 547.617547a140.020149 140.020149 0 0 0-53.370909 12.557861l-5.023144-137.508577A448.315634 448.315634 0 0 0 604.033109 0.722705a448.315634 448.315634 0 0 0-439.525131 453.966671l5.023144 137.508577a140.020149 140.020149 0 0 0-53.998802-8.790503A106.113925 106.113925 0 0 0 0 681.986658l8.790503 251.157218a106.113925 106.113925 0 0 0 119.927571 89.788706A136.252791 136.252791 0 0 0 188.367913 1005.351577a30.766759 30.766759 0 0 0 26.371508 13.185754 31.394652 31.394652 0 0 0 30.138866-32.650439L225.413603 452.805697A385.52633 385.52633 0 0 1 606.544681 63.512009a385.52633 385.52633 0 0 1 407.502586 361.038501l18.836792 528.058051a31.394652 31.394652 0 0 0 53.998802 20.092577 135.624898 135.624898 0 0 0 62.789304 13.813647 106.113925 106.113925 0 0 0 113.020748-98.579208l-8.790503-251.157218a106.113925 106.113925 0 0 0-118.671785-89.160812zM125.578609 960.143277c-30.766759 0-54.626695-14.44154-54.626695-29.510973l-8.790503-251.157218c0-15.069433 21.976257-32.022545 52.743016-33.278331s53.370909 13.813647 54.626695 28.255187l8.790503 254.924576a53.998802 53.998802 0 0 1-52.743016 30.766759z m1074.325-69.696128c0 15.069433-21.976257 32.022545-52.743016 33.278332a53.998802 53.998802 0 0 1-53.998802-25.743615l-8.790503-255.552469c0-14.44154 22.60415-30.766759 52.743016-32.022546s54.626695 14.44154 54.626695 29.510973z" p-id="19029" fill="#dbdbdb"></path><path d="M621.614114 487.967708a31.394652 31.394652 0 0 0-30.138866 32.650438l13.185754 362.92218a31.394652 31.394652 0 1 0 62.789305 0l-13.185754-362.92218a31.394652 31.394652 0 0 0-32.650439-32.650438zM836.981429 335.389698a31.394652 31.394652 0 0 0-30.138866 32.650438l18.208898 507.965473a31.394652 31.394652 0 1 0 62.789304 0l-18.208898-507.965473a31.394652 31.394652 0 0 0-32.650438-32.650438zM406.2468 641.173611a31.394652 31.394652 0 0 0-30.138866 32.650438l7.534716 217.878886a31.394652 31.394652 0 1 0 62.789305 0L439.525131 671.312477a31.394652 31.394652 0 0 0-33.278331-30.138866z" p-id="19030" fill="#dbdbdb"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/live.svg b/src/assets/icons/svg/live.svg new file mode 100644 index 0000000..aeed8b3 --- /dev/null +++ b/src/assets/icons/svg/live.svg @@ -0,0 +1 @@ +<?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="1667669857229" class="icon" viewBox="0 0 1102 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15177" xmlns:xlink="http://www.w3.org/1999/xlink" width="137.75" height="128"><path d="M117.208615 703.015385V551.384615L0 530.668308v482.540307l117.208615-41.432615v-165.415385H303.261538L385.969231 682.456615l-103.424-62.070153-48.206769 82.707692H117.208615zM1102.769231 551.384615L261.907692 0H165.415385L34.422154 206.769231V275.692308l751.300923 482.461538 62.070154-6.931692L1102.769231 551.384615zM34.422154 317.046154v110.276923l758.232615 475.608615h68.844308l34.500923-34.500923 34.422154-103.424s-96.413538 69.001846-103.345231 69.001846C792.654769 806.360615 34.422154 317.046154 34.422154 317.046154z" p-id="15178"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/live1.svg b/src/assets/icons/svg/live1.svg new file mode 100644 index 0000000..e4f3624 --- /dev/null +++ b/src/assets/icons/svg/live1.svg @@ -0,0 +1 @@ +<?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="1695807499295" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3428" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M853.3248 1024H170.6752C76.8 1024 0 947.2 0 853.3248V170.6752C0 76.8 76.8 0 170.6752 0h682.6496C947.2 0 1024 76.8 1024 170.6752v682.6496C1024 947.2 947.2 1024 853.3248 1024z" fill="#3AC2B5" p-id="3429"></path><path d="M785.92 479.5648c-5.12-3.4048-11.0848-3.4048-17.0752-1.6896l-81.0496 35.84v-72.5504c0-19.6096-15.36-34.9696-34.9952-34.9696H265.3952c-9.3952 0-17.92 3.4048-24.7552 10.24-6.8352 6.8096-10.24 15.36-10.24 24.7296v281.6C230.4 742.4 245.76 757.76 265.3952 757.76H652.8c19.6352 0 34.9952-15.36 34.9952-34.9952V670.72l81.0496 35.84c5.12 2.56 11.9552 1.7152 17.0752-1.7152 5.12-3.4048 7.68-8.5248 7.68-14.4896V494.08c0-5.9648-3.4048-11.0848-7.68-14.5152zM551.2448 596.48l-114.3296 65.7152c-5.12 2.56-11.1104 2.56-16.2304 0a16.512 16.512 0 0 1-8.5248-14.5152v-130.56c0-5.9648 3.4048-11.0848 8.5248-14.5152 5.12-2.56 11.1104-2.56 16.2304 0l114.3296 65.7152c5.12 2.56 8.5504 8.5248 8.5504 14.5152-0.8704 5.12-3.4304 11.0848-8.5504 13.6448z m-47.7696-207.36a62.72 62.72 0 0 1-53.76-30.72 60.8768 60.8768 0 0 1 0-61.44 62.72 62.72 0 0 1 53.76-30.72 61.184 61.184 0 0 1 61.44 61.44 61.184 61.184 0 0 1-61.44 61.44z m-123.7504 0a44.6208 44.6208 0 0 1-44.3648-44.3648c0-23.9104 19.6352-44.3904 44.3648-44.3904 23.9104 0 44.3904 19.6352 44.3904 44.3904 0 24.7296-19.6352 44.3648-44.3904 44.3648z" fill="#FFFFFF" p-id="3430"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/lock.svg b/src/assets/icons/svg/lock.svg new file mode 100644 index 0000000..74fee54 --- /dev/null +++ b/src/assets/icons/svg/lock.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/log-a.svg b/src/assets/icons/svg/log-a.svg new file mode 100644 index 0000000..6cdd85d --- /dev/null +++ b/src/assets/icons/svg/log-a.svg @@ -0,0 +1,2 @@ +<?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="1654508193767" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14819" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><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="M310.857143 176.749714A134.107429 134.107429 0 0 0 444.964571 310.857143h134.070858A134.107429 134.107429 0 0 0 713.142857 176.749714h67.035429A134.107429 134.107429 0 0 1 914.285714 310.857143v469.321143A134.107429 134.107429 0 0 1 780.178286 914.285714H243.821714A134.107429 134.107429 0 0 1 109.714286 780.178286V310.857143a134.107429 134.107429 0 0 1 134.107428-134.107429H310.857143z m0 0h402.285714-402.285714z m234.678857 268.214857a33.536 33.536 0 1 0 0 67.035429h201.142857a33.536 33.536 0 0 0 0-67.035429h-201.142857z m0 201.142858a33.536 33.536 0 1 0 0 67.035428h201.142857a33.536 33.536 0 0 0 0-67.035428h-201.142857z m-220.781714-187.245715l-23.698286-23.734857a33.536 33.536 0 0 0-47.433143 47.433143l47.433143 47.396571a33.426286 33.426286 0 0 0 47.396571 0l94.829715-94.829714a33.536 33.536 0 1 0-47.433143-47.396571L324.754286 458.825143z m0 201.142857l-23.698286-23.734857a33.536 33.536 0 0 0-47.433143 47.433143l47.433143 47.396572a33.426286 33.426286 0 0 0 47.396571 0l94.829715-94.829715a33.536 33.536 0 1 0-47.433143-47.396571L324.754286 659.968zM444.964571 109.714286h134.070858a67.035429 67.035429 0 1 1 0 134.107428h-134.070858a67.035429 67.035429 0 0 1 0-134.107428z" p-id="14820"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/log.svg b/src/assets/icons/svg/log.svg new file mode 100644 index 0000000..d879d33 --- /dev/null +++ b/src/assets/icons/svg/log.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/logininfor.svg b/src/assets/icons/svg/logininfor.svg new file mode 100644 index 0000000..267f844 --- /dev/null +++ b/src/assets/icons/svg/logininfor.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/message.svg b/src/assets/icons/svg/message.svg new file mode 100644 index 0000000..14ca817 --- /dev/null +++ b/src/assets/icons/svg/message.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/model.svg b/src/assets/icons/svg/model.svg new file mode 100644 index 0000000..2acc40d --- /dev/null +++ b/src/assets/icons/svg/model.svg @@ -0,0 +1 @@ +<?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="1640534075068" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="20761" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M512.2 475.7c-8.2-0.3-16.1-2.4-23.4-6.1L192.6 330.2c-24.9-11.1-36.1-40.3-25-65.2 5-11.2 13.9-20.1 25-25l281.5-133.2a89.43 89.43 0 0 1 76 0L831.7 240c24.9 11.1 36.1 40.3 25 65.2-5 11.2-13.9 20.1-25 25L535.5 469.5c-7.2 3.8-15.2 5.9-23.3 6.2z m-76.5 452.5c-7.6 0-15.1-1.9-21.8-5.5L146.3 797.2c-17-8.9-27.5-26.5-27.3-45.6v-320c0.1-18 9.7-34.5 25.1-43.7 14.3-8.1 31.8-8.1 46.1 0l267.1 125.4c16.1 8.7 26.4 25.4 27.1 43.7v320.4c-0.2 17.9-9.6 34.4-24.9 43.7-7.2 4.3-15.4 6.8-23.8 7.1z m152.9 0c-8.3 0-16.5-2.2-23.8-6.3-15.3-9.3-24.7-25.8-24.9-43.7V556.9c0.4-18.2 10.4-34.8 26.2-43.7L835 387c14.2-7.5 31.4-7.1 45.2 1.1 15.5 9.1 25 25.7 25.1 43.7v319.8c0.4 18.9-9.7 36.5-26.2 45.6L610.5 922.8c-6.8 3.6-14.3 5.5-21.9 5.4z" p-id="20762"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/money.svg b/src/assets/icons/svg/money.svg new file mode 100644 index 0000000..c1580de --- /dev/null +++ b/src/assets/icons/svg/money.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/monitor-a.svg b/src/assets/icons/svg/monitor-a.svg new file mode 100644 index 0000000..07a4cf1 --- /dev/null +++ b/src/assets/icons/svg/monitor-a.svg @@ -0,0 +1,2 @@ +<?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="1654508048546" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10209" width="128" height="128" xmlns:xlink="http://www.w3.org/1999/xlink"><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="M450.346667 256.213333a20.693333 20.693333 0 0 0-10.666667 1.493334c3.2-1.493333 7.04-2.133333 10.666667-1.493334z" p-id="10210"></path><path d="M874.666667 128H149.333333c-23.466667 0-42.666667 19.2-42.666666 42.666667v512c0 23.466667 19.2 42.666667 42.666666 42.666666h256v128h-128c-11.733333 0-21.333333 9.6-21.333333 21.333334s9.6 21.333333 21.333333 21.333333h469.333334c11.733333 0 21.333333-9.6 21.333333-21.333333s-9.6-21.333333-21.333333-21.333334h-128v-128h256c23.466667 0 42.666667-19.2 42.666666-42.666666V170.666667c0-23.466667-19.2-42.666667-42.666666-42.666667z m-106.666667 320h-94.293333l-79.146667 138.666667c-3.84 6.613333-10.88 10.666667-18.56 10.666666h-1.28a21.269333 21.269333 0 0 1-18.346667-13.013333l-111.146666-259.2-64 112.213333c-3.84 6.613333-10.88 10.666667-18.56 10.666667h-106.666667c-11.733333 0-21.333333-9.6-21.333333-21.333333s9.6-21.333333 21.333333-21.333334h94.293333l79.146667-138.666666a20.906667 20.906667 0 0 1 19.84-10.666667c8.106667 0.426667 15.146667 5.546667 18.346667 13.013333l111.146666 259.2 64-112.213333c3.84-6.613333 10.88-10.666667 18.56-10.666667h106.666667c11.733333 0 21.333333 9.6 21.333333 21.333334s-9.6 21.333333-21.333333 21.333333z" p-id="10211"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/monitor.svg b/src/assets/icons/svg/monitor.svg new file mode 100644 index 0000000..bc308cb --- /dev/null +++ b/src/assets/icons/svg/monitor.svg @@ -0,0 +1,2 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/mq.svg b/src/assets/icons/svg/mq.svg new file mode 100644 index 0000000..ba9dd10 --- /dev/null +++ b/src/assets/icons/svg/mq.svg @@ -0,0 +1 @@ +<?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="1646372847253" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15368" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M768 618.666667c-32 0-61.866667 10.666667-87.466667 27.733333l-53.333333-53.333333c21.333333-32 34.133333-70.4 34.133333-113.066667s-12.8-81.066667-34.133333-113.066667l44.8-44.8c19.2 12.8 40.533333 19.2 64 19.2 64 0 117.333333-53.333333 117.333333-117.333333S800 106.666667 736 106.666667 618.666667 160 618.666667 224c0 17.066667 4.266667 34.133333 10.666666 49.066667L584.533333 320c-34.133333-27.733333-76.8-42.666667-125.866666-42.666667-42.666667 0-81.066667 12.8-113.066667 34.133334l-78.933333-78.933334c6.4-12.8 10.666667-25.6 10.666666-40.533333 0-46.933333-38.4-85.333333-85.333333-85.333333S106.666667 145.066667 106.666667 192s38.4 85.333333 85.333333 85.333333c8.533333 0 17.066667-2.133333 25.6-4.266666l81.066667 81.066666c-27.733333 34.133333-42.666667 76.8-42.666667 125.866667s17.066667 89.6 42.666667 125.866667l-29.866667 29.866666c-14.933333-10.666667-34.133333-17.066667-55.466667-17.066666-59.733333 0-106.666667 46.933333-106.666666 106.666666s46.933333 106.666667 106.666666 106.666667 106.666667-46.933333 106.666667-106.666667c0-14.933333-2.133333-29.866667-8.533333-42.666666l34.133333-34.133334c32 21.333333 70.4 34.133333 113.066667 34.133334 46.933333 0 89.6-17.066667 125.866666-42.666667l55.466667 55.466667c-12.8 21.333333-19.2 46.933333-19.2 74.666666 0 83.2 66.133333 149.333333 149.333333 149.333334s149.333333-66.133333 149.333334-149.333334S851.2 618.666667 768 618.666667zM192 213.333333c-12.8 0-21.333333-8.533333-21.333333-21.333333s8.533333-21.333333 21.333333-21.333333 21.333333 8.533333 21.333333 21.333333-8.533333 21.333333-21.333333 21.333333z m160 298.666667c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32 32 14.933333 32 32-14.933333 32-32 32z m106.666667 0c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32 32 14.933333 32 32-14.933333 32-32 32z m106.666666 0c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32 32 14.933333 32 32-14.933333 32-32 32zM768 853.333333c-46.933333 0-85.333333-38.4-85.333333-85.333333s38.4-85.333333 85.333333-85.333333 85.333333 38.4 85.333333 85.333333-38.4 85.333333-85.333333 85.333333z" p-id="15369" fill="#dbdbdb"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/nested.svg b/src/assets/icons/svg/nested.svg new file mode 100644 index 0000000..06713a8 --- /dev/null +++ b/src/assets/icons/svg/nested.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/number.svg b/src/assets/icons/svg/number.svg new file mode 100644 index 0000000..ad5ce9a --- /dev/null +++ b/src/assets/icons/svg/number.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/online.svg b/src/assets/icons/svg/online.svg new file mode 100644 index 0000000..330a202 --- /dev/null +++ b/src/assets/icons/svg/online.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/ota.svg b/src/assets/icons/svg/ota.svg new file mode 100644 index 0000000..5a85d34 --- /dev/null +++ b/src/assets/icons/svg/ota.svg @@ -0,0 +1 @@ +<?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="1646977045224" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4380" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M534.656 361.408C528.864 355.6 520.848 352 512 352s-16.864 3.6-22.656 9.408l-127.952 127.952a32 32 0 1 0 45.248 45.248L480 461.248V640a32 32 0 1 0 64 0V461.248l73.36 73.36a32 32 0 1 0 45.232-45.264l-127.936-127.936z" p-id="4381"></path><path d="M928 576h-32v-128h32a32 32 0 0 0 0-64h-32v-32c0-123.52-100.48-224-224-224h-32V96a32 32 0 0 0-64 0v32h-128V96a32 32 0 0 0-64 0v32h-32C228.48 128 128 228.48 128 352v32H96a32 32 0 0 0 0 64h32v128H96a32 32 0 0 0 0 64h32v32c0 123.52 100.48 224 224 224h32v32a32 32 0 0 0 64 0v-32h128v32a32 32 0 0 0 64 0v-32h32c123.52 0 224-100.48 224-224v-32h32a32 32 0 0 0 0-64z m-96 96c0 88.224-71.776 160-160 160H352c-88.224 0-160-71.776-160-160V352c0-88.224 71.776-160 160-160h320c88.224 0 160 71.776 160 160v320z" p-id="4382"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/password.svg b/src/assets/icons/svg/password.svg new file mode 100644 index 0000000..6c64def --- /dev/null +++ b/src/assets/icons/svg/password.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/pdf.svg b/src/assets/icons/svg/pdf.svg new file mode 100644 index 0000000..957aa0c --- /dev/null +++ b/src/assets/icons/svg/pdf.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/people.svg b/src/assets/icons/svg/people.svg new file mode 100644 index 0000000..2bd54ae --- /dev/null +++ b/src/assets/icons/svg/people.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/peoples.svg b/src/assets/icons/svg/peoples.svg new file mode 100644 index 0000000..aab852e --- /dev/null +++ b/src/assets/icons/svg/peoples.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/phone.svg b/src/assets/icons/svg/phone.svg new file mode 100644 index 0000000..ab8e8c4 --- /dev/null +++ b/src/assets/icons/svg/phone.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/plugin.svg b/src/assets/icons/svg/plugin.svg new file mode 100644 index 0000000..4e977d7 --- /dev/null +++ b/src/assets/icons/svg/plugin.svg @@ -0,0 +1 @@ +<?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="1646373395495" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="26576" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M627.2 960H166.4c-25.6 0-51.2-12.8-70.4-25.6-19.2-19.2-32-44.8-32-70.4v-115.2c6.4-19.2 12.8-38.4 32-51.2 12.8-6.4 19.2-12.8 32-12.8s25.6 6.4 44.8 12.8H192c12.8 6.4 19.2 6.4 32 6.4s25.6 0 32-6.4c12.8-6.4 19.2-12.8 25.6-19.2 6.4-6.4 12.8-19.2 19.2-25.6 6.4-12.8 6.4-19.2 6.4-32s0-25.6-6.4-32c-6.4-12.8-12.8-19.2-19.2-25.6s-19.2-12.8-25.6-19.2c-12.8-6.4-19.2-6.4-32-6.4s-19.2 0-32 6.4h-6.4c-6.4 6.4-19.2 6.4-25.6 12.8-12.8 6.4-25.6 6.4-38.4 6.4-19.2 0-32-12.8-38.4-25.6-6.4-12.8-12.8-25.6-12.8-44.8V396.8c0-25.6 12.8-51.2 32-70.4 19.2-19.2 44.8-32 70.4-32H256c-6.4-19.2-6.4-32-6.4-51.2 0-25.6 6.4-51.2 12.8-70.4l38.4-57.6c19.2-19.2 38.4-32 57.6-38.4C384 64 403.2 64 428.8 64s51.2 6.4 70.4 12.8l57.6 38.4c19.2 19.2 32 38.4 38.4 57.6 12.8 25.6 12.8 44.8 12.8 70.4 0 19.2 0 38.4-6.4 51.2h25.6c25.6 0 51.2 12.8 70.4 32 19.2 19.2 25.6 44.8 25.6 70.4v64c19.2-6.4 38.4-6.4 57.6-6.4 25.6 0 44.8 6.4 70.4 12.8 19.2 6.4 38.4 25.6 57.6 38.4 19.2 19.2 32 38.4 38.4 57.6 6.4 19.2 12.8 44.8 12.8 70.4 0 25.6-6.4 51.2-12.8 70.4-6.4 19.2-19.2 38.4-38.4 57.6-19.2 19.2-38.4 32-57.6 38.4-19.2 6.4-44.8 12.8-70.4 12.8-19.2 0-38.4 0-57.6-6.4v51.2c0 25.6-12.8 51.2-25.6 70.4-19.2 19.2-44.8 32-70.4 32z m-486.4-192v96c0 6.4 0 12.8 6.4 19.2 6.4 6.4 12.8 6.4 19.2 6.4h460.8c6.4 0 12.8 0 19.2-6.4 6.4-6.4 6.4-12.8 6.4-19.2v-198.4l64 51.2c6.4 6.4 19.2 12.8 32 19.2 12.8 6.4 25.6 6.4 38.4 6.4 12.8 0 25.6 0 38.4-6.4 12.8-6.4 25.6-12.8 32-25.6 12.8-12.8 19.2-19.2 25.6-32 6.4-12.8 6.4-25.6 6.4-38.4 0-12.8 0-25.6-6.4-38.4-6.4-12.8-12.8-25.6-25.6-32-12.8-12.8-19.2-19.2-32-25.6-12.8-6.4-25.6-6.4-38.4-6.4-12.8 0-25.6 0-38.4 6.4-12.8 6.4-25.6 12.8-32 19.2l-64 51.2V409.6c0-6.4 0-12.8-6.4-19.2C640 384 640 384 627.2 384H454.4l51.2-64c19.2-19.2 25.6-38.4 25.6-64 0-12.8 0-32-6.4-44.8-6.4-12.8-12.8-25.6-25.6-32-12.8-12.8-19.2-19.2-32-25.6-12.8-6.4-25.6-6.4-44.8-6.4-12.8 0-25.6 0-44.8 6.4-12.8 6.4-25.6 12.8-32 25.6-12.8 12.8-19.2 19.2-25.6 32-6.4 12.8-6.4 25.6-6.4 44.8 0 12.8 0 25.6 6.4 38.4 6.4 12.8 12.8 25.6 19.2 32l51.2 64H166.4c-6.4 0-12.8 0-19.2 6.4-6.4 6.4-6.4 12.8-6.4 19.2v89.6s6.4 0 6.4-6.4c6.4 0 6.4-6.4 12.8-6.4 19.2-6.4 38.4-12.8 64-12.8 19.2 0 44.8 6.4 64 12.8 19.2 6.4 38.4 19.2 51.2 32 12.8 12.8 25.6 32 32 51.2 6.4 19.2 12.8 38.4 12.8 64 0 19.2-6.4 44.8-12.8 64-6.4 19.2-19.2 38.4-32 51.2-12.8 12.8-32 25.6-51.2 32-19.2 6.4-38.4 12.8-64 12.8-19.2 0-44.8-6.4-64-12.8-6.4-12.8-12.8-19.2-19.2-19.2z" fill="#dbdbdb" p-id="26577"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/post.svg b/src/assets/icons/svg/post.svg new file mode 100644 index 0000000..2922c61 --- /dev/null +++ b/src/assets/icons/svg/post.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/product.svg b/src/assets/icons/svg/product.svg new file mode 100644 index 0000000..d21c806 --- /dev/null +++ b/src/assets/icons/svg/product.svg @@ -0,0 +1 @@ +<?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="1640534278171" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22249" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M146.285714 109.714286h278.857143a36.571429 36.571429 0 0 1 36.571429 36.571428v278.857143a36.571429 36.571429 0 0 1-36.571429 36.571429H146.285714a36.571429 36.571429 0 0 1-36.571428-36.571429V146.285714a36.571429 36.571429 0 0 1 36.571428-36.571428z m0 452.571428h278.857143a36.571429 36.571429 0 0 1 36.571429 36.571429V877.714286a36.571429 36.571429 0 0 1-36.571429 36.571428H146.285714a36.571429 36.571429 0 0 1-36.571428-36.571428v-278.857143a36.571429 36.571429 0 0 1 36.571428-36.571429zM598.857143 109.714286H877.714286a36.571429 36.571429 0 0 1 36.571428 36.571428v278.857143a36.571429 36.571429 0 0 1-36.571428 36.571429h-278.857143a36.571429 36.571429 0 0 1-36.571429-36.571429V146.285714a36.571429 36.571429 0 0 1 36.571429-36.571428z m0 452.571428H877.714286a36.571429 36.571429 0 0 1 36.571428 36.571429V877.714286a36.571429 36.571429 0 0 1-36.571428 36.571428h-278.857143a36.571429 36.571429 0 0 1-36.571429-36.571428v-278.857143a36.571429 36.571429 0 0 1 36.571429-36.571429z" p-id="22250"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/qq.svg b/src/assets/icons/svg/qq.svg new file mode 100644 index 0000000..ee13d4e --- /dev/null +++ b/src/assets/icons/svg/qq.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/qrcode.svg b/src/assets/icons/svg/qrcode.svg new file mode 100644 index 0000000..ae4e80d --- /dev/null +++ b/src/assets/icons/svg/qrcode.svg @@ -0,0 +1 @@ +<?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="1694710419764" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10114" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M774.59911111 67.69777778c-2.61688889 0.34133333-5.34755555 0.11377778-7.96444444 0.11377777-43.23555555 0-86.47111111-0.11377778-129.70666667 0.11377778-12.51555555 0-24.91733333 1.59288889-36.864 5.80266667-21.16266667 7.39555555-33.90577778 22.18666667-39.13955555 43.69066667-1.93422222 7.96444445-2.73066667 16.04266667-2.73066667 24.23466666 0 76.45866667-0.11377778 152.80355555 0.11377777 229.26222222 0 15.70133333 1.024 31.40266667 7.05422223 46.42133334 7.85066667 19.456 22.41422222 30.94755555 42.43911111 36.06755556 7.168 1.82044445 14.56355555 2.50311111 21.95911111 2.5031111h248.03555555c9.44355555 0 18.88711111-0.79644445 28.2168889-2.61688888 27.76177778-5.12 45.96622222-23.552 51.08622222-51.2 0.45511111-2.50311111-0.45511111-5.91644445 3.29955555-7.05422222v-263.96444445c-0.45511111-0.45511111-0.56888889-1.024-0.56888889-1.70666667-1.70666667-5.46133333-1.93422222-11.15022222-3.75466666-16.72533333-8.07822222-23.89333333-24.68977778-38.00177778-48.69688889-44.14577778-7.28177778-1.82044445-14.56355555-2.73066667-22.18666667-2.38933333-1.47911111 0.11377778-3.41333333 1.13777778-4.43733333-1.024h-101.26222223c-0.45511111 2.95822222-3.072 2.38933333-4.89244444 2.61688889z m112.29866667 46.30755555c4.55111111 0 9.216 1.024 13.53955555 2.38933334 7.85066667 2.50311111 12.17422222 8.64711111 12.17422222 17.18044444 0 85.10577778 0.11377778 170.21155555-0.11377777 255.31733334 0 12.74311111-9.78488889 20.48-24.00711111 20.59377777-43.46311111 0.34133333-86.81244445 0.11377778-130.27555556 0.11377778h-128.56888889c-5.12 0-9.78488889-1.47911111-14.44977777-3.072-9.67111111-3.52711111-10.92266667-11.94666667-11.03644445-20.36622222-0.22755555-42.66666667-0.11377778-85.33333333-0.11377778-128V138.12622222c0-7.39555555 1.70666667-14.22222222 7.85066667-19.34222222 5.23377778-4.32355555 11.71911111-4.89244445 17.74933333-4.89244445 85.78844445-0.11377778 171.57688889 0 257.25155556 0.11377778z" fill="#707070" p-id="10115"></path><path d="M773.68888889 65.99111111c-44.94222222 0.11377778-89.88444445 0.11377778-134.71288889 0.11377778-10.69511111 0-21.16266667 1.13777778-31.51644445 3.52711111-13.19822222 3.072-25.14488889 8.76088889-34.13333333 19.00088889-12.06044445 13.76711111-16.83911111 30.60622222-16.83911111 48.46933333-0.22755555 79.18933333-0.22755555 158.49244445 0 237.68177778 0 10.35377778 0.79644445 20.82133333 3.18577778 30.94755555 3.18577778 13.312 8.64711111 25.6 19.00088889 34.70222223 13.312 11.71911111 29.46844445 17.06666667 47.21777777 17.06666667 84.30933333 0.11377778 168.73244445 0.11377778 253.04177778 0 10.58133333 0 21.27644445-0.56888889 31.51644445-3.41333334 21.61777778-6.144 38.22933333-18.09066667 45.51111111-40.73244444 1.93422222-6.03022222 2.048-12.40177778 4.32355556-18.31822222-3.64088889 1.13777778-2.84444445 4.55111111-3.29955556 7.05422222-5.12 27.76177778-23.32444445 46.08-51.08622222 51.2-9.32977778 1.70666667-18.77333333 2.61688889-28.21688889 2.61688888h-248.03555556c-7.39555555 0-14.79111111-0.68266667-21.95911111-2.5031111-19.91111111-5.12-34.58844445-16.61155555-42.43911111-36.06755556-6.03022222-14.90488889-7.05422222-30.72-7.05422222-46.42133334-0.22755555-76.45866667-0.11377778-152.80355555-0.11377778-229.26222222 0-8.192 0.79644445-16.27022222 2.73066667-24.23466666 5.23377778-21.504 17.97688889-36.29511111 39.13955555-43.69066667 11.94666667-4.20977778 24.34844445-5.68888889 36.864-5.80266667 43.23555555-0.22755555 86.47111111-0.11377778 129.70666667-0.11377778 2.61688889 0 5.34755555 0.22755555 7.96444444-0.11377777 1.93422222-0.22755555 4.43733333 0.22755555 4.77866667-2.73066667-1.36533333 2.38933333-3.64088889 1.024-5.57511111 1.024zM66.67377778 396.288c2.27555555 14.22222222 6.25777778 27.76177778 16.27022222 38.68444445 13.08444445 14.44977778 30.15111111 20.48 48.92444445 20.59377777 85.44711111 0.34133333 170.89422222 0.34133333 256.4551111 0 10.69511111 0 21.504-1.13777778 31.97155556-4.43733333 27.87555555-8.76088889 44.48711111-31.06133333 44.48711111-60.416 0-84.19555555 0-168.27733333 0.11377778-252.47288889 0-7.28177778-0.91022222-14.336-2.73066667-21.39022222-6.59911111-25.48622222-27.87555555-44.48711111-54.04444444-48.128-4.66488889-0.68266667-9.32977778-1.25155555-14.10844444-1.25155556-2.27555555 0-5.12 0.68266667-5.91644445-2.73066667h-101.26222222c-1.47911111 2.38933333-3.75466667 1.024-5.57511111 1.024-46.76266667 0.11377778-93.52533333-0.22755555-140.288 0.22755556-16.83911111 0.11377778-33.22311111 2.95822222-48.01422222 12.17422222-14.22222222 8.87466667-22.528 21.73155555-26.96533334 37.54666667-0.91022222 3.072-0.22755555 6.48533333-2.16177778 9.32977778v265.10222222c3.29955555 1.024 2.50311111 3.98222222 2.84444445 6.144z m44.94222222-262.82666667c0-9.216 7.05422222-16.61155555 16.49777778-18.54577778 5.00622222-1.024 10.01244445-1.13777778 15.01866667-1.13777777h249.17333333c4.89244445 0 9.55733333 0.91022222 14.10844444 2.27555555 8.53333333 2.73066667 12.288 7.85066667 12.288 16.61155556v256.56888889c0 9.32977778-4.32355555 15.13244445-13.19822222 18.09066667-4.55111111 1.47911111-9.216 2.38933333-14.10844445 2.27555555-42.32533333-0.11377778-84.53688889-0.11377778-126.86222222-0.11377778-42.89422222 0-85.67466667 0.11377778-128.56888888-0.11377777-7.168 0-14.336-1.024-19.68355556-6.94044445-3.072-3.41333333-4.66488889-7.168-4.66488889-11.49155555-0.11377778-85.67466667-0.11377778-171.57688889 0-257.47911112z" fill="#707070" p-id="10116"></path><path d="M64.85333333 393.10222222c0.11377778 10.12622222 2.95822222 19.68355555 7.28177778 28.55822223 11.83288889 24.34844445 32.88177778 35.27111111 58.70933334 35.49866666 84.76444445 0.68266667 169.52888889 0.22755555 254.17955555 0.22755556 10.58133333 0 21.16266667-0.91022222 31.51644445-3.41333334 30.83377778-7.62311111 49.60711111-30.03733333 49.83466666-61.89511111 0.56888889-83.968 0.22755555-167.936 0.22755556-251.904 0-5.57511111 0-11.15022222-1.024-16.72533333-3.41333333-18.432-12.17422222-33.45066667-27.53422222-44.37333334-12.51555555-8.87466667-26.73777778-12.51555555-41.984-12.97066666-2.61688889-0.11377778-5.57511111 1.36533333-7.85066667-1.024 0.79644445 3.41333333 3.75466667 2.73066667 5.91644444 2.73066666 4.77866667 0 9.44355555 0.68266667 14.10844445 1.25155556 26.16888889 3.64088889 47.44533333 22.64177778 54.04444444 48.128 1.82044445 7.05422222 2.73066667 14.10844445 2.73066667 21.39022222-0.11377778 84.19555555 0 168.27733333-0.11377778 252.47288889 0 29.24088889-16.61155555 51.54133333-44.48711111 60.416-10.46755555 3.29955555-21.27644445 4.43733333-31.97155556 4.43733333-85.44711111 0.22755555-170.89422222 0.34133333-256.45511111 0-18.77333333-0.11377778-35.72622222-6.144-48.92444444-20.59377777-10.01244445-11.03644445-13.99466667-24.46222222-16.27022223-38.68444445-0.34133333-2.16177778 0.45511111-5.23377778-2.95822222-5.91644444 1.47911111 0.11377778 1.024 1.47911111 1.024 2.38933333zM147.68355555 933.77422222c2.38933333-0.34133333 4.89244445-0.11377778 7.39555556-0.11377777h234.38222222c9.55733333 0 18.88711111-1.13777778 28.10311112-3.52711112 29.01333333-7.50933333 47.104-30.60622222 47.21777777-60.52977778 0.11377778-28.78577778 0-57.68533333 0-86.4711111v-168.39111112c0-36.75022222-24.34844445-63.94311111-60.98488889-67.92533333-12.97066667-1.36533333-26.05511111-1.93422222-39.13955555-2.27555555-39.25333333-0.79644445-78.50666667 0.56888889-117.64622223 1.4791111-37.54666667 0.91022222-75.09333333 0.22755555-112.52622222 0.79644445-13.08444445 0.22755555-25.71377778 3.072-37.20533333 9.216-15.47377778 8.192-24.91733333 21.04888889-29.24088889 38.00177778-0.79644445 3.18577778-0.11377778 7.39555555-4.20977778 9.10222222v266.24c2.27555555 6.25777778 2.50311111 12.97066667 4.43733334 19.456 6.71288889 23.552 22.07288889 37.888 45.28355555 44.25955555 7.39555555 2.048 15.01866667 2.61688889 22.64177778 2.38933334 1.59288889 0 3.75466667-1.25155555 5.00622222 1.024h2.27555556c0.22755555-2.61688889 2.38933333-2.50311111 4.20977777-2.73066667z m-12.97066666-46.19377777c-13.88088889 0-23.552-7.50933333-23.43822222-23.32444445 0.45511111-83.39911111 0.22755555-166.79822222 0.11377778-250.31111111 0-13.42577778 7.96444445-20.59377778 20.82133333-21.04888889 84.87822222-2.73066667 169.64266667-0.56888889 254.52088889-0.91022222 7.28177778 0 15.24622222-0.45511111 22.30044444 3.41333333 6.144 3.41333333 9.67111111 8.192 9.67111111 15.58755556-0.11377778 42.66666667 0 85.33333333 0 128 0 42.32533333-0.22755555 84.53688889 0.11377778 126.86222222 0.11377778 13.76711111-8.87466667 20.02488889-21.27644445 21.95911111-9.78488889 1.47911111-19.34222222 0-29.01333333-0.11377778-77.93777778-0.22755555-155.87555555-0.11377778-233.81333333-0.11377777z" fill="#707070" p-id="10117"></path><path d="M149.61777778 935.48088889c77.14133333-0.11377778 154.39644445-0.11377778 231.53777777 0 10.69511111 0 21.27644445-0.22755555 31.85777778-2.38933334 14.22222222-2.84444445 27.07911111-8.87466667 36.97777778-19.456 11.03644445-11.83288889 16.49777778-26.624 16.49777778-42.78044444 0.22755555-84.53688889 0.11377778-169.18755555 0.11377778-253.72444444 0-7.168-0.45511111-14.10844445-2.27555556-21.04888889-6.03022222-22.64177778-19.68355555-38.34311111-41.75644444-46.99022223-15.13244445-5.91644445-31.06133333-5.68888889-46.64888889-6.03022222-26.28266667-0.56888889-52.56533333-1.024-78.848 0.56888889-21.61777778 1.36533333-43.46311111 0.34133333-65.19466667 1.13777778-31.40266667 1.024-62.91911111 0.34133333-94.43555556 0.22755555-7.28177778 0-14.44977778 0.68266667-21.61777777 2.27555556-20.93511111 4.77866667-36.97777778 15.70133333-46.19377778 35.61244444-2.95822222 6.48533333-3.18577778 13.65333333-5.91644445 20.13866667 4.20977778-1.70666667 3.41333333-5.91644445 4.20977778-9.10222222 4.32355555-16.95288889 13.88088889-29.80977778 29.24088889-38.00177778 11.60533333-6.144 24.12088889-8.98844445 37.20533333-9.216 37.54666667-0.56888889 74.97955555 0.11377778 112.52622223-0.79644444 39.25333333-0.91022222 78.39288889-2.27555555 117.64622222-1.47911111 13.08444445 0.22755555 26.16888889 0.79644445 39.13955555 2.27555555 36.63644445 3.98222222 60.87111111 31.17511111 60.9848889 67.92533333v168.39111112c0 28.78577778 0.11377778 57.68533333 0 86.47111111-0.22755555 30.03733333-18.20444445 53.02044445-47.21777778 60.52977777-9.216 2.38933333-18.54577778 3.52711111-28.10311112 3.52711112h-234.38222222c-2.50311111 0-4.89244445-0.11377778-7.39555555 0.11377778-1.82044445 0.22755555-3.98222222 0-4.20977778 2.73066666 1.70666667-2.16177778 4.20977778-0.91022222 6.25777778-0.91022222z" fill="#707070" p-id="10118"></path><path d="M92.84266667 78.39288889c14.79111111-9.10222222 31.17511111-12.06044445 48.01422222-12.17422222 46.76266667-0.45511111 93.52533333-0.11377778 140.288-0.22755556 1.82044445 0 4.096 1.36533333 5.57511111-1.024-1.93422222 1.13777778-4.096 0.56888889-6.144 0.56888889-50.97244445 0.34133333-101.94488889-0.91022222-152.91733333 0.68266667-21.504 0.68266667-39.70844445 9.216-52.90666667 26.85155555-7.168 9.55733333-10.35377778 20.48-11.03644445 32.19911111 2.048-2.73066667 1.36533333-6.144 2.16177778-9.32977778 4.55111111-15.81511111 12.74311111-28.672 26.96533334-37.54666666zM885.19111111 65.99111111c7.50933333-0.34133333 14.90488889 0.56888889 22.18666667 2.38933334 23.89333333 6.144 40.61866667 20.25244445 48.69688889 44.14577777 1.82044445 5.46133333 2.048 11.264 3.75466666 16.72533333v-0.4551111c0.45511111-31.97155555-27.76177778-60.52977778-59.96088888-62.91911112-6.37155555-0.45511111-12.74311111 0.56888889-19.11466667-1.024 0.91022222 2.38933333 2.95822222 1.25155555 4.43733333 1.13777778zM136.07822222 935.48088889c-7.62311111 0.22755555-15.24622222-0.34133333-22.64177777-2.38933334-23.21066667-6.37155555-38.57066667-20.70755555-45.28355556-44.25955555-1.82044445-6.48533333-2.048-13.19822222-4.43733334-19.456 1.25155555 6.03022222 0.91022222 12.288 2.38933334 18.31822222 6.25777778 25.94133333 29.01333333 46.19377778 55.296 47.78666667 6.59911111 0.45511111 13.19822222-0.68266667 19.68355556 0.91022222-1.25155555-2.16177778-3.41333333-1.024-5.00622223-0.91022222z" fill="#707070" p-id="10119"></path><path d="M621.68177778 688.58311111c-13.99466667 0.22755555-23.21066667 9.44355555-23.21066667 22.75555556V906.80888889c0 13.99466667 9.67111111 22.86933333 23.66577778 22.64177778 14.67733333-0.22755555 23.89333333-7.85066667 24.00711111-22.41422222 0.22755555-65.30844445 0.11377778-130.73066667 0-196.03911112 0-13.65333333-9.55733333-22.64177778-24.46222222-22.41422222zM909.53955555 688.81066667c-11.264-2.048-26.51022222 5.57511111-26.51022222 20.70755555-0.22755555 33.22311111 0 66.33244445 0 99.55555556v98.98666667c0 1.82044445-0.11377778 3.86844445 0.45511112 5.5751111 3.75466667 10.69511111 16.384 18.432 26.73777777 15.9288889 12.97066667-3.072 20.36622222-8.192 20.48-24.34844445 0.22755555-63.14666667 0.11377778-126.29333333 0.11377778-189.44-0.11377778-16.384-5.23377778-24.00711111-21.27644445-26.96533333zM804.06755555 756.96355555c-2.95822222-10.69511111-14.79111111-19.11466667-25.14488888-17.18044444-14.10844445 2.73066667-22.07288889 7.50933333-22.18666667 23.77955556-0.34133333 46.76266667-0.11377778 93.63911111-0.11377778 140.40177778 0 15.70133333 6.48533333 22.75555555 19.91111111 25.25866666 12.62933333 2.38933333 27.76177778-5.12 27.87555556-21.73155556v-72.24888888-73.38666667c0-1.47911111 0-3.29955555-0.34133334-4.89244445zM772.55111111 549.31911111c-9.89866667 2.16177778-15.92888889 11.60533333-15.92888889 22.528V672.42666667c0 14.90488889 4.55111111 23.89333333 20.59377778 26.96533333 11.71911111 2.16177778 27.30666667-5.91644445 27.19288889-21.04888889-0.11377778-17.97688889 0-35.95377778 0-54.04444444 0-17.408-0.22755555-34.816 0-52.33777778 0.34133333-21.61777778-16.61155555-25.94133333-31.85777778-22.64177778zM637.15555555 552.27733333c-5.57511111-3.86844445-11.49155555-3.75466667-17.52177777-3.75466666-11.94666667 0-21.04888889 8.98844445-21.04888889 20.82133333v29.58222222c0 10.24-0.11377778 20.48 0 30.72 0.11377778 5.23377778 1.47911111 9.89866667 5.57511111 13.99466667 5.91644445 5.91644445 12.74311111 7.62311111 20.70755555 7.39555556 11.264-0.34133333 21.39022222-10.12622222 21.39022223-21.27644445 0.11377778-20.13866667 0.22755555-40.16355555-0.11377778-60.30222222 0-6.94044445-2.73066667-12.85688889-8.98844445-17.18044445zM928.768 561.94844445c-2.50311111-7.05422222-11.15022222-13.42577778-20.36622222-13.65333334-16.27022222-0.56888889-26.85155555 8.98844445-25.6 25.94133334 0.56888889 7.96444445 0.11377778 15.92888889 0.11377777 23.89333333v28.44444444c0 1.70666667 0 3.41333333 0.45511112 5.00622223 3.64088889 11.71911111 14.67733333 17.63555555 27.19288888 15.92888888 12.51555555-1.82044445 19.79733333-9.55733333 20.0248889-22.41422222 0.34133333-17.97688889 0.11377778-36.06755555 0.11377777-54.04444444 0-3.29955555-0.91022222-6.25777778-1.93422222-9.10222222zM329.95555555 222.77688889c-2.16177778-8.30577778-8.98844445-14.44977778-17.52177777-15.58755556-1.47911111-0.22755555-3.072-0.45511111-4.55111111-0.45511111-0.68266667 0-1.70666667 0.22755555-1.93422222-0.91022222h-32.768c-0.45511111 0.79644445-1.25155555 0.34133333-1.82044445 0.34133333-15.13244445 0-30.26488889-0.11377778-45.39733333 0.11377778-5.46133333 0-10.80888889 1.024-15.58755556 3.98222222-4.66488889 2.84444445-7.28177778 7.05422222-8.76088889 12.17422222-0.22755555 1.024 0 2.16177778-0.68266667 2.95822223v85.90222222c1.13777778 0.22755555 0.79644445 1.25155555 0.91022223 1.93422222 0.79644445 4.66488889 2.048 8.98844445 5.23377777 12.51555556 4.20977778 4.66488889 9.78488889 6.59911111 15.81511112 6.71288889 27.648 0.11377778 55.40977778 0.11377778 83.05777778 0 3.52711111 0 6.94044445-0.34133333 10.35377777-1.47911112 8.98844445-2.84444445 14.44977778-10.12622222 14.44977778-19.56977777v-81.80622223c0.11377778-2.27555555-0.22755555-4.55111111-0.79644445-6.82666666zM823.18222222 214.016c-2.16177778-8.30577778-8.98844445-14.44977778-17.52177777-15.58755555-1.47911111-0.22755555-3.072-0.45511111-4.55111112-0.45511112-0.68266667 0-1.70666667 0.22755555-1.93422222-0.91022222h-32.768c-0.45511111 0.79644445-1.25155555 0.34133333-1.82044444 0.34133334-15.13244445 0-30.26488889-0.11377778-45.39733334 0.11377777-5.46133333 0-10.80888889 1.024-15.58755555 3.98222223-4.66488889 2.84444445-7.28177778 7.05422222-8.76088889 12.17422222-0.22755555 1.024 0 2.16177778-0.68266667 2.95822222v85.90222222c1.13777778 0.22755555 0.79644445 1.25155555 0.91022223 1.93422222 0.79644445 4.66488889 2.048 8.98844445 5.23377777 12.51555556 4.20977778 4.66488889 9.78488889 6.59911111 15.81511111 6.71288889 27.648 0.11377778 55.40977778 0.11377778 83.05777778 0 3.52711111 0 6.94044445-0.34133333 10.35377778-1.47911111 8.98844445-2.84444445 14.44977778-10.12622222 14.44977778-19.56977778v-81.80622222c0.22755555-2.27555555-0.22755555-4.66488889-0.79644445-6.82666667zM329.27288889 699.27822222c-2.16177778-8.30577778-8.98844445-14.44977778-17.52177778-15.58755555-1.47911111-0.22755555-3.072-0.45511111-4.55111111-0.45511112-0.68266667 0-1.70666667 0.22755555-1.93422222-0.91022222h-32.768c-0.45511111 0.79644445-1.25155555 0.34133333-1.82044445 0.34133334-15.13244445 0-30.26488889-0.11377778-45.39733333 0.11377778-5.46133333 0-10.80888889 1.024-15.58755555 3.98222222-4.66488889 2.84444445-7.28177778 7.05422222-8.7608889 12.17422222-0.22755555 1.024 0 2.16177778-0.68266666 2.95822222v85.90222222c1.13777778 0.22755555 0.79644445 1.25155555 0.91022222 1.93422222 0.79644445 4.66488889 2.048 8.98844445 5.23377778 12.51555556 4.20977778 4.66488889 9.78488889 6.59911111 15.81511111 6.71288889 27.648 0.11377778 55.40977778 0.11377778 83.05777778 0 3.52711111 0 6.94044445-0.34133333 10.35377777-1.47911111 8.98844445-2.84444445 14.44977778-10.12622222 14.44977778-19.56977778v-81.80622222c0.11377778-2.27555555-0.22755555-4.55111111-0.79644444-6.82666667z" fill="#707070" p-id="10120"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/question.svg b/src/assets/icons/svg/question.svg new file mode 100644 index 0000000..cf75bd4 --- /dev/null +++ b/src/assets/icons/svg/question.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/radio.svg b/src/assets/icons/svg/radio.svg new file mode 100644 index 0000000..0cde345 --- /dev/null +++ b/src/assets/icons/svg/radio.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/rate.svg b/src/assets/icons/svg/rate.svg new file mode 100644 index 0000000..aa3b14d --- /dev/null +++ b/src/assets/icons/svg/rate.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/receiver.svg b/src/assets/icons/svg/receiver.svg new file mode 100644 index 0000000..065135e --- /dev/null +++ b/src/assets/icons/svg/receiver.svg @@ -0,0 +1 @@ +<?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="1646632360065" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="26932" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M873.691429 0c42.496 0 76.507429 34.706286 77.165714 76.617143v455.021714l-333.677714-1.097143a87.771429 87.771429 0 0 0-88.027429 86.637715L523.776 1024H149.650286A76.653714 76.653714 0 0 1 73.142857 947.382857V76.617143C73.142857 34.706286 107.154286 0 149.650286 0H873.691429z m-113.152 425.764571c0-21.942857-17.115429-40.594286-37.485715-40.594285H257.572571c-20.406857 0-37.485714 17.956571-37.485714 40.594285 0 21.942857 17.078857 40.594286 37.485714 40.594286H723.017143c21.028571 0 37.485714-17.956571 37.485714-40.594286zM256.914286 538.916571c-20.406857 0-37.485714 17.956571-37.485715 40.594286 0 21.942857 17.078857 40.594286 37.485715 40.594286h183.405714c20.406857 0 37.485714-17.956571 37.485714-40.594286 0-21.942857-17.078857-40.594286-37.485714-40.594286H256.914286z m0.658285-238.299428H723.017143c20.370286 0 37.485714-17.956571 37.485714-40.594286 0-21.942857-17.115429-40.594286-37.485714-40.594286H257.572571c-20.406857 0-37.485714 17.956571-37.485714 40.594286 0 22.637714 17.078857 40.594286 37.485714 40.594286z" p-id="26933"></path><path d="M826.514286 786.285714h85.686857a36.571429 36.571429 0 0 1 28.745143 59.172572l-125.915429 160.219428a36.571429 36.571429 0 0 1-57.490286 0l-125.915428-160.219428a36.571429 36.571429 0 0 1 28.745143-59.172572H753.371429v-182.857143a36.571429 36.571429 0 0 1 73.142857 0v182.857143z" p-id="26934"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/redis-list.svg b/src/assets/icons/svg/redis-list.svg new file mode 100644 index 0000000..98a15b2 --- /dev/null +++ b/src/assets/icons/svg/redis-list.svg @@ -0,0 +1,2 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/redis.svg b/src/assets/icons/svg/redis.svg new file mode 100644 index 0000000..2f1d62d --- /dev/null +++ b/src/assets/icons/svg/redis.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/row.svg b/src/assets/icons/svg/row.svg new file mode 100644 index 0000000..0780992 --- /dev/null +++ b/src/assets/icons/svg/row.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/scene.svg b/src/assets/icons/svg/scene.svg new file mode 100644 index 0000000..af2d628 --- /dev/null +++ b/src/assets/icons/svg/scene.svg @@ -0,0 +1 @@ +<?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="1642068336205" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13189" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M837.7 897H211.3c-32.2 0-58.4-26.2-58.4-58.4V468.9c0-32.2 26.2-58.4 58.4-58.4h626.4c32.2 0 58.4 26.2 58.4 58.4v369.6c0 32.3-26.2 58.5-58.4 58.5zM211.3 453.2c-8.7 0-15.8 7.1-15.8 15.8v369.6c0 8.7 7.1 15.7 15.8 15.7h626.4c8.5 0 15.8-7.2 15.8-15.7V468.9c0-8.5-7.2-15.8-15.8-15.8H211.3z" fill="#cdcdcd" p-id="13190"></path><path d="M187.1 441.5c-17.7 0-33.7-12.2-37.8-30.1l-20.5-90.9c-4.7-20.8 8.5-41.5 29.3-46.2L807.7 128c9.9-2.3 20.3-0.5 29.1 5s14.8 14.1 17.1 24.2l20.5 90.9c2.3 10 0.5 20.3-5 29.1s-14.1 14.9-24.2 17.1L195.5 440.6c-2.8 0.6-5.6 0.9-8.4 0.9zM171.3 315l18.7 83.1 642.9-144.8-19.8-82.8L171.3 315zM185.7 578.5h677.6v42.7H185.7z" fill="#cdcdcd" p-id="13191"></path><path d="M302.204 579.604l169.35-169.35 30.193 30.193-169.35 169.35zM585.716 588.968l174.796-174.795 30.193 30.194L615.91 619.162z" fill="#cdcdcd" p-id="13192"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/search.svg b/src/assets/icons/svg/search.svg new file mode 100644 index 0000000..84233dd --- /dev/null +++ b/src/assets/icons/svg/search.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/select.svg b/src/assets/icons/svg/select.svg new file mode 100644 index 0000000..d628382 --- /dev/null +++ b/src/assets/icons/svg/select.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/server.svg b/src/assets/icons/svg/server.svg new file mode 100644 index 0000000..ca37b00 --- /dev/null +++ b/src/assets/icons/svg/server.svg @@ -0,0 +1 @@ +<?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" fill="#bfbfbf" p-id="6718"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/share.svg b/src/assets/icons/svg/share.svg new file mode 100644 index 0000000..6e6ea34 --- /dev/null +++ b/src/assets/icons/svg/share.svg @@ -0,0 +1,2 @@ +<?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="1654884749180" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12269" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><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="M569.979 703.801c-29.354 0-49.096 19.741-49.096 49.094 0 29.356 19.741 49.092 49.096 49.092s49.096-19.735 49.097-49.092C619.075 723.542 599.334 703.801 569.979 703.801zM308.003 508.892c-29.353 0-49.099 19.741-49.099 49.098 0 29.349 19.746 49.097 49.099 49.097 29.354 0 49.097-19.748 49.097-49.097C357.1 528.633 337.357 508.892 308.003 508.892zM749.263 180.695 119.553 180.695c-19.667 0-35.55 6.997-47.654 20.988-12.103 13.995-18.151 31.958-18.151 53.896l0 637.652c0 20.424 7.186 38.196 21.559 53.321 14.37 15.134 30.634 22.697 48.785 22.697L758.34 969.249c21.183 0 38.954-7.374 53.329-22.128 14.37-14.748 21.555-30.821 21.555-48.222l0-626.3c0-27.235-6.616-49.358-19.855-66.379C800.135 189.207 778.766 180.695 749.263 180.695zM569.955 859.316c-58.713 0-106.455-43.612-106.455-102.32 0-9.874 1.78-19.24 4.311-28.342l-104.07-77.413c-16.686 10.855-34.451 13.171-55.794 13.171-58.706 0-106.446-47.745-106.446-106.451 0-58.708 47.74-106.449 106.446-106.449 29.063 0 53.316 7.632 72.562 26.584l87.943-53.995c-3.723-10.86-6.2-18.201-6.2-30.311 0-58.706 47.747-106.448 106.454-106.448 58.705 0 106.445 47.742 106.445 106.448 0 58.709-47.741 106.452-106.445 106.452-27.308 0-49.938-6.492-68.811-23.469l-90.259 53.396c2.819 9.525 4.787 19.423 4.787 29.886 0 17.532-0.554 29.723-8.086 44.329l89.915 69.788c19.316-19.613 44.085-27.723 73.727-27.723 58.733 0 106.424 47.711 106.422 106.42C676.4 811.575 628.655 859.316 569.955 859.316zM941.673 82.851c-19.289-21.182-61.434-31.77-93.204-31.77L326.147 51.081c-17.399 0-32.336 6.048-44.818 18.152-12.479 12.102-18.719 26.855-18.719 44.25l0 10.215 519.925 0c46.896 0 69.1 1.773 88.766 19.168 19.668 17.399 21.192 34.811 21.192 77.172l-0.001 608.252 14.575 0c17.399 0 32.338-6.056 44.817-18.158 12.482-12.096 18.721-26.852 18.721-44.244L970.605 170.702C970.605 143.473 960.965 104.032 941.673 82.851zM568.727 442.89c29.355 0 49.097-19.746 49.097-49.1 0-29.351-19.74-49.096-49.097-49.096-29.348 0-49.096 19.745-49.096 49.096C519.631 423.144 539.379 442.89 568.727 442.89z" p-id="12270" fill="#67C23A"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/shopping.svg b/src/assets/icons/svg/shopping.svg new file mode 100644 index 0000000..87513e7 --- /dev/null +++ b/src/assets/icons/svg/shopping.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/size.svg b/src/assets/icons/svg/size.svg new file mode 100644 index 0000000..ddb25b8 --- /dev/null +++ b/src/assets/icons/svg/size.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/skill.svg b/src/assets/icons/svg/skill.svg new file mode 100644 index 0000000..a3b7312 --- /dev/null +++ b/src/assets/icons/svg/skill.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/slider.svg b/src/assets/icons/svg/slider.svg new file mode 100644 index 0000000..fbe4f39 --- /dev/null +++ b/src/assets/icons/svg/slider.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/small.svg b/src/assets/icons/svg/small.svg new file mode 100644 index 0000000..a27b800 --- /dev/null +++ b/src/assets/icons/svg/small.svg @@ -0,0 +1 @@ +<?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="1676963891061" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="18978" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M877.1 950.7H148.9c-41.2 0-74.8-33.5-74.8-74.8V147.6c0-41.2 33.5-74.8 74.8-74.8h728.3c41.2 0 74.8 33.5 74.8 74.8v728.3c-0.1 41.3-33.6 74.8-74.9 74.8zM148.9 118.4c-16.1 0-29.3 13.1-29.3 29.3V876c0 16.1 13.1 29.3 29.3 29.3h728.3c16.1 0 29.3-13.1 29.3-29.3V147.6c0-16.1-13.1-29.3-29.3-29.3H148.9z" fill="#1890ff" p-id="18979"></path><path d="M740.6 534.6H285.4c-12.6 0-22.8-10.2-22.8-22.8s10.2-22.8 22.8-22.8h455.2c12.6 0 22.8 10.2 22.8 22.8s-10.2 22.8-22.8 22.8z" fill="#1890ff" p-id="18980"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/star.svg b/src/assets/icons/svg/star.svg new file mode 100644 index 0000000..6cf86e6 --- /dev/null +++ b/src/assets/icons/svg/star.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/start.svg b/src/assets/icons/svg/start.svg new file mode 100644 index 0000000..f7e58a5 --- /dev/null +++ b/src/assets/icons/svg/start.svg @@ -0,0 +1 @@ +<?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="1646372713608" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13016" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M512 960c-247.424 0-448-200.512-448-448s200.576-448 448-448c247.488 0 448 200.512 448 448s-200.512 448-448 448zM512 138.88v-0.256C297.92 138.688 138.88 306.304 138.88 512S306.304 885.12 512 885.12s373.12-167.36 373.12-373.12S717.76 138.88 512 138.88z m-66.048 554.816a26.88 26.88 0 0 1-30.336 0.832 35.456 35.456 0 0 1-15.424-29.952V321.984c0-12.416 5.888-23.872 15.424-29.952a26.88 26.88 0 0 1 30.4 0.896l238.912 171.328c8.64 6.272 13.952 17.28 13.952 29.056s-5.312 22.784-14.016 28.992l-238.912 171.392z" p-id="13017"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/stop.svg b/src/assets/icons/svg/stop.svg new file mode 100644 index 0000000..7f99ac3 --- /dev/null +++ b/src/assets/icons/svg/stop.svg @@ -0,0 +1 @@ +<?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="1646372672996" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11831" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M512 928.3c-229.2 0-415-185.8-415-415s185.8-415 415-415 415 185.8 415 415-185.8 415-415 415z m0.4-77.5c186.2 0 337.2-151 337.2-337.2s-151-337.2-337.2-337.2-337.2 151-337.2 337.2 150.9 337.2 337.2 337.2zM382.3 357.6h259.4c14.3 0 25.9 11.6 25.9 25.9V643c0 14.3-11.6 25.9-25.9 25.9H382.3c-14.3 0-25.9-11.6-25.9-25.9V383.6c0-14.4 11.6-26 25.9-26z" p-id="11832"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/subscribe.svg b/src/assets/icons/svg/subscribe.svg new file mode 100644 index 0000000..9c48bdc --- /dev/null +++ b/src/assets/icons/svg/subscribe.svg @@ -0,0 +1 @@ +<?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="1646631091457" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12792" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M228.9 960.4c-24.9 0-49.7-7.4-70.8-21.9-34.1-23.4-54.5-62.1-54.5-103.5V191.4C103.6 122.3 159.8 66 229 66h566.7c69.1 0 125.4 56.2 125.4 125.4V835c0 41.4-20.4 80.1-54.5 103.4-34.1 23.4-77.6 28.4-116.2 13.4l-225-87.4c-8.4-3.3-17.6-3.3-26 0l-225 87.4c-14.8 5.8-30.2 8.6-45.5 8.6z m553.7-91.9c11.2 4.4 23.4 3 33.3-3.8 9.9-6.8 15.6-17.6 15.6-29.6V191.4c0-19.8-16.1-35.9-35.9-35.9H228.9c-19.8 0-35.9 16.1-35.9 35.9V835c0 12 5.7 22.9 15.6 29.6 10 6.8 22.1 8.2 33.3 3.9l225-87.4c29.2-11.4 61.5-11.4 90.7 0l225 87.4z" fill="#cccccc" p-id="12793"></path><path d="M658.6 498.7H374.5c-24.7 0-44.7-20-44.7-44.7 0-24.7 20-44.7 44.7-44.7h284.1c24.7 0 44.7 20 44.7 44.7 0 24.7-20 44.7-44.7 44.7z" fill="#cccccc" p-id="12794"></path><path d="M516.5 640.8c-24.7 0-44.7-20-44.7-44.7V311.9c0-24.7 20-44.7 44.7-44.7 24.7 0 44.7 20 44.7 44.7V596c0 24.7-20 44.8-44.7 44.8z" fill="#cccccc" p-id="12795"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/subscribe1.svg b/src/assets/icons/svg/subscribe1.svg new file mode 100644 index 0000000..a77b7c7 --- /dev/null +++ b/src/assets/icons/svg/subscribe1.svg @@ -0,0 +1 @@ +<?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="1646632203646" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="25228" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M136.5 110.9c21.2-25.3 53.7-40.7 86.7-41h557.1c14.4-0.3 28.8 2.1 42.3 7 26.7 9.6 49.5 29.5 62.7 54.6 9.1 16.9 13.6 36.1 13.6 55.2v397c-18.6-9.8-36.4-21-55.7-29.3-27.3-11.6-56.9-17.9-86.5-18.4-34-0.6-68.1 6.3-99.1 20.2-31.4 14.1-59.6 35.3-81.9 61.5-20.6 24.1-36.2 52.5-45.4 82.9-16.3 53-12.7 111.8 10.1 162.4 8.1 17.9 18.3 34.8 30.6 50.2 10.7 13.2 21.5 26.3 32.2 39.6h-376c-12.3 0.2-24.7-1.5-36.5-5.1-25.3-7.7-47.7-24.5-62.3-46.5-12-17.8-18.8-39.1-19.4-60.6v-653c-0.6-27.9 9.5-55.6 27.5-76.7m176.3 114.7c-10.3 2.2-18.3 12.1-18 22.7-0.4 11.9 9.7 22.9 21.6 23.3h374.9c6.2-0.1 12.2-3.3 16.3-7.9 6.4-7.2 7.5-18.5 2.7-26.8-4-7.3-12.2-12-20.5-11.9H319c-2.1 0-4.2 0.2-6.2 0.6m-0.9 161.5c-4.9 1.3-9.3 4.3-12.3 8.3-6.4 8.1-6.3 20.6 0.2 28.7 4.5 5.8 11.9 9.1 19.2 8.9h370.8c6.3 0 12.5-2.5 16.9-7 7.2-7.1 8.7-19 3.8-27.7-3.7-6.9-11.2-11.7-19.1-11.9H316.5c-1.6 0-3.2 0.2-4.6 0.7m2.3 160.5c-10.1 0.8-18.7 9.5-19.3 19.6-0.1 4.6-0.4 9.4 1.5 13.7 3.2 8 11.5 13.5 20.1 13.4h143.3c9.6 0 18.7-7.3 20.6-16.8 2.5-11.3-4-23.6-14.6-27.9-5.5-2.6-11.7-1.9-17.6-1.9-44.7-0.2-89.4-0.2-134-0.1m-2.3 161.9c-6.2 1.7-11.6 6.1-14.5 11.8-3.6 6.8-3.4 15.5 0.4 22.2 3.9 7 11.5 11.7 19.5 11.8h94.2c6.2 0 12.4-2.7 16.6-7.3 7-7.1 8.4-18.9 3.4-27.5-3.9-7.1-11.9-11.9-20-11.8h-88.2c-3.9 0-7.8-0.3-11.4 0.8z" p-id="25229"></path><path d="M747.3 559.2c47.5-1.4 95.3 14.1 132.9 43.2 25.6 19.6 46.5 45.2 60.6 74.2 16.1 32.8 23.1 69.9 20.6 106.3-2.1 31.6-11.6 62.7-27.6 90.1-16.1 27.8-38.7 51.8-65.4 69.5-24.8 16.5-53.3 27.6-82.8 32.2-39 6.2-79.7 1.2-115.9-14.6-27.8-12-52.9-30.2-73-52.8-24.2-27.1-41.2-60.6-48.6-96.2-7.1-34.2-5.7-70.2 4.5-103.6 8.1-26.9 21.8-52.1 39.8-73.7 19.9-23.7 45-43 73.1-55.9 25.6-11.5 53.7-17.9 81.8-18.7m88 133c-31.3 34.5-62.6 68.9-93.8 103.5-24.5-22-48.8-44.2-73.3-66.3-4.2-3.6-9.8-5.7-15.3-5.5-8.5-0.1-16.8 5.1-20.5 12.7-4.7 9-2.6 21 5.1 27.7 28.5 25.8 57 51.7 85.5 77.5 3.1 2.7 6 5.9 9.9 7.7 6.7 3.2 15.1 3 21.5-0.8 4.2-2.2 7.1-6.1 10.3-9.6l101.4-111.9c2.5-2.8 5.4-5.5 6.9-9.1 4.3-8.7 2.4-20-4.6-26.6-8.5-9-24.7-8.7-33.1 0.7z" p-id="25230"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/swagger.svg b/src/assets/icons/svg/swagger.svg new file mode 100644 index 0000000..05d4e7b --- /dev/null +++ b/src/assets/icons/svg/swagger.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/switch.svg b/src/assets/icons/svg/switch.svg new file mode 100644 index 0000000..0ba61e3 --- /dev/null +++ b/src/assets/icons/svg/switch.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/system.svg b/src/assets/icons/svg/system.svg new file mode 100644 index 0000000..dba28cf --- /dev/null +++ b/src/assets/icons/svg/system.svg @@ -0,0 +1,2 @@ +<?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" fill="#bfbfbf"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/tab.svg b/src/assets/icons/svg/tab.svg new file mode 100644 index 0000000..b4b48e4 --- /dev/null +++ b/src/assets/icons/svg/tab.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/table.svg b/src/assets/icons/svg/table.svg new file mode 100644 index 0000000..0e3dc9d --- /dev/null +++ b/src/assets/icons/svg/table.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/textarea.svg b/src/assets/icons/svg/textarea.svg new file mode 100644 index 0000000..2709f29 --- /dev/null +++ b/src/assets/icons/svg/textarea.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/theme.svg b/src/assets/icons/svg/theme.svg new file mode 100644 index 0000000..5982a2f --- /dev/null +++ b/src/assets/icons/svg/theme.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/time-range.svg b/src/assets/icons/svg/time-range.svg new file mode 100644 index 0000000..13c1202 --- /dev/null +++ b/src/assets/icons/svg/time-range.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/time.svg b/src/assets/icons/svg/time.svg new file mode 100644 index 0000000..b376e32 --- /dev/null +++ b/src/assets/icons/svg/time.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/tool.svg b/src/assets/icons/svg/tool.svg new file mode 100644 index 0000000..c813067 --- /dev/null +++ b/src/assets/icons/svg/tool.svg @@ -0,0 +1 @@ +<?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" fill="#bfbfbf"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/topic.svg b/src/assets/icons/svg/topic.svg new file mode 100644 index 0000000..f757e1c --- /dev/null +++ b/src/assets/icons/svg/topic.svg @@ -0,0 +1 @@ +<?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="1646374389806" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="27033" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M477.866667 308.309333a44.117333 44.117333 0 0 0-51.072 35.797334l-7.552 42.666666H368.554667a44.117333 44.117333 0 0 0 0 88.32h35.157333l-12.416 70.4H329.770667a44.117333 44.117333 0 0 0 0 88.192h45.952l-5.461334 30.890667a44.117333 44.117333 0 1 0 86.912 15.36l8.149334-46.250667h46.165333l-5.461333 30.890667a44.117333 44.117333 0 1 0 86.912 15.36l8.106666-46.250667h54.186667a44.117333 44.117333 0 0 0 0-88.234666h-38.570667l12.373334-70.4h64.938666a44.117333 44.117333 0 0 0 0-88.234667h-49.365333l4.821333-27.392a44.117333 44.117333 0 1 0-86.869333-15.36l-7.552 42.752h-46.165333l4.864-27.392a44.117333 44.117333 0 0 0-35.84-51.114667z m2.986666 237.141334l12.458667-70.4h46.122667l-12.373334 70.4H480.853333z" p-id="27034"></path><path d="M512 80C273.408 80 80 273.408 80 512a430.805333 430.805333 0 0 0 65.877333 229.418667 281.813333 281.813333 0 0 1-2.816 16.170666c-4.096 20.693333-11.605333 51.2-22.698666 91.861334a44.117333 44.117333 0 0 0 54.186666 54.186666 1453.226667 1453.226667 0 0 1 91.861334-22.698666c6.869333-1.365333 12.202667-2.261333 16.213333-2.816A430.848 430.848 0 0 0 512 944c238.506667 0 431.957333-193.408 431.957333-432S750.592 80 512 80zM168.234667 512a343.765333 343.765333 0 1 1 152.789333 285.866667 53.162667 53.162667 0 0 0-25.386667-8.405334 94.293333 94.293333 0 0 0-14.976 0.128c-8.96 0.725333-19.669333 2.432-31.445333 4.778667-7.466667 1.493333-15.786667 3.328-25.045333 5.461333 2.133333-9.216 3.968-17.578667 5.461333-25.045333 2.346667-11.776 4.053333-22.485333 4.778667-31.445333 0.384-4.394667 0.597333-9.642667 0.128-14.976a53.12 53.12 0 0 0-8.405334-25.386667A342.741333 342.741333 0 0 1 168.234667 512z" p-id="27035"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/tree-table.svg b/src/assets/icons/svg/tree-table.svg new file mode 100644 index 0000000..8aafdb8 --- /dev/null +++ b/src/assets/icons/svg/tree-table.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/tree.svg b/src/assets/icons/svg/tree.svg new file mode 100644 index 0000000..dd4b7dd --- /dev/null +++ b/src/assets/icons/svg/tree.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/upload.svg b/src/assets/icons/svg/upload.svg new file mode 100644 index 0000000..bae49c0 --- /dev/null +++ b/src/assets/icons/svg/upload.svg @@ -0,0 +1 @@ +<?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> \ No newline at end of file diff --git a/src/assets/icons/svg/user.svg b/src/assets/icons/svg/user.svg new file mode 100644 index 0000000..0ba0716 --- /dev/null +++ b/src/assets/icons/svg/user.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/validCode.svg b/src/assets/icons/svg/validCode.svg new file mode 100644 index 0000000..9c98305 --- /dev/null +++ b/src/assets/icons/svg/validCode.svg @@ -0,0 +1 @@ +<?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="#999" 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="#999" p-id="1941"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/video.svg b/src/assets/icons/svg/video.svg new file mode 100644 index 0000000..cd1a23b --- /dev/null +++ b/src/assets/icons/svg/video.svg @@ -0,0 +1 @@ +<?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="1694102575985" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4034" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M937.6 326.4c-20.8-28.8-60.8-35.2-89.6-16l-64 44.8V352c0-88-72-160-160-160H240C152 192 80 264 80 352v320c0 88 72 160 160 160h384c84.8 0 153.6-65.6 160-147.2l65.6 44.8c11.2 8 24 11.2 36.8 11.2 35.2 0 64-28.8 64-64V363.2c-1.6-12.8-4.8-25.6-12.8-36.8zM720 672c0 52.8-43.2 96-96 96H240c-52.8 0-96-43.2-96-96V352c0-52.8 43.2-96 96-96h384c52.8 0 96 43.2 96 96v320z m164.8 4.8L784 606.4V433.6l100.8-70.4v313.6z" fill="#cdcdcd" p-id="4035"></path><path d="M288 400m-48 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0Z" fill="#cdcdcd" p-id="4036"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/videotape.svg b/src/assets/icons/svg/videotape.svg new file mode 100644 index 0000000..7fad5a0 --- /dev/null +++ b/src/assets/icons/svg/videotape.svg @@ -0,0 +1 @@ +<?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="1695808416395" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6545" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M760.3712 954.624H274.1248c-107.264 0-194.2016-86.9376-194.2016-194.2016V274.1248c0-107.264 86.9376-194.2016 194.2016-194.2016h486.2464c107.264 0 194.2016 86.9376 194.2016 194.2016v486.2464c0.0512 107.264-86.9376 194.2528-194.2016 194.2528z" fill="#6FA7FF" p-id="6546"></path><path d="M830.208 346.2656c-17.7664-10.24-38.912-10.24-56.6784 0l-52.6848 30.4128v-8.6528c0-66.048-53.7088-119.7568-119.7568-119.7568H311.2448c-66.048 0-119.7568 53.7088-119.7568 119.7568v300.1856c0 66.048 53.7088 119.7568 119.7568 119.7568h172.6464c14.1312 0 25.6-11.4688 25.6-25.6s-11.4688-25.6-25.6-25.6H311.2448c-37.7856 0-68.5568-30.7712-68.5568-68.5568V368.0256c0-37.7856 30.7712-68.5568 68.5568-68.5568h289.8944c37.7856 0 68.5568 30.7712 68.5568 68.5568v300.1856c0 37.7856-30.7712 68.5568-68.5568 68.5568-14.1312 0-25.6 11.4688-25.6 25.6s11.4688 25.6 25.6 25.6c66.048 0 119.7568-53.7088 119.7568-119.7568v-8.6528l52.6848 30.4128c8.8576 5.12 18.5856 7.68 28.3136 7.68 9.728 0 19.456-2.56 28.3136-7.68 17.7152-10.24 28.3136-28.5696 28.3136-49.1008V395.3664c0.0512-20.48-10.5472-38.8608-28.3136-49.1008z m-22.8352 294.6048c0 2.6112-1.4848 3.9936-2.7136 4.7104-1.2288 0.7168-3.2256 1.3312-5.4784 0l-78.2848-45.2096V435.8144l78.2848-45.2096c2.2528-1.28 4.1984-0.7168 5.4784 0 1.2288 0.7168 2.7136 2.1504 2.7136 4.7104v245.5552z" fill="#F7F8F8" p-id="6547"></path><path d="M323.0208 363.6224c-14.1312 0-25.6 11.4688-25.6 25.6s11.4688 25.6 25.6 25.6H425.984c14.1312 0 25.6-11.4688 25.6-25.6s-11.4688-25.6-25.6-25.6H323.0208z" fill="#F7F8F8" p-id="6548"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/wechat.svg b/src/assets/icons/svg/wechat.svg new file mode 100644 index 0000000..c586e55 --- /dev/null +++ b/src/assets/icons/svg/wechat.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svg/wifi_0.svg b/src/assets/icons/svg/wifi_0.svg new file mode 100644 index 0000000..92af048 --- /dev/null +++ b/src/assets/icons/svg/wifi_0.svg @@ -0,0 +1 @@ +<?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="1622135369729" class="icon" viewBox="0 0 1122 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19568" xmlns:xlink="http://www.w3.org/1999/xlink" width="219.140625" height="200"><defs><style type="text/css"></style></defs><path d="M561.152 910.336c-7.68 0-25.088-13.824-53.248-41.984-27.648-28.16-41.472-45.568-41.472-53.248 0-12.288 11.776-22.528 35.84-30.72s43.52-12.8 59.392-12.8c15.872 0 35.328 4.096 59.392 12.8s35.84 18.432 35.84 30.72c0 7.68-13.824 25.6-41.472 53.248-29.184 28.16-46.592 41.984-54.272 41.984z" fill="#e6e6e6" p-id="19569" data-spm-anchor-id="a313x.7781069.0.i63" class="selected"></path><path d="M715.264 755.712c-0.512 0-8.192-4.608-23.04-14.336-14.336-9.728-33.792-18.944-57.856-28.672-24.064-9.728-48.64-14.336-73.216-14.336-24.576 0-49.152 4.608-73.216 14.336-24.064 9.728-43.52 18.944-57.856 28.672-14.336 9.728-22.016 14.336-23.04 14.336-6.656 0-24.576-14.336-53.248-43.008s-43.008-46.08-43.008-53.248c0-5.12 2.048-9.216 5.632-13.312 29.696-29.184 67.072-52.224 112.128-69.12s89.088-25.088 133.12-25.088c44.032 0 88.064 8.192 133.12 25.088 45.056 16.896 82.432 39.936 112.128 69.12 3.584 3.584 5.632 8.192 5.632 13.312 0 6.656-14.336 24.576-43.008 53.248-29.696 28.672-47.104 43.008-54.272 43.008z" fill="#e6e6e6" p-id="19570" data-spm-anchor-id="a313x.7781069.0.i64" class="selected"></path><path d="M871.424 600.064c-4.096 0-8.704-1.536-13.312-4.608-51.712-39.936-99.84-69.632-143.872-88.064s-95.232-28.16-153.088-28.16c-32.256 0-65.024 4.096-97.28 12.8S402.944 510.464 378.88 522.24c-24.064 11.776-45.568 23.552-65.024 35.328s-34.304 22.016-45.056 30.208c-11.264 8.192-16.896 12.8-17.92 12.8-6.656 0-24.064-14.336-52.736-43.008s-43.008-46.08-43.008-53.248c0-4.608 2.048-8.704 5.632-12.8 50.176-50.176 111.104-89.088 182.784-117.248 71.68-27.648 143.872-41.472 217.088-41.472s145.408 13.824 217.088 41.472c71.68 27.648 132.608 67.072 182.784 117.248 3.584 3.584 5.632 8.192 5.632 12.8 0 6.656-14.336 24.576-43.008 53.248s-45.056 42.496-51.712 42.496z" fill="#e6e6e6" p-id="19571" data-spm-anchor-id="a313x.7781069.0.i65" class="selected"></path><path d="M1026.048 445.44c-4.096 0-8.192-1.536-12.8-5.12-68.096-59.904-138.752-104.96-212.48-135.168-73.216-30.208-153.6-45.568-240.128-45.568-87.04 0-166.912 15.36-240.128 45.568S176.64 380.416 108.544 440.32c-4.096 3.584-8.192 5.12-12.8 5.12-6.656 0-24.064-14.336-52.736-43.008S0 356.352 0 349.184c0-5.12 2.048-9.216 5.632-13.312C76.8 265.216 161.792 210.432 260.096 171.52s198.656-58.368 301.056-58.368 202.752 19.456 301.056 58.368 183.296 93.696 254.464 164.352c3.584 3.584 5.632 8.192 5.632 13.312 0 6.656-14.336 24.576-43.008 53.248-28.672 28.672-46.592 43.008-53.248 43.008z" fill="#e6e6e6" p-id="19572" data-spm-anchor-id="a313x.7781069.0.i66" class="selected"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/wifi_1.svg b/src/assets/icons/svg/wifi_1.svg new file mode 100644 index 0000000..e78ac9a --- /dev/null +++ b/src/assets/icons/svg/wifi_1.svg @@ -0,0 +1 @@ +<?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="1622135369729" class="icon" viewBox="0 0 1122 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19568" xmlns:xlink="http://www.w3.org/1999/xlink" width="219.140625" height="200"><defs><style type="text/css"></style></defs><path d="M561.152 910.336c-7.68 0-25.088-13.824-53.248-41.984-27.648-28.16-41.472-45.568-41.472-53.248 0-12.288 11.776-22.528 35.84-30.72s43.52-12.8 59.392-12.8c15.872 0 35.328 4.096 59.392 12.8s35.84 18.432 35.84 30.72c0 7.68-13.824 25.6-41.472 53.248-29.184 28.16-46.592 41.984-54.272 41.984z" fill="#409EFF" p-id="19569" data-spm-anchor-id="a313x.7781069.0.i63" class="selected"></path><path d="M715.264 755.712c-0.512 0-8.192-4.608-23.04-14.336-14.336-9.728-33.792-18.944-57.856-28.672-24.064-9.728-48.64-14.336-73.216-14.336-24.576 0-49.152 4.608-73.216 14.336-24.064 9.728-43.52 18.944-57.856 28.672-14.336 9.728-22.016 14.336-23.04 14.336-6.656 0-24.576-14.336-53.248-43.008s-43.008-46.08-43.008-53.248c0-5.12 2.048-9.216 5.632-13.312 29.696-29.184 67.072-52.224 112.128-69.12s89.088-25.088 133.12-25.088c44.032 0 88.064 8.192 133.12 25.088 45.056 16.896 82.432 39.936 112.128 69.12 3.584 3.584 5.632 8.192 5.632 13.312 0 6.656-14.336 24.576-43.008 53.248-29.696 28.672-47.104 43.008-54.272 43.008z" fill="#e6e6e6" p-id="19570" data-spm-anchor-id="a313x.7781069.0.i64" class=""></path><path d="M871.424 600.064c-4.096 0-8.704-1.536-13.312-4.608-51.712-39.936-99.84-69.632-143.872-88.064s-95.232-28.16-153.088-28.16c-32.256 0-65.024 4.096-97.28 12.8S402.944 510.464 378.88 522.24c-24.064 11.776-45.568 23.552-65.024 35.328s-34.304 22.016-45.056 30.208c-11.264 8.192-16.896 12.8-17.92 12.8-6.656 0-24.064-14.336-52.736-43.008s-43.008-46.08-43.008-53.248c0-4.608 2.048-8.704 5.632-12.8 50.176-50.176 111.104-89.088 182.784-117.248 71.68-27.648 143.872-41.472 217.088-41.472s145.408 13.824 217.088 41.472c71.68 27.648 132.608 67.072 182.784 117.248 3.584 3.584 5.632 8.192 5.632 12.8 0 6.656-14.336 24.576-43.008 53.248s-45.056 42.496-51.712 42.496z" fill="#e6e6e6" p-id="19571" data-spm-anchor-id="a313x.7781069.0.i65" class=""></path><path d="M1026.048 445.44c-4.096 0-8.192-1.536-12.8-5.12-68.096-59.904-138.752-104.96-212.48-135.168-73.216-30.208-153.6-45.568-240.128-45.568-87.04 0-166.912 15.36-240.128 45.568S176.64 380.416 108.544 440.32c-4.096 3.584-8.192 5.12-12.8 5.12-6.656 0-24.064-14.336-52.736-43.008S0 356.352 0 349.184c0-5.12 2.048-9.216 5.632-13.312C76.8 265.216 161.792 210.432 260.096 171.52s198.656-58.368 301.056-58.368 202.752 19.456 301.056 58.368 183.296 93.696 254.464 164.352c3.584 3.584 5.632 8.192 5.632 13.312 0 6.656-14.336 24.576-43.008 53.248-28.672 28.672-46.592 43.008-53.248 43.008z" fill="#e6e6e6" p-id="19572" data-spm-anchor-id="a313x.7781069.0.i66" class=""></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/wifi_2.svg b/src/assets/icons/svg/wifi_2.svg new file mode 100644 index 0000000..4cf889b --- /dev/null +++ b/src/assets/icons/svg/wifi_2.svg @@ -0,0 +1 @@ +<?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="1622135369729" class="icon" viewBox="0 0 1122 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19568" xmlns:xlink="http://www.w3.org/1999/xlink" width="219.140625" height="200"><defs><style type="text/css"></style></defs><path d="M561.152 910.336c-7.68 0-25.088-13.824-53.248-41.984-27.648-28.16-41.472-45.568-41.472-53.248 0-12.288 11.776-22.528 35.84-30.72s43.52-12.8 59.392-12.8c15.872 0 35.328 4.096 59.392 12.8s35.84 18.432 35.84 30.72c0 7.68-13.824 25.6-41.472 53.248-29.184 28.16-46.592 41.984-54.272 41.984z" fill="#409EFF" p-id="19569" data-spm-anchor-id="a313x.7781069.0.i63" class="selected"></path><path d="M715.264 755.712c-0.512 0-8.192-4.608-23.04-14.336-14.336-9.728-33.792-18.944-57.856-28.672-24.064-9.728-48.64-14.336-73.216-14.336-24.576 0-49.152 4.608-73.216 14.336-24.064 9.728-43.52 18.944-57.856 28.672-14.336 9.728-22.016 14.336-23.04 14.336-6.656 0-24.576-14.336-53.248-43.008s-43.008-46.08-43.008-53.248c0-5.12 2.048-9.216 5.632-13.312 29.696-29.184 67.072-52.224 112.128-69.12s89.088-25.088 133.12-25.088c44.032 0 88.064 8.192 133.12 25.088 45.056 16.896 82.432 39.936 112.128 69.12 3.584 3.584 5.632 8.192 5.632 13.312 0 6.656-14.336 24.576-43.008 53.248-29.696 28.672-47.104 43.008-54.272 43.008z" fill="#409EFF" p-id="19570" data-spm-anchor-id="a313x.7781069.0.i64" class="selected"></path><path d="M871.424 600.064c-4.096 0-8.704-1.536-13.312-4.608-51.712-39.936-99.84-69.632-143.872-88.064s-95.232-28.16-153.088-28.16c-32.256 0-65.024 4.096-97.28 12.8S402.944 510.464 378.88 522.24c-24.064 11.776-45.568 23.552-65.024 35.328s-34.304 22.016-45.056 30.208c-11.264 8.192-16.896 12.8-17.92 12.8-6.656 0-24.064-14.336-52.736-43.008s-43.008-46.08-43.008-53.248c0-4.608 2.048-8.704 5.632-12.8 50.176-50.176 111.104-89.088 182.784-117.248 71.68-27.648 143.872-41.472 217.088-41.472s145.408 13.824 217.088 41.472c71.68 27.648 132.608 67.072 182.784 117.248 3.584 3.584 5.632 8.192 5.632 12.8 0 6.656-14.336 24.576-43.008 53.248s-45.056 42.496-51.712 42.496z" fill="#e6e6e6" p-id="19571" data-spm-anchor-id="a313x.7781069.0.i65" class=""></path><path d="M1026.048 445.44c-4.096 0-8.192-1.536-12.8-5.12-68.096-59.904-138.752-104.96-212.48-135.168-73.216-30.208-153.6-45.568-240.128-45.568-87.04 0-166.912 15.36-240.128 45.568S176.64 380.416 108.544 440.32c-4.096 3.584-8.192 5.12-12.8 5.12-6.656 0-24.064-14.336-52.736-43.008S0 356.352 0 349.184c0-5.12 2.048-9.216 5.632-13.312C76.8 265.216 161.792 210.432 260.096 171.52s198.656-58.368 301.056-58.368 202.752 19.456 301.056 58.368 183.296 93.696 254.464 164.352c3.584 3.584 5.632 8.192 5.632 13.312 0 6.656-14.336 24.576-43.008 53.248-28.672 28.672-46.592 43.008-53.248 43.008z" fill="#e6e6e6" p-id="19572" data-spm-anchor-id="a313x.7781069.0.i66" class=""></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/wifi_3.svg b/src/assets/icons/svg/wifi_3.svg new file mode 100644 index 0000000..bfa8d27 --- /dev/null +++ b/src/assets/icons/svg/wifi_3.svg @@ -0,0 +1 @@ +<?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="1622135369729" class="icon" viewBox="0 0 1122 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19568" xmlns:xlink="http://www.w3.org/1999/xlink" width="219.140625" height="200"><defs><style type="text/css"></style></defs><path d="M561.152 910.336c-7.68 0-25.088-13.824-53.248-41.984-27.648-28.16-41.472-45.568-41.472-53.248 0-12.288 11.776-22.528 35.84-30.72s43.52-12.8 59.392-12.8c15.872 0 35.328 4.096 59.392 12.8s35.84 18.432 35.84 30.72c0 7.68-13.824 25.6-41.472 53.248-29.184 28.16-46.592 41.984-54.272 41.984z" fill="#409EFF" p-id="19569" data-spm-anchor-id="a313x.7781069.0.i63" class="selected"></path><path d="M715.264 755.712c-0.512 0-8.192-4.608-23.04-14.336-14.336-9.728-33.792-18.944-57.856-28.672-24.064-9.728-48.64-14.336-73.216-14.336-24.576 0-49.152 4.608-73.216 14.336-24.064 9.728-43.52 18.944-57.856 28.672-14.336 9.728-22.016 14.336-23.04 14.336-6.656 0-24.576-14.336-53.248-43.008s-43.008-46.08-43.008-53.248c0-5.12 2.048-9.216 5.632-13.312 29.696-29.184 67.072-52.224 112.128-69.12s89.088-25.088 133.12-25.088c44.032 0 88.064 8.192 133.12 25.088 45.056 16.896 82.432 39.936 112.128 69.12 3.584 3.584 5.632 8.192 5.632 13.312 0 6.656-14.336 24.576-43.008 53.248-29.696 28.672-47.104 43.008-54.272 43.008z" fill="#409EFF" p-id="19570" data-spm-anchor-id="a313x.7781069.0.i64" class="selected"></path><path d="M871.424 600.064c-4.096 0-8.704-1.536-13.312-4.608-51.712-39.936-99.84-69.632-143.872-88.064s-95.232-28.16-153.088-28.16c-32.256 0-65.024 4.096-97.28 12.8S402.944 510.464 378.88 522.24c-24.064 11.776-45.568 23.552-65.024 35.328s-34.304 22.016-45.056 30.208c-11.264 8.192-16.896 12.8-17.92 12.8-6.656 0-24.064-14.336-52.736-43.008s-43.008-46.08-43.008-53.248c0-4.608 2.048-8.704 5.632-12.8 50.176-50.176 111.104-89.088 182.784-117.248 71.68-27.648 143.872-41.472 217.088-41.472s145.408 13.824 217.088 41.472c71.68 27.648 132.608 67.072 182.784 117.248 3.584 3.584 5.632 8.192 5.632 12.8 0 6.656-14.336 24.576-43.008 53.248s-45.056 42.496-51.712 42.496z" fill="#409EFF" p-id="19571" data-spm-anchor-id="a313x.7781069.0.i65" class="selected"></path><path d="M1026.048 445.44c-4.096 0-8.192-1.536-12.8-5.12-68.096-59.904-138.752-104.96-212.48-135.168-73.216-30.208-153.6-45.568-240.128-45.568-87.04 0-166.912 15.36-240.128 45.568S176.64 380.416 108.544 440.32c-4.096 3.584-8.192 5.12-12.8 5.12-6.656 0-24.064-14.336-52.736-43.008S0 356.352 0 349.184c0-5.12 2.048-9.216 5.632-13.312C76.8 265.216 161.792 210.432 260.096 171.52s198.656-58.368 301.056-58.368 202.752 19.456 301.056 58.368 183.296 93.696 254.464 164.352c3.584 3.584 5.632 8.192 5.632 13.312 0 6.656-14.336 24.576-43.008 53.248-28.672 28.672-46.592 43.008-53.248 43.008z" fill="#e6e6e6" p-id="19572" data-spm-anchor-id="a313x.7781069.0.i66" class=""></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/wifi_4.svg b/src/assets/icons/svg/wifi_4.svg new file mode 100644 index 0000000..f5b090a --- /dev/null +++ b/src/assets/icons/svg/wifi_4.svg @@ -0,0 +1 @@ +<?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="1622135369729" class="icon" viewBox="0 0 1122 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19568" xmlns:xlink="http://www.w3.org/1999/xlink" width="219.140625" height="200"><defs><style type="text/css"></style></defs><path d="M561.152 910.336c-7.68 0-25.088-13.824-53.248-41.984-27.648-28.16-41.472-45.568-41.472-53.248 0-12.288 11.776-22.528 35.84-30.72s43.52-12.8 59.392-12.8c15.872 0 35.328 4.096 59.392 12.8s35.84 18.432 35.84 30.72c0 7.68-13.824 25.6-41.472 53.248-29.184 28.16-46.592 41.984-54.272 41.984z" fill="#409EFF" p-id="19569" data-spm-anchor-id="a313x.7781069.0.i63" class="selected"></path><path d="M715.264 755.712c-0.512 0-8.192-4.608-23.04-14.336-14.336-9.728-33.792-18.944-57.856-28.672-24.064-9.728-48.64-14.336-73.216-14.336-24.576 0-49.152 4.608-73.216 14.336-24.064 9.728-43.52 18.944-57.856 28.672-14.336 9.728-22.016 14.336-23.04 14.336-6.656 0-24.576-14.336-53.248-43.008s-43.008-46.08-43.008-53.248c0-5.12 2.048-9.216 5.632-13.312 29.696-29.184 67.072-52.224 112.128-69.12s89.088-25.088 133.12-25.088c44.032 0 88.064 8.192 133.12 25.088 45.056 16.896 82.432 39.936 112.128 69.12 3.584 3.584 5.632 8.192 5.632 13.312 0 6.656-14.336 24.576-43.008 53.248-29.696 28.672-47.104 43.008-54.272 43.008z" fill="#409EFF" p-id="19570" data-spm-anchor-id="a313x.7781069.0.i64" class="selected"></path><path d="M871.424 600.064c-4.096 0-8.704-1.536-13.312-4.608-51.712-39.936-99.84-69.632-143.872-88.064s-95.232-28.16-153.088-28.16c-32.256 0-65.024 4.096-97.28 12.8S402.944 510.464 378.88 522.24c-24.064 11.776-45.568 23.552-65.024 35.328s-34.304 22.016-45.056 30.208c-11.264 8.192-16.896 12.8-17.92 12.8-6.656 0-24.064-14.336-52.736-43.008s-43.008-46.08-43.008-53.248c0-4.608 2.048-8.704 5.632-12.8 50.176-50.176 111.104-89.088 182.784-117.248 71.68-27.648 143.872-41.472 217.088-41.472s145.408 13.824 217.088 41.472c71.68 27.648 132.608 67.072 182.784 117.248 3.584 3.584 5.632 8.192 5.632 12.8 0 6.656-14.336 24.576-43.008 53.248s-45.056 42.496-51.712 42.496z" fill="#409EFF" p-id="19571" data-spm-anchor-id="a313x.7781069.0.i65" class="selected"></path><path d="M1026.048 445.44c-4.096 0-8.192-1.536-12.8-5.12-68.096-59.904-138.752-104.96-212.48-135.168-73.216-30.208-153.6-45.568-240.128-45.568-87.04 0-166.912 15.36-240.128 45.568S176.64 380.416 108.544 440.32c-4.096 3.584-8.192 5.12-12.8 5.12-6.656 0-24.064-14.336-52.736-43.008S0 356.352 0 349.184c0-5.12 2.048-9.216 5.632-13.312C76.8 265.216 161.792 210.432 260.096 171.52s198.656-58.368 301.056-58.368 202.752 19.456 301.056 58.368 183.296 93.696 254.464 164.352c3.584 3.584 5.632 8.192 5.632 13.312 0 6.656-14.336 24.576-43.008 53.248-28.672 28.672-46.592 43.008-53.248 43.008z" fill="#409EFF" p-id="19572" data-spm-anchor-id="a313x.7781069.0.i66" class="selected"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/zhifubao.svg b/src/assets/icons/svg/zhifubao.svg new file mode 100644 index 0000000..d9096b7 --- /dev/null +++ b/src/assets/icons/svg/zhifubao.svg @@ -0,0 +1,2 @@ +<?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="1650119020631" class="icon" viewBox="0 0 1037 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15187" xmlns:xlink="http://www.w3.org/1999/xlink" width="129.625" height="128"><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="M665.600029 614.4c70.4-128 96-249.6 96-249.6l-12.8 0 0 0L640.000029 364.8 524.800029 364.8 524.800029 275.2l281.6 0L806.400029 236.8 524.800029 236.8 524.800029 102.4l-128 0 0 134.4-256 0 0 38.4 256 0 0 89.6L179.200029 364.8l0 38.4 441.6 0c0 6.4 0 6.4-6.4 12.8C614.400029 460.8 582.400029 524.8 556.800029 576 230.400029 448 134.400029 524.8 108.800029 537.6c-217.6 153.6-12.8 345.6 19.2 339.2 230.4 51.2 377.6-44.8 480-166.4 6.4 6.4 12.8 6.4 19.2 6.4 70.4 38.4 409.6 198.4 409.6 198.4s0-140.8 0-192C985.600029 723.2 800.000029 659.2 665.600029 614.4zM499.200029 672c-160 204.8-352 140.8-384 128C38.400029 780.8 12.800029 640 108.800029 595.2c160-51.2 300.8 6.4 403.2 57.6C505.600029 665.6 499.200029 672 499.200029 672z" p-id="15188" fill="#ffffff"></path></svg> \ No newline at end of file diff --git a/src/assets/icons/svg/zip.svg b/src/assets/icons/svg/zip.svg new file mode 100644 index 0000000..f806fc4 --- /dev/null +++ b/src/assets/icons/svg/zip.svg @@ -0,0 +1 @@ +<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> \ No newline at end of file diff --git a/src/assets/icons/svgo.yml b/src/assets/icons/svgo.yml new file mode 100644 index 0000000..d11906a --- /dev/null +++ b/src/assets/icons/svgo.yml @@ -0,0 +1,22 @@ +# 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' diff --git a/src/assets/images/code.jpg b/src/assets/images/code.jpg new file mode 100644 index 0000000..5108499 --- /dev/null +++ b/src/assets/images/code.jpg Binary files differ diff --git a/src/assets/images/dark.svg b/src/assets/images/dark.svg new file mode 100644 index 0000000..f646bd7 --- /dev/null +++ b/src/assets/images/dark.svg @@ -0,0 +1,39 @@ +<?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> \ No newline at end of file diff --git a/src/assets/images/gateway.png b/src/assets/images/gateway.png new file mode 100644 index 0000000..6918cd6 --- /dev/null +++ b/src/assets/images/gateway.png Binary files differ diff --git a/src/assets/images/light.svg b/src/assets/images/light.svg new file mode 100644 index 0000000..ab7cc08 --- /dev/null +++ b/src/assets/images/light.svg @@ -0,0 +1,39 @@ +<?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> \ No newline at end of file diff --git a/src/assets/images/orange.svg b/src/assets/images/orange.svg new file mode 100644 index 0000000..67746c6 --- /dev/null +++ b/src/assets/images/orange.svg @@ -0,0 +1,39 @@ +<?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="#ff6b03" mask="url(#mask-3)" x="0" y="0" width="16" height="40"></rect> + </g> + </g> + </g> + </g> +</svg> \ No newline at end of file diff --git a/src/assets/images/phone.jpg b/src/assets/images/phone.jpg new file mode 100644 index 0000000..6de9474 --- /dev/null +++ b/src/assets/images/phone.jpg Binary files differ diff --git a/src/assets/images/phone.png b/src/assets/images/phone.png new file mode 100644 index 0000000..5b4b889 --- /dev/null +++ b/src/assets/images/phone.png Binary files differ diff --git a/src/assets/images/product.png b/src/assets/images/product.png new file mode 100644 index 0000000..b34ee88 --- /dev/null +++ b/src/assets/images/product.png Binary files differ diff --git a/src/assets/images/profile.jpg b/src/assets/images/profile.jpg new file mode 100644 index 0000000..ca4c646 --- /dev/null +++ b/src/assets/images/profile.jpg Binary files differ diff --git a/src/assets/images/qq.png b/src/assets/images/qq.png new file mode 100644 index 0000000..3c2aaf7 --- /dev/null +++ b/src/assets/images/qq.png Binary files differ diff --git a/src/assets/images/video.png b/src/assets/images/video.png new file mode 100644 index 0000000..026b691 --- /dev/null +++ b/src/assets/images/video.png Binary files differ diff --git a/src/assets/images/weChat.png b/src/assets/images/weChat.png new file mode 100644 index 0000000..926ac0f --- /dev/null +++ b/src/assets/images/weChat.png Binary files differ diff --git a/src/assets/images/zlm-logo.png b/src/assets/images/zlm-logo.png new file mode 100644 index 0000000..5f492dc --- /dev/null +++ b/src/assets/images/zlm-logo.png Binary files differ diff --git a/src/assets/logo/logo.gif b/src/assets/logo/logo.gif new file mode 100644 index 0000000..c342bbd --- /dev/null +++ b/src/assets/logo/logo.gif Binary files differ diff --git a/src/assets/logo/logo.png b/src/assets/logo/logo.png new file mode 100644 index 0000000..fefb48e --- /dev/null +++ b/src/assets/logo/logo.png Binary files differ diff --git a/src/assets/styles/btn.scss b/src/assets/styles/btn.scss new file mode 100644 index 0000000..e6ba1a8 --- /dev/null +++ b/src/assets/styles/btn.scss @@ -0,0 +1,99 @@ +@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; +} diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss new file mode 100644 index 0000000..363092a --- /dev/null +++ b/src/assets/styles/element-ui.scss @@ -0,0 +1,92 @@ +// 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; +} \ No newline at end of file diff --git a/src/assets/styles/element-variables.scss b/src/assets/styles/element-variables.scss new file mode 100644 index 0000000..1615ff2 --- /dev/null +++ b/src/assets/styles/element-variables.scss @@ -0,0 +1,31 @@ +/** +* 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; +} diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss new file mode 100644 index 0000000..ed436aa --- /dev/null +++ b/src/assets/styles/index.scss @@ -0,0 +1,211 @@ +@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; +} + +.card-margin-bottom{ + margin-bottom: 6px; +} + +.card-padding-bottom{ + padding-bottom: 100px; +} + +.form-item-right{ + float: right; +} + +.form-minus-bomttom{ + margin-bottom: -20px; +} + +.big-box-padding{ + padding: 6px; +} + +.components-container { + margin: 10px; + position: relative; +} + +.pagination-container { + margin-top: 30px; +} + +.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; + } +} + +//refine vue-multiselect plugin +.multiselect { + line-height: 16px; +} + +.multiselect--active { + z-index: 1000 !important; +} diff --git a/src/assets/styles/mixin.scss b/src/assets/styles/mixin.scss new file mode 100644 index 0000000..06fa061 --- /dev/null +++ b/src/assets/styles/mixin.scss @@ -0,0 +1,66 @@ +@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; + } +} diff --git a/src/assets/styles/ruoyi.scss b/src/assets/styles/ruoyi.scss new file mode 100644 index 0000000..8f75852 --- /dev/null +++ b/src/assets/styles/ruoyi.scss @@ -0,0 +1,292 @@ + /** + * 閫氱敤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 { + position: relative; + height: 25px; + margin-bottom: 10px; + margin-top: 15px; + padding: 10px 20px !important; +} + +/* tree border */ +.tree-border { + margin-top: 5px; + border: 1px solid #e5e6e7; + background: #FFFFFF none; + border-radius:4px; +} + +.pagination-container .el-pagination { + right: 0; + position: absolute; +} + +@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 { + padding-right: 15px; + padding-left: 15px; + 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; +} + +/* 淇敼switch鎸夐挳鏍峰紡 */ +.el-switch__core{ + width:45px!important; + height:22px; + border-radius:2px; +} +.el-switch__core:after{ + width:20px; + height:18px; + border-radius:2px; +} +.el-switch.is-checked .el-switch__core::after{ + margin-left:-21px; +} diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss new file mode 100644 index 0000000..ed308b8 --- /dev/null +++ b/src/assets/styles/sidebar.scss @@ -0,0 +1,227 @@ +#app { + + .main-container { + min-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: 2px 0 6px rgba(0,21,41,.35); + + // 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; + } + } +} diff --git a/src/assets/styles/transition.scss b/src/assets/styles/transition.scss new file mode 100644 index 0000000..eb49895 --- /dev/null +++ b/src/assets/styles/transition.scss @@ -0,0 +1,53 @@ +// 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-leave-active { + position: absolute; +} + +.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; +} diff --git a/src/assets/styles/variables.scss b/src/assets/styles/variables.scss new file mode 100644 index 0000000..34484d4 --- /dev/null +++ b/src/assets/styles/variables.scss @@ -0,0 +1,54 @@ +// 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 +} diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue new file mode 100644 index 0000000..1696f54 --- /dev/null +++ b/src/components/Breadcrumb/index.vue @@ -0,0 +1,74 @@ +<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 = this.$route.matched.filter(item => item.meta && item.meta.title) + const first = matched[0] + + if (!this.isDashboard(first)) { + matched = [{ path: '/index', meta: { title: '棣栭〉' }}].concat(matched) + } + + this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) + }, + 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> diff --git a/src/components/Codemirror/index.vue b/src/components/Codemirror/index.vue new file mode 100644 index 0000000..34b74f2 --- /dev/null +++ b/src/components/Codemirror/index.vue @@ -0,0 +1,128 @@ +<template> + <div class="json-editor"> + <textarea ref="textarea" /> + </div> +</template> + +<script> +// import sqlFormatter from "sql-formatter"; +import CodeMirror from "codemirror"; +import "codemirror/lib/codemirror.css"; +import "codemirror/mode/sql/sql.js"; +// 鏇挎崲涓婚杩欓噷闇�淇敼鍚嶇О +import "codemirror/theme/idea.css"; +// 鏀寔浠g爜鑷姩琛ュ叏 +import "codemirror/addon/hint/show-hint.css"; +import "codemirror/addon/hint/show-hint.js"; +import "codemirror/addon/hint/anyword-hint.js"; + +// JSON浠g爜楂樹寒闇�瑕佺敱JavaScript鎻掍欢鏀寔 +import "codemirror/mode/javascript/javascript.js"; + +// 鏀寔鍚勭浠g爜鎶樺彔 +import "codemirror/addon/fold/foldgutter.css"; +import "codemirror/addon/fold/foldcode.js"; +import "codemirror/addon/fold/foldgutter.js"; +import "codemirror/addon/fold/brace-fold.js"; +import "codemirror/addon/fold/comment-fold.js"; + +// 鏀寔鎷彿鑷姩鍖归厤 +import "codemirror/addon/edit/matchbrackets.js"; +import "codemirror/addon/edit/closebrackets.js"; + +// 琛屾敞閲� +import "codemirror/addon/comment/comment.js"; +// JSON閿欒妫�鏌� +import "codemirror/addon/lint/lint.css"; +import "codemirror/addon/lint/lint.js"; + +export default { + props: { + value: '', + height: { + type: String, + required: true, + }, + myMode: { + type: String, + required: true, + }, + }, + data() { + return { + editor: false, + }; + }, + watch: { + value(value) { + const editorValue = this.editor.getValue(); + if (value !== editorValue) { + if (typeof this.value !== "undefined") { + this.editor.setValue(this.value); + } else { + this.editor.setValue(""); + } + } + }, + }, + mounted() { + this.editor = CodeMirror.fromTextArea(this.$refs.textarea, { + mode: this.myMode, //璇█ + smartIndent: true, // 鏄惁鏅鸿兘缂╄繘 + styleActiveLine: true, // 褰撳墠琛岄珮浜� + lineNumbers: true, // 鏄惁鏄剧ず琛屾暟 + indentUnit: 2, // 缂╄繘鍗曚綅锛岄粯璁�2 + gutters: [ + "CodeMirror-linenumbers", + "CodeMirror-foldgutter", + "CodeMirror-lint-markers", // CodeMirror-lint-markers鏄疄鐜拌娉曟姤閿欏姛鑳� + ], + lint: true, + //lineWrapping: true, // 鑷姩鎹㈣ + matchBrackets: true, // 鎷彿鍖归厤鏄剧ず + autoCloseBrackets: true, // 杈撳叆鍜岄��鏍兼椂鎴愬 + readOnly: false, // 鍙 + foldGutter: true, + autoRefresh: true, + }); + //浠g爜鑷姩鎻愮ず鍔熻兘锛岃浣忎娇鐢╟ursorActivity浜嬩欢涓嶈浣跨敤change浜嬩欢锛岃繖鏄竴涓潙锛岄偅鏍烽〉闈㈢洿鎺ヤ細鍗℃ + this.editor.on("inputRead", () => { + this.editor.showHint(); + }); + this.editor.setSize("auto", this.height); + if (typeof this.value !== "undefined") { + this.editor.setValue(this.value); + } else { + this.editor.setValue(""); + } + }, + methods: { + getValue() { + return this.editor.getValue(); + }, + // formatSql() { + // /*锛坰ql缂栬緫鍣ㄥ唴瀹圭粦瀹歝ontent鍙傛暟锛� 灏唖ql鍐呭杩涜鏍煎紡鍚庢斁鍏ョ紪杈戝櫒涓�*/ + // this.content = sqlFormatter.format(this.content); + // }, + }, +}; +</script> + +<style scoped> +.json-editor { + height: 100%; +} + +.json-editor >>> .CodeMirror { + font-size: 14px; + /* overflow-y:auto; */ + font-weight: normal; +} + +.json-editor >>> .CodeMirror-scroll { +} + +.json-editor >>> .cm-s-rubyblue span.cm-string { + color: #f08047; +} +</style> diff --git a/src/components/Crontab/day.vue b/src/components/Crontab/day.vue new file mode 100644 index 0000000..fe3eaf0 --- /dev/null +++ b/src/components/Crontab/day.vue @@ -0,0 +1,161 @@ +<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" /> 鍙锋渶杩戠殑閭d釜宸ヤ綔鏃� + </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> diff --git a/src/components/Crontab/hour.vue b/src/components/Crontab/hour.vue new file mode 100644 index 0000000..4b1f1fc --- /dev/null +++ b/src/components/Crontab/hour.vue @@ -0,0 +1,114 @@ +<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() { + 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> diff --git a/src/components/Crontab/index.vue b/src/components/Crontab/index.vue new file mode 100644 index 0000000..3963df2 --- /dev/null +++ b/src/components/Crontab/index.vue @@ -0,0 +1,430 @@ +<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> diff --git a/src/components/Crontab/min.vue b/src/components/Crontab/min.vue new file mode 100644 index 0000000..43cab90 --- /dev/null +++ b/src/components/Crontab/min.vue @@ -0,0 +1,116 @@ +<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> \ No newline at end of file diff --git a/src/components/Crontab/month.vue b/src/components/Crontab/month.vue new file mode 100644 index 0000000..fd0ac38 --- /dev/null +++ b/src/components/Crontab/month.vue @@ -0,0 +1,114 @@ +<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> diff --git a/src/components/Crontab/result.vue b/src/components/Crontab/result.vue new file mode 100644 index 0000000..aea6e0e --- /dev/null +++ b/src/components/Crontab/result.vue @@ -0,0 +1,559 @@ +<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'); + // 鏍¢獙褰撳墠鏄熸湡鏄惁鍦ㄦ槦鏈熸睜锛坉ayRuleSup锛変腑 + 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'); + // 鎵惧埌瑕佹眰涓渶杩戠殑閭d釜鏄熸湡鍑� + 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; + }, + // 姣旇緝鏁板瓧澶у皬锛堢敤浜嶢rray.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') { + // 鍦╭uartz涓� 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> diff --git a/src/components/Crontab/second.vue b/src/components/Crontab/second.vue new file mode 100644 index 0000000..e7b7761 --- /dev/null +++ b/src/components/Crontab/second.vue @@ -0,0 +1,117 @@ +<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> diff --git a/src/components/Crontab/week.vue b/src/components/Crontab/week.vue new file mode 100644 index 0000000..1cec700 --- /dev/null +++ b/src/components/Crontab/week.vue @@ -0,0 +1,202 @@ +<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> diff --git a/src/components/Crontab/year.vue b/src/components/Crontab/year.vue new file mode 100644 index 0000000..5487a6c --- /dev/null +++ b/src/components/Crontab/year.vue @@ -0,0 +1,131 @@ +<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> diff --git a/src/components/DictData/index.js b/src/components/DictData/index.js new file mode 100644 index 0000000..7b85d4a --- /dev/null +++ b/src/components/DictData/index.js @@ -0,0 +1,49 @@ +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, +} \ No newline at end of file diff --git a/src/components/DictTag/index.vue b/src/components/DictTag/index.vue new file mode 100644 index 0000000..ff2aa65 --- /dev/null +++ b/src/components/DictTag/index.vue @@ -0,0 +1,58 @@ +<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 == ''" + :key="item.value" + :index="index" + :class="item.raw.cssClass" + :size="size" + >{{ 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" + :size="size" + > + {{ item.label }} + </el-tag> + </template> + </template> + </div> +</template> + +<script> +export default { + name: "DictTag", + props: { + options: { + type: Array, + default: null, + }, + value: [Number, String, Array], + size:{ + type: String, + default:"big" + } + }, + computed: { + values() { + if (this.value !== null && typeof this.value !== 'undefined') { + return Array.isArray(this.value) ? this.value : [String(this.value)]; + } else { + return []; + } + }, + }, +}; +</script> +<style scoped> +.el-tag + .el-tag { + margin-left: 10px; +} +</style> \ No newline at end of file diff --git a/src/components/Editor/index.vue b/src/components/Editor/index.vue new file mode 100644 index 0000000..6bb5a18 --- /dev/null +++ b/src/components/Editor/index.vue @@ -0,0 +1,272 @@ +<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 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, + }, + /* 绫诲瀷锛坆ase64鏍煎紡銆乽rl鏍煎紡锛� */ + 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"], // 寮曠敤 浠g爜鍧� + [{ 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.pasteHTML(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) => { + this.uploadType = "image"; + if (value) { + this.$refs.upload.$children[0].$refs.input.click(); + } else { + this.quill.format("image", false); + } + }); + } + this.Quill.pasteHTML(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) { + // 鏍℃鏂囦欢澶у皬 + 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) { + // 鑾峰彇瀵屾枃鏈粍浠跺疄渚� + let quill = this.Quill; + // 濡傛灉涓婁紶鎴愬姛 + if (res.code == 200) { + // 鑾峰彇鍏夋爣鎵�鍦ㄤ綅缃� + 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("鍥剧墖鎻掑叆澶辫触"); + }, + }, +}; +</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> diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue new file mode 100644 index 0000000..608da91 --- /dev/null +++ b/src/components/FileUpload/index.vue @@ -0,0 +1,215 @@ +<template> + <div class="upload-file"> + <el-upload + multiple + :action="uploadFileUrl" + :before-upload="handleBeforeUpload" + :file-list="fileList" + :limit="limit" + :on-error="handleUploadError" + :on-exceed="handleExceed" + :on-success="handleUploadSuccess" + :show-file-list="false" + :headers="headers" + class="upload-file-uploader" + ref="fileUpload" + > + <!-- 涓婁紶鎸夐挳 --> + <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 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">鍒犻櫎</el-link> + </div> + </li> + </transition-group> + </div> +</template> + +<script> +import { getToken } from "@/utils/auth"; + +export default { + name: "FileUpload", + props: { + // 鍊� + value: [String, Object, Array], + // 鏁伴噺闄愬埗 + limit: { + type: Number, + default: 5, + }, + // 澶у皬闄愬埗(MB) + fileSize: { + type: Number, + default: 5, + }, + // 鏂囦欢绫诲瀷, 渚嬪['png', 'jpg', 'jpeg'] + fileType: { + type: Array, + default: () => ["doc", "xls", "ppt", "txt", "pdf"], + }, + // 鏄惁鏄剧ず鎻愮ず + isShowTip: { + type: Boolean, + default: true + } + }, + data() { + return { + number: 0, + uploadList: [], + baseUrl: process.env.VUE_APP_BASE_API, + uploadFileUrl: process.env.VUE_APP_BASE_API + "/iot/tool/upload", // 涓婁紶鏂囦欢鏈嶅姟鍣ㄥ湴鍧� + headers: { + Authorization: "Bearer " + getToken(), + }, + 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 (this.fileSize) { + const isLt = file.size / 1024 / 1024 < this.fileSize; + if (!isLt) { + this.$modal.msgError(`涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 ${this.fileSize} MB!`); + return false; + } + } + this.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��..."); + 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) { + if (name.lastIndexOf("/") > -1) { + return name.slice(name.lastIndexOf("/") + 1); + } else { + return ""; + } + }, + // 瀵硅薄杞垚鎸囧畾瀛楃涓插垎闅� + 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"> +.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> diff --git a/src/components/Hamburger/index.vue b/src/components/Hamburger/index.vue new file mode 100644 index 0000000..368b002 --- /dev/null +++ b/src/components/Hamburger/index.vue @@ -0,0 +1,44 @@ +<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> diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue new file mode 100644 index 0000000..c4d76bb --- /dev/null +++ b/src/components/HeaderSearch/index.vue @@ -0,0 +1,189 @@ +<template> + <div :class="{'show':show}" class="header-search"> + <svg-icon class-name="search-icon" icon-class="search" @click.stop="click" /> + <el-select + ref="headerSearchSelect" + v-model="search" + :remote-method="querySearch" + filterable + default-first-option + remote + placeholder="Search" + class="header-search-select" + @change="change" + > + <el-option v-for="option in options" :key="option.item.path" :value="option.item" :label="option.item.title.join(' > ')" /> + </el-select> + </div> +</template> + +<script> +// fuse is a lightweight fuzzy-search module +// make search results more in line with expectations +import Fuse from 'fuse.js/dist/fuse.min.js' +import path from 'path' + +export default { + name: 'HeaderSearch', + data() { + return { + search: '', + options: [], + searchPool: [], + show: false, + fuse: undefined + } + }, + computed: { + routes() { + return this.$store.getters.permission_routes + } + }, + watch: { + routes() { + this.searchPool = this.generateRoutes(this.routes) + }, + searchPool(list) { + this.initFuse(list) + }, + show(value) { + if (value) { + document.body.addEventListener('click', this.close) + } else { + document.body.removeEventListener('click', this.close) + } + } + }, + mounted() { + this.searchPool = this.generateRoutes(this.routes) + }, + methods: { + click() { + this.show = !this.show + if (this.show) { + this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.focus() + } + }, + close() { + this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.blur() + this.options = [] + this.show = false + }, + change(val) { + const path = val.path; + if(this.ishttp(val.path)) { + // http(s):// 璺緞鏂扮獥鍙f墦寮� + const pindex = path.indexOf("http"); + window.open(path.substr(pindex, path.length), "_blank"); + } else { + this.$router.push(val.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: !this.ishttp(router.path) ? path.resolve(basePath, router.path) : router.path, + title: [...prefixTitle] + } + + if (router.meta && router.meta.title) { + data.title = [...data.title, router.meta.title] + + if (router.redirect !== 'noRedirect') { + // only push the routes with title + // special case: need to exclude parent router without redirect + res.push(data) + } + } + + // 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) { + if (query !== '') { + this.options = this.fuse.search(query) + } else { + this.options = [] + } + }, + ishttp(url) { + return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1 + } + } +} +</script> + +<style lang="scss" scoped> +.header-search { + font-size: 0 !important; + + .search-icon { + cursor: pointer; + font-size: 18px; + vertical-align: middle; + } + + .header-search-select { + font-size: 18px; + transition: width 0.2s; + width: 0; + overflow: hidden; + background: transparent; + border-radius: 0; + display: inline-block; + vertical-align: middle; + + ::v-deep .el-input__inner { + border-radius: 0; + border: 0; + padding-left: 0; + padding-right: 0; + box-shadow: none !important; + border-bottom: 1px solid #d9d9d9; + vertical-align: middle; + } + } + + &.show { + .header-search-select { + width: 210px; + margin-left: 10px; + } + } +} +</style> diff --git a/src/components/IconSelect/index.vue b/src/components/IconSelect/index.vue new file mode 100644 index 0000000..b0ec9fa --- /dev/null +++ b/src/components/IconSelect/index.vue @@ -0,0 +1,68 @@ +<!-- @author zhengjie --> +<template> + <div class="icon-body"> + <el-input v-model="name" style="position: relative;" clearable placeholder="璇疯緭鍏ュ浘鏍囧悕绉�" @clear="filterIcons" @input.native="filterIcons"> + <i slot="suffix" class="el-icon-search el-input__icon" /> + </el-input> + <div class="icon-list"> + <div v-for="(item, index) in iconList" :key="index" @click="selectedIcon(item)"> + <svg-icon :icon-class="item" style="height: 30px;width: 16px;" /> + <span>{{ item }}</span> + </div> + </div> + </div> +</template> + +<script> +import icons from './requireIcons' +export default { + name: 'IconSelect', + 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-list { + height: 200px; + overflow-y: scroll; + div { + height: 30px; + line-height: 30px; + margin-bottom: -5px; + cursor: pointer; + width: 33%; + float: left; + } + span { + display: inline-block; + vertical-align: -0.15em; + fill: currentColor; + overflow: hidden; + } + } + } +</style> diff --git a/src/components/IconSelect/requireIcons.js b/src/components/IconSelect/requireIcons.js new file mode 100644 index 0000000..99e5c54 --- /dev/null +++ b/src/components/IconSelect/requireIcons.js @@ -0,0 +1,11 @@ + +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 diff --git a/src/components/ImagePreview/index.vue b/src/components/ImagePreview/index.vue new file mode 100644 index 0000000..3c770c7 --- /dev/null +++ b/src/components/ImagePreview/index.vue @@ -0,0 +1,90 @@ +<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> diff --git a/src/components/ImageUpload/index.vue b/src/components/ImageUpload/index.vue new file mode 100644 index 0000000..895c88f --- /dev/null +++ b/src/components/ImageUpload/index.vue @@ -0,0 +1,226 @@ +<template> + <div class="component-upload-image"> + <el-upload + multiple + :action="uploadImgUrl" + list-type="picture-card" + :on-success="handleUploadSuccess" + :before-upload="handleBeforeUpload" + :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"> + 璇蜂笂浼� + <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"; + +export default { + props: { + value: [String, Object, Array], + // 鍥剧墖鏁伴噺闄愬埗 + 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 + } + }, + data() { + return { + number: 0, + uploadList: [], + dialogImageUrl: "", + dialogVisible: false, + hideUpload: false, + baseUrl: process.env.VUE_APP_BASE_API, + uploadImgUrl: process.env.VUE_APP_BASE_API + "/iot/tool/upload", // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃 + headers: { + Authorization: "Bearer " + getToken(), + }, + 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) { + 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: { + // 涓婁紶鍓峫oading鍔犺浇 + 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 (this.fileSize) { + const isLt = file.size / 1024 / 1024 < this.fileSize; + if (!isLt) { + this.$modal.msgError(`涓婁紶澶村儚鍥剧墖澶у皬涓嶈兘瓒呰繃 ${this.fileSize} MB!`); + return false; + } + } + this.$modal.loading("姝e湪涓婁紶鍥剧墖锛岃绋嶅��..."); + 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-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> + diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue new file mode 100644 index 0000000..56f5a6b --- /dev/null +++ b/src/components/Pagination/index.vue @@ -0,0 +1,114 @@ +<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; + padding: 32px 16px; +} +.pagination-container.hidden { + display: none; +} +</style> diff --git a/src/components/PanThumb/index.vue b/src/components/PanThumb/index.vue new file mode 100644 index 0000000..1bcf417 --- /dev/null +++ b/src/components/PanThumb/index.vue @@ -0,0 +1,142 @@ +<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> + <!-- eslint-disable-next-line --> + <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> diff --git a/src/components/ParentView/index.vue b/src/components/ParentView/index.vue new file mode 100644 index 0000000..7bf6148 --- /dev/null +++ b/src/components/ParentView/index.vue @@ -0,0 +1,3 @@ +<template > + <router-view /> +</template> diff --git a/src/components/RightPanel/index.vue b/src/components/RightPanel/index.vue new file mode 100644 index 0000000..5abeecb --- /dev/null +++ b/src/components/RightPanel/index.vue @@ -0,0 +1,106 @@ +<template> + <div ref="rightPanel" class="rightPanel-container"> + <div class="rightPanel-background" /> + <div class="rightPanel"> + <div class="rightPanel-items"> + <slot /> + </div> + </div> + </div> +</template> + +<script> +export default { + name: 'RightPanel', + props: { + clickNotClose: { + default: false, + type: Boolean + } + }, + computed: { + show: { + get() { + return this.$store.state.settings.showSettings + }, + set(val) { + this.$store.dispatch('settings/changeSetting', { + key: 'showSettings', + value: val + }) + } + } + }, + watch: { + show(value) { + if (value && !this.clickNotClose) { + this.addEventClick() + } + } + }, + mounted() { + this.addEventClick() + }, + beforeDestroy() { + const elx = this.$refs.rightPanel + elx.remove() + }, + methods: { + addEventClick() { + window.addEventListener('click', this.closeSidebar) + }, + closeSidebar(evt) { + const parent = evt.target.closest('.el-drawer__body') + if (!parent) { + this.show = false + window.removeEventListener('click', this.closeSidebar) + } + } + } +} +</script> + +<style lang="scss" scoped> +.rightPanel-background { + position: fixed; + top: 0; + left: 0; + opacity: 0; + transition: opacity .3s cubic-bezier(.7, .3, .1, 1); + background: rgba(0, 0, 0, .2); + z-index: -1; +} + +.rightPanel { + width: 100%; + max-width: 260px; + height: 100vh; + position: fixed; + top: 0; + right: 0; + box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05); + transition: all .25s cubic-bezier(.7, .3, .1, 1); + transform: translate(100%); + background: #fff; + z-index: 40000; +} + +.handle-button { + width: 48px; + height: 48px; + position: absolute; + left: -48px; + text-align: center; + font-size: 24px; + border-radius: 6px 0 0 6px !important; + z-index: 0; + pointer-events: auto; + cursor: pointer; + color: #fff; + line-height: 48px; + i { + font-size: 24px; + line-height: 48px; + } +} +</style> diff --git a/src/components/RightToolbar/index.vue b/src/components/RightToolbar/index.vue new file mode 100644 index 0000000..527e07c --- /dev/null +++ b/src/components/RightToolbar/index.vue @@ -0,0 +1,104 @@ +<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()" /> + </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, + }, + gutter: { + type: Number, + default: 10, + }, + }, + computed: { + style() { + const ret = {}; + if (this.gutter) { + ret.marginRight = `${this.gutter / 2}px`; + } + return ret; + } + }, + created() { + // 鏄鹃殣鍒楀垵濮嬮粯璁ら殣钘忓垪 + 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); + } + }, + // 鎵撳紑鏄鹃殣鍒梔ialog + showColumn() { + this.open = true; + }, + }, +}; +</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; +} +</style> diff --git a/src/components/RuoYi/Doc/index.vue b/src/components/RuoYi/Doc/index.vue new file mode 100644 index 0000000..75fa864 --- /dev/null +++ b/src/components/RuoYi/Doc/index.vue @@ -0,0 +1,21 @@ +<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> \ No newline at end of file diff --git a/src/components/RuoYi/Git/index.vue b/src/components/RuoYi/Git/index.vue new file mode 100644 index 0000000..bdafbae --- /dev/null +++ b/src/components/RuoYi/Git/index.vue @@ -0,0 +1,21 @@ +<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> \ No newline at end of file diff --git a/src/components/Screenfull/index.vue b/src/components/Screenfull/index.vue new file mode 100644 index 0000000..d4e539c --- /dev/null +++ b/src/components/Screenfull/index.vue @@ -0,0 +1,57 @@ +<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> diff --git a/src/components/SizeSelect/index.vue b/src/components/SizeSelect/index.vue new file mode 100644 index 0000000..069b5de --- /dev/null +++ b/src/components/SizeSelect/index.vue @@ -0,0 +1,56 @@ +<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> diff --git a/src/components/SvgIcon/index.vue b/src/components/SvgIcon/index.vue new file mode 100644 index 0000000..e4bf5ad --- /dev/null +++ b/src/components/SvgIcon/index.vue @@ -0,0 +1,61 @@ +<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> diff --git a/src/components/ThemePicker/index.vue b/src/components/ThemePicker/index.vue new file mode 100644 index 0000000..1714e1f --- /dev/null +++ b/src/components/ThemePicker/index.vue @@ -0,0 +1,173 @@ +<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 version = require('element-ui/package.json').version // element-ui version from node_modules +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 = `https://unpkg.com/element-ui@${version}/lib/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> diff --git a/src/components/TopNav/index.vue b/src/components/TopNav/index.vue new file mode 100644 index 0000000..5f0edbe --- /dev/null +++ b/src/components/TopNav/index.vue @@ -0,0 +1,185 @@ +<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 :icon-class="item.meta.icon" /> + {{ item.meta.title }}</el-menu-item + > + </template> + + <!-- 椤堕儴鑿滃崟瓒呭嚭鏁伴噺鎶樺彔 --> + <el-submenu :style="{'--theme': theme}" index="more" 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 :icon-class="item.meta.icon" /> + {{ item.meta.title }}</el-menu-item + > + </template> + </el-submenu> + </el-menu> +</template> + +<script> +import { constantRoutes } from "@/router"; + +// 闅愯棌渚ц竟鏍忚矾鐢� +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 === "/") { + 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(!this.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); + activePath = "/" + tmpPath.substring(0, tmpPath.indexOf("/")); + if (!this.$route.meta.link) { + 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 (this.ishttp(key)) { + // http(s):// 璺緞鏂扮獥鍙f墦寮� + window.open(key, "_blank"); + } else if (!route || !route.children) { + // 娌℃湁瀛愯矾鐢辫矾寰勫唴閮ㄦ墦寮� + 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); + } + }, + ishttp(url) { + return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1 + } + }, +}; +</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> diff --git a/src/components/iFrame/index.vue b/src/components/iFrame/index.vue new file mode 100644 index 0000000..426857f --- /dev/null +++ b/src/components/iFrame/index.vue @@ -0,0 +1,36 @@ +<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> diff --git a/src/directive/dialog/drag.js b/src/directive/dialog/drag.js new file mode 100644 index 0000000..2e82346 --- /dev/null +++ b/src/directive/dialog/drag.js @@ -0,0 +1,64 @@ +/** +* 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 姝e垯鍖归厤鏇挎崲 + let styL, styT; + + // 娉ㄦ剰鍦╥e涓� 绗竴娆¤幏鍙栧埌鐨勫�间负缁勪欢鑷甫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; + }; + } + } +}; \ No newline at end of file diff --git a/src/directive/dialog/dragHeight.js b/src/directive/dialog/dragHeight.js new file mode 100644 index 0000000..d1590f8 --- /dev/null +++ b/src/directive/dialog/dragHeight.js @@ -0,0 +1,34 @@ +/** +* 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); + } +} \ No newline at end of file diff --git a/src/directive/dialog/dragWidth.js b/src/directive/dialog/dragWidth.js new file mode 100644 index 0000000..d5cda3a --- /dev/null +++ b/src/directive/dialog/dragWidth.js @@ -0,0 +1,30 @@ +/** +* 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); + } +} \ No newline at end of file diff --git a/src/directive/index.js b/src/directive/index.js new file mode 100644 index 0000000..b9b07da --- /dev/null +++ b/src/directive/index.js @@ -0,0 +1,23 @@ +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); // eslint-disable-line +} + +export default install diff --git a/src/directive/module/clipboard.js b/src/directive/module/clipboard.js new file mode 100644 index 0000000..635315a --- /dev/null +++ b/src/directive/module/clipboard.js @@ -0,0 +1,54 @@ +/** +* 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; + } + } +} diff --git a/src/directive/permission/hasPermi.js b/src/directive/permission/hasPermi.js new file mode 100644 index 0000000..719536c --- /dev/null +++ b/src/directive/permission/hasPermi.js @@ -0,0 +1,28 @@ + /** + * 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(`璇疯缃搷浣滄潈闄愭爣绛惧�糮) + } + } +} diff --git a/src/directive/permission/hasRole.js b/src/directive/permission/hasRole.js new file mode 100644 index 0000000..eec4a5b --- /dev/null +++ b/src/directive/permission/hasRole.js @@ -0,0 +1,28 @@ + /** + * 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(`璇疯缃鑹叉潈闄愭爣绛惧��"`) + } + } +} diff --git a/src/layout/components/AppMain.vue b/src/layout/components/AppMain.vue new file mode 100644 index 0000000..f4e74db --- /dev/null +++ b/src/layout/components/AppMain.vue @@ -0,0 +1,61 @@ +<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 /> + </section> +</template> + +<script> +import iframeToggle from "./IframeToggle/index" + +export default { + name: 'AppMain', + components: { iframeToggle }, + computed: { + cachedViews() { + return this.$store.state.tagsView.cachedViews + }, + key() { + return this.$route.path + } + } +} +</script> + +<style lang="scss" scoped> +.app-main { + /* 50= navbar 50 */ + min-height: calc(100vh - 50px); + width: 100%; + position: relative; + overflow: hidden; +} + +.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: 17px; + } +} +</style> diff --git a/src/layout/components/IframeToggle/index.vue b/src/layout/components/IframeToggle/index.vue new file mode 100644 index 0000000..26e17c1 --- /dev/null +++ b/src/layout/components/IframeToggle/index.vue @@ -0,0 +1,24 @@ +<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="item.meta.link" + ></inner-link> + </transition-group> +</template> + +<script> +import InnerLink from "../InnerLink/index" + +export default { + components: { InnerLink }, + computed: { + iframeViews() { + return this.$store.state.tagsView.iframeViews + } + } +} +</script> diff --git a/src/layout/components/InnerLink/index.vue b/src/layout/components/InnerLink/index.vue new file mode 100644 index 0000000..badefc5 --- /dev/null +++ b/src/layout/components/InnerLink/index.vue @@ -0,0 +1,47 @@ +<template> + <div :style="'height:' + height" v-loading="loading" element-loading-text="姝e湪鍔犺浇椤甸潰锛岃绋嶅�欙紒"> + <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> diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue new file mode 100644 index 0000000..39b3dad --- /dev/null +++ b/src/layout/components/Navbar.vue @@ -0,0 +1,200 @@ +<template> + <div class="navbar"> + <hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> + + <breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/> + <top-nav id="topmenu-container" class="topmenu-container" v-if="topNav"/> + + <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="click"> + <div class="avatar-wrapper"> + <img :src="avatar" class="user-avatar"> + <i class="el-icon-caret-bottom" /> + </div> + <el-dropdown-menu slot="dropdown"> + <router-link to="/user/profile"> + <el-dropdown-item>涓汉涓績</el-dropdown-item> + </router-link> + <el-dropdown-item @click.native="setting = true"> + <span>甯冨眬璁剧疆</span> + </el-dropdown-item> + <el-dropdown-item divided @click.native="logout"> + <span>閫�鍑虹櫥褰�</span> + </el-dropdown-item> + </el-dropdown-menu> + </el-dropdown> + </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 { + components: { + Breadcrumb, + TopNav, + Hamburger, + Screenfull, + SizeSelect, + Search, + RuoYiGit, + RuoYiDoc + }, + computed: { + ...mapGetters([ + 'sidebar', + 'avatar', + 'device' + ]), + setting: { + get() { + return this.$store.state.settings.showSettings + }, + set(val) { + this.$store.dispatch('settings/changeSetting', { + key: 'showSettings', + value: val + }) + } + }, + topNav: { + get() { + return this.$store.state.settings.topNav + } + } + }, + methods: { + toggleSideBar() { + this.$store.dispatch('app/toggleSideBar') + }, + async 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: 30px; + + .avatar-wrapper { + margin-top: 5px; + position: relative; + + .user-avatar { + cursor: pointer; + width: 40px; + height: 40px; + border-radius: 10px; + } + + .el-icon-caret-bottom { + cursor: pointer; + position: absolute; + right: -20px; + top: 25px; + font-size: 12px; + } + } + } + } +} +</style> diff --git a/src/layout/components/Settings/index.vue b/src/layout/components/Settings/index.vue new file mode 100644 index 0000000..8b49842 --- /dev/null +++ b/src/layout/components/Settings/index.vue @@ -0,0 +1,260 @@ +<template> + <el-drawer size="280px" :visible="visible" :with-header="false" :append-to-body="true" :show-close="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>鍥哄畾 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> + + <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 }, + data() { + return { + theme: this.$store.state.settings.theme, + sideTheme: this.$store.state.settings.sideTheme + }; + }, + computed: { + visible: { + get() { + return this.$store.state.settings.showSettings + } + }, + 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 + }) + } + }, + 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 + }) + } + }, + }, + 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; + }, + saveSetting() { + this.$modal.loading("姝e湪淇濆瓨鍒版湰鍦帮紝璇风◢鍊�..."); + this.$cache.local.set( + "layout-setting", + `{ + "topNav":${this.topNav}, + "tagsView":${this.tagsView}, + "fixedHeader":${this.fixedHeader}, + "sidebarLogo":${this.sidebarLogo}, + "dynamicTitle":${this.dynamicTitle}, + "sideTheme":"${this.sideTheme}", + "theme":"${this.theme}" + }` + ); + setTimeout(this.$modal.closeLoading(), 1000) + }, + resetSetting() { + this.$modal.loading("姝e湪娓呴櫎璁剧疆缂撳瓨骞跺埛鏂帮紝璇风◢鍊�..."); + 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> diff --git a/src/layout/components/Sidebar/FixiOSBug.js b/src/layout/components/Sidebar/FixiOSBug.js new file mode 100644 index 0000000..6823726 --- /dev/null +++ b/src/layout/components/Sidebar/FixiOSBug.js @@ -0,0 +1,25 @@ +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) + } + } + } + } +} diff --git a/src/layout/components/Sidebar/Item.vue b/src/layout/components/Sidebar/Item.vue new file mode 100644 index 0000000..be3285d --- /dev/null +++ b/src/layout/components/Sidebar/Item.vue @@ -0,0 +1,33 @@ +<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> diff --git a/src/layout/components/Sidebar/Link.vue b/src/layout/components/Sidebar/Link.vue new file mode 100644 index 0000000..8b0bc93 --- /dev/null +++ b/src/layout/components/Sidebar/Link.vue @@ -0,0 +1,43 @@ +<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> diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue new file mode 100644 index 0000000..0e7a4a3 --- /dev/null +++ b/src/layout/components/Sidebar/Logo.vue @@ -0,0 +1,92 @@ +<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" /> + <span class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </span> + </router-link> + </transition> + </div> +</template> + +<script> +import logoImg from '@/assets/logo/logo.gif' +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: 'FastBee', + 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; + overflow: hidden; + margin-left:15px; + + & .sidebar-logo-link { + height: 100%; + width: 100%; + + & .sidebar-logo { + width: 32px; + height: 32px; + vertical-align: middle; + } + + & .sidebar-title { + display: inline-block; + margin: 0; + color: #fff; + font-weight: 400; + line-height: 50px; + font-size: 20px; + font-family:"寰蒋闆呴粦"; + vertical-align: middle; + } + } + + &.collapse { + .sidebar-logo { + margin-right: 0px; + } + } +} +</style> diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue new file mode 100644 index 0000000..4853fbb --- /dev/null +++ b/src/layout/components/Sidebar/SidebarItem.vue @@ -0,0 +1,100 @@ +<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 in item.children" + :key="child.path" + :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 + } else { + // 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> diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue new file mode 100644 index 0000000..51d0839 --- /dev/null +++ b/src/layout/components/Sidebar/index.vue @@ -0,0 +1,57 @@ +<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> diff --git a/src/layout/components/TagsView/ScrollPane.vue b/src/layout/components/TagsView/ScrollPane.vue new file mode 100644 index 0000000..bb753a1 --- /dev/null +++ b/src/layout/components/TagsView/ScrollPane.vue @@ -0,0 +1,94 @@ +<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> diff --git a/src/layout/components/TagsView/index.vue b/src/layout/components/TagsView/index.vue new file mode 100644 index 0000000..cc98071 --- /dev/null +++ b/src/layout/components/TagsView/index.vue @@ -0,0 +1,332 @@ +<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="isActive(tag)?'active':''" + :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)" + > + {{ 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; + } + }, + 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 === this.visitedViews[1].fullPath || this.selectedTag.fullPath === '/index' + } 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) + if (this.$route.meta.link) { + this.$store.dispatch('tagsView/addIframeView', this.$route) + } + } + return false + }, + 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).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; + } + } + } + } + .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> diff --git a/src/layout/components/index.js b/src/layout/components/index.js new file mode 100644 index 0000000..104bd3a --- /dev/null +++ b/src/layout/components/index.js @@ -0,0 +1,5 @@ +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' diff --git a/src/layout/index.vue b/src/layout/index.vue new file mode 100644 index 0000000..f048657 --- /dev/null +++ b/src/layout/index.vue @@ -0,0 +1,111 @@ +<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 /> + <tags-view v-if="needTagsView" /> + </div> + <app-main /> + <right-panel> + <settings /> + </right-panel> + </div> + </div> +</template> + +<script> +import RightPanel from '@/components/RightPanel' +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, + RightPanel, + 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 }) + } + } +} +</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> diff --git a/src/layout/mixin/ResizeHandler.js b/src/layout/mixin/ResizeHandler.js new file mode 100644 index 0000000..e8d0df8 --- /dev/null +++ b/src/layout/mixin/ResizeHandler.js @@ -0,0 +1,45 @@ +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 }) + } + } + } + } +} diff --git a/src/lib/currency.js b/src/lib/currency.js new file mode 100644 index 0000000..b02072c --- /dev/null +++ b/src/lib/currency.js @@ -0,0 +1,431 @@ +/* + * @Author: daidai + * @Date: 2021-12-06 15:53:24 + * @LastEditors: Please set LastEditors + * @LastEditTime: 2022-04-22 09:31:24 + * @FilePath: \web-pc\src\lib\currency.js + */ +import router from '@/router' +import { isString, isHtmlElement } from './types' +export const returnWeek = () => { + var week = new Date().getDay(); + switch (week) { + case 1: + return '鍛ㄤ竴' + case 2: + return '鍛ㄤ簩' + case 3: + return '鍛ㄤ笁' + case 4: + return '鍛ㄥ洓' + case 5: + return '鍛ㄤ簲' + case 6: + return '鍛ㄥ叚' + case 0: + return '鍛ㄦ棩' + } +} + +/** + * 鑾峰彇uuid + */ +export function getUUID() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { + return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16) + }) +} + +/** + * 鏄惁鏈夋潈闄� + * @param {*} key + */ +export function isAuth(key) { + // console.log("key",key,sessionStorage.getItem('permissions')) + // if(process.env.VUE_APP_CONFIG=="dev"){ + // return true + // } + return JSON.parse(sessionStorage.getItem('permissions') || '[]').indexOf(key) !== -1 || false +} +export const rowClassName = ({ row, rowIndex }) => { + if (rowIndex % 2 == 0) { + return 'lightColour'; + } else { + return 'DarkColor'; + } +} + +export const getToken = () => { + return localStorage.getItem("token"); +} +//璺宠浆褰撳墠椤甸潰骞朵紶鍙� +export const currentQuery = (param) => { + let newParam = { ...param } + for (let i in newParam) { + if (newParam[i] === "") { + delete newParam[i] + } + } + // console.log(newParam) + router.push({ + path: router.currentRoute.path, + query: newParam + }) +} +/** + * 鏍戝舰鏁版嵁杞崲 + * @param {*} data + * @param {*} id + * @param {*} pid + * @param {*} order + */ +export function treeDataTranslate(data, id, pid, order) { + // console.log(Array.isArray(data)) + if (data == null || !Array.isArray(data)) { + return []; + } + if (order) { + data.sort(function (a, b) { + return a[order] - b[order]; + }) + } + // console.log(data) + var res = [] + var temp = {} + for (var i = 0; i < data.length; i++) { + temp[data[i][id]] = data[i] + } + for (var k = 0; k < data.length; k++) { + + if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) { + if (!temp[data[k][pid]]['subs']) { + temp[data[k][pid]]['subs'] = [] + } + if (!temp[data[k][pid]]['_level']) { + temp[data[k][pid]]['_level'] = 1 + } + data[k]['_level'] = temp[data[k][pid]]._level + 1 + temp[data[k][pid]]['subs'].push(data[k]) + + + } else { + res.push(data[k]) + } + } + // console.log(outurls) + // console.log(res) + return res +} + +//甯︿簡涓�涓� margin-left +export const dragss = (e, marginleft) => { + + let odiv = e.currentTarget.parentElement; + let disX = e.clientX - odiv.offsetLeft; + let disY = e.clientY - odiv.offsetTop; + document.onmousemove = (e) => { + odiv.style.left = e.clientX - disX + marginleft + 'px'; + odiv.style.top = e.clientY - disY + 'px'; + return false; + }; + document.onmouseup = (e) => { + document.onmousemove = null; + document.onmouseup = null; + }; + return false; +} + +//杞琤ase64 + +export const turnStr = (data) => { + return window.btoa(window.encodeURI(JSON.stringify(data))); +} +// 楠岃瘉鍙兘杈撳叆鏁板瓧鍜屽皬鏁帮紝灏忔暟涓斿彧鑳借緭鍏�2浣嶏紝绗竴浣嶄笉鑳借緭鍏ュ皬鏁扮偣 +// .replace(/[^\d.]/g, '') +// .replace(/\.{2,}/g, '.') +// .replace('.', '$#$') +// .replace(/\./g, '') +// .replace('$#$', '.') +// .replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3') +// .replace(/^\./g, '') +/** + * 娓呴櫎鐧诲綍淇℃伅 + */ +export function clearLoginInfo() { + router.options.isAddDynamicMenuRoutes = false; + localStorage.removeItem('token') + sessionStorage.removeItem("menuList") + sessionStorage.removeItem("permissions") +} + + +//瀵硅薄鎷兼垚璺緞浼犲弬 +export const convertObj = (data) => { + var _result = []; + for (var key in data) { + var value = data[key]; + if (value.constructor == Array) { + value.forEach(function (_value) { + _result.push(key + "=" + _value); + }); + } else { + _result.push(key + '=' + value); + } + } + return _result.join('&'); +} +//鍒ゆ柇娴忚鍣� +function getExplorer() { + var explorer = window.navigator.userAgent; + if (explorer.indexOf('MSIE') >= 0) { + return 'ie'; // ie + } else if (explorer.indexOf('Firefox') >= 0) { + return 'Firefox'; // firefox + } else if (explorer.indexOf('Chrome') >= 0) { + return 'Chrome'; // Chrome + } else if (explorer.indexOf('Opera') >= 0) { + return 'Opera'; // Opera + } else if (explorer.indexOf('Safari') >= 0) { + return 'Safari'; // Safari + } else if (!!explorer.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) { + return 'IOS'; + } else if (u.indexOf('Android') > -1 || u.indexOf('Adr') > -1) { + return 'Android'; + } else { + return explorer + } +}; + +//瀵煎嚭鏂囨。娴� +export const exportFile = (data, name) => { + return new Promise((resolve, reject) => { + let types = getExplorer() + if (types == 'IOS') { + resolve({ + success: false, + msg: "璇蜂娇鐢ㄨ澶囪嚜甯︽祻瑙堝櫒瀵煎嚭锛�" + }) + return + } + if (data.type && data.type.indexOf('application/vnd.ms-excel') >= 0) { + // console.log(data) + try { + let blob = new Blob([data], { + type:data.type|| 'application/vnd.ms-excel;charset=UTF-8' + }) + if (window.navigator && window.navigator.msSaveOrOpenBlob) { + window.navigator.msSaveOrOpenBlob(blob, name); + } else { + const link = document.createElement('a') + link.style.display = 'none'; + link.href = URL.createObjectURL(blob); + if (types == 'Safari') { + link.download = `${name || "鏈懡鍚�"}`; + } else { + link.download = `${name || "鏈懡鍚�"}.xlsx`; + } + // Safari thinks _blank anchor are pop ups. We only want to set _blank + // target if the browser does not support the HTML5 download attribute. + // This allows you to download files in desktop safari if pop up blocking + // is enabled. + if (typeof link.download === 'unde fined') { + tempLink.setAttribute('target', '_blank'); + } + document.body.appendChild(link) + link.click() + // Fixes "webkit blob resource error 1" + let timer = setTimeout(function () { + document.body.removeChild(link) + window.URL.revokeObjectURL(link.href); + clearTimeout(timer) + }, 200) + } + resolve({ + success: true, + msg: "瀵煎嚭鎴愬姛" + }) + } catch (error) { + resolve({ + success: false, + msg: "鏈煡寮傚父锛岃鑱旂郴绠$悊鍛橈紒" + }) + } + } else { + // console.log(data) + readFile(data).then(res => { + resolve(res) + }).catch(err => { + resolve({ + success: false, + msg: "鏈煡寮傚父锛岃鑱旂郴绠$悊鍛橈紒" + }) + }) + } + }) + +} +//闃呰 blod +export const readFile = (data) => { + return new Promise((resole, reject) => { + if (Object.prototype.toString.call(data)==='[object Blob]') { + let reader = new FileReader() + reader.readAsText(data, 'utf-8') + reader.onload = (e) => { + console.log('--瀵煎嚭--', JSON.parse(reader.result)) + let result = JSON.parse(reader.result) + if (result.code == 401) { + router.push("/login") + } + resole(result) + } + } else { + resole(data) + } + + // reader.readAsText(data) + }) + +} + +//element 鏃堕棿閫夋嫨 + + + +export const shortcuts = [{ + text: '鏈�杩戜竴鍛�', + onClick(picker) { + const end = new Date(); + const start = new Date(); + start.setTime(start.getTime() - 3600 * 1000 * 24 * 7); + picker.$emit('pick', [start, end]); + } +}, { + text: '鏈�杩戜竴涓湀', + onClick(picker) { + const end = new Date(); + const start = new Date(); + start.setTime(start.getTime() - 3600 * 1000 * 24 * 30); + picker.$emit('pick', [start, end]); + } +}, { + text: '鏈�杩戜笁涓湀', + onClick(picker) { + const end = new Date(); + const start = new Date(); + start.setTime(start.getTime() - 3600 * 1000 * 24 * 89); + picker.$emit('pick', [start, end]); + } +}] +export const pickerOptions = { + shortcuts: shortcuts +} +/** + * 娓呴櫎鐩稿悓 + * @param {*} origin + * @param {*} target + */ +export const ArrayCleanRepeat = (origin, target) => { + if (target) origin = origin.concat(target); + const result = [] + const tagObj = {} + for (const i of origin) { + if (!tagObj[i]) { + result.push(i) + tagObj[i] = 1 + } + } + return result +} +/** + * @description: + * @param {file:Object} 鏂囦欢 + * @return {*} + */ +export const beforeUpoads = (file) => { + // console.log(file) + var testmsg = file.name.substring(file.name.lastIndexOf('.') + 1) + if ( + testmsg != 'png' && + testmsg != 'jpg' && + testmsg != 'jpeg' && + testmsg != 'webp' + ) { + // testmsg != 'gif' && + return { + success: false, + msg: "涓婁紶鍥剧墖鏍煎紡涓嶆纭紒" + } + } + const if10M = file.size / 1024 / 1024 < 20 + if (!if10M) { + return { + success: false, + msg: "涓婁紶鍥剧墖澶у皬涓嶈兘瓒呰繃20M!" + } + } + // console.log("涓婁紶鍓�",file, this.filelist) + return { + success: true + } +} +//澶嶅埗鏂囧瓧 +export const copy = (value) => { + let transfer = document.createElement('input') + + document.body.appendChild(transfer) + transfer.value = value // 杩欓噷琛ㄧず鎯宠澶嶅埗鐨勫唴瀹� + transfer.focus() + transfer.select() + if (document.execCommand('copy')) { + document.execCommand('copy') + } + transfer.blur() + document.body.removeChild(transfer) + //閫変腑鏂囧瓧 + // let range = document.createRange() + // let referenceNode = this.$refs.xy + // range.selectNodeContents(referenceNode) + // var selection = window.getSelection() + // selection.removeAllRanges() + // selection.addRange(range) +} +// 鍙栧嚭涓や釜鏁扮粍鐨勪笉鍚屽厓绱� +export const getArrDifference = (arr1, arr2) => { + return arr1.concat(arr2).filter(function (v, i, arr) { + return arr.indexOf(v) === arr.lastIndexOf(v); + }); +} + +/** + * 琛ㄦ牸鏈�澶ч珮搴� + * @param {ElementDom} dom + * @param {Boolean} isPaging 鏄惁鎷ユ湁鍒嗛〉 false 娌℃湁 || true 鏈� 榛樿鏈� + * @returns + */ +export const tableHeight = (dom,isPaging=true) => { + //瀹氫綅鐖剁骇鍒版枃妗i珮搴� + if (isString(dom)) { + dom = document.querySelector(dom) + // if (dom) { + // return window.innerHeight - top + // } + } + if (isHtmlElement(dom)) { + var parent = dom.offsetParent; + var top = dom.offsetTop + if(isPaging){ + top= top+ 63 + 4 + }else{ + top= top+ 16 + } + while (parent != null) { + top += parent.offsetTop; + parent = parent.offsetParent; + }; + return window.innerHeight - top + } + + return null +} + +// diff --git a/src/lib/dd-moment.js b/src/lib/dd-moment.js new file mode 100644 index 0000000..5c42864 --- /dev/null +++ b/src/lib/dd-moment.js @@ -0,0 +1,93 @@ + +/* + * @Author: daidai + * @Date: 2021-12-16 14:40:18 + * @LastEditors: Please set LastEditors + * @LastEditTime: 2022-04-19 14:44:14 + * @FilePath: \web-pc\src\lib\dd-moment.js + */ + + +const DDmoment = function (date) { + let time; + if (!date) { + time = new Date() + }else if(date){ + time=new Date(date); + } + return { + time, + format, + subtract, + getTime, + } +} +/** + * @content 鍓嶅灏戝ぉ + * @param days 澶� || years 骞� || months 鏈� || weeks 鍛� + * @returns + */ +function subtract(num, type) { + let time = this.time + time.setTime(time.getTime()-getNeedTime(num, type)) + time=new Date(time) + return { + time, + format, + getTime + } +} +/** + * @param Yy骞� || M 鏈� || Dd 鏃� || Hh 鏃� || m 鍒� || Ss 绉� + * @returns + */ +function format(fmt) { + let date = this.time + let ret; + const opt = { + "Y+": date.getFullYear().toString(), // 骞� + "y+": date.getFullYear().toString(), // 骞� + "M+": (date.getMonth() + 1).toString(), // 鏈� + "d+": date.getDate().toString(), // 鏃� + "D+": date.getDate().toString(), // 鏃� + "h+": date.getHours().toString(), // 鏃� + "H+": date.getHours().toString(), // 鏃� + "m+": date.getMinutes().toString(), // 鍒� + "S+": date.getSeconds().toString(), // 绉� + "s+": date.getSeconds().toString() // 绉� + // 鏈夊叾浠栨牸寮忓寲瀛楃闇�姹傚彲浠ョ户缁坊鍔狅紝蹇呴』杞寲鎴愬瓧绗︿覆 + }; + for (let k in opt) { + ret = new RegExp("(" + k + ")").exec(fmt); + if (ret) { + fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0"))) + }; + }; + return fmt; +} +//鏃堕棿鎴宠浆鏃堕棿 +function getTime() { + return new Date(this.time) +} +//鑾峰彇闇�瑕佺殑鏃堕棿 +function getNeedTime(num, type) { + let time=0 + switch (type) { + case "days": + time= 3600 * 1000 * 24 * num; + break; + case "years": + time=3600 * 1000 * 24 *365 *num; + break; + case "months": + time = 3600 * 1000 * 24 *30* num; + break; + case "weeks": + time= 3600 * 1000 * 24 *7* num; + break; + default: + break; + } + return time; +} +export default DDmoment \ No newline at end of file diff --git a/src/lib/index.js b/src/lib/index.js new file mode 100644 index 0000000..188c948 --- /dev/null +++ b/src/lib/index.js @@ -0,0 +1,9 @@ +import DDmoment from "./dd-moment" +import { colors,colors2 } from "./modules/echarts-options" +import { shortcuts } from "./currency"; + +export {DDmoment,colors,colors2} + +export { + shortcuts +} \ No newline at end of file diff --git a/src/lib/types.js b/src/lib/types.js new file mode 100644 index 0000000..5015768 --- /dev/null +++ b/src/lib/types.js @@ -0,0 +1,46 @@ +/* + * @Author: daidai + * @Date: 2021-12-14 09:15:11 + * @LastEditors: Please set LastEditors + * @LastEditTime: 2022-04-25 10:11:04 + * @FilePath: \web-pc\src\lib\types.js + */ + +export function hasOwn(obj, key) { + return hasOwnProperty.call(obj, key); + }; + export function isVNode(node) { + return node !== null && typeof node === 'object' && hasOwn(node, 'componentOptions'); + }; + +// 鏄惁瀛楃涓� +export function isString2(str) { + return (typeof str == 'string') && str.constructor == String; +} +export function isString(obj) { + return Object.prototype.toString.call(obj) === '[object String]'; +} +export function isObject(obj) { + return Object.prototype.toString.call(obj) === '[object Object]'; +} +export function isNumber(obj) { + return Object.prototype.toString.call(obj) === '[object Number]'; +} +// 鏄惁瀹屾暣鐨� +export function isDef(val) { + return val !== undefined && val !== null; +} +// +export function isKorean(text) { + const reg = /([(\uAC00-\uD7AF)|(\u3130-\u318F)])+/gi; + return reg.test(text); +} + +export function isHtmlElement(node) { + return node && node.nodeType === Node.ELEMENT_NODE; +} +export const isUndefined = (val) => { + return val === void 0; +}; + + diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..f953bde --- /dev/null +++ b/src/main.js @@ -0,0 +1,126 @@ +import Vue from 'vue' + +import Cookies from 'js-cookie' + +import Element from 'element-ui' +import './assets/styles/element-variables.scss' +import busEvent from '@/utils/busEvent' + +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 VueMeta from 'vue-meta' +// 瀛楀吀鏁版嵁缁勪欢 +import DictData from '@/components/DictData' +// Echart +import * as echarts from 'echarts' +// 涓�閿鍒剁矘璐存澘缁勪欢 +import VueClipboard from 'vue-clipboard2' +// Mqtt宸ュ叿 +import mqttTool from '@/utils/mqttTool' + +import ItemWrap from './views/bigScreen/components/item-wrap/item-wrap.vue' +import Message from './views/bigScreen/components/message/message.vue' +import Reacquire from './views/bigScreen/components/reacquire/reacquire.vue' +import {loading,borderBox13,digitalFlop,waterLevelPond,scrollBoard,capsuleChart,borderBox8,decoration12,decoration3,decoration9,activeRingChart} from '@jiaminghi/data-view' + +// datav缁勪欢 ,浼氬鑷寸敓鎴愭枃浠舵棤娉曟墦寮� +Vue.use(loading) +Vue.use(borderBox13) +Vue.use(borderBox8) +Vue.use(digitalFlop) +Vue.use(capsuleChart) +Vue.use(waterLevelPond) +Vue.use(scrollBoard) +Vue.use(decoration12) +Vue.use(activeRingChart) +Vue.use(decoration3) +Vue.use(decoration9) + +// 鑷畾涔夌粍浠� +Vue.component("ItemWrap",ItemWrap) +Vue.component("Message",Message) +Vue.component("Reacquire",Reacquire) + + +// 鍏ㄥ眬鏂规硶鎸傝浇 +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.prototype.$echarts = echarts +Vue.prototype.$mqttTool = mqttTool +Vue.prototype.$busEvent = busEvent + +// 鍏ㄥ眬缁勪欢鎸傝浇 +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(VueClipboard) +Vue.use(directive) +Vue.use(plugins) +Vue.use(VueMeta) +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) +}) + +// 琛ㄦ牸甯﹁竟妗� +Element.Table.props.border = { + default:true, + type:Boolean +} diff --git a/src/permission.js b/src/permission.js new file mode 100644 index 0000000..6bb0a1f --- /dev/null +++ b/src/permission.js @@ -0,0 +1,56 @@ +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 { isRelogin } from '@/utils/request' + +NProgress.configure({ showSpinner: false }) + +const whiteList = ['/login', '/auth-redirect', '/bind', '/register'] + +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 (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 (whiteList.indexOf(to.path) !== -1) { + // 鍦ㄥ厤鐧诲綍鐧藉悕鍗曪紝鐩存帴杩涘叆 + next() + } else { + next(`/login?redirect=${to.fullPath}`) // 鍚﹀垯鍏ㄩ儴閲嶅畾鍚戝埌鐧诲綍椤� + NProgress.done() + } + } +}) + +router.afterEach(() => { + NProgress.done() +}) diff --git a/src/plugins/auth.js b/src/plugins/auth.js new file mode 100644 index 0000000..6c6bc24 --- /dev/null +++ b/src/plugins/auth.js @@ -0,0 +1,60 @@ +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) + }) + } +} diff --git a/src/plugins/cache.js b/src/plugins/cache.js new file mode 100644 index 0000000..6b5c00b --- /dev/null +++ b/src/plugins/cache.js @@ -0,0 +1,77 @@ +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) + } + }, + 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) + } + }, + remove (key) { + localStorage.removeItem(key); + } +} + +export default { + /** + * 浼氳瘽绾х紦瀛� + */ + session: sessionCache, + /** + * 鏈湴缂撳瓨 + */ + local: localCache +} diff --git a/src/plugins/download.js b/src/plugins/download.js new file mode 100644 index 0000000..a3bb8c4 --- /dev/null +++ b/src/plugins/download.js @@ -0,0 +1,72 @@ +import axios from 'axios' +import { 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 + +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(async (res) => { + const isLogin = await blobValidate(res.data); + if (isLogin) { + 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(async (res) => { + const isLogin = await blobValidate(res.data); + if (isLogin) { + 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 + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then(async (res) => { + const isLogin = await blobValidate(res.data); + if (isLogin) { + const blob = new Blob([res.data], { type: 'application/zip' }) + this.saveAs(blob, name) + } else { + this.printErrMsg(res.data); + } + }) + }, + 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); + } +} + diff --git a/src/plugins/index.js b/src/plugins/index.js new file mode 100644 index 0000000..d000f2d --- /dev/null +++ b/src/plugins/index.js @@ -0,0 +1,20 @@ +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 + } +} diff --git a/src/plugins/modal.js b/src/plugins/modal.js new file mode 100644 index 0000000..b37ca14 --- /dev/null +++ b/src/plugins/modal.js @@ -0,0 +1,83 @@ +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(); + } +} diff --git a/src/plugins/tab.js b/src/plugins/tab.js new file mode 100644 index 0000000..cade9f7 --- /dev/null +++ b/src/plugins/tab.js @@ -0,0 +1,67 @@ +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(({ lastPath }) => { + return router.push(lastPath || '/'); + }); + } + return store.dispatch('tagsView/delView', obj); + }, + // 鍏抽棴鎵�鏈塼ab椤电 + 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) { + var 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); + } +} diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..2e20e27 --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,203 @@ +import Vue from 'vue' +import Router from 'vue-router' + +Vue.use(Router) + +/* Layout */ +import Layout from '@/layout' + +/** + * Note: 璺敱閰嶇疆椤� + * + * hidden: true // 褰撹缃� true 鐨勬椂鍊欒璺敱涓嶄細鍐嶄晶杈规爮鍑虹幇 濡�401锛宭ogin绛夐〉闈紝鎴栬�呭涓�浜涚紪杈戦〉闈�/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 // 濡傛灉璁剧疆涓簍rue锛屽垯涓嶄細琚� <keep-alive> 缂撳瓨(榛樿 false) + title: 'title' // 璁剧疆璇ヨ矾鐢卞湪渚ц竟鏍忓拰闈㈠寘灞戜腑灞曠ず鐨勫悕瀛� + icon: 'svg-name' // 璁剧疆璇ヨ矾鐢辩殑鍥炬爣锛屽搴旇矾寰剆rc/assets/icons/svg + breadcrumb: false // 濡傛灉璁剧疆涓篺alse锛屽垯涓嶄細鍦╞readcrumb闈㈠寘灞戜腑鏄剧ず + activeMenu: '/system/user' // 褰撹矾鐢辫缃簡璇ュ睘鎬э紝鍒欎細楂樹寒鐩稿搴旂殑渚ц竟鏍忋�� + } + */ + +// 鍏叡璺敱 +export const constantRoutes = [ + { + path: '/redirect', + component: Layout, + hidden: true, + children: [ + { + path: '/redirect/:path(.*)', + component: () => import('@/views/redirect') + } + ] + }, + { + path: '/bigScreen', + component: () => import('@/views/bigScreen/home'), + hidden: true, + meta: { bigScreen: true } + }, + { + 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: '/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' } + } + ] + }, + { + path: '/iot', + component: Layout, + hidden: true, + permissions: ['iot:device:add'], + children: [ + { + path: 'product-edit', + component: () => import('@/views/iot/product/product-edit'), + name: 'ProductEdit', + meta: { title: '缂栬緫浜у搧', activeMenu: '/iot/product',nocache: true} + }, + { + path: 'device-edit', + component: () => import('@/views/iot/device/device-edit'), + name: 'DeviceEdit', + meta: { title: '缂栬緫璁惧', activeMenu: '/iot/device', noCache: true} + } + ] + }, +] + +// 闃叉杩炵画鐐瑰嚮澶氭璺敱鎶ラ敊 +let routerPush = Router.prototype.push; +Router.prototype.push = function push(location) { + return routerPush.call(this, location).catch(err => err) +} + +export default new Router({ + mode: 'history', // 鍘绘帀url涓殑# + scrollBehavior: () => ({ y: 0 }), + routes: constantRoutes +}) diff --git a/src/settings.js b/src/settings.js new file mode 100644 index 0000000..d0640a6 --- /dev/null +++ b/src/settings.js @@ -0,0 +1,44 @@ +module.exports = { + /** + * 渚ц竟鏍忎富棰� 娣辫壊涓婚theme-dark锛屾祬鑹蹭富棰榯heme-light + */ + sideTheme: 'theme-dark', + + /** + * 鏄惁绯荤粺甯冨眬閰嶇疆 + */ + showSettings: false, + + /** + * 鏄惁鏄剧ず椤堕儴瀵艰埅 + */ + topNav: false, + + /** + * 鏄惁鏄剧ず tagsView + */ + tagsView: false, + + /** + * 鏄惁鍥哄畾澶撮儴 + */ + fixedHeader: false, + + /** + * 鏄惁鏄剧ずlogo + */ + sidebarLogo: true, + + /** + * 鏄惁鏄剧ず鍔ㄦ�佹爣棰� + */ + dynamicTitle: false, + + /** + * @type {string | array} 'production' | ['production', 'development'] + * @description Need show err logs component. + * The default is only used in the production env + * If you want to also use it in dev, you can pass ['production', 'development'] + */ + errorLog: 'production' +} diff --git a/src/store/getters.js b/src/store/getters.js new file mode 100644 index 0000000..8adb1b6 --- /dev/null +++ b/src/store/getters.js @@ -0,0 +1,19 @@ +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, + name: state => state.user.name, + 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 diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 0000000..97aaef8 --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,25 @@ +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 diff --git a/src/store/modules/app.js b/src/store/modules/app.js new file mode 100644 index 0000000..3e22d1c --- /dev/null +++ b/src/store/modules/app.js @@ -0,0 +1,66 @@ +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 +} diff --git a/src/store/modules/dict.js b/src/store/modules/dict.js new file mode 100644 index 0000000..f95bead --- /dev/null +++ b/src/store/modules/dict.js @@ -0,0 +1,50 @@ +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, i) + 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 +} + diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js new file mode 100644 index 0000000..2287665 --- /dev/null +++ b/src/store/modules/permission.js @@ -0,0 +1,133 @@ +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, index) => { + if (el.children && el.children.length) { + if (el.component === 'ParentView' && !lastRouter) { + el.children.forEach(c => { + c.path = el.path + '/' + c.path + if (c.children && c.children.length) { + children = children.concat(filterChildren(c.children, c)) + return + } + children.push(c) + }) + return + } + } + if (lastRouter) { + el.path = lastRouter.path + '/' + el.path + } + children = children.concat(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 diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js new file mode 100644 index 0000000..2455a1e --- /dev/null +++ b/src/store/modules/settings.js @@ -0,0 +1,42 @@ +import defaultSettings from '@/settings' + +const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = 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, + fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, + sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo, + dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle +} +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 + } +} + +export default { + namespaced: true, + state, + mutations, + actions +} + diff --git a/src/store/modules/tagsView.js b/src/store/modules/tagsView.js new file mode 100644 index 0000000..5fc011c --- /dev/null +++ b/src/store/modules/tagsView.js @@ -0,0 +1,228 @@ +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 +} diff --git a/src/store/modules/user.js b/src/store/modules/user.js new file mode 100644 index 0000000..fb516f3 --- /dev/null +++ b/src/store/modules/user.js @@ -0,0 +1,109 @@ +import { login, logout, getInfo } from '@/api/login'; +import { getToken, setToken, removeToken, setUserId, removeUserId } from '@/utils/auth'; + +const user = { + state: { + token: getToken(), + name: '', + avatar: '', + roles: [], + permissions: [], + }, + + mutations: { + SET_TOKEN: (state, token) => { + state.token = token; + }, + SET_NAME: (state, name) => { + state.name = name; + }, + SET_AVATAR: (state, avatar) => { + state.avatar = avatar; + }, + SET_ROLES: (state, roles) => { + state.roles = roles; + }, + SET_PERMISSIONS: (state, permissions) => { + state.permissions = permissions; + }, + SET_MQTT: (state, mqtt) => { + state.mqtt = mqtt; + }, + }, + + 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; + const avatar = user.avatar === '' || user.avatar == null ? require('@/assets/images/profile.jpg') : process.env.VUE_APP_BASE_API + user.avatar; + if (res.roles && res.roles.length > 0) { + // 楠岃瘉杩斿洖鐨剅oles鏄惁鏄竴涓潪绌烘暟缁� + commit('SET_ROLES', res.roles); + commit('SET_PERMISSIONS', res.permissions); + } else { + commit('SET_ROLES', ['ROLE_DEFAULT']); + } + commit('SET_NAME', user.userName); + commit('SET_AVATAR', avatar); + commit('SET_MQTT', res.mqtt); + setUserId(user.userId); + 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(); + removeUserId(); + resolve(); + }) + .catch((error) => { + reject(error); + }); + }); + }, + + // 鍓嶇 鐧诲嚭 + FedLogOut({ commit }) { + return new Promise((resolve) => { + commit('SET_TOKEN', ''); + removeToken(); + resolve(); + }); + }, + }, +}; + +export default user; diff --git a/src/utils/auth.js b/src/utils/auth.js new file mode 100644 index 0000000..0f67d00 --- /dev/null +++ b/src/utils/auth.js @@ -0,0 +1,28 @@ +import Cookies from 'js-cookie' + +const TokenKey = 'Admin-Token' +const UserId = 'userId' + +export function getToken() { + return Cookies.get(TokenKey) +} + +export function setToken(token) { + return Cookies.set(TokenKey, token) +} + +export function removeToken() { + return Cookies.remove(TokenKey) +} + +export function getUserId() { + return Cookies.get(UserId) +} + +export function setUserId(userId) { + return Cookies.set(UserId, userId) +} + +export function removeUserId() { + return Cookies.remove(UserId) +} diff --git a/src/utils/bigScreen/drawMixin.js b/src/utils/bigScreen/drawMixin.js new file mode 100644 index 0000000..280d238 --- /dev/null +++ b/src/utils/bigScreen/drawMixin.js @@ -0,0 +1,75 @@ +/* + * @Author: daidai + * @Date: 2022-02-28 10:48:02 + * @LastEditors: Please set LastEditors + * @LastEditTime: 2022-04-26 14:55:41 + * @FilePath: \web-pc\src\pages\big-screen\utils\drawMixin.js + */ +// 灞忓箷閫傞厤 mixin 鍑芥暟 + +// * 榛樿缂╂斁鍊� +const scale = { + width: '1', + height: '1', +} + +// * 璁捐绋垮昂瀵革紙px锛� +const baseWidth = 1920 +const baseHeight = 1080 + +// * 闇�淇濇寔鐨勬瘮渚嬶紙榛樿1.77778锛� +const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5)) + +export default { + data() { + return { + // * 瀹氭椂鍑芥暟 + drawTiming: null, + } + }, + computed: { + isScale(){ + return this.$store.state.settings.isScale + } + }, + mounted () { + if(!this.isScale){ + return + } + this.calcRate() + window.addEventListener('resize', this.resize) + }, + beforeDestroy () { + window.removeEventListener('resize', this.resize) + }, + methods: { + calcRate () { + const appRef = this.$refs["appRef"] + if (!appRef) return + // 褰撳墠瀹介珮姣� + const currentRate = parseFloat((window.innerWidth / window.innerHeight).toFixed(5)) + if (appRef) { + if (currentRate > baseProportion) { + // 琛ㄧず鏇村 + scale.width = ((window.innerHeight * baseProportion) / baseWidth).toFixed(5) + scale.height = (window.innerHeight / baseHeight).toFixed(5) + appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)` + } else { + // 琛ㄧず鏇撮珮 + scale.height = ((window.innerWidth / baseProportion) / baseHeight).toFixed(5) + scale.width = (window.innerWidth / baseWidth).toFixed(5) + appRef.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)` + } + } + }, + resize () { + if(!this.isScale){ + return + } + clearTimeout(this.drawTiming) + this.drawTiming = setTimeout(() => { + this.calcRate() + }, 200) + } + }, +} \ No newline at end of file diff --git a/src/utils/bigScreen/index.js b/src/utils/bigScreen/index.js new file mode 100644 index 0000000..5869e72 --- /dev/null +++ b/src/utils/bigScreen/index.js @@ -0,0 +1,58 @@ +/* + * @Author: daidai + * @Date: 2022-02-23 08:59:26 + * @LastEditors: daidai + * @LastEditTime: 2022-02-24 17:11:58 + * @FilePath: \big-screen-vue-datav\src\utils\index.js + */ + +/** + * @param {Function} fn 闃叉姈鍑芥暟 + * @param {Number} delay 寤惰繜鏃堕棿 + */ +export function debounce(fn, delay) { + var timer; + return function () { + var context = this; + var args = arguments; + clearTimeout(timer); + timer = setTimeout(function () { + fn.apply(context, args); + }, delay); + }; +} +/** + * @param {date} time 闇�瑕佽浆鎹㈢殑鏃堕棿 + * @param {String} fmt 闇�瑕佽浆鎹㈢殑鏍煎紡 濡� yyyy-MM-dd銆亂yyy-MM-dd HH:mm:ss + */ +export function formatTime(time, fmt) { + if (!time) return ''; + else { + const date = new Date(time); + const o = { + 'M+': date.getMonth() + 1, + 'd+': date.getDate(), + 'H+': date.getHours(), + 'm+': date.getMinutes(), + 's+': date.getSeconds(), + 'q+': Math.floor((date.getMonth() + 3) / 3), + S: date.getMilliseconds(), + }; + if (/(y+)/.test(fmt)) + fmt = fmt.replace( + RegExp.$1, + (date.getFullYear() + '').substr(4 - RegExp.$1.length) + ); + for (const k in o) { + if (new RegExp('(' + k + ')').test(fmt)) { + fmt = fmt.replace( + RegExp.$1, + RegExp.$1.length === 1 + ? o[k] + : ('00' + o[k]).substr(('' + o[k]).length) + ); + } + } + return fmt; + } +} diff --git a/src/utils/busEvent.js b/src/utils/busEvent.js new file mode 100644 index 0000000..1974073 --- /dev/null +++ b/src/utils/busEvent.js @@ -0,0 +1,5 @@ +import Vue from 'vue' + +const busEvent = new Vue() + +export default busEvent diff --git a/src/utils/dict/Dict.js b/src/utils/dict/Dict.js new file mode 100644 index 0000000..104bd6e --- /dev/null +++ b/src/utils/dict/Dict.js @@ -0,0 +1,82 @@ +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 + }) +} diff --git a/src/utils/dict/DictConverter.js b/src/utils/dict/DictConverter.js new file mode 100644 index 0000000..0cf5df8 --- /dev/null +++ b/src/utils/dict/DictConverter.js @@ -0,0 +1,17 @@ +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)) +} diff --git a/src/utils/dict/DictData.js b/src/utils/dict/DictData.js new file mode 100644 index 0000000..afc763e --- /dev/null +++ b/src/utils/dict/DictData.js @@ -0,0 +1,13 @@ +/** + * @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 + } +} diff --git a/src/utils/dict/DictMeta.js b/src/utils/dict/DictMeta.js new file mode 100644 index 0000000..9779daa --- /dev/null +++ b/src/utils/dict/DictMeta.js @@ -0,0 +1,38 @@ +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 + } +} + + +/** + * 瑙f瀽瀛楀吀鍏冩暟鎹� + * @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) +} diff --git a/src/utils/dict/DictOptions.js b/src/utils/dict/DictOptions.js new file mode 100644 index 0000000..338a94e --- /dev/null +++ b/src/utils/dict/DictOptions.js @@ -0,0 +1,51 @@ +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([]) + }, + /** + * 瀛楀吀鍝嶅簲鏁版嵁杞崲鍣紝鏂规硶绛惧悕涓篺unction(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 diff --git a/src/utils/dict/index.js b/src/utils/dict/index.js new file mode 100644 index 0000000..215eb9e --- /dev/null +++ b/src/utils/dict/index.js @@ -0,0 +1,33 @@ +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) + } + }) + }) + }, + }) +} diff --git a/src/utils/errorCode.js b/src/utils/errorCode.js new file mode 100644 index 0000000..d2111ee --- /dev/null +++ b/src/utils/errorCode.js @@ -0,0 +1,6 @@ +export default { + '401': '璁よ瘉澶辫触锛屾棤娉曡闂郴缁熻祫婧�', + '403': '褰撳墠鎿嶄綔娌℃湁鏉冮檺', + '404': '璁块棶璧勬簮涓嶅瓨鍦�', + 'default': '绯荤粺鏈煡閿欒锛岃鍙嶉缁欑鐞嗗憳' +} diff --git a/src/utils/generator/config.js b/src/utils/generator/config.js new file mode 100644 index 0000000..7abf227 --- /dev/null +++ b/src/utils/generator/config.js @@ -0,0 +1,438 @@ +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鐨勮Е鍙戞柟寮忥紝鏃犺Е鍙戞柟寮忕殑缁勪欢涓嶇敓鎴恟ule +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' +} diff --git a/src/utils/generator/css.js b/src/utils/generator/css.js new file mode 100644 index 0000000..c1c62e6 --- /dev/null +++ b/src/utils/generator/css.js @@ -0,0 +1,18 @@ +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') +} diff --git a/src/utils/generator/drawingDefalut.js b/src/utils/generator/drawingDefalut.js new file mode 100644 index 0000000..09f133c --- /dev/null +++ b/src/utils/generator/drawingDefalut.js @@ -0,0 +1,29 @@ +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: '鎵嬫満鍙锋牸寮忛敊璇�' + }] + } +] diff --git a/src/utils/generator/drawingDefault.js b/src/utils/generator/drawingDefault.js new file mode 100644 index 0000000..09f133c --- /dev/null +++ b/src/utils/generator/drawingDefault.js @@ -0,0 +1,29 @@ +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: '鎵嬫満鍙锋牸寮忛敊璇�' + }] + } +] diff --git a/src/utils/generator/html.js b/src/utils/generator/html.js new file mode 100644 index 0000000..9bcc536 --- /dev/null +++ b/src/utils/generator/html.js @@ -0,0 +1,359 @@ +/* eslint-disable max-len */ +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鍖呰9 +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 +} diff --git a/src/utils/generator/icon.json b/src/utils/generator/icon.json new file mode 100644 index 0000000..2d9999a --- /dev/null +++ b/src/utils/generator/icon.json @@ -0,0 +1 @@ +["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"] \ No newline at end of file diff --git a/src/utils/generator/js.js b/src/utils/generator/js.js new file mode 100644 index 0000000..35e3e21 --- /dev/null +++ b/src/utils/generator/js.js @@ -0,0 +1,236 @@ +import { isArray } from 'util' +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 = isArray(conf.defaultValue) ? 'type: \'array\',' : '' + let message = 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 && 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 +} diff --git a/src/utils/generator/render.js b/src/utils/generator/render.js new file mode 100644 index 0000000..e8640f0 --- /dev/null +++ b/src/utils/generator/render.js @@ -0,0 +1,126 @@ +import { makeMap } from '@/utils/index' + +// 鍙傝�僪ttps://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'] +} diff --git a/src/utils/index.js b/src/utils/index.js new file mode 100644 index 0000000..8b4d0a8 --- /dev/null +++ b/src/utils/index.js @@ -0,0 +1,425 @@ +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 + // 濡傛灉璁惧畾涓篿mmediate===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) +} + +/** + * @desc 鏃堕棿鎴宠浆鏃ユ湡姣 + * @param {String} format 鏃堕棿鏍煎紡 Y:骞达紝M:鏈堬紝D:澶� h:灏忔椂锛宮:鍒嗛挓锛宻:绉� 榛樿:'Y/M/D h:m' + */ +export function formatDate2 (arg, format) { + // console.log(typeof arg.toString()); + let now + if (!arg) { + return null + } else { + now = new Date(arg) + } + format = format || 'Y.M.D h:m' + + const year = now.getFullYear() + let month = now.getMonth() + 1 + month = month >= 10 ? month : '0' + month + let date = now.getDate() + date = date >= 10 ? date : '0' + date + let hour = now.getHours() + hour = hour >= 10 ? hour : '0' + hour + let minute = now.getMinutes() + + minute = minute >= 10 ? minute : '0' + minute + let second = now.getSeconds() + second = second >= 10 ? second : '0' + second + return format + .replace('Y', year) + .replace('M', month) + .replace('D', date) + .replace('h', hour) + .replace('m', minute) + .replace('s', second) +} + diff --git a/src/utils/jsencrypt.js b/src/utils/jsencrypt.js new file mode 100644 index 0000000..78d9523 --- /dev/null +++ b/src/utils/jsencrypt.js @@ -0,0 +1,30 @@ +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) // 瀵规暟鎹繘琛屽姞瀵� +} + +// 瑙e瘑 +export function decrypt(txt) { + const encryptor = new JSEncrypt() + encryptor.setPrivateKey(privateKey) // 璁剧疆绉侀挜 + return encryptor.decrypt(txt) // 瀵规暟鎹繘琛岃В瀵� +} + diff --git a/src/utils/map.js b/src/utils/map.js new file mode 100644 index 0000000..7775907 --- /dev/null +++ b/src/utils/map.js @@ -0,0 +1,28 @@ +export function loadBMap() { + return new Promise(function(resolve, reject) { + if (typeof BMap !== 'undefined') { + resolve(BMap) + return true + } + window.onBMapCallback = function() { + resolve(BMap) + } + // 浣跨敤https鍗忚闇�瑕佹坊鍔犱竴涓媘eta鏍囩 + var protocolStr = document.location.protocol; + if(protocolStr == "https:") + { + let meta = document.createElement('meta') + meta.httpEquiv = 'Content-Security-Policy' + meta.content ='upgrade-insecure-requests' + meta.onerror = reject + document.head.appendChild(meta) + } + // 寮曞叆鐧惧害鍦板浘 + let script = document.createElement('script') + script.type = 'text/javascript' + script.src = + 'http://api.map.baidu.com/api?v=2.0&ak='+ process.env.VUE_APP_BAI_DU_AK +'&s=1&__ec_v__=20190126&callback=onBMapCallback' + script.onerror = reject + document.head.appendChild(script) + }) +} \ No newline at end of file diff --git a/src/utils/mqttTool.js b/src/utils/mqttTool.js new file mode 100644 index 0000000..4ebf8d7 --- /dev/null +++ b/src/utils/mqttTool.js @@ -0,0 +1,152 @@ +import mqtt from 'mqtt'; +import { getToken } from '@/utils/auth'; + +let mqttTool = { + client: null, +}; + +/** 杩炴帴Mqtt */ +mqttTool.connect = function () { + let options = { + username: 'FastBee', + password: getToken(), + cleanSession: true, + keepAlive: 30, + clientId: 'web-' + Math.random().toString(16).substr(2), + connectTimeout: 60000, + }; + // 閰嶇疆Mqtt鍦板潃 + let url = process.env.VUE_APP_MQTT_SERVER_URL; + if (url == '') { + console.log('鑷姩鑾峰彇mqtt杩炴帴鍦板潃'); + if (window.location.protocol === 'http:') { + url = 'ws://' + window.location.hostname + ':8083/mqtt'; + } else { + url = 'wss://' + window.location.hostname + '/mqtt'; + } + } + console.log('mqtt鍦板潃锛�', url); + mqttTool.client = mqtt.connect(url, options); + mqttTool.client.on('connect', (e) => { + console.log('mqtt杩炴帴鎴愬姛'); + }); + // 閲嶆柊杩炴帴 + mqttTool.client.on('reconnect', (error) => { + console.log('姝e湪閲嶈繛:', error); + }); + // 鍙戠敓閿欒 + mqttTool.client.on('error', (error) => { + console.log('Mqtt瀹㈡埛绔繛鎺ュけ璐ワ細', error); + mqttTool.client.end(); + }); + // 鏂紑杩炴帴 + mqttTool.client.on('close', function (res) { + console.log('宸叉柇寮�Mqtt杩炴帴'); + }); +}; +/** 鏂紑杩炴帴 */ +mqttTool.end = function () { + return new Promise((resolve, reject) => { + if (mqttTool.client == null) { + resolve('鏈繛鎺�'); + console.log('鏈繛鎺�'); + return; + } + mqttTool.client.end(); + mqttTool.client = null; + console.log('Mqtt鏈嶅姟鍣ㄥ凡鏂紑杩炴帴锛�'); + resolve('杩炴帴缁堟'); + }); +}; +/** 閲嶆柊杩炴帴 */ +mqttTool.reconnect = function () { + return new Promise((resolve, reject) => { + if (mqttTool.client == null) { + // 璋冪敤resolve鏂规硶锛孭romise鍙樹负鎿嶄綔鎴愬姛鐘舵�侊紙fulfilled锛� + resolve('鏈繛鎺�'); + console.log('鏈繛鎺�'); + return; + } + console.log('姝e湪閲嶈繛...', res); + mqttTool.client.reconnect(); + }); +}; +/** 娑堟伅璁㈤槄 */ +mqttTool.subscribe = function (topics) { + return new Promise((resolve, reject) => { + if (mqttTool.client == null) { + resolve('鏈繛鎺�'); + console.log('鏈繛鎺�'); + uni.showToast({ + icon: 'none', + title: 'mqtt鏈繛鎺�', + }); + return; + } + mqttTool.client.subscribe( + topics, + { + qos: 1, + }, + function (err, res) { + console.log('璁㈤槄涓婚锛�', topics); + if (!err) { + console.log('璁㈤槄鎴愬姛'); + resolve('璁㈤槄鎴愬姛'); + } else { + console.log('璁㈤槄澶辫触锛屼富棰樺彲鑳藉凡缁忚闃�'); + resolve('璁㈤槄澶辫触'); + return; + } + } + ); + }); +}; +/** 鍙栨秷璁㈤槄 */ +mqttTool.unsubscribe = function (topics) { + return new Promise((resolve, reject) => { + if (mqttTool.client == null) { + resolve('鏈繛鎺�'); + console.log('鏈繛鎺�'); + return; + } + mqttTool.client.unsubscribe(topics, function (err) { + if (!err) { + resolve('鍙栨秷璁㈤槄鎴愬姛'); + console.log('鍙栨秷璁㈤槄鎴愬姛'); + } else { + resolve('鍙栨秷璁㈤槄澶辫触'); + console.log('鍙栨秷璁㈤槄澶辫触'); + return; + } + }); + }); +}; +mqttTool.publish = function (topic, message, name) { + return new Promise((resolve, reject) => { + if (mqttTool.client == null) { + resolve('Mqtt瀹㈡埛绔湭杩炴帴'); + console.log('Mqtt瀹㈡埛绔湭杩炴帴'); + return; + } + mqttTool.client.publish(topic, message, { qos: 1 }, function (err) { + console.log('鍙戦�佷富棰橈細', topic); + console.log('鍙戦�佸唴瀹癸細', message); + if (!err) { + if (topic.indexOf('offline') > 0) { + console.log('[ ' + name + ' ] 褰卞瓙鎸囦护鍙戦�佹垚鍔�'); + resolve('[ ' + name + ' ] 褰卞瓙鎸囦护鍙戦�佹垚鍔�'); + } else { + console.log('[ ' + name + ' ] 鎸囦护鍙戦�佹垚鍔�'); + resolve('[ ' + name + ' ] 鎸囦护鍙戦�佹垚鍔�'); + } + } else { + console.log('[ ' + name + ' ] 鎸囦护鍙戦�佸け璐�'); + reject('[ ' + name + ' ] 鎸囦护鍙戦�佸け璐�'); + return; + } + }); + }); +}; + +export default mqttTool; diff --git a/src/utils/permission.js b/src/utils/permission.js new file mode 100644 index 0000000..1730e33 --- /dev/null +++ b/src/utils/permission.js @@ -0,0 +1,51 @@ +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) + }) + + if (!hasPermission) { + return false + } + return true + } 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) + }) + + if (!hasRole) { + return false + } + return true + } else { + console.error(`need roles! Like checkRole="['admin','editor']"`) + return false + } +} \ No newline at end of file diff --git a/src/utils/request.js b/src/utils/request.js new file mode 100644 index 0000000..d1f0a05 --- /dev/null +++ b/src/utils/request.js @@ -0,0 +1,146 @@ +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閫夐」锛岃〃绀鸿姹俇RL鍏叡閮ㄥ垎 + baseURL: process.env.VUE_APP_BASE_API, + // 瓒呮椂 + timeout: 20000 +}) + +// 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 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 = '鏁版嵁姝e湪澶勭悊锛岃鍕块噸澶嶆彁浜�'; + 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: "姝e湪涓嬭浇鏁版嵁锛岃绋嶅��", 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 isLogin = await blobValidate(data); + if (isLogin) { + 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 diff --git a/src/utils/ruoyi.js b/src/utils/ruoyi.js new file mode 100644 index 0000000..243c4c7 --- /dev/null +++ b/src/utils/ruoyi.js @@ -0,0 +1,239 @@ + + +/** + * 閫氱敤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 nodeIds = {}; + var tree = []; + + for (let d of data) { + let parentId = d[config.parentId]; + if (childrenListMap[parentId] == null) { + childrenListMap[parentId] = []; + } + nodeIds[d[config.id]] = d; + childrenListMap[parentId].push(d); + } + + for (let d of data) { + let parentId = d[config.parentId]; + if (nodeIds[parentId] == null) { + tree.push(d); + } + } + + for (let t of tree) { + adaptToChildrenList(t); + } + + function adaptToChildrenList(o) { + if (childrenListMap[o[config.id]] !== null) { + o[config.childrenList] = childrenListMap[o[config.id]]; + } + if (o[config.childrenList]) { + for (let c of o[config.childrenList]) { + adaptToChildrenList(c); + } + } + } + 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 +} + +// 楠岃瘉鏄惁涓篵lob鏍煎紡 +export async function blobValidate(data) { + try { + const text = await data.text(); + JSON.parse(text); + return false; + } catch (error) { + return true; + } +} diff --git a/src/utils/scroll-to.js b/src/utils/scroll-to.js new file mode 100644 index 0000000..c5d8e04 --- /dev/null +++ b/src/utils/scroll-to.js @@ -0,0 +1,58 @@ +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() +} diff --git a/src/utils/validate.js b/src/utils/validate.js new file mode 100644 index 0000000..558e9a8 --- /dev/null +++ b/src/utils/validate.js @@ -0,0 +1,114 @@ +/** + * @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) { + if (typeof str === 'string' || str instanceof String) { + return true + } + return false +} + +/** + * @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) +} +//数值范围校验 +export function checkNumber(rule, value, callback) { + if (!value) { + return callback(new Error('输入不可以为空')); + } + setTimeout(() => { + if (!Number(value)) { + } else { + if (value < 1 || value > 64) { + callback(new Error('数值范围为1-64')); + } else { + callback(); + } + } + }, 100); +} +export function checkNumberAddr(rule, value, callback) { + if (!value) { + return callback(new Error('输入不可以为空')); + } + setTimeout(() => { + if (!Number(value)) { + } else { + if (value < 1 || value > 65536) { + callback(new Error('数值范围为1-65536')); + } else { + callback(); + } + } + }, 100); +} diff --git a/src/views/bigScreen/components/echart/index.vue b/src/views/bigScreen/components/echart/index.vue new file mode 100644 index 0000000..bf39dc2 --- /dev/null +++ b/src/views/bigScreen/components/echart/index.vue @@ -0,0 +1,65 @@ +<template> + <div :id="id" :class="className" :style="{ height: height, width: width }" /> +</template> + +<script> +import tdTheme from './theme.json' // 寮曞叆榛樿涓婚 + +export default { + name: 'echart', + props: { + className: { + type: String, + default: 'chart' + }, + id: { + type: String, + default: 'chart' + }, + width: { + type: String, + default: '100%' + }, + height: { + type: String, + default: '100%' + }, + options: { + type: Object, + default: ()=>({}) + } + }, + data () { + return { + chart: null + } + }, + watch: { + options: { + handler (options) { + // 璁剧疆true娓呯┖echart缂撳瓨 + this.chart.setOption(options, true) + }, + deep: true + } + }, + mounted () { + // echarts.registerTheme('tdTheme', tdTheme); // 瑕嗙洊榛樿涓婚 + this.initChart(); + }, + beforeDestroy () { + this.chart.dispose() + this.chart = null + }, + methods: { + initChart () { + // 鍒濆鍖杄chart + this.chart = echarts.init(this.$el, 'tdTheme') + this.chart.setOption(this.options, true) + } + } +} +</script> + +<style> +</style> diff --git a/src/views/bigScreen/components/echart/theme.json b/src/views/bigScreen/components/echart/theme.json new file mode 100644 index 0000000..ce81aba --- /dev/null +++ b/src/views/bigScreen/components/echart/theme.json @@ -0,0 +1,490 @@ +{ + "color": [ + "#2d8cf0", + "#19be6b", + "#ff9900", + "#E46CBB", + "#9A66E4", + "#ed3f14" + ], + "backgroundColor": "rgba(0,0,0,0)", + "textStyle": {}, + "title": { + "textStyle": { + "color": "#516b91" + }, + "subtextStyle": { + "color": "#93b7e3" + } + }, + "line": { + "itemStyle": { + "normal": { + "borderWidth": "2" + } + }, + "lineStyle": { + "normal": { + "width": "2" + } + }, + "symbolSize": "6", + "symbol": "emptyCircle", + "smooth": true + }, + "radar": { + "itemStyle": { + "normal": { + "borderWidth": "2" + } + }, + "lineStyle": { + "normal": { + "width": "2" + } + }, + "symbolSize": "6", + "symbol": "emptyCircle", + "smooth": true + }, + "bar": { + "itemStyle": { + "normal": { + "barBorderWidth": 0, + "barBorderColor": "#ccc" + }, + "emphasis": { + "barBorderWidth": 0, + "barBorderColor": "#ccc" + } + } + }, + "pie": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "scatter": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "boxplot": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "parallel": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "sankey": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "funnel": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "gauge": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + }, + "emphasis": { + "borderWidth": 0, + "borderColor": "#ccc" + } + } + }, + "candlestick": { + "itemStyle": { + "normal": { + "color": "#edafda", + "color0": "transparent", + "borderColor": "#d680bc", + "borderColor0": "#8fd3e8", + "borderWidth": "2" + } + } + }, + "graph": { + "itemStyle": { + "normal": { + "borderWidth": 0, + "borderColor": "#ccc" + } + }, + "lineStyle": { + "normal": { + "width": 1, + "color": "#aaa" + } + }, + "symbolSize": "6", + "symbol": "emptyCircle", + "smooth": true, + "color": [ + "#2d8cf0", + "#19be6b", + "#f5ae4a", + "#9189d5", + "#56cae2", + "#cbb0e3" + ], + "label": { + "normal": { + "textStyle": { + "color": "#eee" + } + } + } + }, + "map": { + "itemStyle": { + "normal": { + "areaColor": "#f3f3f3", + "borderColor": "#516b91", + "borderWidth": 0.5 + }, + "emphasis": { + "areaColor": "rgba(165,231,240,1)", + "borderColor": "#516b91", + "borderWidth": 1 + } + }, + "label": { + "normal": { + "textStyle": { + "color": "#000" + } + }, + "emphasis": { + "textStyle": { + "color": "rgb(81,107,145)" + } + } + } + }, + "geo": { + "itemStyle": { + "normal": { + "areaColor": "#f3f3f3", + "borderColor": "#516b91", + "borderWidth": 0.5 + }, + "emphasis": { + "areaColor": "rgba(165,231,240,1)", + "borderColor": "#516b91", + "borderWidth": 1 + } + }, + "label": { + "normal": { + "textStyle": { + "color": "#000" + } + }, + "emphasis": { + "textStyle": { + "color": "rgb(81,107,145)" + } + } + } + }, + "categoryAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#fff" + } + }, + "splitLine": { + "show": false, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.05)", + "rgba(200,200,200,0.02)" + ] + } + } + }, + "valueAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#fff" + } + }, + "splitLine": { + "show": false, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.05)", + "rgba(200,200,200,0.02)" + ] + } + } + }, + "logAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.05)", + "rgba(200,200,200,0.02)" + ] + } + } + }, + "timeAxis": { + "axisLine": { + "show": true, + "lineStyle": { + "color": "#cccccc" + } + }, + "axisTick": { + "show": false, + "lineStyle": { + "color": "#333" + } + }, + "axisLabel": { + "show": true, + "textStyle": { + "color": "#999999" + } + }, + "splitLine": { + "show": true, + "lineStyle": { + "color": [ + "#eeeeee" + ] + } + }, + "splitArea": { + "show": false, + "areaStyle": { + "color": [ + "rgba(250,250,250,0.05)", + "rgba(200,200,200,0.02)" + ] + } + } + }, + "toolbox": { + "iconStyle": { + "normal": { + "borderColor": "#999" + }, + "emphasis": { + "borderColor": "#666" + } + } + }, + "legend": { + "textStyle": { + "color": "#fff" + } + }, + "tooltip": { + "axisPointer": { + "lineStyle": { + "color": "#ccc", + "width": 1 + }, + "crossStyle": { + "color": "#ccc", + "width": 1 + } + } + }, + "timeline": { + "lineStyle": { + "color": "#8fd3e8", + "width": 1 + }, + "itemStyle": { + "normal": { + "color": "#8fd3e8", + "borderWidth": 1 + }, + "emphasis": { + "color": "#8fd3e8" + } + }, + "controlStyle": { + "normal": { + "color": "#8fd3e8", + "borderColor": "#8fd3e8", + "borderWidth": 0.5 + }, + "emphasis": { + "color": "#8fd3e8", + "borderColor": "#8fd3e8", + "borderWidth": 0.5 + } + }, + "checkpointStyle": { + "color": "#8fd3e8", + "borderColor": "rgba(138,124,168,0.37)" + }, + "label": { + "normal": { + "textStyle": { + "color": "#8fd3e8" + } + }, + "emphasis": { + "textStyle": { + "color": "#8fd3e8" + } + } + } + }, + "visualMap": { + "color": [ + "#516b91", + "#59c4e6", + "#a5e7f0" + ] + }, + "dataZoom": { + "backgroundColor": "rgba(0,0,0,0)", + "dataBackgroundColor": "rgba(255,255,255,0.3)", + "fillerColor": "rgba(167,183,204,0.4)", + "handleColor": "#a7b7cc", + "handleSize": "100%", + "textStyle": { + "color": "#333" + } + }, + "markPoint": { + "label": { + "normal": { + "textStyle": { + "color": "#eee" + } + }, + "emphasis": { + "textStyle": { + "color": "#eee" + } + } + } + } +} diff --git a/src/views/bigScreen/components/item-wrap/item-wrap.vue b/src/views/bigScreen/components/item-wrap/item-wrap.vue new file mode 100644 index 0000000..f8e1825 --- /dev/null +++ b/src/views/bigScreen/components/item-wrap/item-wrap.vue @@ -0,0 +1,90 @@ +<template> + <dv-border-box-13 class="lr_titles"> + <div class="item_title" v-if="title !== ''"> + <div class="zuo"></div> + <span class="title-inner"> {{ title }} </span> + <div class="you"></div> + </div> + <div + :class="title !== '' ? 'item_title_content' : 'item_title_content_def'" + > + <slot></slot> + </div> + </dv-border-box-13> +</template> + +<script> +export default { + data() { + return {}; + }, + props: { + title: { + type: String, + default: () => "", + }, + }, + created() {}, + + mounted() {}, + methods: {}, +}; +</script> +<style lang='scss' scoped> +$item-title-height: 38px; +$item_title_content-height: calc(100% - 38px); + +.lr_titles { + box-sizing: border-box; + + ::v-deep .border-box-content { + box-sizing: border-box; + padding: 6px 16px 0px; + } + + .item_title { + height: $item-title-height; + line-height: $item-title-height; + width: 100%; + color: #31abe3; + text-align: center; + // background: linear-gradient(to right, transparent, #0f0756, transparent); + position: relative; + display: flex; + align-items: center; + justify-content: center; + + .zuo, + .you { + width: 58px; + height: 14px; + background-image: url("../../../../assets/bigScreen/img/titles/zuo.png"); + } + + .you { + transform: rotate(180deg); + } + .title-inner { + font-weight: 900; + letter-spacing: 2px; + background: linear-gradient( + 92deg, + #0072ff 0%, + #00eaff 48.8525390625%, + #01aaff 100% + ); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + } + } + + .item_title_content { + height: $item_title_content-height; + } + + .item_title_content_def { + width: 100%; + height: 100%; + } +} +</style> \ No newline at end of file diff --git a/src/views/bigScreen/components/message/message.js b/src/views/bigScreen/components/message/message.js new file mode 100644 index 0000000..177e026 --- /dev/null +++ b/src/views/bigScreen/components/message/message.js @@ -0,0 +1,49 @@ +/* + * @Author: daidai + * @Date: 2022-02-16 17:08:26 + * @LastEditors: Please set LastEditors + * @LastEditTime: 2022-04-25 10:12:36 + * @FilePath: \yhht-ui\yhht-ui\packagesEle\getXY\src\main.js + */ +import Vue from 'vue'; +import Main from './message.vue'; +import {isObject,isVNode} from '@/lib/types' +let Message = Vue.extend(Main); +let instance; +var message = function (options) { + if (Vue.prototype.$isServer) return; + if(!instance){ + instance = new Message({ + data: { + ...options + }, + + }); + instance.$mount(); + } + instance.destroy=()=>{ + document.body.removeChild(instance.$el); + instance&&instance.$destroy() + instance=null + return null + } + instance.init(options) + document.body.appendChild(instance.$el); + return instance; +}; +['success', 'warning', 'info', 'error'].forEach(type => { + message[type] = (options) => { + if (isObject(options) && !isVNode(options)) { + return message({ + ...options, + type + }); + } + return message({ + type, + text: options + }); + }; + }); + +export default message; \ No newline at end of file diff --git a/src/views/bigScreen/components/message/message.vue b/src/views/bigScreen/components/message/message.vue new file mode 100644 index 0000000..73d8ebb --- /dev/null +++ b/src/views/bigScreen/components/message/message.vue @@ -0,0 +1,67 @@ +<template> + <div class="messages" v-if="visible"> + <svg fill="none" viewBox="0 0 16 16" width="1em" height="1em" class="message-icon"> + <path fill="currentColor" d="M15 8A7 7 0 101 8a7 7 0 0014 0zM8.5 4v5.5h-1V4h1zm-1.1 7h1.2v1.2H7.4V11z" + fill-opacity="0.9" v-if="'warning'==type"></path> + </svg> + {{ text }} + </div> +</template> + +<script> +export default { + data() { + return { + visible: false, + text: "", + type:'warning' + }; + }, + props: {}, + created() { }, + + mounted() { }, + methods: { + init(param) { + clearTimeout(this.timer); + this.visible = true; + this.text = param.text || ""; + this.type = param.type || "success"; + this.timer = setTimeout(() => { + this.visible = false; + clearTimeout(this.timer); + }, 2000); + }, + }, +}; +</script> +<style lang='scss' scoped> +.messages { + position: fixed; + min-width: 200px; + top: 160px; + left: 50%; + transform: translate(-50%, 0); + border: solid 1px #4b4b4b; + // box-shadow: 0 16px 24px rgba(0, 0, 0, 0.14), 0 6px 30px rgba(0, 0, 0, 12%), + // 0 8px 10px rgba(0, 0, 0, 20%), inset 0 0.5px 0 #5e5e5e, + // inset 0.5px 0 0 #5e5e5e, inset 0 -0.5px 0 #5e5e5e, inset -0.5px 0 0 #5e5e5e; + width: fit-content; + border-radius: 6px; + display: flex; + align-items: center; + z-index: 999; + color: rgba(255, 255, 255, 0.9); + background-color: #242424; + line-height: 22px; + font-size: 14px; + padding: 13px 16px; + + .message-icon { + color: #cf6e2d; + font-size: 20px; + margin-right: 8px; + fill: currentColor; + } +} +</style> \ No newline at end of file diff --git a/src/views/bigScreen/components/reacquire/reacquire.vue b/src/views/bigScreen/components/reacquire/reacquire.vue new file mode 100644 index 0000000..845547e --- /dev/null +++ b/src/views/bigScreen/components/reacquire/reacquire.vue @@ -0,0 +1,63 @@ +<template> + <div class='reacquire flex justify-center blocks cursor-pointer' :style="{ lineHeight: lineHeight }" + @click="getData"> + <span> + 閲嶆柊鑾峰彇 + </span> + + </div> +</template> + +<script> +export default { + components: {}, + props: { + lineHeight: { + type: String, + default: '200px' + } + }, + data() { + return { + + }; + }, + computed: {}, + methods: { + init() { + }, + getData(e){ + this.$emit("onclick",e) + } + }, + created() { + + }, + mounted() { + + }, + beforeDestroy() { + }, +} +</script> + +<style lang='scss' scoped> +.reacquire { + + user-select:none; + color: rgb(168, 168, 168); + span:hover{ + // color:$primary-color ; + text-decoration: underline; + } +} + +.blocks { + width: 100%; + height: 100%; +} + +.cursor-pointer { + cursor: pointer; +} +</style> \ No newline at end of file diff --git a/src/views/bigScreen/home.scss b/src/views/bigScreen/home.scss new file mode 100644 index 0000000..9d19332 --- /dev/null +++ b/src/views/bigScreen/home.scss @@ -0,0 +1,266 @@ +#index { + color: #d3d6dd; + width: 1920px; + height: 1080px; + overflow: hidden; + + &.pageisScale { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + transform-origin: left top; + } + + + .bg { + width: 100%; + height: 100%; + padding: 16px 16px 10px 16px; + box-sizing: border-box; + // 娣辫摑鑹茶儗鏅� + // background-image: radial-gradient(closest-side,#264194, #12214c); + background-color: #0e2e87; + background-size: cover; + background-position: center center; + } + + .host-body { + height: 100%; + + .title_wrap { + height: 60px; + background-image: url("../../assets/bigScreen/img/top.png"); + background-size: cover; + background-position: center center; + position: relative; + margin-bottom: 4px; + + .guang { + position: absolute; + bottom: -26px; + background-image: url("../../assets/bigScreen/img/guang.png"); + background-position: 80px center; + width: 100%; + height: 56px; + } + + .zuojuxing, + .youjuxing { + position: absolute; + top: -2px; + width: 140px; + height: 6px; + background-image: url("../../assets/bigScreen/img/headers/juxing1.png"); + } + + .zuojuxing { + + left: 11%; + } + + .youjuxing { + right: 11%; + transform: rotate(180deg); + } + + .timers { + position: absolute; + right: 0; + top: 30px; + font-size: 18px; + display: flex; + align-items: center; + + .blq-icon-shezhi02 { + cursor: pointer; + } + } + } + + .title { + position: relative; + // width: 500px; + text-align: center; + background-size: cover; + color: transparent; + height: 60px; + line-height: 46px; + + .title-text { + font-size: 38px; + font-weight: 900; + letter-spacing: 6px; + width: 100%; + background: linear-gradient(92deg, #0072FF 0%, #00EAFF 48.8525390625%, #01AAFF 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + } + } + } + + +} + +.index_home { + width: 100vw; + height: 100vh; + background-color: #03050C; + .pagetab { + position: absolute; + top: -35px; + display: flex; + + .item { + width: 130px; + height: 36px; + color: #00FBF8; + text-indent: 5px; + line-height: 36px; + font-size: 16px; + } + } +} + +.setting { + position: fixed; + width: 100%; + height: 100%; + z-index: 999; + top: 0; + left: 0; + + .left_shu { + color: #000; + font-weight: 900; + position: relative; + text-indent: 10px; + padding:16px 0 10px 0 ; + &::before { + display: block; + content: " "; + height: 16px; + width: 4px; + border-radius: 2px; + background: #0072FF; + position: absolute; + left: 0px; + } + } + + .setting_dislog { + background-color: rgba($color: #000000, $alpha: .5); + position: absolute; + width: 100%; + height: 100%; + z-index: 0; + right: 0; + top: 0; + } + + .setting_inner { + box-sizing: border-box; + background: #FFF; + width: 340px; + height: 100%; + position: absolute; + right: 0px; + top: 0; + z-index: 1; + color: #000000; + 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); + + .setting_header { + font-size: 20px; + color: rgb(0, 0, 0); + font-weight: 900; + text-align: center; + line-height: 40px; + } + + .setting_body { + padding: 0px 16px; + box-sizing: border-box; + position: relative; + } + + .setting_item { + font-size: 14px; + line-height: 1.5; + + // display: flex; + .setting_label { + color: #555454; + } + .setting_label_tip{ + font-size: 12px; + color: #838282; + } + } + } + + .setting_inner { + animation: rtl-drawer-out .3s; + } +} + + +.settingShow { + .setting_inner { + animation: rtl-drawer-in .3s 1ms; + } + +} + +.yh-setting-fade-enter-active { + animation: yh-setting-fade-in .3s; +} + +.yh-setting-fade-leave-active { + + animation: yh-setting-fade-out .3s; + +} + +@keyframes yh-setting-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@keyframes yh-setting-fade-out { + 0% { + opacity: 1; + + } + + 100% { + opacity: 0; + } +} + + +@keyframes rtl-drawer-in { + 0% { + transform: translate(100%, 0) + } + + 100% { + -webkit-transform: translate(0, 0); + transform: translate(0, 0) + } +} + +@keyframes rtl-drawer-out { + 0% { + transform: translate(0, 0) + } + + 100% { + transform: translate(100%, 0) + } +} diff --git a/src/views/bigScreen/home.vue b/src/views/bigScreen/home.vue new file mode 100644 index 0000000..46dd3d8 --- /dev/null +++ b/src/views/bigScreen/home.vue @@ -0,0 +1,96 @@ +<template> +<div id="index" ref="appRef" class="index_home" :class="{ pageisScale: true }"> + <div class="bg"> + <dv-loading v-if="loading">Loading...</dv-loading> + <div v-else class="host-body"> + <!-- 澶撮儴 s --> + <div class="d-flex jc-center title_wrap"> + <div class="zuojuxing"></div> + <div class="youjuxing"></div> + <div class="guang"></div> + <div class="d-flex jc-center"> + <div class="title"> + <span class="title-text">FastBee鐗╄仈缃戝钩鍙�</span> + </div> + </div> + <div class="timers "> + {{ dateYear }} {{ dateWeek }} {{ dateDay }} + <i class=" blq-icon-shezhi02" style="margin-left:10px" @click="showSetting"></i> + </div> + </div> + <!-- 澶撮儴 e--> + <!-- 鍐呭 s--> + <index></index> + <!-- 鍐呭 e --> + </div> + </div> + <Setting ref="setting" /> +</div> +</template> + +<script> +import drawMixin from "../../utils/bigScreen/drawMixin"; +import { + formatTime +} from "../../utils/bigScreen/index.js"; +import Setting from './setting.vue' +import index from './indexs/index.vue' +export default { + mixins: [drawMixin], + components: { + Setting, + index + }, + data() { + return { + timing: null, + loading: true, + dateDay: null, + dateYear: null, + dateWeek: null, + weekday: ["鍛ㄦ棩", "鍛ㄤ竴", "鍛ㄤ簩", "鍛ㄤ笁", "鍛ㄥ洓", "鍛ㄤ簲", "鍛ㄥ叚"], + }; + }, + filters: { + numsFilter(msg) { + return msg || 0; + }, + }, + computed: { + + }, + created() { + + }, + mounted() { + this.timeFn(); + this.cancelLoading(); + }, + beforeDestroy() { + clearInterval(this.timing); + }, + methods: { + showSetting() { + this.$refs.setting.init() + }, + timeFn() { + this.timing = setInterval(() => { + this.dateDay = formatTime(new Date(), "HH: mm: ss"); + this.dateYear = formatTime(new Date(), "yyyy-MM-dd"); + this.dateWeek = this.weekday[new Date().getDay()]; + }, 1000); + }, + cancelLoading() { + setTimeout(() => { + this.loading = false; + }, 500); + }, + }, +}; +</script> + +<style lang="scss"> +@import "./home.scss"; +@import '../../assets/bigScreen/css/theme/index.css'; +@import "../../assets/bigScreen/css/index.scss" +</style> diff --git a/src/views/bigScreen/indexs/center-bottom.vue b/src/views/bigScreen/indexs/center-bottom.vue new file mode 100644 index 0000000..9003e8b --- /dev/null +++ b/src/views/bigScreen/indexs/center-bottom.vue @@ -0,0 +1,176 @@ +<template> +<div class="center_bottom"> + <div> + <dv-scroll-board :config="config" style="width:360px;height:175px" /> + </div> + <div style="display:flex;height:115px;margin-top:30px;"> + <div> + <dv-water-level-pond :config="configCpu" style="width:115px;height:100%;" /> + <div style="text-align: center;margin-top:10px;color:#23cdd8;font-weight:600;">CPU</div> + </div> + <div style="margin:0 20px;"> + <dv-water-level-pond :config="configMemery" style="width:115px;height:100%;" /> + <div style="text-align: center;margin-top:10px;color:#23cdd8;font-weight:600;">鍐呭瓨</div> + </div> + <div style=""> + <dv-water-level-pond :config="configDisk" style="width:115px;height:100%;" /> + <div style="text-align: center;margin-top:10px;color:#23cdd8;font-weight:600;">绯荤粺鐩�</div> + </div> + </div> +</div> +</template> + +<script> +import { + getServer +} from "@/api/monitor/server"; +export default { + data() { + return { + timer: null, + config: {}, + data: [ + ['鏈嶅姟鍣ㄥ悕绉�', ''], + ['鏈嶅姟鍣↖P', ""], + ['鎿嶄綔绯荤粺', ''], + ['绯荤粺鏋舵瀯', ""], + ['CPU鏍稿績鏁�', ''], + ['鏈嶅姟鍣ㄥ唴瀛�', ""], + ['Java鍚嶇О', ''], + ['Java鐗堟湰', ''], + ['Java鍚姩鏃堕棿', ""], + ['Java杩愯鏃堕暱', ""], + ['Java鍗犵敤鍐呭瓨', ''], + ['Java鎬诲唴瀛�', ""] + ], + // 鏈嶅姟鍣ㄤ俊鎭� + server: { + jvm: { + name: "", + version: "", + startTime: "", + runTime: "", + used: "", + total: 100 + }, + sys: { + computerName: "", + osName: "", + computerIp: "", + osArch: "" + }, + cpu: { + cpuNum: 1 + }, + mem: { + total: 2 + } + }, + configCpu: { + data: [50], + shape: 'roundRect', + formatter: '{value}%', + waveHeight: 10 + }, + configMemery: { + data: [50], + shape: 'roundRect', + formatter: '{value}%', + waveHeight: 10 + }, + configDisk: { + data: [50], + shape: 'roundRect', + formatter: '{value}%', + waveHeight: 10 + } + }; + }, + props: {}, + mounted() { + this.getServer(); + }, + beforeDestroy() { + this.clearData(); + }, + methods: { + /** 鏌ヨ鏈嶅姟鍣ㄤ俊鎭� */ + getServer() { + getServer().then(response => { + this.server = response.data; + this.config = { + rowNum: 6, + oddRowBGC: '', + evenRowBGC: '', + columnWidth: [105, 230], + data: [ + ['鏈嶅姟鍣ㄥ悕锛�', this.server.sys.computerName], + ['鏈嶅姟鍣↖P锛�', this.server.sys.computerIp], + ['鎿嶄綔绯荤粺锛�', this.server.sys.osName], + ['绯荤粺鏋舵瀯锛�', this.server.sys.osArch], + ['CPU鏍稿績锛�', this.server.cpu.cpuNum], + ['绯荤粺鍐呭瓨锛�', this.server.mem.total], + ['Java鍚嶇О锛�', this.server.jvm.name], + ['Java鐗堟湰锛�', this.server.jvm.version], + ['鍚姩鏃堕棿锛�', this.server.jvm.startTime], + ['杩愯鏃堕暱锛�', this.server.jvm.runTime], + ['杩愯鍐呭瓨锛�', this.server.jvm.used], + ['JVM鎬诲唴瀛橈細', this.server.jvm.total], + ], + }; + // 璁$畻CPU浣跨敤 + let cpu = (this.server.cpu.used + this.server.cpu.sys) / (this.server.cpu.used + this.server.cpu.sys + this.server.cpu.free) * 100; + this.configCpu = { + data: [cpu.toFixed(1), cpu.toFixed(1) - 10], + shape: 'roundRect', + formatter: '{value}%', + waveHeight: 10 + }; + // 璁$畻鍐呭瓨 + let memery = this.server.mem.used / (this.server.mem.used + this.server.mem.free) * 100; + this.configMemery = { + data: [memery.toFixed(1), memery.toFixed(1) - 10], + shape: 'roundRect', + formatter: '{value}%', + waveHeight: 10 + }; + // 璁$畻纭洏 + let disk = Number(this.server.sysFiles[0].used.replace("GB", "")) / (Number(this.server.sysFiles[0].used.replace("GB", "")) + Number(this.server.sysFiles[0].free.replace("GB", ""))) * 100; + this.configDisk = { + data: [disk.toFixed(1), disk.toFixed(1) - 10], + shape: 'roundRect', + formatter: '{value}%', + waveHeight: 10 + }; + // 杞 + this.switper() + }); + }, + clearData() { + if (this.timer) { + clearInterval(this.timer) + this.timer = null + } + }, + //杞 + switper() { + if (this.timer) { + return + } + let looper = (a) => { + this.getServer(); + }; + this.timer = setInterval(looper, 60000); + }, + } +} +</script> + +<style lang="scss" scoped> +.center_bottom { + width: 100%; + height: 100%; + padding: 10px; + display: flex; +} +</style> diff --git a/src/views/bigScreen/indexs/center-map.vue b/src/views/bigScreen/indexs/center-map.vue new file mode 100644 index 0000000..2c0f208 --- /dev/null +++ b/src/views/bigScreen/indexs/center-map.vue @@ -0,0 +1,392 @@ +<template> +<div class="centermap"> + <div class="maptitle"> + <div class="zuo"></div> + <span class="titletext">璁惧鍒嗗竷鍥�</span> + <div class="you"></div> + </div> + <div style="height:640px;background-color:#0e2e87;"> + <dv-border-box-8> + <div ref="map" style="height:600px;width:760px;padding:10px;"></div> + </dv-border-box-8> + </div> +</div> +</template> + +<script> +import { + loadBMap +} from '@/utils/map.js' +//瀹夎鐨勬槸echarts瀹屾暣鍖咃紝閲岄潰鍖呭惈鐧惧害鍦板浘鎵╁睍锛岃矾寰勪负 echarts/extension/bmap/bmap.js锛屽皢鍏跺紩鍏� +//ECharts鐨勭櫨搴﹀湴鍥炬墿灞曪紝鍙互鍦ㄧ櫨搴﹀湴鍥句笂灞曠幇鐐瑰浘锛岀嚎鍥撅紝鐑姏鍥剧瓑鍙鍖� +require('echarts/extension/bmap/bmap') +import { + listAllDeviceShort, +} from "@/api/iot/device"; +export default { + data() { + return { + // 璁惧鍒楄〃 + deviceList: [], + }; + }, + created() { + this.getAllDevice(); + }, + beforeDestroy() { + this.clearData(); + }, + methods: { + clearData() { + if (this.timer) { + clearInterval(this.timer) + this.timer = null + } + }, + //杞 + switper() { + if (this.timer) { + return + } + let looper = (a) => { + this.getAllDevice(); + }; + this.timer = setInterval(looper, 120000); + }, + /**鏌ヨ鎵�鏈夎澶� */ + getAllDevice() { + listAllDeviceShort(this.queryParams).then(response => { + this.deviceList = response.rows; + this.deviceCount = response.total; + this.loadMap(); + // 杞 + this.switper() + }) + }, + /**鍔犺浇鍦板浘*/ + loadMap() { + loadBMap().then(() => { + this.getmap(); + }); + }, + + /** 鍦板浘 */ + getmap() { + var myChart = this.$echarts.init(this.$refs.map); + var option; + + // 鍗曞嚮浜嬩欢 + myChart.on('click', (params) => { + if (params.data.deviceId) { + this.$router.push({ + path: '/iot/device-edit', + query: { + t: Date.now(), + deviceId: params.data.deviceId, + } + }); + } + }); + + // 鏍煎紡鍖栨暟鎹� + let convertData = function (data, status) { + var res = []; + for (var i = 0; i < data.length; i++) { + var geoCoord = [data[i].longitude, data[i].latitude]; + if (geoCoord && data[i].status == status) { + res.push({ + name: data[i].deviceName, + value: geoCoord, + serialNumber: data[i].serialNumber, + status: data[i].status, + isShadow: data[i].isShadow, + firmwareVersion: data[i].firmwareVersion, + networkAddress: data[i].networkAddress, + productName: data[i].productName, + activeTime: data[i].activeTime == null ? '' : data[i].activeTime, + deviceId: data[i].deviceId, + serialNumber: data[i].serialNumber, + locationWay: data[i].locationWay, + }); + } + } + return res; + }; + option = { + tooltip: { + trigger: 'item', + backgroundColor: "rgba(58,73,116,0.7)", + textStyle: { + color: "rgba(65,235,246,1)" + }, + formatter: function (params) { + var htmlStr = '<div style="padding:5px;line-height:28px;">'; + htmlStr += "璁惧鍚嶇О锛� <span style='color:#FFF'>" + params.data.name + "</span><br />"; + htmlStr += "璁惧缂栧彿锛� " + params.data.serialNumber + "<br />"; + htmlStr += "璁惧鐘舵�侊細 "; + if (params.data.status == 1) { + htmlStr += "<span style='color:#E6A23C'>鏈縺娲�</span>" + "<br />"; + } else if (params.data.status == 2) { + htmlStr += "<span style='color:#F56C6C'>绂佺敤</span>" + "<br />"; + } else if (params.data.status == 3) { + htmlStr += "<span style='color:#67C23A'>鍦ㄧ嚎</span>" + "<br />"; + } else if (params.data.status == 4) { + htmlStr += "<span style='color:#909399'>绂荤嚎</span>" + "<br />"; + } + if (params.data.isShadow == 1) { + htmlStr += "璁惧褰卞瓙锛� " + "<span style='color:#67C23A'>鍚敤</span>" + "<br />"; + } else { + htmlStr += "璁惧褰卞瓙锛� " + "<span style='color:#909399'>鏈惎鐢�</span>" + "<br />"; + } + htmlStr += "浜у搧鍚嶇О锛� " + params.data.productName + "<br />"; + htmlStr += "鍥轰欢鐗堟湰锛� Version " + params.data.firmwareVersion + "<br />"; + htmlStr += "婵�娲绘椂闂达細 " + params.data.activeTime + "<br />"; + htmlStr += "瀹氫綅鏂瑰紡锛� "; + if (params.data.locationWay == 1) { + htmlStr += "鑷姩瀹氫綅" + "<br />"; + } else if (params.data.locationWay == 2) { + htmlStr += "璁惧瀹氫綅" + "<br />"; + } else if (params.data.locationWay == 3) { + htmlStr += "鑷畾涔変綅缃�" + "<br />"; + } else { + htmlStr += "鏈煡" + "<br />"; + } + htmlStr += "鎵�鍦ㄥ湴鍧�锛� " + params.data.networkAddress + "<br />"; + htmlStr += '</div>'; + return htmlStr; + } + }, + bmap: { + center: [106, 37.5], + zoom: 5, + // 澶у睆鐢▃omm缂╂斁锛屽鑷村湴鍥剧缉鏀句腑蹇冪偣浼氬亸绉� + roam: 'move', + mapStyle: { + styleJson: [{ + featureType: 'water', + elementType: 'all', + stylers: { + color: '#3863db' + } + }, + { + featureType: 'land', + elementType: 'all', + stylers: { + color: '#0e2e87' + } + }, + { + featureType: 'railway', + elementType: 'all', + stylers: { + visibility: 'off' + } + }, + { + featureType: 'highway', + elementType: 'all', + stylers: { + visibility: 'off', + color: '#fdfdfd' + } + }, + { + featureType: 'highway', + elementType: 'labels', + stylers: { + visibility: 'off', + visibility: 'off' + } + }, + { + featureType: 'arterial', + elementType: 'geometry', + stylers: { + visibility: 'off', + color: '#fefefe' + } + }, + { + featureType: 'arterial', + elementType: 'geometry.fill', + stylers: { + visibility: 'off', + color: '#fefefe' + } + }, + { + featureType: 'poi', + elementType: 'all', + stylers: { + visibility: 'off', + visibility: 'off' + } + }, + { + featureType: 'green', + elementType: 'all', + stylers: { + visibility: 'off' + } + }, + { + featureType: 'subway', + elementType: 'all', + stylers: { + visibility: 'off' + } + }, + { + featureType: 'manmade', + elementType: 'all', + stylers: { + visibility: 'off', + color: '#d1d1d1' + } + }, + { + featureType: 'local', + elementType: 'all', + stylers: { + visibility: 'off', + color: '#d1d1d1' + } + }, + { + featureType: 'arterial', + elementType: 'labels', + stylers: { + visibility: 'off' + } + }, + { + featureType: 'boundary', + elementType: 'all', + stylers: { + color: '#23cdd8' + } + }, + { + featureType: 'building', + elementType: 'all', + stylers: { + visibility: 'off', + color: '#d1d1d1' + } + }, + { + featureType: 'label', + elementType: 'labels.text.fill', + stylers: { + color: '#264194', + visibility: 'off' + } + } + ] + } + }, + series: [{ + type: 'scatter', + coordinateSystem: 'bmap', + data: convertData(this.deviceList, 1), + symbolSize: 10, + itemStyle: { + color: '#e8fc05' + } + }, + { + type: 'scatter', + coordinateSystem: 'bmap', + data: convertData(this.deviceList, 2), + symbolSize: 10, + itemStyle: { + color: '#fc3464' + } + }, { + type: 'scatter', + coordinateSystem: 'bmap', + data: convertData(this.deviceList, 4), + symbolSize: 10, + itemStyle: { + color: '#eee' + } + }, { + type: 'effectScatter', + coordinateSystem: 'bmap', + data: convertData(this.deviceList, 3), + symbolSize: 12, + showEffectOn: 'render', + rippleEffect: { + brushType: 'stroke', + scale: 5 + }, + label: { + formatter: '{b}', + position: 'right', + show: false + }, + itemStyle: { + color: '#5de88e', + shadowBlur: 100, + shadowColor: '#333' + }, + zlevel: 1 + } + ] + }; + option && myChart.setOption(option, true); + }, + }, +}; +</script> + +<style lang="scss"> +/* 娓呴櫎鍦板浘LOGO */ +.BMap_cpyCtrl { + display: none !important; +} + +.anchorBL { + display: none !important; +} + +.centermap { + .maptitle { + height: 60px; + display: flex; + justify-content: center; + padding-top: 10px; + box-sizing: border-box; + + .titletext { + font-size: 28px; + font-weight: 900; + letter-spacing: 6px; + background: linear-gradient(92deg, + #0072ff 0%, + #00eaff 48.8525390625%, + #01aaff 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + margin: 0 10px; + } + + .zuo, + .you { + background-size: 100% 100%; + width: 29px; + height: 20px; + margin-top: 8px; + } + + .zuo { + background: url("../../../assets/bigScreen/img/xiezuo.png") no-repeat; + } + + .you { + background: url("../../../assets/bigScreen/img/xieyou.png") no-repeat; + } + } +} +</style> diff --git a/src/views/bigScreen/indexs/index.vue b/src/views/bigScreen/indexs/index.vue new file mode 100644 index 0000000..6c5cd8f --- /dev/null +++ b/src/views/bigScreen/indexs/index.vue @@ -0,0 +1,141 @@ +<template> +<div class="contents"> + <div class="contetn_left"> + <div class="pagetab"> + <dv-decoration-12 style="width:30px;height:30px;" /> + <div class="item">瀹炴椂鐩戞祴鏁版嵁</div> + </div> + <ItemWrap class="contetn_left-top contetn_lr-item" title="璁惧鎬昏"> + <LeftTop /> + + </ItemWrap> + <ItemWrap class="contetn_left-center contetn_lr-item" title="Mqtt缁熻"> + <LeftCenter /> + </ItemWrap> + <ItemWrap class="contetn_left-bottom contetn_lr-item" title="鐩戞祴鏁版嵁" style="padding: 0 10px 16px 10px"> + <LeftBottom /> + </ItemWrap> + </div> + <div class="contetn_center"> + <CenterMap class="contetn_center_top" /> + <ItemWrap class="contetn_center-bottom" title="鏈嶅姟鍣ㄤ俊鎭�"> + <CenterBottom /> + </ItemWrap> + </div> + <div class="contetn_right"> + <ItemWrap class="contetn_left-bottom contetn_lr-item" title="Mqtt鐘舵��"> + <RightTop /> + </ItemWrap> + <ItemWrap class="contetn_left-bottom contetn_lr-item" title="Mqtt娑堟伅" style="padding: 0 10px 16px 10px"> + <RightCenter /> + </ItemWrap> + <ItemWrap class="contetn_left-bottom contetn_lr-item" title="璁惧鎻愰啋 "> + <RightBottom /> + </ItemWrap> + </div> +</div> +</template> + +<script> +import LeftTop from './left-top.vue' +import LeftCenter from "./left-center.vue"; +import LeftBottom from "./left-bottom.vue"; +import CenterMap from "./center-map.vue"; +import CenterBottom from "./center-bottom.vue"; +import RightTop from "./right-top.vue"; +import RightCenter from "./right-center.vue"; +import RightBottom from "./right-bottom.vue"; + +export default { + components: { + LeftTop, + LeftCenter, + LeftBottom, + CenterMap, + RightTop, + RightCenter, + RightBottom, + CenterBottom, + }, + data() { + return { + + }; + }, + filters: { + numsFilter(msg) { + return msg || 0; + }, + }, + created() {}, + + mounted() {}, + methods: { + + }, +}; +</script> + +<style lang="scss" scoped> +// 鍐呭 +.contents { + + .contetn_left, + .contetn_right { + width: 500px; + box-sizing: border-box; + // padding: 16px 0; + } + + .contetn_center { + width: 800px; + } + + //宸﹀彸涓や晶 涓変釜鍧� + .contetn_lr-item { + height: 310px; + } + + .contetn_center_top { + width: 100%; + } + + // 涓棿 + .contetn_center { + display: flex; + flex-direction: column; + justify-content: space-around; + } + + .contetn_center-bottom { + height: 255px; + } + + //宸﹁竟 鍙宠竟 缁撴瀯涓�鏍� + .contetn_left, + .contetn_right { + display: flex; + flex-direction: column; + justify-content: space-around; + position: relative; + + } +} + +@keyframes rotating { + 0% { + -webkit-transform: rotate(0) scale(1); + transform: rotate(0) scale(1); + } + + 50% { + -webkit-transform: rotate(180deg) scale(1.1); + transform: rotate(180deg) scale(1.1); + } + + 100% { + -webkit-transform: rotate(360deg) scale(1); + transform: rotate(360deg) scale(1); + } +} +</style> diff --git a/src/views/bigScreen/indexs/left-bottom.vue b/src/views/bigScreen/indexs/left-bottom.vue new file mode 100644 index 0000000..8e1cea9 --- /dev/null +++ b/src/views/bigScreen/indexs/left-bottom.vue @@ -0,0 +1,100 @@ +<template> +<div v-if="pageflag" style="overflow:hidden;width: 100%;height:250px;font-size:12px;line-height:24px;"> + <vue-seamless-scroll :data="deviceLogList" :class-option="defaultOption"> + <div style="display:flex;margin-bottom:10px;border-bottom:2px dashed #23cdd8;color:#bbb;" v-for="(item, i) in deviceLogList" :key="i"> + <span style="width:50px;color:#23cdd8;font-size:16px;line-height:48px;font-weight:bolder;">{{ i + 1 }}</span> + <div style="display:flex;flex-wrap: wrap;"> + <div style="width:200px;"> + <span>璁惧缂栧彿锛�</span> + <span style="color:#23cdd8">{{ item.serialNumber }}</span> + </div> + <div style="width:150px;white-space: nowrap;overflow:hidden;text-overflow:ellipsis;"> + <span>鏍囪瘑绗︼細</span> + <span style="color:#fff;">{{item.identity}}</span> + </div> + <div style="width:60px;align-items: flex-end;text-align: right;"> + <span v-if="item.logType==1" style="color:#ffdb5c">灞炴�т笂鎶�</span> + <span v-else-if="item.logType==2" style="color:#ffdb5c">鍔熻兘璋冪敤</span> + <span v-else-if="item.logType==3" style="color:#fb7293">浜嬩欢涓婃姤</span> + <span v-else-if="item.logType==4" style="color:#ffdb5c">璁惧鍗囩骇</span> + <span v-else-if="item.logType==5" style="color:#9fe6b8">璁惧涓婄嚎</span> + <span v-else-if="item.logType==6" style="color:#ff9f7f">璁惧绂荤嚎</span> + </div> + <div style="width:200px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"> + <span>涓婃姤鏃堕棿锛�</span> + <span style="color:#fff;">{{ item.createTime }}</span> + </div> + <div style="margin-bottom:10px;width:210px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"> + <span>涓婃姤鍊硷細</span> + <span style="color:#fff;">{{item.logValue }}</span> + </div> + </div> + </div> + </vue-seamless-scroll> +</div> + +<Reacquire v-else @onclick="getData" style="line-height:200px;color:#23cdd8;margin-left:210px;"> + 閲嶆柊鑾峰彇 +</Reacquire> +</template> + +<script> +import vueSeamlessScroll from "vue-seamless-scroll"; +import { + listDeviceLog +} from "@/api/iot/deviceLog"; +export default { + components: { + vueSeamlessScroll, + }, + data() { + return { + deviceLogList: [], + pageflag: true, + defaultOption: { + step: 2, + limitMoveNum: 4, + hoverStop: true, + singleHeight: 280, + openWatch: true, + waitTime: 3000, + }, + queryParams: { + pageNum: 1, + pageSize: 20, + }, + }; + }, + created() { + this.getData(); + }, + beforeDestroy() { + this.clearData() + }, + methods: { + getData() { + listDeviceLog(this.queryParams).then(response => { + this.deviceLogList = response.rows; + // 杞 + this.switper() + }); + }, + clearData() { + if (this.timer) { + clearInterval(this.timer) + this.timer = null + } + }, + //杞 + switper() { + if (this.timer) { + return + } + let looper = (a) => { + this.getData() + }; + this.timer = setInterval(looper, 60000); + }, + }, +}; +</script> diff --git a/src/views/bigScreen/indexs/left-center.vue b/src/views/bigScreen/indexs/left-center.vue new file mode 100644 index 0000000..e5dfc6c --- /dev/null +++ b/src/views/bigScreen/indexs/left-center.vue @@ -0,0 +1,152 @@ +<template> + <div> + <div ref="statsChart" style="height: 240px; margin: 20px 0 40px 0"></div> + </div> +</template> + +<script> +import { getNettyMqttStats } from '@/api/iot/netty'; +export default { + data() { + return { + timer: null, + // emqx鐘舵�佹暟鎹� + stats: {}, + mqtt: this.$store.state.user.mqtt, + }; + }, + created() { + this.getMqttStats(); + }, + beforeDestroy() { + this.clearData(); + }, + methods: { + /** 鏌ヨmqtt鐘舵�佹暟鎹�*/ + getMqttStats() { + if (this.mqtt) { + getNettyMqttStats().then((response) => { + this.stats = response.data; + this.drawStats(); + // 杞 + this.switper(); + }); + } else { + this.$nextTick(() => { + // 鍒濆鍊� + this.stats = { + 'connections.count': 800, + 'connections.max': 8000, + 'sessions.count': 700, + 'sessions.max': 7000, + 'topics.count': 600, + 'topics.max': 6000, + 'subscribers.count': 500, + 'subscribers.max': 5000, + 'routes.count': 400, + 'routes.max': 4000, + 'retained.count': 300, + 'retained.max': 3000, + }; + this.drawStats(); + // 杞 + this.switper(); + }); + } + }, + /** EMQX鐘舵�佺粺璁� */ + drawStats() { + // 鍩轰簬鍑嗗濂界殑dom锛屽垵濮嬪寲echarts瀹炰緥 + let myChart = this.$echarts.init(this.$refs.statsChart); + var option; + option = { + animationDuration: 3000, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow', + }, + backgroundColor: 'rgba(58,73,116,0.7)', + textStyle: { + color: 'rgba(65,235,246,1)', + }, + }, + legend: { + textStyle: { + color: 'rgba(65,235,246,1)', + }, + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true, + }, + xAxis: { + type: 'value', + boundaryGap: [0, 0.01], + axisLabel: { + fontSize: 12, + color: '#fff', + }, + splitLine: { + //缃戞牸绾� + lineStyle: { + type: 'dashed', //璁剧疆缃戞牸绾跨被鍨� dotted锛氳櫄绾� solid:瀹炵嚎 + color: 'rgba(65,235,246,1)', //缃戞牸绾块鑹� + width: 0.5, + }, + }, + }, + yAxis: { + type: 'category', + axisLabel: { + fontSize: 12, + color: '#fff', + }, + data: this.mqtt ? ['杩炴帴鏁伴噺', '浼氳瘽鏁伴噺', '璁㈤槄鏁伴噺', '璺敱鏁伴噺', '淇濈暀娑堟伅'] : ['杩炴帴鏁伴噺', '浼氳瘽鏁伴噺', '涓婚鏁伴噺', '璁㈤槄鏁伴噺', '璺敱鏁伴噺', '淇濈暀娑堟伅'], + }, + series: [ + { + name: '褰撳墠鏁伴噺', + type: 'bar', + data: this.mqtt + ? [this.stats['connection_count'], this.stats['session_count'], this.stats['subscription_count'], this.stats['retain_count'], this.stats['retain_count']] + : [this.stats['connections.count'], this.stats['sessions.count'], this.stats['topics.count'], this.stats['subscribers.count'], this.stats['routes.count'], this.stats['retained.count']], + itemStyle: { + color: '#67e0e3', + }, + }, + { + name: this.mqtt ? '绱鎬绘暟' : '鍘嗗彶鏈�澶ф暟', + type: 'bar', + data: this.mqtt + ? [this.stats['connection_total'], this.stats['session_total'], this.stats['subscription_total'], this.stats['retain_total'], this.stats['retain_total']] + : [this.stats['connections.max'], this.stats['sessions.max'], this.stats['topics.max'], this.stats['subscribers.max'], this.stats['routes.max'], this.stats['retained.max']], + itemStyle: { + color: '#ffdb5c', + }, + }, + ], + }; + option && myChart.setOption(option); + }, + clearData() { + if (this.timer) { + clearInterval(this.timer); + this.timer = null; + } + }, + //杞 + switper() { + if (this.timer) { + return; + } + let looper = (a) => { + this.getMqttStats(); + }; + this.timer = setInterval(looper, 60000); + }, + }, +}; +</script> diff --git a/src/views/bigScreen/indexs/left-top.vue b/src/views/bigScreen/indexs/left-top.vue new file mode 100644 index 0000000..073e7ba --- /dev/null +++ b/src/views/bigScreen/indexs/left-top.vue @@ -0,0 +1,75 @@ +<template> +<div style="display:flex;margin-top:60px;"> + <div style="margin-left:10px;color:#32c5e9;"> + <dv-decoration-9 style="width:90px;height:90px;font-weight:600;" :dur="10" :color="['#32c5e9', '#238aa4']">{{deviceStatistic.deviceCount}}</dv-decoration-9> + <div style="text-align: center;margin-top:25px;">璁惧鎬绘暟</div> + </div> + <div style="margin:0 30px;color:#9fe6b8"> + <dv-decoration-9 style="width:90px;height:90px;font-weight:600;" :dur="10" :color="['#9fe6b8', '#70a181']">{{deviceStatistic.deviceOnlineCount}}</dv-decoration-9> + <div style="text-align: center;margin-top:25px;font-weight:400;">鍦ㄧ嚎璁惧</div> + </div> + <div style="margin-right:30px;color:#ffdb5c"> + <dv-decoration-9 style="width:90px;height:90px;font-weight:600;" :dur="10" :color="['#ffdb5c', '#b39a41']">{{deviceStatistic.deviceCount-deviceStatistic.deviceOnlineCount}}</dv-decoration-9> + <div style="text-align: center;margin-top:25px;font-weight:400;">绂荤嚎璁惧</div> + </div> + <div style="color:#fb7293;"> + <dv-decoration-9 style="width:90px;height:90px;font-weight:600;" :dur="10" :color="['#fb7293', '#ad4f65']">{{deviceStatistic.alertCount}}</dv-decoration-9> + <div style="text-align: center;margin-top:25px;font-weight:400;">鍛婅鏁伴噺</div> + </div> +</div> +</template> + +<script> +import { + getDeviceStatistic, +} from "@/api/iot/device"; +export default { + data() { + return { + // 璁惧缁熻淇℃伅 + deviceStatistic: { + deviceCount: 100, + productCount: 100, + eventCount: 100, + alertCount: 100, + deviceOnlineCount:100 + }, + timer: null, + }; + }, + created() { + this.getDeviceStatic() + }, + beforeDestroy() { + this.clearData() + }, + methods: { + clearData() { + if (this.timer) { + clearInterval(this.timer) + this.timer = null + } + }, + getDeviceStatic() { + getDeviceStatistic().then(response => { + if (response.code == 200) { + this.deviceStatistic = response.data; + // 杞 + this.switper() + } + }); + }, + //杞 + switper() { + if (this.timer) { + return + } + let looper = (a) => { + this.getDeviceStatic(); + }; + this.timer = setInterval(looper, 60000); + }, + + }, +}; +</script> diff --git a/src/views/bigScreen/indexs/right-bottom.vue b/src/views/bigScreen/indexs/right-bottom.vue new file mode 100644 index 0000000..9a2bf3e --- /dev/null +++ b/src/views/bigScreen/indexs/right-bottom.vue @@ -0,0 +1,99 @@ +<template> +<div v-if="pageflag" style="overflow:hidden;width: 100%;height:250px;font-size:12px;line-height:24px;"> + <vue-seamless-scroll :data="deviceLogList" :class-option="defaultOption"> + <div style="display:flex;margin-bottom:10px;border-bottom:2px dashed #23cdd8;color:#bbb;" v-for="(item, i) in deviceLogList" :key="i"> + <span style="width:50px;color:#23cdd8;font-size:16px;line-height:48px;font-weight:bolder;">{{ i + 1 }}</span> + <div style="display:flex;flex-wrap: wrap;"> + <div style="width:200px;"> + <span>璁惧缂栧彿锛�</span> + <span style="color:#23cdd8">{{ item.serialNumber }}</span> + </div> + <div style="width:150px;white-space: nowrap;overflow:hidden;text-overflow:ellipsis;"> + <span>鏍囪瘑绗︼細</span> + <span style="color:#fff;">{{item.identify}}</span> + </div> + <div style="width:60px;align-items: flex-end;text-align: right;"> + <span style="color:#ffdb5c">缂栫爜锛歿{ item.resultCode }}</span> + </div> + <div style="width:200px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"> + <span>涓婃姤鏃堕棿锛�</span> + <span style="color:#fff;">{{ item.createTime }}</span> + </div> + <div style="margin-bottom:10px;width:210px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"> + <span>涓婃姤鍊硷細</span> + <span style="color:#fff;">{{item.funValue }}</span> + </div> + </div> + </div> + </vue-seamless-scroll> +</div> + +<Reacquire v-else @onclick="getData" style="line-height:200px;color:#23cdd8;margin-left:210px;"> + 閲嶆柊鑾峰彇 +</Reacquire> +</template> + +<script> +import vueSeamlessScroll from "vue-seamless-scroll"; +import { + listLog, + getLog, + delLog, + addLog, + updateLog +} from "@/api/iot/functionLog"; +export default { + components: { + vueSeamlessScroll, + }, + data() { + return { + deviceLogList: [], + pageflag: true, + defaultOption: { + step: 2, + limitMoveNum: 4, + hoverStop: true, + singleHeight: 280, + openWatch: true, + waitTime: 3000, + }, + queryParams: { + pageNum: 1, + pageSize: 5, + }, + }; + }, + created() { + this.getData(); + }, + beforeDestroy() { + this.clearData() + }, + methods: { + getData() { + listLog(this.queryParams).then(response => { + this.deviceLogList = response.rows; + // 杞 + this.switper() + }); + }, + clearData() { + if (this.timer) { + clearInterval(this.timer) + this.timer = null + } + }, + //杞 + switper() { + if (this.timer) { + return + } + let looper = (a) => { + this.getData() + }; + this.timer = setInterval(looper, 60000); + }, + }, +}; +</script> diff --git a/src/views/bigScreen/indexs/right-center.vue b/src/views/bigScreen/indexs/right-center.vue new file mode 100644 index 0000000..55d4a5f --- /dev/null +++ b/src/views/bigScreen/indexs/right-center.vue @@ -0,0 +1,121 @@ +<template> + <div style="display: flex"> + <dv-active-ring-chart :config="config" style="width: 250px; height: 250px" /> + <div style="font-size: 14px; margin-top: 80px; line-height: 10px; margin-left: -20px"> + <div style="margin-bottom: 20px; color: #23cdd8" v-if="mqtt"> + <div style="margin-bottom: 20px; color: #23cdd8"> + 鍙戦�佹秷鎭�绘暟锛� + <span style="color: #fff">{{ formatter(this.static['send_total']) }}</span> + <dv-decoration-3 style="width: 200px; height: 20px; margin-top: 5px" /> + </div> + </div> + <div style="margin-bottom: 20px; color: #23cdd8" v-else> + 鍙戦�佸瓧鑺傦細 + <span style="color: #fff">{{ formatter(this.static['bytes.sent']) }}</span> + <dv-decoration-3 style="width: 200px; height: 20px; margin-top: 5px" /> + </div> + <div style="margin-bottom: 20px; color: #23cdd8" v-if="mqtt"> + 鎺ユ敹娑堟伅鎬绘暟锛� + <span style="color: #fff">{{ formatter(this.static['receive_total']) }}</span> + <dv-decoration-3 style="width: 200px; height: 20px; margin-top: 5px" /> + </div> + <div style="margin-bottom: 20px; color: #23cdd8" v-else> + 鎺ユ敹瀛楄妭锛� + <span style="color: #fff">{{ formatter(this.static['bytes.received']) }}</span> + <dv-decoration-3 style="width: 200px; height: 20px; margin-top: 5px" /> + </div> + </div> + </div> +</template> + +<script> +import { statisticNettyMqtt } from '@/api/iot/netty'; + +export default { + data() { + return { + // emqx缁熻淇℃伅 + static: {}, + config: {}, + timer: null, + mqtt: this.$store.state.user.mqtt, + }; + }, + created() { + this.statisticMqtt(); + }, + computed: {}, + beforeDestroy() { + this.clearData(); + }, + methods: { + /** 鏌ヨemqx缁熻*/ + statisticMqtt() { + if (this.mqtt) { + statisticNettyMqtt().then((response) => { + this.static = response.data; + // 鍥炬爣閰嶇疆 + this.config = { + data: [ + { + name: '鍙戦��', + value: this.static['send_total'], + }, + { + name: '鎺ユ敹', + value: this.static['receive_total'], + }, + ], + color: ['#ffdb5c', '#67e0e3'], + }; + // 杞 + this.switper(); + }); + } else { + // 鍥炬爣閰嶇疆 + this.config = { + data: [ + { + name: '鍙戦��', + value: 32761563, + }, + { + name: '鎺ユ敹', + value: 31910071, + }, + ], + color: ['#ffdb5c', '#67e0e3'], + }; + // 杞 + this.switper(); + } + }, + // 鏁板瓧鏍煎紡鍖� + formatter(number) { + if (number) { + const numbers = number.toString().split('').reverse(); + const segs = []; + while (numbers.length) segs.push(numbers.splice(0, 3).join('')); + return segs.join(',').split('').reverse().join(''); + } + return 1024; + }, + clearData() { + if (this.timer) { + clearInterval(this.timer); + this.timer = null; + } + }, + //杞 + switper() { + if (this.timer) { + return; + } + let looper = (a) => { + this.statisticMqtt(); + }; + this.timer = setInterval(looper, 60000); + }, + }, +}; +</script> diff --git a/src/views/bigScreen/indexs/right-top.vue b/src/views/bigScreen/indexs/right-top.vue new file mode 100644 index 0000000..7b6aa2f --- /dev/null +++ b/src/views/bigScreen/indexs/right-top.vue @@ -0,0 +1,125 @@ +<template> + <div style="padding-top: 10px"> + <dv-capsule-chart :config="config" style="width: 430px; height: 230px" /> + </div> +</template> + +<script> +import { statisticNettyMqtt } from '@/api/iot/netty'; +export default { + data() { + return { + // emqx缁熻淇℃伅 + static: {}, + config: {}, + timer: null, + mqtt: this.$store.state.user.mqtt, + }; + }, + created() { + this.statisticMqtt(); + }, + + mounted() {}, + beforeDestroy() { + this.clearData(); + }, + methods: { + /** 鏌ヨmqtt缁熻*/ + statisticMqtt() { + if (this.mqtt) { + statisticNettyMqtt().then((response) => { + this.static = response.data; + this.config = { + data: [ + { + name: '浠婃棩鎺ユ敹', + value: this.static['today_received'], + }, + { + name: '浠婃棩鍙戦��', + value: this.static['today_send'], + }, + { + name: '璁㈤槄鎬绘暟', + value: this.static['subscribe_total'], + }, + { + name: '鍙戝竷娑堟伅', + value: this.static['send_total'], + }, + { + name: '鎺ユ敹娑堟伅', + value: this.static['receive_total'], + }, + { + name: '璁よ瘉娆℃暟', + value: this.static['auth_total'], + }, + { + name: '璁よ瘉鎴愬姛', + value: this.static['auth_total'], + }, + ], + unit: '娆℃暟', + showValue: true, + }; + this.switper(); + }); + } else { + this.config = { + data: [ + { + name: '浠婃棩鎺ユ敹', + value: 6000, + }, + { + name: '浠婃棩鍙戦��', + value: 5000, + }, + { + name: '璁㈤槄鎬绘暟', + value: 4000, + }, + { + name: '鍙戝竷娑堟伅', + value: 3000, + }, + { + name: '鎺ユ敹娑堟伅', + value: 2000, + }, + { + name: '璁よ瘉娆℃暟', + value: 1000, + }, + { + name: '璁よ瘉鎴愬姛', + value: 1000, + }, + ], + unit: '娆℃暟', + showValue: true, + }; + this.switper(); + } + }, + clearData() { + if (this.timer) { + clearInterval(this.timer); + this.timer = null; + } + }, + //杞 + switper() { + if (this.timer) { + return; + } + let looper = (a) => { + this.statisticMqtt(); + }; + this.timer = setInterval(looper, 60000); + }, + }, +}; +</script> diff --git a/src/views/bigScreen/setting.vue b/src/views/bigScreen/setting.vue new file mode 100644 index 0000000..9450c73 --- /dev/null +++ b/src/views/bigScreen/setting.vue @@ -0,0 +1,105 @@ +<template> + <transition name="yh-setting-fade"> + <div class="setting" :class="{ settingShow: settingShow }" v-show="settingShow"> + <div class="setting_dislog" @click="settingShow = false"> + + </div> + <div class="setting_inner"> + <div class="setting_header"> + 璁剧疆 + </div> + <div class="setting_body"> + <!-- <div class="left_shu"> 瀹炴椂鐩戞祴</div> --> + <div class="left_shu"> 鍏ㄥ眬璁剧疆</div> + <div class="setting_item"> + <span class="setting_label"> + 鏄惁杩涜鑷姩閫傞厤<span class="setting_label_tip">(榛樿鍒嗚鲸鐜�1920*1080)</span>: + </span> + <div class="setting_content"> + <el-radio-group v-model="isScaleradio" @change="(val) => radiochange(val, 'isScale')"> + <el-radio :label="true">鏄�</el-radio> + <el-radio :label="false">鍚�</el-radio> + </el-radio-group> + + </div> + </div> + <div class="left_shu"> 瀹炴椂鐩戞祴</div> + <div class="setting_item"> + <span class="setting_label"> + 璁惧鎻愰啋鑷姩杞: <span class="setting_label_tip"></span> + </span> + <div class="setting_content"> + <el-radio-group v-model="sbtxradio" @change="(val) => radiochange(val, 'sbtxSwiper')"> + <el-radio :label="true">鏄�</el-radio> + <el-radio :label="false">鍚�</el-radio> + </el-radio-group> + + </div> + </div> + <div class="setting_item"> + <span class="setting_label"> + 瀹炴椂棰勮杞挱: + </span> + <div class="setting_content"> + <el-radio-group v-model="ssyjradio" @change="(val) => radiochange(val, 'ssyjSwiper')"> + <el-radio :label="true">鏄�</el-radio> + <el-radio :label="false">鍚�</el-radio> + </el-radio-group> + </div> + </div> + <div class="flex justify-center"> + <!-- <el-button type="primary" round size="mini">纭畾</el-button> --> + </div> + </div> + </div> + </div> + </transition> +</template> + +<script> + +export default { + components: {}, + data() { + return { + settingShow: false, + sbtxradio:true, + ssyjradio: true, + isScaleradio:true, + }; + }, + computed: {}, + methods: { + init() { + this.settingShow = true + }, + radiochange(val, type) { + this.$store.commit('setting/updateSwiper', { val, type }) + if(type==='isScale'){ + this.$router.go(0) + // location.reload() + // window.location.href=window.location.href+"?t="+Date.now() + } + }, + }, + created() { + //this.$store.commit('setting/initSwipers') + // this.sbtxradio = this.$store.state.settings.sbtxSwiper, + // this.ssyjradio = this.$store.state.settings.ssyjSwiper, + // this.isScaleradio = this.$store.state.settings.isScale; + }, + mounted() { + document.body.appendChild(this.$el); + }, + beforeDestroy() { + }, + destroyed() { + if (this.$el && this.$el.parentNode) { + this.$el.parentNode.removeChild(this.$el); + } + } +} +</script> + +<style lang='scss' scoped> +</style> \ No newline at end of file diff --git a/src/views/components/icons/element-icons.js b/src/views/components/icons/element-icons.js new file mode 100644 index 0000000..9ea4d63 --- /dev/null +++ b/src/views/components/icons/element-icons.js @@ -0,0 +1,3 @@ +const elementIcons = ['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'] + +export default elementIcons diff --git a/src/views/components/icons/index.vue b/src/views/components/icons/index.vue new file mode 100644 index 0000000..d3c9a71 --- /dev/null +++ b/src/views/components/icons/index.vue @@ -0,0 +1,87 @@ +<template> + <div class="icons-container"> + <aside> + <a href="#" target="_blank">Add and use + </a> + </aside> + <el-tabs type="border-card"> + <el-tab-pane label="Icons"> + <div v-for="item of svgIcons" :key="item"> + <el-tooltip placement="top"> + <div slot="content"> + {{ generateIconCode(item) }} + </div> + <div class="icon-item"> + <svg-icon :icon-class="item" class-name="disabled" /> + <span>{{ item }}</span> + </div> + </el-tooltip> + </div> + </el-tab-pane> + <el-tab-pane label="Element-UI Icons"> + <div v-for="item of elementIcons" :key="item"> + <el-tooltip placement="top"> + <div slot="content"> + {{ generateElementIconCode(item) }} + </div> + <div class="icon-item"> + <i :class="'el-icon-' + item" /> + <span>{{ item }}</span> + </div> + </el-tooltip> + </div> + </el-tab-pane> + </el-tabs> + </div> +</template> + +<script> +import svgIcons from './svg-icons' +import elementIcons from './element-icons' + +export default { + name: 'Icons', + data() { + return { + svgIcons, + elementIcons + } + }, + methods: { + generateIconCode(symbol) { + return `<svg-icon icon-class="${symbol}" />` + }, + generateElementIconCode(symbol) { + return `<i class="el-icon-${symbol}" />` + } + } +} +</script> + +<style lang="scss" scoped> +.icons-container { + margin: 10px 20px 0; + overflow: hidden; + + .icon-item { + margin: 20px; + height: 85px; + text-align: center; + width: 100px; + float: left; + font-size: 30px; + color: #24292e; + cursor: pointer; + } + + span { + display: block; + font-size: 16px; + margin-top: 10px; + } + + .disabled { + pointer-events: none; + } +} +</style> diff --git a/src/views/components/icons/svg-icons.js b/src/views/components/icons/svg-icons.js new file mode 100644 index 0000000..724cd8e --- /dev/null +++ b/src/views/components/icons/svg-icons.js @@ -0,0 +1,10 @@ +const req = require.context('../../../assets/icons/svg', false, /\.svg$/) +const requireAll = requireContext => requireContext.keys() + +const re = /\.\/(.*)\.svg/ + +const svgIcons = requireAll(req).map(i => { + return i.match(re)[1] +}) + +export default svgIcons diff --git a/src/views/dashboard/BarChart.vue b/src/views/dashboard/BarChart.vue new file mode 100644 index 0000000..cd33d2d --- /dev/null +++ b/src/views/dashboard/BarChart.vue @@ -0,0 +1,102 @@ +<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> diff --git a/src/views/dashboard/LineChart.vue b/src/views/dashboard/LineChart.vue new file mode 100644 index 0000000..ddd1063 --- /dev/null +++ b/src/views/dashboard/LineChart.vue @@ -0,0 +1,135 @@ +<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> diff --git a/src/views/dashboard/PanelGroup.vue b/src/views/dashboard/PanelGroup.vue new file mode 100644 index 0000000..1a1081f --- /dev/null +++ b/src/views/dashboard/PanelGroup.vue @@ -0,0 +1,181 @@ +<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> diff --git a/src/views/dashboard/PieChart.vue b/src/views/dashboard/PieChart.vue new file mode 100644 index 0000000..c360057 --- /dev/null +++ b/src/views/dashboard/PieChart.vue @@ -0,0 +1,79 @@ +<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> diff --git a/src/views/dashboard/RaddarChart.vue b/src/views/dashboard/RaddarChart.vue new file mode 100644 index 0000000..b1790ca --- /dev/null +++ b/src/views/dashboard/RaddarChart.vue @@ -0,0 +1,116 @@ +<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> diff --git a/src/views/dashboard/mixins/resize.js b/src/views/dashboard/mixins/resize.js new file mode 100644 index 0000000..b1e76e9 --- /dev/null +++ b/src/views/dashboard/mixins/resize.js @@ -0,0 +1,56 @@ +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() + } + } +} diff --git a/src/views/error/401.vue b/src/views/error/401.vue new file mode 100644 index 0000000..448b6ec --- /dev/null +++ b/src/views/error/401.vue @@ -0,0 +1,88 @@ +<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> diff --git a/src/views/error/404.vue b/src/views/error/404.vue new file mode 100644 index 0000000..96f075c --- /dev/null +++ b/src/views/error/404.vue @@ -0,0 +1,233 @@ +<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"> + 瀵逛笉璧凤紝鎮ㄦ鍦ㄥ鎵剧殑椤甸潰涓嶅瓨鍦ㄣ�傚皾璇曟鏌RL鐨勯敊璇紝鐒跺悗鎸夋祻瑙堝櫒涓婄殑鍒锋柊鎸夐挳鎴栧皾璇曞湪鎴戜滑鐨勫簲鐢ㄧ▼搴忎腑鎵惧埌鍏朵粬鍐呭銆� + </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> diff --git a/src/views/index.vue b/src/views/index.vue new file mode 100644 index 0000000..2456e51 --- /dev/null +++ b/src/views/index.vue @@ -0,0 +1,877 @@ +<template> + <div style="padding: 10px; background-color: #f8f8f8"> + <el-row :gutter="20" style="margin: 10px 0px 20px 0px"> + <el-col :xs="24" :sm="24" :md="24" :lg="14" :xl="14"> + <div style="overflow: hidden; border: 1px solid #ccc"> + <div ref="map" style="height: 650px"></div> + </div> + </el-col> + + <el-col :xs="24" :sm="24" :md="24" :lg="10" :xl="10"> + <el-card shadow="none" style=""> + <h3 style="font-weight: bold"> + <i class="el-icon-s-data"></i> + 璁惧缁熻 + </h3> + <el-row :gutter="40" class="panel-group"> + <el-col :span="12" class="card-panel-col"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-blue"> + <svg-icon icon-class="device" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text">璁惧鏁伴噺</div> + <count-to :start-val="0" :end-val="deviceStatistic.deviceCount" :duration="3000" class="card-panel-num" /> + </div> + </div> + </el-col> + <el-col :span="12" class="card-panel-col"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-red"> + <svg-icon icon-class="monitor-a" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text">鐩戞祴鏁版嵁</div> + <count-to :start-val="0" :end-val="deviceStatistic.monitorCount" :duration="3000" class="card-panel-num" /> + </div> + </div> + </el-col> + <el-col :span="12" class="card-panel-col"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-blue"> + <svg-icon icon-class="model" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text">浜у搧鏁伴噺</div> + <count-to :start-val="0" :end-val="deviceStatistic.productCount" :duration="1000" class="card-panel-num" /> + </div> + </div> + </el-col> + <el-col :span="12" class="card-panel-col"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-red"> + <svg-icon icon-class="alert" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text">鍛婅鏁伴噺</div> + <count-to :start-val="0" :end-val="deviceStatistic.alertCount" :duration="1000" class="card-panel-num" /> + </div> + </div> + </el-col> + <el-col :span="12" class="card-panel-col"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-blue"> + <svg-icon icon-class="log-a" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text">鎿嶄綔璁板綍</div> + <count-to :start-val="0" :end-val="deviceStatistic.functionCount" :duration="2000" class="card-panel-num" /> + </div> + </div> + </el-col> + <el-col :span="12" class="card-panel-col"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-red"> + <svg-icon icon-class="event-a" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text">涓婃姤浜嬩欢</div> + <count-to :start-val="0" :end-val="deviceStatistic.eventCount" :duration="2000" class="card-panel-num" /> + </div> + </div> + </el-col> + </el-row> + </el-card> + <el-card shadow="none" style="margin-top: 22px; height: 302px"> + <h3 style="font-weight: bold; margin-bottom: 10px"> + <i class="el-icon-s-order"></i> + 淇℃伅鏍� + </h3> + <div style="cursor: pointer; display: table; width: 100%; line-height: 36px" @click="openDetail(item.noticeId)" v-for="item in noticeList" :key="item.noticeId"> + <div style="display: table-cell; padding-right: 10px"> + <el-tag size="mini" effect="dark" type="warning" v-if="item.noticeType == 2">鍏憡</el-tag> + <el-tag size="mini" effect="dark" v-else>淇℃伅</el-tag> + {{ item.noticeTitle }} + </div> + <div style="display: table-cell; width: 90px; font-size: 14px"> + <i class="el-icon-time"></i> + {{ parseTime(item.createTime, '{y}-{m}-{d}') }} + </div> + </div> + </el-card> + </el-col> + </el-row> + + <el-card shadow="none" style="margin: 10px 10px 20px 10px"> + <el-row :gutter="120" v-if="isAdmin"> + <el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8"> + <div style="padding: 20px"> + <div ref="pieCpu" style="height: 161px"></div> + </div> + </el-col> + <el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8"> + <div style="padding: 20px"> + <div ref="pieMemery" style="height: 161px"></div> + </div> + </el-col> + <el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8"> + <div style="padding: 20px"> + <div ref="pieDisk" style="height: 161px"></div> + </div> + </el-col> + </el-row> + </el-card> + + + <!--閫氱煡鍏憡璇︽儏 --> + <el-dialog :title="notice.noticeTitle" :visible.sync="open" width="800px" append-to-body> + <div style="margin-top: -20px; margin-bottom: 10px"> + <el-tag size="mini" effect="dark" type="warning" v-if="notice.noticeType == 2">鍏憡</el-tag> + <el-tag size="mini" effect="dark" v-else>淇℃伅</el-tag> + <span style="margin-left: 20px">{{ notice.createTime }}</span> + </div> + <div v-loading="loading" class="content"> + <div v-html="notice.noticeContent"></div> + </div> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="closeDetail">鍏� 闂�</el-button> + </div> + </el-dialog> + + <div style="width: 100%; text-align: center; font-size: 14px; color: #666; line-height: 32px; margin-top: 150px"> + <span> + Copyright 漏 2004锛�2023 娉扮憺鏁板垱绉戞妧(鍖椾含)鑲′唤鏈夐檺鍏徃鐗堟潈鎵�鏈� | 浜叕缃戝畨澶� 11010802036351鍙� | 浜琁CP璇�140146鍙� + </span> + <br /> + + </div> + </div> +</template> + +<script> +import { getDeviceStatistic } from '@/api/iot/device'; +import { listNotice, getNotice } from '@/api/system/notice'; +import CountTo from 'vue-count-to'; +import { loadBMap } from '@/utils/map.js'; +//瀹夎鐨勬槸echarts瀹屾暣鍖咃紝閲岄潰鍖呭惈鐧惧害鍦板浘鎵╁睍锛岃矾寰勪负 echarts/extension/bmap/bmap.js锛屽皢鍏跺紩鍏� +//ECharts鐨勭櫨搴﹀湴鍥炬墿灞曪紝鍙互鍦ㄧ櫨搴﹀湴鍥句笂灞曠幇鐐瑰浘锛岀嚎鍥撅紝鐑姏鍥剧瓑鍙鍖� +require('echarts/extension/bmap/bmap'); +import { getServer } from '@/api/monitor/server'; +import { listAllDeviceShort } from '@/api/iot/device'; + +export default { + name: 'Index', + components: { + CountTo, + }, + data() { + return { + // 閬僵灞� + loading: true, + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 淇℃伅鍒楄〃 + noticeList: [], + // 淇℃伅璇︽儏 + notice: {}, + // 鏄惁涓虹鐞嗗憳 + isAdmin: false, + // 璁惧鍒楄〃 + deviceList: [], + // 璁惧缁熻淇℃伅 + deviceStatistic: {}, + // 璁惧鎬绘暟 + deviceCount: 0, + // 鐗堟湰鍙� + version: '3.8.0', + // 鏈嶅姟鍣ㄤ俊鎭� + server: { + jvm: { + name: '', + version: '', + startTime: '', + runTime: '', + used: '', + total: 100, + }, + sys: { + computerName: '', + osName: '', + computerIp: '', + osArch: '', + }, + cpu: { + cpuNum: 1, + }, + mem: { + total: 2, + }, + }, + tableData: [], + }; + }, + created() { + this.init(); + this.getAllDevice(); + this.getNoticeList(); + this.getDeviceStatistic(); + }, + methods: { + init() { + if (this.$store.state.user.roles.indexOf('tenant') === -1 && this.$store.state.user.roles.indexOf('general') === -1) { + this.isAdmin = true; + this.getServer(); + } + }, + //鍒锋柊iframe + flushIframe() { + var iframe = window.parent.document.getElementById('iframe'); + iframe.contentWindow.location.reload(true); + }, + /** 鏌ヨ璁惧缁熻淇℃伅 */ + getDeviceStatistic() { + getDeviceStatistic().then((response) => { + this.deviceStatistic = response.data; + }); + }, + /** 鏌ヨ鍏憡鍒楄〃 */ + getNoticeList() { + let queryParams = { + pageNum: 1, + pageSize: 6, + }; + listNotice(queryParams).then((response) => { + this.noticeList = response.rows.splice(0, 6); + }); + }, + // 鎵撳紑淇℃伅璇︽儏 + openDetail(id) { + this.open = true; + this.loading = true; + getNotice(id).then((response) => { + this.notice = response.data; + this.open = true; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + closeDetail() { + this.title = ''; + this.open = false; + }, + /**鏌ヨ鎵�鏈夎澶� */ + getAllDevice() { + listAllDeviceShort(this.queryParams).then((response) => { + this.deviceList = response.rows; + this.deviceCount = response.total; + this.loadMap(); + }); + }, + /**鍔犺浇鍦板浘*/ + loadMap() { + this.$nextTick(() => { + loadBMap().then(() => { + this.getmap(); + }); + }); + }, + /** 鏌ヨ鏈嶅姟鍣ㄤ俊鎭� */ + getServer() { + getServer().then((response) => { + this.server = response.data; + this.tableData = [ + { + server: '鏈嶅姟鍣ㄥ悕', + serverContent: this.server.sys.computerName, + java: 'Java鍚嶇О', + javaContent: this.server.jvm.name, + }, + { + server: '鏈嶅姟鍣↖P', + serverContent: this.server.sys.computerIp, + java: '鍚姩鏃堕棿', + javaContent: this.server.jvm.startTime, + }, + { + server: '鎿嶄綔绯荤粺', + serverContent: this.server.sys.osName, + java: 'Java鐗堟湰', + javaContent: this.server.jvm.version, + }, + { + server: '绯荤粺鏋舵瀯', + serverContent: this.server.sys.osArch, + java: '杩愯鏃堕暱', + javaContent: this.server.jvm.runTime, + }, + { + server: 'CPU鏍稿績', + serverContent: this.server.cpu.cpuNum, + java: '鍗犵敤鍐呭瓨', + javaContent: this.server.jvm.used, + }, + { + server: '鍐呭瓨澶у皬', + serverContent: this.server.mem.total, + java: 'JVM鎬诲唴瀛�', + javaContent: this.server.jvm.total, + }, + ]; + this.$nextTick(() => { + this.drawPieCpu(); + this.drawPieMemery(); + this.drawPieDisk(); + }); + }); + }, + + /** 鍦板浘 */ + getmap() { + var myChart = this.$echarts.init(this.$refs.map); + var option; + + // 鍗曞嚮浜嬩欢 + myChart.on('click', (params) => { + if (params.data.deviceId) { + this.$router.push({ + path: '/iot/device-edit', + query: { + t: Date.now(), + deviceId: params.data.deviceId, + }, + }); + } + }); + + // 鏍煎紡鍖栨暟鎹� + let convertData = function (data, status) { + var res = []; + for (var i = 0; i < data.length; i++) { + var geoCoord = [data[i].longitude, data[i].latitude]; + if (geoCoord && data[i].status == status) { + res.push({ + name: data[i].deviceName, + value: geoCoord, + serialNumber: data[i].serialNumber, + status: data[i].status, + isShadow: data[i].isShadow, + firmwareVersion: data[i].firmwareVersion, + networkAddress: data[i].networkAddress, + productName: data[i].productName, + activeTime: data[i].activeTime == null ? '' : data[i].activeTime, + deviceId: data[i].deviceId, + serialNumber: data[i].serialNumber, + locationWay: data[i].locationWay, + }); + } + } + return res; + }; + option = { + title: { + text: '璁惧鍒嗗竷锛堝湪绾挎暟 ' + this.deviceList.filter((x) => x.status == 3).length + '锛�', + subtext: 'fastbee open source iot platform', + sublink: 'https://iot.fastbee.cn', + target: '_blank', + textStyle: { + color: '#333', + textBorderColor: '#fff', + textBorderWidth: 10, + }, + top: 10, + left: 'center', + }, + tooltip: { + trigger: 'item', + formatter: function (params) { + var htmlStr = '<div style="padding:5px;line-height:28px;">'; + htmlStr += "璁惧鍚嶇О锛� <span style='color:#409EFF'>" + params.data.name + '</span><br />'; + htmlStr += '璁惧缂栧彿锛� ' + params.data.serialNumber + '<br />'; + htmlStr += '璁惧鐘舵�侊細 '; + if (params.data.status == 1) { + htmlStr += "<span style='color:#E6A23C'>鏈縺娲�</span>" + '<br />'; + } else if (params.data.status == 2) { + htmlStr += "<span style='color:#F56C6C'>绂佺敤</span>" + '<br />'; + } else if (params.data.status == 3) { + htmlStr += "<span style='color:#67C23A'>鍦ㄧ嚎</span>" + '<br />'; + } else if (params.data.status == 4) { + htmlStr += "<span style='color:#909399'>绂荤嚎</span>" + '<br />'; + } + if (params.data.isShadow == 1) { + htmlStr += '璁惧褰卞瓙锛� ' + "<span style='color:#67C23A'>鍚敤</span>" + '<br />'; + } else { + htmlStr += '璁惧褰卞瓙锛� ' + "<span style='color:#909399'>鏈惎鐢�</span>" + '<br />'; + } + htmlStr += '浜у搧鍚嶇О锛� ' + params.data.productName + '<br />'; + htmlStr += '鍥轰欢鐗堟湰锛� Version ' + params.data.firmwareVersion + '<br />'; + htmlStr += '婵�娲绘椂闂达細 ' + params.data.activeTime + '<br />'; + htmlStr += '瀹氫綅鏂瑰紡锛� '; + if (params.data.locationWay == 1) { + htmlStr += '鑷姩瀹氫綅' + '<br />'; + } else if (params.data.locationWay == 2) { + htmlStr += '璁惧瀹氫綅' + '<br />'; + } else if (params.data.locationWay == 3) { + htmlStr += '鑷畾涔変綅缃�' + '<br />'; + } else { + htmlStr += '鏈煡' + '<br />'; + } + htmlStr += '鎵�鍦ㄥ湴鍧�锛� ' + params.data.networkAddress + '<br />'; + htmlStr += '</div>'; + return htmlStr; + }, + }, + bmap: { + center: [133, 38], + zoom: 5, + roam: true, + mapStyle: { + styleJson: [ + { + featureType: 'water', + elementType: 'all', + stylers: { + color: '#a0cfff', + }, + }, + { + featureType: 'land', + elementType: 'all', + stylers: { + color: '#fafafa', // #fffff8 娣¢粍鑹� + }, + }, + { + featureType: 'railway', + elementType: 'all', + stylers: { + visibility: 'off', + }, + }, + { + featureType: 'highway', + elementType: 'all', + stylers: { + color: '#fdfdfd', + }, + }, + { + featureType: 'highway', + elementType: 'labels', + stylers: { + visibility: 'off', + }, + }, + { + featureType: 'arterial', + elementType: 'geometry', + stylers: { + color: '#fefefe', + }, + }, + { + featureType: 'arterial', + elementType: 'geometry.fill', + stylers: { + color: '#fefefe', + }, + }, + { + featureType: 'poi', + elementType: 'all', + stylers: { + visibility: 'off', + }, + }, + { + featureType: 'green', + elementType: 'all', + stylers: { + visibility: 'off', + }, + }, + { + featureType: 'subway', + elementType: 'all', + stylers: { + visibility: 'off', + }, + }, + { + featureType: 'manmade', + elementType: 'all', + stylers: { + color: '#d1d1d1', + }, + }, + { + featureType: 'local', + elementType: 'all', + stylers: { + color: '#d1d1d1', + }, + }, + { + featureType: 'arterial', + elementType: 'labels', + stylers: { + visibility: 'off', + }, + }, + { + featureType: 'boundary', + elementType: 'all', + stylers: { + color: '#999999', + }, + }, + { + featureType: 'building', + elementType: 'all', + stylers: { + color: '#d1d1d1', + }, + }, + { + featureType: 'label', + elementType: 'labels.text.fill', + stylers: { + color: '#999999', + }, + }, + ], + }, + }, + series: [ + { + type: 'scatter', + coordinateSystem: 'bmap', + data: convertData(this.deviceList, 1), + symbolSize: 15, + itemStyle: { + color: '#E6A23C', + }, + }, + { + type: 'scatter', + coordinateSystem: 'bmap', + data: convertData(this.deviceList, 2), + symbolSize: 15, + itemStyle: { + color: '#F56C6C', + }, + }, + { + type: 'scatter', + coordinateSystem: 'bmap', + data: convertData(this.deviceList, 4), + symbolSize: 15, + itemStyle: { + color: '#909399', + }, + }, + { + type: 'effectScatter', + coordinateSystem: 'bmap', + data: convertData(this.deviceList, 3), + symbolSize: 15, + showEffectOn: 'render', + rippleEffect: { + brushType: 'stroke', + scale: 5, + }, + label: { + formatter: '{b}', + position: 'right', + show: false, + }, + itemStyle: { + color: '#67C23A', + shadowBlur: 100, + shadowColor: '#333', + }, + zlevel: 1, + }, + ], + }; + + option && myChart.setOption(option); + }, + + drawPieCpu() { + // 鍩轰簬鍑嗗濂界殑dom锛屽垵濮嬪寲echarts瀹炰緥 + let myChart = this.$echarts.init(this.$refs.pieCpu); + var option; + option = { + title: { + text: 'CPU浣跨敤鐜�', + left: 'left', + textStyle: { + fontSize: 16, + }, + }, + tooltip: { + trigger: 'item', + }, + legend: { + orient: 'vertical', + left: 'right', + }, + color: ['#E6A23C', '#F56C6C', '#DDD'], + series: [ + { + name: 'CPU浣跨敤鐜� %', + type: 'pie', + radius: '55%', + label: { + show: false, + }, + labelLine: { + normal: { + position: 'inner', + show: false, + }, + }, + data: [ + { + value: this.server.cpu.used, + name: '鐢ㄦ埛', + }, + { + value: this.server.cpu.sys, + name: '绯荤粺', + }, + { + value: this.server.cpu.free, + name: '绌洪棽', + }, + ], + }, + ], + }; + option && myChart.setOption(option); + }, + drawPieMemery() { + // 鍩轰簬鍑嗗濂界殑dom锛屽垵濮嬪寲echarts瀹炰緥 + let myChart = this.$echarts.init(this.$refs.pieMemery); + var option; + option = { + title: { + text: '鍐呭瓨浣跨敤鐜�', + left: 'left', + textStyle: { + fontSize: 16, + }, + }, + tooltip: { + trigger: 'item', + }, + legend: { + orient: 'vertical', + left: 'right', + }, + color: ['#F56C6C', '#DDD'], + series: [ + { + name: '鍐呭瓨浣跨敤鐜� G', + type: 'pie', + radius: '55%', + label: { + show: false, + }, + labelLine: { + normal: { + position: 'inner', + show: false, + }, + }, + data: [ + { + value: this.server.mem.used, + name: '宸茬敤', + }, + { + value: this.server.mem.free, + name: '鍓╀綑', + }, + ], + }, + ], + }; + option && myChart.setOption(option); + }, + drawPieDisk() { + // 鍩轰簬鍑嗗濂界殑dom锛屽垵濮嬪寲echarts瀹炰緥 + let myChart = this.$echarts.init(this.$refs.pieDisk); + var option; + let one = this.server.sysFiles[0].used.replace('GB', ''); + let two = this.server.sysFiles[0].free.replace('GB', ''); + option = { + title: { + text: '绯荤粺鐩樹娇鐢ㄧ巼', + left: 'left', + textStyle: { + fontSize: 16, + }, + }, + tooltip: { + trigger: 'item', + }, + legend: { + orient: 'vertical', + left: 'right', + }, + color: ['#F56C6C', '#DDD'], + series: [ + { + name: '纾佺洏鐘舵�� G', + type: 'pie', + radius: '55%', + label: { + show: false, + }, + labelLine: { + normal: { + position: 'inner', + show: false, + }, + }, + data: [ + { + value: one, + name: '宸茬敤', + }, + { + value: two, + name: '鍙敤', + }, + ], + }, + ], + }; + option && myChart.setOption(option); + }, + }, +}; +</script> + +<style lang="scss" scoped> +.phone { + height: 729px; + width: 370px; + background-image: url('../assets/images/phone.png'); + background-size: cover; + margin: 0 auto; +} + +.phone-container { + height: 618px; + width: 343px; + position: relative; + top: 46px; + left: 12px; + background-color: #fff; +} + +.content { + line-height: 24px; + padding: 10px; + border: 1px solid #eee; + border-radius: 10px; +} + +.description { + font-size: 12px; + + tr { + line-height: 20px; + } +} + +.panel-group { + .card-panel-col { + margin-bottom: 10px; + } + + .card-panel { + height: 68px; + cursor: pointer; + position: relative; + overflow: hidden; + color: #666; + border: 1px solid #eee; + border-radius: 5px; + //box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.08); + background-color: #fff; + + &:hover { + .card-panel-icon-wrapper { + color: #fff; + } + + .icon-blue { + background: #36a3f7; + } + + .icon-green { + background: #34bfa3; + } + + .icon-red { + background: #f56c6c; + } + + .icon-orange { + background: #e6a23c; + } + } + + .icon-blue { + color: #36a3f7; + } + + .icon-green { + color: #34bfa3; + } + + .icon-red { + color: #f56c6c; + } + + .icon-orange { + color: #e6a23c; + } + + .card-panel-icon-wrapper { + float: left; + margin: 10px; + padding: 10px; + transition: all 0.38s ease-out; + border-radius: 6px; + } + + .card-panel-icon { + float: left; + font-size: 30px; + } + + .card-panel-description { + float: right; + font-weight: bold; + margin: 15px; + margin-left: 0px; + + .card-panel-text { + line-height: 14px; + color: rgba(0, 0, 0, 0.45); + font-size: 14px; + margin-bottom: 12px; + text-align: right; + } + + .card-panel-num { + font-size: 18px; + } + } + } +} +</style> diff --git a/src/views/index_v1.vue b/src/views/index_v1.vue new file mode 100644 index 0000000..d2d2ec6 --- /dev/null +++ b/src/views/index_v1.vue @@ -0,0 +1,98 @@ +<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> diff --git a/src/views/iot/business/index.vue b/src/views/iot/business/index.vue new file mode 100644 index 0000000..d9599fe --- /dev/null +++ b/src/views/iot/business/index.vue @@ -0,0 +1,19 @@ +<template> + <div style="padding-left:20px;"> + <el-row :gutter="10"> + <el-col :span="14"> + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-tag type="danger" style="margin-left:15px;">寮�婧愮増鏈笉鏀寔璇ュ姛鑳�,璇峰墠寰�璐拱鍟嗕笟鐗堟湰</el-tag> + </el-col> + </el-row> + </el-col> + </el-row> + </div> +</template> + +<style scoped lang="scss"> + +</style> +<script> +</script> diff --git a/src/views/iot/category/index.vue b/src/views/iot/category/index.vue new file mode 100644 index 0000000..867bf30 --- /dev/null +++ b/src/views/iot/category/index.vue @@ -0,0 +1,275 @@ +<template> + <div style="padding:6px;"> + <el-card v-show="showSearch" style="margin-bottom:5px;"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom:-20px;"> + <el-form-item label="鍒嗙被鍚嶇О" prop="categoryName"> + <el-input v-model="queryParams.categoryName" placeholder="璇疯緭鍏ヤ骇鍝佸垎绫诲悕绉�" clearable size="small" + @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-item style="float:right;"> + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" + v-hasPermi="['iot:category:add']">鏂板</el-button> + </el-form-item> + </el-form> + </el-card> + + <el-card style="padding-bottom:100px;"> + <el-table v-loading="loading" :data="categoryList" @selection-change="handleSelectionChange" border> + <el-table-column label="浜у搧鍒嗙被鍚嶇О" align="center" prop="categoryName" /> + <el-table-column label="澶囨敞" align="left" header-align="center" prop="remark" min-width="150" /> + <el-table-column label="绯荤粺瀹氫箟" align="center" prop="isSys"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isSys" /> + </template> + </el-table-column> + <el-table-column label="鏄剧ず椤哄簭" align="center" prop="orderNum" /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width" width="150"> + <template slot-scope="scope"> + <el-button size="small" type="primary" style="padding:5px;" icon="el-icon-edit" + @click="handleUpdate(scope.row)" v-hasPermi="['iot:category:query']" + v-if="scope.row.isSys == '0' ? true : !isTenant">淇敼</el-button> + <el-button size="small" type="danger" style="padding:5px;" icon="el-icon-delete" + @click="handleDelete(scope.row)" v-hasPermi="['iot:category:remove']" + v-if="scope.row.isSys == '0' ? true : !isTenant">鍒犻櫎</el-button> + <span style="font-size:10px;color:#999;" v-if="scope.row.isSys == '1' && isTenant">绯荤粺瀹氫箟锛屼笉鑳戒慨鏀�</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-dialog 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="categoryName"> + <el-input v-model="form.categoryName" placeholder="璇疯緭鍏ヤ骇鍝佸垎绫诲悕绉�" /> + </el-form-item> + <el-form-item label="鏄剧ず椤哄簭" prop="orderNum"> + <el-input-number controls-position="right" v-model="form.orderNum" + placeholder="璇疯緭鍏ユ樉绀洪『搴�" style="width:100%" /> + </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" v-hasPermi="['iot:category:edit']" + v-show="form.categoryId">淇� 鏀�</el-button> + <el-button type="primary" @click="submitForm" v-hasPermi="['iot:category:add']" + v-show="!form.categoryId">鏂� 澧�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + + </el-card> + </div> +</template> + +<script> +import { + listCategory, + getCategory, + delCategory, + addCategory, + updateCategory +} from "@/api/iot/category"; + +export default { + name: "Category", + dicts: ["iot_yes_no"], + data() { + return { + // 鏄惁涓虹鎴� + isTenant: false, + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 浜у搧鍒嗙被琛ㄦ牸鏁版嵁 + categoryList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 20, + categoryName: null, + isSys: null, + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + categoryName: [{ + required: true, + message: "浜у搧鍒嗙被鍚嶇О涓嶈兘涓虹┖", + trigger: "blur" + }, { + min: 1, + max: 64, + message: '浜у搧鍒嗙被涓嶈兘灏戜簬1涓瓧绗﹀拰瓒呰繃64瀛楃', + }, + ], + orderNum: [{ + required: true, + message: '鍒嗙被椤哄簭涓嶈兘涓虹┖', + trigger: 'blur', + }, { + type: 'number', + min: -2147483648, + max: 2147483647, + message: '椤哄簭鍊间笉鑳借秴杩噄nt鍨嬬殑鍙栧�艰寖鍥�(-2^31鈥斺��2^31-1)', + trigger: 'blur', + }], + remark: [{ + required: false, + min: 0, + max: 500, + message: '澶囨敞涓嶈兘杈撳叆瓒呰繃500涓瓧绗�', + trigger: 'blur', + }], + isSys: [{ + required: true, + message: "鏄惁绯荤粺閫氱敤涓嶈兘涓虹┖", + trigger: "blur" + }], + } + }; + }, + created() { + this.getList(); + this.init(); + }, + methods: { + init() { + if (this.$store.state.user.roles.indexOf("tenant") !== -1) { + this.isTenant = true + } + }, + /** 鏌ヨ浜у搧鍒嗙被鍒楄〃 */ + getList() { + this.loading = true; + listCategory(this.queryParams).then(response => { + this.categoryList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + categoryId: null, + categoryName: null, + tenantId: null, + tenantName: null, + isSys: null, + parentId: null, + orderNum: 0, + delFlag: null, + createBy: null, + createTime: null, + updateBy: null, + updateTime: null, + remark: 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.categoryId) + this.single = selection.length !== 1 + this.multiple = !selection.length + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞浜у搧鍒嗙被"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const categoryId = row.categoryId || this.ids + getCategory(categoryId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼浜у搧鍒嗙被"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.categoryId != null) { + updateCategory(this.form).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + }); + } else { + addCategory(this.form).then(response => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const categoryIds = row.categoryId || this.ids; + let msg = ""; + this.$modal.confirm('鏄惁纭鍒犻櫎浜у搧鍒嗙被缂栧彿涓�"' + categoryIds + '"鐨勬暟鎹」锛�').then(function () { + return delCategory(categoryIds).then(response => { + msg = response.msg; + }); + }).then(() => { + this.getList(); + this.$modal.msgSuccess(msg); + }).catch(() => { }); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download('iot/category/export', { + ...this.queryParams + }, `category_${new Date().getTime()}.xlsx`) + } + } +}; +</script> diff --git a/src/views/iot/clientDetails/index.vue b/src/views/iot/clientDetails/index.vue new file mode 100644 index 0000000..e5c109a --- /dev/null +++ b/src/views/iot/clientDetails/index.vue @@ -0,0 +1,292 @@ +<template> +<div style="padding: 6px"> + <el-card v-show="showSearch" style="margin-bottom: 6px"> + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px" style="margin-bottom:-20px;"> + <el-form-item label="瀹㈡埛绔疘D" prop="clientId"> + <el-input v-model="queryParams.clientId" placeholder="璇疯緭鍏ュ鎴风ID" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="鎺堟潈骞冲彴" prop="type"> + <el-select v-model="queryParams.type" placeholder="璇烽�夋嫨骞冲彴" clearable size="small"> + <el-option v-for="dict in dict.type.oauth_platform" :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-tag type="danger" style="margin-left:15px;">璇ュ姛鑳芥殏涓嶅彲鐢�,鍚庨潰鐗堟湰鍙戝竷</el-tag> + </el-form-item> + <el-form-item style="float:right;"> + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['iot:clientDetails:add']">鏂板</el-button> + </el-form-item> + </el-form> + </el-card> + + <el-card style="padding-bottom: 100px"> + <el-table v-loading="loading" :data="clientDetailsList" @selection-change="handleSelectionChange"> + <el-table-column label="瀹㈡埛绔疘D" align="center" prop="clientId" /> + <el-table-column label="璧勬簮" align="center" prop="resourceIds" /> + <el-table-column label="鏉冮檺鑼冨洿" align="center" prop="scope" /> + <el-table-column label="鎺堟潈骞冲彴" align="center" prop="type"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.oauth_platform" :value="scope.row.type" /> + </template> + </el-table-column> + <el-table-column label="鑷姩鎺堟潈" align="center" prop="autoapprove"> + <template slot-scope="scope"> + <span v-if="scope.row.autoapprove=='true'">鑷姩鎺堟潈</span> + <span v-if="scope.row.autoapprove=='false'">鐢ㄦ埛楠岃瘉</span> + </template> + </el-table-column> + <el-table-column label="鎺堟潈妯″紡" align="center" prop="authorizedGrantTypes"> + <template slot-scope="scope"> + <div v-html="formatGrantTypesDisplay(scope.row.authorizedGrantTypes)"></div> + </template> + </el-table-column> + <el-table-column label="鍥炶皟鍦板潃" align="center" prop="webServerRedirectUri" min-width="130" /> + <el-table-column label="鏉冮檺" align="center" prop="authorities" /> + <el-table-column label="Token鏈夋晥鏈�" align="center" prop="accessTokenValidity" /> + <el-table-column label="Token鍒锋柊鏃堕棿" align="center" prop="refreshTokenValidity" /> + + <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="['iot:clientDetails:edit']">淇敼</el-button> + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['iot:clientDetails:remove']" disabled>鍒犻櫎</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="600px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="120px"> + <el-form-item label="鎺堟潈骞冲彴" prop="type"> + <el-select v-model="form.type" placeholder="璇烽�夋嫨鎺堟潈骞冲彴"> + <el-option v-for="dict in dict.type.oauth_platform" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option> + </el-select> + </el-form-item> + <el-form-item label="瀹㈡埛绔疘D" prop="clientId"> + <el-input v-model="form.clientId" placeholder="璇疯緭鍏ュ鎴风ID" /> + </el-form-item> + <el-form-item label="璧勬簮闆嗗悎" prop="resourceIds"> + <el-input v-model="form.resourceIds" placeholder="璇疯緭鍏ヨ祫婧�" /> + </el-form-item> + <el-form-item label="鎺堟潈妯″紡" prop="authorizedGrantTypes"> + <el-input v-model="form.authorizedGrantTypes" type="textarea" placeholder="璇疯緭鍏ユ巿鏉冩ā寮�" /> + </el-form-item> + <el-form-item label="绉橀挜" prop="clientSecret"> + <el-input v-model="form.clientSecret" placeholder="璇疯緭鍏ュ鎴风绉橀挜" /> + </el-form-item> + <el-form-item label="鍥炶皟鍦板潃" prop="webServerRedirectUri"> + <el-input v-model="form.webServerRedirectUri" type="textarea" placeholder="璇疯緭鍏ュ洖璋冨湴鍧�" /> + </el-form-item> + <el-form-item label="鏉冮檺" prop="authorities"> + <el-input v-model="form.authorities" placeholder="璇疯緭鍏ユ潈闄�" /> + </el-form-item> + <el-form-item label="Token鏈夋晥鏈�" prop="accessTokenValidity"> + <el-input v-model="form.accessTokenValidity" placeholder="璇疯緭鍏oken鏈夋晥鏃堕棿" /> + </el-form-item> + <el-form-item label="Token鍒锋柊鏃堕棿" prop="refreshTokenValidity"> + <el-input v-model="form.refreshTokenValidity" placeholder="璇疯緭鍏oken鍒锋柊鏈夋晥鏃堕棿" /> + </el-form-item> + <el-form-item label="棰勭暀淇℃伅" prop="additionalInformation"> + <el-input v-model="form.additionalInformation" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" /> + </el-form-item> + + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm" disabled>纭� 瀹�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + </el-card> +</div> +</template> + +<script> +import { + listClientDetails, + getClientDetails, + delClientDetails, + addClientDetails, + updateClientDetails, +} from "@/api/iot/clientDetails"; + +export default { + name: "ClientDetails", + dicts: ["oauth_platform"], + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 浜戜簯瀵规帴琛ㄦ牸鏁版嵁 + clientDetailsList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + clientId: null, + authorizedGrantTypes: null, + autoapprove: null, + type: null, + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: {}, + }; + }, + created() { + this.getList(); + }, + methods: { + /** 鏌ヨ浜戜簯瀵规帴鍒楄〃 */ + getList() { + this.loading = true; + listClientDetails(this.queryParams).then((response) => { + this.clientDetailsList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + clientId: null, + resourceIds: null, + clientSecret: null, + scope: null, + authorizedGrantTypes: null, + webServerRedirectUri: null, + authorities: null, + accessTokenValidity: null, + refreshTokenValidity: null, + additionalInformation: null, + autoapprove: null, + type: 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.clientId); + this.single = selection.length !== 1; + this.multiple = !selection.length; + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞浜戜簯瀵规帴"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const clientId = row.clientId || this.ids; + getClientDetails(clientId).then((response) => { + this.form = response.data; + this.open = true; + this.title = "淇敼浜戜簯瀵规帴"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + this.$refs["form"].validate((valid) => { + if (valid) { + if (this.form.clientId != null) { + updateClientDetails(this.form).then((response) => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + }); + } else { + addClientDetails(this.form).then((response) => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const clientIds = row.clientId || this.ids; + this.$modal + .confirm('鏄惁纭鍒犻櫎浜戜簯瀵规帴缂栧彿涓�"' + clientIds + '"鐨勬暟鎹」锛�') + .then(function () { + return delClientDetails(clientIds); + }) + .then(() => { + this.getList(); + this.$modal.msgSuccess("鍒犻櫎鎴愬姛"); + }) + .catch(() => {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download( + "iot/clientDetails/export", { + ...this.queryParams, + }, + `clientDetails_${new Date().getTime()}.xlsx` + ); + }, + /** 鏍煎紡鍖栨樉绀烘巿鏉冩ā寮� */ + formatGrantTypesDisplay(data) { + let dataArray = data.split(","); + let displayHtml = "" + for (let i = 0; i < dataArray.length; i++) { + displayHtml = displayHtml + "<div style='background-color:#eee;margin:0 auto;margin-bottom:5px;width:86px;border-radius:5px;padding:3px;'>" + this.convertGrantType(dataArray[i]) + "</div>" + } + return displayHtml; + }, + /** 鎺堟潈妯″紡杞崲 */ + convertGrantType(type) { + if (type == "client_credentials") { + return "瀹㈡埛绔ā寮�" + } else if (type == "password") { + return "瀵嗙爜妯″紡"; + } else if (type == "authorization_code") { + return "鎺堟潈鐮佹ā寮�"; + } else if (type == "implicit") { + return "绠�鍖栨ā寮�"; + } else if (type == "refresh_token") { + return "鍒锋柊Token"; + } else { + return ""; + } + } + + }, +}; +</script> diff --git a/src/views/iot/device/device-edit.vue b/src/views/iot/device/device-edit.vue new file mode 100644 index 0000000..a90b2ff --- /dev/null +++ b/src/views/iot/device/device-edit.vue @@ -0,0 +1,932 @@ +<template> + <el-card style="margin: 6px; padding-bottom: 100px"> + <el-tabs v-model="activeName" tab-position="left" @tab-click="tabChange" style="padding: 10px; min-height: 400px"> + <el-tab-pane name="basic"> + <span slot="label">* 鍩烘湰淇℃伅</span> + <el-form ref="form" :model="form" :rules="rules" label-width="100px"> + <el-row :gutter="100"> + <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8"> + <el-form-item label="璁惧鍚嶇О" prop="deviceName"> + <el-input v-model="form.deviceName" placeholder="璇疯緭鍏ヨ澶囧悕绉�"> + <el-button slot="append" @click="openSummaryDialog" v-if="form.deviceId != 0">鎽樿</el-button> + </el-input> + </el-form-item> + <el-form-item label="" prop="productName"> + <template slot="label"> + <span style="color: red">*</span> + 鎵�灞炰骇鍝� + </template> + <el-input readonly v-model="form.productName" placeholder="璇烽�夋嫨浜у搧" :disabled="form.status != 1"> + <el-button slot="append" @click="selectProduct()" :disabled="form.status != 1">閫夋嫨</el-button> + </el-input> + </el-form-item> + <el-form-item label="" prop="serialNumber"> + <template slot="label"> + <span style="color: red">*</span> + 璁惧缂栧彿 + </template> + <el-input v-model="form.serialNumber" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" :disabled="form.status !== 1" maxlength="32"> + <el-button slot="append" @click="generateNum" :loading="genDisabled" + :disabled="form.status !== 1">鐢熸垚</el-button> + </el-input> + </el-form-item> + <el-form-item v-if="openServerTip"> + <template> + <el-alert type="info" show-icon description="褰撳墠閫夋嫨TCP鍗忚,璁惧缂栧彿鐢熸垚涓篐EX鏍煎紡"></el-alert> + </template> + </el-form-item> + <el-form-item v-if="openTip"> + <template> + <el-alert type="success" show-icon description="褰撳墠閫夋嫨鐨勪骇鍝佸睘浜巑odbus鍗忚,灏嗗湪缃戝叧璁惧鍒涘缓鍚庢牴鎹噰闆嗙偣妯℃澘鐢熸垚瀛愯澶�"></el-alert> + </template> + </el-form-item> + <el-form-item label="鍥轰欢鐗堟湰" prop="firmwareVersion"> + <el-input v-model="form.firmwareVersion" placeholder="璇疯緭鍏ュ浐浠剁増鏈�" type="number" step="0.1" + :disabled="form.status != 1 || form.deviceType === 3"> + <template slot="prepend">Version</template> + </el-input> + </el-form-item> + <el-form-item label="妯℃嫙璁惧" prop="isSimulate"> + <el-switch v-model="form.isSimulate" active-text="" inactive-text="" :active-value="1" :inactive-value="0" + :disabled="form.deviceType === 3"></el-switch> + </el-form-item> + <el-form-item label="璁惧褰卞瓙" prop="isShadow"> + <el-switch v-model="form.isShadow" active-text="" inactive-text="" :active-value="1" :inactive-value="0" + :disabled="form.deviceType === 3"></el-switch> + </el-form-item> + <el-form-item label="绂佺敤璁惧" prop="deviceStatus"> + <el-switch v-model="deviceStatus" active-text="" inactive-text="" + :disabled="form.status === 1 || form.deviceType === 3" :active-value="1" :inactive-value="0" + active-color="#F56C6C"></el-switch> + </el-form-item> + <el-form-item label="澶囨敞淇℃伅" prop="remark"> + <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" rows="1" /> + </el-form-item> + </el-col> + <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8"> + <el-form-item label="瀹氫綅鏂瑰紡" prop="locationWay"> + <el-select v-model="form.locationWay" placeholder="璇烽�夋嫨璁惧鐘舵��" clearable size="small" style="width: 100%" + :disabled="form.deviceType === 3"> + <el-option v-for="dict in dict.type.iot_location_way" :key="dict.value" :label="dict.label" + :value="Number(dict.value)" /> + </el-select> + </el-form-item> + <el-form-item label="璁惧缁忓害" prop="longitude"> + <el-input v-model="form.longitude" placeholder="璇疯緭鍏ヨ澶囩粡搴�" type="number" :disabled="form.locationWay != 3"> + <el-link slot="append" :underline="false" href="https://api.map.baidu.com/lbsapi/getpoint/index.html" + target="_blank" :disabled="form.locationWay != 3">鍧愭爣鎷惧彇</el-link> + </el-input> + </el-form-item> + <el-form-item label="璁惧绾害" prop="latitude"> + <el-input v-model="form.latitude" placeholder="璇疯緭鍏ヨ澶囩含搴�" type="number" :disabled="form.locationWay != 3"> + <el-link slot="append" :underline="false" href="https://api.map.baidu.com/lbsapi/getpoint/index.html" + target="_blank" :disabled="form.locationWay != 3">鍧愭爣鎷惧彇</el-link> + </el-input> + </el-form-item> + <el-form-item label="鎵�鍦ㄥ湴鍧�" prop="networkAddress"> + <el-input v-model="form.networkAddress" placeholder="璇疯緭鍏ヨ澶囨墍鍦ㄥ湴鍧�" :disabled="form.locationWay != 3" /> + </el-form-item> + <el-form-item label="鍏ョ綉鍦板潃" prop="networkIp"> + <el-input v-model="form.networkIp" placeholder="璁惧鍏ョ綉IP" disabled /> + </el-form-item> + <el-form-item label="婵�娲绘椂闂�" prop="activeTime"> + <el-date-picker clearable v-model="form.activeTime" type="date" value-format="yyyy-MM-dd" + placeholder="璁惧婵�娲绘椂闂�" disabled style="width: 100%"></el-date-picker> + </el-form-item> + <el-form-item label="璁惧淇″彿" prop="rssi"> + <el-input v-model="form.rssi" placeholder="璁惧淇″彿寮哄害" disabled /> + </el-form-item> + <el-form-item label="鍏朵粬淇℃伅" prop="remark" v-if="form.deviceId != 0"> + <dict-tag :options="dict.type.iot_device_status" :value="form.status" + style="display: inline-block; margin-right: 8px" /> + <el-button size="small" @click="handleViewMqtt()">璁よ瘉淇℃伅</el-button> + <el-button size="small" @click="openCodeDialog()">浜岀淮鐮�</el-button> + </el-form-item> + </el-col> + <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8" v-if="form.deviceId != 0"> + <div + style="border: 1px solid #dfe4ed; border-radius: 5px; padding: 5px; text-align: center; line-height: 400px"> + <div id="map" style="height: 435px; width: 100%">鍦板浘灞曠ず鍖哄煙锛屾柊澧炲悗鏄剧ず</div> + </div> + </el-col> + </el-row> + </el-form> + + <el-form label-width="100px" style="margin-top: 50px"> + <el-form-item style="text-align: center; margin-left: -100px; margin-top: 10px"> + <el-button type="primary" @click="submitForm" v-hasPermi="['iot:device:edit']" v-show="form.deviceId != 0">淇� + 鏀�</el-button> + <el-button type="primary" @click="submitForm" v-hasPermi="['iot:device:add']" v-show="form.deviceId == 0">鏂� + 澧�</el-button> + </el-form-item> + </el-form> + + <!-- 閫夋嫨浜у搧 --> + <product-list ref="productList" :productId="form.productId" @productEvent="getProductData($event)" /> + </el-tab-pane> + + <el-tab-pane name="runningStatus" v-if="form.deviceType !== 3 && !isSubDev"> + <span slot="label">杩愯鐘舵��</span> + <running-status ref="runningStatus" :device="form" @statusEvent="getDeviceStatusData($event)"/> + </el-tab-pane> + + <el-tab-pane name="runningStatus" v-if="isSubDev"> + <span slot="label"><span style="color:red;">锟� </span>杩愯鐘舵��</span> + <business ref="business"/> + </el-tab-pane> + + <el-tab-pane name="sipChannel" :disabled="form.deviceId === 0" v-if="form.deviceType === 3"> + <span slot="label"><span style="color:red;">锟� </span>璁惧閫氶亾</span> + <business ref="business"/> + </el-tab-pane> + + <el-tab-pane :disabled="form.deviceId === 0" v-if="form.deviceType === 3" name="sipPlayer"> + <span slot="label"><span style="color:red;">锟� </span>璁惧鐩存挱</span> + <business ref="business"/> + </el-tab-pane> + + <el-tab-pane :disabled="form.deviceId === 0" v-if="form.deviceType === 3" name="sipVideo"> + <span slot="label"><span style="color:red;">锟� </span>鐩存挱褰曞儚</span> + <business ref="business"/> + </el-tab-pane> + + <el-tab-pane name="deviceTimer" :disabled="form.deviceId === 0" + v-if="form.deviceType !== 3 && hasShrarePerm('timer')"> + <span slot="label">璁惧瀹氭椂</span> + <device-timer ref="deviceTimer" :device="form" /> + </el-tab-pane> + + <el-tab-pane name="deviceUser" :disabled="form.deviceId == 0"> + <span slot="label">璁惧鐢ㄦ埛</span> + <device-user ref="deviceUser" :device="form" @userEvent="getUserData($event)" /> + </el-tab-pane> + + <el-tab-pane name="deviceLog" :disabled="form.deviceId == 0 && hasShrarePerm('log')" lazy> + <span slot="label">浜嬩欢鏃ュ織</span> + <device-log ref="deviceLog" :device="form" /> + </el-tab-pane> + + <el-tab-pane name="deviceFuncLog" :disabled="form.deviceId == 0" + v-if="form.deviceType !== 3 && hasShrarePerm('log')" lazy> + <span slot="label">鎸囦护鏃ュ織</span> + <device-func ref="deviceFuncLog" :device="form" /> + </el-tab-pane> + + <el-tab-pane name="deviceMonitor" :disabled="form.deviceId == 0 " + v-if="form.deviceType !== 3 && hasShrarePerm('monitor')"> + <span slot="label">瀹炴椂鐩戞祴</span> + <device-monitor ref="deviceMonitor" :device="form" /> + </el-tab-pane> + + <el-tab-pane name="deviceStastic" :disabled="form.deviceId == 0" + v-if="form.deviceType !== 3 && hasShrarePerm('statistic')"> + <span slot="label">鐩戞祴缁熻</span> + <device-statistic ref="deviceStatistic" :device="form" /> + </el-tab-pane> + + <!-- 鐢ㄤ簬璁剧疆闂磋窛 --> + <el-tab-pane disabled> + <span slot="label"> + <div style="margin-top: 350px"></div> + </span> + </el-tab-pane> + + <el-tab-pane name="deviceReturn" disabled> + <span slot="label"> + <el-button type="info" size="mini" @click="goBack()">杩斿洖鍒楄〃</el-button> + </span> + </el-tab-pane> + </el-tabs> + + <!-- 璁惧閰嶇疆JSON --> + <el-dialog title="鎽樿锛堣澶囦笂浼犵殑鍙鏁版嵁锛�" :visible.sync="openSummary" width="700px" append-to-body> + <el-row :gutter="20"> + <el-col :span="14"> + <div style="border: 1px solid #ccc; margin-top: -15px; height: 350px; width: 360px; overflow: scroll"> + <json-viewer :value="summary" :expand-depth="10" copyable> + <template v-slot:copy>澶嶅埗</template> + </json-viewer> + </div> + </el-col> + <el-col :span="10"> + <div style="border: 1px solid #ccc; width: 200px; text-align: center; margin-left: 20px; margin-top: -10px"> + <vue-qr :text="qrText" :size="200"></vue-qr> + <div style="padding-bottom: 10px">璁惧浜岀淮鐮�</div> + </div> + </el-col> + </el-row> + <div slot="footer" class="dialog-footer"> + <el-button type="info" @click="closeSummaryDialog">鍏� 闂�</el-button> + </div> + </el-dialog> + <!-- 浜岀淮鐮� --> + <el-dialog :visible.sync="openCode" width="300px" append-to-body> + <div style="border: 1px solid #ccc; width: 220px; text-align: center; margin: 0 auto; margin-top: -15px"> + <vue-qr :text="qrText" :size="200"></vue-qr> + <div style="padding-bottom: 10px">璁惧浜岀淮鐮�</div> + </div> + </el-dialog> + <el-dialog title="Mqtt杩炴帴鍙傛暟" :visible.sync="openViewMqtt" width="600px" append-to-body> + <el-form ref="listQuery" :model="listQuery" :rules="rules" label-width="150px"> + <el-form-item label="clientId" prop="clientId"> + <el-input v-model="listQuery.clientId" disabled style="width: 80%" /> + </el-form-item> + <el-form-item label="username" prop="username"> + <el-input v-model="listQuery.username" disabled style="width: 80%" /> + </el-form-item> + <el-form-item label="passwd" prop="passwd"> + <el-input clearable v-model="listQuery.passwd" disabled style="width: 80%"></el-input> + </el-form-item> + <el-form-item label="port" prop="port"> + <el-input clearable v-model="listQuery.port" disabled style="width: 80%"></el-input> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button class="btns" type="primary" @click="doCopy(2)">涓�閿鍒�</el-button> + <el-button @click="closeSummaryDialog">鍏� 闂�</el-button> + </div> + </el-dialog> + </el-card> +</template> + +<script> +import JsonViewer from 'vue-json-viewer'; +import 'vue-json-viewer/style.css'; +import productList from './product-list'; +import deviceLog from './device-log'; +import deviceUser from './device-user'; +import runningStatus from './running-status'; +import deviceMonitor from './device-monitor'; +import deviceStatistic from './device-statistic'; +import deviceTimer from './device-timer'; +import DeviceFunc from './device-functionlog'; +import business from "@/views/iot/business/index.vue"; +import vueQr from 'vue-qr'; +import { loadBMap } from '@/utils/map.js'; +import { deviceSynchronization, getDevice, addDevice, updateDevice, generatorDeviceNum, listDevice, getMqttConnect } from '@/api/iot/device'; +import { getDeviceRunningStatus } from '@/api/iot/device'; +import { cacheJsonThingsModel } from '@/api/iot/model'; +import { getDeviceTemp } from '@/api/iot/temp'; + +export default { + name: 'DeviceEdit', + dicts: ['iot_device_status', 'iot_location_way'], + components: { + business, + DeviceFunc, + deviceLog, + deviceUser, + deviceMonitor, + deviceStatistic, + runningStatus, + productList, + deviceTimer, + JsonViewer, + vueQr, + }, + watch: { + activeName(val) { + if (val == 'deviceStastic') { + this.$nextTick(() => { + // TODO 閲嶇疆缁熻琛ㄦ牸鐨勫昂瀵� + }); + } + }, + }, + computed: { + deviceStatus: { + set(val) { + if (val == 1) { + // 1-鏈縺娲伙紝2-绂佺敤锛�3-鍦ㄧ嚎锛�4-绂荤嚎 + this.form.status = 2; + } else if (val == 0) { + this.form.status = 4; + } else { + this.form.status = this.oldDeviceStatus; + } + }, + get() { + if (this.form.status == 2) { + return 1; + } + return 0; + }, + }, + }, + data() { + return { + // 浜岀淮鐮佸唴瀹� + qrText: 'fastbee', + // 鎵撳紑璁惧閰嶇疆瀵硅瘽妗� + openSummary: false, + //浜岀淮鐮� + openCode: false, + openViewMqtt: false, + // 鐢熸垚璁惧缂栫爜鏄惁绂佺敤 + genDisabled: false, + // 閫変腑閫夐」鍗� + activeName: 'basic', + //鏌ョ湅mqtt鍙傛暟 + mqttList: [], + // 閬僵灞� + loading: true, + // 璁惧寮�濮嬬姸鎬� + oldDeviceStatus: null, + deviceId: '', + channelId: '', + // 琛ㄥ崟鍙傛暟 + form: { + productId: 0, + status: 1, + locationWay: 1, + firmwareVersion: 1.0, + serialNumber: '', + deviceType: 1, + isSimulate: 0, + }, + //mqtt鍙傛暟鏌ョ湅 + listQuery: { + clientId: 0, + username: '', + passwd: '', + port: '', + }, + openTip: false, + openServerTip: false, + serverType: 1, + //鐢ㄤ簬鍒ゆ柇鏄惁鏄澶囩粍(modbus) + isSubDev: false, + // 璁惧鎽樿 + summary: [], + // 鍦板潃 + baseUrl: process.env.VUE_APP_BASE_API, + // 鍦板浘鐩稿叧 + map: null, + mk: null, + latitude: '', + longitude: '', + // 琛ㄥ崟鏍¢獙 + rules: { + deviceName: [ + { + required: true, + message: '璁惧鍚嶇О涓嶈兘涓虹┖', + trigger: 'blur', + }, + { + min: 2, + max: 32, + message: '璁惧鍚嶇О闀垮害鍦� 2 鍒� 32 涓瓧绗�', + trigger: 'blur', + }, + ], + firmwareVersion: [ + { + required: true, + message: '鍥轰欢鐗堟湰涓嶈兘涓虹┖', + trigger: 'blur', + }, + ], + }, + isMediaDevice: false, + }; + }, + created() { + let activeName = this.$route.query.activeName; + if (activeName != null && activeName != '') { + this.activeName = activeName; + } + // 鑾峰彇璁惧淇℃伅 + this.form.deviceId = this.$route.query && this.$route.query.deviceId; + if (this.form.deviceId != 0) { + this.connectMqtt(); + this.getDevice(this.form.deviceId); + } + this.isSubDev = this.$route.query.isSubDev === 1; + }, + activated() { + // 璺宠浆閫夐」鍗� + let activeName = this.$route.query.activeName; + if (activeName != null && activeName != '') { + this.activeName = activeName; + } + }, + destroyed() { + // 鍙栨秷璁㈤槄涓婚 + this.mqttUnSubscribe(this.form); + }, + methods: { + /* 杩炴帴Mqtt娑堟伅鏈嶅姟鍣� */ + async connectMqtt() { + if (this.$mqttTool.client == null) { + await this.$mqttTool.connect(this.vuex_token); + } + this.mqttCallback(); + }, + /* Mqtt鍥炶皟澶勭悊 */ + mqttCallback() { + this.$mqttTool.client.on('message', (topic, message, buffer) => { + let topics = topic.split('/'); + let productId = topics[1]; + let deviceNum = topics[2]; + message = JSON.parse(message.toString()); + if (!message) { + return; + } + if (topics[3] == 'status' || topics[2] == 'status') { + console.log('鎺ユ敹鍒般�愯澶囩姸鎬�-璇︽儏銆戜富棰橈細', topic); + console.log('鎺ユ敹鍒般�愯澶囩姸鎬�-璇︽儏銆戝唴瀹癸細', message); + // 鏇存柊鍒楄〃涓澶囩殑鐘舵�� + if (this.form.serialNumber == deviceNum) { + this.oldDeviceStatus = message.status; + this.form.status = message.status; + this.form.isShadow = message.isShadow; + this.form.rssid = message.rssid; + } + } + //涓嶆槸modbus涓嶈浆鍙戝埌瀛愰〉闈紝鍏朵粬璁惧鐨勯〉闈㈡湁鍥炶皟鏂规硶 + if (this.isSubDev) { + /*鍙戦�佽澶囦笂鎶ュ埌瀛愭ā鍧�*/ + if (topic.endsWith('ws/service')) { + this.$busEvent.$emit('updateData', { + serialNumber: topics[2], + productId: this.form.productId, + data: message, + }); + } + } + /*鍙戦�佽澶囦笂鎶ュ埌瀛愭ā鍧�*/ + if (topic.endsWith('ws/post/simulate')) { + this.$busEvent.$emit('logData', { + serialNumber: topics[1], + productId: this.form.productId, + data: message, + }); + } + }); + }, + /** Mqtt璁㈤槄涓婚 */ + mqttSubscribe(device) { + // 璁㈤槄褰撳墠璁惧鐘舵�佸拰瀹炴椂鐩戞祴 + let topicStatus = '/' + device.productId + '/' + device.serialNumber + '/status/post'; + let topicProperty = '/' + device.productId + '/' + device.serialNumber + '/property/post'; + let topicFunction = '/' + device.productId + '/' + device.serialNumber + '/function/post'; + let topicMonitor = '/' + device.productId + '/' + device.serialNumber + '/monitor/post'; + let topicReply = '/' + device.productId + '/' + device.serialNumber + '/service/reply'; + let topics = []; + let serviceTop = '/' + device.productId + '/' + device.serialNumber + '/ws/service'; + topics.push(serviceTop); + + topics.push(topicStatus); + topics.push(topicFunction); + topics.push(topicMonitor); + topics.push(topicReply); + /*modbus璁惧涓嶈闃呮topic*/ + if (!this.isSubDev) { + // topics.push(topicProperty); + } + this.$mqttTool.subscribe(topics); + }, + /** Mqtt鍙栨秷璁㈤槄涓婚 */ + mqttUnSubscribe(device) { + // 璁㈤槄褰撳墠璁惧鐘舵�佸拰瀹炴椂鐩戞祴 + let topicStatus = '/' + device.productId + '/' + device.serialNumber + '/status/post'; + let topicProperty = '/' + device.productId + '/' + device.serialNumber + '/property/post'; + let topicFunction = '/' + device.productId + '/' + device.serialNumber + '/function/post'; + let topicMonitor = '/' + device.productId + '/' + device.serialNumber + '/monitor/post'; + let topicReply = '/' + device.productId + '/' + device.serialNumber + '/service/reply'; + let topics = []; + let serviceTop = '/' + device.productId + '/' + device.serialNumber + '/ws/service'; + topics.push(serviceTop); + + topics.push(topicStatus); + topics.push(topicFunction); + topics.push(topicMonitor); + topics.push(topicReply); + /*modbus璁惧涓嶈闃呮topic*/ + if (!this.isSubDev) { + /*閫氳繃缃戝叧鍐嶈浆鍙�*/ + // topics.push(topicProperty); + } + this.$mqttTool.unsubscribe(topics); + }, + + // 鑾峰彇瀛愮粍浠惰闃呯殑璁惧鐘舵�� + getDeviceStatusData(status) { + this.form.status = status; + }, + + /** 閫夐」鍗℃敼鍙樹簨浠�*/ + tabChange(panel) { + this.$nextTick(() => { + // 鑾峰彇鐩戞祴缁熻鏁版嵁 + if (panel.name === 'deviceStastic' && !this.isSubDev) { + this.$refs.deviceStatistic.getListHistory(); + } else if (panel.name === 'deviceTimer'&& !this.isSubDev) { + this.$refs.deviceTimer.getList(); + } + }); + }, + /** 鏁版嵁鍚屾*/ + deviceSynchronization() { + deviceSynchronization(this.form.serialNumber).then(async (response) => { + // 鑾峰彇缂撳瓨鐗╂ā鍨� + response.data.cacheThingsModel = await this.getCacheThingsModdel(response.data.productId); + // 鑾峰彇璁惧杩愯鐘舵�� + response.data.thingsModels = await this.getDeviceStatus(this.form); + // 鏍煎紡鍖栫墿妯″瀷锛屾媶鍒嗗嚭鐩戞祴鍊�,鏁扮粍娣诲姞鍓嶇紑 + this.formatThingsModel(response.data); + this.form = response.data; + // 閫夐」鍗″垏鎹� + this.activeName = 'runningStatus'; + this.oldDeviceStatus = this.form.status; + this.loadMap(); + }); + }, + /**鑾峰彇璁惧璇︽儏*/ + getDevice(deviceId) { + getDevice(deviceId).then(async (response) => { + // 鍒嗕韩璁惧鑾峰彇鐢ㄦ埛鏉冮檺 + response.data.userPerms = []; + if (response.data.isOwner == 0) { + getDeviceUser(deviceId, this.$store.state.user.userId).then((permResponse) => { + response.data.userPerms = permResponse.data.perms.split(','); + // 鑾峰彇璁惧鐘舵�佸拰鐗╂ā鍨� + this.getDeviceStatusWitchThingsModel(response); + }); + } else { + // 鑾峰彇璁惧鐘舵�佸拰鐗╂ā鍨� + this.getDeviceStatusWitchThingsModel(response); + } + }); + }, + /**鐢ㄦ埛鏄惁鎷ユ湁鍒嗕韩璁惧鏉冮檺*/ + hasShrarePerm(permission) { + if (this.form.isOwner == 0) { + // 鍒嗕韩璁惧鏉冮檺 + if (this.form.userPerms.indexOf(permission) == -1) { + return false; + } + } + return true; + }, + /** 鑾峰彇缂撳瓨鐗╂ā鍨�*/ + getCacheThingsModdel(productId) { + return new Promise((resolve, reject) => { + cacheJsonThingsModel(productId) + .then((response) => { + resolve(JSON.parse(response.data)); + }) + .catch((error) => { + reject(error); + }); + }); + }, + /**鑾峰彇璁惧杩愯鐘舵��*/ + getDeviceStatus(data) { + const params = { + deviceId: data.deviceId, + }; + return new Promise((resolve, reject) => { + getDeviceRunningStatus(params) + .then((response) => { + resolve(response.data.thingsModels); + }) + .catch((error) => { + reject(error); + }); + }); + }, + formatThingsModel(data) { + data.chartList = []; + data.monitorList = []; + data.staticList = []; + // 鐗╂ā鍨嬫牸寮忓寲 + for (let i = 0; i < data.thingsModels.length; i++) { + // 鏁板瓧绫诲瀷璁剧疆榛樿鍊煎苟杞崲鏈暟鍊� + if (data.thingsModels[i].datatype.type == 'integer' || data.thingsModels[i].datatype.type == 'decimal') { + if (data.thingsModels[i].shadow == '') { + data.thingsModels[i].shadow = Number(data.thingsModels[i].datatype.min); + } else { + data.thingsModels[i].shadow = Number(data.thingsModels[i].shadow); + } + } + + // 鐗╂ā鍨嬪垎绫绘斁缃� + if (data.thingsModels[i].datatype.type == 'array') { + if (data.thingsModels[i].datatype.arrayType == 'object') { + for (let k = 0; k < data.thingsModels[i].datatype.arrayParams.length; k++) { + for (let j = 0; j < data.thingsModels[i].datatype.arrayParams[k].length; j++) { + // 鏁扮粍鍏冪礌涓弬鏁癐D娣诲姞鍓嶇紑锛屼緥濡傦細array_00_ + let index = k > 9 ? String(k) : '0' + k; + let prefix = 'array_' + index + '_'; + data.thingsModels[i].datatype.arrayParams[k][j].id = prefix + data.thingsModels[i].datatype.arrayParams[k][j].id; + // 鍥捐〃銆佸疄鏃剁洃娴嬨�佺洃娴嬬粺璁″垎绫绘斁缃� + if (data.thingsModels[i].datatype.arrayParams[k][j].isChart == 1) { + // 鍥捐〃 + data.thingsModels[i].datatype.arrayParams[k][j].name = '[' + data.thingsModels[i].name + (k + 1) + '] ' + data.thingsModels[i].datatype.arrayParams[k][j].name; + data.thingsModels[i].datatype.arrayParams[k][j].datatype.arrayType = 'object'; + data.chartList.push(data.thingsModels[i].datatype.arrayParams[k][j]); + if (data.thingsModels[i].datatype.arrayParams[k][j].isHistory == 1) { + // 鐩戞祴缁熻 + data.staticList.push(data.thingsModels[i].datatype.arrayParams[k][j]); + } + if (data.thingsModels[i].datatype.arrayParams[k][j].isMonitor == 1) { + // 瀹炴椂鐩戞祴 + data.monitorList.push(data.thingsModels[i].datatype.arrayParams[k][j]); + } + data.thingsModels[i].datatype.arrayParams[k].splice(j--, 1); + } + } + } + } else { + // 瀛楃涓叉媶鍒嗕负鐗╂ā鍨嬫暟缁� model=id/name/type/isReadonly/value/shadow + let values = data.thingsModels[i].value != '' ? data.thingsModels[i].value.split(',') : []; + let shadows = data.thingsModels[i].shadow != '' ? data.thingsModels[i].shadow.split(',') : []; + for (let j = 0; j < data.thingsModels[i].datatype.arrayCount; j++) { + if (!data.thingsModels[i].datatype.arrayModel) { + data.thingsModels[i].datatype.arrayModel = []; + } + // 鏁扮粍閲岄潰鐨処D闇�瑕佹坊鍔犲墠缂�鍜岀储寮曪紝渚嬪锛歛rray_00_temperature + let index = j > 9 ? String(j) : '0' + j; + let prefix = 'array_' + index + '_'; + data.thingsModels[i].datatype.arrayModel[j] = { + id: prefix + data.thingsModels[i].id, + name: data.thingsModels[i].name, + type: data.thingsModels[i].type, + isReadonly: data.thingsModels[i].isReadonly, + value: values[j] ? values[j] : '', + shadow: shadows[j] ? shadows[j] : '', + }; + } + } + } else if (data.thingsModels[i].datatype.type == 'object') { + for (let j = 0; j < data.thingsModels[i].datatype.params.length; j++) { + // 鍥捐〃銆佸疄鏃剁洃娴嬨�佺洃娴嬬粺璁″垎绫绘斁缃� + if (data.thingsModels[i].datatype.params[j].isChart == 1) { + // 鍥捐〃 + data.thingsModels[i].datatype.params[j].name = '[' + data.thingsModels[i].name + '] ' + data.thingsModels[i].datatype.params[j].name; + data.chartList.push(data.thingsModels[i].datatype.params[j]); + if (data.thingsModels[i].datatype.params[j].isHistory == 1) { + // 鐩戞祴缁熻 + data.staticList.push(data.thingsModels[i].datatype.params[j]); + } + if (data.thingsModels[i].datatype.params[j].isMonitor == 1) { + // 瀹炴椂鐩戞祴 + data.monitorList.push(data.thingsModels[i].datatype.params[j]); + } + data.thingsModels[i].datatype.params.splice(j--, 1); + } + } + } else if (data.thingsModels[i].isChart == 1) { + // // 鍥捐〃銆佸疄鏃剁洃娴嬨�佺洃娴嬬粺璁″垎绫绘斁缃� + data.chartList.push(data.thingsModels[i]); + if (data.thingsModels[i].isHistory == 1) { + // 鐩戞祴缁熻 + data.staticList.push(data.thingsModels[i]); + } + if (data.thingsModels[i].isMonitor == 1) { + // 瀹炴椂鐩戞祴 + data.monitorList.push(data.thingsModels[i]); + } + // 浣跨敤i--瑙e喅绱㈠紩鍙樻洿闂 + data.thingsModels.splice(i--, 1); + } + } + }, + /**鍔犺浇鍦板浘*/ + loadMap() { + this.$nextTick(() => { + loadBMap().then(() => { + this.getmap(); + }); + }); + }, + /** 杩斿洖鎸夐挳 */ + goBack() { + const obj = { + path: '/iot/device', + query: { + t: Date.now(), + pageNum: this.$route.query.pageNum, + }, + }; + this.$tab.closeOpenPage(obj); + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + deviceId: 0, + deviceName: null, + productId: null, + productName: null, + userId: null, + userName: null, + tenantId: null, + tenantName: null, + serialNumber: '', + firmwareVersion: 1.0, + status: 1, + rssi: null, + networkAddress: null, + networkIp: null, + longitude: null, + latitude: null, + activeTime: null, + createBy: null, + createTime: null, + updateBy: null, + updateTime: null, + remark: null, + locationWay: 1, + clientId: 0, + }; + this.deviceStatus = 0; + this.resetForm('form'); + }, + /** 鎻愪氦鎸夐挳 */ + async submitForm() { + if (this.form.serialNumber == null || this.form.serialNumber == 0) { + this.$modal.alertError('璁惧缂栧彿涓嶈兘涓虹┖'); + return; + } + let reg = /^[0-9a-zA-Z]+$/; + if (!reg.test(this.form.serialNumber)) { + this.$modal.alertError('璁惧缂栧彿鍙兘鏄瓧姣嶅拰鏁板瓧'); + return; + } + if (this.form.productId == null || this.form.productId == 0) { + this.$modal.alertError('鎵�灞炰骇鍝佷笉鑳戒负绌�'); + return; + } + + this.$refs['form'].validate((valid) => { + if (valid) { + if (this.form.deviceId != 0) { + updateDevice(this.form).then((response) => { + if (response.data == 0) { + this.$modal.alertError(response.msg); + } else { + this.$modal.alertSuccess('淇敼鎴愬姛'); + this.form = JSON.parse(JSON.stringify(this.form)); + this.loadMap(); + } + }); + } else { + addDevice(this.form).then(async (response) => { + // 鑾峰彇璁惧鐘舵�� + await this.getDeviceStatusWitchThingsModel(response); + if (this.form.deviceId == null || this.form.deviceId == 0) { + this.$modal.alertError('璁惧缂栧彿宸茬粡瀛樺湪锛屾坊鍔犺澶囧け璐�'); + } else { + if (this.form.status == 2) { + this.deviceStatus = 1; + } + + this.$modal.alertSuccess('娣诲姞璁惧鎴愬姛'); + this.loadMap(); + } + }); + } + } + }); + }, + /** 鑾峰彇璁惧鐘舵�佸拰鐗╂ā鍨� **/ + async getDeviceStatusWitchThingsModel(response) { + // 鑾峰彇缂撳瓨鐗╂ā鍨� + response.data.cacheThingsModel = await this.getCacheThingsModdel(response.data.productId); + // 鑾峰彇璁惧杩愯鐘舵�� + response.data.thingsModels = await this.getDeviceStatus(response.data); + //鍒嗕韩璁惧杩囨护娌℃湁鏉冮檺鐨勭墿妯″瀷 + if (response.data.isOwner == 0) { + for (let i = 0; i < response.data.thingsModels.length; i++) { + if (response.data.userPerms.indexOf(response.data.thingsModels[i].id) == -1) { + response.data.thingsModels.splice(i--, 1); + } + } + } + // 鏍煎紡鍖栫墿妯″瀷锛屾媶鍒嗗嚭鐩戞祴鍊�,鏁扮粍娣诲姞鍓嶇紑 + this.formatThingsModel(response.data); + this.form = response.data; + // 瑙f瀽璁惧鎽樿 + if (this.form.summary != null && this.form.summary != '') { + this.summary = JSON.parse(this.form.summary); + } + this.isSubDev = this.form.subDeviceList && this.form.subDeviceList.length > 0; + this.oldDeviceStatus = this.form.status; + this.loadMap(); + //Mqtt璁㈤槄 + this.connectMqtt(); + this.mqttSubscribe(this.form); + }, + /**閫夋嫨浜у搧 */ + selectProduct() { + this.$refs.productList.open = true; + this.$refs.productList.getList(); + }, + genSipID() { + this.$refs.sipidGen.open = true; + }, + /**鑾峰彇閫変腑鐨勪骇鍝� */ + getProductData(product) { + this.form.productId = product.productId; + this.form.productName = product.productName; + this.form.deviceType = product.deviceType; + this.form.tenantId = product.tenantId; + this.form.tenantName = product.tenantName; + if (product.transport === 'TCP') { + this.openServerTip = true; + this.serverType = 3; + } else { + this.openServerTip = false; + this.serverType = 1; + } + }, + // 鑾峰彇閫変腑鐨勭敤鎴� + getUserData(user) { }, + /**鍏抽棴鐗╂ā鍨� */ + openSummaryDialog() { + let json = { + type: 1, // 1=鎵爜鍏宠仈璁惧 + deviceNumber: this.form.serialNumber, + productId: this.form.productId, + // productName: this.form.productName, + }; + this.qrText = JSON.stringify(json); + this.openSummary = true; + }, + /**鍏抽棴鐗╂ā鍨� */ + closeSummaryDialog() { + this.openSummary = false; + this.openViewMqtt = false; + }, + doCopy(type) { + if (type == 2) { + const input = document.createElement('input'); + input.value = '{clientId:' + this.listQuery.clientId + ',username:' + this.listQuery.username + ',passwd:' + this.listQuery.passwd + ',port:' + this.listQuery.port + '}'; + document.body.appendChild(input); + input.select(); //閫変腑杈撳叆妗� + document.execCommand('Copy'); //澶嶅埗褰撳墠閫変腑鏂囨湰鍒板墠鍒囨澘 + document.body.removeChild(input); + this.$message.success('澶嶅埗鎴愬姛'); + } + }, + openCodeDialog() { + let json = { + type: 1, // 1=鎵爜鍏宠仈璁惧 + deviceNumber: this.form.serialNumber, + productId: this.form.productId, + productName: this.form.productName, + }; + this.qrText = JSON.stringify(json); + this.openCode = true; + }, + // 鍦板浘瀹氫綅 + getmap() { + this.map = new BMap.Map('map'); + let point = null; + if (this.form.longitude != null && this.form.longitude != '' && this.form.latitude != null && this.form.latitude != '') { + point = new BMap.Point(this.form.longitude, this.form.latitude); + } else { + point = new BMap.Point(116.404, 39.915); + } + this.map.centerAndZoom(point, 19); + this.map.enableScrollWheelZoom(true); // 寮�鍚紶鏍囨粴杞缉鏀� + this.map.addControl(new BMap.NavigationControl()); + + // 鏍囨敞璁惧浣嶇疆 + this.mk = new BMap.Marker(point); + this.map.addOverlay(this.mk); + this.map.panTo(point); + }, + // 鐢熸垚闅忔満瀛楁瘝鍜屾暟瀛� + generateNum() { + if (!this.form.productId || this.form.productId == 0) { + this.$modal.alertError('璇峰厛閫夋嫨浜у搧'); + return; + } + this.genDisabled = true; + const params = { type: this.serverType }; + generatorDeviceNum(params).then((response) => { + this.form.serialNumber = response.data; + this.genDisabled = false; + }); + }, + //mqtt鍙傛暟鏌ョ湅 + handleViewMqtt() { + this.openViewMqtt = true; + this.loading = true; + const params = { + deviceId: this.form.deviceId, + }; + getMqttConnect(params).then((response) => { + if (response.code == 200) { + this.listQuery = response.data; + this.loading = false; + } + }); + }, + }, +}; +</script> diff --git a/src/views/iot/device/device-functionlog.vue b/src/views/iot/device/device-functionlog.vue new file mode 100644 index 0000000..81223ef --- /dev/null +++ b/src/views/iot/device/device-functionlog.vue @@ -0,0 +1,222 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> + <el-form-item label="璇烽�夋嫨璁惧浠庢満:" label-width="120px" v-if="isSubDev"> + <el-select v-model="queryParams.slaveId" placeholder="璇烽�夋嫨璁惧浠庢満" @change="selectSlave"> + <el-option v-for="slave in slaveList" :key="slave.slaveId" :label="`${slave.deviceName} (浠庢満鍦板潃:${slave.slaveId})`" :value="slave.slaveId"></el-option> + </el-select> + </el-form-item> + <el-form-item label="鏃ュ織绫诲瀷" prop="funType"> + <el-select v-model="queryParams.funType" placeholder="璇烽�夋嫨绫诲瀷" clearable size="small"> + <el-option v-for="dict in dict.type.iot_function_type" :key="dict.value" :label="dict.label" :value="dict.value" /> + </el-select> + </el-form-item> + <el-form-item label="鏍囪瘑绗�" prop="identify"> + <el-input v-model="queryParams.identify" placeholder="璇疯緭鍏ユ爣璇嗙" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="鏃堕棿鑼冨洿"> + <el-date-picker v-model="daterangeTime" size="small" 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-table v-loading="loading" :data="logList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column :label="showName" align="center" prop="identify" /> + <el-table-column label="鎸囦护绫诲瀷" align="center" prop="funType" width="120px"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_function_type" :value="scope.row.funType" /> + </template> + </el-table-column> + <el-table-column label="璁剧疆鍊�" align="center" prop="funValue" /> + <el-table-column label="璁惧缂栧彿" align="center" prop="serialNumber" /> + <el-table-column label="涓嬪彂鏃堕棿" align="center" prop="createTime" /> + <el-table-column label="涓嬪彂缁撴灉鎻忚堪" align="center" prop="resultMsg" /> + <el-table-column label="鎿嶄綔" align="center" width="80"> + <template slot-scope="scope"> + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['iot:device: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" /> + </div> +</template> + +<script> +import { listLog, delLog } from '@/api/iot/functionLog'; + +export default { + name: 'device-func', + dicts: ['iot_function_type', 'iot_yes_no'], + props: { + device: { + type: Object, + default: null, + }, + }, + watch: { + // 鑾峰彇鍒扮埗缁勪欢浼犻�掔殑device鍚� + device: function (newVal) { + this.deviceInfo = newVal; + if (this.deviceInfo && this.deviceInfo.deviceId != 0) { + this.isSubDev = this.deviceInfo.subDeviceList && this.deviceInfo.subDeviceList.length > 0; + this.showName = this.isSubDev ? '瀵勫瓨鍣ㄥ湴鍧�' : '鏍囪瘑绗�'; + this.queryParams.deviceId = this.deviceInfo.deviceId; + this.queryParams.slaveId = this.deviceInfo.slaveId; + this.queryParams.serialNumber = this.deviceInfo.serialNumber; + this.slaveList = newVal.subDeviceList; + this.getList(); + } + }, + }, + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 璁惧鏈嶅姟涓嬪彂鏃ュ織琛ㄦ牸鏁版嵁 + logList: [], + // 寮瑰嚭灞傛爣棰� + title: '', + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + //璁惧鏁版嵁 + deviceInfo: {}, + // 鏃堕棿鑼冨洿 + daterangeTime: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + identify: null, + funType: null, + funValue: null, + messageId: null, + deviceName: null, + serialNumber: null, + mode: null, + userId: null, + resultMsg: null, + resultCode: null, + slaveId: null, + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + //鏄惁鏄痬odbus璁惧缁� + isSubDev: false, + showName: null, + slaveList: [], + // 琛ㄥ崟鏍¢獙 + rules: { + identify: [{ required: true, message: '鏍囪瘑绗︿笉鑳戒负绌�', trigger: 'blur' }], + funType: [{ required: true, message: '鍔熻兘涓嬪彂绫诲瀷涓嶈兘涓虹┖', trigger: 'change' }], + funValue: [{ required: true, message: '鏃ュ織鍊间笉鑳戒负绌�', trigger: 'blur' }], + serialNumber: [{ required: true, message: '璁惧缂栧彿涓嶈兘涓虹┖', trigger: 'blur' }], + }, + }; + }, + created() { + this.queryParams.serialNumber = this.device.serialNumber; + this.getList(); + }, + methods: { + /** 鏌ヨ璁惧鏈嶅姟涓嬪彂鏃ュ織鍒楄〃 */ + getList() { + this.loading = true; + if (null != this.daterangeTime && '' != this.daterangeTime) { + this.queryParams.beginTime = this.daterangeTime[0]; + this.queryParams.endTime = this.daterangeTime[1]; + } + if (this.queryParams.slaveId) { + this.queryParams.serialNumber = this.queryParams.serialNumber + '_' + this.queryParams.slaveId; + } + listLog(this.queryParams).then((response) => { + this.logList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + id: null, + identify: null, + funType: null, + funValue: null, + messageId: null, + deviceName: null, + serialNumber: null, + mode: null, + userId: null, + resultMsg: null, + resultCode: null, + createBy: null, + createTime: null, + remark: 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; + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const ids = row.id || this.ids; + this.$modal + .confirm('鏄惁纭鍒犻櫎璁惧鏈嶅姟涓嬪彂鏃ュ織缂栧彿涓�"' + ids + '"鐨勬暟鎹」锛�') + .then(function () { + return delLog(ids); + }) + .then(() => { + this.getList(); + this.$modal.msgSuccess('鍒犻櫎鎴愬姛'); + }) + .catch(() => {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download( + 'iot/log/export', + { + ...this.queryParams, + }, + `log_${new Date().getTime()}.xlsx` + ); + }, + //閫夋嫨浠庢満 + selectSlave() {}, + }, +}; +</script> diff --git a/src/views/iot/device/device-log.vue b/src/views/iot/device/device-log.vue new file mode 100644 index 0000000..6be328d --- /dev/null +++ b/src/views/iot/device/device-log.vue @@ -0,0 +1,306 @@ +<template> +<div style="padding-left:20px;"> + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> + <el-form-item label="鏃ュ織绫诲瀷" prop="logType"> + <el-select v-model="queryParams.logType" placeholder="璇烽�夋嫨绫诲瀷" clearable size="small"> + <el-option v-for="dict in dict.type.iot_event_type" :key="dict.value" :label="dict.label" :value="dict.value" /> + </el-select> + </el-form-item> + <el-form-item label="鏍囪瘑绗�" prop="identity"> + <el-input v-model="queryParams.identity" placeholder="璇疯緭鍏ユ爣璇嗙" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="鏃堕棿鑼冨洿"> + <el-date-picker v-model="daterangeTime" size="small" 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-table v-loading="loading" :data="deviceLogList" size="mini"> + <el-table-column label="绫诲瀷" align="center" prop="logType" width="120"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_event_type" :value="scope.row.logType" /> + </template> + </el-table-column> + <el-table-column label="妯″紡" align="center" prop="logType" width="120"> + <template slot-scope="scope"> + <el-tag type="primary" v-if="scope.row.mode==1">褰卞瓙妯″紡</el-tag> + <el-tag type="success" v-else-if="scope.row.mode==2">鍦ㄧ嚎妯″紡</el-tag> + <el-tag type="info" v-else>鍏朵粬淇℃伅</el-tag> + </template> + </el-table-column> + <el-table-column label="鏃堕棿" align="center" prop="createTime" width="150"> + <template slot-scope="scope"> + <span>{{ scope.row.createTime }}</span> + </template> + </el-table-column> + <el-table-column label="鏍囪瘑绗�" align="center" prop="identity" /> + <el-table-column label="鍔ㄤ綔" align="left" header-align="center" prop="logValue"> + <template slot-scope="scope"> + <div v-html="formatValueDisplay(scope.row)"></div> + </template> + </el-table-column> + + <el-table-column label="澶囨敞" header-align="center" align="left" prop="remark"> + <template slot-scope="scope"> + {{scope.row.remark==null ?"鏃�":scope.row.remark}} + </template> + </el-table-column> + + </el-table> + <div style="height:40px;"> + <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" /> + </div> + +</div> +</template> + +<script> +import { + listEventLog +} from "../../../api/iot/eventLog"; + +export default { + name: "DeviceLog", + dicts: ['iot_event_type', "iot_yes_no"], + props: { + device: { + type: Object, + default: null + } + }, + watch: { + // 鑾峰彇鍒扮埗缁勪欢浼犻�掔殑device鍚庯紝鍒锋柊鍒楄〃 + device: function (newVal, oldVal) { + this.deviceInfo = newVal; + if (this.deviceInfo && this.deviceInfo.deviceId != 0) { + this.queryParams.serialNumber = this.deviceInfo.serialNumber; + this.getList(); + // 瑙f瀽缂撳瓨鐗╂ā鍨� + this.thingsModel = this.deviceInfo.cacheThingsModel; + } + } + }, + data() { + return { + // 鐗╂ā鍨� + thingsModel: {}, + // 閬僵灞� + loading: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 璁惧鏃ュ織琛ㄦ牸鏁版嵁 + deviceLogList: [], + queryParams: { + pageNum: 1, + pageSize: 10, + logType: null, + logValue: null, + deviceId: null, + serialNumber: null, + deviceName: null, + identity: null, + isMonitor: null, + }, + // 鏃堕棿鑼冨洿 + daterangeTime: [], + }; + }, + created() { + this.queryParams.serialNumber = this.device.serialNumber; + this.getList(); + }, + methods: { + /** 鏌ヨ璁惧鏃ュ織鍒楄〃 */ + getList() { + this.loading = true; + listEventLog(this.addDateRange(this.queryParams, this.daterangeTime)).then(response => { + this.deviceLogList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("queryForm"); + this.daterangeTime=[]; + this.handleQuery(); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download('iot/event/export', { + ...this.queryParams + }, `eventLog_${new Date().getTime()}.xlsx`) + }, + /** 鏍煎紡鍖栨樉绀烘暟鎹畾涔� */ + formatValueDisplay(row) { + // 绫诲瀷锛�1=灞炴�т笂鎶ワ紝2=璋冪敤鍔熻兘锛�3=浜嬩欢涓婃姤锛�4=璁惧鍗囩骇锛�5=璁惧涓婄嚎锛�6=璁惧绂荤嚎锛� + if (row.logType == 1) { + let propertyItem = this.getThingsModelItem(1, row.identity); + if (propertyItem != "") { + return (propertyItem.parentName ? '[' + propertyItem.parentName + (propertyItem.arrayIndex ? propertyItem.arrayIndex : '') + '] ' : '') + + propertyItem.name + + '锛� <span style="color:#409EFF;">' + this.getThingsModelItemValue(propertyItem, row.logValue) + ' ' + + (propertyItem.datatype.unit != undefined ? propertyItem.datatype.unit : '') + '</span>'; + } + } else if (row.logType == 2) { + let functionItem = this.getThingsModelItem(2, row.identity); + if (functionItem != "") { + return (functionItem.parentName ? '[' + functionItem.parentName + (functionItem.arrayIndex ? functionItem.arrayIndex : '') + '] ' : '') + + functionItem.name + + '锛� <span style="color:#409EFF">' + this.getThingsModelItemValue(functionItem, row.logValue) + ' ' + + (functionItem.datatype.unit != undefined ? functionItem.datatype.unit : '') + '</span>'; + } + } else if (row.logType == 3) { + let eventItem = this.getThingsModelItem(3, row.identity); + if (eventItem != "") { + return (eventItem.parentName ? '[' + eventItem.parentName + (eventItem.arrayIndex ? eventItem.arrayIndex : '') + '] ' : '') + + eventItem.name + + '锛� <span style="color:#409EFF">' + this.getThingsModelItemValue(eventItem, row.logValue) + ' ' + + (eventItem.datatype.unit != undefined ? eventItem.datatype.unit : '') + '</span>'; + } + else { + return row.logValue; + } + } else if (row.logType == 4) { + return '<span style="font-weight:bold">璁惧鍗囩骇</span>'; + } else if (row.logType == 5) { + return '<span style="font-weight:bold">璁惧涓婄嚎</span>'; + } else if (row.logType == 6) { + return '<span style="font-weight:bold">璁惧绂荤嚎</span>'; + } + return ""; + }, + /** 鑾峰彇鐗╂ā鍨嬮」涓殑鍊�*/ + getThingsModelItemValue(item, oldValue) { + // 鏋氫妇鍜屽竷灏旇浆鎹负鏂囧瓧 + if (item.datatype.type == "bool") { + if (oldValue == "0") { + return item.datatype.falseText; + } else if (oldValue == "1") { + return item.datatype.trueText; + } + } else if (item.datatype.type == "enum") { + for (let i = 0; i < item.datatype.enumList.length; i++) { + if (oldValue == item.datatype.enumList[i].value) { + return item.datatype.enumList[i].text; + } + } + } + return oldValue; + }, + /** 鑾峰彇鐗╂ā鍨嬩腑鐨勯」*/ + getThingsModelItem(type, identity) { + if (type == 1 && this.thingsModel.properties) { + for (let i = 0; i < this.thingsModel.properties.length; i++) { + //鏅�氱被鍨� integer/decimal/string/emum//bool + if (this.thingsModel.properties[i].id == identity) { + return this.thingsModel.properties[i]; + } + // 瀵硅薄 object + if (this.thingsModel.properties[i].datatype.type == "object") { + for (let j = 0; j < this.thingsModel.properties[i].datatype.params.length; j++) { + if (this.thingsModel.properties[i].datatype.params[j].id == identity) { + this.thingsModel.properties[i].datatype.params[j].parentName = this.thingsModel.properties[i].name; + return this.thingsModel.properties[i].datatype.params[j]; + } + } + } + // 鏁扮粍 array + if (this.thingsModel.properties[i].datatype.type == "array" && this.thingsModel.properties[i].datatype.arrayType) { + if (this.thingsModel.properties[i].datatype.arrayType == "object") { + // 鏁扮粍鍏冪礌鏍煎紡锛歛rray_01_parentId_humidity,array_01_鍓嶇紑缁堢涓婃姤鏃跺姞涓婏紝鐗╂ā鍨嬩腑娌℃湁 + let realIdentity = identity; + let arrayIndex = 0; + if (identity.indexOf("array_") > -1) { + arrayIndex = identity.substring(6, 8); + realIdentity = identity.substring(9); + } + for (let j = 0; j < this.thingsModel.properties[i].datatype.params.length; j++) { + if (this.thingsModel.properties[i].datatype.params[j].id == realIdentity) { + // 鏍囨敞绱㈠紩鍜岀埗绾у悕绉� + this.thingsModel.properties[i].datatype.params[j].arrayIndex = Number(arrayIndex) + 1; + this.thingsModel.properties[i].datatype.params[j].parentName = this.thingsModel.properties[i].name; + return this.thingsModel.properties[i].datatype.params[j]; + } + } + } else { + // 鏅�氱被鍨� + for (let j = 0; j < this.thingsModel.properties[i].datatype.arrayCount.length; j++) { + if (this.thingsModel.properties[i].id == realIdentity) { + this.thingsModel.properties[i].arrayIndex = Number(arrayIndex) + 1; + this.thingsModel.properties[i].parentName = "鍏冪礌"; + return this.thingsModel.properties[i]; + } + } + } + + } + } + } else if (type == 2 && this.thingsModel.functions) { + for (let i = 0; i < this.thingsModel.functions.length; i++) { + //鏅�氱被鍨� integer/decimal/string/emum/bool + if (this.thingsModel.functions[i].id == identity) { + return this.thingsModel.functions[i]; + } + // 瀵硅薄 object + if (this.thingsModel.functions[i].datatype.type == "object") { + for (let j = 0; j < this.thingsModel.functions[i].datatype.params.length; j++) { + if (this.thingsModel.functions[i].datatype.params[j].id == identity) { + this.thingsModel.functions[i].datatype.params[j].parentName = this.thingsModel.functions[i].name; + return this.thingsModel.functions[i].datatype.params[j]; + } + } + } + // 鏁扮粍 array + if (this.thingsModel.functions[i].datatype.type == "array" && this.thingsModel.functions[i].datatype.arrayType) { + // 鏁扮粍鍏冪礌鏍煎紡锛歛rray_01_parentId_humidity,array_01_鍓嶇紑缁堢涓婃姤鏃跺姞涓婏紝鐗╂ā鍨嬩腑娌℃湁 + let realIdentity = identity; + let arrayIndex = 0; + if (identity.indexOf("array_") > -1) { + arrayIndex = identity.substring(6, 8); + realIdentity = identity.substring(9); + } + if (this.thingsModel.functions[i].datatype.arrayType == "object") { + for (let j = 0; j < this.thingsModel.functions[i].datatype.params.length; j++) { + if (this.thingsModel.functions[i].datatype.params[j].id == realIdentity) { + // 鏍囨敞绱㈠紩鍜岀埗绾у悕绉� + this.thingsModel.functions[i].datatype.params[j].arrayIndex = Number(arrayIndex) + 1; + this.thingsModel.functions[i].datatype.params[j].parentName = this.thingsModel.functions[i].name; + return this.thingsModel.functions[i].datatype.params[j]; + } + } + } else { + // 鏅�氱被鍨� + for (let j = 0; j < this.thingsModel.functions[i].datatype.arrayCount.length; j++) { + if (this.thingsModel.functions[i].id == realIdentity) { + this.thingsModel.functions[i].arrayIndex = Number(arrayIndex) + 1; + this.thingsModel.functions[i].parentName = "鍏冪礌"; + return this.thingsModel.functions[i]; + } + } + } + + } + } + } else if (type == 3 && this.thingsModel.events) { + for (let i = 0; i < this.thingsModel.events.length; i++) { + if (this.thingsModel.events[i].id == identity) { + return this.thingsModel.events[i]; + } + } + } + return ""; + } + } +}; +</script> diff --git a/src/views/iot/device/device-monitor.vue b/src/views/iot/device/device-monitor.vue new file mode 100644 index 0000000..2448dc9 --- /dev/null +++ b/src/views/iot/device/device-monitor.vue @@ -0,0 +1,296 @@ +<template> + <div style="padding-left: 20px"> + <el-form :inline="true" label-width="100px"> + <el-form-item label="鐩戞祴闂撮殧(ms)"> + <el-tooltip class="item" effect="light" content="鍙栧�艰寖鍥�500-10000姣" placement="top"> + <el-input v-model="monitorInterval" placeholder="璇疯緭鍏ョ洃娴嬮棿闅�" type="number" clearable size="small" style="width: 180px" /> + </el-tooltip> + </el-form-item> + <el-form-item label="鐩戞祴娆℃暟"> + <el-tooltip class="item" effect="light" content="鍙栧�兼柟浣�1-300" placement="top"> + <el-input v-model="monitorNumber" placeholder="璇疯緭鍏ョ洃娴嬫鏁�" type="number" clearable size="small" style="width: 180px" /> + </el-tooltip> + </el-form-item> + <el-form-item> + <el-button type="success" icon="el-icon-video-play" size="mini" @click="beginMonitor()" style="margin-left: 30px">寮�濮嬬洃娴�</el-button> + <el-button type="danger" icon="el-icon-video-pause" size="mini" @click="stopMonitor()">鍋滄鐩戞祴</el-button> + </el-form-item> + </el-form> + <el-row :gutter="20" v-loading="chartLoading" element-loading-text="姝e湪鎺ユ敹璁惧鏁版嵁锛岃鑰愬績绛夊緟......" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)"> + <el-col :span="12" v-for="(item, index) in monitorThings" :key="index" style="margin-bottom: 20px"> + <el-card shadow="hover" :body-style="{ paddingTop: '10px', marginBottom: '-20px' }"> + <div ref="monitor" style="height: 210px; padding: 0"></div> + </el-card> + </el-col> + </el-row> + </div> +</template> + +<script> +export default { + name: 'DeviceMonitor', + props: { + device: { + type: Object, + default: null, + }, + }, + watch: { + // 鑾峰彇鍒扮埗缁勪欢浼犻�掔殑device鍚庯紝鍒锋柊鍒楄〃 + device: function (newVal, oldVal) { + this.deviceInfo = newVal; + if (this.deviceInfo && this.deviceInfo.deviceId != 0) { + // 鐩戞祴鏁版嵁 + this.monitorThings = this.deviceInfo.monitorList; + // 鐩戞祴鏁版嵁闆嗗悎鍒濆鍖� + this.dataList = []; + for (let i = 0; i < this.monitorThings.length; i++) { + this.dataList.push({ + id: this.monitorThings[i].id, + name: this.monitorThings[i].name, + data: [], + }); + // this.dataList[i].data.push(["2022-03-14 23:32:09", "30"]); + } + // 缁樺埗鐩戞祴鍥捐〃 + this.$nextTick(function () { + this.getMonitorChart(); + }); + this.mqttCallback(); + } + }, + }, + data() { + return { + // 瀹炴椂鐩戞祴闂撮殧 + monitorInterval: 1000, + // 瀹炴椂鐩戞祴娆℃暟 + monitorNumber: 60, + // 鍥捐〃闆嗗悎 + chart: [], + // 鍥捐〃鏁版嵁闆嗗悎 + dataList: [], + // 鐩戞祴鐗╂ā鍨� + monitorThings: [], + // 鍥捐〃閬僵灞� + chartLoading: false, + // 璁惧淇℃伅 + deviceInfo: {}, + }; + }, + created() {}, + methods: { + /** + * Mqtt鍙戝竷娑堟伅 + * @device 璁惧 + * @model 鐗╂ā鍨� ,type 绫诲瀷(1=灞炴�э紝2=鍔熻兘锛�3=OTA鍗囩骇(鍟嗕笟鐗堟敮鎸�)锛�4=瀹炴椂鐩戞祴) + * */ + mqttPublish(device, model) { + let topic = ''; + let message = ''; + if (model.type == 4) { + // 瀹炴椂鐩戞祴 + topic = '/' + device.productId + '/' + device.serialNumber + '/monitor/get'; + message = '{"count":' + model.value + ',"interval":' + this.monitorInterval + '}'; + } else { + return; + } + if (topic != '') { + // 鍙戝竷 + this.$mqttTool + .publish(topic, message, model.name) + .then((res) => { + this.$modal.notifySuccess(res); + }) + .catch((res) => { + this.$modal.notifyError(res); + }); + } + }, + /* Mqtt鍥炶皟澶勭悊 */ + mqttCallback() { + this.$mqttTool.client.on('message', (topic, message, buffer) => { + let topics = topic.split('/'); + let productId = topics[1]; + let deviceNum = topics[2]; + message = JSON.parse(message.toString()); + if (!message) { + return; + } + if (topics[3] == 'status') { + console.log('鎺ユ敹鍒般�愯澶囩姸鎬併�戜富棰橈細', topic); + console.log('鎺ユ敹鍒般�愯澶囩姸鎬併�戝唴瀹癸細', message); + // 鏇存柊鍒楄〃涓澶囩殑鐘舵�� + if (this.deviceInfo.serialNumber == deviceNum) { + this.deviceInfo.status = message.status; + this.deviceInfo.isShadow = message.isShadow; + this.deviceInfo.rssi = message.rssi; + } + } + if (topics[3] == 'monitor') { + console.log('鎺ユ敹鍒般�愬疄鏃剁洃娴嬨�戜富棰橈細', topic); + console.log('鎺ユ敹鍒般�愬疄鏃剁洃娴嬨�戝唴瀹癸細', message); + // 瀹炴椂鐩戞祴 + this.chartLoading = false; + for (let k = 0; k < message.length; k++) { + let value = message[k].value; + let id = message[k].id; + let remark = message[k].remark; + // 鏁版嵁鍔犺浇鍒板浘琛� + for (let i = 0; i < this.dataList.length; i++) { + if (id == this.dataList[i].id) { + // 鏅�氱被鍨嬪尮閰� + if (this.dataList[i].length > 50) { + this.dataList[i].shift(); + } + this.dataList[i].data.push([this.getTime(), value]); + // 鏇存柊鍥捐〃 + this.chart[i].setOption({ + series: [ + { + data: this.dataList[i].data, + }, + ], + }); + break; + } else if (this.dataList[i].id.indexOf('array_') == 0) { + // 鏁扮粍绫诲瀷鍖归厤,渚嬪锛歡ateway_temperature,鍥捐〃id鍘婚櫎鍓嶇紑鍚庡尮閰� + let index = this.dataList[i].id.substring(6, 8); + let identity = this.dataList[i].id.substring(9); + if (identity == id) { + let values = value.split(','); + if (this.dataList[i].length > 50) { + this.dataList[i].shift(); + } + this.dataList[i].data.push([this.getTime(), values[index]]); + // 鏇存柊鍥捐〃 + this.chart[i].setOption({ + series: [ + { + data: this.dataList[i].data, + }, + ], + }); + break; + } + } + } + } + } + }); + }, + /** 鏇存柊瀹炴椂鐩戞祴鍙傛暟*/ + beginMonitor() { + console.log('deviceInfo', this.deviceInfo); + if (this.deviceInfo.status != 3) { + this.$modal.alertError('璁惧涓嶅湪绾匡紝涓嬪彂鎸囦护澶辫触'); + return; + } + // 娓呯┖鍥捐〃鏁版嵁 + for (let i = 0; i < this.dataList.length; i++) { + this.dataList[i].data = []; + } + if (this.monitorInterval < 500 || this.monitorInterval > 10000) { + this.$modal.alertError('瀹炴椂鐩戞祴鐨勯棿闅旇寖鍥�500-10000姣'); + } + if (this.monitorNumber == 0 || this.monitorNumber > 300) { + this.$modal.alertError('瀹炴椂鐩戞祴鏁伴噺鑼冨洿1-300'); + } + // Mqtt鍙戝竷瀹炴椂鐩戞祴娑堟伅 + let model = {}; + model.name = '鏇存柊瀹炴椂鐩戞祴'; + model.value = this.monitorNumber; + model.type = 4; + this.mqttPublish(this.deviceInfo, model); + this.chartLoading = true; + }, + /** 鍋滄瀹炴椂鐩戞祴 */ + stopMonitor() { + if (this.deviceInfo.status != 3) { + this.$modal.alertError('璁惧涓嶅湪绾匡紝涓嬪彂鎸囦护澶辫触'); + return; + } + this.chartLoading = false; + // Mqtt鍙戝竷瀹炴椂鐩戞祴 + let model = {}; + model.name = '鍏抽棴瀹炴椂鐩戞祴'; + model.value = 0; + model.type = 4; + this.mqttPublish(this.deviceInfo, model); + }, + /**鐩戞祴鏁版嵁 */ + getMonitorChart() { + let color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc']; + for (let i = 0; i < this.monitorThings.length; i++) { + // 璁剧疆瀹藉害 + this.$refs.monitor[i].style.width = document.documentElement.clientWidth / 2 - 255 + 'px'; + this.chart[i] = this.$echarts.init(this.$refs.monitor[i]); + var option; + option = { + title: { + left: 'center', + text: this.monitorThings[i].name + ' 锛堝崟浣� ' + (this.monitorThings[i].datatype.unit != undefined ? this.monitorThings[i].datatype.unit : '鏃�') + '锛�', + textStyle: { + fontSize: 14, + }, + }, + grid: { + top: '50px', + left: '20px', + right: '20px', + bottom: '10px', + containLabel: true, + }, + tooltip: { + trigger: 'axis', + axisPointer: { + animation: true, + }, + }, + xAxis: { + type: 'time', + // show: false, + splitLine: { + show: false, + }, + }, + yAxis: { + type: 'value', + // boundaryGap: [0, '100%'], + // splitLine: { + // show: true, + // }, + }, + series: [ + { + name: this.monitorThings[i].name, + type: 'line', + // smooth: true, + // itemStyle: { + // color: i > 9 ? color[0] : color[i], + // }, + // areaStyle: {}, + data: [], + }, + ], + }; + option && this.chart[i].setOption(option); + } + }, + /* 鑾峰彇褰撳墠鏃堕棿*/ + getTime() { + let date = new Date(); + let y = date.getFullYear(); + let m = date.getMonth() + 1; + let d = date.getDate(); + let H = date.getHours(); + let mm = date.getMinutes(); + let s = date.getSeconds(); + m = m < 10 ? '0' + m : m; + d = d < 10 ? '0' + d : d; + H = H < 10 ? '0' + H : H; + return y + '-' + m + '-' + d + ' ' + H + ':' + mm + ':' + s; + }, + }, +}; +</script> diff --git a/src/views/iot/device/device-statistic.vue b/src/views/iot/device/device-statistic.vue new file mode 100644 index 0000000..446c8c9 --- /dev/null +++ b/src/views/iot/device/device-statistic.vue @@ -0,0 +1,225 @@ +<template> + <div style="padding-left: 20px"> + <el-row> + <el-col :span="24"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="75px"> + <el-form-item label="璇烽�夋嫨璁惧浠庢満:" label-width="120px" v-if="isSubDev"> + <el-select v-model="queryParams.slaveId" placeholder="璇烽�夋嫨璁惧浠庢満" @change="selectSlave"> + <el-option v-for="slave in slaveList" :key="slave.slaveId" :label="`${slave.deviceName} (${slave.slaveId})`" + :value="slave.slaveId"></el-option> + </el-select> + </el-form-item> + <el-form-item label="鏃堕棿鑼冨洿"> + <el-date-picker v-model="daterangeTime" size="small" 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="getListHistory">鏌ヨ</el-button> + </el-form-item> + </el-form> + </el-col> + <el-col :span="23"> + <div v-for="(item, index) in staticList" :key="index" style="margin-bottom: 30px"> + <el-card shadow="hover" :body-style="{ padding: '10px 0px', overflow: 'auto' }" v-loading="loading"> + <div ref="statisticMap" style="height: 300px; width: 1080px"></div> + </el-card> + </div> + </el-col> + </el-row> + </div> +</template> + +<script> +import { listHistory } from '@/api/iot/deviceLog'; + +export default { + name: 'device-statistic', + props: { + device: { + type: Object, + default: null, + }, + }, + watch: { + // 鑾峰彇鍒扮埗缁勪欢浼犻�掔殑device鍚� + device: function (newVal, oldVal) { + this.deviceInfo = newVal; + if (this.deviceInfo && this.deviceInfo.deviceId != 0) { + this.isSubDev = this.deviceInfo.subDeviceList && this.deviceInfo.subDeviceList.length > 0; + this.queryParams.slaveId = this.deviceInfo.slaveId; + this.queryParams.serialNumber = this.deviceInfo.serialNumber; + this.slaveList = newVal.subDeviceList; + // 鐩戞祴鏁版嵁 + if (this.isSubDev) { + this.staticList = this.deviceInfo.cacheThingsModel['properties'].filter((item) => { + return item.tempSlaveId == this.queryParams.slaveId; + }); + } else { + this.staticList = this.deviceInfo.staticList; + } + // 鍔犺浇鍥捐〃 + this.$nextTick(function () { + // 缁樺埗鍥捐〃 + this.getStatistic(); + }); + } + }, + }, + data() { + return { + loading: true, + // 璁惧淇℃伅 + deviceInfo: {}, + // 缁熻鐗╂ā鍨� + staticList: [], + // 鍥捐〃闆嗗悎 + chart: [], + // 婵�娲绘椂闂磋寖鍥� + daterangeTime: [this.getTime(), this.getTime()], + // 鏌ヨ鍙傛暟 + queryParams: { + serialNumber: null, + identity: '', + slaveId: undefined, + }, + // 瀵硅薄鏁扮粍绫诲瀷鐗╂ā鍨嬫殏瀛樻暟鎹� + arrayData: [], + // 瀛愯澶囧垪琛� + slaveList: [], + isSubDev: false, + }; + }, + mounted() { + // 鑾峰彇缁熻鏁版嵁 + // this.getListHistory(); + }, + methods: { + /** 鑾峰彇褰撳墠鏃ユ湡 **/ + getTime() { + let date = new Date(); + let y = date.getFullYear(); + let m = date.getMonth() + 1; + let d = date.getDate(); + m = m < 10 ? '0' + m : m; + d = d < 10 ? '0' + d : d; + return y + '-' + m + '-' + d; + }, + /* 鑾峰彇鐩戞祴鍘嗗彶鏁版嵁*/ + getListHistory() { + this.loading = true; + this.queryParams.serialNumber = this.queryParams.slaveId ? this.deviceInfo.serialNumber + '_' + this.queryParams.slaveId : this.deviceInfo.serialNumber; + if (null != this.daterangeTime && '' != this.daterangeTime) { + this.queryParams.beginTime = this.daterangeTime[0]; + this.queryParams.endTime = this.daterangeTime[1] + ' 23:59'; + } + listHistory(this.queryParams).then((res) => { + for (let key in res.data) { + for (let i = 0; i < this.staticList.length; i++) { + if (key == this.staticList[i].id) { + // 瀵硅薄杞暟缁� + let dataList = []; + for (let j = 0; j < res.data[key].length; j++) { + let item = []; + item[0] = res.data[key][j].time; + item[1] = res.data[key][j].value; + dataList.push(item); + } + // 鍥捐〃鏄剧ず鏁版嵁 + this.chart[i].setOption({ + series: [ + { + data: dataList, + }, + ], + }); + } + } + } + this.loading = false; + }); + }, + + /**鐩戞祴缁熻鏁版嵁 */ + getStatistic() { + let color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc']; + for (let i = 0; i < this.staticList.length; i++) { + // 璁剧疆瀹藉害 + this.$refs.statisticMap[i].style.width = document.documentElement.clientWidth - 510 + 'px'; + this.chart[i] = this.$echarts.init(this.$refs.statisticMap[i]); + var option; + option = { + animationDurationUpdate: 3000, + tooltip: { + trigger: 'axis', + }, + title: { + left: 'center', + text: this.staticList[i].name + '缁熻 锛堝崟浣� ' + (this.staticList[i].datatype && this.staticList[i].datatype.unit != undefined ? this.staticList[i].datatype.unit : '鏃�') + '锛�', + }, + grid: { + top: '80px', + left: '50px', + right: '20px', + bottom: '80px', + // containLabel: true, + }, + toolbox: { + feature: { + dataZoom: { + yAxisIndex: 'none', + }, + restore: {}, + saveAsImage: {}, + }, + }, + xAxis: { + type: 'time', + }, + yAxis: { + type: 'value', + }, + dataZoom: [ + { + type: 'inside', + start: 0, + end: 100, + }, + { + start: 0, + end: 100, + }, + ], + series: [ + { + name: this.staticList[i].name, + type: 'line', + symbol: 'none', + sampling: 'lttb', + itemStyle: { + color: i > 9 ? color[0] : color[i], + }, + areaStyle: {}, + data: [], + }, + ], + }; + option && this.chart[i].setOption(option); + } + }, + + /*閫夋嫨浠庢満*/ + selectSlave() { + this.staticList = this.deviceInfo.cacheThingsModel['properties'].filter((item) => { + return item.tempSlaveId == this.queryParams.slaveId; + }); + // 鍔犺浇鍥捐〃 + this.$nextTick(function () { + // 缁樺埗鍥捐〃 + this.getStatistic(); + // 鑾峰彇缁熻鏁版嵁 + this.getListHistory(); + }); + }, + }, +}; +</script> diff --git a/src/views/iot/device/device-timer.vue b/src/views/iot/device/device-timer.vue new file mode 100644 index 0000000..49b808b --- /dev/null +++ b/src/views/iot/device/device-timer.vue @@ -0,0 +1,780 @@ +<template> + <div style="padding-left: 20px"> + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="70px"> + <el-form-item label="瀹氭椂鍚嶇О" prop="jobName"> + <el-input v-model="queryParams.jobName" placeholder="璇疯緭鍏ュ畾鏃跺悕绉�" clearable size="small" + @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="瀹氭椂鐘舵��" prop="status" style="margin-left: 20px"> + <el-select v-model="queryParams.status" placeholder="璇烽�夋嫨瀹氭椂鐘舵��" clearable size="small"> + <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-item style="float: right"> + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" + v-hasPermi="['iot:device:timer']">鏂板</el-button> + </el-form-item> + </el-form> + + <el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange" size="small"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="鍚嶇О" align="center" prop="jobName" :show-overflow-tooltip="true" /> + <el-table-column label="鎻忚堪" align="center" prop="cronText"> + <template slot-scope="scope"> + <div v-html="formatCronDisplay(scope.row)"></div> + </template> + </el-table-column> + <el-table-column label="CRON琛ㄨ揪寮�" align="center" prop="cronExpression" :show-overflow-tooltip="true" /> + <el-table-column label="鍔ㄤ綔" align="left" prop="actions" :show-overflow-tooltip="true"> + <template slot-scope="scope"> + <div v-html="formatActionsDisplay(scope.row.actions)" style="overflow: hidden; white-space: nowrap"></div> + </template> + </el-table-column> + + <el-table-column label="鐘舵��" align="center"> + <template slot-scope="scope"> + <el-switch v-model="scope.row.status" active-value="0" inactive-value="1" active-text="鍚敤" + @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="['iot:device:timer']">淇敼</el-button> + <el-button size="mini" type="text" icon="el-icon-caret-right" @click="handleView(scope.row)" + v-hasPermi="['iot:device:timer']">瀹氭椂璇︾粏</el-button> + <br /> + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" + v-hasPermi="['iot:device:timer']">鍒犻櫎</el-button> + <el-button size="mini" type="text" icon="el-icon-caret-right" @click="handleRun(scope.row)" + v-hasPermi="['iot:device:timer']">鎵ц涓�娆�</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="800px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="120px"> + <el-form-item label="瀹氭椂鍚嶇О" prop="jobName"> + <el-input v-model="form.jobName" placeholder="璇疯緭鍏ュ畾鏃跺悕绉�" style="width: 340px" /> + </el-form-item> + <el-form-item label="鎵ц鏃堕棿" required> + <el-time-picker v-model="timerTimeValue" value-format="HH:mm" format="HH:mm" placeholder="閫夋嫨鏃堕棿" :editable="false" + style="width: 340px" @change="timeChange" :disabled="form.isAdvance == 1"></el-time-picker> + </el-form-item> + <el-form-item label="閫夋嫨鏄熸湡" prop="timerWeek"> + <el-row> + <el-col :span="18"> + <el-select v-model="timerWeekValue" placeholder="璇烽�夋嫨" multiple style="width: 100%" @change="weekChange" + :disabled="form.isAdvance == 1"> + <el-option v-for="item in timerWeeks" :key="item.value" :label="item.label" + :value="item.value"></el-option> + </el-select> + </el-col> + </el-row> + </el-form-item> + <el-form-item label="cron琛ㄨ揪寮�" prop="cron"> + <el-row> + <el-col :span="18"> + <el-input v-model="form.cronExpression" placeholder="cron鎵ц琛ㄨ揪寮�" :disabled="form.isAdvance == 0"> + <template slot="append"> + <el-button type="primary" @click="handleShowCron" :disabled="form.isAdvance == 0"> + 鐢熸垚琛ㄨ揪寮� + <i class="el-icon-time el-icon--right"></i> + </el-button> + </template> + </el-input> + </el-col> + <el-col :span="4" :offset="1"> + <el-checkbox v-model="form.isAdvance" :true-label="1" :false-label="0" + @change="customerCronChange">鑷畾涔夎〃杈惧紡</el-checkbox> + </el-col> + </el-row> + </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_job_status" :key="dict.value" :label="dict.value">{{ dict.label + }}</el-radio> + </el-radio-group> + </el-form-item> + + <div style="padding-bottom: 15px; padding: 0 20px"> + <el-divider></el-divider> + </div> + <el-form-item label="鎵ц鍔ㄤ綔" required> + <el-row v-for="(actionItem, index) in actionList" :key="index + 'action'" style="margin-bottom: 10px"> + <el-col :span="4"> + <el-select v-model="actionItem.type" placeholder="璇烽�夋嫨绫诲埆" @change="actionTypeChange($event, index)"> + <el-option v-for="(subItem, subIndex) in modelTypes" :key="subIndex + 'type'" :label="subItem.label" + :value="subItem.value"></el-option> + </el-select> + </el-col> + <el-col :span="4" :offset="1"> + <el-select v-model="actionItem.id" placeholder="璇烽�夋嫨" v-if="actionItem.type == 1" + @change="thingsModelItemChange($event, index)"> + <el-option v-for="(subItem, subIndex) in thingsModel.properties" :key="subIndex + 'property'" + :label="subItem.name" :value="subItem.id"></el-option> + </el-select> + <el-select v-model="actionItem.id" placeholder="璇烽�夋嫨" v-else-if="actionItem.type == 2" + @change="thingsModelItemChange($event, index)"> + <el-option v-for="(subItem, subIndex) in thingsModel.functions" :key="subIndex + 'func'" + :label="subItem.name" :value="subItem.id"></el-option> + </el-select> + <el-select v-model="form.id" placeholder="璇烽�夋嫨" v-else-if="actionItem.type == 3" + @change="thingsModelItemChange($event, index)"> + <el-option v-for="(subItem, subIndex) in thingsModel.functions" :key="subIndex + 'func'" + :label="subItem.name" :value="subItem.id"></el-option> + </el-select> + </el-col> + <el-col :span="10" :offset="1"> + <!--鐗╂ā鍨嬮」鐨勫��--> + <span + v-if="actionItem.thingsModelItem && (actionItem.thingsModelItem.datatype.type == 'integer' || actionItem.thingsModelItem.datatype.type == 'decimal')"> + <el-input v-model="actionItem.value" placeholder="鍊�" :max="actionItem.thingsModelItem.datatype.max" + :min="actionItem.thingsModelItem.datatype.min" type="number" size="small"> + <template slot="append">{{ actionItem.thingsModelItem.datatype.unit }}</template> + </el-input> + </span> + <span v-else-if="actionItem.thingsModelItem && actionItem.thingsModelItem.datatype.type == 'bool'"> + <el-switch v-model="actionItem.value" :active-text="actionItem.thingsModelItem.datatype.trueText" + :inactive-text="actionItem.thingsModelItem.datatype.falseText" active-value="1" + inactive-value="0"></el-switch> + </span> + <span v-else-if="actionItem.thingsModelItem && actionItem.thingsModelItem.datatype.type == 'enum'"> + <el-select v-model="actionItem.value" placeholder="璇烽�夋嫨" style="width: 100%"> + <el-option v-for="(subItem, subIndex) in actionItem.thingsModelItem.datatype.enumList" + :key="subIndex + 'things'" :label="subItem.text" :value="subItem.value"></el-option> + </el-select> + </span> + <span v-else-if="actionItem.thingsModelItem && actionItem.thingsModelItem.datatype.type == 'string'"> + <el-input v-model="actionItem.value" placeholder="璇疯緭鍏ュ瓧绗︿覆" + :max="actionItem.thingsModelItem.datatype.maxLength" /> + </span> + <span v-else-if="actionItem.thingsModelItem && actionItem.thingsModelItem.datatype.type == 'array'"> + <el-input v-model="actionItem.value" placeholder="璇疯緭鍏ヨ嫳鏂囬�楀彿鍒嗛殧鐨勬暟缁�" /> + </span> + </el-col> + <el-col :span="2" :offset="1" v-if="index != 0"><a style="color: #f56c6c" + @click="removeEnumItem(index)">鍒犻櫎</a></el-col> + </el-row> + <div> + + + <a style="color: #409eff" @click="addEnumItem()">娣诲姞鎵ц鍔ㄤ綔</a> + </div> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm" :loading="submitButtonLoading">纭� 瀹�</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" style="padding-bottom: 80px"> + </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="鏄惁骞跺彂锛�"> + <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="cron琛ㄨ揪寮忥細">{{ form.cronExpression }}</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-col :span="12"> + <el-form-item label="涓嬫鎵ц鏃堕棿锛�">{{ parseTime(form.nextValidTime) }}</el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="瀹氭椂鐘舵�侊細"> + <div v-if="form.status == 0">姝e父</div> + <div v-else-if="form.status == 1">鏆傚仠</div> + </el-form-item> + </el-col> + + <el-col :span="24"> + <el-form-item label="鎵ц鍔ㄤ綔锛�"> + <div v-html="formatActionsDisplay(form.actions)" + style="border: 1px solid #ddd; padding: 10px; border-radius: 5px; width: 465px"></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/iot/deviceJob'; +import Crontab from '@/components/Crontab'; +export default { + components: { + Crontab, + }, + name: 'device-timer', + dicts: ['sys_job_group', 'sys_job_status'], + props: { + device: { + type: Object, + default: null, + }, + }, + watch: { + // 鑾峰彇鍒扮埗缁勪欢浼犻�掔殑device鍚� + device: function (newVal, oldVal) { + this.deviceInfo = newVal; + if (this.deviceInfo && this.deviceInfo.deviceId != 0) { + this.thingsModel = this.deviceInfo.cacheThingsModel; + this.queryParams.deviceId = this.deviceInfo.deviceId; + } + }, + }, + data() { + return { + // 鐗╂ā鍨婮SON + thingsModel: {}, + // 鍔ㄤ綔鍒楄〃 + actionList: [], + // 璁惧 + deviceInfo: {}, + // 閬僵灞� + loading: false, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 瀹氭椂瀹氭椂琛ㄦ牸鏁版嵁 + jobList: [], + // 寮瑰嚭灞傛爣棰� + title: '', + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏄惁鏄剧ず璇︾粏寮瑰嚭灞� + openView: false, + // 鏄惁鏄剧ずCron琛ㄨ揪寮忓脊鍑哄眰 + openCron: false, + // 浼犲叆鐨勮〃杈惧紡 + expression: '', + // 鎻愪氦鎸夐挳鍔犺浇 + submitButtonLoading: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + deviceId: 0, + jobName: undefined, + jobGroup: undefined, + status: undefined, + }, + // 鍛� + timerWeeks: [ + { + value: 1, + label: '鍛ㄤ竴', + }, + { + value: 2, + label: '鍛ㄤ簩', + }, + { + value: 3, + label: '鍛ㄤ笁', + }, + { + value: 4, + label: '鍛ㄥ洓', + }, + { + value: 5, + label: '鍛ㄤ簲', + }, + { + value: 6, + label: '鍛ㄥ叚', + }, + { + value: 7, + label: '鍛ㄦ棩', + }, + ], + timerWeekValue: [1, 2, 3, 4, 5, 6, 7], + // 鏃堕棿 + timerTimeValue: '', + // 鐗╂ā鍨嬬被鍒� + modelTypes: [ + { + value: 1, + label: '灞炴��', + }, + { + value: 2, + label: '鍔熻兘', + }, + ], + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + jobName: [ + { + required: true, + message: '瀹氭椂鍚嶇О涓嶈兘涓虹┖', + 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, + cronExpression: undefined, + status: '0', + jobGroup: 'DEFAULT', // 瀹氭椂鍒嗙粍 + misfirePolicy: 2, // 1=绔嬪嵆鎵ц锛�2=鎵ц涓�娆★紝3=鏀惧純鎵ц + concurrent: 1, // 鏄惁骞跺彂锛�1=绂佹锛�0=鍏佽 + isAdvance: 0, // 鏄惁璇︾粏cron琛ㄨ揪寮� + jobType: 1, // 浠诲姟绫诲瀷 1=璁惧瀹氭椂锛�2=璁惧鍛婅锛�3=鍦烘櫙鑱斿姩 + productId: 0, + productName: '', + sceneId: 0, //鍦烘櫙ID + alertId: 0, // 鍛婅ID + actions: '', + }; + this.submitButtonLoading = false; + this.timerWeekValue = [1, 2, 3, 4, 5, 6, 7]; + this.timerTimeValue = ''; + this.actionList = [ + { + id: '', + name: '', + value: '', + type: 2, // 1=灞炴�э紝2=鍔熻兘锛�3=浜嬩欢锛�5=璁惧涓婄嚎锛�6=璁惧涓嬬嚎 + deviceId: this.deviceInfo.deviceId, + deviceName: this.deviceInfo.deviceName, + thingsModelItem: { + id: '', + name: '', + datatype: { + type: '', + }, + }, + }, + ]; + // 鐗╂ā鍨嬮」,瀵瑰簲actions + 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; + }, + // 瀹氭椂鐘舵�佷慨鏀� + 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; + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + 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; + // actionList璧嬪�� + this.actionList = JSON.parse(this.form.actions); + for (let i = 0; i < this.actionList.length; i++) { + if (this.actionList[i].type == 1) { + for (let j = 0; j < this.thingsModel.properties.length; j++) { + if (this.actionList[i].id == this.thingsModel.properties[j].id) { + this.actionList[i].thingsModelItem = this.thingsModel.properties[j]; + break; + } + } + } else if (this.actionList[i].type == 2) { + for (let j = 0; j < this.thingsModel.functions.length; j++) { + if (this.actionList[i].id == this.thingsModel.functions[j].id) { + this.actionList[i].thingsModelItem = this.thingsModel.functions[j]; + break; + } + } + } + } + if (this.form.isAdvance == 0) { + let arrayValue = this.form.cronExpression.substring(12).split(',').map(Number); + this.timerWeekValue = arrayValue; + this.timerTimeValue = this.form.cronExpression.substring(5, 7) + ':' + this.form.cronExpression.substring(2, 4); + } + this.open = true; + this.title = '淇敼瀹氭椂'; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function () { + this.$refs['form'].validate((valid) => { + if (valid) { + // 楠岃瘉涓嶈兘涓虹┖ + if (this.form.isAdvance == 0) { + if (this.timerTimeValue == '' || this.timerTimeValue == null) { + this.$modal.alertError('鎵ц鏃堕棿涓嶈兘绌�'); + return; + } + if (this.timerWeekValue == null || this.timerWeekValue == '') { + this.$modal.alertError('璇烽�夋嫨瑕佹墽琛岀殑鏄熸湡'); + return; + } + } else if (this.form.isAdvance == 1) { + if (this.form.cronExpression == '') { + this.$modal.alertError('cron琛ㄨ揪寮忎笉鑳戒负绌�'); + return; + } + } + for (let i = 0; i < this.actionList.length; i++) { + if (this.actionList[i].id == '' || this.actionList[i].name == '' || this.actionList[i].value == '') { + this.$modal.alertError('鎵ц鍔ㄤ綔涓殑閫夐」鍜屽�间笉鑳戒负绌�'); + return; + } + } + // 鍔ㄤ綔 + this.actionList[0].deviceId = this.deviceInfo.deviceId; + this.actionList[0].deviceName = this.deviceInfo.deviceName; + // 鍒犻櫎瀵硅薄涓殑鐗╂ā鍨嬪睘鎬� + for (let i = 0; i < this.actionList.length; i++) { + this.$delete(this.actionList[i], 'thingsModelItem'); + } + this.form.actions = JSON.stringify(this.actionList); + // 璁惧淇℃伅 + this.form.deviceId = this.deviceInfo.deviceId; + this.form.deviceName = this.deviceInfo.deviceName; + this.form.serialNumber = this.deviceInfo.serialNumber; + this.form.productId = this.deviceInfo.productId; + this.form.productName = this.deviceInfo.productName; + // 鎸夐挳绛夊緟鍚庣鍔犺浇瀹� + this.submitButtonLoading = true; + if (this.form.jobId != undefined) { + updateJob(this.form).then((response) => { + this.$modal.msgSuccess('淇敼鎴愬姛'); + this.submitButtonLoading = false; + this.open = false; + this.getList(); + }); + } else { + addJob(this.form).then((response) => { + this.$modal.msgSuccess('鏂板鎴愬姛'); + this.submitButtonLoading = false; + 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( + 'iot/job/export', + { + ...this.queryParams, + }, + `job_${new Date().getTime()}.xlsx` + ); + }, + + /** 娣诲姞鏋氫妇椤� */ + addEnumItem() { + this.actionList.push({ + id: '', + name: '', + value: '', + type: 2, // 1=灞炴�э紝2=鍔熻兘锛�3=浜嬩欢锛�5=璁惧涓婄嚎锛�6=璁惧涓嬬嚎 + deviceId: this.deviceInfo.deviceId, + deviceName: this.deviceInfo.deviceName, + thingsModelItem: { + id: '', + name: '', + datatype: { + type: '', + }, + }, + }); + }, + /** 鍒犻櫎鏋氫妇椤� */ + removeEnumItem(index) { + this.actionList.splice(index, 1); + }, + /** 鏄熸湡鏀瑰彉浜嬩欢 **/ + weekChange(data) { + this.gentCronExpression(); + }, + /** 鏃堕棿鏀瑰彉浜嬩欢 **/ + timeChange(data) { + this.gentCronExpression(); + }, + /**鑷畾涔塩ron琛ㄨ揪寮忛�夐」鏀瑰彉浜嬩欢 */ + customerCronChange(data) { + if (data == 0) { + this.gentCronExpression(); + } + }, + /** 鐢熸垚cron琛ㄨ揪寮�**/ + gentCronExpression() { + let hour = '00'; + let minute = '00'; + if (this.timerTimeValue != null && this.timerTimeValue != '') { + hour = this.timerTimeValue.substring(0, 2); + minute = this.timerTimeValue.substring(3); + } + let week = '*'; + if (this.timerWeekValue.length > 0) { + week = this.timerWeekValue.sort(); + } + this.form.cronExpression = '0 ' + minute + ' ' + hour + ' ? * ' + week; + }, + + /** 鍔ㄤ綔绫诲瀷鏀瑰彉浜嬩欢 **/ + actionTypeChange(data, index) { + this.actionList[index].id = ''; + this.actionList[index].value = ''; + this.actionList[index].thingsModelItem = null; + }, + /** 鐗╂ā鍨嬮」鏀瑰彉浜嬩欢 **/ + thingsModelItemChange(identifier, index) { + this.actionList[index].value = ''; + if (this.actionList[index].type == 1) { + //灞炴�� + for (let i = 0; i < this.thingsModel.properties.length; i++) { + if (this.thingsModel.properties[i].id == identifier) { + this.actionList[index].name = this.thingsModel.properties[i].name; + this.actionList[index].thingsModelItem = this.thingsModel.properties[i]; + break; + } + } + } else if (this.actionList[index].type == 2) { + //浜嬩欢 + for (let i = 0; i < this.thingsModel.functions.length; i++) { + if (this.thingsModel.functions[i].id == identifier) { + this.actionList[index].name = this.thingsModel.functions[i].name; + this.actionList[index].thingsModelItem = this.thingsModel.functions[i]; + break; + } + } + } + }, + /** 鏍煎紡鍖栨樉绀哄姩浣� */ + formatActionsDisplay(json) { + if (json == null || json == '') { + return; + } + let actions = JSON.parse(json); + let result = ''; + for (let i = 0; i < actions.length; i++) { + let value = actions[i].value; + if (actions[i].type == 1) { + // 灞炴�� + for (let j = 0; j < this.thingsModel.properties.length; j++) { + if (actions[i].id == this.thingsModel.properties[j].id) { + if (this.thingsModel.properties[j].datatype.type == 'decimal' || this.thingsModel.properties[j].datatype.type == 'integer') { + value = actions[i].value + this.thingsModel.properties[j].datatype.unit; + } else if (this.thingsModel.properties[j].datatype.type == 'enum') { + for (let k = 0; k < this.thingsModel.properties[j].datatype.enumList.length; k++) { + if (actions[i].value == this.thingsModel.properties[j].datatype.enumList[k].value) { + value = this.thingsModel.properties[j].datatype.enumList[k].text; + break; + } + } + } else if (this.thingsModel.properties[j].datatype.type == 'bool') { + value = actions[i].value == '1' ? this.thingsModel.properties[j].datatype.trueText : this.thingsModel.properties[j].datatype.falseText; + } + break; + } + } + } else if (actions[i].type == 2) { + // 鍔熻兘 + for (let j = 0; j < this.thingsModel.functions.length; j++) { + if (actions[i].id == this.thingsModel.functions[j].id) { + if (this.thingsModel.functions[j].datatype.type == 'decimal' || this.thingsModel.functions[j].datatype.type == 'integer') { + value = actions[i].value + this.thingsModel.functions[j].datatype.unit; + } else if (this.thingsModel.functions[j].datatype.type == 'enum') { + for (let k = 0; k < this.thingsModel.functions[j].datatype.enumList.length; k++) { + if (actions[i].value == this.thingsModel.functions[j].datatype.enumList[k].value) { + value = this.thingsModel.functions[j].datatype.enumList[k].text; + break; + } + } + } else if (this.thingsModel.functions[j].datatype.type == 'bool') { + value = actions[i].value == '1' ? this.thingsModel.functions[j].datatype.trueText : this.thingsModel.functions[j].datatype.falseText; + } + break; + } + } + } + result = result + actions[i].name + '锛�<span style="color:#F56C6C">' + value + '</span><br />'; + } + return result; + }, + /** 鏍煎紡鍖栨樉绀篊RON鎻忚堪 */ + formatCronDisplay(item) { + let result = ''; + if (item.isAdvance == 0) { + let time = '<br /><span style="color:#F56C6C">鏃堕棿 ' + item.cronExpression.substring(5, 7) + ':' + item.cronExpression.substring(2, 4) + '</span>'; + let week = item.cronExpression.substring(12); + if (week == '1,2,3,4,5,6,7') { + result = '姣忓ぉ ' + time; + } else { + let weekArray = week.split(','); + for (let i = 0; i < weekArray.length; i++) { + if (weekArray[i] == '1') { + result = result + '鍛ㄤ竴銆�'; + } else if (weekArray[i] == '2') { + result = result + '鍛ㄤ簩銆�'; + } else if (weekArray[i] == '3') { + result = result + '鍛ㄤ笁銆�'; + } else if (weekArray[i] == '4') { + result = result + '鍛ㄥ洓銆�'; + } else if (weekArray[i] == '5') { + result = result + '鍛ㄤ簲銆�'; + } else if (weekArray[i] == '6') { + result = result + '鍛ㄥ叚銆�'; + } else if (weekArray[i] == '7') { + result = result + '鍛ㄦ棩銆�'; + } + } + result = result.substring(0, result.length - 1) + ' ' + time; + } + } else { + result = '鑷畾涔塁ron琛ㄨ揪寮�'; + } + return result; + }, + }, +}; +</script> diff --git a/src/views/iot/device/device-user.vue b/src/views/iot/device/device-user.vue new file mode 100644 index 0000000..45d4567 --- /dev/null +++ b/src/views/iot/device/device-user.vue @@ -0,0 +1,348 @@ +<template> + <div style="padding-left: 20px"> + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button type="primary" plain icon="el-icon-share" size="mini" @click="shareDevice" v-hasPermi="['iot:device:share']">鍒嗕韩璁惧</el-button> + </el-col> + <el-col :span="1.5"> + <el-button type="warning" plain icon="el-icon-refresh" size="mini" @click="getList">鍒锋柊</el-button> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="deviceUserList" @selection-change="handleSelectionChange" size="mini"> + <el-table-column label="鐢ㄦ埛缂栧彿" align="center" prop="userId" width="100" /> + <el-table-column label="鐢ㄦ埛鍚嶇О" align="center" prop="userName" /> + <el-table-column label="鎵嬫満鍙风爜" align="center" prop="phonenumber" width="150" /> + <el-table-column label="鐢ㄦ埛绫诲瀷" align="center" prop="isOwner" width="150"> + <template slot-scope="scope"> + <el-tag type="primary" v-if="scope.row.isOwner">涓讳汉</el-tag> + <el-tag type="success" v-else>鍒嗕韩</el-tag> + </template> + </el-table-column> + <el-table-column label="鍒嗕韩鏃堕棿" align="center" prop="createTime" width="150"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> + </template> + </el-table-column> + <el-table-column label="澶囨敞" align="left" prop="remark" header-align="center" min-width="150" /> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width" width="180"> + <template slot-scope="scope"> + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['iot:device:share']" v-if="scope.row.isOwner == 0">缂栬緫</el-button> + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['iot:device:share']" v-if="scope.row.isOwner == 0">鍙栨秷鍒嗕韩</el-button> + </template> + </el-table-column> + </el-table> + + <!--璁惧鍒嗕韩瀵硅瘽妗�--> + <el-dialog title="璁惧鍒嗕韩" :visible.sync="open" width="800px"> + <div style="margin-top: -50px"> + <el-divider></el-divider> + </div> + <!--鐢ㄦ埛鏌ヨ--> + <el-form :model="permParams" ref="queryForm" :rules="rules" :inline="true" label-width="80px" v-if="type == 1"> + <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber"> + <el-input type="text" placeholder="璇疯緭鍏ョ敤鎴锋墜鏈哄彿鐮�" v-model="permParams.phonenumber" minlength="10" clearable size="small" show-word-limit style="width: 240px" @keyup.enter.native="handleQuery"></el-input> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="userQuery">鏌ヨ鐢ㄦ埛</el-button> + </el-form-item> + </el-form> + + <!--鐢ㄦ埛淇℃伅鍜屾潈闄愯缃�--> + <div v-loading="permsLoading" style="background-color: #f8f8f9; line-height: 28px"> + <div v-if="message" style="padding: 20px">{{ message }}</div> + <div v-if="form.userId" style="padding: 15px"> + <div style="font-weight: bold; line-height: 28px">鐢ㄦ埛淇℃伅</div> + <span style="width: 80px; display: inline-block">鐢ㄦ埛ID锛�</span> + <span>{{ form.userId }}</span> + <br /> + <span style="width: 80px; display: inline-block">鎵嬫満鍙风爜锛�</span> + <span>{{ form.phonenumber }}</span> + <br /> + <span style="width: 80px; display: inline-block">鐢ㄦ埛鍚嶇О锛�</span> + <span>{{ form.userName }}</span> + <br /> + <!--閫夋嫨鏉冮檺--> + <div style="font-weight: bold; margin: 15px 0 10px">璁剧疆鐢ㄦ埛鏉冮檺</div> + <el-table :data="sharePermissionList" highlight-current-row size="mini" ref="multipleTable" @select="handleSelectionChange" @select-all="handleSelectionAll"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="鏉冮檺鍚嶇О" align="center" key="modelName" prop="modelName" /> + <el-table-column label="鏉冮檺鏍囪瘑" align="center" key="identifier" prop="identifier" /> + <el-table-column label="澶囨敞淇℃伅" align="left" min-width="100" header-align="center" key="remark" prop="remark" /> + </el-table> + <!--閫夋嫨鏉冮檺--> + <div style="font-weight: bold; margin: 15px 0 10px">澶囨敞淇℃伅</div> + <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" rows="2" /> + </div> + </div> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm" :disabled="!form.userId || !deviceInfo.deviceId">纭畾</el-button> + <el-button @click="closeSelectUser">鍏� 闂�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { addDeviceUser, listDeviceUser, getDeviceUser, delDeviceUser, updateDeviceUser, shareUser } from '@/api/iot/deviceuser'; +import { permListModel } from '@/api/iot/model'; + +export default { + name: 'device-user', + dicts: ['iot_yes_no'], + props: { + device: { + type: Object, + default: null, + }, + }, + watch: { + // 鑾峰彇鍒扮埗缁勪欢浼犻�掔殑device鍚庯紝鍒锋柊鍒楄〃 + device: function (newVal, oldVal) { + this.deviceInfo = newVal; + if (this.deviceInfo && this.deviceInfo.deviceId != 0) { + this.queryParams.deviceId = this.deviceInfo.deviceId; + this.getList(); + } + }, + }, + data() { + return { + // 绫诲瀷,1=鏂板锛�2=鏇存柊 + type: 1, + // 娑堟伅鎻愮ず + message: '', + // 鏉冮檺閬僵灞� + permsLoading: false, + // 鏉冮檺鍒楄〃 + sharePermissionList: [], + // 璁惧淇℃伅 + deviceInfo: {}, + // 鏄惁鏄剧ず閫夋嫨鐢ㄦ埛寮瑰嚭灞� + open: false, + // 鏌ヨ鍙傛暟 + permParams: { + userName: undefined, + phonenumber: undefined, + deviceId: null, + }, + // 鏌ヨ琛ㄥ崟楠岃瘉 + rules: { + phonenumber: [ + { + required: true, + message: '鎵嬫満鍙风爜涓嶈兘涓虹┖', + trigger: 'blur', + }, + { + min: 11, + max: 11, + message: '鎵嬫満鍙风爜闀垮害涓�11浣�', + trigger: 'blur', + }, + ], + }, + // 閬僵灞� + loading: true, + // 鎬绘潯鏁� + total: 0, + // 璁惧鐢ㄦ埛琛ㄦ牸鏁版嵁 + deviceUserList: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + deviceName: null, + userName: null, + userId: null, + tenantName: null, + isOwner: null, + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + }; + }, + created() { + this.queryParams.deviceId = this.device.deviceId; + this.getList(); + }, + methods: { + /** 鏌ヨ璁惧鐢ㄦ埛鍒楄〃 */ + getList() { + this.loading = true; + listDeviceUser(this.queryParams).then((response) => { + this.deviceUserList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + deviceId: null, + userId: null, + deviceName: null, + userName: null, + perms: null, + phonenumber: null, + remark: null, + }; + this.sharePermissionList = []; + this.message = ''; + this.resetForm('form'); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + this.type = 2; //鏇存柊 + getDeviceUser(row.deviceId, row.userId).then((response) => { + this.form = response.data; + // 鏌ヨ鐗╂ā鍨嬫潈闄愬垪琛� + this.getPermissionList(); + this.open = true; + }); + }, + // 璁惧鍒嗕韩 + shareDevice() { + this.type = 1; // 鏂板 + this.open = true; + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const deviceUser = row; + this.$modal + .confirm('纭鍙栨秷鍒嗕韩璁惧锛�') + .then(function () { + return delDeviceUser(deviceUser); + }) + .then(() => { + this.getList(); + this.$modal.msgSuccess('鍙栨秷鍒嗕韩鎴愬姛'); + }) + .catch(() => {}); + }, + /** 鐢ㄦ埛鎸夐挳鎿嶄綔 */ + userQuery() { + this.$refs['queryForm'].validate((valid) => { + if (valid) { + this.reset(); + this.getShareUser(); + } + }); + }, + /** 鏌ヨ鐢ㄦ埛 */ + getShareUser() { + this.permsLoading = true; + if (!this.deviceInfo.deviceId) { + this.$modal.alert('鏌ヨ涓嶅埌璁惧淇℃伅锛岃鍒锋柊鍚庨噸璇�'); + return; + } + this.permParams.deviceId = this.deviceInfo.deviceId; + shareUser(this.permParams).then((response) => { + if (response.data) { + this.form = response.data; + // 鏌ヨ鐗╂ā鍨嬫潈闄愬垪琛� + this.getPermissionList(); + } else { + this.permsLoading = false; + this.message = '鏌ヨ涓嶅埌鐢ㄦ埛淇℃伅锛屾垨鑰呰鐢ㄦ埛宸茬粡鏄澶囩敤鎴�'; + } + }); + }, + /** 鏌ヨ浜у搧鐗╂ā鍨嬭澶囨潈闄愬垪琛� */ + async getPermissionList() { + let perms = []; + if (this.form.perms) { + perms = this.form.perms.split(','); + } + console.log('deviceInfo', this.deviceInfo); + permListModel(this.deviceInfo.productId).then((response) => { + // 鍥哄畾澧炲姞璁惧绯荤粺鐩稿叧鏉冮檺 + this.sharePermissionList = [ + { + identifier: 'timer', + modelName: '璁惧瀹氭椂', + remark: '瀹氭椂鎵ц浠诲姟', + }, + { + identifier: 'log', + modelName: '璁惧鏃ュ織', + remark: '鍖呭惈浜嬩欢鏃ュ織鍜屾寚浠ゆ棩蹇�', + }, + { + identifier: 'monitor', + modelName: '瀹炴椂鐩戞祴', + remark: '涓嬪彂瀹炴椂鐩戞祴鎸囦护鍚庯紝鍥捐〃瀹炴椂鏄剧ず璁惧涓婃姤鏁版嵁', + }, + { + identifier: 'statistic', + modelName: '鐩戞祴缁熻', + remark: '鍥捐〃鏄剧ず瀛樺偍鐨勫巻鍙茬洃娴嬫暟鎹�', + }, + ]; + this.sharePermissionList = this.sharePermissionList.concat(response.data); + + // 璁剧疆閫変腑 + if (perms.length > 0) { + for (let i = 0; i < this.sharePermissionList.length; i++) { + for (let j = 0; j < perms.length; j++) { + if (this.sharePermissionList[i].identifier == perms[j]) { + this.$nextTick(() => { + this.$refs.multipleTable.toggleRowSelection(this.sharePermissionList[i], true); + }); + break; + } + } + } + } + this.permsLoading = false; + }); + }, + // 閲嶇疆鏌ヨ + resetUserQuery() { + this.resetForm('queryForm'); + this.reset(); + }, + // 鍏抽棴閫夋嫨鐢ㄦ埛 + closeSelectUser() { + this.open = false; + this.resetUserQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.form.perms = selection.map((x) => x.identifier).join(','); + }, + // 鍏ㄩ�変簨浠跺鐞� + handleSelectionAll(selection) { + this.form.perms = selection.map((x) => x.identifier).join(','); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + if (this.type == 2) { + // 鏇存柊璁惧鐢ㄦ埛 + updateDeviceUser(this.form).then((response) => { + this.$modal.msgSuccess('鏇存柊鎴愬姛'); + this.resetUserQuery(); + this.open = false; + this.getList(); + }); + } else if (this.type == 1) { + // 娣诲姞璁惧鐢ㄦ埛 + this.form.deviceId = this.deviceInfo.deviceId; + this.form.deviceName = this.deviceInfo.deviceName; + addDeviceUser(this.form).then((response) => { + this.$modal.msgSuccess('鏂板鎴愬姛'); + this.resetUserQuery(); + this.open = false; + this.getList(); + }); + } + }, + }, +}; +</script> diff --git a/src/views/iot/device/index.vue b/src/views/iot/device/index.vue new file mode 100644 index 0000000..66320db --- /dev/null +++ b/src/views/iot/device/index.vue @@ -0,0 +1,509 @@ +<template> + <div style="padding: 6px"> + <el-card style="margin-bottom: 6px"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="75px" style="margin-bottom: -20px"> + <el-form-item label="璁惧鍚嶇О" prop="deviceName"> + <el-input v-model="queryParams.deviceName" placeholder="璇疯緭鍏ヨ澶囧悕绉�" clearable size="small" + @keyup.enter.native="handleQuery" style="width: 150px" /> + </el-form-item> + <el-form-item label="璁惧缂栧彿" prop="serialNumber"> + <el-input v-model="queryParams.serialNumber" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" clearable size="small" + @keyup.enter.native="handleQuery" style="width: 150px" /> + </el-form-item> + <el-form-item label="璁惧鐘舵��" prop="status"> + <el-select v-model="queryParams.status" placeholder="璇烽�夋嫨璁惧鐘舵��" clearable size="small" style="width: 150px"> + <el-option v-for="dict in dict.type.iot_device_status" :key="dict.value" :label="dict.label" + :value="dict.value" /> + </el-select> + </el-form-item> + <el-form-item label="鎴戠殑鍒嗙粍"> + <el-select v-model="queryParams.groupId" placeholder="璇烽�夋嫨鎴戠殑鍒嗙粍" clearable size="small" style="width: 150px"> + <el-option v-for="group in myGroupList" :key="group.groupId" :label="group.groupName" + :value="group.groupId" /> + </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-item style="float: right"> + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleEditDevice(0)" + v-hasPermi="['iot:device:add']">鏂板</el-button> + <el-button type="primary" plain icon="el-icon-s-grid" size="mini" @click="handleChangeShowType" + v-hasPermi="['iot:device:add']">鍒囨崲</el-button> + </el-form-item> + </el-form> + </el-card> + + <el-card style="padding-bottom: 100px" v-if="showType == 'list'"> + <el-table v-loading="loading" :data="deviceList" border> + <el-table-column label="缂栧彿" align="center" header-align="center" prop="deviceId" width="50" /> + <el-table-column label="璁惧鍚嶇О" align="center" header-align="center" prop="deviceName" min-width="120" /> + <el-table-column label="璁惧缂栧彿" align="center" prop="serialNumber" min-width="130" /> + <el-table-column label="鎵�灞炰骇鍝�" align="center" prop="productName" min-width="120" /> + <el-table-column label="鍗忚" align="center" prop="transport" min-width="50" /> + <el-table-column label="閫氳鍗忚" align="center" prop="protocolCode" min-width="100" /> + <el-table-column label="瀛愯澶囨暟" align="center" prop="subDeviceCount" width="80"> + <template slot-scope="scope"> + {{ scope.row.subDeviceCount }} + </template> + </el-table-column> + <el-table-column label="璁惧褰卞瓙" align="center" prop="isShadow" width="80"> + <template slot-scope="scope"> + <el-tag type="success" size="small" v-if="scope.row.isShadow == 1">鍚敤</el-tag> + <el-tag type="info" size="small" v-else>绂佺敤</el-tag> + </template> + </el-table-column> + <el-table-column label="鐘舵��" align="center" prop="status" width="80"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_device_status" :value="scope.row.status" size="small" /> + </template> + </el-table-column> + <el-table-column label="淇″彿" align="center" prop="rssi" width="60"> + <template slot-scope="scope"> + <svg-icon v-if="scope.row.status == 3 && scope.row.rssi >= '-55'" icon-class="wifi_4" /> + <svg-icon v-else-if="scope.row.status == 3 && scope.row.rssi >= '-70' && scope.row.rssi < '-55'" + icon-class="wifi_3" /> + <svg-icon v-else-if="scope.row.status == 3 && scope.row.rssi >= '-85' && scope.row.rssi < '-70'" + icon-class="wifi_2" /> + <svg-icon v-else-if="scope.row.status == 3 && scope.row.rssi >= '-100' && scope.row.rssi < '-85'" + icon-class="wifi_1" /> + <svg-icon v-else icon-class="wifi_0" /> + </template> + </el-table-column> + <el-table-column label="瀹氫綅鏂瑰紡" align="center" prop="locationWay"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_location_way" :value="scope.row.locationWay" size="small" /> + </template> + </el-table-column> + <el-table-column label="鍥轰欢鐗堟湰" align="center" prop="firmwareVersion"> + <template slot-scope="scope"> + <el-tag size="mini" type="info">Ver {{ scope.row.firmwareVersion }}</el-tag> + </template> + </el-table-column> + <el-table-column label="婵�娲绘椂闂�" align="center" prop="activeTime"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.activeTime, '{y}-{m}-{d}') }}</span> + </template> + </el-table-column> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> + </template> + </el-table-column> + + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width" width="200"> + <template slot-scope="scope"> + <el-button type="danger" size="small" style="padding: 5px" icon="el-icon-delete" + @click="handleDelete(scope.row)" v-hasPermi="['iot:device:remove']">鍒犻櫎</el-button> + <el-button type="primary" size="small" style="padding: 5px" icon="el-icon-view" + @click="handleEditDevice(scope.row)" v-hasPermi="['iot:device:add']">鏌ョ湅</el-button> + <el-button type="primary" size="small" style="padding: 5px" @click="openSummaryDialog(scope.row)" + v-if="form.deviceId != 0">浜岀淮鐮�</el-button> + </template> + </el-table-column> + </el-table> + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" + :pageSizes="[12, 24, 36, 60]" @pagination="getList" /> + + </el-card> + + <el-card style="padding-bottom: 100px" v-if="showType == 'card'"> + <el-row :gutter="30" v-loading="loading"> + <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" v-for="(item, index) in deviceList" :key="index" + style="margin-bottom: 30px; text-align: center"> + <el-card :body-style="{ padding: '20px' }" shadow="always" class="card-item"> + <el-row type="flex" :gutter="10" justify="space-between"> + <el-col :span="20" style="text-align: left"> + <el-link type="" :underline="false" @click="handleEditDevice(item)" + style="font-weight: bold; font-size: 16px; line-height: 32px"> + <el-tooltip class="item" effect="dark" content="鍒嗕韩鐨勮澶�" placement="top-start"> + <svg-icon icon-class="share" style="font-size: 20px" v-if="item.isOwner != 1" /> + </el-tooltip> + <svg-icon icon-class="device" v-if="item.isOwner == 1" /> + <span style="margin: 0 5px">{{ item.deviceName }}</span> + <!-- <el-tag size="mini" type="info">Ver {{item.firmwareVersion}}</el-tag>--> + <!-- <el-text v-if="item.protocolCode" type="info" size="mini" style="font-size: 14px; color: #ccc">{{ item.protocolCode }}</el-text> --> + </el-link> + </el-col> + <el-col :span="1.5" style="font-size: 20px; padding-top: 5px; cursor: pointer"> + <svg-icon icon-class="qrcode" @click="openSummaryDialog(item)" /> + </el-col> + <el-col :span="3"> + <div style="font-size: 28px; color: #ccc"> + <svg-icon v-if="item.status == 3 && item.rssi >= '-55'" icon-class="wifi_4" /> + <svg-icon v-else-if="item.status == 3 && item.rssi >= '-70' && item.rssi < '-55'" icon-class="wifi_3" /> + <svg-icon v-else-if="item.status == 3 && item.rssi >= '-85' && item.rssi < '-70'" icon-class="wifi_2" /> + <svg-icon v-else-if="item.status == 3 && item.rssi >= '-100' && item.rssi < '-85'" + icon-class="wifi_1" /> + <svg-icon v-else icon-class="wifi_0" /> + </div> + </el-col> + </el-row> + <el-row :gutter="10"> + <el-col :span="17"> + <div style="text-align: left; line-height: 40px; white-space: nowrap"> + <dict-tag :options="dict.type.iot_device_status" :value="item.status" size="small" + style="display: inline-block" /> + <span style="display: inline-block; margin: 0 10px"> + <!-- <el-tag type="success" size="small" v-if="item.isShadow == 1">褰卞瓙</el-tag> + <el-tag type="info" size="small" v-else>褰卞瓙</el-tag> --> + <el-tag type="primary" size="small" v-if="item.protocolCode">{{ item.protocolCode }}</el-tag> + </span> + <el-tag type="primary" size="small" v-if="item.transport">{{ item.transport }}</el-tag> + <!-- <dict-tag :options="dict.type.iot_location_way" :value="item.locationWay" size="small" style="display:inline-block;" /> --> + <!-- <dict-tag :options="dict.type.iot_transport_type" :value="item.transport" size="small" style="display: inline-block" /> --> + </div> + <el-descriptions :column="1" size="mini" style="white-space: nowrap"> + <el-descriptions-item label="缂栧彿"> + {{ item.serialNumber }} + </el-descriptions-item> + <el-descriptions-item label="浜у搧"> + {{ item.productName }} + </el-descriptions-item> + <el-descriptions-item label="婵�娲绘椂闂�"> + {{ parseTime(item.activeTime, '{y}-{m}-{d}') }} + </el-descriptions-item> + </el-descriptions> + </el-col> + <el-col :span="7"> + <div style="margin-top: 10px"> + <el-image style="width: 100%; height: 100px; border-radius: 10px" lazy + :preview-src-list="[baseUrl + item.imgUrl]" :src="baseUrl + item.imgUrl" fit="cover" + v-if="item.imgUrl != null && item.imgUrl != ''"></el-image> + <el-image style="width: 100%; height: 100px; border-radius: 10px" + :preview-src-list="[require('@/assets/images/gateway.png')]" + :src="require('@/assets/images/gateway.png')" fit="cover" v-else-if="item.deviceType == 2"></el-image> + <el-image style="width: 100%; height: 100px; border-radius: 10px" + :preview-src-list="[require('@/assets/images/video.png')]" :src="require('@/assets/images/video.png')" + fit="cover" v-else-if="item.deviceType == 3"></el-image> + <el-image style="width: 100%; height: 100px; border-radius: 10px" + :preview-src-list="[require('@/assets/images/product.png')]" + :src="require('@/assets/images/product.png')" fit="cover" v-else></el-image> + </div> + </el-col> + </el-row> + <el-button-group style="margin-top: 15px"> + <el-button type="danger" size="mini" style="padding: 5px 10px" icon="el-icon-delete" + @click="handleDelete(item)" v-hasPermi="['iot:device:remove']">鍒犻櫎</el-button> + <el-button type="primary" size="mini" style="padding: 5px 15px" icon="el-icon-view" + @click="handleEditDevice(item, 'basic')" v-hasPermi="['iot:device:add']">鏌ョ湅</el-button> + <el-button type="success" size="mini" style="padding: 5px 15px" icon="el-icon-odometer" + @click="handleRunDevice(item)" v-hasPermi="['iot:device:add']">杩愯鐘舵��</el-button> + </el-button-group> + </el-card> + </el-col> + </el-row> + <el-empty description="鏆傛棤鏁版嵁锛岃娣诲姞璁惧" v-if="total == 0"></el-empty> + <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" + :pageSizes="[12, 24, 36, 60]" @pagination="getList" /> + </el-card> + <!-- 浜岀淮鐮� --> + <el-dialog :visible.sync="openSummary" width="300px" append-to-body> + <div style="border: 1px solid #ccc; width: 220px; text-align: center; margin: 0 auto; margin-top: -15px"> + <vue-qr :text="qrText" :size="200"></vue-qr> + <div style="padding-bottom: 10px">璁惧浜岀淮鐮�</div> + </div> + </el-dialog> + </div> +</template> + +<script> +import vueQr from 'vue-qr'; +import { listDeviceShort, delDevice } from '@/api/iot/device'; +import { listGroup } from '@/api/iot/group'; + +export default { + name: 'Device', + dicts: ['iot_device_status', 'iot_is_enable', 'iot_location_way', 'iot_transport_type'], + components: { + vueQr, + }, + data() { + return { + // 浜岀淮鐮佸唴瀹� + qrText: 'fastbee', + // 鎵撳紑璁惧閰嶇疆瀵硅瘽妗� + openSummary: false, + // 灞曠ず鏂瑰紡 + showType: 'card', + // 閬僵灞� + loading: true, + // 鎬绘潯鏁� + total: 0, + // 璁惧鍒楄〃鏁版嵁 + deviceList: [], + // 鎴戠殑鍒嗙粍鍒楄〃鏁版嵁 + myGroupList: [], + // 鏍硅矾寰� + baseUrl: process.env.VUE_APP_BASE_API, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 12, + deviceName: null, + productId: null, + groupId: null, + productName: null, + userId: null, + userName: null, + tenantId: null, + tenantName: null, + serialNumber: null, + status: null, + networkAddress: null, + activeTime: null, + }, + // 琛ㄥ崟鍙傛暟 + form: { + productId: 0, + status: 1, + locationWay: 1, + firmwareVersion: 1.0, + serialNumber: '', + deviceType: 1, + isSimulate: 0, + }, + isSubDev: false, + }; + }, + created() { + // 浜у搧绛涢�� + let productId = this.$route.query.productId; + if (productId != null) { + this.queryParams.productId = Number(productId); + this.queryParams.groupId = null; + this.queryParams.serialNumber = null; + } + // 鍒嗙粍绛涢�� + let groupId = this.$route.query.groupId; + if (groupId != null) { + this.queryParams.groupId = Number(groupId); + this.queryParams.productId = null; + this.queryParams.serialNumber = null; + } + // 璁惧缂栧彿绛涢�� + let sn = this.$route.query.sn; + if (sn != null) { + this.queryParams.serialNumber = sn; + this.queryParams.productId = null; + this.queryParams.groupId = null; + } + this.connectMqtt(); + }, + activated() { + const time = this.$route.query.t; + if (time != null && time != this.uniqueId) { + this.uniqueId = time; + // 椤电爜绛涢�� + let pageNum = this.$route.query.pageNum; + if (pageNum != null) { + this.queryParams.pageNum = Number(pageNum); + } + // 浜у搧绛涢�� + let productId = this.$route.query.productId; + if (productId != null) { + this.queryParams.productId = Number(productId); + this.queryParams.groupId = null; + this.queryParams.serialNumber = null; + } + // 鍒嗙粍绛涢�� + let groupId = this.$route.query.groupId; + if (groupId != null) { + this.queryParams.groupId = Number(groupId); + this.queryParams.productId = null; + this.queryParams.serialNumber = null; + } + // 璁惧缂栧彿绛涢�� + let sn = this.$route.query.sn; + if (sn != null) { + this.queryParams.serialNumber = sn; + this.queryParams.productId = null; + this.queryParams.groupId = null; + } + this.getList(); + } + }, + methods: { + /* 杩炴帴Mqtt娑堟伅鏈嶅姟鍣� */ + async connectMqtt() { + if (this.$mqttTool.client == null) { + await this.$mqttTool.connect(); + } + this.mqttCallback(); + this.getList(); + }, + /* Mqtt鍥炶皟澶勭悊 */ + mqttCallback() { + this.$mqttTool.client.on('message', (topic, message, buffer) => { + let topics = topic.split('/'); + let productId = topics[1]; + let deviceNum = topics[2]; + message = JSON.parse(message.toString()); + if (!message) { + return; + } + if (topics[3] == 'status') { + console.log('鎺ユ敹鍒般�愯澶囩姸鎬併�戜富棰橈細', topic); + console.log('鎺ユ敹鍒般�愯澶囩姸鎬併�戝唴瀹癸細', message); + // 鏇存柊鍒楄〃涓澶囩殑鐘舵�� + for (let i = 0; i < this.deviceList.length; i++) { + if (this.deviceList[i].serialNumber == deviceNum) { + this.deviceList[i].status = message.status; + this.deviceList[i].isShadow = message.isShadow; + this.deviceList[i].rssi = message.rssi; + return; + } + } + } + }); + }, + openSummaryDialog(row) { + let json = { + type: 1, // 1=鎵爜鍏宠仈璁惧 + deviceNumber: row.serialNumber, + productId: row.productId, + productName: row.productName, + }; + this.qrText = JSON.stringify(json); + this.openSummary = true; + }, + /* 璁㈤槄娑堟伅 */ + mqttSubscribe(list) { + // 璁㈤槄褰撳墠椤甸潰璁惧鐘舵�佸拰瀹炴椂鐩戞祴 + let topics = []; + for (let i = 0; i < list.length; i++) { + let topicStatus = '/' + '+' + '/' + list[i].serialNumber + '/status/post'; + topics.push(topicStatus); + } + this.$mqttTool.subscribe(topics); + }, + /** 鏌ヨ璁惧鍒嗙粍鍒楄〃 */ + getGroupList() { + this.loading = true; + let queryParams = { + pageSize: 30, + pageNum: 1, + userId: this.$store.state.user.userId, + }; + listGroup(queryParams).then((response) => { + this.myGroupList = response.rows; + }); + }, + /** 鏌ヨ鎵�鏈夌畝鐭澶囧垪琛� */ + getList() { + this.loading = true; + this.queryParams.params = {}; + this.getGroupList(); + listDeviceShort(this.queryParams).then((response) => { + this.deviceList = response.rows; + this.total = response.total; + // 璁㈤槄娑堟伅 + if (this.deviceList && this.deviceList.length > 0) { + this.mqttSubscribe(this.deviceList); + } + this.loading = false; + }); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.queryParams.productId = null; + this.queryParams.groupId = null; + this.queryParams.serialNumber = null; + this.resetForm('queryForm'); + this.handleQuery(); + }, + /** 鍒囨崲鏄剧ず鏂瑰紡 */ + handleChangeShowType() { + this.showType = this.showType == 'card' ? 'list' : 'card'; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleEditDevice(row, activeName) { + let deviceId = 0; + let isSubDev = 0; + if (row != 0) { + deviceId = row.deviceId || this.ids; + isSubDev = row.subDeviceCount > 0 ? 1 : 0; + } + this.$router.push({ + path: '/iot/device-edit', + query: { + deviceId: deviceId, + isSubDev: isSubDev, + pageNum: this.queryParams.pageNum, + activeName: activeName, + }, + }); + }, + /** 杩愯鐘舵�佹寜閽搷浣� */ + handleRunDevice(row) { + let deviceId = 0; + let isSubDev = 0; + if (row != 0) { + deviceId = row.deviceId || this.ids; + isSubDev = row.subDeviceCount > 0 ? 1 : 0; + } + if (row.deviceType === 3) { + this.$router.push({ + path: '/iot/device-edit', + query: { + deviceId: deviceId, + isSubDev: isSubDev, + pageNum: this.queryParams.pageNum, + activeName: 'sipChannel', + }, + }); + } else { + this.$router.push({ + path: '/iot/device-edit', + query: { + deviceId: deviceId, + isSubDev: isSubDev, + pageNum: this.queryParams.pageNum, + activeName: 'runningStatus', + }, + }); + } + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const deviceIds = row.deviceId || this.ids; + this.$modal + .confirm('鏄惁纭鍒犻櫎璁惧缂栧彿涓�"' + deviceIds + '"鐨勬暟鎹」锛�') + .then(function () { + if (row.deviceType === 3) { + delSipDeviceBySipId(row.serialNumber); + } + return delDevice(deviceIds); + }) + .then(() => { + this.getList(); + this.$modal.msgSuccess('鍒犻櫎鎴愬姛'); + }) + .catch(() => { }); + }, + /** 鏈惎鐢ㄨ澶囧奖瀛�*/ + shadowUnEnable(device, thingsModel) { + // 1-鏈縺娲伙紝2-绂佺敤锛�3-鍦ㄧ嚎锛�4-绂荤嚎 + if (device.status != 3 && device.isShadow == 0) { + return true; + } + if (thingsModel.isReadonly) { + return true; + } + return false; + }, + }, +}; +</script> + +<style scoped> +.card-item { + border-radius: 15px; +} +</style> diff --git a/src/views/iot/device/product-list.vue b/src/views/iot/device/product-list.vue new file mode 100644 index 0000000..b39099d --- /dev/null +++ b/src/views/iot/device/product-list.vue @@ -0,0 +1,156 @@ +<template> +<el-dialog title="閫夋嫨浜у搧" :visible.sync="open" width="800px"> + <div style="margin-top:-55px;"> + <el-divider style="margin-top:-30px;"></el-divider> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px"> + <el-form-item label="浜у搧鍚嶇О" prop="productName"> + <el-input v-model="queryParams.productName" placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�" clearable size="small" @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" ref="singleTable" :data="productList" @row-click="rowClick" highlight-current-row size="mini"> + <el-table-column label="閫夋嫨" width="50" align="center"> + <template slot-scope="scope"> + <input type="radio" :checked="scope.row.isSelect" name="product" /> + </template> + </el-table-column> + <el-table-column label="浜у搧鍚嶇О" align="center" prop="productName" /> + <el-table-column label="鍒嗙被鍚嶇О" align="center" prop="categoryName" /> + <el-table-column label="绉熸埛鍚嶇О" align="center" prop="tenantName" /> + <el-table-column label="鎺堟潈鐮�" align="center" prop="status" width="70"> + <template slot-scope="scope"> + <el-tag type="success" v-if="scope.row.isAuthorize==1">鍚敤</el-tag> + <el-tag type="info" v-if="scope.row.isAuthorize==0">鏈惎鐢�</el-tag> + </template> + </el-table-column> + <el-table-column label="璁よ瘉鏂瑰紡" align="center" prop="status"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_vertificate_method" :value="scope.row.vertificateMethod" /> + </template> + </el-table-column> + <el-table-column label="鑱旂綉鏂瑰紡" align="center" prop="networkMethod"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_network_method" :value="scope.row.networkMethod" /> + </template> + </el-table-column> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="100"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</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> + <div slot="footer" class="dialog-footer"> + <el-button @click="confirmSelectProduct" type="primary">纭畾</el-button> + <el-button @click="closeDialog" type="info">鍏� 闂�</el-button> + </div> +</el-dialog> +</template> + +<script> +import { + listProduct, +} from "@/api/iot/product"; + +export default { + name: "ProductList", + dicts: ['iot_vertificate_method', 'iot_network_method'], + props: { + productId: { + type: Number, + default: 0 + } + }, + data() { + return { + // 閬僵灞� + loading: true, + // 鎬绘潯鏁� + total: 0, + // 鎵撳紑閫夋嫨浜у搧瀵硅瘽妗� + open: false, + // 浜у搧鍒楄〃 + productList: [], + // 閫変腑鐨勪骇鍝� + product: {}, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + productName: null, + categoryId: null, + categoryName: null, + tenantId: null, + tenantName: null, + isSys: null, + status: 2, //宸插彂甯� + deviceType: null, + networkMethod: null, + }, + }; + }, + created() { + + }, + methods: { + /** 鏌ヨ浜у搧鍒楄〃 */ + getList() { + this.loading = true; + listProduct(this.queryParams).then(response => { + //浜у搧鍒楄〃鍒濆鍖杋sSelect鍊硷紝鐢ㄤ簬鍗曢�� + for (let i = 0; i < response.rows.length; i++) { + response.rows[i].isSelect = false; + } + this.productList = response.rows; + this.total = response.total; + if (this.productId != 0) { + this.setRadioSelected(this.productId); + } + this.loading = false; + }); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + /** 鍗曢�夋暟鎹� */ + rowClick(product) { + if (product != null) { + this.setRadioSelected(product.productId); + this.product = product; + } + }, + /** 璁剧疆鍗曢�夋寜閽�変腑 */ + setRadioSelected(productId) { + for (let i = 0; i < this.productList.length; i++) { + if (this.productList[i].productId == productId) { + this.productList[i].isSelect = true; + } else { + this.productList[i].isSelect = false; + } + } + }, + /**纭畾閫夋嫨浜у搧锛屼骇鍝佷紶閫掔粰鐖剁粍浠� */ + confirmSelectProduct() { + this.$emit('productEvent', this.product); + this.open = false; + }, + /**鍏抽棴瀵硅瘽妗� */ + closeDialog() { + this.open = false; + } + } +}; +</script> diff --git a/src/views/iot/device/running-status.vue b/src/views/iot/device/running-status.vue new file mode 100644 index 0000000..f26cf7d --- /dev/null +++ b/src/views/iot/device/running-status.vue @@ -0,0 +1,946 @@ +<template> + <div style="padding-left: 20px"> + <el-row :gutter="120"> + <el-col :xs="24" :sm="24" :md="24" :lg="14" :xl="10" style="margin-bottom: 50px"> + <el-descriptions :column="1" border style="margin-bottom: 50px"> + <!-- 璁惧妯″紡--> + <el-descriptions-item :labelStyle="statusColor"> + <template slot="label"> + <i class="el-icon-menu"></i> + 璁惧妯″紡 + </template> + <el-link :underline="false" style="line-height: 28px; font-size: 16px; padding-right: 10px">{{ title }}</el-link> + </el-descriptions-item> + + <!-- 璁惧鐗╂ā鍨�--> + <el-descriptions-item v-for="(item, index) in deviceInfo.thingsModels" :key="index" :labelStyle="statusColor"> + <template slot="label"> + <i class="el-icon-open"></i> + {{ item.name }} + </template> + <div v-if="item.datatype.type == 'bool'"> + <el-switch + v-model="item.shadow" + @change="mqttPublish(deviceInfo, item)" + active-text="" + inactive-text="" + active-value="1" + inactive-value="0" + style="min-width: 100px" + :disabled="shadowUnEnable || item.isReadonly == 1" + /> + </div> + <div v-if="item.datatype.type == 'enum'"> + <div v-if="item.datatype.showWay && item.datatype.showWay == 'button'"> + <el-button + style="margin: 5px" + size="mini" + @click="enumButtonClick(deviceInfo, item, subItem.value)" + v-for="subItem in item.datatype.enumList" + :key="subItem.value" + :disabled="shadowUnEnable || item.isReadonly == 1" + > + {{ subItem.text }} + </el-button> + </div> + <el-select v-else v-model="item.shadow" placeholder="璇烽�夋嫨" @change="mqttPublish(deviceInfo, item)" :disabled="shadowUnEnable || item.isReadonly == 1"> + <el-option v-for="subItem in item.datatype.enumList" :key="subItem.value" :label="subItem.text" :value="subItem.value" /> + </el-select> + </div> + <div v-if="item.datatype.type == 'string'"> + <el-input v-model="item.shadow" :placeholder="'璇疯緭鍏ュ瓧绗︿覆 ' + (item.datatype.unit ? '锛屽崟浣嶏細' + item.datatype.unit : '')" :disabled="shadowUnEnable || item.isReadonly == 1"> + <el-button + slot="append" + icon="el-icon-s-promotion" + @click="mqttPublish(deviceInfo, item)" + style="font-size: 20px" + title="鎸囦护鍙戦��" + v-if="!shadowUnEnable && item.isReadonly == 0" + ></el-button> + </el-input> + </div> + <div v-if="item.datatype.type == 'decimal'"> + <div style="width: 80%; float: left"> + <el-slider + v-model="item.shadow" + :min="item.datatype.min" + :max="item.datatype.max" + :step="item.datatype.step" + :format-tooltip="(x) => x + ' ' + item.datatype.unit" + :disabled="shadowUnEnable || item.isReadonly == 1" + ></el-slider> + </div> + <div style="width: 20%; float: left"> + <el-button + icon="el-icon-s-promotion" + type="info" + @click="mqttPublish(deviceInfo, item)" + style="font-size: 16px; padding: 1px 8px; margin: 2px 0 0 5px; border-radius: 3px" + title="鎸囦护鍙戦��" + v-if="!shadowUnEnable && item.isReadonly == 0" + ></el-button> + </div> + </div> + <div v-if="item.datatype.type == 'integer'"> + <div style="width: 80%; float: left"> + <el-slider + v-model="item.shadow" + :min="item.datatype.min" + :max="item.datatype.max" + :step="item.datatype.step" + :format-tooltip="(x) => x + ' ' + item.datatype.unit" + :disabled="shadowUnEnable || item.isReadonly == 1" + ></el-slider> + </div> + <div style="width: 20%; float: left"> + <el-button + icon="el-icon-s-promotion" + type="info" + @click="mqttPublish(deviceInfo, item)" + style="font-size: 16px; padding: 1px 8px; margin: 4px 0 0 10px; border-radius: 3px" + title="鎸囦护鍙戦��" + v-if="!shadowUnEnable && item.isReadonly == 0" + ></el-button> + </div> + </div> + <div v-if="item.datatype.type == 'object'"> + <el-descriptions :column="1" size="mini" border> + <el-descriptions-item v-for="(param, index) in item.datatype.params" :key="index" :label="param.name"> + <div v-if="param.datatype.type == 'bool'"> + <el-switch + v-model="param.shadow" + @change="mqttPublish(deviceInfo, param)" + active-text="" + inactive-text="" + active-value="1" + inactive-value="0" + style="min-width: 100px" + :disabled="shadowUnEnable || param.isReadonly == 1" + /> + </div> + <div v-if="param.datatype.type == 'enum'"> + <div v-if="param.datatype.showWay && param.datatype.showWay == 'button'"> + <el-button + style="margin: 5px" + size="mini" + @click="enumButtonClick(deviceInfo, param, subItem.value)" + v-for="subItem in param.datatype.enumList" + :key="subItem.value" + :disabled="shadowUnEnable || param.isReadonly == 1" + > + {{ subItem.text }} + </el-button> + </div> + <el-select size="small" v-else v-model="param.shadow" placeholder="璇烽�夋嫨" @change="mqttPublish(deviceInfo, param)" :disabled="shadowUnEnable || param.isReadonly == 1"> + <el-option v-for="subItem in param.datatype.enumList" :key="subItem.value" :label="subItem.text" :value="subItem.value" /> + </el-select> + </div> + <div v-if="param.datatype.type == 'string'"> + <el-input v-model="param.shadow" placeholder="璇疯緭鍏ュ瓧绗︿覆" :disabled="shadowUnEnable || param.isReadonly == 1"> + <el-button + slot="append" + icon="el-icon-s-promotion" + @click="mqttPublish(deviceInfo, param)" + style="font-size: 20px" + title="鎸囦护鍙戦��" + v-if="!shadowUnEnable && param.isReadonly == 0" + ></el-button> + </el-input> + </div> + <div v-if="param.datatype.type == 'decimal'"> + <el-input v-model="param.shadow" type="number" placeholder="璇疯緭鍏ュ皬鏁� " :disabled="shadowUnEnable || param.isReadonly == 1"> + <el-button + slot="append" + icon="el-icon-s-promotion" + @click="mqttPublish(deviceInfo, param)" + style="font-size: 20px" + title="鎸囦护鍙戦��" + v-if="!shadowUnEnable && param.isReadonly == 0" + ></el-button> + </el-input> + </div> + <div v-if="param.datatype.type == 'integer'"> + <el-input v-model="param.shadow" type="integer" placeholder="璇疯緭鍏ユ暣鏁� " :disabled="shadowUnEnable || param.isReadonly == 1"> + <el-button + slot="append" + icon="el-icon-s-promotion" + @click="mqttPublish(deviceInfo, param)" + style="font-size: 20px" + title="鎸囦护鍙戦��" + v-if="!shadowUnEnable && param.isReadonly == 0" + ></el-button> + </el-input> + </div> + </el-descriptions-item> + </el-descriptions> + </div> + <div v-if="item.datatype.type == 'array'"> + <el-descriptions :column="1" size="mini" border v-if="item.datatype.arrayType != 'object'"> + <el-descriptions-item v-for="(model, index) in item.datatype.arrayModel" :key="index" :label="item.name + (index + 1)"> + <div v-if="item.datatype.arrayType == 'string'"> + <el-input placeholder="璇疯緭鍏ュ瓧绗︿覆" size="mini" v-model="model.shadow" :disabled="shadowUnEnable || item.isReadonly == 1" @input="arrayItemChange($event, item)"> + <el-button + slot="append" + icon="el-icon-s-promotion" + @click="mqttPublish(deviceInfo, model)" + style="font-size: 20px" + title="鎸囦护鍙戦��" + v-if="!shadowUnEnable || item.isReadonly == 0" + ></el-button> + </el-input> + </div> + <div v-if="item.datatype.arrayType == 'decimal'"> + <el-input type="number" placeholder="璇疯緭鍏ュ皬鏁� " size="mini" v-model="model.shadow" :disabled="shadowUnEnable || item.isReadonly == 1" @input="arrayItemChange($event, item)"> + <el-button + slot="append" + icon="el-icon-s-promotion" + @click="mqttPublish(deviceInfo, model)" + style="font-size: 20px" + title="鎸囦护鍙戦��" + v-if="!shadowUnEnable || item.isReadonly == 0" + ></el-button> + </el-input> + </div> + <div v-if="item.datatype.arrayType == 'integer'"> + <el-input type="integer" placeholder="璇疯緭鍏ユ暣鏁� " size="mini" v-model="model.shadow" :disabled="shadowUnEnable || item.isReadonly == 1" @input="arrayItemChange($event, item)"> + <el-button + slot="append" + icon="el-icon-s-promotion" + @click="mqttPublish(deviceInfo, model)" + style="font-size: 20px" + title="鎸囦护鍙戦��" + v-if="!shadowUnEnable || item.isReadonly == 0" + ></el-button> + </el-input> + </div> + </el-descriptions-item> + </el-descriptions> + <el-collapse v-if="item.datatype.arrayType == 'object'"> + <el-collapse-item v-for="(arrayParam, index) in item.datatype.arrayParams" :key="index"> + <template slot="title"> + <span style="color: #666"> + <i class="el-icon-tickets"></i> + {{ item.name + (index + 1) }} + </span> + </template> + <el-descriptions :column="1" size="mini" border> + <el-descriptions-item v-for="(param, index) in arrayParam" :key="index" :label="param.name"> + <div v-if="param.datatype.type == 'bool'"> + <el-switch + v-model="param.shadow" + @change="mqttPublish(deviceInfo, param)" + active-text="" + inactive-text="" + active-value="1" + inactive-value="0" + style="min-width: 100px" + :disabled="shadowUnEnable || param.isReadonly == 1" + /> + </div> + <div v-if="param.datatype.type == 'enum'"> + <div v-if="param.datatype.showWay && param.datatype.showWay == 'button'"> + <el-button + style="margin: 5px" + size="mini" + @click="enumButtonClick(deviceInfo, param, subItem.value)" + v-for="subItem in param.datatype.enumList" + :key="subItem.value" + :disabled="shadowUnEnable || param.isReadonly == 1" + > + {{ subItem.text }} + </el-button> + </div> + <el-select v-else v-model="param.shadow" placeholder="璇烽�夋嫨" size="small" @change="mqttPublish(deviceInfo, param)" :disabled="shadowUnEnable || param.isReadonly == 1"> + <el-option v-for="subItem in param.datatype.enumList" :key="subItem.value" :label="subItem.text" :value="subItem.value" /> + </el-select> + </div> + <div v-if="param.datatype.type == 'string'"> + <el-input v-model="param.shadow" placeholder="璇疯緭鍏ュ瓧绗︿覆" :disabled="shadowUnEnable || param.isReadonly == 1"> + <el-button + slot="append" + icon="el-icon-s-promotion" + @click="mqttPublish(deviceInfo, param)" + style="font-size: 20px" + title="鎸囦护鍙戦��" + v-if="!shadowUnEnable && param.isReadonly == 0" + ></el-button> + </el-input> + </div> + <div v-if="param.datatype.type == 'decimal'"> + <el-input v-model="param.shadow" type="number" placeholder="璇疯緭鍏ュ皬鏁� " :disabled="shadowUnEnable || param.isReadonly == 1"> + <el-button + slot="append" + icon="el-icon-s-promotion" + @click="mqttPublish(deviceInfo, param)" + style="font-size: 20px" + title="鎸囦护鍙戦��" + v-if="!shadowUnEnable && param.isReadonly == 0" + ></el-button> + </el-input> + </div> + <div v-if="param.datatype.type == 'integer'"> + <el-input v-model="param.shadow" type="integer" placeholder="璇疯緭鍏ユ暣鏁� " :disabled="shadowUnEnable || param.isReadonly == 1"> + <el-button + slot="append" + icon="el-icon-s-promotion" + @click="mqttPublish(deviceInfo, param)" + style="font-size: 20px" + title="鎸囦护鍙戦��" + v-if="!shadowUnEnable && param.isReadonly == 0" + ></el-button> + </el-input> + </div> + </el-descriptions-item> + </el-descriptions> + </el-collapse-item> + </el-collapse> + </div> + </el-descriptions-item> + </el-descriptions> + + <!---璁惧鐘舵��(褰卞瓙妯″紡锛寁alue鍊间笉浼氭洿鏂�)--> + <el-descriptions :column="1" border size="mini" v-if="deviceInfo.isShadow == 1 && deviceInfo.status != 3"> + <template slot="title"> + <span style="font-size: 14px; color: #606266">璁惧绂荤嚎鏃剁姸鎬�</span> + </template> + + <!-- 璁惧鐗╂ā鍨�--> + <el-descriptions-item v-for="(item, index) in deviceInfo.thingsModels" :key="index"> + <template slot="label"> + <i class="el-icon-open"></i> + {{ item.name }} + </template> + <div v-if="item.datatype.type == 'bool'"> + <el-switch v-model="item.value" @change="mqttPublish(deviceInfo, item)" active-text="" inactive-text="" active-value="1" inactive-value="0" style="min-width: 100px" disabled /> + </div> + <div v-if="item.datatype.type == 'enum'"> + <div v-if="item.datatype.showWay && item.datatype.showWay == 'button'"> + <el-button style="margin: 5px" size="mini" disabled v-for="subItem in item.datatype.enumList" :key="subItem.value">{{ subItem.text }}</el-button> + </div> + <el-select v-else v-model="item.value" placeholder="璇烽�夋嫨" @change="mqttPublish(deviceInfo, item)" disabled size="mini"> + <el-option v-for="subItem in item.datatype.enumList" :key="subItem.value" :label="subItem.text" :value="subItem.value" /> + </el-select> + </div> + <div v-if="item.datatype.type == 'string'"> + <el-input v-model="item.value" placeholder="璇疯緭鍏ュ瓧绗︿覆" disabled size="mini"></el-input> + </div> + <div v-if="item.datatype.type == 'decimal'"> + <el-input v-model="item.value" type="number" placeholder="璇疯緭鍏ュ皬鏁� " disabled size="mini"></el-input> + </div> + <div v-if="item.datatype.type == 'integer'"> + <el-input v-model="item.value" type="integer" placeholder="璇疯緭鍏ユ暣鏁� " disabled size="mini"></el-input> + </div> + <div v-if="item.datatype.type == 'object'"> + <el-descriptions :column="1" size="mini" border> + <el-descriptions-item v-for="(param, index) in item.datatype.params" :key="index" :label="param.name"> + <div v-if="param.datatype.type == 'bool'"> + <el-switch + v-model="param.value" + size="mini" + @change="mqttPublish(deviceInfo, param)" + active-text="" + inactive-text="" + active-value="1" + inactive-value="0" + style="min-width: 100px" + disabled + /> + </div> + <div v-if="param.datatype.type == 'enum'"> + <el-select v-model="param.value" placeholder="璇烽�夋嫨" @change="mqttPublish(deviceInfo, param)" disabled size="mini"> + <el-option v-for="subItem in param.datatype.enumList" :key="subItem.value" :label="subItem.text" :value="subItem.value" /> + </el-select> + </div> + <div v-if="param.datatype.type == 'string'"> + <el-input v-model="param.value" placeholder="璇疯緭鍏ュ瓧绗︿覆" disabled size="mini"></el-input> + </div> + <div v-if="param.datatype.type == 'decimal'"> + <el-input v-model="param.value" type="number" placeholder="璇疯緭鍏ュ皬鏁� " disabled size="mini"></el-input> + </div> + <div v-if="param.datatype.type == 'integer'"> + <el-input v-model="param.value" type="integer" placeholder="璇疯緭鍏ユ暣鏁� " disabled size="mini"></el-input> + </div> + </el-descriptions-item> + </el-descriptions> + </div> + <div v-if="item.datatype.type == 'array'"> + <el-descriptions :column="1" size="mini" border v-if="item.datatype.arrayType != 'object'"> + <el-descriptions-item v-for="(model, index) in item.datatype.arrayModel" :key="index" :label="item.name + (index + 1)"> + <div v-if="item.datatype.arrayType == 'string'"> + <el-input v-model="model.value" placeholder="璇疯緭鍏ュ瓧绗︿覆" size="mini" disabled></el-input> + </div> + <div v-if="item.datatype.arrayType == 'decimal'"> + <el-input v-model="model.value" type="number" placeholder="璇疯緭鍏ュ皬鏁� " size="mini" disabled></el-input> + </div> + <div v-if="item.datatype.arrayType == 'integer'"> + <el-input v-model="model.value" type="integer" placeholder="璇疯緭鍏ユ暣鏁� " size="mini" disabled></el-input> + </div> + </el-descriptions-item> + </el-descriptions> + <el-collapse v-if="item.datatype.arrayType == 'object'"> + <el-collapse-item v-for="(arrayParam, index) in item.datatype.arrayParams" :key="index"> + <template slot="title"> + <span style="color: #666"> + <i class="el-icon-tickets"></i> + {{ item.name + (index + 1) }} + </span> + </template> + <el-descriptions :column="1" size="mini" border> + <el-descriptions-item v-for="(param, index) in arrayParam" :key="index" :label="param.name"> + <div v-if="param.datatype.type == 'bool'"> + <el-switch + v-model="param.value" + @change="mqttPublish(deviceInfo, param)" + active-text="" + inactive-text="" + active-value="1" + inactive-value="0" + style="min-width: 100px" + disabled + /> + </div> + <div v-if="param.datatype.type == 'enum'"> + <el-select v-model="param.value" placeholder="璇烽�夋嫨" @change="mqttPublish(deviceInfo, param)" disabled size="mini"> + <el-option v-for="subItem in param.datatype.enumList" :key="subItem.value" :label="subItem.text" :value="subItem.value" /> + </el-select> + </div> + <div v-if="param.datatype.type == 'string'"> + <el-input v-model="param.value" placeholder="璇疯緭鍏ュ瓧绗︿覆" disabled size="mini"></el-input> + </div> + <div v-if="param.datatype.type == 'decimal'"> + <el-input v-model="param.value" type="number" placeholder="璇疯緭鍏ュ皬鏁� " disabled size="mini"></el-input> + </div> + <div v-if="param.datatype.type == 'integer'"> + <el-input v-model="param.value" type="integer" placeholder="璇疯緭鍏ユ暣鏁� " disabled size="mini"></el-input> + </div> + </el-descriptions-item> + </el-descriptions> + </el-collapse-item> + </el-collapse> + </div> + </el-descriptions-item> + </el-descriptions> + </el-col> + + <el-col :xs="24" :sm="24" :md="24" :lg="10" :xl="14"> + <!-- 璁惧鐩戞祴鍥捐〃--> + <el-row :gutter="20" style="background-color: #f5f7fa; padding: 20px 10px 20px 10px; border-radius: 15px; margin-right: 5px" v-if="deviceInfo.chartList.length > 0"> + <el-col :xs="24" :sm="12" :md="12" :lg="24" :xl="8" v-for="(item, index) in deviceInfo.chartList" :key="index"> + <el-card shadow="hover" style="border-radius: 30px; margin-bottom: 20px"> + <div ref="map" style="height: 230px; width: 185px; margin: 0 auto"></div> + </el-card> + </el-col> + </el-row> + </el-col> + </el-row> + </div> +</template> + +<script> +import { serviceInvoke } from '@/api/iot/runstatus'; + +export default { + name: 'running-status', + props: { + device: { + type: Object, + default: null, + }, + }, + watch: { + // 鑾峰彇鍒扮埗缁勪欢浼犻�掔殑device鍚庯紝鍒锋柊鍒楄〃 + device: function (newVal, oldVal) { + if (newVal && newVal.deviceId != 0) { + this.deviceInfo = newVal; + this.updateDeviceStatus(this.deviceInfo); + this.$nextTick(function () { + this.MonitorChart(); + }); + this.mqttCallback(); + } + }, + }, + data() { + return { + // 鎺у埗妯″潡鏍囬 + title: '璁惧鎺у埗 ', + // 鏈惎鐢ㄨ澶囧奖瀛� + shadowUnEnable: false, + // 鎺у埗椤规爣棰樿儗鏅� + statusColor: { + background: '#67C23A', + color: '#fff', + minWidth: '100px', + }, + // 鏈�鏂板浐浠朵俊鎭� + firmware: {}, + // 鎵撳紑鍥轰欢瀵硅瘽妗� + openFirmware: false, + // 閬僵灞� + loading: true, + // 璁惧淇℃伅 + deviceInfo: { + boolList: [], + enumList: [], + stringList: [], + integerList: [], + decimalList: [], + arrayList: [], + thingsModels: [], + chartList: [], + }, + // 鐩戞祴鍥捐〃 + monitorChart: [ + { + chart: {}, + data: { + id: '', + name: '', + value: '', + }, + }, + ], + remoteCommand: {}, + }; + }, + created() {}, + methods: { + /* Mqtt鍥炶皟澶勭悊 */ + mqttCallback() { + this.$mqttTool.client.on('message', (topic, message, buffer) => { + let topics = topic.split('/'); + let productId = topics[1]; + let deviceNum = topics[2]; + console.log('浠〃鐩�', topic); + message = JSON.parse(message.toString()); + if (!message) { + return; + } + if (topics[3] == 'status') { + console.log('鎺ユ敹鍒般�愯澶囩姸鎬�-杩愯銆戜富棰橈細', topic); + console.log('鎺ユ敹鍒般�愯澶囩姸鎬�-杩愯銆戝唴瀹癸細', message); + // 鏇存柊鍒楄〃涓澶囩殑鐘舵�� + if (this.deviceInfo.serialNumber == deviceNum) { + this.deviceInfo.status = message.status; + this.deviceInfo.isShadow = message.isShadow; + this.deviceInfo.rssi = message.rssi; + this.updateDeviceStatus(this.deviceInfo); + } + } + if (topics[3] === 'monitor') { + for (let m = 0; m < this.monitorChart.length; m++) { + for (let j = 0; j < message.length; j++) { + if (this.monitorChart[m].data.id === message[j].id) { + let data = [ + { + value: message[j].value, + name: this.monitorChart[m].data.name, + }, + ]; + this.monitorChart[m].chart.setOption({ + series: [ + { + data: data, + }, + ], + }); + } + } + } + } + //鍏煎璁惧鍥炲 + if (topics[4] == 'reply') { + this.$modal.notifySuccess(message); + } + if (topic.endsWith('ws/service')) { + console.log('鎺ユ敹鍒般�愮墿妯″瀷銆戜富棰�1锛�', topic); + console.log('鎺ユ敹鍒般�愮墿妯″瀷銆戝唴瀹癸細', message); + // 鏇存柊鍒楄〃涓澶囩殑灞炴�� + if (this.deviceInfo.serialNumber == deviceNum) { + for (let j = 0; j < message.length; j++) { + let isComplete = false; + // 璁惧鐘舵�� + for (let k = 0; k < this.deviceInfo.thingsModels.length && !isComplete; k++) { + if (this.deviceInfo.thingsModels[k].id == message[j].id) { + // 鏅�氱被鍨�(灏忔暟/鏁存暟/瀛楃涓�/甯冨皵/鏋氫妇) + if (this.deviceInfo.thingsModels[k].datatype.type == 'decimal' || this.deviceInfo.thingsModels[k].datatype.type == 'integer') { + this.deviceInfo.thingsModels[k].shadow = Number(message[j].value); + } else { + this.deviceInfo.thingsModels[k].shadow = message[j].value; + } + isComplete = true; + break; + } else if (this.deviceInfo.thingsModels[k].datatype.type == 'object') { + // 瀵硅薄绫诲瀷 + for (let n = 0; n < this.deviceInfo.thingsModels[k].datatype.params.length; n++) { + if (this.deviceInfo.thingsModels[k].datatype.params[n].id == message[j].id) { + this.deviceInfo.thingsModels[k].datatype.params[n].shadow = message[j].value; + isComplete = true; + break; + } + } + } else if (this.deviceInfo.thingsModels[k].datatype.type == 'array') { + // 鏁扮粍绫诲瀷 + if (this.deviceInfo.thingsModels[k].datatype.arrayType == 'object') { + // 1.瀵硅薄绫诲瀷鏁扮粍,id涓烘暟缁勪腑涓�涓厓绱�,渚嬪锛歛rray_01_gateway_temperature + if (String(message[j].id).indexOf('array_') == 0) { + for (let n = 0; n < this.deviceInfo.thingsModels[k].datatype.arrayParams.length; n++) { + for (let m = 0; m < this.deviceInfo.thingsModels[k].datatype.arrayParams[n].length; m++) { + if (this.deviceInfo.thingsModels[k].datatype.arrayParams[n][m].id == message[j].id) { + this.deviceInfo.thingsModels[k].datatype.arrayParams[n][m].shadow = message[j].value; + isComplete = true; + break; + } + } + if (isComplete) { + break; + } + } + } else { + // 2.瀵硅薄绫诲瀷鏁扮粍锛屼緥濡傦細gateway_temperature,娑堟伅ID娣诲姞鍓嶇紑鍚庡尮閰� + for (let n = 0; n < this.deviceInfo.thingsModels[k].datatype.arrayParams.length; n++) { + for (let m = 0; m < this.deviceInfo.thingsModels[k].datatype.arrayParams[n].length; m++) { + let index = n > 9 ? String(n) : '0' + k; + let prefix = 'array_' + index + '_'; + if (this.deviceInfo.thingsModels[k].datatype.arrayParams[n][m].id == prefix + message[j].id) { + this.deviceInfo.thingsModels[k].datatype.arrayParams[n][m].shadow = message[j].value; + isComplete = true; + } + } + if (isComplete) { + break; + } + } + } + } else { + // 鏁存暟銆佸皬鏁板拰瀛楃涓茬被鍨嬫暟缁� + for (let n = 0; n < this.deviceInfo.thingsModels[k].datatype.arrayModel.length; n++) { + if (this.deviceInfo.thingsModels[k].datatype.arrayModel[n].id == message[j].id) { + this.deviceInfo.thingsModels[k].datatype.arrayModel[n].shadow = message[j].value; + isComplete = true; + break; + } + } + } + } + } + // 鍥捐〃鏁版嵁 + for (let k = 0; k < this.deviceInfo.chartList.length; k++) { + if (this.deviceInfo.chartList[k].id.indexOf('array_') == 0) { + // 鏁扮粍绫诲瀷鍖归厤,渚嬪锛歛rray_00_gateway_temperature + if (this.deviceInfo.chartList[k].id == message[j].id) { + // let shadows = message[j].value.split(","); + this.deviceInfo.chartList[k].shadow = message[j].value; + // 鏇存柊鍥捐〃 + for (let m = 0; m < this.monitorChart.length; m++) { + if (message[j].id == this.monitorChart[m].data.id) { + let data = [ + { + value: message[j].value, + name: this.monitorChart[m].data.name, + }, + ]; + this.monitorChart[m].chart.setOption({ + series: [ + { + data: data, + }, + ], + }); + break; + } + } + } + } else { + // 鏅�氱被鍨嬪尮閰� + if (this.deviceInfo.chartList[k].id == message[j].id) { + this.deviceInfo.chartList[k].shadow = message[j].value; + // 鏇存柊鍥捐〃 + console.log('鏇存柊鍥捐〃', message); + for (let m = 0; m < this.monitorChart.length; m++) { + if (message[j].id == this.monitorChart[m].data.id) { + isComplete = true; + let data = [ + { + value: message[j].value, + name: this.monitorChart[m].data.name, + }, + ]; + this.monitorChart[m].chart.setOption({ + series: [ + { + data: data, + }, + ], + }); + break; + } + } + } + } + if (isComplete) { + break; + } + } + } + } + } + }); + }, + + //鍙戦�佹寚浠� + mqttPublish(device, model) { + const command = {}; + command[model.id] = model.shadow; + const data = { + serialNumber: device.serialNumber, + productId: device.productId, + remoteCommand: command, + identifier: model.id, + modelName: model.name, + isShadow: device.status != 3, + type: model.type, + }; + serviceInvoke(data).then((response) => { + if (response.code === 200) { + this.$message({ + type: 'success', + message: '鏈嶅姟璋冪敤鎴愬姛!', + }); + } + }); + }, + + /** + * Mqtt鍙戝竷娑堟伅 + * @device 璁惧 + * @model 鐗╂ā鍨�(id/name/type/name/isReadonly/value/shadow)锛宼ype 绫诲瀷(1=灞炴�э紝2=鍔熻兘锛�3=OTA鍗囩骇锛�4=瀹炴椂鐩戞祴) + * */ + // mqttPublish(device, model) { + // let topic = ""; + // let message = "" + // if (model.type == 1) { + // if (device.status == 3) { + // // 灞炴��,鍦ㄧ嚎妯″紡 + // topic = "/" + device.productId + "/" + device.serialNumber + "/property-online/get"; + // } else if (device.isShadow) { + // // 灞炴��,绂荤嚎妯″紡 + // topic = "/" + device.productId + "/" + device.serialNumber + "/property-offline/post"; + // } + // message = '[{"id":"' + model.id + '","value":"' + model.shadow + '"}]'; + // } else if (model.type == 2) { + // if (device.status == 3) { + // // 鍔熻兘,鍦ㄧ嚎妯″紡 + // topic = "/" + device.productId + "/" + device.serialNumber + "/function-online/get"; + // + // } else if (device.isShadow) { + // // 鍔熻兘,绂荤嚎妯″紡 + // topic = "/" + device.productId + "/" + device.serialNumber + "/function-offline/post"; + // } + // message = '[{"id":"' + model.id + '","value":"' + model.shadow + '"}]'; + // } else if (model.type == 3) { + // // OTA鍗囩骇 + // topic = "/" + device.productId + "/" + device.serialNumber + "/ota/get"; + // message = '{"version":' + this.firmware.version + ',"downloadUrl":"' + this.getDownloadUrl(this.firmware.filePath) + '"}'; + // } else { + // return; + // } + // if (topic != "") { + // // 鍙戝竷 + // this.$mqttTool.publish(topic, message, model.name).then(res => { + // this.$modal.notifySuccess(res); + // }).catch(res => { + // this.$modal.notifyError(res); + // }); + // } + // }, + + /** 鏋氫妇绫诲瀷鎸夐挳鍗曞嚮 */ + enumButtonClick(device, model, value) { + model.shadow = value; + this.mqttPublish(device, model); + }, + + /** 鏇存柊璁惧鐘舵�� */ + updateDeviceStatus(device) { + if (device.status == 3) { + this.statusColor.background = '#12d09f'; + this.title = '鍦ㄧ嚎妯″紡'; + } else { + if (device.isShadow == 1) { + this.statusColor.background = '#409EFF'; + this.title = '褰卞瓙妯″紡'; + } else { + this.statusColor.background = '#909399'; + this.title = '绂荤嚎妯″紡'; + this.shadowUnEnable = true; + } + } + this.$emit('statusEvent', this.deviceInfo.status); + }, + /** 鐗╂ā鍨嬫暟缁勫厓绱犲�兼敼鍙樹簨浠� */ + arrayItemChange(value, thingsModel) { + let shadow = ''; + for (let i = 0; i < thingsModel.datatype.arrayCount; i++) { + shadow += thingsModel.datatype.arrayModel[i].shadow + ','; + } + shadow = shadow.substring(0, shadow.length - 1); + thingsModel.shadow = shadow; + }, + /** 鐗╂ā鍨嬩腑鏁扮粍鍊兼敼鍙樹簨浠� */ + arrayInputChange(value, thingsModel) { + let arrayModels = value.split(','); + if (arrayModels.length != thingsModel.datatype.arrayCount) { + this.$modal.alertWarning('鍏冪礌涓暟涓嶅尮閰嶏紝鏁扮粍鍏冪礌涓暟涓�' + thingsModel.datatype.arrayCount + '涓紝浠ヨ嫳鏂囬�楀彿鍒嗛殧銆�'); + } else { + for (let i = 0; i < thingsModel.datatype.arrayCount; i++) { + thingsModel.datatype.arrayModel[i].shadow = arrayModels[i]; + } + } + }, + /**鐢ㄦ埛鏄惁鎷ユ湁鍒嗕韩璁惧鏉冮檺*/ + hasShrarePerm(permission) { + if (this.deviceInfo.isOwner == 0) { + // 鍒嗕韩璁惧鏉冮檺 + if (this.deviceInfo.userPerms.indexOf(permission) == -1) { + return false; + } + } + return true; + }, + /** 璁惧鍗囩骇 */ + otaUpgrade() { + // OTA鍗囩骇 + let topic = '/' + this.deviceInfo.productId + '/' + this.deviceInfo.serialNumber + '/ota/get'; + let message = '{"version":' + this.firmware.version + ',"downloadUrl":"' + this.getDownloadUrl(this.firmware.filePath) + '"}'; + // 鍙戝竷 + this.$mqttTool + .publish(topic, message, '璁惧鍗囩骇') + .then((res) => { + this.$modal.notifySuccess(res); + }) + .catch((res) => { + this.$modal.notifyError(res); + }); + this.openFirmware = false; + }, + /** 鑾峰彇鏈�鏂板浐浠� */ + getLatestFirmware(deviceId) { + getLatestFirmware(deviceId).then((response) => { + this.firmware = response.data; + this.openFirmware = true; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.openFirmware = false; + }, + // 鑾峰彇涓嬭浇璺緞鍓嶇紑 + getDownloadUrl(path) { + return window.location.origin + process.env.VUE_APP_BASE_API + path; + }, + /**鍥捐〃灞曠ず*/ + MonitorChart() { + for (let i = 0; i < this.deviceInfo.chartList.length; i++) { + this.monitorChart[i] = { + chart: this.$echarts.init(this.$refs.map[i]), + data: { + id: this.deviceInfo.chartList[i].id, + name: this.deviceInfo.chartList[i].name, + value: this.deviceInfo.chartList[i].shadow ? this.deviceInfo.chartList[i].shadow : this.deviceInfo.chartList[i].datatype.min, + }, + }; + var option; + option = { + tooltip: { + formatter: ' {b} <br/> {c}' + this.deviceInfo.chartList[i].datatype.unit, + }, + series: [ + { + name: this.deviceInfo.chartList[i].datatype.type, + type: 'gauge', + min: this.deviceInfo.chartList[i].datatype.min, + max: this.deviceInfo.chartList[i].datatype.max, + colorBy: 'data', + splitNumber: 10, + radius: '100%', + // 鍒嗗壊绾� + splitLine: { + distance: 4, + }, + axisLabel: { + fontSize: 10, + distance: 10, + }, + // 鍒诲害绾� + axisTick: { + distance: 4, + }, + // 浠〃鐩樿酱绾� + axisLine: { + lineStyle: { + width: 8, + color: [ + [0.2, '#409EFF'], // 0~20% + [0.8, '#12d09f'], // 40~60% + [1, '#F56C6C'], // 80~100% + ], + opacity: 0.3, + }, + }, + pointer: { + icon: 'triangle', + length: '60%', + width: 7, + }, + progress: { + show: true, + width: 8, + }, + detail: { + valueAnimation: true, + formatter: '{value}' + ' ' + this.deviceInfo.chartList[i].datatype.unit, + offsetCenter: [0, '80%'], + fontSize: 20, + }, + data: [ + { + value: this.deviceInfo.chartList[i].shadow ? this.deviceInfo.chartList[i].shadow : this.deviceInfo.chartList[i].datatype.min, + name: this.deviceInfo.chartList[i].name, + }, + ], + title: { + offsetCenter: [0, '115%'], + fontSize: 16, + }, + }, + ], + }; + option && this.monitorChart[i].chart.setOption(option); + } + }, + }, +}; +</script> + +<style> +/* 閲嶅啓婊戝姩鍧楁牱寮� */ +.el-slider__bar { + height: 18px; +} + +.el-slider__runway { + height: 18px; + margin: 5px 0; +} + +.el-slider__button { + height: 18px; + width: 18px; + border-radius: 10%; +} + +.el-slider__button-wrapper { + top: -9px; +} +</style> diff --git a/src/views/iot/device/user-list.vue b/src/views/iot/device/user-list.vue new file mode 100644 index 0000000..dd91ad0 --- /dev/null +++ b/src/views/iot/device/user-list.vue @@ -0,0 +1,194 @@ +<template> +<el-dialog title="閫夋嫨鐢ㄦ埛" :visible.sync="openSelectUser" width="800px"> + <div style="margin-top:-50px;"> + <el-divider></el-divider> + </div> + <!--鐢ㄦ埛鏁版嵁--> + <el-form :model="queryParams" ref="queryForm" :rules="rules" :inline="true" label-width="80px"> + <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber"> + <el-input type="text" placeholder="璇疯緭鍏ョ敤鎴锋墜鏈哄彿鐮�" v-model="queryParams.phonenumber" minlength="10" clearable size="small" show-word-limit style="width: 240px" @keyup.enter.native="handleQuery"></el-input> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">鏌ヨ</el-button> + </el-form-item> + </el-form> + + <el-table v-loading="loading" :data="userList" highlight-current-row size="mini" @current-change="handleCurrentChange" border> + <el-table-column label="閫夋嫨" width="50" align="center"> + <template slot-scope="scope"> + <input type="radio" :checked="scope.row.isSelect" name="user" /> + </template> + </el-table-column> + <el-table-column label="鐢ㄦ埛缂栧彿" align="center" key="userId" prop="userId" width="120" /> + <el-table-column label="鐢ㄦ埛鍚嶇О" align="center" key="userName" prop="userName" /> + <el-table-column label="鐢ㄦ埛鏄电О" align="center" key="nickName" prop="nickName" /> + <el-table-column label="鎵嬫満鍙风爜" align="center" key="phonenumber" prop="phonenumber" width="120" /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="160"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime) }}</span> + </template> + </el-table-column> + + </el-table> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="addDeviceUser">鍒嗕韩</el-button> + <el-button @click="closeSelectUser">鍏� 闂�</el-button> + </div> +</el-dialog> +</template> + +<script> +import { + listUser +} from "@/api/iot/tool"; +import { + addDeviceUser, + addDeviceUsers, +} from "@/api/iot/deviceuser"; + +export default { + name: "user-list", + props: { + device: { + type: Array, + default: null + } + }, + watch: { + // 鑾峰彇鍒扮埗缁勪欢浼犻�掔殑device + device: function (newVal, oldVal) { + this.deviceInfo = newVal; + } + }, + data() { + return { + // 閬僵灞� + loading: false, + // 閫変腑鏁扮粍 + ids: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鐢ㄦ埛鍒楄〃 + userList: [], + // 閫変腑鐨勭敤鎴� + user: {}, + // 璁惧淇℃伅 + deviceInfo: {}, + // 鏄惁鏄剧ず閫夋嫨鐢ㄦ埛寮瑰嚭灞� + openSelectUser: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + userName: undefined, + phonenumber: undefined, + status: 0, + deptId: undefined + }, + // 琛ㄥ崟鏍¢獙 + rules: { + phonenumber: [{ + required: true, + message: "鎵嬫満鍙风爜涓嶈兘涓虹┖", + trigger: "blur" + }, { + min: 11, + max: 11, + message: '鎵嬫満鍙风爜闀垮害涓�11浣�', + trigger: 'blur' + }], + }, + }; + }, + created() {}, + methods: { + /** 鏌ヨ鐢ㄦ埛鍒楄〃 */ + getList() { + this.loading = true; + listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => { + this.userList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.$refs["queryForm"].validate(valid => { + if (valid) { + this.queryParams.pageNum = 1; + this.getList(); + } + }); + + }, + // 閲嶇疆鏌ヨ + resetQuery() { + this.$refs["queryForm"].resetFields(); + this.userList = []; + }, + //璁剧疆鍗曢�夋寜閽�変腑 + setRadioSelected(userId) { + for (let i = 0; i < this.userList.length; i++) { + if (this.userList[i].userId == userId) { + this.userList[i].isSelect = true; + this.user = this.userList[i]; + } else { + this.userList[i].isSelect = false; + } + } + }, + // 鍗曢�夋暟鎹� + handleCurrentChange(user) { + if (user != null) { + this.setRadioSelected(user.userId); + this.user = user; + } + }, + // 鍏抽棴閫夋嫨鐢ㄦ埛 + closeSelectUser() { + this.openSelectUser = false; + this.resetQuery(); + }, + // 娣诲姞璁惧鐢ㄦ埛 + addDeviceUser() { + if (this.deviceInfo != null && this.deviceInfo.length > 0 && this.user != null) { + if (this.deviceInfo.length == 1) { + var form = {}; + form.deviceId = this.deviceInfo[0].deviceId; + form.deviceName = this.deviceInfo[0].deviceName; + form.userId = this.user.userId; + form.userName = this.user.userName; + form.phonenumber=this.user.phonenumber; + addDeviceUser(form).then(response => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.resetQuery(); + this.openSelectUser = false; + this.$parent.getList(); + }); + } else { + var form = []; + this.deviceInfo.forEach(device => { + let data = {}; + data.deviceId = device.deviceId; + data.deviceName = device.deviceName + data.userId = this.user.userId; + data.userName = this.user.userName; + data.phonenumber=this.user.phonenumber; + form.push(data); + }); + + addDeviceUsers(form).then(response => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.resetQuery(); + this.openSelectUser = false; + this.$parent.getList(); + }); + + } + } else { + this.openSelectUser = false; + } + }, + } +}; +</script> diff --git a/src/views/iot/group/device-list.vue b/src/views/iot/group/device-list.vue new file mode 100644 index 0000000..fc02ca6 --- /dev/null +++ b/src/views/iot/group/device-list.vue @@ -0,0 +1,191 @@ +<template> +<el-dialog title="閫夋嫨璁惧" :visible.sync="openDeviceList" width="800px" append-to-body> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px"> + <el-form-item label="璁惧鍚嶇О" prop="deviceName"> + <el-input v-model="queryParams.deviceName" placeholder="璇疯緭鍏ヨ澶囧悕绉�" clearable size="small" @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-form-item> + </el-form> + + <el-table v-loading="loading" :data="deviceList" @select="handleSelectionChange" @select-all="handleSelectionAll" ref="multipleTable" size="mini" border> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="璁惧鍚嶇О" align="center" prop="deviceName" /> + <el-table-column label="璁惧缂栧彿" align="center" prop="serialNumber" /> + <el-table-column label="浜у搧鍚嶇О" align="center" prop="productName" /> + <el-table-column label="璁惧绫诲瀷" align="center"> + <template slot-scope="scope"> + <el-tag type="success" v-if="scope.row.isOwner==0">鍒嗕韩</el-tag> + <el-tag type="primary" v-else>鎷ユ湁</el-tag> + </template> + </el-table-column> + <el-table-column label="璁惧鐘舵��" align="center" prop="status"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_device_status" :value="scope.row.status" /> + </template> + </el-table-column> + </el-table> + <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" /> + + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="handleDeviceSelected">纭� 瀹�</el-button> + <el-button @click="closeSelectDeviceList">鍙� 娑�</el-button> + </div> +</el-dialog> +</template> + +<script> +import { + getDeviceIds, + updateDeviceGroups +} from "@/api/iot/group" +import { + listDeviceByGroup, +} from "@/api/iot/device"; + +export default { + name: "device-list", + dicts: ['iot_device_status'], + props: { + group: { + type: Object, + default: null + } + }, + data() { + return { + // 璁惧鍒嗙粍 + deviceGroup: {}, + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 鏄惁鏄剧ず璁惧鍒楄〃 + openDeviceList: false, + // 鎬绘潯鏁� + total: 0, + // 璁惧琛ㄦ牸鏁版嵁 + deviceList: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + deviceName: null, + productId: null, + productName: null, + userId: null, + userName: null, + tenantId: null, + tenantName: null, + serialNumber: null, + status: null, + networkAddress: null, + activeTime: null, + }, + }; + }, + watch: { + // 鑾峰彇鍒扮埗缁勪欢浼犻�掔殑group鍚庯紝鍒锋柊鍒楄〃 + group: { + handler(newVal, oldVal) { + if (newVal.groupId) { + this.deviceGroup = newVal; + // 鑾峰彇鍒嗙粍涓嬬殑璁惧 + this.queryParams.userId = this.deviceGroup.userId; + this.queryParams.pageNum = 1; + this.getDeviceIdsByGroupId(this.deviceGroup.groupId); + } + }, + immediate: true + } + }, + created() { + + }, + methods: { + // 鑾峰彇鍒嗙粍涓嬪叧鑱旂殑璁惧ID鏁扮粍 + getDeviceIdsByGroupId(groupId) { + getDeviceIds(groupId).then(response => { + this.ids = response.data; + this.getList(); + }); + }, + /** 鏌ヨ璁惧鍒楄〃 */ + getList() { + this.loading = true; + this.queryParams.params = {}; + if (null != this.daterangeActiveTime && '' != this.daterangeActiveTime) { + this.queryParams.params["beginActiveTime"] = this.daterangeActiveTime[0]; + this.queryParams.params["endActiveTime"] = this.daterangeActiveTime[1]; + } + listDeviceByGroup(this.queryParams).then(response => { + this.deviceList = response.rows; + this.total = response.total; + this.loading = false; + // 璁剧疆鍒嗙粍鍏宠仈鐨勮澶囬�変腑 + this.deviceList.forEach(row => { + this.$nextTick(() => { + if (this.ids.some(x => x === row.deviceId)) { + this.$refs.multipleTable.toggleRowSelection(row, true); + } + }) + }); + }); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.daterangeActiveTime = []; + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection, row) { + // 璁惧ID鏄惁瀛樺湪浜庡師濮嬭澶嘔D鏁扮粍涓� + let index = this.ids.indexOf(row.deviceId); + // 鏄惁閫変腑 + let value = selection.indexOf(row); + if (index == -1 && value != -1) { + // 涓嶅瓨鍦ㄤ笖閫変腑 + this.ids.push(row.deviceId); + } else if (index != -1 && value == -1) { + // 瀛樺湪涓斿彇娑堥�変腑 + this.ids.splice(index, 1); + } + }, + // 鍏ㄩ�変簨浠跺鐞� + handleSelectionAll(selection) { + for (let i = 0; i < this.deviceList.length; i++) { + // 璁惧ID鏄惁瀛樺湪浜庡師濮嬭澶嘔D鏁扮粍涓� + let index = this.ids.indexOf(this.deviceList[i].deviceId); + // 鏄惁閫変腑 + let value = selection.indexOf(this.deviceList[i]); + if (index == -1 && value != -1) { + // 涓嶅瓨鍦ㄤ笖閫変腑 + this.ids.push(this.deviceList[i].deviceId); + } else if (index != -1 && value == -1) { + // 瀛樺湪涓斿彇娑堥�変腑 + this.ids.splice(index, 1); + } + } + }, + // 鍏抽棴閫夋嫨璁惧鍒楄〃 + closeSelectDeviceList() { + this.openDeviceList = false; + }, + // 鏇存柊鍒嗙粍涓嬬殑璁惧 + handleDeviceSelected() { + this.group.deviceIds = this.ids; + updateDeviceGroups(this.group).then(response => { + this.$modal.msgSuccess("鏇存柊鍒嗙粍涓嬬殑璁惧鎴愬姛"); + this.openDeviceList = false; + }) + } + } +}; +</script> diff --git a/src/views/iot/group/index.vue b/src/views/iot/group/index.vue new file mode 100644 index 0000000..b284e1a --- /dev/null +++ b/src/views/iot/group/index.vue @@ -0,0 +1,289 @@ +<template> + <div style="padding: 6px"> + <el-card v-show="showSearch" style="margin-bottom: 6px"> + <el-form ref="queryForm" :model="queryParams" :inline="true" label-width="68px" style="margin-bottom: -20px"> + <el-form-item label="鍒嗙粍鍚嶇О" prop="groupName"> + <el-input v-model="queryParams.groupName" placeholder="璇疯緭鍏ュ垎缁勫悕绉�" clearable size="small" + @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item v-if="isAdmin" label="鎴戠殑鍒嗙粍" style="margin: 0 20px"> + <el-switch v-model="myGroup" @change="myGroupChange"></el-switch> + </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-item style="float: right"> + <el-button v-hasPermi="['iot:group:add']" type="primary" plain icon="el-icon-plus" size="mini" + @click="handleAdd">鏂板</el-button> + </el-form-item> + </el-form> + </el-card> + + <el-card style="padding-bottom: 100px"> + <el-table v-loading="loading" :data="groupList" border @selection-change="handleSelectionChange"> + <el-table-column label="鍒嗙粍鍚嶇О" align="center" prop="groupName" width="200" /> + <el-table-column label="鍒嗙粍鎺掑簭" align="center" prop="groupOrder" width="100" /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> + </template> + </el-table-column> + <el-table-column v-if="isAdmin" label="鎵�灞炵敤鎴�" align="center" prop="userName" width="100" /> + <el-table-column label="澶囨敞" align="left" header-align="center" prop="remark" /> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width" width="320"> + <template slot-scope="scope"> + <el-button v-hasPermi="['iot:device:query']" size="small" type="warning" style="padding: 5px" + icon="el-icon-search" @click="handleViewDevice(scope.row.groupId)">鏌ョ湅璁惧</el-button> + <el-button v-hasPermi="['iot:group:add']" size="small" type="success" style="padding: 5px" icon="el-icon-edit" + @click="selectDevice(scope.row)">娣诲姞璁惧</el-button> + <el-button v-hasPermi="['iot:group:edit']" size="small" type="primary" style="padding: 5px" + icon="el-icon-edit" @click="handleUpdate(scope.row)">淇敼</el-button> + <el-button v-hasPermi="['iot:group:remove']" size="small" type="danger" style="padding: 5px" + icon="el-icon-delete" @click="handleDelete(scope.row)">鍒犻櫎</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" /> + + <!-- 鍒嗙粍璁惧鍒楄〃 --> + <deviceList ref="groupDeviceList" :group="group"></deviceList> + + <!-- 娣诲姞鎴栦慨鏀硅澶囧垎缁勫璇濇 --> + <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="groupName"> + <el-input v-model="form.groupName" placeholder="璇疯緭鍏ュ垎缁勫悕绉�" /> + </el-form-item> + <el-form-item label="鍒嗙粍鎺掑簭" prop="groupOrder"> + <el-input v-model="form.groupOrder" type="number" placeholder="璇疯緭鍏ュ垎缁勬帓搴�" /> + </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> + </el-card> + </div> +</template> + +<script> +import deviceList from './device-list' +import { listGroup, getGroup, delGroup, addGroup, updateGroup } from '@/api/iot/group' +import {getUserId} from "@/utils/auth"; + +export default { + name: 'Group', + components: { + deviceList, + }, + data() { + return { + // 鏄惁绠$悊鍛� + isAdmin: false, + // 鎴戠殑鍒嗙粍 + myGroup: false, + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 璁惧鍒嗙粍琛ㄦ牸鏁版嵁 + groupList: [], + // 寮瑰嚭灞傛爣棰� + title: '', + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + groupName: null, + userId: null, + }, + // 璁惧鍒嗙粍 + group: {}, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + groupName: [ + { + required: true, + message: '鍒嗙粍鍚嶇О涓嶈兘涓虹┖', + trigger: 'blur', + }, + { + min: 1, + max: 64, + message: '鍒嗙粍鍚嶇О涓嶈兘灏戜簬1涓瓧绗﹀拰瓒呰繃64瀛楃', + }, + ], + groupOrder: [ + { + required: true, + message: '鍒嗙粍鎺掑簭涓嶈兘涓虹┖,鏈�澶у�间负99', + trigger: 'blur', + }, + { + max: 128, + message: '鍒嗙粍鎺掑簭涓嶈兘灏戜簬1涓綅鍜岃秴杩�10浣�', + trigger: 'blur', + }, + ], + }, + } + }, + created() { + this.getList() + this.init() + }, + methods: { + init() { + if (this.$store.state.user.roles.indexOf('tenant') === -1 && this.$store.state.user.roles.indexOf('general') === -1) { + this.isAdmin = true + } + }, + // 鎴戠殑鍒嗙粍鏀瑰彉浜嬩欢 + myGroupChange() { + this.queryParams.userId = this.myGroup ? getUserId() : null; + this.handleQuery(); + }, + /** 鏌ョ湅璁惧鎸夐挳鎿嶄綔 */ + handleViewDevice(groupId) { + this.$router.push({ + path: '/iot/device', + query: { + t: Date.now(), + groupId: groupId, + }, + }) + }, + /** 鏌ヨ璁惧鍒嗙粍鍒楄〃 */ + getList() { + this.loading = true + listGroup(this.queryParams).then((response) => { + this.groupList = response.rows + this.total = response.total + this.loading = false + }) + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false + this.reset() + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + groupId: null, + groupName: null, + groupOrder: null, + userId: null, + userName: null, + delFlag: null, + createBy: null, + createTime: null, + updateBy: null, + updateTime: null, + remark: 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.groupId) + this.single = selection.length !== 1 + this.multiple = !selection.length + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset() + this.open = true + this.title = '娣诲姞璁惧鍒嗙粍' + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset() + const groupId = row.groupId || this.ids + getGroup(groupId).then((response) => { + this.form = response.data + this.open = true + this.title = '淇敼璁惧鍒嗙粍' + }) + }, + /** 閫夋嫨璁惧 */ + selectDevice(row) { + this.group = row + // 鍒锋柊瀛愮粍浠� + this.$refs.groupDeviceList.openDeviceList = true + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + this.$refs['form'].validate((valid) => { + if (valid) { + if (this.form.groupId != null) { + updateGroup(this.form).then((response) => { + this.$modal.msgSuccess('淇敼鎴愬姛') + this.open = false + this.getList() + }) + } else { + addGroup(this.form).then((response) => { + this.$modal.msgSuccess('鏂板鎴愬姛') + this.open = false + this.getList() + }) + } + } + }) + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const groupIds = row.groupId || this.ids + this.$modal + .confirm('鏄惁纭鍒犻櫎璁惧鍒嗙粍缂栧彿涓�"' + groupIds + '"鐨勬暟鎹」锛�') + .then(function () { + return delGroup(groupIds) + }) + .then(() => { + this.getList() + this.$modal.msgSuccess('鍒犻櫎鎴愬姛') + }) + .catch(() => { }) + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download( + 'iot/group/export', + { + ...this.queryParams, + }, + `group_${new Date().getTime()}.xlsx` + ) + }, + }, +} +</script> diff --git a/src/views/iot/log/index.vue b/src/views/iot/log/index.vue new file mode 100644 index 0000000..f94bf07 --- /dev/null +++ b/src/views/iot/log/index.vue @@ -0,0 +1,391 @@ +<template> +<div style="padding:6px;"> + <el-card v-show="showSearch" style="margin-bottom:6px;"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom:-20px;"> + <el-form-item label="鏃ュ織鍚嶇О" prop="logName"> + <el-input v-model="queryParams.logName" placeholder="璇疯緭鍏ユ棩蹇楀悕绉�" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="绫诲瀷" prop="logType"> + <el-select v-model="queryParams.logType" placeholder="璇烽�夋嫨绫诲瀷" clearable size="small"> + <el-option v-for="dict in dict.type.iot_things_type" :key="dict.value" :label="dict.label" :value="dict.value" /> + </el-select> + </el-form-item> + <el-form-item label="鏃ュ織绾у埆" prop="logLevel"> + <el-input v-model="queryParams.logLevel" placeholder="璇疯緭鍏ユ棩蹇楃骇鍒�" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="璁惧ID" prop="deviceId"> + <el-input v-model="queryParams.deviceId" placeholder="璇疯緭鍏ヨ澶嘔D" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="璁惧鍚嶇О" prop="deviceName"> + <el-input v-model="queryParams.deviceName" placeholder="璇疯緭鍏ヨ澶囧悕绉�" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="鐢ㄦ埛鏄电О" prop="userName"> + <el-input v-model="queryParams.userName" placeholder="璇疯緭鍏ョ敤鎴锋樀绉�" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="绉熸埛鍚嶇О" prop="tenantName"> + <el-input v-model="queryParams.tenantName" placeholder="璇疯緭鍏ョ鎴峰悕绉�" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="鐢熸垚鍛婅" prop="isAlert"> + <el-input v-model="queryParams.isAlert" placeholder="璇疯緭鍏ユ槸鍚︾敓鎴愬憡璀�" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="鍛婅澶勭悊" prop="status"> + <el-select v-model="queryParams.status" placeholder="璇烽�夋嫨鍛婅澶勭悊" clearable size="small"> + <el-option v-for="dict in dict.type.iot_yes_no" :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-card> + + <el-card style="padding-bottom:100px;"> + <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="['iot:log: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="['iot:log: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="['iot:log: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="['iot:log:export']">瀵煎嚭</el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <el-table v-loading="loading" :data="logList" @selection-change="handleSelectionChange" border> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="鏃ュ織鍚嶇О" align="center" prop="logName" /> + <el-table-column label="鍊�" align="center" prop="logValue" /> + <el-table-column label="绫诲瀷" align="center" prop="logType"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_things_type" :value="scope.row.logType" /> + </template> + </el-table-column> + <el-table-column label="鏃ュ織绾у埆" align="center" prop="logLevel"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.logLevel" /> + </template> + </el-table-column> + <el-table-column label="璁惧ID" align="center" prop="deviceId" /> + <el-table-column label="璁惧鍚嶇О" align="center" prop="deviceName" /> + <el-table-column label="鐢ㄦ埛ID" align="center" prop="userId" /> + <el-table-column label="鐢ㄦ埛鏄电О" align="center" prop="userName" /> + <el-table-column label="绉熸埛ID" align="center" prop="tenantId" /> + <el-table-column label="绉熸埛鍚嶇О" align="center" prop="tenantName" /> + <el-table-column label="瑙﹀彂婧�" align="center" prop="triggerSource"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.triggerSource" /> + </template> + </el-table-column> + <el-table-column label="鐢熸垚鍛婅" align="center" prop="isAlert"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isAlert" /> + </template> + </el-table-column> + <el-table-column label="鍛婅澶勭悊" align="center" prop="status"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :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, '{y}-{m}-{d}') }}</span> + </template> + </el-table-column> + <el-table-column label="澶囨敞" align="center" prop="remark" /> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width" width="150"> + <template slot-scope="scope"> + <el-button size="small" type="primary" style="padding:5px;" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['iot:log:edit']">澶勭悊</el-button> + <!-- <el-button size="small" type="danger" style="padding:5px;" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['iot:log: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="logName"> + <el-input v-model="form.logName" placeholder="璇疯緭鍏ユ棩蹇楀悕绉�" /> + </el-form-item> + <el-form-item label="绫诲瀷" prop="logType"> + <el-select v-model="form.logType" placeholder="璇烽�夋嫨绫诲瀷"> + <el-option v-for="dict in dict.type.iot_things_type" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)"></el-option> + </el-select> + </el-form-item> + <el-form-item label="鏃ュ織绾у埆" prop="logLevel"> + <el-input v-model="form.logLevel" placeholder="璇疯緭鍏ユ棩蹇楃骇鍒�" /> + </el-form-item> + <el-form-item label="璁惧ID" prop="deviceId"> + <el-input v-model="form.deviceId" placeholder="璇疯緭鍏ヨ澶嘔D" /> + </el-form-item> + <el-form-item label="璁惧鍚嶇О" prop="deviceName"> + <el-input v-model="form.deviceName" placeholder="璇疯緭鍏ヨ澶囧悕绉�" /> + </el-form-item> + <el-form-item label="鐢ㄦ埛ID" prop="userId"> + <el-input v-model="form.userId" placeholder="璇疯緭鍏ョ敤鎴稩D" /> + </el-form-item> + <el-form-item label="鐢ㄦ埛鏄电О" prop="userName"> + <el-input v-model="form.userName" placeholder="璇疯緭鍏ョ敤鎴锋樀绉�" /> + </el-form-item> + <el-form-item label="绉熸埛ID" prop="tenantId"> + <el-input v-model="form.tenantId" placeholder="璇疯緭鍏ョ鎴稩D" /> + </el-form-item> + <el-form-item label="绉熸埛鍚嶇О" prop="tenantName"> + <el-input v-model="form.tenantName" placeholder="璇疯緭鍏ョ鎴峰悕绉�" /> + </el-form-item> + <el-form-item label="瑙﹀彂婧�" prop="triggerSource"> + <el-input v-model="form.triggerSource" placeholder="璇疯緭鍏ヨЕ鍙戞簮" /> + </el-form-item> + <el-form-item label="鏄惁鐢熸垚鍛婅" prop="isAlert"> + <el-input v-model="form.isAlert" placeholder="璇疯緭鍏ユ槸鍚︾敓鎴愬憡璀�" /> + </el-form-item> + <el-form-item label="鍛婅澶勭悊"> + <el-radio-group v-model="form.status"> + <el-radio v-for="dict in dict.type.iot_yes_no" :key="dict.value" :label="parseInt(dict.value)">{{dict.label}}</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="澶囨敞" prop="remark"> + <el-input v-model="form.remark" placeholder="璇疯緭鍏ュ娉�" /> + </el-form-item> + <el-form-item label="鏃ュ織鏀跺埌鐨勫��" prop="logValue"> + <el-input v-model="form.logValue" placeholder="璇疯緭鍏ユ棩蹇楁敹鍒扮殑鍊�" /> + </el-form-item> + <el-form-item label="鏄惁缃《" prop="istop"> + <el-input v-model="form.istop" placeholder="璇疯緭鍏ユ槸鍚︾疆椤�" /> + </el-form-item> + <el-form-item label="鏄惁鐩戞祴" prop="ismonitor"> + <el-input v-model="form.ismonitor" 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> + + </el-card> +</div> +</template> + +<script> +import { + listLog, + getLog, + delLog, + addLog, + updateLog +} from "@/api/iot/log"; + +export default { + name: "Log", + dicts: ['iot_things_type', 'iot_yes_no'], + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 璁惧鏃ュ織琛ㄦ牸鏁版嵁 + logList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + logName: null, + logType: null, + logLevel: null, + deviceId: null, + deviceName: null, + userName: null, + tenantName: null, + triggerSource: null, + isAlert: null, + status: null, + istop: null, + ismonitor: null + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + logName: [{ + required: true, + message: "鏃ュ織鍚嶇О涓嶈兘涓虹┖", + trigger: "blur" + }], + logType: [{ + required: true, + message: "绫诲瀷涓嶈兘涓虹┖", + trigger: "change" + }], + logLevel: [{ + required: true, + message: "鏃ュ織绾у埆涓嶈兘涓虹┖", + trigger: "blur" + }], + deviceId: [{ + required: true, + message: "璁惧ID涓嶈兘涓虹┖", + trigger: "blur" + }], + deviceName: [{ + required: true, + message: "璁惧鍚嶇О涓嶈兘涓虹┖", + trigger: "blur" + }], + userId: [{ + required: true, + message: "鐢ㄦ埛ID涓嶈兘涓虹┖", + trigger: "blur" + }], + userName: [{ + required: true, + message: "鐢ㄦ埛鏄电О涓嶈兘涓虹┖", + trigger: "blur" + }], + tenantId: [{ + required: true, + message: "绉熸埛ID涓嶈兘涓虹┖", + trigger: "blur" + }], + tenantName: [{ + required: true, + message: "绉熸埛鍚嶇О涓嶈兘涓虹┖", + trigger: "blur" + }], + } + }; + }, + created() { + this.getList(); + }, + methods: { + /** 鏌ヨ璁惧鏃ュ織鍒楄〃 */ + getList() { + this.loading = true; + listLog(this.queryParams).then(response => { + this.logList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + deviceLogId: null, + logName: null, + logType: null, + logLevel: null, + deviceId: null, + deviceName: null, + userId: null, + userName: null, + tenantId: null, + tenantName: null, + triggerSource: null, + isAlert: null, + status: 0, + createBy: null, + createTime: null, + remark: null, + logValue: null, + istop: null, + ismonitor: 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.deviceLogId) + this.single = selection.length !== 1 + this.multiple = !selection.length + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞璁惧鏃ュ織"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const deviceLogId = row.deviceLogId || this.ids + getLog(deviceLogId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼璁惧鏃ュ織"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.deviceLogId != null) { + updateLog(this.form).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + }); + } else { + addLog(this.form).then(response => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const deviceLogIds = row.deviceLogId || this.ids; + this.$modal.confirm('鏄惁纭鍒犻櫎璁惧鏃ュ織缂栧彿涓�"' + deviceLogIds + '"鐨勬暟鎹」锛�').then(function () { + return delLog(deviceLogIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(() => {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download('iot/log/export', { + ...this.queryParams + }, `log_${new Date().getTime()}.xlsx`) + } + } +}; +</script> diff --git a/src/views/iot/netty/clients.vue b/src/views/iot/netty/clients.vue new file mode 100644 index 0000000..0e1cdc5 --- /dev/null +++ b/src/views/iot/netty/clients.vue @@ -0,0 +1,324 @@ +<template> + <div style="padding: 6px"> + <el-card v-show="showSearch" style="margin-bottom: 6px"> + <el-form @submit.native.prevent :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom: -20px"> + <el-form-item label="瀹㈡埛绔�" prop="clientId"> + <el-input v-model="queryParams.clientId" placeholder="璇疯緭鍏ュ鎴风ID" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item prop="isClient"> + <el-checkbox v-model="queryParams.isClient" true-label="1" false-label="0">鍙湅璁惧绔�</el-checkbox> + </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-card> + + <el-tabs type="border-card" v-model="serverType" @tab-click="handleClick" style="flex: 1; height: 800px; margin-bottom: 5px"> + <el-tab-pane label="MQTT瀹㈡埛绔�" name="MQTT"> + <el-table v-loading="loading" :data="clientList"> + <el-table-column label="瀹㈡埛绔疘D" align="left" header-align="center" prop="clientId"> + <template slot-scope="scope"> + <el-link :underline="false" type="primary" @click.native="handleOpen(scope.row)">{{ scope.row.clientId }}</el-link> + </template> + </el-table-column> + <el-table-column label="绫诲瀷" align="center" prop="type"> + <template slot-scope="scope"> + <el-tag type="danger" v-if="scope.row.clientId.indexOf('server') == 0">鏈嶅姟绔�</el-tag> + <el-tag type="success" v-else-if="scope.row.clientId.indexOf('web') == 0">Web绔�</el-tag> + <el-tag type="warning" v-else-if="scope.row.clientId.indexOf('phone') == 0">绉诲姩绔�</el-tag> + <el-tag type="info" v-else-if="scope.row.clientId.indexOf('test') == 0">娴嬭瘯绔�</el-tag> + <el-tag type="primary" v-else>璁惧绔�</el-tag> + </template> + </el-table-column> + <el-table-column label="杩炴帴鐘舵��" align="center" prop="connected"> + <template slot-scope="scope"> + <el-tag type="success" v-if="scope.row.connected">宸茶繛鎺�</el-tag> + <el-tag type="info" v-else>宸叉柇寮�</el-tag> + </template> + </el-table-column> + <el-table-column label="蹇冭烦(绉�)" align="center" prop="keepAlive" width="100" /> + <el-table-column label="璐﹀彿" align="center" prop="username" width="100px" /> + <el-table-column label="褰撳墠璁㈤槄鏁伴噺" align="center" prop="topicCount" width="100" /> + <el-table-column label="杩炴帴鏃堕棿" align="center" prop="connected_at" /> + + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template #default="scope"> + <el-button link type="primary" icon="Edit" @click="clickClientOut(scope.row)">韪㈠嚭</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" /> + + <!-- MQTT瀹㈡埛绔缁� --> + <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body> + <el-tabs v-model="activeName" tab-position="top" style="padding: 10px"> + <el-tab-pane name="subscribe"> + <span slot="label">璁㈤槄鍒楄〃</span> + <el-row :gutter="10" class="mb8"></el-row> + <el-table :data="subscribeList" size="mini"> + <el-table-column label="涓婚" align="center" prop="topicName" /> + <el-table-column label="QoS" align="center" prop="qos" /> + </el-table> + </el-tab-pane> + </el-tabs> + </el-dialog> + </el-tab-pane> + <el-tab-pane label="TCP瀹㈡埛绔�" name="TCP"> + <el-table v-loading="loading" :data="clientList"> + <el-table-column label="瀹㈡埛绔疘D" align="left" header-align="center" prop="clientId"></el-table-column> + <el-table-column label="绫诲瀷" align="center" prop="type"> + <template slot-scope="scope"> + <el-tag type="danger" v-if="scope.row.clientId.indexOf('server') == 0">鏈嶅姟绔�</el-tag> + <el-tag type="success" v-else-if="scope.row.clientId.indexOf('web') == 0">Web绔�</el-tag> + <el-tag type="warning" v-else-if="scope.row.clientId.indexOf('phone') == 0">绉诲姩绔�</el-tag> + <el-tag type="info" v-else-if="scope.row.clientId.indexOf('test') == 0">娴嬭瘯绔�</el-tag> + <el-tag type="primary" v-else>璁惧绔�</el-tag> + </template> + </el-table-column> + <el-table-column label="杩炴帴鐘舵��" align="center" prop="connected"> + <template slot-scope="scope"> + <el-tag type="success" v-if="scope.row.connected">宸茶繛鎺�</el-tag> + <el-tag type="info" v-else>宸叉柇寮�</el-tag> + </template> + </el-table-column> + <el-table-column label="蹇冭烦(绉�)" align="center" prop="keepAlive" width="100" /> + <el-table-column label="杩炴帴鏃堕棿" align="center" prop="connected_at" /> + + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template #default="scope"> + <el-button link type="primary" icon="Edit" @click="clickClientOut(scope.row)">韪㈠嚭</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" /> + + <!-- MQTT瀹㈡埛绔缁� --> + <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body> + <el-tabs v-model="activeName" tab-position="top" style="padding: 10px"> + <el-tab-pane name="subscribe"> + <span slot="label">璁㈤槄鍒楄〃</span> + <el-row :gutter="10" class="mb8"></el-row> + <el-table :data="subscribeList" size="mini"> + <el-table-column label="涓婚" align="center" prop="topicName" /> + <el-table-column label="QoS" align="center" prop="qos" /> + </el-table> + </el-tab-pane> + </el-tabs> + </el-dialog> + </el-tab-pane> + </el-tabs> + + <!-- 娣诲姞鎴栦慨鏀硅闃呭璇濇 --> + <el-dialog title="娣诲姞璁㈤槄" :visible.sync="subscribeOpen" width="800px" append-to-body> + <el-form ref="subscribeForm" :model="subscribeForm" :rules="rules" label-width="60px"> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="涓婚" prop="topic"> + <el-input v-model="subscribeForm.topic" placeholder="璇疯緭鍏ヤ富棰�" /> + </el-form-item> + <el-form-item label="Qos" prop="qos"> + <el-select v-model="subscribeForm.qos" placeholder="璇烽�夋嫨娑堟伅绫诲瀷"> + <el-option key="0" label="0" value="0"></el-option> + <el-option key="1" label="1" value="1"></el-option> + <el-option key="2" label="2" value="2"></el-option> + </el-select> + </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="cancelSubscribe">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { clientOut, listNettyMqttClient } from '@/api/iot/netty'; + +export default { + name: 'Category', + data() { + return { + // 闈炲崟涓鐢� + single: true, + // 閬僵灞� + loading: true, + loadSubscribeing: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 浜у搧鍒嗙被琛ㄦ牸鏁版嵁 + clientList: [], + // 寮瑰嚭灞傛爣棰� + title: '', + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏄惁鏄剧ず娣诲姞璁㈤槄寮瑰嚭灞� + subscribeOpen: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + clientId: null, + isClient: 0, + serverCode: 'MQTT', + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 閫変腑閫夐」鍗� + activeName: 'subscribe', + //璁㈤槄鍒楄〃鏁版嵁 + subscribeList: [], + //璁㈤槄鏁版嵁 + subscribe: { + topic: '', + clientId: '', + }, + //娣诲姞璁㈤槄琛ㄥ崟鍙傛暟 + subscribeForm: { + qos: '0', + }, + //瀹㈡埛绔疘D + clientId: '', + //鏈嶅姟鍗忚绫诲瀷 + serverType: 'MQTT', + // 琛ㄥ崟鏍¢獙 + rules: { + topic: [ + { + required: true, + message: '涓婚涓嶈兘涓虹┖', + trigger: 'blur', + }, + ], + }, + }; + }, + created() { + this.getList(); + }, + methods: { + /** 鏌ヨ瀹㈡埛绔垪琛� */ + getList() { + this.loading = true; + listNettyMqttClient(this.queryParams).then((response) => { + this.clientList = response.data; + this.total = response.total; + this.loading = false; + }); + }, + + /*灏嗗鎴风韪㈠嚭*/ + clickClientOut(row) { + const params = { clientId: row.clientId }; + clientOut(params).then((res) => { + //鍒锋柊鍒楄〃 + this.getList(); + }); + }, + + /*tabs鍒囨崲*/ + handleClick() { + this.queryParams.serverCode = this.serverType; + this.getList(); + }, + + /** 鏌ヨ瀹㈡埛绔闃呭垪琛� */ + getSubscribeList(clientId) { + this.clientId = clientId; + this.loadSubscribeing = true; + getSubscriptionsByClientId(clientId).then((res) => { + this.subscribeList = res.data.data; + this.loadSubscribeing = false; + }); + }, + + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm('queryForm'); + this.handleQuery(); + }, + /** 鏂紑瀹㈡埛绔繛鎺� */ + handleDelete(row) { + const clientId = row.clientId; + this.$modal + .confirm('鏄惁纭鍒犻櫎MQTT瀹㈡埛绔紪鍙蜂负"' + clientId + '"鐨勬暟鎹」锛�') + .then(function () { + return eliminateClient(clientId); + }) + .then(() => { + this.getList(); + this.$modal.msgSuccess('鍒犻櫎鎴愬姛'); + }) + .catch(() => {}); + }, + //鍙栨秷涓婚璁㈤槄 + handleUnsubscribe(row) { + const clientId = row.clientId; + const topic = row.topic; + this.$modal + .confirm('鏄惁纭鍙栨秷璁㈤槄涓婚涓�"' + topic + '"鐨勬暟鎹」锛�') + .then(function () { + const param = {}; + param.topic = topic; + param.clientId = clientId; + return unsubscribe(param); + }) + .then(() => { + this.getSubscribeList(clientId); + this.$modal.msgSuccess('鍙栨秷璁㈤槄鎴愬姛'); + }) + .catch(() => {}); + }, + //鏌ョ湅瀹㈡埛绔鎯� + handleOpen(row) { + this.open = true; + this.title = '璇︽儏'; + this.subscribeList = row.topics; + console.log(this.subscribeList); + }, + + //娣诲姞璁㈤槄 + handleAdd() { + this.subscribeOpen = true; + }, + //鎻愪氦娣诲姞璁㈤槄琛ㄥ崟 + submitForm() { + this.subscribeForm.clientId = this.clientId; + console.log(this.subscribeForm); + this.$refs['subscribeForm'].validate((valid) => { + if (valid) { + addSubscribe(this.subscribeForm).then((response) => { + this.$modal.msgSuccess('鏂板璁㈤槄鎴愬姛'); + this.subscribeOpen = false; + this.getSubscribeList(this.clientId); + }); + } + }); + }, + cancelSubscribe() { + this.subscribeOpen = false; + this.resetForm('subscribeForm'); + //鍒锋柊鍒楄〃 + this.getSubscribeList(this.clientId); + }, + }, +}; +</script> diff --git a/src/views/iot/netty/mqtt.vue b/src/views/iot/netty/mqtt.vue new file mode 100644 index 0000000..095e809 --- /dev/null +++ b/src/views/iot/netty/mqtt.vue @@ -0,0 +1,346 @@ +<template> + <div style="padding: 6px"> + <el-card style="margin-bottom: 6px"> + <el-row :gutter="120"> + <el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="8"> + <h3 style="font-weight: bold">Mqtt 缁熻鎸囨爣</h3> + <el-row :gutter="20" class="panel-group"> + <el-col :span="24" class="card-panel-col" style="margin-bottom: 17px"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-orange"> + <svg-icon icon-class="guide" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div> + <div class="card-panel-text">鍙戦�佹秷鎭�</div> + <count-to :start-val="0" :end-val="this.static['send_total']" :duration="3000" class="card-panel-num" /> + </div> + </div> + </div> + </el-col> + <el-col :span="24" class="card-panel-col" style="margin-bottom: 18px"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-green"> + <svg-icon icon-class="receiver" class-name="card-panel-icon" /> + </div> + + <div class="card-panel-description"> + <div> + <div class="card-panel-text">鎺ユ敹娑堟伅</div> + <count-to :start-val="0" :end-val="this.static['receive_total']" :duration="3000" class="card-panel-num" /> + </div> + </div> + </div> + </el-col> + <el-col :span="24" class="card-panel-col" style="margin-bottom: 17px"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-orange"> + <svg-icon icon-class="authenticate" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text">璁よ瘉娆℃暟</div> + <count-to :start-val="0" :end-val="this.static['auth_total']" :duration="1000" class="card-panel-num" /> + </div> + </div> + </el-col> + <el-col :span="24" class="card-panel-col" style="margin-bottom: 18px"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-green"> + <svg-icon icon-class="connect" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text">杩炴帴娆℃暟</div> + <count-to :start-val="0" :end-val="this.static['connect_total']" :duration="1000" class="card-panel-num" /> + </div> + </div> + </el-col> + <el-col :span="24" class="card-panel-col" style="margin-bottom: 17px"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-orange"> + <svg-icon icon-class="subscribe1" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text">璁㈤槄娆℃暟</div> + <count-to :start-val="0" :end-val="this.static['subscribe_total']" :duration="2000" class="card-panel-num" /> + </div> + </div> + </el-col> + + <el-col :span="24" class="card-panel-col" style="margin-bottom: 17px"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-green"> + <svg-icon icon-class="message" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div> + <div class="card-panel-text">浠婃棩鎺ユ敹</div> + <count-to :start-val="0" :end-val="this.static['today_received']" :duration="3000" class="card-panel-num" /> + </div> + </div> + </div> + </el-col> + <el-col :span="24" class="card-panel-col" style="margin-bottom: 17px"> + <div class="card-panel"> + <div class="card-panel-icon-wrapper icon-orange"> + <svg-icon icon-class="subscribe1" class-name="card-panel-icon" /> + </div> + <div class="card-panel-description"> + <div class="card-panel-text">浠婃棩鍙戦��</div> + <count-to :start-val="0" :end-val="this.static['today_send']" :duration="2000" class="card-panel-num" /> + </div> + </div> + </el-col> + </el-row> + </el-col> + + <el-col :xs="24" :sm="24" :md="24" :lg="15" :xl="15"> + <div style="padding: 30px 0 85px"> + <div ref="pieTotal" style="height: 230px"></div> + </div> + <div ref="statsChart" style="height: 275px; margin: 20px 0 40px 0"></div> + </el-col> + </el-row> + </el-card> + </div> +</template> + +<script> +import { getNettyMqttStats, statisticNettyMqtt } from '@/api/iot/netty'; +import CountTo from 'vue-count-to'; + +export default { + name: 'Mqtt', + components: { + CountTo, + }, + data() { + return { + // mqtt鐘舵�佹暟鎹� + stats: {}, + // mqtt缁熻淇℃伅 + static: {}, + }; + }, + created() { + this.getMqttStats(); + this.statisticMqtt(); + }, + methods: { + /** 鏌ヨmqtt缁熻*/ + statisticMqtt() { + statisticNettyMqtt().then((response) => { + this.static = response.data; + this.totalMqtt(); + }); + }, + /** 鏌ヨmqtt鐘舵�佹暟鎹�*/ + getMqttStats() { + getNettyMqttStats().then((response) => { + this.stats = response.data; + this.drawStats(); + }); + }, + // 缁樺埗mqtt楗煎浘 + totalMqtt() { + // 鍩轰簬鍑嗗濂界殑dom锛屽垵濮嬪寲echarts瀹炰緥 + let myChart = this.$echarts.init(this.$refs.pieTotal); + var option; + option = { + title: { + text: 'Mqtt娑堟伅', + left: 'left', + textStyle: { + fontSize: 16, + }, + }, + tooltip: { + trigger: 'item', + }, + legend: { + orient: 'vertical', + left: 'right', + }, + color: ['#E6A23C', '#F56C6C', '#DDD'], + series: [ + { + name: 'Mqtt娑堟伅 %', + type: 'pie', + radius: '55%', + label: { + show: true, + }, + labelLine: { + normal: { + position: 'inner', + show: false, + }, + }, + data: [ + { + value: this.static['send_total'], + name: '鍙戦�佹秷鎭�绘暟', + }, + { + value: this.static['receive_total'], + name: '鎺ユ敹娑堟伅鎬绘暟', + }, + ], + }, + ], + }; + option && myChart.setOption(option); + }, + /** 缁樺埗mqtt鐘舵�佺粺璁� */ + drawStats() { + // 鍩轰簬鍑嗗濂界殑dom锛屽垵濮嬪寲echarts瀹炰緥 + let myChart = this.$echarts.init(this.$refs.statsChart); + var option; + + option = { + title: { + text: 'Mqtt 鐘舵�佹暟鎹�', + textStyle: { + fontSize: 18, + color: '#000', + fontWeight: 800, + }, + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow', + }, + }, + legend: {}, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true, + }, + xAxis: { + type: 'value', + boundaryGap: [0, 0.01], + }, + yAxis: { + type: 'category', + axisLabel: { + fontSize: 14, + }, + data: ['杩炴帴鏁伴噺', '浼氳瘽鏁伴噺', '璁㈤槄鏁伴噺', '璺敱鏁伴噺', '淇濈暀娑堟伅'], + }, + series: [ + { + name: '褰撳墠鏁伴噺', + type: 'bar', + data: [this.stats['connection_count'], this.stats['session_count'], this.stats['subscription_count'], this.stats['retain_count'], this.stats['retain_count']], + itemStyle: { + color: '#67C23A', + }, + }, + { + name: '绱鎬绘暟', + type: 'bar', + data: [this.stats['connection_total'], this.stats['session_total'], this.stats['subscription_total'], this.stats['retain_total'], this.stats['retain_total']], + itemStyle: { + color: '#409EFF', + }, + }, + ], + }; + + option && myChart.setOption(option); + }, + }, +}; +</script> + +<style lang="scss" scoped> +.panel-group { + .card-panel-col { + margin-bottom: 10px; + } + + .card-panel { + height: 68px; + cursor: pointer; + position: relative; + overflow: hidden; + color: #666; + border: 1px solid #eee; + border-radius: 5px; + //box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.08); + background-color: #fff; + + &:hover { + .card-panel-icon-wrapper { + color: #fff; + } + + .icon-blue { + background: #36a3f7; + } + + .icon-green { + background: #34bfa3; + } + + .icon-red { + background: #f56c6c; + } + + .icon-orange { + background: #e6a23c; + } + } + + .icon-blue { + color: #36a3f7; + } + + .icon-green { + color: #34bfa3; + } + + .icon-red { + color: #f56c6c; + } + + .icon-orange { + color: #e6a23c; + } + + .card-panel-icon-wrapper { + float: left; + margin: 10px; + padding: 10px; + transition: all 0.38s ease-out; + border-radius: 6px; + } + + .card-panel-icon { + float: left; + font-size: 30px; + } + + .card-panel-description { + float: right; + font-weight: bold; + margin: 15px; + margin-left: 0px; + + .card-panel-text { + line-height: 14px; + color: rgba(0, 0, 0, 0.45); + font-size: 14px; + margin-bottom: 12px; + text-align: right; + } + + .card-panel-num { + font-size: 18px; + } + } + } +} +</style> diff --git a/src/views/iot/news/index.vue b/src/views/iot/news/index.vue new file mode 100644 index 0000000..04605ff --- /dev/null +++ b/src/views/iot/news/index.vue @@ -0,0 +1,443 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="60px" v-if="isAdmin"> + <el-form-item label="鏍囬" prop="title"> + <el-input v-model="queryParams.title" placeholder="璇疯緭鍏ユ爣棰�" clearable size="small" + @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="鍒嗙被" prop="categoryName"> + <el-input v-model="queryParams.categoryName" placeholder="璇疯緭鍏ュ垎绫诲悕绉�" clearable size="small" + @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="缃《" prop="isTop"> + <el-select v-model="queryParams.isTop" placeholder="鏄惁缃《" clearable size="small" style="width:100px;"> + <el-option v-for="dict in dict.type.iot_yes_no" :key="dict.value" :label="dict.label" + :value="dict.value" /> + </el-select> + </el-form-item> + <el-form-item label="杞挱" prop="isBanner"> + <el-select v-model="queryParams.isBanner" placeholder="鏄惁杞挱" clearable size="small" style="width:100px;"> + <el-option v-for="dict in dict.type.iot_yes_no" :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 size="small" style="width:100px;"> + <el-option v-for="dict in dict.type.iot_yes_no" :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="['iot:news: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="['iot:news: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="['iot:news: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="['iot:news:export']">瀵煎嚭</el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <el-table v-loading="loading" :data="newsList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="鍥剧墖" align="center" prop="imgUrl" width="140px;"> + <template slot-scope="scope"> + <el-image style="border-radius:5px;height:80px;width:120px;margin-bottom:-5px;" lazy + :preview-src-list="[baseUrl + scope.row.imgUrl]" :src="baseUrl + scope.row.imgUrl" + fit="cover"></el-image> + </template> + </el-table-column> + <el-table-column label="鏍囬" align="center" prop="title" /> + <el-table-column label="鍒嗙被" align="center" prop="categoryName"> + <template slot-scope="scope"> + <el-tag type="info">{{ scope.row.categoryName }}</el-tag> + </template> + </el-table-column> + <el-table-column label="浣滆��" align="center" prop="author" width="100" /> + <el-table-column label="缃《" align="center" prop="isTop" width="80"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isTop" /> + </template> + </el-table-column> + <el-table-column label="杞挱" align="center" prop="isBanner" width="80"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isBanner" /> + </template> + </el-table-column> + <el-table-column label="鍙戝竷" align="center" prop="status" width="80"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.status" /> + </template> + </el-table-column> + + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="120"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> + </template> + </el-table-column> + <el-table-column label="澶囨敞" align="center" prop="remark" /> + <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="openDetailDialog(scope.row.newsId)">鏌ョ湅</el-button> + <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" + v-hasPermi="['iot:news:edit']">淇敼</el-button> + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" + v-hasPermi="['iot:news: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="800px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="60px"> + <el-row :gutter="20"> + <el-col :span="12"> + <el-form-item label="鏍囬" prop="title"> + <el-input v-model="form.title" placeholder="璇疯緭鍏ユ爣棰�" /> + </el-form-item> + <el-form-item label="浣滆��" prop="author"> + <el-input v-model="form.author" placeholder="璇疯緭鍏ヤ綔鑰�" /> + </el-form-item> + <el-form-item label="鎽樿" prop="remark"> + <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" rows="3" /> + </el-form-item> + <el-row> + <el-col :span="8"> + <el-form-item label="缃《" prop="isTop"> + <el-switch v-model="form.isTop" active-text="" inactive-text="" :active-value="1" + :inactive-value="0"></el-switch> + </el-form-item> + </el-col> + <el-col :span="8"> + <el-form-item label="杞挱" prop="isBanner"> + <el-switch v-model="form.isBanner" active-text="" inactive-text="" :active-value="1" + :inactive-value="0"></el-switch> + </el-form-item> + </el-col> + <el-col :span="8"> + <el-form-item label="鍙戝竷" prop="status"> + <el-switch v-model="form.status" active-text="" inactive-text="" :active-value="1" + :inactive-value="0"></el-switch> + </el-form-item> + </el-col> + </el-row> + + </el-col> + <el-col :span="12"> + <el-form-item label="鍒嗙被" prop="categoryId"> + <el-select v-model="form.categoryId" placeholder="璇烽�夋嫨鍒嗙被" @change="selectCategory"> + <el-option v-for="category in categoryList" :key="category.id" :label="category.name" + :value="category.id"></el-option> + </el-select> + </el-form-item> + <el-form-item label="鍥剧墖"> + <imageUpload ref="image-upload" :value="form.imgUrl" :limit="1" :fileSize="1" + @input="getImagePath($event)"></imageUpload> + </el-form-item> + </el-col> + </el-row> + <el-form-item label="鍐呭"> + <editor v-model="form.content" :min-height="192" /> + </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> + + <!--閫氱煡鍏憡璇︽儏 --> + <el-dialog :title="form.title" :visible.sync="openDetail" width="800px" append-to-body> + <div style="margin-top:-20px;margin-bottom:10px;"> + <el-tag size="mini" effect="dark" type="success">{{ form.categoryName }}</el-tag> + <span style="margin-left:20px;">{{ form.createTime }}</span> + </div> + <div v-loading="loadingDetail" class="content"> + <div v-html="form.content"></div> + </div> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="closeDetail"> 鍏� 闂� </el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { + listNews, + getNews, + delNews, + addNews, + updateNews +} from "@/api/iot/news"; +import { + listShortNewsCategory +} from '@/api/iot/newsCategory' +import imageUpload from "../../../components/ImageUpload/index" + +export default { + name: "News", + dicts: ['iot_yes_no'], + components: { + imageUpload + }, + data() { + return { + // 鏄惁涓虹鐞嗗憳 + isAdmin: false, + // 璇︽儏鍔犺浇 + loadingDetail: false, + // 鎵撳紑璇︽儏 + openDetail: false, + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 鏂伴椈璧勮琛ㄦ牸鏁版嵁 + newsList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鍒嗙被鍒楄〃 + categoryList: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + title: null, + isTop: null, + isBanner: null, + categoryName: null, + status: '1', // 榛樿涓哄彂甯� + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + baseUrl: process.env.VUE_APP_BASE_API, + // 琛ㄥ崟鏍¢獙 + rules: { + title: [{ + required: true, + message: "鏍囬涓嶈兘涓虹┖", + trigger: "blur" + }, + { + min: 1, + max: 64, + message: '鏍囬涓嶈兘灏戜簬1涓瓧绗﹀拰瓒呰繃64瀛楃', + }, + ], + content: [{ + required: true, + message: "鍐呭涓嶈兘涓虹┖", + trigger: "blur" + }], + categoryId: [{ + required: true, + message: "鍒嗙被涓嶈兘涓虹┖", + trigger: "blur" + }], + author: [{ + required: true, + message: "浣滆�呬笉鑳戒负绌�", + trigger: "blur" + }, + { + min: 1, + max: 50, + message: '浣滆�呭悕绉颁笉鑳藉皯浜�1涓瓧绗﹀拰瓒呰繃50瀛楃', + },], + } + }; + }, + created() { + this.getList(); + this.init(); + + }, + methods: { + init() { + if (this.$store.state.user.roles.indexOf("tenant") === -1 && this.$store.state.user.roles.indexOf("general") === -1) { + this.isAdmin = true + // 鑾峰彇鍒嗙被鍒楄〃 + listShortNewsCategory().then(response => { + this.categoryList = response.data; + }) + } + }, + /** 鏌ヨ鏂伴椈璧勮鍒楄〃 */ + getList() { + this.loading = true; + listNews(this.queryParams).then(response => { + this.newsList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + /**鑾峰彇涓婁紶鍥剧墖鐨勮矾寰� */ + getImagePath(data) { + this.form.imgUrl = data; + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + newsId: null, + title: null, + content: "鏆傛棤鍐呭", + imgUrl: "", + isTop: null, + isBanner: null, + categoryId: null, + categoryName: null, + status: null, + author: null, + delFlag: null, + createBy: null, + createTime: null, + updateBy: null, + updateTime: null, + remark: 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.newsId) + this.single = selection.length !== 1 + this.multiple = !selection.length + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞鏂伴椈璧勮"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const newsId = row.newsId || this.ids + getNews(newsId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼鏂伴椈璧勮"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + console.log(this.form); + if (this.form.imgUrl == null || this.form.imgUrl == "") { + this.$modal.msgError("璇蜂笂浼犲浘鐗�"); + return; + } + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.newsId != null) { + updateNews(this.form).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + }); + } else { + addNews(this.form).then(response => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const newsIds = row.newsId || this.ids; + this.$modal.confirm('鏄惁纭鍒犻櫎鏂伴椈璧勮缂栧彿涓�"' + newsIds + '"鐨勬暟鎹」锛�').then(function () { + return delNews(newsIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(() => { }); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download('iot/news/export', { + ...this.queryParams + }, `news_${new Date().getTime()}.xlsx`) + }, + /** 閫夋嫨鍒嗙被 */ + selectCategory(val) { + for (var i = 0; i < this.categoryList.length; i++) { + if (this.categoryList[i].id == val) { + this.form.categoryName = this.categoryList[i].name; + return; + } + } + }, + // 鎵撳紑淇℃伅璇︽儏 + openDetailDialog(newsId) { + this.openDetail = true; + this.loadingDetail = true; + getNews(newsId).then(response => { + this.form = response.data; + this.openDetail = true; + this.loadingDetail = false; + }); + }, + // 鍙栨秷鎸夐挳 + closeDetail() { + this.titleDetail = "璇︽儏"; + this.openDetail = false; + this.reset(); + }, + } +}; +</script> + +<style lang="scss" scoped>.content { + line-height: 24px; + padding: 10px; + border: 1px solid #eee; + border-radius: 10px; +}</style> diff --git a/src/views/iot/newsCategory/index.vue b/src/views/iot/newsCategory/index.vue new file mode 100644 index 0000000..c89eabb --- /dev/null +++ b/src/views/iot/newsCategory/index.vue @@ -0,0 +1,250 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> + <el-form-item label="鍒嗙被鍚嶇О" prop="categoryName"> + <el-input v-model="queryParams.categoryName" placeholder="璇疯緭鍏ュ垎绫诲悕绉�" clearable size="small" + @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="['iot:newsCategory: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="['iot:newsCategory: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="['iot:newsCategory: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="['iot:newsCategory:export']">瀵煎嚭</el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <el-table v-loading="loading" :data="categoryList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="鍒嗙被缂栧彿" align="center" prop="categoryId" /> + <el-table-column label="鍒嗙被鍚嶇О" align="center" prop="categoryName" /> + <el-table-column label="鏄剧ず椤哄簭" align="center" prop="orderNum" /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span> + </template> + </el-table-column> + <el-table-column label="澶囨敞" align="center" prop="remark" min-width="200" header-align="center" /> + <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="handleUpdate(scope.row)" + v-hasPermi="['iot:newsCategory:add']">鏌ョ湅</el-button> + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" + v-hasPermi="['iot:newsCategory: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="categoryName"> + <el-input v-model="form.categoryName" placeholder="璇疯緭鍏ュ垎绫诲悕绉�" /> + </el-form-item> + <el-form-item label="鏄剧ず椤哄簭" prop="orderNum"> + <el-input-number v-model="form.orderNum" placeholder="璇疯緭鍏ユ樉绀洪『搴�" type="number" controls-position="right" + style="width: 100%" /> + </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" v-hasPermi="['iot:newsCategory:edit']" + v-show="form.categoryId">淇� 鏀�</el-button> + <el-button type="primary" @click="submitForm" v-hasPermi="['iot:newsCategory:add']" + v-show="!form.categoryId">鏂� 澧�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { + listNewsCategory, + getNewsCategory, + delNewsCategory, + addNewsCategory, + updateNewsCategory +} from "@/api/iot/newsCategory"; + +export default { + name: "Category", + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 鏂伴椈鍒嗙被琛ㄦ牸鏁版嵁 + categoryList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + categoryName: null, + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + categoryName: [{ + required: true, + message: "鍒嗙被鍚嶅瓧涓嶈兘涓虹┖", + trigger: "blur" + }, + { + min: 1, + max: 64, + message: '鍒嗙被鍚嶅瓧涓嶈兘灏戜簬1涓瓧绗﹀拰瓒呰繃64瀛楃', + }, + ], + orderNum: [{ + required: true, + message: "鏄剧ず椤哄簭涓嶈兘涓虹┖", + trigger: "blur" + } + ], + } + }; + }, + created() { + this.getList(); + }, + methods: { + /** 鏌ヨ鏂伴椈鍒嗙被鍒楄〃 */ + getList() { + this.loading = true; + listNewsCategory(this.queryParams).then(response => { + this.categoryList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + categoryId: null, + categoryName: null, + orderNum: null, + delFlag: null, + createBy: null, + createTime: null, + updateBy: null, + updateTime: null, + remark: 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.categoryId) + this.single = selection.length !== 1 + this.multiple = !selection.length + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞鏂伴椈鍒嗙被"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const categoryId = row.categoryId || this.ids + getNewsCategory(categoryId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼鏂伴椈鍒嗙被"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.categoryId != null) { + updateNewsCategory(this.form).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + }); + } else { + addNewsCategory(this.form).then(response => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const categoryIds = row.categoryId || this.ids; + let msg = ""; + this.$modal.confirm('鏄惁纭鍒犻櫎鏂伴椈鍒嗙被缂栧彿涓�"' + categoryIds + '"鐨勬暟鎹」锛�').then(function () { + return delNewsCategory(categoryIds).then(response => { + msg = response.msg; + }); + }).then(() => { + this.getList(); + this.$modal.msgSuccess(msg); + }).catch(() => { }); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download('iot/newsCategory/export', { + ...this.queryParams + }, `category_${new Date().getTime()}.xlsx`) + } + } +}; +</script> diff --git a/src/views/iot/platform/index.vue b/src/views/iot/platform/index.vue new file mode 100644 index 0000000..5557571 --- /dev/null +++ b/src/views/iot/platform/index.vue @@ -0,0 +1,338 @@ +<template> +<div class="app-container"> + <el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-width="85px"> + <el-form-item label="绗笁鏂瑰钩鍙�" prop="platform"> + <el-select v-model="queryParams.platform" clearable placeholder="璇烽�夋嫨骞冲彴" size="small"> + <el-option v-for="dict in dict.type.iot_social_platform" :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" clearable placeholder="璇烽�夋嫨鐘舵��" size="small"> + <el-option v-for="dict in dict.type.iot_social_platform_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="['iot:platform: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="['iot:platform: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="['iot:platform: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="['iot:platform:export']">瀵煎嚭 + </el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <el-table v-loading="loading" :data="platformList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column align="center" label="骞冲彴鍚嶇О" prop="platform"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_social_platform" :value="scope.row.platform" /> + </template> + </el-table-column> + + <el-table-column align="center" label="鐘舵��" prop="status" width="75"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_social_platform_status" :value="scope.row.status" /> + </template> + </el-table-column> + <el-table-column label="骞冲彴鐢宠ID" align="center" prop="clientId" /> + <el-table-column label="璺宠浆鍦板潃" align="center" prop="redirectUri" width="180" :show-overflow-tooltip="true" /> + <el-table-column align="center" label="缁戝畾鐧诲綍uri" prop="bindUri" :show-tooltip-when-overflow="true" :render-header="(h,column)=>renderHeaderMethods(h,column,columnTips.bindId)" /> + <el-table-column align="center" label="璺宠浆鐧诲綍uri" prop="redirectLoginUri" :show-tooltip-when-overflow="true" :render-header="(h,column)=>renderHeaderMethods(h,column,columnTips.redirectLogin)" /> + <el-table-column align="center" label="閿欒鎻愮ずuri" prop="errorMsgUri" :show-tooltip-when-overflow="true" :render-header="(h,column)=>renderHeaderMethods(h,column,columnTips.errorId)" /> + <el-table-column align="center" label="鍒涘缓鏃堕棿" prop="createTime" width="100"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</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="['iot:platform:edit']">淇敼 + </el-button> + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['iot:platform: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="600px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="140px"> + <el-form-item label="绗笁鏂瑰钩鍙板悕绉�" prop="platform"> + <el-select v-model="form.platform" placeholder="璇烽�夋嫨绗笁鏂瑰钩鍙�"> + <el-option v-for="dict in dict.type.iot_social_platform" :key="dict.value" :label="dict.label" :value="dict.value"></el-option> + </el-select> + </el-form-item> + <el-form-item label="绗笁鏂瑰钩鍙扮姸鎬�" prop="status"> + <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��"> + <el-option v-for="dict in dict.type.iot_social_platform_status" :key="dict.value" :label="dict.label" :value="dict.value"></el-option> + </el-select> + </el-form-item> + <el-form-item label="绗笁鏂瑰钩鍙扮敵璇稩D" prop="clientId"> + <el-input v-model="form.clientId" placeholder="璇疯緭鍏ョ涓夋柟骞冲彴鐢宠Id" /> + </el-form-item> + <el-form-item label="绗笁鏂瑰钩鍙板瘑閽�" prop="secretKey"> + <el-input v-model="form.secretKey" placeholder="璇疯緭鍏ョ涓夋柟骞冲彴瀵嗛挜" /> + </el-form-item> + <el-form-item label="鐢ㄦ埛璁よ瘉璺宠浆鍦板潃" prop="redirectUri"> + <el-input v-model="form.redirectUri" placeholder="璇疯緭鍏ョ敤鎴疯璇佸悗璺宠浆鍦板潃" /> + </el-form-item> + <el-form-item label="缁戝畾娉ㄥ唽鐧诲綍URI" prop="bindUri"> + <el-input v-model="form.bindUri" placeholder="璇疯緭鍏ョ粦瀹氭敞鍐岀櫥褰晆ri,http://localhost/login?bindId=" /> + </el-form-item> + <el-form-item label="璺宠浆鐧诲綍URI" prop="redirectLoginUri"> + <el-input v-model="form.redirectLoginUri" placeholder="璇疯緭鍏ヨ烦杞櫥褰晆ri,http://localhost/login?loginId=" /> + </el-form-item> + <el-form-item label="閿欒鎻愮ずURI" prop="errorMsgUri"> + <el-input v-model="form.errorMsgUri" placeholder="璇疯緭鍏ラ敊璇彁绀簎ri,http://localhost/login?errorId=" /> + </el-form-item> + <el-form-item label="澶囨敞" prop="remark"> + <el-input v-model="form.remark" placeholder="璇疯緭鍏ュ唴瀹�" type="textarea" /> + </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 { + addPlatform, + delPlatform, + getPlatform, + listPlatform, + updatePlatform +} from "@/api/iot/platform"; + +export default { + name: "Platform", + dicts: ['iot_social_platform', 'iot_social_platform_status'], + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 绗笁鏂圭櫥褰曞钩鍙版帶鍒惰〃鏍兼暟鎹� + platformList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + platform: null, + status: null, + }, + columnTips: { + bindId: "缁戝畾鐧诲綍uri, http://localhost/login?bindId=,鍩熷悕鎹㈡垚瀵瑰簲鍩熷悕鍗冲彲锛屾湰鍦板紑鍙戜笉闇�瑕佹洿鏀�", + redirectLogin: "璺宠浆鐧诲綍uri,http://localhost/login?loginId=,鍩熷悕鎹㈡垚瀵瑰簲鍩熷悕鍗冲彲锛屾湰鍦板紑鍙戜笉闇�瑕佹洿鏀�", + errorId: "閿欒鎻愮ず鑾峰彇uri,http://localhost/login?errorId=,鍩熷悕鎹㈡垚瀵瑰簲鍩熷悕鍗冲彲锛屾湰鍦板紑鍙戜笉闇�瑕佹洿鏀�" + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + platform: [{ + required: true, + message: "绗笁鏂瑰钩鍙颁笉鑳戒负绌�", + trigger: "change" + }], + status: [{ + required: true, + message: " 0:鍚敤 ,1:绂佺敤涓嶈兘涓虹┖", + trigger: "change" + }], + clientId: [{ + required: true, + message: "绗笁鏂瑰钩鍙扮敵璇稩d涓嶈兘涓虹┖", + trigger: "blur" + }], + secretKey: [{ + required: true, + message: "绗笁鏂瑰钩鍙板瘑閽ヤ笉鑳戒负绌�", + trigger: "blur" + }], + redirectUri: [{ + required: true, + message: "鐢ㄦ埛璁よ瘉鍚庤烦杞湴鍧�涓嶈兘涓虹┖", + trigger: "blur" + }], + bindUri: [{ + required: true, + message: "缁戝畾娉ㄥ唽鐧诲綍uri,http://localhost/login?bindId=涓嶈兘涓虹┖", + trigger: "blur" + }], + redirectLoginUri: [{ + required: true, + message: "璺宠浆鐧诲綍uri,http://localhost/login?loginId=涓嶈兘涓虹┖", + trigger: "blur" + }], + errorMsgUri: [{ + required: true, + message: "閿欒鎻愮ずuri,http://localhost/login?errorId=涓嶈兘涓虹┖", + trigger: "blur" + }] + } + }; + }, + created() { + this.getList(); + }, + methods: { + renderHeaderMethods(h, { + column + }, content) { + return h( + 'div', [ + h('span', column.label), + h('el-tooltip', { + props: { + effect: 'dark', + content: content, + placement: 'top' + }, + }, [ + h('i', { + class: 'el-icon-question', + style: 'color:#409EFF;margin-left:5px;' + }) + ]) + ] + ); + }, + /** 鏌ヨ绗笁鏂圭櫥褰曞钩鍙版帶鍒跺垪琛� */ + getList() { + this.loading = true; + listPlatform(this.queryParams).then(response => { + this.platformList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + socialPlatformId: null, + platform: null, + status: null, + clientId: null, + secretKey: null, + redirectUri: null, + createBy: null, + createTime: null, + updateTime: null, + updateBy: null, + remark: null, + bindUri: null, + redirectLoginUri: null, + errorMsgUri: 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.socialPlatformId) + this.single = selection.length !== 1 + this.multiple = !selection.length + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞绗笁鏂圭櫥褰曞钩鍙版帶鍒�"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const socialPlatformId = row.socialPlatformId || this.ids + getPlatform(socialPlatformId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼绗笁鏂圭櫥褰曞钩鍙版帶鍒�"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.socialPlatformId != null) { + updatePlatform(this.form).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + }); + } else { + addPlatform(this.form).then(response => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const socialPlatformIds = row.socialPlatformId || this.ids; + this.$modal.confirm('鏄惁纭鍒犻櫎绗笁鏂圭櫥褰曞钩鍙版帶鍒剁紪鍙蜂负"' + socialPlatformIds + '"鐨勬暟鎹」锛�').then(function () { + return delPlatform(socialPlatformIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(() => {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download('iot/platform/export', { + ...this.queryParams + }, `platform_${new Date().getTime()}.xlsx`) + } + } +}; +</script> diff --git a/src/views/iot/product/index.vue b/src/views/iot/product/index.vue new file mode 100644 index 0000000..5d7bcf6 --- /dev/null +++ b/src/views/iot/product/index.vue @@ -0,0 +1,302 @@ +<template> +<div style="padding:6px;"> + <el-card style="margin-bottom:5px;"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom:-20px;"> + <el-form-item label="浜у搧鍚嶇О" prop="productName"> + <el-input v-model="queryParams.productName" placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="鍒嗙被鍚嶇О" prop="categoryName"> + <el-input v-model="queryParams.categoryName" placeholder="璇疯緭鍏ヤ骇鍝佸垎绫诲悕绉�" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="鐘舵��" prop="status"> + <el-select v-model="queryParams.status" placeholder="璇烽�夋嫨鐘舵��" clearable size="small"> + <el-option v-for="dict in dict.type.iot_product_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-item style="float:right;"> + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleEditProduct(0)" v-hasPermi="['iot:product:add']">鏂板</el-button> + </el-form-item> + </el-form> + </el-card> + <el-card style="padding-bottom:100px;"> + <el-row :gutter="30" v-loading="loading"> + <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" v-for="(item,index) in productList" :key="index" style="margin-bottom:30px;text-align:center;"> + <el-card :body-style="{ padding: '20px'}" shadow="always" class="card-item"> + <el-row type="flex" :gutter="10" justify="space-between"> + <el-col :span="20" style="text-align:left;"> + <el-link type="" :underline="false" @click="handleEditProduct(item)" style="font-weight:bold;font-size:16px;line-height:32px;white-space:nowrap;"> + <svg-icon icon-class="product" /> {{item.productName}} + <el-tag type="info" size="mini" style="margin-left:5px;font-weight:200" v-if="item.isSys==1">绯荤粺</el-tag> + </el-link> + </el-col> + <el-col :span="4"> + <el-tooltip class="item" effect="dark" content="鍙栨秷鍙戝竷" placement="top-start" v-if="item.status==2"> + <el-button type="success" size="mini" style="padding:5px;" @click="changeProductStatus(item.productId,1,item.deviceType)">宸插彂甯�</el-button> + </el-tooltip> + <el-tooltip class="item" effect="dark" content="鐜板湪鍙戝竷" placement="top-start" v-if="item.status==1"> + <el-button type="info" size="mini" style="padding:5px;" @click="changeProductStatus(item.productId,2,item.deviceType)">鏈彂甯�</el-button> + </el-tooltip> + </el-col> + </el-row> + <el-row :gutter="10"> + <el-col :span="14"> + <el-descriptions :column="1" size="small" style="margin-top:10px;white-space:nowrap;"> + <el-descriptions-item label="鎵�灞炲垎绫�"> + <el-link type="primary" :underline="false">{{item.categoryName}}</el-link> + </el-descriptions-item> + <el-descriptions-item label="浜у搧绫诲瀷"> + <dict-tag :options="dict.type.iot_device_type" :value="item.deviceType" /> + </el-descriptions-item> + <el-descriptions-item label="鑱旂綉鏂瑰紡"> + <dict-tag :options="dict.type.iot_network_method" :value="item.networkMethod" /> + </el-descriptions-item> + <el-descriptions-item label="璁惧鎺堟潈"> + <el-tag type="success" size="mini" v-if="item.isAuthorize==1">宸插惎鐢�</el-tag> + <el-tag type="info" size="mini" v-else>鏈惎鐢�</el-tag> + </el-descriptions-item> + </el-descriptions> + </el-col> + <el-col :span="10"> + <div style="margin-top:10px;"> + <el-image style="width:100%;height:100px;border-radius:10px;" lazy :preview-src-list="[baseUrl+item.imgUrl]" :src="baseUrl+item.imgUrl" fit="cover" v-if="item.imgUrl!=null && item.imgUrl!=''"></el-image> + <el-image style="width:100%;height:100px;border-radius:10px;" :preview-src-list="[require('@/assets/images/gateway.png')]" :src="require('@/assets/images/gateway.png')" fit="cover" v-else-if="item.deviceType==2"></el-image> + <el-image style="width:100%;height:100px;border-radius:10px;" :preview-src-list="[require('@/assets/images/video.png')]" :src="require('@/assets/images/video.png')" fit="cover" v-else-if="item.deviceType==3"></el-image> + <el-image style="width:100%;height:100px;border-radius:10px;" :preview-src-list="[require('@/assets/images/product.png')]" :src="require('@/assets/images/product.png')" fit="cover" v-else></el-image> + </div> + </el-col> + </el-row> + <el-button-group style="margin-top:15px;height:28px;"> + <el-button size="mini" type="primary" icon="el-icon-view" @click="handleEditProduct(item)" v-hasPermi="['iot:product:query']">璇︽儏</el-button> + <el-button size="mini" type="danger" icon="el-icon-delete" @click="handleDelete(item)" v-hasPermi="['iot:product:remove']" v-if="item.status==1">鍒犻櫎</el-button> + <el-button size="mini" type="success" icon="el-icon-s-check" @click="handleDeviceAuthorize(item)" v-hasPermi="['iot:product:edit']" v-if="item.status==2" :disabled="item.isAuthorize!=1">璁惧鎺堟潈</el-button> + <el-button size="mini" type="warning" icon="el-icon-search" @click="handleViewDevice(item.productId)" v-hasPermi="['iot:device:query']">鏌ョ湅璁惧</el-button> + </el-button-group> + </el-card> + </el-col> + </el-row> + + <el-empty description="鏆傛棤鏁版嵁锛岃娣诲姞浜у搧" v-if="total==0"></el-empty> + <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" :pageSizes="[12, 24, 36, 60]" @pagination="getList" /> + + <!-- 涓嬭浇SDK --> + <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body> + <el-link type="danger" style="padding-left:10px;" :underline="false">璇ュ姛鑳芥殏鏈疄鐜帮紝鍙傝�冩暀绋嬪拰椤圭洰鐨凷DK绀轰緥</el-link> + <el-form label-width="80px"> + <el-form-item label="璁惧绫诲瀷"> + <el-radio-group v-model="form.datatype"> + <el-radio v-for="dict in dict.type.iot_device_chip" :key="dict.value" :label="dict.value" style="margin-top:15px;width:160px;">{{dict.label}}</el-radio> + </el-radio-group> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="downloadSdk" disabled>涓� 杞�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + + </el-card> +</div> +</template> + +<script> +import { + listProduct, + delProduct, + changeProductStatus, + deviceCount, +} from "@/api/iot/product"; + +import { + checkPermi +} from "@/utils/permission" + +export default { + name: "Product", + dicts: ['iot_yes_no', 'iot_product_status', 'iot_device_type', 'iot_network_method', 'iot_vertificate_method', 'iot_device_chip'], + data() { + return { + // 閬僵灞� + loading: true, + // 鎬绘潯鏁� + total: 0, + // 浜у搧琛ㄦ牸鏁版嵁 + productList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 12, + productName: null, + categoryId: null, + categoryName: null, + tenantId: null, + tenantName: null, + isSys: null, + status: null, + deviceType: null, + networkMethod: null, + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + baseUrl: process.env.VUE_APP_BASE_API, + }; + }, + created() { + this.getList(); + }, + activated() { + const time = this.$route.query.t; + if (time != null && time != this.uniqueId) { + this.uniqueId = time; + this.queryParams.pageNum = Number(this.$route.query.pageNum); + this.getList(); + } + }, + methods: { + /** 鏌ヨ浜у搧鍒楄〃 */ + getList() { + this.loading = true; + listProduct(this.queryParams).then(response => { + this.productList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + /**鍚屾鑾峰彇浜у搧涓嬬殑璁惧鏁伴噺**/ + getDeviceCountByProductId(productId) { + return new Promise((resolve, reject) => { + deviceCount(productId).then(res => { + resolve(res); + }).catch(error => { + reject(error); + }) + }) + }, + /** 鏇存柊浜у搧鐘舵�� */ + async changeProductStatus(productId, status, deviceType) { + let message = "纭畾鍙栨秷鍙戝竷锛�"; + if (status == 2) { + // 鍙戝竷 + let hasPermission = checkPermi(['iot:product:add']); + if (!hasPermission) { + this.$modal.alertError("娌℃湁鎿嶄綔鏉冮檺"); + return; + } + message = "浜у搧鍙戝竷鍚庯紝鍙互鍒涘缓瀵瑰簲鐨勮澶�"; + } else if (status == 1) { + // 鍙栨秷鍙戝竷 + let hasPermission = checkPermi(['iot:product:edit']); + if (!hasPermission) { + this.$modal.alertError("娌℃湁鎿嶄綔鏉冮檺"); + return; + } + let result = await this.getDeviceCountByProductId(productId); + if (result.data > 0) { + message = "閲嶈鎻愮ず锛氫骇鍝佷笅宸叉湁 " + result.data + " 涓澶囷紝鍙栨秷鍙戝竷鍙互淇敼浜у搧淇℃伅鍜屾ā鍨嬶紝閲嶆柊鍙戝竷鍚庡搴旇澶囩姸鎬佸皢浼氳閲嶇疆锛�" + } + } + this.$confirm(message, '鎻愮ず', { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' + }).then(() => { + let data = {}; + data.productId = productId; + data.status = status; + data.deviceType = deviceType; + changeProductStatus(data).then(response => { + this.getList(); + this.$modal.alertSuccess(response.msg); + }).catch(() => {}); + }).catch(() => {}); + }, + /** 鏌ョ湅璁惧鎸夐挳鎿嶄綔 */ + handleViewDevice(productId) { + this.$router.push({ + path: '/iot/device', + query: { + t: Date.now(), + productId: productId, + } + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + /** 鐢熸垚SDK */ + handleGeneratorSDK(row) { + this.title = "鐢熸垚SDK" + this.open = true; + }, + /** 涓嬭浇SDK */ + downloadSdk() { + this.$download.zip("/iot/tool/genSdk?deviceChip=" + 1, "fastbee-sdk"); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const productIds = row.productId || this.ids; + let msg = ""; + this.$modal.confirm('鏄惁纭鍒犻櫎浜у搧缂栧彿涓�"' + productIds + '"鐨勬暟鎹」锛�').then(function () { + // // 鍒犻櫎SIP閰嶇疆 + // delSipconfigByProductId(productIds).then(response => {}); + return delProduct(productIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess(msg); + }).catch(() => {}); + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleEditProduct(row) { + let productId = 0; + if (row != 0) { + productId = row.productId || this.ids + } + this.$router.push({ + path: '/iot/product-edit', + query: { + productId: productId, + pageNum: this.queryParams.pageNum + } + }); + }, + /** 璁惧鎺堟潈鎿嶄綔 */ + handleDeviceAuthorize(row) { + let productId = row.productId + this.$router.push({ + path: '/iot/product-edit', + query: { + productId: productId, + tabPanelName: 'productAuthorize', + pageNum: this.queryParams.pageNum + } + }); + }, + } +}; +</script> + +<style scoped> +.card-item { + border-radius: 15px; +} +</style> diff --git a/src/views/iot/product/product-app.vue b/src/views/iot/product/product-app.vue new file mode 100644 index 0000000..7e6d958 --- /dev/null +++ b/src/views/iot/product/product-app.vue @@ -0,0 +1,129 @@ +<template> +<div style="padding-left:20px;"> + <el-row :gutter="10"> + <el-col :span="14"> + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button type="warning" plain icon="el-icon-refresh" size="mini" @click="getList">鍒锋柊</el-button> + </el-col> + <el-tag type="danger" style="margin-left:15px;">璇ュ姛鑳芥殏涓嶅彲鐢�,鍚庨潰鐗堟湰鍙戝竷</el-tag> + </el-row> + <el-table v-loading="loading" :data="modelList" border style="margin-bottom:60px;margin-top:20px;" size="small"> + <el-table-column label="鍚嶇О" align="center" prop="modelName" /> + <el-table-column label="鏍囪瘑绗�" align="center" prop="identifier" /> + <el-table-column label="鐗╂ā鍨嬬被鍒�" align="center" prop="type"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_things_type" :value="scope.row.type" /> + </template> + </el-table-column> + <el-table-column label="鏁版嵁绫诲瀷" align="center" prop="datatype"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_data_type" :value="scope.row.datatype" /> + </template> + </el-table-column> + <el-table-column label="閮ㄤ欢" align="center" prop="part"> + <template slot-scope="scope"> + {{scope.row.part}} 绯荤粺瀹氫箟鐨勯儴浠� + </template> + </el-table-column> + </el-table> + + <el-divider>楂樼骇鍔熻兘</el-divider> + <el-form ref="form" :model="form" label-width="100px"> + <el-form-item label="鑷畾涔夐〉闈�" prop="page"> + <el-input v-model="form.page" placeholder="璇疯緭鍏ヨ嚜瀹氫箟椤甸潰" /> + </el-form-item> + </el-form> + + </el-col> + <el-col :span="8" :offset="2"> + <div class="phone"> + <div class="phone-container"></div> + </div> + <div style="text-align:center;margin-top:15px;width:370px;">鐣岄潰灞曠ず</div> + </el-col> + + </el-row> +</div> +</template> + +<script> +import { + listModel, +} from "@/api/iot/model"; +export default { + name: "device-log", + dicts: ["iot_things_type", "iot_data_type", "iot_yes_no"], + props: { + product: { + type: Object, + default: null + } + }, + data() { + return { + // 閬僵灞� + loading: false, + // 浜у搧鐗╂ā鍨嬭〃鏍兼暟鎹� + modelList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏌ヨ鍙傛暟 + queryParams: { + productId: 0, + // 1-灞炴�э紝2-鍔熻兘锛�3-浜嬩欢锛�4-灞炴�у拰鍔熻兘 + type: 4, + }, + form: {}, + // 浜у搧 + productInfo: {}, + }; + }, + watch: { + // 鑾峰彇鍒扮埗缁勪欢浼犻�掔殑productId鍚庯紝鍒锋柊鍒楄〃 + product: function (newVal, oldVal) { + this.productInfo = newVal; + if (this.productInfo && this.productInfo.productId != 0) { + this.queryParams.productId = this.productInfo.productId; + this.getList(); + } + } + }, + created() { + + }, + methods: { + /** 鏌ヨ浜у搧鐗╂ā鍨嬪垪琛� */ + getList() { + this.loading = true; + listModel(this.queryParams).then((response) => { + this.modelList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + } +}; +</script> + +<style scoped> +.phone { + height: 700px; + width: 370px; + background-image: url("../../../assets/images/phone.jpg"); + background-size: cover; + top: 0px; +} + +.phone-container { + height: 620px; + width: 345px; + border-radius: 20px; + position: relative; + top: 45px; + left: 12px; + border: 1px solid #888; + background: linear-gradient(303deg, #b2e9fc 50%, #b5c4f8 50%); + +} +</style> diff --git a/src/views/iot/product/product-authorize.vue b/src/views/iot/product/product-authorize.vue new file mode 100644 index 0000000..a2033f5 --- /dev/null +++ b/src/views/iot/product/product-authorize.vue @@ -0,0 +1,515 @@ +<template> +<div style="padding-left:20px;"> + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> + <el-form-item label="璁惧缂栧彿" prop="serialNumber"> + <el-input v-model="queryParams.serialNumber" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="鎺堟潈鐮�" prop="authorizeCode"> + <el-input v-model="queryParams.authorizeCode" placeholder="璇疯緭鍏ユ巿鏉冪爜" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="鐘舵��" prop="status"> + <el-select v-model="queryParams.status" placeholder="璇烽�夋嫨鐘舵��" clearable size="small"> + <el-option v-for="dict in dict.type.iot_auth_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="['iot:authorize:add']">鐢熸垚鎺堟潈鐮�</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="['iot:authorize: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="['iot:authorize:export']">瀵煎嚭</el-button> + </el-col> + <el-col :span="1.5"> + <el-link type="info" style="padding-top:5px" :underline="false">Tips锛氬弻鍑诲彲浠ュ鍒舵巿鏉冪爜銆�</el-link> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="authorizeList" @selection-change="handleSelectionChange" @cell-dblclick="celldblclick" size="small"> + <el-table-column type="selection" :selectable="selectable" width="55" align="center" /> + <el-table-column label="鎺堟潈鐮�" width="320" align="center" prop="authorizeCode" /> + <el-table-column label="鐘舵��" align="center" prop="active" width="100"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_auth_status" :value="scope.row.status" /> + </template> + </el-table-column> + <el-table-column label="璁惧缂栧彿" width="150" align="center" prop="serialNumber"> + <template slot-scope="scope"> + <el-link type="primary" @click="getDeviceBySerialNumber(scope.row.serialNumber)" :underline="false">{{scope.row.serialNumber}}</el-link> + </template> + </el-table-column> + <el-table-column label="鎺堟潈鏃堕棿" align="center" prop="updateTime" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d} {h}:{m}:{s}') }}</span> + </template> + </el-table-column> + <el-table-column label="澶囨敞" align="center" prop="remark" /> + <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-s-check" @click="handleUpdate(scope.row,'auth')" v-hasPermi="['iot:authorize:edit']" v-if="scope.row.status==1 && !scope.row.deviceId">璁惧鎺堟潈</el-button> + <el-button size="mini" type="text" icon="el-icon-notebook-1" @click="handleUpdate(scope.row,'remark')" v-hasPermi="['iot:authorize:edit']">澶囨敞</el-button> + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['iot:authorize:remove']" v-if="!scope.row.deviceId">鍒犻櫎</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="editWidth" append-to-body> + <div v-if="editType=='auth'"> + <div class="el-divider el-divider--horizontal" style="margin-top: -25px;"></div> + <el-form :model="deviceParams" ref="queryDeviceForm" :inline="true" label-width="68px"> + <el-form-item label="璁惧鍚嶇О" prop="deviceName"> + <el-input v-model="deviceParams.deviceName" placeholder="璇疯緭鍏ヨ澶囧悕绉�" clearable size="small" @keyup.enter.native="handleQuery" style="width:150px;" /> + </el-form-item> + <el-form-item label="璁惧缂栧彿" prop="serialNumber" style="margin:0 30px;"> + <el-input v-model="deviceParams.serialNumber" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" clearable size="small" @keyup.enter.native="handleQuery" style="width:150px;" /> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="el-icon-search" size="mini" @click="handleDeviceQuery">鎼滅储</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetDeviceQuery">閲嶇疆</el-button> + </el-form-item> + </el-form> + <el-table v-loading="deviceLoading" :data="deviceList" ref="singleTable" size="mini" @row-click="rowClick" highlight-current-row> + <el-table-column label="閫夋嫨" width="50" align="center"> + <template slot-scope="scope"> + <input type="radio" :checked="scope.row.isSelect" name="device" /> + </template> + </el-table-column> + <el-table-column label="璁惧鍚嶇О" align="center" prop="deviceName" /> + <el-table-column label="璁惧ID" align="center" prop="deviceId" /> + <el-table-column label="璁惧缂栧彿" align="center" prop="serialNumber" /> + <el-table-column label="鐢ㄦ埛鍚嶇О" align="center" prop="userName" /> + <el-table-column label="璁惧鐘舵��" align="center" prop="status"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_device_status" :value="scope.row.status" /> + </template> + </el-table-column> + </el-table> + <pagination v-show="deviceTotal>0" :total="deviceTotal" :page.sync="deviceParams.pageNum" :limit.sync="deviceParams.pageSize" @pagination="getDeviceList" /> + </div> + <div v-if="editType=='remark'"> + <el-input v-model="form.remark" type="textarea" rows="4" placeholder="璇疯緭鍏ュ唴瀹�" /> + </div> + <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="璁惧璇︽儏" :visible.sync="openDevice" width="600px" append-to-body> + <div v-if="device==null" style="text-align:center;"><i class="el-icon-warning" style="color:#E6A23C;"></i> 鎻愮ず锛氭煡鎵句笉鍒拌澶囷紝鍙兘宸茬粡琚垹闄�</div> + <el-descriptions border :column="2" size="medium" v-if="device!=null"> + <el-descriptions-item label="璁惧ID">{{device.deviceId}}</el-descriptions-item> + <el-descriptions-item label="璁惧鍚嶇О">{{device.deviceName}}</el-descriptions-item> + <el-descriptions-item label="璁惧缂栧彿">{{device.serialNumber}}</el-descriptions-item> + <el-descriptions-item label="璁惧鐘舵��"> + <!-- 锛�1-鏈縺娲伙紝2-绂佺敤锛�3-鍦ㄧ嚎锛�4-绂荤嚎锛� --> + <el-tag v-if="device.status==1" type="warning">鏈縺娲�</el-tag> + <el-tag v-else-if="device.status==2" type="danger">绂佺敤</el-tag> + <el-tag v-else-if="device.status==3" type="success">鍦ㄧ嚎</el-tag> + <el-tag v-else-if="device.status==4" type="info">绂荤嚎</el-tag> + </el-descriptions-item> + <el-descriptions-item label="璁惧褰卞瓙"> + <el-tag v-if="device.isShadow==1" type="success">鍚敤</el-tag> + <el-tag v-else type="info">鏈惎鐢�</el-tag> + </el-descriptions-item> + <el-descriptions-item label="瀹氫綅鏂瑰紡"> + <!-- (1=ip鑷姩瀹氫綅锛�2=璁惧瀹氫綅锛�3=鑷畾涔�) --> + <el-tag v-if="device.locationWay==1" type="success">鑷姩瀹氫綅</el-tag> + <el-tag v-else-if="device.locationWay==2" type="warning">璁惧瀹氫綅</el-tag> + <el-tag v-else-if="device.locationWay==3" type="primary">鑷畾涔変綅缃�</el-tag> + </el-descriptions-item> + <el-descriptions-item label="浜у搧鍚嶇О">{{device.productName}}</el-descriptions-item> + <el-descriptions-item label="绉熸埛鍚嶇О">{{device.userName}}</el-descriptions-item> + <el-descriptions-item label="鍥轰欢鐗堟湰">Version {{device.firmwareVersion}}</el-descriptions-item> + <el-descriptions-item label="鎵�鍦ㄥ湴鍧�">{{device.networkAddress}}</el-descriptions-item> + <el-descriptions-item label="璁惧缁忓害">{{device.longitude}}</el-descriptions-item> + <el-descriptions-item label="璁惧绾害">{{device.latitude}}</el-descriptions-item> + <el-descriptions-item label="鍏ョ綉IP">{{device.networkIp}}</el-descriptions-item> + <el-descriptions-item label="璁惧淇″彿">{{device.rssi}}</el-descriptions-item> + <el-descriptions-item label="鍒涘缓鏃堕棿">{{device.createTime}}</el-descriptions-item> + <el-descriptions-item label="婵�娲绘椂闂�">{{device.activeTime}}</el-descriptions-item> + <el-descriptions-item label="澶囨敞淇℃伅">{{device.remark}}</el-descriptions-item> + </el-descriptions> + <div slot="footer" class="dialog-footer"> + <el-button @click="goToEditDevice(device.deviceId)" type="primary">鏌ョ湅璁惧</el-button> + <el-button @click="closeDevice">鍏� 闂�</el-button> + </div> + </el-dialog> +</div> +</template> + +<style> +.createNum { + width: 300px; +} + +.createNum input { + width: 260px; +} +</style> + +<script> +import { + getDeviceBySerialNumber, +} from "@/api/iot/device"; +import { + listUnAuthDevice, +} from "@/api/iot/device"; +import { + listAuthorize, + getAuthorize, + delAuthorize, + addProductAuthorizeByNum, + updateAuthorize +} from "@/api/iot/authorize"; +export default { + name: "product-authorize", + dicts: ['iot_auth_status', 'iot_device_status'], + props: { + product: { + type: Object, + default: null + } + }, + watch: { + // 鑾峰彇鍒扮埗缁勪欢浼犻�掔殑productId鍚庯紝鍒锋柊鍒楄〃 + product: function (newVal, oldVal) { + this.productInfo = newVal; + if (this.productInfo && this.productInfo.productId != 0) { + this.queryParams.productId = this.productInfo.productId; + this.deviceParams.productId = this.productInfo.productId; + this.getList(); + this.getDeviceList(); + } + } + }, + data() { + return { + // 璁惧淇℃伅 + device: {}, + // 璁惧淇℃伅瀵硅瘽妗� + openDevice: false, + // 璁惧閬僵灞� + deviceLoading: true, + // 鎬绘潯鏁� + deviceTotal: 0, + // 璁惧琛ㄦ牸鏁版嵁 + deviceList: [], + // 鏌ヨ鍙傛暟 + deviceParams: { + pageNum: 1, + pageSize: 10, + userId: null, + deviceName: null, + productId: 0, + productName: null, + userId: null, + userName: null, + tenantId: null, + tenantName: null, + serialNumber: null, + status: null, + networkAddress: null, + activeTime: null, + }, + // 缂栬緫绫诲瀷锛宺emark=澶囨敞銆乤uth=璁惧鎺堟潈 + editType: '', + // 缂栬緫鐣岄潰瀹藉害 + editWidth: '500px', + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 浜у搧鎺堟潈鐮佽〃鏍兼暟鎹� + authorizeList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏂板鎺堟潈鐮佷釜鏁� + createNum: 10, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + authorizeCode: null, + productId: null, + deviceId: null, + serialNumber: null, + userId: null, + userName: null, + status: null, + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 浜у搧 + productInfo: {}, + }; + }, + created() { + + }, + methods: { + /**鑾峰彇璁惧璇︽儏*/ + getDeviceBySerialNumber(serialNumber) { + this.openDevice = true; + getDeviceBySerialNumber(serialNumber).then(response => { + this.device = response.data; + }); + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + goToEditDevice(deviceId) { + this.openDevice = false; + this.$router.push({ + path: '/iot/device-edit', + query: { + deviceId: deviceId, + } + }); + }, + /** 鏌ヨ璁惧鍒楄〃 */ + getDeviceList() { + this.deviceLoading = true; + this.deviceParams.params = {}; + listUnAuthDevice(this.deviceParams).then(response => { + //璁惧鍒楄〃鍒濆鍖杋sSelect鍊硷紝鐢ㄤ簬鍗曢�� + for (let i = 0; i < response.rows.length; i++) { + response.rows[i].isSelect = false; + } + this.deviceList = response.rows; + this.deviceTotal = response.total; + this.deviceLoading = false; + }); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleDeviceQuery() { + this.deviceParams.pageNum = 1; + this.getDeviceList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetDeviceQuery() { + this.resetForm("queryDeviceForm"); + this.handleDeviceQuery(); + }, + /** 鍗曢�夋暟鎹� */ + rowClick(device) { + if (device != null) { + this.setRadioSelected(device.deviceId); + // 璧嬪�� + this.form.userId = device.userId; + this.form.userName = device.userName; + this.form.deviceId = device.deviceId; + this.form.serialNumber = device.serialNumber; + } + }, + /** 璁剧疆鍗曢�夋寜閽�変腑 */ + setRadioSelected(deviceId) { + for (let i = 0; i < this.deviceList.length; i++) { + let device = this.deviceList[i]; + if (this.deviceList[i].deviceId == deviceId) { + device.isSelect = true; + this.$set(this.deviceList, i, device); + } else { + device.isSelect = false; + this.$set(this.deviceList, i, device); + } + } + }, + /** 鏌ヨ浜у搧鎺堟潈鐮佸垪琛� */ + getList() { + this.loading = true; + listAuthorize(this.queryParams).then(response => { + this.authorizeList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 鍏抽棴璁惧璇︽儏 + closeDevice() { + this.openDevice = false; + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + authorizeId: null, + authorizeCode: null, + productId: "", + userId: "", + deviceId: null, + serialNumber: null, + userName: null, + delFlag: null, + createBy: null, + createTime: null, + updateBy: null, + updateTime: null, + remark: null + }; + this.device = {}; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.authorizeId) + this.multiple = !selection.length + }, + /** 鎵归噺鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.$prompt('', '杈撳叆鎺堟潈鐮佹暟閲�', { + customClass: 'createNum', + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + inputPattern: /[0-9\-]/, + inputErrorMessage: '鏁伴噺鍐呭涓嶆纭�', + inputType: 'number', + inputValue: this.createNum + }).then(({ + value + }) => { + this.createNum = value + if (this.queryParams.productId != null) { + let _addData = { + productId: this.queryParams.productId, + createNum: this.createNum + } + addProductAuthorizeByNum(_addData).then(response => { + this.$modal.msgSuccess("鏂板鎺堟潈鐮佹垚鍔�"); + this.getList(); + this.createNum = 10; + }); + } + }).catch(() => { + this.$message({ + type: 'info', + message: '鍙栨秷鏂板' + }); + }); + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row, editType) { + this.reset(); + this.editType = editType; + const authorizeId = row.authorizeId || this.ids + getAuthorize(authorizeId).then(response => { + this.form = response.data; + this.open = true; + if (this.editType == 'auth') { + this.title = "閫夋嫨璁惧"; + this.editWidth = "800px"; + } else { + this.title = "澶囨敞淇℃伅"; + this.editWidth = "500px"; + } + // 鍙栨秷閫変腑 + + for (let i = 0; i < this.deviceList.length; i++) { + // this.deviceList[i].isSelect=false; + let device = this.deviceList[i]; + device.isSelect = false; + // this.deviceList.splice(i,1,device ) + this.$set(this.deviceList, i, device); + } + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + if (this.editType == 'auth') { + if (this.form.deviceId != null && this.form.deviceId != 0) { + updateAuthorize(this.form).then(response => { + this.$modal.msgSuccess("璁惧鎺堟潈鎴愬姛"); + this.open = false; + this.getList(); + }); + } else { + this.$modal.msg("璇烽�夋嫨瑕佹巿鏉冪殑璁惧"); + } + } else if (this.form.authorizeId != null) { + updateAuthorize(this.form).then(response => { + this.$modal.msgSuccess("澶囨敞鎴愬姛"); + this.open = false; + this.getList(); + }); + } + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const authorizeIds = row.authorizeId || this.ids; + this.$modal.confirm('鏄惁纭鍒犻櫎浜у搧鎺堟潈鐮佺紪鍙蜂负"' + authorizeIds + '"鐨勬暟鎹」锛�').then(function () { + return delAuthorize(authorizeIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(() => {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download('iot/authorize/export', { + ...this.queryParams + }, `authorize_${new Date().getTime()}.xlsx`) + }, + //绂佺敤鏈夌粦瀹氳澶囩殑澶嶉�夋 + selectable(row) { + return row.deviceId != null ? false : true; + }, + //琛ㄦ牸澧炲姞澶嶅埗鍔熻兘 + celldblclick(row, column, cell, event) { + this.$copyText(row[column.property]).then(e => { + this.onCopy() + }, function (e) { + this.onError() + }) + }, + onCopy() { + this.$notify({ + title: '鎴愬姛', + message: '澶嶅埗鎴愬姛锛�', + type: 'success', + offset: 50, + duration: 2000 + }) + }, + onError() { + this.$notify({ + title: '澶辫触', + message: '澶嶅埗澶辫触锛�', + type: 'error', + offset: 50, + duration: 2000 + }) + }, + } +}; +</script> diff --git a/src/views/iot/product/product-edit.vue b/src/views/iot/product/product-edit.vue new file mode 100644 index 0000000..12866fd --- /dev/null +++ b/src/views/iot/product/product-edit.vue @@ -0,0 +1,560 @@ +<template> + <el-card style="margin:6px;padding-bottom:100px;"> + <el-tabs v-model="activeName" tab-position="left" style="padding:10px;min-height:400px;" @tab-click="tabChange"> + <el-tab-pane name="basic"> + <span slot="label"><span style="color:red;">* </span>鍩烘湰淇℃伅</span> + <el-form ref="form" :model="form" :rules="rules" label-width="100px"> + <el-row :gutter="100"> + <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8"> + <el-form-item label="浜у搧鍚嶇О" prop="productName"> + <el-input v-model="form.productName" placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�" :readonly="form.status == 2" /> + </el-form-item> + <el-form-item label="浜у搧鍒嗙被" prop="categoryId"> + <el-select v-model="form.categoryId" placeholder="璇烽�夋嫨鍒嗙被" @change="selectCategory" + style="width:100%" :disabled="form.status == 2"> + <el-option v-for="category in categoryShortList" :key="category.id" + :label="category.name" :value="category.id"></el-option> + </el-select> + </el-form-item> + <el-form-item label="璁惧绫诲瀷" prop="deviceType"> + <el-select v-model="form.deviceType" placeholder="璇烽�夋嫨璁惧绫诲瀷" :disabled="form.status == 2" + style="width:100%"> + <el-option v-for="dict in dict.type.iot_device_type" :key="dict.value" + :label="dict.label" :value="parseInt(dict.value)"></el-option> + </el-select> + </el-form-item> + <el-form-item label="浼犺緭鍗忚" prop="transport"> + <el-select v-model="form.transport" placeholder="璇烽�夋嫨浼犺緭鍗忚" style="width: 100%" + :disabled="form.status == 2"> + <el-option v-for="dict in dict.type.iot_transport_type" :key="dict.value" + :label="dict.label" :value="dict.value" /> + </el-select> + </el-form-item> + <el-form-item v-if="form.deviceType !== 3" label="缂栫爜鍗忚" prop="protocolCode"> + <el-select v-model="form.protocolCode" placeholder="璇烽�夋嫨缂栫爜鍗忚" style="width: 100%" + :disabled="form.status == 2" @change="changeProductCode"> + <el-option v-for="p in protocolList" :key="p.protocolCode" :label="p.protocolName" + :value="p.protocolCode" /> + </el-select> + </el-form-item> + <el-form-item label="鑱旂綉鏂瑰紡" prop="networkMethod"> + <el-select v-model="form.networkMethod" placeholder="璇烽�夋嫨鑱旂綉鏂瑰紡" style="width:100%;" + :disabled="form.status == 2"> + <el-option v-for="dict in dict.type.iot_network_method" :key="dict.value" + :label="dict.label" :value="parseInt(dict.value)"></el-option> + </el-select> + </el-form-item> + + <el-form-item label="澶囨敞淇℃伅" prop="remark"> + <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" rows="3" + :readonly="form.status == 2" /> + </el-form-item> + </el-col> + <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8"> + <el-form-item label="鍚敤鎺堟潈" prop="networkMethod"> + <el-switch v-model="form.isAuthorize" @change="changeIsAuthorize(form.isAuthorize)" + :active-value="1" :inactive-value="0" + :disabled="form.status == 2 || form.deviceType == 3" /> + </el-form-item> + <el-form-item label="璁よ瘉鏂瑰紡" prop="vertificateMethod"> + <el-select v-model="form.vertificateMethod" placeholder="璇烽�夋嫨璁よ瘉鏂瑰紡" style="width:100%" + :disabled="form.status == 2 || form.deviceType == 3"> + <el-option v-for="dict in dict.type.iot_vertificate_method" :key="dict.value" + :label="dict.label" :value="parseInt(dict.value)"></el-option> + </el-select> + </el-form-item> + <el-form-item label="浜у搧缂栧彿" prop="productId"> + <el-input v-model="form.productId" placeholder="鑷姩鐢熸垚" + :disabled="!form.mqttAccount || form.deviceType == 3" readonly /> + </el-form-item> + <el-form-item label="Mqtt璐﹀彿" prop="mqttAccount"> + <el-input v-model="form.mqttAccount" placeholder="涓嶅~鑷姩鐢熸垚" :disabled="form.deviceType == 3" + :readonly="accountInputType == 'password'" :type="accountInputType"> + <el-button slot="append" icon="el-icon-view" style="font-size:18px;" + @click="changeInputType('account')"></el-button> + </el-input> + </el-form-item> + <el-form-item label="Mqtt瀵嗙爜" prop="mqttPassword"> + <el-input v-model="form.mqttPassword" placeholder="涓嶅~鍒欒嚜鍔ㄧ敓鎴�" :disabled="form.deviceType == 3" + :readonly="passwordInputType == 'password'" :type="passwordInputType"> + <el-button slot="append" icon="el-icon-view" style="font-size:18px;" + @click="changeInputType('password')"></el-button> + </el-input> + </el-form-item> + <el-form-item label="浜у搧绉橀挜" prop="mqttSecret"> + <el-input v-model="form.mqttSecret" placeholder="鑷姩鐢熸垚" + :disabled="!form.mqttAccount || form.deviceType == 3" readonly :type="keyInputType"> + <el-button slot="append" icon="el-icon-view" style="font-size:18px;" + @click="changeInputType('key')"></el-button> + </el-input> + </el-form-item> + </el-col> + <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="8"> + <el-form-item label="浜у搧鍥剧墖"> + <div v-if="form.status == 2 && form.imgUrl == null"> + <el-image style="height:145px;height:145px;border-radius:10px;" + :preview-src-list="[require('@/assets/images/gateway.png')]" + :src="require('@/assets/images/gateway.png')" fit="cover" + v-if="form.deviceType == 2"></el-image> + <el-image style="height:145px;height:145px;border-radius:10px;" + :preview-src-list="[require('@/assets/images/video.png')]" + :src="require('@/assets/images/video.png')" fit="cover" + v-else-if="form.deviceType == 3"></el-image> + <el-image style="height:145px;height:145px;border-radius:10px;" + :preview-src-list="[require('@/assets/images/product.png')]" + :src="require('@/assets/images/product.png')" fit="cover" v-else></el-image> + </div> + <div v-else> + <imageUpload ref="image-upload" :disabled="true" :value="form.imgUrl" + :limit="form.status == 2 ? 0 : 1" :fileSize="1" @input="getImagePath($event)"> + </imageUpload> + </div> + <div class="el-upload__tip" style="color:#f56c6c" + v-if="form.productId == null || form.productId == 0">鎻愮ず锛氫笂浼犲悗闇�瑕佹彁浜や繚瀛�</div> + </el-form-item> + </el-col> + </el-row> + + <el-col :span="20"> + <el-form-item style="text-align: center;margin:40px 0px;"> + <el-button type="primary" @click="submitForm" v-hasPermi="['iot:product:edit']" + v-show="form.productId != 0 && form.status != 2">淇� 鏀�</el-button> + <el-button type="primary" @click="submitForm" v-hasPermi="['iot:product:add']" + v-show="form.productId == 0 && form.status != 2">鏂� 澧�</el-button> + </el-form-item> + </el-col> + </el-form> + </el-tab-pane> + + <el-tab-pane label="" name="things" :disabled="form.productId == 0"> + <span slot="label"><span style="color:red;">* </span>浜у搧妯″瀷</span> + <product-things-model ref="productThingsModel" :product="form" /> + </el-tab-pane> + + <el-tab-pane label="" name="productAuthorize" :disabled="form.productId == 0" v-if="form.deviceType !== 3"> + <span slot="label">璁惧鎺堟潈</span> + <product-authorize ref="productAuthorize" :product="form" /> + </el-tab-pane> + + <el-tab-pane label="" name="alert" :disabled="form.productId == 0" v-if="form.deviceType !== 3"> + <span slot="label"><span style="color:red;">锟� </span>鍛婅閰嶇疆</span> + <business ref="business"/> + </el-tab-pane> + + + <div style="margin-top:200px;"></div> + + <!-- 鐢ㄤ簬璁剧疆闂磋窛 --> + <el-tab-pane> + <span slot="label"> + <div style="margin-top:200px;"></div> + </span> + </el-tab-pane> + + <el-tab-pane v-if="form.status == 1" name="product04" disabled> + <span slot="label"> + <el-button type="success" size="mini" @click="changeProductStatus(2)" + v-hasPermi="['iot:product:add']">鍙戝竷浜у搧</el-button> + </span> + </el-tab-pane> + <el-tab-pane v-if="form.status == 2" name="product05" disabled> + <span slot="label"> + <el-button type="danger" size="mini" @click="changeProductStatus(1)" + v-hasPermi="['iot:product:edit']">鍙栨秷鍙戝竷</el-button> + </span> + </el-tab-pane> + <el-tab-pane name="product06" disabled> + <span slot="label"> + <el-button type="info" size="mini" @click="goBack()">杩斿洖鍒楄〃</el-button> + </span> + </el-tab-pane> + </el-tabs> + + </el-card> +</template> + +<script> +import productThingsModel from "./product-things-model"; +import productApp from "./product-app" +import productAuthorize from "./product-authorize" +import imageUpload from "../../../components/ImageUpload/index" +import business from "../business/index" +import { + listProtocol +} from "@/api/iot/protocol"; + +import { + listShortCategory, +} from "@/api/iot/category"; +import { + getProduct, + addProduct, + updateProduct, + changeProductStatus, + deviceCount, +} from "@/api/iot/product"; + +import { + getAllPoints +} from "@/api/iot/template"; + +export default { + name: "ProductEdit", + dicts: ['iot_device_type', 'iot_network_method', 'iot_vertificate_method', 'iot_transport_type', 'data_collect_type'], + components: { + productThingsModel, + productApp, + productAuthorize, + imageUpload, + business, + }, + data() { + return { + // 杈撳叆妗嗙被鍨� + keyInputType: "password", + accountInputType: "password", + passwordInputType: "password", + // 閫変腑閫夐」鍗� + activeName: 'basic', + // 鍒嗙被鐭垪琛� + categoryShortList: [], + //鍗忚鍒楄〃 + protocolList: [], + // 琛ㄥ崟鍙傛暟 + form: { + networkMethod: 1, + deviceType: 1, + vertificateMethod: 3, + transport: 'MQTT', + imgUrl: "", + }, + // 琛ㄥ崟鏍¢獙 + rules: { + productName: [{ + required: true, + message: "浜у搧鍚嶇О涓嶈兘涓虹┖", + trigger: "blur", + + }, + { + min: 1, + max: 64, + message: '浜у搧鍚嶇О涓嶈兘灏戜簬1涓瓧绗﹀拰瓒呰繃64瀛楃', + trigger: 'blur', + }, + ], + categoryId: [{ + required: true, + message: "浜у搧鍒嗙被ID涓嶈兘涓虹┖", + trigger: "blur" + }], + deviceType: [{ + required: true, + message: "璇烽�夋嫨璁惧绫诲瀷", + trigger: "blur" + }], + protocolCode: [{ + required: true, + message: "璁惧鍗忚涓嶈兘涓虹┖", + trigger: "blur" + }], + transport: [{ + required: true, + message: "浼犺緭鍗忚涓嶈兘涓虹┖", + trigger: 'blur' + }] + }, + // 鏌ヨ鍙傛暟 + queryParams: { + tenantName: null, + }, + pointList: [], + open: false, + // 寮瑰嚭灞傛爣棰� + title: "", + loading: true, + tempList: [], + // 鎬绘潯鏁� + total: 0, + tempTotal: 0, + // 鏌ヨ鍙傛暟 + pointsParams: { + pageNum: 1, + pageSize: 8, + templateId: 0, + }, + tempParams: { + pageNum: 1, + pageSize: 10, + }, + currentRow: {}, + selectRowData: {}, + isModbus: false, + + }; + }, + created() { + // 鑾峰彇浜у搧淇℃伅 + const productId = this.$route.query && this.$route.query.productId; + this.form.productId = productId; + if (this.form.productId != 0 && this.form.productId != null) { + this.getProduct(); + } + // 鍒囨崲閫夐」鍗� + const tabPanelName = this.$route.query && this.$route.query.tabPanelName; + if (tabPanelName != null && tabPanelName != '') { + this.activeName = tabPanelName; + } + // 鑾峰彇鍒嗙被淇℃伅 + this.getShortCategory(); + // 璁剧疆璐﹀彿瀵嗙爜杈撳叆妗嗙被鍨�,鏂板鏃朵负text锛屾煡鐪嬫椂涓簆assword + if (!this.form.productId || this.form.productId == 0) { + this.accountInputType = "text"; + this.passwordInputType = "text"; + } + this.getProtocol(); + }, + activated() { + const time = this.$route.query.t; + if (time != null && time != this.uniqueId) { + this.uniqueId = time; + } + // 鑾峰彇浜у搧淇℃伅 + let productId = this.$route.query.productId + if (productId != null && productId != 0) { + this.form.productId = Number(productId); + this.getProduct(); + this.getShortCategory(); + } + // 鍒囨崲閫夐」鍗� + const tabPanelName = this.$route.query && this.$route.query.tabPanelName; + if (tabPanelName != null && tabPanelName != '') { + this.activeName = tabPanelName; + } + + }, + methods: { + // 鑾峰彇绠�鐭垎绫诲垪琛� + getShortCategory() { + listShortCategory().then(response => { + this.categoryShortList = response.data; + }) + }, + /** 杩斿洖鎸夐挳 */ + goBack() { + const obj = { + path: "/iot/product", + query: { + t: Date.now(), + pageNum: this.$route.query.pageNum + } + }; + this.$tab.closeOpenPage(obj); + this.reset(); + }, + /** 鑾峰彇浜у搧淇℃伅 */ + getProduct() { + getProduct(this.form.productId).then(response => { + this.form = response.data; + this.changeProductCode(this.form.protocolCode); + }); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + productId: 0, + productName: null, + categoryId: null, + categoryName: null, + status: 0, + tslJson: null, + isAuthorize: 0, + deviceType: 1, + networkMethod: 1, + vertificateMethod: 3, + mqttAccount: null, + mqttPassword: null, + mqttSecret: null, + remark: null, + imgUrl: "", + }; + this.resetForm("form"); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.productId != null && this.form.productId != 0) { + updateProduct(this.form).then(response => { + this.changeProductCode(this.form.protocolCode); + this.$modal.alertSuccess("淇敼鎴愬姛"); + }); + } else { + addProduct(this.form).then(response => { + if (!this.form.isModbus) { + this.$modal.alertSuccess("娣诲姞鎴愬姛,鍙互寮�濮嬪畾涔夌墿妯″瀷鎴栭厤缃�"); + } else { + this.$modal.alertSuccess("鐗╂ā鍨嬪凡缁忎粠閲囬泦鐐规ā鏉垮悓姝ヨ嚦浜у搧") + } + this.form = response.data; + this.changeProductCode(this.form.protocolCode); + }); + } + } + }); + }, + /**鍚屾鑾峰彇浜у搧涓嬬殑璁惧鏁伴噺**/ + getDeviceCountByProductId(productId) { + return new Promise((resolve, reject) => { + deviceCount(productId).then(res => { + resolve(res); + }).catch(error => { + reject(error); + }) + }) + }, + /** 鏇存柊浜у搧鐘舵�� */ + async changeProductStatus(status) { + let message = "纭畾鍙栨秷鍙戝竷锛�"; + if (status == 2) { + message = "浜у搧鍙戝竷鍚庯紝鍙互鍒涘缓瀵瑰簲鐨勮澶�"; + } else if (status == 1) { + let result = await this.getDeviceCountByProductId(this.form.productId); + if (result.data > 0) { + message = "閲嶈鎻愮ず锛氫骇鍝佷笅宸叉湁 " + result.data + " 涓澶囷紝鍙栨秷鍙戝竷鍙互淇敼浜у搧淇℃伅鍜屾ā鍨嬶紝閲嶆柊鍙戝竷鍚庡搴旇澶囩姸鎬佸皢浼氳閲嶇疆锛�" + } + } + this.$confirm(message, '鎻愮ず', { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning' + }).then(() => { + let data = {}; + data.productId = this.form.productId; + data.status = status; + data.deviceType = this.form.deviceType; + changeProductStatus(data).then(response => { + this.$modal.alertSuccess(response.msg); + this.activeName = "basic"; + this.getProduct(); + }).catch(() => { + if (status == 2) { + this.activeName = "basic"; + } else { + this.goBack(); + } + }); + }).catch(() => { + this.activeName = "basic"; + }); + }, + /** 閫夋嫨鍒嗙被 */ + selectCategory(val) { + for (var i = 0; i < this.categoryShortList.length; i++) { + if (this.categoryShortList[i].id == val) { + this.form.categoryName = this.categoryShortList[i].name; + return; + } + } + }, + /**鑾峰彇涓婁紶鍥剧墖鐨勮矾寰� */ + getImagePath(data) { + this.form.imgUrl = data; + }, + /**鏀瑰彉杈撳叆妗嗙被鍨�**/ + changeInputType(name) { + if (name == "key") { + this.keyInputType = this.keyInputType == "password" ? "text" : "password"; + } else if (name == "account") { + this.accountInputType = this.accountInputType == "password" ? "text" : "password"; + } else if (name == "password") { + this.passwordInputType = this.passwordInputType == "password" ? "text" : "password"; + } + }, + // 鎺堟潈鐮佺姸鎬佷慨鏀� + changeIsAuthorize() { + let text = this.form.isAuthorize == "1" ? "鍚敤" : "鍋滅敤"; + this.$modal.confirm('纭瑕�' + text + '鎺堟潈鐮佸悧锛�').then(() => { + if (this.form.productId != null && this.form.productId != 0) { + updateProduct(this.form).then(response => { + this.$modal.alertSuccess("鎺堟潈鐮佸凡" + text); + }); + } + }).catch(() => { + this.form.isAuthorize = 0; + }); + }, + //鑾峰彇璁惧鍗忚 + getProtocol() { + const data = { + protocolStatus: 1 + }; + listProtocol(data).then(res => { + this.protocolList = res.rows; + }) + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + // this.reset(); + }, + getList() { + getAllPoints(this.pointsParams).then(response => { + this.pointList = response.rows; + this.total = response.total; + }); + }, + changeProductCode(val) { + if (val && val.startsWith("MODBUS")) { + this.form.deviceType = 2; + this.form.isModbus = true; + if (this.form.productId != 0 && this.form.productId != null) { + //this.getTempDetail() + } + } else { + this.form.isModbus = false; + } + }, + /**閫夐」鍗″垏鎹簨浠�**/ + tabChange(tabItem) { + // 鍒囨崲鍒板憡璀﹂厤缃紝鑾峰彇鐗╂ā鍨� + if (tabItem.paneName == "alert") { + //this.$refs.productAlert.getCacheThingsModel(this.form.productId); + } + }, + + /*鎸夌収妯℃澘鍚嶆煡璇�*/ + queryTemp() { + this.getTempList(); + }, + + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.tempParams.pageNum = 1 + this.getTempList() + }, + + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm('tempParams') + this.handleQuery() + }, + } +}; +</script> + +<style> +.el-aside { + margin: 0; + padding: 0; + background-color: #fff; + color: #333; +} + +.el-main { + margin: 0; + padding: 0 10px; + background-color: #fff; + color: #333; +} +</style> diff --git a/src/views/iot/product/product-select-template.vue b/src/views/iot/product/product-select-template.vue new file mode 100644 index 0000000..1436feb --- /dev/null +++ b/src/views/iot/product/product-select-template.vue @@ -0,0 +1,125 @@ +<template> + <div style="margin-top:-50px;"> + <el-divider></el-divider> + <el-form :model="queryParams" ref="product-select-template" :inline="true" label-width="48px"> + <el-form-item label="鍚嶇О" prop="templateName"> + <el-input v-model="queryParams.templateName" placeholder="璇疯緭鍏ョ墿妯″瀷鍚嶇О" clearable size="small" + @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="绫诲埆" prop="type"> + <el-select v-model="queryParams.type" placeholder="璇烽�夋嫨妯″瀷绫诲埆" clearable size="small"> + <el-option v-for="dict in dict.type.iot_things_type" :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-table v-loading="loading" :data="templateList" @selection-change="handleSelectionChange" + ref="selectTemplateTable" size="small"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="鍚嶇О" align="center" prop="templateName" /> + <el-table-column label="鏍囪瘑绗�" align="center" prop="identifier" /> + <el-table-column label="鐗╂ā鍨嬬被鍒�" align="center" prop="type"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_things_type" :value="scope.row.type" /> + </template> + </el-table-column> + <el-table-column label="鍥捐〃灞曠ず" align="center" prop="isChart" width="75"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isChart" /> + </template> + </el-table-column> + <el-table-column label="瀹炴椂鐩戞祴" align="center" prop="isMonitor" width="75"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isMonitor" /> + </template> + </el-table-column> + <el-table-column label="鍙" align="center" prop="isReadonly" width="75"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isReadonly" /> + </template> + </el-table-column> + <el-table-column label="鍘嗗彶瀛樺偍" align="center" prop="isHistory" width="75"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isHistory" /> + </template> + </el-table-column> + <el-table-column label="鏁版嵁绫诲瀷" align="center" prop="datatype"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_data_type" :value="scope.row.datatype" /> + </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 { + listTemplate, +} from "@/api/iot/template"; +export default { + name: "product-select-template", + dicts: ["iot_things_type", "iot_data_type", "iot_yes_no"], + data() { + return { + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鎬绘潯鏁� + total: 0, + // 閫氱敤鐗╂ā鍨嬭〃鏍兼暟鎹� + templateList: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + templateName: null, + type: null, + }, + }; + }, + created() { + this.getList(); + this.ids = []; + }, + methods: { + /** 鏌ヨ閫氱敤鐗╂ā鍨嬪垪琛� */ + getList() { + this.loading = true; + listTemplate(this.queryParams).then((response) => { + this.templateList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("product-select-template"); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map((item) => item.templateId); + this.single = selection.length !== 1; + this.multiple = !selection.length; + // Id鏁扮粍浼犻�掑埌鐖剁粍浠� + this.$emit('idsToParentEvent', this.ids); + }, + }, +}; +</script> diff --git a/src/views/iot/product/product-things-model.vue b/src/views/iot/product/product-things-model.vue new file mode 100644 index 0000000..ab46afd --- /dev/null +++ b/src/views/iot/product/product-things-model.vue @@ -0,0 +1,984 @@ +<template> + <div style="padding-left: 20px"> + <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-if="productInfo.status == 1">鏂板</el-button> + </el-col> + <el-col :span="1.5"> + <el-button type="success" plain icon="el-icon-upload2" size="mini" @click="handleSelect" + v-if="productInfo.status == 1">瀵煎叆閫氱敤鐗╂ā鍨�</el-button> + </el-col> + <el-col :span="1.5"> + <el-button type="warning" plain icon="el-icon-refresh" size="mini" @click="getList">鍒锋柊</el-button> + </el-col> + <el-col :span="1.5"> + <el-button type="info" plain icon="el-icon-view" size="mini" @click="handleOpenThingsModel">鏌ョ湅鐗╂ā鍨�</el-button> + </el-col> + <el-col :span="1.5"> + <el-link type="danger" style="padding-top: 5px" :underline="false">娉ㄦ剰锛氭爣璇嗙涓嶈兘閲嶅</el-link> + </el-col> + </el-row> + + <el-table v-loading="loading" :data="modelList" size="mini"> + <el-table-column label="鍚嶇О" align="center" prop="modelName" width="230" /> + <el-table-column label="鏍囪瘑绗�" align="center" prop="identifier" /> + <el-table-column label="鍥捐〃灞曠ず" align="center" prop="" width="80"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isChart" /> + </template> + </el-table-column> + <el-table-column label="瀹炴椂鐩戞祴" align="center" prop="" width="75"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isMonitor" /> + </template> + </el-table-column> + <el-table-column label="鍙" align="center" prop="" width="75"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isReadonly" /> + </template> + </el-table-column> + <el-table-column label="鍘嗗彶瀛樺偍" align="center" prop="" width="75"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isHistory" /> + </template> + </el-table-column> + <el-table-column label="鐗╂ā鍨嬬被鍒�" align="center" prop="type" width="100"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_things_type" :value="scope.row.type" /> + </template> + </el-table-column> + <el-table-column label="鏁版嵁绫诲瀷" align="center" prop="datatype" width="80"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_data_type" :value="scope.row.datatype" /> + </template> + </el-table-column> + <el-table-column label="鏁版嵁瀹氫箟" align="left" header-align="center" prop="specs" min-width="150" + class-name="specsColor"> + <template slot-scope="scope"> + <div v-html="formatSpecsDisplay(scope.row.specs)"></div> + </template> + </el-table-column> + <el-table-column label="璁$畻鍏紡" align="center" prop="formula" /> + <el-table-column label="鎺掑簭" align="center" prop="modelOrder" width="80" /> + <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-if="productInfo.status != 2">淇敼</el-button> + <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" + v-if="productInfo.status != 2">鍒犻櫎</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="100px"> + <el-form-item label="妯″瀷鍚嶇О" prop="modelName"> + <el-input v-model="form.modelName" placeholder="璇疯緭鍏ョ墿妯″瀷鍚嶇О锛屼緥濡傦細娓╁害" style="width: 385px" /> + </el-form-item> + <el-form-item label="妯″瀷鏍囪瘑" prop="identifier"> + <el-input v-model="form.identifier" placeholder="璇疯緭鍏ユ爣璇嗙锛屼緥濡傦細temperature" style="width: 385px" /> + </el-form-item> + <el-form-item label="妯″瀷鎺掑簭" prop="modelOrder"> + <el-input-number v-model="form.modelOrder" placeholder="璇疯緭鍏ユ帓搴�" type="number" style="width: 386px" + controls-position="right" /> + </el-form-item> + <el-form-item label="妯″瀷绫诲埆" prop="type"> + <el-radio-group v-model="form.type" @change="typeChange(form.type)"> + <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-form-item label="妯″瀷鐗规��" prop="property"> + <el-checkbox name="isChart" label="鍥捐〃灞曠ず" @change="isChartChange" v-show="form.type == 1" v-model="form.isChart" + :true-label="1" :false-label="0"></el-checkbox> + <el-checkbox name="isMonitor" label="瀹炴椂鐩戞祴" @change="isMonitorChange" v-show="form.type == 1" + v-model="form.isMonitor" :true-label="1" :false-label="0"></el-checkbox> + <el-checkbox name="isReadonly" label="鍙鏁版嵁" @change="isReadonlyChange" :disabled="form.type == 3" + v-model="form.isReadonly" :true-label="1" :false-label="0"></el-checkbox> + <el-checkbox name="isHistory" label="鍘嗗彶瀛樺偍" v-model="form.isHistory" :true-label="1" + :false-label="0"></el-checkbox> + <el-checkbox name="isSharePerm" label="鍒嗕韩鏉冮檺" v-model="form.isSharePerm" :true-label="1" + :false-label="0"></el-checkbox> + </el-form-item> + <el-divider></el-divider> + <el-form-item label="鏁版嵁绫诲瀷" prop="datatype"> + <el-select v-model="form.datatype" placeholder="璇烽�夋嫨鏁版嵁绫诲瀷" @change="dataTypeChange" style="width: 175px"> + <el-option key="integer" label="鏁存暟" value="integer"></el-option> + <el-option key="decimal" label="灏忔暟" value="decimal"></el-option> + <el-option key="bool" label="甯冨皵" value="bool" :disabled="form.isChart == 1"></el-option> + <el-option key="enum" label="鏋氫妇" value="enum" :disabled="form.isChart == 1"></el-option> + <el-option key="string" label="瀛楃涓�" value="string" :disabled="form.isChart == 1"></el-option> + <el-option key="array" label="鏁扮粍" value="array" :disabled="form.isChart == 1"></el-option> + <el-option key="object" label="瀵硅薄" value="object" :disabled="form.isChart == 1"></el-option> + </el-select> + </el-form-item> + <el-form-item label="鍙栧�艰寖鍥�" v-if="form.datatype == 'integer'"> + <el-row> + <el-col :span="9"> + <el-input v-model="form.specs.min" placeholder="鏈�灏忓��" controls-position="right" type="number" + style="width: 174px;" @input="handleEdit" /> + </el-col> + <el-col :span="2" align="center">鍒�</el-col> + <el-col :span="9"> + <el-input v-model="form.specs.max" placeholder="鏈�澶у��" type="number" controls-position="right" + style="width: 174px;" @input="handleEditmax" /> + </el-col> + </el-row> + </el-form-item> + <el-form-item label="鍙栧�艰寖鍥�" v-if="form.datatype == 'decimal'"> + <el-row> + <el-col :span="9"> + <el-input v-model="form.specs.min" placeholder="鏈�灏忓��" controls-position="right" type="number" + style="width: 174px;" /> + </el-col> + <el-col :span="2" align="center">鍒�</el-col> + <el-col :span="9"> + <el-input v-model="form.specs.max" placeholder="鏈�澶у��" type="number" controls-position="right" + style="width: 174px;" /> + </el-col> + </el-row> + </el-form-item> + <div v-if="form.datatype == 'integer' || form.datatype == 'decimal'"> + <el-form-item label="鍗曚綅"> + <el-input v-model="form.specs.unit" placeholder="璇疯緭鍏ュ崟浣嶏紝渚嬪锛氣剝" style="width: 385px" /> + </el-form-item> + <el-form-item label="姝ラ暱"> + <el-input-number v-model="form.specs.step" placeholder="璇疯緭鍏ユ闀匡紝渚嬪锛�1" type="number" style="width: 386px" + controls-position="right" /> + </el-form-item> + <el-form-item label="璁$畻鍏紡" prop="formula"> + <template slot="label"> + <span>璁$畻鍏紡</span> + <el-tooltip style="cursor: pointer" effect="light" placement="top"> + <div slot="content"> + 璁惧涓婅鏁版嵁缁忚绠楀叕寮忚绠楀悗鏄剧ず 銆� + <br /> + 鍏紡涓殑%s涓哄崰浣嶇锛屾槸鍥哄畾瀛楁銆� + <br /> + 濡傦細 + <br /> + 鍔狅細%s+10 + <br /> + 鍑忥細%s-10 + <br /> + 涔橈細%s*10 + <br /> + 闄わ細%s/10 + <br /> + 浣欐暟锛�%s%10 + <br /> + </div> + <i class="el-icon-question" /> + </el-tooltip> + </template> + <el-input v-model="form.formula" style="width: 385px" /> + </el-form-item> + </div> + + <div v-if="form.datatype == 'bool'"> + <el-form-item label="甯冨皵鍊�" prop=""> + <el-row style="margin-bottom: 10px"> + <el-col :span="9"> + <el-input v-model="form.specs.falseText" placeholder="渚嬪锛氬叧闂�" /> + </el-col> + <el-col :span="10" :offset="1">锛�0 鍊煎搴旀枃鏈級</el-col> + </el-row> + <el-row> + <el-col :span="9"> + <el-input v-model="form.specs.trueText" placeholder="渚嬪锛氭墦寮�" /> + </el-col> + <el-col :span="10" :offset="1">锛�1 鍊煎搴旀枃鏈級</el-col> + </el-row> + </el-form-item> + </div> + + <div v-if="form.datatype == 'enum'"> + <el-form-item label="灞曠ず鏂瑰紡"> + <el-select v-model="form.specs.showWay" placeholder="璇烽�夋嫨灞曠ず鏂瑰紡" style="width: 175px"> + <el-option key="select" label="涓嬫媺妗�" value="select"></el-option> + <el-option key="button" label="鎸夐挳" value="button"></el-option> + </el-select> + </el-form-item> + <el-form-item label="鏋氫妇椤�" prop=""> + <el-row v-for="(item, index) in form.specs.enumList" :key="'enum' + index" style="margin-bottom: 10px"> + <el-col :span="9"> + <el-input v-model="item.value" placeholder="鍙傛暟鍊硷紝渚嬪锛�0" /> + </el-col> + <el-col :span="11" :offset="1"> + <el-input v-model="item.text" placeholder="鍙傛暟鎻忚堪锛屼緥濡傦細涓�熸。浣�" /> + </el-col> + <el-col :span="2" :offset="1" v-if="index != 0"><a style="color: #f56c6c" + @click="removeEnumItem(index)">鍒犻櫎</a></el-col> + </el-row> + <div> + + + <a style="color: #409eff" @click="addEnumItem()">娣诲姞鏋氫妇椤�</a> + </div> + </el-form-item> + </div> + + <div v-if="form.datatype == 'string'"> + <el-form-item label="鏈�澶ч暱搴�" prop=""> + <el-row> + <el-col :span="9"> + <el-input v-model="form.specs.maxLength" placeholder="渚嬪锛�1024" type="number" /> + </el-col> + <el-col :span="14" :offset="1">锛堝瓧绗︿覆鐨勬渶澶ч暱搴︼級</el-col> + </el-row> + </el-form-item> + </div> + + <div v-if="form.datatype == 'array'"> + <el-form-item label="鍏冪礌涓暟" prop=""> + <el-row> + <el-col :span="9"> + <el-input v-model="form.specs.arrayCount" placeholder="渚嬪锛�5" type="number" /> + </el-col> + </el-row> + </el-form-item> + <el-form-item label="鏁扮粍绫诲瀷" prop=""> + <el-radio-group v-model="form.specs.arrayType"> + <el-radio label="integer">鏁存暟</el-radio> + <el-radio label="decimal">灏忔暟</el-radio> + <el-radio label="string">瀛楃涓�</el-radio> + <el-radio label="object">瀵硅薄</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="瀵硅薄鍙傛暟" v-if="form.specs.arrayType == 'object'"> + <div style="background-color: #f8f8f8; border-radius: 5px"> + <el-row style="padding: 0 10px 5px" v-for="(item, index) in form.specs.params" :key="index"> + <div style="margin-top: 5px" v-if="index == 0"></div> + <el-col :span="18"> + <el-input readonly v-model="item.name" size="mini" placeholder="璇烽�夋嫨璁惧" style="margin-top: 3px"> + <template slot="prepend"> + <el-tag size="mini" effect="dark" style="margin-left: -21px; height: 26px; line-height: 26px">{{ + item.order }}</el-tag> + {{ form.identifier + '_' + item.id }} + </template> + <el-button slot="append" @click="editParameter(item, index)" size="small">缂栬緫</el-button> + </el-input> + </el-col> + <el-col :span="2" :offset="2"> + <el-button size="small" plain type="danger" style="padding: 5px" icon="el-icon-delete" + @click="removeParameter(index)">鍒犻櫎</el-button> + </el-col> + </el-row> + </div> + <div> + + + <a style="color: #409eff" @click="addParameter()">娣诲姞鍙傛暟</a> + </div> + </el-form-item> + </div> + <div v-if="form.datatype == 'object'"> + <el-form-item label="瀵硅薄鍙傛暟" prop=""> + <div style="background-color: #f8f8f8; border-radius: 5px"> + <el-row style="padding: 0 10px 5px" v-for="(item, index) in form.specs.params" :key="index"> + <div style="margin-top: 5px" v-if="index == 0"></div> + <el-col :span="18"> + <el-input readonly v-model="item.name" size="mini" placeholder="璇烽�夋嫨璁惧" style="margin-top: 3px"> + <template slot="prepend"> + <el-tag size="mini" effect="dark" style="margin-left: -21px; height: 26px; line-height: 26px">{{ + item.order }}</el-tag> + {{ form.identifier + '_' + item.id }} + </template> + <el-button slot="append" @click="editParameter(item, index)" size="small">缂栬緫</el-button> + </el-input> + </el-col> + <el-col :span="2" :offset="2"> + <el-button size="small" plain type="danger" style="padding: 5px" icon="el-icon-delete" + @click="removeParameter(index)">鍒犻櫎</el-button> + </el-col> + </el-row> + </div> + <div> + + + <a style="color: #409eff" @click="addParameter()">娣诲姞鍙傛暟</a> + </div> + </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> + + <!--鐗╂ā鍨嬪弬鏁扮被鍨�--> + <things-parameter :data="paramData" @dataEvent="getParamData($event)" /> + + <!-- 瀵煎叆閫氱敤鐗╂ā鍨嬪璇濇 --> + <el-dialog :title="title" :visible.sync="openSelect" width="800px" append-to-body> + <product-select-template ref="productSelectTemplate" @idsToParentEvent="getChildData($event)" /> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="importSelect">瀵� 鍏�</el-button> + <el-button @click="cancelSelect">鍙� 娑�</el-button> + </div> + </el-dialog> + + <!-- 鐗╂ā鍨婮SON --> + <el-dialog :title="title" :visible.sync="openThingsModel" width="600px" append-to-body> + <div style="border: 1px solid #ccc; margin-top: -15px; height: 600px; overflow: scroll"> + <json-viewer :value="thingsModel" :expand-depth="10" copyable> + <template v-slot:copy>澶嶅埗</template> + </json-viewer> + </div> + <div slot="footer" class="dialog-footer"> + <el-button type="info" @click="handleCloseThingsModel">鍏� 闂�</el-button> + </div> + </el-dialog> + </div> +</template> + +<style> +.specsColor { + background-color: #fcfcfc; +} +</style> + +<script> +import productSelectTemplate from './product-select-template'; +import JsonViewer from 'vue-json-viewer'; +import 'vue-json-viewer/style.css'; +import thingsParameter from '../template/parameter'; +import { listModel, getModel, delModel, addModel, updateModel, importModel } from '@/api/iot/model'; + +export default { + name: 'product-things-model', + dicts: ['iot_things_type', 'iot_data_type', 'iot_yes_no'], + components: { + productSelectTemplate, + thingsParameter, + JsonViewer, + }, + props: { + product: { + type: Object, + default: null, + }, + }, + watch: { + // 鑾峰彇鍒扮埗缁勪欢浼犻�掔殑productId鍚庯紝鍒锋柊鍒楄〃 + product: function (newVal, oldVal) { + this.productInfo = newVal; + if (this.productInfo && this.productInfo.productId != 0) { + this.queryParams.productId = this.productInfo.productId; + this.queryParams.isModbus = this.productInfo.isModbus; + this.getList(); + } + }, + }, + data() { + return { + // 鐗╂ā鍨� + thingsModel: {}, + // 鐖剁粍浠舵帴鏀剁殑浜у搧淇℃伅 + productInfo: {}, + // 瀛愮粍浠堕�変腑鐨刬d鏁扮粍 + templateIds: [], + // 閬僵灞� + loading: false, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 浜у搧鐗╂ā鍨嬭〃鏍兼暟鎹� + modelList: [], + //鏄惁涓哄皬鏁扮殑鍒ゆ柇 + isDecimal: '', + isDecimalMax: '', + // 寮瑰嚭灞傛爣棰� + title: '', + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + openSelect: false, + openThingsModel: false, + // 鏌ヨ鍙傛暟 + queryParams: { + productId: 0, + pageNum: 1, + pageSize: 100, + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 瀵硅薄绫诲瀷鍙傛暟 + paramData: { + index: -1, + parameter: {}, + }, + //鏄惁鏄痬odbus + isModbus: false, + slaveList: [], + slave: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + modelName: [ + { + required: true, + message: '鐗╂ā鍨嬪悕绉颁笉鑳戒负绌�', + trigger: 'blur', + }, + { + min: 1, + max: 64, + message: '鐗╂ā鍨嬪悕绉颁笉鑳藉皯浜�1涓瓧绗﹀拰瓒呰繃64瀛楃', + trigger: 'blur', + }, + ], + identifier: [ + { + required: true, + message: '鏍囪瘑绗︼紝浜у搧涓嬪敮涓�涓嶈兘涓虹┖', + trigger: 'blur', + }, + { + min: 1, + max: 32, + message: '妯″瀷鏍囪瘑涓嶈兘灏戜簬1涓瓧绗﹀拰瓒呰繃32瀛楃', + trigger: 'blur', + }, + ], + modelOrder: [ + { + required: true, + message: '妯″瀷鎺掑簭涓嶈兘涓虹┖', + trigger: 'blur', + }, { + type: 'number', + min: -2147483648, + max: 2147483647, + message: '鎺掑簭涓嶈兘瓒呰繃int鍨嬬殑鑼冨洿鍊�( -2^31鈥斺��2^31-1)', + trigger: 'blur', + }, + ], + type: [ + { + required: true, + message: '妯″瀷绫诲埆涓嶈兘涓虹┖', + trigger: 'change', + }, + + ], + datatype: [ + { + required: true, + message: '鏁版嵁绫诲瀷涓嶈兘涓虹┖', + trigger: 'change', + }, + ], + }, + }; + }, + created() { }, + methods: { + /** 鏌ヨ浜у搧鐗╂ā鍨嬪垪琛� */ + getList() { + this.loading = true; + listModel(this.queryParams).then((response) => { + this.modelList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + templateId: null, + templateName: null, + userId: null, + userName: null, + tenantId: null, + tenantName: null, + identifier: null, + modelOrder: 0, + type: 1, + datatype: 'integer', + isSys: null, + isChart: 1, + isHistory: 1, + isSharePerm: 1, + isMonitor: 1, + isReadonly: 1, + delFlag: null, + createBy: null, + createTime: null, + updateBy: null, + updateTime: null, + remark: null, + specs: { + enumList: [ + { + value: '', + text: '', + }, + ], + arrayType: 'integer', + arrayCount: 5, + showWay: 'select', // 鏄剧ず鏂瑰紡select=涓嬫媺閫夋嫨妗嗭紝button=鎸夐挳 + params: [], + }, + }; + this.resetForm('form'); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm('queryForm'); + this.handleQuery(); + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = '娣诲姞鐗╂ā鍨�'; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const modelId = row.modelId; + getModel(modelId).then((response) => { + let tempForm = response.data; + this.open = true; + this.title = '淇敼鐗╂ā鍨�'; + // Json杞璞� + tempForm.specs = JSON.parse(tempForm.specs); + if (!tempForm.specs.enumList) { + tempForm.specs.showWay = 'select'; + tempForm.specs.enumList = [ + { + value: '', + text: '', + }, + ]; + } + if (!tempForm.specs.arrayType) { + tempForm.specs.arrayType = 'integer'; + } + if (!tempForm.specs.arrayCount) { + tempForm.specs.arrayCount = 5; + } + if (!tempForm.specs.params) { + tempForm.specs.params = []; + } + // 瀵硅薄鍜屾暟缁勪腑鍙傛暟鍒犻櫎鍓嶇紑 + if ((tempForm.specs.type == 'array' && tempForm.specs.arrayType == 'object') || tempForm.specs.type == 'object') { + for (let i = 0; i < tempForm.specs.params.length; i++) { + tempForm.specs.params[i].id = String(tempForm.specs.params[i].id).substring(String(tempForm.identifier).length + 1); + } + } + this.form = tempForm; + }); + }, + /**鏌ョ湅鐗╂ā鍨� */ + handleOpenThingsModel() { + this.title = '鐗╂ā鍨�'; + // 鐢熸垚鐗╂ā鍨� + this.thingsModel = { + properties: [], + functions: [], + events: [], + }; + for (var i = 0; i < this.modelList.length; i++) { + let thingsItem = {}; + thingsItem.id = this.modelList[i].identifier; + thingsItem.name = this.modelList[i].modelName; + if (this.modelList[i].type == 1) { + //灞炴�� + thingsItem.isChart = this.modelList[i].isChart; + thingsItem.isMonitor = this.modelList[i].isMonitor; + thingsItem.isHistory = this.modelList[i].isHistory; + thingsItem.isSharePerm = this.modelList[i].isSharePerm; + thingsItem.isReadonly = this.modelList[i].isReadonly; + thingsItem.datatype = JSON.parse(this.modelList[i].specs); + this.thingsModel.properties.push(thingsItem); + } else if (this.modelList[i].type == 2) { + // 鍔熻兘 + thingsItem.isHistory = this.modelList[i].isHistory; + thingsItem.isSharePerm = this.modelList[i].isSharePerm; + thingsItem.isReadonly = this.modelList[i].isReadonly; + thingsItem.datatype = JSON.parse(this.modelList[i].specs); + this.thingsModel.functions.push(thingsItem); + } else if (this.modelList[i].type == 3) { + // 浜嬩欢 + thingsItem.isHistory = this.modelList[i].isHistory; + thingsItem.isSharePerm = this.modelList[i].isSharePerm; + thingsItem.isReadonly = this.modelList[i].isReadonly; + thingsItem.datatype = JSON.parse(this.modelList[i].specs); + this.thingsModel.events.push(thingsItem); + } + } + + this.openThingsModel = true; + }, + /**鍏抽棴鐗╂ā鍨� */ + handleCloseThingsModel() { + this.openThingsModel = false; + }, + /** 閫夋嫨鐗╂ā鍨� */ + handleSelect() { + this.openSelect = true; + this.title = '瀵煎叆閫氱敤鐗╂ā鍨�'; + this.form.type = 1; + this.form.datatype = 'integer'; + this.form.specs = { + enumList: [], + }; + }, + // 鍙栨秷瀵煎叆閫氱敤鐗╂ā鍨嬫寜閽� + cancelSelect() { + this.openSelect = false; + this.$refs.productSelectTemplate.$refs.selectTemplateTable.clearSelection(); + }, + // 鑾峰彇瀛愮粍浠剁殑鍊� + getChildData(data) { + this.templateIds = data; + }, + // 瀵煎叆閫氱敤鐗╂ā鍨嬫寜閽� + importSelect() { + if (this.templateIds != null && this.templateIds.length > 0) { + var importData = { + productId: this.productInfo.productId, + productName: this.productInfo.productName, + templateIds: this.templateIds, + }; + importModel(importData).then((response) => { + this.$modal.msgSuccess(response.msg); + this.openSelect = false; + this.$refs.productSelectTemplate.$refs.selectTemplateTable.clearSelection(); + this.getList(); + }); + } + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + this.$refs['form'].validate((valid) => { + if (valid) { + // 楠岃瘉瀵硅薄鎴栧璞℃暟缁勪腑鐨勫弬鏁颁笉鑳戒负绌� + if (this.form.datatype == 'object' || (this.form.datatype == 'array' && this.form.specs.arrayType == 'object')) { + if (!this.form.specs.params || this.form.specs.params == 0) { + this.$modal.msgError('瀵硅薄鐨勫弬鏁颁笉鑳戒负绌�'); + return; + } + } + // 楠岃瘉瀵硅薄鍙傛暟鏍囪瘑绗︿笉鑳界浉鍚� + if (this.form.specs.params && this.form.specs.params.length > 0) { + let arr = this.form.specs.params.map((item) => item.id).sort(); + for (let i = 0; i < arr.length; i++) { + if (arr[i] == arr[i + 1]) { + this.$modal.msgError('鍙傛暟鏍囪瘑 ' + arr[i] + ' 閲嶅'); + return; + } + } + } + //楠岃瘉杈撳叆鐨勫彇鍊艰寖鍥存渶澶у�间笉鑳藉皬浜庢渶灏忓�� + if (this.form.datatype == 'integer' || this.form.datatype == 'decimal') { + if (parseFloat(this.form.specs.min) > parseFloat(this.form.specs.max)) { + this.$modal.msgError('璇烽噸鏂拌緭鍏ュ彇鍊艰寖鍥�,鏈�澶у�间笉鑳芥瘮鏈�灏忓�煎皬!'); + return; + } + } + if (this.form.datatype == 'decimal') { + this.hasDecimalPoint(); + this.hasDecimalPointMax(); + if (this.isDecimal === false || this.isDecimalMax === false) { + this.$modal.msgError('鍙栧�艰寖鍥村繀椤昏緭鍏ュ皬鏁�,璇烽噸鏂拌緭鍏�!'); + return; + } + } + //楠岃瘉妯″瀷鐗规�т负鍥捐〃灞曠ず鏃讹紝鏁版嵁绫诲瀷鏄惁涓烘暣鏁版垨鑰呭皬鏁� + if ((this.form.isChart == 1 && this.form.datatype != 'integer') && (this.form.isChart == 1 && this.form.datatype != 'decimal')) { + this.$modal.msgError('璇烽噸鏂伴�夋嫨鏁版嵁绫诲瀷锛�'); + } + else if (this.form.modelId != null) { + // 鏍煎紡鍖杝pecs + let tempForm = JSON.parse(JSON.stringify(this.form)); + tempForm.specs = this.formatThingsSpecs(); + if (this.form.type == 2) { + tempForm.isMonitor = 0; + tempForm.isChart = 0; + } else if (this.form.type == 3) { + tempForm.isMonitor = 0; + tempForm.isChart = 0; + } + updateModel(tempForm).then((response) => { + this.$modal.msgSuccess('淇敼鎴愬姛'); + this.open = false; + this.getList(); + }); + } else { + // 鏍煎紡鍖杝pecs + let tempForm = JSON.parse(JSON.stringify(this.form)); + tempForm.specs = this.formatThingsSpecs(); + tempForm.productId = this.productInfo.productId; + tempForm.productName = this.productInfo.productName; + if (this.form.type == 2) { + tempForm.isMonitor = 0; + } else if (this.form.type == 3) { + tempForm.isMonitor = 0; + tempForm.isChart = 0; + } + addModel(tempForm).then((response) => { + this.$modal.msgSuccess('鏂板鎴愬姛'); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const modelIds = row.modelId; + // if (!this.queryParams.isModbus) { + this.$modal + .confirm('鏄惁纭鍒犻櫎鐗╂ā鍨嬬紪鍙蜂负"' + modelIds + '"鐨勬暟鎹」锛�') + .then(function () { + return delModel(modelIds); + }) + .then(() => { + this.getList(); + this.$modal.msgSuccess('鍒犻櫎鎴愬姛'); + }) + .catch(() => { }); + // } else { + // this.$modal.alert('閲囬泦鐐瑰垹闄よ鍦ㄩ噰闆嗙偣妯℃澘淇敼'); + // } + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download( + 'iot/model/export', + { + ...this.queryParams, + }, + `model_${new Date().getTime()}.xlsx` + ); + }, + // 绫诲瀷鏀瑰彉 + typeChange(type) { + if (type == 1) { + this.form.isChart = 1; + this.form.isHistory = 1; + this.form.isSharePerm = 1; + this.form.isMonitor = 1; + this.form.isReadonly = 1; + this.form.datatype = 'integer'; + } else if (type == 2) { + this.form.isChart = 0; + this.form.isHistory = 1; + this.form.isSharePerm = 1; + this.form.isMonitor = 0; + this.form.isReadonly = 0; + } else if (type == 3) { + this.form.isChart = 0; + this.form.isHistory = 1; + this.form.isSharePerm = 0; + this.form.isMonitor = 0; + this.form.isReadonly = 1; + } + }, + // 鏄惁鍥捐〃灞曠ず鏀瑰彉 + isChartChange() { + if (this.form.isChart == 1) { + this.form.isReadonly = 1; + } else { + this.form.isMonitor = 0; + } + }, + // 鏄惁瀹炴椂鐩戞祴鏀瑰彉 + isMonitorChange() { + if (this.form.isMonitor == 1) { + this.form.isReadonly = 1; + this.form.isChart = 1; + } + }, + // 鏄惁鍙鏁版嵁鏀瑰彉 + isReadonlyChange() { + if (this.form.isReadonly == 0) { + this.form.isMonitor = 0; + this.form.isChart = 0; + } + }, + // 鏍煎紡鍖栫墿妯″瀷 + formatThingsSpecs() { + var data = {}; + data.type = this.form.datatype; + if (this.form.datatype == 'integer' || this.form.datatype == 'decimal') { + data.min = Number(this.form.specs.min ? this.form.specs.min : 0); + data.max = Number(this.form.specs.max ? this.form.specs.max : 100); + data.unit = this.form.specs.unit ? this.form.specs.unit : ''; + data.step = Number(this.form.specs.step ? this.form.specs.step : 1); + } else if (this.form.datatype == 'string') { + data.maxLength = Number(this.form.specs.maxLength ? this.form.specs.maxLength : 1024); + } else if (this.form.datatype == 'bool') { + data.falseText = this.form.specs.falseText ? this.form.specs.falseText : '鍏抽棴'; + data.trueText = this.form.specs.trueText ? this.form.specs.trueText : '鎵撳紑'; + } else if (this.form.datatype == 'enum') { + data.showWay = this.form.specs.showWay; + if (this.form.specs.enumList && this.form.specs.enumList[0].text != '') { + data.enumList = this.form.specs.enumList; + } else { + data.showWay = 'select'; + data.enumList = [ + { + value: '0', + text: '浣�', + }, + { + value: '1', + text: '楂�', + }, + ]; + } + } else if (this.form.datatype == 'array') { + data.arrayType = this.form.specs.arrayType; + data.arrayCount = this.form.specs.arrayCount ? this.form.specs.arrayCount : 5; + if (data.arrayType == 'object') { + data.params = this.form.specs.params; + // 鐗╂ā鍨嬪悕绉颁綔涓哄弬鏁扮殑鏍囪瘑绗﹀墠缂� + for (let i = 0; i < data.params.length; i++) { + data.params[i].id = this.form.identifier + '_' + data.params[i].id; + } + } + } else if (this.form.datatype == 'object') { + data.params = this.form.specs.params; + // 鐗╂ā鍨嬪悕绉颁綔涓哄弬鏁扮殑鏍囪瘑绗﹀墠缂� + for (let i = 0; i < data.params.length; i++) { + data.params[i].id = this.form.identifier + '_' + data.params[i].id; + } + } + return JSON.stringify(data); + }, + /** 鏁版嵁绫诲瀷鏀瑰彉 */ + dataTypeChange(val) { }, + /** 娣诲姞鏋氫妇椤� */ + addEnumItem() { + this.form.specs.enumList.push({ + value: '', + text: '', + }); + }, + /** 鍒犻櫎鏋氫妇椤� */ + removeEnumItem(index) { + this.form.specs.enumList.splice(index, 1); + }, + /** 鏍煎紡鍖栨樉绀烘暟鎹畾涔� */ + formatSpecsDisplay(json) { + let specs = JSON.parse(json); + if (specs.type === 'integer' || specs.type === 'decimal' || specs.type === 'INT16' || specs.type === 'INT') { + return ( + '<span style=\'width:50%;display:inline-block;\'>鏈�澶у�硷細<span style="color:#F56C6C">' + + specs.max + + '</span></span>鏈�灏忓�硷細<span style="color:#F56C6C">' + + specs.min + + '</span><br /><span style=\'width:50%;display:inline-block;\'>姝ラ暱锛�<span style="color:#F56C6C">' + + specs.step + + '</span></span>鍗曚綅锛�<span style="color:#F56C6C">' + + specs.unit + ); + } else if (specs.type === 'string') { + return '鏈�澶ч暱搴︼細<span style="color:#F56C6C">' + specs.maxLength + '</span>'; + } else if (specs.type === 'array') { + return '<span style=\'width:50%;display:inline-block;\'>鏁扮粍绫诲瀷锛�<span style="color:#F56C6C">' + specs.arrayType + '</span></span>鍏冪礌涓暟锛�<span style="color:#F56C6C">' + specs.arrayCount; + } else if (specs.type === 'enum') { + let items = ''; + for (let i = 0; i < specs.enumList.length; i++) { + items = items + "<span style='width:50%;display:inline-block;'>" + specs.enumList[i].value + "锛�<span style='color:#F56C6C'>" + specs.enumList[i].text + '</span></span>'; + if (i > 0 && i % 2 != 0) { + items = items + '<br />'; + } + } + return items; + } else if (specs.type === 'bool') { + return '<span style=\'width:50%;display:inline-block;\'>0锛�<span style="color:#F56C6C">' + specs.falseText + '</span></span>1锛�<span style="color:#F56C6C">' + specs.trueText; + } else if (specs.type === 'object') { + let items = ''; + for (let i = 0; i < specs.params.length; i++) { + items = items + "<span style='width:50%;display:inline-block;'>" + specs.params[i].name + "锛�<span style='color:#F56C6C'>" + specs.params[i].datatype.type + '</span></span>'; + if (i > 0 && i % 2 != 0) { + items = items + '<br />'; + } + } + return items; + } + }, + /** 娣诲姞鍙傛暟 */ + addParameter() { + this.paramData = { + index: -1, + parameter: {}, + }; + }, + /** 缂栬緫鍙傛暟*/ + editParameter(data, index) { + this.paramData = null; + this.paramData = { + index: index, + parameter: data, + }; + }, + /** 鍒犻櫎鍔ㄤ綔 */ + removeParameter(index) { + this.form.specs.params.splice(index, 1); + }, + /**鑾峰彇璁剧疆鐨勫弬鏁板璞�*/ + getParamData(data) { + if (data.index == -1) { + this.form.specs.params.push(data.parameter); + } else { + this.form.specs.params[data.index] = data.parameter; + // 瑙e喅鏁扮粍鍦ㄧ晫闈腑涓嶆洿鏂伴棶棰� + this.$set(this.form.specs.params, data.index, this.form.specs.params[data.index]); + } + }, + // 鍦ㄨ緭鍏ユ渶灏忓�兼敼鍙樻椂瑙﹀彂 + handleEdit(e) { + let value = e.replace(/[^\-\d]/g, ""); // 鍙兘杈撳叆-鍜屾暟瀛� + value = value.replace(/\-{2,}/g, "-"); // -鍙兘淇濈暀涓�涓� + value = value.replace(/(\d)\-/g, "$1"); // 鏁板瓧鍚庨潰涓嶈兘鎺�-锛屼笉鑳藉嚭鐜扮被浼�-11-2,12-锛�11-23 + value = value.replace(/(-)0+/g, "$1"); // 涓嶈兘鍑虹幇-0,-001,-0001绫讳技 + value = value.replace(/(-\d{10})\d*/, '$1') // 鏈�澶氫繚鐣�10浣嶆暣鏁� + this.form.specs.min = value; + }, + // 鍦ㄨ緭鍏ユ渶澶у�兼敼鍙樻椂瑙﹀彂 + handleEditmax(e) { + let value = e.replace(/[^\-\d]/g, ""); // 鍙兘杈撳叆-鍜屾暟瀛� + value = value.replace(/\-{2,}/g, "-"); // -鍙兘淇濈暀涓�涓� + value = value.replace(/(\d)\-/g, "$1"); // 鏁板瓧鍚庨潰涓嶈兘鎺�-锛屼笉鑳藉嚭鐜扮被浼�-11-2,12-锛�11-23 + value = value.replace(/(-)0+/g, "$1"); // 涓嶈兘鍑虹幇-0,-001,-0001绫讳技 + value = value.replace(/(-\d{10})\d*/, '$1') // 鏈�澶氫繚鐣�10浣嶆暣鏁� + this.form.specs.max = value; + }, + //鏁版嵁绫诲瀷涓哄皬鏁扮殑鏍¢獙 + hasDecimalPoint() { + const regex = /^-?\d+\.\d+$/; // 浣跨敤姝e垯琛ㄨ揪寮忓尮閰嶅皬鏁扮偣鏍煎紡 + this.isDecimal = regex.test(this.form.specs.min); + return this.isDecimal; + }, + hasDecimalPointMax() { + const regex = /^-?\d+\.\d+$/; // 浣跨敤姝e垯琛ㄨ揪寮忓尮閰嶅皬鏁扮偣鏍煎紡 + this.isDecimalMax = regex.test(this.form.specs.max); + return this.isDecimalMax; + }, + }, +}; +</script> diff --git a/src/views/iot/protocol/index.vue b/src/views/iot/protocol/index.vue new file mode 100644 index 0000000..f641ede --- /dev/null +++ b/src/views/iot/protocol/index.vue @@ -0,0 +1,234 @@ +<template> +<div style="padding:6px;"> + <el-card v-show="showSearch" style="margin-bottom:6px;"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom:-20px;"> + <el-form-item label="鍗忚鍚嶇О" prop="protocolName"> + <el-input v-model="queryParams.protocolName" placeholder="璇疯緭鍏ュ崗璁悕绉�" clearable size="small" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="鍗忚缂栫爜" prop="protocolCode"> + <el-input v-model="queryParams.protocolCode" placeholder="璇疯緭鍏ュ崗璁紪鐮�" clearable size="small" @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-card> + + <el-card style="padding-bottom:100px;"> + <el-table v-loading="loading" :data="protocolList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="鍗忚鍚嶇О" align="center" prop="protocolName" /> + <el-table-column label="鍗忚缂栫爜" align="center" prop="protocolCode" /> + <el-table-column label="涓婁紶鍦板潃" align="center" prop="protocolFileUrl" /> + <el-table-column label="鍗忚绫诲瀷" align="center" prop="protocolType" /> + <el-table-column label="鍗忚鎽樿" align="center" prop="jarSign" /> + </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="600px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="100px"> + <el-form-item label="鍗忚鍚嶇О" prop="protocolName"> + <el-input v-model="form.protocolName" placeholder="璇疯緭鍏ュ崗璁悕绉�" /> + </el-form-item> + <el-form-item label="鍗忚缂栫爜" prop="protocolCode"> + <el-input v-model="form.protocolCode" placeholder="璇疯緭鍏ュ崗璁紪鐮�" /> + </el-form-item> + <el-form-item label="涓婁紶鍦板潃" prop="protocolFileUrl"> + <el-input v-model="form.protocolFileUrl" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�" /> + </el-form-item> + <el-form-item label="鍗忚鎽樿" prop="jarSign"> + <el-input v-model="form.jarSign" placeholder="璇疯緭鍏ュ崗璁枃浠舵憳瑕�(鏂囦欢鐨刴d5)" /> + </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> + + </el-card> +</div> +</template> + +<script> +import { + listProtocol, + getProtocol, + delProtocol, + addProtocol, + updateProtocol +} from "@/api/iot/protocol"; + +export default { + name: "Protocol", + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 鍗忚琛ㄦ牸鏁版嵁 + protocolList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + protocolCode: null, + protocolName: null, + protocolFileUrl: null, + protocolType: null, + jarSign: null, + protocolStatus: null, + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + protocolCode: [{ + required: true, + message: "鍗忚缂栫爜涓嶈兘涓虹┖", + trigger: "blur" + }], + protocolName: [{ + required: true, + message: "鍗忚鍚嶇О涓嶈兘涓虹┖", + trigger: "blur" + }], + protocolFileUrl: [{ + required: true, + message: "鍗忚涓婁紶鍦板潃涓嶈兘涓虹┖", + trigger: "blur" + }], + protocolType: [{ + required: true, + message: "鍗忚绫诲瀷涓嶈兘涓虹┖", + trigger: "change" + }], + jarSign: [{ + required: true, + message: "鍗忚鎽樿涓嶈兘涓虹┖", + trigger: "blur" + }] + } + }; + }, + created() { + this.getList(); + }, + methods: { + /** 鏌ヨ鍗忚鍒楄〃 */ + getList() { + this.loading = true; + listProtocol(this.queryParams).then(response => { + this.protocolList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + id: null, + protocolCode: null, + protocolName: null, + protocolFileUrl: null, + protocolType: null, + jarSign: null, + createTime: null, + updateTime: null, + protocolStatus: 0, + delFlag: 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.title = "娣诲姞鍗忚"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const id = row.id || this.ids + getProtocol(id).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼鍗忚"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.id != null) { + updateProtocol(this.form).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + }); + } else { + addProtocol(this.form).then(response => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const ids = row.id || this.ids; + this.$modal.confirm('鏄惁纭鍒犻櫎鍗忚缂栧彿涓�"' + ids + '"鐨勬暟鎹」锛�').then(function () { + return delProtocol(ids); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(() => {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download('iot/protocol/export', { + ...this.queryParams + }, `protocol_${new Date().getTime()}.xlsx`) + } + } +}; +</script> diff --git a/src/views/iot/template/index.vue b/src/views/iot/template/index.vue new file mode 100644 index 0000000..9da8859 --- /dev/null +++ b/src/views/iot/template/index.vue @@ -0,0 +1,889 @@ +<template> + <div style="padding: 6px"> + <el-card v-show="showSearch" style="margin-bottom: 5px"> + <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px" style="margin-bottom: -20px"> + <el-form-item label="妯″瀷鍚嶇О" prop="templateName"> + <el-input v-model="queryParams.templateName" placeholder="璇疯緭鍏ユā鍨嬪悕绉�" clearable size="small" + @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item label="妯″瀷绫诲埆" prop="type"> + <el-select v-model="queryParams.type" placeholder="璇烽�夋嫨妯″瀷绫诲埆" clearable size="small"> + <el-option v-for="dict in dict.type.iot_things_type" :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-item style="float: right"> + <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" + v-hasPermi="['iot:template:add']">鏂板</el-button> + </el-form-item> + </el-form> + </el-card> + + <el-card style="padding-bottom: 100px"> + <el-table v-loading="loading" :data="templateList" @selection-change="handleSelectionChange" border> + <el-table-column label="妯″瀷鍚嶇О" align="center" prop="templateName" /> + <el-table-column label="鏍囪瘑绗�" align="center" prop="identifier" /> + <el-table-column label="鍥捐〃灞曠ず" align="center" prop="isMonitor" width="75"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isChart" /> + </template> + </el-table-column> + <el-table-column label="瀹炴椂鐩戞祴" align="center" prop="" width="75"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isMonitor" /> + </template> + </el-table-column> + <el-table-column label="鍙" align="center" prop="" width="75"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isReadonly" /> + </template> + </el-table-column> + <el-table-column label="鍘嗗彶瀛樺偍" align="center" prop="" width="75"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isHistory" /> + </template> + </el-table-column> + <el-table-column label="绯荤粺瀹氫箟" align="center" prop="isSys" width="80"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_yes_no" :value="scope.row.isSys" /> + </template> + </el-table-column> + <el-table-column label="鐗╂ā鍨嬬被鍒�" align="center" prop="type" width="100"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_things_type" :value="scope.row.type" /> + </template> + </el-table-column> + <el-table-column label="鏁版嵁绫诲瀷" align="center" prop="datatype" width="80"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_data_type" :value="scope.row.datatype" /> + </template> + </el-table-column> + <el-table-column label="鏁版嵁瀹氫箟" align="left" header-align="center" prop="specs" min-width="150" + class-name="specsColor"> + <template slot-scope="scope"> + <div v-html="formatSpecsDisplay(scope.row.specs)"></div> + </template> + </el-table-column> + <el-table-column label="鎺掑簭" align="center" prop="modelOrder" width="80" /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="200"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{m}:{s}') }}</span> + </template> + </el-table-column> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width" width="150"> + <template slot-scope="scope"> + <el-button size="small" type="primary" style="padding: 5px" icon="el-icon-edit" + @click="handleUpdate(scope.row)" v-hasPermi="['iot:template:query']" + v-if="scope.row.isSys == '0' ? true : !isTenant"> + 淇敼 + </el-button> + <el-button size="small" type="danger" style="padding: 5px" icon="el-icon-delete" + @click="handleDelete(scope.row)" v-hasPermi="['iot:template:remove']" + v-if="scope.row.isSys == '0' ? true : !isTenant"> + 鍒犻櫎 + </el-button> + <span style="font-size: 10px; color: #999" v-if="scope.row.isSys == '1' && isTenant">绯荤粺瀹氫箟锛屼笉鑳戒慨鏀�</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-dialog :title="title" :visible.sync="open" width="600px" append-to-body :close-on-click-modal="false"> + <el-form ref="form" :model="form" :rules="rules" label-width="100px"> + <el-form-item label="妯″瀷鍚嶇О" prop="templateName"> + <el-input v-model="form.templateName" placeholder="璇疯緭鍏ユā鍨嬪悕绉帮紝渚嬪锛氭俯搴�" style="width: 385px" /> + </el-form-item> + <el-form-item label="妯″瀷鏍囪瘑" prop="identifier"> + <el-input v-model="form.identifier" placeholder="璇疯緭鍏ユ爣璇嗙锛屼緥濡傦細temperature" style="width: 385px" /> + </el-form-item> + <el-form-item label="妯″瀷鎺掑簭" prop="modelOrder"> + <el-input-number controls-position="right" v-model="form.modelOrder" placeholder="璇疯緭鍏ユ帓搴�" + style="width: 386px" /> + </el-form-item> + <el-form-item label="妯″瀷绫诲埆" prop="type"> + <el-radio-group v-model="form.type" @change="typeChange(form.type)"> + <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-form-item label="妯″瀷鐗规��" prop="property"> + <el-row> + <el-col :span="6"> + <el-tooltip effect="dark" content="璁惧璇︽儏涓互鍥捐〃鏂瑰紡灞曠ず" placement="top"> + <el-checkbox name="isChart" label="鍥捐〃灞曠ず" @change="isChartChange" v-show="form.type == 1" + v-model="form.isChart" :true-label="1" :false-label="0"></el-checkbox> + </el-tooltip> + </el-col> + <el-col :span="6"> + <el-tooltip effect="dark" content="瀹炴椂鏄剧ず鐩戞祴鏁版嵁锛屼絾鏄笉浼氬瓨鍌ㄥ埌鏁版嵁搴�" placement="top"> + <el-checkbox name="isMonitor" label="瀹炴椂鐩戞祴" @change="isMonitorChange" v-show="form.type == 1" + v-model="form.isMonitor" :true-label="1" :false-label="0"></el-checkbox> + </el-tooltip> + </el-col> + <el-col :span="6"> + <el-tooltip effect="dark" content="璁惧涓婃姤鏁版嵁锛屼絾鏄钩鍙颁笉鑳戒笅鍙戞寚浠�" placement="top"> + <el-checkbox name="isReadonly" label="鍙鏁版嵁" @change="isReadonlyChange" :disabled="form.type == 3" + v-model="form.isReadonly" :true-label="1" :false-label="0"></el-checkbox> + </el-tooltip> + </el-col> + <el-col :span="6"> + <el-tooltip effect="dark" content="璁惧涓婃姤鐨勬暟鎹細瀛樺偍鍒版暟鎹簱浣滀负鍘嗗彶鏁版嵁" placement="top"> + <el-checkbox name="isHistory" label="鍘嗗彶瀛樺偍" v-model="form.isHistory" :true-label="1" + :false-label="0"></el-checkbox> + </el-tooltip> + </el-col> + <el-col :span="6"> + <el-tooltip effect="dark" content="璁惧鍒嗕韩鏃堕渶瑕佹寚瀹氭槸鍚︽嫢鏈夎鏉冮檺" placement="top"> + <el-checkbox name="isSharePerm" label="鍒嗕韩鏉冮檺" v-model="form.isSharePerm" :true-label="1" + :false-label="0"></el-checkbox> + </el-tooltip> + </el-col> + </el-row> + </el-form-item> + + <el-divider></el-divider> + <el-form-item label="鏁版嵁绫诲瀷" prop="datatype"> + <el-select v-model="form.datatype" placeholder="璇烽�夋嫨鏁版嵁绫诲瀷" @change="dataTypeChange" style="width: 175px"> + <el-option key="integer" label="鏁存暟" value="integer"></el-option> + <el-option key="decimal" label="灏忔暟" value="decimal"></el-option> + <el-option key="bool" label="甯冨皵" value="bool" :disabled="form.isChart == 1"></el-option> + <el-option key="enum" label="鏋氫妇" value="enum" :disabled="form.isChart == 1"></el-option> + <el-option key="string" label="瀛楃涓�" value="string" :disabled="form.isChart == 1"></el-option> + <el-option key="array" label="鏁扮粍" value="array" :disabled="form.isChart == 1"></el-option> + <el-option key="object" label="瀵硅薄" value="object" :disabled="form.isChart == 1"></el-option> + </el-select> + </el-form-item> + <div> + <el-form-item label="鍙栧�艰寖鍥�" v-if="form.datatype == 'integer'"> + <el-row> + <el-col :span="9"> + <el-input v-model="form.specs.min" placeholder="鏈�灏忓��" controls-position="right" type="number" + style="width: 174px;" @input="handleEdit" /> + </el-col> + <el-col :span="2" align="center">鍒�</el-col> + <el-col :span="9"> + <el-input v-model="form.specs.max" placeholder="鏈�澶у��" type="number" controls-position="right" + style="width: 174px;" @input="handleEditmax" /> + </el-col> + </el-row> + </el-form-item> + <el-form-item label="鍙栧�艰寖鍥�" v-if="form.datatype == 'decimal'"> + <el-row> + <el-col :span="9"> + <el-input v-model="form.specs.min" placeholder="鏈�灏忓��" controls-position="right" type="number" + style="width: 174px;" /> + </el-col> + <el-col :span="2" align="center">鍒�</el-col> + <el-col :span="9"> + <el-input v-model="form.specs.max" placeholder="鏈�澶у��" type="number" controls-position="right" + style="width: 174px;" /> + </el-col> + </el-row> + </el-form-item> + <el-form-item label="鍗曚綅" prop="unit" v-if="form.datatype == 'integer' || form.datatype == 'decimal'"> + <el-input v-model="form.specs.unit" placeholder="璇疯緭鍏ュ崟浣嶏紝渚嬪锛氣剝" style="width: 385px" /> + </el-form-item> + <el-form-item label="姝ラ暱" prop="step" v-if="form.datatype == 'integer' || form.datatype == 'decimal'"> + <el-input controls-position="right" v-model="form.specs.step" placeholder="璇疯緭鍏ユ闀匡紝渚嬪锛�1" type="number" + style="width: 386px" /> + </el-form-item> + </div> + <div v-if="form.datatype == 'bool'"> + <el-form-item label="甯冨皵鍊�" prop=""> + <el-row style="margin-bottom: 10px"> + <el-col :span="9"> + <el-input v-model="form.specs.falseText" placeholder="渚嬪锛氬叧闂�" /> + </el-col> + <el-col :span="10" :offset="1">锛�0 鍊煎搴旀枃鏈級</el-col> + </el-row> + <el-row> + <el-col :span="9"> + <el-input v-model="form.specs.trueText" placeholder="渚嬪锛氭墦寮�" /> + </el-col> + <el-col :span="10" :offset="1">锛�1 鍊煎搴旀枃鏈級</el-col> + </el-row> + </el-form-item> + </div> + <div v-if="form.datatype == 'enum'"> + <el-form-item label="灞曠ず鏂瑰紡"> + <el-select v-model="form.specs.showWay" placeholder="璇烽�夋嫨灞曠ず鏂瑰紡" style="width: 175px"> + <el-option key="select" label="涓嬫媺妗�" value="select"></el-option> + <el-option key="button" label="鎸夐挳" value="button"></el-option> + </el-select> + </el-form-item> + <el-form-item label="鏋氫妇椤�" prop=""> + <el-row v-for="(item, index) in form.specs.enumList" :key="'enum' + index" style="margin-bottom: 10px"> + <el-col :span="9"> + <el-input v-model="item.value" placeholder="鍙傛暟鍊硷紝渚嬪锛�0" /> + </el-col> + <el-col :span="11" :offset="1"> + <el-input v-model="item.text" placeholder="鍙傛暟鎻忚堪锛屼緥濡傦細涓�熸。浣�" /> + </el-col> + <el-col :span="2" :offset="1" v-if="index != 0"><a style="color: #f56c6c" + @click="removeEnumItem(index)">鍒犻櫎</a></el-col> + </el-row> + <div> + + + <a style="color: #409eff" @click="addEnumItem()">娣诲姞鏋氫妇椤�</a> + </div> + </el-form-item> + </div> + <div v-if="form.datatype == 'string'"> + <el-form-item label="鏈�澶ч暱搴�" prop=""> + <el-row> + <el-col :span="9"> + <el-input v-model="form.specs.maxLength" placeholder="渚嬪锛�1024" type="number" /> + </el-col> + <el-col :span="14" :offset="1">锛堝瓧绗︿覆鐨勬渶澶ч暱搴︼級</el-col> + </el-row> + </el-form-item> + </div> + <div v-if="form.datatype == 'array'"> + <el-form-item label="鍏冪礌涓暟" prop=""> + <el-row> + <el-col :span="9"> + <el-input v-model="form.specs.arrayCount" placeholder="渚嬪锛�5" type="number" /> + </el-col> + </el-row> + </el-form-item> + <el-form-item label="鏁扮粍绫诲瀷" prop=""> + <el-radio-group v-model="form.specs.arrayType"> + <el-radio label="integer">鏁存暟</el-radio> + <el-radio label="decimal">灏忔暟</el-radio> + <el-radio label="string">瀛楃涓�</el-radio> + <el-radio label="object">瀵硅薄</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item label="瀵硅薄鍙傛暟" v-if="form.specs.arrayType == 'object'"> + <div style="background-color: #f8f8f8; border-radius: 5px"> + <el-row style="padding: 0 10px 5px" v-for="(item, index) in form.specs.params" :key="index"> + <div style="margin-top: 5px" v-if="index == 0"></div> + <el-col :span="18"> + <el-input readonly v-model="item.name" size="mini" placeholder="璇烽�夋嫨璁惧" style="margin-top: 3px"> + <template slot="prepend"> + <el-tag size="mini" effect="dark" style="margin-left: -21px; height: 26px; line-height: 26px">{{ + item.order }}</el-tag> + {{ form.identifier + '_' + item.id }} + </template> + <el-button slot="append" @click="editParameter(item, index)" size="small">缂栬緫</el-button> + </el-input> + </el-col> + <el-col :span="2" :offset="2"> + <el-button size="small" plain type="danger" style="padding: 5px" icon="el-icon-delete" + @click="removeParameter(index)">鍒犻櫎</el-button> + </el-col> + </el-row> + </div> + <div> + + + <a style="color: #409eff" @click="addParameter()">娣诲姞鍙傛暟</a> + </div> + </el-form-item> + </div> + <div v-if="form.datatype == 'object'"> + <el-form-item label="瀵硅薄鍙傛暟" prop=""> + <div style="background-color: #f8f8f8; border-radius: 5px"> + <el-row style="padding: 0 10px 5px" v-for="(item, index) in form.specs.params" :key="index"> + <div style="margin-top: 5px" v-if="index == 0"></div> + <el-col :span="18"> + <el-input readonly v-model="item.name" size="mini" placeholder="璇烽�夋嫨璁惧" style="margin-top: 3px"> + <template slot="prepend"> + <el-tag size="mini" effect="dark" style="margin-left: -21px; height: 26px; line-height: 26px">{{ + item.order }}</el-tag> + {{ form.identifier + '_' + item.id }} + </template> + <el-button slot="append" @click="editParameter(item, index)">缂栬緫</el-button> + </el-input> + </el-col> + <el-col :span="2" :offset="2"> + <el-button size="small" plain type="danger" style="padding: 5px" icon="el-icon-delete" + @click="removeParameter(index)">鍒犻櫎</el-button> + </el-col> + </el-row> + </div> + <div> + + + <a style="color: #409eff" @click="addParameter()">娣诲姞鍙傛暟</a> + </div> + </el-form-item> + </div> + </el-form> + + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm" v-hasPermi="['iot:template:edit']" v-show="form.templateId">淇� + 鏀�</el-button> + <el-button type="primary" @click="submitForm" v-hasPermi="['iot:template:add']" v-show="!form.templateId">鏂� + 澧�</el-button> + <el-button @click="cancel">鍙� 娑�</el-button> + </div> + </el-dialog> + + <!--鐗╂ā鍨嬪弬鏁扮被鍨�--> + <things-parameter :data="paramData" @dataEvent="getParamData($event)" /> + </el-card> + </div> +</template> + +<style> +.specsColor { + background-color: #fcfcfc; +} +</style> + +<script> +import { listTemplate, getTemplate, delTemplate, addTemplate, updateTemplate } from '@/api/iot/template'; +import thingsParameter from './parameter'; +export default { + name: 'Template', + dicts: ['iot_things_type', 'iot_data_type', 'iot_yes_no'], + components: { + thingsParameter, + }, + data() { + return { + // 鏄惁涓虹鎴� + isTenant: false, + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + //鏄惁涓哄皬鏁扮殑鍒ゆ柇 + isDecimal: '', + isDecimalMax: '', + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 閫氱敤鐗╂ā鍨嬭〃鏍兼暟鎹� + templateList: [], + // 寮瑰嚭灞傛爣棰� + title: '', + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + templateName: null, + type: null, + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 瀵硅薄绫诲瀷鍙傛暟 + paramData: { + index: -1, + parameter: {}, + }, + // 琛ㄥ崟鏍¢獙 + rules: { + templateName: [ + { + required: true, + message: '妯″瀷鍚嶇О涓嶈兘涓虹┖', + trigger: 'blur', + }, + { + min: 1, + max: 64, + message: '妯″瀷鍚嶇О涓嶈兘灏戜簬1涓瓧绗﹀拰瓒呰繃64瀛楃', + trigger: 'blur', + }, + ], + identifier: [ + { + required: true, + message: '鏍囪瘑绗︼紝浜у搧涓嬪敮涓�涓嶈兘涓虹┖', + trigger: 'blur', + }, + { + min: 1, + max: 32, + message: '鏍囪瘑绗︿笉鑳藉皯浜�1涓瓧绗﹀拰瓒呰繃32瀛楃', + trigger: 'blur', + }, + ], + modelOrder: [ + { + required: true, + message: '妯″瀷鎺掑簭涓嶈兘涓虹┖', + trigger: 'blur', + }, + { + type: 'number', + min: -2147483648, + max: 2147483647, + message: '鎺掑簭涓嶈兘瓒呰繃int鍨嬬殑鑼冨洿鍊�( -2^31鈥斺��2^31-1)', + trigger: 'blur', + }, + ], + type: [ + { + required: true, + message: '妯″瀷绫诲埆涓嶈兘涓虹┖', + trigger: 'change', + }, + ], + datatype: [ + { + required: true, + message: '鏁版嵁绫诲瀷涓嶈兘涓虹┖', + trigger: 'change', + }, + ], + + }, + }; + }, + created() { + this.getList(); + this.init(); + }, + methods: { + init() { + if (this.$store.state.user.roles.indexOf('tenant') !== -1) { + this.isTenant = true; + } + }, + /** 鏌ヨ閫氱敤鐗╂ā鍨嬪垪琛� */ + getList() { + this.loading = true; + listTemplate(this.queryParams).then((response) => { + this.templateList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + templateId: null, + templateName: null, + userId: null, + userName: null, + tenantId: null, + tenantName: null, + identifier: null, + modelOrder: 0, + type: 1, + datatype: 'integer', + isSys: null, + isChart: 1, + isHistory: 1, + isMonitor: 1, + isReadonly: 1, + isSharePerm: 1, + delFlag: null, + createBy: null, + createTime: null, + updateBy: null, + updateTime: null, + remark: null, + specs: { + enumList: [ + { + value: '', + text: '', + }, + ], + arrayType: 'integer', + arrayCount: 5, + showWay: 'select', // 鏄剧ず鏂瑰紡select=涓嬫媺閫夋嫨妗嗭紝button=鎸夐挳 + params: [], + }, + }; + this.resetForm('form'); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm('queryForm'); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map((item) => item.templateId); + this.single = selection.length !== 1; + this.multiple = !selection.length; + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = '娣诲姞閫氱敤鐗╂ā鍨�'; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const templateId = row.templateId || this.ids; + getTemplate(templateId).then((response) => { + let tempForm = response.data; + this.open = true; + this.title = '淇敼閫氱敤鐗╂ā鍨�'; + // Json杞璞� + tempForm.specs = JSON.parse(tempForm.specs); + if (!tempForm.specs.enumList) { + tempForm.specs.showWay = 'select'; + tempForm.specs.enumList = [ + { + value: '', + text: '', + }, + ]; + } + if (!tempForm.specs.arrayType) { + tempForm.specs.arrayType = 'integer'; + } + if (!tempForm.specs.arrayCount) { + tempForm.specs.arrayCount = 5; + } + if (!tempForm.specs.params) { + tempForm.specs.params = []; + } + // 瀵硅薄鍜屾暟缁勪腑鍙傛暟鍒犻櫎鍓嶇紑 + if ((tempForm.specs.type == 'array' && tempForm.specs.arrayType == 'object') || tempForm.specs.type == 'object') { + for (let i = 0; i < tempForm.specs.params.length; i++) { + tempForm.specs.params[i].id = String(tempForm.specs.params[i].id).substring(String(tempForm.identifier).length + 1); + } + } + this.form = tempForm; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + this.$refs['form'].validate((valid) => { + if (valid) { + // 楠岃瘉瀵硅薄鎴栧璞℃暟缁勪腑鐨勫弬鏁颁笉鑳戒负绌� + if (this.form.datatype == 'object' || (this.form.datatype == 'array' && this.form.specs.arrayType == 'object')) { + if (!this.form.specs.params || this.form.specs.params == 0) { + this.$modal.msgError('瀵硅薄鐨勫弬鏁颁笉鑳戒负绌�'); + return; + } + } + //楠岃瘉杈撳叆鐨勫彇鍊艰寖鍥存渶澶у�间笉鑳藉皬浜庢渶灏忓�� + if (this.form.datatype == 'integer' || this.form.datatype == 'decimal') { + if (parseFloat(this.form.specs.min) > parseFloat(this.form.specs.max)) { + this.$modal.msgError('璇烽噸鏂拌緭鍏ュ彇鍊艰寖鍥�,鏈�澶у�间笉鑳芥瘮鏈�灏忓�煎皬!'); + return; + } + } + if (this.form.datatype == 'decimal') { + this.hasDecimalPoint(); + this.hasDecimalPointMax(); + if (this.isDecimal === false || this.isDecimalMax === false) { + this.$modal.msgError('鍙栧�艰寖鍥村繀椤昏緭鍏ュ皬鏁�,璇烽噸鏂拌緭鍏�!'); + return; + } + } + // 楠岃瘉瀵硅薄鍙傛暟鏍囪瘑绗︿笉鑳界浉鍚� + if (this.form.specs.params && this.form.specs.params.length > 0) { + let arr = this.form.specs.params.map((item) => item.id).sort(); + for (let i = 0; i < arr.length; i++) { + if (arr[i] == arr[i + 1]) { + this.$modal.msgError('鍙傛暟鏍囪瘑 ' + arr[i] + ' 閲嶅'); + return; + } + } + } + //楠岃瘉妯″瀷鐗规�т负鍥捐〃灞曠ず鏃讹紝鏁版嵁绫诲瀷鏄惁涓烘暣鏁版垨鑰呭皬鏁� + if ((this.form.isChart == 1 && this.form.datatype != 'integer') && (this.form.isChart == 1 && this.form.datatype != 'decimal')) { + this.$modal.msgError('璇烽噸鏂伴�夋嫨鏁版嵁绫诲瀷锛�'); + } + else if (this.form.templateId != null) { + // 鏍煎紡鍖杝pecs + let tempForm = JSON.parse(JSON.stringify(this.form)); + tempForm.specs = this.formatThingsSpecs(); + if (this.form.type == 2) { + tempForm.isMonitor = 0; + tempForm.isChart = 0; + } else if (this.form.type == 3) { + tempForm.isMonitor = 0; + tempForm.isChart = 0; + } + // 娣诲姞閫氱敤鐗╂ā鍨嬬殑淇敼鑰� + tempForm.updateBy = this.$store.state.user.name; + updateTemplate(tempForm).then((response) => { + this.$modal.msgSuccess('淇敼鎴愬姛'); + this.open = false; + this.getList(); + }); + } else { + // 鏍煎紡鍖杝pecs + let tempForm = JSON.parse(JSON.stringify(this.form)); + tempForm.specs = this.formatThingsSpecs(); + if (this.form.type == 2) { + tempForm.isMonitor = 0; + } else if (this.form.type == 3) { + tempForm.isMonitor = 0; + tempForm.isChart = 0; + } + // 娣诲姞閫氱敤鐗╂ā鍨嬬殑鍒涢�犺�� + tempForm.createBy = this.$store.state.user.name; + addTemplate(tempForm).then((response) => { + this.$modal.msgSuccess('鏂板鎴愬姛'); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const templateIds = row.templateId || this.ids; + this.$modal + .confirm('鏄惁纭鍒犻櫎閫氱敤鐗╂ā鍨嬬紪鍙蜂负"' + templateIds + '"鐨勬暟鎹」锛�') + .then(function () { + return delTemplate(templateIds); + }) + .then(() => { + this.getList(); + this.$modal.msgSuccess('鍒犻櫎鎴愬姛'); + }) + .catch(() => { }); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download( + 'iot/template/export', + { + ...this.queryParams, + }, + `template_${new Date().getTime()}.xlsx` + ); + }, + // 绫诲瀷鏀瑰彉 + typeChange(type) { + if (type == 1) { + this.form.isChart = 1; + this.form.isHistory = 1; + this.form.isMonitor = 1; + this.form.isReadonly = 1; + this.form.isSharePerm = 1; + this.form.datatype = 'integer'; + } else if (type == 2) { + this.form.isChart = 0; + this.form.isHistory = 1; + this.form.isSharePerm = 1; + this.form.isMonitor = 0; + this.form.isReadonly = 0; + } else if (type == 3) { + this.form.isChart = 0; + this.form.isHistory = 1; + this.form.isMonitor = 0; + this.form.isReadonly = 1; + this.form.isSharePerm = 0; + } + }, + // 鏄惁鍥捐〃灞曠ず鏀瑰彉 + isChartChange() { + if (this.form.isChart == 1) { + this.form.isReadonly = 1; + } else { + this.form.isMonitor = 0; + } + }, + // 鏄惁瀹炴椂鐩戞祴鏀瑰彉 + isMonitorChange() { + if (this.form.isMonitor == 1) { + this.form.isReadonly = 1; + this.form.isChart = 1; + } + }, + // 鏄惁鍙鏁版嵁鏀瑰彉 + isReadonlyChange() { + if (this.form.isReadonly == 0) { + this.form.isMonitor = 0; + this.form.isChart = 0; + } + }, + // 鏍煎紡鍖栫墿妯″瀷 + formatThingsSpecs() { + var data = {}; + data.type = this.form.datatype; + if (this.form.datatype == 'integer' || this.form.datatype == 'decimal') { + data.min = Number(this.form.specs.min ? this.form.specs.min : 0); + data.max = Number(this.form.specs.max ? this.form.specs.max : 100); + data.unit = this.form.specs.unit ? this.form.specs.unit : ''; + data.step = Number(this.form.specs.step ? this.form.specs.step : 1); + } else if (this.form.datatype == 'string') { + data.maxLength = Number(this.form.specs.maxLength ? this.form.specs.maxLength : 1024); + } else if (this.form.datatype == 'bool') { + data.falseText = this.form.specs.falseText ? this.form.specs.falseText : '鍏抽棴'; + data.trueText = this.form.specs.trueText ? this.form.specs.trueText : '鎵撳紑'; + } else if (this.form.datatype == 'enum') { + data.showWay = this.form.specs.showWay; + if (this.form.specs.enumList && this.form.specs.enumList[0].text != '') { + data.enumList = this.form.specs.enumList; + } else { + data.showWay = 'select'; + data.enumList = [ + { + value: '0', + text: '浣�', + }, + { + value: '1', + text: '楂�', + }, + ]; + } + } else if (this.form.datatype == 'array') { + data.arrayType = this.form.specs.arrayType; + data.arrayCount = this.form.specs.arrayCount ? this.form.specs.arrayCount : 5; + if (data.arrayType == 'object') { + data.params = this.form.specs.params; + // 鐗╂ā鍨嬪悕绉颁綔涓哄弬鏁扮殑鏍囪瘑绗﹀墠缂� + for (let i = 0; i < data.params.length; i++) { + data.params[i].id = this.form.identifier + '_' + data.params[i].id; + } + } + } else if (this.form.datatype == 'object') { + data.params = this.form.specs.params; + // 鐗╂ā鍨嬪悕绉颁綔涓哄弬鏁扮殑鏍囪瘑绗﹀墠缂� + for (let i = 0; i < data.params.length; i++) { + data.params[i].id = this.form.identifier + '_' + data.params[i].id; + } + } + return JSON.stringify(data); + }, + /** 鏁版嵁绫诲瀷鏀瑰彉 */ + dataTypeChange(val) { + this.form.specs = {}; + }, + /** 娣诲姞鏋氫妇椤� */ + addEnumItem() { + this.form.specs.enumList.push({ + value: '', + text: '', + }); + }, + /** 鍒犻櫎鏋氫妇椤� */ + removeEnumItem(index) { + this.form.specs.enumList.splice(index, 1); + }, + /** 鏍煎紡鍖栨樉绀烘暟鎹畾涔� */ + formatSpecsDisplay(json) { + if (json == null || json == undefined) { + return; + } + let specs = JSON.parse(json); + if (specs.type === 'integer' || specs.type === 'decimal') { + return ( + '<span style=\'width:50%;display:inline-block;\'>鏈�澶у�硷細<span style="color:#F56C6C">' + + specs.max + + '</span></span>鏈�灏忓�硷細<span style="color:#F56C6C">' + + specs.min + + '</span><br /><span style=\'width:50%;display:inline-block;\'>姝ラ暱锛�<span style="color:#F56C6C">' + + specs.step + + '</span></span>鍗曚綅锛�<span style="color:#F56C6C">' + + specs.unit + ); + } else if (specs.type === 'string') { + return '鏈�澶ч暱搴︼細<span style="color:#F56C6C">' + specs.maxLength + '</span>'; + } else if (specs.type === 'array') { + return '<span style=\'width:50%;display:inline-block;\'>鏁扮粍绫诲瀷锛�<span style="color:#F56C6C">' + specs.arrayType + '</span></span>鍏冪礌涓暟锛�<span style="color:#F56C6C">' + specs.arrayCount; + } else if (specs.type === 'enum') { + let items = ''; + for (let i = 0; i < specs.enumList.length; i++) { + items = items + "<span style='width:50%;display:inline-block;'>" + specs.enumList[i].value + "锛�<span style='color:#F56C6C'>" + specs.enumList[i].text + '</span></span>'; + if (i > 0 && i % 2 != 0) { + items = items + '<br />'; + } + } + return items; + } else if (specs.type === 'bool') { + return '<span style=\'width:50%;display:inline-block;\'>0锛�<span style="color:#F56C6C">' + specs.falseText + '</span></span>1锛�<span style="color:#F56C6C">' + specs.trueText; + } else if (specs.type === 'object') { + let items = ''; + for (let i = 0; i < specs.params.length; i++) { + items = items + "<span style='width:50%;display:inline-block;'>" + specs.params[i].name + "锛�<span style='color:#F56C6C'>" + specs.params[i].datatype.type + '</span></span>'; + if (i > 0 && i % 2 != 0) { + items = items + '<br />'; + } + } + return items; + } + }, + /** 娣诲姞鍙傛暟 */ + addParameter() { + this.paramData = { + index: -1, + parameter: {}, + }; + }, + /** 缂栬緫鍙傛暟*/ + editParameter(data, index) { + this.paramData = null; + this.paramData = { + index: index, + parameter: data, + }; + }, + /** 鍒犻櫎鍔ㄤ綔 */ + removeParameter(index) { + this.form.specs.params.splice(index, 1); + }, + /**鑾峰彇璁剧疆鐨勫弬鏁板璞�*/ + getParamData(data) { + if (data.index == -1) { + this.form.specs.params.push(data.parameter); + } else { + this.form.specs.params[data.index] = data.parameter; + // 瑙e喅鏁扮粍鍦ㄧ晫闈腑涓嶆洿鏂伴棶棰� + this.$set(this.form.specs.params, data.index, this.form.specs.params[data.index]); + } + }, + // 鍦ㄨ緭鍏ユ渶灏忓�兼敼鍙樻椂瑙﹀彂 + handleEdit(e) { + let value = e.replace(/[^\-\d]/g, ""); // 鍙兘杈撳叆-鍜屾暟瀛� + value = value.replace(/\-{2,}/g, "-"); // -鍙兘淇濈暀涓�涓� + value = value.replace(/(\d)\-/g, "$1"); // 鏁板瓧鍚庨潰涓嶈兘鎺�-锛屼笉鑳藉嚭鐜扮被浼�-11-2,12-锛�11-23 + value = value.replace(/(-)0+/g, "$1"); // 涓嶈兘鍑虹幇-0,-001,-0001绫讳技 + value = value.replace(/(-\d{10})\d*/, '$1') // 鏈�澶氫繚鐣�10浣嶆暣鏁� + this.form.specs.min = value; + }, + // 鍦ㄨ緭鍏ユ渶澶у�兼敼鍙樻椂瑙﹀彂 + handleEditmax(e) { + let value = e.replace(/[^\-\d]/g, ""); // 鍙兘杈撳叆-鍜屾暟瀛� + value = value.replace(/\-{2,}/g, "-"); // -鍙兘淇濈暀涓�涓� + value = value.replace(/(\d)\-/g, "$1"); // 鏁板瓧鍚庨潰涓嶈兘鎺�-锛屼笉鑳藉嚭鐜扮被浼�-11-2,12-锛�11-23 + value = value.replace(/(-)0+/g, "$1"); // 涓嶈兘鍑虹幇-0,-001,-0001绫讳技 + value = value.replace(/(-\d{10})\d*/, '$1') // 鏈�澶氫繚鐣�10浣嶆暣鏁� + this.form.specs.max = value; + }, + //鏁版嵁绫诲瀷涓哄皬鏁扮殑鏍¢獙 + hasDecimalPoint() { + const regex = /^-?\d+\.\d+$/; // 浣跨敤姝e垯琛ㄨ揪寮忓尮閰嶅皬鏁扮偣鏍煎紡 + this.isDecimal = regex.test(this.form.specs.min); + return this.isDecimal; + }, + hasDecimalPointMax() { + const regex = /^-?\d+\.\d+$/; // 浣跨敤姝e垯琛ㄨ揪寮忓尮閰嶅皬鏁扮偣鏍煎紡 + this.isDecimalMax = regex.test(this.form.specs.max); + return this.isDecimalMax; + }, + }, +}; +</script> diff --git a/src/views/iot/template/parameter.vue b/src/views/iot/template/parameter.vue new file mode 100644 index 0000000..8ea8f54 --- /dev/null +++ b/src/views/iot/template/parameter.vue @@ -0,0 +1,440 @@ +<template> + <div style="padding: 6px"> + <!-- 娣诲姞鎴栦慨鏀归�氱敤鐗╂ā鍨嬪璇濇 --> + <el-dialog title="缂栬緫鍙傛暟" :visible.sync="openEdit" width="900px" append-to-body> + <div style="margin: -30px 0 30px; background-color: #ddd; height: 1px"></div> + <el-row> + <el-col :span="12" style="border: 1px solid #ddd; border-radius: 5px; padding: 10px; background-color: #eee"> + <el-form :model="queryParams" :inline="true" label-width="48px" size="small"> + <el-form-item label="" prop="templateName"> + <el-input v-model="queryParams.templateName" placeholder="璇疯緭鍏ョ墿妯″瀷鍚嶇О" style="width: 160px" clearable size="mini" @keyup.enter.native="handleQuery" /> + </el-form-item> + <el-form-item> + <el-button type="info" icon="el-icon-search" size="mini" @click="handleQuery" style="padding: 5px">鎼滅储</el-button> + </el-form-item> + <el-form-item> + <el-link :underline="false" icon="el-icon-info" type="primary" style="margin-left: 20px">鍗曞嚮搴旂敤妯℃澘</el-link> + </el-form-item> + </el-form> + + <el-table v-loading="loading" :data="templateList" size="mini" @row-click="rowClick" highlight-current-row :border="false" :show-header="false" :row-style="{ backgroundColor: '#eee' }"> + <el-table-column label="閫夋嫨" width="30" align="center"> + <template slot-scope="scope"> + <input type="radio" :checked="scope.row.isSelect" :disabled="scope.row.datatype == 'array' || scope.row.datatype == 'object'" name="template" /> + </template> + </el-table-column> + <el-table-column label="鍚嶇О" align="left" prop="templateName" /> + <el-table-column label="鏍囪瘑绗�" align="left" prop="identifier" /> + <el-table-column label="鏁版嵁绫诲瀷" align="center" prop="datatype" width="60"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.iot_data_type" :value="scope.row.datatype" /> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total > 0" + small + style="margin: 0 0 10px; background-color: #eee" + layout="prev, pager, next" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + </el-col> + + <el-col :span="11" :offset="1"> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="鍙傛暟鍚嶇О" prop="name"> + <el-input v-model="form.name" placeholder="渚嬪锛氭俯搴�" style="width: 270px" size="small" /> + </el-form-item> + <el-form-item label="鍙傛暟鏍囪瘑" prop="id"> + <el-input v-model="form.id" placeholder="渚嬪锛歵emperature" style="width: 270px" size="small"></el-input> + </el-form-item> + <el-form-item label="鍙傛暟鎺掑簭" prop="order"> + <el-input-number controls-position="right" v-model="form.order" placeholder="璇疯緭鍏ユ帓搴�" type="number" style="width: 270px" size="small" /> + </el-form-item> + + <el-form-item label="鍙傛暟鐗规��" prop="property"> + <el-checkbox name="isChart" label="鍥捐〃灞曠ず" @change="isChartChange" v-model="form.isChart" :true-label="1" :false-label="0"></el-checkbox> + <el-checkbox name="isMonitor" label="瀹炴椂鐩戞祴" @change="isMonitorChange" v-model="form.isMonitor" :true-label="1" :false-label="0"></el-checkbox> + <el-checkbox name="isReadonly" label="鍙鏁版嵁" @change="isReadonlyChange" v-model="form.isReadonly" :true-label="1" :false-label="0"></el-checkbox> + <el-checkbox name="isHistory" label="鍘嗗彶瀛樺偍" v-model="form.isHistory" :true-label="1" :false-label="0"></el-checkbox> + <el-checkbox name="isSharePerm" label="鍒嗕韩鏉冮檺" v-model="form.isSharePerm" :true-label="1" :false-label="0"></el-checkbox> + </el-form-item> + + <div style="margin-bottom: 20px; background-color: #ddd; height: 1px"></div> + <el-form-item label="鏁版嵁绫诲瀷" prop="datatype"> + <el-select v-model="form.datatype" placeholder="璇烽�夋嫨鏁版嵁绫诲瀷" style="width: 125px" size="small"> + <el-option key="integer" label="鏁存暟" value="integer"></el-option> + <el-option key="decimal" label="灏忔暟" value="decimal"></el-option> + <el-option key="bool" label="甯冨皵" value="bool" :disabled="form.isChart == 1"></el-option> + <el-option key="enum" label="鏋氫妇" value="enum" :disabled="form.isChart == 1"></el-option> + <el-option key="string" label="瀛楃涓�" value="string" :disabled="form.isChart == 1"></el-option> + </el-select> + </el-form-item> + <div v-if="form.datatype == 'integer' || form.datatype == 'decimal'"> + <el-form-item label="鍙栧�艰寖鍥�"> + <el-row> + <el-col :span="10"> + <el-input v-model="form.specs.min" placeholder="鏈�灏忓��" type="number" size="small" /> + </el-col> + <el-col :span="4" align="center">鍒�</el-col> + <el-col :span="10"> + <el-input v-model="form.specs.max" placeholder="鏈�澶у��" type="number" size="small" /> + </el-col> + </el-row> + </el-form-item> + <el-form-item label="鍗曚綅"> + <el-input v-model="form.specs.unit" placeholder="渚嬪锛氣剝" style="width: 308px" size="small" /> + </el-form-item> + <el-form-item label="姝ラ暱"> + <el-input-number controls-position="right" v-model="form.specs.step" placeholder="渚嬪锛�1" type="number" style="width: 308px" size="small" /> + </el-form-item> + </div> + <div v-if="form.datatype == 'bool'"> + <el-form-item label="甯冨皵鍊�" prop=""> + <el-row style="margin-bottom: 10px"> + <el-col :span="10"> + <el-input v-model="form.specs.falseText" placeholder="渚嬪锛氬叧闂�" size="small" /> + </el-col> + <el-col :span="10" :offset="1">锛�0 鍊煎搴旀枃鏈級</el-col> + </el-row> + <el-row> + <el-col :span="10"> + <el-input v-model="form.specs.trueText" placeholder="渚嬪锛氭墦寮�" size="small" /> + </el-col> + <el-col :span="10" :offset="1">锛�1 鍊煎搴旀枃鏈級</el-col> + </el-row> + </el-form-item> + </div> + <div v-if="form.datatype == 'enum'"> + <el-form-item label="灞曠ず鏂瑰紡"> + <el-select v-model="form.specs.showWay" placeholder="璇烽�夋嫨灞曠ず鏂瑰紡" style="width: 175px"> + <el-option key="select" label="涓嬫媺妗�" value="select"></el-option> + <el-option key="button" label="鎸夐挳" value="button"></el-option> + </el-select> + </el-form-item> + <el-form-item label="鏋氫妇椤�" prop=""> + <el-row v-for="(item, index) in form.specs.enumList" :key="'enum' + index" style="margin-bottom: 10px"> + <el-col :span="8"> + <el-input v-model="item.value" placeholder="渚嬪锛�0" size="small" /> + </el-col> + <el-col :span="11" :offset="1"> + <el-input v-model="item.text" placeholder="渚嬪锛氫腑閫熸尅浣�" size="small" /> + </el-col> + <el-col :span="3" :offset="1" v-if="index != 0"><a style="color: #f56c6c" @click="removeEnumItem(index)">鍒犻櫎</a></el-col> + </el-row> + <div> + + + <a style="color: #409eff" @click="addEnumItem()">娣诲姞鏋氫妇椤�</a> + </div> + </el-form-item> + </div> + <div v-if="form.datatype == 'string'"> + <el-form-item label="鏈�澶ч暱搴�" prop=""> + <el-row> + <el-col :span="10"> + <el-input v-model="form.specs.maxLength" placeholder="渚嬪锛�1024" type="number" size="small" /> + </el-col> + </el-row> + </el-form-item> + </div> + </el-form> + </el-col> + </el-row> + + <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> + +<style> +.specsColor { + background-color: #fcfcfc; +} +</style> + +<script> +import { listTemplate } from '@/api/iot/template'; +export default { + name: 'things_parameter', + dicts: ['iot_things_type', 'iot_data_type', 'iot_yes_no'], + props: { + data: { + type: Object, + default: null, + }, + }, + watch: { + data: function (newVal, oldVal) { + this.index = newVal.index; + if (newVal && newVal.parameter.name && newVal.parameter.name != '') { + this.form.name = newVal.parameter.name; + this.form.id = newVal.parameter.id; + this.form.order = newVal.parameter.order; + this.form.isChart = newVal.parameter.isChart ? newVal.parameter.isChart : 0; + this.form.isHistory = newVal.parameter.isHistory ? newVal.parameter.isHistory : 1; + this.form.isSharePerm = newVal.parameter.isSharePerm ? newVal.parameter.isSharePerm : 0; + this.form.isMonitor = newVal.parameter.isMonitor ? newVal.parameter.isMonitor : 0; + this.form.isReadonly = newVal.parameter.isReadonly ? newVal.parameter.isReadonly : 0; + this.form.specs = newVal.parameter.datatype; + this.form.datatype = this.form.specs.type; + if (!this.form.specs.enumList) { + this.form.specs.enumList = [ + { + value: '', + text: '', + }, + ]; + } + if (!this.form.specs.arrayType) { + this.form.specs.arrayType = 'int'; + } + } + this.openEdit = true; + this.getList(); + }, + }, + data() { + return { + // 閬僵灞� + loading: true, + // 鎬绘潯鏁� + total: 0, + // 閫氱敤鐗╂ā鍨嬭〃鏍兼暟鎹� + templateList: [], + // 鏄惁鏄剧ず寮瑰嚭灞� + openEdit: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + name: null, + type: null, + }, + // 鍙傛暟绱㈠紩 + index: -1, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + name: [ + { + required: true, + message: '鍙傛暟鍚嶇О涓嶈兘涓虹┖', + trigger: 'blur', + }, + ], + id: [ + { + required: true, + message: '鍙傛暟鏍囪瘑绗︿笉鑳戒负绌�', + trigger: 'blur', + }, + ], + order: [ + { + required: true, + message: '妯″瀷鎺掑簭涓嶈兘涓虹┖', + trigger: 'blur', + }, + ], + datatype: [ + { + required: true, + message: '鏁版嵁绫诲瀷涓嶈兘涓虹┖', + trigger: 'change', + }, + ], + }, + }; + }, + created() { + this.getList(); + this.reset(); + }, + methods: { + /** 鏌ヨ閫氱敤鐗╂ā鍨嬪垪琛� */ + getList() { + this.loading = true; + listTemplate(this.queryParams).then((response) => { + //妯℃澘鍒楄〃鍒濆鍖杋sSelect鍊硷紝鐢ㄤ簬鍗曢�� + for (let i = 0; i < response.rows.length; i++) { + response.rows[i].isSelect = false; + } + this.templateList = response.rows; + this.total = response.total; + this.setRadioSelected(this.productId); + this.loading = false; + }); + }, + /** 鍗曢�夋暟鎹� */ + rowClick(item) { + if (item != null && item.datatype != 'array' && item.datatype != 'object') { + this.form.name = item.templateName; + this.form.id = item.identifier; + this.form.order = item.modelOrder; + this.form.isChart = item.isChart ? item.isChart : 0; + this.form.isHistory = item.isHistory ? item.isHistory : 1; + this.form.isSharePerm = item.isSharePerm ? item.isSharePerm : 0; + this.form.isReadonly = item.isReadonly ? item.isReadonly : 0; + this.form.isMonitor = item.isMonitor ? item.isMonitor : 0; + this.form.datatype = item.datatype; + // Json杞璞� + this.form.specs = JSON.parse(item.specs); + if (!this.form.specs.enumList) { + this.form.specs.enumList = [ + { + value: '', + text: '', + }, + ]; + } + if (!this.form.specs.arrayType) { + this.form.specs.arrayType = 'int'; + } + this.setRadioSelected(item.templateId); + } + }, + /** 璁剧疆鍗曢�夋寜閽�変腑 */ + setRadioSelected(templateId) { + for (let i = 0; i < this.templateList.length; i++) { + if (this.templateList[i].templateId == templateId) { + this.templateList[i].isSelect = true; + } else { + this.templateList[i].isSelect = false; + } + } + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.openEdit = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.index = -1; + this.form = { + name: null, + id: null, + order: 0, + datatype: 'integer', + isChart: 0, + isHistory: 1, + isSharePerm: 0, + isMonitor: 0, + isReadonly: 0, + specs: { + enumList: [ + { + value: '', + text: '', + }, + ], + showWay: 'select', // 鏄剧ず鏂瑰紡select=涓嬫媺閫夋嫨妗嗭紝button=鎸夐挳 + }, + }; + this.resetForm('form'); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + this.$refs['form'].validate((valid) => { + if (valid) { + // 鏍煎紡鍖杁atatype + this.form.datatype = this.formatThingsSpecs(); + // 娓呯┖涓嶉渶瑕佸瓨鍌ㄦ暟鎹� + delete this.form.specs; + this.openEdit = false; + // 杩斿洖鍙傛暟瀵硅薄 + let data = { + parameter: JSON.parse(JSON.stringify(this.form)), + index: this.index, + }; + console.log('data', data); + this.$emit('dataEvent', data); + this.reset(); + } + }); + }, + // 鏄惁鍥捐〃灞曠ず鏀瑰彉 + isChartChange() { + if (this.form.isChart == 1) { + this.form.isReadonly = 1; + } else { + this.form.isMonitor = 0; + } + }, + // 鏄惁瀹炴椂鐩戞祴鏀瑰彉 + isMonitorChange() { + if (this.form.isMonitor == 1) { + this.form.isReadonly = 1; + this.form.isChart = 1; + } + }, + // 鏄惁鍙鏁版嵁鏀瑰彉 + isReadonlyChange() { + if (this.form.isReadonly == 0) { + this.form.isMonitor = 0; + this.form.isChart = 0; + } + }, + // 鏍煎紡鍖栫墿妯″瀷 + formatThingsSpecs() { + var data = {}; + data.type = this.form.datatype; + if (this.form.datatype == 'integer' || this.form.datatype == 'decimal') { + data.min = Number(this.form.specs.min ? this.form.specs.min : 0); + data.max = Number(this.form.specs.max ? this.form.specs.max : 100); + data.unit = this.form.specs.unit ? this.form.specs.unit : ''; + data.step = Number(this.form.specs.step ? this.form.specs.step : 1); + } else if (this.form.datatype == 'string') { + data.maxLength = Number(this.form.specs.maxLength ? this.form.specs.maxLength : 1024); + } else if (this.form.datatype == 'bool') { + data.falseText = this.form.specs.falseText ? this.form.specs.falseText : '鍏抽棴'; + data.trueText = this.form.specs.trueText ? this.form.specs.trueText : '鎵撳紑'; + } else if (this.form.datatype == 'array') { + data.arrayType = this.form.specs.arrayType; + } else if (this.form.datatype == 'enum') { + data.showWay = this.form.specs.showWay; + if (this.form.specs.enumList && this.form.specs.enumList[0].text != '') { + data.enumList = this.form.specs.enumList; + } else { + data.showWay = 'select'; + data.enumList = [ + { + value: '0', + text: '浣�', + }, + { + value: '1', + text: '楂�', + }, + ]; + } + } + return data; + }, + /** 娣诲姞鏋氫妇椤� */ + addEnumItem() { + this.form.specs.enumList.push({ + value: '', + text: '', + }); + }, + /** 鍒犻櫎鏋氫妇椤� */ + removeEnumItem(index) { + this.form.specs.enumList.splice(index, 1); + }, + }, +}; +</script> diff --git a/src/views/login.vue b/src/views/login.vue new file mode 100644 index 0000000..2581b09 --- /dev/null +++ b/src/views/login.vue @@ -0,0 +1,403 @@ +<template> + <div class="login"> + <el-row> + <el-col :xs="24"> + <div style="color: #fff; background-color: #0f73ee; width: 100%; height: 200px; text-align: center; padding: 15px; font-family: '寰蒋闆呴粦'"> + <div style="font-size: 42px; padding-top: 40px; width: 400px; margin: 0 auto"> + <div class="logoImg"></div> + <!-- <img :src="logo" alt="logo" style="width: 100px; height: 100px; float: left" /> --> + <div style="float: left; margin-top: 13px; width: 300px; text-align: left"> + <div>TerraDT</div> + <div style="letter-spacing: 1.5px; font-size: 20px; font-weight: 600; margin-top: -8px; margin-left: 3px">娉扮憺宸ヤ笟鏁板瓧瀛敓绠$悊骞冲彴</div> + </div> + </div> + </div> + + <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"> + <!-- <div style="margin-bottom: 10px; font-size: 14px; font-family: '寰蒋闆呴粦'; color: #f78e21">婕旂ず璐﹀彿锛歠astbee 123456</div> --> + <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="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="input-icon" /> + </el-input> + </el-form-item> + <el-form-item v-if="captchaOnOff" prop="code"> + <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="input-icon" /> + </el-input> + + <div class="login-code"> + <img :src="codeUrl" @click="getCode" /> + </div> + </el-form-item> + <el-checkbox v-model="loginForm.rememberMe" style="margin: 0px 0px 25px 0px; color: #000">璁颁綇瀵嗙爜</el-checkbox> + + <el-form-item style="width: 100%"> + <div style="margin-bottom: 10px"> + <el-button v-if="!bindAccount" :loading="loading" type="primary" style="width: 100%" @click.native.prevent="handleLogin"> + <span v-if="!loading">鐧� 褰�</span> + <span v-else>鐧� 褰� 涓�...</span> + </el-button> + <el-button v-else :loading="loading" type="primary" style="width: 100%" @click.native.prevent="handleBind"> + <span v-if="!loading">缁� 瀹�</span> + <span v-else>缁� 瀹� 涓�...</span> + </el-button> + </div> + </el-form-item> + </el-form> + </el-col> + </el-row> + <!-- 搴曢儴 --> + <div class="el-login-footer"> + <span> + Copyright 漏 2004锛�2023 + <a target="_blank" href="https://www.smartearth.cn/">SmartEarth</a> + All Rights Reserved. + </span> + </div> + </div> +</template> + +<script> +import 'element-ui/lib/theme-chalk/display.css'; +import logo from '@/assets/logo/logo.png'; +import { getCodeImg, checkBindId, getErrorMsg, socialLogin, bindLogin } from '@/api/login'; +import Cookies from 'js-cookie'; +import { encrypt, decrypt } from '@/utils/jsencrypt'; +import { setToken } from '@/utils/auth'; + +export default { + name: 'Login', + data() { + return { + logo, + codeUrl: '', + loginForm: { + username: '', + password: '', + rememberMe: false, + code: '', + uuid: '', + bindId: '', + // loginId: '', + }, + loginRules: { + username: [ + { + required: true, + trigger: 'blur', + message: '璇疯緭鍏ユ偍鐨勮处鍙�', + }, + ], + password: [ + { + required: true, + trigger: 'blur', + message: '璇疯緭鍏ユ偍鐨勫瘑鐮�', + }, + ], + code: [ + { + required: true, + trigger: 'change', + message: '璇疯緭鍏ラ獙璇佺爜', + }, + ], + }, + loading: false, + // 楠岃瘉鐮佸紑鍏� + captchaOnOff: true, + bindAccount: false, + // 娉ㄥ唽寮�鍏� + register: true, + redirect: undefined, + }; + }, + watch: { + $route: { + handler: function (route) { + this.redirect = route.query && route.query.redirect; + }, + immediate: true, + }, + }, + created() { + const loginId = this.$route.query.loginId; + if (loginId === undefined || loginId === null) { + this.checkBind(); + this.getCode(); + this.checkErrorMsg(); + this.getCookie(); + } else { + this.redirectSocialLogin(loginId); + } + }, + methods: { + redirectLogin(loginId) { + this.loading = true; + this.$store + .dispatch('RedirectLogin', loginId) + .then(() => { + this.$router + .push({ + path: this.redirect || '/', + }) + .catch(() => {}); + }) + .catch(() => { + this.loading = false; + if (this.captchaOnOff) { + this.getCode(); + } + this.$router.push({ + query: {}, + }); + }); + }, + redirectSocialLogin() { + const query = this.$route.query; + const loginId = query.loginId; + socialLogin(loginId).then((res) => { + // 淇濆瓨token + this.loading = true; + setToken(res.token); + this.$router + .push({ + path: this.redirect || '/', + }) + .catch(() => {}); + if (this.captchaOnOff) { + this.getCode(); + this.loading = false; + } + }); + }, + checkBind() { + const query = this.$route.query; + const bindId = query.bindId; + if (bindId === undefined || bindId === null) { + this.bindAccount = false; + } else { + this.bindAccount = true; + checkBindId(bindId).then((res) => { + this.bindAccount = res.bindAccount === undefined ? true : res.bindAccount; + if (this.bindAccount) { + this.loginForm.bindId = bindId; + } else { + this.loginForm.bindId = ''; + this.$router.push({ + query: {}, + }); + } + }); + } + }, + checkErrorMsg() { + const errorId = this.$route.query.errorId; + if (errorId !== undefined && errorId !== null) { + getErrorMsg(errorId) + .then((res) => {}) + .catch((err) => { + this.$router.push({ query: {} }); + console.log(err); + }); + } + }, + getCode() { + getCodeImg().then((res) => { + this.captchaOnOff = res.captchaOnOff === undefined ? true : res.captchaOnOff; + if (this.captchaOnOff) { + 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'); + const loginId = Cookies.get('loginId'); + this.loginForm = { + username: username === undefined ? this.loginForm.username : username, + password: password === undefined ? this.loginForm.password : decrypt(password), + rememberMe: rememberMe === undefined ? false : Boolean(rememberMe), + loginId: loginId === undefined ? this.loginForm.loginId : loginId, + }; + }, + qqLogin() { + window.location.href = 'http://localhost:8080/auth/render/qq'; + }, + weChatLogin() { + const baseURL = process.env.VUE_APP_BASE_API; + window.location.href = baseURL + '/auth/render/wechat_open_web'; + }, + authLogin() { + this.$alert('绗笁鏂圭櫥褰曟鍦ㄩ泦鎴愪腑...', '鎻愮ず娑堟伅', { + confirmButtonText: '纭畾', + callback: (action) => { + this.$message({ + type: 'info', + message: `action: ${action}`, + }); + }, + }); + }, + handleBind() { + 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.loginForm.bindId = this.$route.query.bindId; + bindLogin(this.loginForm) + .then((res) => { + // 淇濆瓨token + setToken(res.token); + this.$router + .push({ + path: '/', + }) + .catch(() => {}); + }) + .catch(() => { + this.loading = false; + if (this.captchaOnOff) { + this.loading = false; + this.getCode(); + } + }); + } + }); + }, + 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.captchaOnOff) { + this.getCode(); + } + }); + } + }); + }, + }, +}; +</script> + +<style lang="scss"> +.login { + height: 100%; + overflow: auto; +} +.logoImg { + width: 100px; + height: 100px; + background: url('../assets/logo/logo.png') no-repeat; + background-size: 100% 100%; + float: left; +} +.bindAccountTitle { + margin: 0px auto 30px auto; + text-align: center; + color: #333; + font-size: 24px; +} + +.login-form { + margin: 30px auto 0 auto; + padding: 15px; + z-index: 1000; + max-width: 350px; + + input { + height: 38px; + background-color: #f1f1f1; + color: #666; + } + + .input-icon { + height: 39px; + width: 14px; + margin-left: 2px; + } +} + +.login-code { + width: 33%; + float: right; + + img { + cursor: pointer; + vertical-align: middle; + border-radius: 3px; + height: 38px; + } +} + +.el-login-footer { + height: 40px; + line-height: 40px; + position: fixed; + bottom: 0; + width: 100%; + text-align: center; + color: #333; + font-family: Arial; + font-size: 12px; + letter-spacing: 1px; +} + +.alert-box-wrap { + border: 1px solid #f78e21; + + .alert-message-wrap { + font-size: 14px; + font-family: '寰蒋闆呴粦'; + color: rgba(197, 41, 41, 0.856); + margin-left: 10px; + } +} +</style> diff --git a/src/views/monitor/cache/index.vue b/src/views/monitor/cache/index.vue new file mode 100644 index 0000000..53f6eee --- /dev/null +++ b/src/views/monitor/cache/index.vue @@ -0,0 +1,146 @@ +<template> + <div class="app-container"> + <el-row> + <el-col :span="24" class="card-box"> + <el-card> + <div slot="header"><span>鍩烘湰淇℃伅</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>鍛戒护缁熻</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>鍐呭瓨淇℃伅</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: "鍐呭瓨娑堣��", + } + ] + } + ] + }); + }); + }, + // 鎵撳紑鍔犺浇灞� + openLoading() { + this.$modal.loading("姝e湪鍔犺浇缂撳瓨鐩戞帶鏁版嵁锛岃绋嶅�欙紒"); + } + } +}; +</script> diff --git a/src/views/monitor/cache/list.vue b/src/views/monitor/cache/list.vue new file mode 100644 index 0000000..a1e7955 --- /dev/null +++ b/src/views/monitor/cache/list.vue @@ -0,0 +1,241 @@ +<template> + <div class="app-container"> + <el-row :gutter="10"> + <el-col :span="8"> + <el-card style="height: calc(100vh - 125px)"> + <div slot="header"> + <span>缂撳瓨鍒楄〃</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>閿悕鍒楄〃</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>缂撳瓨鍐呭</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("娓呯悊缂撳瓨鍚嶇О[" + this.nowCacheName + "]鎴愬姛"); + 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> diff --git a/src/views/monitor/druid/index.vue b/src/views/monitor/druid/index.vue new file mode 100644 index 0000000..c6ad585 --- /dev/null +++ b/src/views/monitor/druid/index.vue @@ -0,0 +1,15 @@ +<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> diff --git a/src/views/monitor/job/index.vue b/src/views/monitor/job/index.vue new file mode 100644 index 0000000..37c8fc1 --- /dev/null +++ b/src/views/monitor/job/index.vue @@ -0,0 +1,513 @@ +<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璋冪敤绀轰緥锛歳yTask.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="璇疯緭鍏ron鎵ц琛ㄨ揪寮�"> + <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"> + <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-col :span="12"> + <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-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">姝e父</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> diff --git a/src/views/monitor/job/log.vue b/src/views/monitor/job/log.vue new file mode 100644 index 0000000..60bee1d --- /dev/null +++ b/src/views/monitor/job/log.vue @@ -0,0 +1,295 @@ +<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">姝e父</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> diff --git a/src/views/monitor/logininfor/index.vue b/src/views/monitor/logininfor/index.vue new file mode 100644 index 0000000..8a9b17a --- /dev/null +++ b/src/views/monitor/logininfor/index.vue @@ -0,0 +1,245 @@ +<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" + 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: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']" + >瑙i攣</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" /> + <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(() => {}); + }, + /** 瑙i攣鎸夐挳鎿嶄綔 */ + handleUnlock() { + const username = this.selectName; + this.$modal.confirm('鏄惁纭瑙i攣鐢ㄦ埛"' + username + '"鏁版嵁椤�?').then(function() { + return unlockLogininfor(username); + }).then(() => { + this.$modal.msgSuccess("鐢ㄦ埛" + username + "瑙i攣鎴愬姛"); + }).catch(() => {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download('monitor/logininfor/export', { + ...this.queryParams + }, `logininfor_${new Date().getTime()}.xlsx`) + } + } +}; +</script> + diff --git a/src/views/monitor/online/index.vue b/src/views/monitor/online/index.vue new file mode 100644 index 0000000..ad613c9 --- /dev/null +++ b/src/views/monitor/online/index.vue @@ -0,0 +1,122 @@ +<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> + diff --git a/src/views/monitor/operlog/index.vue b/src/views/monitor/operlog/index.vue new file mode 100644 index 0000000..c1b5377 --- /dev/null +++ b/src/views/monitor/operlog/index.vue @@ -0,0 +1,305 @@ +<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="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" + 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: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="55" align="center" /> + <el-table-column label="鏃ュ織缂栧彿" align="center" prop="operId" /> + <el-table-column label="绯荤粺妯″潡" align="center" prop="title" /> + <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="requestMethod" /> + <el-table-column label="鎿嶄綔浜哄憳" align="center" prop="operName" width="100" :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" sortable="custom" :sort-orders="['descending', 'ascending']" width="180"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.operTime) }}</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="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.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="12"> + <el-form-item label="鎿嶄綔鐘舵�侊細"> + <div v-if="form.status === 0">姝e父</div> + <div v-else-if="form.status === 1">澶辫触</div> + </el-form-item> + </el-col> + <el-col :span="12"> + <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, + 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> + diff --git a/src/views/monitor/server/index.vue b/src/views/monitor/server/index.vue new file mode 100644 index 0000000..b122edf --- /dev/null +++ b/src/views/monitor/server/index.vue @@ -0,0 +1,207 @@ +<template> + <div class="app-container"> + <el-row> + <el-col :span="12" class="card-box"> + <el-card> + <div slot="header"><span>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>鍐呭瓨</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>鏈嶅姟鍣ㄤ俊鎭�</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">鏈嶅姟鍣↖P</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>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>纾佺洏鐘舵��</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("姝e湪鍔犺浇鏈嶅姟鐩戞帶鏁版嵁锛岃绋嶅�欙紒"); + } + } +}; +</script> \ No newline at end of file diff --git a/src/views/redirect.vue b/src/views/redirect.vue new file mode 100644 index 0000000..db4c1d6 --- /dev/null +++ b/src/views/redirect.vue @@ -0,0 +1,12 @@ +<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> diff --git a/src/views/register.vue b/src/views/register.vue new file mode 100644 index 0000000..c0c934f --- /dev/null +++ b/src/views/register.vue @@ -0,0 +1,329 @@ +<template> + <div class="register"> + <el-row> + <el-col :xs="24"> + <div + style="color: #fff; background-color: #0f73ee; width: 100%; height: 200px; text-align: center; padding: 15px; font-family: '寰蒋闆呴粦'"> + <div style="font-size: 42px; padding-top: 40px; width: 300px; margin: 0 auto"> + <img :src="logo" alt="logo" style="width: 100px; height: 100px; float: left" /> + <div style="float: left; margin-top: 13px; width: 200px; text-align: left"> + <div>FastBee</div> + <div style="letter-spacing: 1.5px; font-size: 20px; font-weight: 600; margin-top: -8px; margin-left: 3px"> + 寮�婧愮墿鑱旂綉骞冲彴</div> + </div> + </div> + </div> + <el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form" + style="z-index: 1000;"> + <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="phonenumber"> + <el-input v-model="registerForm.phonenumber" type="text" auto-complete="off" placeholder="鎵嬫満鍙风爜"> + <svg-icon slot="prefix" icon-class="phone" 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 v-if="captchaOnOff" prop="code"> + <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" /> + </div> + </el-form-item> + <el-form-item style="width: 100%"> + <el-button v-if="!bindAccount" :loading="loading" type="primary" style="width: 100%" + @click.native.prevent="handleRegister"> + <span v-if="!loading">娉� 鍐�</span> + <span v-else>娉� 鍐� 涓�...</span> + </el-button> + <el-button v-else :loading="loading" type="primary" style="width: 100%" + @click.native.prevent="handleRegister"> + <span v-if="!loading">娉� 鍐� 缁� 瀹�</span> + <span v-else>缁� 瀹� 涓�...</span> + </el-button> + </el-form-item> + <el-form-item> + <el-link href="https://fastbee.cn/" :underline="false" target="_blank" style="float: left">杩斿洖瀹樼綉</el-link> + <el-link href="https://fastbee.cn/doc" :underline="false" target="_blank" + style="float: left; margin-left: 20px">鏌ョ湅鏂囨。</el-link> + <router-link :to="{ path: '/login', query: this.$route.query }" + style="float: left; margin-left: 20px">璐﹀彿鐧诲綍</router-link> + </el-form-item> + </el-form> + </el-col> + </el-row> + <!-- 搴曢儴 --> + <div class="el-register-footer"> + <span> + Copyright 漏 2023 + <a target="_blank" href="http://fastbee.cn">FastBee</a> + All Rights Reserved. + </span> + </div> + </div> +</template> + +<script> +import 'element-ui/lib/theme-chalk/display.css'; +import logo from '@/assets/logo/logo.gif'; +import { getCodeImg, checkBindId, bindRegister } from '@/api/login'; +import { register } from '@/api/iot/tool'; + +export default { + name: 'Register', + data() { + const equalToPassword = (rule, value, callback) => { + if (this.registerForm.password !== value) { + callback(new Error('涓ゆ杈撳叆鐨勫瘑鐮佷笉涓�鑷�')); + } else { + callback(); + } + }; + return { + logo, + codeUrl: '', + registerForm: { + username: '', + phonenumber: '', + password: '', + confirmPassword: '', + code: '', + uuid: '', + bindId: '', + }, + registerRules: { + username: [ + { + required: true, + trigger: 'blur', + message: '璇疯緭鍏ユ偍鐨勮处鍙�', + }, + { + min: 2, + max: 20, + message: '鐢ㄦ埛璐﹀彿闀垮害蹇呴』浠嬩簬 2 鍜� 20 涔嬮棿', + trigger: 'blur', + }, + ], + phonenumber: [ + { + required: true, + trigger: 'blur', + message: '璇疯緭鍏ユ偍鐨勬墜鏈哄彿鐮�', + }, + { + min: 11, + max: 11, + message: '鎵嬫満鍙风爜闀垮害涓�11', + trigger: 'blur', + }, + ], + password: [ + { + required: true, + trigger: 'blur', + message: '璇疯緭鍏ユ偍鐨勫瘑鐮�', + }, + { + min: 5, + max: 20, + message: '鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿', + trigger: 'blur', + }, + { + trigger: 'blur', + validator: (rule, value, callback) => { + var passwordreg = /(?![A-Z]*$)(?![a-z]*$)(?![0-9]*$)(?![^a-zA-Z0-9]*$)/ + if (!passwordreg.test(value)) { + callback(new Error('瀵嗙爜椤荤敱澶у啓,灏忓啓瀛楁瘝,鏁板瓧,鐗规畩绗︿腑鐨�2绉嶅強浠ヤ笂绫诲瀷缁勬垚')) + } + else { + callback() + } + } + }, + ], + confirmPassword: [ + { + required: true, + trigger: 'blur', + message: '璇峰啀娆¤緭鍏ユ偍鐨勫瘑鐮�', + }, + { + required: true, + validator: equalToPassword, + trigger: 'blur', + }, + ], + code: [ + { + required: true, + trigger: 'change', + message: '璇疯緭鍏ラ獙璇佺爜', + }, + ], + }, + loading: false, + captchaOnOff: true, + bindAccount: false, + }; + }, + created() { + this.checkBind(); + this.getCode(); + }, + methods: { + checkBind() { + const query = this.$route.query; + const bindId = query.bindId; + if (bindId === undefined || bindId === null) { + this.bindAccount = false; + } else { + this.bindAccount = true; + checkBindId(bindId).then((res) => { + this.bindAccount = res.bindAccount === undefined ? true : res.bindAccount; + if (this.bindAccount) { + this.registerForm.bindId = bindId; + } else { + this.registerForm.bindId = ''; + this.$router.push({ + query: {}, + }); + } + }); + } + }, + + getCode() { + getCodeImg().then((res) => { + this.captchaOnOff = res.captchaOnOff === undefined ? true : res.captchaOnOff; + if (this.captchaOnOff) { + this.codeUrl = 'data:image/gif;base64,' + res.img; + this.registerForm.uuid = res.uuid; + } + }); + }, + qqLogin() { + window.location.href = 'http://localhost:8080/auth/render/qq'; + }, + authLogin() { + this.$alert('绗笁鏂圭櫥褰曟鍦ㄩ泦鎴愪腑...', '鎻愮ず娑堟伅', { + confirmButtonText: '纭畾', + callback: (action) => { + this.$message({ + type: 'info', + message: `action: ${action}`, + }); + }, + }); + }, + handleRegister() { + this.$refs.registerForm.validate((valid) => { + if (valid) { + this.loading = true; + if (this.bindAccount) { + bindRegister(this.registerForm) + .then((res) => { + this.innerRegister(res); + }) + .catch(() => { + this.loading = false; + if (this.captchaOnOff) { + this.getCode(); + } + }); + } else { + register(this.registerForm) + .then((res) => { + this.innerRegister(res); + }) + .catch(() => { + this.loading = false; + if (this.captchaOnOff) { + this.getCode(); + } + }); + } + } + }); + }, + innerRegister(res) { + const username = this.registerForm.username; + this.$alert("<font color='red'>鎭枩浣狅紝鎮ㄧ殑璐﹀彿 " + username + ' 娉ㄥ唽鎴愬姛锛�</font>', '绯荤粺鎻愮ず', { + dangerouslyUseHTMLString: true, + type: 'success', + }) + .then(() => { + this.$router.push('/login'); + }) + .catch(() => { }); + }, + }, +}; +</script> + +<style lang="scss"> +.register { + height: 100%; + overflow: auto; +} + +.register-form { + margin: 30px auto 0 auto; + padding: 15px; + z-index: 1000; + max-width: 350px; + + input { + height: 38px; + background-color: #f1f1f1; + color: #666; + } + + .input-icon { + height: 39px; + width: 14px; + margin-left: 2px; + } +} + +.register-code { + width: 33%; + float: right; + + img { + cursor: pointer; + vertical-align: middle; + border-radius: 3px; + height: 38px; + } +} + +.el-register-footer { + height: 40px; + line-height: 40px; + position: fixed; + bottom: 0; + width: 100%; + text-align: center; + color: #333; + font-family: Arial; + font-size: 12px; + letter-spacing: 1px; +}</style> diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue new file mode 100644 index 0000000..f580b98 --- /dev/null +++ b/src/views/system/config/index.vue @@ -0,0 +1,343 @@ +<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" /> + <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" 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> diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue new file mode 100644 index 0000000..e502b4e --- /dev/null +++ b/src/views/system/dept/index.vue @@ -0,0 +1,340 @@ +<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="璇疯緭鍏ヨ礋璐d汉" 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> diff --git a/src/views/system/dict/data.vue b/src/views/system/dict/data.vue new file mode 100644 index 0000000..324bb64 --- /dev/null +++ b/src/views/system/dict/data.vue @@ -0,0 +1,402 @@ +<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.dictLabel}}</span> + <el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass">{{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, + dictName: undefined, + dictType: 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> \ No newline at end of file diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue new file mode 100644 index 0000000..6ca5457 --- /dev/null +++ b/src/views/system/dict/index.vue @@ -0,0 +1,347 @@ +<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> \ No newline at end of file diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue new file mode 100644 index 0000000..57b56e5 --- /dev/null +++ b/src/views/system/menu/index.vue @@ -0,0 +1,453 @@ +<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-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-col :span="24" 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" /> + <el-input slot="reference" v-model="form.icon" placeholder="鐐瑰嚮閫夋嫨鍥炬爣" readonly> + <svg-icon + v-if="form.icon" + slot="prefix" + :icon-class="form.icon" + class="el-input__icon" + style="height: 32px;width: 16px;" + /> + <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="menuName"> + <el-input v-model="form.menuName" 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-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-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-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-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" v-if="form.menuType != 'F'"> + <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> diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue new file mode 100644 index 0000000..7982b54 --- /dev/null +++ b/src/views/system/notice/index.vue @@ -0,0 +1,312 @@ +<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="noticeTitle"> + <el-input + v-model="queryParams.noticeTitle" + placeholder="璇疯緭鍏ュ叕鍛婃爣棰�" + clearable + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鎿嶄綔浜哄憳" prop="createBy"> + <el-input + v-model="queryParams.createBy" + placeholder="璇疯緭鍏ユ搷浣滀汉鍛�" + clearable + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="绫诲瀷" prop="noticeType"> + <el-select v-model="queryParams.noticeType" placeholder="鍏憡绫诲瀷" clearable> + <el-option + v-for="dict in dict.type.sys_notice_type" + :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:notice: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:notice: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:notice:remove']" + >鍒犻櫎</el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="搴忓彿" align="center" prop="noticeId" width="100" /> + <el-table-column + label="鍏憡鏍囬" + align="center" + prop="noticeTitle" + :show-overflow-tooltip="true" + /> + <el-table-column label="鍏憡绫诲瀷" align="center" prop="noticeType" width="100"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.sys_notice_type" :value="scope.row.noticeType"/> + </template> + </el-table-column> + <el-table-column label="鐘舵��" align="center" prop="status" width="100"> + <template slot-scope="scope"> + <dict-tag :options="dict.type.sys_notice_status" :value="scope.row.status"/> + </template> + </el-table-column> + <el-table-column label="鍒涘缓鑰�" align="center" prop="createBy" width="100" /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="100"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</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:notice:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:notice: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="780px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-row> + <el-col :span="12"> + <el-form-item label="鍏憡鏍囬" prop="noticeTitle"> + <el-input v-model="form.noticeTitle" placeholder="璇疯緭鍏ュ叕鍛婃爣棰�" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鍏憡绫诲瀷" prop="noticeType"> + <el-select v-model="form.noticeType" placeholder="璇烽�夋嫨鍏憡绫诲瀷"> + <el-option + v-for="dict in dict.type.sys_notice_type" + :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 label="鐘舵��"> + <el-radio-group v-model="form.status"> + <el-radio + v-for="dict in dict.type.sys_notice_status" + :key="dict.value" + :label="dict.value" + >{{dict.label}}</el-radio> + </el-radio-group> + </el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="鍐呭"> + <editor v-model="form.noticeContent" :min-height="192"/> + </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 { listNotice, getNotice, delNotice, addNotice, updateNotice } from "@/api/system/notice"; + +export default { + name: "Notice", + dicts: ['sys_notice_status', 'sys_notice_type'], + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 鍏憡琛ㄦ牸鏁版嵁 + noticeList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + noticeTitle: undefined, + createBy: undefined, + status: undefined + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + noticeTitle: [ + { required: true, message: "鍏憡鏍囬涓嶈兘涓虹┖", trigger: "blur" } + ], + noticeType: [ + { required: true, message: "鍏憡绫诲瀷涓嶈兘涓虹┖", trigger: "change" } + ] + } + }; + }, + created() { + this.getList(); + }, + methods: { + /** 鏌ヨ鍏憡鍒楄〃 */ + getList() { + this.loading = true; + listNotice(this.queryParams).then(response => { + this.noticeList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + noticeId: undefined, + noticeTitle: undefined, + noticeType: undefined, + noticeContent: undefined, + 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.noticeId) + this.single = selection.length!=1 + this.multiple = !selection.length + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞鍏憡"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const noticeId = row.noticeId || this.ids + getNotice(noticeId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼鍏憡"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.noticeId != undefined) { + updateNotice(this.form).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + }); + } else { + addNotice(this.form).then(response => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const noticeIds = row.noticeId || this.ids + this.$modal.confirm('鏄惁纭鍒犻櫎鍏憡缂栧彿涓�"' + noticeIds + '"鐨勬暟鎹」锛�').then(function() { + return delNotice(noticeIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(() => {}); + } + } +}; +</script> diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue new file mode 100644 index 0000000..444bf63 --- /dev/null +++ b/src/views/system/post/index.vue @@ -0,0 +1,309 @@ +<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="postCode"> + <el-input + v-model="queryParams.postCode" + placeholder="璇疯緭鍏ュ矖浣嶇紪鐮�" + clearable + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="宀椾綅鍚嶇О" prop="postName"> + <el-input + v-model="queryParams.postName" + 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:post: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:post: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:post: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:post:export']" + >瀵煎嚭</el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="宀椾綅缂栧彿" align="center" prop="postId" /> + <el-table-column label="宀椾綅缂栫爜" align="center" prop="postCode" /> + <el-table-column label="宀椾綅鍚嶇О" align="center" prop="postName" /> + <el-table-column label="宀椾綅鎺掑簭" align="center" prop="postSort" /> + <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-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['system:post:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:post: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="postName"> + <el-input v-model="form.postName" placeholder="璇疯緭鍏ュ矖浣嶅悕绉�" /> + </el-form-item> + <el-form-item label="宀椾綅缂栫爜" prop="postCode"> + <el-input v-model="form.postCode" placeholder="璇疯緭鍏ョ紪鐮佸悕绉�" /> + </el-form-item> + <el-form-item label="宀椾綅椤哄簭" prop="postSort"> + <el-input-number v-model="form.postSort" controls-position="right" :min="0" /> + </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-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 { listPost, getPost, delPost, addPost, updatePost } from "@/api/system/post"; + +export default { + name: "Post", + dicts: ['sys_normal_disable'], + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 宀椾綅琛ㄦ牸鏁版嵁 + postList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + postCode: undefined, + postName: undefined, + status: undefined + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + // 琛ㄥ崟鏍¢獙 + rules: { + postName: [ + { required: true, message: "宀椾綅鍚嶇О涓嶈兘涓虹┖", trigger: "blur" } + ], + postCode: [ + { required: true, message: "宀椾綅缂栫爜涓嶈兘涓虹┖", trigger: "blur" } + ], + postSort: [ + { required: true, message: "宀椾綅椤哄簭涓嶈兘涓虹┖", trigger: "blur" } + ] + } + }; + }, + created() { + this.getList(); + }, + methods: { + /** 鏌ヨ宀椾綅鍒楄〃 */ + getList() { + this.loading = true; + listPost(this.queryParams).then(response => { + this.postList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + postId: undefined, + postCode: undefined, + postName: undefined, + postSort: 0, + status: "0", + remark: undefined + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.postId) + this.single = selection.length!=1 + this.multiple = !selection.length + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "娣诲姞宀椾綅"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const postId = row.postId || this.ids + getPost(postId).then(response => { + this.form = response.data; + this.open = true; + this.title = "淇敼宀椾綅"; + }); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.postId != undefined) { + updatePost(this.form).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + }); + } else { + addPost(this.form).then(response => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const postIds = row.postId || this.ids; + this.$modal.confirm('鏄惁纭鍒犻櫎宀椾綅缂栧彿涓�"' + postIds + '"鐨勬暟鎹」锛�').then(function() { + return delPost(postIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(() => {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download('system/post/export', { + ...this.queryParams + }, `post_${new Date().getTime()}.xlsx`) + } + } +}; +</script> diff --git a/src/views/system/role/authUser.vue b/src/views/system/role/authUser.vue new file mode 100644 index 0000000..147aa33 --- /dev/null +++ b/src/views/system/role/authUser.vue @@ -0,0 +1,199 @@ +<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 { allocatedUserList, authUserCancel, authUserCancelAll } from "@/api/system/role"; +import selectUser from "./selectUser"; + +export default { + name: "AuthUser", + 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; + allocatedUserList(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> \ No newline at end of file diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue new file mode 100644 index 0000000..1ea77c5 --- /dev/null +++ b/src/views/system/role/index.vue @@ -0,0 +1,606 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"> + <el-form-item label="瑙掕壊鍚嶇О" prop="roleName"> + <el-input + v-model="queryParams.roleName" + placeholder="璇疯緭鍏ヨ鑹插悕绉�" + clearable + style="width: 240px" + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="鏉冮檺瀛楃" prop="roleKey"> + <el-input + v-model="queryParams.roleKey" + 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:role: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:role: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:role: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:role:export']" + >瀵煎嚭</el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="瑙掕壊缂栧彿" prop="roleId" width="120" /> + <el-table-column label="瑙掕壊鍚嶇О" prop="roleName" :show-overflow-tooltip="true" width="150" /> + <el-table-column label="鏉冮檺瀛楃" prop="roleKey" :show-overflow-tooltip="true" width="150" /> + <el-table-column label="鏄剧ず椤哄簭" prop="roleSort" width="100" /> + <el-table-column label="鐘舵��" align="center" width="100"> + <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" 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"> +<!-- v-if="scope.row.roleId !== 1 && scope.row.roleId !== 2 && scope.row.roleId !== 3" --> + <template slot-scope="scope" v-if="scope.row.roleId !== 1"> + <el-button + size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['system:role:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:role:remove']" + >鍒犻櫎</el-button> + <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:role:edit']"> + <el-button size="mini" type="text" icon="el-icon-d-arrow-right">鏇村</el-button> + <el-dropdown-menu slot="dropdown"> + <el-dropdown-item command="handleDataScope" icon="el-icon-circle-check" + v-hasPermi="['system:role:edit']">鏁版嵁鏉冮檺</el-dropdown-item> + <el-dropdown-item command="handleAuthUser" icon="el-icon-user" + v-hasPermi="['system:role:edit']">鍒嗛厤鐢ㄦ埛</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="500px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="100px"> + <el-form-item label="瑙掕壊鍚嶇О" prop="roleName"> + <el-input v-model="form.roleName" placeholder="璇疯緭鍏ヨ鑹插悕绉�" /> + </el-form-item> + <el-form-item prop="roleKey"> + <span slot="label"> + <el-tooltip content="鎺у埗鍣ㄤ腑瀹氫箟鐨勬潈闄愬瓧绗︼紝濡傦細@PreAuthorize(`@ss.hasRole('admin')`)" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + 鏉冮檺瀛楃 + </span> + <el-input v-model="form.roleKey" placeholder="璇疯緭鍏ユ潈闄愬瓧绗�" /> + </el-form-item> + <el-form-item label="瑙掕壊椤哄簭" prop="roleSort"> + <el-input-number v-model="form.roleSort" controls-position="right" :min="0" /> + </el-form-item> + <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-form-item label="鑿滃崟鏉冮檺"> + <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">灞曞紑/鎶樺彔</el-checkbox> + <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">鍏ㄩ��/鍏ㄤ笉閫�</el-checkbox> + <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">鐖跺瓙鑱斿姩</el-checkbox> + <el-tree + class="tree-border" + :data="menuOptions" + show-checkbox + ref="menu" + node-key="id" + :check-strictly="!form.menuCheckStrictly" + empty-text="鍔犺浇涓紝璇风◢鍊�" + :props="defaultProps" + ></el-tree> + </el-form-item> + <el-form-item label="澶囨敞"> + <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> + + <!-- 鍒嗛厤瑙掕壊鏁版嵁鏉冮檺瀵硅瘽妗� --> + <el-dialog :title="title" :visible.sync="openDataScope" width="500px" append-to-body> + <el-form :model="form" label-width="80px"> + <el-form-item label="瑙掕壊鍚嶇О"> + <el-input v-model="form.roleName" :disabled="true" /> + </el-form-item> + <el-form-item label="鏉冮檺瀛楃"> + <el-input v-model="form.roleKey" :disabled="true" /> + </el-form-item> + <el-form-item label="鏉冮檺鑼冨洿"> + <el-select v-model="form.dataScope" @change="dataScopeSelectChange"> + <el-option + v-for="item in dataScopeOptions" + :key="item.value" + :label="item.label" + :value="item.value" + ></el-option> + </el-select> + </el-form-item> + <el-form-item label="鏁版嵁鏉冮檺" v-show="form.dataScope == 2"> + <el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">灞曞紑/鎶樺彔</el-checkbox> + <el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">鍏ㄩ��/鍏ㄤ笉閫�</el-checkbox> + <el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">鐖跺瓙鑱斿姩</el-checkbox> + <el-tree + class="tree-border" + :data="deptOptions" + show-checkbox + default-expand-all + ref="dept" + node-key="id" + :check-strictly="!form.deptCheckStrictly" + empty-text="鍔犺浇涓紝璇风◢鍊�" + :props="defaultProps" + ></el-tree> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitDataScope">纭� 瀹�</el-button> + <el-button @click="cancelDataScope">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus, deptTreeSelect } from "@/api/system/role"; +import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu"; + +export default { + name: "Role", + dicts: ['sys_normal_disable'], + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 瑙掕壊琛ㄦ牸鏁版嵁 + roleList: [], + // 寮瑰嚭灞傛爣棰� + title: "", + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏄惁鏄剧ず寮瑰嚭灞傦紙鏁版嵁鏉冮檺锛� + openDataScope: false, + menuExpand: false, + menuNodeAll: false, + deptExpand: true, + deptNodeAll: false, + // 鏃ユ湡鑼冨洿 + dateRange: [], + // 鏁版嵁鑼冨洿閫夐」 + dataScopeOptions: [ + { + value: "1", + label: "鍏ㄩ儴鏁版嵁鏉冮檺" + }, + { + value: "2", + label: "鑷畾鏁版嵁鏉冮檺" + }, + { + value: "3", + label: "鏈儴闂ㄦ暟鎹潈闄�" + }, + { + value: "4", + label: "鏈儴闂ㄥ強浠ヤ笅鏁版嵁鏉冮檺" + }, + { + value: "5", + label: "浠呮湰浜烘暟鎹潈闄�" + } + ], + // 鑿滃崟鍒楄〃 + menuOptions: [], + // 閮ㄩ棬鍒楄〃 + deptOptions: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + roleName: undefined, + roleKey: undefined, + status: undefined + }, + // 琛ㄥ崟鍙傛暟 + form: {}, + defaultProps: { + children: "children", + label: "label" + }, + // 琛ㄥ崟鏍¢獙 + rules: { + roleName: [ + { required: true, message: "瑙掕壊鍚嶇О涓嶈兘涓虹┖", trigger: "blur" } + ], + roleKey: [ + { required: true, message: "鏉冮檺瀛楃涓嶈兘涓虹┖", trigger: "blur" } + ], + roleSort: [ + { required: true, message: "瑙掕壊椤哄簭涓嶈兘涓虹┖", trigger: "blur" } + ] + } + }; + }, + created() { + this.getList(); + }, + methods: { + /** 鏌ヨ瑙掕壊鍒楄〃 */ + getList() { + this.loading = true; + listRole(this.addDateRange(this.queryParams, this.dateRange)).then(response => { + this.roleList = response.rows; + this.total = response.total; + this.loading = false; + } + ); + }, + /** 鏌ヨ鑿滃崟鏍戠粨鏋� */ + getMenuTreeselect() { + menuTreeselect().then(response => { + this.menuOptions = response.data; + }); + }, + // 鎵�鏈夎彍鍗曡妭鐐规暟鎹� + getMenuAllCheckedKeys() { + // 鐩墠琚�変腑鐨勮彍鍗曡妭鐐� + let checkedKeys = this.$refs.menu.getCheckedKeys(); + // 鍗婇�変腑鐨勮彍鍗曡妭鐐� + let halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys(); + checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys); + return checkedKeys; + }, + // 鎵�鏈夐儴闂ㄨ妭鐐规暟鎹� + getDeptAllCheckedKeys() { + // 鐩墠琚�変腑鐨勯儴闂ㄨ妭鐐� + let checkedKeys = this.$refs.dept.getCheckedKeys(); + // 鍗婇�変腑鐨勯儴闂ㄨ妭鐐� + let halfCheckedKeys = this.$refs.dept.getHalfCheckedKeys(); + checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys); + return checkedKeys; + }, + /** 鏍规嵁瑙掕壊ID鏌ヨ鑿滃崟鏍戠粨鏋� */ + getRoleMenuTreeselect(roleId) { + return roleMenuTreeselect(roleId).then(response => { + this.menuOptions = response.menus; + return response; + }); + }, + /** 鏍规嵁瑙掕壊ID鏌ヨ閮ㄩ棬鏍戠粨鏋� */ + getDeptTree(roleId) { + return deptTreeSelect(roleId).then(response => { + this.deptOptions = response.depts; + return response; + }); + }, + // 瑙掕壊鐘舵�佷慨鏀� + handleStatusChange(row) { + let text = row.status === "0" ? "鍚敤" : "鍋滅敤"; + this.$modal.confirm('纭瑕�"' + text + '""' + row.roleName + '"瑙掕壊鍚楋紵').then(function() { + return changeRoleStatus(row.roleId, row.status); + }).then(() => { + this.$modal.msgSuccess(text + "鎴愬姛"); + }).catch(function() { + row.status = row.status === "0" ? "1" : "0"; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 鍙栨秷鎸夐挳锛堟暟鎹潈闄愶級 + cancelDataScope() { + this.openDataScope = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + if (this.$refs.menu != undefined) { + this.$refs.menu.setCheckedKeys([]); + } + this.menuExpand = false, + this.menuNodeAll = false, + this.deptExpand = true, + this.deptNodeAll = false, + this.form = { + roleId: undefined, + roleName: undefined, + roleKey: undefined, + roleSort: 0, + status: "0", + menuIds: [], + deptIds: [], + menuCheckStrictly: true, + deptCheckStrictly: true, + remark: undefined + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.dateRange = []; + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.roleId) + this.single = selection.length!=1 + this.multiple = !selection.length + }, + // 鏇村鎿嶄綔瑙﹀彂 + handleCommand(command, row) { + switch (command) { + case "handleDataScope": + this.handleDataScope(row); + break; + case "handleAuthUser": + this.handleAuthUser(row); + break; + default: + break; + } + }, + // 鏍戞潈闄愶紙灞曞紑/鎶樺彔锛� + handleCheckedTreeExpand(value, type) { + if (type == 'menu') { + let treeList = this.menuOptions; + for (let i = 0; i < treeList.length; i++) { + this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value; + } + } else if (type == 'dept') { + let treeList = this.deptOptions; + for (let i = 0; i < treeList.length; i++) { + this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value; + } + } + }, + // 鏍戞潈闄愶紙鍏ㄩ��/鍏ㄤ笉閫夛級 + handleCheckedTreeNodeAll(value, type) { + if (type == 'menu') { + this.$refs.menu.setCheckedNodes(value ? this.menuOptions: []); + } else if (type == 'dept') { + this.$refs.dept.setCheckedNodes(value ? this.deptOptions: []); + } + }, + // 鏍戞潈闄愶紙鐖跺瓙鑱斿姩锛� + handleCheckedTreeConnect(value, type) { + if (type == 'menu') { + this.form.menuCheckStrictly = value ? true: false; + } else if (type == 'dept') { + this.form.deptCheckStrictly = value ? true: false; + } + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + this.getMenuTreeselect(); + this.open = true; + this.title = "娣诲姞瑙掕壊"; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const roleId = row.roleId || this.ids + const roleMenu = this.getRoleMenuTreeselect(roleId); + getRole(roleId).then(response => { + this.form = response.data; + this.open = true; + this.$nextTick(() => { + roleMenu.then(res => { + let checkedKeys = res.checkedKeys + checkedKeys.forEach((v) => { + this.$nextTick(()=>{ + this.$refs.menu.setChecked(v, true ,false); + }) + }) + }); + }); + this.title = "淇敼瑙掕壊"; + }); + }, + /** 閫夋嫨瑙掕壊鏉冮檺鑼冨洿瑙﹀彂 */ + dataScopeSelectChange(value) { + if(value !== '2') { + this.$refs.dept.setCheckedKeys([]); + } + }, + /** 鍒嗛厤鏁版嵁鏉冮檺鎿嶄綔 */ + handleDataScope(row) { + this.reset(); + const deptTreeSelect = this.getDeptTree(row.roleId); + getRole(row.roleId).then(response => { + this.form = response.data; + this.openDataScope = true; + this.$nextTick(() => { + deptTreeSelect.then(res => { + this.$refs.dept.setCheckedKeys(res.checkedKeys); + }); + }); + this.title = "鍒嗛厤鏁版嵁鏉冮檺"; + }); + }, + /** 鍒嗛厤鐢ㄦ埛鎿嶄綔 */ + handleAuthUser: function(row) { + const roleId = row.roleId; + this.$router.push("/system/role-auth/user/" + roleId); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.roleId != undefined) { + this.form.menuIds = this.getMenuAllCheckedKeys(); + updateRole(this.form).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + }); + } else { + this.form.menuIds = this.getMenuAllCheckedKeys(); + addRole(this.form).then(response => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鎻愪氦鎸夐挳锛堟暟鎹潈闄愶級 */ + submitDataScope: function() { + if (this.form.roleId != undefined) { + this.form.deptIds = this.getDeptAllCheckedKeys(); + dataScope(this.form).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.openDataScope = false; + this.getList(); + }); + } + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const roleIds = row.roleId || this.ids; + this.$modal.confirm('鏄惁纭鍒犻櫎瑙掕壊缂栧彿涓�"' + roleIds + '"鐨勬暟鎹」锛�').then(function() { + return delRole(roleIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(() => {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download('system/role/export', { + ...this.queryParams + }, `role_${new Date().getTime()}.xlsx`) + } + } +}; +</script> \ No newline at end of file diff --git a/src/views/system/role/selectUser.vue b/src/views/system/role/selectUser.vue new file mode 100644 index 0000000..b2b072f --- /dev/null +++ b/src/views/system/role/selectUser.vue @@ -0,0 +1,138 @@ +<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 { 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() { + unallocatedUserList(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); + if (res.code === 200) { + this.visible = false; + this.$emit("ok"); + } + }); + } + } +}; +</script> diff --git a/src/views/system/user/authRole.vue b/src/views/system/user/authRole.vue new file mode 100644 index 0000000..ab5e72f --- /dev/null +++ b/src/views/system/user/authRole.vue @@ -0,0 +1,117 @@ +<template> + <div class="app-container"> + <h4 class="form-header h4">鍩烘湰淇℃伅</h4> + <el-form ref="form" :model="form" label-width="80px"> + <el-row> + <el-col :span="8" :offset="2"> + <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName"> + <el-input v-model="form.nickName" disabled /> + </el-form-item> + </el-col> + <el-col :span="8" :offset="2"> + <el-form-item label="鐧诲綍璐﹀彿" prop="userName"> + <el-input v-model="form.userName" disabled /> + </el-form-item> + </el-col> + </el-row> + </el-form> + + <h4 class="form-header h4">瑙掕壊淇℃伅</h4> + <el-table v-loading="loading" :row-key="getRowKey" @row-click="clickRow" ref="table" @selection-change="handleSelectionChange" :data="roles.slice((pageNum-1)*pageSize,pageNum*pageSize)"> + <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 type="selection" :reserve-selection="true" width="55"></el-table-column> + <el-table-column label="瑙掕壊缂栧彿" align="center" prop="roleId" /> + <el-table-column label="瑙掕壊鍚嶇О" align="center" prop="roleName" /> + <el-table-column label="鏉冮檺瀛楃" align="center" prop="roleKey" /> + <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="pageNum" :limit.sync="pageSize" /> + + <el-form label-width="100px"> + <el-form-item style="text-align: center;margin-left:-120px;margin-top:30px;"> + <el-button type="primary" @click="submitForm()">鎻愪氦</el-button> + <el-button @click="close()">杩斿洖</el-button> + </el-form-item> + </el-form> + </div> +</template> + +<script> +import { getAuthRole, updateAuthRole } from "@/api/system/user"; + +export default { + name: "AuthRole", + data() { + return { + // 閬僵灞� + loading: true, + // 鍒嗛〉淇℃伅 + total: 0, + pageNum: 1, + pageSize: 10, + // 閫変腑瑙掕壊缂栧彿 + roleIds:[], + // 瑙掕壊淇℃伅 + roles: [], + // 鐢ㄦ埛淇℃伅 + form: {} + }; + }, + created() { + const userId = this.$route.params && this.$route.params.userId; + if (userId) { + this.loading = true; + getAuthRole(userId).then((response) => { + this.form = response.user; + this.roles = response.roles; + this.total = this.roles.length; + this.$nextTick(() => { + this.roles.forEach((row) => { + if (row.flag) { + this.$refs.table.toggleRowSelection(row); + } + }); + }); + this.loading = false; + }); + } + }, + methods: { + /** 鍗曞嚮閫変腑琛屾暟鎹� */ + clickRow(row) { + this.$refs.table.toggleRowSelection(row); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.roleIds = selection.map((item) => item.roleId); + }, + // 淇濆瓨閫変腑鐨勬暟鎹紪鍙� + getRowKey(row) { + return row.roleId; + }, + /** 鎻愪氦鎸夐挳 */ + submitForm() { + const userId = this.form.userId; + const roleIds = this.roleIds.join(","); + updateAuthRole({ userId: userId, roleIds: roleIds }).then((response) => { + this.$modal.msgSuccess("鎺堟潈鎴愬姛"); + this.close(); + }); + }, + /** 鍏抽棴鎸夐挳 */ + close() { + const obj = { path: "/system/user" }; + this.$tab.closeOpenPage(obj); + }, + }, +}; +</script> \ No newline at end of file diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue new file mode 100644 index 0000000..ae87fe4 --- /dev/null +++ b/src/views/system/user/index.vue @@ -0,0 +1,670 @@ +<template> + <div class="app-container"> + <el-row :gutter="20"> + <!--閮ㄩ棬鏁版嵁--> + <el-col :span="4" :xs="24"> + <div class="head-container"> + <el-input + v-model="deptName" + placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" + clearable + size="small" + prefix-icon="el-icon-search" + style="margin-bottom: 20px" + /> + </div> + <div class="head-container"> + <el-tree + :data="deptOptions" + :props="defaultProps" + :expand-on-click-node="false" + :filter-node-method="filterNode" + ref="tree" + node-key="id" + default-expand-all + highlight-current + @node-click="handleNodeClick" + /> + </div> + </el-col> + <!--鐢ㄦ埛鏁版嵁--> + <el-col :span="20" :xs="24"> + <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"> + <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 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:user: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:user: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:user:remove']" + >鍒犻櫎</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="info" + plain + icon="el-icon-upload2" + size="mini" + @click="handleImport" + v-hasPermi="['system:user:import']" + >瀵煎叆</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:user:export']" + >瀵煎嚭</el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar> + </el-row> + + <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="50" align="center" /> + <el-table-column label="鐢ㄦ埛缂栧彿" align="center" key="userId" prop="userId" v-if="columns[0].visible" /> + <el-table-column label="鐢ㄦ埛鍚嶇О" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" /> + <el-table-column label="鐢ㄦ埛鏄电О" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" /> + <el-table-column label="閮ㄩ棬" align="center" key="deptName" prop="dept.deptName" v-if="columns[3].visible" :show-overflow-tooltip="true" /> + <el-table-column label="鎵嬫満鍙风爜" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" /> + <el-table-column label="鐘舵��" align="center" key="status" v-if="columns[5].visible"> + <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" prop="createTime" v-if="columns[6].visible" width="160"> + <template slot-scope="scope"> + <span>{{ parseTime(scope.row.createTime) }}</span> + </template> + </el-table-column> + <el-table-column + label="鎿嶄綔" + align="center" + width="160" + class-name="small-padding fixed-width" + > + <template slot-scope="scope" v-if="scope.row.userId !== 1"> + <el-button + size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['system:user:edit']" + >淇敼</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['system:user:remove']" + >鍒犻櫎</el-button> + <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:user:resetPwd', 'system:user:edit']"> + <el-button size="mini" type="text" icon="el-icon-d-arrow-right">鏇村</el-button> + <el-dropdown-menu slot="dropdown"> + <el-dropdown-item command="handleResetPwd" icon="el-icon-key" + v-hasPermi="['system:user:resetPwd']">閲嶇疆瀵嗙爜</el-dropdown-item> + <el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check" + v-hasPermi="['system:user:edit']">鍒嗛厤瑙掕壊</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-col> + </el-row> + + <!-- 娣诲姞鎴栦慨鏀圭敤鎴烽厤缃璇濇 --> + <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="12"> + <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName"> + <el-input v-model="form.nickName" placeholder="璇疯緭鍏ョ敤鎴锋樀绉�" maxlength="30" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="褰掑睘閮ㄩ棬" prop="deptId"> + <treeselect v-model="form.deptId" :options="deptOptions" :show-count="true" placeholder="璇烽�夋嫨褰掑睘閮ㄩ棬" /> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :span="12"> + <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber"> + <el-input v-model="form.phonenumber" placeholder="璇疯緭鍏ユ墜鏈哄彿鐮�" maxlength="11" /> + </el-form-item> + </el-col> + <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-row> + <el-row> + <el-col :span="12"> + <el-form-item v-if="form.userId == undefined" label="鐢ㄦ埛鍚嶇О" prop="userName"> + <el-input v-model="form.userName" placeholder="璇疯緭鍏ョ敤鎴峰悕绉�" maxlength="30" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item v-if="form.userId == undefined" label="鐢ㄦ埛瀵嗙爜" prop="password"> + <el-input v-model="form.password" placeholder="璇疯緭鍏ョ敤鎴峰瘑鐮�" type="password" maxlength="20" show-password/> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :span="12"> + <el-form-item label="鐢ㄦ埛鎬у埆"> + <el-select v-model="form.sex" placeholder="璇烽�夋嫨鎬у埆"> + <el-option + v-for="dict in dict.type.sys_user_sex" + :key="dict.value" + :label="dict.label" + :value="dict.value" + ></el-option> + </el-select> + </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-row> + <el-col :span="12"> + <el-form-item label="宀椾綅"> + <el-select v-model="form.postIds" multiple placeholder="璇烽�夋嫨宀椾綅"> + <el-option + v-for="item in postOptions" + :key="item.postId" + :label="item.postName" + :value="item.postId" + :disabled="item.status == 1" + ></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="瑙掕壊"> + <el-select v-model="form.roleIds" multiple placeholder="璇烽�夋嫨瑙掕壊"> + <el-option + v-for="item in roleOptions" + :key="item.roleId" + :label="item.roleName" + :value="item.roleId" + :disabled="item.status == 1" + ></el-option> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :span="24"> + <el-form-item label="澶囨敞"> + <el-input v-model="form.remark" type="textarea" placeholder="璇疯緭鍏ュ唴瀹�"></el-input> + </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="upload.title" :visible.sync="upload.open" width="400px" append-to-body> + <el-upload + ref="upload" + :limit="1" + accept=".xlsx, .xls" + :headers="upload.headers" + :action="upload.url + '?updateSupport=' + upload.updateSupport" + :disabled="upload.isUploading" + :on-progress="handleFileUploadProgress" + :on-success="handleFileSuccess" + :auto-upload="false" + drag + > + <i class="el-icon-upload"></i> + <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div> + <div class="el-upload__tip text-center" slot="tip"> + <div class="el-upload__tip" slot="tip"> + <el-checkbox v-model="upload.updateSupport" /> 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹� + </div> + <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span> + <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">涓嬭浇妯℃澘</el-link> + </div> + </el-upload> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button> + <el-button @click="upload.open = false">鍙� 娑�</el-button> + </div> + </el-dialog> + </div> +</template> + +<script> +import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, deptTreeSelect } from "@/api/system/user"; +import { getToken } from "@/utils/auth"; +import Treeselect from "@riophae/vue-treeselect"; +import "@riophae/vue-treeselect/dist/vue-treeselect.css"; + +export default { + name: "User", + dicts: ['sys_normal_disable', 'sys_user_sex'], + components: { Treeselect }, + data() { + return { + // 閬僵灞� + loading: true, + // 閫変腑鏁扮粍 + ids: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 鐢ㄦ埛琛ㄦ牸鏁版嵁 + userList: null, + // 寮瑰嚭灞傛爣棰� + title: "", + // 閮ㄩ棬鏍戦�夐」 + deptOptions: undefined, + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 閮ㄩ棬鍚嶇О + deptName: undefined, + // 榛樿瀵嗙爜 + initPassword: undefined, + // 鏃ユ湡鑼冨洿 + dateRange: [], + // 宀椾綅閫夐」 + postOptions: [], + // 瑙掕壊閫夐」 + roleOptions: [], + // 琛ㄥ崟鍙傛暟 + form: {}, + defaultProps: { + children: "children", + label: "label" + }, + // 鐢ㄦ埛瀵煎叆鍙傛暟 + upload: { + // 鏄惁鏄剧ず寮瑰嚭灞傦紙鐢ㄦ埛瀵煎叆锛� + open: false, + // 寮瑰嚭灞傛爣棰橈紙鐢ㄦ埛瀵煎叆锛� + title: "", + // 鏄惁绂佺敤涓婁紶 + isUploading: false, + // 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹� + updateSupport: 0, + // 璁剧疆涓婁紶鐨勮姹傚ご閮� + headers: { Authorization: "Bearer " + getToken() }, + // 涓婁紶鐨勫湴鍧� + url: process.env.VUE_APP_BASE_API + "/system/user/importData" + }, + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + userName: undefined, + phonenumber: undefined, + status: undefined, + deptId: undefined + }, + // 鍒椾俊鎭� + columns: [ + { key: 0, label: `鐢ㄦ埛缂栧彿`, visible: true }, + { key: 1, label: `鐢ㄦ埛鍚嶇О`, visible: true }, + { key: 2, label: `鐢ㄦ埛鏄电О`, visible: true }, + { key: 3, label: `閮ㄩ棬`, visible: true }, + { key: 4, label: `鎵嬫満鍙风爜`, visible: true }, + { key: 5, label: `鐘舵�乣, visible: true }, + { key: 6, label: `鍒涘缓鏃堕棿`, visible: true } + ], + // 琛ㄥ崟鏍¢獙 + rules: { + userName: [ + { required: true, message: "鐢ㄦ埛鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }, + { min: 2, max: 20, message: '鐢ㄦ埛鍚嶇О闀垮害蹇呴』浠嬩簬 2 鍜� 20 涔嬮棿', trigger: 'blur' } + ], + nickName: [ + { required: true, message: "鐢ㄦ埛鏄电О涓嶈兘涓虹┖", trigger: "blur" } + ], + password: [ + { required: true, message: "鐢ㄦ埛瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" }, + { min: 5, max: 20, message: '鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿', trigger: 'blur' } + ], + email: [ + { + type: "email", + message: "璇疯緭鍏ユ纭殑閭鍦板潃", + trigger: ["blur", "change"] + } + ], + phonenumber: [ + { + pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, + message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", + trigger: "blur" + } + ] + } + }; + }, + watch: { + // 鏍规嵁鍚嶇О绛涢�夐儴闂ㄦ爲 + deptName(val) { + this.$refs.tree.filter(val); + } + }, + created() { + this.getList(); + this.getDeptTree(); + this.getConfigKey("sys.user.initPassword").then(response => { + this.initPassword = response.msg; + }); + }, + methods: { + /** 鏌ヨ鐢ㄦ埛鍒楄〃 */ + getList() { + this.loading = true; + listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => { + this.userList = response.rows; + this.total = response.total; + this.loading = false; + } + ); + }, + /** 鏌ヨ閮ㄩ棬涓嬫媺鏍戠粨鏋� */ + getDeptTree() { + deptTreeSelect().then(response => { + this.deptOptions = response.data; + }); + }, + // 绛涢�夎妭鐐� + filterNode(value, data) { + if (!value) return true; + return data.label.indexOf(value) !== -1; + }, + // 鑺傜偣鍗曞嚮浜嬩欢 + handleNodeClick(data) { + this.queryParams.deptId = data.id; + this.handleQuery(); + }, + // 鐢ㄦ埛鐘舵�佷慨鏀� + handleStatusChange(row) { + let text = row.status === "0" ? "鍚敤" : "鍋滅敤"; + this.$modal.confirm('纭瑕�"' + text + '""' + row.userName + '"鐢ㄦ埛鍚楋紵').then(function() { + return changeUserStatus(row.userId, row.status); + }).then(() => { + this.$modal.msgSuccess(text + "鎴愬姛"); + }).catch(function() { + row.status = row.status === "0" ? "1" : "0"; + }); + }, + // 鍙栨秷鎸夐挳 + cancel() { + this.open = false; + this.reset(); + }, + // 琛ㄥ崟閲嶇疆 + reset() { + this.form = { + userId: undefined, + deptId: undefined, + userName: undefined, + nickName: undefined, + password: undefined, + phonenumber: undefined, + email: undefined, + sex: undefined, + status: "0", + remark: undefined, + postIds: [], + roleIds: [] + }; + this.resetForm("form"); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.dateRange = []; + this.resetForm("queryForm"); + this.queryParams.deptId = undefined; + this.$refs.tree.setCurrentKey(null); + this.handleQuery(); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.userId); + this.single = selection.length != 1; + this.multiple = !selection.length; + }, + // 鏇村鎿嶄綔瑙﹀彂 + handleCommand(command, row) { + switch (command) { + case "handleResetPwd": + this.handleResetPwd(row); + break; + case "handleAuthRole": + this.handleAuthRole(row); + break; + default: + break; + } + }, + /** 鏂板鎸夐挳鎿嶄綔 */ + handleAdd() { + this.reset(); + getUser().then(response => { + this.postOptions = response.posts; + this.roleOptions = response.roles; + this.open = true; + this.title = "娣诲姞鐢ㄦ埛"; + this.form.password = this.initPassword; + }); + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleUpdate(row) { + this.reset(); + const userId = row.userId || this.ids; + getUser(userId).then(response => { + this.form = response.data; + this.postOptions = response.posts; + this.roleOptions = response.roles; + this.$set(this.form, "postIds", response.postIds); + this.$set(this.form, "roleIds", response.roleIds); + this.open = true; + this.title = "淇敼鐢ㄦ埛"; + this.form.password = ""; + }); + }, + /** 閲嶇疆瀵嗙爜鎸夐挳鎿嶄綔 */ + handleResetPwd(row) { + this.$prompt('璇疯緭鍏�"' + row.userName + '"鐨勬柊瀵嗙爜', "鎻愮ず", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + closeOnClickModal: false, + inputPattern: /^.{5,20}$/, + inputErrorMessage: "鐢ㄦ埛瀵嗙爜闀垮害蹇呴』浠嬩簬 5 鍜� 20 涔嬮棿" + }).then(({ value }) => { + resetUserPwd(row.userId, value).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛锛屾柊瀵嗙爜鏄細" + value); + }); + }).catch(() => {}); + }, + /** 鍒嗛厤瑙掕壊鎿嶄綔 */ + handleAuthRole: function(row) { + const userId = row.userId; + this.$router.push("/system/user-auth/role/" + userId); + }, + /** 鎻愪氦鎸夐挳 */ + submitForm: function() { + this.$refs["form"].validate(valid => { + if (valid) { + if (this.form.userId != undefined) { + updateUser(this.form).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.open = false; + this.getList(); + }); + } else { + addUser(this.form).then(response => { + this.$modal.msgSuccess("鏂板鎴愬姛"); + this.open = false; + this.getList(); + }); + } + } + }); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const userIds = row.userId || this.ids; + this.$modal.confirm('鏄惁纭鍒犻櫎鐢ㄦ埛缂栧彿涓�"' + userIds + '"鐨勬暟鎹」锛�').then(function() { + return delUser(userIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(() => {}); + }, + /** 瀵煎嚭鎸夐挳鎿嶄綔 */ + handleExport() { + this.download('system/user/export', { + ...this.queryParams + }, `user_${new Date().getTime()}.xlsx`) + }, + /** 瀵煎叆鎸夐挳鎿嶄綔 */ + handleImport() { + this.upload.title = "鐢ㄦ埛瀵煎叆"; + this.upload.open = true; + }, + /** 涓嬭浇妯℃澘鎿嶄綔 */ + importTemplate() { + this.download('system/user/importTemplate', { + }, `user_template_${new Date().getTime()}.xlsx`) + }, + // 鏂囦欢涓婁紶涓鐞� + handleFileUploadProgress(event, file, fileList) { + this.upload.isUploading = true; + }, + // 鏂囦欢涓婁紶鎴愬姛澶勭悊 + handleFileSuccess(response, file, fileList) { + this.upload.open = false; + this.upload.isUploading = false; + this.$refs.upload.clearFiles(); + this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "瀵煎叆缁撴灉", { dangerouslyUseHTMLString: true }); + this.getList(); + }, + // 鎻愪氦涓婁紶鏂囦欢 + submitFileForm() { + this.$refs.upload.submit(); + } + } +}; +</script> \ No newline at end of file diff --git a/src/views/system/user/profile/index.vue b/src/views/system/user/profile/index.vue new file mode 100644 index 0000000..33553af --- /dev/null +++ b/src/views/system/user/profile/index.vue @@ -0,0 +1,212 @@ +<template> + <div class="app-container"> + <el-row :gutter="20"> + <el-col :span="6" :xs="24"> + <el-card class="box-card"> + <div slot="header" class="clearfix"> + <span>涓汉淇℃伅</span> + </div> + <div> + <div class="text-center"> + <userAvatar :user="user" /> + </div> + <ul class="list-group list-group-striped"> + <li class="list-group-item"> + <svg-icon icon-class="user" />鐢ㄦ埛鍚嶇О + <div class="pull-right">{{ user.userName }}</div> + </li> + <li class="list-group-item"> + <svg-icon icon-class="phone" />鎵嬫満鍙风爜 + <div class="pull-right">{{ user.phonenumber }}</div> + </li> + <li class="list-group-item"> + <svg-icon icon-class="email" />鐢ㄦ埛閭 + <div class="pull-right">{{ user.email }}</div> + </li> + <li class="list-group-item"> + <svg-icon icon-class="tree" />鎵�灞為儴闂� + <div v-if="user.dept" class="pull-right">{{ user.dept.deptName }} / {{ postGroup }}</div> + </li> + <li class="list-group-item"> + <svg-icon icon-class="peoples" />鎵�灞炶鑹� + <div class="pull-right">{{ roleGroup }}</div> + </li> + <li class="list-group-item"> + <svg-icon icon-class="date" />鍒涘缓鏃ユ湡 + <div class="pull-right">{{ user.createTime }}</div> + </li> + <li class="list-group-item"> + <svg-icon icon-class="wechat" />寰俊缁戝畾 + <div v-if="wxbind" style="color:#007AFf" class="pull-right" @click="secureBind">宸茬粦瀹�,鐐瑰嚮瑙g粦</div> + <div v-else class="pull-right" @click="loginWxCode">鏈粦瀹�,鐐瑰嚮缁戝畾</div> + </li> + <div id="weixinLogin" style="width: 150px;height: 200px;"></div> + </ul> + </div> + </el-card> + </el-col> + <el-col :span="18" :xs="24"> + <el-card> + <div slot="header" class="clearfix"> + <span>鍩烘湰璧勬枡</span> + </div> + <el-tabs v-model="activeTab"> + <el-tab-pane label="鍩烘湰璧勬枡" name="userinfo"> + <userInfo :user="user" /> + </el-tab-pane> + <el-tab-pane label="淇敼瀵嗙爜" name="resetPwd"> + <resetPwd /> + </el-tab-pane> + </el-tabs> + </el-card> + </el-col> + </el-row> + <el-dialog title="璇疯緭鍏ユ偍鐨勫瘑鐮�" :visible.sync="secureBindDialog" width="600px" append-to-body> + <el-form label-width="150px"> + <el-form-item label="瀵嗙爜" prop="pasaward"> + <el-input v-model="password" style="width: 80%" type="password" /> + </el-form-item> + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button @click="closeSummaryDialog">鍏� 闂�</el-button> + <el-button class="btns" type="primary" @click="handleSecureBind">纭畾</el-button> + </div> + </el-dialog> + </div> +</template> +<script > +import userAvatar from './userAvatar'; +import userInfo from './userInfo'; +import resetPwd from './resetPwd'; +import { getWxBindMsg} from '@/api/login'; +import { getUserProfile, getLoginParam, secureBind } from '@/api/system/user'; + +export default { + name: 'Profile', + components: { userAvatar, userInfo, resetPwd }, + data() { + return { + user: {}, + roleGroup: {}, + postGroup: {}, + activeTab: 'userinfo', + qrText: 'fastbee', + wxbind: '', + secureBindDialog: false, + password: '', + verifyType: 1, + userPhone: '', + smsCode: '', + }; + }, + + created() { + this.getUser(); + const wxBindMsgId = this.$route.query.wxBindMsgId; + if (wxBindMsgId != null && wxBindMsgId !== undefined) { + this.getWxBindMsg(); + } else { + console.log('姝ゆ椂娌℃湁杩涜缁戝畾鎿嶄綔锛�'); + } + }, + + mounted() { + const script = document.createElement('script'); + script.type = 'text/javascript', + script.src = 'http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js', + document.body.appendChild(script); + }, + methods: { + getUser() { + getUserProfile().then(response => { + console.log(response.data); + this.user = response.data; + this.wxbind = response.wxBind; + this.roleGroup = response.roleGroup; + this.postGroup = response.postGroup; + }); + }, + secureBind() { + this.secureBindDialog = true; + }, + handleSecureBind() { + const params = { + password: this.password, + verifyType: this.verifyType, + userPhone: this.userPhone, + smsCode: this.smsCode, + }; + secureBind(params).then(response => { + this.loading = true; + this.$modal.msgSuccess(response.msg); + this.secureBindDialog = false; + if (response.code === 200) { + this.getUser(); + } + }) + .catch(() => { + // eslint-disable-next-line no-undef + this.$modal.msgError(response.msg); + this.loading = false; + }); + }, + closeSummaryDialog() { + this.secureBindDialog = false; + }, + // 寰俊缁戝畾浜岀淮鐮� + loginWxCode() { + getLoginParam().then(response => { + // 瀹炰緥寰俊js瀵硅薄 + // eslint-disable-next-line no-undef + const s = document.createElement('script'); + s.type = 'text/javascript'; + s.src = 'https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js'; + const wxElement = document.body.appendChild(s); + wxElement.onload = function () { + var obj = new WxLogin({ + self_redirect: false, + id: 'weixinLogin', + appid: response.data.appid, + scope: response.data.scope, + redirect_uri: response.data.redirectUri, + state: response.data.state, + style: 'black', + href: 'data:text/css;base64,LmltcG93ZXJCb3ggLnRpdGxlIHsKIGRpc3BsYXk6IG5vbmU7Cn0KLmltcG93ZXJCb3ggLnN0YXR1cy5zdGF0dXNfYnJvd3NlciB7CiBkaXNwbGF5OiBub25lOwp9Ci5pbXBvd2VyQm94IC5xcmNvZGUgewogYm9yZGVyOm5vbmU7CiB3aWR0aDogMjAwcHg7CiBoZWlnaHQ6IDIwMHB4OwogbWFyZ2luOjAgYXV0bzsKfQouaW1wb3dlckJveCAuc3RhdHVzewogZGlzcGxheTogbm9uZQp9', + }); + }; + }); + }, + // 鑾峰彇寰俊缁戝畾杩斿洖缁撴灉淇℃伅 + getWxBindMsg() { + const query = this.$route.query; + const wxBindMsgId = query.wxBindMsgId; + getWxBindMsg(wxBindMsgId).then((res) => { + this.$modal.msgSuccess(res.msg) + .catch(() => { + setTimeout(function() { + this.$modal.msgError(res.msg); + }, 1000); + }); + }); + }, + }, +}; +</script> +<styule lang="scss"> +// 鑷畾涔変簩缁寸爜鏍峰紡 +.impowerBox .title { + display: none; +} +.impowerBox .status.status_browser { + display: none; +} +.impowerBox .qrcode { + border:none; + width: 200px; + height: 200px; + margin:0 auto; +} +.impowerBox .status{ + display: none +} +</styule> diff --git a/src/views/system/user/profile/resetPwd.vue b/src/views/system/user/profile/resetPwd.vue new file mode 100644 index 0000000..6c86c38 --- /dev/null +++ b/src/views/system/user/profile/resetPwd.vue @@ -0,0 +1,87 @@ +<template> + <el-form ref="form" :model="user" :rules="rules" label-width="80px"> + <el-form-item label="鏃у瘑鐮�" prop="oldPassword"> + <el-input v-model="user.oldPassword" placeholder="璇疯緭鍏ユ棫瀵嗙爜" type="password" show-password /> + </el-form-item> + <el-form-item label="鏂板瘑鐮�" prop="newPassword"> + <el-input v-model="user.newPassword" placeholder="璇疯緭鍏ユ柊瀵嗙爜" type="password" show-password /> + </el-form-item> + <el-form-item label="纭瀵嗙爜" prop="confirmPassword"> + <el-input v-model="user.confirmPassword" placeholder="璇风‘璁ゆ柊瀵嗙爜" type="password" show-password /> + </el-form-item> + <el-form-item> + <el-button type="primary" size="mini" @click="submit">淇濆瓨</el-button> + <el-button type="danger" size="mini" @click="close">鍏抽棴</el-button> + </el-form-item> + </el-form> +</template> + +<script> +import { updateUserPwd } from "@/api/system/user"; + +export default { + data() { + const equalToPassword = (rule, value, callback) => { + if (this.user.newPassword !== value) { + callback(new Error("涓ゆ杈撳叆鐨勫瘑鐮佷笉涓�鑷�")); + } else { + callback(); + } + }; + return { + user: { + oldPassword: undefined, + newPassword: undefined, + confirmPassword: undefined + }, + // 琛ㄥ崟鏍¢獙 + rules: { + oldPassword: [ + { required: true, message: "鏃у瘑鐮佷笉鑳戒负绌�", trigger: "blur" } + ], + newPassword: [ + { required: true, message: "鏂板瘑鐮佷笉鑳戒负绌�", trigger: "blur" }, + { min: 6, max: 20, message: "闀垮害鍦� 6 鍒� 20 涓瓧绗�", trigger: "blur" }, + { + trigger: 'blur', + validator: (rule, value, callback) => { + var passwordreg = /(?![A-Z]*$)(?![a-z]*$)(?![0-9]*$)(?![^a-zA-Z0-9]*$)/ + if (!passwordreg.test(value)) { + callback(new Error('瀵嗙爜蹇呴』鐢卞ぇ鍐欏瓧姣嶃�佸皬鍐欏瓧姣嶃�佹暟瀛椼�佺壒娈婄鍙蜂腑鐨�2绉嶅強浠ヤ笂绫诲瀷缁勬垚!')) + } + else { + callback() + } + } + }, + ], + confirmPassword: [ + { required: true, message: "纭瀵嗙爜涓嶈兘涓虹┖", trigger: "blur" }, + { required: true, validator: equalToPassword, trigger: "blur" }, + ] + } + }; + }, + methods: { + submit() { + this.$refs["form"].validate(valid => { + if (valid) { + updateUserPwd(this.user.oldPassword, this.user.newPassword).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛锛岃閲嶆柊鐧诲綍锛�"); + if (response.code == 200) { + //娓呴櫎鐧诲綍缂撳瓨 + localStorage.removeItem('token'); + this.$store.dispatch('LogOut').then(() => { + location.href = '/index'; + }) + } + }); + } + }); + }, + close() { + this.$tab.closePage(); + } + } +}; +</script> diff --git a/src/views/system/user/profile/userAvatar.vue b/src/views/system/user/profile/userAvatar.vue new file mode 100644 index 0000000..70d8487 --- /dev/null +++ b/src/views/system/user/profile/userAvatar.vue @@ -0,0 +1,187 @@ +<template> + <div> + <div class="user-info-head" @click="editCropper()"><img v-bind:src="options.img" title="鐐瑰嚮涓婁紶澶村儚" class="img-circle img-lg" /></div> + <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog"> + <el-row> + <el-col :xs="24" :md="12" :style="{height: '350px'}"> + <vue-cropper + ref="cropper" + :img="options.img" + :info="true" + :autoCrop="options.autoCrop" + :autoCropWidth="options.autoCropWidth" + :autoCropHeight="options.autoCropHeight" + :fixedBox="options.fixedBox" + :outputType="options.outputType" + @realTime="realTime" + v-if="visible" + /> + </el-col> + <el-col :xs="24" :md="12" :style="{height: '350px'}"> + <div class="avatar-upload-preview"> + <img :src="previews.url" :style="previews.img" /> + </div> + </el-col> + </el-row> + <br /> + <el-row> + <el-col :lg="2" :sm="3" :xs="3"> + <el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload"> + <el-button size="small"> + 閫夋嫨 + <i class="el-icon-upload el-icon--right"></i> + </el-button> + </el-upload> + </el-col> + <el-col :lg="{span: 1, offset: 2}" :sm="2" :xs="2"> + <el-button icon="el-icon-plus" size="small" @click="changeScale(1)"></el-button> + </el-col> + <el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2"> + <el-button icon="el-icon-minus" size="small" @click="changeScale(-1)"></el-button> + </el-col> + <el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2"> + <el-button icon="el-icon-refresh-left" size="small" @click="rotateLeft()"></el-button> + </el-col> + <el-col :lg="{span: 1, offset: 1}" :sm="2" :xs="2"> + <el-button icon="el-icon-refresh-right" size="small" @click="rotateRight()"></el-button> + </el-col> + <el-col :lg="{span: 2, offset: 6}" :sm="2" :xs="2"> + <el-button type="primary" size="small" @click="uploadImg()">鎻� 浜�</el-button> + </el-col> + </el-row> + </el-dialog> + </div> +</template> + +<script> +import store from "@/store"; +import { VueCropper } from "vue-cropper"; +import { uploadAvatar } from "@/api/system/user"; +import { debounce } from '@/utils' + +export default { + components: { VueCropper }, + props: { + user: { + type: Object + } + }, + data() { + return { + // 鏄惁鏄剧ず寮瑰嚭灞� + open: false, + // 鏄惁鏄剧ずcropper + visible: false, + // 寮瑰嚭灞傛爣棰� + title: "淇敼澶村儚", + options: { + img: store.getters.avatar, //瑁佸壀鍥剧墖鐨勫湴鍧� + autoCrop: true, // 鏄惁榛樿鐢熸垚鎴浘妗� + autoCropWidth: 200, // 榛樿鐢熸垚鎴浘妗嗗搴� + autoCropHeight: 200, // 榛樿鐢熸垚鎴浘妗嗛珮搴� + fixedBox: true, // 鍥哄畾鎴浘妗嗗ぇ灏� 涓嶅厑璁告敼鍙� + outputType:"png" // 榛樿鐢熸垚鎴浘涓篜NG鏍煎紡 + }, + previews: {}, + resizeHandler: null + }; + }, + methods: { + // 缂栬緫澶村儚 + editCropper() { + this.open = true; + }, + // 鎵撳紑寮瑰嚭灞傜粨鏉熸椂鐨勫洖璋� + modalOpened() { + this.visible = true; + if (!this.resizeHandler) { + this.resizeHandler = debounce(() => { + this.refresh() + }, 100) + } + window.addEventListener("resize", this.resizeHandler) + }, + // 鍒锋柊缁勪欢 + refresh() { + this.$refs.cropper.refresh(); + }, + // 瑕嗙洊榛樿鐨勪笂浼犺涓� + requestUpload() { + }, + // 鍚戝乏鏃嬭浆 + rotateLeft() { + this.$refs.cropper.rotateLeft(); + }, + // 鍚戝彸鏃嬭浆 + rotateRight() { + this.$refs.cropper.rotateRight(); + }, + // 鍥剧墖缂╂斁 + changeScale(num) { + num = num || 1; + this.$refs.cropper.changeScale(num); + }, + // 涓婁紶棰勫鐞� + beforeUpload(file) { + if (file.type.indexOf("image/") == -1) { + this.$modal.msgError("鏂囦欢鏍煎紡閿欒锛岃涓婁紶鍥剧墖绫诲瀷,濡傦細JPG锛孭NG鍚庣紑鐨勬枃浠躲��"); + } else { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => { + this.options.img = reader.result; + }; + } + }, + // 涓婁紶鍥剧墖 + uploadImg() { + this.$refs.cropper.getCropBlob(data => { + let formData = new FormData(); + formData.append("avatarfile", data); + uploadAvatar(formData).then(response => { + this.open = false; + this.options.img = process.env.VUE_APP_BASE_API + response.imgUrl; + store.commit('SET_AVATAR', this.options.img); + this.$modal.msgSuccess("淇敼鎴愬姛"); + this.visible = false; + }); + }); + }, + // 瀹炴椂棰勮 + realTime(data) { + this.previews = data; + }, + // 鍏抽棴绐楀彛 + closeDialog() { + this.options.img = store.getters.avatar + this.visible = false; + window.removeEventListener("resize", this.resizeHandler) + } + } +}; +</script> +<style scoped lang="scss"> +.user-info-head { + position: relative; + display: inline-block; + height: 120px; +} + +.user-info-head:hover:after { + content: '+'; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + color: #eee; + background: rgba(0, 0, 0, 0.5); + font-size: 24px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + cursor: pointer; + line-height: 110px; + border-radius: 50%; +} +</style> diff --git a/src/views/system/user/profile/userInfo.vue b/src/views/system/user/profile/userInfo.vue new file mode 100644 index 0000000..c09a20b --- /dev/null +++ b/src/views/system/user/profile/userInfo.vue @@ -0,0 +1,75 @@ +<template> + <el-form ref="form" :model="user" :rules="rules" label-width="80px"> + <el-form-item label="鐢ㄦ埛鏄电О" prop="nickName"> + <el-input v-model="user.nickName" maxlength="30" /> + </el-form-item> + <el-form-item label="鎵嬫満鍙风爜" prop="phonenumber"> + <el-input v-model="user.phonenumber" maxlength="11" /> + </el-form-item> + <el-form-item label="閭" prop="email"> + <el-input v-model="user.email" maxlength="50" /> + </el-form-item> + <el-form-item label="鎬у埆"> + <el-radio-group v-model="user.sex"> + <el-radio label="0">鐢�</el-radio> + <el-radio label="1">濂�</el-radio> + </el-radio-group> + </el-form-item> + <el-form-item> + <el-button type="primary" size="mini" @click="submit">淇濆瓨</el-button> + <el-button type="danger" size="mini" @click="close">鍏抽棴</el-button> + </el-form-item> + </el-form> +</template> + +<script> +import { updateUserProfile } from "@/api/system/user"; + +export default { + props: { + user: { + type: Object + } + }, + data() { + return { + // 琛ㄥ崟鏍¢獙 + rules: { + nickName: [ + { required: true, message: "鐢ㄦ埛鏄电О涓嶈兘涓虹┖", trigger: "blur" } + ], + email: [ + { required: true, message: "閭鍦板潃涓嶈兘涓虹┖", trigger: "blur" }, + { + type: "email", + message: "璇疯緭鍏ユ纭殑閭鍦板潃", + trigger: ["blur", "change"] + } + ], + phonenumber: [ + { required: true, message: "鎵嬫満鍙风爜涓嶈兘涓虹┖", trigger: "blur" }, + { + pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, + message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", + trigger: "blur" + } + ] + } + }; + }, + methods: { + submit() { + this.$refs["form"].validate(valid => { + if (valid) { + updateUserProfile(this.user).then(response => { + this.$modal.msgSuccess("淇敼鎴愬姛"); + }); + } + }); + }, + close() { + this.$tab.closePage(); + } + } +}; +</script> diff --git a/src/views/tool/build/CodeTypeDialog.vue b/src/views/tool/build/CodeTypeDialog.vue new file mode 100644 index 0000000..b5c2e2e --- /dev/null +++ b/src/views/tool/build/CodeTypeDialog.vue @@ -0,0 +1,106 @@ +<template> + <div> + <el-dialog + v-bind="$attrs" + width="500px" + :close-on-click-modal="false" + :modal-append-to-body="false" + v-on="$listeners" + @open="onOpen" + @close="onClose" + > + <el-row :gutter="15"> + <el-form + ref="elForm" + :model="formData" + :rules="rules" + size="medium" + label-width="100px" + > + <el-col :span="24"> + <el-form-item label="鐢熸垚绫诲瀷" prop="type"> + <el-radio-group v-model="formData.type"> + <el-radio-button + v-for="(item, index) in typeOptions" + :key="index" + :label="item.value" + :disabled="item.disabled" + > + {{ item.label }} + </el-radio-button> + </el-radio-group> + </el-form-item> + <el-form-item v-if="showFileName" label="鏂囦欢鍚�" prop="fileName"> + <el-input v-model="formData.fileName" placeholder="璇疯緭鍏ユ枃浠跺悕" clearable /> + </el-form-item> + </el-col> + </el-form> + </el-row> + + <div slot="footer"> + <el-button @click="close"> + 鍙栨秷 + </el-button> + <el-button type="primary" @click="handleConfirm"> + 纭畾 + </el-button> + </div> + </el-dialog> + </div> +</template> +<script> +export default { + inheritAttrs: false, + props: ['showFileName'], + data() { + return { + formData: { + fileName: undefined, + type: 'file' + }, + rules: { + fileName: [{ + required: true, + message: '璇疯緭鍏ユ枃浠跺悕', + trigger: 'blur' + }], + type: [{ + required: true, + message: '鐢熸垚绫诲瀷涓嶈兘涓虹┖', + trigger: 'change' + }] + }, + typeOptions: [{ + label: '椤甸潰', + value: 'file' + }, { + label: '寮圭獥', + value: 'dialog' + }] + } + }, + computed: { + }, + watch: {}, + mounted() {}, + methods: { + onOpen() { + if (this.showFileName) { + this.formData.fileName = `${+new Date()}.vue` + } + }, + onClose() { + }, + close(e) { + this.$emit('update:visible', false) + }, + handleConfirm() { + this.$refs.elForm.validate(valid => { + if (!valid) return + this.$emit('confirm', { ...this.formData }) + this.close() + }) + } + } +} +</script> diff --git a/src/views/tool/build/DraggableItem.vue b/src/views/tool/build/DraggableItem.vue new file mode 100644 index 0000000..e881778 --- /dev/null +++ b/src/views/tool/build/DraggableItem.vue @@ -0,0 +1,100 @@ +<script> +import draggable from 'vuedraggable' +import render from '@/utils/generator/render' + +const components = { + itemBtns(h, element, index, parent) { + const { copyItem, deleteItem } = this.$listeners + return [ + <span class="drawing-item-copy" title="澶嶅埗" onClick={event => { + copyItem(element, parent); event.stopPropagation() + }}> + <i class="el-icon-copy-document" /> + </span>, + <span class="drawing-item-delete" title="鍒犻櫎" onClick={event => { + deleteItem(index, parent); event.stopPropagation() + }}> + <i class="el-icon-delete" /> + </span> + ] + } +} +const layouts = { + colFormItem(h, element, index, parent) { + const { activeItem } = this.$listeners + let className = this.activeId === element.formId ? 'drawing-item active-from-item' : 'drawing-item' + if (this.formConf.unFocusedComponentBorder) className += ' unfocus-bordered' + return ( + <el-col span={element.span} class={className} + nativeOnClick={event => { activeItem(element); event.stopPropagation() }}> + <el-form-item label-width={element.labelWidth ? `${element.labelWidth}px` : null} + label={element.label} required={element.required}> + <render key={element.renderKey} conf={element} onInput={ event => { + this.$set(element, 'defaultValue', event) + }} /> + </el-form-item> + {components.itemBtns.apply(this, arguments)} + </el-col> + ) + }, + rowFormItem(h, element, index, parent) { + const { activeItem } = this.$listeners + const className = this.activeId === element.formId ? 'drawing-row-item active-from-item' : 'drawing-row-item' + let child = renderChildren.apply(this, arguments) + if (element.type === 'flex') { + child = <el-row type={element.type} justify={element.justify} align={element.align}> + {child} + </el-row> + } + return ( + <el-col span={element.span}> + <el-row gutter={element.gutter} class={className} + nativeOnClick={event => { activeItem(element); event.stopPropagation() }}> + <span class="component-name">{element.componentName}</span> + <draggable list={element.children} animation={340} group="componentsGroup" class="drag-wrapper"> + {child} + </draggable> + {components.itemBtns.apply(this, arguments)} + </el-row> + </el-col> + ) + } +} + +function renderChildren(h, element, index, parent) { + if (!Array.isArray(element.children)) return null + return element.children.map((el, i) => { + const layout = layouts[el.layout] + if (layout) { + return layout.call(this, h, el, i, element.children) + } + return layoutIsNotFound() + }) +} + +function layoutIsNotFound() { + throw new Error(`娌℃湁涓�${this.element.layout}鍖归厤鐨刲ayout`) +} + +export default { + components: { + render, + draggable + }, + props: [ + 'element', + 'index', + 'drawingList', + 'activeId', + 'formConf' + ], + render(h) { + const layout = layouts[this.element.layout] + + if (layout) { + return layout.call(this, h, this.element, this.index, this.drawingList) + } + return layoutIsNotFound() + } +} +</script> diff --git a/src/views/tool/build/IconsDialog.vue b/src/views/tool/build/IconsDialog.vue new file mode 100644 index 0000000..958be50 --- /dev/null +++ b/src/views/tool/build/IconsDialog.vue @@ -0,0 +1,123 @@ +<template> + <div class="icon-dialog"> + <el-dialog + v-bind="$attrs" + width="980px" + :modal-append-to-body="false" + v-on="$listeners" + @open="onOpen" + @close="onClose" + > + <div slot="title"> + 閫夋嫨鍥炬爣 + <el-input + v-model="key" + size="mini" + :style="{width: '260px'}" + placeholder="璇疯緭鍏ュ浘鏍囧悕绉�" + prefix-icon="el-icon-search" + clearable + /> + </div> + <ul class="icon-ul"> + <li + v-for="icon in iconList" + :key="icon" + :class="active===icon?'active-item':''" + @click="onSelect(icon)" + > + <i :class="icon" /> + <div>{{ icon }}</div> + </li> + </ul> + </el-dialog> + </div> +</template> +<script> +import iconList from '@/utils/generator/icon.json' + +const originList = iconList.map(name => `el-icon-${name}`) + +export default { + inheritAttrs: false, + props: ['current'], + data() { + return { + iconList: originList, + active: null, + key: '' + } + }, + watch: { + key(val) { + if (val) { + this.iconList = originList.filter(name => name.indexOf(val) > -1) + } else { + this.iconList = originList + } + } + }, + methods: { + onOpen() { + this.active = this.current + this.key = '' + }, + onClose() {}, + onSelect(icon) { + this.active = icon + this.$emit('select', icon) + this.$emit('update:visible', false) + } + } +} +</script> +<style lang="scss" scoped> +.icon-ul { + margin: 0; + padding: 0; + font-size: 0; + li { + list-style-type: none; + text-align: center; + font-size: 14px; + display: inline-block; + width: 16.66%; + box-sizing: border-box; + height: 108px; + padding: 15px 6px 6px 6px; + cursor: pointer; + overflow: hidden; + &:hover { + background: #f2f2f2; + } + &.active-item{ + background: #e1f3fb; + color: #7a6df0 + } + > i { + font-size: 30px; + line-height: 50px; + } + } +} +.icon-dialog { + ::v-deep .el-dialog { + border-radius: 8px; + margin-bottom: 0; + margin-top: 4vh !important; + display: flex; + flex-direction: column; + max-height: 92vh; + overflow: hidden; + box-sizing: border-box; + .el-dialog__header { + padding-top: 14px; + } + .el-dialog__body { + margin: 0 20px 20px 20px; + padding: 0; + overflow: auto; + } + } +} +</style> diff --git a/src/views/tool/build/RightPanel.vue b/src/views/tool/build/RightPanel.vue new file mode 100644 index 0000000..c2760eb --- /dev/null +++ b/src/views/tool/build/RightPanel.vue @@ -0,0 +1,946 @@ +<template> + <div class="right-board"> + <el-tabs v-model="currentTab" class="center-tabs"> + <el-tab-pane label="缁勪欢灞炴��" name="field" /> + <el-tab-pane label="琛ㄥ崟灞炴��" name="form" /> + </el-tabs> + <div class="field-box"> + <a class="document-link" target="_blank" :href="documentLink" title="鏌ョ湅缁勪欢鏂囨。"> + <i class="el-icon-link" /> + </a> + <el-scrollbar class="right-scrollbar"> + <!-- 缁勪欢灞炴�� --> + <el-form v-show="currentTab==='field' && showField" size="small" label-width="90px"> + <el-form-item v-if="activeData.changeTag" label="缁勪欢绫诲瀷"> + <el-select + v-model="activeData.tagIcon" + placeholder="璇烽�夋嫨缁勪欢绫诲瀷" + :style="{width: '100%'}" + @change="tagChange" + > + <el-option-group v-for="group in tagList" :key="group.label" :label="group.label"> + <el-option + v-for="item in group.options" + :key="item.label" + :label="item.label" + :value="item.tagIcon" + > + <svg-icon class="node-icon" :icon-class="item.tagIcon" /> + <span> {{ item.label }}</span> + </el-option> + </el-option-group> + </el-select> + </el-form-item> + <el-form-item v-if="activeData.vModel!==undefined" label="瀛楁鍚�"> + <el-input v-model="activeData.vModel" placeholder="璇疯緭鍏ュ瓧娈靛悕锛坴-model锛�" /> + </el-form-item> + <el-form-item v-if="activeData.componentName!==undefined" label="缁勪欢鍚�"> + {{ activeData.componentName }} + </el-form-item> + <el-form-item v-if="activeData.label!==undefined" label="鏍囬"> + <el-input v-model="activeData.label" placeholder="璇疯緭鍏ユ爣棰�" /> + </el-form-item> + <el-form-item v-if="activeData.placeholder!==undefined" label="鍗犱綅鎻愮ず"> + <el-input v-model="activeData.placeholder" placeholder="璇疯緭鍏ュ崰浣嶆彁绀�" /> + </el-form-item> + <el-form-item v-if="activeData['start-placeholder']!==undefined" label="寮�濮嬪崰浣�"> + <el-input v-model="activeData['start-placeholder']" placeholder="璇疯緭鍏ュ崰浣嶆彁绀�" /> + </el-form-item> + <el-form-item v-if="activeData['end-placeholder']!==undefined" label="缁撴潫鍗犱綅"> + <el-input v-model="activeData['end-placeholder']" placeholder="璇疯緭鍏ュ崰浣嶆彁绀�" /> + </el-form-item> + <el-form-item v-if="activeData.span!==undefined" label="琛ㄥ崟鏍呮牸"> + <el-slider v-model="activeData.span" :max="24" :min="1" :marks="{12:''}" @change="spanChange" /> + </el-form-item> + <el-form-item v-if="activeData.layout==='rowFormItem'" label="鏍呮牸闂撮殧"> + <el-input-number v-model="activeData.gutter" :min="0" placeholder="鏍呮牸闂撮殧" /> + </el-form-item> + <el-form-item v-if="activeData.layout==='rowFormItem'" label="甯冨眬妯″紡"> + <el-radio-group v-model="activeData.type"> + <el-radio-button label="default" /> + <el-radio-button label="flex" /> + </el-radio-group> + </el-form-item> + <el-form-item v-if="activeData.justify!==undefined&&activeData.type==='flex'" label="姘村钩鎺掑垪"> + <el-select v-model="activeData.justify" placeholder="璇烽�夋嫨姘村钩鎺掑垪" :style="{width: '100%'}"> + <el-option + v-for="(item, index) in justifyOptions" + :key="index" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + <el-form-item v-if="activeData.align!==undefined&&activeData.type==='flex'" label="鍨傜洿鎺掑垪"> + <el-radio-group v-model="activeData.align"> + <el-radio-button label="top" /> + <el-radio-button label="middle" /> + <el-radio-button label="bottom" /> + </el-radio-group> + </el-form-item> + <el-form-item v-if="activeData.labelWidth!==undefined" label="鏍囩瀹藉害"> + <el-input v-model.number="activeData.labelWidth" type="number" placeholder="璇疯緭鍏ユ爣绛惧搴�" /> + </el-form-item> + <el-form-item v-if="activeData.style&&activeData.style.width!==undefined" label="缁勪欢瀹藉害"> + <el-input v-model="activeData.style.width" placeholder="璇疯緭鍏ョ粍浠跺搴�" clearable /> + </el-form-item> + <el-form-item v-if="activeData.vModel!==undefined" label="榛樿鍊�"> + <el-input + :value="setDefaultValue(activeData.defaultValue)" + placeholder="璇疯緭鍏ラ粯璁ゅ��" + @input="onDefaultValueInput" + /> + </el-form-item> + <el-form-item v-if="activeData.tag==='el-checkbox-group'" label="鑷冲皯搴旈��"> + <el-input-number + :value="activeData.min" + :min="0" + placeholder="鑷冲皯搴旈��" + @input="$set(activeData, 'min', $event?$event:undefined)" + /> + </el-form-item> + <el-form-item v-if="activeData.tag==='el-checkbox-group'" label="鏈�澶氬彲閫�"> + <el-input-number + :value="activeData.max" + :min="0" + placeholder="鏈�澶氬彲閫�" + @input="$set(activeData, 'max', $event?$event:undefined)" + /> + </el-form-item> + <el-form-item v-if="activeData.prepend!==undefined" label="鍓嶇紑"> + <el-input v-model="activeData.prepend" placeholder="璇疯緭鍏ュ墠缂�" /> + </el-form-item> + <el-form-item v-if="activeData.append!==undefined" label="鍚庣紑"> + <el-input v-model="activeData.append" placeholder="璇疯緭鍏ュ悗缂�" /> + </el-form-item> + <el-form-item v-if="activeData['prefix-icon']!==undefined" label="鍓嶅浘鏍�"> + <el-input v-model="activeData['prefix-icon']" placeholder="璇疯緭鍏ュ墠鍥炬爣鍚嶇О"> + <el-button slot="append" icon="el-icon-thumb" @click="openIconsDialog('prefix-icon')"> + 閫夋嫨 + </el-button> + </el-input> + </el-form-item> + <el-form-item v-if="activeData['suffix-icon'] !== undefined" label="鍚庡浘鏍�"> + <el-input v-model="activeData['suffix-icon']" placeholder="璇疯緭鍏ュ悗鍥炬爣鍚嶇О"> + <el-button slot="append" icon="el-icon-thumb" @click="openIconsDialog('suffix-icon')"> + 閫夋嫨 + </el-button> + </el-input> + </el-form-item> + <el-form-item v-if="activeData.tag === 'el-cascader'" label="閫夐」鍒嗛殧绗�"> + <el-input v-model="activeData.separator" placeholder="璇疯緭鍏ラ�夐」鍒嗛殧绗�" /> + </el-form-item> + <el-form-item v-if="activeData.autosize !== undefined" label="鏈�灏忚鏁�"> + <el-input-number v-model="activeData.autosize.minRows" :min="1" placeholder="鏈�灏忚鏁�" /> + </el-form-item> + <el-form-item v-if="activeData.autosize !== undefined" label="鏈�澶ц鏁�"> + <el-input-number v-model="activeData.autosize.maxRows" :min="1" placeholder="鏈�澶ц鏁�" /> + </el-form-item> + <el-form-item v-if="activeData.min !== undefined" label="鏈�灏忓��"> + <el-input-number v-model="activeData.min" placeholder="鏈�灏忓��" /> + </el-form-item> + <el-form-item v-if="activeData.max !== undefined" label="鏈�澶у��"> + <el-input-number v-model="activeData.max" placeholder="鏈�澶у��" /> + </el-form-item> + <el-form-item v-if="activeData.step !== undefined" label="姝ラ暱"> + <el-input-number v-model="activeData.step" placeholder="姝ユ暟" /> + </el-form-item> + <el-form-item v-if="activeData.tag === 'el-input-number'" label="绮惧害"> + <el-input-number v-model="activeData.precision" :min="0" placeholder="绮惧害" /> + </el-form-item> + <el-form-item v-if="activeData.tag === 'el-input-number'" label="鎸夐挳浣嶇疆"> + <el-radio-group v-model="activeData['controls-position']"> + <el-radio-button label=""> + 榛樿 + </el-radio-button> + <el-radio-button label="right"> + 鍙充晶 + </el-radio-button> + </el-radio-group> + </el-form-item> + <el-form-item v-if="activeData.maxlength !== undefined" label="鏈�澶氳緭鍏�"> + <el-input v-model="activeData.maxlength" placeholder="璇疯緭鍏ュ瓧绗﹂暱搴�"> + <template slot="append"> + 涓瓧绗� + </template> + </el-input> + </el-form-item> + <el-form-item v-if="activeData['active-text'] !== undefined" label="寮�鍚彁绀�"> + <el-input v-model="activeData['active-text']" placeholder="璇疯緭鍏ュ紑鍚彁绀�" /> + </el-form-item> + <el-form-item v-if="activeData['inactive-text'] !== undefined" label="鍏抽棴鎻愮ず"> + <el-input v-model="activeData['inactive-text']" placeholder="璇疯緭鍏ュ叧闂彁绀�" /> + </el-form-item> + <el-form-item v-if="activeData['active-value'] !== undefined" label="寮�鍚��"> + <el-input + :value="setDefaultValue(activeData['active-value'])" + placeholder="璇疯緭鍏ュ紑鍚��" + @input="onSwitchValueInput($event, 'active-value')" + /> + </el-form-item> + <el-form-item v-if="activeData['inactive-value'] !== undefined" label="鍏抽棴鍊�"> + <el-input + :value="setDefaultValue(activeData['inactive-value'])" + placeholder="璇疯緭鍏ュ叧闂��" + @input="onSwitchValueInput($event, 'inactive-value')" + /> + </el-form-item> + <el-form-item + v-if="activeData.type !== undefined && 'el-date-picker' === activeData.tag" + label="鏃堕棿绫诲瀷" + > + <el-select + v-model="activeData.type" + placeholder="璇烽�夋嫨鏃堕棿绫诲瀷" + :style="{ width: '100%' }" + @change="dateTypeChange" + > + <el-option + v-for="(item, index) in dateOptions" + :key="index" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + <el-form-item v-if="activeData.name !== undefined" label="鏂囦欢瀛楁鍚�"> + <el-input v-model="activeData.name" placeholder="璇疯緭鍏ヤ笂浼犳枃浠跺瓧娈靛悕" /> + </el-form-item> + <el-form-item v-if="activeData.accept !== undefined" label="鏂囦欢绫诲瀷"> + <el-select + v-model="activeData.accept" + placeholder="璇烽�夋嫨鏂囦欢绫诲瀷" + :style="{ width: '100%' }" + clearable + > + <el-option label="鍥剧墖" value="image/*" /> + <el-option label="瑙嗛" value="video/*" /> + <el-option label="闊抽" value="audio/*" /> + <el-option label="excel" value=".xls,.xlsx" /> + <el-option label="word" value=".doc,.docx" /> + <el-option label="pdf" value=".pdf" /> + <el-option label="txt" value=".txt" /> + </el-select> + </el-form-item> + <el-form-item v-if="activeData.fileSize !== undefined" label="鏂囦欢澶у皬"> + <el-input v-model.number="activeData.fileSize" placeholder="璇疯緭鍏ユ枃浠跺ぇ灏�"> + <el-select slot="append" v-model="activeData.sizeUnit" :style="{ width: '66px' }"> + <el-option label="KB" value="KB" /> + <el-option label="MB" value="MB" /> + <el-option label="GB" value="GB" /> + </el-select> + </el-input> + </el-form-item> + <el-form-item v-if="activeData.action !== undefined" label="涓婁紶鍦板潃"> + <el-input v-model="activeData.action" placeholder="璇疯緭鍏ヤ笂浼犲湴鍧�" clearable /> + </el-form-item> + <el-form-item v-if="activeData['list-type'] !== undefined" label="鍒楄〃绫诲瀷"> + <el-radio-group v-model="activeData['list-type']" size="small"> + <el-radio-button label="text"> + text + </el-radio-button> + <el-radio-button label="picture"> + picture + </el-radio-button> + <el-radio-button label="picture-card"> + picture-card + </el-radio-button> + </el-radio-group> + </el-form-item> + <el-form-item + v-if="activeData.buttonText !== undefined" + v-show="'picture-card' !== activeData['list-type']" + label="鎸夐挳鏂囧瓧" + > + <el-input v-model="activeData.buttonText" placeholder="璇疯緭鍏ユ寜閽枃瀛�" /> + </el-form-item> + <el-form-item v-if="activeData['range-separator'] !== undefined" label="鍒嗛殧绗�"> + <el-input v-model="activeData['range-separator']" placeholder="璇疯緭鍏ュ垎闅旂" /> + </el-form-item> + <el-form-item v-if="activeData['picker-options'] !== undefined" label="鏃堕棿娈�"> + <el-input + v-model="activeData['picker-options'].selectableRange" + placeholder="璇疯緭鍏ユ椂闂存" + /> + </el-form-item> + <el-form-item v-if="activeData.format !== undefined" label="鏃堕棿鏍煎紡"> + <el-input + :value="activeData.format" + placeholder="璇疯緭鍏ユ椂闂存牸寮�" + @input="setTimeValue($event)" + /> + </el-form-item> + <template v-if="['el-checkbox-group', 'el-radio-group', 'el-select'].indexOf(activeData.tag) > -1"> + <el-divider>閫夐」</el-divider> + <draggable + :list="activeData.options" + :animation="340" + group="selectItem" + handle=".option-drag" + > + <div v-for="(item, index) in activeData.options" :key="index" class="select-item"> + <div class="select-line-icon option-drag"> + <i class="el-icon-s-operation" /> + </div> + <el-input v-model="item.label" placeholder="閫夐」鍚�" size="small" /> + <el-input + placeholder="閫夐」鍊�" + size="small" + :value="item.value" + @input="setOptionValue(item, $event)" + /> + <div class="close-btn select-line-icon" @click="activeData.options.splice(index, 1)"> + <i class="el-icon-remove-outline" /> + </div> + </div> + </draggable> + <div style="margin-left: 20px;"> + <el-button + style="padding-bottom: 0" + icon="el-icon-circle-plus-outline" + type="text" + @click="addSelectItem" + > + 娣诲姞閫夐」 + </el-button> + </div> + <el-divider /> + </template> + + <template v-if="['el-cascader'].indexOf(activeData.tag) > -1"> + <el-divider>閫夐」</el-divider> + <el-form-item label="鏁版嵁绫诲瀷"> + <el-radio-group v-model="activeData.dataType" size="small"> + <el-radio-button label="dynamic"> + 鍔ㄦ�佹暟鎹� + </el-radio-button> + <el-radio-button label="static"> + 闈欐�佹暟鎹� + </el-radio-button> + </el-radio-group> + </el-form-item> + + <template v-if="activeData.dataType === 'dynamic'"> + <el-form-item label="鏍囩閿悕"> + <el-input v-model="activeData.labelKey" placeholder="璇疯緭鍏ユ爣绛鹃敭鍚�" /> + </el-form-item> + <el-form-item label="鍊奸敭鍚�"> + <el-input v-model="activeData.valueKey" placeholder="璇疯緭鍏ュ�奸敭鍚�" /> + </el-form-item> + <el-form-item label="瀛愮骇閿悕"> + <el-input v-model="activeData.childrenKey" placeholder="璇疯緭鍏ュ瓙绾ч敭鍚�" /> + </el-form-item> + </template> + + <el-tree + v-if="activeData.dataType === 'static'" + draggable + :data="activeData.options" + node-key="id" + :expand-on-click-node="false" + :render-content="renderContent" + /> + <div v-if="activeData.dataType === 'static'" style="margin-left: 20px"> + <el-button + style="padding-bottom: 0" + icon="el-icon-circle-plus-outline" + type="text" + @click="addTreeItem" + > + 娣诲姞鐖剁骇 + </el-button> + </div> + <el-divider /> + </template> + + <el-form-item v-if="activeData.optionType !== undefined" label="閫夐」鏍峰紡"> + <el-radio-group v-model="activeData.optionType"> + <el-radio-button label="default"> + 榛樿 + </el-radio-button> + <el-radio-button label="button"> + 鎸夐挳 + </el-radio-button> + </el-radio-group> + </el-form-item> + <el-form-item v-if="activeData['active-color'] !== undefined" label="寮�鍚鑹�"> + <el-color-picker v-model="activeData['active-color']" /> + </el-form-item> + <el-form-item v-if="activeData['inactive-color'] !== undefined" label="鍏抽棴棰滆壊"> + <el-color-picker v-model="activeData['inactive-color']" /> + </el-form-item> + + <el-form-item v-if="activeData['allow-half'] !== undefined" label="鍏佽鍗婇��"> + <el-switch v-model="activeData['allow-half']" /> + </el-form-item> + <el-form-item v-if="activeData['show-text'] !== undefined" label="杈呭姪鏂囧瓧"> + <el-switch v-model="activeData['show-text']" @change="rateTextChange" /> + </el-form-item> + <el-form-item v-if="activeData['show-score'] !== undefined" label="鏄剧ず鍒嗘暟"> + <el-switch v-model="activeData['show-score']" @change="rateScoreChange" /> + </el-form-item> + <el-form-item v-if="activeData['show-stops'] !== undefined" label="鏄剧ず闂存柇鐐�"> + <el-switch v-model="activeData['show-stops']" /> + </el-form-item> + <el-form-item v-if="activeData.range !== undefined" label="鑼冨洿閫夋嫨"> + <el-switch v-model="activeData.range" @change="rangeChange" /> + </el-form-item> + <el-form-item + v-if="activeData.border !== undefined && activeData.optionType === 'default'" + label="鏄惁甯﹁竟妗�" + > + <el-switch v-model="activeData.border" /> + </el-form-item> + <el-form-item v-if="activeData.tag === 'el-color-picker'" label="棰滆壊鏍煎紡"> + <el-select + v-model="activeData['color-format']" + placeholder="璇烽�夋嫨棰滆壊鏍煎紡" + :style="{ width: '100%' }" + @change="colorFormatChange" + > + <el-option + v-for="(item, index) in colorFormatOptions" + :key="index" + :label="item.label" + :value="item.value" + /> + </el-select> + </el-form-item> + <el-form-item + v-if="activeData.size !== undefined && + (activeData.optionType === 'button' || + activeData.border || + activeData.tag === 'el-color-picker')" + label="閫夐」灏哄" + > + <el-radio-group v-model="activeData.size"> + <el-radio-button label="medium"> + 涓瓑 + </el-radio-button> + <el-radio-button label="small"> + 杈冨皬 + </el-radio-button> + <el-radio-button label="mini"> + 杩蜂綘 + </el-radio-button> + </el-radio-group> + </el-form-item> + <el-form-item v-if="activeData['show-word-limit'] !== undefined" label="杈撳叆缁熻"> + <el-switch v-model="activeData['show-word-limit']" /> + </el-form-item> + <el-form-item v-if="activeData.tag === 'el-input-number'" label="涓ユ牸姝ユ暟"> + <el-switch v-model="activeData['step-strictly']" /> + </el-form-item> + <el-form-item v-if="activeData.tag === 'el-cascader'" label="鏄惁澶氶��"> + <el-switch v-model="activeData.props.props.multiple" /> + </el-form-item> + <el-form-item v-if="activeData.tag === 'el-cascader'" label="灞曠ず鍏ㄨ矾寰�"> + <el-switch v-model="activeData['show-all-levels']" /> + </el-form-item> + <el-form-item v-if="activeData.tag === 'el-cascader'" label="鍙惁绛涢��"> + <el-switch v-model="activeData.filterable" /> + </el-form-item> + <el-form-item v-if="activeData.clearable !== undefined" label="鑳藉惁娓呯┖"> + <el-switch v-model="activeData.clearable" /> + </el-form-item> + <el-form-item v-if="activeData.showTip !== undefined" label="鏄剧ず鎻愮ず"> + <el-switch v-model="activeData.showTip" /> + </el-form-item> + <el-form-item v-if="activeData.multiple !== undefined" label="澶氶�夋枃浠�"> + <el-switch v-model="activeData.multiple" /> + </el-form-item> + <el-form-item v-if="activeData['auto-upload'] !== undefined" label="鑷姩涓婁紶"> + <el-switch v-model="activeData['auto-upload']" /> + </el-form-item> + <el-form-item v-if="activeData.readonly !== undefined" label="鏄惁鍙"> + <el-switch v-model="activeData.readonly" /> + </el-form-item> + <el-form-item v-if="activeData.disabled !== undefined" label="鏄惁绂佺敤"> + <el-switch v-model="activeData.disabled" /> + </el-form-item> + <el-form-item v-if="activeData.tag === 'el-select'" label="鏄惁鍙悳绱�"> + <el-switch v-model="activeData.filterable" /> + </el-form-item> + <el-form-item v-if="activeData.tag === 'el-select'" label="鏄惁澶氶��"> + <el-switch v-model="activeData.multiple" @change="multipleChange" /> + </el-form-item> + <el-form-item v-if="activeData.required !== undefined" label="鏄惁蹇呭~"> + <el-switch v-model="activeData.required" /> + </el-form-item> + + <template v-if="activeData.layoutTree"> + <el-divider>甯冨眬缁撴瀯鏍�</el-divider> + <el-tree + :data="[activeData]" + :props="layoutTreeProps" + node-key="renderKey" + default-expand-all + draggable + > + <span slot-scope="{ node, data }"> + <span class="node-label"> + <svg-icon class="node-icon" :icon-class="data.tagIcon" /> + {{ node.label }} + </span> + </span> + </el-tree> + </template> + + <template v-if="activeData.layout === 'colFormItem' && activeData.tag !== 'el-button'"> + <el-divider>姝e垯鏍¢獙</el-divider> + <div + v-for="(item, index) in activeData.regList" + :key="index" + class="reg-item" + > + <span class="close-btn" @click="activeData.regList.splice(index, 1)"> + <i class="el-icon-close" /> + </span> + <el-form-item label="琛ㄨ揪寮�"> + <el-input v-model="item.pattern" placeholder="璇疯緭鍏ユ鍒�" /> + </el-form-item> + <el-form-item label="閿欒鎻愮ず" style="margin-bottom:0"> + <el-input v-model="item.message" placeholder="璇疯緭鍏ラ敊璇彁绀�" /> + </el-form-item> + </div> + <div style="margin-left: 20px"> + <el-button icon="el-icon-circle-plus-outline" type="text" @click="addReg"> + 娣诲姞瑙勫垯 + </el-button> + </div> + </template> + </el-form> + <!-- 琛ㄥ崟灞炴�� --> + <el-form v-show="currentTab === 'form'" size="small" label-width="90px"> + <el-form-item label="琛ㄥ崟鍚�"> + <el-input v-model="formConf.formRef" placeholder="璇疯緭鍏ヨ〃鍗曞悕锛坮ef锛�" /> + </el-form-item> + <el-form-item label="琛ㄥ崟妯″瀷"> + <el-input v-model="formConf.formModel" placeholder="璇疯緭鍏ユ暟鎹ā鍨�" /> + </el-form-item> + <el-form-item label="鏍¢獙妯″瀷"> + <el-input v-model="formConf.formRules" placeholder="璇疯緭鍏ユ牎楠屾ā鍨�" /> + </el-form-item> + <el-form-item label="琛ㄥ崟灏哄"> + <el-radio-group v-model="formConf.size"> + <el-radio-button label="medium"> + 涓瓑 + </el-radio-button> + <el-radio-button label="small"> + 杈冨皬 + </el-radio-button> + <el-radio-button label="mini"> + 杩蜂綘 + </el-radio-button> + </el-radio-group> + </el-form-item> + <el-form-item label="鏍囩瀵归綈"> + <el-radio-group v-model="formConf.labelPosition"> + <el-radio-button label="left"> + 宸﹀榻� + </el-radio-button> + <el-radio-button label="right"> + 鍙冲榻� + </el-radio-button> + <el-radio-button label="top"> + 椤堕儴瀵归綈 + </el-radio-button> + </el-radio-group> + </el-form-item> + <el-form-item label="鏍囩瀹藉害"> + <el-input-number v-model="formConf.labelWidth" placeholder="鏍囩瀹藉害" /> + </el-form-item> + <el-form-item label="鏍呮牸闂撮殧"> + <el-input-number v-model="formConf.gutter" :min="0" placeholder="鏍呮牸闂撮殧" /> + </el-form-item> + <el-form-item label="绂佺敤琛ㄥ崟"> + <el-switch v-model="formConf.disabled" /> + </el-form-item> + <el-form-item label="琛ㄥ崟鎸夐挳"> + <el-switch v-model="formConf.formBtns" /> + </el-form-item> + <el-form-item label="鏄剧ず鏈�変腑缁勪欢杈规"> + <el-switch v-model="formConf.unFocusedComponentBorder" /> + </el-form-item> + </el-form> + </el-scrollbar> + </div> + + <treeNode-dialog :visible.sync="dialogVisible" title="娣诲姞閫夐」" @commit="addNode" /> + <icons-dialog :visible.sync="iconsVisible" :current="activeData[currentIconModel]" @select="setIcon" /> + </div> +</template> + +<script> +import { isArray } from 'util' +import draggable from 'vuedraggable' +import TreeNodeDialog from './TreeNodeDialog' +import { isNumberStr } from '@/utils/index' +import IconsDialog from './IconsDialog' +import { + inputComponents, + selectComponents, + layoutComponents +} from '@/utils/generator/config' + +const dateTimeFormat = { + date: 'yyyy-MM-dd', + week: 'yyyy 绗� WW 鍛�', + month: 'yyyy-MM', + year: 'yyyy', + datetime: 'yyyy-MM-dd HH:mm:ss', + daterange: 'yyyy-MM-dd', + monthrange: 'yyyy-MM', + datetimerange: 'yyyy-MM-dd HH:mm:ss' +} + +export default { + components: { + draggable, + TreeNodeDialog, + IconsDialog + }, + props: ['showField', 'activeData', 'formConf'], + data() { + return { + currentTab: 'field', + currentNode: null, + dialogVisible: false, + iconsVisible: false, + currentIconModel: null, + dateTypeOptions: [ + { + label: '鏃�(date)', + value: 'date' + }, + { + label: '鍛�(week)', + value: 'week' + }, + { + label: '鏈�(month)', + value: 'month' + }, + { + label: '骞�(year)', + value: 'year' + }, + { + label: '鏃ユ湡鏃堕棿(datetime)', + value: 'datetime' + } + ], + dateRangeTypeOptions: [ + { + label: '鏃ユ湡鑼冨洿(daterange)', + value: 'daterange' + }, + { + label: '鏈堣寖鍥�(monthrange)', + value: 'monthrange' + }, + { + label: '鏃ユ湡鏃堕棿鑼冨洿(datetimerange)', + value: 'datetimerange' + } + ], + colorFormatOptions: [ + { + label: 'hex', + value: 'hex' + }, + { + label: 'rgb', + value: 'rgb' + }, + { + label: 'rgba', + value: 'rgba' + }, + { + label: 'hsv', + value: 'hsv' + }, + { + label: 'hsl', + value: 'hsl' + } + ], + justifyOptions: [ + { + label: 'start', + value: 'start' + }, + { + label: 'end', + value: 'end' + }, + { + label: 'center', + value: 'center' + }, + { + label: 'space-around', + value: 'space-around' + }, + { + label: 'space-between', + value: 'space-between' + } + ], + layoutTreeProps: { + label(data, node) { + return data.componentName || `${data.label}: ${data.vModel}` + } + } + } + }, + computed: { + documentLink() { + return ( + this.activeData.document + || 'https://element.eleme.cn/#/zh-CN/component/installation' + ) + }, + dateOptions() { + if ( + this.activeData.type !== undefined + && this.activeData.tag === 'el-date-picker' + ) { + if (this.activeData['start-placeholder'] === undefined) { + return this.dateTypeOptions + } + return this.dateRangeTypeOptions + } + return [] + }, + tagList() { + return [ + { + label: '杈撳叆鍨嬬粍浠�', + options: inputComponents + }, + { + label: '閫夋嫨鍨嬬粍浠�', + options: selectComponents + } + ] + } + }, + methods: { + addReg() { + this.activeData.regList.push({ + pattern: '', + message: '' + }) + }, + addSelectItem() { + this.activeData.options.push({ + label: '', + value: '' + }) + }, + addTreeItem() { + ++this.idGlobal + this.dialogVisible = true + this.currentNode = this.activeData.options + }, + renderContent(h, { node, data, store }) { + return ( + <div class="custom-tree-node"> + <span>{node.label}</span> + <span class="node-operation"> + <i on-click={() => this.append(data)} + class="el-icon-plus" + title="娣诲姞" + ></i> + <i on-click={() => this.remove(node, data)} + class="el-icon-delete" + title="鍒犻櫎" + ></i> + </span> + </div> + ) + }, + append(data) { + if (!data.children) { + this.$set(data, 'children', []) + } + this.dialogVisible = true + this.currentNode = data.children + }, + remove(node, data) { + const { parent } = node + const children = parent.data.children || parent.data + const index = children.findIndex(d => d.id === data.id) + children.splice(index, 1) + }, + addNode(data) { + this.currentNode.push(data) + }, + setOptionValue(item, val) { + item.value = isNumberStr(val) ? +val : val + }, + setDefaultValue(val) { + if (Array.isArray(val)) { + return val.join(',') + } + if (['string', 'number'].indexOf(val) > -1) { + return val + } + if (typeof val === 'boolean') { + return `${val}` + } + return val + }, + onDefaultValueInput(str) { + if (isArray(this.activeData.defaultValue)) { + // 鏁扮粍 + this.$set( + this.activeData, + 'defaultValue', + str.split(',').map(val => (isNumberStr(val) ? +val : val)) + ) + } else if (['true', 'false'].indexOf(str) > -1) { + // 甯冨皵 + this.$set(this.activeData, 'defaultValue', JSON.parse(str)) + } else { + // 瀛楃涓插拰鏁板瓧 + this.$set( + this.activeData, + 'defaultValue', + isNumberStr(str) ? +str : str + ) + } + }, + onSwitchValueInput(val, name) { + if (['true', 'false'].indexOf(val) > -1) { + this.$set(this.activeData, name, JSON.parse(val)) + } else { + this.$set(this.activeData, name, isNumberStr(val) ? +val : val) + } + }, + setTimeValue(val, type) { + const valueFormat = type === 'week' ? dateTimeFormat.date : val + this.$set(this.activeData, 'defaultValue', null) + this.$set(this.activeData, 'value-format', valueFormat) + this.$set(this.activeData, 'format', val) + }, + spanChange(val) { + this.formConf.span = val + }, + multipleChange(val) { + this.$set(this.activeData, 'defaultValue', val ? [] : '') + }, + dateTypeChange(val) { + this.setTimeValue(dateTimeFormat[val], val) + }, + rangeChange(val) { + this.$set( + this.activeData, + 'defaultValue', + val ? [this.activeData.min, this.activeData.max] : this.activeData.min + ) + }, + rateTextChange(val) { + if (val) this.activeData['show-score'] = false + }, + rateScoreChange(val) { + if (val) this.activeData['show-text'] = false + }, + colorFormatChange(val) { + this.activeData.defaultValue = null + this.activeData['show-alpha'] = val.indexOf('a') > -1 + this.activeData.renderKey = +new Date() // 鏇存柊renderKey,閲嶆柊娓叉煋璇ョ粍浠� + }, + openIconsDialog(model) { + this.iconsVisible = true + this.currentIconModel = model + }, + setIcon(val) { + this.activeData[this.currentIconModel] = val + }, + tagChange(tagIcon) { + let target = inputComponents.find(item => item.tagIcon === tagIcon) + if (!target) target = selectComponents.find(item => item.tagIcon === tagIcon) + this.$emit('tag-change', target) + } + } +} +</script> + +<style lang="scss" scoped> +.right-board { + width: 350px; + position: absolute; + right: 0; + top: 0; + padding-top: 3px; + .field-box { + position: relative; + height: calc(100vh - 42px); + box-sizing: border-box; + overflow: hidden; + } + .el-scrollbar { + height: 100%; + } +} +.select-item { + display: flex; + border: 1px dashed #fff; + box-sizing: border-box; + & .close-btn { + cursor: pointer; + color: #f56c6c; + } + & .el-input + .el-input { + margin-left: 4px; + } +} +.select-item + .select-item { + margin-top: 4px; +} +.select-item.sortable-chosen { + border: 1px dashed #409eff; +} +.select-line-icon { + line-height: 32px; + font-size: 22px; + padding: 0 4px; + color: #777; +} +.option-drag { + cursor: move; +} +.time-range { + .el-date-editor { + width: 227px; + } + ::v-deep .el-icon-time { + display: none; + } +} +.document-link { + position: absolute; + display: block; + width: 26px; + height: 26px; + top: 0; + left: 0; + cursor: pointer; + background: #409eff; + z-index: 1; + border-radius: 0 0 6px 0; + text-align: center; + line-height: 26px; + color: #fff; + font-size: 18px; +} +.node-label{ + font-size: 14px; +} +.node-icon{ + color: #bebfc3; +} +</style> diff --git a/src/views/tool/build/TreeNodeDialog.vue b/src/views/tool/build/TreeNodeDialog.vue new file mode 100644 index 0000000..fa7f0b2 --- /dev/null +++ b/src/views/tool/build/TreeNodeDialog.vue @@ -0,0 +1,149 @@ +<template> + <div> + <el-dialog + v-bind="$attrs" + :close-on-click-modal="false" + :modal-append-to-body="false" + v-on="$listeners" + @open="onOpen" + @close="onClose" + > + <el-row :gutter="0"> + <el-form + ref="elForm" + :model="formData" + :rules="rules" + size="small" + label-width="100px" + > + <el-col :span="24"> + <el-form-item + label="閫夐」鍚�" + prop="label" + > + <el-input + v-model="formData.label" + placeholder="璇疯緭鍏ラ�夐」鍚�" + clearable + /> + </el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item + label="閫夐」鍊�" + prop="value" + > + <el-input + v-model="formData.value" + placeholder="璇疯緭鍏ラ�夐」鍊�" + clearable + > + <el-select + slot="append" + v-model="dataType" + :style="{width: '100px'}" + > + <el-option + v-for="(item, index) in dataTypeOptions" + :key="index" + :label="item.label" + :value="item.value" + :disabled="item.disabled" + /> + </el-select> + </el-input> + </el-form-item> + </el-col> + </el-form> + </el-row> + <div slot="footer"> + <el-button + type="primary" + @click="handleConfirm" + > + 纭畾 + </el-button> + <el-button @click="close"> + 鍙栨秷 + </el-button> + </div> + </el-dialog> + </div> +</template> +<script> +import { isNumberStr } from '@/utils/index' + +export default { + components: {}, + inheritAttrs: false, + props: [], + data() { + return { + id: 100, + formData: { + label: undefined, + value: undefined + }, + rules: { + label: [ + { + required: true, + message: '璇疯緭鍏ラ�夐」鍚�', + trigger: 'blur' + } + ], + value: [ + { + required: true, + message: '璇疯緭鍏ラ�夐」鍊�', + trigger: 'blur' + } + ] + }, + dataType: 'string', + dataTypeOptions: [ + { + label: '瀛楃涓�', + value: 'string' + }, + { + label: '鏁板瓧', + value: 'number' + } + ] + } + }, + computed: {}, + watch: { + // eslint-disable-next-line func-names + 'formData.value': function (val) { + this.dataType = isNumberStr(val) ? 'number' : 'string' + } + }, + created() {}, + mounted() {}, + methods: { + onOpen() { + this.formData = { + label: undefined, + value: undefined + } + }, + onClose() {}, + close() { + this.$emit('update:visible', false) + }, + handleConfirm() { + this.$refs.elForm.validate(valid => { + if (!valid) return + if (this.dataType === 'number') { + this.formData.value = parseFloat(this.formData.value) + } + this.formData.id = this.id++ + this.$emit('commit', this.formData) + this.close() + }) + } + } +} +</script> diff --git a/src/views/tool/build/index.vue b/src/views/tool/build/index.vue new file mode 100644 index 0000000..3068438 --- /dev/null +++ b/src/views/tool/build/index.vue @@ -0,0 +1,783 @@ +<template> + <div class="container"> + <div class="left-board"> + <div class="logo-wrapper"> + <div class="logo"> + <img :src="logo" alt="logo"> Form Generator + </div> + </div> + <el-scrollbar class="left-scrollbar"> + <div class="components-list"> + <div class="components-title"> + <svg-icon icon-class="component" />杈撳叆鍨嬬粍浠� + </div> + <draggable + class="components-draggable" + :list="inputComponents" + :group="{ name: 'componentsGroup', pull: 'clone', put: false }" + :clone="cloneComponent" + draggable=".components-item" + :sort="false" + @end="onEnd" + > + <div + v-for="(element, index) in inputComponents" :key="index" class="components-item" + @click="addComponent(element)" + > + <div class="components-body"> + <svg-icon :icon-class="element.tagIcon" /> + {{ element.label }} + </div> + </div> + </draggable> + <div class="components-title"> + <svg-icon icon-class="component" />閫夋嫨鍨嬬粍浠� + </div> + <draggable + class="components-draggable" + :list="selectComponents" + :group="{ name: 'componentsGroup', pull: 'clone', put: false }" + :clone="cloneComponent" + draggable=".components-item" + :sort="false" + @end="onEnd" + > + <div + v-for="(element, index) in selectComponents" + :key="index" + class="components-item" + @click="addComponent(element)" + > + <div class="components-body"> + <svg-icon :icon-class="element.tagIcon" /> + {{ element.label }} + </div> + </div> + </draggable> + <div class="components-title"> + <svg-icon icon-class="component" /> 甯冨眬鍨嬬粍浠� + </div> + <draggable + class="components-draggable" :list="layoutComponents" + :group="{ name: 'componentsGroup', pull: 'clone', put: false }" :clone="cloneComponent" + draggable=".components-item" :sort="false" @end="onEnd" + > + <div + v-for="(element, index) in layoutComponents" :key="index" class="components-item" + @click="addComponent(element)" + > + <div class="components-body"> + <svg-icon :icon-class="element.tagIcon" /> + {{ element.label }} + </div> + </div> + </draggable> + </div> + </el-scrollbar> + </div> + + <div class="center-board"> + <div class="action-bar"> + <el-button icon="el-icon-download" type="text" @click="download"> + 瀵煎嚭vue鏂囦欢 + </el-button> + <el-button class="copy-btn-main" icon="el-icon-document-copy" type="text" @click="copy"> + 澶嶅埗浠g爜 + </el-button> + <el-button class="delete-btn" icon="el-icon-delete" type="text" @click="empty"> + 娓呯┖ + </el-button> + </div> + <el-scrollbar class="center-scrollbar"> + <el-row class="center-board-row" :gutter="formConf.gutter"> + <el-form + :size="formConf.size" + :label-position="formConf.labelPosition" + :disabled="formConf.disabled" + :label-width="formConf.labelWidth + 'px'" + > + <draggable class="drawing-board" :list="drawingList" :animation="340" group="componentsGroup"> + <draggable-item + v-for="(element, index) in drawingList" + :key="element.renderKey" + :drawing-list="drawingList" + :element="element" + :index="index" + :active-id="activeId" + :form-conf="formConf" + @activeItem="activeFormItem" + @copyItem="drawingItemCopy" + @deleteItem="drawingItemDelete" + /> + </draggable> + <div v-show="!drawingList.length" class="empty-info"> + 浠庡乏渚ф嫋鍏ユ垨鐐归�夌粍浠惰繘琛岃〃鍗曡璁� + </div> + </el-form> + </el-row> + </el-scrollbar> + </div> + + <right-panel + :active-data="activeData" + :form-conf="formConf" + :show-field="!!drawingList.length" + @tag-change="tagChange" + /> + + <code-type-dialog + :visible.sync="dialogVisible" + title="閫夋嫨鐢熸垚绫诲瀷" + :show-file-name="showFileName" + @confirm="generate" + /> + <input id="copyNode" type="hidden"> + </div> +</template> + +<script> +import draggable from 'vuedraggable' +import beautifier from 'js-beautify' +import ClipboardJS from 'clipboard' +import render from '@/utils/generator/render' +import RightPanel from './RightPanel' +import { inputComponents, selectComponents, layoutComponents, formConf } from '@/utils/generator/config' +import { beautifierConf, titleCase } from '@/utils/index' +import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html' +import { makeUpJs } from '@/utils/generator/js' +import { makeUpCss } from '@/utils/generator/css' +import drawingDefault from '@/utils/generator/drawingDefault' +import logo from '@/assets/logo/logo.gif' +import CodeTypeDialog from './CodeTypeDialog' +import DraggableItem from './DraggableItem' + +let oldActiveId +let tempActiveData + +export default { + components: { + draggable, + render, + RightPanel, + CodeTypeDialog, + DraggableItem + }, + data() { + return { + logo, + idGlobal: 100, + formConf, + inputComponents, + selectComponents, + layoutComponents, + labelWidth: 100, + drawingList: drawingDefault, + drawingData: {}, + activeId: drawingDefault[0].formId, + drawerVisible: false, + formData: {}, + dialogVisible: false, + generateConf: null, + showFileName: false, + activeData: drawingDefault[0] + } + }, + created() { + // 闃叉 firefox 涓� 鎷栨嫿 浼氭柊鎵撳崱涓�涓�夐」鍗� + document.body.ondrop = event => { + event.preventDefault() + event.stopPropagation() + } + }, + watch: { + // eslint-disable-next-line func-names + 'activeData.label': function (val, oldVal) { + if ( + this.activeData.placeholder === undefined + || !this.activeData.tag + || oldActiveId !== this.activeId + ) { + return + } + this.activeData.placeholder = this.activeData.placeholder.replace(oldVal, '') + val + }, + activeId: { + handler(val) { + oldActiveId = val + }, + immediate: true + } + }, + mounted() { + const clipboard = new ClipboardJS('#copyNode', { + text: trigger => { + const codeStr = this.generateCode() + this.$notify({ + title: '鎴愬姛', + message: '浠g爜宸插鍒跺埌鍓垏鏉匡紝鍙矘璐淬��', + type: 'success' + }) + return codeStr + } + }) + clipboard.on('error', e => { + this.$message.error('浠g爜澶嶅埗澶辫触') + }) + }, + methods: { + activeFormItem(element) { + this.activeData = element + this.activeId = element.formId + }, + onEnd(obj, a) { + if (obj.from !== obj.to) { + this.activeData = tempActiveData + this.activeId = this.idGlobal + } + }, + addComponent(item) { + const clone = this.cloneComponent(item) + this.drawingList.push(clone) + this.activeFormItem(clone) + }, + cloneComponent(origin) { + const clone = JSON.parse(JSON.stringify(origin)) + clone.formId = ++this.idGlobal + clone.span = formConf.span + clone.renderKey = +new Date() // 鏀瑰彉renderKey鍚庡彲浠ュ疄鐜板己鍒舵洿鏂扮粍浠� + if (!clone.layout) clone.layout = 'colFormItem' + if (clone.layout === 'colFormItem') { + clone.vModel = `field${this.idGlobal}` + clone.placeholder !== undefined && (clone.placeholder += clone.label) + tempActiveData = clone + } else if (clone.layout === 'rowFormItem') { + delete clone.label + clone.componentName = `row${this.idGlobal}` + clone.gutter = this.formConf.gutter + tempActiveData = clone + } + return tempActiveData + }, + AssembleFormData() { + this.formData = { + fields: JSON.parse(JSON.stringify(this.drawingList)), + ...this.formConf + } + }, + generate(data) { + const func = this[`exec${titleCase(this.operationType)}`] + this.generateConf = data + func && func(data) + }, + execRun(data) { + this.AssembleFormData() + this.drawerVisible = true + }, + execDownload(data) { + const codeStr = this.generateCode() + const blob = new Blob([codeStr], { type: 'text/plain;charset=utf-8' }) + this.$download.saveAs(blob, data.fileName) + }, + execCopy(data) { + document.getElementById('copyNode').click() + }, + empty() { + this.$confirm('纭畾瑕佹竻绌烘墍鏈夌粍浠跺悧锛�', '鎻愮ず', { type: 'warning' }).then( + () => { + this.drawingList = [] + } + ) + }, + drawingItemCopy(item, parent) { + let clone = JSON.parse(JSON.stringify(item)) + clone = this.createIdAndKey(clone) + parent.push(clone) + this.activeFormItem(clone) + }, + createIdAndKey(item) { + item.formId = ++this.idGlobal + item.renderKey = +new Date() + if (item.layout === 'colFormItem') { + item.vModel = `field${this.idGlobal}` + } else if (item.layout === 'rowFormItem') { + item.componentName = `row${this.idGlobal}` + } + if (Array.isArray(item.children)) { + item.children = item.children.map(childItem => this.createIdAndKey(childItem)) + } + return item + }, + drawingItemDelete(index, parent) { + parent.splice(index, 1) + this.$nextTick(() => { + const len = this.drawingList.length + if (len) { + this.activeFormItem(this.drawingList[len - 1]) + } + }) + }, + generateCode() { + const { type } = this.generateConf + this.AssembleFormData() + const script = vueScript(makeUpJs(this.formData, type)) + const html = vueTemplate(makeUpHtml(this.formData, type)) + const css = cssStyle(makeUpCss(this.formData)) + return beautifier.html(html + script + css, beautifierConf.html) + }, + download() { + this.dialogVisible = true + this.showFileName = true + this.operationType = 'download' + }, + run() { + this.dialogVisible = true + this.showFileName = false + this.operationType = 'run' + }, + copy() { + this.dialogVisible = true + this.showFileName = false + this.operationType = 'copy' + }, + tagChange(newTag) { + newTag = this.cloneComponent(newTag) + newTag.vModel = this.activeData.vModel + newTag.formId = this.activeId + newTag.span = this.activeData.span + delete this.activeData.tag + delete this.activeData.tagIcon + delete this.activeData.document + Object.keys(newTag).forEach(key => { + if (this.activeData[key] !== undefined + && typeof this.activeData[key] === typeof newTag[key]) { + newTag[key] = this.activeData[key] + } + }) + this.activeData = newTag + this.updateDrawingList(newTag, this.drawingList) + }, + updateDrawingList(newTag, list) { + const index = list.findIndex(item => item.formId === this.activeId) + if (index > -1) { + list.splice(index, 1, newTag) + } else { + list.forEach(item => { + if (Array.isArray(item.children)) this.updateDrawingList(newTag, item.children) + }) + } + } + } +} +</script> + +<style lang='scss'> +body, html{ + margin: 0; + padding: 0; + background: #fff; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; +} + +input, textarea{ + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; +} + +.editor-tabs{ + background: #121315; + .el-tabs__header{ + margin: 0; + border-bottom-color: #121315; + .el-tabs__nav{ + border-color: #121315; + } + } + .el-tabs__item{ + height: 32px; + line-height: 32px; + color: #888a8e; + border-left: 1px solid #121315 !important; + background: #363636; + margin-right: 5px; + user-select: none; + } + .el-tabs__item.is-active{ + background: #1e1e1e; + border-bottom-color: #1e1e1e!important; + color: #fff; + } + .el-icon-edit{ + color: #f1fa8c; + } + .el-icon-document{ + color: #a95812; + } +} + +// home +.right-scrollbar { + .el-scrollbar__view { + padding: 12px 18px 15px 15px; + } +} +.left-scrollbar .el-scrollbar__wrap { + box-sizing: border-box; + overflow-x: hidden !important; + margin-bottom: 0 !important; +} +.center-tabs{ + .el-tabs__header{ + margin-bottom: 0!important; + } + .el-tabs__item{ + width: 50%; + text-align: center; + } + .el-tabs__nav{ + width: 100%; + } +} +.reg-item{ + padding: 12px 6px; + background: #f8f8f8; + position: relative; + border-radius: 4px; + .close-btn{ + position: absolute; + right: -6px; + top: -6px; + display: block; + width: 16px; + height: 16px; + line-height: 16px; + background: rgba(0, 0, 0, 0.2); + border-radius: 50%; + color: #fff; + text-align: center; + z-index: 1; + cursor: pointer; + font-size: 12px; + &:hover{ + background: rgba(210, 23, 23, 0.5) + } + } + & + .reg-item{ + margin-top: 18px; + } +} +.action-bar{ + & .el-button+.el-button { + margin-left: 15px; + } + & i { + font-size: 20px; + vertical-align: middle; + position: relative; + top: -1px; + } +} + +.custom-tree-node{ + width: 100%; + font-size: 14px; + .node-operation{ + float: right; + } + i[class*="el-icon"] + i[class*="el-icon"]{ + margin-left: 6px; + } + .el-icon-plus{ + color: #409EFF; + } + .el-icon-delete{ + color: #157a0c; + } +} + +.left-scrollbar .el-scrollbar__view{ + overflow-x: hidden; +} + +.el-rate{ + display: inline-block; + vertical-align: text-top; +} +.el-upload__tip{ + line-height: 1.2; +} + +$selectedColor: #f6f7ff; +$lighterBlue: #409EFF; + +.container { + position: relative; + width: 100%; + height: 100%; +} + +.components-list { + padding: 8px; + box-sizing: border-box; + height: 100%; + .components-item { + display: inline-block; + width: 48%; + margin: 1%; + transition: transform 0ms !important; + } +} +.components-draggable{ + padding-bottom: 20px; +} +.components-title{ + font-size: 14px; + color: #222; + margin: 6px 2px; + .svg-icon{ + color: #666; + font-size: 18px; + } +} + +.components-body { + padding: 8px 10px; + background: $selectedColor; + font-size: 12px; + cursor: move; + border: 1px dashed $selectedColor; + border-radius: 3px; + .svg-icon{ + color: #777; + font-size: 15px; + } + &:hover { + border: 1px dashed #787be8; + color: #787be8; + .svg-icon { + color: #787be8; + } + } +} + +.left-board { + width: 260px; + position: absolute; + left: 0; + top: 0; + height: 100vh; +} +.left-scrollbar{ + height: calc(100vh - 42px); + overflow: hidden; +} +.center-scrollbar { + height: calc(100vh - 42px); + overflow: hidden; + border-left: 1px solid #f1e8e8; + border-right: 1px solid #f1e8e8; + box-sizing: border-box; +} +.center-board { + height: 100vh; + width: auto; + margin: 0 350px 0 260px; + box-sizing: border-box; +} +.empty-info{ + position: absolute; + top: 46%; + left: 0; + right: 0; + text-align: center; + font-size: 18px; + color: #ccb1ea; + letter-spacing: 4px; +} +.action-bar{ + position: relative; + height: 42px; + text-align: right; + padding: 0 15px; + box-sizing: border-box;; + border: 1px solid #f1e8e8; + border-top: none; + border-left: none; + .delete-btn{ + color: #F56C6C; + } +} +.logo-wrapper{ + position: relative; + height: 42px; + background: #fff; + border-bottom: 1px solid #f1e8e8; + box-sizing: border-box; +} +.logo{ + position: absolute; + left: 12px; + top: 6px; + line-height: 30px; + color: #00afff; + font-weight: 600; + font-size: 17px; + white-space: nowrap; + > img{ + width: 30px; + height: 30px; + vertical-align: top; + } + .github{ + display: inline-block; + vertical-align: sub; + margin-left: 15px; + > img{ + height: 22px; + } + } +} + +.center-board-row { + padding: 12px 12px 15px 12px; + box-sizing: border-box; + & > .el-form { + // 69 = 12+15+42 + height: calc(100vh - 69px); + } +} +.drawing-board { + height: 100%; + position: relative; + .components-body { + padding: 0; + margin: 0; + font-size: 0; + } + .sortable-ghost { + position: relative; + display: block; + overflow: hidden; + &::before { + content: " "; + position: absolute; + left: 0; + right: 0; + top: 0; + height: 3px; + background: rgb(89, 89, 223); + z-index: 2; + } + } + .components-item.sortable-ghost { + width: 100%; + height: 60px; + background-color: $selectedColor; + } + .active-from-item { + & > .el-form-item{ + background: $selectedColor; + border-radius: 6px; + } + & > .drawing-item-copy, & > .drawing-item-delete{ + display: initial; + } + & > .component-name{ + color: $lighterBlue; + } + } + .el-form-item{ + margin-bottom: 15px; + } +} +.drawing-item{ + position: relative; + cursor: move; + &.unfocus-bordered:not(.activeFromItem) > div:first-child { + border: 1px dashed #ccc; + } + .el-form-item{ + padding: 12px 10px; + } +} +.drawing-row-item{ + position: relative; + cursor: move; + box-sizing: border-box; + border: 1px dashed #ccc; + border-radius: 3px; + padding: 0 2px; + margin-bottom: 15px; + .drawing-row-item { + margin-bottom: 2px; + } + .el-col{ + margin-top: 22px; + } + .el-form-item{ + margin-bottom: 0; + } + .drag-wrapper{ + min-height: 80px; + } + &.active-from-item{ + border: 1px dashed $lighterBlue; + } + .component-name{ + position: absolute; + top: 0; + left: 0; + font-size: 12px; + color: #bbb; + display: inline-block; + padding: 0 6px; + } +} +.drawing-item, .drawing-row-item{ + &:hover { + & > .el-form-item{ + background: $selectedColor; + border-radius: 6px; + } + & > .drawing-item-copy, & > .drawing-item-delete{ + display: initial; + } + } + & > .drawing-item-copy, & > .drawing-item-delete{ + display: none; + position: absolute; + top: -10px; + width: 22px; + height: 22px; + line-height: 22px; + text-align: center; + border-radius: 50%; + font-size: 12px; + border: 1px solid; + cursor: pointer; + z-index: 1; + } + & > .drawing-item-copy{ + right: 56px; + border-color: $lighterBlue; + color: $lighterBlue; + background: #fff; + &:hover{ + background: $lighterBlue; + color: #fff; + } + } + & > .drawing-item-delete{ + right: 24px; + border-color: #F56C6C; + color: #F56C6C; + background: #fff; + &:hover{ + background: #F56C6C; + color: #fff; + } + } +} + +</style> diff --git a/src/views/tool/gen/basicInfoForm.vue b/src/views/tool/gen/basicInfoForm.vue new file mode 100644 index 0000000..7029529 --- /dev/null +++ b/src/views/tool/gen/basicInfoForm.vue @@ -0,0 +1,60 @@ +<template> + <el-form ref="basicInfoForm" :model="info" :rules="rules" label-width="150px"> + <el-row> + <el-col :span="12"> + <el-form-item label="琛ㄥ悕绉�" prop="tableName"> + <el-input placeholder="璇疯緭鍏ヤ粨搴撳悕绉�" v-model="info.tableName" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="琛ㄦ弿杩�" prop="tableComment"> + <el-input placeholder="璇疯緭鍏�" v-model="info.tableComment" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="瀹炰綋绫诲悕绉�" prop="className"> + <el-input placeholder="璇疯緭鍏�" v-model="info.className" /> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="浣滆��" prop="functionAuthor"> + <el-input placeholder="璇疯緭鍏�" v-model="info.functionAuthor" /> + </el-form-item> + </el-col> + <el-col :span="24"> + <el-form-item label="澶囨敞" prop="remark"> + <el-input type="textarea" :rows="3" v-model="info.remark"></el-input> + </el-form-item> + </el-col> + </el-row> + </el-form> +</template> + +<script> +export default { + props: { + info: { + type: Object, + default: null + } + }, + data() { + return { + rules: { + tableName: [ + { required: true, message: "璇疯緭鍏ヨ〃鍚嶇О", trigger: "blur" } + ], + tableComment: [ + { required: true, message: "璇疯緭鍏ヨ〃鎻忚堪", trigger: "blur" } + ], + className: [ + { required: true, message: "璇疯緭鍏ュ疄浣撶被鍚嶇О", trigger: "blur" } + ], + functionAuthor: [ + { required: true, message: "璇疯緭鍏ヤ綔鑰�", trigger: "blur" } + ] + } + }; + } +}; +</script> diff --git a/src/views/tool/gen/editTable.vue b/src/views/tool/gen/editTable.vue new file mode 100644 index 0000000..951497a --- /dev/null +++ b/src/views/tool/gen/editTable.vue @@ -0,0 +1,234 @@ +<template> + <el-card> + <el-tabs v-model="activeName"> + <el-tab-pane label="鍩烘湰淇℃伅" name="basic"> + <basic-info-form ref="basicInfo" :info="info" /> + </el-tab-pane> + <el-tab-pane label="瀛楁淇℃伅" name="columnInfo"> + <el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight"> + <el-table-column label="搴忓彿" type="index" min-width="5%" class-name="allowDrag" /> + <el-table-column + label="瀛楁鍒楀悕" + prop="columnName" + min-width="10%" + :show-overflow-tooltip="true" + /> + <el-table-column label="瀛楁鎻忚堪" min-width="10%"> + <template slot-scope="scope"> + <el-input v-model="scope.row.columnComment"></el-input> + </template> + </el-table-column> + <el-table-column + label="鐗╃悊绫诲瀷" + prop="columnType" + min-width="10%" + :show-overflow-tooltip="true" + /> + <el-table-column label="Java绫诲瀷" min-width="11%"> + <template slot-scope="scope"> + <el-select v-model="scope.row.javaType"> + <el-option label="Long" value="Long" /> + <el-option label="String" value="String" /> + <el-option label="Integer" value="Integer" /> + <el-option label="Double" value="Double" /> + <el-option label="BigDecimal" value="BigDecimal" /> + <el-option label="Date" value="Date" /> + <el-option label="Boolean" value="Boolean" /> + </el-select> + </template> + </el-table-column> + <el-table-column label="java灞炴��" min-width="10%"> + <template slot-scope="scope"> + <el-input v-model="scope.row.javaField"></el-input> + </template> + </el-table-column> + + <el-table-column label="鎻掑叆" min-width="5%"> + <template slot-scope="scope"> + <el-checkbox true-label="1" false-label="0" v-model="scope.row.isInsert"></el-checkbox> + </template> + </el-table-column> + <el-table-column label="缂栬緫" min-width="5%"> + <template slot-scope="scope"> + <el-checkbox true-label="1" false-label="0" v-model="scope.row.isEdit"></el-checkbox> + </template> + </el-table-column> + <el-table-column label="鍒楄〃" min-width="5%"> + <template slot-scope="scope"> + <el-checkbox true-label="1" false-label="0" v-model="scope.row.isList"></el-checkbox> + </template> + </el-table-column> + <el-table-column label="鏌ヨ" min-width="5%"> + <template slot-scope="scope"> + <el-checkbox true-label="1" false-label="0" v-model="scope.row.isQuery"></el-checkbox> + </template> + </el-table-column> + <el-table-column label="鏌ヨ鏂瑰紡" min-width="10%"> + <template slot-scope="scope"> + <el-select v-model="scope.row.queryType"> + <el-option label="=" value="EQ" /> + <el-option label="!=" value="NE" /> + <el-option label=">" value="GT" /> + <el-option label=">=" value="GTE" /> + <el-option label="<" value="LT" /> + <el-option label="<=" value="LTE" /> + <el-option label="LIKE" value="LIKE" /> + <el-option label="BETWEEN" value="BETWEEN" /> + </el-select> + </template> + </el-table-column> + <el-table-column label="蹇呭~" min-width="5%"> + <template slot-scope="scope"> + <el-checkbox true-label="1" false-label="0" v-model="scope.row.isRequired"></el-checkbox> + </template> + </el-table-column> + <el-table-column label="鏄剧ず绫诲瀷" min-width="12%"> + <template slot-scope="scope"> + <el-select v-model="scope.row.htmlType"> + <el-option label="鏂囨湰妗�" value="input" /> + <el-option label="鏂囨湰鍩�" value="textarea" /> + <el-option label="涓嬫媺妗�" value="select" /> + <el-option label="鍗曢�夋" value="radio" /> + <el-option label="澶嶉�夋" value="checkbox" /> + <el-option label="鏃ユ湡鎺т欢" value="datetime" /> + <el-option label="鍥剧墖涓婁紶" value="imageUpload" /> + <el-option label="鏂囦欢涓婁紶" value="fileUpload" /> + <el-option label="瀵屾枃鏈帶浠�" value="editor" /> + </el-select> + </template> + </el-table-column> + <el-table-column label="瀛楀吀绫诲瀷" min-width="12%"> + <template slot-scope="scope"> + <el-select v-model="scope.row.dictType" clearable filterable placeholder="璇烽�夋嫨"> + <el-option + v-for="dict in dictOptions" + :key="dict.dictType" + :label="dict.dictName" + :value="dict.dictType"> + <span style="float: left">{{ dict.dictName }}</span> + <span style="float: right; color: #8492a6; font-size: 13px">{{ dict.dictType }}</span> + </el-option> + </el-select> + </template> + </el-table-column> + </el-table> + </el-tab-pane> + <el-tab-pane label="鐢熸垚淇℃伅" name="genInfo"> + <gen-info-form ref="genInfo" :info="info" :tables="tables" :menus="menus"/> + </el-tab-pane> + </el-tabs> + <el-form label-width="100px"> + <el-form-item style="text-align: center;margin-left:-100px;margin-top:10px;"> + <el-button type="primary" @click="submitForm()">鎻愪氦</el-button> + <el-button @click="close()">杩斿洖</el-button> + </el-form-item> + </el-form> + </el-card> +</template> + +<script> +import { getGenTable, updateGenTable } from "@/api/tool/gen"; +import { optionselect as getDictOptionselect } from "@/api/system/dict/type"; +import { listMenu as getMenuTreeselect } from "@/api/system/menu"; +import basicInfoForm from "./basicInfoForm"; +import genInfoForm from "./genInfoForm"; +import Sortable from 'sortablejs' + +export default { + name: "GenEdit", + components: { + basicInfoForm, + genInfoForm + }, + data() { + return { + // 閫変腑閫夐」鍗$殑 name + activeName: "columnInfo", + // 琛ㄦ牸鐨勯珮搴� + tableHeight: document.documentElement.scrollHeight - 245 + "px", + // 琛ㄤ俊鎭� + tables: [], + // 琛ㄥ垪淇℃伅 + columns: [], + // 瀛楀吀淇℃伅 + dictOptions: [], + // 鑿滃崟淇℃伅 + menus: [], + // 琛ㄨ缁嗕俊鎭� + info: {} + }; + }, + created() { + const tableId = this.$route.params && this.$route.params.tableId; + if (tableId) { + // 鑾峰彇琛ㄨ缁嗕俊鎭� + getGenTable(tableId).then(res => { + this.columns = res.data.rows; + this.info = res.data.info; + this.tables = res.data.tables; + }); + /** 鏌ヨ瀛楀吀涓嬫媺鍒楄〃 */ + getDictOptionselect().then(response => { + this.dictOptions = response.data; + }); + /** 鏌ヨ鑿滃崟涓嬫媺鍒楄〃 */ + getMenuTreeselect().then(response => { + this.menus = this.handleTree(response.data, "menuId"); + }); + } + }, + methods: { + /** 鎻愪氦鎸夐挳 */ + submitForm() { + const basicForm = this.$refs.basicInfo.$refs.basicInfoForm; + const genForm = this.$refs.genInfo.$refs.genInfoForm; + Promise.all([basicForm, genForm].map(this.getFormPromise)).then(res => { + const validateResult = res.every(item => !!item); + if (validateResult) { + const genTable = Object.assign({}, basicForm.model, genForm.model); + genTable.columns = this.columns; + genTable.params = { + treeCode: genTable.treeCode, + treeName: genTable.treeName, + treeParentCode: genTable.treeParentCode, + parentMenuId: genTable.parentMenuId + }; + updateGenTable(genTable).then(res => { + this.$modal.msgSuccess(res.msg); + if (res.code === 200) { + this.close(); + } + }); + } else { + this.$modal.msgError("琛ㄥ崟鏍¢獙鏈�氳繃锛岃閲嶆柊妫�鏌ユ彁浜ゅ唴瀹�"); + } + }); + }, + getFormPromise(form) { + return new Promise(resolve => { + form.validate(res => { + resolve(res); + }); + }); + }, + /** 鍏抽棴鎸夐挳 */ + close() { + const obj = { path: "/tool/gen", query: { t: Date.now(), pageNum: this.$route.query.pageNum } }; + this.$tab.closeOpenPage(obj); + } + }, + mounted() { + const el = this.$refs.dragTable.$el.querySelectorAll(".el-table__body-wrapper > table > tbody")[0]; + const sortable = Sortable.create(el, { + handle: ".allowDrag", + onEnd: evt => { + const targetRow = this.columns.splice(evt.oldIndex, 1)[0]; + this.columns.splice(evt.newIndex, 0, targetRow); + for (let index in this.columns) { + this.columns[index].sort = parseInt(index) + 1; + } + } + }); + } +}; +</script> diff --git a/src/views/tool/gen/genInfoForm.vue b/src/views/tool/gen/genInfoForm.vue new file mode 100644 index 0000000..3f8d67f --- /dev/null +++ b/src/views/tool/gen/genInfoForm.vue @@ -0,0 +1,299 @@ +<template> + <el-form ref="genInfoForm" :model="info" :rules="rules" label-width="150px"> + <el-row> + <el-col :span="12"> + <el-form-item prop="tplCategory"> + <span slot="label">鐢熸垚妯℃澘</span> + <el-select v-model="info.tplCategory" @change="tplSelectChange"> + <el-option label="鍗曡〃锛堝鍒犳敼鏌ワ級" value="crud" /> + <el-option label="鏍戣〃锛堝鍒犳敼鏌ワ級" value="tree" /> + <el-option label="涓诲瓙琛紙澧炲垹鏀规煡锛�" value="sub" /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item prop="packageName"> + <span slot="label"> + 鐢熸垚鍖呰矾寰� + <el-tooltip content="鐢熸垚鍦ㄥ摢涓猨ava鍖呬笅锛屼緥濡� com.ruoyi.system" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-input v-model="info.packageName" /> + </el-form-item> + </el-col> + + <el-col :span="12"> + <el-form-item prop="moduleName"> + <span slot="label"> + 鐢熸垚妯″潡鍚� + <el-tooltip content="鍙悊瑙d负瀛愮郴缁熷悕锛屼緥濡� system" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-input v-model="info.moduleName" /> + </el-form-item> + </el-col> + + <el-col :span="12"> + <el-form-item prop="businessName"> + <span slot="label"> + 鐢熸垚涓氬姟鍚� + <el-tooltip content="鍙悊瑙d负鍔熻兘鑻辨枃鍚嶏紝渚嬪 user" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-input v-model="info.businessName" /> + </el-form-item> + </el-col> + + <el-col :span="12"> + <el-form-item prop="functionName"> + <span slot="label"> + 鐢熸垚鍔熻兘鍚� + <el-tooltip content="鐢ㄤ綔绫绘弿杩帮紝渚嬪 鐢ㄦ埛" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-input v-model="info.functionName" /> + </el-form-item> + </el-col> + + <el-col :span="12"> + <el-form-item> + <span slot="label"> + 涓婄骇鑿滃崟 + <el-tooltip content="鍒嗛厤鍒版寚瀹氳彍鍗曚笅锛屼緥濡� 绯荤粺绠$悊" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <treeselect + :append-to-body="true" + v-model="info.parentMenuId" + :options="menus" + :normalizer="normalizer" + :show-count="true" + placeholder="璇烽�夋嫨绯荤粺鑿滃崟" + /> + </el-form-item> + </el-col> + + <el-col :span="12"> + <el-form-item prop="genType"> + <span slot="label"> + 鐢熸垚浠g爜鏂瑰紡 + <el-tooltip content="榛樿涓簔ip鍘嬬缉鍖呬笅杞斤紝涔熷彲浠ヨ嚜瀹氫箟鐢熸垚璺緞" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-radio v-model="info.genType" label="0">zip鍘嬬缉鍖�</el-radio> + <el-radio v-model="info.genType" label="1">鑷畾涔夎矾寰�</el-radio> + </el-form-item> + </el-col> + + <el-col :span="24" v-if="info.genType == '1'"> + <el-form-item prop="genPath"> + <span slot="label"> + 鑷畾涔夎矾寰� + <el-tooltip content="濉啓纾佺洏缁濆璺緞锛岃嫢涓嶅~鍐欙紝鍒欑敓鎴愬埌褰撳墠Web椤圭洰涓�" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-input v-model="info.genPath"> + <el-dropdown slot="append"> + <el-button type="primary"> + 鏈�杩戣矾寰勫揩閫熼�夋嫨 + <i class="el-icon-arrow-down el-icon--right"></i> + </el-button> + <el-dropdown-menu slot="dropdown"> + <el-dropdown-item @click.native="info.genPath = '/'">鎭㈠榛樿鐨勭敓鎴愬熀纭�璺緞</el-dropdown-item> + </el-dropdown-menu> + </el-dropdown> + </el-input> + </el-form-item> + </el-col> + </el-row> + + <el-row v-show="info.tplCategory == 'tree'"> + <h4 class="form-header">鍏朵粬淇℃伅</h4> + <el-col :span="12"> + <el-form-item> + <span slot="label"> + 鏍戠紪鐮佸瓧娈� + <el-tooltip content="鏍戞樉绀虹殑缂栫爜瀛楁鍚嶏紝 濡傦細dept_id" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-select v-model="info.treeCode" placeholder="璇烽�夋嫨"> + <el-option + v-for="(column, index) in info.columns" + :key="index" + :label="column.columnName + '锛�' + column.columnComment" + :value="column.columnName" + ></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item> + <span slot="label"> + 鏍戠埗缂栫爜瀛楁 + <el-tooltip content="鏍戞樉绀虹殑鐖剁紪鐮佸瓧娈靛悕锛� 濡傦細parent_Id" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-select v-model="info.treeParentCode" placeholder="璇烽�夋嫨"> + <el-option + v-for="(column, index) in info.columns" + :key="index" + :label="column.columnName + '锛�' + column.columnComment" + :value="column.columnName" + ></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item> + <span slot="label"> + 鏍戝悕绉板瓧娈� + <el-tooltip content="鏍戣妭鐐圭殑鏄剧ず鍚嶇О瀛楁鍚嶏紝 濡傦細dept_name" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-select v-model="info.treeName" placeholder="璇烽�夋嫨"> + <el-option + v-for="(column, index) in info.columns" + :key="index" + :label="column.columnName + '锛�' + column.columnComment" + :value="column.columnName" + ></el-option> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row v-show="info.tplCategory == 'sub'"> + <h4 class="form-header">鍏宠仈淇℃伅</h4> + <el-col :span="12"> + <el-form-item> + <span slot="label"> + 鍏宠仈瀛愯〃鐨勮〃鍚� + <el-tooltip content="鍏宠仈瀛愯〃鐨勮〃鍚嶏紝 濡傦細sys_user" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-select v-model="info.subTableName" placeholder="璇烽�夋嫨" @change="subSelectChange"> + <el-option + v-for="(table, index) in tables" + :key="index" + :label="table.tableName + '锛�' + table.tableComment" + :value="table.tableName" + ></el-option> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item> + <span slot="label"> + 瀛愯〃鍏宠仈鐨勫閿悕 + <el-tooltip content="瀛愯〃鍏宠仈鐨勫閿悕锛� 濡傦細user_id" placement="top"> + <i class="el-icon-question"></i> + </el-tooltip> + </span> + <el-select v-model="info.subTableFkName" placeholder="璇烽�夋嫨"> + <el-option + v-for="(column, index) in subColumns" + :key="index" + :label="column.columnName + '锛�' + column.columnComment" + :value="column.columnName" + ></el-option> + </el-select> + </el-form-item> + </el-col> + </el-row> + </el-form> +</template> + +<script> +import Treeselect from "@riophae/vue-treeselect"; +import "@riophae/vue-treeselect/dist/vue-treeselect.css"; + +export default { + components: { Treeselect }, + props: { + info: { + type: Object, + default: null + }, + tables: { + type: Array, + default: null + }, + menus: { + type: Array, + default: [] + }, + }, + data() { + return { + subColumns: [], + rules: { + tplCategory: [ + { required: true, message: "璇烽�夋嫨鐢熸垚妯℃澘", trigger: "blur" } + ], + packageName: [ + { required: true, message: "璇疯緭鍏ョ敓鎴愬寘璺緞", trigger: "blur" } + ], + moduleName: [ + { required: true, message: "璇疯緭鍏ョ敓鎴愭ā鍧楀悕", trigger: "blur" } + ], + businessName: [ + { required: true, message: "璇疯緭鍏ョ敓鎴愪笟鍔″悕", trigger: "blur" } + ], + functionName: [ + { required: true, message: "璇疯緭鍏ョ敓鎴愬姛鑳藉悕", trigger: "blur" } + ], + } + }; + }, + created() {}, + watch: { + 'info.subTableName': function(val) { + this.setSubTableColumns(val); + } + }, + methods: { + /** 杞崲鑿滃崟鏁版嵁缁撴瀯 */ + normalizer(node) { + if (node.children && !node.children.length) { + delete node.children; + } + return { + id: node.menuId, + label: node.menuName, + children: node.children + }; + }, + /** 閫夋嫨瀛愯〃鍚嶈Е鍙� */ + subSelectChange(value) { + this.info.subTableFkName = ''; + }, + /** 閫夋嫨鐢熸垚妯℃澘瑙﹀彂 */ + tplSelectChange(value) { + if(value !== 'sub') { + this.info.subTableName = ''; + this.info.subTableFkName = ''; + } + }, + /** 璁剧疆鍏宠仈澶栭敭 */ + setSubTableColumns(value) { + for (var item in this.tables) { + const name = this.tables[item].tableName; + if (value === name) { + this.subColumns = this.tables[item].columns; + break; + } + } + } + } +}; +</script> diff --git a/src/views/tool/gen/importTable.vue b/src/views/tool/gen/importTable.vue new file mode 100644 index 0000000..3ea9532 --- /dev/null +++ b/src/views/tool/gen/importTable.vue @@ -0,0 +1,120 @@ +<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="tableName"> + <el-input + v-model="queryParams.tableName" + placeholder="璇疯緭鍏ヨ〃鍚嶇О" + clearable + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="琛ㄦ弿杩�" prop="tableComment"> + <el-input + v-model="queryParams.tableComment" + 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="dbTableList" @selection-change="handleSelectionChange" height="260px"> + <el-table-column type="selection" width="55"></el-table-column> + <el-table-column prop="tableName" label="琛ㄥ悕绉�" :show-overflow-tooltip="true"></el-table-column> + <el-table-column prop="tableComment" label="琛ㄦ弿杩�" :show-overflow-tooltip="true"></el-table-column> + <el-table-column prop="createTime" label="鍒涘缓鏃堕棿"></el-table-column> + <el-table-column prop="updateTime" label="鏇存柊鏃堕棿"></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="handleImportTable">纭� 瀹�</el-button> + <el-button @click="visible = false">鍙� 娑�</el-button> + </div> + </el-dialog> +</template> + +<script> +import { listDbTable, importTable } from "@/api/tool/gen"; +export default { + data() { + return { + // 閬僵灞� + visible: false, + // 閫変腑鏁扮粍鍊� + tables: [], + // 鎬绘潯鏁� + total: 0, + // 琛ㄦ暟鎹� + dbTableList: [], + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + tableName: undefined, + tableComment: undefined + } + }; + }, + methods: { + // 鏄剧ず寮规 + show() { + this.getList(); + this.visible = true; + }, + clickRow(row) { + this.$refs.table.toggleRowSelection(row); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.tables = selection.map(item => item.tableName); + }, + // 鏌ヨ琛ㄦ暟鎹� + getList() { + listDbTable(this.queryParams).then(res => { + if (res.code === 200) { + this.dbTableList = res.rows; + this.total = res.total; + } + }); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + /** 瀵煎叆鎸夐挳鎿嶄綔 */ + handleImportTable() { + const tableNames = this.tables.join(","); + if (tableNames == "") { + this.$modal.msgError("璇烽�夋嫨瑕佸鍏ョ殑琛�"); + return; + } + importTable({ tables: tableNames }).then(res => { + this.$modal.msgSuccess(res.msg); + if (res.code === 200) { + this.visible = false; + this.$emit("ok"); + } + }); + } + } +}; +</script> diff --git a/src/views/tool/gen/index.vue b/src/views/tool/gen/index.vue new file mode 100644 index 0000000..3f1f930 --- /dev/null +++ b/src/views/tool/gen/index.vue @@ -0,0 +1,337 @@ +<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="tableName"> + <el-input + v-model="queryParams.tableName" + placeholder="璇疯緭鍏ヨ〃鍚嶇О" + clearable + @keyup.enter.native="handleQuery" + /> + </el-form-item> + <el-form-item label="琛ㄦ弿杩�" prop="tableComment"> + <el-input + v-model="queryParams.tableComment" + placeholder="璇疯緭鍏ヨ〃鎻忚堪" + clearable + @keyup.enter.native="handleQuery" + /> + </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-download" + size="mini" + @click="handleGenTable" + v-hasPermi="['tool:gen:code']" + >鐢熸垚</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="info" + plain + icon="el-icon-upload" + size="mini" + @click="openImportTable" + v-hasPermi="['tool:gen:import']" + >瀵煎叆</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="success" + plain + icon="el-icon-edit" + size="mini" + :disabled="single" + @click="handleEditTable" + v-hasPermi="['tool:gen: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="['tool:gen:remove']" + >鍒犻櫎</el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <el-table v-loading="loading" :data="tableList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" align="center" width="55"></el-table-column> + <el-table-column label="搴忓彿" type="index" width="50" align="center"> + <template slot-scope="scope"> + <span>{{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}</span> + </template> + </el-table-column> + <el-table-column + label="琛ㄥ悕绉�" + align="center" + prop="tableName" + :show-overflow-tooltip="true" + width="120" + /> + <el-table-column + label="琛ㄦ弿杩�" + align="center" + prop="tableComment" + :show-overflow-tooltip="true" + width="120" + /> + <el-table-column + label="瀹炰綋" + align="center" + prop="className" + :show-overflow-tooltip="true" + width="120" + /> + <el-table-column label="鍒涘缓鏃堕棿" align="center" prop="createTime" width="160" /> + <el-table-column label="鏇存柊鏃堕棿" align="center" prop="updateTime" width="160" /> + <el-table-column label="鎿嶄綔" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + type="text" + size="small" + icon="el-icon-view" + @click="handlePreview(scope.row)" + v-hasPermi="['tool:gen:preview']" + >棰勮</el-button> + <el-button + type="text" + size="small" + icon="el-icon-edit" + @click="handleEditTable(scope.row)" + v-hasPermi="['tool:gen:edit']" + >缂栬緫</el-button> + <el-button + type="text" + size="small" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['tool:gen:remove']" + >鍒犻櫎</el-button> + <el-button + type="text" + size="small" + icon="el-icon-refresh" + @click="handleSynchDb(scope.row)" + v-hasPermi="['tool:gen:edit']" + >鍚屾</el-button> + <el-button + type="text" + size="small" + icon="el-icon-download" + @click="handleGenTable(scope.row)" + v-hasPermi="['tool:gen:code']" + >鐢熸垚浠g爜</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="preview.title" :visible.sync="preview.open" width="80%" top="5vh" append-to-body class="scrollbar"> + <el-tabs v-model="preview.activeName"> + <el-tab-pane + v-for="(value, key) in preview.data" + :label="key.substring(key.lastIndexOf('/')+1,key.indexOf('.vm'))" + :name="key.substring(key.lastIndexOf('/')+1,key.indexOf('.vm'))" + :key="key" + > + <el-link :underline="false" icon="el-icon-document-copy" v-clipboard:copy="value" v-clipboard:success="clipboardSuccess" style="float:right">澶嶅埗</el-link> + <pre><code class="hljs" v-html="highlightedCode(value, key)"></code></pre> + </el-tab-pane> + </el-tabs> + </el-dialog> + <import-table ref="import" @ok="handleQuery" /> + </div> +</template> + +<script> +import { listTable, previewTable, delTable, genCode, synchDb } from "@/api/tool/gen"; +import importTable from "./importTable"; +import hljs from "highlight.js/lib/highlight"; +import "highlight.js/styles/github-gist.css"; +hljs.registerLanguage("java", require("highlight.js/lib/languages/java")); +hljs.registerLanguage("xml", require("highlight.js/lib/languages/xml")); +hljs.registerLanguage("html", require("highlight.js/lib/languages/xml")); +hljs.registerLanguage("vue", require("highlight.js/lib/languages/xml")); +hljs.registerLanguage("javascript", require("highlight.js/lib/languages/javascript")); +hljs.registerLanguage("sql", require("highlight.js/lib/languages/sql")); + +export default { + name: "Gen", + components: { importTable }, + data() { + return { + // 閬僵灞� + loading: true, + // 鍞竴鏍囪瘑绗� + uniqueId: "", + // 閫変腑鏁扮粍 + ids: [], + // 閫変腑琛ㄦ暟缁� + tableNames: [], + // 闈炲崟涓鐢� + single: true, + // 闈炲涓鐢� + multiple: true, + // 鏄剧ず鎼滅储鏉′欢 + showSearch: true, + // 鎬绘潯鏁� + total: 0, + // 琛ㄦ暟鎹� + tableList: [], + // 鏃ユ湡鑼冨洿 + dateRange: "", + // 鏌ヨ鍙傛暟 + queryParams: { + pageNum: 1, + pageSize: 10, + tableName: undefined, + tableComment: undefined + }, + // 棰勮鍙傛暟 + preview: { + open: false, + title: "浠g爜棰勮", + data: {}, + activeName: "domain.java" + } + }; + }, + created() { + this.getList(); + }, + activated() { + const time = this.$route.query.t; + if (time != null && time != this.uniqueId) { + this.uniqueId = time; + this.queryParams.pageNum = Number(this.$route.query.pageNum); + this.getList(); + } + }, + methods: { + /** 鏌ヨ琛ㄩ泦鍚� */ + getList() { + this.loading = true; + listTable(this.addDateRange(this.queryParams, this.dateRange)).then(response => { + this.tableList = response.rows; + this.total = response.total; + this.loading = false; + } + ); + }, + /** 鎼滅储鎸夐挳鎿嶄綔 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 鐢熸垚浠g爜鎿嶄綔 */ + handleGenTable(row) { + const tableNames = row.tableName || this.tableNames; + if (tableNames == "") { + this.$modal.msgError("璇烽�夋嫨瑕佺敓鎴愮殑鏁版嵁"); + return; + } + if(row.genType === "1") { + genCode(row.tableName).then(response => { + this.$modal.msgSuccess("鎴愬姛鐢熸垚鍒拌嚜瀹氫箟璺緞锛�" + row.genPath); + }); + } else { + this.$download.zip("/tool/gen/batchGenCode?tables=" + tableNames, "ruoyi.zip"); + } + }, + /** 鍚屾鏁版嵁搴撴搷浣� */ + handleSynchDb(row) { + const tableName = row.tableName; + this.$modal.confirm('纭瑕佸己鍒跺悓姝�"' + tableName + '"琛ㄧ粨鏋勫悧锛�').then(function() { + return synchDb(tableName); + }).then(() => { + this.$modal.msgSuccess("鍚屾鎴愬姛"); + }).catch(() => {}); + }, + /** 鎵撳紑瀵煎叆琛ㄥ脊绐� */ + openImportTable() { + this.$refs.import.show(); + }, + /** 閲嶇疆鎸夐挳鎿嶄綔 */ + resetQuery() { + this.dateRange = []; + this.resetForm("queryForm"); + this.handleQuery(); + }, + /** 棰勮鎸夐挳 */ + handlePreview(row) { + previewTable(row.tableId).then(response => { + this.preview.data = response.data; + this.preview.open = true; + this.preview.activeName = "domain.java"; + }); + }, + /** 楂樹寒鏄剧ず */ + highlightedCode(code, key) { + const vmName = key.substring(key.lastIndexOf("/") + 1, key.indexOf(".vm")); + var language = vmName.substring(vmName.indexOf(".") + 1, vmName.length); + const result = hljs.highlight(language, code || "", true); + return result.value || ' '; + }, + /** 澶嶅埗浠g爜鎴愬姛 */ + clipboardSuccess() { + this.$modal.msgSuccess("澶嶅埗鎴愬姛"); + }, + // 澶氶�夋閫変腑鏁版嵁 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.tableId); + this.tableNames = selection.map(item => item.tableName); + this.single = selection.length != 1; + this.multiple = !selection.length; + }, + /** 淇敼鎸夐挳鎿嶄綔 */ + handleEditTable(row) { + const tableId = row.tableId || this.ids[0]; + const tableName = row.tableName || this.tableNames[0]; + const params = { pageNum: this.queryParams.pageNum }; + this.$tab.openPage("淇敼[" + tableName + "]鐢熸垚閰嶇疆", '/tool/gen-edit/index/' + tableId, params); + }, + /** 鍒犻櫎鎸夐挳鎿嶄綔 */ + handleDelete(row) { + const tableIds = row.tableId || this.ids; + this.$modal.confirm('鏄惁纭鍒犻櫎琛ㄧ紪鍙蜂负"' + tableIds + '"鐨勬暟鎹」锛�').then(function() { + return delTable(tableIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("鍒犻櫎鎴愬姛"); + }).catch(() => {}); + } + } +}; +</script> diff --git a/src/views/tool/swagger/index.vue b/src/views/tool/swagger/index.vue new file mode 100644 index 0000000..b8becc6 --- /dev/null +++ b/src/views/tool/swagger/index.vue @@ -0,0 +1,15 @@ +<template> + <i-frame :src="url" /> +</template> +<script> +import iFrame from "@/components/iFrame/index"; +export default { + name: "Swagger", + components: { iFrame }, + data() { + return { + url: process.env.VUE_APP_BASE_API + "/swagger-ui/index.html" + }; + }, +}; +</script> diff --git a/vue.config.js b/vue.config.js new file mode 100644 index 0000000..0bb32f5 --- /dev/null +++ b/vue.config.js @@ -0,0 +1,131 @@ +'use strict'; +const path = require('path'); + +function resolve(dir) { + return path.join(__dirname, dir); +} + +const CompressionPlugin = require('compression-webpack-plugin'); + +const name = process.env.VUE_APP_TITLE || '娉扮憺宸ヤ笟鏁板瓧瀛敓绠$悊骞冲彴'; // 缃戦〉鏍囬 + +const port = process.env.port || process.env.npm_config_port || 80; // 绔彛 + +// vue.config.js 閰嶇疆璇存槑 +//瀹樻柟vue.config.js 鍙傝�冩枃妗� https://cli.vuejs.org/zh/config/#css-loaderoptions +// 杩欓噷鍙垪涓�閮ㄥ垎锛屽叿浣撻厤缃弬鑰冩枃妗� +module.exports = { + // 閮ㄧ讲鐢熶骇鐜鍜屽紑鍙戠幆澧冧笅鐨刄RL銆� + // 榛樿鎯呭喌涓嬶紝Vue CLI 浼氬亣璁句綘鐨勫簲鐢ㄦ槸琚儴缃插湪涓�涓煙鍚嶇殑鏍硅矾寰勪笂 + // 渚嬪 https://www.ruoyi.vip/銆傚鏋滃簲鐢ㄨ閮ㄧ讲鍦ㄤ竴涓瓙璺緞涓婏紝浣犲氨闇�瑕佺敤杩欎釜閫夐」鎸囧畾杩欎釜瀛愯矾寰勩�備緥濡傦紝濡傛灉浣犵殑搴旂敤琚儴缃插湪 https://www.ruoyi.vip/admin/锛屽垯璁剧疆 baseUrl 涓� /admin/銆� + publicPath: process.env.NODE_ENV === 'production' ? '/' : '/', + // 鍦╪pm run build 鎴� yarn build 鏃� 锛岀敓鎴愭枃浠剁殑鐩綍鍚嶇О锛堣鍜宐aseUrl鐨勭敓浜х幆澧冭矾寰勪竴鑷达級锛堥粯璁ist锛� + outputDir: 'dist', + // 鐢ㄤ簬鏀剧疆鐢熸垚鐨勯潤鎬佽祫婧� (js銆乧ss銆乮mg銆乫onts) 鐨勶紱锛堥」鐩墦鍖呬箣鍚庯紝闈欐�佽祫婧愪細鏀惧湪杩欎釜鏂囦欢澶逛笅锛� + assetsDir: 'static', + // 鏄惁寮�鍚痚slint淇濆瓨妫�娴嬶紝鏈夋晥鍊硷細ture | false | 'error' + lintOnSave: process.env.NODE_ENV === 'development', + // 濡傛灉浣犱笉闇�瑕佺敓浜х幆澧冪殑 source map锛屽彲浠ュ皢鍏惰缃负 false 浠ュ姞閫熺敓浜х幆澧冩瀯寤恒�� + productionSourceMap: false, + // webpack-dev-server 鐩稿叧閰嶇疆 + devServer: { + host: '0.0.0.0', + port: port, + open: true, + proxy: { + // detail: https://cli.vuejs.org/config/#devserver-proxy + [process.env.VUE_APP_BASE_API]: { + target: process.env.VUE_APP_SERVER_API_URL, + changeOrigin: true, + pathRewrite: { + ['^' + process.env.VUE_APP_BASE_API]: '', + }, + }, + }, + disableHostCheck: true, + }, + css: { + loaderOptions: { + sass: { + sassOptions: { outputStyle: 'expanded' }, + }, + }, + }, + configureWebpack: { + name: name, + resolve: { + alias: { + '@': resolve('src'), + }, + }, + plugins: [ + // http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#浣跨敤gzip瑙e帇缂╅潤鎬佹枃浠� + new CompressionPlugin({ + cache: false, // 涓嶅惎鐢ㄦ枃浠剁紦瀛� + test: /\.(js|css|html)?$/i, // 鍘嬬缉鏂囦欢鏍煎紡 + filename: '[path].gz[query]', // 鍘嬬缉鍚庣殑鏂囦欢鍚� + algorithm: 'gzip', // 浣跨敤gzip鍘嬬缉 + minRatio: 0.8, // 鍘嬬缉鐜囧皬浜�1鎵嶄細鍘嬬缉 + }), + ], + }, + chainWebpack(config) { + config.plugins.delete('preload'); // TODO: need test + config.plugins.delete('prefetch'); // TODO: need test + + // set svg-sprite-loader + config.module.rule('svg').exclude.add(resolve('src/assets/icons')).end(); + config.module + .rule('icons') + .test(/\.svg$/) + .include.add(resolve('src/assets/icons')) + .end() + .use('svg-sprite-loader') + .loader('svg-sprite-loader') + .options({ + symbolId: 'icon-[name]', + }) + .end(); + + config.when(process.env.NODE_ENV !== 'development', (config) => { + config + .plugin('ScriptExtHtmlWebpackPlugin') + .after('html') + .use('script-ext-html-webpack-plugin', [ + { + // `runtime` must same as runtimeChunk name. default is `runtime` + inline: /runtime\..*\.js$/, + }, + ]) + .end(); + config.optimization.splitChunks({ + chunks: 'all', + cacheGroups: { + libs: { + name: 'chunk-libs', + test: /[\\/]node_modules[\\/]/, + priority: 10, + chunks: 'initial', // only package third parties that are initially dependent + }, + elementUI: { + name: 'chunk-elementUI', // split elementUI into a single package + priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app + test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm + }, + commons: { + name: 'chunk-commons', + test: resolve('src/components'), // can customize your rules + minChunks: 3, // minimum common number + priority: 5, + reuseExistingChunk: true, + }, + }, + }); + config.optimization.runtimeChunk('single'), + { + from: path.resolve(__dirname, './public/robots.txt'), //闃茬埇铏枃浠� + to: './', //鍒版牴鐩綍涓� + }; + }); + }, +}; -- Gitblit v1.9.3