From 65d1ad93efd5f5dc65bcb5974294479d00d00ca4 Mon Sep 17 00:00:00 2001 From: zhoumengru Date: Tue, 23 Sep 2025 14:19:36 +0800 Subject: [PATCH] =?UTF-8?q?```=20feat(web):=20=E6=B7=BB=E5=8A=A0=20sm-cryp?= =?UTF-8?q?to=20=E5=BA=93=E6=94=AF=E6=8C=81=20SM3=20=E5=8A=A0=E5=AF=86?= =?UTF-8?q?=E5=8F=8A=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在登录模块中增加 SM3 加密调用逻辑 - 新增导出按钮和相关处理逻辑,支持统计分析数据导出 - 调整多个页面样式布局,优化组件结构与代码可读性 - 更新设备类型配置,新增“冷机”和“网关”类型 - 添加 download 工具函数,支持通过 URL 下载文件 - 配置 webpack 代理,支持文件下载路径转发 ``` --- web/package-lock.json | 16 +++ web/package.json | 1 + web/src/components/SearchBox.vue | 17 +-- web/src/utils/btnList.js | 3 +- web/src/utils/config.js | 10 ++ web/src/utils/download.js | 16 +++ web/src/views/LoginView.vue | 13 +- web/src/views/statisticalAnalysis.vue | 169 ++++++++++++++++---------- web/src/views/system/device.vue | 11 +- web/src/views/system/policy.vue | 5 +- web/src/views/system/role.vue | 4 +- web/src/views/system/service.vue | 4 +- web/src/views/system/station.vue | 4 +- web/src/views/system/user.vue | 4 +- web/vue.config.js | 8 ++ 15 files changed, 192 insertions(+), 93 deletions(-) create mode 100644 web/src/utils/download.js diff --git a/web/package-lock.json b/web/package-lock.json index 58c10d3..91a24b2 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -14,6 +14,7 @@ "echarts": "^6.0.0", "moment": "^2.30.1", "qs": "^6.12.3", + "sm-crypto": "^0.3.13", "vue": "^3.2.13", "vue-router": "^4.0.3", "vuex": "^4.0.0" @@ -9791,6 +9792,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "license": "MIT" + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz", @@ -13633,6 +13640,15 @@ "node": ">=8" } }, + "node_modules/sm-crypto": { + "version": "0.3.13", + "resolved": "https://registry.npmmirror.com/sm-crypto/-/sm-crypto-0.3.13.tgz", + "integrity": "sha512-ztNF+pZq6viCPMA1A6KKu3bgpkmYti5avykRHbcFIdSipFdkVmfUw2CnpM2kBJyppIalqvczLNM3wR8OQ0pT5w==", + "license": "MIT", + "dependencies": { + "jsbn": "^1.1.0" + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmmirror.com/sockjs/-/sockjs-0.3.24.tgz", diff --git a/web/package.json b/web/package.json index 4ebbaef..230bcce 100644 --- a/web/package.json +++ b/web/package.json @@ -15,6 +15,7 @@ "echarts": "^6.0.0", "moment": "^2.30.1", "qs": "^6.12.3", + "sm-crypto": "^0.3.13", "vue": "^3.2.13", "vue-router": "^4.0.3", "vuex": "^4.0.0" diff --git a/web/src/components/SearchBox.vue b/web/src/components/SearchBox.vue index 4befc3f..a94fa3e 100644 --- a/web/src/components/SearchBox.vue +++ b/web/src/components/SearchBox.vue @@ -192,11 +192,12 @@ input:-internal-autofill-selected { color: var(--theme-text-default) !important; } .search { - height:70px; + // height:70px; color: #fff; display: flex; - flex-direction: column; + // flex-direction: column; justify-content: space-between; + margin-bottom: 20px; .page-title { display: flex; align-items: center; @@ -321,17 +322,17 @@ input:-internal-autofill-selected { .item { display: flex; align-items: center; - margin-bottom: 15px; + // margin-bottom: 15px; margin-right: 20px; } } } .bottom { - display: flex; - margin-top: 20px; - margin-bottom: 20px; - justify-content: space-between; - align-items: center; + // display: flex; + // margin-top: 20px; + // margin-bottom: 20px; + // justify-content: space-between; + // align-items: center; .button { // margin-left: 10px; } diff --git a/web/src/utils/btnList.js b/web/src/utils/btnList.js index 0fac717..c2f78ce 100644 --- a/web/src/utils/btnList.js +++ b/web/src/utils/btnList.js @@ -3,7 +3,8 @@ const btnList = [ { label: '新增', type: 'add', disFlag: 'is_add', icon: 'icon-add' }, { label: '查看', type: 'read', disFlag: 'is_view' }, { label: '修改', type: 'edit', disFlag: 'is_edit' }, - { label: '删除', type: 'del', disFlag: 'is_del', icon: 'icon-del' } + { label: '删除', type: 'del', disFlag: 'is_del', icon: 'icon-del' }, + { label: '导出', type: 'output', disFlag: 'is_edit', icon: 'icon-add' } ] function findNodeByRoute(tree, targetRoute) { for (const node of tree) { diff --git a/web/src/utils/config.js b/web/src/utils/config.js index edd23ba..79ecbbc 100644 --- a/web/src/utils/config.js +++ b/web/src/utils/config.js @@ -80,6 +80,16 @@ export const deviceTypeList = [ label: '视频监控', iconfont: 'icon-shipinjiankong' }, + { + value: '14', + label: '冷机', + iconfont: 'icon-lengjitubiao' + }, + { + value: '15', + label: '网关', + iconfont: 'icon-wangguan' + }, { value: '100', label: '储能预制舱', diff --git a/web/src/utils/download.js b/web/src/utils/download.js new file mode 100644 index 0000000..2568d7f --- /dev/null +++ b/web/src/utils/download.js @@ -0,0 +1,16 @@ +export function downloadByUrl(file) { + fetch(file.url) + .then((response) => response.blob()) + .then((blob) => { + const url = window.URL.createObjectURL(blob) + const a = document.createElement('a') + a.style.display = 'none' + a.href = url + // 设置下载的文件名 + a.download = file.name + document.body.appendChild(a) + a.click() + window.URL.revokeObjectURL(url) + }) + .catch((error) => console.error('Error downloading the file:', error)) +} diff --git a/web/src/views/LoginView.vue b/web/src/views/LoginView.vue index aac664d..cf1de08 100644 --- a/web/src/views/LoginView.vue +++ b/web/src/views/LoginView.vue @@ -38,8 +38,10 @@