diff --git a/CANVAS_DRIVER_GUIDE.md b/CANVAS_DRIVER_GUIDE.md new file mode 100644 index 0000000..f500b52 --- /dev/null +++ b/CANVAS_DRIVER_GUIDE.md @@ -0,0 +1,177 @@ +# Canvas 场景下使用 Driver.js 的指南 + +## 概述 + +Driver.js 可以用于 Canvas 场景,但有一些限制和特殊处理方式。 + +## Driver.js 在 Canvas 中的限制 + +1. **无法直接高亮 Canvas 内部元素**:Driver.js 只能高亮 DOM 元素,而 Canvas 内部绘制的内容(如设备图标、点标记等)不是 DOM 元素,无法直接高亮。 + +2. **可以高亮 Canvas 元素本身**:可以高亮整个 `` 标签,但无法精确定位到 Canvas 内部的某个绘制内容。 + +## 解决方案 + +### 方案 1:高亮整个 Canvas(最简单) + +直接高亮 Canvas 元素本身,适用于引导用户了解 Canvas 区域的功能。 + +```javascript +{ + element: '.main-canvas', // 或 '.canvas-wrapper' + popover: { + title: '平面图区域', + description: '这是平面图显示区域,您可以在这里查看设备位置和状态。', + side: 'top', + align: 'center' + } +} +``` + +### 方案 2:使用占位元素(推荐用于精确引导) + +如果需要在 Canvas 内部某个特定位置进行引导,可以创建一个临时的占位 DOM 元素: + +```javascript +// 创建占位元素 +const createPlaceholder = (x, y, width, height) => { + const placeholder = document.createElement('div'); + placeholder.className = 'canvas-placeholder'; + placeholder.style.position = 'absolute'; + placeholder.style.left = `${x}px`; + placeholder.style.top = `${y}px`; + placeholder.style.width = `${width}px`; + placeholder.style.height = `${height}px`; + placeholder.style.pointerEvents = 'none'; // 不阻挡 Canvas 交互 + placeholder.style.zIndex = '1000'; + document.body.appendChild(placeholder); + return placeholder; +}; + +// 在引导步骤中使用 +{ + element: '.canvas-placeholder', + popover: { + title: '设备图标', + description: '这是设备图标的位置,在编辑模式下可以拖拽移动。', + side: 'top', + align: 'center' + } +} +``` + +### 方案 3:使用自定义高亮(高级) + +结合 Canvas 坐标计算和自定义高亮层: + +```javascript +// 计算 Canvas 内部元素的屏幕坐标 +const getCanvasElementScreenPos = (canvasElement, canvasX, canvasY, scale, offsetX, offsetY) => { + const rect = canvasElement.getBoundingClientRect(); + const screenX = rect.left + (canvasX * scale + offsetX); + const screenY = rect.top + (canvasY * scale + offsetY); + return { screenX, screenY }; +}; + +// 创建自定义高亮层 +const createCustomHighlight = (x, y, width, height) => { + const highlight = document.createElement('div'); + highlight.className = 'custom-canvas-highlight'; + highlight.style.position = 'fixed'; + highlight.style.left = `${x}px`; + highlight.style.top = `${y}px`; + highlight.style.width = `${width}px`; + highlight.style.height = `${height}px`; + highlight.style.border = '3px solid #4dabf7'; + highlight.style.borderRadius = '8px'; + highlight.style.boxShadow = '0 0 20px rgba(77, 171, 247, 0.5)'; + highlight.style.pointerEvents = 'none'; + highlight.style.zIndex = '9999'; + document.body.appendChild(highlight); + return highlight; +}; +``` + +## 实际应用示例 + +### 示例 1:引导 Canvas 区域 + +```javascript +{ + element: '.canvas-wrapper', + popover: { + title: '平面图区域', + description: '这是主要的平面图显示区域,所有设备都会在这里显示。', + side: 'top', + align: 'center' + } +} +``` + +### 示例 2:引导 Canvas 中的特定设备(需要坐标计算) + +```javascript +// 假设要引导一个设备,其 Canvas 坐标为 (pointX, pointY) +const guideDevice = (pointX, pointY) => { + nextTick(() => { + if (!canvasRef.value) return; + + // 计算设备在屏幕上的位置 + const rect = canvasRef.value.getBoundingClientRect(); + const screenX = rect.left + (pointX * BL.value * scale.value + offsetX.value); + const screenY = rect.top + (pointY * BL.value * scale.value + offsetY.value); + + // 创建占位元素 + const placeholder = document.createElement('div'); + placeholder.className = 'device-placeholder'; + placeholder.style.position = 'fixed'; + placeholder.style.left = `${screenX - 20}px`; + placeholder.style.top = `${screenY - 20}px`; + placeholder.style.width = '40px'; + placeholder.style.height = '40px'; + placeholder.style.pointerEvents = 'none'; + placeholder.style.zIndex = '9999'; + document.body.appendChild(placeholder); + + // 使用 driver.js 高亮占位元素 + driverObj.highlight({ + element: '.device-placeholder', + popover: { + title: '设备图标', + description: '这是设备图标,在编辑模式下可以拖拽移动。', + side: 'bottom', + align: 'center' + } + }); + + // 引导结束后移除占位元素 + setTimeout(() => { + placeholder.remove(); + }, 5000); + }); +}; +``` + +## 当前项目中的最佳实践 + +在当前项目中,由于主要功能按钮(筛选、分区、编辑)都是 DOM 元素,Driver.js 可以正常工作。对于 Canvas 内部的引导,建议: + +1. **引导 Canvas 容器**:高亮整个 Canvas 区域,说明整体功能 +2. **引导相关操作按钮**:通过引导操作按钮(如编辑按钮)来间接引导 Canvas 功能 +3. **结合文字说明**:在引导提示中详细说明 Canvas 的操作方式 + +## 注意事项 + +1. **坐标转换**:Canvas 内部坐标需要转换为屏幕坐标才能创建占位元素 +2. **缩放和偏移**:需要考虑 Canvas 的缩放(scale)和偏移(offsetX, offsetY) +3. **动态更新**:如果 Canvas 内容会移动或变化,占位元素的位置也需要动态更新 +4. **性能考虑**:占位元素应该及时清理,避免内存泄漏 + +## 总结 + +Driver.js **可以**用于 Canvas 场景,但需要根据具体需求选择合适的方案: +- 简单场景:直接高亮 Canvas 元素 +- 精确引导:使用占位元素或自定义高亮 +- 当前项目:已有 DOM 按钮的引导已经足够,无需额外处理 Canvas 内部元素 + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8564f29 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2018 RuoYi + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f107fe2 --- /dev/null +++ b/README.md @@ -0,0 +1,108 @@ +

+ logo +

+

RuoYi v3.9.0

+

基于SpringBoot+Vue3前后端分离的Java快速开发框架

+

+ + + +

+ +## 平台简介 + +* 本仓库为前端技术栈 [Vue3](https://v3.cn.vuejs.org) + [Element Plus](https://element-plus.org/zh-CN) + [Vite](https://cn.vitejs.dev) 版本。 +* 配套后端代码仓库地址[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) 或 [RuoYi-Vue-fast](https://gitcode.com/yangzongzhuan/RuoYi-Vue-fast) 版本。 +* 前端技术栈([Vue2](https://cn.vuejs.org) + [Element](https://github.com/ElemeFE/element) + [Vue CLI](https://cli.vuejs.org/zh)),请移步[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue/tree/master/ruoyi-ui)。 +* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)   + +## 前端运行 + +```bash +# 克隆项目 +git clone https://github.com/yangzongzhuan/RuoYi-Vue3.git + +# 进入项目目录 +cd RuoYi-Vue3 + +# 安装依赖 +yarn --registry=https://registry.npmmirror.com + +# 启动服务 +yarn dev + +# 构建测试环境 yarn build:stage +# 构建生产环境 yarn build:prod +# 前端访问地址 http://localhost:80 +``` + +## 内置功能 + +1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 +2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。 +3. 岗位管理:配置系统用户所属担任职务。 +4. 菜单管理:配置系统菜单,操作权限,按钮权限标识等。 +5. 角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。 +6. 字典管理:对系统中经常使用的一些较为固定的数据进行维护。 +7. 参数管理:对系统动态配置常用参数。 +8. 通知公告:系统通知公告信息发布维护。 +9. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 +10. 登录日志:系统登录日志记录查询包含登录异常。 +11. 在线用户:当前系统中活跃用户状态监控。 +12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 +13. 代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。 +14. 系统接口:根据业务代码自动生成相关的api接口文档。 +15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。 +16. 缓存监控:对系统的缓存信息查询,命令统计等。 +17. 在线构建器:拖动表单元素生成相应的HTML代码。 +18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。 + +## 在线体验 + +- admin/admin123 +- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。 + +演示地址:http://vue.ruoyi.vip +文档地址:http://doc.ruoyi.vip + +## 演示图 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +## 若依前后端分离交流群 + +QQ群: [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/已满-170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [![加入QQ群](https://img.shields.io/badge/已满-108482800-blue.svg)](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [![加入QQ群](https://img.shields.io/badge/已满-101046199-blue.svg)](https://jq.qq.com/?_wv=1027&k=SpyH2875) [![加入QQ群](https://img.shields.io/badge/已满-136919097-blue.svg)](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [![加入QQ群](https://img.shields.io/badge/已满-143961921-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [![加入QQ群](https://img.shields.io/badge/已满-174951577-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [![加入QQ群](https://img.shields.io/badge/已满-161281055-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [![加入QQ群](https://img.shields.io/badge/已满-138988063-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [![加入QQ群](https://img.shields.io/badge/已满-151450850-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) [![加入QQ群](https://img.shields.io/badge/已满-224622315-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=F58bgRa-Dp-rsQJThiJqIYv8t4-lWfXh&authKey=UmUs4CVG5OPA1whvsa4uSespOvyd8%2FAr9olEGaWAfdLmfKQk%2FVBp2YU3u2xXXt76&noverify=0&group_code=224622315) [![加入QQ群](https://img.shields.io/badge/已满-287842588-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Nxb2EQ5qozWa218Wbs7zgBnjLSNk_tVT&authKey=obBKXj6SBKgrFTJZx0AqQnIYbNOvBB2kmgwWvGhzxR67RoRr84%2Bus5OadzMcdJl5&noverify=0&group_code=287842588) [![加入QQ群](https://img.shields.io/badge/已满-187944233-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=numtK1M_I4eVd2Gvg8qtbuL8JgX42qNh&authKey=giV9XWMaFZTY%2FqPlmWbkB9g3fi0Ev5CwEtT9Tgei0oUlFFCQLDp4ozWRiVIzubIm&noverify=0&group_code=187944233) [![加入QQ群](https://img.shields.io/badge/已满-228578329-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G6r5KGCaa3pqdbUSXNIgYloyb8e0_L0D&authKey=4w8tF1eGW7%2FedWn%2FHAypQksdrML%2BDHolQSx7094Agm7Luakj9EbfPnSTxSi2T1LQ&noverify=0&group_code=228578329) [![加入QQ群](https://img.shields.io/badge/191164766-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GsOo-OLz53J8y_9TPoO6XXSGNRTgbFxA&authKey=R7Uy%2Feq%2BZsoKNqHvRKhiXpypW7DAogoWapOawUGHokJSBIBIre2%2FoiAZeZBSLuBc&noverify=0&group_code=191164766) 点击按钮入群。 \ No newline at end of file diff --git a/bin/build.bat b/bin/build.bat new file mode 100644 index 0000000..8868727 --- /dev/null +++ b/bin/build.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] Weḅdistļ +echo. + +%~d0 +cd %~dp0 + +cd .. +yarn 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..8693727 --- /dev/null +++ b/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] װWeḅnode_modulesļ +echo. + +%~d0 +cd %~dp0 + +cd .. +yarn --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..f9d3ae8 --- /dev/null +++ b/bin/run-web.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] ʹ Vite Web ̡ +echo. + +%~d0 +cd %~dp0 + +cd .. +yarn dev + +pause \ No newline at end of file diff --git a/html/ie.html b/html/ie.html new file mode 100644 index 0000000..390ce8a --- /dev/null +++ b/html/ie.html @@ -0,0 +1,46 @@ + + + + + + 请升级您的浏览器 + + + + + + +

请升级您的浏览器,以便我们更好的为您提供服务!

+

您正在使用 Internet Explorer 的早期版本(IE11以下版本或使用该内核的浏览器)。这意味着在升级浏览器前,您将无法访问此网站。

+
+

请注意:微软公司对Windows XP 及 Internet Explorer 早期版本的支持已经结束

+

自 2016 年 1 月 12 日起,Microsoft 不再为 IE 11 以下版本提供相应支持和更新。没有关键的浏览器安全更新,您的电脑可能易受有害病毒、间谍软件和其他恶意软件的攻击,它们可以窃取或损害您的业务数据和信息。请参阅 微软对 Internet Explorer 早期版本的支持将于 2016 年 1 月 12 日结束的说明

+
+

您可以选择更先进的浏览器

+

推荐使用以下浏览器的最新版本。如果您的电脑已有以下浏览器的最新版本则直接使用该浏览器访问即可。

+ +
+ + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..ba758d1 --- /dev/null +++ b/index.html @@ -0,0 +1,216 @@ + + + + + + + + + + 武汉礼河路管廊综合管理平台 + + + + + +
+
+
+
+
+
正在加载系统资源,请耐心等待
+
+
+ + + + + \ No newline at end of file diff --git a/public/config.js b/public/config.js new file mode 100644 index 0000000..3b27f31 --- /dev/null +++ b/public/config.js @@ -0,0 +1,14 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-26 16:33:30 + * @Description: + */ +window.customConfigUrl = { + // baseURL: 'http://172.16.1.254:13020', //常用接口地址 + baseURL: 'http://forex.zicp.net', //常用接口地址 + refreshTime: 3000000, //详情窗口数据轮询间隔时间 + deviceDataReqTime: 3000000, //平面图页面状态轮询间隔 + faultColor: '#FF9912', //故障 报警 颜色 + openColor: '#00C957', //运行中 颜色 + closeColor: '#FF0000' //非运行中 颜色 +}; \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..e263760 Binary files /dev/null and b/public/favicon.ico differ diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..87b89b0 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,15 @@ + + + diff --git a/src/api/alarm/index.js b/src/api/alarm/index.js new file mode 100644 index 0000000..24d7cc7 --- /dev/null +++ b/src/api/alarm/index.js @@ -0,0 +1,98 @@ +import request from "@/utils/request"; + +//级别列表查询 +export function getLevelList(query) { + return request({ + url: "/sysConfig/level/list", + method: "get", + params: query, + }); +} +// 单条级别查询 +export function getLevelDetail(query) { + return request({ + url: "/sysConfig/level/" + query.id, + method: "get", + }); +} +// 新增级别数据 +export function addLevel(data) { + return request({ + url: "/sysConfig/level/add", + method: "post", + data + }); +} +// 修改级别数据 +export function updateLevel(data) { + return request({ + url: "/sysConfig/level/update", + method: "post", + data + }); +} +// 删除级别数据 +export function delLevel(query) { + return request({ + url: "/sysConfig/level/remove/" + query.id, + method: "get", + }); +} +// 查询人员列表 +export function getUser(query) { + return request({ + url: "/sysConfig/level/getUser", + method: "get", + params:query + }); +} + +//查询报警列表 +export function getAlarmList(query) { + return request({ + url: "/sysConfig/warningConfig/list", + method: "get", + params:query + }); +} +// 查看报警详情 +export function getAlarmDetail(query) { + return request({ + url: "/sysConfig/warningConfig/"+query.id, + method: "get", + // params:query + }); +} +// 修改报警 +export function updateAlarm(data) { + return request({ + url: "/sysConfig/warningConfig/update", + method: "post", + data + }); +} +// 查看报警详情 +export function delAlarm(query) { + return request({ + url: "/sysConfig/warningConfig/remove/"+query.id, + method: "get", + // params:query + }); +} +// 新增报警 +export function addAlarm(data) { + return request({ + url: "/sysConfig/warningConfig/add", + method: "post", + data + }); +} +// 根据类型查询参数 +export function getStatus(query) { + return request({ + url: "/sysConfig/warningConfig/getStatus/"+query.id, + method: "get", + // params:query + }); +} + diff --git a/src/api/area.js b/src/api/area.js new file mode 100644 index 0000000..3aab881 --- /dev/null +++ b/src/api/area.js @@ -0,0 +1,41 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-26 11:23:42 + * @Description: + */ +import request from '@/utils/request' + +// 获取区域列表 +export function getArea(params) { + return request({ + url: '/v1/areas', + method: 'get', + params: params + }) +} + +// 创建区域 +export function createArea(data) { + return request({ + url: '/v1/areas', + method: 'post', + data: data + }) +} + +// 删除区域 +export function deleteArea(id) { + return request({ + url: '/v1/areas/' + id, + method: 'delete', + }) +} + +// 修改区域 +export function updateArea(id, data) { + return request({ + url: '/v1/areas/' + id, + method: 'put', + data + }) +} diff --git a/src/api/energyConsumption.js b/src/api/energyConsumption.js new file mode 100644 index 0000000..e25951e --- /dev/null +++ b/src/api/energyConsumption.js @@ -0,0 +1,80 @@ +import request from "@/utils/request"; +export function waterMeterMonitor(data) { + return request({ + url: "/energyConsumptionManagement/waterMeterMonitor", + method: "post", + data, + }); +} +export function electricityMeterMonitor(data) { + return request({ + url: `/energyConsumptionManagement/electricityMeterMonitor`, + method: "post", + data, + }); +} +export function controlAllList(data) { + return request({ + url: `/device/control/allList`, + method: "post", + data, + }); +} +export function conditionalDeviceAndControlArea(query) { + return request({ + url: `/energyConsumptionManagement/conditionalDeviceAndControlArea`, + method: "get", + params: query, + }); +} +export function saveDeviceRule(data) { + return request({ + url: `/energyConsumptionManagement/saveDeviceRule`, + method: "post", + data, + }); +} +export function pageListDeviceRule(query) { + return request({ + url: `/energyConsumptionManagement/pageListDeviceRule`, + method: "get", + params: query, + }); +} +export function detailDeviceRule(ruleId, typeId) { + return request({ + url: `/energyConsumptionManagement/detailDeviceRule?deviceRuleId=${ruleId}&deviceTypeId=${typeId}`, + method: "get", + }); +} +export function deleteDeviceRuleById(id) { + return request({ + url: `/energyConsumptionManagement/deleteDeviceRuleById?deviceRuleId=${id}`, + method: "get", + }); +} +export function getElectricityUsageDetails(date, type) { + return request({ + url: `/energyConsumptionManagement/getElectricityUsageDetails?searchDate=${date}&searchType=${type}`, + method: "get", + }); +} +export function getWaterUsageDetails(date, type) { + return request({ + url: `/energyConsumptionManagement/getWaterUsageDetails?searchDate=${date}&searchType=${type}`, + method: "get", + }); +} +export function getEnergyConsumptionData(query = {}) { + return request({ + url: `/energyConsumptionManagement/getEnergyConsumptionData`, + method: "get", + params: query, + }); +} +export function getPowerLadderDetail(date) { + return request({ + url: `/energyConsumptionManagement/getPowerLadderDetail?date=${date}`, + method: "get", + }); +} diff --git a/src/api/environmental.js b/src/api/environmental.js new file mode 100644 index 0000000..d4289ff --- /dev/null +++ b/src/api/environmental.js @@ -0,0 +1,62 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-26 11:23:42 + * @Description: + */ +import request from "@/utils/request"; +export function deviceControlList(data) { + return request({ + url: "/device/control/list", + method: "post", + data, + }); +} + +export function deviceControlListOther(data) { + return request({ + url: "/device/control/listOther", + method: "post", + data, + }); +} +export function controlDevice(data) { + return request({ + url: `/ControlDevice`, + method: "post", + data, + baseUrl: process.env.VITE_VUE_APP_CONTROL_BASE_API, + }); +} + + +// 新增巡更管理接口 +export function addPatrol(data) { + return request({ + url: `/sysConfig/management/add`, + method: "post", + data, + }); +} +// 查询巡更管理接口 +export function getPatrolList(query) { + return request({ + url: `/sysConfig/management/list`, + method: "get", + params: query, + }); +} +// 修改巡更管理接口 +export function updatePatrol(data) { + return request({ + url: `/sysConfig/management/update`, + method: "post", + data, + }); +} +// 删除 +export function delPatrol(query) { + return request({ + url: `/sysConfig/management/remove/${query.id}`, + method: "get", + }); +} diff --git a/src/api/equipment.js b/src/api/equipment.js new file mode 100644 index 0000000..543260f --- /dev/null +++ b/src/api/equipment.js @@ -0,0 +1,350 @@ +import request from "@/utils/request"; +export function deviceList(query) { + return request({ + url: "/device/device/list", + method: "get", + params: query, + }); +} +export function deviceTypeList(query) { + return request({ + url: "/device/device/deviceTypeList", + method: "get", + params: query, + }); +} +export function addDevice(data) { + return request({ + url: "/device/device/add", + method: "post", + data, + }); +} +export function editDevice(data) { + return request({ + url: "/device/device/edit", + method: "post", + data, + }); +} +export function deleteDevice(query) { + return request({ + url: `/device/device/remove/${query}`, + method: "get", + // params: query, + }); +} +export function instructionList(query = {}) { + return request({ + url: `/device/instruction/list`, + method: "get", + params: query, + }); +} +export function addInstruction(data) { + return request({ + url: `/device/instruction/add`, + method: "post", + data, + }); +} +export function editInstruction(data) { + return request({ + url: `/device/instruction/edit`, + method: "post", + data, + }); +} +export function deleteInstruction(query) { + return request({ + url: `/device/instruction/remove/${query}`, + method: "get", + }); +} +export function deviceTypeModel(query) { + return request({ + url: `/device/typeModel/${query}`, + method: "get", + }); +} +export function deviceTypeModelList(query) { + return request({ + url: `/device/typeModel/list`, + method: "get", + params: query, + }); +} +export function deviceTypeModelAdd(data) { + return request({ + url: `/device/typeModel/add`, + method: "post", + data, + }); +} +export function deviceTypeModelEdit(data) { + return request({ + url: `/device/typeModel/edit`, + method: "post", + data, + }); +} +export function deviceTypeModelDelete(id) { + return request({ + url: `/device/typeModel/remove/${id}`, + method: "get", + }); +} +export function monitorList(query = {}) { + return request({ + url: `/device/management/list`, + method: "get", + params: query, + }); +} +// http协议外层编辑 +export function protocolHttpEdit(data) { + return request({ + url: `/device/protocolHttp/edit`, + method: "post", + data, + }); +} +// 其他协议外层编辑 +export function protocolOtherEdit(data) { + return request({ + url: `/device/protocolOther/edit`, + method: "post", + data, + }); +} +// http协议表格增删改查 +export function protocolHttpValueList(query) { + return request({ + url: `/device/protocolHttpValue/list`, + method: "get", + params: query, + }); +} +export function protocolHttpValueAdd(data) { + return request({ + url: `/device/protocolHttpValue/add`, + method: "post", + data, + }); +} +export function protocolHttpValueEdit(data) { + return request({ + url: `/device/protocolHttpValue/edit`, + method: "post", + data, + }); +} +export function protocolHttpValueDelete(id) { + return request({ + url: `/device/protocolHttpValue/remove/${id}`, + method: "get", + }); +} +// 其他协议表格增删改查 +export function protocolOtherValueList(query) { + return request({ + url: `/device/protocolOtherValue/list`, + method: "get", + params: query, + }); +} +export function protocolOtherValueAdd(data) { + return request({ + url: `/device/protocolOtherValue/add`, + method: "post", + data, + }); +} +export function protocolOtherValueEdit(data) { + return request({ + url: `/device/protocolOtherValue/edit`, + method: "post", + data, + }); +} +export function protocolOtherValueDelete(id) { + return request({ + url: `/device/protocolOtherValue/remove/${id}`, + method: "get", + }); +} +export function minitorAdd(data) { + return request({ + url: "/device/management/add", + method: "post", + data, + }); +} +export function minitorEdit(data) { + return request({ + url: "/device/management/edit", + method: "post", + data, + }); +} +export function minitorDelete(id) { + return request({ + url: `/device/management/remove/${id}`, + method: "get", + }); +} + +export function ruleAdd(data) { + return request({ + url: "/management/rule/add", + method: "post", + data, + }); +} + +export function ruleList(query) { + return request({ + url: `/management/rule/list`, + method: "get", + params: query, + }); +} + +export function ruleDel(data) { + return request({ + url: "/management/rule/remove/"+data, + method: "get", + }); +} + +export function rulegroupAdd(data) { + return request({ + url: "/management/rulegroup/add", + method: "post", + data, + }); +} + +export function rulegroupList(query) { + return request({ + url: `/management/rulegroup/list`, + method: "get", + params: query, + }); +} + +export function rulegroupDel(data) { + return request({ + url: "/management/rulegroup/remove/"+data, + method: "get", + }); +} + +export function rulegroupUpdate(data) { + return request({ + url: "/management/rulegroup/update", + method: "post", + data, + }); +} + +export function ruleQuerybyId(data) { + return request({ + url: "/management/rule/"+data, + method: "get", + }); +} + +export function rulegroupQuerybyId(data) { + return request({ + url: "/management/rulegroup/"+data, + method: "get", + }); +} + +export function ruleUpdate(data) { + return request({ + url: "/management/rule/update", + method: "post", + data, + }); +} + +export function getServerData(query) { + return request({ + url: `/GetData/`, + method: "get", + params: query, + baseUrl: process.env.VITE_VUE_APP_SERVER_BASE_API, + }); +} + +export function setServerData(query) { + return request({ + url: `/ControlServer/`, + method: "get", + params: query, + baseUrl: process.env.VITE_VUE_APP_SERVER_BASE_API, + }); +} + +export function getSysConfig(query) { + return request({ + url: `/sysConfig/config/1`, + method: "get", + params: query, + }); +} + +export function sysConfigUpdate(data) { + return request({ + url: "/sysConfig/config/update", + method: "post", + data, + }); +} + +export function deviceAdd(data) { + return request({ + url: "/device/day/add", + method: "post", + data, + }); +} + +export function devicedayList(query) { + return request({ + url: `/device/day/list`, + method: "get", + params: query, + }); +} + +export function deviceDayDel(data) { + return request({ + url: "/device/day/remove/"+data, + method: "get", + }); +} + +export function deviceDayUpdate(data) { + return request({ + url: "/device/day/update", + method: "post", + data, + }); +} +export function deviceGetYear(query) { + return request({ + url: `/device/day/getYear`, + method: "get", + params: query, + }); +} +export function getVacationDayByYear(query) { + return request({ + url: `/device/day/getVacationDayByYear`, + method: "get", + params: query, + }); +} diff --git a/src/api/index.js b/src/api/index.js new file mode 100644 index 0000000..7cb463a --- /dev/null +++ b/src/api/index.js @@ -0,0 +1,15 @@ +import request from "@/utils/request"; +export function deviceTypeListCount(query) { + return request({ + url: "/device/device/deviceTypeListCount", + method: "get", + params: query, + }); +} +export function getEnergyUseTrend(query = {}) { + return request({ + url: "/energyConsumptionManagement/getEnergyUseTrend", + method: "get", + params: query, + }); +} diff --git a/src/api/knowledge/content.js b/src/api/knowledge/content.js new file mode 100644 index 0000000..c64b3cc --- /dev/null +++ b/src/api/knowledge/content.js @@ -0,0 +1,52 @@ +import request from "@/utils/request"; + +//知识库内容新增 +export function knowledgeAdd(query) { + return request({ + url: "/device/knowledge/add", + method: "post", + data: query, + }); +} +//知识库查询 +export function knowledgeList(query) { + return request({ + url: "/device/knowledge/list", + method: "get", + params: query, + }); +} + +//知识库修改 +export function knowledgeUpdate(query) { + return request({ + url: "/device/knowledge/update", + method: "post", + data: query, + }); +} + +//知识库删除 +export function knowledgeRemove(query) { + return request({ + url: "/device/knowledge/remove/" + query, + method: "get", + params: query, + }); +} + +//知识库单条查询 +export function knowledgeById(query) { + return request({ + url: "/device/knowledge/" + query, + method: "get", + }); +} +//知识库类型查询 +export function knowledgeTypeList(query) { + return request({ + url: "/device/knowledgeType/list", + method: "get", + params: query, + }); +} \ No newline at end of file diff --git a/src/api/knowledge/type.js b/src/api/knowledge/type.js new file mode 100644 index 0000000..22e10cc --- /dev/null +++ b/src/api/knowledge/type.js @@ -0,0 +1,36 @@ +import request from "@/utils/request"; + +//知识库类型新增 +export function knowledgeTypeAdd(query) { + return request({ + url: "/device/knowledgeType/add", + method: "post", + data: query, + }); +} +//知识库类型查询 +export function knowledgeTypeList(query) { + return request({ + url: "/device/knowledgeType/list", + method: "get", + params: query, + }); +} + +//知识库类型修改 +export function knowledgeTypeUpdate(query) { + return request({ + url: "/device/knowledgeType/update", + method: "post", + data: query, + }); +} + +//知识库类型删除 +export function knowledgeTypeRemove(query) { + return request({ + url: "/device/knowledgeType/remove/" + query, + method: "get", + params: query, + }); +} \ No newline at end of file diff --git a/src/api/login.js b/src/api/login.js new file mode 100644 index 0000000..be8015c --- /dev/null +++ b/src/api/login.js @@ -0,0 +1,65 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-26 11:23:42 + * @Description: + */ +import request from '@/utils/request' + +// 登录方法 +export function login(username, password, code, uuid) { + const data = { + username, + password, + code, + uuid + } + return request({ + url: '/v1/auth/login', + headers: { + isToken: false, + repeatSubmit: false + }, + method: 'post', + data: data + }) +} + +// 退出方法 +export function logout() { + return request({ + url: '/v1/auth/logout', + method: 'post' + }) +} + +// 注册方法 +export function register(data) { + return request({ + url: '/register', + headers: { + isToken: false + }, + method: 'post', + data: data + }) +} + +// 获取用户详细信息 +export function getInfo() { + return request({ + url: '/getInfo', + method: 'get' + }) +} + +// 获取验证码 +export function getCodeImg() { + return request({ + url: '/captchaImage', + headers: { + isToken: false + }, + method: 'get', + timeout: 20000 + }) +} \ No newline at end of file diff --git a/src/api/menu.js b/src/api/menu.js new file mode 100644 index 0000000..6e52e6e --- /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..e1f2c87 --- /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..b33ad3d --- /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..654bbae --- /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..c49a40e --- /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' + }) +} + +// 解锁用户登录状态 +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..288ebe0 --- /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..6e881df --- /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..cac7791 --- /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/area.js b/src/api/system/area.js new file mode 100644 index 0000000..32049c0 --- /dev/null +++ b/src/api/system/area.js @@ -0,0 +1,36 @@ +import request from "@/utils/request"; +export function managementList(query) { + return request({ + url: "/management/management/list", + method: "get", + params: query, + }); +} +export function managementListAll(query) { + return request({ + url: "/management/management/listAll", + method: "get", + params: query, + }); +} +export function managementAdd(data) { + return request({ + url: "/management/management/add", + method: "post", + data: data, + }); +} +export function managementDelete(query) { + return request({ + url: `/management/management/remove/${query}`, + method: "get", + // params: query, + }); +} +export function managementEdit(data) { + return request({ + url: `/management/management/edit`, + method: "post", + data, + }); +} diff --git a/src/api/system/config.js b/src/api/system/config.js new file mode 100644 index 0000000..7858c69 --- /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..9ca6966 --- /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..2a6e481 --- /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..526977d --- /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/manual.js b/src/api/system/manual.js new file mode 100644 index 0000000..97739da --- /dev/null +++ b/src/api/system/manual.js @@ -0,0 +1,31 @@ +import request from '@/utils/request' + +// 获取操作手册 +export function getManual() { + return request({ + url: '/system/manual', + method: 'get' + }) +} + +// 上传操作手册 +export function uploadManual(data) { + return request({ + url: '/system/manual/upload', + method: 'post', + data: data, + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} + +// 删除操作手册 +export function deleteManual(id) { + return request({ + url: '/system/manual/' + id, + method: 'delete' + }) +} + + diff --git a/src/api/system/menu.js b/src/api/system/menu.js new file mode 100644 index 0000000..97258ee --- /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..737fc16 --- /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..8faa266 --- /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..528cd18 --- /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..cdddda5 --- /dev/null +++ b/src/api/system/user.js @@ -0,0 +1,139 @@ +import request from '@/utils/request' +import { parseStrEmpty } from "@/utils/ruoyi"; + +// 查询用户列表 +export function listUser(query) { + return request({ + url: '/v1/users', + method: 'get', + params: query + }) +} + +// 查询用户详细 +export function getUser(userId) { + return request({ + url: '/system/user/' + parseStrEmpty(userId), + method: 'get' + }) +} + +// 新增用户 +export function addUser(data) { + return request({ + url: '/v1/users', + method: 'post', + data: data + }) +} + +// 修改用户 +export function updateUser(userId, data) { + console.log(userId, data); + + return request({ + url: '/v1/users/' + userId, + method: 'put', + data: data + }) +} + +// 删除用户 +export function delUser(userId) { + return request({ + url: '/v1/users/' + userId, + method: 'delete' + }) +} + +// 用户密码重置 +export function resetUserPwd(username, old_password, new_password) { + const data = { + username, + old_password, + new_password + } + return request({ + url: '/v1/users/change-password', + method: 'put', + data: data + }) +} + +// 用户状态修改 +export function changeUserStatus(userId, status) { + const data = { + userId, + status + } + return request({ + url: '/system/user/changeStatus', + method: 'put', + data: data + }) +} + +// 查询用户个人信息 +export function getUserProfile() { + return request({ + url: '/system/user/profile', + method: 'get' + }) +} + +// 修改用户个人信息 +export function updateUserProfile(data) { + return request({ + url: '/system/user/profile', + method: 'put', + data: data + }) +} + +// 用户密码重置 +export function updateUserPwd(oldPassword, newPassword) { + const data = { + oldPassword, + newPassword + } + return request({ + url: '/system/user/profile/updatePwd', + method: 'put', + params: data + }) +} + +// 用户头像上传 +export function uploadAvatar(data) { + return request({ + url: '/system/user/profile/avatar', + method: 'post', + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + data: data + }) +} + +// 查询授权角色 +export function getAuthRole(userId) { + return request({ + url: '/system/user/authRole/' + userId, + method: 'get' + }) +} + +// 保存授权角色 +export function updateAuthRole(data) { + return request({ + url: '/system/user/authRole', + method: 'put', + params: data + }) +} + +// 查询部门下拉树结构 +export function deptTreeSelect() { + return request({ + url: '/system/user/deptTree', + method: 'get' + }) +} diff --git a/src/api/tool/gen.js b/src/api/tool/gen.js new file mode 100644 index 0000000..5728980 --- /dev/null +++ b/src/api/tool/gen.js @@ -0,0 +1,85 @@ +import request from '@/utils/request' + +// 查询生成表数据 +export function listTable(query) { + return request({ + url: '/tool/gen/list', + method: 'get', + params: query + }) +} +// 查询db数据库列表 +export function listDbTable(query) { + return request({ + url: '/tool/gen/db/list', + method: 'get', + params: query + }) +} + +// 查询表详细信息 +export function getGenTable(tableId) { + return request({ + url: '/tool/gen/' + tableId, + method: 'get' + }) +} + +// 修改代码生成信息 +export function updateGenTable(data) { + return request({ + url: '/tool/gen', + method: 'put', + data: data + }) +} + +// 导入表 +export function importTable(data) { + return request({ + url: '/tool/gen/importTable', + method: 'post', + params: data + }) +} + +// 创建表 +export function createTable(data) { + return request({ + url: '/tool/gen/createTable', + method: 'post', + params: data + }) +} + +// 预览生成代码 +export function previewTable(tableId) { + return request({ + url: '/tool/gen/preview/' + tableId, + method: 'get' + }) +} + +// 删除表数据 +export function delTable(tableId) { + return request({ + url: '/tool/gen/' + tableId, + method: 'delete' + }) +} + +// 生成代码(自定义路径) +export function genCode(tableName) { + return request({ + url: '/tool/gen/genCode/' + tableName, + method: 'get' + }) +} + +// 同步数据库 +export function synchDb(tableName) { + return request({ + url: '/tool/gen/synchDb/' + tableName, + method: 'get' + }) +} diff --git a/src/assets/401_images/401.gif b/src/assets/401_images/401.gif new file mode 100644 index 0000000..cd6e0d9 Binary files /dev/null and b/src/assets/401_images/401.gif differ diff --git a/src/assets/404_images/404.png b/src/assets/404_images/404.png new file mode 100644 index 0000000..3d8e230 Binary files /dev/null and b/src/assets/404_images/404.png 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 Binary files /dev/null and b/src/assets/404_images/404_cloud.png differ diff --git a/src/assets/beij/COPa.png b/src/assets/beij/COPa.png new file mode 100644 index 0000000..b176e43 Binary files /dev/null and b/src/assets/beij/COPa.png differ diff --git a/src/assets/beij/COPa1.png b/src/assets/beij/COPa1.png new file mode 100644 index 0000000..aedcc3c Binary files /dev/null and b/src/assets/beij/COPa1.png differ diff --git a/src/assets/beij/COPa4.7.png b/src/assets/beij/COPa4.7.png new file mode 100644 index 0000000..849cc50 Binary files /dev/null and b/src/assets/beij/COPa4.7.png differ diff --git a/src/assets/beij/COPa422.png b/src/assets/beij/COPa422.png new file mode 100644 index 0000000..070b5aa Binary files /dev/null and b/src/assets/beij/COPa422.png differ diff --git a/src/assets/beij/COPaItem.png b/src/assets/beij/COPaItem.png new file mode 100644 index 0000000..afcf866 Binary files /dev/null and b/src/assets/beij/COPaItem.png differ diff --git a/src/assets/beij/Rectangle 2060(1).png b/src/assets/beij/Rectangle 2060(1).png new file mode 100644 index 0000000..70fb008 Binary files /dev/null and b/src/assets/beij/Rectangle 2060(1).png differ diff --git a/src/assets/beij/Rectangle 2060.png b/src/assets/beij/Rectangle 2060.png new file mode 100644 index 0000000..8b862c1 Binary files /dev/null and b/src/assets/beij/Rectangle 2060.png differ diff --git a/src/assets/beij/VRV.png b/src/assets/beij/VRV.png new file mode 100644 index 0000000..5e72047 Binary files /dev/null and b/src/assets/beij/VRV.png differ diff --git a/src/assets/beij/VRV1.png b/src/assets/beij/VRV1.png new file mode 100644 index 0000000..f59581c Binary files /dev/null and b/src/assets/beij/VRV1.png differ diff --git a/src/assets/beij/baoj.png b/src/assets/beij/baoj.png new file mode 100644 index 0000000..ec268c4 Binary files /dev/null and b/src/assets/beij/baoj.png differ diff --git a/src/assets/beij/baojh1.png b/src/assets/beij/baojh1.png new file mode 100644 index 0000000..64f7458 Binary files /dev/null and b/src/assets/beij/baojh1.png differ diff --git a/src/assets/beij/bjTit.png b/src/assets/beij/bjTit.png new file mode 100644 index 0000000..13a3fd0 Binary files /dev/null and b/src/assets/beij/bjTit.png differ diff --git a/src/assets/beij/bjTit1.png b/src/assets/beij/bjTit1.png new file mode 100644 index 0000000..13a3fd0 Binary files /dev/null and b/src/assets/beij/bjTit1.png differ diff --git a/src/assets/beij/box.png b/src/assets/beij/box.png new file mode 100644 index 0000000..26e976f Binary files /dev/null and b/src/assets/beij/box.png differ diff --git a/src/assets/beij/close.png b/src/assets/beij/close.png new file mode 100644 index 0000000..90bf77f Binary files /dev/null and b/src/assets/beij/close.png differ diff --git a/src/assets/beij/closeBox.png b/src/assets/beij/closeBox.png new file mode 100644 index 0000000..1ef5e94 Binary files /dev/null and b/src/assets/beij/closeBox.png differ diff --git a/src/assets/beij/dangnian.png b/src/assets/beij/dangnian.png new file mode 100644 index 0000000..13373b6 Binary files /dev/null and b/src/assets/beij/dangnian.png differ diff --git a/src/assets/beij/dangri.png b/src/assets/beij/dangri.png new file mode 100644 index 0000000..93eab74 Binary files /dev/null and b/src/assets/beij/dangri.png differ diff --git a/src/assets/beij/dangyue.png b/src/assets/beij/dangyue.png new file mode 100644 index 0000000..b28eae0 Binary files /dev/null and b/src/assets/beij/dangyue.png differ diff --git a/src/assets/beij/day-h.png b/src/assets/beij/day-h.png new file mode 100644 index 0000000..1b48759 Binary files /dev/null and b/src/assets/beij/day-h.png differ diff --git a/src/assets/beij/day.png b/src/assets/beij/day.png new file mode 100644 index 0000000..e4e8a91 Binary files /dev/null and b/src/assets/beij/day.png differ diff --git a/src/assets/beij/dayno.png b/src/assets/beij/dayno.png new file mode 100644 index 0000000..9771bb1 Binary files /dev/null and b/src/assets/beij/dayno.png differ diff --git a/src/assets/beij/dayxz.png b/src/assets/beij/dayxz.png new file mode 100644 index 0000000..06d515e Binary files /dev/null and b/src/assets/beij/dayxz.png differ diff --git a/src/assets/beij/dlItem.png b/src/assets/beij/dlItem.png new file mode 100644 index 0000000..d880e51 Binary files /dev/null and b/src/assets/beij/dlItem.png differ diff --git a/src/assets/beij/dnhb.png b/src/assets/beij/dnhb.png new file mode 100644 index 0000000..16018e4 Binary files /dev/null and b/src/assets/beij/dnhb.png differ diff --git a/src/assets/beij/dnhb1.png b/src/assets/beij/dnhb1.png new file mode 100644 index 0000000..56a48bf Binary files /dev/null and b/src/assets/beij/dnhb1.png differ diff --git a/src/assets/beij/dnhbnrk.png b/src/assets/beij/dnhbnrk.png new file mode 100644 index 0000000..c7692e2 Binary files /dev/null and b/src/assets/beij/dnhbnrk.png differ diff --git a/src/assets/beij/fdtjfx.png b/src/assets/beij/fdtjfx.png new file mode 100644 index 0000000..c613e2f Binary files /dev/null and b/src/assets/beij/fdtjfx.png differ diff --git a/src/assets/beij/gf-bg.jpg b/src/assets/beij/gf-bg.jpg new file mode 100644 index 0000000..e62465c Binary files /dev/null and b/src/assets/beij/gf-bg.jpg differ diff --git a/src/assets/beij/gf-bg1.jpg b/src/assets/beij/gf-bg1.jpg new file mode 100644 index 0000000..8751541 Binary files /dev/null and b/src/assets/beij/gf-bg1.jpg differ diff --git a/src/assets/beij/gltjfx.png b/src/assets/beij/gltjfx.png new file mode 100644 index 0000000..7f71376 Binary files /dev/null and b/src/assets/beij/gltjfx.png differ diff --git a/src/assets/beij/goSys.png b/src/assets/beij/goSys.png new file mode 100644 index 0000000..80d6209 Binary files /dev/null and b/src/assets/beij/goSys.png differ diff --git a/src/assets/beij/gonglv1.png b/src/assets/beij/gonglv1.png new file mode 100644 index 0000000..c90c195 Binary files /dev/null and b/src/assets/beij/gonglv1.png differ diff --git a/src/assets/beij/gonglv2.png b/src/assets/beij/gonglv2.png new file mode 100644 index 0000000..4cc9284 Binary files /dev/null and b/src/assets/beij/gonglv2.png differ diff --git a/src/assets/beij/guangfu-t.png b/src/assets/beij/guangfu-t.png new file mode 100644 index 0000000..ed38716 Binary files /dev/null and b/src/assets/beij/guangfu-t.png differ diff --git a/src/assets/beij/hjjcsj.png b/src/assets/beij/hjjcsj.png new file mode 100644 index 0000000..76f44f8 Binary files /dev/null and b/src/assets/beij/hjjcsj.png differ diff --git a/src/assets/beij/jiank1.png b/src/assets/beij/jiank1.png new file mode 100644 index 0000000..f661cca Binary files /dev/null and b/src/assets/beij/jiank1.png differ diff --git a/src/assets/beij/jiankTit.png b/src/assets/beij/jiankTit.png new file mode 100644 index 0000000..14934a8 Binary files /dev/null and b/src/assets/beij/jiankTit.png differ diff --git a/src/assets/beij/jiankbox.png b/src/assets/beij/jiankbox.png new file mode 100644 index 0000000..c9e073a Binary files /dev/null and b/src/assets/beij/jiankbox.png differ diff --git a/src/assets/beij/left.png b/src/assets/beij/left.png new file mode 100644 index 0000000..5f1ca62 Binary files /dev/null and b/src/assets/beij/left.png differ diff --git a/src/assets/beij/left1.png b/src/assets/beij/left1.png new file mode 100644 index 0000000..f2b543a Binary files /dev/null and b/src/assets/beij/left1.png differ diff --git a/src/assets/beij/left11.png b/src/assets/beij/left11.png new file mode 100644 index 0000000..c674513 Binary files /dev/null and b/src/assets/beij/left11.png differ diff --git a/src/assets/beij/left12.png b/src/assets/beij/left12.png new file mode 100644 index 0000000..b5436c1 Binary files /dev/null and b/src/assets/beij/left12.png differ diff --git a/src/assets/beij/left2.png b/src/assets/beij/left2.png new file mode 100644 index 0000000..d505db2 Binary files /dev/null and b/src/assets/beij/left2.png differ diff --git a/src/assets/beij/left3.png b/src/assets/beij/left3.png new file mode 100644 index 0000000..ee55533 Binary files /dev/null and b/src/assets/beij/left3.png differ diff --git a/src/assets/beij/leftdis.png b/src/assets/beij/leftdis.png new file mode 100644 index 0000000..5e9bde5 Binary files /dev/null and b/src/assets/beij/leftdis.png differ diff --git a/src/assets/beij/ljcl.png b/src/assets/beij/ljcl.png new file mode 100644 index 0000000..6a05164 Binary files /dev/null and b/src/assets/beij/ljcl.png differ diff --git a/src/assets/beij/ljll.png b/src/assets/beij/ljll.png new file mode 100644 index 0000000..f1bd227 Binary files /dev/null and b/src/assets/beij/ljll.png differ diff --git a/src/assets/beij/ljnl.png b/src/assets/beij/ljnl.png new file mode 100644 index 0000000..85ce7b6 Binary files /dev/null and b/src/assets/beij/ljnl.png differ diff --git a/src/assets/beij/ljnl4.7.png b/src/assets/beij/ljnl4.7.png new file mode 100644 index 0000000..bd45d77 Binary files /dev/null and b/src/assets/beij/ljnl4.7.png differ diff --git a/src/assets/beij/ljnl422.png b/src/assets/beij/ljnl422.png new file mode 100644 index 0000000..c701c59 Binary files /dev/null and b/src/assets/beij/ljnl422.png differ diff --git a/src/assets/beij/ljrn.png b/src/assets/beij/ljrn.png new file mode 100644 index 0000000..51088f9 Binary files /dev/null and b/src/assets/beij/ljrn.png differ diff --git a/src/assets/beij/ljyd.png b/src/assets/beij/ljyd.png new file mode 100644 index 0000000..b0b303f Binary files /dev/null and b/src/assets/beij/ljyd.png differ diff --git a/src/assets/beij/ljyd111.png b/src/assets/beij/ljyd111.png new file mode 100644 index 0000000..1702764 Binary files /dev/null and b/src/assets/beij/ljyd111.png differ diff --git a/src/assets/beij/ljydl.png b/src/assets/beij/ljydl.png new file mode 100644 index 0000000..55e316a Binary files /dev/null and b/src/assets/beij/ljydl.png differ diff --git a/src/assets/beij/ljydl2.png b/src/assets/beij/ljydl2.png new file mode 100644 index 0000000..ea2dde2 Binary files /dev/null and b/src/assets/beij/ljydl2.png differ diff --git a/src/assets/beij/ljydl4.22.png b/src/assets/beij/ljydl4.22.png new file mode 100644 index 0000000..2e9fe92 Binary files /dev/null and b/src/assets/beij/ljydl4.22.png differ diff --git a/src/assets/beij/ljydl4.7.png b/src/assets/beij/ljydl4.7.png new file mode 100644 index 0000000..56a186d Binary files /dev/null and b/src/assets/beij/ljydl4.7.png differ diff --git a/src/assets/beij/ljys.png b/src/assets/beij/ljys.png new file mode 100644 index 0000000..8bea14e Binary files /dev/null and b/src/assets/beij/ljys.png differ diff --git a/src/assets/beij/ljzll.png b/src/assets/beij/ljzll.png new file mode 100644 index 0000000..80814a8 Binary files /dev/null and b/src/assets/beij/ljzll.png differ diff --git a/src/assets/beij/ljzll2.png b/src/assets/beij/ljzll2.png new file mode 100644 index 0000000..061a1f1 Binary files /dev/null and b/src/assets/beij/ljzll2.png differ diff --git a/src/assets/beij/ljzrl.png b/src/assets/beij/ljzrl.png new file mode 100644 index 0000000..21dbd64 Binary files /dev/null and b/src/assets/beij/ljzrl.png differ diff --git a/src/assets/beij/ljzrl2.png b/src/assets/beij/ljzrl2.png new file mode 100644 index 0000000..b704fcc Binary files /dev/null and b/src/assets/beij/ljzrl2.png differ diff --git a/src/assets/beij/load.png b/src/assets/beij/load.png new file mode 100644 index 0000000..b51ec82 Binary files /dev/null and b/src/assets/beij/load.png differ diff --git a/src/assets/beij/load1.jpg b/src/assets/beij/load1.jpg new file mode 100644 index 0000000..0848d4b Binary files /dev/null and b/src/assets/beij/load1.jpg differ diff --git a/src/assets/beij/load11.png b/src/assets/beij/load11.png new file mode 100644 index 0000000..f1152a3 Binary files /dev/null and b/src/assets/beij/load11.png differ diff --git a/src/assets/beij/loginBox.png b/src/assets/beij/loginBox.png new file mode 100644 index 0000000..b83b36d Binary files /dev/null and b/src/assets/beij/loginBox.png differ diff --git a/src/assets/beij/loginBoxH.png b/src/assets/beij/loginBoxH.png new file mode 100644 index 0000000..92f7401 Binary files /dev/null and b/src/assets/beij/loginBoxH.png differ diff --git a/src/assets/beij/logo (2).png b/src/assets/beij/logo (2).png new file mode 100644 index 0000000..4b683d8 Binary files /dev/null and b/src/assets/beij/logo (2).png differ diff --git a/src/assets/beij/logo.png b/src/assets/beij/logo.png new file mode 100644 index 0000000..264972c Binary files /dev/null and b/src/assets/beij/logo.png differ diff --git a/src/assets/beij/month-h.png b/src/assets/beij/month-h.png new file mode 100644 index 0000000..48cef77 Binary files /dev/null and b/src/assets/beij/month-h.png differ diff --git a/src/assets/beij/month.png b/src/assets/beij/month.png new file mode 100644 index 0000000..be4ccb0 Binary files /dev/null and b/src/assets/beij/month.png differ diff --git a/src/assets/beij/monthno.png b/src/assets/beij/monthno.png new file mode 100644 index 0000000..15ea374 Binary files /dev/null and b/src/assets/beij/monthno.png differ diff --git a/src/assets/beij/monthxz.png b/src/assets/beij/monthxz.png new file mode 100644 index 0000000..4763104 Binary files /dev/null and b/src/assets/beij/monthxz.png differ diff --git a/src/assets/beij/nengliangItem.png b/src/assets/beij/nengliangItem.png new file mode 100644 index 0000000..a72cc87 Binary files /dev/null and b/src/assets/beij/nengliangItem.png differ diff --git a/src/assets/beij/nhsj.png b/src/assets/beij/nhsj.png new file mode 100644 index 0000000..7b05249 Binary files /dev/null and b/src/assets/beij/nhsj.png differ diff --git a/src/assets/beij/nrk.png b/src/assets/beij/nrk.png new file mode 100644 index 0000000..9b692ad Binary files /dev/null and b/src/assets/beij/nrk.png differ diff --git a/src/assets/beij/pop1.png b/src/assets/beij/pop1.png new file mode 100644 index 0000000..e220b81 Binary files /dev/null and b/src/assets/beij/pop1.png differ diff --git a/src/assets/beij/pop11.png b/src/assets/beij/pop11.png new file mode 100644 index 0000000..b3f05fa Binary files /dev/null and b/src/assets/beij/pop11.png differ diff --git a/src/assets/beij/pop2.png b/src/assets/beij/pop2.png new file mode 100644 index 0000000..a0374a6 Binary files /dev/null and b/src/assets/beij/pop2.png differ diff --git a/src/assets/beij/pop22.png b/src/assets/beij/pop22.png new file mode 100644 index 0000000..ab85870 Binary files /dev/null and b/src/assets/beij/pop22.png differ diff --git a/src/assets/beij/quxiao.png b/src/assets/beij/quxiao.png new file mode 100644 index 0000000..0968094 Binary files /dev/null and b/src/assets/beij/quxiao.png differ diff --git a/src/assets/beij/right.png b/src/assets/beij/right.png new file mode 100644 index 0000000..737f008 Binary files /dev/null and b/src/assets/beij/right.png differ diff --git a/src/assets/beij/rightdis.png b/src/assets/beij/rightdis.png new file mode 100644 index 0000000..db76567 Binary files /dev/null and b/src/assets/beij/rightdis.png differ diff --git a/src/assets/beij/rq.png b/src/assets/beij/rq.png new file mode 100644 index 0000000..9625a0b Binary files /dev/null and b/src/assets/beij/rq.png differ diff --git a/src/assets/beij/shb.png b/src/assets/beij/shb.png new file mode 100644 index 0000000..6a5d0e6 Binary files /dev/null and b/src/assets/beij/shb.png differ diff --git a/src/assets/beij/shebei1.png b/src/assets/beij/shebei1.png new file mode 100644 index 0000000..5646cc9 Binary files /dev/null and b/src/assets/beij/shebei1.png differ diff --git a/src/assets/beij/shebei2.png b/src/assets/beij/shebei2.png new file mode 100644 index 0000000..ee49785 Binary files /dev/null and b/src/assets/beij/shebei2.png differ diff --git a/src/assets/beij/shebei3.png b/src/assets/beij/shebei3.png new file mode 100644 index 0000000..56a7e73 Binary files /dev/null and b/src/assets/beij/shebei3.png differ diff --git a/src/assets/beij/shgx-t.png b/src/assets/beij/shgx-t.png new file mode 100644 index 0000000..5f09af7 Binary files /dev/null and b/src/assets/beij/shgx-t.png differ diff --git a/src/assets/beij/sure.png b/src/assets/beij/sure.png new file mode 100644 index 0000000..cb808ab Binary files /dev/null and b/src/assets/beij/sure.png differ diff --git a/src/assets/beij/sytjfx.png b/src/assets/beij/sytjfx.png new file mode 100644 index 0000000..c18bb9a Binary files /dev/null and b/src/assets/beij/sytjfx.png differ diff --git a/src/assets/beij/tit.png b/src/assets/beij/tit.png new file mode 100644 index 0000000..55d6bde Binary files /dev/null and b/src/assets/beij/tit.png differ diff --git a/src/assets/beij/tit1.png b/src/assets/beij/tit1.png new file mode 100644 index 0000000..495d33c Binary files /dev/null and b/src/assets/beij/tit1.png differ diff --git a/src/assets/beij/tit2.png b/src/assets/beij/tit2.png new file mode 100644 index 0000000..9a394d1 Binary files /dev/null and b/src/assets/beij/tit2.png differ diff --git a/src/assets/beij/titLeft.png b/src/assets/beij/titLeft.png new file mode 100644 index 0000000..956290d Binary files /dev/null and b/src/assets/beij/titLeft.png differ diff --git a/src/assets/beij/titMid.png b/src/assets/beij/titMid.png new file mode 100644 index 0000000..7274c8e Binary files /dev/null and b/src/assets/beij/titMid.png differ diff --git a/src/assets/beij/titTable.png b/src/assets/beij/titTable.png new file mode 100644 index 0000000..9f1512c Binary files /dev/null and b/src/assets/beij/titTable.png differ diff --git a/src/assets/beij/title (2).png b/src/assets/beij/title (2).png new file mode 100644 index 0000000..3854a04 Binary files /dev/null and b/src/assets/beij/title (2).png differ diff --git a/src/assets/beij/title (2)1.png b/src/assets/beij/title (2)1.png new file mode 100644 index 0000000..9852205 Binary files /dev/null and b/src/assets/beij/title (2)1.png differ diff --git a/src/assets/beij/title.png b/src/assets/beij/title.png new file mode 100644 index 0000000..0c7e5df Binary files /dev/null and b/src/assets/beij/title.png differ diff --git a/src/assets/beij/title3.png b/src/assets/beij/title3.png new file mode 100644 index 0000000..8b02604 Binary files /dev/null and b/src/assets/beij/title3.png differ diff --git a/src/assets/beij/title4.png b/src/assets/beij/title4.png new file mode 100644 index 0000000..42c9b0c Binary files /dev/null and b/src/assets/beij/title4.png differ diff --git a/src/assets/beij/title5.png b/src/assets/beij/title5.png new file mode 100644 index 0000000..239163a Binary files /dev/null and b/src/assets/beij/title5.png differ diff --git a/src/assets/beij/title7.png b/src/assets/beij/title7.png new file mode 100644 index 0000000..332d49b Binary files /dev/null and b/src/assets/beij/title7.png differ diff --git a/src/assets/beij/titletable2.png b/src/assets/beij/titletable2.png new file mode 100644 index 0000000..87ce40a Binary files /dev/null and b/src/assets/beij/titletable2.png differ diff --git a/src/assets/beij/titright.png b/src/assets/beij/titright.png new file mode 100644 index 0000000..bd33f27 Binary files /dev/null and b/src/assets/beij/titright.png differ diff --git a/src/assets/beij/top.png b/src/assets/beij/top.png new file mode 100644 index 0000000..dbb1e9b Binary files /dev/null and b/src/assets/beij/top.png differ diff --git a/src/assets/beij/top1.png b/src/assets/beij/top1.png new file mode 100644 index 0000000..1cd512a Binary files /dev/null and b/src/assets/beij/top1.png differ diff --git a/src/assets/beij/top2.png b/src/assets/beij/top2.png new file mode 100644 index 0000000..20c4e4a Binary files /dev/null and b/src/assets/beij/top2.png differ diff --git a/src/assets/beij/top3.png b/src/assets/beij/top3.png new file mode 100644 index 0000000..c401a8a Binary files /dev/null and b/src/assets/beij/top3.png differ diff --git a/src/assets/beij/videoimg.png b/src/assets/beij/videoimg.png new file mode 100644 index 0000000..7112a1b Binary files /dev/null and b/src/assets/beij/videoimg.png differ diff --git a/src/assets/beij/week-h.png b/src/assets/beij/week-h.png new file mode 100644 index 0000000..3368dcc Binary files /dev/null and b/src/assets/beij/week-h.png differ diff --git a/src/assets/beij/week.png b/src/assets/beij/week.png new file mode 100644 index 0000000..6c83403 Binary files /dev/null and b/src/assets/beij/week.png differ diff --git a/src/assets/beij/xlk.png b/src/assets/beij/xlk.png new file mode 100644 index 0000000..e1ff34f Binary files /dev/null and b/src/assets/beij/xlk.png differ diff --git a/src/assets/beij/year-h.png b/src/assets/beij/year-h.png new file mode 100644 index 0000000..bf99ff4 Binary files /dev/null and b/src/assets/beij/year-h.png differ diff --git a/src/assets/beij/year.png b/src/assets/beij/year.png new file mode 100644 index 0000000..74e0d61 Binary files /dev/null and b/src/assets/beij/year.png differ diff --git a/src/assets/beij/yearno.png b/src/assets/beij/yearno.png new file mode 100644 index 0000000..e20bfff Binary files /dev/null and b/src/assets/beij/yearno.png differ diff --git a/src/assets/beij/yearxz.png b/src/assets/beij/yearxz.png new file mode 100644 index 0000000..e6d1a54 Binary files /dev/null and b/src/assets/beij/yearxz.png differ diff --git a/src/assets/beij/yjzdl.png b/src/assets/beij/yjzdl.png new file mode 100644 index 0000000..2df851c Binary files /dev/null and b/src/assets/beij/yjzdl.png differ diff --git a/src/assets/beij/yjztl.png b/src/assets/beij/yjztl.png new file mode 100644 index 0000000..d94d809 Binary files /dev/null and b/src/assets/beij/yjztl.png differ diff --git a/src/assets/beij/yjztl2.png b/src/assets/beij/yjztl2.png new file mode 100644 index 0000000..c5a18d3 Binary files /dev/null and b/src/assets/beij/yjztl2.png differ diff --git a/src/assets/beij/ysl.png b/src/assets/beij/ysl.png new file mode 100644 index 0000000..f3cd95b Binary files /dev/null and b/src/assets/beij/ysl.png differ diff --git a/src/assets/beij/zhongyang.png b/src/assets/beij/zhongyang.png new file mode 100644 index 0000000..a47618f Binary files /dev/null and b/src/assets/beij/zhongyang.png differ diff --git a/src/assets/beij/zhongyang1.png b/src/assets/beij/zhongyang1.png new file mode 100644 index 0000000..e57627f Binary files /dev/null and b/src/assets/beij/zhongyang1.png differ diff --git a/src/assets/beij/zjtl.png b/src/assets/beij/zjtl.png new file mode 100644 index 0000000..4370b1f Binary files /dev/null and b/src/assets/beij/zjtl.png differ diff --git a/src/assets/beij/zydl.png b/src/assets/beij/zydl.png new file mode 100644 index 0000000..9397802 Binary files /dev/null and b/src/assets/beij/zydl.png differ diff --git a/src/assets/beij/zysl.png b/src/assets/beij/zysl.png new file mode 100644 index 0000000..5dbca3b Binary files /dev/null and b/src/assets/beij/zysl.png differ diff --git a/src/assets/beij/下遮罩.png b/src/assets/beij/下遮罩.png new file mode 100644 index 0000000..d350977 Binary files /dev/null and b/src/assets/beij/下遮罩.png differ diff --git a/src/assets/beij/右侧装饰.png b/src/assets/beij/右侧装饰.png new file mode 100644 index 0000000..58157bb Binary files /dev/null and b/src/assets/beij/右侧装饰.png differ diff --git a/src/assets/beij/展开.png b/src/assets/beij/展开.png new file mode 100644 index 0000000..0cac741 Binary files /dev/null and b/src/assets/beij/展开.png differ diff --git a/src/assets/beij/左侧装饰.png b/src/assets/beij/左侧装饰.png new file mode 100644 index 0000000..e3f69d9 Binary files /dev/null and b/src/assets/beij/左侧装饰.png differ diff --git a/src/assets/beij/年-h.png b/src/assets/beij/年-h.png new file mode 100644 index 0000000..7e27b14 Binary files /dev/null and b/src/assets/beij/年-h.png differ diff --git a/src/assets/beij/年.png b/src/assets/beij/年.png new file mode 100644 index 0000000..74dbbfd Binary files /dev/null and b/src/assets/beij/年.png differ diff --git a/src/assets/beij/底装饰.png b/src/assets/beij/底装饰.png new file mode 100644 index 0000000..bde8086 Binary files /dev/null and b/src/assets/beij/底装饰.png differ diff --git a/src/assets/beij/执法记录仪(2).png b/src/assets/beij/执法记录仪(2).png new file mode 100644 index 0000000..6f275f9 Binary files /dev/null and b/src/assets/beij/执法记录仪(2).png differ diff --git a/src/assets/beij/执法记录仪.png b/src/assets/beij/执法记录仪.png new file mode 100644 index 0000000..f661cca Binary files /dev/null and b/src/assets/beij/执法记录仪.png differ diff --git a/src/assets/beij/收益标题.png b/src/assets/beij/收益标题.png new file mode 100644 index 0000000..ed38716 Binary files /dev/null and b/src/assets/beij/收益标题.png differ diff --git a/src/assets/beij/日-h.png b/src/assets/beij/日-h.png new file mode 100644 index 0000000..4a5799e Binary files /dev/null and b/src/assets/beij/日-h.png differ diff --git a/src/assets/beij/日.png b/src/assets/beij/日.png new file mode 100644 index 0000000..7483e62 Binary files /dev/null and b/src/assets/beij/日.png differ diff --git a/src/assets/beij/月-h.png b/src/assets/beij/月-h.png new file mode 100644 index 0000000..5d00f9f Binary files /dev/null and b/src/assets/beij/月-h.png differ diff --git a/src/assets/beij/月.png b/src/assets/beij/月.png new file mode 100644 index 0000000..92912a6 Binary files /dev/null and b/src/assets/beij/月.png differ diff --git a/src/assets/beij/楼层框.png b/src/assets/beij/楼层框.png new file mode 100644 index 0000000..95cd44f Binary files /dev/null and b/src/assets/beij/楼层框.png differ diff --git a/src/assets/beij/滑动1.png b/src/assets/beij/滑动1.png new file mode 100644 index 0000000..528ec60 Binary files /dev/null and b/src/assets/beij/滑动1.png differ diff --git a/src/assets/beij/滑动2.png b/src/assets/beij/滑动2.png new file mode 100644 index 0000000..7f37744 Binary files /dev/null and b/src/assets/beij/滑动2.png differ diff --git a/src/assets/beij/滚动1.png b/src/assets/beij/滚动1.png new file mode 100644 index 0000000..e8be888 Binary files /dev/null and b/src/assets/beij/滚动1.png differ diff --git a/src/assets/beij/滚动2.png b/src/assets/beij/滚动2.png new file mode 100644 index 0000000..feba6da Binary files /dev/null and b/src/assets/beij/滚动2.png differ diff --git a/src/assets/beij/环状图数据.png b/src/assets/beij/环状图数据.png new file mode 100644 index 0000000..04c2d63 Binary files /dev/null and b/src/assets/beij/环状图数据.png differ diff --git a/src/assets/beij/立即处理.png b/src/assets/beij/立即处理.png new file mode 100644 index 0000000..6a05164 Binary files /dev/null and b/src/assets/beij/立即处理.png differ diff --git a/src/assets/beij/设备总数.png b/src/assets/beij/设备总数.png new file mode 100644 index 0000000..a03a3b1 Binary files /dev/null and b/src/assets/beij/设备总数.png differ diff --git a/src/assets/bg-reset.png b/src/assets/bg-reset.png new file mode 100644 index 0000000..06fd1e5 Binary files /dev/null and b/src/assets/bg-reset.png differ diff --git a/src/assets/bg-save.png b/src/assets/bg-save.png new file mode 100644 index 0000000..7e24cb4 Binary files /dev/null and b/src/assets/bg-save.png differ diff --git a/src/assets/by.png b/src/assets/by.png new file mode 100644 index 0000000..29e4136 Binary files /dev/null and b/src/assets/by.png differ diff --git a/src/assets/edit-no.png b/src/assets/edit-no.png new file mode 100644 index 0000000..c9888f9 Binary files /dev/null and b/src/assets/edit-no.png differ diff --git a/src/assets/edit-yes.png b/src/assets/edit-yes.png new file mode 100644 index 0000000..8f05019 Binary files /dev/null and b/src/assets/edit-yes.png differ diff --git a/src/assets/fengji.png b/src/assets/fengji.png new file mode 100644 index 0000000..cca13c2 Binary files /dev/null and b/src/assets/fengji.png differ diff --git a/src/assets/gl.png b/src/assets/gl.png new file mode 100644 index 0000000..a12b5b0 Binary files /dev/null and b/src/assets/gl.png differ diff --git a/src/assets/go-left.png b/src/assets/go-left.png new file mode 100644 index 0000000..de40698 Binary files /dev/null and b/src/assets/go-left.png differ diff --git a/src/assets/go-right.png b/src/assets/go-right.png new file mode 100644 index 0000000..69cab8c Binary files /dev/null and b/src/assets/go-right.png differ diff --git a/src/assets/guanlang.png b/src/assets/guanlang.png new file mode 100644 index 0000000..1f9de23 Binary files /dev/null and b/src/assets/guanlang.png differ diff --git a/src/assets/icon/fengji.png b/src/assets/icon/fengji.png new file mode 100644 index 0000000..41f5ee6 Binary files /dev/null and b/src/assets/icon/fengji.png differ diff --git a/src/assets/icon/shuibeng.png b/src/assets/icon/shuibeng.png new file mode 100644 index 0000000..f3220a7 Binary files /dev/null and b/src/assets/icon/shuibeng.png differ diff --git a/src/assets/icon/zhaoming.png b/src/assets/icon/zhaoming.png new file mode 100644 index 0000000..0b84524 Binary files /dev/null and b/src/assets/icon/zhaoming.png differ diff --git a/src/assets/icons/index.js b/src/assets/icons/index.js new file mode 100644 index 0000000..d79e164 --- /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/1.svg b/src/assets/icons/svg/1.svg new file mode 100644 index 0000000..b258268 --- /dev/null +++ b/src/assets/icons/svg/1.svg @@ -0,0 +1 @@ + \ No newline at end of file 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/afmj.svg b/src/assets/icons/svg/afmj.svg new file mode 100644 index 0000000..d661899 --- /dev/null +++ b/src/assets/icons/svg/afmj.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/afxt.svg b/src/assets/icons/svg/afxt.svg new file mode 100644 index 0000000..c83f66e --- /dev/null +++ b/src/assets/icons/svg/afxt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/areai.svg b/src/assets/icons/svg/areai.svg new file mode 100644 index 0000000..5c38548 --- /dev/null +++ b/src/assets/icons/svg/areai.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/bbgl.svg b/src/assets/icons/svg/bbgl.svg new file mode 100644 index 0000000..5b3aeea --- /dev/null +++ b/src/assets/icons/svg/bbgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/bjgl-bjpz.svg b/src/assets/icons/svg/bjgl-bjpz.svg new file mode 100644 index 0000000..68869a2 --- /dev/null +++ b/src/assets/icons/svg/bjgl-bjpz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/bjgl-jbpz.svg b/src/assets/icons/svg/bjgl-jbpz.svg new file mode 100644 index 0000000..0ead6bc --- /dev/null +++ b/src/assets/icons/svg/bjgl-jbpz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/bjgl.svg b/src/assets/icons/svg/bjgl.svg new file mode 100644 index 0000000..befe7d2 --- /dev/null +++ b/src/assets/icons/svg/bjgl.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/cabini.svg b/src/assets/icons/svg/cabini.svg new file mode 100644 index 0000000..f7b88aa --- /dev/null +++ b/src/assets/icons/svg/cabini.svg @@ -0,0 +1 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/cgq.svg b/src/assets/icons/svg/cgq.svg new file mode 100644 index 0000000..f651888 --- /dev/null +++ b/src/assets/icons/svg/cgq.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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..5f9c5ab --- /dev/null +++ b/src/assets/icons/svg/code.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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..546d0e6 --- /dev/null +++ b/src/assets/icons/svg/device.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/deviceMaintenance.svg b/src/assets/icons/svg/deviceMaintenance.svg new file mode 100644 index 0000000..0a3998d --- /dev/null +++ b/src/assets/icons/svg/deviceMaintenance.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/dianli.svg b/src/assets/icons/svg/dianli.svg new file mode 100644 index 0000000..5f4119f --- /dev/null +++ b/src/assets/icons/svg/dianli.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/fan.svg b/src/assets/icons/svg/fan.svg new file mode 100644 index 0000000..fc2be17 --- /dev/null +++ b/src/assets/icons/svg/fan.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/gjdj.svg b/src/assets/icons/svg/gjdj.svg new file mode 100644 index 0000000..7fdf89a --- /dev/null +++ b/src/assets/icons/svg/gjdj.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/gongc.svg b/src/assets/icons/svg/gongc.svg new file mode 100644 index 0000000..6a75f13 --- /dev/null +++ b/src/assets/icons/svg/gongc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/guangb.svg b/src/assets/icons/svg/guangb.svg new file mode 100644 index 0000000..9c24fd5 --- /dev/null +++ b/src/assets/icons/svg/guangb.svg @@ -0,0 +1 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/hjjk-zyktkz.svg b/src/assets/icons/svg/hjjk-zyktkz.svg new file mode 100644 index 0000000..8a1e79e --- /dev/null +++ b/src/assets/icons/svg/hjjk-zyktkz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/hjkz-VRV.svg b/src/assets/icons/svg/hjkz-VRV.svg new file mode 100644 index 0000000..c502047 --- /dev/null +++ b/src/assets/icons/svg/hjkz-VRV.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/hjkz-hjjc.svg b/src/assets/icons/svg/hjkz-hjjc.svg new file mode 100644 index 0000000..edadfc9 --- /dev/null +++ b/src/assets/icons/svg/hjkz-hjjc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/hjkz-pqskz.svg b/src/assets/icons/svg/hjkz-pqskz.svg new file mode 100644 index 0000000..7cc1549 --- /dev/null +++ b/src/assets/icons/svg/hjkz-pqskz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/hjkz-xfxt.svg b/src/assets/icons/svg/hjkz-xfxt.svg new file mode 100644 index 0000000..d411817 --- /dev/null +++ b/src/assets/icons/svg/hjkz-xfxt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/hjkz-zmkz.svg b/src/assets/icons/svg/hjkz-zmkz.svg new file mode 100644 index 0000000..96723cc --- /dev/null +++ b/src/assets/icons/svg/hjkz-zmkz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/hjkz.svg b/src/assets/icons/svg/hjkz.svg new file mode 100644 index 0000000..32c0704 --- /dev/null +++ b/src/assets/icons/svg/hjkz.svg @@ -0,0 +1 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/index.svg b/src/assets/icons/svg/index.svg new file mode 100644 index 0000000..a5a3ee2 --- /dev/null +++ b/src/assets/icons/svg/index.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/kshtd.svg b/src/assets/icons/svg/kshtd.svg new file mode 100644 index 0000000..04fde63 --- /dev/null +++ b/src/assets/icons/svg/kshtd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/ktjz.svg b/src/assets/icons/svg/ktjz.svg new file mode 100644 index 0000000..1791a6a --- /dev/null +++ b/src/assets/icons/svg/ktjz.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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..70db62b --- /dev/null +++ b/src/assets/icons/svg/monitor.svg @@ -0,0 +1,2 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/nhgl-aijncl.svg b/src/assets/icons/svg/nhgl-aijncl.svg new file mode 100644 index 0000000..b32115e --- /dev/null +++ b/src/assets/icons/svg/nhgl-aijncl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/nhgl-clfz.svg b/src/assets/icons/svg/nhgl-clfz.svg new file mode 100644 index 0000000..5e0ac23 --- /dev/null +++ b/src/assets/icons/svg/nhgl-clfz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/nhgl-cslkz.svg b/src/assets/icons/svg/nhgl-cslkz.svg new file mode 100644 index 0000000..509f365 --- /dev/null +++ b/src/assets/icons/svg/nhgl-cslkz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/nhgl-dbjc.svg b/src/assets/icons/svg/nhgl-dbjc.svg new file mode 100644 index 0000000..b962c09 --- /dev/null +++ b/src/assets/icons/svg/nhgl-dbjc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/nhgl-nhfx.svg b/src/assets/icons/svg/nhgl-nhfx.svg new file mode 100644 index 0000000..adf3abd --- /dev/null +++ b/src/assets/icons/svg/nhgl-nhfx.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/nhgl-sbjc.svg b/src/assets/icons/svg/nhgl-sbjc.svg new file mode 100644 index 0000000..d7e5de4 --- /dev/null +++ b/src/assets/icons/svg/nhgl-sbjc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/nhgl.svg b/src/assets/icons/svg/nhgl.svg new file mode 100644 index 0000000..12262eb --- /dev/null +++ b/src/assets/icons/svg/nhgl.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/plan.svg b/src/assets/icons/svg/plan.svg new file mode 100644 index 0000000..5722c4b --- /dev/null +++ b/src/assets/icons/svg/plan.svg @@ -0,0 +1 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/pump.svg b/src/assets/icons/svg/pump.svg new file mode 100644 index 0000000..ed8c917 --- /dev/null +++ b/src/assets/icons/svg/pump.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/qygl.svg b/src/assets/icons/svg/qygl.svg new file mode 100644 index 0000000..5a6461e --- /dev/null +++ b/src/assets/icons/svg/qygl.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ 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..4b8b782 --- /dev/null +++ b/src/assets/icons/svg/redis-list.svg @@ -0,0 +1,2 @@ + \ 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 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/sbgl-jkgl.svg b/src/assets/icons/svg/sbgl-jkgl.svg new file mode 100644 index 0000000..5c916b3 --- /dev/null +++ b/src/assets/icons/svg/sbgl-jkgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/sbgl-sblxgl.svg b/src/assets/icons/svg/sbgl-sblxgl.svg new file mode 100644 index 0000000..23b788c --- /dev/null +++ b/src/assets/icons/svg/sbgl-sblxgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/sbgl.svg b/src/assets/icons/svg/sbgl.svg new file mode 100644 index 0000000..dad3b7f --- /dev/null +++ b/src/assets/icons/svg/sbgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/sbtz.svg b/src/assets/icons/svg/sbtz.svg new file mode 100644 index 0000000..d5bbed7 --- /dev/null +++ b/src/assets/icons/svg/sbtz.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ 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..eb287e3 --- /dev/null +++ b/src/assets/icons/svg/server.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/sjgl.svg b/src/assets/icons/svg/sjgl.svg new file mode 100644 index 0000000..5d7f804 --- /dev/null +++ b/src/assets/icons/svg/sjgl.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/spjk.svg b/src/assets/icons/svg/spjk.svg new file mode 100644 index 0000000..9bf20f4 --- /dev/null +++ b/src/assets/icons/svg/spjk.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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..76d41ba --- /dev/null +++ b/src/assets/icons/svg/system.svg @@ -0,0 +1,2 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/tongf.svg b/src/assets/icons/svg/tongf.svg new file mode 100644 index 0000000..b9eca0e --- /dev/null +++ b/src/assets/icons/svg/tongf.svg @@ -0,0 +1 @@ + \ 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..48e0e35 --- /dev/null +++ b/src/assets/icons/svg/tool.svg @@ -0,0 +1 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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 @@ + \ 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..cfb1021 --- /dev/null +++ b/src/assets/icons/svg/validCode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/wbgl.svg b/src/assets/icons/svg/wbgl.svg new file mode 100644 index 0000000..d86f0de --- /dev/null +++ b/src/assets/icons/svg/wbgl.svg @@ -0,0 +1 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xjgl.svg b/src/assets/icons/svg/xjgl.svg new file mode 100644 index 0000000..5b1e32f --- /dev/null +++ b/src/assets/icons/svg/xjgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-bmgl.svg b/src/assets/icons/svg/xtgl-bmgl.svg new file mode 100644 index 0000000..acde95f --- /dev/null +++ b/src/assets/icons/svg/xtgl-bmgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-cdgl.svg b/src/assets/icons/svg/xtgl-cdgl.svg new file mode 100644 index 0000000..ab28ba1 --- /dev/null +++ b/src/assets/icons/svg/xtgl-cdgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-cssz.svg b/src/assets/icons/svg/xtgl-cssz.svg new file mode 100644 index 0000000..213284a --- /dev/null +++ b/src/assets/icons/svg/xtgl-cssz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-gwgl.svg b/src/assets/icons/svg/xtgl-gwgl.svg new file mode 100644 index 0000000..148c2dc --- /dev/null +++ b/src/assets/icons/svg/xtgl-gwgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-jjrgl.svg b/src/assets/icons/svg/xtgl-jjrgl.svg new file mode 100644 index 0000000..6f04a90 --- /dev/null +++ b/src/assets/icons/svg/xtgl-jjrgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-jsgl.svg b/src/assets/icons/svg/xtgl-jsgl.svg new file mode 100644 index 0000000..4260cb1 --- /dev/null +++ b/src/assets/icons/svg/xtgl-jsgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-qygl.svg b/src/assets/icons/svg/xtgl-qygl.svg new file mode 100644 index 0000000..5cf759b --- /dev/null +++ b/src/assets/icons/svg/xtgl-qygl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-rzgl-czrz.svg b/src/assets/icons/svg/xtgl-rzgl-czrz.svg new file mode 100644 index 0000000..fa79832 --- /dev/null +++ b/src/assets/icons/svg/xtgl-rzgl-czrz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-rzgl-dlrz.svg b/src/assets/icons/svg/xtgl-rzgl-dlrz.svg new file mode 100644 index 0000000..33dca32 --- /dev/null +++ b/src/assets/icons/svg/xtgl-rzgl-dlrz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-rzgl.svg b/src/assets/icons/svg/xtgl-rzgl.svg new file mode 100644 index 0000000..db211de --- /dev/null +++ b/src/assets/icons/svg/xtgl-rzgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-tzgg.svg b/src/assets/icons/svg/xtgl-tzgg.svg new file mode 100644 index 0000000..331ca64 --- /dev/null +++ b/src/assets/icons/svg/xtgl-tzgg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-yhgl.svg b/src/assets/icons/svg/xtgl-yhgl.svg new file mode 100644 index 0000000..12ee72d --- /dev/null +++ b/src/assets/icons/svg/xtgl-yhgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-yxpz.svg b/src/assets/icons/svg/xtgl-yxpz.svg new file mode 100644 index 0000000..62db90b --- /dev/null +++ b/src/assets/icons/svg/xtgl-yxpz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl-zdgl.svg b/src/assets/icons/svg/xtgl-zdgl.svg new file mode 100644 index 0000000..479d1f0 --- /dev/null +++ b/src/assets/icons/svg/xtgl-zdgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtgl.svg b/src/assets/icons/svg/xtgl.svg new file mode 100644 index 0000000..a21050e --- /dev/null +++ b/src/assets/icons/svg/xtgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtjk-fwjk.svg b/src/assets/icons/svg/xtjk-fwjk.svg new file mode 100644 index 0000000..37876a6 --- /dev/null +++ b/src/assets/icons/svg/xtjk-fwjk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtjk-hcjk.svg b/src/assets/icons/svg/xtjk-hcjk.svg new file mode 100644 index 0000000..10577f1 --- /dev/null +++ b/src/assets/icons/svg/xtjk-hcjk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtjk-hclb.svg b/src/assets/icons/svg/xtjk-hclb.svg new file mode 100644 index 0000000..0d44924 --- /dev/null +++ b/src/assets/icons/svg/xtjk-hclb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtjk-zxyh.svg b/src/assets/icons/svg/xtjk-zxyh.svg new file mode 100644 index 0000000..03ded34 --- /dev/null +++ b/src/assets/icons/svg/xtjk-zxyh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/xtjk.svg b/src/assets/icons/svg/xtjk.svg new file mode 100644 index 0000000..ec52c16 --- /dev/null +++ b/src/assets/icons/svg/xtjk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/ywgl.svg b/src/assets/icons/svg/ywgl.svg new file mode 100644 index 0000000..25ad072 --- /dev/null +++ b/src/assets/icons/svg/ywgl.svg @@ -0,0 +1 @@ + \ 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 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/zskgl-zsklx.svg b/src/assets/icons/svg/zskgl-zsklx.svg new file mode 100644 index 0000000..2989a8f --- /dev/null +++ b/src/assets/icons/svg/zskgl-zsklx.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/zskgl-zsknr.svg b/src/assets/icons/svg/zskgl-zsknr.svg new file mode 100644 index 0000000..04b3f6e --- /dev/null +++ b/src/assets/icons/svg/zskgl-zsknr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/zskgl.svg b/src/assets/icons/svg/zskgl.svg new file mode 100644 index 0000000..d59289e --- /dev/null +++ b/src/assets/icons/svg/zskgl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/svg/中央.svg b/src/assets/icons/svg/中央.svg new file mode 100644 index 0000000..3290458 --- /dev/null +++ b/src/assets/icons/svg/中央.svg @@ -0,0 +1 @@ + \ 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..14f8f5c --- /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/BulbFilled-active.png b/src/assets/images/BulbFilled-active.png new file mode 100644 index 0000000..f6b7a79 Binary files /dev/null and b/src/assets/images/BulbFilled-active.png differ diff --git a/src/assets/images/BulbFilled.png b/src/assets/images/BulbFilled.png new file mode 100644 index 0000000..c7d9f94 Binary files /dev/null and b/src/assets/images/BulbFilled.png differ diff --git a/src/assets/images/Recovery.jpg b/src/assets/images/Recovery.jpg new file mode 100644 index 0000000..9f4f082 Binary files /dev/null and b/src/assets/images/Recovery.jpg differ diff --git a/src/assets/images/Screenshot.jpg b/src/assets/images/Screenshot.jpg new file mode 100644 index 0000000..608f4f6 Binary files /dev/null and b/src/assets/images/Screenshot.jpg differ diff --git a/src/assets/images/Stop.jpg b/src/assets/images/Stop.jpg new file mode 100644 index 0000000..2960845 Binary files /dev/null and b/src/assets/images/Stop.jpg differ diff --git a/src/assets/images/bg.png b/src/assets/images/bg.png new file mode 100644 index 0000000..8cdd300 Binary files /dev/null and b/src/assets/images/bg.png differ diff --git a/src/assets/images/control.jpg b/src/assets/images/control.jpg new file mode 100644 index 0000000..e3df978 Binary files /dev/null and b/src/assets/images/control.jpg differ diff --git a/src/assets/images/dark.svg b/src/assets/images/dark.svg new file mode 100644 index 0000000..36b58b5 --- /dev/null +++ b/src/assets/images/dark.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/energy01.png b/src/assets/images/energy01.png new file mode 100644 index 0000000..24e2580 Binary files /dev/null and b/src/assets/images/energy01.png differ diff --git a/src/assets/images/energy02.png b/src/assets/images/energy02.png new file mode 100644 index 0000000..2f12da4 Binary files /dev/null and b/src/assets/images/energy02.png differ diff --git a/src/assets/images/energySmall01.png b/src/assets/images/energySmall01.png new file mode 100644 index 0000000..cd8ecd7 Binary files /dev/null and b/src/assets/images/energySmall01.png differ diff --git a/src/assets/images/energySmall02.png b/src/assets/images/energySmall02.png new file mode 100644 index 0000000..26728e6 Binary files /dev/null and b/src/assets/images/energySmall02.png differ diff --git a/src/assets/images/fresh-1.png b/src/assets/images/fresh-1.png new file mode 100644 index 0000000..cb36a32 Binary files /dev/null and b/src/assets/images/fresh-1.png differ diff --git a/src/assets/images/fresh-2.png b/src/assets/images/fresh-2.png new file mode 100644 index 0000000..76f6445 Binary files /dev/null and b/src/assets/images/fresh-2.png differ diff --git a/src/assets/images/illustration.svg b/src/assets/images/illustration.svg new file mode 100644 index 0000000..b58ffd0 --- /dev/null +++ b/src/assets/images/illustration.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/light.svg b/src/assets/images/light.svg new file mode 100644 index 0000000..efd52c6 --- /dev/null +++ b/src/assets/images/light.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/list-1.png b/src/assets/images/list-1.png new file mode 100644 index 0000000..0d74cfe Binary files /dev/null and b/src/assets/images/list-1.png differ diff --git a/src/assets/images/list.png b/src/assets/images/list.png new file mode 100644 index 0000000..d50ceb2 Binary files /dev/null and b/src/assets/images/list.png differ diff --git a/src/assets/images/login-background.jpg b/src/assets/images/login-background.jpg new file mode 100644 index 0000000..8a89eb8 Binary files /dev/null and b/src/assets/images/login-background.jpg differ diff --git a/src/assets/images/pay.png b/src/assets/images/pay.png new file mode 100644 index 0000000..bb8b967 Binary files /dev/null and b/src/assets/images/pay.png differ diff --git a/src/assets/images/profile.jpg b/src/assets/images/profile.jpg new file mode 100644 index 0000000..b3a940b Binary files /dev/null and b/src/assets/images/profile.jpg differ diff --git a/src/assets/images/smallWater01.png b/src/assets/images/smallWater01.png new file mode 100644 index 0000000..b48a1b5 Binary files /dev/null and b/src/assets/images/smallWater01.png differ diff --git a/src/assets/images/smallWater02.png b/src/assets/images/smallWater02.png new file mode 100644 index 0000000..87c07aa Binary files /dev/null and b/src/assets/images/smallWater02.png differ diff --git a/src/assets/images/tea-active.png b/src/assets/images/tea-active.png new file mode 100644 index 0000000..407c3b1 Binary files /dev/null and b/src/assets/images/tea-active.png differ diff --git a/src/assets/images/tea.png b/src/assets/images/tea.png new file mode 100644 index 0000000..589eb32 Binary files /dev/null and b/src/assets/images/tea.png differ diff --git a/src/assets/images/water01.png b/src/assets/images/water01.png new file mode 100644 index 0000000..44bb8ae Binary files /dev/null and b/src/assets/images/water01.png differ diff --git a/src/assets/images/water02.png b/src/assets/images/water02.png new file mode 100644 index 0000000..4756ba8 Binary files /dev/null and b/src/assets/images/water02.png differ diff --git a/src/assets/images/windmill-active.png b/src/assets/images/windmill-active.png new file mode 100644 index 0000000..3262321 Binary files /dev/null and b/src/assets/images/windmill-active.png differ diff --git a/src/assets/images/windmill.png b/src/assets/images/windmill.png new file mode 100644 index 0000000..38313d4 Binary files /dev/null and b/src/assets/images/windmill.png differ diff --git a/src/assets/link.png b/src/assets/link.png new file mode 100644 index 0000000..a2f9a85 Binary files /dev/null and b/src/assets/link.png differ diff --git a/src/assets/logo/BulbFilled-active.png b/src/assets/logo/BulbFilled-active.png new file mode 100644 index 0000000..f6b7a79 Binary files /dev/null and b/src/assets/logo/BulbFilled-active.png differ diff --git a/src/assets/logo/logo-1.png b/src/assets/logo/logo-1.png new file mode 100644 index 0000000..e4c7982 Binary files /dev/null and b/src/assets/logo/logo-1.png differ diff --git a/src/assets/logo/logo-2.png b/src/assets/logo/logo-2.png new file mode 100644 index 0000000..b778bb4 Binary files /dev/null and b/src/assets/logo/logo-2.png differ diff --git a/src/assets/logo/logo-3.png b/src/assets/logo/logo-3.png new file mode 100644 index 0000000..d4da89e Binary files /dev/null and b/src/assets/logo/logo-3.png differ diff --git a/src/assets/logo/logo.png b/src/assets/logo/logo.png new file mode 100644 index 0000000..6c4c8aa Binary files /dev/null and b/src/assets/logo/logo.png differ diff --git a/src/assets/planBg/0101.png b/src/assets/planBg/0101.png new file mode 100644 index 0000000..22cd567 Binary files /dev/null and b/src/assets/planBg/0101.png differ diff --git a/src/assets/planBg/0102.png b/src/assets/planBg/0102.png new file mode 100644 index 0000000..4a943a2 Binary files /dev/null and b/src/assets/planBg/0102.png differ diff --git a/src/assets/planBg/0201.png b/src/assets/planBg/0201.png new file mode 100644 index 0000000..9409056 Binary files /dev/null and b/src/assets/planBg/0201.png differ diff --git a/src/assets/planBg/0202.png b/src/assets/planBg/0202.png new file mode 100644 index 0000000..b66d536 Binary files /dev/null and b/src/assets/planBg/0202.png differ diff --git a/src/assets/planBg/0301.png b/src/assets/planBg/0301.png new file mode 100644 index 0000000..e5835fb Binary files /dev/null and b/src/assets/planBg/0301.png differ diff --git a/src/assets/planBg/0302.png b/src/assets/planBg/0302.png new file mode 100644 index 0000000..8a76971 Binary files /dev/null and b/src/assets/planBg/0302.png differ diff --git a/src/assets/planBg/0401.png b/src/assets/planBg/0401.png new file mode 100644 index 0000000..65a5dd6 Binary files /dev/null and b/src/assets/planBg/0401.png differ diff --git a/src/assets/planBg/0402.png b/src/assets/planBg/0402.png new file mode 100644 index 0000000..d3f1992 Binary files /dev/null and b/src/assets/planBg/0402.png differ diff --git a/src/assets/planBg/ground.png b/src/assets/planBg/ground.png new file mode 100644 index 0000000..5aea4cf Binary files /dev/null and b/src/assets/planBg/ground.png differ diff --git a/src/assets/planIcon/byqwky.svg b/src/assets/planIcon/byqwky.svg new file mode 100644 index 0000000..aa982fe --- /dev/null +++ b/src/assets/planIcon/byqwky.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/cyfdjz.svg b/src/assets/planIcon/cyfdjz.svg new file mode 100644 index 0000000..c3343ec --- /dev/null +++ b/src/assets/planIcon/cyfdjz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/db.svg b/src/assets/planIcon/db.svg new file mode 100644 index 0000000..13c886a --- /dev/null +++ b/src/assets/planIcon/db.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/ddff.svg b/src/assets/planIcon/ddff.svg new file mode 100644 index 0000000..3ef62aa --- /dev/null +++ b/src/assets/planIcon/ddff.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/eyht.svg b/src/assets/planIcon/eyht.svg new file mode 100644 index 0000000..c41fcd4 --- /dev/null +++ b/src/assets/planIcon/eyht.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/fengji.svg b/src/assets/planIcon/fengji.svg new file mode 100644 index 0000000..36aafd8 --- /dev/null +++ b/src/assets/planIcon/fengji.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/fengliang.svg b/src/assets/planIcon/fengliang.svg new file mode 100644 index 0000000..2f2fb19 --- /dev/null +++ b/src/assets/planIcon/fengliang.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/ktjz.svg b/src/assets/planIcon/ktjz.svg new file mode 100644 index 0000000..5f7a8b2 --- /dev/null +++ b/src/assets/planIcon/ktjz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/mj.svg b/src/assets/planIcon/mj.svg new file mode 100644 index 0000000..267bef1 --- /dev/null +++ b/src/assets/planIcon/mj.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/pingjun.svg b/src/assets/planIcon/pingjun.svg new file mode 100644 index 0000000..6ebf95f --- /dev/null +++ b/src/assets/planIcon/pingjun.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/qixiang.svg b/src/assets/planIcon/qixiang.svg new file mode 100644 index 0000000..9a4a9c8 --- /dev/null +++ b/src/assets/planIcon/qixiang.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/sb.svg b/src/assets/planIcon/sb.svg new file mode 100644 index 0000000..ec5963a --- /dev/null +++ b/src/assets/planIcon/sb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/sgxwd.svg b/src/assets/planIcon/sgxwd.svg new file mode 100644 index 0000000..f94d095 --- /dev/null +++ b/src/assets/planIcon/sgxwd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/shuiwen.svg b/src/assets/planIcon/shuiwen.svg new file mode 100644 index 0000000..7ace8ad --- /dev/null +++ b/src/assets/planIcon/shuiwen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/sll.svg b/src/assets/planIcon/sll.svg new file mode 100644 index 0000000..c3df769 --- /dev/null +++ b/src/assets/planIcon/sll.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/spjk.svg b/src/assets/planIcon/spjk.svg new file mode 100644 index 0000000..9f5cc3c --- /dev/null +++ b/src/assets/planIcon/spjk.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/weiji.svg b/src/assets/planIcon/weiji.svg new file mode 100644 index 0000000..bb152d6 --- /dev/null +++ b/src/assets/planIcon/weiji.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/wenshidu.svg b/src/assets/planIcon/wenshidu.svg new file mode 100644 index 0000000..85d3c02 --- /dev/null +++ b/src/assets/planIcon/wenshidu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/xfbjzj.svg b/src/assets/planIcon/xfbjzj.svg new file mode 100644 index 0000000..abc64b7 --- /dev/null +++ b/src/assets/planIcon/xfbjzj.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/xfjwjz.svg b/src/assets/planIcon/xfjwjz.svg new file mode 100644 index 0000000..e8cf881 --- /dev/null +++ b/src/assets/planIcon/xfjwjz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/xfzj.svg b/src/assets/planIcon/xfzj.svg new file mode 100644 index 0000000..656de69 --- /dev/null +++ b/src/assets/planIcon/xfzj.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/yangqi.svg b/src/assets/planIcon/yangqi.svg new file mode 100644 index 0000000..345d396 --- /dev/null +++ b/src/assets/planIcon/yangqi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/yb.svg b/src/assets/planIcon/yb.svg new file mode 100644 index 0000000..31859db --- /dev/null +++ b/src/assets/planIcon/yb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/yewei.svg b/src/assets/planIcon/yewei.svg new file mode 100644 index 0000000..fa56e12 --- /dev/null +++ b/src/assets/planIcon/yewei.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/yjcl.svg b/src/assets/planIcon/yjcl.svg new file mode 100644 index 0000000..a73fbeb --- /dev/null +++ b/src/assets/planIcon/yjcl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/youqi.svg b/src/assets/planIcon/youqi.svg new file mode 100644 index 0000000..d3682eb --- /dev/null +++ b/src/assets/planIcon/youqi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/youwei.svg b/src/assets/planIcon/youwei.svg new file mode 100644 index 0000000..9e795f7 --- /dev/null +++ b/src/assets/planIcon/youwei.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/yyht.svg b/src/assets/planIcon/yyht.svg new file mode 100644 index 0000000..7f831d2 --- /dev/null +++ b/src/assets/planIcon/yyht.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/zhiliuping.svg b/src/assets/planIcon/zhiliuping.svg new file mode 100644 index 0000000..b499c9a --- /dev/null +++ b/src/assets/planIcon/zhiliuping.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/znyb.svg b/src/assets/planIcon/znyb.svg new file mode 100644 index 0000000..763d7b0 --- /dev/null +++ b/src/assets/planIcon/znyb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/planIcon/znzm.svg b/src/assets/planIcon/znzm.svg new file mode 100644 index 0000000..d737ad8 --- /dev/null +++ b/src/assets/planIcon/znzm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/styles/btn.scss b/src/assets/styles/btn.scss new file mode 100644 index 0000000..bc30304 --- /dev/null +++ b/src/assets/styles/btn.scss @@ -0,0 +1,99 @@ +@use './variables.module.scss' as *; + +@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..0251be7 --- /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..5bf2fbb --- /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..1c63068 --- /dev/null +++ b/src/assets/styles/index.scss @@ -0,0 +1,199 @@ +@use './variables.module.scss' as *; +@use './mixin.scss' as *; +@use './transition.scss' as *; +@use './element-ui.scss' as *; +@use './sidebar.scss' as *; +@use './btn.scss' as *; + +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); + } + } +} +.el-select,.el-time-picker,.el-range-editor { + width: 100%; +} +.el-time-picker { + width: 100%; +} +.el-range-editor--medium.el-input__inner { + width: 100%; +} +.el-date-editor { + width: 100% !important; +} +//main-container全局样式 +.app-container { + padding: 20px; + height: calc(100vh - 84px); + overflow-y: scroll; +} + +.components-container { + margin: 30px 50px; + 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; + } +} + +.margin0 { + margin: 0 !important; +} diff --git a/src/assets/styles/mixin.scss b/src/assets/styles/mixin.scss new file mode 100644 index 0000000..64d9cf6 --- /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..1685004 --- /dev/null +++ b/src/assets/styles/ruoyi.scss @@ -0,0 +1,291 @@ +/** +* 通用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; +} diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss new file mode 100644 index 0000000..8ac4115 --- /dev/null +++ b/src/assets/styles/sidebar.scss @@ -0,0 +1,232 @@ +@use './variables.module.scss' as *; + +#app { + + .main-container { + height: 100%; + transition: margin-left .28s; + margin-left: $base-sidebar-width; + position: relative; + } + + .sidebarHide { + margin-left: 0!important; + } + + .sidebar-container { + -webkit-transition: width .28s; + transition: width 0.28s; + width: $base-sidebar-width !important; + 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; + display: flex; + align-items: center; + } + + .svg-icon { + margin-right: 16px; + } + + .el-menu { + border: none; + height: 100%; + width: 100% !important; + } + .el-menu-item { + width: 100%; + } + .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..7e1b103 --- /dev/null +++ b/src/assets/styles/transition.scss @@ -0,0 +1,49 @@ +// global transition css + +/* fade */ +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.28s; +} + +.fade-enter, +.fade-leave-active { + opacity: 0; +} + +/* fade-transform */ +.fade-transform--move, +.fade-transform-leave-active, +.fade-transform-enter-active { + transition: all .5s; +} + +.fade-transform-enter { + opacity: 0; + transform: translateX(-30px); +} + +.fade-transform-leave-to { + opacity: 0; + transform: translateX(30px); +} + +/* breadcrumb transition */ +.breadcrumb-enter-active, +.breadcrumb-leave-active { + transition: all .5s; +} + +.breadcrumb-enter, +.breadcrumb-leave-active { + opacity: 0; + transform: translateX(20px); +} + +.breadcrumb-move { + transition: all .5s; +} + +.breadcrumb-leave-active { + position: absolute; +} diff --git a/src/assets/styles/variables.module.scss b/src/assets/styles/variables.module.scss new file mode 100644 index 0000000..09e510b --- /dev/null +++ b/src/assets/styles/variables.module.scss @@ -0,0 +1,221 @@ +// base color +$blue: #324157; +$light-blue: #333c46; +$red: #C03639; +$pink: #E65D6E; +$green: #30B08F; +$tiffany: #4AB7BD; +$yellow: #FEC171; +$panGreen: #30B08F; + +// 默认主题变量 +$menuText: #bfcbd9; +$menuActiveText: #409eff; +$menuBg: #304156; +$menuHover: #263445; + +// 浅色主题theme-light +$menuLightBg: #ffffff; +$menuLightHover: #f0f1f5; +$menuLightText: #303133; +$menuLightActiveText: #409EFF; + +// 基础变量 +$base-sidebar-width: 200px; +$sideBarWidth: 200px; + +// 菜单暗色变量 +$base-menu-color: #bfcbd9; +$base-menu-color-active: #f4f4f5; +$base-menu-background: #304156; +$base-sub-menu-background: #1f2d3d; +$base-sub-menu-hover: #001528; + +// 组件变量 +$--color-primary: #409EFF; +$--color-success: #67C23A; +$--color-warning: #E6A23C; +$--color-danger: #F56C6C; +$--color-info: #909399; + +:export { + menuText: $menuText; + menuActiveText: $menuActiveText; + menuBg: $menuBg; + menuHover: $menuHover; + menuLightBg: $menuLightBg; + menuLightHover: $menuLightHover; + menuLightText: $menuLightText; + menuLightActiveText: $menuLightActiveText; + sideBarWidth: $sideBarWidth; + // 导出基础颜色 + blue: $blue; + lightBlue: $light-blue; + red: $red; + pink: $pink; + green: $green; + tiffany: $tiffany; + yellow: $yellow; + panGreen: $panGreen; + // 导出组件颜色 + colorPrimary: $--color-primary; + colorSuccess: $--color-success; + colorWarning: $--color-warning; + colorDanger: $--color-danger; + colorInfo: $--color-info; +} + +// CSS变量定义 +:root { + /* 亮色模式变量 */ + --sidebar-bg: #{$menuBg}; + --sidebar-text: #{$menuText}; + --menu-hover: #{$menuHover}; + + --navbar-bg: #ffffff; + --navbar-text: #303133; + + /* splitpanes default-theme 变量 */ + --splitpanes-default-bg: #ffffff; + +} + +// 暗黑模式变量 +html.dark { + /* 默认通用 */ + --el-bg-color: #141414; + --el-bg-color-overlay: #1d1e1f; + --el-text-color-primary: #ffffff; + --el-text-color-regular: #d0d0d0; + --el-border-color: #434343; + --el-border-color-light: #434343; + + /* 侧边栏 */ + --sidebar-bg: #141414; + --sidebar-text: #ffffff; + --menu-hover: #2d2d2d; + --menu-active-text: #{$menuActiveText}; + + /* 顶部导航栏 */ + --navbar-bg: #141414; + --navbar-text: #ffffff; + --navbar-hover: #141414; + + /* 标签栏 */ + --tags-bg: #141414; + --tags-item-bg: #1d1e1f; + --tags-item-border: #303030; + --tags-item-text: #d0d0d0; + --tags-item-hover: #2d2d2d; + --tags-close-hover: #64666a; + + /* splitpanes 组件暗黑模式变量 */ + --splitpanes-bg: #141414; + --splitpanes-border: #303030; + --splitpanes-splitter-bg: #1d1e1f; + --splitpanes-splitter-hover-bg: #2d2d2d; + + /* blockquote 暗黑模式变量 */ + --blockquote-bg: #1d1e1f; + --blockquote-border: #303030; + --blockquote-text: #d0d0d0; + + /* Cron 时间表达式 模式变量 */ + --cron-border: #303030; + + /* splitpanes default-theme 暗黑模式变量 */ + --splitpanes-default-bg: #141414; + + /* 侧边栏菜单覆盖 */ + .sidebar-container { + .el-menu-item, .menu-title { + color: var(--el-text-color-regular); + } + & .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title, + & .theme-dark .el-sub-menu .el-menu-item { + background-color: var(--el-bg-color) !important; + } + } + + /* 顶部栏栏菜单覆盖 */ + .el-menu--horizontal { + .el-menu-item { + &:not(.is-disabled) { + &:hover, + &:focus { + background-color: var(--navbar-hover) !important; + } + } + } + } + + /* 分割窗格覆盖 */ + .splitpanes { + background-color: var(--splitpanes-bg); + + .splitpanes__pane { + background-color: var(--splitpanes-bg); + border-color: var(--splitpanes-border); + } + + .splitpanes__splitter { + background-color: var(--splitpanes-splitter-bg); + border-color: var(--splitpanes-border); + + &:hover { + background-color: var(--splitpanes-splitter-hover-bg); + } + + &:before, + &:after { + background-color: var(--splitpanes-border); + } + } + } + + /* 表格样式覆盖 */ + .el-table { + --el-table-header-bg-color: var(--el-bg-color-overlay) !important; + --el-table-header-text-color: var(--el-text-color-regular) !important; + --el-table-border-color: var(--el-border-color-light) !important; + --el-table-row-hover-bg-color: var(--el-bg-color-overlay) !important; + + .el-table__header-wrapper, .el-table__fixed-header-wrapper { + th { + background-color: var(--el-bg-color-overlay, #f8f8f9) !important; + color: var(--el-text-color-regular, #515a6e); + } + } + } + + /* 树组件高亮样式覆盖 */ + .el-tree { + .el-tree-node.is-current > .el-tree-node__content { + background-color: var(--el-bg-color-overlay) !important; + color: var(--el-color-primary); + } + + .el-tree-node__content:hover { + background-color: var(--el-bg-color-overlay); + } + } + + /* 下拉菜单样式覆盖 */ + .el-dropdown-menu__item:not(.is-disabled):focus, .el-dropdown-menu__item:not(.is-disabled):hover{ + background-color: var(--navbar-hover) !important; + } + + /* blockquote样式覆盖 */ + blockquote { + background-color: var(--blockquote-bg) !important; + border-left-color: var(--blockquote-border) !important; + color: var(--blockquote-text) !important; + } + + /* 时间表达式标题样式覆盖 */ + .popup-result .title { + background: var(--cron-border); + } + +} + diff --git a/src/assets/table.png b/src/assets/table.png new file mode 100644 index 0000000..5c5a375 Binary files /dev/null and b/src/assets/table.png differ diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue new file mode 100644 index 0000000..27b0044 --- /dev/null +++ b/src/components/Breadcrumb/index.vue @@ -0,0 +1,98 @@ + + + + + \ No newline at end of file diff --git a/src/components/Crontab/day.vue b/src/components/Crontab/day.vue new file mode 100644 index 0000000..456686f --- /dev/null +++ b/src/components/Crontab/day.vue @@ -0,0 +1,174 @@ + + + + \ No newline at end of file diff --git a/src/components/Crontab/hour.vue b/src/components/Crontab/hour.vue new file mode 100644 index 0000000..d05779e --- /dev/null +++ b/src/components/Crontab/hour.vue @@ -0,0 +1,133 @@ + + + + + \ No newline at end of file diff --git a/src/components/Crontab/index.vue b/src/components/Crontab/index.vue new file mode 100644 index 0000000..e9fd4dd --- /dev/null +++ b/src/components/Crontab/index.vue @@ -0,0 +1,313 @@ + + + + + \ No newline at end of file diff --git a/src/components/Crontab/min.vue b/src/components/Crontab/min.vue new file mode 100644 index 0000000..33e9bec --- /dev/null +++ b/src/components/Crontab/min.vue @@ -0,0 +1,126 @@ + + + + \ 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..542dd6f --- /dev/null +++ b/src/components/Crontab/month.vue @@ -0,0 +1,141 @@ + + + + + \ No newline at end of file diff --git a/src/components/Crontab/result.vue b/src/components/Crontab/result.vue new file mode 100644 index 0000000..b260d59 --- /dev/null +++ b/src/components/Crontab/result.vue @@ -0,0 +1,540 @@ + + + \ No newline at end of file diff --git a/src/components/Crontab/second.vue b/src/components/Crontab/second.vue new file mode 100644 index 0000000..05e8855 --- /dev/null +++ b/src/components/Crontab/second.vue @@ -0,0 +1,128 @@ + + + + + \ No newline at end of file diff --git a/src/components/Crontab/week.vue b/src/components/Crontab/week.vue new file mode 100644 index 0000000..69a03b0 --- /dev/null +++ b/src/components/Crontab/week.vue @@ -0,0 +1,197 @@ + + + + + \ No newline at end of file diff --git a/src/components/Crontab/year.vue b/src/components/Crontab/year.vue new file mode 100644 index 0000000..01b58f3 --- /dev/null +++ b/src/components/Crontab/year.vue @@ -0,0 +1,143 @@ + + + + + \ 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..5e70502 --- /dev/null +++ b/src/components/DictTag/index.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/src/components/Editor/index.vue b/src/components/Editor/index.vue new file mode 100644 index 0000000..efd0edc --- /dev/null +++ b/src/components/Editor/index.vue @@ -0,0 +1,276 @@ + + + + + diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue new file mode 100644 index 0000000..7affc96 --- /dev/null +++ b/src/components/FileUpload/index.vue @@ -0,0 +1,256 @@ + + + + diff --git a/src/components/Hamburger/index.vue b/src/components/Hamburger/index.vue new file mode 100644 index 0000000..3ea9388 --- /dev/null +++ b/src/components/Hamburger/index.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue new file mode 100644 index 0000000..b8c318d --- /dev/null +++ b/src/components/HeaderSearch/index.vue @@ -0,0 +1,252 @@ + + + + + diff --git a/src/components/IconSelect/index.vue b/src/components/IconSelect/index.vue new file mode 100644 index 0000000..3bb177f --- /dev/null +++ b/src/components/IconSelect/index.vue @@ -0,0 +1,111 @@ + + + + + \ No newline at end of file diff --git a/src/components/IconSelect/requireIcons.js b/src/components/IconSelect/requireIcons.js new file mode 100644 index 0000000..ccdfaa4 --- /dev/null +++ b/src/components/IconSelect/requireIcons.js @@ -0,0 +1,8 @@ +let icons = [] +const modules = import.meta.glob('./../../assets/icons/svg/*.svg') +for (const path in modules) { + const p = path.split('assets/icons/svg/')[1].split('.svg')[0] + icons.push(p) +} + +export default icons \ No newline at end of file diff --git a/src/components/ImagePreview/index.vue b/src/components/ImagePreview/index.vue new file mode 100644 index 0000000..00212c5 --- /dev/null +++ b/src/components/ImagePreview/index.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/src/components/ImageUpload/index.vue b/src/components/ImageUpload/index.vue new file mode 100644 index 0000000..3929896 --- /dev/null +++ b/src/components/ImageUpload/index.vue @@ -0,0 +1,258 @@ + + + + + \ No newline at end of file diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue new file mode 100644 index 0000000..a5ae1a2 --- /dev/null +++ b/src/components/Pagination/index.vue @@ -0,0 +1,109 @@ + + + + + \ No newline at end of file diff --git a/src/components/ParentView/index.vue b/src/components/ParentView/index.vue new file mode 100644 index 0000000..ad6360c --- /dev/null +++ b/src/components/ParentView/index.vue @@ -0,0 +1,3 @@ + diff --git a/src/components/RightToolbar/index.vue b/src/components/RightToolbar/index.vue new file mode 100644 index 0000000..68eb0f0 --- /dev/null +++ b/src/components/RightToolbar/index.vue @@ -0,0 +1,181 @@ + + + + + diff --git a/src/components/RuoYi/Doc/index.vue b/src/components/RuoYi/Doc/index.vue new file mode 100644 index 0000000..91aebe0 --- /dev/null +++ b/src/components/RuoYi/Doc/index.vue @@ -0,0 +1,13 @@ + + + \ 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..96fdea7 --- /dev/null +++ b/src/components/RuoYi/Git/index.vue @@ -0,0 +1,13 @@ + + + diff --git a/src/components/Screenfull/index.vue b/src/components/Screenfull/index.vue new file mode 100644 index 0000000..cf23223 --- /dev/null +++ b/src/components/Screenfull/index.vue @@ -0,0 +1,22 @@ + + + + + \ No newline at end of file diff --git a/src/components/SizeSelect/index.vue b/src/components/SizeSelect/index.vue new file mode 100644 index 0000000..5ff0a91 --- /dev/null +++ b/src/components/SizeSelect/index.vue @@ -0,0 +1,45 @@ + + + + + \ No newline at end of file diff --git a/src/components/SvgIcon/index.vue b/src/components/SvgIcon/index.vue new file mode 100644 index 0000000..41f64c9 --- /dev/null +++ b/src/components/SvgIcon/index.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/src/components/SvgIcon/svgicon.js b/src/components/SvgIcon/svgicon.js new file mode 100644 index 0000000..05284e3 --- /dev/null +++ b/src/components/SvgIcon/svgicon.js @@ -0,0 +1,10 @@ +import * as components from '@element-plus/icons-vue' + +export default { + install: (app) => { + for (const key in components) { + const componentConfig = components[key] + app.component(componentConfig.name, componentConfig) + } + } +} diff --git a/src/components/TopNav/index.vue b/src/components/TopNav/index.vue new file mode 100644 index 0000000..9d9bf13 --- /dev/null +++ b/src/components/TopNav/index.vue @@ -0,0 +1,217 @@ + + + + + diff --git a/src/components/iFrame/index.vue b/src/components/iFrame/index.vue new file mode 100644 index 0000000..fe98b2d --- /dev/null +++ b/src/components/iFrame/index.vue @@ -0,0 +1,31 @@ + + + diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue new file mode 100644 index 0000000..f420297 --- /dev/null +++ b/src/layout/components/Navbar.vue @@ -0,0 +1,255 @@ + + + + + diff --git a/src/layout/components/Settings/index.vue b/src/layout/components/Settings/index.vue new file mode 100644 index 0000000..4c4d6e0 --- /dev/null +++ b/src/layout/components/Settings/index.vue @@ -0,0 +1,221 @@ + + + + + \ No newline at end of file diff --git a/src/layout/components/Sidebar/Link.vue b/src/layout/components/Sidebar/Link.vue new file mode 100644 index 0000000..15692ba --- /dev/null +++ b/src/layout/components/Sidebar/Link.vue @@ -0,0 +1,40 @@ + + + diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue new file mode 100644 index 0000000..94e161d --- /dev/null +++ b/src/layout/components/Sidebar/Logo.vue @@ -0,0 +1,103 @@ + + + + + + \ No newline at end of file diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue new file mode 100644 index 0000000..f395d95 --- /dev/null +++ b/src/layout/components/Sidebar/SidebarItem.vue @@ -0,0 +1,100 @@ + + + diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue new file mode 100644 index 0000000..f807b9a --- /dev/null +++ b/src/layout/components/Sidebar/index.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/src/layout/components/TagsView/ScrollPane.vue b/src/layout/components/TagsView/ScrollPane.vue new file mode 100644 index 0000000..a14a36c --- /dev/null +++ b/src/layout/components/TagsView/ScrollPane.vue @@ -0,0 +1,107 @@ + + + + + \ No newline at end of file diff --git a/src/layout/components/TagsView/index.vue b/src/layout/components/TagsView/index.vue new file mode 100644 index 0000000..6ce20cd --- /dev/null +++ b/src/layout/components/TagsView/index.vue @@ -0,0 +1,371 @@ + + + + + + + \ No newline at end of file diff --git a/src/layout/components/index.js b/src/layout/components/index.js new file mode 100644 index 0000000..d1308ce --- /dev/null +++ b/src/layout/components/index.js @@ -0,0 +1,4 @@ +export { default as AppMain } from './AppMain' +export { default as Navbar } from './Navbar' +export { default as Settings } from './Settings' +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..dbc95a9 --- /dev/null +++ b/src/layout/index.vue @@ -0,0 +1,130 @@ + + + + + \ No newline at end of file diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..5d76529 --- /dev/null +++ b/src/main.js @@ -0,0 +1,92 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-26 11:23:42 + * @Description: + */ +import { createApp } from 'vue' + +import Cookies from 'js-cookie' + +import ElementPlus from 'element-plus' +import 'element-plus/dist/index.css' +import 'element-plus/theme-chalk/dark/css-vars.css' +import locale from 'element-plus/es/locale/lang/zh-cn' + +import '@/assets/styles/index.scss' // global 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' + +// svg图标 +import 'virtual:svg-icons-register' +import SvgIcon from '@/components/SvgIcon' +import elementIcons from '@/components/SvgIcon/svgicon' + +import './permission' // permission control + +import { useDict } from '@/utils/dict' +import { getConfigKey } from "@/api/system/config" +import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels } 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' + +const app = createApp(App) + +// 全局方法挂载 +app.config.globalProperties.useDict = useDict +app.config.globalProperties.download = download +app.config.globalProperties.parseTime = parseTime +app.config.globalProperties.resetForm = resetForm +app.config.globalProperties.handleTree = handleTree +app.config.globalProperties.addDateRange = addDateRange +app.config.globalProperties.getConfigKey = getConfigKey +app.config.globalProperties.selectDictLabel = selectDictLabel +app.config.globalProperties.selectDictLabels = selectDictLabels + +app.config.globalProperties.$FileBaseUrl = import.meta.env.VITE_VUE_APP_BASE_FILEURL; +window.$FileBaseUrl = import.meta.env.VITE_VUE_APP_BASE_FILEURL; + +// 全局组件挂载 +app.component('DictTag', DictTag) +app.component('Pagination', Pagination) +app.component('FileUpload', FileUpload) +app.component('ImageUpload', ImageUpload) +app.component('ImagePreview', ImagePreview) +app.component('RightToolbar', RightToolbar) +app.component('Editor', Editor) + +app.use(router) +app.use(store) +app.use(plugins) +app.use(elementIcons) +app.component('svg-icon', SvgIcon) + +directive(app) + +// 使用element-plus 并且设置全局的大小 +app.use(ElementPlus, { + locale: locale, + // 支持 large、default、small + size: Cookies.get('size') || 'default' +}) + +app.mount('#app') diff --git a/src/mock/data.js b/src/mock/data.js new file mode 100644 index 0000000..11ca062 --- /dev/null +++ b/src/mock/data.js @@ -0,0 +1,784 @@ +const data = [ + { + "IsOpen": 0, + "IsFault": 0, + "IsAlarm": 0, + "DeviceId": "A2C20864-1CDC-4375-91C4-D0C70A3D0B0D", + "TypeId": 3, + "AreaId": 1, + "StateId": 0, + "CabinId": 2, + "AreaName": "1单元1栋", + "CabinName": "R1", + "DeviceName": "水泵", + "DeviceCode": "WSC01JSK-SB001", + "IP": "10.9.4.200", + "Station": 1, + "TypeName": "水泵", + "Data": [ + { + "TypeAttrId": 3057, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "水泵自动状态", + "AttrField": "", + "AttrValue": "66", + "AttrUnit": "", + "AttrIndex": 0, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DI", + "ReadPoint": "", + "Value": 1, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3058, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "水泵运行状态", + "AttrField": "", + "AttrValue": "67", + "AttrUnit": "", + "AttrIndex": 1, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "1", + "StateType": "DI", + "ReadPoint": "", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3059, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "水泵故障状态", + "AttrField": "", + "AttrValue": "68", + "AttrUnit": "", + "AttrIndex": 2, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "1", + "OperationIndex": "0", + "StateType": "DI", + "ReadPoint": "", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3060, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 12, + "AttrType": "类型属性", + "AttrName": "水泵启动", + "AttrField": "", + "AttrValue": "55", + "AttrUnit": "", + "AttrIndex": 3, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DO", + "ReadPoint": "67", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3061, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 12, + "AttrType": "类型属性", + "AttrName": "水泵停止", + "AttrField": "", + "AttrValue": "56", + "AttrUnit": "", + "AttrIndex": 4, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DO", + "ReadPoint": "67", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + } + ], + x: 530, + y: 350, + "target": "device" + }, + { + "IsOpen": 0, + "IsFault": 0, + "IsAlarm": 0, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A380B0D", + "TypeId": 3, + "AreaId": 1, + "StateId": 0, + "CabinId": 2, + "AreaName": "1单元1栋", + "CabinName": "R1", + "DeviceName": "水泵", + "DeviceCode": "WSC01JSK-SB001", + "IP": "10.9.4.200", + "Station": 1, + "TypeName": "水泵", + "Data": [ + { + "TypeAttrId": 3057, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "水泵自动状态", + "AttrField": "", + "AttrValue": "66", + "AttrUnit": "", + "AttrIndex": 0, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DI", + "ReadPoint": "", + "Value": 1, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3058, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "水泵运行状态", + "AttrField": "", + "AttrValue": "67", + "AttrUnit": "", + "AttrIndex": 1, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "1", + "StateType": "DI", + "ReadPoint": "", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3059, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "水泵故障状态", + "AttrField": "", + "AttrValue": "68", + "AttrUnit": "", + "AttrIndex": 2, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "1", + "OperationIndex": "0", + "StateType": "DI", + "ReadPoint": "", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3060, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 12, + "AttrType": "类型属性", + "AttrName": "水泵启动", + "AttrField": "", + "AttrValue": "55", + "AttrUnit": "", + "AttrIndex": 3, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DO", + "ReadPoint": "67", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3061, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 12, + "AttrType": "类型属性", + "AttrName": "水泵停止", + "AttrField": "", + "AttrValue": "56", + "AttrUnit": "", + "AttrIndex": 4, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DO", + "ReadPoint": "67", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + } + ], + x: 500, + y: 450, + "target": "device" + }, + + { + "IsOpen": 0, + "IsFault": 0, + "IsAlarm": 0, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "TypeId": 3, + "AreaId": 1, + "StateId": 0, + "CabinId": 2, + "AreaName": "1单元1栋", + "CabinName": "R1", + "DeviceName": "水泵", + "DeviceCode": "WSC01JSK-SB001", + "IP": "10.9.4.200", + "Station": 1, + "TypeName": "水泵", + "Data": [ + { + "TypeAttrId": 3057, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "水泵自动状态", + "AttrField": "", + "AttrValue": "66", + "AttrUnit": "", + "AttrIndex": 0, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DI", + "ReadPoint": "", + "Value": 1, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3058, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "水泵运行状态", + "AttrField": "", + "AttrValue": "67", + "AttrUnit": "", + "AttrIndex": 1, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "1", + "StateType": "DI", + "ReadPoint": "", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3059, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "水泵故障状态", + "AttrField": "", + "AttrValue": "68", + "AttrUnit": "", + "AttrIndex": 2, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "1", + "OperationIndex": "0", + "StateType": "DI", + "ReadPoint": "", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3060, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 12, + "AttrType": "类型属性", + "AttrName": "水泵启动", + "AttrField": "", + "AttrValue": "55", + "AttrUnit": "", + "AttrIndex": 3, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DO", + "ReadPoint": "67", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3061, + "DeviceId": "A2C40864-1CDC-4375-91C4-D0C70A3D0B0D", + "StateId": 12, + "AttrType": "类型属性", + "AttrName": "水泵停止", + "AttrField": "", + "AttrValue": "56", + "AttrUnit": "", + "AttrIndex": 4, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DO", + "ReadPoint": "67", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + } + ], + x: 470, + y: 550, + "target": "device" + }, + { + "IsOpen": 0, + "IsFault": 0, + "IsAlarm": 0, + "DeviceId": "BAhF5811-22C1-406E-B343-CE433B7C2CC5", + "TypeId": 1, + "AreaId": 1, + "StateId": 0, + "CabinId": 2, + "AreaName": "分区1", + "CabinName": "污水舱", + "DeviceName": "污水舱送风机", + "DeviceCode": "WSC01JFS-BY001", + "IP": "10.9.4.200", + "Station": 1, + "TypeName": "风机", + "Data": [ + { + "TypeAttrId": 3002, + "DeviceId": "BA5F5811-22C1-406E-B343-CE433B7C2CC5", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "上层开到位", + "AttrField": "", + "AttrValue": "36", + "AttrUnit": "", + "AttrIndex": 0, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "1", + "StateType": "DI", + "ReadPoint": "", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3003, + "DeviceId": "BA5F5811-22C1-406E-B343-CE433B7C2CC5", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "下层开到位", + "AttrField": "", + "AttrValue": "37", + "AttrUnit": "", + "AttrIndex": 1, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DI", + "ReadPoint": "", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 3004, + "DeviceId": "BA5F5811-22C1-406E-B343-CE433B7C2CC5", + "StateId": 12, + "AttrType": "类型属性", + "AttrName": "开启/关闭百叶", + "AttrField": "", + "AttrValue": "29", + "AttrUnit": "", + "AttrIndex": 2, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DO", + "ReadPoint": "36", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + } + ], + "x": 605, + "y": 350, + "target": "device" + }, + + { + "IsOpen": 0, + "IsFault": 0, + "IsAlarm": 0, + "DeviceId": "F661BA74-90BF-4E21-97A8-568437pA018C", + "TypeId": 1, + "AreaId": 1, + "StateId": 0, + "CabinId": 2, + "AreaName": "分区1", + "CabinName": "污水舱", + "DeviceName": "污水舱送风机", + "DeviceCode": "WSC01JFS-JFJ001", + "IP": "10.9.4.200", + "Station": 1, + "TypeName": "送风机", + "Data": [ + { + "TypeAttrId": 2968, + "DeviceId": "F661BA74-90BF-4E21-97A8-568437CA018C", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "送风机自动", + "AttrField": "", + "AttrValue": "26", + "AttrUnit": "", + "AttrIndex": 0, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DI", + "ReadPoint": "", + "Value": 1, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 2969, + "DeviceId": "F661BA74-90BF-4E21-97A8-568437CA018C", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "送风机运行", + "AttrField": "", + "AttrValue": "27", + "AttrUnit": "", + "AttrIndex": 1, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "1", + "StateType": "DI", + "ReadPoint": "", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 2970, + "DeviceId": "F661BA74-90BF-4E21-97A8-568437CA018C", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "送风机故障", + "AttrField": "", + "AttrValue": "28", + "AttrUnit": "", + "AttrIndex": 2, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "1", + "OperationIndex": "0", + "StateType": "DI", + "ReadPoint": "", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 2971, + "DeviceId": "F661BA74-90BF-4E21-97A8-568437CA018C", + "StateId": 12, + "AttrType": "类型属性", + "AttrName": "送风机开启", + "AttrField": "", + "AttrValue": "23", + "AttrUnit": "", + "AttrIndex": 3, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DO", + "ReadPoint": "27", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 2972, + "DeviceId": "F661BA74-90BF-4E21-97A8-568437CA018C", + "StateId": 12, + "AttrType": "类型属性", + "AttrName": "送风机关闭", + "AttrField": "", + "AttrValue": "37", + "AttrUnit": "", + "AttrIndex": 4, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DO", + "ReadPoint": "27", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + } + ], + "x": 562, + y: 550, + "target": "device" + }, + { + "IsOpen": 0, + "IsFault": 0, + "IsAlarm": 0, + "DeviceId": "F661BA74-91BF-4E21-97A8-568437CA018l", + "TypeId": 1, + "AreaId": 1, + "StateId": 0, + "CabinId": 2, + "AreaName": "分区1", + "CabinName": "污水舱", + "DeviceName": "污水舱送风机", + "DeviceCode": "WSC01JFS-JFJ001", + "IP": "10.9.4.200", + "Station": 1, + "TypeName": "送风机", + "Data": [ + { + "TypeAttrId": 2968, + "DeviceId": "Fg61BA74-90BF-4E21-97A8-568437CA018C", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "送风机自动", + "AttrField": "", + "AttrValue": "26", + "AttrUnit": "", + "AttrIndex": 0, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DI", + "ReadPoint": "", + "Value": 1, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 2969, + "DeviceId": "F661BA74-90BF-4E21-97A8-568437CA018C", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "送风机运行", + "AttrField": "", + "AttrValue": "27", + "AttrUnit": "", + "AttrIndex": 1, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "1", + "StateType": "DI", + "ReadPoint": "", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 2970, + "DeviceId": "F661BA74-901F-4E21-97A8-568437CA018C", + "StateId": 11, + "AttrType": "类型属性", + "AttrName": "送风机故障", + "AttrField": "", + "AttrValue": "28", + "AttrUnit": "", + "AttrIndex": 2, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "1", + "OperationIndex": "0", + "StateType": "DI", + "ReadPoint": "", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 2971, + "DeviceId": "F661BA74-90BF-4E21-97A8-568437CA018C", + "StateId": 12, + "AttrType": "类型属性", + "AttrName": "送风机开启", + "AttrField": "", + "AttrValue": "23", + "AttrUnit": "", + "AttrIndex": 3, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DO", + "ReadPoint": "27", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + }, + { + "TypeAttrId": 2972, + "DeviceId": "F661BA74-90BF-4E21-97A8-568437CA018C", + "StateId": 12, + "AttrType": "类型属性", + "AttrName": "送风机关闭", + "AttrField": "", + "AttrValue": "37", + "AttrUnit": "", + "AttrIndex": 4, + "UpperLimitValue": "", + "LowerLimitValue": "", + "OverStandard": null, + "FaultPoint": "0", + "OperationIndex": "0", + "StateType": "DO", + "ReadPoint": "27", + "Value": 0, + "Remark1": "", + "Remark2": null, + "Transformation": "0", + "AlarmName": null + } + ], + x: 580, + y: 450, + "target": "device" + }, + +] + +export default data; + diff --git a/src/permission.js b/src/permission.js new file mode 100644 index 0000000..2a2663d --- /dev/null +++ b/src/permission.js @@ -0,0 +1,96 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-04 19:58:43 + * @Description: + */ +import router from './router' +import { ElMessage } from 'element-plus' +import NProgress from 'nprogress' +import 'nprogress/nprogress.css' +import { getToken } from '@/utils/auth' +import { isHttp, isPathMatch } from '@/utils/validate' +import { isRelogin } from '@/utils/request' +import { useUserStore } from '@/store/modules/user' +import { useSettingsStore } from '@/store/modules/settings' +import { usePermissionStore } from '@/store/modules/permission' + +NProgress.configure({ showSpinner: false }) + +const whiteList = ['/login', '/register', 'index'] + +// 添加路由的辅助函数 +const addRoutes = (routes) => { + routes.forEach(route => { + router.addRoute(route) + }) +} + +// 初始化路由 +const initRoutes = () => { + const permissionStore = usePermissionStore() + permissionStore.GenerateRoutes().then(accessRoutes => { + // 根据roles权限生成可访问的路由表 + addRoutes(accessRoutes) // 动态添加可访问路由表 + // next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 + }) +} + +router.beforeEach((to, from, next) => { + NProgress.start() + + // 在路由守卫内部获取store实例 + const userStore = useUserStore() + const settingsStore = useSettingsStore() + const permissionStore = usePermissionStore() + + if (getToken()) { + to.meta.title && settingsStore.setTitle(to.meta.title) + /* has token*/ + if (to.path === '/login') { + next({ path: '/' }) + NProgress.done() + } else if (whiteList.indexOf(to.path) !== -1) { + next() + } else { + if (userStore.roles.length === 0) { + isRelogin.show = true + // 判断当前用户是否已拉取完user_info信息 + // userStore.GetInfo().then(() => { + isRelogin.show = false + next() + + // permissionStore.GenerateRoutes().then(accessRoutes => { + // // 根据roles权限生成可访问的路由表 + // addRoutes(accessRoutes) // 动态添加可访问路由表 + // next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 + // }) + // }).catch(err => { + // userStore.LogOut().then(() => { + // ElMessage.error(err) + // next({ path: '/' }) + // }) + // }) + } else { + next() + } + } + } else { + // 没有token + if (whiteList.indexOf(to.path) !== -1) { + // 在免登录白名单,直接进入 + next() + } else { + next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页 + NProgress.done() + } + } +}) + +router.afterEach(() => { + NProgress.done() +}) + +// 在应用启动后初始化路由 +setTimeout(() => { + initRoutes() +}, 0) diff --git a/src/plugins/auth.js b/src/plugins/auth.js new file mode 100644 index 0000000..9a9cf96 --- /dev/null +++ b/src/plugins/auth.js @@ -0,0 +1,72 @@ +import { useUserStore } from '@/store/modules/user' + +function authPermission(permission) { + const all_permission = "*:*:*" + try { + const userStore = useUserStore() + const permissions = userStore.permissions || [] + if (permission && permission.length > 0) { + return permissions.some(v => { + return all_permission === v || v === permission + }) + } else { + return false + } + } catch (error) { + console.warn('Permission check failed:', error) + return false + } +} + +function authRole(role) { + const super_admin = "admin" + try { + const userStore = useUserStore() + const roles = userStore.roles || [] + if (role && role.length > 0) { + return roles.some(v => { + return super_admin === v || v === role + }) + } else { + return false + } + } catch (error) { + console.warn('Role check failed:', error) + 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..4d29dfe --- /dev/null +++ b/src/plugins/cache.js @@ -0,0 +1,79 @@ +const sessionCache = { + set (key, value) { + if (!sessionStorage) { + return + } + if (key != null && value != null) { + sessionStorage.setItem(key, value) + } + }, + get (key) { + if (!sessionStorage) { + return null + } + if (key == null) { + return null + } + return sessionStorage.getItem(key) + }, + setJSON (key, jsonValue) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)) + } + }, + getJSON (key) { + const value = this.get(key) + if (value != null) { + return JSON.parse(value) + } + return null + }, + remove (key) { + sessionStorage.removeItem(key) + } +} +const localCache = { + set (key, value) { + if (!localStorage) { + return + } + if (key != null && value != null) { + localStorage.setItem(key, value) + } + }, + get (key) { + if (!localStorage) { + return null + } + if (key == null) { + return null + } + return localStorage.getItem(key) + }, + setJSON (key, jsonValue) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)) + } + }, + getJSON (key) { + const value = this.get(key) + if (value != null) { + return JSON.parse(value) + } + return null + }, + remove (key) { + localStorage.removeItem(key) + } +} + +export default { + /** + * 会话级缓存 + */ + session: sessionCache, + /** + * 本地缓存 + */ + local: localCache +} diff --git a/src/plugins/download.js b/src/plugins/download.js new file mode 100644 index 0000000..82e26ed --- /dev/null +++ b/src/plugins/download.js @@ -0,0 +1,79 @@ +import axios from 'axios' +import { ElLoading, ElMessage } from 'element-plus' +import { saveAs } from 'file-saver' +import { getToken } from '@/utils/auth' +import errorCode from '@/utils/errorCode' +import { blobValidate } from '@/utils/ruoyi' + +const baseURL = import.meta.env.VITE_APP_BASE_API +let downloadLoadingInstance + +export default { + name(name, isDelete = true) { + var url = baseURL + "/common/download?fileName=" + encodeURIComponent(name) + "&delete=" + isDelete + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then((res) => { + const isBlob = blobValidate(res.data) + if (isBlob) { + const blob = new Blob([res.data]) + this.saveAs(blob, decodeURIComponent(res.headers['download-filename'])) + } else { + this.printErrMsg(res.data) + } + }) + }, + resource(resource) { + var url = baseURL + "/common/download/resource?resource=" + encodeURIComponent(resource) + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then((res) => { + const isBlob = blobValidate(res.data) + if (isBlob) { + const blob = new Blob([res.data]) + this.saveAs(blob, decodeURIComponent(res.headers['download-filename'])) + } else { + this.printErrMsg(res.data) + } + }) + }, + zip(url, name) { + var url = baseURL + url + downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", }) + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then((res) => { + const isBlob = blobValidate(res.data) + if (isBlob) { + const blob = new Blob([res.data], { type: 'application/zip' }) + this.saveAs(blob, name) + } else { + this.printErrMsg(res.data) + } + downloadLoadingInstance.close() + }).catch((r) => { + console.error(r) + ElMessage.error('下载文件出现错误,请联系管理员!') + downloadLoadingInstance.close() + }) + }, + saveAs(text, name, opts) { + saveAs(text, name, opts) + }, + async printErrMsg(data) { + const resText = await data.text() + const rspObj = JSON.parse(resText) + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] + ElMessage.error(errMsg) + } +} + diff --git a/src/plugins/index.js b/src/plugins/index.js new file mode 100644 index 0000000..fb75c63 --- /dev/null +++ b/src/plugins/index.js @@ -0,0 +1,18 @@ +import tab from './tab' +import auth from './auth' +import cache from './cache' +import modal from './modal' +import download from './download' + +export default function installPlugins(app){ + // 页签操作 + app.config.globalProperties.$tab = tab + // 认证对象 + app.config.globalProperties.$auth = auth + // 缓存对象 + app.config.globalProperties.$cache = cache + // 模态框对象 + app.config.globalProperties.$modal = modal + // 下载文件 + app.config.globalProperties.$download = download +} diff --git a/src/plugins/modal.js b/src/plugins/modal.js new file mode 100644 index 0000000..8695360 --- /dev/null +++ b/src/plugins/modal.js @@ -0,0 +1,82 @@ +import { ElMessage, ElMessageBox, ElNotification, ElLoading } from 'element-plus' + +let loadingInstance + +export default { + // 消息提示 + msg(content) { + ElMessage.info(content) + }, + // 错误消息 + msgError(content) { + ElMessage.error(content) + }, + // 成功消息 + msgSuccess(content) { + ElMessage.success(content) + }, + // 警告消息 + msgWarning(content) { + ElMessage.warning(content) + }, + // 弹出提示 + alert(content) { + ElMessageBox.alert(content, "系统提示") + }, + // 错误提示 + alertError(content) { + ElMessageBox.alert(content, "系统提示", { type: 'error' }) + }, + // 成功提示 + alertSuccess(content) { + ElMessageBox.alert(content, "系统提示", { type: 'success' }) + }, + // 警告提示 + alertWarning(content) { + ElMessageBox.alert(content, "系统提示", { type: 'warning' }) + }, + // 通知提示 + notify(content) { + ElNotification.info(content) + }, + // 错误通知 + notifyError(content) { + ElNotification.error(content) + }, + // 成功通知 + notifySuccess(content) { + ElNotification.success(content) + }, + // 警告通知 + notifyWarning(content) { + ElNotification.warning(content) + }, + // 确认窗体 + confirm(content) { + return ElMessageBox.confirm(content, "系统提示", { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: "warning", + }) + }, + // 提交内容 + prompt(content) { + return ElMessageBox.prompt(content, "系统提示", { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: "warning", + }) + }, + // 打开遮罩层 + loading(content) { + loadingInstance = ElLoading.service({ + lock: true, + text: content, + 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..ed20948 --- /dev/null +++ b/src/plugins/tab.js @@ -0,0 +1,71 @@ +import { useTagsViewStore } from '@/store/modules/tagsView' +import router from '@/router' + +export default { + // 刷新当前tab页签 + refreshPage(obj) { + const { path, query, matched } = router.currentRoute.value + 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 useTagsViewStore().delCachedView(obj).then(() => { + const { path, query } = obj + router.replace({ + path: '/redirect' + path, + query: query + }) + }) + }, + // 关闭当前tab页签,打开新页签 + closeOpenPage(obj) { + useTagsViewStore().delView(router.currentRoute.value) + if (obj !== undefined) { + return router.push(obj) + } + }, + // 关闭指定tab页签 + closePage(obj) { + if (obj === undefined) { + return useTagsViewStore().delView(router.currentRoute.value).then(({ visitedViews }) => { + const latestView = visitedViews.slice(-1)[0] + if (latestView) { + return router.push(latestView.fullPath) + } + return router.push('/') + }) + } + return useTagsViewStore().delView(obj) + }, + // 关闭所有tab页签 + closeAllPage() { + return useTagsViewStore().delAllViews() + }, + // 关闭左侧tab页签 + closeLeftPage(obj) { + return useTagsViewStore().delLeftTags(obj || router.currentRoute.value) + }, + // 关闭右侧tab页签 + closeRightPage(obj) { + return useTagsViewStore().delRightTags(obj || router.currentRoute.value) + }, + // 关闭其他tab页签 + closeOtherPage(obj) { + return useTagsViewStore().delOthersViews(obj || router.currentRoute.value) + }, + // 打开tab页签 + openPage(title, url, params) { + const obj = { path: url, meta: { title: title } } + useTagsViewStore().addView(obj) + return router.push({ path: url, query: params }) + }, + // 修改tab页签 + updatePage(obj) { + return useTagsViewStore().updateVisitedView(obj) + } +} diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..c8c283b --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,762 @@ +import { createWebHistory, createRouter } from 'vue-router' +/* Layout */ +import Layout from '@/layout' + +/** + * Note: 路由配置项 + * + * hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1 + * alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 + * // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面 + * // 若你想不管路由下面的 children 声明的个数都显示你的根路由 + * // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由 + * redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 + * name:'router-name' // 设定路由的名字,一定要填写不然使用时会出现各种问题 + * query: '{"id": 1, "name": "ry"}' // 访问路由的默认传递参数 + * roles: ['admin', 'common'] // 访问路由的角色权限 + * permissions: ['a:a:a', 'b:b:b'] // 访问路由的菜单权限 + * meta : { + noCache: true // 如果设置为true,则不会被 缓存(默认 false) + title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 + icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg + breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示 + activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。 + } + */ + +// 封装一个生成通配符路由的函数 +const createCatchAllRoute = (component, name = 'NotFound') => { + return { + path: '/:pathMatch(.*)*', + name, + component + } +} + +// 公共路由 +export const constantRoutes = [ + { + path: '/redirect', + component: Layout, + hidden: true, + children: [ + { + path: '/redirect/:path(.*)', + component: createCatchAllRoute(() => import('@/views/redirect')) + + } + ] + }, + { + path: '/login', + component: () => import('@/views/login'), + hidden: true + }, + { + path: '/register', + component: () => import('@/views/register'), + hidden: true + }, + { + path: '/404', + component: () => import('@/views/error/404'), + hidden: true + }, + { + path: '/401', + component: () => import('@/views/error/401'), + hidden: true + }, + // { + // path: '', + // component: Layout, + // redirect: 'index', + // children: [ + // { + // path: 'index', + // component: () => import('@/views/index'), + // name: 'Index', + // meta: { title: '工作台', icon: 'index' } + // // meta: { title: '首页', icon: '@/assets/treeIcons/index.png', affix: true } affix 是否常驻 + // }, + // ] + // }, + { + path: '', + component: Layout, + redirect: 'index', + hidden: true, + children: [ + { + path: 'index', + component: () => import('@/views/index'), + name: 'index', + meta: { + title: '驾驶舱', + icon: 'plan', + } + }, + ] + }, + { + path: '', + component: Layout, + redirect: 'plan', + hidden: true, + children: [ + { + path: 'plan', + component: () => import('@/views/plan'), + name: 'plan', + meta: { title: '平面图', icon: 'plan' } + }, + + ] + }, + { + name: "Device", + alwaysShow: true, + component: Layout, + hidden: false, + name: "Device", + path: "/Device", + redirect: "noRedirect", + meta: { + icon: "device", + link: null, + noCache: false, + title: "设备管理", + }, + children: [ + { + component: () => import('@/views/Device/deviceControl'), + hidden: false, + name: "deviceControl", + path: "deviceControl", + meta: { + icon: "server", + link: null, + noCache: false, + title: "设备列表", + }, + }, + { + component: () => import('@/views/Device/ledger'), + hidden: false, + name: "ledger", + path: "ledger", + meta: { + icon: "sbtz", + link: null, + noCache: false, + title: "设备台账", + }, + }, + + ] + + }, + { + name: "linkConfig", + alwaysShow: true, + component: Layout, + hidden: false, + name: "linkConfig", + path: "/linkConfig", + redirect: "noRedirect", + meta: { + icon: "link", + link: null, + noCache: false, + title: "联动配置管理", + }, + children: [ + { + component: () => import('@/views/linkConfig/alarmConfig'), + hidden: false, + name: "alarmConfig", + path: "alarmConfig", + meta: { + icon: "gjdj", + link: null, + noCache: false, + title: "报警等级配置", + }, + }, + { + component: () => import('@/views/linkConfig/fanLinkConfig'), + hidden: false, + name: "fanLinkConfig", + path: "fanLinkConfig", + meta: { + icon: "fan", + link: null, + noCache: false, + title: "风机联动阈值配置", + }, + }, + // { + // component: () => import('@/views/linkConfig/pumpLinkConfig'), + // hidden: false, + // name: "pumpLinkConfig", + // path: "pumpLinkConfig", + // meta: { + // icon: "pump", + // link: null, + // noCache: false, + // title: "水泵联动阈值配置", + // }, + // }, + { + component: () => import('@/views/linkConfig/sensorConfig'), + hidden: false, + name: "sensorConfig", + path: "sensorConfig", + meta: { + icon: "cgq", + link: null, + noCache: false, + title: "传感器报警阈值", + }, + }, + ] + }, + + { + name: "Equipment", + alwaysShow: true, + component: Layout, + hidden: false, + name: "Equipment", + path: "/equipment", + redirect: "noRedirect", + meta: { + icon: "xtjk", + link: null, + noCache: false, + title: "智能化控制系统", + }, + children: [ + { + component: () => import('@/views/equipment/environmentMonitoring'), + + hidden: false, + name: "environmentMonitoring", + path: "environmentMonitoring", + meta: { + icon: "hjkz", + link: null, + noCache: false, + title: "环境监测", + }, + }, + { + component: () => import('@/views/equipment/ventilation'), + + hidden: false, + name: "ventilation", + path: "ventilation", + meta: { + icon: "tongf", + link: null, + noCache: false, + title: "通风", + }, + }, + { + component: () => import('@/views/equipment/electric'), + hidden: false, + name: "electric", + path: "electric", + meta: { + icon: "dianli", + link: null, + noCache: false, + title: "电力通信", + }, + }, + { + component: () => import('@/views/equipment/lighting'), + hidden: false, + name: "lighting", + path: "lighting", + meta: { + icon: "hjkz-zmkz", + link: null, + noCache: false, + title: "照明", + }, + }, + { + component: () => import('@/views/equipment/wastewater'), + hidden: false, + name: "wastewater", + path: "wastewater", + meta: { + icon: "nhgl-sbjc", + link: null, + noCache: false, + // title: "水泵", + title: "水泵", + }, + }, + { + component: () => import('@/views/equipment/ollPump'), + hidden: false, + name: "ollPump", + path: "ollPump", + meta: { + icon: "nhgl-sbjc", + link: null, + noCache: false, + title: "油泵", + }, + }, + { + component: () => import('@/views/equipment/air'), + hidden: false, + name: "air", + path: "air", + meta: { + icon: "ktjz", + link: null, + noCache: false, + title: "空调机组", + }, + }, + ], + }, + + { + name: "areaManage", + alwaysShow: true, + component: Layout, + hidden: false, + name: "areaManage", + path: "/areaManage", + redirect: "noRedirect", + meta: { + icon: "qygl", + link: null, + noCache: false, + title: "区域管理", + }, + children: [ + { + component: () => import('@/views/areaManage/area'), + hidden: false, + name: "area", + path: "area", + meta: { + icon: "areai", + link: null, + noCache: false, + title: "分区管理", + }, + }, + { + component: () => import('@/views/areaManage/cabin'), + hidden: false, + name: "cabin", + path: "cabin", + meta: { + icon: "cabini", + link: null, + noCache: false, + title: "房间管理", + }, + }, + ] + }, + { + name: "dataManage", + alwaysShow: true, + component: Layout, + hidden: false, + name: "dataManage", + path: "/dataManage", + redirect: "noRedirect", + meta: { + icon: "sjgl", + link: null, + noCache: false, + title: "数据管理", + }, + children: [ + { + component: () => import('@/views/dataManage/env'), + hidden: false, + name: "env", + path: "env", + meta: { + icon: "hjkz", + link: null, + noCache: false, + title: "环境监测", + }, + }, + { + component: () => import('@/views/dataManage/electric'), + hidden: false, + name: "electricData", + path: "electricData", + meta: { + icon: "dianli", + link: null, + noCache: false, + title: "电力通信", + }, + } + ] + }, + + { + name: "operationManage", + alwaysShow: true, + component: Layout, + hidden: false, + name: "operationManage", + path: "/operationManage", + redirect: "noRedirect", + meta: { + icon: "ywgl", + link: null, + noCache: false, + title: "运维管理", + }, + children: [ + { + component: () => import('@/views/operationManage/maintenance'), + hidden: false, + name: "maintenance", + path: "maintenance", + meta: { + icon: "wbgl", + link: null, + noCache: false, + title: "维保管理", + }, + }, + // { + // component: () => import('@/views/operationManage/patrol'), + // hidden: false, + // name: "patrol", + // path: "patrol", + // meta: { + // icon: "xjgl", + // link: null, + // noCache: false, + // title: "巡检管理", + // }, + // }, + { + component: () => import('@/views/operationManage/alarm'), + hidden: false, + name: "alarm", + path: "alarm", + meta: { + icon: "bjgl", + link: null, + noCache: false, + title: "报警管理", + }, + }, + // { + // component: () => import('@/views/operationManage/report'), + // hidden: false, + // name: "report", + // path: "report", + // meta: { + // icon: "bbgl", + // link: null, + // noCache: false, + // title: "报表管理", + // }, + // }, + ] + }, + + // { + // name: "EngineerSupport", + // alwaysShow: true, + // component: Layout, + // hidden: false, + // name: "EngineerSupport", + // path: "/EngineerSupport", + // redirect: "noRedirect", + // meta: { + // icon: "gongc", + // link: null, + // noCache: false, + // title: "工程保障系统", + // }, + // children: [ + // { + // component: () => import('@/views/EngineerSupport/etherphone'), + // hidden: false, + // name: "etherphone", + // path: "etherphone", + // meta: { + // icon: "guangb", + // link: null, + // noCache: false, + // title: "广播电话", + // }, + // }, + // { + // component: () => import('@/views/EngineerSupport/visualizedDispatch'), + // hidden: false, + // name: "visualizedDispatch", + // path: "visualizedDispatch", + // meta: { + // icon: "kshtd", + // link: null, + // noCache: false, + // title: "可视化调度", + // }, + // }, + + // ] + + // }, + { + name: "Security", + alwaysShow: true, + component: Layout, + hidden: false, + name: "Security", + path: "/Security", + redirect: "noRedirect", + meta: { + icon: "afxt", + link: null, + noCache: false, + title: "安防系统", + }, + children: [ + { + component: () => import('@/views/Security/videoSurveillance'), + hidden: false, + name: "videoSurveillance", + path: "videoSurveillance", + meta: { + icon: "afmj", + link: null, + noCache: false, + title: "视频监控", + }, + }, + { + component: () => import('@/views/Security/doorControl'), + hidden: false, + name: "doorControl", + path: "doorControl", + meta: { + icon: "spjk", + link: null, + noCache: false, + title: "门禁", + }, + }, + ] + + }, + { + path: '', + component: Layout, + redirect: 'propertyManage', + children: [ + { + path: 'propertyManage', + component: () => import('@/views/propertyManage'), + name: 'propertyManage', + meta: { title: '资产管理', icon: 'plan' } + }, + + ] + }, + { + name: "System", + alwaysShow: true, + component: Layout, + hidden: false, + name: "System", + path: "/system", + redirect: "noRedirect", + meta: { + icon: "xtgl", + link: null, + noCache: false, + title: "系统管理", + }, + children: [ + { + component: () => import('@/views/system/user/index'), + hidden: false, + name: "user", + path: "user", + meta: { + icon: "user", + link: null, + noCache: false, + title: "用户管理", + }, + }, + { + component: () => import('@/views/system/role/index'), + hidden: false, + name: "role", + path: "role", + meta: { + icon: "peoples", + link: null, + noCache: false, + title: "角色管理", + }, + }, + { + component: () => import('@/views/system/dict/index'), + hidden: false, + name: "dict", + path: "dict", + meta: { + icon: "dict", + link: null, + noCache: false, + title: "字典管理", + }, + }, + // { + // component: () => import('@/views/system/menu/index'), + // hidden: false, + // name: "menu", + // path: "menu", + // meta: { + // icon: "menu", + // link: null, + // noCache: false, + // title: "菜单管理", + // }, + // }, + + { + component: () => import('@/views/system/log/index'), + hidden: false, + name: "log", + path: "log", + meta: { + icon: "log", + link: null, + noCache: false, + title: "日志管理", + }, + }, + { + component: () => import('@/views/system/manual/index'), + hidden: false, + name: "manual", + path: "manual", + meta: { + icon: "documentation", + link: null, + noCache: false, + title: "操作手册", + }, + }, + ] + + } + + +] + +// 动态路由,基于用户权限动态去加载 +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' } + } + ] + } +] + + + + + +const router = createRouter({ + history: createWebHistory(), + routes: constantRoutes, + scrollBehavior(to, from, savedPosition) { + if (savedPosition) { + return savedPosition + } + return { top: 0 } + }, +}) + +export default router diff --git a/src/settings.js b/src/settings.js new file mode 100644 index 0000000..0d8dc12 --- /dev/null +++ b/src/settings.js @@ -0,0 +1,62 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-26 11:23:42 + * @Description: + */ +export default { + /** + * 网页标题 + */ + title: import.meta.env.VITE_APP_TITLE, + + /** + * 侧边栏主题 深色主题theme-dark,浅色主题theme-light + */ + sideTheme: 'theme-dark', + + /** + * 是否系统布局配置 + */ + showSettings: true, + + /** + * 是否显示顶部导航 + */ + topNav: false, + + /** + * 是否显示 tagsView + */ + tagsView: true, + + /** + * 显示页签图标 + */ + tagsIcon: false, + + /** + * 是否固定头部 + */ + fixedHeader: false, + + /** + * 是否显示logo + */ + sidebarLogo: true, + + /** + * 是否显示动态标题 + */ + dynamicTitle: false, + + /** + * 是否显示底部版权 + */ + footerVisible: false, + + /** + * 底部版权文本内容 + */ + footerContent: 'Copyright © 2018-2025 RuoYi. All Rights Reserved.' +} + diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 0000000..f45e27e --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,10 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-02 13:27:08 + * @Description: + */ +import { createPinia } from 'pinia' + +const store = createPinia() + +export default store \ No newline at end of file diff --git a/src/store/modules/app.js b/src/store/modules/app.js new file mode 100644 index 0000000..7cf2cdc --- /dev/null +++ b/src/store/modules/app.js @@ -0,0 +1,48 @@ +import { defineStore } from 'pinia' +import Cookies from 'js-cookie' + +export const useAppStore = defineStore('app', { + state: () => ({ + sidebar: { + opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, + withoutAnimation: false, + hide: false + }, + device: 'desktop', + size: Cookies.get('size') || 'medium' + }), + + actions: { + toggleSideBar() { + if (this.sidebar.hide) { + return false + } + this.sidebar.opened = !this.sidebar.opened + this.sidebar.withoutAnimation = false + if (this.sidebar.opened) { + Cookies.set('sidebarStatus', 1) + } else { + Cookies.set('sidebarStatus', 0) + } + }, + + closeSideBar(withoutAnimation) { + Cookies.set('sidebarStatus', 0) + this.sidebar.opened = false + this.sidebar.withoutAnimation = withoutAnimation + }, + + toggleDevice(device) { + this.device = device + }, + + setSize(size) { + this.size = size + Cookies.set('size', size) + }, + + toggleSideBarHide(status) { + this.sidebar.hide = status + } + } +}) diff --git a/src/store/modules/dict.js b/src/store/modules/dict.js new file mode 100644 index 0000000..637a2fb --- /dev/null +++ b/src/store/modules/dict.js @@ -0,0 +1,38 @@ +import { defineStore } from 'pinia' + +export const useDictStore = defineStore('dict', { + state: () => ({ + dict: [] + }), + + actions: { + // 设置字典 + setDict(data) { + if (data.key !== null && data.key !== "") { + this.dict.push({ + key: data.key, + value: data.value + }) + } + }, + + // 删除字典 + removeDict(key) { + try { + for (let i = 0; i < this.dict.length; i++) { + if (this.dict[i].key == key) { + this.dict.splice(i, 1) + return true + } + } + } catch (e) { + // 处理错误 + } + }, + + // 清空字典 + cleanDict() { + this.dict = [] + } + } +}) diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js new file mode 100644 index 0000000..0c2e41e --- /dev/null +++ b/src/store/modules/permission.js @@ -0,0 +1,141 @@ +import { defineStore } from 'pinia' +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" + +export const usePermissionStore = defineStore('permission', { + state: () => ({ + routes: [], + addRoutes: [], + defaultRoutes: [], + topbarRouters: [], + sidebarRouters: [], + }), + + actions: { + // 生成路由 + GenerateRoutes() { + return new Promise((resolve) => { + // 向后端请求路由数据 + const newMenu = [] + let data = [] + const sdata = JSON.parse(JSON.stringify(data)) + const rdata = JSON.parse(JSON.stringify(data)) + const sidebarRoutes = filterAsyncRouter(sdata) + const rewriteRoutes = filterAsyncRouter(rdata, false, true) + const asyncRoutes = filterDynamicRoutes(dynamicRoutes) + rewriteRoutes.push({ path: "/:pathMatch(.*)*", redirect: "/404", hidden: true }) + this.addRoutes = rewriteRoutes + this.routes = constantRoutes.concat(rewriteRoutes) + this.sidebarRouters = constantRoutes.concat(sidebarRoutes) + this.defaultRoutes = sidebarRoutes + this.topbarRouters = sidebarRoutes + + resolve(rewriteRoutes) + + return + getRouters().then((res) => { + res.data = [...newMenu] + 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: "/:pathMatch(.*)*", redirect: "/404", hidden: true }) + this.addRoutes = rewriteRoutes + this.routes = constantRoutes.concat(rewriteRoutes) + this.sidebarRouters = constantRoutes.concat(sidebarRoutes) + this.defaultRoutes = sidebarRoutes + this.topbarRouters = 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 + if (el.children && el.children.length) { + children = children.concat(filterChildren(el.children, el)) + return + } + } + 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}.vue`); + } +} + diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js new file mode 100644 index 0000000..b132417 --- /dev/null +++ b/src/store/modules/settings.js @@ -0,0 +1,40 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-26 11:23:54 + * @Description: + */ +import { defineStore } from 'pinia' +import defaultSettings from '@/settings' + +const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings + +const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '' + +export const useSettingsStore = defineStore('settings', { + state: () => ({ + title: '', + isDark: false, + 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 + }), + + actions: { + // 修改布局设置 + changeSetting(data) { + if (this.hasOwnProperty(data.key)) { + this[data.key] = data.value + } + }, + // 设置网页标题 + setTitle(title) { + this.title = title + } + } +}) + diff --git a/src/store/modules/tagsView.js b/src/store/modules/tagsView.js new file mode 100644 index 0000000..148cef9 --- /dev/null +++ b/src/store/modules/tagsView.js @@ -0,0 +1,200 @@ +import { defineStore } from 'pinia' + +export const useTagsViewStore = defineStore('tagsView', { + state: () => ({ + visitedViews: [], + cachedViews: [], + iframeViews: [] + }), + + actions: { + addView(view) { + this.addVisitedView(view) + this.addCachedView(view) + }, + + addIframeView(view) { + if (this.iframeViews.some(v => v.path === view.path)) return + this.iframeViews.push( + Object.assign({}, view, { + title: view.meta.title || 'no-name' + }) + ) + }, + + addVisitedView(view) { + if (this.visitedViews.some(v => v.path === view.path)) return + this.visitedViews.push( + Object.assign({}, view, { + title: view.meta.title || 'no-name' + }) + ) + }, + + addCachedView(view) { + if (this.cachedViews.includes(view.name)) return + if (view.meta && !view.meta.noCache) { + this.cachedViews.push(view.name) + } + }, + + delView(view) { + return new Promise(resolve => { + this.delVisitedView(view) + this.delCachedView(view) + resolve({ + visitedViews: [...this.visitedViews], + cachedViews: [...this.cachedViews] + }) + }) + }, + + delVisitedView(view) { + return new Promise(resolve => { + for (const [i, v] of this.visitedViews.entries()) { + if (v.path === view.path) { + this.visitedViews.splice(i, 1) + break + } + } + this.iframeViews = this.iframeViews.filter(item => item.path !== view.path) + resolve([...this.visitedViews]) + }) + }, + + delIframeView(view) { + return new Promise(resolve => { + this.iframeViews = this.iframeViews.filter(item => item.path !== view.path) + resolve([...this.iframeViews]) + }) + }, + + delCachedView(view) { + return new Promise(resolve => { + const index = this.cachedViews.indexOf(view.name) + index > -1 && this.cachedViews.splice(index, 1) + resolve([...this.cachedViews]) + }) + }, + + delOthersViews(view) { + return new Promise(resolve => { + this.delOthersVisitedViews(view) + this.delOthersCachedViews(view) + resolve({ + visitedViews: [...this.visitedViews], + cachedViews: [...this.cachedViews] + }) + }) + }, + + delOthersVisitedViews(view) { + return new Promise(resolve => { + this.visitedViews = this.visitedViews.filter(v => { + return v.meta.affix || v.path === view.path + }) + this.iframeViews = this.iframeViews.filter(item => item.path === view.path) + resolve([...this.visitedViews]) + }) + }, + + delOthersCachedViews(view) { + return new Promise(resolve => { + const index = this.cachedViews.indexOf(view.name) + if (index > -1) { + this.cachedViews = this.cachedViews.slice(index, index + 1) + } else { + this.cachedViews = [] + } + resolve([...this.cachedViews]) + }) + }, + + delAllViews(view) { + return new Promise(resolve => { + this.delAllVisitedViews(view) + this.delAllCachedViews(view) + resolve({ + visitedViews: [...this.visitedViews], + cachedViews: [...this.cachedViews] + }) + }) + }, + + delAllVisitedViews() { + return new Promise(resolve => { + // keep affix tags + const affixTags = this.visitedViews.filter(tag => tag.meta.affix) + this.visitedViews = affixTags + this.iframeViews = [] + resolve([...this.visitedViews]) + }) + }, + + delAllCachedViews() { + return new Promise(resolve => { + this.cachedViews = [] + resolve([...this.cachedViews]) + }) + }, + + updateVisitedView(view) { + for (let v of this.visitedViews) { + if (v.path === view.path) { + v = Object.assign(v, view) + break + } + } + }, + + delRightTags(view) { + return new Promise(resolve => { + const index = this.visitedViews.findIndex(v => v.path === view.path) + if (index === -1) { + resolve([...this.visitedViews]) + return + } + this.visitedViews = this.visitedViews.filter((item, idx) => { + if (idx <= index || (item.meta && item.meta.affix)) { + return true + } + const i = this.cachedViews.indexOf(item.name) + if (i > -1) { + this.cachedViews.splice(i, 1) + } + if(item.meta.link) { + const fi = this.iframeViews.findIndex(v => v.path === item.path) + this.iframeViews.splice(fi, 1) + } + return false + }) + resolve([...this.visitedViews]) + }) + }, + + delLeftTags(view) { + return new Promise(resolve => { + const index = this.visitedViews.findIndex(v => v.path === view.path) + if (index === -1) { + resolve([...this.visitedViews]) + return + } + this.visitedViews = this.visitedViews.filter((item, idx) => { + if (idx >= index || (item.meta && item.meta.affix)) { + return true + } + const i = this.cachedViews.indexOf(item.name) + if (i > -1) { + this.cachedViews.splice(i, 1) + } + if(item.meta.link) { + const fi = this.iframeViews.findIndex(v => v.path === item.path) + this.iframeViews.splice(fi, 1) + } + return false + }) + resolve([...this.visitedViews]) + }) + } + } +}) diff --git a/src/store/modules/user.js b/src/store/modules/user.js new file mode 100644 index 0000000..d3fac7a --- /dev/null +++ b/src/store/modules/user.js @@ -0,0 +1,106 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-26 11:24:16 + * @Description: + */ +import { defineStore } from 'pinia' +import { login, logout, getInfo } from "@/api/login" +import { managementListAll } from "@/api/system/area" +import { getToken, setToken, removeToken } from "@/utils/auth" +import profileImg from "@/assets/images/profile.jpg"; + +export const useUserStore = defineStore('user', { + state: () => ({ + token: getToken(), + id: "", + name: "", + avatar: "", + roles: [], + permissions: [], + firstArea: [], + }), + + actions: { + // 登录 + Login(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) => { + if(res && res.code == 200) { + setToken(res.data.token) + this.token = res.data.token; + + let VITE_VUE_APP_BASE_FILEURL = import.meta.env.VITE_VUE_APP_BASE_FILEURL; + + const user = res.data.user; + const avatar = user.avatar ? VITE_VUE_APP_BASE_FILEURL + user.avatar : profileImg; + + if (res.data.roles && res.data.roles.length > 0) { + console.log("获取用户信息") + // 验证返回的roles是否是一个非空数组 + this.roles = res.data.roles + this.permissions = res.data.permissions + } else { + this.roles = ["ROLE_DEFAULT"] + } + + this.id = user.userId + this.name = user.userName + this.avatar = avatar + resolve() + } + }) + .catch((error) => { + reject(error) + }) + }) + }, + + GetFirstArea() { + return new Promise((resolve, reject) => { + managementListAll() + .then((res) => { + var firstArea = res.data.filter((item) => item.parentId == null) + if (res.data && res.data.length > 0) { + this.firstArea = firstArea + resolve(res.data) + } + }) + .catch((error) => { + reject(error) + }) + }) + }, + + // 退出系统 + logOut() { + return new Promise((resolve, reject) => { + logout(this.token) + .then(() => { + this.token = "" + this.roles = [] + this.permissions = [] + removeToken() + resolve() + }) + .catch((error) => { + reject(error) + }) + }) + }, + + // 前端 登出 + FedLogOut() { + return new Promise((resolve) => { + this.token = "" + removeToken() + resolve() + }) + }, + }, +}) + diff --git a/src/utils/ExcelExporter.js b/src/utils/ExcelExporter.js new file mode 100644 index 0000000..47dd636 --- /dev/null +++ b/src/utils/ExcelExporter.js @@ -0,0 +1,370 @@ +/** + * Excel导出组件(支持表头宽度配置) + * 依赖SheetJS库(xlsx),使用前请确保已引入 + * 用法: + * const exporter = new ExcelExporter(headers, data); + * exporter.export('文件名'); + */ + +import * as XLSX from 'xlsx' +import { ElMessage } from 'element-plus' + +class ExcelExporter { + /** + * 构造函数 + * @param {Array} headers 表头配置数组 + * @param {Array} data 要导出的数据数组 + * @param {Object} options 配置选项 + * headers格式: [{ + * field: '字段名', + * header: '表头名称', + * selected: true/false, + * width: 列宽(数字,单位:字符宽度) + * }] + */ + constructor(headers, data, options = {}) { + // 验证参数 + if (!Array.isArray(headers) || headers.length === 0) { + throw new Error('表头配置不能为空'); + } + if (!Array.isArray(data)) { + throw new Error('数据必须是数组'); + } + + // 表头配置(处理width字段,默认值10) + this.headers = headers.map(header => ({ + field: header.field, + header: header.header || header.field, + selected: header.selected !== undefined ? header.selected : true, + width: typeof header.width === 'number' && header.width > 0 ? header.width : 10 + })); + + // 数据 + this.data = data; + + // 配置选项 + this.options = { + defaultFilename: '导出数据', + defaultColWidth: 10, + ...options + }; + + // 创建导出配置面板 + this.initExportPanel(); + } + + /** + * 初始化导出配置面板 + */ + initExportPanel() { + // 创建面板元素 + this.panel = document.createElement('div'); + this.panel.className = 'excel-exporter-panel'; + this.panel.style.cssText = ` + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 700px; + background: white; + border-radius: 8px; + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); + z-index: 1000; + display: none; + `; + + // 面板标题 + const title = document.createElement('div'); + title.className = 'excel-exporter-title'; + title.style.cssText = ` + padding: 16px; + border-bottom: 1px solid #eee; + font-size: 18px; + font-weight: 500; + display: flex; + justify-content: space-between; + align-items: center; + `; + title.innerHTML = ` + 导出Excel配置 + + `; + this.panel.appendChild(title); + + // 表头配置区域 + const headerConfig = document.createElement('div'); + headerConfig.className = 'excel-exporter-header-config'; + headerConfig.style.cssText = ` + padding: 4px 16px; + overflow-y: auto; + `; + + // 创建表头配置表格(新增列宽设置列) + let tableHtml = ` +

自定义表头列

+ + + + + + + + + + + `; + + // 填充表头配置 + this.headers.forEach((header, index) => { + tableHtml += ` + + + + + + + `; + }); + + tableHtml += ` + +
选择数据字段表头名称列宽(字符)
+ + ${header.field} + + + +
+ `; + headerConfig.innerHTML = tableHtml; + this.panel.appendChild(headerConfig); + + // 文件名设置区域 + const filenameArea = document.createElement('div'); + filenameArea.className = 'excel-exporter-filename'; + filenameArea.style.cssText = ` + padding: 0 16px 16px; + `; + filenameArea.innerHTML = ` +
文件名
+ + `; + this.panel.appendChild(filenameArea); + + // 按钮区域 + const buttonArea = document.createElement('div'); + buttonArea.className = 'excel-exporter-buttons'; + buttonArea.style.cssText = ` + padding: 12px 16px; + border-top: 1px solid #eee; + text-align: right; + `; + buttonArea.innerHTML = ` + + + `; + this.panel.appendChild(buttonArea); + + // 遮罩层 + this.mask = document.createElement('div'); + this.mask.className = 'excel-exporter-mask'; + this.mask.style.cssText = ` + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + z-index: 999; + display: none; + `; + + // 添加到文档 + document.body.appendChild(this.mask); + document.body.appendChild(this.panel); + + // 绑定事件 + this.bindEvents(); + } + + /** + * 绑定事件 + */ + bindEvents() { + // 关闭按钮 + this.panel.querySelector('.excel-exporter-close').addEventListener('click', () => { + this.hidePanel(); + }); + + // 取消按钮 + this.panel.querySelector('.excel-exporter-cancel').addEventListener('click', () => { + this.hidePanel(); + }); + + // 遮罩层点击 + this.mask.addEventListener('click', () => { + this.hidePanel(); + }); + + // 确认导出按钮 + this.panel.querySelector('.excel-exporter-confirm').addEventListener('click', () => { + this.processExport(); + }); + + // 表头选择框事件 + this.panel.querySelectorAll('.header-checkbox').forEach(checkbox => { + checkbox.addEventListener('change', (e) => { + const index = parseInt(e.target.dataset.index); + this.headers[index].selected = e.target.checked; + }); + }); + + // 表头输入框事件 + this.panel.querySelectorAll('.header-input').forEach(input => { + input.addEventListener('input', (e) => { + const index = parseInt(e.target.dataset.index); + this.headers[index].header = e.target.value; + }); + }); + + // 列宽输入框事件(新增) + this.panel.querySelectorAll('.header-width').forEach(input => { + input.addEventListener('change', (e) => { + const index = parseInt(e.target.dataset.index); + const width = parseInt(e.target.value); + if (!isNaN(width) && width >= 5 && width <= 50) { + this.headers[index].width = width; + } + }); + }); + } + + /** + * 显示导出配置面板 + */ + showPanel() { + this.panel.style.display = 'block'; + this.mask.style.display = 'block'; + } + + /** + * 隐藏导出配置面板 + */ + hidePanel() { + this.panel.style.display = 'none'; + this.mask.style.display = 'none'; + } + + /** + * 处理导出逻辑(新增列宽设置) + */ + processExport() { + // 获取选中的表头 + const selectedHeaders = this.headers.filter(header => header.selected); + + if (selectedHeaders.length === 0) { + ElMessage.error('请至少选择一列导出:'); + return; + } + + // 获取文件名 + const filenameInput = this.panel.querySelector('.filename-input'); + let filename = filenameInput.value.trim() || this.options.defaultFilename; + if (!filename.endsWith('.xlsx')) { + filename += '.xlsx'; + } + + // 处理数据 + const exportData = this.data.map(row => { + const formattedRow = {}; + selectedHeaders.forEach(header => { + // 支持嵌套字段,如 'user.name' + if (header.field.includes('.')) { + const fields = header.field.split('.'); + let value = row; + for (const field of fields) { + if (value === undefined || value === null) break; + value = value[field]; + } + formattedRow[header.header] = value; + } else { + formattedRow[header.header] = row[header.field]; + } + }); + return formattedRow; + }); + + // 执行导出 + try { + // 创建工作表 + const worksheet = XLSX.utils.json_to_sheet(exportData); + + // 设置列宽(新增核心逻辑) + worksheet['!cols'] = selectedHeaders.map(header => ({ + wch: header.width // wch表示字符宽度 + })); + + // 创建工作簿并添加工作表 + const workbook = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(workbook, worksheet, '数据'); + + // 导出文件 + XLSX.writeFile(workbook, filename); + + // 隐藏面板并提示 + this.hidePanel(); + ElMessage.success('数据导出成功'); + } catch (error) { + ElMessage.error('导出失败: ' + error.message); + } + } + + /** + * 触发导出 + * @param {string} filename 可选的文件名 + */ + export(filename) { + if (filename) { + const filenameInput = this.panel.querySelector('.filename-input'); + if (filenameInput) { + filenameInput.value = filename; + } + } + this.showPanel(); + } + + /** + * 销毁组件,清理DOM + */ + destroy() { + if (this.panel && this.panel.parentNode) { + this.panel.parentNode.removeChild(this.panel); + } + if (this.mask && this.mask.parentNode) { + this.mask.parentNode.removeChild(this.mask); + } + } +} + + +export default ExcelExporter + \ No newline at end of file diff --git a/src/utils/auth.js b/src/utils/auth.js new file mode 100644 index 0000000..88d7b6c --- /dev/null +++ b/src/utils/auth.js @@ -0,0 +1,15 @@ +import Cookies from 'js-cookie' + +const TokenKey = 'Admin-Token' + +export function getToken() { + return Cookies.get(TokenKey) +} + +export function setToken(token) { + return Cookies.set(TokenKey, token) +} + +export function removeToken() { + return Cookies.remove(TokenKey) +} diff --git a/src/utils/client.js b/src/utils/client.js new file mode 100644 index 0000000..995f915 --- /dev/null +++ b/src/utils/client.js @@ -0,0 +1,604 @@ +import mqtt from "mqtt"; + +// 实例池,用于缓存相同配置的实例(仅用于MQTT) +const instancePool = new Map(); + +class DataMiddleware { + /** + * 构造函数 + * @param {Object} options - 实例配置 + */ + constructor(options = {}) { + // 存储实例配置 + this.options = { + url: options.url || '', + reconnectConfig: { + maxRetries: 10, //最大重连次数 + initialDelay: 1000, // + maxDelay: 30000, + ...options.reconnectConfig + }, + mqttOptions: options.mqttOptions || {}, + httpOptions: options.httpOptions || {}, + reconnect: true + }; + + // 存储所有请求/订阅的信息 + this.requests = { + http: new Map(), // HTTP请求仅用于跟踪当前请求以便取消 + mqtt: new Map() // MQTT订阅缓存: key为topic + }; + + // 客户端实例 + this.mqttClient = null; + + // 连接状态 + this.connectionStatus = { + mqtt: 'disconnected', // disconnected, connecting, connected, error + http: 'idle', + retryCount: 0 + }; + + // 用于生成唯一订阅ID + this.subscriptionIdCounter = 0; + } + + /** + * 获取实例的唯一标识键 + */ + getInstanceKey() { + return this.options.url; + } + + /** + * 静态方法:获取或创建实例 + */ + static getInstance(options = {}) { + const key = options.url || ''; + + if (instancePool.has(key)) { + return instancePool.get(key); + } + + const instance = new DataMiddleware(options); + instancePool.set(key, instance); + + return instance; + } + + /** + * 获取当前连接状态 + */ + getStatus() { + return { ...this.connectionStatus }; + } + + /** + * 获取当前MQTT客户端实例(用于发布消息) + */ + getMqttClient() { + return this.mqttClient; + } + + /** + * HTTP请求方法 - 优化参数处理,支持keys可选 + * @param {string} url - 请求地址 + * @param {string[]|Function} [keys] - 需要提取的key数组,可选 + * @param {Function} [callback] - 回调函数,格式: (data, error) => {},可选 + * @returns {Promise} 返回Promise对象,同时通过callback暴露结果 + */ + httpRequest(url, keys, callback) { + // 处理参数:支持keys可选,自动识别callback + let actualKeys = []; + let actualCallback = null; + + if (typeof keys === 'function') { + actualCallback = keys; + actualKeys = []; + } else if (Array.isArray(keys) && typeof callback === 'function') { + actualKeys = keys; + actualCallback = callback; + } else if (Array.isArray(keys)) { + actualKeys = keys; + actualCallback = null; + } else if (arguments.length === 1) { + actualKeys = []; + actualCallback = null; + } + + // 生成唯一请求ID + const requestId = this.generateSubscriptionId(); + + // 创建AbortController用于取消请求 + const controller = new AbortController(); + + // 存储请求信息以便后续取消 + this.requests.http.set(requestId, { + controller, + url + }); + + // 将keys数组转换为逗号分隔的字符串 + const keysStr = Array.isArray(actualKeys) && actualKeys.length > 0 + ? actualKeys.join(',') + : ''; + + // 构建URL并添加keys参数 + const fullUrl = new URL(url); + if (keysStr) { + fullUrl.searchParams.append('keys', keysStr); + } + + // 构建请求选项,禁用缓存 + const fetchOptions = { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Cache-Control': 'no-cache, no-store, must-revalidate', + 'Pragma': 'no-cache', + 'Expires': '0', + ...this.options.httpOptions.headers + }, + signal: controller.signal, + ...this.options.httpOptions + }; + + this.connectionStatus.http = 'loading'; + + // 返回Promise,同时支持callback + const promise = new Promise((resolve, reject) => { + fetch(fullUrl.toString(), fetchOptions) + .then(response => { + this.connectionStatus.http = 'idle'; + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response.json(); + }) + .then(data => { + // 请求完成后从跟踪表中移除 + this.requests.http.delete(requestId); + + // 根据keys过滤数据 + // const filteredData = this._filterDataByKeys(data, actualKeys); + + // 调用回调函数(如果提供) + if (typeof actualCallback === 'function') { + actualCallback(data, null); + } + + resolve(data); + }) + .catch(error => { + this.connectionStatus.http = 'idle'; + this.requests.http.delete(requestId); + + // 忽略取消请求的错误 + if (error.name !== 'AbortError') { + // 调用回调函数(如果提供) + if (typeof actualCallback === 'function') { + actualCallback(null, error); + } + reject(error); + } + }); + }); + + // 将请求ID附加到promise上,方便取消请求 + promise.requestId = requestId; + return promise; + } + + /** + * 取消HTTP请求 + * @param {string} requestId - 请求ID + * @returns {boolean} 是否取消成功 + */ + cancelHttpRequest(requestId) { + if (this.requests.http.has(requestId)) { + const { controller } = this.requests.http.get(requestId); + controller.abort(); + this.requests.http.delete(requestId); + return true; + } + return false; + } + + /** + * 连接到MQTT服务器 + */ + _connectMqtt() { + if (!this.options.url) { + console.error('MQTT WebSocket URL未配置'); + return; + } + + // 如果已有连接,先断开 + if (this.mqttClient) { + this.mqttClient.end(false, {}, () => { + console.log('已断开现有MQTT连接'); + }); + } + + this.connectionStatus.mqtt = 'connecting'; + this._notifyAllMqttSubscribers({ + type: 'status', + status: 'connecting' + }); + + // 使用mqtt.js连接 + this.mqttClient = mqtt.connect(this.options.url, { + clientId: `vue-client-${Math.random().toString(36).substr(2, 10)}`, + clean: true, + reconnectPeriod: 0, // 禁用内置重连,使用自定义重连策略 + ...this.options.mqttOptions + }); + + + // 连接成功回调 + this.mqttClient.on('connect', () => { + console.log('MQTT连接成功'); + this.connectionStatus.mqtt = 'connected'; + this.connectionStatus.retryCount = 0; + + // 通知所有订阅者 + this._notifyAllMqttSubscribers({ + type: 'status', + status: 'connected' + }); + + // 重新订阅所有主题 + this.requests.mqtt.forEach((info, topic) => { + this.mqttClient.subscribe(topic, { qos: info.qos }); + }); + }); + + // 收到消息回调 + this.mqttClient.on('message', (topic, message) => { + try { + const data = JSON.parse(message.toString()); + this._onMqttMessage(topic, data); + } catch (error) { + console.error('解析MQTT消息失败:', error); + this._notifyMqttError(topic, new Error('消息格式错误')); + } + }); + + // 连接断开回调 + this.mqttClient.on('close', () => { + if (this.connectionStatus.mqtt !== 'disconnected') { + console.log('MQTT连接已关闭'); + this.connectionStatus.mqtt = 'disconnected'; + this._notifyAllMqttSubscribers({ + type: 'status', + status: 'disconnected' + }); + if(this.reconnect) { + this._scheduleReconnect(); + } + } + }); + + // 错误回调 + this.mqttClient.on('error', (error) => { + console.error('MQTT错误:', error); + this.connectionStatus.mqtt = 'error'; + this._notifyAllMqttSubscribers({ + type: 'error', + error: new Error(`连接错误: ${error.message}`) + }); + }); + } + + /** + * 订阅MQTT主题 + */ + + + mqttSubscribe(topics, callback, options = {}) { + if (!this.options.url) { + throw new Error('MQTT WebSocket URL未配置'); + } + + // 验证输入参数 + if (!Array.isArray(topics) || topics.length === 0) { + throw new Error('请提供有效的主题数组'); + } + + if (typeof callback !== 'function') { + throw new Error('请提供回调函数'); + } + + const subIds = []; + + // 遍历主题数组,为每个主题创建订阅 + topics.forEach(topic => { + const subId = this.generateSubscriptionId(); + const mqttKey = topic; + + // 添加订阅者 + if (this.requests.mqtt.has(mqttKey)) { + const mqttInfo = this.requests.mqtt.get(mqttKey); + mqttInfo.subscribers[subId] = { callback }; + } else { + const mqttInfo = { + topic, + options, + subscribers: { + [subId]: { callback } + }, + qos: options.qos || 1 + }; + this.requests.mqtt.set(mqttKey, mqttInfo); + } + + subIds.push(subId); + }); + + // 连接MQTT(如果尚未连接) + if (!this.mqttClient || !this.mqttClient.connected) { + this._connectMqtt(); + } else { + // 已连接状态下直接订阅所有主题 + topics.forEach(topic => { + this.mqttClient.subscribe(topic, { qos: options.qos || 0 }); + }); + } + + // 返回所有订阅ID的数组 + return subIds; + } + + /** + * 处理接收到的MQTT消息 + */ + _onMqttMessage(topic, data) { + const mqttInfo = this.requests.mqtt.get(topic); + if (!mqttInfo) return; + + // 通知该主题的所有订阅者 + Object.values(mqttInfo.subscribers).forEach(({ keys, callback }) => { + try { + const filteredData = this._filterDataByKeys(data, keys); + callback({ + type: 'data', + data: filteredData, + topic, + timestamp: Date.now() + }, null); + } catch (error) { + console.error('通知MQTT订阅者失败:', error); + } + }); + } + + /** + * 发布MQTT消息 + */ + mqttPublish(topic, message, options = {}) { + return new Promise((resolve, reject) => { + if (!this.mqttClient || !this.mqttClient.connected) { + reject(new Error('MQTT客户端未连接')); + return; + } + + this.mqttClient.publish(topic, JSON.stringify(message), options, (error) => { + if (error) { + reject(error); + } else { + resolve(true); + } + }); + }); + } + + /** + * 安排重连 + */ + _scheduleReconnect() { + if (this.connectionStatus.retryCount >= this.options.reconnectConfig.maxRetries) { + console.error('已达到最大重连次数'); + return; + } + + this.connectionStatus.retryCount++; + const delay = Math.min( + this.options.reconnectConfig.initialDelay * Math.pow(2, this.connectionStatus.retryCount - 1), + this.options.reconnectConfig.maxDelay + ); + + console.log(`将在 ${delay}ms 后尝试重连 (第 ${this.connectionStatus.retryCount} 次)`); + + setTimeout(() => { + this._connectMqtt(); + }, delay); + } + + /** + * 计算重连延迟 + */ + _calculateReconnectDelay(attempt) { + const delay = this.options.reconnectConfig.initialDelay * Math.pow(2, attempt); + return Math.min(delay, this.options.reconnectConfig.maxDelay); + } + + /** + * 取消订阅 + */ + unsubscribe(data) { + if(data && data.length) { + data.forEach((d)=> { + this.unsubscribeFun(d); + }) + } + } + + + /** + * 取消订阅 + */ + unsubscribeFun(subId) { + // if (!['http', 'mqtt'].includes(type)) { + // console.error('无效的订阅类型'); + // return false; + // } + + let removed = false; + this.requests['mqtt'].forEach((info, key) => { + + if (info.subscribers && info.subscribers[subId]) { + delete info.subscribers[subId]; + removed = true; + console.log(info.subscribers,"----info.subscribers"); + + // 如果没有订阅者了,清理资源 + if (info.subscribers && Object.keys(info.subscribers).length === 0) { + console.log('移除------'); + this._cleanupRequest( key, info); + } + } + }); + + return removed; + } + + /** + * 清理不再有订阅者的请求/订阅 + */ + _cleanupRequest(key, info) { + if (this.mqttClient && this.mqttClient.connected) { + this.mqttClient.unsubscribe(info.topic); + } + this.requests.mqtt.delete(key); + if(!this.requests.mqtt.size) { + this.destroy(); + } + // if (type === 'http') { + // 清除HTTP请求的控制器 + // if (info.controller) { + // info.controller.abort(); + // } + // this.requests.http.delete(key); + // } else if (type === 'mqtt') { + // if (this.mqttClient && this.mqttClient.connected) { + // this.mqttClient.unsubscribe(info.topic); + // } + // this.requests.mqtt.delete(key); + // } + } + + /** + * 生成唯一订阅ID + */ + generateSubscriptionId() { + return `sub_${this.subscriptionIdCounter++}`; + } + + /** + * 根据key数组过滤数据 + */ + _filterDataByKeys(data, keys) { + if (!keys || keys.length === 0) { + return data; + } + + if (Array.isArray(data)) { + return data.map(item => this._filterObjectByKeys(item, keys)); + } + + return this._filterObjectByKeys(data, keys); + } + + /** + * 根据key数组过滤对象属性 + */ + _filterObjectByKeys(obj, keys) { + if (typeof obj !== 'object' || obj === null) { + return obj; + } + + return keys.reduce((result, key) => { + const value = this._getNestedValue(obj, key); + if (value !== undefined) { + result[key] = value; + } + return result; + }, {}); + } + + /** + * 获取对象的嵌套属性值 + */ + _getNestedValue(obj, key) { + return key.split('.').reduce((current, part) => { + if (current && typeof current === 'object' && part in current) { + return current[part]; + } + return undefined; + }, obj); + } + + /** + * 通知所有MQTT订阅者 + */ + _notifyAllMqttSubscribers(message) { + this.requests.mqtt.forEach((mqttInfo) => { + Object.values(mqttInfo.subscribers).forEach(({ callback }) => { + try { + if (message.error) { + callback(null, message.error); + } else { + callback(message, null); + } + } catch (err) { + console.error('通知MQTT订阅者失败:', err); + } + }); + }); + } + + /** + * 通知MQTT订阅者错误 + */ + _notifyMqttError(topic, error) { + const mqttInfo = this.requests.mqtt.get(topic); + if (!mqttInfo) return; + + Object.values(mqttInfo.subscribers).forEach(({ callback }) => { + try { + callback(null, error); + } catch (err) { + console.error('通知MQTT订阅者错误失败:', err); + } + }); + } + + /** + * 销毁实例 + */ + destroy() { + // 断开MQTT连接 + if (this.mqttClient) { + this.reconnect = false; + this.mqttClient.end(true); + this.mqttClient = null; + } + + // 取消所有HTTP请求 + // this.requests.http.forEach(info => { + // if (info.controller) { + // info.controller.abort(); + // } + // }); + + // 清空请求缓存 + // this.requests.http.clear(); + this.requests.mqtt.clear(); + + // 从实例池移除 + instancePool.delete(this.getInstanceKey()); + } +} + +export default DataMiddleware; \ No newline at end of file diff --git a/src/utils/dict.js b/src/utils/dict.js new file mode 100644 index 0000000..f0e7725 --- /dev/null +++ b/src/utils/dict.js @@ -0,0 +1,31 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-26 11:23:42 + * @Description: + */ +import { useDictStore } from '@/store/modules/dict' +import { getDicts } from '@/api/system/dict/data' + +/** + * 获取字典数据 + */ +export function useDict(...args) { + const res = ref({}) + return (() => { + args.forEach((dictType, index) => { + res.value[dictType] = [] + // const dicts = useDictStore().getDict(dictType) + // if (dicts) { + // res.value[dictType] = dicts + // } else { + getDicts(dictType).then(resp => { + if(resp && resp.data) { + res.value[dictType] = resp.data.map(p => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass })) + useDictStore().setDict(dictType, res.value[dictType]) + } + }) + // } + }) + return toRefs(res.value) + })() +} \ No newline at end of file diff --git a/src/utils/dynamicTitle.js b/src/utils/dynamicTitle.js new file mode 100644 index 0000000..22fc2b4 --- /dev/null +++ b/src/utils/dynamicTitle.js @@ -0,0 +1,14 @@ +import defaultSettings from '@/settings' +import { useSettingsStore } from '@/store/modules/settings' + +/** + * 动态修改标题 + */ +export function useDynamicTitle() { + const settingsStore = useSettingsStore() + if (settingsStore.dynamicTitle) { + document.title = settingsStore.title + ' - ' + defaultSettings.title + } else { + document.title = defaultSettings.title + } +} \ No newline at end of file diff --git a/src/utils/equipmentType.js b/src/utils/equipmentType.js new file mode 100644 index 0000000..dfedcf4 --- /dev/null +++ b/src/utils/equipmentType.js @@ -0,0 +1,29 @@ +/* + * @Author: 季万俊 + * @Date: 2025-06-18 09:39:37 + * @Description: + */ +const typesDictionary = [ + + { + value: 1, + label: '风机', + img: 'fengji', + isSelected: false + }, + { + value: 2, + label: '水泵', + img: 'shuibeng', + isSelected: false + }, + { + value: 3, + label: '照明', + img: 'zhaoming', + isSelected: false + }, + +] + +export default typesDictionary; \ No newline at end of file diff --git a/src/utils/errorCode.js b/src/utils/errorCode.js new file mode 100644 index 0000000..b72d026 --- /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..449715f --- /dev/null +++ b/src/utils/generator/config.js @@ -0,0 +1,452 @@ +export const formConf = { + formRef: 'formRef', + formModel: 'formData', + size: 'default', + labelPosition: 'right', + labelWidth: 100, + formRules: 'rules', + gutter: 15, + disabled: false, + span: 24, + formBtns: true, +} + +export const inputComponents = [ + { + label: '单行文本', + tag: 'el-input', + tagIcon: 'input', + type: 'text', + 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-plus.org/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-plus.org/zh-CN/component/input', + }, + { + label: '密码', + tag: 'el-input', + tagIcon: 'password', + type: '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-plus.org/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-plus.org/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-plus.org/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-plus.org/zh-CN/component/cascader', + }, + { + label: '单选框组', + tag: 'el-radio-group', + tagIcon: 'radio', + defaultValue: 0, + span: 24, + labelWidth: null, + style: {}, + optionType: 'default', + border: false, + size: 'default', + disabled: false, + required: true, + options: [ + { + label: '选项一', + value: 1, + }, + { + label: '选项二', + value: 2, + }, + ], + regList: [], + changeTag: true, + document: 'https://element-plus.org/zh-CN/component/radio', + }, + { + label: '多选框组', + tag: 'el-checkbox-group', + tagIcon: 'checkbox', + defaultValue: [], + span: 24, + labelWidth: null, + style: {}, + optionType: 'default', + border: false, + size: 'default', + disabled: false, + required: true, + options: [ + { + label: '选项一', + value: 1, + }, + { + label: '选项二', + value: 2, + }, + ], + regList: [], + changeTag: true, + document: 'https://element-plus.org/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-plus.org/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-plus.org/zh-CN/component/slider', + }, + { + label: '时间选择', + tag: 'el-time-picker', + tagIcon: 'time', + placeholder: '请选择', + defaultValue: '', + span: 24, + labelWidth: null, + style: { width: '100%' }, + disabled: false, + clearable: true, + required: true, + format: 'HH:mm:ss', + 'value-format': 'HH:mm:ss', + regList: [], + changeTag: true, + document: 'https://element-plus.org/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-plus.org/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-plus.org/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-plus.org/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-plus.org/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: 'default', + regList: [], + changeTag: true, + document: 'https://element-plus.org/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-plus.org/zh-CN/component/upload', + tip: '只能上传不超过 2MB 的文件', + style: { width: '100%' }, + }, +] + +export const layoutComponents = [ + { + layout: 'rowFormItem', + tagIcon: 'row', + type: 'default', + justify: 'start', + align: 'top', + label: '行容器', + layoutTree: true, + children: [], + document: 'https://element-plus.org/zh-CN/component/layout', + }, + { + layout: 'colFormItem', + label: '按钮', + changeTag: true, + labelWidth: null, + tag: 'el-button', + tagIcon: 'button', + span: 24, + default: '主要按钮', + type: 'primary', + icon: 'Search', + size: 'default', + disabled: false, + document: 'https://element-plus.org/zh-CN/component/button', + }, +] + +// 组件rule的触发方式,无触发方式的组件不生成rule +export const trigger = { + 'el-input': 'blur', + 'el-input-number': 'blur', + 'el-select': 'change', + 'el-radio-group': 'change', + 'el-checkbox-group': 'change', + 'el-cascader': 'change', + 'el-time-picker': 'change', + 'el-date-picker': 'change', + 'el-rate': 'change', +} 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..1105c28 --- /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': 'Cellphone', + '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..4b29841 --- /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 ` + ${str} + + ` +} + +export function vueTemplate(str) { + return `` +} + +export function vueScript(str) { + return `` +} + +export function cssStyle(cssStr) { + return `` +} + +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 = ` + ${child} + ${buildFromBtns(conf, type)} + ` + if (someSpanIsNot24) { + str = ` + ${str} + ` + } + return str +} + +function buildFromBtns(conf, type) { + let str = '' + if (conf.formBtns && type === 'file') { + str = ` + 提交 + 重置 + ` + if (someSpanIsNot24) { + str = ` + ${str} + ` + } + } + return str +} + +// span不为24的用el-col包裹 +function colWrapper(element, str) { + if (someSpanIsNot24 || element.span !== 24) { + return ` + ${str} + ` + } + 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 = ` + ${tagDom} + ` + 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 = ` + ${children.join('\n')} + ` + 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-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-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-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-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-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-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-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-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-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-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-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-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-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}` + } +} + +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(``) + } + if (conf.append) { + children.push(``) + } + return children.join('\n') +} + +function buildElSelectChild(conf) { + const children = [] + if (conf.options && conf.options.length) { + children.push(``) + } + 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" :value="item.value" :disabled="item.disabled" ${border}>{{item.label}}`) + } + 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" :value="item.label" :disabled="item.disabled" ${border} />`) + } + return children.join('\n') +} + +function buildElUploadChild(conf) { + const list = [] + if (conf['list-type'] === 'picture-card') list.push('') + else list.push(`${conf.buttonText}`) + if (conf.showTip) list.push(`
只能上传不超过 ${conf.fileSize}${conf.sizeUnit} 的${conf.accept}文件
`) + 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..dc38bfe --- /dev/null +++ b/src/utils/generator/js.js @@ -0,0 +1,370 @@ +import { titleCase } from '@/utils/index' +import { trigger } from './config' +// 文件大小设置 +const units = { + KB: '1024', + MB: '1024 / 1024', + GB: '1024 / 1024 / 1024', +} +/** + * @name: 生成js需要的数据 + * @description: 生成js需要的数据 + * @param {*} conf + * @param {*} type 弹窗或表单 + * @return {*} + */ +export function makeUpJs(conf, type) { + conf = JSON.parse(JSON.stringify(conf)) + const dataList = [] + const ruleList = [] + const optionsList = [] + const propsList = [] + const methodList = [] + 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') + ) + + return script +} +/** + * @name: 生成参数 + * @description: 生成参数,包括表单数据表单验证数据,多选选项数据,上传数据等 + * @return {*} + */ +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( + ` + // 上传请求路径 + const ${el.vModel}Action = ref('${el.action}') + // 上传文件列表 + const ${el.vModel}fileList = ref([])` + ) + 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 + ) + }) + } +} +/** + * @name: 生成表单数据formData + * @description: 生成表单数据formData + * @param {*} conf + * @param {*} dataList 数据列表 + * @return {*} + */ +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},`) +} +/** + * @name: 生成表单验证数据rule + * @description: 生成表单验证数据rule + * @param {*} conf + * @param {*} ruleList 验证数据列表 + * @return {*} + */ +function buildRules(conf, ruleList) { + if (conf.vModel === undefined) return + const rules = [] + if (trigger[conf.tag]) { + if (conf.required) { + const type = Array.isArray(conf.defaultValue) ? "type: 'array'," : '' + let message = Array.isArray(conf.defaultValue) + ? `请至少选择一个${conf.vModel}` + : conf.placeholder + if (message === undefined) message = `${conf.label}不能为空` + rules.push( + `{ required: true, ${type} message: '${message}', trigger: '${ + trigger[conf.tag] + }' }` + ) + } + if (conf.regList && Array.isArray(conf.regList)) { + conf.regList.forEach((item) => { + if (item.pattern) { + rules.push( + `{ pattern: new RegExp(${item.pattern}), message: '${ + item.message + }', trigger: '${trigger[conf.tag]}' }` + ) + } + }) + } + ruleList.push(`${conf.vModel}: [${rules.join(',')}],`) + } +} +/** + * @name: 生成选项数据 + * @description: 生成选项数据,单选多选下拉等 + * @param {*} conf + * @param {*} optionsList 选项数据列表 + * @return {*} + */ +function buildOptions(conf, optionsList) { + if (conf.vModel === undefined) return + if (conf.dataType === 'dynamic') { + conf.options = [] + } + const str = `const ${conf.vModel}Options = ref(${JSON.stringify(conf.options)})` + optionsList.push(str) +} +/** + * @name: 生成方法 + * @description: 生成方法 + * @param {*} methodName 方法名 + * @param {*} model + * @param {*} methodList 方法列表 + * @return {*} + */ +function buildOptionMethod(methodName, model, methodList) { + const str = `function ${methodName}() { + // TODO 发起请求获取数据 + ${model}.value + }` + methodList.push(str) +} +/** + * @name: 生成表单组件需要的props设置 + * @description: 生成表单组件需要的props设置,如;级联组件 + * @param {*} conf + * @param {*} propsList + * @return {*} + */ +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 = ` + // props设置 + const ${conf.vModel}Props = ref(${JSON.stringify(conf.props.props)})` + propsList.push(str) +} +/** + * @name: 生成上传组件的相关内容 + * @description: 生成上传组件的相关内容 + * @param {*} conf + * @return {*} + */ +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){ + proxy.$modal.msgError('文件大小超过 ${conf.fileSize}${conf.sizeUnit}') + }` + returnList.push('isRightSize') + } + if (conf.accept) { + acceptCode = `let isAccept = new RegExp('${conf.accept}').test(file.type) + if(!isAccept){ + proxy.$modal.msgError('应该选择${conf.accept}类型的文件') + }` + returnList.push('isAccept') + } + const str = ` + /** + * @name: 上传之前的文件判断 + * @description: 上传之前的文件判断,判断文件大小文件类型等 + * @param {*} file + * @return {*} + */ + function ${conf.vModel}BeforeUpload(file) { + ${rightSizeCode} + ${acceptCode} + return ${returnList.join('&&')} + }` + return returnList.length ? str : '' +} +/** + * @name: 生成提交表单方法 + * @description: 生成提交表单方法 + * @param {Object} conf vModel 表单ref + * @return {*} + */ +function buildSubmitUpload(conf) { + const str = `function submitUpload() { + this.$refs['${conf.vModel}'].submit() + }` + return str +} +/** + * @name: 组装js代码 + * @description: 组装js代码方法 + * @return {*} + */ +function buildexport( + conf, + type, + data, + rules, + selectOptions, + uploadVar, + props, + methods +) { + let str = ` + const { proxy } = getCurrentInstance() + const ${conf.formRef} = ref() + const data = reactive({ + ${conf.formModel}: { + ${data} + }, + ${conf.formRules}: { + ${rules} + } + }) + + const {${conf.formModel}, ${conf.formRules}} = toRefs(data) + + ${selectOptions} + + ${uploadVar} + + ${props} + + ${methods} + ` + + if(type === 'dialog') { + str += ` + // 弹窗设置 + const dialogVisible = defineModel() + // 弹窗确认回调 + const emit = defineEmits(['confirm']) + /** + * @name: 弹窗打开后执行 + * @description: 弹窗打开后执行方法 + * @return {*} + */ + function onOpen(){ + + } + /** + * @name: 弹窗关闭时执行 + * @description: 弹窗关闭方法,重置表单 + * @return {*} + */ + function onClose(){ + ${conf.formRef}.value.resetFields() + } + /** + * @name: 弹窗取消 + * @description: 弹窗取消方法 + * @return {*} + */ + function close(){ + dialogVisible.value = false + } + /** + * @name: 弹窗表单提交 + * @description: 弹窗表单提交方法 + * @return {*} + */ + function handelConfirm(){ + ${conf.formRef}.value.validate((valid) => { + if (!valid) return + // TODO 提交表单 + + close() + // 回调父级组件 + emit('confirm') + }) + } + ` + } else { + str += ` + /** + * @name: 表单提交 + * @description: 表单提交方法 + * @return {*} + */ + function submitForm() { + ${conf.formRef}.value.validate((valid) => { + if (!valid) return + // TODO 提交表单 + }) + } + /** + * @name: 表单重置 + * @description: 表单重置方法 + * @return {*} + */ + function resetForm() { + ${conf.formRef}.value.resetFields() + } + ` + } + return str +} diff --git a/src/utils/generator/render.js b/src/utils/generator/render.js new file mode 100644 index 0000000..d6d4414 --- /dev/null +++ b/src/utils/generator/render.js @@ -0,0 +1,156 @@ +import { defineComponent, h } from 'vue' +import { makeMap } from '@/utils/index' + +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' + 'prefix-icon' +) +const isNotProps = makeMap( + 'layout,prepend,regList,tag,document,changeTag,defaultValue' +) + +function useVModel(props, emit) { + return { + modelValue: props.defaultValue, + 'onUpdate:modelValue': (val) => emit('update:modelValue', val), + } +} +const componentChild = { + 'el-button': { + default(h, conf, key) { + return conf[key] + }, + }, + 'el-select': { + options(h, conf, key) { + return conf.options.map(item => h(resolveComponent('el-option'), { + label: item.label, + value: item.value, + })) + } + }, + 'el-radio-group': { + options(h, conf, key) { + return conf.optionType === 'button' ? conf.options.map(item => h(resolveComponent('el-checkbox-button'), { + label: item.value, + }, () => item.label)) : conf.options.map(item => h(resolveComponent('el-radio'), { + label: item.value, + border: conf.border, + }, () => item.label)) + } + }, + 'el-checkbox-group': { + options(h, conf, key) { + return conf.optionType === 'button' ? conf.options.map(item => h(resolveComponent('el-checkbox-button'), { + label: item.value, + }, () => item.label)) : conf.options.map(item => h(resolveComponent('el-checkbox'), { + label: item.value, + border: conf.border, + }, () => item.label)) + } + }, + 'el-upload': { + 'list-type': (h, conf, key) => { + const option = {} + // if (conf.showTip) { + // tip = h('div', { + // class: "el-upload__tip" + // }, () => '只能上传不超过' + conf.fileSize + conf.sizeUnit + '的' + conf.accept + '文件') + // } + if (conf['list-type'] === 'picture-card') { + return h(resolveComponent('el-icon'), option, () => h(resolveComponent('Plus'))) + } else { + // option.size = "small" + option.type = "primary" + option.icon = "Upload" + return h(resolveComponent('el-button'), option, () => conf.buttonText) + } + }, + + } +} +const componentSlot = { + 'el-upload': { + 'tip': (h, conf, key) => { + if (conf.showTip) { + return () => h('div', { + class: "el-upload__tip" + }, '只能上传不超过' + conf.fileSize + conf.sizeUnit + '的' + conf.accept + '文件') + } + }, + } +} +export default defineComponent({ + + // 使用 render 函数 + render() { + const dataObject = { + attrs: {}, + props: {}, + on: {}, + style: {} + } + const confClone = JSON.parse(JSON.stringify(this.conf)) + const children = [] + const slot = {} + 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)) + } + }) + } + const slotObjs = componentSlot[confClone.tag] + if (slotObjs) { + Object.keys(slotObjs).forEach(key => { + const childFunc = slotObjs[key] + if (confClone[key]) { + slot[key] = childFunc(h, confClone, key) + } + }) + } + Object.keys(confClone).forEach(key => { + const val = confClone[key] + if (dataObject[key]) { + dataObject[key] = val + } else if (isAttr(key)) { + dataObject.attrs[key] = val + } else if (!isNotProps(key)) { + dataObject.props[key] = val + } + }) + if(children.length > 0){ + slot.default = () => children + } + + return h(resolveComponent(this.conf.tag), + { + modelValue: this.$attrs.modelValue, + ...dataObject.props, + ...dataObject.attrs, + style: { + ...dataObject.style + }, + } + , slot ?? null) + }, + props: { + conf: { + type: Object, + required: true, + }, + } +}) \ No newline at end of file diff --git a/src/utils/index.js b/src/utils/index.js new file mode 100644 index 0000000..da79665 --- /dev/null +++ b/src/utils/index.js @@ -0,0 +1,390 @@ +import { parseTime } from './ruoyi' + +/** + * 表格时间格式化 + */ +export function formatDate(cellValue) { + if (cellValue == null || cellValue == "") return "" + var date = new Date(cellValue) + var year = date.getFullYear() + var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 + var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() + var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() + var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() + var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() + return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds +} + +/** + * @param {number} time + * @param {string} option + * @returns {string} + */ +export function formatTime(time, option) { + if (('' + time).length === 10) { + time = parseInt(time) * 1000 + } else { + time = +time + } + const d = new Date(time) + const now = Date.now() + + const diff = (now - d) / 1000 + + if (diff < 30) { + return '刚刚' + } else if (diff < 3600) { + // less 1 hour + return Math.ceil(diff / 60) + '分钟前' + } else if (diff < 3600 * 24) { + return Math.ceil(diff / 3600) + '小时前' + } else if (diff < 3600 * 24 * 2) { + return '1天前' + } + if (option) { + return parseTime(time, option) + } else { + return ( + d.getMonth() + + 1 + + '月' + + d.getDate() + + '日' + + d.getHours() + + '时' + + d.getMinutes() + + '分' + ) + } +} + +/** + * @param {string} url + * @returns {Object} + */ +export function getQueryObject(url) { + url = url == null ? window.location.href : url + const search = url.substring(url.lastIndexOf('?') + 1) + const obj = {} + const reg = /([^?&=]+)=([^?&=]*)/g + search.replace(reg, (rs, $1, $2) => { + const name = decodeURIComponent($1) + let val = decodeURIComponent($2) + val = String(val) + obj[name] = val + return rs + }) + return obj +} + +/** + * @param {string} input value + * @returns {number} output value + */ +export function byteLength(str) { + // returns the byte length of an utf8 string + let s = str.length + for (var i = str.length - 1; i >= 0; i--) { + const code = str.charCodeAt(i) + if (code > 0x7f && code <= 0x7ff) s++ + else if (code > 0x7ff && code <= 0xffff) s += 2 + if (code >= 0xDC00 && code <= 0xDFFF) i-- + } + return s +} + +/** + * @param {Array} actual + * @returns {Array} + */ +export function cleanArray(actual) { + const newArray = [] + for (let i = 0; i < actual.length; i++) { + if (actual[i]) { + newArray.push(actual[i]) + } + } + return newArray +} + +/** + * @param {Object} json + * @returns {Array} + */ +export function param(json) { + if (!json) return '' + return cleanArray( + Object.keys(json).map(key => { + if (json[key] === undefined) return '' + return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]) + }) + ).join('&') +} + +/** + * @param {string} url + * @returns {Object} + */ +export function param2Obj(url) { + const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') + if (!search) { + return {} + } + const obj = {} + const searchArr = search.split('&') + searchArr.forEach(v => { + const index = v.indexOf('=') + if (index !== -1) { + const name = v.substring(0, index) + const val = v.substring(index + 1, v.length) + obj[name] = val + } + }) + return obj +} + +/** + * @param {string} val + * @returns {string} + */ +export function html2Text(val) { + const div = document.createElement('div') + div.innerHTML = val + return div.textContent || div.innerText +} + +/** + * Merges two objects, giving the last one precedence + * @param {Object} target + * @param {(Object|Array)} source + * @returns {Object} + */ +export function objectMerge(target, source) { + if (typeof target !== 'object') { + target = {} + } + if (Array.isArray(source)) { + return source.slice() + } + Object.keys(source).forEach(property => { + const sourceProperty = source[property] + if (typeof sourceProperty === 'object') { + target[property] = objectMerge(target[property], sourceProperty) + } else { + target[property] = sourceProperty + } + }) + return target +} + +/** + * @param {HTMLElement} element + * @param {string} className + */ +export function toggleClass(element, className) { + if (!element || !className) { + return + } + let classString = element.className + const nameIndex = classString.indexOf(className) + if (nameIndex === -1) { + classString += '' + className + } else { + classString = + classString.substr(0, nameIndex) + + classString.substr(nameIndex + className.length) + } + element.className = classString +} + +/** + * @param {string} type + * @returns {Date} + */ +export function getTime(type) { + if (type === 'start') { + return new Date().getTime() - 3600 * 1000 * 24 * 90 + } else { + return new Date(new Date().toDateString()) + } +} + +/** + * @param {Function} func + * @param {number} wait + * @param {boolean} immediate + * @return {*} + */ +export function debounce(func, wait, immediate) { + let timeout, args, context, timestamp, result + + const later = function() { + // 据上一次触发时间间隔 + const last = +new Date() - timestamp + + // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait + if (last < wait && last > 0) { + timeout = setTimeout(later, wait - last) + } else { + timeout = null + // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 + if (!immediate) { + result = func.apply(context, args) + if (!timeout) context = args = null + } + } + } + + return function(...args) { + context = this + timestamp = +new Date() + const callNow = immediate && !timeout + // 如果延时不存在,重新设定延时 + if (!timeout) timeout = setTimeout(later, wait) + if (callNow) { + result = func.apply(context, args) + context = args = null + } + + return result + } +} + +/** + * This is just a simple version of deep copy + * Has a lot of edge cases bug + * If you want to use a perfect deep copy, use lodash's _.cloneDeep + * @param {Object} source + * @returns {Object} + */ +export function deepClone(source) { + if (!source && typeof source !== 'object') { + throw new Error('error arguments', 'deepClone') + } + const targetObj = source.constructor === Array ? [] : {} + Object.keys(source).forEach(keys => { + if (source[keys] && typeof source[keys] === 'object') { + targetObj[keys] = deepClone(source[keys]) + } else { + targetObj[keys] = source[keys] + } + }) + return targetObj +} + +/** + * @param {Array} arr + * @returns {Array} + */ +export function uniqueArr(arr) { + return Array.from(new Set(arr)) +} + +/** + * @returns {string} + */ +export function createUniqueString() { + const timestamp = +new Date() + '' + const randomNum = parseInt((1 + Math.random()) * 65536) + '' + return (+(randomNum + timestamp)).toString(32) +} + +/** + * Check if an element has a class + * @param {HTMLElement} elm + * @param {string} cls + * @returns {boolean} + */ +export function hasClass(ele, cls) { + return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) +} + +/** + * Add class to element + * @param {HTMLElement} elm + * @param {string} cls + */ +export function addClass(ele, cls) { + if (!hasClass(ele, cls)) ele.className += ' ' + cls +} + +/** + * Remove class from element + * @param {HTMLElement} elm + * @param {string} cls + */ +export function removeClass(ele, cls) { + if (hasClass(ele, cls)) { + const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)') + ele.className = ele.className.replace(reg, ' ') + } +} + +export function makeMap(str, expectsLowerCase) { + const map = Object.create(null) + const list = str.split(',') + for (let i = 0; i < list.length; i++) { + map[list[i]] = true + } + return expectsLowerCase + ? val => map[val.toLowerCase()] + : val => map[val] +} + +export const exportDefault = 'export default ' + +export const beautifierConf = { + html: { + indent_size: '2', + indent_char: ' ', + max_preserve_newlines: '-1', + preserve_newlines: false, + keep_array_indentation: false, + break_chained_methods: false, + indent_scripts: 'separate', + brace_style: 'end-expand', + space_before_conditional: true, + unescape_strings: false, + jslint_happy: false, + end_with_newline: true, + wrap_line_length: '110', + indent_inner_html: true, + comma_first: false, + e4x: true, + indent_empty_lines: true + }, + js: { + indent_size: '2', + indent_char: ' ', + max_preserve_newlines: '-1', + preserve_newlines: false, + keep_array_indentation: false, + break_chained_methods: false, + indent_scripts: 'normal', + brace_style: 'end-expand', + space_before_conditional: true, + unescape_strings: false, + jslint_happy: true, + end_with_newline: true, + wrap_line_length: '110', + indent_inner_html: true, + comma_first: false, + e4x: true, + indent_empty_lines: true + } +} + +// 首字母大小 +export function titleCase(str) { + return str.replace(/( |^)[a-z]/g, L => L.toUpperCase()) +} + +// 下划转驼峰 +export function camelCase(str) { + return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase()) +} + +export function isNumberStr(str) { + return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str) +} + diff --git a/src/utils/jsencrypt.js b/src/utils/jsencrypt.js new file mode 100644 index 0000000..9f3a280 --- /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) // 对数据进行加密 +} + +// 解密 +export function decrypt(txt) { + const encryptor = new JSEncrypt() + encryptor.setPrivateKey(privateKey) // 设置私钥 + return encryptor.decrypt(txt) // 对数据进行解密 +} + diff --git a/src/utils/permission.js b/src/utils/permission.js new file mode 100644 index 0000000..86f14d2 --- /dev/null +++ b/src/utils/permission.js @@ -0,0 +1,63 @@ +import { useUserStore } from '@/store/modules/user' + +/** + * 字符权限校验 + * @param {Array} value 校验值 + * @returns {Boolean} + */ +export function checkPermi(value) { + if (value && value instanceof Array && value.length > 0) { + try { + const userStore = useUserStore() + const permissions = userStore.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 + } catch (error) { + console.warn('Permission check failed:', error) + return false + } + } 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) { + try { + const userStore = useUserStore() + const roles = userStore.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 + } catch (error) { + console.warn('Role check failed:', error) + return false + } + } else { + console.error(`need roles! Like checkRole="['admin','editor']"`) + return false + } +} diff --git a/src/utils/request.js b/src/utils/request.js new file mode 100644 index 0000000..fc54ca9 --- /dev/null +++ b/src/utils/request.js @@ -0,0 +1,170 @@ +import axios from 'axios' +import { ElNotification , ElMessageBox, ElMessage, ElLoading } from 'element-plus' +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' +import { useUserStore } from '@/store/modules/user' + +let downloadLoadingInstance +// 是否显示重新登录 +export let isRelogin = { show: false } + +axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' +// 创建axios实例 +const service = axios.create({ + // axios中请求配置有baseURL选项,表示请求URL公共部分 + baseURL: import.meta.env.VITE_APP_BASE_API, + // 超时 + timeout: 10000 +}) + +// request拦截器 +service.interceptors.request.use(config => { + // 是否需要设置 token + const isToken = (config.headers || {}).isToken === false + // 是否需要防止数据重复提交 + const isRepeatSubmit = (config.headers || {}).repeatSubmit === false + if (getToken() && !isToken) { + config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 + } + // get请求映射params参数 + if (config.method === 'get' && config.params) { + let url = config.url + '?' + tansParams(config.params) + url = url.slice(0, -1) + config.params = {} + config.url = url + } + if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { + const requestObj = { + url: config.url, + data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, + time: new Date().getTime() + } + const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小 + const limitSize = 5 * 1024 * 1024 // 限制存放数据5M + if (requestSize >= limitSize) { + console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。') + return config + } + const sessionObj = cache.session.getJSON('sessionObj') + if (sessionObj === undefined || sessionObj === null || sessionObj === '') { + cache.session.setJSON('sessionObj', requestObj) + } else { + const s_url = sessionObj.url // 请求地址 + const s_data = sessionObj.data // 请求数据 + const s_time = sessionObj.time // 请求时间 + const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交 + if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { + const message = '数据正在处理,请勿重复提交' + console.warn(`[${s_url}]: ` + message) + return Promise.reject(new Error(message)) + } else { + cache.session.setJSON('sessionObj', requestObj) + } + } + } + return config +}, error => { + console.log(error) + Promise.reject(error) +}) + +// 响应拦截器 +service.interceptors.response.use(res => { + // 未设置状态码则默认成功状态 + const code = res.data.code || 200 || 201 + // 获取错误信息 + 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 + ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { + isRelogin.show = false + useUserStore().logOut().then(() => { + location.href = '/index' + }) + }).catch(() => { + isRelogin.show = false + }) + } + return Promise.reject('无效的会话,或者会话已过期,请重新登录。') + } else if (code === 500) { + ElMessage({ message: msg, type: 'error' }) + return Promise.reject(new Error(msg)) + } else if (code === 601) { + ElMessage({ message: msg, type: 'warning' }) + return Promise.reject(new Error(msg)) + } else if (code !== 200 && code !== 201) { + ElNotification.error({ title: msg }) + return Promise.reject('error') + } else { + return Promise.resolve(res.data) + } + }, + error => { + console.log('err' + error) + + let status_code = error.response && error.response.status; + if(status_code === 401) { + if (!isRelogin.show) { + ElMessageBox.confirm('登录状态已过期,请重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { + isRelogin.show = false + useUserStore().logOut().then(() => { + location.href = '/login' + return + }) + }) + } + } + + let { message } = error + if (message == "Network Error") { + message = "后端接口连接异常" + } else if (message.includes("timeout")) { + message = "系统接口请求超时" + } else if (message.includes("Request failed with status code")) { + if(error.response && error.response.data && error.response.data.message) { + message = error.response.data.message + } else { + message = "系统接口" + message.substr(message.length - 3) + "异常" + } + } + ElMessage({ message: message, type: 'error', duration: 5 * 1000 }) + return Promise.reject(error) + } +) + +// 通用下载方法 +export function download(url, params, filename, config) { + downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", }) + return service.post(url, params, { + transformRequest: [(params) => { return tansParams(params) }], + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + responseType: 'blob', + ...config + }).then(async (data) => { + const isBlob = blobValidate(data) + if (isBlob) { + const blob = new Blob([data]) + saveAs(blob, filename) + } else { + const resText = await data.text() + const rspObj = JSON.parse(resText) + const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default'] + ElMessage.error(errMsg) + } + downloadLoadingInstance.close() + }).catch((r) => { + console.error(r) + ElMessage.error('下载文件出现错误,请联系管理员!') + downloadLoadingInstance.close() + }) +} + +export default service diff --git a/src/utils/ruoyi.js b/src/utils/ruoyi.js new file mode 100644 index 0000000..0d72c1a --- /dev/null +++ b/src/utils/ruoyi.js @@ -0,0 +1,228 @@ +/** + * 通用js方法封装处理 + * Copyright (c) 2019 ruoyi + */ + +// 日期格式化 +export function parseTime(time, pattern) { + if (arguments.length === 0 || !time) { + return null + } + const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}' + let date + if (typeof time === 'object') { + date = time + } else { + if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { + time = parseInt(time) + } else if (typeof time === 'string') { + time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '') + } + if ((typeof time === 'number') && (time.toString().length === 10)) { + time = time * 1000 + } + date = new Date(time) + } + const formatObj = { + y: date.getFullYear(), + m: date.getMonth() + 1, + d: date.getDate(), + h: date.getHours(), + i: date.getMinutes(), + s: date.getSeconds(), + a: date.getDay() + } + const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { + let value = formatObj[key] + // Note: getDay() returns 0 on Sunday + if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] } + if (result.length > 0 && value < 10) { + value = '0' + value + } + return value || 0 + }) + return time_str +} + +// 表单重置 +export function resetForm(refName) { + if (this.$refs[refName]) { + this.$refs[refName].resetFields() + } +} + +// 添加日期范围 +export function addDateRange(params, dateRange, propName) { + let search = params + search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {} + dateRange = Array.isArray(dateRange) ? dateRange : [] + if (typeof (propName) === 'undefined') { + search.params['beginTime'] = dateRange[0] + search.params['endTime'] = dateRange[1] + } else { + search.params['begin' + propName] = dateRange[0] + search.params['end' + propName] = dateRange[1] + } + return search +} + +// 回显数据字典 +export function selectDictLabel(datas, value) { + if (value === undefined) { + return "" + } + var actions = [] + Object.keys(datas).some((key) => { + if (datas[key].value == ('' + value)) { + actions.push(datas[key].label) + return true + } + }) + if (actions.length === 0) { + actions.push(value) + } + return actions.join('') +} + +// 回显数据字典(字符串、数组) +export function selectDictLabels(datas, value, separator) { + if (value === undefined || value.length ===0) { + return "" + } + if (Array.isArray(value)) { + value = value.join(",") + } + var actions = [] + var currentSeparator = undefined === separator ? "," : separator + var temp = value.split(currentSeparator) + Object.keys(value.split(currentSeparator)).some((val) => { + var match = false + Object.keys(datas).some((key) => { + if (datas[key].value == ('' + temp[val])) { + actions.push(datas[key].label + currentSeparator) + match = true + } + }) + if (!match) { + actions.push(temp[val] + currentSeparator) + } + }) + return actions.join('').substring(0, actions.join('').length - 1) +} + +// 字符串格式化(%s ) +export function sprintf(str) { + var args = arguments, flag = true, i = 1 + str = str.replace(/%s/g, function () { + var arg = args[i++] + if (typeof arg === 'undefined') { + flag = false + return '' + } + return arg + }) + return flag ? str : '' +} + +// 转换字符串,undefined,null等转化为"" +export function parseStrEmpty(str) { + if (!str || str == "undefined" || str == "null") { + return "" + } + return str +} + +// 数据合并 +export function mergeRecursive(source, target) { + for (var p in target) { + try { + if (target[p].constructor == Object) { + source[p] = mergeRecursive(source[p], target[p]) + } else { + source[p] = target[p] + } + } catch (e) { + source[p] = target[p] + } + } + return source +} + +/** + * 构造树型结构数据 + * @param {*} data 数据源 + * @param {*} id id字段 默认 'id' + * @param {*} parentId 父节点字段 默认 'parentId' + * @param {*} children 孩子节点字段 默认 'children' + */ +export function handleTree(data, id, parentId, children) { + let config = { + id: id || 'id', + parentId: parentId || 'parentId', + childrenList: children || 'children' + } + + var childrenListMap = {} + var tree = [] + for (let d of data) { + let id = d[config.id] + childrenListMap[id] = d + if (!d[config.childrenList]) { + d[config.childrenList] = [] + } + } + + for (let d of data) { + let parentId = d[config.parentId] + let parentObj = childrenListMap[parentId] + if (!parentObj) { + tree.push(d) + } else { + parentObj[config.childrenList].push(d) + } + } + return tree +} + +/** +* 参数处理 +* @param {*} params 参数 +*/ +export function tansParams(params) { + let result = '' + for (const propName of Object.keys(params)) { + const value = params[propName] + var part = encodeURIComponent(propName) + "=" + if (value !== null && value !== "" && typeof (value) !== "undefined") { + if (typeof value === 'object') { + for (const key of Object.keys(value)) { + if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') { + let params = propName + '[' + key + ']' + var subPart = encodeURIComponent(params) + "=" + result += subPart + encodeURIComponent(value[key]) + "&" + } + } + } else { + result += part + encodeURIComponent(value) + "&" + } + } + } + return result +} + +// 返回项目路径 +export function getNormalPath(p) { + if (p.length === 0 || !p || p == 'undefined') { + return p + } + let res = p.replace('//', '/') + if (res[res.length - 1] === '/') { + return res.slice(0, res.length - 1) + } + return res +} + +// 验证是否为blob格式 +export function blobValidate(data) { + return data.type !== 'application/json' +} diff --git a/src/utils/scroll-to.js b/src/utils/scroll-to.js new file mode 100644 index 0000000..709fa57 --- /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/theme.js b/src/utils/theme.js new file mode 100644 index 0000000..f4badc6 --- /dev/null +++ b/src/utils/theme.js @@ -0,0 +1,49 @@ +// 处理主题样式 +export function handleThemeStyle(theme) { + document.documentElement.style.setProperty('--el-color-primary', theme) + for (let i = 1; i <= 9; i++) { + document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, `${getLightColor(theme, i / 10)}`) + } + for (let i = 1; i <= 9; i++) { + document.documentElement.style.setProperty(`--el-color-primary-dark-${i}`, `${getDarkColor(theme, i / 10)}`) + } +} + +// hex颜色转rgb颜色 +export function hexToRgb(str) { + str = str.replace('#', '') + let hexs = str.match(/../g) + for (let i = 0; i < 3; i++) { + hexs[i] = parseInt(hexs[i], 16) + } + return hexs +} + +// rgb颜色转Hex颜色 +export function rgbToHex(r, g, b) { + let hexs = [r.toString(16), g.toString(16), b.toString(16)] + for (let i = 0; i < 3; i++) { + if (hexs[i].length == 1) { + hexs[i] = `0${hexs[i]}` + } + } + return `#${hexs.join('')}` +} + +// 变浅颜色值 +export function getLightColor(color, level) { + let rgb = hexToRgb(color) + for (let i = 0; i < 3; i++) { + rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i]) + } + return rgbToHex(rgb[0], rgb[1], rgb[2]) +} + +// 变深颜色值 +export function getDarkColor(color, level) { + let rgb = hexToRgb(color) + for (let i = 0; i < 3; i++) { + rgb[i] = Math.floor(rgb[i] * (1 - level)) + } + return rgbToHex(rgb[0], rgb[1], rgb[2]) +} diff --git a/src/utils/userGuide.js b/src/utils/userGuide.js new file mode 100644 index 0000000..8d923a2 --- /dev/null +++ b/src/utils/userGuide.js @@ -0,0 +1,306 @@ +import { driver } from "driver.js"; +import "driver.js/dist/driver.css"; +import { nextTick } from "vue"; + +// Driver.js 实例 +let driverObj = null; + +// 页面准备的注册函数(用于页面注册自己的准备工作) +const pagePrepareCallbacks = {}; + +// 设备列表引导状态管理 +let deviceGuideState = { + addButtonListener: null, + isFirstStep: false +}; + +// 平面图页面的引导步骤(共享配置) +const planGuideSteps = [ + { + element: '.tabbar-content', + popover: { + title: '设备类型筛选', + description: '点击左侧设备类型列表中的任意一项,可以筛选出相应的设备。再次点击同一项可以取消筛选。', + side: 'right', + align: 'start', + doneBtnText: '完成', + closeBtnText: '关闭', + nextBtnText: '下一步', + prevBtnText: '上一步', + } + }, + { + element: '.bar-content', + popover: { + title: '切换分区视图', + description: '点击分区按钮切换视图到对应分区。', + side: 'right', + align: 'start', + doneBtnText: '完成', + closeBtnText: '关闭', + nextBtnText: '下一步', + prevBtnText: '上一步', + } + }, + { + element: '[data-driver-step="edit-button"]', + popover: { + title: '编辑模式', + description: '点击编辑按钮可以进入编辑模式,此时可以拖拽平面图中的设备图标来调整位置。再次点击编辑按钮可以取消编辑状态。', + side: 'bottom', + align: 'center', + doneBtnText: '完成', + closeBtnText: '关闭', + nextBtnText: '下一步', + prevBtnText: '上一步', + } + }, + { + element: '.canvas-wrapper', + popover: { + title: '平面图区域', + description: '这是平面图显示区域,所有设备图标都会显示在这里。您可以双击设备图标查看详情,或在编辑模式下拖拽图标调整位置。', + side: 'top', + align: 'center', + doneBtnText: '完成', + closeBtnText: '关闭', + prevBtnText: '上一步', + } + } +]; + +/** + * 生成通用的增删改查引导步骤配置 + * @param {object} options - 配置选项 + * @param {string} options.entityName - 实体名称(如:设备、区域、房间) + * @param {string} options.addButtonSelector - 新增按钮选择器 + * @param {string} options.deleteButtonSelector - 删除按钮选择器 + * @param {string} options.editButtonSelector - 编辑按钮选择器 + * @param {string} options.searchFormSelector - 查询表单选择器 + * @param {string} options.searchDescription - 查询步骤的描述文本 + * @returns {Array} 引导步骤配置数组 + */ +function createCRUDGuideSteps(options) { + const { + entityName = '数据', + addButtonSelector = '[data-driver-step="add-button"]', + deleteButtonSelector = '[data-driver-step^="delete-button-"]', + editButtonSelector = '[data-driver-step^="edit-button-"]', + searchFormSelector = '[data-driver-step="search-form"]', + searchDescription = `在查询区域可以输入筛选条件进行查询。` + } = options; + + return [ + { + element: addButtonSelector, + popover: { + title: `第一步:新增${entityName}`, + description: `点击"新增"按钮可以添加新的${entityName}。`, + side: 'bottom', + align: 'center', + doneBtnText: '完成', + closeBtnText: '关闭', + nextBtnText: '下一步', + prevBtnText: '上一步', + } + }, + { + element: deleteButtonSelector, + popover: { + title: `第二步:删除${entityName}`, + description: `点击列表中的"删除"按钮可以删除对应的${entityName}记录。`, + side: 'left', + align: 'center', + doneBtnText: '完成', + closeBtnText: '关闭', + nextBtnText: '下一步', + prevBtnText: '上一步', + } + }, + { + element: editButtonSelector, + popover: { + title: `第三步:编辑${entityName}`, + description: `点击列表中的"编辑"按钮可以修改${entityName}信息。`, + side: 'left', + align: 'center', + doneBtnText: '完成', + closeBtnText: '关闭', + nextBtnText: '下一步', + prevBtnText: '上一步', + } + }, + { + element: searchFormSelector, + popover: { + title: `第四步:查询${entityName}`, + description: searchDescription, + side: 'bottom', + align: 'start', + doneBtnText: '完成', + closeBtnText: '关闭', + prevBtnText: '上一步', + } + } + ]; +} + +// 设备列表页面的引导步骤 +const deviceControlGuideSteps = createCRUDGuideSteps({ + entityName: '设备', + addButtonSelector: '[data-driver-step="add-device-button"]', + deleteButtonSelector: '[data-driver-step^="delete-button-"]', + editButtonSelector: '[data-driver-step^="edit-button-"]', + searchFormSelector: '[data-driver-step="search-form"]', + searchDescription: '在查询区域可以输入筛选条件,如区域、舱室、类型、名称、编码等,然后点击搜索按钮进行查询。' +}); + +// 分区管理页面的引导步骤 +const areaGuideSteps = createCRUDGuideSteps({ + entityName: '区域', + addButtonSelector: '[data-driver-step="add-area-button"]', + deleteButtonSelector: '[data-driver-step^="delete-area-button-"]', + editButtonSelector: '[data-driver-step^="edit-area-button-"]', + searchFormSelector: '[data-driver-step="search-area-form"]', + searchDescription: '在查询区域可以输入区域名称进行查询。' +}); + +// 房间管理页面的引导步骤 +const cabinGuideSteps = createCRUDGuideSteps({ + entityName: '房间', + addButtonSelector: '[data-driver-step="add-cabin-button"]', + deleteButtonSelector: '[data-driver-step^="delete-cabin-button-"]', + editButtonSelector: '[data-driver-step^="edit-cabin-button-"]', + searchFormSelector: '[data-driver-step="search-cabin-form"]', + searchDescription: '在查询区域可以选择区域或输入房间名称进行查询。' +}); + +// 不同页面的引导配置 +const guideConfigs = { + // 平面图页面的引导配置(支持多个路径) + '/plan': { + steps: planGuideSteps + }, + // 首页/平面图(如果路由是 index) + '/index': { + steps: planGuideSteps + }, + // 设备列表页面的引导配置 + '/Device/deviceControl': { + steps: deviceControlGuideSteps + }, + // 分区管理页面的引导配置 + '/areaManage/area': { + steps: areaGuideSteps + }, + // 房间管理页面的引导配置 + '/areaManage/cabin': { + steps: cabinGuideSteps + }, + // 可以添加其他页面的配置 + // '/other-page': { + // steps: [...] + // } +}; + +/** + * 启动用户引导 + * @param {string} routePath - 当前路由路径,用于匹配对应的引导配置 + * @param {object} options - 可选的自定义选项 + */ +export function startUserGuide(routePath, options = {}) { + // 如果已有引导实例,先销毁 + if (driverObj) { + driverObj.destroy(); + driverObj = null; + } + + // 获取当前路由对应的配置(支持路径别名) + let config = guideConfigs[routePath]; + + // 如果找不到,尝试查找路径别名 + if (!config && routePath === '/index') { + config = guideConfigs['/plan']; + } + + if (!config) { + console.warn(`未找到路由 ${routePath} 的引导配置`); + return; + } + + // 执行引导前的准备工作(支持路径别名) + let prepareCallback = pagePrepareCallbacks[routePath]; + if (!prepareCallback && routePath === '/index') { + prepareCallback = pagePrepareCallbacks['/plan']; + } + const beforeStartPromise = prepareCallback ? prepareCallback() : Promise.resolve(); + + beforeStartPromise.then(() => { + // 等待DOM更新 + nextTick(() => { + // 初始化 driver.js + driverObj = driver({ + showProgress: true, + allowClose: false, + overlayOpacity: 0.5, + ...options, // 允许外部传入自定义选项 + steps: config.steps, + onDestroyStarted: () => { + // 引导结束时清理实例 + console.log('用户引导已完成!所有步骤都已走完。'); + if (driverObj) { + driverObj.destroy(); + driverObj = null; + } + } + }); + + // 启动引导 + driverObj.drive(); + }); + }); +} + +/** + * 注册新的引导配置 + * @param {string} routePath - 路由路径 + * @param {object} config - 引导配置 + */ +export function registerGuideConfig(routePath, config) { + guideConfigs[routePath] = config; +} + +/** + * 销毁引导实例 + */ +export function destroyGuide() { + if (driverObj) { + driverObj.destroy(); + driverObj = null; + } +} + +/** + * 获取引导配置 + */ +export function getGuideConfig(routePath) { + return guideConfigs[routePath]; +} + +/** + * 注册页面引导前的准备工作 + * @param {string} routePath - 路由路径 + * @param {function} callback - 准备工作的回调函数,返回 Promise + */ +export function registerPagePrepare(routePath, callback) { + pagePrepareCallbacks[routePath] = callback; +} + +/** + * 取消注册页面准备工作 + * @param {string} routePath - 路由路径 + */ +export function unregisterPagePrepare(routePath) { + delete pagePrepareCallbacks[routePath]; +} + diff --git a/src/utils/validate.js b/src/utils/validate.js new file mode 100644 index 0000000..13b7a15 --- /dev/null +++ b/src/utils/validate.js @@ -0,0 +1,114 @@ +/** + * 路径匹配器 + * @param {string} pattern + * @param {string} path + * @returns {Boolean} + */ +export function isPathMatch(pattern, path) { + const regexPattern = pattern.replace(/\//g, '\\/').replace(/\*\*/g, '.*').replace(/\*/g, '[^\\/]*') + const regex = new RegExp(`^${regexPattern}$`) + return regex.test(path) +} + +/** + * 判断value字符串是否为空 + * @param {string} value + * @returns {Boolean} + */ +export function isEmpty(value) { + if (value == null || value == "" || value == undefined || value == "undefined") { + return true + } + return false +} + +/** + * 判断url是否是http或https + * @param {string} url + * @returns {Boolean} + */ +export function isHttp(url) { + return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1 +} + +/** + * 判断path是否为外链 + * @param {string} path + * @returns {Boolean} + */ +export function isExternal(path) { + return /^(https?:|mailto:|tel:)/.test(path) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validUsername(str) { + const valid_map = ['admin', 'editor'] + return valid_map.indexOf(str.trim()) >= 0 +} + +/** + * @param {string} url + * @returns {Boolean} + */ +export function validURL(url) { + const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ + return reg.test(url) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validLowerCase(str) { + const reg = /^[a-z]+$/ + return reg.test(str) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validUpperCase(str) { + const reg = /^[A-Z]+$/ + return reg.test(str) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function validAlphabets(str) { + const reg = /^[A-Za-z]+$/ + return reg.test(str) +} + +/** + * @param {string} email + * @returns {Boolean} + */ +export function validEmail(email) { + const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ + return reg.test(email) +} + +/** + * @param {string} str + * @returns {Boolean} + */ +export function isString(str) { + return typeof str === 'string' || str instanceof String +} + +/** + * @param {Array} arg + * @returns {Boolean} + */ +export function isArray(arg) { + if (typeof Array.isArray === 'undefined') { + return Object.prototype.toString.call(arg) === '[object Array]' + } + return Array.isArray(arg) +} diff --git a/src/views/Device/deviceControl.vue b/src/views/Device/deviceControl.vue new file mode 100644 index 0000000..375eeea --- /dev/null +++ b/src/views/Device/deviceControl.vue @@ -0,0 +1,339 @@ + + + + + \ No newline at end of file diff --git a/src/views/Device/ledger.vue b/src/views/Device/ledger.vue new file mode 100644 index 0000000..c13bfde --- /dev/null +++ b/src/views/Device/ledger.vue @@ -0,0 +1,504 @@ + + + + + \ No newline at end of file diff --git a/src/views/EngineerSupport/etherphone.vue b/src/views/EngineerSupport/etherphone.vue new file mode 100644 index 0000000..ff62d04 --- /dev/null +++ b/src/views/EngineerSupport/etherphone.vue @@ -0,0 +1,340 @@ + + + + + \ No newline at end of file diff --git a/src/views/EngineerSupport/visualizedDispatch.vue b/src/views/EngineerSupport/visualizedDispatch.vue new file mode 100644 index 0000000..67d2c5e --- /dev/null +++ b/src/views/EngineerSupport/visualizedDispatch.vue @@ -0,0 +1,563 @@ + + + + + \ No newline at end of file diff --git a/src/views/Security/doorControl.vue b/src/views/Security/doorControl.vue new file mode 100644 index 0000000..7da281c --- /dev/null +++ b/src/views/Security/doorControl.vue @@ -0,0 +1,414 @@ + + + + + \ No newline at end of file diff --git a/src/views/Security/videoSurveillance.vue b/src/views/Security/videoSurveillance.vue new file mode 100644 index 0000000..0a537a1 --- /dev/null +++ b/src/views/Security/videoSurveillance.vue @@ -0,0 +1,492 @@ + + + + + \ No newline at end of file diff --git a/src/views/areaManage/area.vue b/src/views/areaManage/area.vue new file mode 100644 index 0000000..c6366b4 --- /dev/null +++ b/src/views/areaManage/area.vue @@ -0,0 +1,364 @@ + + + + + \ No newline at end of file diff --git a/src/views/areaManage/cabin.vue b/src/views/areaManage/cabin.vue new file mode 100644 index 0000000..47422ef --- /dev/null +++ b/src/views/areaManage/cabin.vue @@ -0,0 +1,392 @@ + + + + + \ No newline at end of file diff --git a/src/views/components/dateComponent.vue b/src/views/components/dateComponent.vue new file mode 100644 index 0000000..38f0e29 --- /dev/null +++ b/src/views/components/dateComponent.vue @@ -0,0 +1,305 @@ + + + + + + \ No newline at end of file diff --git a/src/views/components/dialogEle.vue b/src/views/components/dialogEle.vue new file mode 100644 index 0000000..e7e5415 --- /dev/null +++ b/src/views/components/dialogEle.vue @@ -0,0 +1,617 @@ + + + + + \ No newline at end of file diff --git a/src/views/components/draughtLink.vue b/src/views/components/draughtLink.vue new file mode 100644 index 0000000..b90484c --- /dev/null +++ b/src/views/components/draughtLink.vue @@ -0,0 +1,545 @@ + + + + \ No newline at end of file diff --git a/src/views/components/numberDate.vue b/src/views/components/numberDate.vue new file mode 100644 index 0000000..b5b863c --- /dev/null +++ b/src/views/components/numberDate.vue @@ -0,0 +1,134 @@ + + + + + + \ No newline at end of file diff --git a/src/views/components/tableEle.vue b/src/views/components/tableEle.vue new file mode 100644 index 0000000..9864b1a --- /dev/null +++ b/src/views/components/tableEle.vue @@ -0,0 +1,548 @@ + + + + \ No newline at end of file diff --git a/src/views/components/videoEle.vue b/src/views/components/videoEle.vue new file mode 100644 index 0000000..765ffae --- /dev/null +++ b/src/views/components/videoEle.vue @@ -0,0 +1,434 @@ + + + + + \ No newline at end of file diff --git a/src/views/dashboard/BarChart.vue b/src/views/dashboard/BarChart.vue new file mode 100644 index 0000000..c9fcb2a --- /dev/null +++ b/src/views/dashboard/BarChart.vue @@ -0,0 +1,101 @@ + + + diff --git a/src/views/dashboard/BarChartzljsc.vue b/src/views/dashboard/BarChartzljsc.vue new file mode 100644 index 0000000..ff38228 --- /dev/null +++ b/src/views/dashboard/BarChartzljsc.vue @@ -0,0 +1,198 @@ + + + diff --git a/src/views/dashboard/LineChart.vue b/src/views/dashboard/LineChart.vue new file mode 100644 index 0000000..f219372 --- /dev/null +++ b/src/views/dashboard/LineChart.vue @@ -0,0 +1,498 @@ + + + diff --git a/src/views/dashboard/LineChartJsc.vue b/src/views/dashboard/LineChartJsc.vue new file mode 100644 index 0000000..e37da0f --- /dev/null +++ b/src/views/dashboard/LineChartJsc.vue @@ -0,0 +1,549 @@ + + + diff --git a/src/views/dashboard/LineChartTpf.vue b/src/views/dashboard/LineChartTpf.vue new file mode 100644 index 0000000..a805f1e --- /dev/null +++ b/src/views/dashboard/LineChartTpf.vue @@ -0,0 +1,381 @@ + + + diff --git a/src/views/dashboard/LineChartduoneng.vue b/src/views/dashboard/LineChartduoneng.vue new file mode 100644 index 0000000..0448d20 --- /dev/null +++ b/src/views/dashboard/LineChartduoneng.vue @@ -0,0 +1,286 @@ + + + diff --git a/src/views/dashboard/LineCharttpfqs.vue b/src/views/dashboard/LineCharttpfqs.vue new file mode 100644 index 0000000..d7239e0 --- /dev/null +++ b/src/views/dashboard/LineCharttpfqs.vue @@ -0,0 +1,148 @@ + + + diff --git a/src/views/dashboard/PanelGroup.vue b/src/views/dashboard/PanelGroup.vue new file mode 100644 index 0000000..8d3a73b --- /dev/null +++ b/src/views/dashboard/PanelGroup.vue @@ -0,0 +1,181 @@ + + + + + diff --git a/src/views/dashboard/PieChart.vue b/src/views/dashboard/PieChart.vue new file mode 100644 index 0000000..6b3242f --- /dev/null +++ b/src/views/dashboard/PieChart.vue @@ -0,0 +1,79 @@ + + + diff --git a/src/views/dashboard/PieChartTpffb.vue b/src/views/dashboard/PieChartTpffb.vue new file mode 100644 index 0000000..f2580c7 --- /dev/null +++ b/src/views/dashboard/PieChartTpffb.vue @@ -0,0 +1,162 @@ + + + + diff --git a/src/views/dashboard/PieChartdevice.vue b/src/views/dashboard/PieChartdevice.vue new file mode 100644 index 0000000..319efd4 --- /dev/null +++ b/src/views/dashboard/PieChartdevice.vue @@ -0,0 +1,162 @@ + + + diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue new file mode 100644 index 0000000..67950af --- /dev/null +++ b/src/views/dashboard/index.vue @@ -0,0 +1,2149 @@ + + + + + + +> + \ No newline at end of file diff --git a/src/views/dashboard/jfb.png b/src/views/dashboard/jfb.png new file mode 100644 index 0000000..04c2d63 Binary files /dev/null and b/src/views/dashboard/jfb.png differ diff --git a/src/views/dashboard/mixins/resize.js b/src/views/dashboard/mixins/resize.js new file mode 100644 index 0000000..d26194c --- /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/dataManage/electric.vue b/src/views/dataManage/electric.vue new file mode 100644 index 0000000..f13415f --- /dev/null +++ b/src/views/dataManage/electric.vue @@ -0,0 +1,239 @@ + + + + + \ No newline at end of file diff --git a/src/views/dataManage/env.vue b/src/views/dataManage/env.vue new file mode 100644 index 0000000..4c0d315 --- /dev/null +++ b/src/views/dataManage/env.vue @@ -0,0 +1,300 @@ + + + + + \ No newline at end of file diff --git a/src/views/equipment/air.vue b/src/views/equipment/air.vue new file mode 100644 index 0000000..d610211 --- /dev/null +++ b/src/views/equipment/air.vue @@ -0,0 +1,305 @@ + + + + + \ No newline at end of file diff --git a/src/views/equipment/electric.vue b/src/views/equipment/electric.vue new file mode 100644 index 0000000..a5d33f6 --- /dev/null +++ b/src/views/equipment/electric.vue @@ -0,0 +1,268 @@ + + + + + \ No newline at end of file diff --git a/src/views/equipment/environmentMonitoring.vue b/src/views/equipment/environmentMonitoring.vue new file mode 100644 index 0000000..09fd01d --- /dev/null +++ b/src/views/equipment/environmentMonitoring.vue @@ -0,0 +1,257 @@ + + + + + \ No newline at end of file diff --git a/src/views/equipment/lighting.vue b/src/views/equipment/lighting.vue new file mode 100644 index 0000000..f9b85d6 --- /dev/null +++ b/src/views/equipment/lighting.vue @@ -0,0 +1,354 @@ + + + + + \ No newline at end of file diff --git a/src/views/equipment/ollPump.vue b/src/views/equipment/ollPump.vue new file mode 100644 index 0000000..cc08179 --- /dev/null +++ b/src/views/equipment/ollPump.vue @@ -0,0 +1,392 @@ + + + + + \ No newline at end of file diff --git a/src/views/equipment/ventilation.vue b/src/views/equipment/ventilation.vue new file mode 100644 index 0000000..9b1b49e --- /dev/null +++ b/src/views/equipment/ventilation.vue @@ -0,0 +1,563 @@ + + + + + \ No newline at end of file diff --git a/src/views/equipment/wastewater.vue b/src/views/equipment/wastewater.vue new file mode 100644 index 0000000..bff8d9b --- /dev/null +++ b/src/views/equipment/wastewater.vue @@ -0,0 +1,392 @@ + + + + + \ No newline at end of file diff --git a/src/views/error/401.vue b/src/views/error/401.vue new file mode 100644 index 0000000..2bc8922 --- /dev/null +++ b/src/views/error/401.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/src/views/error/404.vue b/src/views/error/404.vue new file mode 100644 index 0000000..08a617a --- /dev/null +++ b/src/views/error/404.vue @@ -0,0 +1,227 @@ + + + + + diff --git a/src/views/index.vue b/src/views/index.vue new file mode 100644 index 0000000..6d13ea1 --- /dev/null +++ b/src/views/index.vue @@ -0,0 +1,465 @@ + + + + + + \ No newline at end of file diff --git a/src/views/index.vue.backup b/src/views/index.vue.backup new file mode 100644 index 0000000..69f4cf3 --- /dev/null +++ b/src/views/index.vue.backup @@ -0,0 +1,868 @@ + + + + + diff --git a/src/views/linkConfig/alarmConfig.vue b/src/views/linkConfig/alarmConfig.vue new file mode 100644 index 0000000..203db83 --- /dev/null +++ b/src/views/linkConfig/alarmConfig.vue @@ -0,0 +1,222 @@ + + + + + + + diff --git a/src/views/linkConfig/fanLinkConfig.vue b/src/views/linkConfig/fanLinkConfig.vue new file mode 100644 index 0000000..16ff658 --- /dev/null +++ b/src/views/linkConfig/fanLinkConfig.vue @@ -0,0 +1,1222 @@ + + + + + + \ No newline at end of file diff --git a/src/views/linkConfig/pumpLinkConfig.vue b/src/views/linkConfig/pumpLinkConfig.vue new file mode 100644 index 0000000..32d1225 --- /dev/null +++ b/src/views/linkConfig/pumpLinkConfig.vue @@ -0,0 +1,830 @@ + + + + + \ No newline at end of file diff --git a/src/views/linkConfig/sensorConfig.vue b/src/views/linkConfig/sensorConfig.vue new file mode 100644 index 0000000..8aa298c --- /dev/null +++ b/src/views/linkConfig/sensorConfig.vue @@ -0,0 +1,418 @@ + + + + + diff --git a/src/views/login.vue b/src/views/login.vue new file mode 100644 index 0000000..d54c6c5 --- /dev/null +++ b/src/views/login.vue @@ -0,0 +1,320 @@ + + + + + \ No newline at end of file diff --git a/src/views/mock/data.js b/src/views/mock/data.js new file mode 100644 index 0000000..8e8666b --- /dev/null +++ b/src/views/mock/data.js @@ -0,0 +1,47 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-26 15:19:01 + * @Description: + */ +// mock/data.js +export const mockDeviceData = [ + { + DeviceId: 1, + TypeId: 1, + AreaId: 1, + CabinName: "燃气舱", + DeviceName: "1分区燃气舱进口排风机", + IsOpen: true, + IsAlarm: false, + IsFault: false, + x: 200, + y: 355, + target: "device" + }, + // 更多设备... +]; + +export const mockCameraData = [ + { + CamId: 1, + AreaId: 1, + CabinName: "燃气舱", + CamName: "摄像头1", + CamAddress: "192.168.1.100", + x: 300, + y: 355, + target: "camera" + }, + // 更多摄像头... +]; + +export const mockAlertData = [ + { + AlertId: 1, + DeviceId: 1, + AreaId: 1, + Title: "设备报警", + Content: "燃气舱百叶窗异常", + AlertMode: "消防报警" + } +]; \ No newline at end of file diff --git a/src/views/monitor/cache/index.vue b/src/views/monitor/cache/index.vue new file mode 100644 index 0000000..b351fa9 --- /dev/null +++ b/src/views/monitor/cache/index.vue @@ -0,0 +1,132 @@ + + + diff --git a/src/views/monitor/cache/list.vue b/src/views/monitor/cache/list.vue new file mode 100644 index 0000000..77baec4 --- /dev/null +++ b/src/views/monitor/cache/list.vue @@ -0,0 +1,246 @@ + + + diff --git a/src/views/monitor/druid/index.vue b/src/views/monitor/druid/index.vue new file mode 100644 index 0000000..1faaead --- /dev/null +++ b/src/views/monitor/druid/index.vue @@ -0,0 +1,13 @@ + + + diff --git a/src/views/monitor/job/index.vue b/src/views/monitor/job/index.vue new file mode 100644 index 0000000..8dfbad2 --- /dev/null +++ b/src/views/monitor/job/index.vue @@ -0,0 +1,502 @@ + + + diff --git a/src/views/monitor/job/log.vue b/src/views/monitor/job/log.vue new file mode 100644 index 0000000..b425e45 --- /dev/null +++ b/src/views/monitor/job/log.vue @@ -0,0 +1,283 @@ + + + diff --git a/src/views/monitor/logininfor/index.vue b/src/views/monitor/logininfor/index.vue new file mode 100644 index 0000000..aa42b52 --- /dev/null +++ b/src/views/monitor/logininfor/index.vue @@ -0,0 +1,233 @@ + + + diff --git a/src/views/monitor/online/index.vue b/src/views/monitor/online/index.vue new file mode 100644 index 0000000..21f6463 --- /dev/null +++ b/src/views/monitor/online/index.vue @@ -0,0 +1,109 @@ + + + diff --git a/src/views/monitor/operlog/index.vue b/src/views/monitor/operlog/index.vue new file mode 100644 index 0000000..2f89b4c --- /dev/null +++ b/src/views/monitor/operlog/index.vue @@ -0,0 +1,310 @@ + + + diff --git a/src/views/monitor/server/index.vue b/src/views/monitor/server/index.vue new file mode 100644 index 0000000..5eb7945 --- /dev/null +++ b/src/views/monitor/server/index.vue @@ -0,0 +1,187 @@ + + + diff --git a/src/views/operationManage/alarm.vue b/src/views/operationManage/alarm.vue new file mode 100644 index 0000000..1677075 --- /dev/null +++ b/src/views/operationManage/alarm.vue @@ -0,0 +1,375 @@ + + + + + \ No newline at end of file diff --git a/src/views/operationManage/maintenance.vue b/src/views/operationManage/maintenance.vue new file mode 100644 index 0000000..78d7378 --- /dev/null +++ b/src/views/operationManage/maintenance.vue @@ -0,0 +1,849 @@ + + + + + diff --git a/src/views/operationManage/patrol.vue b/src/views/operationManage/patrol.vue new file mode 100644 index 0000000..d2bfa0e --- /dev/null +++ b/src/views/operationManage/patrol.vue @@ -0,0 +1,756 @@ + + + + + \ No newline at end of file diff --git a/src/views/operationManage/report.vue b/src/views/operationManage/report.vue new file mode 100644 index 0000000..aabaac3 --- /dev/null +++ b/src/views/operationManage/report.vue @@ -0,0 +1,397 @@ + + + + + \ No newline at end of file diff --git a/src/views/plan.vue b/src/views/plan.vue new file mode 100644 index 0000000..4d276d4 --- /dev/null +++ b/src/views/plan.vue @@ -0,0 +1,1481 @@ + + + + + + diff --git a/src/views/propertyManage.vue b/src/views/propertyManage.vue new file mode 100644 index 0000000..f06813b --- /dev/null +++ b/src/views/propertyManage.vue @@ -0,0 +1,484 @@ + + + + + \ No newline at end of file diff --git a/src/views/redirect/index.vue b/src/views/redirect/index.vue new file mode 100644 index 0000000..d932b25 --- /dev/null +++ b/src/views/redirect/index.vue @@ -0,0 +1,14 @@ + + + \ No newline at end of file diff --git a/src/views/register.vue b/src/views/register.vue new file mode 100644 index 0000000..e711967 --- /dev/null +++ b/src/views/register.vue @@ -0,0 +1,220 @@ + + + + + diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue new file mode 100644 index 0000000..77d9f5a --- /dev/null +++ b/src/views/system/config/index.vue @@ -0,0 +1,316 @@ + + + diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue new file mode 100644 index 0000000..5eb99cd --- /dev/null +++ b/src/views/system/dept/index.vue @@ -0,0 +1,283 @@ + + + diff --git a/src/views/system/dict/data.vue b/src/views/system/dict/data.vue new file mode 100644 index 0000000..eb98606 --- /dev/null +++ b/src/views/system/dict/data.vue @@ -0,0 +1,362 @@ + + + diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue new file mode 100644 index 0000000..73b35d8 --- /dev/null +++ b/src/views/system/dict/index.vue @@ -0,0 +1,322 @@ + + + diff --git a/src/views/system/log/index.vue b/src/views/system/log/index.vue new file mode 100644 index 0000000..9f763fc --- /dev/null +++ b/src/views/system/log/index.vue @@ -0,0 +1,211 @@ + + + + + \ No newline at end of file diff --git a/src/views/system/manual/index.vue b/src/views/system/manual/index.vue new file mode 100644 index 0000000..78abae5 --- /dev/null +++ b/src/views/system/manual/index.vue @@ -0,0 +1,332 @@ + + + + + + diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue new file mode 100644 index 0000000..78c49cf --- /dev/null +++ b/src/views/system/menu/index.vue @@ -0,0 +1,452 @@ + + + diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue new file mode 100644 index 0000000..96dadcc --- /dev/null +++ b/src/views/system/notice/index.vue @@ -0,0 +1,292 @@ + + + diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue new file mode 100644 index 0000000..2608669 --- /dev/null +++ b/src/views/system/post/index.vue @@ -0,0 +1,287 @@ + + + diff --git a/src/views/system/role/authUser.vue b/src/views/system/role/authUser.vue new file mode 100644 index 0000000..20be11c --- /dev/null +++ b/src/views/system/role/authUser.vue @@ -0,0 +1,179 @@ + + + + diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue new file mode 100644 index 0000000..dd7aedf --- /dev/null +++ b/src/views/system/role/index.vue @@ -0,0 +1,590 @@ + + + diff --git a/src/views/system/role/selectUser.vue b/src/views/system/role/selectUser.vue new file mode 100644 index 0000000..3e3d8aa --- /dev/null +++ b/src/views/system/role/selectUser.vue @@ -0,0 +1,144 @@ + + + diff --git a/src/views/system/user/authRole.vue b/src/views/system/user/authRole.vue new file mode 100644 index 0000000..3935ab1 --- /dev/null +++ b/src/views/system/user/authRole.vue @@ -0,0 +1,123 @@ + + + diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue new file mode 100644 index 0000000..cf3db1a --- /dev/null +++ b/src/views/system/user/index.vue @@ -0,0 +1,624 @@ + + + + + \ 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..df23125 --- /dev/null +++ b/src/views/system/user/profile/index.vue @@ -0,0 +1,94 @@ + + + diff --git a/src/views/system/user/profile/resetPwd.vue b/src/views/system/user/profile/resetPwd.vue new file mode 100644 index 0000000..308229a --- /dev/null +++ b/src/views/system/user/profile/resetPwd.vue @@ -0,0 +1,59 @@ + + + diff --git a/src/views/system/user/profile/userAvatar.vue b/src/views/system/user/profile/userAvatar.vue new file mode 100644 index 0000000..9dc42dd --- /dev/null +++ b/src/views/system/user/profile/userAvatar.vue @@ -0,0 +1,180 @@ + + + + + \ No newline at end of file diff --git a/src/views/system/user/profile/userInfo.vue b/src/views/system/user/profile/userInfo.vue new file mode 100644 index 0000000..77f6924 --- /dev/null +++ b/src/views/system/user/profile/userInfo.vue @@ -0,0 +1,67 @@ + + + diff --git a/src/views/tool/build/CodeTypeDialog.vue b/src/views/tool/build/CodeTypeDialog.vue new file mode 100644 index 0000000..de0beb7 --- /dev/null +++ b/src/views/tool/build/CodeTypeDialog.vue @@ -0,0 +1,71 @@ + + + \ No newline at end of file diff --git a/src/views/tool/build/DraggableItem.vue b/src/views/tool/build/DraggableItem.vue new file mode 100644 index 0000000..9ae2354 --- /dev/null +++ b/src/views/tool/build/DraggableItem.vue @@ -0,0 +1,68 @@ + + \ No newline at end of file diff --git a/src/views/tool/build/IconsDialog.vue b/src/views/tool/build/IconsDialog.vue new file mode 100644 index 0000000..98d9c13 --- /dev/null +++ b/src/views/tool/build/IconsDialog.vue @@ -0,0 +1,115 @@ + + + diff --git a/src/views/tool/build/RightPanel.vue b/src/views/tool/build/RightPanel.vue new file mode 100644 index 0000000..5fe80fb --- /dev/null +++ b/src/views/tool/build/RightPanel.vue @@ -0,0 +1,906 @@ + + + + + \ No newline at end of file diff --git a/src/views/tool/build/TreeNodeDialog.vue b/src/views/tool/build/TreeNodeDialog.vue new file mode 100644 index 0000000..372d3af --- /dev/null +++ b/src/views/tool/build/TreeNodeDialog.vue @@ -0,0 +1,93 @@ + + diff --git a/src/views/tool/build/index.vue b/src/views/tool/build/index.vue new file mode 100644 index 0000000..60159b0 --- /dev/null +++ b/src/views/tool/build/index.vue @@ -0,0 +1,653 @@ + + + + + diff --git a/src/views/tool/gen/basicInfoForm.vue b/src/views/tool/gen/basicInfoForm.vue new file mode 100644 index 0000000..8bfc373 --- /dev/null +++ b/src/views/tool/gen/basicInfoForm.vue @@ -0,0 +1,48 @@ + + + diff --git a/src/views/tool/gen/createTable.vue b/src/views/tool/gen/createTable.vue new file mode 100644 index 0000000..ef6f8f3 --- /dev/null +++ b/src/views/tool/gen/createTable.vue @@ -0,0 +1,46 @@ + + + diff --git a/src/views/tool/gen/editTable.vue b/src/views/tool/gen/editTable.vue new file mode 100644 index 0000000..f0a832c --- /dev/null +++ b/src/views/tool/gen/editTable.vue @@ -0,0 +1,211 @@ + + + diff --git a/src/views/tool/gen/genInfoForm.vue b/src/views/tool/gen/genInfoForm.vue new file mode 100644 index 0000000..b416a89 --- /dev/null +++ b/src/views/tool/gen/genInfoForm.vue @@ -0,0 +1,305 @@ + + + diff --git a/src/views/tool/gen/importTable.vue b/src/views/tool/gen/importTable.vue new file mode 100644 index 0000000..23dbf28 --- /dev/null +++ b/src/views/tool/gen/importTable.vue @@ -0,0 +1,126 @@ + + + diff --git a/src/views/tool/gen/index.vue b/src/views/tool/gen/index.vue new file mode 100644 index 0000000..d179f09 --- /dev/null +++ b/src/views/tool/gen/index.vue @@ -0,0 +1,308 @@ + + + diff --git a/src/views/tool/swagger/index.vue b/src/views/tool/swagger/index.vue new file mode 100644 index 0000000..f29c40f --- /dev/null +++ b/src/views/tool/swagger/index.vue @@ -0,0 +1,9 @@ + + + diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..03632d5 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,89 @@ +/* + * @Author: 季万俊 + * @Date: 2025-09-04 19:58:43 + * @Description: + */ +import { defineConfig, loadEnv } from 'vite' +import path from 'path' +import createVitePlugins from './vite/plugins' + +const baseUrl = 'http://172.16.1.162:18080/' // 后端接口 + +// https://vitejs.dev/config/ +export default defineConfig(({ mode, command }) => { + const env = loadEnv(mode, process.cwd()) + const { VITE_APP_ENV } = env + return { + // 部署生产环境和开发环境下的URL。 + // 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上 + // 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。 + base: VITE_APP_ENV === 'production' ? '/' : '/', + plugins: createVitePlugins(env, command === 'build'), + resolve: { + // https://cn.vitejs.dev/config/#resolve-alias + alias: { + // 设置路径 + '~': path.resolve(__dirname, './'), + // 设置别名 + '@': path.resolve(__dirname, './src') + }, + // https://cn.vitejs.dev/config/#resolve-extensions + extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'] + }, + // 打包配置 + build: { + // https://vite.dev/config/build-options.html + sourcemap: command === 'build' ? false : 'inline', + outDir: 'dist', + assetsDir: 'assets', + chunkSizeWarningLimit: 2000, + rollupOptions: { + output: { + chunkFileNames: 'static/js/[name]-[hash].js', + entryFileNames: 'static/js/[name]-[hash].js', + assetFileNames: 'static/[ext]/[name]-[hash].[ext]' + } + } + }, + // vite 相关配置 + server: { + port: 80, + host: true, + open: true, + proxy: { + // https://cn.vitejs.dev/config/#server-proxy + '/api': { + target: baseUrl, + changeOrigin: true, + // pathRewrite: { '^/dev-api': '' } + }, + } + }, + css: { + preprocessorOptions: { + scss: { + // 屏蔽Sass的@import deprecation警告 + quietDeps: true, // 抑制依赖中的警告 + // 可选:针对特定警告代码进行屏蔽(Sass的@import警告代码为deprecation-module-import) + warningSuppress: [ + { code: 'deprecation-module-import' } + ] + } + }, + postcss: { + plugins: [ + { + postcssPlugin: 'internal:charset-removal', + AtRule: { + charset: (atRule) => { + if (atRule.name === 'charset') { + atRule.remove() + } + } + } + } + ] + } + } + } +}) diff --git a/vite/plugins/auto-import.js b/vite/plugins/auto-import.js new file mode 100644 index 0000000..ba51689 --- /dev/null +++ b/vite/plugins/auto-import.js @@ -0,0 +1,12 @@ +import autoImport from 'unplugin-auto-import/vite' + +export default function createAutoImport() { + return autoImport({ + imports: [ + 'vue', + 'vue-router', + 'pinia' + ], + dts: false + }) +} diff --git a/vite/plugins/compression.js b/vite/plugins/compression.js new file mode 100644 index 0000000..9767308 --- /dev/null +++ b/vite/plugins/compression.js @@ -0,0 +1,28 @@ +import compression from 'vite-plugin-compression' + +export default function createCompression(env) { + const { VITE_BUILD_COMPRESS } = env + const plugin = [] + if (VITE_BUILD_COMPRESS) { + const compressList = VITE_BUILD_COMPRESS.split(',') + if (compressList.includes('gzip')) { + // http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件 + plugin.push( + compression({ + ext: '.gz', + deleteOriginFile: false + }) + ) + } + if (compressList.includes('brotli')) { + plugin.push( + compression({ + ext: '.br', + algorithm: 'brotliCompress', + deleteOriginFile: false + }) + ) + } + } + return plugin +} diff --git a/vite/plugins/index.js b/vite/plugins/index.js new file mode 100644 index 0000000..7715adc --- /dev/null +++ b/vite/plugins/index.js @@ -0,0 +1,15 @@ +import vue from '@vitejs/plugin-vue' + +import createAutoImport from './auto-import' +import createSvgIcon from './svg-icon' +import createCompression from './compression' +import createSetupExtend from './setup-extend' + +export default function createVitePlugins(viteEnv, isBuild = false) { + const vitePlugins = [vue()] + vitePlugins.push(createAutoImport()) + vitePlugins.push(createSetupExtend()) + vitePlugins.push(createSvgIcon(isBuild)) + isBuild && vitePlugins.push(...createCompression(viteEnv)) + return vitePlugins +} diff --git a/vite/plugins/setup-extend.js b/vite/plugins/setup-extend.js new file mode 100644 index 0000000..eac072c --- /dev/null +++ b/vite/plugins/setup-extend.js @@ -0,0 +1,5 @@ +import setupExtend from 'unplugin-vue-setup-extend-plus/vite' + +export default function createSetupExtend() { + return setupExtend({}) +} diff --git a/vite/plugins/svg-icon.js b/vite/plugins/svg-icon.js new file mode 100644 index 0000000..f23beff --- /dev/null +++ b/vite/plugins/svg-icon.js @@ -0,0 +1,10 @@ +import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' +import path from 'path' + +export default function createSvgIcon(isBuild) { + return createSvgIconsPlugin({ + iconDirs: [path.resolve(process.cwd(), 'src/assets/icons/svg')], + symbolId: 'icon-[dir]-[name]', + svgoOptions: isBuild + }) +}