From f0720439d2e91d471aa0b776973c3cc8e203b454 Mon Sep 17 00:00:00 2001
From: ym1026 <1539963735@qq.com>
Date: Fri, 12 Sep 2025 10:58:59 +0800
Subject: [PATCH] =?UTF-8?q?=E6=A0=B7=E5=BC=8F=20=E8=AD=A6=E5=91=8A?=
=?UTF-8?q?=E5=A4=84=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web/public/config/columnList.js | 30 +----
web/src/components/ComTable.vue | 10 +-
web/src/components/EditCom.vue | 121 +++++++++++++-----
web/src/components/TreeTable.vue | 5 +
web/src/router/index.js | 40 +++++-
web/src/style/antd.scss | 13 +-
web/src/views/statisticalAnalysis.vue | 174 ++++++++++++--------------
web/src/views/system/permission.vue | 1 -
web/src/views/system/role.vue | 3 +-
web/src/views/system/service.vue | 3 +-
web/src/views/system/station.vue | 3 +-
web/src/views/system/user.vue | 2 +
12 files changed, 246 insertions(+), 159 deletions(-)
diff --git a/web/public/config/columnList.js b/web/public/config/columnList.js
index 3620499..fdba700 100644
--- a/web/public/config/columnList.js
+++ b/web/public/config/columnList.js
@@ -228,6 +228,8 @@ export const columnList = [
{
title: '操作',
dataIndex: 'operate',
+ fixed: 'right',
+
key: 'operate',
scopedSlots: { customRender: 'action' }
}
@@ -667,29 +669,9 @@ export const stationOptions = [
label: '场站运行模式',
value: undefined,
key: 'work_mode',
- type: 'select',
- list: [
- {
- label: '峰谷套利',
- value: '1'
- },
- {
- label: '增网配容',
- value: '2'
- },
- {
- label: '应急供电',
- value: '3'
- },
- {
- label: '并网保电',
- value: '4'
- },
- {
- label: '自定时段',
- value: '5'
- }
- ]
+ type: 'slot',
+ slotName: 'work_mode',
+ list: []
},
{
// 0:未启用,1:启用
@@ -697,7 +679,7 @@ export const stationOptions = [
label: '场站运行策略',
value: undefined,
key: 'policy_id',
- type: 'select',
+ type: 'unshow',
list: [
{
label: '削峰套利',
diff --git a/web/src/components/ComTable.vue b/web/src/components/ComTable.vue
index 47a8073..53e8dd4 100644
--- a/web/src/components/ComTable.vue
+++ b/web/src/components/ComTable.vue
@@ -387,11 +387,15 @@ defineExpose({ ...toRefs(data), loading, mountedScroll, scroll: data.scroll })
background: #082e4a !important;
}
+ :deep(.ant-table.ant-table-has-fix-left.ant-table-middle.ant-table-bordered){
+ border-radius: 20px !important;
+
+ }
:deep(.ant-table-body) {
color:#fff;
background: $table-bg !important;
- border: 1px solid $table-border;
- border-radius: 0px 0px 20px 20px;
+ // border: 1px solid $table-border;
+ border-radius: 20px!important;
.ant-table-cell {
background: var(--theme-bg) !important;
}
@@ -424,6 +428,8 @@ defineExpose({ ...toRefs(data), loading, mountedScroll, scroll: data.scroll })
}
:deep(.ant-table-wrapper .ant-table) {
+ border: 1px solid $table-border!important;
+
background-color: transparent !important;
}
diff --git a/web/src/components/EditCom.vue b/web/src/components/EditCom.vue
index 05fbead..8e7f709 100644
--- a/web/src/components/EditCom.vue
+++ b/web/src/components/EditCom.vue
@@ -8,6 +8,24 @@
:ref="'detailInfo' + index"
:disabled="disabled"
>
+
+
+
+ {{ selectItem.label }}
+
+
+
+
({
// ...item,
@@ -325,8 +389,8 @@ export default {
// }))
// console.log(arr,"arr")
- const data=this.filterTreeData(selectedRowKeys,this.$refs.treeTable[0].tableData)
- const arr = data.map((item) => ({
+ const data = this.filterTreeData(selectedRowKeys, this.$refs.treeTable[0].tableData)
+ const arr = data.map((item) => ({
...item,
// 转换操作权限为布尔值
@@ -335,14 +399,13 @@ export default {
children: item.children
? item.children.map((child) => ({
...child,
- ...this.getPerOperBoolean(child),
-
+ ...this.getPerOperBoolean(child)
}))
: []
}))
const paramsDate = {
...this.form,
- permission:arr
+ permission: arr
}
if (this.action == 'edit') {
@@ -363,61 +426,57 @@ export default {
},
// 定义筛选树形数据的函数
filterTreeData(list1, list2) {
- const keySet = new Set(list1);
+ const keySet = new Set(list1)
// 递归处理节点的函数
const filterNode = (node) => {
// 创建新节点对象(浅拷贝)
- const newNode = Object.assign({}, node);
+ const newNode = Object.assign({}, node)
// 临时删除children属性以便处理
- const { children, ...rest } = newNode;
+ const { children, ...rest } = newNode
// 处理子节点
- let newChildren = [];
+ let newChildren = []
if (children) {
- newChildren = children
- .map((child) => filterNode(child))
- .filter((child) => child !== null);
+ newChildren = children.map((child) => filterNode(child)).filter((child) => child !== null)
}
// 重建新节点
- const resultNode = Object.assign(rest, {});
+ const resultNode = Object.assign(rest, {})
if (newChildren.length > 0) {
- resultNode.children = newChildren;
+ resultNode.children = newChildren
}
// 判断是否保留节点
if (keySet.has(node.key)) {
- return resultNode;
+ return resultNode
}
// 保留有符合条件子节点的父节点(移除自身key)
if (newChildren.length > 0) {
- return resultNode;
+ return resultNode
}
- return null;
- };
+ return null
+ }
// 处理根节点
- const result = list2
- .map((node) => filterNode(node))
- .filter((node) => node !== null);
+ const result = list2.map((node) => filterNode(node)).filter((node) => node !== null)
- return result;
+ return result
},
getPerOperBoolean(data) {
return {
- is_add: Boolean(data.is_add)? '1' : '0',
- is_del: Boolean(data.is_del)? '1' : '0',
- is_edit: Boolean(data.is_edit)? '1' : '0',
- is_view: Boolean(data.is_view)? '1' : '0'
+ is_add: Boolean(data.is_add) ? '1' : '0',
+ is_del: Boolean(data.is_del) ? '1' : '0',
+ is_edit: Boolean(data.is_edit) ? '1' : '0',
+ is_view: Boolean(data.is_view) ? '1' : '0'
}
},
- getPermissionData(keys,list){
- const arr=[]
+ getPermissionData(keys, list) {
+ const arr = []
// list.forEach(item=>{
// if(keys.include(item.key)){
// arr.push(item)
diff --git a/web/src/components/TreeTable.vue b/web/src/components/TreeTable.vue
index 73c8db3..0b53b26 100644
--- a/web/src/components/TreeTable.vue
+++ b/web/src/components/TreeTable.vue
@@ -439,8 +439,13 @@ export default {
}
:deep(.ant-table-container > .ant-table-content > table) {
+
border-inline-start: 1px solid var(--theme-bg) !important;
}
+ :deep(.ant-table.ant-table-has-fix-left.ant-table-middle.ant-table-bordered){
+ border-radius: 20px !important;
+
+ }
:deep(.ant-pagination-item-link) {
color: var(--theme-text-default) !important;
diff --git a/web/src/router/index.js b/web/src/router/index.js
index 8a545e5..b2d8a11 100644
--- a/web/src/router/index.js
+++ b/web/src/router/index.js
@@ -14,40 +14,47 @@ export const routes = [
path: '/',
name: '/',
redirect: '/home',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "main" */ '@/views/MainView.vue'),
children: [
{
path: 'home',
- component: () => import(/* webpackChunkName: "monitor" */ '@/views/sub/Home.vue')
+ component: () => import(/* webpackChunkName: "monitor" */ '@/views/sub/Home.vue'),
+ meta: { requiresAuth: true }
},
{
path: 'monitor',
name: 'monitor',
title: '运行监控',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "monitor" */ '@/views/monitor.vue')
},
{
path: 'predict',
name: 'predict',
title: '预测管理',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "predict" */ '@/views/predict.vue')
},
{
path: 'statisticalAnalysis',
name: 'statisticalAnalysis',
title: '统计分析',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "monitor" */ '@/views/statisticalAnalysis.vue')
},
{
path: 'system',
name: 'system',
redirect: '/system/user',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/index.vue'),
children: [
{
path: 'user',
name: 'user',
title: '用户管理',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/user.vue')
},
@@ -55,12 +62,14 @@ export const routes = [
name: 'role',
path: 'role',
title: '角色管理',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/role.vue')
},
{
name: 'permission',
path: 'permission',
title: '权限管理',
+ meta: { requiresAuth: true },
component: () =>
import(/* webpackChunkName: "system" */ '@/views/system/permission.vue')
},
@@ -68,36 +77,42 @@ export const routes = [
name: 'station',
path: 'station',
title: '场站管理',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/station.vue')
},
{
name: 'service',
path: 'service',
title: '服务管理',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/service.vue')
},
{
path: 'policy',
name: 'policy',
title: '策略管理',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/policy.vue')
},
{
name: 'device',
path: 'device',
title: '设备管理',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/device.vue')
},
{
name: 'alarmlog',
path: 'alarmlog',
title: '告警日志',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/alarmLog.vue')
},
{
name: 'syslog',
path: 'syslog',
title: '系统日志',
+ meta: { requiresAuth: true },
component: () => import(/* webpackChunkName: "system" */ '@/views/system/log.vue')
}
]
@@ -111,4 +126,27 @@ const router = createRouter({
routes
})
+// 全局前置守卫
+router.beforeEach((to, from, next) => {
+ const isLoggedIn = localStorage.getItem('token') // 检查用户是否已登录
+
+ // 2. 如果访问登录页且已登录,跳转到首页
+ if (to.path === '/login' && isLoggedIn) {
+ next('/')
+ return
+ }
+
+ // 3. 检查路由权限
+ if (to.matched.some((record) => record.meta.requiresAuth)) {
+ if (!isLoggedIn) {
+ // 未登录则重定向到登录页,并携带原路径
+ next('/login')
+ } else {
+ next()
+ }
+ } else {
+ next() // 无需认证的路由直接放行
+ }
+})
+
export default router
diff --git a/web/src/style/antd.scss b/web/src/style/antd.scss
index 3e659de..189abcd 100644
--- a/web/src/style/antd.scss
+++ b/web/src/style/antd.scss
@@ -18,8 +18,14 @@ $page-border: #cad2dd;
.ant-switch {
background: #b1c4c4;
}
-.ant-switch.ant-switch-checked{
- background: #00fffb
+.ant-switch.ant-switch-checked {
+ background: #00fffb;
+}
+.ant-select .ant-select-arrow {
+ background: transparent !important;
+}
+.ant-select .ant-select-clear {
+ background: transparent !important;
}
.ant-switch .ant-switch-handle::before {
@@ -58,9 +64,8 @@ $page-border: #cad2dd;
.ant-picker-input input::placeholder {
color: #ffffff3b !important;
}
- .ant-picker-suffix{
+ .ant-picker-suffix {
color: #ffffff !important;
-
}
}
.ant-input-affix-wrapper {
diff --git a/web/src/views/statisticalAnalysis.vue b/web/src/views/statisticalAnalysis.vue
index 8d585a6..d1bfb54 100644
--- a/web/src/views/statisticalAnalysis.vue
+++ b/web/src/views/statisticalAnalysis.vue
@@ -20,7 +20,7 @@
>
@@ -166,7 +166,7 @@ export default {
}
],
chartData: {},
- chartDatav: {},
+ chartDatav: {}
},
2: {
chartOptions: [
@@ -281,19 +281,20 @@ export default {
}
},
activeKey: 1,
- interval:null,
+ interval: null,
tabList: [
{
key: 1,
name: '储能设备'
},
- {
- key: 2,
- name: '光伏设备'
- },
+
{
key: 3,
name: '充电设备'
+ },
+ {
+ key: 2,
+ name: '光伏设备'
}
],
tableList: {
@@ -505,123 +506,116 @@ export default {
watch: {
activeKey: {
handler(newVal) {
- if (!newVal) return;
-
+ if (!newVal) return
+
// 清除之前的数据
- this.resetDataForInactiveKey();
-
+ this.resetDataForInactiveKey()
+
// 并行加载新数据
- Promise.all([
- this.getEchartsListForActiveKey(),
- this.getTableListForActiveKey()
- ]).then(() => {
- this.$nextTick(() => {
- this.getStatCharts();
-
- });
- });
+ Promise.all([this.getEchartsListForActiveKey(), this.getTableListForActiveKey()]).then(
+ () => {
+ this.$nextTick(() => {
+ this.getStatCharts()
+ })
+ }
+ )
},
immediate: true // 添加立即执行
}
},
async mounted() {
- // 优先加载第一个页面(activeKey=1)所需的数据
+ // 优先加载第一个页面(activeKey=1)所需的数据
await Promise.all([
this.getStationList(),
this.getEchartsListForActiveKey(),
this.getTableListForActiveKey()
- ]);
-
+ ])
+
// 初始化实时刷新
- this.startRealtimeRefresh();
+ this.startRealtimeRefresh()
},
beforeUnmount() {
console.log('beforeUnmount')
- clearInterval(this.interval); // 组件销毁时清除定时器
+ clearInterval(this.interval) // 组件销毁时清除定时器
},
methods: {
forceRerender() {
- this.renderKey += 1;
+ this.renderKey += 1
},
resetDataForInactiveKey() {
- // 重置非当前激活页面的数据,减少内存占用
+ // 重置非当前激活页面的数据,减少内存占用
Object.keys(this.echartsInfo).forEach((key) => {
if (key != this.activeKey) {
- this.echartsInfo[key].chartData={}
- this.echartsInfo[key].chartDatav={}
-
+ this.echartsInfo[key].chartData = {}
+ this.echartsInfo[key].chartDatav = {}
}
- });
-
+ })
+
Object.keys(this.tableList).forEach((key) => {
if (key != this.activeKey) {
- this.echartsInfo[key].tableData={}
-
+ this.echartsInfo[key].tableData = {}
}
- });
+ })
},
async getEchartsListForActiveKey() {
- if (!this.activeKey) return;
- this.loading.chart = true;
-
- const currentInfo = this.echartsInfo[this.activeKey];
+ if (!this.activeKey) return
+ this.loading.chart = true
+
+ const currentInfo = this.echartsInfo[this.activeKey]
const query = {
...this.paramsDate,
category: this.activeKey
- };
-
+ }
+
try {
- const res = await getReq('/queryStatDayList', query);
+ const res = await getReq('/queryStatDayList', query)
if (res.errcode === 0) {
- this.echartsInfo[this.activeKey].chartData=res.data
- this.loading.chart = false;
+ this.echartsInfo[this.activeKey].chartData = res.data
+ this.loading.chart = false
} else {
- throw res;
+ throw res
}
} catch (error) {
- this.loading.chart = false;
- this.echartsInfo[this.activeKey].chartData={}
-
+ this.loading.chart = false
+ this.echartsInfo[this.activeKey].chartData = {}
}
},
// 专门获取当前激活页面的表格数据
async getTableListForActiveKey() {
- this.loading.table = true;
- if (!this.activeKey) return;
-
- const currentInfo = this.tableList[this.activeKey];
+ this.loading.table = true
+ if (!this.activeKey) return
+
+ const currentInfo = this.tableList[this.activeKey]
const query = {
...this.paramsDate,
category: this.activeKey,
page_size: currentInfo.pageOption.pageSize,
pageNumber: currentInfo.pageOption.page
- };
-
+ }
+
try {
- const res = await getReq('/queryStatDayList', query);
+ const res = await getReq('/queryStatDayList', query)
if (res.errcode === 0) {
- this.tableList[this.activeKey].tableData=res.data.list || res.data
- this.tableList[this.activeKey].pageOption.count=res.data.count || 0
- this.loading.table = false;
+ this.tableList[this.activeKey].tableData = res.data.list || res.data
+ this.tableList[this.activeKey].pageOption.count = res.data.count || 0
+ this.loading.table = false
} else {
- throw res;
+ throw res
}
} catch (error) {
-
- this.tableList[this.activeKey].tableData=[]
- this.tableList[this.activeKey].pageOption.count= 0
- this.loading.table = false;
+ this.tableList[this.activeKey].tableData = []
+ this.tableList[this.activeKey].pageOption.count = 0
+ this.loading.table = false
}
},
startRealtimeRefresh() {
this.interval = setInterval(() => {
if (this.activeKey) {
- this.getStatCharts(); // 定时获取最新实时数据
+ this.getStatCharts() // 定时获取最新实时数据
}
- }, 10000); // 30秒刷新一次
+ }, 10000) // 30秒刷新一次
},
-
async getStationList() {
const params = {
page_size: 1000,
@@ -655,21 +649,18 @@ export default {
this.tableList[this.activeKey].pageOption.pageSize = e.pageSize
this.tableList[this.activeKey].pageOption.page = e.page
this.getTableListForActiveKey()
-
},
onSearch(data) {
this.paramsDate.start_date = data.time ? data.time[0] : ''
this.paramsDate.end_date = data.time ? data.time[1] : ''
this.tableList[this.activeKey].pageOption.page = 1
- this.getStationList(),
- this.getEchartsListForActiveKey(),
- this.getTableListForActiveKey()
+ this.getStationList(), this.getEchartsListForActiveKey(), this.getTableListForActiveKey()
},
changeStation() {
- this.getStatCharts();
+ this.getStatCharts()
},
-
+
// async getEchartsList() {
// const key = activeKey || this.activeKey;
// if (!key) return;
@@ -705,26 +696,23 @@ export default {
const res = await getReq('/queryStatCharts', query)
if (res.errcode === 0) {
this.echartsInfo[this.activeKey].chartDatav = {
- "V":[100.0,100.0,100.0], // 电压曲线
- "I":[10.0,10.0,10.0], // 电流曲线
- "P":[1000.0,1000.0,1000.0], // 功率曲线
+ V: [100.0, 100.0, 100.0], // 电压曲线
+ I: [10.0, 10.0, 10.0], // 电流曲线
+ P: [1000.0, 1000.0, 1000.0] // 功率曲线
}
// x轴0点到24点
-
-
-
} else {
throw res
}
} catch (error) {
this.echartsInfo[this.activeKey].chartDatav = {
- "V":[100.0,100.0,100.0], // 电压曲线
- "I":[10.0,10.0,10.0], // 电流曲线
- "P":[1000.0,1000.0,1000.0], // 功率曲线
+ V: [100.0, 100.0, 100.0], // 电压曲线
+ I: [10.0, 10.0, 10.0], // 电流曲线
+ P: [1000.0, 1000.0, 1000.0] // 功率曲线
}
}
- },
+ }
// async getTableList() {
// const currentInfo = this.tableList[this.activeKey]
diff --git a/web/src/views/system/permission.vue b/web/src/views/system/permission.vue
index cea6922..aaee665 100644
--- a/web/src/views/system/permission.vue
+++ b/web/src/views/system/permission.vue
@@ -3,7 +3,6 @@
diff --git a/web/src/views/system/role.vue b/web/src/views/system/role.vue
index ecee782..05d606d 100644
--- a/web/src/views/system/role.vue
+++ b/web/src/views/system/role.vue
@@ -3,7 +3,6 @@
@@ -125,6 +124,8 @@ export default {
throw err
}
} catch (error) {
+ this.$refs.comTable.loading = false
+
//统一处理报错提示
}
},
diff --git a/web/src/views/system/service.vue b/web/src/views/system/service.vue
index 8d6e70a..6d1c7f3 100644
--- a/web/src/views/system/service.vue
+++ b/web/src/views/system/service.vue
@@ -3,7 +3,6 @@
@@ -145,6 +144,8 @@ export default {
}
} catch (error) {
//统一处理报错提示
+ this.$refs.comTable.loading = false
+
}
},
operateForm(type, record = {}) {
diff --git a/web/src/views/system/station.vue b/web/src/views/system/station.vue
index 9ffad72..84e249c 100644
--- a/web/src/views/system/station.vue
+++ b/web/src/views/system/station.vue
@@ -3,7 +3,6 @@
@@ -161,6 +160,8 @@ export default {
}
} catch (error) {
//统一处理报错提示
+ this.$refs.comTable.loading = false
+
}
},
operateForm(type, record = {}) {
diff --git a/web/src/views/system/user.vue b/web/src/views/system/user.vue
index 36c530a..9d713f7 100644
--- a/web/src/views/system/user.vue
+++ b/web/src/views/system/user.vue
@@ -114,6 +114,8 @@ export default {
throw err
}
} catch (error) {
+ this.$refs.comTable.loading = false
+
//统一处理报错提示
}
},