120 Commits

Author SHA1 Message Date
caozehui
8a5bcca901 微调 2025-01-02 20:27:36 +08:00
caozehui
410cd53e51 正式检测-预检测提示及日志功能 2025-01-02 18:00:58 +08:00
sjl
4031724fa9 tab页面自动切换 2025-01-02 14:17:41 +08:00
sjl
e95552e6b9 微调 2025-01-02 13:12:13 +08:00
sjl
012f7e3346 Merge branch 'master' of http://192.168.1.22:3000/frontend/pqs-9100_client 2025-01-02 09:02:54 +08:00
sjl
cbe6c4a98d 微调 2025-01-02 09:02:46 +08:00
caozehui
aa52778e99 微调 2024-12-31 19:54:27 +08:00
caozehui
5e8dda0b75 微调 2024-12-31 19:03:52 +08:00
caozehui
081aeacff7 微调 2024-12-31 14:27:36 +08:00
caozehui
65e54ee2b5 正式检测-左侧检测大项动态获取 2024-12-30 20:55:11 +08:00
sjl
0fd6ebf810 系数校准调整 2024-12-30 19:59:15 +08:00
sjl
fa4b5d26e5 系数校准 2024-12-30 19:17:39 +08:00
sjl
23f45b38cb Merge branch 'master' of http://192.168.1.22:3000/frontend/pqs-9100_client 2024-12-30 14:43:20 +08:00
sjl
d76b055730 系数校准 2024-12-30 14:43:13 +08:00
caozehui
c334c07b39 微调 2024-12-30 14:41:34 +08:00
caozehui
45a5dcb068 微调 2024-12-28 16:50:32 +08:00
caozehui
3d9ba8b1cb 微调 2024-12-27 14:29:21 +08:00
caozehui
c6836cad06 微调 2024-12-27 13:36:20 +08:00
caozehui
e70d1cb3f2 处理正式检测bug 2024-12-27 10:31:15 +08:00
caozehui
af454e1a56 修改正式检测样式 2024-12-26 10:49:55 +08:00
sjl
6ce58e86ad 微调 2024-12-26 09:28:19 +08:00
2e17531c52 预见测代码 2024-12-25 20:29:27 +08:00
caozehui
6b76d89507 微调 2024-12-25 18:04:16 +08:00
caozehui
e4025e39cb 微调 2024-12-25 13:22:54 +08:00
sjl
af12dc8d0a frontend/src/views/machine/errorSystem/components/errorSystemDetailTable.vue 2024-12-24 20:25:10 +08:00
sjl
f0edeaee85 误差体系禁用 2024-12-24 20:22:36 +08:00
caozehui
5cbdadecc4 微调 2024-12-24 19:21:43 +08:00
caozehui
30c1f90513 微调 2024-12-24 11:29:31 +08:00
c241d8b819 预见测代码 2024-12-24 08:55:04 +08:00
24f12a3590 预见测代码 2024-12-23 21:02:00 +08:00
sjl
f17f5c9925 误差体系 2024-12-23 16:12:46 +08:00
sjl
99877b1c98 系数校准动态通道数 2024-12-23 15:08:14 +08:00
sjl
fdf91965d9 微调 2024-12-23 14:05:53 +08:00
caozehui
fd21d32f4a 微调 2024-12-23 13:23:28 +08:00
caozehui
0a4385f29b 微调 2024-12-21 12:41:06 +08:00
caozehui
63c6693d04 微调 2024-12-20 20:34:39 +08:00
caozehui
ff7084a332 微调 2024-12-20 20:20:08 +08:00
caozehui
b63e8897f5 微调 2024-12-20 20:14:52 +08:00
caozehui
dc3976f525 微调 2024-12-20 19:14:07 +08:00
caozehui
9b8765f001 引入store存放检测设备的相关信息 2024-12-20 18:19:18 +08:00
bbe23e1b14 预见测代码 2024-12-20 16:32:03 +08:00
sjl
5f0b36b3bb Merge branch 'master' of http://192.168.1.22:3000/frontend/pqs-9100_client 2024-12-20 10:43:58 +08:00
sjl
f0b75eae2f frontend/src/views/home/components/test.vue
frontend/src/views/home/components/timeTest.vue
2024-12-20 10:43:43 +08:00
caozehui
45e62b2750 微调 2024-12-20 10:43:17 +08:00
sjl
d11e4822ed 系数校准 2024-12-20 10:21:36 +08:00
caozehui
93b67fe845 修改正式检测,使其能按照通道进行页面展示 2024-12-20 10:19:58 +08:00
caozehui
ebc2ac1a41 微调 2024-12-18 20:26:18 +08:00
caozehui
4fd2f10ec6 正式检测页面修改 2024-12-18 18:53:55 +08:00
caozehui
2715871017 正式检测页面修改 2024-12-18 15:56:59 +08:00
sjl
4cfca89895 样式调整 2024-12-18 15:49:29 +08:00
53ead0e62f 下拉框添加模糊匹配 2024-12-18 14:55:14 +08:00
caozehui
b00967159a Merge remote-tracking branch 'origin/master' 2024-12-17 14:08:35 +08:00
caozehui
1b37684e3c 微调 2024-12-17 14:08:13 +08:00
sjl
48f393be25 主页模式切换 2024-12-17 14:08:01 +08:00
sjl
645fb83bce 微调 2024-12-17 13:57:45 +08:00
caozehui
fe8bc407d3 饼图数据默认,饼图数据计算方式调整 2024-12-17 13:57:18 +08:00
sjl
d20cab57be 微调 2024-12-17 13:38:59 +08:00
sjl
68df3d5e23 # frontend/src/views/home/components/table.vue
#	frontend/src/views/home/tabs/dashboard.vue
2024-12-17 11:36:02 +08:00
sjl
8984bc577e 微调 2024-12-17 11:34:54 +08:00
caozehui
07d02307e2 默认选中第一条检测计划 2024-12-17 11:12:21 +08:00
sjl
a027dc75c3 左侧树点击刷新饼图和表格 2024-12-16 16:33:18 +08:00
sjl
5da07d8631 微调 2024-12-16 15:25:30 +08:00
sjl
d061fc9b32 检测计划列表 2024-12-16 14:09:21 +08:00
caozehui
ae47d429ba 微调 2024-12-16 11:34:12 +08:00
caozehui
396d6a7336 微调 2024-12-16 10:54:40 +08:00
sjl
fdf826d5f8 Merge branch 'master' of http://192.168.1.22:3000/frontend/pqs-9100_client 2024-12-13 16:35:55 +08:00
sjl
0db5fa650f 微调 2024-12-13 16:35:27 +08:00
GYYM
53b4616a87 微调 2024-12-13 08:56:42 +08:00
GYYM
b923b7c35d 饼图样式调整 2024-12-12 13:23:09 +08:00
sjl
8bd5351d29 检测计划表格误差体系,检测源跳转 2024-12-12 11:38:42 +08:00
GYYM
726f7841e8 日志显示内容微调 2024-12-11 19:12:04 +08:00
sjl
47883ce426 微调 2024-12-11 20:24:00 +08:00
GYYM
2459fc1848 正式检测日志修改 2024-12-11 18:48:54 +08:00
sjl
cbc11f636a Merge branch 'master' of http://192.168.1.22:3000/frontend/pqs-9100_client 2024-12-11 19:39:16 +08:00
sjl
5dbd6eb8be 检测计划 2024-12-11 19:39:09 +08:00
GYYM
167716e61b 首页、守时检测页样式调整 2024-12-11 17:46:59 +08:00
GYYM
6d7f045bce 归档页调整 2024-12-09 16:17:04 +08:00
GYYM
a73417ea02 修改未检状态的描述 2024-12-06 15:06:38 +08:00
GYYM
9c3850db98 文字修改 2024-12-06 09:21:55 +08:00
393ad5fa0b 单元格样式调整 2024-12-06 09:18:13 +08:00
sjl
9e8fe2c91f Merge branch 'master' of http://192.168.1.22:3000/frontend/pqs-9100_client 2024-12-06 09:11:55 +08:00
sjl
b57a7edf28 微调弹出框 2024-12-06 09:11:44 +08:00
GYYM
85cc5ebb27 修改不合格项表头的提示方式 2024-12-06 09:10:39 +08:00
GGJ
0cd32fbb5f 修改表格样式 2024-12-06 09:07:16 +08:00
GYYM
2833e65f57 修改正式检测首列的显示样式 2024-12-05 22:15:12 +08:00
GYYM
5a29403636 Merge branch 'master' of http://192.168.1.22:3000/frontend/pqs-9100_client 2024-12-05 21:34:10 +08:00
GYYM
9c0b9a7c93 样式调整 2024-12-05 21:33:52 +08:00
sjl
69a4cbbbc2 微调 2024-12-05 20:29:28 +08:00
sjl
e2b2382cc4 误差体系 2024-12-05 20:11:26 +08:00
sjl
f8a4d05f57 误差体系 2024-12-05 20:06:59 +08:00
caozehui
d996c43f9f Merge remote-tracking branch 'origin/master' 2024-12-05 19:31:56 +08:00
caozehui
c195a58eb4 微调 2024-12-05 19:31:43 +08:00
GGJ
b1c9375873 修改样式 2024-12-05 18:14:43 +08:00
GYYM
6010cbf20a 微调 2024-12-05 17:30:25 +08:00
sjl
11c32ed360 3列弹出框 2024-12-05 16:23:20 +08:00
GYYM
0494822ff4 Merge branch 'master' of http://192.168.1.22:3000/frontend/pqs-9100_client 2024-12-05 15:26:06 +08:00
GYYM
2611f43d1f 微调 2024-12-05 15:25:49 +08:00
GGJ
ea4edfadd0 修改样式 2024-12-05 15:22:46 +08:00
caozehui
8e2a22cf61 微调 2024-12-05 14:37:50 +08:00
sjl
3a1cfe0f31 微调 2024-12-05 13:59:15 +08:00
sjl
5bdc44b301 微调 2024-12-05 13:51:47 +08:00
GYYM
92a1736667 守时微调 2024-12-05 13:46:53 +08:00
caozehui
57f9238033 Merge remote-tracking branch 'origin/master' 2024-12-05 13:43:19 +08:00
caozehui
1b171d4b8d 微调 2024-12-05 13:43:05 +08:00
GYYM
c5acb84d97 Merge branch 'master' of http://192.168.1.22:3000/frontend/pqs-9100_client 2024-12-05 11:21:28 +08:00
GYYM
63a1e9ec56 微调 2024-12-05 11:21:10 +08:00
sjl
f06a8d6b15 Merge branch 'master' of http://192.168.1.22:3000/frontend/pqs-9100_client 2024-12-05 11:07:57 +08:00
GGJ
92df927453 修改样式问题 2024-12-05 11:07:54 +08:00
sjl
2878dce69d 模式切换 2024-12-05 11:07:45 +08:00
caozehui
7d5d128b54 微调 2024-12-05 09:55:35 +08:00
GYYM
6e9e3db358 Merge branch 'master' of http://192.168.1.22:3000/frontend/pqs-9100_client 2024-12-04 21:37:25 +08:00
GYYM
a415ffa12a 样式调整 2024-12-04 21:36:12 +08:00
sjl
9e8cdaead6 Merge branch 'master' of http://192.168.1.22:3000/frontend/pqs-9100_client 2024-12-04 20:00:15 +08:00
sjl
e5d4aae846 微调 2024-12-04 20:00:04 +08:00
caozehui
d6af35828d 样式调整 2024-12-04 19:54:56 +08:00
GYYM
aa86c5e662 微调 2024-12-04 10:20:55 +08:00
GYYM
f99aa94b8f 数据内容微调 2024-12-04 09:44:26 +08:00
sjl
f5c226ba28 微调通用配置 2024-12-04 09:08:48 +08:00
sjl
741020fe79 微调 2024-12-04 08:49:42 +08:00
GYYM
33004e081d 样式调整 2024-12-03 17:13:47 +08:00
94 changed files with 10390 additions and 6709 deletions

View File

@@ -2,17 +2,23 @@
"cSpell.words": [
"Chns",
"Combox",
"Datasource",
"daterange",
"devicedata",
"errordata",
"errordetail",
"Interharmonic",
"IRMS",
"logdata",
"MSQI",
"Pids",
"plandata",
"PQDIF",
"resourcedata",
"resourcename",
"rmark",
"showtest"
"showtest",
"UNBAN",
"VRMS"
]
}

View File

@@ -25,10 +25,10 @@ module.exports = (appInfo) => {
*/
config.windowsOption = {
title: '自动检测平台',
width: 1280,
height: 850,
minWidth: 1280,
minHeight: 850,
width: 1600,
height: 950,
minWidth: 1600,
minHeight: 950,
webPreferences: {
//webSecurity: false,
contextIsolation: false, // false -> 可在渲染进程中使用electron的apitrue->需要bridge.js(contextBridge)

View File

@@ -0,0 +1,117 @@
export namespace CheckData {
export interface DataCheck {
scriptName: string,
errorSysName: string,
dataRule: string,
deviceName: string,
monitorIdx: string,
}
/**
* 用于定义 查看(设备)通道检测结果 类型
*/
export interface CheckResult {
chnNum: string,
standardValue: number,
A?: number,
A_errValue?: number,
B?: number,
B_errValue?: number,
C?: number,
C_errValue?: number,
T?: number,
T_errValue?: number,
maxErrVaule: number,
result: string,
}
/**
* 用于定义 具体通道的原始数据类型
*/
export interface RawDataItem {
updateTime: string,
A?: number,
B?: number,
C?: number
T?: number
}
export interface Device {
deviceId: string; //装置序号Id
deviceName: string; //设备名称
chnNum: number; //设备通道数
}
// 用来描述检测脚本类型
export interface ScriptItem{
scriptName: string,
scriptType?: string,
children?: ScriptItem1[]
}
// 用来描述 通道检测结果
export enum ChnCheckResultEnum {
UNKNOWN = -1,
LOADING = 0,
SUCCESS = 1,
FAIL = 2,
UNCONNECTED = 3,
ERRORDATA = 4
}
//用来描述 某个脚本测试项对所有通道的检测结果
export interface ScriptChnItem {
scriptType: string
scriptName?: string //可以不要该属性,有点多余
// 设备
devices: Array<{
deviceId: string,
deviceName: string,
chnResult: ChnCheckResultEnum[] //通道检测结果
}>
}
export enum ButtonColorEnum {
INFO = '#909399',
LOADING = '#607eab',
SUCCESS = '#67c23a',
WARNING = '#e6a23c',
DANGER = '#f56c6c',
}
/**
* 用于描述 (设备)通道检测结果展示的按钮类型
*/
export interface ButtonResult {
color: ButtonColorEnum
icon: 'Minus' | 'Loading' | 'Close' | 'CircleCheckFilled' | 'Link' | 'WarnTriangleFilled'
}
/**
* 用于描述 脚本检测结果展示的按钮类型
*/
export interface ScriptChnViewItem {
scriptType: string,
scriptName?: string //脚本项名称,可以不要该属性,有点多余
// 设备
devices: Array<{
deviceId: string,
deviceName: string,
chnResult: ButtonResult[],
}>
}
/**
* 定义检测日志类型
*/
export interface LogItem {
type: 'info' | 'warning' | 'error'
log: string
}
}

View File

@@ -0,0 +1,45 @@
import http from "@/api";
export const getBigTestItem = (planId: string) => {
return http.get(`/adPlan/getBigTestItem?planId=${planId}`, {loading: false});
}
/**
* 获取弹出框表单数据
* @param params 当为scriptType为null时表示查询所有脚本类型否则只查询指定脚本类型。当为chnNum为-1时表示查询所有通道否则只查询指定通道。
*/
export const getFormData = (params: {
planId: string,
deviceId: string,
chnNum: string,
scriptType: string | null
}) => {
return http.post("/result/formContent/", params, {loading: false});
}
/**
* 获取树形结构数据
* @param params
*/
export const getTreeData = (params: {
scriptId: string,
deviceId: string,
devNum: string,
scriptType: string | null,
code: string
}) => {
return http.post("/result/treeData/", params, {loading: false});
}
/**
* 获取检查数据
* @param params
*/
export const getTableData = (params: {
scriptId: string,
deviceId: string,
chnNum: string,
scriptType: string | null
}) => {
return http.post("/result/tableData/", params, {loading: false});
}

View File

@@ -48,64 +48,64 @@ const data = [
{
id: '1', //装置序号ID
name: '240001', //设备名称
dev_Type: 'PQS882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '未检', //检测结果
dev_Type: 'PQS-882B4',//设备类型
dev_Chns: 4, //设备通道数
check_Result: '未检', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'未检',//检测状态
check_State:'未检',//检测状态
reCheck_Num: 0, //复检次数
},
{
id: '2', //装置序号ID
name: '240002', //设备名称
dev_Type: 'PQS882B4',//设备类型
dev_Type: 'PQS-882B4',//设备类型
dev_Chns: 4, //设备通道数
check_Result: '未检', //检测结果
check_Result: '未检', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'未检',//检测状态
check_State:'未检',//检测状态
reCheck_Num: 0, //复检次数
},
{
id: '3', //装置序号ID
name: '240003', //设备名称
dev_Type: 'PQS882B4',//设备类型
dev_Type: 'PQS-882B4',//设备类型
dev_Chns: 4, //设备通道数
check_Result: '未检', //检测结果
check_Result: '未检', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'未检',//检测状态
check_State:'未检',//检测状态
reCheck_Num: 0, //复检次数
},
{
id: '4', //装置序号ID
name: '240004', //设备名称
dev_Type: 'PQS882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '未检', //检测结果
dev_Type: 'PQS-882B4',//设备类型
dev_Chns: 4, //设备通道数
check_Result: '未检', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'未检',//检测状态
check_State:'未检',//检测状态
reCheck_Num: 0, //复检次数
},
{
id: '5', //装置序号ID
name: '240005', //设备名称
dev_Type: 'PQS882A',//设备类型
dev_Type: 'PQS-882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '有不合格项', //检测结果
check_Result: '不符合', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'检测完成',//检测状态
reCheck_Num: 0, //复检次数
reCheck_Num: 1, //复检次数
},
{
id: '6', //装置序号ID
name: '240006', //设备名称
dev_Type: 'PQS882B4',//设备类型
dev_Type: 'PQS-882B4',//设备类型
dev_Chns: 4, //设备通道数
check_Result: '有不合格项', //检测结果
check_Result: '不符合', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'检测完成',//检测状态
@@ -114,9 +114,9 @@ const data = [
{
id: '7', //装置序号ID
name: '240007', //设备名称
dev_Type: 'PQS882A',//设备类型
dev_Type: 'PQS-882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '全部合格', //检测结果
check_Result: '符合', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'检测完成',//检测状态
@@ -125,20 +125,20 @@ const data = [
{
id: '8', //装置序号ID
name: '240008', //设备名称
dev_Type: 'PQS882B4',//设备类型
dev_Type: 'PQS-882B4',//设备类型
dev_Chns: 4, //设备通道数
check_Result: '全部合格', //检测结果
check_Result: '符合', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'检测完成',//检测状态
reCheck_Num: 0, //复检次数
reCheck_Num: 1, //复检次数
},
{
id: '9', //装置序号ID
name: '240009', //设备名称
dev_Type: 'PQS882B4',//设备类型
dev_Type: 'PQS-882B4',//设备类型
dev_Chns: 4, //设备通道数
check_Result: '有不合格项', //检测结果
check_Result: '不符合', //检测结果
report_State: '已生成', //报告状态
document_State: '未归档', //归档状态
check_State:'检测完成',//检测状态
@@ -147,9 +147,9 @@ const data = [
{
id: '10', //装置序号ID
name: '240010', //设备名称
dev_Type: 'PQS882A',//设备类型
dev_Type: 'PQS-882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '全部合格', //检测结果
check_Result: '符合', //检测结果
report_State: '已生成', //报告状态
document_State: '未归档', //归档状态
check_State:'检测完成',//检测状态
@@ -158,9 +158,9 @@ const data = [
{
id: '11', //装置序号ID
name: '240011', //设备名称
dev_Type: 'PQS882A',//设备类型
dev_Type: 'PQS-882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '全部合格', //检测结果
check_Result: '符合', //检测结果
report_State: '已生成', //报告状态
document_State: '已归档', //归档状态
check_State:'检测完成',//检测状态
@@ -169,9 +169,9 @@ const data = [
{
id: '12', //装置序号ID
name: '240012', //设备名称
dev_Type: 'PQS882B4',//设备类型
dev_Type: 'PQS-882B4',//设备类型
dev_Chns: 4, //设备通道数
check_Result: '全部合格', //检测结果
check_Result: '符合', //检测结果
report_State: '已生成', //报告状态
document_State: '已归档', //归档状态
check_State:'检测完成',//检测状态
@@ -180,89 +180,89 @@ const data = [
{
id: '13', //装置序号ID
name: '240013', //设备名称
dev_Type: 'PQS882A',//设备类型
dev_Type: 'PQS-882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '未检', //检测结果
check_Result: '未检', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'未检',//检测状态
check_State:'未检',//检测状态
reCheck_Num: 0, //复检次数
},
{
id: '14', //装置序号ID
name: '240014', //设备名称
dev_Type: 'PQS882A',//设备类型
dev_Type: 'PQS-882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '未检', //检测结果
check_Result: '未检', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'未检',//检测状态
check_State:'未检',//检测状态
reCheck_Num: 0, //复检次数
},
{
id: '15', //装置序号ID
name: '240013', //设备名称
dev_Type: 'PQS882A',//设备类型
name: '240015', //设备名称
dev_Type: 'PQS-882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '未检', //检测结果
check_Result: '未检', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'未检',//检测状态
check_State:'未检',//检测状态
reCheck_Num: 0, //复检次数
},
{
id: '16', //装置序号ID
name: '240014', //设备名称
dev_Type: 'PQS882A',//设备类型
name: '240016', //设备名称
dev_Type: 'PQS-882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '未检', //检测结果
check_Result: '未检', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'未检',//检测状态
check_State:'未检',//检测状态
reCheck_Num: 0, //复检次数
},
{
id: '17', //装置序号ID
name: '240017', //设备名称
dev_Type: 'PQS882A',//设备类型
dev_Type: 'PQS-882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '未检', //检测结果
check_Result: '未检', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'未检',//检测状态
check_State:'未检',//检测状态
reCheck_Num: 0, //复检次数
},
{
id: '18', //装置序号ID
name: '240018', //设备名称
dev_Type: 'PQS882A',//设备类型
dev_Type: 'PQS-882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '未检', //检测结果
check_Result: '未检', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'未检',//检测状态
check_State:'未检',//检测状态
reCheck_Num: 0, //复检次数
},
{
id: '19', //装置序号ID
name: '240019', //设备名称
dev_Type: 'PQS882A',//设备类型
dev_Type: 'PQS-882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '未检', //检测结果
check_Result: '未检', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'未检',//检测状态
check_State:'未检',//检测状态
reCheck_Num: 0, //复检次数
},
{
id: '20', //装置序号ID
name: '240020', //设备名称
dev_Type: 'PQS882A',//设备类型
dev_Type: 'PQS-882A',//设备类型
dev_Chns: 1, //设备通道数
check_Result: '未检', //检测结果
check_Result: '未检', //检测结果
report_State: '未生成', //报告状态
document_State: '未归档', //归档状态
check_State:'未检',//检测状态
check_State:'未检',//检测状态
reCheck_Num: 0, //复检次数
},
]

View File

@@ -30,177 +30,202 @@ const errordata = ref<ErrorSystem.ErrorSystemList[]>([
},
])
const errordetail = ref<ErrorSystem.Error_detail[]>([
const errorADetail = ref<ErrorSystem.Error_detail[]>([
{
measured: '电压偏差',
col1: '电压偏差',
col2: '',
deviceLevel: 'A',
measurementType:'电压',
condition: '10%~150%标称电压',
maxErrorValue: '±0.1%Un'
},
{
measured: '频率偏差',
col1:'频率偏差',
col2: '',
deviceLevel: 'A',
measurementType:'频率',
condition: '42.5~57.5 Hz',
maxErrorValue: '±0.01Hz'
},
{
measured: '三相不平衡度',
col1:'三相不平衡度',
col2: '',
deviceLevel: 'A',
measurementType:'电压',
condition: '0.5%~5%',
maxErrorValue: '±0.15%'
},
{
measured: '三相不平衡度',
col1:'三相不平衡度',
col2: '',
deviceLevel: 'A',
measurementType:'电压',
condition: '5%(不包含)~ 40%',
maxErrorValue: '±0.3%'
},
{
measured: '三相不平衡度',
col1:'三相不平衡度',
col2: '',
deviceLevel: 'A',
measurementType:'电流',
condition: '',
maxErrorValue: '±1%'
},
{
measured: '电压波动幅值',
col1:'电压波动',
col2: '电压幅值',
deviceLevel: 'A',
measurementType:'电压',
condition: '',
maxErrorValue: '±0.2%Un'
},
{
measured: '电压波动持续时间',
col1:'电压波动',
col2: '持续时间',
deviceLevel: 'A',
measurementType:'时间',
condition: '',
maxErrorValue: '±1周波'
},
{
measured: '闪变',
col1:'闪变',
col2: '',
deviceLevel: 'A',
measurementType:'短时间闪变',
condition: 'Pst0.2~10',
maxErrorValue: '±5%'
},
{
measured: '谐波和间谐波',
col1:'谐波和间谐波',
col2: '',
deviceLevel: 'A',
measurementType:'电压',
condition: 'Uh≥1%Un',
maxErrorValue: '±5%Uh'
},
{
measured: '谐波和间谐波',
col1:'谐波和间谐波',
col2: '',
deviceLevel: 'A',
measurementType:'电压',
condition: 'Uh1%Un',
maxErrorValue: '±0.05%Un'
},
{
measured: '谐波和间谐波',
col1:'谐波和间谐波',
col2: '',
deviceLevel: 'A',
measurementType:'电流',
condition: 'In≥3%In',
maxErrorValue: '±5%Ih'
},
{
measured: '谐波和间谐波',
col1:'谐波和间谐波',
col2: '',
deviceLevel: 'A',
measurementType:'电流',
condition: 'In3%In',
maxErrorValue: '±0.15%In'
},
{
measured: '谐波和间谐波',
col1:'谐波和间谐波',
col2: '',
deviceLevel: 'A',
measurementType:'相角',
condition: '',
maxErrorValue: 'h≤5,±1°*h'
},
{
measured: '谐波和间谐波',
col1:'谐波和间谐波',
col2: '',
deviceLevel: 'A',
measurementType:'相角',
condition: '',
maxErrorValue: 'h>5,±5°'
},
{
measured: '谐波和间谐波',
col1:'谐波和间谐波',
col2: '',
deviceLevel: 'A',
measurementType:'功率',
condition: 'Ph≥150W',
maxErrorValue: '±1%Ph'
},
{
measured: '谐波和间谐波',
col1:'谐波和间谐波',
col2: '',
deviceLevel: 'A',
measurementType:'功率',
condition: 'Ph150W',
maxErrorValue: '±1.5W'
},
{
measured: '高频次谐波',
col1:'高频次谐波',
col2: '',
deviceLevel: 'A',
measurementType:'电压',
condition: 'Uh≥1%Un',
maxErrorValue: '±5%Uh'
},
{
measured: '高频次谐波',
col1:'高频次谐波',
col2: '',
deviceLevel: 'A',
measurementType:'电压',
condition: 'Uh1%Un',
maxErrorValue: '±0.05%Un'
},
{
measured: '高频次谐波',
col1:'高频次谐波',
col2: '',
deviceLevel: 'A',
measurementType:'电流',
condition: 'In≥3%In',
maxErrorValue: '±5%Ih'
},
{
measured: '高频次谐波',
col1:'高频次谐波',
col2: '',
deviceLevel: 'A',
measurementType:'电流',
condition: 'In3%In',
maxErrorValue: '±0.15%In'
},
{
measured: '功率',
col1:'功率',
col2: '',
deviceLevel: 'A',
measurementType:'功率',
condition: '',
maxErrorValue: '±0.5%'
},
{
measured: '电流',
col1:'电流',
col2: '',
deviceLevel: 'A',
measurementType:'电流',
condition: 'I≥0.05In',
maxErrorValue: '±0.5%'
},
{
measured: '电流',
col1:'电流',
col2: '',
deviceLevel: 'A',
measurementType:'电流',
condition: '0.01In≤I0.05In',
maxErrorValue: '±1%'
},
{
measured: '暂态电压幅值',
col1: '电压暂降、电压暂升和短时中断',
col2: '电压幅值',
deviceLevel: 'A',
measurementType:'电压',
condition: '',
maxErrorValue: '±0.2%Un'
},
{
measured: '暂态持续时间',
col1: '电压暂降、电压暂升和短时中断',
col2: '持续时间',
deviceLevel: 'A',
measurementType:'时间',
condition: '',
@@ -208,5 +233,191 @@ const errordata = ref<ErrorSystem.ErrorSystemList[]>([
},
])
const errorSDetail = ref<ErrorSystem.Error_detail[]>([
{
col1: '电压偏差',
col2: '',
deviceLevel: 'S',
measurementType:'电压',
condition: '20%~120%标称电压',
maxErrorValue: '±0.5%'
},
{
col1:'频率偏差',
col2: '',
deviceLevel: 'S',
measurementType:'频率',
condition: '42.5~57.5 Hz',
maxErrorValue: '±0.05Hz'
},
{
col1:'三相不平衡度',
col2: '',
deviceLevel: 'S',
measurementType:'电压',
condition: '1%~5%',
maxErrorValue: '±0.2%'
},
{
col1:'三相不平衡度',
col2: '',
deviceLevel: 'S',
measurementType:'电压',
condition: '5%(不包含)~ 40%',
maxErrorValue: '±0.6%'
},
{
col1:'三相不平衡度',
col2: '',
deviceLevel: 'S',
measurementType:'电流',
condition: '',
maxErrorValue: '±1%'
},
{
col1:'电压波动',
col2: '电压幅值',
deviceLevel: 'S',
measurementType:'电压',
condition: '',
maxErrorValue: '±1.0%Un'
},
{
col1:'电压波动',
col2: '持续时间',
deviceLevel: 'S',
measurementType:'时间',
condition: '使用半波刷新方均根值',
maxErrorValue: '±1周波'
},
{
col1:'电压波动',
col2: '持续时间',
deviceLevel: 'S',
measurementType:'时间',
condition: '使用全波刷新方均根值',
maxErrorValue: '±2周波'
},
{
col1:'闪变',
col2: '',
deviceLevel: 'S',
measurementType:'短时间闪变',
condition: 'Pst0.4~4',
maxErrorValue: '±10%'
},
{
col1:'谐波和间谐波',
col2: '',
deviceLevel: 'S',
measurementType:'电压',
condition: 'Uh≥3%Un',
maxErrorValue: '±5%Uh'
},
{
col1:'谐波和间谐波',
col2: '',
deviceLevel: 'S',
measurementType:'电压',
condition: 'Uh3%Un',
maxErrorValue: '±0.15%Un'
},
{
col1:'谐波和间谐波',
col2: '',
deviceLevel: 'S',
measurementType:'电流',
condition: 'In≥10%In',
maxErrorValue: '±5%Ih'
},
{
col1:'谐波和间谐波',
col2: '',
deviceLevel: 'S',
measurementType:'电流',
condition: 'In10%In',
maxErrorValue: '±0.5%In'
},
{
col1:'高频次谐波',
col2: '',
deviceLevel: 'S',
measurementType:'电压',
condition: 'Uh≥3%Un',
maxErrorValue: '±5%Uh'
},
{
col1:'高频次谐波',
col2: '',
deviceLevel: 'S',
measurementType:'电压',
condition: 'Uh3%Un',
maxErrorValue: '±0.15%Un'
},
{
col1:'高频次谐波',
col2: '',
deviceLevel: 'S',
measurementType:'电流',
condition: 'In≥10%In',
maxErrorValue: '±5%Ih'
},
{
col1:'高频次谐波',
col2: '',
deviceLevel: 'S',
measurementType:'电流',
condition: 'In10%In',
maxErrorValue: '±0.5%In'
},
{
col1:'功率',
col2: '',
deviceLevel: 'S',
measurementType:'功率',
condition: '',
maxErrorValue: '±0.5%'
},
{
col1:'电流',
col2: '',
deviceLevel: 'S',
measurementType:'电流',
condition: 'I≥0.05In',
maxErrorValue: '±0.5%'
},
{
col1:'电流',
col2: '',
deviceLevel: 'S',
measurementType:'电流',
condition: '0.01In≤I0.05In',
maxErrorValue: '±1%'
},
{
col1: '电压暂降、电压暂升和短时中断',
col2: '电压幅值',
deviceLevel: 'S',
measurementType:'电压',
condition: '',
maxErrorValue: '±1.0%Un'
},
{
col1: '电压暂降、电压暂升和短时中断',
col2: '持续时间',
deviceLevel: 'S',
measurementType:'时间',
condition: '使用半波刷新方均根值',
maxErrorValue: '±1周波'
},
{
col1: '电压暂降、电压暂升和短时中断',
col2: '持续时间',
deviceLevel: 'S',
measurementType:'时间',
condition: '使用全波刷新方均根值',
maxErrorValue: '±2周波'
},
])
export default {errordata,errordetail}
export default {errordata,errorADetail,errorSDetail}

View File

@@ -4,12 +4,14 @@ import type { ReqPage,ResPage } from '@/api/interface'
export namespace Device {
/**
* 电能质量指标字典数据表格分页查询参数
* 被检设备表格分页查询参数
*/
export interface ReqPqDevParams extends ReqPage{
id: string; // 装置序号id 必填
name: string; //设备名称
devType?: string; // 设备名称
createTime?:string; //创建时间
pattern:string;
}
/**
@@ -46,6 +48,10 @@ export namespace Device {
reportPath?: string| null; //报告路径
qRCode?: string| null; //设备关键信息二维码
reCheckNum: number; //复检次数
planId?:string;//检测计划Id
timeCheckResult?:number;//守时检测结果(0:不符合1:符合)
factorFlag?:number;//是否支持系数校准(0:不支持,1:支持)
factorCheckResult?: number;//系数校准结果(0:不符合1:符合)
state: number; //状态
createBy?: string| null; //创建用户
createTime?: string| null; //创建时间

View File

@@ -22,25 +22,27 @@ export namespace ErrorSystem {
// 查看详细误差体系
export interface ErrorSystemDetail {
nextId: number;
sort: number;
id:string;//误差体系子表ID
errorSysId:string;//所属误差体系ID
type: string;//检测脚本类型,树形字典表(没有树形表则需要拆分字段)
startValue?:number;//误差判断起始值(误差范围)
errorType: string;//误差类型,树形字典表(没有树形表则需要拆分字段)
scriptType: string;//脚本类型
startValue?:number | null;//误差判断起始值(误差范围)
startFlag?:number;//是否包含起始值
endValue?:number;//;误差判断结束值(误差范围)
endValue?:number | null;//;误差判断结束值(误差范围)
endFlag?:number;//是否包含结束值
conditionType?:string;//判断条件值类型(包括值类型,绝对值、相对值)
maxErrorValue:number;//误差最大值
errorValueType:string;//误差值类型包括值类型绝对值、相对值1、相对值2
}
// 查看详细误差体系
// export interface Error_detail {
// measured: string;
// deviceLevel: string;
// measurementType:string;
// condition: string;
// maxErrorValue: string;
// }
//查看详细误差体系
export interface Error_detail {
col1: string;
col2: string;
deviceLevel: string;
measurementType:string;
condition: string;
maxErrorValue: string;
}
}

View File

@@ -1,4 +1,4 @@
import type { ReqPage,ResPage } from '@/api/interface'
import type { ReqPage, ResPage } from '@/api/interface'
// 被检设备模块
export namespace Monitor {
@@ -6,30 +6,30 @@ export namespace Monitor {
/**
* 电能质量指标字典数据表格分页查询参数
*/
export interface ReqPqMonParams extends ReqPage{
export interface ReqPqMonParams extends ReqPage {
id: string; // 装置序号id 必填
devType?: string; // 设备名称
createTime?:string; //创建时间
createTime?: string; //创建时间
}
/**
/**
* 被检设备新增、修改、根据id查询返回的对象
*/
export interface ResPqMon {
id: string; //监测点ID
code: string; //默认与谐波系统监测点ID相同
devId: string; //所属设备ID
name: string; //所属母线
num: number; //监测点序号
pt: number; //PT变比
ct: number; //CT变比
ptType:string; //接线方式,字典表
}
export interface ResPqMon {
id: string; //监测点ID
code: string; //默认与谐波系统监测点ID相同
devId: string; //所属设备ID
name: string; //所属母线
num: number; //监测点序号
pt: number; //PT变比
ct: number; //CT变比
ptType: string; //接线方式,字典表
}
/**
/**
* 被检设备表格查询分页返回的对象;
*/
export interface ResPqMonPage extends ResPage<ResPqMon> {
}
}
}

View File

@@ -11,13 +11,14 @@ export namespace TestScript {
id: string; // 装置序号id 必填
name: string;
type: string;
pattern:string;
}
// 检测脚本接口
export interface ResTestScript {
id?: string; //检测脚本ID
name: string; //检测脚本名称
type: string; //检测脚本类型(字典表Code字段脚本还是模板)
type: string; //设定0为脚本1为模板
pattern: string;//检测脚本模式(字典表Code字段数字、模拟、比对)
valueType?: string;//脚本值类型(字典表Code字段相对值脚本、绝对值脚本、无)
standardName: string;//参照标准名称

View File

@@ -15,7 +15,7 @@ export namespace TestSource {
// 检测源接口
export interface ResTestSource {
id: string; //检测源ID
name: string; //检测源名称(检测源类型 + 设备类型 + 数字自动生成)
name?: string; //检测源名称(检测源类型 + 设备类型 + 数字自动生成)
pattern: string;//检测源模式(字典表Code字段数字、模拟、比对)
type: string; //检测源类型(字典表Code字段标准源、高精度设备)
devType: string;//检测源设备类型(字典表Code字段)
@@ -34,9 +34,9 @@ export namespace TestSource {
}
export interface ParameterType{
id:string;
sourceParamType:string;
sourceParamDesc:string;
sourceParamValue:string;
type:string;
desc:string;
value:string|null;
sort:number;
pId:string;
children?:ParameterType[];

View File

@@ -1,227 +1,194 @@
{
"code": "A0000",
"data": [
"code": "A0000",
"data": [
{
"id": "1",
"pid": "0",
"name": "频率准确度检测",
"children": [
{
"id": "0",
"name": "频率准确度检测",
"children": [
{
"pid": 0,
"id": "0-1",
"name": "额定工作条件下的检测",
"children": [
{
"scriptIdx":1,
"isChildNode":true,
"pid": "0-1",
"id": "0-1-1",
"name": "输入:频率 42.5Hz..."
},
{
"scriptIdx":2,
"isChildNode":true,
"pid": "0-1",
"id": "0-1-2",
"name": "输入:频率 50.0Hz..."
},
{
"scriptIdx":3,
"isChildNode":true,
"pid": "0-1",
"id": "0-1-3",
"name": "输入:频率 50.05Hz..."
}
]
},
{
"pid": 0,
"id": "0-2",
"name": "电压对频率测量的影响",
"children": [
{
"scriptIdx":4,
"isChildNode":true,
"pid": "0-2",
"id": "0-2-1",
"name": "输入:频率 50.05Hz Ua =10%Un..."
},
{
"scriptIdx":5,
"isChildNode":true,
"pid": "0-2",
"id": "0-2-1",
"name": "输入:频率 51.05Hz Ua =10%Un..."
},
{
"scriptIdx":6,
"isChildNode":true,
"pid": "0-2",
"id": "0-2-2",
"name": "输入:频率 52.05Hz Ua =10%Un..."
}
]
},
{
"pid": 0,
"id": "0-3",
"name": "谐波对频率测量的影响",
"children": [
{
"scriptIdx":7,
"isChildNode":true,
"pid": "0-3",
"id": "0-3-1",
"name": "输入:频率 50.05Hz Ua =100%Un..."
}
]
}
]
"id": "1-1",
"pid": "1",
"name": "额定工作条件下的检测",
"children": [
{
"id": "1-1-1",
"pid": "1-1",
"name": "输入:频率 42.5Hz..."
},
{
"id": "1-1-2",
"pid": "1-1",
"name": "输入:频率 50.0Hz..."
},
{
"id": "1-1-3",
"pid": "1-1",
"name": "输入:频率 50.05Hz...."
}
]
},
{
"id": "1",
"name": "电压准确度检测",
"children": [
{
"pid": 1,
"id": "1-1",
"name": "额定工作条件下的检测",
"children": [
{
"scriptIdx":8,
"isChildNode":true,
"pid": "1-1",
"id": "1-1-1",
"name": "输入:频率 42.5Hz..."
},
{
"scriptIdx":9,
"isChildNode":true,
"pid": "1-1",
"id": "1-1-2",
"name": "输入:频率 50.0Hz..."
},
{
"scriptIdx":10,
"isChildNode":true,
"pid": "1-1",
"id": "1-1-3",
"name": "输入:频率 50.05Hz..."
}
]
},
{
"pid": 0,
"id": "1-2",
"name": "电压对频率测量的影响",
"children": [
{
"scriptIdx":11,
"isChildNode":true,
"pid": "1-2",
"id": "1-2-1",
"name": "输入:频率 50.05Hz Ua =10%Un..."
},
{
"scriptIdx":12,
"isChildNode":true,
"pid": "1-2",
"id": "1-2-1",
"name": "输入:频率 51.05Hz Ua =10%Un..."
},
{
"scriptIdx":13,
"isChildNode":true,
"pid": "1-2",
"id": "1-2-2",
"name": "输入:频率 52.05Hz Ua =10%Un..."
}
]
},
{
"pid": 0,
"id": "0-3",
"name": "谐波对频率测量的影响",
"children": [
{
"scriptIdx":14,
"isChildNode":true,
"pid": "0-3",
"id": "0-3-1",
"name": "输入:频率 50.05Hz Ua =100%Un..."
}
]
}
]
"id": "1-2",
"pid": "1",
"name": "电压对频率测量的影响",
"children": [
{
"id": "1-2-1",
"pid": "1-2",
"name": "输入:频率 50.05Hz Ua =10%Un..."
},
{
"id": "1-2-1",
"pid": "1-2",
"name": "输入:频率 51.05Hz Ua =10%Un..."
},
{
"id": "1-2-2",
"pid": "1-2",
"name": "输入:频率 52.05Hz Ua =10%Un..."
}
]
},
{
"id": "2",
"name": "谐波准确度检测",
"children": [
{
"pid": 2,
"id": "2-1",
"name": "额定工作条件下的检测",
"children": [
{
"scriptIdx":15,
"pid": "2-1",
"id": "2-1-1",
"name": "输入:频率 42.5Hz..."
},
{
"scriptIdx":16,
"pid": "2-1",
"id": "2-1-2",
"name": "输入:频率 50.0Hz..."
},
{
"scriptIdx":17,
"pid": "2-1",
"id": "2-1-3",
"name": "输入:频率 50.05Hz..."
}
]
},
{
"pid": 2,
"id": "2-2",
"name": "电压对频率测量的影响",
"children": [
{
"scriptIdx":18,
"pid": "2-2",
"id": "2-2-1",
"name": "输入:频率 50.05Hz Ua =10%Un..."
},
{
"scriptIdx":19,
"pid": "2-2",
"id": "2-2-1",
"name": "输入:频率 51.05Hz Ua =10%Un..."
},
{
"scriptIdx":20,
"pid": "2-2",
"id": "2-2-2",
"name": "输入:频率 52.05Hz Ua =10%Un..."
}
]
},
{
"pid": 2,
"id": "2-3",
"name": "谐波对频率测量的影响",
"children": [
{
"scriptIdx":21,
"pid": "2-3",
"id": "2-3-1",
"name": "输入:频率 50.05Hz Ua =100%Un..."
}
]
}
]
"id": "1-3",
"pid": "1",
"name": "谐波对频率测量的影响",
"children": [
{
"id": "1-3-1",
"pid": "1-3",
"name": "输入:频率 50.05Hz Ua =100%Un..."
}
]
}
]
]
},
{
"id": "2",
"pid": "0",
"name": "电压准确度检测",
"children": [
{
"pid": "2",
"id": "2-1",
"name": "额定工作条件下的检测",
"children": [
{
"id": "2-1-1",
"pid": "2-1",
"name": "输入:频率 42.5Hz..."
},
{
"id": "2-1-2",
"pid": "2-1",
"name": "输入:频率 50.0Hz..."
},
{
"id": "2-1-3",
"pid": "2-1",
"name": "输入:频率 50.05Hz..."
}
]
},
{
"pid": "2",
"id": "2-2",
"name": "电压对频率测量的影响",
"children": [
{
"id": "2-2-1",
"pid": "2-2",
"name": "输入:频率 50.05Hz Ua =10%Un..."
},
{
"id": "2-2-1",
"pid": "2-2",
"name": "输入:频率 51.05Hz Ua =10%Un..."
},
{
"id": "2-2-2",
"pid": "2-2",
"name": "输入:频率 52.05Hz Ua =10%Un..."
}
]
},
{
"pid": "2",
"id": "2-3",
"name": "谐波对频率测量的影响",
"children": [
{
"id": "2-3-1",
"pid": "2-3",
"name": "输入:频率 50.05Hz Ua =100%Un..."
}
]
}
]
},
{
"id": "3",
"pid": "0",
"name": "谐波准确度检测",
"children": [
{
"id": "3-1",
"pid": "3",
"name": "额定工作条件下的检测",
"children": [
{
"id": "3-1-1",
"pid": "3-1",
"name": "输入:频率 42.5Hz..."
},
{
"id": "3-1-2",
"pid": "3-1",
"name": "输入:频率 50.0Hz..."
},
{
"id": "3-1-3",
"pid": "3-1",
"name": "输入:频率 50.05Hz..."
}
]
},
{
"id": "3-2",
"pid": "3",
"name": "电压对频率测量的影响",
"children": [
{
"id": "3-2-1",
"pid": "3-2",
"name": "输入:频率 50.05Hz Ua =10%Un..."
},
{
"id": "3-2-1",
"pid": "3-2",
"name": "输入:频率 51.05Hz Ua =10%Un..."
},
{
"id": "3-2-2",
"pid": "3-2",
"name": "输入:频率 52.05Hz Ua =10%Un..."
}
]
},
{
"id": "3-3",
"pid": "3",
"name": "谐波对频率测量的影响",
"children": [
{
"id": "3-3-1",
"pid": "3-3",
"name": "输入:频率 50.05Hz Ua =100%Un..."
}
]
}
]
}
]
}

View File

@@ -1,72 +1,44 @@
import type { ReqPage } from '@/api/interface'
import type { DatetimeFormatProps } from 'vue-i18n';
// 检测计划模块
export namespace Plan {
// 检测计划接口
export interface PlanBO {
id?: string; //检测计划ID
export interface ResPlan {
id: string; //检测计划ID
name: string; //检测计划名称
pattern: string; //模式,字典表(数字、模拟、比对)
father_Plan_Id?: string; //父计划ID
dataSource_Id: string[]; //数据源ID
script_Id: string; //检测脚本ID
error_Sys_Id: string;//误差体系ID
test_State: string; //检测状态
report_State: string; //报告生成状态
result: string;//检测结果
create_Time?: string;//创建时间
fatherPlanId?: string; //父计划ID
dataSourceId: string; //数据源ID
scriptId: string; //检测脚本ID
errorSysId: string;//误差体系ID
timeCheck:number;//守时检测:0否1。是
testState: number; //检测状态:0:未检、1检测中、2检测完成,默认为 0
reportState: number; //报告生成状态:0:未生成、1部分生成、2全部生成,默认为 0
result: number;//检测结果:0:不符合、1:符合、2/,默认为 2
code:number; //自动生成,用于生成数据表后缀
state: number;//;状态0-删除 1-正常
createBy?:string; //创建用户
createTime?:string; //创建时间
updateBy?:string; //更新用户
updateTime?:string; //更新时间
}
// 检测计划 + 分页
export interface ReqPlanParams extends ReqPage,PlanBO {
export interface ReqPlanParams extends ReqPage,ResPlan {
}
// 检测计划 + 检测源
export interface PlanAndSourceBO extends PlanBO {
testSourceName: string;//计划所属检测源
source_Id: string[];
device_Id?: string[];
testSourceList?: string[];//临时测试
dataSource_Ids:string;
}
// // 检测计划列表
// export interface PlanList {
// id: string; //检测计划ID
// name: string; //检测计划名称
// pattern: string; //模式,字典表(数字、模拟、比对)
// father_Plan_Id: string; //父计划ID
// dataSource_Id: string; //数据源ID
// script_Id: string; //检测脚本ID
// error_Sys_Id: string;//误差体系ID
// test_State: string; //检测状态
// report_State: string; //报告生成状态
// result: string;//检测结果
// state: number; //状态
// create_By?: string; //创建用户
// create_Time?: string;//创建时间
// update_By?: string; //更新用户
// update_Time?: string; //更新时间
// }
// // 被检设备参数
// export interface ReqPlanParams extends ReqPage {
// id: string; //检测计划ID
// name: string; //检测计划名称
// pattern: string; //模式,字典表(数字、模拟、比对)
// father_Plan_Id: string; //父计划ID
// dataSource_Id: string; //数据源ID
// script_Id: string; //检测脚本ID
// error_Sys_Id: string;//误差体系ID
// test_State: string; //检测状态
// report_State: string; //报告生成状态
// result: string;//检测结果
// state: number; //状态
// create_By?: string; //创建用户
// create_Time?: string;//创建时间
// update_By?: string; //更新用户
// update_Time?: string; //更新时间
// }
export interface ReqPlan extends ResPlan {
datasourceIds:string;
sourceIds: string;
planId:string;
scriptName: string ;
errorSysName: string;
sourceName: string ;
devIds: string[];
}
}

View File

@@ -1,27 +1,79 @@
import { ResPage } from '@/api/interface'
import { Plan } from './interface'
import { ADMIN as rePrefix } from '@/api/config/serviceName'
import type { ResPage } from '@/api/interface'
import type { Plan } from './interface'
import http from '@/api'
import type { TestSource } from '../device/interface/testSource'
import type { TestScript } from '../device/interface/testScript'
import type { ErrorSystem } from '../device/interface/error'
import type { Device } from '../device/interface/device'
/**
* @name 检测计划管理模块
*/
// 获取检测计划列表
export const getPlanList = (params: Plan.ReqPlanParams) => {
return http.post<ResPage<Plan.PlanBO>>(`/plan/list`, params)
return http.post(`/adPlan/list`, params)
}
// 新增检测计划
export const addPlan = (params: Plan.PlanBO) => {
return http.post(`/role/add`, params)
export const addPlan = (params:any) => {
return http.post(`/adPlan/add`, params)
}
// 编辑检测计划
export const editPlan = (params: Plan.PlanBO) => {
return http.post(`/role/edit`, params)
export const updatePlan = (params: any) => {
return http.post(`/adPlan/update`, params)
}
// 删除检测计划
export const deletePlan = (params: { id: string[] }) => {
return http.post(`/role/del`, params)
return http.post(`/adPlan/delete`, params)
}
// 获取指定模式下所有检测源
export const getTestSourceList = (params: Plan.ReqPlan) => {
return http.get(`/pqSource/getAll?patternId=${params.pattern}`)
}
// 获取指定模式下所有检测脚本
export const getPqScriptList = (params: Plan.ReqPlan) => {
return http.get(`/pqScript/getAll?patternId=${params.pattern}`)
}
//获取所有误差体系
export const getPqErrSysList = () => {
return http.get<ErrorSystem.ErrorSystemList>(`/pqErrSys/getAll`)
}
//获取指定模式下所有未绑定的设备
export const getUnboundPqDevList = (params: Plan.ReqPlan) => {
return http.get(`/pqDev/listUnbound?pattern=${params.pattern}`)
}
//根据检测计划id查询出所有已绑定的设备
export const getBoundPqDevList = (params: any) => {
return http.post(`/pqDev/listByPlanId`,params)
}
//检测计划绑定设备
// export const BindPqDevList = (params: any) => {
// return http.post(`/pqDev/bindDev`,params)
// }
// 按照模式查询检测计划(用于首页展示)
export const getPlanListByPattern = (params:Plan.ReqPlan) => {
return http.get(`/adPlan/listByPattern?pattern=${params.pattern}`)
}
// 导出检测计划
export const exportPlan=(params: Device.ReqPqDevParams)=>{
return http.download(`/adPlan/export`, params)
}
// 下载模板
export const downloadTemplate = () => {
return http.download(`/adPlan/downloadTemplate`)
}
// 导入检测计划
export const importPlan=(params: Device.ReqPqDevParams)=>{
return http.upload(`/adPlan/import`, params)
}

View File

@@ -58,11 +58,15 @@ const dictReportState: Dict[] = [
const dictResult: Dict[] = [
{
id: "0",
label: '符合',
label: '符合',
},
{
id: "1",
label: '符合',
label: '符合',
},
{
id: "2",
label: '/',
},
]
@@ -170,35 +174,35 @@ const testFatherPlanList: Dict[] = [
const sourceDataList: Dict[] = [
{
id: "1",
label: '标准源-福禄克-6100A',
label: '标准源-FLUKE.6100A电能功率标准源-1',
},
{
id: "2",
label: '标准源-昂立-PF2',
label: '标准源-ANGLI-FP2高性能数字信号源-1',
},
{
id: "3",
label: '标准源-丹迪克-DKLN1',
label: '标准源-DKLN-1电能质量测试分析仪智能检定装置-1',
},
{
id: "4",
label: '标准源-博电源-PQC600A',
label: '标准源-PQC600A高精度电能功率标准源-1',
},
{
id: "5",
label: '高精度设备-PQV520-1',
label: '高精度设备-PQV-520便携式电能质量监测装置-1',
},
{
id: "6",
label: '高精度设备-PQV520-2',
label: '高精度设备-PQV-520便携式电能质量监测装置-2',
},
{
id: "7",
label: '高精度设备-PQV520-3',
label: '高精度设备-PQV-520便携式电能质量监测装置-3',
},
{
id: "8",
label: '高精度设备-PQV520-4',
label: '高精度设备-PQV-520便携式电能质量监测装置-4',
},
]
@@ -206,46 +210,80 @@ const sourceDataList: Dict[] = [
const deviceDataList: Dict[] = [
{
id: "1",
label: '模拟装置1',
label: '240001',
},
{
id: "2",
label: '模拟装置2',
label: '240002',
},
{
id: "3",
label: '模拟装置3',
label: '240003',
},
{
id: "4",
label: '模拟装置4',
label: '240004',
},
{
id: "5",
label: '中电送检装置',
label: '240005',
},
{
id: "6",
label: '易司拓测试装置',
label: '240006',
},
{
id: "7",
label: '山大电力测试装置1',
label: '240007',
},
{
id: "8",
label: '山大电力测试装置2',
label: '240008',
},
]
// const deviceDataList: Dict[] = [
// {
// id: "1",
// label: '模拟装置1',
// },
// {
// id: "2",
// label: '模拟装置2',
// },
// {
// id: "3",
// label: '模拟装置3',
// },
// {
// id: "4",
// label: '模拟装置4',
// },
// {
// id: "5",
// label: '中电送检装置',
// },
// {
// id: "6",
// label: '易司拓测试装置',
// },
// {
// id: "7",
// label: '山大电力测试装置1',
// },
// {
// id: "8",
// label: '山大电力测试装置2',
// },
// ]
const planData = ref<Plan.PlanAndSourceBO[]>([
{
'id': '1',
'name': '检测计划1',
'name': '沧州110kV东光站装置送检',
'pattern':'1',
"source_Id" : ['1'],
"testSourceName":'标准源-福禄克-6100A',
"testSourceName":'标准源-FLUKE.6100A电能功率标准源-1',
'dataSource_Id':['1'],
'dataSource_Ids':'实时数据',
'script_Id':'1',
@@ -256,32 +294,32 @@ const planData = ref<Plan.PlanAndSourceBO[]>([
},
{
'id': '2',
'name': '检测计划2',
'name': '邯郸2台安徽振兴终端送检',
'pattern':'1',
"source_Id" : ['5','6','7','8'],
"testSourceName":'高精度设备-PQV520-1',
"testSourceName":'高精度设备-PQV-520便携式电能质量监测装置-1',
'father_Plan_Id':'1',
'dataSource_Id':['5'],
'dataSource_Ids':'分钟统计数据CP95值',
'dataSource_Id':['1'],
'dataSource_Ids':'实时数据',
'script_Id':'2',
'error_Sys_Id':'2',
'test_State':'2',
'report_State':'2',
'result':'0',
"testSourceList":[
'高精度设备-PQV520-2','高精度设备-PQV520-3','高精度设备-PQV520-4'
'高精度设备-PQV-520便携式电能质量监测装置-2','高精度设备-PQV-520便携式电能质量监测装置-3','高精度设备-PQV-520便携式电能质量监测装置-4'
]
},
{
'id': '3',
'name': '检测子计划3',
'name': '浙江分布式光伏电能质量试点',
'pattern':'1',
"source_Id" : ['3'],
"testSourceName":'标准源-丹迪克-DKLN1',
"testSourceName":'标准源-DKLN-1电能质量测试分析仪智能检定装置-1',
'father_Plan_Id':'1',
'dataSource_Id':['1'],
'dataSource_Ids':'实时数据',
'script_Id':'3',
'script_Id':'4',
'error_Sys_Id':'3',
'test_State':'1',
'report_State':'1',

View File

@@ -2,12 +2,12 @@
"code": "200",
"data": [
{
"name": "未检",
"name": "未检",
"children": [
{
"id": 4,
"pid": 1,
"name": "邯郸220kV团城站等4座站电能质量检测"
"name": "邯郸220kV团城站电能质量检测"
},
{
"id": 5,
@@ -17,7 +17,7 @@
{
"id": 6,
"pid": 1,
"name": "深圳市中电软件有限公司委托送检"
"name": "深圳市中电公司委托送检"
}
],
"id": 1
@@ -28,17 +28,17 @@
{
"id": 7,
"pid": 2,
"name": "沧州220kV留古等4座变电站电能质量检测"
"name": "沧州220kV留古站电能质量检测"
},
{
"id": 8,
"pid": 2,
"name": "沧州供电公司110kV东光站等10台装置送检"
"name": "沧州110kV东光站装置送检"
},
{
"id": 9,
"pid": 2,
"name": "保定分布式光伏电能质量监测试点"
"name": "浙江分布式光伏电能质量试点"
}
],
"id": 2
@@ -54,7 +54,7 @@
{
"id": 11,
"pid": 3,
"name": "北京2024现场检测"
"name": "深圳2台中电终端委托送检"
}
],
"id": 3

View File

@@ -0,0 +1,34 @@
import http from '@/api'
export const startPreTest = (params) => {
return http.post(`/prepare/startPreTest`, params, {loading: false})
}
export const closePreTest = (params) => {
return http.post(`/prepare/closePreTest`, params,{ loading: false })
}
/**
* 开始正式检测
* @param params
*/
export const startTest = (params) => {
return http.post(`/prepare/startTest`, params, {loading: false})
}
/**
* 暂停正式检测
* @param params
*/
export const pauseTest = (params) => {
return http.post(`/test/pauseTest`, params, {loading: false})
}
/**
* 继续正式检测
* @param params
*/
export const resumeTest = (params) => {
return http.post(`/test/resumeTest`, params, {loading: false})
}

View File

@@ -216,7 +216,7 @@ const dictData: Dict[] = [
children: [
{
id: "0",
label: 'FLUKE6100A电能功率标准源',
label: 'FLUKE.6100A电能功率标准源',
code: 0,
},
{
@@ -236,7 +236,7 @@ const dictData: Dict[] = [
},
{
id: "4",
label: 'PQV-520电能质量测装置',
label: 'PQV-520便携式电能质量测装置',
code: 4,
},
],

View File

@@ -116,10 +116,10 @@ export namespace Dict {
storeFlag?:string ;//sts、di的是否存储 1:存储 0:不存 储;
curSts?:number | null;//sts、do的当前值
ctlSts?:number;//do的是否可远程控制 1:是 0:否;
maxNum?:number ;//设置最大值
minNum?: number;//设置最小值
maxNum?:number | null;//设置最大值
minNum?: number| null;//设置最小值
setValue?:string | null;//参数为enum可设置的所有值序列
strlen?:number ;//参数string可设置字符串的长度上 限
strlen?:number | null;//参数string可设置字符串的长度上 限
defaultValue?:string | null; //参数缺省值、告警code值
resourcesId?:string ; //报表数据来源(统计表表名)
limitName?:string | null; //限值字段名称

View File

@@ -48,6 +48,7 @@ import { ElNotification, UploadRequestOptions, UploadRawFile } from "element-plu
export interface ExcelParameterProps {
title: string; // 标题
showCover?: boolean; // 是否显示”数据覆盖“选项
patternId?: string; // 模式ID
fileSize?: number; // 上传文件的大小
fileType?: File.ExcelMimeType[]; // 上传文件的类型
tempApi?: (params: any) => Promise<any>; // 下载模板的Api
@@ -77,14 +78,16 @@ const acceptParams = (params: ExcelParameterProps) => {
// Excel 导入模板下载
const downloadTemp = () => {
if (!parameter.value.tempApi) return;
useDownload(parameter.value.tempApi, `${parameter.value.title}模板`,{},true);
useDownload(parameter.value.tempApi, `${parameter.value.title}模板`,{},false);
};
// 文件上传
const uploadExcel = async (param: UploadRequestOptions) => {
debugger
let excelFormData = new FormData();
excelFormData.append("file", param.file);
if(parameter.value.patternId){
excelFormData.append("patternId",parameter.value.patternId)
}
isCover.value && excelFormData.append("isCover", isCover.value as unknown as Blob);
await parameter.value.importApi!(excelFormData);
parameter.value.getTableList && parameter.value.getTableList();

View File

@@ -313,7 +313,7 @@
border: 1px solid #dcdfe6;
border-radius: 4px;
line-height: 40px;
width: 100%;
width: 110%;
height: 35px;
padding-inline-start: 0px;
padding-left: 10px;

View File

@@ -8,9 +8,8 @@
:search-param='searchParam'
:search-col='searchCol'
/>
<!-- 表格主体 -->
<div class='card table-main'>
<div class='table-main' :class='{ card: showCard }' >
<!-- 表格头部 操作按钮 -->
<div class='table-header'>
<div class='header-button-lf'>
@@ -43,10 +42,11 @@
>
<!-- 默认插槽 -->
<slot />
<template v-for='item in tableColumns' :key='item'>
<!-- selection || radio || index || expand || sort -->
<el-table-column
v-if='item.type && columnTypes.includes(item.type)'
v-if='item.type && columnTypes.includes(item.type) && item.isShow'
v-bind='item'
:align="item.align ?? 'center'"
:reserve-selection="item.type == 'selection'"
@@ -126,6 +126,7 @@ export interface ProTableProps {
requestError?: (params: any) => void; // 表格 api 请求错误监听 ==> 非必传
dataCallback?: (data: any) => any; // 返回数据的回调函数,可以对数据进行处理 ==> 非必传
title?: string; // 表格标题 ==> 非必传
showCard?: boolean; // 下个是否需要卡片
pagination?: boolean; // 是否需要分页组件 ==> 非必传默认为true
initParam?: any; // 初始化请求参数 ==> 非必传(默认为{}
border?: boolean; // 是否带有纵向边框 ==> 非必传默认为true
@@ -141,6 +142,7 @@ const props = withDefaults(defineProps<ProTableProps>(), {
pagination: true,
initParam: {},
border: true,
showCard: true,
toolButton: true,
rowKey: 'id',
searchCol: () => ({ xs: 1, sm: 2, md: 2, lg: 3, xl: 4 }),

View File

@@ -1,5 +1,5 @@
<template>
<div class='icon-box'>
<div class='icon-box' >
<el-input
ref='inputRef'
v-model='valueIcon'
@@ -13,7 +13,7 @@
<el-button :icon='customIcons[iconValue]' />
</template>
</el-input>
<el-dialog v-model='dialogVisible' :title='placeholder' top='50px' width='66%'>
<el-dialog v-model='dialogVisible' :title='placeholder' top='5%' width='30%' >
<el-input v-model='inputValue' placeholder='搜索图标' size='large' :prefix-icon='Icons.Search' />
<el-scrollbar v-if='Object.keys(iconsList).length'>
<div class='icon-list'>

View File

@@ -126,6 +126,15 @@ const handleChange = (unit: string) => {
endDate.value = new Date()
}
timeUnit.value = unit
// 确保开始时间和结束时间不为空
if (!startDate.value) {
startDate.value = new Date()
}
if (!endDate.value) {
endDate.value = new Date()
}
emitDateChange() // 变化时也发出更新事件
updateNextButtonStatus()
}
@@ -172,7 +181,13 @@ const updateDateRange = () => {
// endDate.value.setHours(23, 59, 59, 999); // 设置结束时间为今天的23:59:59.999
// }
}
// 确保开始时间和结束时间不为空
if (!startDate.value) {
startDate.value = new Date()
}
if (!endDate.value) {
endDate.value = new Date()
}
updateNextButtonStatus()
}
@@ -285,7 +300,10 @@ const disableEndDate = (date: Date) => {
// 格式化日期yyyy-mm-dd
function formatDate(date:Date) {
function formatDate(date: Date | null): string {
if (!date) {
return '';
}
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');

View File

@@ -4,6 +4,7 @@
</template>
<script lang="ts" setup>
import * as echarts from "echarts";
import { ref } from "vue";
const chartsRef = ref();
const props = defineProps({
//饼图数据
@@ -40,7 +41,7 @@ const init = () => {
icon: "roundRect", // 图例项的icon,类型包括 circle(圆形),rect(正方形),//roundRect(圆角正方形),triangle(三角形),diamond(菱形),//pin(大头针行),arrow(箭头形),none(无图例项的icon)
orient: "vertical", //图例排列方向
left: "right", //可选属性left,right,top,bottom,可选属性值 left,right,top,bottom,px,百分比,数值,
itemGap: 1, // 设置图例项之间的间隔为20
itemGap: 10, // 设置图例项之间的间隔为20
...props.legendData,
};
chart.value = chartsRef.value && echarts.init(chartsRef.value);
@@ -49,7 +50,21 @@ const init = () => {
text: customData.value.title,
left: customData.value.textAlign,
},
legend: legendData.value,
legend:legendData.value,
// legend: {
// icon: legendData.value.icon, // 图例项的icon,类型包括 circle(圆形),rect(正方形),//roundRect(圆角正方形),triangle(三角形),diamond(菱形),//pin(大头针行),arrow(箭头形),none(无图例项的icon)
// orient: "vertical", //图例排列方向
// left: legendData.value.left, //可选属性left,right,top,bottom,可选属性值 left,right,top,bottom,px,百分比,数值,
// itemGap: 1, // 设置图例项之间的间隔为20
// formatter: function (name) {
// const item = props.chartsData.filter(item=>item.name==name)
// console.log(item)
// if(item)
// return item[0].value;
// },
// },
tooltip: {
show: true,
trigger: "item",
@@ -61,6 +76,12 @@ const init = () => {
type: "pie",
radius: customData.value.isRing ? ["55", "75"] : "80%",
data: props.chartsData,
formatter: function (name: any) {
const item = props.chartsData.filter(item=>item.name==name)
//console.log(item)
if(item)
return item[0].value;
},
center: ["55%", "50%"], // 设置饼图的中心位置
// padAngle: 2,
minAngle: 15, //最小角度
@@ -75,11 +96,14 @@ const init = () => {
label: {
normal: {
show: true,
position: "inside",
position: "outside",
textStyle: {
color: "#fff",
//color: "#fff",
fontSize: 12,
},
formatter: function (data) {
return data.value +'台'
}
},
},
itemStyle: {
@@ -108,7 +132,7 @@ const reSize = (widthValue: number,heightValue: number,silentValue: boolean) =>
}
};
const resizeCharts = () => {
console.log(chart.value,111111);
//console.log(chart.value,111111);
if (chart.value) {
chart.value.resize();

View File

@@ -18,13 +18,13 @@
<!-- </el-button> -->
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="title = '模拟式模块'"
<el-dropdown-item @click="handelOpen('模拟式')"
>模拟式模块</el-dropdown-item
>
<el-dropdown-item @click="title = '数字式模块'"
<el-dropdown-item @click="handelOpen('数字式')"
>数字式模块</el-dropdown-item
>
<el-dropdown-item @click="title = '比对式模块'"
<el-dropdown-item @click="handelOpen('比对式')"
>比对式模块</el-dropdown-item
>
</el-dropdown-menu>
@@ -39,13 +39,16 @@
</template>
<script lang="ts" setup>
import { ref, reactive, computed, onMounted, watch } from "vue";
const title = ref("模拟式模块");
import { useAuthStore } from "@/stores/modules/auth";
import { useModeStore } from '@/stores/modules/mode'; // 引入模式 store
import { useRouter } from "vue-router";
const title = ref("模拟式模块");
const router = useRouter();
const authStore = useAuthStore();
const modeStore = useModeStore();
watch(() => modeStore.currentMode, (newVal) => {
//console.log('当前模式:', newVal);
switch (newVal) {
onMounted(() => {
switch (modeStore.currentMode) {
case '模拟式':
title.value = '模拟式模块';
break;
@@ -59,6 +62,18 @@ watch(() => modeStore.currentMode, (newVal) => {
title.value = '模拟式模块';
}
});
const handelOpen = async (item: string) => {
await authStore.setShowMenu();
modeStore.setCurrentMode(item); // 将模式code存入 store
if (router.currentRoute.value.path === '/home/index') {
// 强制刷新页面
window.location.reload();
} else {
router.push({ path: '/home/index' });
}
};
</script>
<style scoped lang="scss">
@import "./index.scss";

View File

@@ -17,3 +17,5 @@ export const USER_STORE_KEY = "cn-user";
// pinia中dict store的key
export const DICT_STORE_KEY = "cn-dictData";
export const CHECK_STORE_KEY = "cn-check";

View File

@@ -0,0 +1,39 @@
import {defineStore} from "pinia";
import {CHECK_STORE_KEY} from "@/stores/constant";
import type {CheckData} from "@/api/check/interface";
export const useCheckStore = defineStore("check", {
id: CHECK_STORE_KEY,
state: () => ({
devices: Array<CheckData.Device>(),
planId: String(""),
planCode: String(""),
scriptId: String(""),
}),
getters: {},
actions: {
addDevices(device: CheckData.Device[]) {
this.devices.push(...device);
},
clearDevices() {
this.devices = [];
},
setPlanId(planId: string) {
this.planId = planId
},
setPlanCode(planCode: string) {
this.planCode = planCode
},
setScriptId(scriptId: string) {
this.scriptId = scriptId
}
}
});

View File

@@ -1,3 +1,5 @@
/* flex */
.flx-center {
display: flex;
@@ -77,8 +79,8 @@
/* scroll bar */
::-webkit-scrollbar {
width: 6px;
height: 200px;
width: 8px;
height: 8px;
// background-color: var(--el-color-primary);
}
/* 滚动条实际可拖动部分的颜色 */

View File

@@ -143,13 +143,17 @@
}
}
.el-table__body {
// border-left: 1px solid var(--el-table-border-color)
}
// el-table 表格样式
.el-table {
// border: 1px solid var(--el-table-border-color);
// flex: 1;
width: 100%;
height: 100%;
// 修复 safari 浏览器表格错位 https://github.com/HalseySpicy/Geeker-Admin/issues/83
border-left: 1px solid var(--el-table-border-color) // 修复 safari 浏览器表格错位 https://github.com/HalseySpicy/Geeker-Admin/issues/83
table {
width: 100%;
}
@@ -398,7 +402,7 @@
&::-webkit-scrollbar {
width: 8px !important;
height: 200px !important;
height: 8px !important;
// background-color: var(--el-color-primary);
z-index: 3001;
}
@@ -441,7 +445,7 @@
.dialog-small {
.el-dialog__body {
max-height: 260px;
max-height: 340px;
}
}
@@ -457,6 +461,81 @@
}
}
.cn-render-buttons {
cursor: pointer;
display: inline-block;
margin-left: 13px;
line-height: 18px;
padding: 2px;
.icon {
font-size: 12px !important;
// color: var(--ba-bg-color-overlay) !important;
}
}
.el-message-box {
padding: 0px !important;
.el-message-box__header {
background-color: var(--el-color-primary);
.el-message-box__title {
color: #fff;
padding: 10px 10px 0;
}
}
.el-message-box__headerbtn {
top: 5px;
}
.el-message-box__close {
svg {
color: #fff;
}
:hover {
color: #409eff;
}
}
.el-message-box__content {
padding: 10px;
border-bottom: 1px solid #cccccc;
}
.el-message-box__btns {
padding: 10px;
}
}
.form-one {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.el-form-item {
display: flex;
width: 98%;
margin-bottom: 15px !important;
.el-form-item__content {
flex: 1;
.el-select,
.el-cascader,
.el-input__inner,
.el-date-editor {
width: 100%;
}
}
}
}
.form-two {
display: flex;
flex-wrap: wrap;
@@ -479,14 +558,28 @@
}
}
.cn-render-buttons {
cursor: pointer;
display: inline-block;
margin-left: 13px;
line-height: 18px;
padding: 2px;
.icon {
font-size: 12px !important;
// color: var(--ba-bg-color-overlay) !important;
.form-three {
display: flex;
flex-wrap: wrap;
// justify-content: space-between;
.el-form-item {
display: flex;
width: 32.3%;
.el-form-item__content {
flex: 1;
.el-select,
.el-cascader,
.el-input__inner,
.el-date-editor {
width: 100%;
}
}
}
}
.el-table__cell {
border-right: 1px solid #ebeef5 !important;
border-left: 1px solid #ebeef5 !important;
}

View File

@@ -0,0 +1,103 @@
import {ElMessage} from "element-plus";
export default class SocketService {
static instance = null;
static get Instance() {
if (!this.instance) {
this.instance = new SocketService();
}
return this.instance;
}
// 和服务端连接的socket对象
ws = null;
// 存储回调函数
callBackMapping = {};
// 标识是否连接成功
connected = false;
// 记录重试的次数
sendRetryCount = 0;
// 重新连接尝试的次数
connectRetryCount = 0;
// 定义连接服务器的方法
connect(url) {
// 连接服务器
if (!window.WebSocket) {
return console.log('您的浏览器不支持WebSocket');
}
console.log(url)
// let token = $.cookie('123');
// let token = '4E6EF539AAF119D82AC4C2BC84FBA21F';
this.ws = new WebSocket(url);
// 连接成功的事件
this.ws.onopen = () => {
ElMessage.success("webSocket连接服务端成功了");
console.log('连接服务端成功了');
this.connected = true;
// 重置重新连接的次数
this.connectRetryCount = 0;
};
// 1.连接服务端失败
// 2.当连接成功之后, 服务器关闭的情况
this.ws.onclose = () => {
console.log('连接服务端失败');
this.connected = false;
this.connectRetryCount++;
setTimeout(() => {
// this.connect();
}, 500 * this.connectRetryCount);
};
// 得到服务端发送过来的数据
this.ws.onmessage = (event) => {
let message: { [key: string]: any };
try {
message = JSON.parse(event.data);
} catch (e) {
return console.error("消息解析失败", event.data, e);
}
//console.log(message, "从服务端获取到了数据");
/* 通过接受服务端发送的type字段来回调函数 */
if (message?.type && this.callBackMapping[message.type]) {
this.callBackMapping[message.type](message);
} else {
console.log("抛弃====>"+message)
/* 丢弃或继续写你的逻辑 */
}
};
}
// 回调函数的注册
registerCallBack(socketType, callBack) {
this.callBackMapping[socketType] = callBack;
}
// 取消某一个回调函数
unRegisterCallBack(socketType) {
this.callBackMapping[socketType] = null;
}
// 发送数据的方法
send(data) {
// 判断此时此刻有没有连接成功
if (this.connected) {
this.sendRetryCount = 0;
try {
this.ws.send(JSON.stringify(data));
} catch (e) {
this.ws.send(data);
}
} else {
this.sendRetryCount++;
setTimeout(() => {
this.send(data);
}, this.sendRetryCount * 500);
}
}
// 断开方法
closeWs() {
if (this.connected) {
this.ws.close()
}
console.log('WS关闭中..');
}
}

View File

@@ -1,6 +1,6 @@
<template>
<el-dialog :title="dialogTitle" :model-value="dialogVisible" @close="close" v-bind="dialogMiddle">
<el-form :model="formContent" ref='dialogFormRef' :rules='rules' >
<el-form :model="formContent" ref='dialogFormRef' :rules='rules' class="form-two">
<el-form-item label="上级菜单" prop="pid" :label-width="100">
<el-tree-select
v-model="displayPid"
@@ -19,7 +19,7 @@
<el-form-item label="编码" prop="code" :label-width="100">
<el-input v-model="formContent.code" />
</el-form-item>
<el-form-item label="图标" prop="icon" :label-width="100">
<el-form-item v-if="!formContent.type" label="图标" prop="icon" :label-width="100">
<IconSelect
v-model="formContent.icon"
:iconValue="formContent.icon"
@@ -27,10 +27,10 @@
placeholder="选择一个图标"
/>
</el-form-item>
<el-form-item label="路由地址" prop="path" :label-width="100">
<el-form-item v-if="!formContent.type" label="路由地址" prop="path" :label-width="100">
<el-input v-model="formContent.path" />
</el-form-item>
<el-form-item label="组件地址" prop="component" :label-width="100">
<el-form-item v-if="!formContent.type" label="组件地址" prop="component" :label-width="100">
<el-input v-model="formContent.component" />
</el-form-item>
<el-form-item label="排序" prop="sort" :label-width="100">

View File

@@ -146,7 +146,6 @@ const open = async (sign: string, data: Role.RoleBO, AllFunction: Function.ResFu
const allIds = getAllIds(AllFunction);
// 匹配 roleFunctions 中的 id 并设置 checkedKeys
const checkedKeys = allIds.filter(id => roleFunctions.some(roleFunc => roleFunc.id === id));
// 过滤出叶子节点
const leafCheckedKeys = filterLeafNodes(AllFunction, checkedKeys);

View File

@@ -9,9 +9,9 @@
<!-- 表格 header 按钮 -->
<template #tableHeader='scope'>
<el-button v-auth.role="'add'" type='primary' :icon='CirclePlus' @click="openDrawer('新增角色')">新增</el-button>
<el-button v-auth.role="'batchDelete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
<el-button v-auth.role="'delete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
@click='batchDelete(scope.selectedListIds)'>
批量删除
删除
</el-button>
</template>
<!-- 表格操作 -->
@@ -91,6 +91,22 @@ const columns = reactive<ColumnProps<Role.RoleBO>[]>([
search: { el: 'input' },
minWidth: 200,
},
{
prop: 'type',
label: '类型',
minWidth: 200,
render: (scope) => {
const typeMap: { [key: number]: { label: string; type: string } } = {
0: { label: '超级管理员', type: 'primary' },
1: { label: '管理员角色', type: 'success' },
2: { label: '普通角色', type: 'info' },
};
const typeInfo = typeMap[scope.row.type] || { label: '未知', type: 'danger' };
return (
<el-tag type={typeInfo.type}>{typeInfo.label}</el-tag>
);
},
},
{
prop: 'remark',
label: '描述',

View File

@@ -1,6 +1,6 @@
<template>
<!-- 基础信息弹出框 -->
<el-dialog v-model='dialogVisible' :title="dialogTitle" v-bind="dialogSmall" @close="close">
<el-dialog v-model='dialogVisible' :title="dialogTitle" v-bind="dialogSmall" @close="close" >
<div>
<el-form :model="formContent"
ref='dialogFormRef'

View File

@@ -9,9 +9,9 @@
<!-- 表格 header 按钮 -->
<template #tableHeader='scope'>
<el-button v-auth.user="'add'" type='primary' :icon='CirclePlus' @click="openDialog('add')">新增</el-button>
<el-button v-auth.user="'batchDelete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
<el-button v-auth.user="'delete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
@click='batchDelete(scope.selectedListIds)'>
批量删除
删除
</el-button>
</template>
<!-- 表格操作 -->

View File

@@ -12,7 +12,7 @@
<el-button type='primary' :icon='Download' plain @click='downloadFile'>导出用户数据</el-button>
<el-button type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
@click='batchDelete(scope.selectedListIds)'>
批量删除用户
删除用户
</el-button>
</template>
<!-- 表格操作 -->
@@ -32,15 +32,12 @@
</template>
<script setup lang='tsx' name='useProTable'>
import { ref, reactive } from 'vue'
import { User } from '@/api/user/interface'
import { useHandleData } from '@/hooks/useHandleData'
import { useDownload } from '@/hooks/useDownload'
import { useAuthButtons } from '@/hooks/useAuthButtons'
import ProTable from '@/components/ProTable/index.vue'
import ImportExcel from '@/components/ImportExcel/index.vue'
import { ProTableInstance, ColumnProps } from '@/components/ProTable/interface'
import { CirclePlus, Delete, EditPen, Download, Upload, View, Refresh } from '@element-plus/icons-vue'
import userDataList from '@/api/user/userData'
import { useDictStore } from '@/stores/modules/dict'
import SingleColumn from '@/views/demo/proTable/singleColumn.vue'
import Open from '@/views/demo/proTable/Open.vue'
@@ -53,9 +50,6 @@ const dictStore = useDictStore()
import {
getUserList,
deleteUser,
changeUserStatus,
exportUserInfo,
BatchAddUser,
} from '@/api/user/user'
import { ElMessageBox } from 'element-plus'
@@ -87,7 +81,7 @@ const getTableList = (params: any) => {
// 页面按钮权限(按钮权限既可以使用 hooks也可以直接使用 v-auth 指令指令适合直接绑定在按钮上hooks 适合根据按钮权限显示不同的内容)
const { BUTTONS } = useAuthButtons()
// 表格配置项
const columns = reactive<ColumnProps<User.ResUserList>[]>([
const columns = reactive<ColumnProps<any>[]>([
{ type: 'selection', fixed: 'left', width: 70 },
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
{
@@ -173,38 +167,34 @@ const batchDelete = async (id: string[]) => {
proTable.value?.getTableList()
}
// 重置用户密码
const resetPass = async (params: User.ResUserList) => {
const resetPass = async (params: any) => {
// await useHandleData(resetUserPassWord, { id: params.id }, `重置【${params.username}】用户密码`)
// proTable.value?.getTableList()
doubleColumn.value.open('双列弹出框')
}
// 切换用户状态
const changeStatus = async (row: User.ResUserList) => {
await useHandleData(changeUserStatus, {
id: row.id,
status: row.status == 1 ? 0 : 1,
}, `切换【${row.username}】用户状态`)
const changeStatus = async (row: any) => {
// await useHandleData(changeUserStatus, {
// id: row.id,
// status: row.status == 1 ? 0 : 1,
// }, `切换【${row.username}】用户状态`)
proTable.value?.getTableList()
}
// 导出用户列表
const downloadFile = async () => {
ElMessageBox.confirm('确认导出用户数据?', '温馨提示', { type: 'warning' }).then(() =>
useDownload(exportUserInfo, '用户列表', proTable.value?.searchParam),
)
}
// 批量添加用户
const dialogRef = ref<InstanceType<typeof ImportExcel> | null>(null)
const batchAdd = () => {
const params = {
title: '用户',
tempApi: exportUserInfo,
importApi: BatchAddUser,
getTableList: proTable.value?.getTableList,
}
dialogRef.value?.acceptParams(params)
}
// 打开 drawer(新增、查看、编辑)
const openDrawer = (title: string, row: Partial<User.ResUserList> = {}) => {
const openDrawer = (title: string, row: Partial<any> = {}) => {
singleColumn.value.open('单列弹出框')
}
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -1,72 +1,236 @@
<template>
<div class="table-container">
<el-table :data="tableData" :header-cell-style="{ textAlign: 'center' } " :cell-style="{ textAlign: 'center' }" style="width: 100%" >
<el-table-column prop="id" label="序号" width="70" />
<el-table-column prop="updateTime" label="上送时刻" />
<el-table-column prop="deviceName" label="设备名称" />
<el-table-column prop="MonitorIdx" label="监测点序号" />
<div class="table-container table-main">
<el-table :data="tableData"
:header-cell-style="{ textAlign: 'center' } "
:cell-style="{ textAlign: 'center' }"
style="width: 100%"
max-height="400px"
:span-method="objectSpanMethod">
<el-table-column prop="MonitorIdx" label="监测点序号" width="80"/>
<!-- <el-table-column prop="updateTime" label="上送时刻" width="180"/> -->
<el-table-column prop="deviceName" label="描述" width="90"/>
<el-table-column label="电压通道" >
<el-table-column prop="Ua" label="L1">
<el-table-column prop="UaData" label="数据(V)">
<template #default="scope">
<el-icon v-if="scope.row.UaData === '—'&& loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
{{ scope.row.UaData }}
</span>
</template>
</el-table-column>
<el-table-column prop="UaChannel" label="系数">
<template #default="scope">
<el-tag type="danger" v-if="scope.row.UaChannel === '不合格'">
{{ scope.row.UaChannel }}
</el-tag>
<el-icon v-else-if="scope.row.UaChannel === '—'&& loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
{{ scope.row.UaChannel }}
</span>
<!-- <el-tag type="danger" v-if="scope.row.UaChannel === '不合格'">{{ scope.row.UaChannel }}</el-tag> -->
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="Ub" label="L2">
<el-table-column prop="UbData" label="数据(V)">
<template #default="scope">
<el-icon v-if="scope.row.UbData === '—'&& loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
{{ scope.row.UbData }}
</span>
</template>
</el-table-column>
<el-table-column prop="UbChannel" label="系数">
<template #default="scope">
<el-tag type="danger" v-if="scope.row.UbChannel === '不合格'">
{{ scope.row.UbChannel }}
</el-tag>
<el-icon v-else-if="scope.row.UbChannel === '—'&& loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
{{ scope.row.UbChannel }}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="Uc" label="L3">
<el-table-column prop="UcData" label="数据(V)">
<template #default="scope">
<el-icon v-if="scope.row.UcData === '—'&& loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
{{ scope.row.UcData }}
</span>
</template>
</el-table-column>
<el-table-column prop="UcChannel" label="系数">
<template #default="scope">
<el-tag type="danger" v-if="scope.row.UcChannel === '不合格'">
{{ scope.row.UcChannel }}
</el-tag>
<el-icon v-else-if="scope.row.UcChannel === '—'&& loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
{{ scope.row.UcChannel }}
</span>
</template>
</el-table-column>
</el-table-column>
</el-table-column>
<el-table-column label="电流通道" >
<el-table-column prop="Ia" label="L1">
<el-table-column prop="IaData" label="数据(A)">
<template #default="scope">
<el-icon v-if="scope.row.IaData === '—'&& loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
{{ scope.row.IaData }}
</span>
</template>
</el-table-column>
<el-table-column prop="IaChannel" label="系数">
<template #default="scope">
<el-tag type="danger" v-if="scope.row.IaChannel === '不合格'">
{{ scope.row.IaChannel }}
</el-tag>
<el-icon v-else-if="scope.row.IaChannel === '—'&& loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
{{ scope.row.IaChannel }}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="Ib" label="L2">
<el-table-column prop="IbData" label="数据(A)">
<template #default="scope">
<el-icon v-if="scope.row.IbData === '—'&& loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
{{ scope.row.IbData }}
</span>
</template>
</el-table-column>
<el-table-column prop="IbChannel" label="系数">
<template #default="scope">
<el-tag type="danger" v-if="scope.row.IbChannel === '不合格'">
{{ scope.row.IbChannel }}
</el-tag>
<el-icon v-else-if="scope.row.IbChannel === '—'&& loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
{{ scope.row.IbChannel }}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="Ic" label="L3">
<el-table-column prop="IcData" label="数据(A)">
<template #default="scope">
<el-icon v-if="scope.row.IcData === '—'&& loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
{{ scope.row.IcData }}
</span>
</template>
</el-table-column>
<el-table-column prop="IcChannel" label="系数">
<template #default="scope">
<el-tag type="danger" v-if="scope.row.IcChannel === '不合格'">
{{ scope.row.IcChannel }}
</el-tag>
<el-icon v-else-if="scope.row.IcChannel === '—'&& loading" class="loading-box">
<el-icon-loading />
</el-icon>
<span v-else>
{{ scope.row.IcChannel }}
</span>
</template>
</el-table-column>
</el-table-column>
</el-table-column>
<el-table-column label="校准结果">
<!-- <el-table-column label="校准结果">
<template #default="scope">
<el-tag :type="scope.row.Result === '合格' ? 'success' : 'danger'">{{ scope.row.Result }}</el-tag>
</template>
</el-table-column>
<el-tag type="danger" v-if="scope.row.Result === '合格'">{{ scope.row.Result }}</el-tag>
<span v-if="scope.row.Result != '不合格'">{{ scope.row.Result }}</span>
</template>
</el-table-column> -->
</el-table>
</div>
</template>
<script lang="ts" setup name="ErrorSystemDialog">
import{ElMessage, FormInstance,FormItemRule}from'element-plus'
import { defineProps, defineEmits, reactive,watch,ref, Ref } from 'vue';
import { dialogBig,dialogMiddle} from '@/utils/elementBind'
import { defineProps } from 'vue';
import { ElIcon, ElLoading, ElTag } from 'element-plus';
//import IndicatorTypeDialog from "@/views/machine/errorSystem/components/IndicatorTypeDialog.vue"; // 导入子组件
import {CirclePlus, Delete, EditPen,FolderOpened,CopyDocument} from '@element-plus/icons-vue'
import { useDictStore } from '@/stores/modules/dict'
const dictStore = useDictStore()
const props = defineProps<{
tableData: {
tableData: Array<{
id: string;
updateTime: string;
deviceName:string;
MonitorIdx:number;
Ua:number;
Ub:number;
Uc:number;
Ia:number;
Ib:number;
Ic:number;
Result: string;
};
deviceName?: string;
MonitorIdx: number;
UaData?: number | string;
UaChannel?: number | string;
UbData?: number | string;
UbChannel?: number | string;
UcData?: number | string;
UcChannel?: number | string;
IaData?: number | string;
IaChannel?: number | string;
IbData?: number | string;
IbChannel?: number | string;
IcData?: number | string;
IcChannel?: number | string;
Result?: string | string;
updateTime?: string;
}>
loading: boolean; // 定义 loading 属性
}>();
function objectSpanMethod({ row, column, rowIndex, columnIndex }: { row: any, column: any, rowIndex: number, columnIndex: number }) {
if (columnIndex === 0) {
if (rowIndex % 4 === 0) {
return {
rowspan: 4,
colspan: 1,
};
} else {
return {
rowspan: 0,
colspan: 0,
};
}
}
if (columnIndex === 1) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1,
};
} else {
return {
rowspan: 0,
colspan: 0,
};
}
}
}
// const tableData = ref([
// {
@@ -123,6 +287,9 @@
// },
// ])
// 监听 tableData 的变化
</script>
<style scoped>
@@ -157,4 +324,18 @@
overflow-y: auto; /* 允许垂直滚动 */
overflow-x: hidden; /* 隐藏水平滚动条 */
}
/* 确保 el-icon-loading 的动画效果没有被覆盖 */
.loading-box {
animation: rotate 2s linear infinite;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>

View File

@@ -1,32 +1,22 @@
<template>
<el-dialog title="数据查询" :model-value='visible' @close="handleCancel" width="1065px" draggable>
<el-dialog title="数据查询" :model-value='visible' @close="handleCancel" width="1065px" draggable>
<div class="data-check-dialog">
<div class="data-check-title">
<el-form :model='formContent'>
<el-row :gutter="24" >
<el-col :span="8">
<el-form-item label="检测脚本:" >
<el-input v-model='testScriptName' :disabled="true"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="误差体系:" >
<el-input v-model='errorSysName' :disabled="true"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="数据处理原则:" >
<el-input v-model='dataRule' :disabled="true"/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" >
<el-col :span="8">
<el-form-item label="设备名称:" >
<el-input v-model='deviceName' :disabled="true"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form :model='formContent' label-width="auto" class="form-three ">
<el-form-item label="检测脚本">
<el-input v-model='testScriptName' :disabled="true" />
</el-form-item>
<el-form-item label="误差体系">
<el-input v-model='errorSysName' :disabled="true" />
</el-form-item>
<el-form-item label="数据原则">
<el-input v-model='dataRule' :disabled="true" />
</el-form-item>
<el-form-item label="设备名称">
<el-input v-model='deviceName' :disabled="true" />
</el-form-item>
<!-- <el-col :span="8">
<el-form-item label='复检次数:'>
<el-select v-model="reCheckIdx">
<el-option
@@ -37,48 +27,44 @@
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label='通道号:'>
<el-select v-model="monitorIdx">
<el-option
v-for="item in monitorIdxList"
:key="item.value"
:label="item.value"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-col> -->
<el-form-item label='通道号'>
<el-select v-model="monitorIdx">
<el-option v-for="item in monitorIdxList" :key="item.value" :label="item.value"
:value="item.value" />
</el-select>
</el-form-item>
</el-form>
</div>
<div class="data-check-content">
<div class="content-left-tree">
<div class="content-left-tree-switch">
<el-switch
<!-- <el-switch
v-model="scriptSwitch"
class="ml-2"
inline-prompt
style="--el-switch-on-color: #003078; --el-switch-off-color: #5a79a9"
active-text="不合格测试项"
inactive-text="全部测试项"
/>
/> -->
<el-radio-group v-model="scriptSwitch">
<el-radio-button label="不合格测试项" value="0" />
<el-radio-button label="全部测试项" value="1" />
</el-radio-group>
</div>
<div>
<el-tree
:default-expanded-keys="['0','0-1','0-2','0-3','1']"
node-key="id"
:data="data"
:props="defaultProps"
@node-click="handleNodeClick"
/>
<div class="content-tree">
<el-tree :default-expanded-keys="['0', '0-1', '0-2', '0-3', '1']" node-key="id" :data="data"
:props="defaultProps" @node-click="handleNodeClick" />
</div>
</div>
<div class="content-right">
<div class="content-right-title">
<el-divider >当前检测项目</el-divider>
<span>{{currentScriptDsc}}</span>
<!-- <el-divider>当前检测项目</el-divider> -->
<div>
当前检测项目
</div>
<span>{{ currentScriptDsc }}</span>
</div>
<div class="content-right-Tabs">
<el-tabs type="border-card" v-model="activeName">
@@ -114,52 +100,52 @@ import { type Monitor } from '@/api/device/interface/monitor'
import { data } from "@/api/plan/autoTest.json";
import DataCheckResultTable from './dataCheckResultTable.vue'
import DataCheckRawDataTable from './dataCheckRawDataTable.vue'
const formContent = ref({})
const activeName = ref('rawDataTab')
const deviceName = ref('被检设备1');
const monitorIdx = ref('1');
const reCheckIdx = ref('3');
const testScriptName = ref('Q/GDW 10650.4-2021 模拟式');
const errorSysName = ref('Q/GDW 10650.2-2021');
const dataRule = ref('所有值');
const scriptSwitch = ref(true);
const currentScriptDsc = ref('频率准确度检测频率42.5Hz Ua=46.192V 0° Ub=46.192V -120° Uc=46.192V 120° Ia=1A 0° Ib=1A -120° Ic=1A 120°');
const defaultProps = {
children: "children",
label: "name",
pid: "pid",
const deviceName = ref('240001');
const monitorIdx = ref('1');
const reCheckIdx = ref('3');
const testScriptName = ref('Q/GDW 10650.4-2021 模拟式');
const errorSysName = ref('Q/GDW 10650.2-2021');
const dataRule = ref('所有值');
const scriptSwitch = ref("0");
const currentScriptDsc = ref('电压准确度检测频率42.5Hz Ua=46.192V 0° Ub=46.192V -120° Uc=46.192V 120° Ia=1A 0° Ib=1A -120° Ic=1A 120°');
const defaultProps = {
children: "children",
label: "name",
pid: "pid",
};
const reCheckList = [
{
value: '0',
},
{
value: '1',
},
{
value: '2',
},
{
value: '3',
},
{
value: '0',
},
{
value: '1',
},
{
value: '2',
},
{
value: '3',
},
]
const monitorIdxList = [
{
value: '1',
},
{
value: '2 (不合格)',
},
{
value: '3',
},
{
value: '4 (不合格)',
},
{
value: '1',
},
{
value: '2 (不合格)',
},
{
value: '3',
},
{
value: '4 (不合格)',
},
]
const handleNodeClick = (data) => {
console.log(data);
console.log(data);
};
const MonIsShow = ref(false)
const DevIsShow = ref(false)
@@ -168,55 +154,76 @@ const dictStore = useDictStore()
// 定义弹出组件元信息
const dialogFormRef = ref()
const disabledDate = (time: Date) => {
return time.getTime() > Date.now()
return time.getTime() > Date.now()
}
const props = defineProps<{
visible: boolean;
}>();
}>();
const emit = defineEmits<{
const emit = defineEmits<{
(e: 'update:visible', value: boolean): void;
(e: 'submit', data: any): void;
}>();
}>();
const handleCancel = () => {
const handleCancel = () => {
emit('update:visible', false); // 关闭对话框
};
};
</script>
<style scoped>
.data-check-dialog{
.data-check-dialog {
display: flex;
flex-direction: column;
max-height: 580px;
}
.data-check-title{
.data-check-title {
display: flex;
flex-direction: row;
margin-top: 10px;
}
.data-check-content{
.data-check-content {
display: flex;
flex-direction: row;
/* flex-direction: row; */
}
.content-left-tree{
width: 20%;
max-height: 475px;
overflow-y: auto;
.content-left-tree {
width: 240px;
max-height: 445px;
/* overflow-y: auto; */
padding: 10px 0;
border: 1px solid #ccc;
/* background-color: gray; */
}
.content-left-tree-switch{
.content-tree {
max-height: 405px;
margin-top: 10px;
overflow-y: auto;
}
.content-left-tree-switch {
text-align: right;
margin-right: 10px;
}
.content-right{
margin-left: 20px;
.content-right {
margin-left: 10px;
flex: 1;
}
.content-right-Tabs{
.content-right-Tabs {
margin-top: 15px;
}
:deep(.el-divider--horizontal) {
margin: 15px 0;
}
.content-right-title{
div{
font-size: 16px;
font-weight: 600;
}
}
</style>

View File

@@ -1,177 +1,47 @@
<template>
<div class="table-container">
<el-table :data="tableData" stripe :header-cell-style="{ textAlign: 'center' } " :cell-style="{ textAlign: 'center' }" height="310px" style="width: 100%" >
<el-table-column prop="id" label="序号" width="70" />
<el-table-column prop="updateTime" label="数据时间" />
<el-table-column prop="L1" label="L1V" />
<el-table-column prop="L2" label="L2V" />
<el-table-column prop="L3" label="L3V" />
</el-table>
</div>
<div class="table-main">
<el-table :data="tableData" stripe border :header-cell-style="{ textAlign: 'center' } "
:cell-style="{ textAlign: 'center' }" height="335px"
style="width: 100%;">
<el-table-column type="index" label="序号" width="70" fixed="left"/>
<el-table-column prop="updateTime" label="数据时间"/>
<template v-if="phaseFlag === 0">
<el-table-column prop="A" :label="`A${unit}`"/>
<el-table-column prop="B" :label="`B${unit}`"/>
<el-table-column prop="C" :label="`C${unit}`"/>
</template>
<template v-if="phaseFlag === 1">
<el-table-column prop="T" :label="`T${unit}`"/>
</template>
</el-table>
</div>
</template>
<script lang="tsx" setup>
import{ElMessage, FormInstance,FormItemRule}from'element-plus'
import { defineProps, defineEmits, reactive,watch,ref, Ref } from 'vue';
import { dialogBig,dialogMiddle} from '@/utils/elementBind'
//import IndicatorTypeDialog from "@/views/machine/errorSystem/components/IndicatorTypeDialog.vue"; // 导入子组件
import {CirclePlus, Delete, EditPen,FolderOpened,CopyDocument} from '@element-plus/icons-vue'
import { useDictStore } from '@/stores/modules/dict'
const tableData = ref([
{
id: 1,
updateTime: "2024-10-10 09:30:00",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 2,
updateTime: "2024-10-10 09:30:03",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 3,
updateTime: "2024-10-10 09:30:06",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 4,
updateTime: "2024-10-10 09:30:09",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 5,
updateTime: "2024-10-10 09:30:12",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 6,
updateTime: "2024-10-10 09:30:15",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 7,
updateTime: "2024-10-10 09:30:18",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 8,
updateTime: "2024-10-10 09:30:21",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 9,
updateTime: "2024-10-10 09:30:24",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 10,
updateTime: "2024-10-10 09:30:27",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 11,
updateTime: "2024-10-10 09:30:30",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 12,
updateTime: "2024-10-10 09:30:33",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 13,
updateTime: "2024-10-10 09:30:36",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 14,
updateTime: "2024-10-10 09:30:39",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 15,
updateTime: "2024-10-10 09:30:42",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 16,
updateTime: "2024-10-10 09:30:45",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 17,
updateTime: "2024-10-10 09:30:48",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 18,
updateTime: "2024-10-10 09:30:51",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 19,
updateTime: "2024-10-10 09:30:54",
L1:57.73,
L2:57.73,
L3:57.73,
},
{
id: 20,
updateTime: "2024-10-10 09:30:57",
L1:57.73,
L2:57.73,
L3:57.73,
},
])
import {CheckData} from "@/api/check/interface";
const {tableData} = defineProps<{
tableData: CheckData.RawDataItem[]
}>()
const unit = computed(() => {
return "V"
})
const phaseFlag = computed(() => {
let result = 0;
if (tableData.length > 0) {
result = !tableData[0].T ? 0 : 1;
}
return result;
})
</script>
<style scoped>
.table-container {
max-height: 320px; /* 根据需要调整高度 */
overflow-y: auto; /* 允许垂直滚动 */
overflow-x: hidden; /* 隐藏水平滚动条 */
}
</style>

View File

@@ -1,108 +1,129 @@
<template>
<div class="table-container">
<el-table :data="tableData" max-height="300" :header-cell-style="{ textAlign: 'center' } " :cell-style="{ textAlign: 'center' }" style="width: 100%" >
<div class="table-main">
<el-table :data="tableData" height="335px" :header-cell-style="{ textAlign: 'center' } "
:cell-style="{ textAlign: 'center' }">
<!-- <el-table-column prop="chnNum" label="通道号" width="80">-->
<!-- <template #default="{row}">-->
<!-- {{ '通道' + row.chnNum }}-->
<!-- </template>-->
<!-- </el-table-column>-->
<template v-if="phaseFlag === 0">
<el-table-column :label="`A${unit}`">
<el-table-column prop="standardValue" width="74" label="标准值V"/>
<el-table-column prop="A" width="74" label="被检值">
<el-table-column prop="id" label="序号" width="70" />
<el-table-column prop="standardValue" label="标准值V" />
</el-table-column>
<el-table-column prop="A_errValue" width="74" label="误差值">
<el-table-column label="L1V" >
<el-table-column prop="L1" label="被检值">
</el-table-column>
</el-table-column>
<el-table-column :label="`B${unit}`">
<el-table-column prop="standardValue" width="74" label="标准值V"/>
<el-table-column prop="B" width="74" label="被检值">
</el-table-column>
<el-table-column prop="L1_errValue" label="误差值">
</el-table-column>
<el-table-column prop="B_errValue" width="74" label="误差值">
</el-table-column>
</el-table-column>
<el-table-column label="L2V" >
<el-table-column prop="L2" label="被检值">
</el-table-column>
</el-table-column>
<el-table-column :label="`C${unit}`">
<el-table-column prop="standardValue" width="74" label="标准值V"/>
<el-table-column prop="C" width="74" label="被检值">
</el-table-column>
<el-table-column prop="L2_errValue" label="误差值">
</el-table-column>
<el-table-column prop="C_errValue" width="74" label="误差值">
</el-table-column>
</el-table-column>
<el-table-column label="L3V" >
<el-table-column prop="L3" label="被检值">
</el-table-column>
</el-table-column>
<el-table-column prop="maxErrVaule" label="最大误差V">
</el-table-column>
<el-table-column prop="L3_errValue" label="误差值">
</el-table-column>
<el-table-column prop="result" label="检测结果" width="70">
<template #default="scope">
<el-tag type="danger" v-if="scope.row.result === '不合格'">{{ scope.row.result }}</el-tag>
<span v-if="scope.row.result != '不合格'">{{ scope.row.result }}</span>
</template>
</el-table-column>
</template>
<template v-if="phaseFlag === 1">
<el-table-column :label="`T${unit}`">
<el-table-column prop="standardValue" label="标准值V"/>
<el-table-column prop="T" label="被检值">
</el-table-column>
</el-table-column>
</el-table-column>
<el-table-column prop="T_errValue" label="误差值">
<el-table-column prop="maxErrVaule" label="最大误差V">
</el-table-column>
</el-table-column>
<el-table-column prop="maxErrVaule" label="最大误差V">
</el-table-column>
<el-table-column prop="Result" label="检测结果">
<template #default="scope">
<el-tag :type="scope.row.Result === '合格' ? 'success' : 'danger'">{{ scope.row.Result }}</el-tag>
</template>
</el-table-column>
</el-table>
</div>
</el-table-column>
<el-table-column prop="result" label="检测结果">
<template #default="scope">
<el-tag type="danger" v-if="scope.row.result === '合格'">{{ scope.row.result }}</el-tag>
<span v-if="scope.row.result != '不合格'">{{ scope.row.result }}</span>
</template>
</el-table-column>
</template>
</el-table>
</div>
</template>
<script lang="tsx" setup>
import{ElMessage, FormInstance,FormItemRule}from'element-plus'
import { defineProps, defineEmits, reactive,watch,ref, Ref } from 'vue';
import { dialogBig,dialogMiddle} from '@/utils/elementBind'
//import IndicatorTypeDialog from "@/views/machine/errorSystem/components/IndicatorTypeDialog.vue"; // 导入子组件
import {CirclePlus, Delete, EditPen,FolderOpened,CopyDocument} from '@element-plus/icons-vue'
import { useDictStore } from '@/stores/modules/dict'
import {defineProps} from 'vue';
import {CheckData} from "@/api/check/interface";
const tableData = ref([
{
id: '1',
standardValue: 57.74,
L1:57.73,
L1_errValue: 0.01,
L2:57.73,
L2_errValue: 0.01,
L3:57.73,
L3_errValue: 0.01,
maxErrVaule: 0.05774,
Result: '合格',
},
const {tableData} = defineProps<{
tableData: CheckData.CheckResult[],
}>();
])
const unit = computed(() => {
return "V"
})
const phaseFlag = computed(() => {
let result = 0;
if (tableData.length > 0) {
result = !tableData[0].T ? 0:1;
}
return result;
})
</script>
<style scoped>
.form-grid {
display: flex;
flex-direction: row; /* 横向排列 */
flex-wrap: wrap; /* 允许换行 */
display: flex;
flex-direction: row; /* 横向排列 */
flex-wrap: wrap; /* 允许换行 */
}
.form-grid .el-form-item {
flex: 1 1 30%; /* 控件宽度 */
margin-right: 20px; /* 控件间距 */
flex: 1 1 30%; /* 控件宽度 */
margin-right: 20px; /* 控件间距 */
}
.form-grid .el-form-item:last-child {
margin-right: 0; /* 最后一个控件不需要右边距 */
margin-right: 0; /* 最后一个控件不需要右边距 */
}
.dialog-footer {
display: flex;
justify-content: flex-start;
margin-bottom: 10px; /* 调整这里的值以增加或减少间距 */
display: flex;
justify-content: flex-start;
margin-bottom: 10px; /* 调整这里的值以增加或减少间距 */
}
.el-tabs {
margin-bottom: 20px; /* 添加底部边距 */
margin-bottom: 20px; /* 添加底部边距 */
}
.el-table th, .el-table td {
text-align: center; /* 所有单元格文字居中 */
text-align: center; /* 所有单元格文字居中 */
}
.table-container {
max-height: 400px; /* 根据需要调整高度 */
overflow-y: auto; /* 允许垂直滚动 */
overflow-x: hidden; /* 隐藏水平滚动条 */
}
</style>

View File

@@ -1,151 +1,643 @@
<template>
<el-dialog title="数据查询" :model-value='visible' @close="handleCancel" v-bind="dialogBig" width="950px">
<div class="data-check-dialog">
<div class="data-check-title">
<el-dialog :append-to-body="appendToBody" class="dialog" title="数据查询" :model-value='visible' @close="close"
v-bind="dialogBig" :draggable="false" style="margin-left: 20%;">
<div class="data-check-dialog">
<div class="data-check-head">
<el-form :model='formContent' label-width="auto" class="form-three ">
<el-form-item label="检测脚本">
<el-input v-model='formContent.scriptName' :disabled="true"/>
</el-form-item>
<el-form-item label="误差体系">
<el-input v-model='formContent.errorSysName' :disabled="true"/>
</el-form-item>
<el-form-item label="数据原则">
<el-input v-model='formContent.dataRule' :disabled="true"/>
</el-form-item>
<el-form-item label="设备名称">
<el-input v-model='formContent.deviceName' :disabled="true"/>
</el-form-item>
<el-form-item label='通道号'>
<el-select v-model="formContent.chnNum">
<el-option v-for="item in chnList" :key="item.value" :label="item.label"
:value="item.value"/>
</el-select>
</el-form-item>
</el-form>
</div>
<!-- <el-form-item label='通道号:'>
<el-select v-model="monitorIdx">
<el-option
v-for="item in monitorIdxList"
:key="item.value"
:label="item.value"
:value="item.value"
/>
</el-select>
</el-form-item> -->
</div>
<div class="data-check-content">
<div class="content-right">
<div class="content-right-title">
<el-divider >当前检测项目</el-divider>
<span>{{currentScriptDsc}}</span>
</div>
<div class="content-right-Tabs">
<el-tabs type="border-card" v-model="activeName">
<el-tab-pane label="检测结果" name="resultTab">
<DataCheckResultTable></DataCheckResultTable>
</el-tab-pane>
<el-tab-pane label="原始数据" name="rawDataTab">
<DataCheckRawDataTable></DataCheckRawDataTable>
</el-tab-pane>
</el-tabs>
</div>
</div>
</div>
<div class="data-check-body">
<div class="content-left-tree">
<div>
<el-radio-group v-model="switchItem" @change="handleSwitchChange">
<el-radio-button label="不符合测试项" :value="0"/>
<el-radio-button label="全部测试项" :value="1"/>
</el-radio-group>
</div>
<div class="content-tree">
<el-tree v-if="switchItem === 0" :default-expanded-keys="defaultExpandedKeys" node-key="scriptType"
:data="treeDataUnqualified" :props="defaultProps" @node-click="handleNodeClick"
class="custom-tree">
<template #default="{ node, data }">
<span class="custom-tree-node">{{ data.scriptName }}</span>
</template>
</el-tree>
<el-tree v-if="switchItem === 1" :default-expanded-keys="defaultExpandedKeys" node-key="scriptType"
:data="treeDataAll" :props="defaultProps" @node-click="handleNodeClick" class="custom-tree">
<template #default="{ node, data }">
<span class="custom-tree-node">{{ data.scriptName }}</span>
</template>
</el-tree>
</div>
</div>
</el-dialog>
<div class="content-right">
<div class="content-right-title">
<el-divider>当前检测项目</el-divider>
<span>{{ currentScriptDsc }}</span>
</div>
<div class="content-right-Tabs">
<el-tabs type="border-card" v-model="activeTab">
<el-tab-pane label="检测结果" name="resultTab">
<DataCheckResultTable :tableData="checkResultTableData" ref="resultTableRef"/>
</el-tab-pane>
<el-tab-pane label="原始数据" name="rawDataTab">
<DataCheckRawDataTable :tableData="rawTableData" ref="rawDataTableRef"/>
</el-tab-pane>
</el-tabs>
</div>
</div>
</div>
</div>
</el-dialog>
</template>
<script setup lang='ts'>
import IPAddress from '@/components/IpAddress/index.vue'
import { dialogBig } from '@/utils/elementBind'
import { type Device } from '@/api/device/interface/device'
import { ElMessage, type FormItemRule } from 'element-plus'
import { addPqDev, updatePqDev } from '@/api/device/device'
import { computed, reactive, type Ref, ref } from 'vue'
import { useDictStore } from '@/stores/modules/dict'
import { CirclePlus, Delete, EditPen } from '@element-plus/icons-vue'
// 使用 dayjs 库格式化
import dayjs from 'dayjs'
import { getPqMonList } from '@/api/device/monitor'
import { type ColumnProps } from '@/components/ProTable/interface'
import { type Monitor } from '@/api/device/interface/monitor'
import { data } from "@/api/plan/autoTest.json";
import {dialogBig} from '@/utils/elementBind'
import {reactive, ref} from 'vue'
import DataCheckResultTable from './dataCheckResultTable.vue'
import DataCheckRawDataTable from './dataCheckRawDataTable.vue'
import {CheckData} from "@/api/check/interface";
import {useDictStore} from "@/stores/modules/dict";
import {useCheckStore} from "@/stores/modules/check";
import {getFormData, getTreeData} from "@/api/check/test";
const activeName = ref('rawDataTab')
const deviceName = ref('被检设备1');
const monitorIdx = ref('1');
const testScriptName = ref('Q/GDW 10650.4-2021 模拟式');
const errorSysName = ref('Q/GDW 10650.2-2021');
const dataRule = ref('所有值');
const scriptSwitch = ref(true);
const currentScriptDsc = ref('频率准确度检测频率42.5Hz Ua=46.192V 0° Ub=46.192V -120° Uc=46.192V 120° Ia=1A 0° Ib=1A -120° Ic=1A 120°');
const defaultProps = {
const {appendToBody} = withDefaults(defineProps<{
appendToBody: boolean
}>(), {appendToBody: true})
const defaultProps = {
label: "scriptName",
children: "children",
label: "name",
pid: "pid",
};
const monitorIdxList = [
{
value: '1',
},
{
value: '2',
},
{
value: '3',
},
{
value: '4',
},
]
const handleNodeClick = (data) => {
console.log(data);
};
const MonIsShow = ref(false)
const DevIsShow = ref(false)
const IsPasswordShow = ref(false)
const dictStore = useDictStore()
// 定义弹出组件元信息
const dialogFormRef = ref()
const disabledDate = (time: Date) => {
return time.getTime() > Date.now()
const checkStore = useCheckStore()
const visible = ref(false)
// 表单数据
const formContent = reactive<CheckData.DataCheck>({
scriptName: '',
errorSysName: '',
dataRule: '',
deviceName: '',
chnNum: '',
})
let deviceId: string = ''
let scriptType: string | null = null
// 通道下拉列表
let chnList: any[] = []
// 不符合测试项、全部测试项切换
const switchItem = ref<number>(0)
// 左侧树数据
let treeDataUnqualified: CheckData.ScriptItem[] = []
let treeDataAll: CheckData.ScriptItem[] = []
// 左侧树被选中的叶子节点id
const checkedScriptType = ref<string>('')
const currentScriptDsc = ref('');
// 右侧Tab选中项
const activeTab = ref<string>('resultTab')
// 检测结果表格数据
let checkResultTableData: CheckData.CheckResult = []
// 原始数据表格数据
let rawTableData: CheckData.RawDataItem[] = []
const resultTableRef = ref()
const rawDataTableRef = ref()
// 左侧树默认展开节点id
let defaultExpandedKeys: string[] = []
// 点击左侧树节点触发事件
const handleNodeClick = async (data: any) => {
if (!data.children) {
checkedScriptType.value = data.scriptType
currentScriptDsc.value = data.scriptName
if (checkedScriptType.value) {
await updateTableData()
}
}
};
watch(() => formContent.chnNum, async (newVal, oldVal) => {
console.log("通道号", newVal);
switchItem.value = 0
await handleSwitchChange(0)
})
const handleSwitchChange = async (data: any) => {
console.log("切换不合格测试项、全部测试项", data);
if (data === 0) {
// 发起请求,查询该测试项的检测结果
const {data: treeDataTemp} = await getTreeData({
scriptId: checkStore.scriptId,
deviceId,
devNum: formContent.chnNum + '',
scriptType,
code: checkStore.planCode
})
treeDataUnqualified = []
//filterTree(treeDataTemp,2)
//treeDataUnqualified=treeDataTemp
// treeDataUnqualified = [{
// "scriptName": "频率准确度检测",
// "children": [
// {
// "scriptName": "电压对频率测量的影响",
// "children": [
// {
// "scriptName": "输入:频率 50.05Hz Ua =10%Un...",
// "scriptType": '2346adafdf'
// },
// {
// "scriptName": "输入:频率 51.05Hz Ua =10%Un...",
// "scriptType": '1246adaafdf'
// },
// {
// "scriptName": "输入:频率 52.05Hz Ua =10%Un...",
// "scriptType": '2136ada3fdf'
// }
// ]
// },
// {
// "scriptName": "谐波对频率测量的影响",
// "children": [
// {
// "scriptName": "输入:频率 50.05Hz Ua =100%Un...",
// "scriptType": '234246adafdf'
// }
// ]
// }
// ]
// }]
} else {
// 发起请求,查询该测试项的检测结果
// const {data:treeDataAll} = await getTreeData({scriptId:checkStore.scriptId,deviceId, devNum: formContent.chnNum+'', scriptType,code:checkStore.planCode})
treeDataAll = []
// treeDataAll = [
// {
// "scriptName": "频率准确度检测",
// "children": [
// {
// "scriptName": "额定工作条件下的检测",
// "children": [
// {
// "scriptName": "输入:频率 42.5Hz...",
// "scriptType": '2246ada2fdf'
// },
// {
// "scriptName": "输入:频率 50.0Hz...",
// "scriptType": '2246a3dafdf'
// },
// {
// "scriptName": "输入:频率 50.05Hz....",
// "scriptType": '22246adafdf'
// }
// ]
// },
// {
// "scriptName": "电压对频率测量的影响",
// "children": [
// {
// "scriptName": "输入:频率 50.05Hz Ua =10%Un...",
// "scriptType": '224a6adafdf'
// },
// {
// "scriptName": "输入:频率 51.05Hz Ua =10%Un...",
// "scriptType": '2246aadafdf'
// },
// {
// "scriptName": "输入:频率 52.05Hz Ua =10%Un...",
// "scriptType": '2246adaffdf'
// }
// ]
// },
// {
// "scriptName": "谐波对频率测量的影响",
// "children": [
// {
// "scriptName": "输入:频率 50.05Hz Ua =100%Un...",
// "scriptType": '2246aadafdf'
// }
// ]
// }
// ]
// }
// ]
}
defaultOperate()
await updateTableData()
}
const props = defineProps<{
visible: boolean;
}>();
// 默认操作
const defaultOperate = () => {
let node = null
if (switchItem.value === 0) {
node = getDefaultNode(treeDataUnqualified)
} else {
node = getDefaultNode(treeDataAll)
}
if (node) {
currentScriptDsc.value = node.scriptName
checkedScriptType.value = node.scriptType
defaultExpandedKeys = [node.scriptType]
} else {
currentScriptDsc.value = ''
checkedScriptType.value = ''
defaultExpandedKeys = []
}
}
const emit = defineEmits<{
(e: 'update:visible', value: boolean): void;
(e: 'submit', data: any): void;
}>();
const updateTableData = async () => {
console.log("左侧树被选中的叶子节点scriptType", checkedScriptType.value);
// 发起请求,查询该测试项的检测结果
// const result = await getTableData({checkStore.scriptId,deviceId, formContent.chnNum, scriptType})
const handleCancel = () => {
emit('update:visible', false); // 关闭对话框
};
checkResultTableData = [{
chnNum: '1',
standardValue: 57.74,
A: 57.73,
A_errValue: 0.01,
B: 57.73,
B_errValue: 0.01,
C: 57.73,
C_errValue: 0.01,
maxErrVaule: 0.05774,
result: '合格',
}]
rawTableData = [
{
updateTime: "2024-10-10 09:30:00",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:03",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:06",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:09",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:12",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:15",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:18",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:21",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:24",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:27",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:30",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:33",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:36",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:39",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:42",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:45",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:48",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:51",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:54",
A: 57.73,
B: 57.73,
C: 57.73,
},
{
updateTime: "2024-10-10 09:30:57",
A: 57.73,
B: 57.73,
C: 57.73,
}
]
}
const open = async (_deviceId: string, chnNum: string, _scriptType: string | null) => {
// console.log(checkStore.scriptId, _deviceId, chnNum, _scriptType);
deviceId = _deviceId
scriptType = _scriptType
// 发起后端请求,查询详细信息 当chnNum为-1时查询所有通道号
const {data: resFormContent} = await getFormData({planId: checkStore.planId, deviceId, chnNum, scriptType})
// 数据处理
// let resFormContent = {
// scriptName: 'Q/GDW 10650.4-2021 模拟式',
// errorSysName: 'Q/GDW 10650.2-2021',
// dataRule: '505f063f9f91ab108d895a9fe96b5dce',
// deviceName: '被检设备1',
// chnList: [
// {value: '1', label: '1'},
// {value: '2', label: '0'},
// {value: '3', label: '1'},
// {value: '4', label: '0'}],
// }
chnList = resFormContent.chnList.map(item => ({
value: item.value,
label: item.label == '1' ? `${item.value}` : `${item.value}(不符合)`
}))
let dataRuleName = dictStore.getDictData('Data_Rule').find(item => item.id == resFormContent.dataRule)?.name
Object.assign(formContent, {
...resFormContent,
dataRule: dataRuleName,
chnNum: chnList[0].value
})
visible.value = true;
// console.log(filterTree(treeD, 1))
}
const close = () => {
//数据清空
Object.assign(formContent, {
scriptName: '',
errorSysName: '',
dataRule: '',
deviceName: '',
chnNum: '',
})
treeDataUnqualified = []
treeDataAll = []
checkedScriptType.value = ''
activeTab.value = 'rawDataTab'
currentScriptDsc.value = ''
switchItem.value = 0
visible.value = false;
};
const findFirstLeafNode = (node: any): any => {
if (!node.children || node.children.length === 0) {
return node;
}
return findFirstLeafNode(node.children[0]);
}
const getDefaultNode = (data: any[]) => {
if (!data || data.length === 0) {
return null;
}
const firstElement = data[0];
return findFirstLeafNode(firstElement);
}
// let treeD: any = [{
// "scriptTypeName": "暂态",
// "sort": null,
// "fly": null,
// "children": [
// {
// "scriptTypeName": "额定工作条件下的测量1",
// "sort": null,
// "fly": null,
// "children": [
// {
// "scriptTypeName": "输入:频率=50.0Hz Ua=100.0%Un Ub=100.0%Un Uc=100.0%Un Ia=100.0%In Ib=100.0%In Ic=100.0%In 暂态 A相(暂态深度=null% 暂态持续时间=null%) B相(暂态深度=null% 暂态持续时间=null%) C相(暂态深度=null% 暂态持续时间=null%) ",
// "sort": 81,
// "fly": 1,
// "children": null
// },
// {
// "scriptTypeName": "输入:频率=45.0Hz Ua=100.0%Un Ub=100.0%Un Uc=100.0%Un Ia=100.0%In Ib=100.0%In Ic=100.0%In 暂态 A相(暂态深度=null% 暂态持续时间=null%) B相(暂态深度=null% 暂态持续时间=null%) C相(暂态深度=null% 暂态持续时间=null%) ",
// "sort": 81,
// "fly": 0,
// "children": null
// }
// ]
// },
// {
// "scriptTypeName": "额定工作条件下的测量2",
// "sort": null,
// "fly": null,
// "children": [
// {
// "scriptTypeName": "输入:频率=50.0Hz Ua=100.0%Un Ub=100.0%Un Uc=100.0%Un Ia=100.0%In Ib=100.0%In Ic=100.0%In 暂态 A相(暂态深度=null% 暂态持续时间=null%) B相(暂态深度=null% 暂态持续时间=null%) C相(暂态深度=null% 暂态持续时间=null%) ",
// "sort": 81,
// "fly": 1,
// "children": null
// },
// {
// "scriptTypeName": "输入:频率=45.0Hz Ua=100.0%Un Ub=100.0%Un Uc=100.0%Un Ia=100.0%In Ib=100.0%In Ic=100.0%In 暂态 A相(暂态深度=null% 暂态持续时间=null%) B相(暂态深度=null% 暂态持续时间=null%) C相(暂态深度=null% 暂态持续时间=null%) ",
// "sort": 81,
// "fly": 0,
// "children": null
// }
// ]
// }
// ]
// }]
// fly: 1合格 2不合格 4数据错误
const filterTree = (treeData: any[], fly: number): any[] => {
if (!treeData || treeData.length === 0) {
return []
}
filter(treeData, fly)
return treeData
}
const filter = (treeData: any[], fly: number) => {
for (let i = 0; i < treeData.length; i++) {
let node = treeData[i]
if (node && node.fly !== fly) {
if (node.children && node.children.length > 0) {
filter(node.children, fly)
} else {
treeData.splice(i, 1)
}
}
}
}
defineExpose({
open
})
</script>
<style scoped>
.data-check-dialog{
<style lang="scss" scoped>
.dialog {
display: flex;
flex-direction: column;
overflow-y: hidden;
overflow-x: hidden;
.data-check-dialog {
display: flex;
flex-direction: column;
width: 100%;
.data-check-head {
display: flex;
flex-direction: row;
width: 100%;
}
.data-check-body {
width: 100%;
display: flex;
flex-direction: row;
.content-left-tree {
width: 25%;
display: flex;
flex-direction: column;
align-items: center;
max-height: 473px;
padding: 10px 0;
border: 1px solid #ccc;
overflow-y: auto;
.content-tree {
width: 100%;
height: 100%;
max-height: 100%;
margin-top: 10px;
.custom-tree-node {
overflow-x: hidden !important; // 溢出部分隐藏
white-space: nowrap !important; //禁止自动换行
text-overflow: ellipsis !important; // 使溢出部分以省略号显示
}
}
}
.content-right {
width: 75%;
margin-left: 10px;
flex: 1;
.content-right-title {
/*margin-bottom: 10px;*/
div {
font-size: 16px;
font-weight: 600;
}
}
.content-right-Tabs {
box-sizing: border-box;
margin-top: 20px;
margin-bottom: 10px;
max-height: 400px;
}
}
}
}
}
.data-check-title{
display: flex;
flex-direction: row;
margin-top: 5px;
width: 100%;
}
.data-check-content{
display: flex;
flex-direction: row;
width: 100%;
}
.content-right{
width: 100%;
}
.content-right-title{
margin-bottom: 10px;
}
.content-right-Tabs{
box-sizing: border-box;
margin-top: 20px;
margin-bottom: 10px;
max-height: 400px;
}
</style>

View File

@@ -1,131 +1,132 @@
<template>
<div>
<el-tabs type="border-card">
<el-tab-pane label="预检测项目">
<div class="form-grid">
<el-checkbox
v-for="(item, index) in detectionOptions"
v-model="item.selected"
:key="index"
:label="item.name"
<div>
<el-tabs type="border-card">
<el-tab-pane label="预检测项目">
<div class="form-grid">
<el-checkbox v-for="(item, index) in detectionOptions" v-model="item.selected" :key="index"
:label="item.name"></el-checkbox>
<!-- disabled="true" -->
</div>
</el-tab-pane>
</el-tabs>
></el-checkbox
>
<!-- disabled="true" -->
</div>
</el-tab-pane>
</el-tabs>
<div class = "test-dialog">
<div class="dialog-left">
<el-steps direction="vertical" :active="activeIndex" :process-status="currentStepStatus" finish-status="success">
<el-step title="源通讯校验" />
<el-step title="设备通讯校验" />
<el-step title="协议校验" />
<el-step title="相序校验" />
<el-step title="检测完成" />
</el-steps>
</div>
<div class="dialog-right">
<div class="test-dialog">
<div class="dialog-left">
<el-steps direction="vertical" :active="activeIndex" :process-status="currentStepStatus"
finish-status="success">
<el-step :status="step1" title="源通讯校验" />
<el-step :status="step2" title="设备通讯校验" />
<el-step :status="step3" title="协议校验" />
<el-step :status="step4" title="相序校验" />
<el-step :status="step5" title="检测完成" />
</el-steps>
</div>
<div class="dialog-right">
<el-collapse v-model="collapseActiveName" accordion>
<el-collapse-item title="源通讯校验" name="1">
<div class = "div-log">
<p v-for="(item, index) in step1InitLog" :key="index" :style="{color:item.type==='error'?'#F56C6C':'var(--el-text-color-regular)'}">
{{ item.log }} <br />
</p>
</div>
</el-collapse-item>
<el-collapse-item title="设备通讯校验" name="2">
<div class = "div-log">
<p v-for="(item, index) in step2InitLog" :key="index" :style="{color:item.type==='error'?'#F56C6C':'var(--el-text-color-regular)'}">
{{ item.log }} <br />
</p>
</div>
</el-collapse-item>
<el-collapse-item title="协议校验" name="3">
<div class = "div-log">
<p v-for="(item, index) in step3InitLog" :key="index" :style="{color:item.type==='error'?'#F56C6C':'var(--el-text-color-regular)'}">
{{ item.log }} <br />
</p>
</div>
</el-collapse-item>
<el-collapse-item title="相序校验" name="4">
<div class = "div-log">
<p v-for="(item, index) in step4InitLog" :key="index" :style="{color:item.type==='error'?'#F56C6C':'var(--el-text-color-regular)'}">
{{ item.log }} <br />
</p>
</div>
</el-collapse-item>
<el-collapse-item title="源通讯校验" name="1">
<div class="div-log">
<p v-for="(item, index) in step1InitLog" :key="index"
:style="{ color: item.type === 'error' ? '#F56C6C' : 'var(--el-text-color-regular)' }">
{{ item.log }} <br />
</p>
</div>
</el-collapse-item>
<el-collapse-item title="设备通讯校验" name="2">
<div class="div-log">
<p v-for="(item, index) in step2InitLog" :key="index"
:style="{ color: item.type === 'error' ? '#F56C6C' : 'var(--el-text-color-regular)' }">
{{ item.log }} <br />
</p>
</div>
</el-collapse-item>
<el-collapse-item title="协议校验" name="3">
<div class="div-log">
<p v-for="(item, index) in step3InitLog" :key="index"
:style="{ color: item.type === 'error' ? '#F56C6C' : 'var(--el-text-color-regular)' }">
{{ item.log }} <br />
</p>
</div>
</el-collapse-item>
<el-collapse-item title="相序校验" name="4">
<div class="div-log">
<p v-for="(item, index) in step4InitLog" :key="index"
:style="{ color: item.type === 'error' ? '#F56C6C' : 'var(--el-text-color-regular)' }">
{{ item.log }} <br />
</p>
</div>
</el-collapse-item>
</el-collapse>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="tsx" setup name="preTest">
import {ElMessage} from "element-plus";
import { defineExpose } from 'vue';
const step1InitLog = ref([
{
type: 'info',
log:'暂无数据,等待检测开始',
log: '暂无数据,等待检测开始',
},
])
const step1Log = ref([
{
type: 'info',
log:'源通讯校验成功',
log: '源通讯校验成功',
},
])
const step2InitLog = ref([
{
type: 'info',
log:'暂无数据,等待检测开始',
log: '暂无数据,等待检测开始',
},
])
const step2Log = ref([
{
type: 'info',
log:'被检设备1通讯校验成功',
log: '被检设备240001通讯校验成功',
},
{
type: 'info',
log:'被检设备2通讯校验成功',
log: '被检设备240002通讯校验成功',
},
{
type: 'info',
log:'被检设备3通讯校验成功',
log: '被检设备240003通讯校验成功',
},
{
type: 'info',
log:'被检设备4通讯校验成功',
log: '被检设备240004通讯校验成功',
},
])
const step3InitLog = ref([
{
type: 'info',
log:'暂无数据,等待检测开始',
log: '暂无数据,等待检测开始',
},
])
const step3Log = ref([
{
type: 'info',
log:'被检设备1协议校验成功',
log: '被检设备240001协议校验成功',
},
{
type: 'info',
log:'被检设备2协议校验成功',
log: '被检设备240002协议校验成功',
},
{
type: 'info',
log:'被检设备3协议校验成功',
log: '被检设备240003协议校验成功',
},
{
type: 'info',
log:'被检设备4协议校验成功',
log: '被检设备240004协议校验成功',
},
])
@@ -133,32 +134,38 @@ const step3Log = ref([
const step4InitLog = ref([
{
type: 'info',
log:'暂无数据,等待检测开始',
log: '暂无数据,等待检测开始',
},
])
const step4Log = ref([
{
type: 'info',
log:'被检设备1相序校验成功',
log: '被检设备240001相序校验成功',
},
{
type: 'info',
log:'被检设备2相序校验成功',
log: '被检设备240002相序校验成功',
},
{
type: 'info',
log:'被检设备3相序校验成功',
log: '被检设备240003相序校验成功',
},
{
type: 'info',
log:'被检设备4相序校验成功',
log: '被检设备240004相序校验成功',
},
])
const collapseActiveName = ref('1')
const activeIndex = ref(0)
const activeTotalNum = ref(5)
const step1 = ref('wait')
const step2 = ref('wait')
const step3 = ref('wait')
const step4 = ref('wait')
const step5 = ref('wait')
//定义与预检测配置数组
const detectionOptions = ref([
{
@@ -181,16 +188,16 @@ const detectionOptions = ref([
name: "相序校验",//判断装置的接线是否正确
selected: true,
},
// {
// id: 4,
// name: "守时校验",//判断装置24小时内的守时误差是否小于1s
// selected: true,
// },
// {
// id: 5,
// name: "通道系数校准",//通过私有协议与装置进行通讯,校准三相电压电流的通道系数
// selected: true,
// },
// {
// id: 4,
// name: "守时校验",//判断装置24小时内的守时误差是否小于1s
// selected: true,
// },
// {
// id: 5,
// name: "通道系数校准",//通过私有协议与装置进行通讯,校准三相电压电流的通道系数
// selected: true,
// },
// {
// id: 6,
// name: "实时数据比对",
@@ -203,65 +210,331 @@ const detectionOptions = ref([
const currentStepStatus = ref<'error' | 'finish' | 'wait' | 'success' | 'process'>('finish');
const props = defineProps({
testStatus: {
const props = defineProps({
testStatus: {
type: String,
default: 'wait'
},
webMsgSend: {
type: Object,
default: () => ({})
}
})
const testStatus = toRef(props, 'testStatus');
const webMsgSend = toRef(props, 'webMsgSend');
const ts = ref('');
watch(activeIndex, function (newValue, oldValue) {
watch(webMsgSend,function (newValue,oldValue){
// console.log(newValue)
if(activeIndex.value === 1)
{
step1InitLog.value.length = 0;
step1InitLog.value = step1Log.value;
switch (newValue.requestId){
case 'yjc_ytxjy':
switch (newValue.operateCode){
case 'INIT_GATHER':
if(newValue.code == 10200) {
step1InitLog.value.push({
type: 'info',
log: '源校验成功!',
})
activeIndex.value = 1
step1.value = 'success'
step2.value = 'process'
}else if(newValue.code == 10201){
step1.value = 'process'
step1InitLog.value = [{
type: 'wait',
log: '正在进行源校验!',
}];
}else if(newValue.code == 10552){
ElMessage.error(newValue.code)
step1.value = 'error'
ts.value = 'error'
}
break;
}
break;
case 'yjc_sbtxjy':
switch (newValue.operateCode) {
case 'INIT_GATHER$01':
if (newValue.code == 10200) {
step2InitLog.value.push({
type: 'info',
log: newValue.data+'设备通讯校验成功!',
})
} else if (newValue.code == 10201) {
step2.value = 'process'
step2InitLog.value = [{
type: 'wait',
log: '正在进行设备通讯校验.....',
}];
} else if (newValue.code == 10550) {
step2InitLog.value.push({
type: 'error',
log: newValue.data+'设备连接异常!',
})
step2.value = 'error'
ts.value = 'error'
}else if (newValue.code == 10551) {
step2InitLog.value.push({
type: 'error',
log: newValue.data+'设备触发报告异常!',
})
step2.value = 'error'
ts.value = 'error'
} else if (newValue.code == 10552) {
//ElMessage.error("存在已经初始化步骤,已经自动关闭,请重新发起检测!")
step2InitLog.value = [{
type: 'wait',
log: '存在已经初始化步骤,执行自动关闭,请重新发起检测!',
}];
step2.value = 'error'
ts.value = 'error'
} else if (newValue.code == 25001) {
activeIndex.value = 2
step2.value = 'success'
step3.value = 'process'
}
break;
}
break;
case 'yjc_xyjy':
switch (newValue.operateCode) {
case 'INIT_GATHER$01':
if (newValue.code == 10200) {
step3InitLog.value.push({
type: 'info',
log: '统计数据协议校验:'+newValue.data+'通讯协议校验成功!',
})
} else if (newValue.code == 10201) {
step3.value = 'process'
step3InitLog.value = [{
type: 'wait',
log: '正在进行通讯协议校验.....',
}];
} else if (newValue.code == 10550) {
step3InitLog.value.push({
type: 'error',
log: newValue.data+'设备连接异常!',
})
step3.value = 'error'
ts.value = 'error'
}else if (newValue.code == 10551) {
step3InitLog.value.push({
type: 'error',
log: newValue.data+'设备触发报告异常!',
})
step3.value = 'error'
ts.value = 'error'
}else if (newValue.code == 10552) {
step3.value = 'error'
//ElMessage.error("存在已经初始化步骤,已经自动关闭,请重新发起检测!")
step3InitLog.value = [{
type: 'wait',
log: '存在已经初始化步骤,执行自动关闭,请重新发起检测!',
}];
ts.value = 'error'
}
break;
case 'INIT_GATHER$02':
if (newValue.code == 10200) {
step3InitLog.value.push({
type: 'info',
log: '实时数据协议校验:'+newValue.data+'通讯协议校验成功!',
})
} else if (newValue.code == 10201) {
step3.value = 'process'
step3InitLog.value = [{
type: 'wait',
log: '正在进行通讯协议校验.....',
}];
}else if (newValue.code == 10550) {
step3InitLog.value.push({
type: 'error',
log: newValue.data+'设备连接异常!',
})
step3.value = 'error'
ts.value = 'error'
}else if (newValue.code == 10551) {
step3InitLog.value.push({
type: 'error',
log: newValue.data+'设备触发报告异常!',
})
step3.value = 'error'
ts.value = 'error'
} else if (newValue.code == 10552) {
step3.value = 'error'
//ElMessage.error("存在已经初始化步骤,已经自动关闭,请重新发起检测!")
step3InitLog.value = [{
type: 'wait',
log: '存在已经初始化步骤,执行自动关闭,请重新发起检测!',
}];
ts.value = 'error'
}
break;
case 'INIT_GATHER$03':
if (newValue.code == 10200) {
step3InitLog.value.push({
type: 'info',
log: '暂态数据协议校验:'+newValue.data+'通讯协议校验成功!',
})
} else if (newValue.code == 10201) {
step3.value = 'process'
}else if (newValue.code == 10550) {
step3InitLog.value.push({
type: 'error',
log: newValue.data+'设备连接异常!',
})
step3.value = 'error'
ts.value = 'error'
}else if (newValue.code == 10551) {
step3InitLog.value.push({
type: 'error',
log: newValue.data+'设备触发报告异常!',
})
step3.value = 'error'
ts.value = 'error'
} else if (newValue.code == 10552) {
//ElMessage.error("当前步骤已经初始化,执行自动关闭,请重新发起检测!")
step3.value = 'error'
step3InitLog.value = [{
type: 'wait',
log: '存在已经初始化步骤,执行自动关闭,请重新发起检测!',
}];
ts.value = 'error'
} else if (newValue.code == 25001) {
activeIndex.value = 3
step3.value = 'success'
step4.value = 'process'
}
break;
}
break;
case 'YJC_xujy':
switch (newValue.operateCode) {
case 'OPER_GATHER':
if (newValue.code == 10200) {
step4InitLog.value.push({
type: 'info',
log: '源已接通!',
})
} else if (newValue.code == 10201) {
step4.value = 'process'
step4InitLog.value = [{
type: 'wait',
log: '正在接通源.....',
}];
} else if (newValue.code == 10552) {
ElMessage.error("存在已经初始化步骤,已经自动关闭,请重新发起检测!")
step4.value = 'error'
ts.value = 'error'
} else if (newValue.code == 10520) {
step4.value = 'error'
step4InitLog.value.push({
type: 'error',
log: '解析报文异常',
})
ts.value = 'error'
}
break;
case 'DATA_REQUEST$02':
if (newValue.code == 10200) {
step4InitLog.value.push({
type: 'info',
log: '相序校验:'+newValue.data,
})
} else if (newValue.code == 10201) {
step4.value = 'process'
step4InitLog.value = [{
type: 'wait',
log: '获取数据相序校验数据!',
}];
}
else if (newValue.code == 25001) {
step4.value = 'success'
step5.value = 'success'
step4InitLog.value.push({
type: 'wait',
log: '相序校验成功!',
})
}
activeIndex.value = 5
ts.value = 'success'
break
}
break;
case 'quit':
break;
case 'connect':
switch (newValue.operateCode){
case "Source":
step1.value = 'error'
step1InitLog.value = [{
type: 'error',
log: '源服务端连接失败!',
}];
ts.value = 'error'
break;
case "Dev":
step2.value = 'error'
step2InitLog.value = [{
type: 'error',
log: '设备服务端连接失败!',
}];
ts.value = 'error'
break;
}
break;
}
if(activeIndex.value === 2)
{
step2InitLog.value.length = 0;
step2InitLog.value = step2Log.value;
})
watch(activeIndex, function (newValue, oldValue) {
if (newValue <= activeTotalNum.value - 2){
collapseActiveName.value = (newValue+1).toString()
} else{
collapseActiveName.value = (newValue - 1).toString()
}
if(activeIndex.value === 3)
{
step3InitLog.value.length = 0;
step3InitLog.value = step3Log.value;
}
if(activeIndex.value > 3)
{
step4InitLog.value.length = 0;
step4InitLog.value = step4Log.value;
}
if(activeIndex.value < activeTotalNum.value - 2)
collapseActiveName.value = (newValue+1).toString()
else
collapseActiveName.value = (activeTotalNum.value - 1).toString()
})
//监听goods_sn的变化
watch(testStatus, function (newValue, oldValue) {
ts.value = props.testStatus;
if(ts.value==='start')
{
if (ts.value === 'start') {
ts.value = 'process'
let timer = setInterval(() => {
if(activeIndex.value < activeTotalNum.value - 2)
activeIndex.value++
else if(activeIndex.value === activeTotalNum.value -2)
{
activeIndex.value++
activeIndex.value++
}
else
{
clearInterval(timer)
ts.value = 'success'
}
}, 1500);
}else if(ts.value === 'waiting'){
activeIndex.value = 0
step1InitLog.value = [
{
type: 'info',
log: '暂无数据,等待检测开始',
},
]
step1.value = 'finish'
step2.value = 'wait'
step3.value = 'wait'
step4.value = 'wait'
step5.value = 'wait'
}
})
@@ -269,52 +542,107 @@ const emit = defineEmits(['update:testStatus']);
//监听sn
watch(ts, function (newValue, oldValue) {
//修改父组件
emit('update:testStatus',ts.value)
emit('update:testStatus', ts.value)
})
// 定义一个初始化参数的方法
function initializeParameters() {
activeIndex.value = 0
step1.value = 'process'
step2.value = 'wait'
step3.value = 'wait'
step4.value = 'wait'
step5.value = 'wait'
step1InitLog.value = [
{
type: 'info',
log: '暂无数据,等待检测开始',
},
]
step2InitLog.value = [
{
type: 'info',
log: '暂无数据,等待检测开始',
},
]
step3InitLog.value = [
{
type: 'info',
log: '暂无数据,等待检测开始',
},
]
step4InitLog.value = [
{
type: 'info',
log: '暂无数据,等待检测开始',
},
]
}
defineExpose({
initializeParameters,
});
</script>
<style scoped lang="scss">
<style scoped lang="scss">
.test-dialog {
height: 350px;
display: flex;
.test-dialog{
height: 350px;
display: flex;
flex-direction: row; /* 横向排列 */
margin-top: 20px;
/* .dialog-left{
flex-direction: row;
/* 横向排列 */
margin-top: 20px;
/* .dialog-left{
margin-right: 20px;
} */
}
.dialog-left{
width: 15%;
margin-left: 20px;
}
/* .dialog-left :deep(.test-head-steps){
.dialog-left {
width: 15%;
margin-left: 20px;
}
/* .dialog-left :deep(.test-head-steps){
height: 80px;
/* margin-bottom: 10px;
}
*/
/* .dialog-left :deep(.el-step__title) {
/* .dialog-left :deep(.el-step__title) {
font-size: 18px !important; /* 设置标题字体大小
} */
/* .dialog-left :deep(.el-step__icon-inner) {
/* .dialog-left :deep(.el-step__icon-inner) {
font-size: 24px !important;
} */
.dialog-right{
margin-left: 20px;
width: 80%;
height: 100%;
}
.dialog-right :deep(.el-collapse-item__header) {
font-size: 16px;
}
.dialog-right {
margin-left: 20px;
width: 80%;
height: 100%;
}
.div-log{
height: 100px;
padding-left: 10px;
}
.dialog-right :deep(.el-collapse-item__header) {
font-size: 16px;
}
.div-log {
height: 145px;
overflow-y: auto;
padding-left: 10px;
p {
margin: 5px 0;
font-size: 14px;
}
}
</style>

View File

@@ -1,56 +1,54 @@
<template>
<el-dialog title="报告生成" :model-value='visible' @close="handleCancel" width="832px">
<el-dialog title="报告生成" :model-value='visible' @close="handleCancel" width="832px" draggable>
<div class="report-dialog">
<div class="report-title">
<div>
<el-row :gutter="24" >
<el-col :span="12">
<el-form-item label="检测脚本:" >
<div class="report-title form-two">
<el-form-item label="检测脚本" label-width="100px">
<el-input v-model='testScriptName' :disabled="true"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="误差体系" >
<el-form-item label="误差体系" label-width="100px">
<el-input v-model='errorSysName' :disabled="true"/>
</el-form-item>
</el-col>
</el-row>
</div>
<div>
<el-row :gutter="24" >
<el-col :span="12">
<el-form-item label="数据处理原则" >
<el-input v-model='dataRule' :disabled="true"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="报告模板" >
<el-input v-model='reportTemplate' :disabled="true"/>
</el-form-item>
</el-col>
</el-row>
</div>
<el-form-item label="数据原则" label-width="100px">
<el-input v-model='dataRule' :disabled="true"/>
</el-form-item>
<el-form-item label="报告模板" label-width="100px">
<el-input v-model='reportTemplate' :disabled="true"/>
</el-form-item>
</div>
<div class="report-content">
<div>
<el-tabs type="border-card">
<el-tab-pane label="报告生成状态表:">
<el-tab-pane label="报告生成进度">
<div class="form-grid">
<div class="tabs-title"><el-button type="primary" loading >已生成2台/共4台</el-button> </div>
<el-table :data="reportData" stripe="" :header-cell-style="{ textAlign: 'center' } " :cell-style="{ textAlign: 'center' }" style="width: 100%" border class="custom-table">
<div class="tabs-title ">
<el-button type="primary" :icon="Download" >报告下载</el-button>
<span style=" font-size: 18px;font-weight: 600;">
已生成 <span style="color: #67C23A">2</span> / <span style="color: green">3</span>
</span>
</div>
<div class="table-main">
<el-table :data="reportData" :header-cell-style="{ textAlign: 'center' } " :cell-style="{ textAlign: 'center' }" style="width: 100%" border class="custom-table">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" width="70" label="序号" />
<el-table-column prop="deviceName" width="150" label="设备名称" />
<el-table-column label="生成进度" width="450">
<el-table-column label="生成进度">
<template #default="scope">
<el-progress :color="customColors" :percentage="scope.row.processValue" />
</template>
</el-table-column>
<el-table-column prop="action" label="操作" width="100">
<template #default="scope">
<el-button type='primary' link :icon='View' :disabled="scope.row.processValue < 100">查看</el-button>
<el-button type='primary' link :icon='Download' :disabled="scope.row.processValue < 100">下载</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
</el-tab-pane>
</el-tabs>
@@ -69,7 +67,7 @@ import { ElMessage, type FormItemRule } from 'element-plus'
import { addPqDev, updatePqDev } from '@/api/device/device'
import { computed, reactive, type Ref, ref } from 'vue'
import { useDictStore } from '@/stores/modules/dict'
import { CirclePlus, Delete, EditPen,View } from '@element-plus/icons-vue'
import { CirclePlus, Delete, Download,View } from '@element-plus/icons-vue'
@@ -78,12 +76,12 @@ import { CirclePlus, Delete, EditPen,View } from '@element-plus/icons-vue'
const errorSysName = ref('Q/GDW 10650.2-2021');
const dataRule = ref('所有值');
const scriptSwitch = ref(true);
const currentScriptDsc = ref('频率准确度检测频率42.5Hz Ua=46.192V 0° Ub=46.192V -120° Uc=46.192V 120° Ia=1A 0° Ib=1A -120° Ic=1A 120°');
const currentScriptDsc = ref('电压准确度检测频率42.5Hz Ua=46.192V 0° Ub=46.192V -120° Uc=46.192V 120° Ia=1A 0° Ib=1A -120° Ic=1A 120°');
const reportData = ref([
{ id: '1', deviceName: '被检设备1', processValue: '100' , action:'查看' },
{ id: '2', deviceName: '被检设备2', processValue: '100' , action:'查看' },
{ id: '3', deviceName: '被检设备3', processValue: '10', action:'查看' },
{ id: '1', deviceName: '240001', processValue: '100' , action:'查看' },
{ id: '2', deviceName: '240002', processValue: '100' , action:'查看' },
{ id: '3', deviceName: '240003', processValue: '10', action:'查看' },
])
const customColors = [
{ color: "red", percentage: 0 },
@@ -146,7 +144,7 @@ const props = defineProps<{
}
.tabs-title{
display: flex;
justify-content: flex-end;
justify-content: space-between;
margin-bottom: 10px;
}

View File

@@ -3,13 +3,13 @@
<div class="result-dialog">
<div class="result-title">
<el-row>
<el-form-item label="检测脚本:" >
<el-form-item label="检测脚本" >
<el-input v-model='testScriptName' :disabled="true"/>
</el-form-item>
<el-form-item label="误差体系" >
<el-input v-model='errorSysName' :disabled="true"/>
</el-form-item>
<el-form-item label="数据处理原则" >
<el-form-item label="数据原则" >
<el-input v-model='dataRule' :disabled="true"/>
</el-form-item>
</el-row>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +1,23 @@
<template>
<el-dialog :title="dialogTitle" :model-value="visible" :before-close="beforeClose" @close="handleCancel" width="1200px" height="1000px" draggable>
<el-dialog :title="dialogTitle" :model-value="dialogVisible" :before-close="beforeClose" @close="handleCancel" width="1200px" height="1000px" draggable>
<div class="steps-container">
<!-- simple -->
<!-- :style="{color:node.label=='未检'?'#F56C6C':node.label=='检测中'?'#E6A23C':'#67C23A'}" -->
<!-- :style="{color:node.label=='未检'?'#F56C6C':node.label=='检测中'?'#E6A23C':'#67C23A'}" -->
<el-steps class="test-head-steps" simple :active="stepsActiveIndex" process-status="finish" finish-status="success" >
<!-- style="height:100px" -->
<!-- <el-step title="预检测" :icon="getIcon(0)" /> -->
<el-step title="预检测" :icon="stepsActiveIndex > 1 ? SuccessFilled :Edit" />
<el-step title="守时检测" :icon="stepsActiveIndex > 1 ? SuccessFilled :UploadFilled"/>
<el-step title="系数校准" :icon="stepsActiveIndex > 2 ? SuccessFilled :Odometer" />
<el-step title="守时检测" :icon="stepsActiveIndex > 1 ? SuccessFilled :UploadFilled" v-if="isTimeCheck"/>
<!-- <el-step title="系数校准" :icon="stepsActiveIndex > 2 ? SuccessFilled :Odometer" /> -->
<el-step title="正式检测" :icon="stepsActiveIndex > 3 ? SuccessFilled :Coin" />
<el-step title="检测完成" :icon="stepsActiveIndex > 4 ? SuccessFilled :Key" />
</el-steps>
</div>
<preTest v-if="stepsActiveIndex === 0" v-model:testStatus="preTestStatus"></preTest>
<timeTest v-if="stepsActiveIndex === 1" v-model:testStatus="timeTestStatus"></timeTest>
<channelsTest v-if="stepsActiveIndex === 2" v-model:testStatus="channelsTestStatus"></channelsTest>
<test v-if="stepsActiveIndex >= 3" v-model:testStatus="TestStatus"></test>
<preTest ref="preTestRef" v-if="stepsActiveIndex === 0" v-model:testStatus="preTestStatus" :webMsgSend="webMsgSend"></preTest>
<timeTest v-if="stepsActiveIndex === 1 && isTimeCheck" v-model:testStatus="timeTestStatus"></timeTest>
<!-- <channelsTest v-if="stepsActiveIndex === 2" v-model:testStatus="channelsTestStatus"></channelsTest> -->
<test ref="testRef" v-if="stepsActiveIndex >= 2" v-model:testStatus="TestStatus" :webMsgSend="webMsgSend" @update:webMsgSend="webMsgSend=$event" @sendPause="sendPause" @sendResume="sendResume"></test>
<template #footer>
<div>
@@ -25,8 +25,13 @@
<el-button type="primary" :icon="DArrowRight" v-if="stepsActiveIndex < 2 && ActiveStatue != 'success'" :disabled="skipDisabled" @click="nextStep">跳过</el-button>
<el-button type="primary" :icon="VideoPlay" v-if="ActiveStatue === 'waiting'" @click="handleSubmit">开始检测</el-button>
<el-button type="danger" :icon="Close" v-if="ActiveStatue === 'process'" @click="handleSubmit">停止检测</el-button>
<el-button type="primary" :icon="Refresh" v-if="ActiveStatue === 'error'" @click="handleSubmit">重新检测</el-button>
<el-button type="primary" :icon="Right" v-if="ActiveStatue === 'success'" @click="nextStep">{{nextStepText}}</el-button>
<el-button type="danger" :icon="Close" v-if="ActiveStatue === 'paused'" @click="handleSubmit">继续检测</el-button>
<el-button type="primary" :icon="RefreshLeft" v-if="ActiveStatue === 'error'" @click="handleSubmit">重新检测</el-button>
<el-button type="primary" :icon="Refresh" v-if="ActiveStatue === 'preTest_process'" disabled>预检测中</el-button>
<el-button :type="ActiveStatue==='success'?'primary':'danger'" :icon="Right"
v-if="ActiveStatue === 'success'||ActiveStatue==='preTest_fail'" @click="nextStep">
{{ nextStepText }}
</el-button>
</div>
</template>
</el-dialog>
@@ -35,16 +40,31 @@
</template>
<script lang="tsx" setup name="testPopup">
import { h } from 'vue';
import{ElMessage, ElSelectV2, FormInstance,FormItemRule}from'element-plus'
import { defineProps, defineEmits, reactive,watch,ref, Ref } from 'vue';
import { dialogBig,dialogMiddle} from '@/utils/elementBind'
import {h, reactive, ref, watch} from 'vue';
import {ElMessage, ElMessageBox} from 'element-plus'
//import IndicatorTypeDialog from "@/views/machine/errorSystem/components/IndicatorTypeDialog.vue"; // 导入子组件
import {CirclePlus, Delete, EditPen,FolderOpened,CopyDocument,Edit, Picture, UploadFilled, SuccessFilled,VideoPlay,Right,Refresh,Close, Odometer,Coin,Key, DArrowRight} from '@element-plus/icons-vue'
import { useDictStore } from '@/stores/modules/dict'
import {
Close,
Coin,
DArrowRight,
Edit,
Key,
Odometer,
Refresh,
Right,
SuccessFilled,
UploadFilled,
VideoPlay,
RefreshLeft
} from '@element-plus/icons-vue'
import preTest from './preTest.vue'
import timeTest from './timeTest.vue'
import channelsTest from './channelsTest.vue'
import { Device } from '@/api/device/interface/device';
import socketClient from '@/utils/webSocketClient';
import {useCheckStore} from "@/stores/modules/check";
import {startPreTest,startTest,pauseTest,resumeTest} from '@/api/socket/socket'
//import SvgIcon from '@/components/SvgIcon.vue';
// import preTestIcon from '@/assets/icons/preTest.svg'
@@ -53,28 +73,30 @@
// <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6">
// </svg>
// `;
const props = defineProps<{
visible: boolean;
dialogTitle: string;
// const props = defineProps<{
// visible: boolean;
// dialogTitle: string;
formData: {
id: string;//误差体系表Id
name: string;//误差体系名称
standard_Name:string;//参照标准名称
standard_Time:string;//标准推行时间
dev_Level:string;//使用设备等级
enable:number;//状态0-不启用 1-启用
state:number;//0-删除 1-正常
};
}>();
// formData: {
// id: string;//误差体系表Id
// name: string;//误差体系名称
// standard_Name:string;//参照标准名称
// standard_Time:string;//标准推行时间
// dev_Level:string;//使用设备等级
// enable:number;//状态0-不启用 1-启用
// state:number;//0-删除 1-正常
// };
// }>();
const emit = defineEmits<{
(e: 'update:visible', value: boolean): void;
(e: 'submit', data: any): void;
}>();
// const emit = defineEmits<{
// (e: 'update:visible', value: boolean): void;
// (e: 'submit', data: any): void;
// }>();
const checkStore = useCheckStore();
const skipDisabled = ref(false);
const nextStepText = ref('下一步');
const dialogVisible = ref(false)
//定义与预检测配置数组
const detectionOptions = ref([
{
@@ -117,13 +139,170 @@ const detectionOptions = ref([
// },
]);
const stepsTotalNum = ref(5);//步骤总数
const stepsTotalNum = ref(4);//步骤总数
const stepsActiveIndex = ref(0); //当前正在执行的步骤索引
const ActiveStatue = ref('waiting');//当前步骤状态
const preTestStatus = ref('waiting');//预检测执行状态
const timeTestStatus = ref('waiting');//守时校验执行状态
const channelsTestStatus = ref('waiting');//通道系数校准执行状态
const TestStatus = ref('waiting');//正式检测执行状态
const webMsgSend = ref();//webSocket推送的数据
const dialogTitle = ref('');
const isTimeCheck = ref(false)
const preTestRef = ref(null);
const testRef = ref(null);
// const devIdArr = ref([])
// const planId = ref('')
// 打开弹窗,可能是新增,也可能是编辑
const open = (selection: Device.ResPqDev[],title: string,time:boolean) => {
const checkStates = selection.map(item => item.checkState);
// devIdArr.value = selection.map(item => item.id);
// planId.value =selection[0].planId
// console.log('wwwwwwwwwwwwwwwww',selection)
const allCheckStatesEqual = new Set(checkStates).size <= 1;
if (!allCheckStatesEqual) {
ElMessageBox.confirm(
'所勾选设备检测状态不一致,请重新选择',
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
return
}
dialogTitle.value = title;
dialogVisible.value = true;
isTimeCheck.value = time
if (preTestRef.value) {
preTestRef.value.initializeParameters();
}
preTestStatus.value = 'waiting';//预检测执行状态
//开始创建webSocket客户端
const data = reactive({
socketServe: socketClient.Instance,
});
const url = 'ws://localhost:7777/hello?name=cdf';
socketClient.Instance.connect(url);
data.socketServe = socketClient.Instance;
data.socketServe.registerCallBack('aaa', (res) => {
// 处理来自服务器的消息
console.log('Received message:', res);
// 根据需要在这里添加更多的处理逻辑
if(res.code === 20000){
ElMessage.error(message.message)
loading.close()
}else {
webMsgSend.value = res
}
});
}
let loading;
const handleSubmit = () => {
skipDisabled.value = true
console.log('=============',stepsActiveIndex.value)
let deviceIds = checkStore.devices.map((item) => item.deviceId)
let planId = checkStore.planId
switch (stepsActiveIndex.value) {
case 0:
preTestStatus.value = 'start'
/* loading = ElLoading.service({
lock: true,
text: '',
background: 'rgb(255, 255, 255, 0)',
})*/
startPreTest({
userPageId: "cdf",
devIds:deviceIds,
planId:planId,
operateType:'0' // '0'为预检测、1为正式检测
}).then(res=>{
})
break;
case 1:
timeTestStatus.value = 'start'
break;
// case 2:
// channelsTestStatus.value = 'start'
// break;
case 2:
if (TestStatus.value == "waiting") {
// startTest({
// userPageId: "cdf",
// devIds:deviceIds,
// planId:planId,
// operateType:'1' // '0'为预检测、1为正式检测
// }).then(res => {
// console.log(res)
// if (res.code === 20000) {
// TestStatus.value = 'start'
// webMsgSend.value = ''
// } else {
// ElMessage.error(res.message)
// }
// })
TestStatus.value = 'start'
} else if (TestStatus.value == 'process') {
// 发送暂停指令
// pauseTest({deviceIds}).then(res => {
// console.log(res)
// if (res.code === 20000) {
// TestStatus.value = 'paused'
// webMsgSend.value = ''
// } else {
// ElMessage.error(res.message)
// }
// })
TestStatus.value = 'paused'
} else if (TestStatus.value == 'paused') {
// 发送继续指令
// resumeTest({deviceIds}).then(res => {
// console.log(res)
// if (res.code === 20000) {
// TestStatus.value = 'process'
// webMsgSend.value = ''
// } else {
// ElMessage.error(res.message)
// }
// })
TestStatus.value = 'process'
}
break;
default:
break;
}
};
watch(preTestStatus,function(newValue,oldValue){
console.log(newValue,oldValue);
@@ -148,8 +327,9 @@ const detectionOptions = ref([
watch(ActiveStatue,function(newValue,oldValue){
if(newValue === 'success' || newValue === 'error')
skipDisabled.value = false
if(newValue === 'success' || newValue === 'error'){
skipDisabled.value = false
}
if(newValue === 'success' && stepsActiveIndex.value === stepsTotalNum.value - 2)
{
@@ -157,8 +337,22 @@ const detectionOptions = ref([
stepsActiveIndex.value++;
nextStepText.value = '检测完成'
}
if(newValue === 'preTest_fail' && stepsActiveIndex.value === stepsTotalNum.value - 2)
{
stepsActiveIndex.value++;
stepsActiveIndex.value++;
nextStepText.value = '预检测失败'
}
})
const sendPause = () => {
console.log('发送暂停指令')
}
const sendResume = () => {
console.log('发送继续检测指令')
}
const getIcon = (index: number) => {
if (stepsActiveIndex.value > index) return SuccessFilled;
switch (index) {
@@ -175,13 +369,17 @@ const getIcon = (index: number) => {
if(stepsActiveIndex.value < stepsTotalNum.value )
{
stepsActiveIndex.value++
if(!isTimeCheck.value){//不具备守时检测,预检测后直接跳正式检测
stepsActiveIndex.value++
}
ActiveStatue.value = 'waiting'
}
else if(stepsActiveIndex.value === stepsTotalNum.value)
{
emit('update:visible', false); // 关闭对话框
//emit('update:visible', false); // 关闭对话框
clearData()
dialogVisible.value = false;
}
};
@@ -191,6 +389,8 @@ const getIcon = (index: number) => {
timeTestStatus.value = "waiting"
channelsTestStatus.value = "waiting"
TestStatus.value = "waiting"
ActiveStatue.value = "waiting"
skipDisabled.value = false
nextStepText.value = "下一步"
}
const beforeClose = (done: () => void) => {
@@ -208,14 +408,16 @@ const getIcon = (index: number) => {
)
.then(() => {
clearData()
emit('update:visible', false); // 关闭对话框
// todo 关闭弹窗,终止整个检测流程
//emit('update:visible', false); // 关闭对话框
dialogVisible.value = false;
})
}
else
{
clearData()
emit('update:visible', false); // 关闭对话框
//emit('update:visible', false); // 关闭对话框
dialogVisible.value = false;
}
// ElMessageBox.confirm('Are you sure to close this dialog?')
// .then(() => {
@@ -228,62 +430,21 @@ const getIcon = (index: number) => {
const handleCancel = () => {
// clearData()
// emit('update:visible', false); // 关闭对话框
testRef.value?.clear()
};
const handleSubmit = () => {
skipDisabled.value = true
switch (stepsActiveIndex.value) {
case 0:
preTestStatus.value = 'start'
break;
case 1:
timeTestStatus.value = 'start'
break;
case 2:
channelsTestStatus.value = 'start'
break;
case 3:
TestStatus.value = 'start'
break;
default:
break;
}
};
// 当 props.visible 改变时,更新 formData
watch(() => props.visible, (newVal) => {
if (!newVal) {
// 这里可以重置表单数据,如果需要的话
}
});
//选中
// 处理选择变化
const handleSelectionChange = (selection: any[]) => {
multipleSelection.value = selection.map(row => row.id); // 更新选中的行
};
const openAddDialog = () => {
tableData.value.push({
id: tableData.value.length + 1,
type: '',
startSelect: '',
startRange: '',
endSelect: '',
endRange: '',
unit:'',
maxErrorValue:'',
errorType:''
});
};
// // 当 props.visible 改变时,更新 formData
// watch(() => props.visible, (newVal) => {
// if (!newVal) {
// // 这里可以重置表单数据,如果需要的话
// }
// });
// 对外映射
defineExpose({ open })
</script>
<style scoped lang="scss">

View File

@@ -1,8 +1,37 @@
<template>
<div>
<div class = "test-dialog">
<div class="dialog-left">
<el-timeline style="max-width: 600px">
<div>
<el-tabs type="border-card">
<el-tab-pane label="守时误差">
<div class="right-title" >
<span v-if="activeIndex <= 1"> </span>
<span v-if="activeIndex > 1" style=" font-size: 18px;font-weight: 600;">
标准时间: <span style="color: #003078">{{ gpsTime }}</span>
</span>
<div class="error-dsc">
<div class="green-div"></div>
<span style=" color: #606266; font-size: 16px;font-weight: 600;">
合格1000ms
</span>
<div class="red-div"></div>
<span style=" color: #F56C6c; font-size: 16px;font-weight: 600;">
不合格>1000ms
</span>
</div>
</div>
</el-tab-pane>
</el-tabs>
<div class="test-dialog">
<div class="dialog-left">
<el-steps direction="vertical" :active="stepsIndex" :process-status="currentStepStatus"
finish-status="success">
<el-step title="开始检测" />
<el-step title="触发设备检测GPS时刻的标准时间"/>
<el-step title="设备开始上送"/>
<el-step title="设备结束上送"/>
<el-step title="检测完成"/>
</el-steps>
<!-- <el-timeline style="max-width: 600px">
<el-timeline-item
v-for="(activity, index) in activities"
:key="index"
@@ -15,38 +44,81 @@
>
{{ activity.content }}
</el-timeline-item>
</el-timeline>
</div>
<div class="dialog-right">
</el-timeline> -->
</div>
<div class="dialog-right">
<div class="right-title">
<!-- <div>设备上送时刻表</div> -->
<div>
<el-button type="primary" loading v-if="activeIndex > 0 && activeIndex < activeTotalNum">设备已合格3台/共4台</el-button>
<el-button type="primary" disabled="true" v-if="activeIndex === activeTotalNum">设备已合格3台/共4台</el-button>
</div>
<!-- <div>设备上送时刻表</div> -->
<!-- <span v-if="activeIndex <= 1"> </span>
<span v-if="activeIndex > 1" style=" font-size: 18px;font-weight: 600;">
标准时间: <span style="color: #003078">{{ gpsTime }}</span>
</span>
<div class="error-dsc">
<div class="green-div"></div>
<span style=" color: #606266; font-size: 16px;font-weight: 600;">
守时误差1000ms
</span>
<div class="red-div"></div>
<span style=" color: #F56C6c; font-size: 16px;font-weight: 600;">
守时误差>1000ms
</span>
</div> -->
<!-- <span style=" font-size: 18px;font-weight: 600;">
设备已合格 <span style="color: #67C23A">{{ qualified }}</span> / <span style="color: green">4</span>
</span> -->
<!-- <el-button type="primary" loading v-if="activeIndex > 0 && activeIndex < activeTotalNum">设备已合格3台/共4台</el-button>
<el-button type="primary" disabled="true" v-if="activeIndex === activeTotalNum">设备已合格3台/共4台</el-button> -->
</div>
<div class="right-content">
<el-table :data="deviceOperatorData" stripe :header-cell-style="{ textAlign: 'center' } " :cell-style="{ textAlign: 'center' }" style="width: 100%" border>
<el-table-column prop="deviceName" label="设备名" />
<div class="right-content table-main">
<el-empty description="暂无数据,等待检测开始" v-if="activeIndex === 0" />
<!-- <ProTable v-if="activeIndex > 0" ref='proTable' :pagination='false' :toolButton='false' :showCard='false' :columns='columns'
:data='deviceOperatorData' stripe :header-cell-style="{ textAlign: 'center' }"
:cell-style="{ textAlign: 'center' }" style="width: 100%; height:435px" border>
</ProTable> -->
<el-table v-if="activeIndex > 0" :data="deviceOperatorData" stripe :header-cell-style="{ textAlign: 'center' } " :cell-style="{ textAlign: 'center' }" style="margin-top: -30px;width: 100%" border>
<el-table-column prop="deviceName" label="设备名称" />
<el-table-column prop="updataTime" label="上送时刻" />
<el-table-column prop="ErrorValue" label="守时误差(ms)" />
<el-table-column prop="Result" label="检测结果">
<template #default="scope">
<el-tag :type="scope.row.Result === '合格' ? 'success' : 'danger'">{{ scope.row.Result }}</el-tag>
</template>
<el-table-column prop="ErrorValue" label="守时误差(ms)">
<!-- <template #header>
<span>守时误差(ms)</span>
<el-tooltip content = "守时误差 = |设备上送时间 - 标准时间|最大显示值为9999毫秒超过该值的统一用ErrorMax来表示" placement="top" style="align-items: bottom;">
<el-icon><InfoFilled /></el-icon>
</el-tooltip>
</template> -->
</el-table-column>
</el-table>
<el-table-column prop="Result" label="检测结果">
<!-- <template #header>
<span>检测结果</span>
<el-tooltip content = "守时误差小于等于1000毫秒为合格否则不合格" placement="top" style="align-items: bottom;">
<el-icon><InfoFilled /></el-icon>
</el-tooltip>
</template> -->
<template #default="scope">
<el-tag v-if="scope.row.Result === '不合格'" type="danger">{{ scope.row.Result }}</el-tag>
<span v-if="scope.row.Result != '不合格'">{{scope.row.Result}}</span>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="tsx" setup name="timeTest">
import { SuccessFilled } from '@element-plus/icons-vue'
const stepsIndex = ref(0)
const activeIndex = ref(0)
const activeTotalNum = ref(5)
const activeTotalNum = ref(7)
const startTime = ref('')
const gpsTime = ref('')
const devStartTime = ref('')
const devEndTime = ref('')
const finishTime = ref('')
interface Activity {
content: string;
@@ -56,6 +128,7 @@ interface Activity {
color?: string;
icon?: any;
}
const qualified = ref(0)
const activities = ref<Activity[]>([
{
content: '开始检测',
@@ -63,182 +136,267 @@ const activities = ref<Activity[]>([
},])
const deviceOperatorData = ref([
{
deviceName: '被检设备1',
updataTime: '—',
ErrorValue:'—',
Result: '—',
},
{
deviceName: '被检设备2',
updataTime: '—',
ErrorValue:'—',
Result: '—',
},
{
deviceName: '被检设备3',
updataTime: '—',
ErrorValue:'—',
Result: '—',
},
{
deviceName: '被检设备4',
updataTime: '—',
ErrorValue:'—',
Result: '—',
},
])
const deviceOperatorData = ref([])
const deviceData = ref([
{
deviceName: '被检设备1',
updataTime: '10:30:08.136',
ErrorValue:'148',
Result: '合格',
},
{
deviceName: '被检设备2',
updataTime: '10:30:08.136',
ErrorValue:'136',
Result: '合格',
},
{
deviceName: '被检设备3',
updataTime: '10:30:09.006',
ErrorValue:'1006',
Result: '不合格',
},
{
deviceName: '被检设备4',
updataTime: '10:30:08.736',
ErrorValue:'736',
Result: '合格',
},
])
const deviceData = ref([
{
deviceName: '240001',
updataTime: '2024-12-05 10:30:08.136',
ErrorValue: '148',
Result: '合格',
},
{
deviceName: '240002',
updataTime: '2024-12-05 10:30:08.136',
ErrorValue: '136',
Result: '合格',
},
{
deviceName: '240003',
updataTime: '2024-12-05 10:30:09.006',
ErrorValue: '1006',
Result: '不合格',
},
{
deviceName: '240004',
updataTime: '2024-12-05 10:30:08.736',
ErrorValue: '736',
Result: '合格',
},
])
const currentStepStatus = ref<'error' | 'finish' | 'wait' | 'success' | 'process'>('finish');
const props = defineProps({
testStatus: {
const props = defineProps({
testStatus: {
type: String,
default: 'wait'
}
})
const testStatus = toRef(props, 'testStatus');
const ts = ref('');
// 表格配置项
const columns = reactive([
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
{
prop: 'deviceName',
label: '设备名称',
},
{
prop: 'updataTime',
label: '上送时刻',
// width: 230,
},
{
prop: 'ErrorValue',
label: '守时误差ms',
// width: 100,
},
{
prop: 'Result',
label: '检测结果',
// width: 100,
render: (scope) => {
if (scope.row.Result === '不合格') {
return (
<el-tag type='danger'>{scope.row.Result}</el-tag>
)
}
else {
return (
<span>{scope.row.Result}</span>
)
}
},
},
])
//监听testStatus的变化
watch(testStatus, function (newValue, oldValue) {
ts.value = props.testStatus;
if(ts.value==='start')
{
if (ts.value === 'start') {
ts.value = 'process'
let timer = setInterval(() => {
if(activeIndex.value < activeTotalNum.value - 2)
activeIndex.value++
else if(activeIndex.value === activeTotalNum.value -2)
{
activeIndex.value++
activeIndex.value++
}
else
{
clearInterval(timer)
ts.value = 'success'
}
}, 1000);
if (activeIndex.value < activeTotalNum.value)
activeIndex.value++
// else if (activeIndex.value === activeTotalNum.value - 2) {
// activeIndex.value++
// activeIndex.value++
// }
else {
clearInterval(timer)
ts.value = 'success'
}
}, 1000);
}
})
function formatDateTime(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
}
function addMillisecondsToDate(dateString: string, millisecondsToAdd: number): Date {
// 解析字符串为 Date 对象
const [datePart, timePart] = dateString.split(' ');
const [year, month, day] = datePart.split('-').map(Number);
const [hours, minutes, seconds, milliseconds] = timePart.split(':').flatMap(part => part.split('.')).map(Number);
// 创建 Date 对象(注意:月份是从 0 开始的)
const date = new Date(year, month - 1, day, hours, minutes, seconds, milliseconds);
// 增加指定的毫秒数
date.setMilliseconds(date.getMilliseconds() + millisecondsToAdd);
return date;
}
watch(activeIndex, function (newValue, oldValue) {
if(activeIndex.value === 1)
{
activities.value.length = 0;
activities.value.push({
content: '开始检测',
timestamp: '2018-04-12 20:46',
size: 'large',
color: '#0bbd87',
icon: SuccessFilled,
});
}
if(activeIndex.value === 2)
{
activities.value.push({
content: 'GPS上送时刻',
timestamp: '2018-04-03 20:46',
color: '#0bbd87',
icon: SuccessFilled,
size: 'large',
});
}
if(activeIndex.value === 3)
{
activities.value.push({
content: '设备最早上送时刻',
timestamp: '2018-04-03 20:46',
color: '#0bbd87',
icon: SuccessFilled,
size: 'large',
});
console.log(activeIndex.value,111,stepsIndex.value,222)
if (activeIndex.value === 1) {
startTime.value = formatDateTime(new Date());
stepsIndex.value = 1;
// activities.value.length = 0;
// activities.value.push({
// content: '开始检测',
// timestamp: '2018-04-12 20:46',
// size: 'large',
// color: '#0bbd87',
// icon: SuccessFilled,
// });
}
if (activeIndex.value === 2) {
stepsIndex.value = 2;
gpsTime.value = formatDateTime(new Date());
// activities.value.push({
// content: 'GPS上送时刻',
// timestamp: '2018-04-03 20:46',
// color: '#0bbd87',
// icon: SuccessFilled,
// size: 'large',
// });
}
if (activeIndex.value === 3) {
stepsIndex.value = 3;
deviceOperatorData.value.length = 0;
// deviceOperatorData.value = deviceData.value;
deviceOperatorData.value.push({
deviceName: '240002',
updataTime: formatDateTime(addMillisecondsToDate(gpsTime.value, 136)),
ErrorValue: '136',
Result: '合格',
});
}
if (activeIndex.value === 4) {
deviceOperatorData.value.push({
deviceName: '240001',
updataTime: formatDateTime(addMillisecondsToDate(gpsTime.value, 148)),
ErrorValue: '148',
Result: '合格',
});
}
if (activeIndex.value === 5) {
deviceOperatorData.value.push({
deviceName: '240004',
updataTime: formatDateTime(addMillisecondsToDate(gpsTime.value, 736)),
ErrorValue: '736',
Result: '合格',
});
}
if (activeIndex.value === 6) {
stepsIndex.value = 5;
deviceOperatorData.value.push({
deviceName: '240003',
updataTime: formatDateTime(addMillisecondsToDate(gpsTime.value, 1006)),
ErrorValue: '1006',
Result: '不合格',
});
}
deviceOperatorData.value.length = 0;
deviceOperatorData.value = deviceData.value;
}
if(activeIndex.value > 3)
{
activities.value.push({
content: '设备最晚上送时刻',
timestamp: '2018-04-03 20:46',
color: '#0bbd87',
icon: SuccessFilled,
size: 'large',
});
activities.value.push({
content: '检测结束',
timestamp: '2018-04-03 20:46',
color: '#0bbd87',
icon: SuccessFilled,
size: 'large',
});
}
})
const emit = defineEmits(['update:testStatus']);
//监听sn
watch(ts, function (newValue, oldValue) {
//修改父组件
emit('update:testStatus',ts.value)
emit('update:testStatus', ts.value)
})
</script>
<style scoped>
.test-dialog{
display: flex;
flex-direction: row; /* 横向排列 */
margin-top: 20px;
min-height: 300px;
/* .dialog-left{
.test-dialog {
height: 350px;
display: flex;
flex-direction: row;
/* 横向排列 */
margin-top: 20px;
/* .dialog-left{
margin-right: 20px;
} */
}
.dialog-left{
margin-left: 20px;
width: 20%;
}
.dialog-right{
margin-top: 25px;
margin-left: 20px;
width: 80%;
}
.right-title{
display: flex;
flex-direction: row; /* 横向排列 */
justify-content: flex-end;
margin-bottom: 10px;
}
/* width: 100%;
.dialog-left {
margin-left: 20px;
width: 20%;
}
.dialog-right {
/* margin-top: 25px;
margin-left: 20px; */
width: 80%;
}
.right-title {
height: 32px;
display: flex;
flex-direction: row;
/* 横向排列 */
justify-content: space-between;
/* margin-bottom: 10px; */
}
.error-dsc{
display: flex;
flex-direction: row;
justify-content: center;
align-items: baseline;
}
.green-div{
width: 20px;
height: 14px;
border-radius: 4px;
background-color: #606266;
margin-left: 5px;
margin-right: 5px;
}
.red-div{
width: 20px;
height: 14px;
border-radius: 4px;
background-color: #F56C6C;
margin-left: 5px;
margin-right: 5px;
}
.right-content{
height: 440px;
}
/* width: 100%;
height: auto;
background: #fff;
border-radius: 4px;

View File

@@ -15,6 +15,7 @@
:filter-node-method='filterNode'
:props='defaultProps'
node-key='id'
class="filter-tree"
default-expand-all
:default-checked-keys='defaultChecked'
@node-click='handleNodeClick'
@@ -22,7 +23,7 @@
<template #default='{ node, data }'>
<span class='custom-tree-node' style='display: flex;align-items: center;'>
<Platform v-if='!data.pid' style='width:18px;height: 18px;margin-right:8px;'
:style="{color:node.label=='未检'?'#F56C6C':node.label=='检测中'?'#E6A23C':'#67C23A'}" />
:style="{color:node.label=='未检'?'#F56C6C':node.label=='检测中'?'#E6A23C':'#67C23A'}" />
<span>{{ node.label }}</span>
<!-- <Menu v-if="data.pid" @click.stop="detail(data)" style="width: 12px;margin-left: 8px;"/> -->
</span>
@@ -32,10 +33,15 @@
</div>
</template>
<script lang='ts' setup>
import { type Plan } from '@/api/plan/interface';
import { Menu, Platform, CircleCheck,Loading } from '@element-plus/icons-vue'
import { onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router'
import {useCheckStore} from "@/stores/modules/check";
const router = useRouter()
const checkStore = useCheckStore()
const data: any = ref([])
const defaultProps = {
children: 'children',
@@ -45,11 +51,15 @@ const defaultProps = {
const searchForm = ref({
planName: '',
})
const defaultChecked = ref([])
const defaultChecked = ref<number[]>([]) // 明确类型为 number[]
const getTreeData = (val: any) => {
defaultChecked.value = []
data.value = val
defaultChecked.value.push(data.value[0].children[0].id)
if (data.value.length > 0 && data.value[0].children.length > 0) {
defaultChecked.value.push(data.value[0].children[0].id as number)
}
checkStore.setPlanId(defaultChecked.value[0])
checkStore.setPlanCode(data.value[0].code)
}
const filterText = ref('')
const treeRef = ref()
@@ -65,11 +75,13 @@ watch(
deep: true,
},
)
const handleNodeClick = (data) => {
// console.log(data)
updateSelectedTreeNode()
const handleNodeClick = (data: Plan.ResPlan) => {
checkStore.setPlanId(data.id)
checkStore.setPlanCode(data.code)
checkStore.setScriptId(data.scriptId)
updateSelectedTreeNode(data.id)
}
const filterNode = (value: string, data) => {
const filterNode = (value: string, data: any) => {
if (!value) return true
return data.name.includes(value)
}
@@ -85,7 +97,7 @@ defineExpose({ getTreeData })
<style lang='scss' scoped>
.plan_tree {
// width: 200px;
// height: 100%;
height: 100%;
display: flex;
flex-direction: column;
padding: 5px;
@@ -112,13 +124,50 @@ defineExpose({ getTreeData })
}
.tree_container {
height: 100%;
width: 100%;
flex: 1;
overflow-y: auto;
overflow-x: auto;
.el-tree {
height: 100%;
width: 100%;
// height: 100%;
width: auto;
}
}
}
.filter-tree {
// border: 1px solid #dcdfe6;
min-width: 100%;
height: 97%;
display: inline-block;
overflow: auto;
margin-top: 12px;
}
//.filter-tree span {
// font-size: 16px;
// display:block;
// overflow:hidden;
// word-break:keep-all;
// white-space:nowrap;
// text-overflow:ellipsis;
// padding-right: 12px;
//}
.leftBox {
// float: left;
// width: 20%;
height: 100%;
width: 100%;
}
.left {
height: calc(100% - 45px);
overflow: auto;
}
/* 设置滚动条宽度 */
:deep(.bodyTwo ::-webkit-scrollbar) {
width: 3px !important;
height: 6px !important;
}
</style>

View File

@@ -81,7 +81,8 @@ const handleSelect = (key: string, keyPath: string[]) => {
//console.log(key, keyPath);
};
onMounted(() => {
//console.log();
//console.log(111);
});
</script>
<style lang="scss" scoped>

View File

@@ -9,16 +9,16 @@
<!-- 功能选择 -->
<div class="container_function">
<div
class="function_item"
:class="
class="function_item"
:class="
item.checked ? 'function_item checked_function' : 'function_item'
"
v-for="(item, index) in tabsList"
:key="index"
@click="handleCheckFunction(item.value)"
v-for="(item, index) in tabsList"
:key="index"
@click="handleCheckFunction(item.value)"
>
<div class="item_img">
<img :src="item.img" alt="" />
<img :src="item.img" alt=""/>
</div>
<div class="item_text">
<p>{{ item.label }}</p>
@@ -26,92 +26,112 @@
</div>
</div>
<!-- <el-collapse v-model="activeNames" @change="handleChange">
<el-collapse-item title="检测进度展示" name="1"> -->
<div class="container_pieShow">
<!-- <el-collapse v-model="activeNames" @change="handleChange">
<el-collapse-item title="检测进度展示" name="1"> -->
<div class="container_pieShow">
<el-collapse model-value="1" accordion @change="handleCollapseChange">
<el-collapse-item title="&nbsp&nbsp&nbsp&nbsp检测进度展示" name="1">
<!-- 饼图 -->
<div class="container_charts">
<div class="charts_info">
<pie
:customData="{
<el-collapse-item name="1">
<template #title>
<div style="display: flex; justify-content: space-between; width: 100%;">
<span style="font-weight: bold;margin-left: 15px;">检测计划统计</span>
<span style="font-weight: bold;margin-right: 15px;">{{ planName }}</span>
</div>
</template>
<!-- 饼图 -->
<div class="container_charts">
<div class="charts_info" ref="chartsInfoRef">
<pie
:customData="{
title: '设备检测状态',
textAlign: 'right',
textAlign: 'left',
}"
:legendData="{
:legendData="{
icon: 'circle',
left: 'left',
top: 'bottom',
}"
:chartsData="chartsData1"
ref="pieRef1"
></pie>
</div>
<div class="charts_info">
<pie
:customData="{
:chartsData="chartsData1"
ref="pieRef1"
></pie>
</div>
<div class="charts_info">
<pie
:customData="{
title: '设备检测结果',
textAlign: 'right',
textAlign: 'left',
}"
:legendData="{
:legendData="{
icon: 'circle',
left: 'left',
top: 'bottom',
}"
:chartsData="chartsData2"
ref="pieRef2"
></pie>
</div>
<div class="charts_info">
<pie
:customData="{
:chartsData="chartsData2"
ref="pieRef2"
></pie>
</div>
<div class="charts_info">
<pie
:customData="{
title: '设备报告状态',
textAlign: 'right',
textAlign: 'left',
label: {
normal: {
position: 'inner',
},
},
}"
:legendData="{
:legendData="{
icon: 'circle',
left: 'left',
top: 'bottom',
}"
:chartsData="chartsData3"
ref="pieRef3"
></pie>
</div>
</div>
</el-collapse-item>
:chartsData="chartsData3"
ref="pieRef3"
></pie>
</div>
</div>
</el-collapse-item>
</el-collapse>
</div>
<el-tabs class="tabs-menu" type="border-card" @tab-change="handleTabsChange" v-model="editableTabsValue" :style="{ height: tabsHeight }">
<el-tab-pane :label="tabLabel1" :style="{ height: tabPaneHeight }">
<!-- 列表数据 -->
<div class="container_table" :style="{ height: tableHeight }">
<Table ref="tableRef1"></Table>
</div>
</el-tab-pane>
<el-tab-pane label="已检设备" v-if="tabShow" :style="{ height: tabPaneHeight }">
<!-- 列表数据 -->
<div class="container_table" :style="{ height: tableHeight }">
<Table ref="tableRef2"></Table>
</div>
</el-tab-pane>
</el-tabs>
</div>
<el-tabs class="tabs-menu" type="border-card" @tab-change="handleTabsChange" v-model="editableTabsValue" :style="{ height: tabsHeight }">
<el-tab-pane :label="tabLabel1" :style="{ height: tabPaneHeight }">
<!-- 列表数据 -->
<div class="container_table" :style="{ height: tableHeight }">
<Table ref="tableRef1" :id='currentId' :isTimeCheck='isTimeCheck'></Table>
</div>
</el-tab-pane>
<!-- <el-tab-pane label="已检设备" v-if="tabShow" :style="{ height: tabPaneHeight }">-->
<!-- &lt;!&ndash; 列表数据 &ndash;&gt;-->
<!-- <div class="container_table" :style="{ height: tableHeight }">-->
<!-- <Table ref="tableRef2" :id='currentId'></Table>-->
<!-- </div>-->
<!-- </el-tab-pane>-->
</el-tabs>
</div>
</div>
</template>
<script lang="ts" setup>
import { getStaticTreeData } from "@/api/plan/static";
import pie from "@/components/echarts/pie/default.vue";
import { useRouter } from "vue-router";
import {useRouter} from "vue-router";
import tree from "../components/tree.vue";
import Table from "../components/table.vue";
import { data } from "@/api/plan/static.json";
//import { data } from "@/api/plan/static.json";
import deviceDataList from '@/api/device/device/deviceData'
import {getBoundPqDevList, getPlanListByPattern} from '@/api/plan/plan.ts'
import {onBeforeMount, onUnmounted, ref, watch} from "vue";
import {useModeStore} from '@/stores/modules/mode'; // 引入模式 store
import {useDictStore} from '@/stores/modules/dict'
import {type Plan} from "@/api/plan/interface";
import type {CollapseModelValue} from "element-plus/es/components/collapse/src/collapse.mjs";
import {type Device} from "@/api/device/interface/device";
import {ResultData} from "@/api/interface";
const planName = ref('')
const dictStore = useDictStore()
const modeStore = useModeStore();
const chartsInfoRef = ref<HTMLElement | null>(null);
const chartsWidth = ref<number>(0);
const deviceData = deviceDataList.plan_devicedata
const treeRef = ref();
const form: any = ref({
@@ -126,23 +146,27 @@ const form: any = ref({
});
const router = useRouter();
const activeNames = ref(['2'])
const tabShow= ref(false);
const tabShow = ref(false);
const tabLabel1 = ref('设备检测')
const editableTabsValue = ref('0')
const checkStateTable = ref<number[]>([0, 1, 2])
const tabsHeight = ref('calc(100vh - 538px)'); // 初始高度
const tabPaneHeight = ref('calc(100% - 5px)'); // 初始高度
const tableHeight = ref('calc(100% - 5px)'); // 初始高度
const handleChange = (val: string[]) => {
// console.log(val)
}
const isTimeCheck = ref<boolean>(false);
const planList = ref<ResultData<Plan.ReqPlan[]>>();
const handleCollapseChange = (val: CollapseModelValue) => {
const handleCollapseChange = (val: string[]) => {
console.log(val)
console.log(val.length)
// 计算新的高度
const newHeight = val.length > 0 ? 'calc(100vh - 538px)' : 'calc(100vh - 333px)';
let newHeight;
if (Array.isArray(val)) {
newHeight = val.length > 0 ? 'calc(100vh - 538px)' : 'calc(100vh - 333px)';
} else {
newHeight = val ? 'calc(100vh - 538px)' : 'calc(100vh - 333px)';
}
//const newtableHeight= val.length > 0 ? 'calc(100vh - 638px)' : 'calc(100vh - 433px)';
tabsHeight.value = newHeight;
tabPaneHeight.value = `calc(100% - 5px)`;
@@ -152,11 +176,10 @@ const handleCollapseChange = (val: string[]) => {
// tableRef2.value.resize();
};
const handleTabsChange = (val) => {
const handleTabsChange = (val: any) => {
form.value.activeTabs = 0;
form.value.activeTabs = 3;
form.value.activeChildTabs = Number(val);
console.log(val)
}
localStorage.setItem("color", "red");
@@ -181,114 +204,149 @@ const tabsList = ref([
checked: false,
},
{
label: "数据查询",
label: "设备归档",
value: 4,
img: "/src/assets/images/plan/static/4.svg",
checked: false,
},
{
label: "数据操作",
value: 5,
img: "/src/assets/images/plan/static/5.svg",
checked: false,
},
// {
// label: "设备归档",
// value: 4,
// img: "/src/assets/images/plan/static/4.svg",
// checked: false,
// },
]);
form.value.activeTabs = tabsList.value[0].value;
const tableRef1 = ref();
const tableRef2 = ref();
const currentId = ref('');
watch(
() => form.value,
(val, oldVal) => {
if (val) {
() => form.value,
(val, oldVal) => {
if (val) {
console.log(form.value.activeTabs,111);
if(form.value.activeTabs === 0 || form.value.activeTabs === 4)//设备检测、设备归档
if (form.value.activeTabs === 0)//设备检测
{
const tabledata = deviceData.filter((item) => item.document_State === "未归档")
tableRef1.value && tableRef1.value.changeActiveTabs(form.value.activeTabs, form.value.activeChildTabs, tabledata);
} else if (form.value.activeTabs === 4)//设备归档
{
const tabledata = deviceData.filter((item) => item.check_State === "检测完成" && item.document_State === "未归档")
tableRef1.value && tableRef1.value.changeActiveTabs(form.value.activeTabs, form.value.activeChildTabs, tabledata);
} else if (form.value.activeTabs === 3 || form.value.activeTabs === 5)//报告生成、数据查询
{
const tabledata = deviceData.filter((item) => item.check_State === "检测完成");
tableRef1.value && tableRef1.value.changeActiveTabs(form.value.activeTabs, form.value.activeChildTabs, tabledata);
}
}
},
{
const tabledata = deviceData.filter((item) => item.document_State === "未归档")
tableRef1.value && tableRef1.value.changeActiveTabs(form.value.activeTabs,form.value.activeChildTabs,tabledata);
immediate: true,
deep: true,
}
else if(form.value.activeTabs === 3 || form.value.activeTabs === 5)//报告生成、数据查询
{
const tabledata = deviceData.filter((item) => item.check_State === "检测完成");
tableRef1.value && tableRef1.value.changeActiveTabs(form.value.activeTabs,form.value.activeChildTabs,tabledata);
}
}
},
{
immediate: true,
deep: true,
}
);
watch(
() => form.value,
(val, oldVal) => {
if (val) {
tableRef2.value && tableRef2.value.changeActiveTabs(form.value.activeTabs,form.value.activeChildTabs);
console.log(form.value.activeTabs,form.value.activeChildTabs);
() => form.value,
(val, oldVal) => {
if (val) {
tableRef2.value && tableRef2.value.changeActiveTabs(form.value.activeTabs, form.value.activeChildTabs);
}
},
{
immediate: true,
deep: true,
}
},
{
immediate: true,
deep: true,
}
);
const pieRef1 = ref(),
pieRef2 = ref(),
pieRef3 = ref();
const changeSelect = () => {
console.log(form.value.activeTabs);
getPieData();
};
pieRef2 = ref(),
pieRef3 = ref();
const chartsData1: any = ref([]),
chartsData2: any = ref([]),
chartsData3: any = ref([]);
const getPieData = () => {
chartsData2: any = ref([]),
chartsData3: any = ref([]);
const findPlanById = (plans: Plan.ReqPlan[], id: string): Plan.ReqPlan | undefined => {
for (const plan of plans) {
if (plan.id === id) {
return plan;
}
if (plan.children) {
const foundPlan = findPlanById(plan.children, id);
if (foundPlan) {
return foundPlan;
}
}
}
return undefined;
};
const getPieData = async (id: string) => {
currentId.value = id; // 设置当前ID
//handleCheckFunction(0)//切换左侧树默认css功能是设备检测
// 初始化计数对象
const checkStateCount: { [key: number]: number } = {0: 0, 1: 0, 2: 0, 3: 0};
const checkResultCount: { [key: number]: number } = {0: 0, 1: 0, 2: 0};
const reportStateCount: { [key: number]: number } = {0: 0, 1: 0, 2: 0};
if (id) {
const boundPqDevList = ref<Device.ResPqDev[]>([])//根据检测计划id查询出所有已绑定的设备
const plan = findPlanById(planList.value?.data || [], id);
planName.value = '所选计划:' + plan.name
if (plan) {
//isTimeCheck.value = plan.timeCheck === 1; // 将 1 转换为 true0 转换为 false
isTimeCheck.value = false; // 将 1 转换为 true0 转换为 false ----目前不用守时检测,先去除
} else {
// 处理未找到计划的情况
isTimeCheck.value = false; // 或者其他默认值
}
const pqDevList_Result2 = await getBoundPqDevList({'planId': id, 'checkStateList': [0, 1, 2, 3]});
boundPqDevList.value = pqDevList_Result2.data as Device.ResPqDev[];
// 遍历 boundPqDevList 并更新计数对象
boundPqDevList.value.forEach(t => {
if (t.checkState !== undefined && t.checkState !== null && checkStateCount[t.checkState] !== undefined) {
checkStateCount[t.checkState]++;
}
});
boundPqDevList.value.forEach(t => {
if (t.checkResult !== undefined && t.checkResult !== null && checkResultCount[t.checkResult] !== undefined) {
checkResultCount[t.checkResult]++;
}
});
boundPqDevList.value.forEach(t => {
if (t.reportState !== undefined && t.reportState !== null && reportStateCount[t.reportState] !== undefined) {
reportStateCount[t.reportState]++;
}
});
}
chartsData1.value = [
{ value: Math.floor(Math.random() * 100) + 1, name: "未检", itemStyle: { color: '#fac858' } },
{ value: Math.floor(Math.random() * 100) + 1, name: "检测中", itemStyle: { color: '#ee6666' } },
{ value: Math.floor(Math.random() * 100) + 1, name: "检测完成", itemStyle: { color: '#91cc75' } },
{ value: Math.floor(Math.random() * 100) + 1, name: "归档", itemStyle: { color: '#5470c6' } },
{value: checkStateCount[0], name: "未检", itemStyle: {color: '#fac858'}},
{value: checkStateCount[1], name: "检测中", itemStyle: {color: '#ee6666'}},
{value: checkStateCount[2], name: "检测完成", itemStyle: {color: '#91cc75'}},
{value: checkStateCount[3], name: "归档", itemStyle: {color: '#5470c6'}},
];
chartsData2.value = [
{ value: Math.floor(Math.random() * 100) + 1, name: "未检" , itemStyle: { color: '#fac858' } },
{ value: Math.floor(Math.random() * 100) + 1, name: "有不合格项" , itemStyle: { color: '#ee6666' } },
{ value: Math.floor(Math.random() * 100) + 1, name: "全部合格", itemStyle: { color: '#91cc75' } },
{value: checkResultCount[2], name: "未检", itemStyle: {color: '#fac858'}},
{value: checkResultCount[0], name: "不符合", itemStyle: {color: '#ee6666'}},
{value: checkResultCount[1], name: "符合", itemStyle: {color: '#91cc75'}},
];
// pieRef2.value.init();
chartsData3.value = [
// { value: Math.floor(Math.random() * 100) + 1, name: "已生成报告" },
// { value: Math.floor(Math.random() * 100) + 1, name: "未生成报告" },
{ value: Math.floor(Math.random() * 100) + 1, name: "未检测" , itemStyle: { color: '#fac858' } },
{ value: Math.floor(Math.random() * 100) + 1, name: "未生成" , itemStyle: { color: '#ee6666' } },
{ value: Math.floor(Math.random() * 100) + 1, name: "已生成", itemStyle: { color: '#91cc75' } },
// { value: Math.floor(Math.random() * 100) + 1, name: "未检测" , itemStyle: { color: '#fac858' } },
// { value: Math.floor(Math.random() * 100) + 1, name: "有不合格项未生成报告" },
// { value: Math.floor(Math.random() * 100) + 1, name: "全部合格未生成报告" },
// { value: Math.floor(Math.random() * 100) + 1, name: "有不合格项已生成报告" },
// { value: Math.floor(Math.random() * 100) + 1, name: "全部合格已生成报告" },
{value: reportStateCount[2], name: "未检", itemStyle: {color: '#fac858'}},
{value: reportStateCount[0], name: "未生成", itemStyle: {color: '#ee6666'}},
{value: reportStateCount[1], name: "已生成", itemStyle: {color: '#91cc75'}},
];
// pieRef3.value.init();
pieRef1.value.init();
pieRef2.value.init();
pieRef3.value.init();
pieRef1.value.reSize(470,145,true);
pieRef2.value.reSize(470,145,true);
pieRef3.value.reSize(470,145,true);
// pieRef1.value.reSize(470,145,true);
// pieRef2.value.reSize(470,145,true);
// pieRef3.value.reSize(470,145,true);
};
const getTree = () => {
const getTree = (data?: any) => {
treeRef.value.getTreeData(data);
// getStaticTreeData({ userName: "zhangsan", planName: "111" }).then((res) => {
// console.log(res, "99999999");
// // treeRef.value.getTreeData(res.data);
// treeRef.value.getTreeData(data);
// });
};
//前往检测
const handleDetection = () => {
@@ -304,7 +362,6 @@ const planDetail = () => {
};
//功能选择css切换
const handleCheckFunction = (val: any) => {
editableTabsValue.value = '0';
form.value.activeChildTabs = 0;
tabsList.value.map((item: any, index: any) => {
@@ -319,34 +376,87 @@ const handleCheckFunction = (val: any) => {
switch (val) {
case 0://自动检测
tabLabel1.value = "设备检测";
break;
checkStateTable.value = [0, 1, 2]
tabLabel1.value = "设备检测";
break;
case 1://手动检测
tabLabel1.value = "手动检测";
break;
tabLabel1.value = "手动检测";
break;
case 2://设备复检
tabLabel1.value = "设备复检";
break;
tabLabel1.value = "设备复检";
break;
case 3://报告生成
tabLabel1.value = "报告生成";
//tabShow.value = true;
break;
checkStateTable.value = [2, 3]
tabLabel1.value = "报告生成";
//tabShow.value = true;
break;
case 4://设备归档
tabLabel1.value = "设备归档";
break;
checkStateTable.value = [2]
tabLabel1.value = "设备归档";
break;
case 5://数据查询
tabLabel1.value = "数据查询";
break;
checkStateTable.value = [2, 3]
tabLabel1.value = "数据查询";
break;
}
form.value.activeTabs = val;
};
onMounted(() => {
// console.log();
getTree();
getPieData();
const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
chartsWidth.value = entry.contentRect.width;
//console.log('Charts Info Width:', chartsWidth.value);
pieRef1.value?.reSize(chartsWidth.value * 0.95, 180, true);
pieRef2.value?.reSize(chartsWidth.value * 0.95, 180, true);
pieRef3.value?.reSize(chartsWidth.value * 0.95, 180, true);
}
});
onBeforeMount(async () => {
const patternId = dictStore.getDictData('Pattern').find(item => item.name === modeStore.currentMode)?.id ?? ''//获取数据字典中对应的id
const reqPlan: Plan.ReqPlan = {
pattern: patternId,
datasourceIds: "",
sourceIds: "",
planId: "",
scriptName: "",
errorSysName: "",
sourceName: "",
devIds: [],
id: "",
name: "",
dataSourceId: "",
scriptId: "",
errorSysId: "",
timeCheck: 0,
testState: 0,
reportState: 0,
result: 0,
code: 0,
state: 0
};
planList.value = (await getPlanListByPattern(reqPlan)) as ResultData<Plan.ReqPlan[]>;
if (planList.value.data[0].children[0]) {
currentId.value = planList.value.data[0].children[0].id;
}
if (chartsInfoRef.value) {
resizeObserver.observe(chartsInfoRef.value);
}
getTree(planList.value.data);
getPieData(currentId.value);
});
onUnmounted(() => {
if (chartsInfoRef.value) {
resizeObserver.unobserve(chartsInfoRef.value);
}
});
</script>
<style lang="scss" scoped>
.static {
@@ -355,7 +465,7 @@ onMounted(() => {
height: 100%;
display: flex;
justify-content: space-between;
//background-color: #eee;
//background-color: #eee;
.left_tree {
width: 14% !important;
@@ -401,6 +511,7 @@ onMounted(() => {
border-radius: 8px;
padding: 0px 30px;
margin-right: 50px;;
.item_img {
width: 60px;
height: 60px;
@@ -430,7 +541,7 @@ onMounted(() => {
p {
margin: 0;
font-weight: 800;
color: var(--el-color-primary);
color: #fff;
font-size: 14px;
font-family: "Microsoft YaHei", "微软雅黑", "Arial", sans-serif;
}
@@ -453,6 +564,7 @@ onMounted(() => {
}
}
}
// .container_function {
// width: 100%;
// height: auto;
@@ -534,20 +646,21 @@ onMounted(() => {
// }
// }
.container_pieShow{
.container_pieShow {
width: 100% !important;
//min-height: 200px !important;
height:auto;
height: auto;
background-color: #eee;
// display: flex;
// justify-content: space-between;
// padding-left: 2ch;
margin-bottom: 10px;
}
.el-collapse {
width: 100% !important;
// min-height: 200px !important;
height:100% !important;
height: 100% !important;
background-color: #eee;
// display: flex;
// justify-content: space-between;
@@ -555,10 +668,10 @@ onMounted(() => {
// margin-bottom: 10px;
}
.el-collapse-item{
.el-collapse-item {
width: 100% !important;
// min-height: 200px !important;
height:100% !important;
height: 100% !important;
background-color: #eee;
// display: flex !important;
}
@@ -566,29 +679,32 @@ onMounted(() => {
.container_charts {
width: 100%;
//min-height: 180px !important;
height:90%;
height: 100%;
background-color: #eee;
display: flex;
justify-content: space-between;
margin-bottom: 10px;
.charts_info {
margin-top: 5px;
border-radius: 4px;
flex: none;
width: 32.9%;
width: 33.1%;
height: 100% !important;
background-color: #fff;
border-radius: 4px;
// border-radius: 4px;
}
}
.el-tabs{
.el-tabs {
width: 100% !important;
border-radius: 4px;
}
.tabs-menu{
.tabs-menu {
height: 100%;
}
.container_table {
// width: 100%;
flex: 1 !important;
@@ -604,4 +720,20 @@ onMounted(() => {
}
}
}
:deep(.el-collapse-item__header) {
color: var(--el-color-primary);
font-size: 14px;
font-family: "Microsoft YaHei", "微软雅黑", "Arial", sans-serif;
}
:deep(.el-collapse-item__conten) {
// background-color:#f6f6f6;
padding-bottom: 0px !important;
}
:deep(.el-collapse-item__content ) {
// background-color:#f6f6f6;
padding-bottom: 0px !important;
}
</style>

View File

@@ -62,18 +62,17 @@ const modeList = [
},
];
const handelOpen = async (item: any) => {
await authStore.setShowMenu();
modeStore.setCurrentMode(item.code); // 将模式code存入 store
await authStore.setShowMenu();
return;
if (isActive) {
router.push({ path: "/static" });
} else {
ElMessage({
message: "当前模式未配置",
type: "warning",
});
}
// if (isActive) {
// router.push({ path: "/static" });
// } else {
// ElMessage({
// message: "当前模式未配置",
// type: "warning",
// });
// }
};
const handleSelect = (key: string, keyPath: string[]) => {
console.log(key, keyPath);

View File

@@ -2,18 +2,14 @@
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig">
<el-tabs type="border-card">
<el-tab-pane label="设备台账信息">
<div class="form-grid">
<el-form :model='formContent' ref='dialogFormRef' :rules='rules' :disabled="false">
<div >
<el-form :model='formContent' ref='dialogFormRef' :rules='rules' :disabled="false" label-width="auto" class="form-three">
<el-divider >设备信息</el-divider>
<el-row :gutter="24" >
<el-col :span="8">
<el-form-item label="设备名称" prop="name" :label-width="100">
<el-form-item label="设备名称" prop="name" >
<el-input v-model='formContent.name' placeholder="请输入设备名称"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label='设备类型' prop='devType' :label-width="100">
<el-select v-model="formContent.devType" clearable placeholder="请选择设备类型">
<el-form-item label='设备类型' prop='devType' >
<el-select v-model="formContent.devType" filterable clearable placeholder="请选择设备类型">
<el-option
v-for="item in dictStore.getDictData('Dev_Type')"
:key="item.id"
@@ -22,9 +18,7 @@
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label='设备模式' prop='pattern' :label-width="100">
<el-form-item label='设备模式' prop='pattern' >
<el-select v-model="formContent.pattern" clearable placeholder="请选择设备模式" disabled>
<el-option
v-for="item in dictStore.getDictData('Pattern')"
@@ -34,13 +28,7 @@
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" >
<el-col :span="8">
<el-form-item label='生产厂商' prop='manufacturer' :label-width="100">
<el-form-item label='设备厂家' prop='manufacturer' >
<el-select v-model="formContent.manufacturer" clearable placeholder="请选择生产厂商">
<el-option
v-for="item in dictStore.getDictData('Dev_Manufacturers')"
@@ -50,40 +38,24 @@
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="生产日期" prop="createDate" :label-width="100">
<el-form-item label="出厂日期" prop="createDate" >
<el-date-picker
v-model="formContent.createDate"
placeholder="请选择生产日期"
placeholder="请选择出厂日期"
:disabled-date="disabledDate"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="出厂编号" prop="createId" placeholder="请输入出厂编号" :label-width="100">
<el-input v-model="formContent.createId" />
<el-form-item label="设备序列号" prop="createId" >
<el-input v-model="formContent.createId" placeholder="请输入设备序列号"/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" >
<el-col :span="8">
<el-form-item label="固件版本" prop="hardwareVersion" :label-width="100">
<el-form-item label="固件版本" prop="hardwareVersion" >
<el-input v-model="formContent.hardwareVersion" placeholder="请输入固件版本"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="软件版本" prop="softwareVersion" :label-width="100">
<el-form-item label="软件版本" prop="softwareVersion" >
<el-input v-model="formContent.softwareVersion" placeholder="请输入软件版本"/>
</el-form-item>
</el-col>
</el-row>
<el-divider >参数信息</el-divider>
<el-row :gutter="24" >
<el-col :span="8">
<el-form-item label="设备通道数" prop="devChns" :label-width="100">
<el-form-item label="通道数" prop="devChns" >
<el-select v-model="formContent.devChns" clearable placeholder="请选择设备通道数">
<el-option
v-for="item in dictStore.getDictData('Dev_Chns')"
@@ -93,9 +65,7 @@
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="额定电压(V)" prop="devVolt" :label-width="100">
<el-form-item label="额定电压(V)" prop="devVolt" >
<el-select v-model="formContent.devVolt" clearable placeholder="请选择额定电压">
<el-option
v-for="item in dictStore.getDictData('Dev_Volt')"
@@ -105,9 +75,7 @@
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="额定电流(A)" prop="devCurr" :label-width="100">
<el-form-item label="额定电流(A)" prop="devCurr" >
<el-select v-model="formContent.devCurr" clearable placeholder="请选择额定电流">
<el-option
v-for="item in dictStore.getDictData('Dev_Curr')"
@@ -117,12 +85,8 @@
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" >
<el-col :span="8">
<el-form-item label='通讯协议' prop='protocol' :label-width="100">
<el-select v-model="formContent.protocol" clearable placeholder="请选择通讯协议" @change="handleEncryptionChange">
<el-form-item label='通讯协议' prop='protocol' >
<el-select v-model="formContent.protocol" clearable placeholder="请选择通讯协议" >
<el-option
v-for="item in dictStore.getDictData('Protocol')"
:key="item.id"
@@ -131,73 +95,49 @@
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="IP地址" prop="ip" :label-width="100">
<el-form-item label="IP地址" prop="ip" >
<IPAddress v-model:value="formContent.ip"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="端口号" prop="port" placeholder="请输入端口号" :label-width="100">
<el-form-item label="端口号" prop="port" placeholder="请输入端口号" >
<el-input v-model="formContent.port" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" >
<el-col :span="8">
<el-form-item label='是否加密' prop='encryptionFlag' :label-width="100">
<el-select v-model="formContent.encryptionFlag" clearable placeholder="请选择是否加密" @change="handleEncryptionChange">
<el-form-item label='是否加密' prop='encryptionFlag' >
<el-select v-model="formContent.encryptionFlag" clearable placeholder="请选择是否加密">
<el-option label="是" :value="1"></el-option>
<el-option label="否" :value="0"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8" v-if="IsPasswordShow">
<el-form-item label='识别码' prop='series' clearable placeholder="请输入识别码" :label-width="100">
<el-input v-model='formContent.series' show-password/>
<el-form-item label='识别码' prop='series' clearable v-if="formContent.encryptionFlag">
<el-input v-model='formContent.series' placeholder="请输入识别码" show-password/>
</el-form-item>
</el-col>
<el-col :span="8" v-if="IsPasswordShow">
<el-form-item label='密钥' prop='devKey' clearable placeholder="请输入密钥" :label-width="100">
<el-input v-model='formContent.devKey' show-password/>
<el-form-item label='密钥' prop='devKey' clearable v-if="formContent.encryptionFlag">
<el-input v-model='formContent.devKey' placeholder="请输入密钥" show-password/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" v-if="DevIsShow">
<el-col :span="8">
<el-form-item label='样品编号' prop='sampleID' clearable placeholder="请输入样品编号" :label-width="100">
<el-input v-model='formContent.sampleID' />
<el-form-item label='样品编号' prop='sampleID' clearable v-if="DevIsShow">
<el-input v-model='formContent.sampleID' placeholder="请输入样品编号" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label='送样日期' prop='arrivedDate' :label-width="100">
<el-form-item label='送样日期' prop='arrivedDate' >
<el-date-picker
v-model="formContent.arrivedDate"
placeholder="请选择送样日期"
:disabled-date="disabledDate"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" v-if="MonIsShow">
<el-col :span="8">
<el-form-item label='所属地市' prop='cityName' clearable placeholder="请输入所属地市" :label-width="100">
<el-form-item label='所属地市' prop='cityName' clearable placeholder="请输入所属地市" v-if="MonIsShow">
<el-input v-model='formContent.cityName' />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label='所属供电公司' prop='gDName' clearable placeholder="请输入所属供电公司" :label-width="100">
<el-form-item label='所属供电公司' prop='gDName' clearable placeholder="请输入所属供电公司" v-if="MonIsShow">
<el-input v-model='formContent.gDName' />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label='所属电站' prop='subName' clearable placeholder="请输入所属电站" :label-width="100">
<el-form-item label='所属电站' prop='subName' clearable placeholder="请输入所属电站" v-if="MonIsShow">
<el-input v-model='formContent.subName' />
</el-form-item>
</el-col>
</el-row>
<el-form-item v-auth.device="'factorFlag'" label="是否支持系数校准" prop='factorFlag'>
<el-radio-group v-model="formContent.factorFlag" >
<el-radio :value="1"></el-radio>
<el-radio :value="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</div>
</el-tab-pane>
@@ -230,7 +170,7 @@ import MonitorTable from '@/views/machine/device/components/monitorTab.vue';
const MonIsShow = ref(false)
const DevIsShow = ref(false)
const IsPasswordShow = ref(false)
// const IsPasswordShow = ref(false)
const dictStore = useDictStore()
const mode = ref()
// 定义弹出组件元信息
@@ -251,16 +191,17 @@ const disabledDate = (time: Date) => {
devVolt:57.74,
devCurr:1,
manufacturer: '',
createDate: '',
createDate: dayjs().format('YYYY-MM-DD'),
createId: '',
hardwareVersion: '',
softwareVersion: '',
protocol: 'MMS',
ip: '',
ip: '192.168.1.200',
port: 102,
encryptionFlag: 1,
encryptionFlag: 0,
reCheckNum:0,
state: 1,
factorFlag:0,
})
return { dialogVisible, titleType, formContent }
}
@@ -277,16 +218,17 @@ const disabledDate = (time: Date) => {
devVolt:57.74,
devCurr:1,
manufacturer: '',
createDate: '',
createDate: dayjs().format('YYYY-MM-DD'),
createId: '',
hardwareVersion: '',
softwareVersion: '',
protocol: 'MMS',
ip: '',
ip: '192.168.1.200',
port: 102,
encryptionFlag: 1,
encryptionFlag: 0,
reCheckNum:0,
state: 1,
factorFlag:0,
}
}
@@ -344,12 +286,10 @@ const disabledDate = (time: Date) => {
try {
dialogFormRef.value?.validate(async (valid: boolean) => {
if (formContent.value.encryptionFlag === 1) {
handleEncryptionChange(1)
} else {
handleEncryptionChange(0)
if (formContent.value.encryptionFlag === 0) {
formContent.value.series = ''
formContent.value.devKey = ''
}
if (valid) {
formContent.value.createDate = dayjs(formContent.value.createDate).format('YYYY-MM-DD');
if (formContent.value.arrivedDate)
@@ -401,34 +341,34 @@ const open = (sign: string, data: Device.ResPqDev,currentMode: string) => {
}
if (data.encryptionFlag === 1) {
handleEncryptionChange(1)
//handleEncryptionChange(1)
} else {
handleEncryptionChange(0)
//handleEncryptionChange(0)
}
if (data.id) {
formContent.value = { ...data }
} else {
resetFormContent()
handleEncryptionChange(1)
//handleEncryptionChange(1)
}
// 重置表单
dialogFormRef.value?.resetFields()
}
const handleEncryptionChange = (value: number) => {
// 根据是否加密来显示或隐藏识别码和密钥
if(value === 1){
IsPasswordShow.value = true
}else
{
IsPasswordShow.value = false
// formContent.value.series = ''
// formContent.value.devKey = ''
// rules.value.series = [];
// rules.value.devKey = [];
}
}
// const handleEncryptionChange = (value: number) => {
// // 根据是否加密来显示或隐藏识别码和密钥
// if(value === 1){
// IsPasswordShow.value = true
//
// }else
// {
// IsPasswordShow.value = false
// // formContent.value.series = ''
// // formContent.value.devKey = ''
// // rules.value.series = [];
// // rules.value.devKey = [];
// }
// }
// 对外映射
defineExpose({ open })

View File

@@ -5,11 +5,12 @@
<ProTable
ref='proTable'
:columns='columns'
:style="{ height: '326px',maxHeight: '400px',overflow:'hidden'}"
>
<!-- 表格 header 按钮 -->
<template #tableHeader='scope'>
<el-button type='primary' :icon='CirclePlus'>新增</el-button>
<el-button type='danger' :icon='Delete' plain :disabled='!scope.isSelected'>批量删除</el-button>
<el-button type='danger' :icon='Delete' plain :disabled='!scope.isSelected'>删除</el-button>
</template>
<!-- 表格操作 -->
<template #operation>
@@ -30,7 +31,10 @@
import { type ColumnProps } from '@/components/ProTable/interface'
import { type Monitor } from '@/api/device/interface/monitor'
// 定义 props
const props = defineProps<{
MonIsShow: boolean;
}>();
// 表格配置项

View File

@@ -10,10 +10,10 @@
<template #tableHeader='scope'>
<el-button v-auth.device="'add'" type='primary' :icon='CirclePlus' @click="openDialog('add')">新增</el-button>
<el-button v-auth.device="'export'" type='primary' :icon='Upload' plain @click='downloadFile()'>导出</el-button>
<el-button v-auth.device="'import'" type='primary' :icon='Download' plain @click='importFile()'>导入</el-button>
<el-button v-auth.device="'import'" type='primary' :icon='Download' plain @click='importFile()' v-if='modeStore.currentMode === "比对式"'>导入</el-button>
<el-button v-auth.device="'delete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
@click='batchDelete(scope.selectedListIds)'>
批量删除
删除
</el-button>
</template>
<!-- 表格操作 -->
@@ -51,7 +51,10 @@ const proTable = ref<ProTableInstance>()
const devicePopup = ref()
// 定义包含和排除的单位
const getTableList = (params: any) => {
const boundPqDevList=ref<Device.ReqPqDevParams[]>([])//根据检测计划id查询出所有已绑定的设备
const getTableList = async (params: any) => {
let newParams = JSON.parse(JSON.stringify(params))
newParams.searchEndTime = endDate.value
newParams.searchBeginTime = startDate.value
@@ -67,7 +70,7 @@ const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
{
prop: 'name',
label: '设备名称',
label: '名称',
search: { el: 'input' },
minWidth: 200,
},
@@ -80,7 +83,7 @@ const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
},
{
prop: 'createDate',
label: '生产日期',
label: '出厂日期',
minWidth: 200,
search: {
span: 2,
@@ -98,7 +101,7 @@ const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
},
{
prop: 'devChns',
label: '设备通道数',
label: '通道数',
minWidth: 110,
},
@@ -116,7 +119,7 @@ const columns = reactive<ColumnProps<Device.ResPqDev>[]>([
},
{
prop: 'manufacturer',
label: '生产厂商',
label: '设备厂家',
enum: dictStore.getDictData('Dev_Manufacturers'),
search: { el: 'select', props: { filterable: true }, order: 1 },
fieldNames: { label: 'name', value: 'id' },
@@ -142,14 +145,16 @@ const openDialog = (titleType: string, row: Partial<Device.ResPqDev> = {}) => {
// 批量删除设备
const batchDelete = async (id: string[]) => {
await useHandleData(deletePqDev, id, '删除所选设备')
const patternId = dictStore.getDictData('Pattern').find(item=>item.name=== modeStore.currentMode)?.id ?? ''//获取数据字典中对应的id
await useHandleData(deletePqDev, {'ids':id,'pattern': patternId} , '删除所选设备')
proTable.value?.clearSelection()
proTable.value?.getTableList()
}
// 删除设备
const handleDelete = async (params: Device.ResPqDev) => {
await useHandleData(deletePqDev, [params.id], `删除【${params.name}】设备`)
const patternId = dictStore.getDictData('Pattern').find(item=>item.name=== modeStore.currentMode)?.id//获取数据字典中对应的id
await useHandleData(deletePqDev, {'ids': [params.id] ,'pattern': patternId}, `删除【${params.name}】设备`)
proTable.value?.getTableList()
}
@@ -162,10 +167,10 @@ const downloadFile = async () => {
searchParam.searchBeginTime = startDate.value;
searchParam.searchEndTime = endDate.value;
ElMessageBox.confirm('确认导出被检设备?', '温馨提示', { type: 'warning' }).then(() =>
useDownload(exportPqDev,'被检设备导出数据', proTable.value?.searchParam, false,'.xlsx'),
)
ElMessageBox.confirm('确认导出被检设备?', '温馨提示', { type: 'warning' }).then(() =>{
const patternId = dictStore.getDictData('Pattern').find(item=>item.name=== modeStore.currentMode)?.id//获取数据字典中对应的id
useDownload(exportPqDev,'被检设备导出数据', {...proTable.value?.searchParam,pattern:patternId}, false,'.xlsx')
})
}
//导入设备

View File

@@ -2,40 +2,47 @@
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig">
<div class="table-container">
<el-table :data="errorData"
height="500"
:header-cell-style="{ textAlign: 'center',backgroundColor: '#003078',color: '#fff' } "
:cell-style="{ textAlign: 'center' }"
style="width: 100%"
:span-method="spanMethod"
border
class="custom-table">
<el-table-column prop="measured" label="被测量" />
<el-table-column prop="deviceLevel" label="检测装置级别" />
<el-table-column prop="measurementType" label="测量类型" />
<el-table-column prop="condition" label="测量条件" />
<el-table-column prop="maxErrorValue" label="最大误差" />
</el-table>
<div class="notes-container">
<label>注1:UN:测量的标称电压;IN:测量仪器的标称电流;Uh和Ih:测量值,h表示谐波次数</label>
<label>注2:对于数字式接入监测终端与电能质量信号采集单元联合准确度需满足本表要求</label>
</div>
<el-table :data="errorData.value"
height="500"
:header-cell-style="rowClass"
:cell-style="{ textAlign: 'center' }"
style="width: 100%"
:span-method="spanMethod"
:border="true"
class="custom-table"
>
<el-table-column label="被测量">
<el-table-column prop="col1" width="150"/>
<el-table-column prop="col2" width="120" />
</el-table-column>
<el-table-column prop="deviceLevel" label="检测装置级别" width="120"/>
<el-table-column prop="measurementType" label="测量类型" />
<el-table-column prop="condition" label="测量条件" />
<el-table-column prop="maxErrorValue" label="最大误差" />
</el-table>
</div>
<div>
<label class="left-align-label">注1UN测量的标称电压IN测量仪器的标称电流Uh和Ih测量值h表示谐波次数</label>
</div>
<div>
<label class="left-align-label">注2对于数字式接入监测终端与电能质量信号采集单元联合准确度需满足本表要求</label>
</div>
</el-dialog>
</template>
<script lang="ts" setup name="IndicatorTypeDialog">
import { defineProps, defineEmits, reactive,watch,ref,computed } from 'vue';
import { defineProps, defineEmits, reactive,watch,ref,computed, type CSSProperties } from 'vue';
import { dialogBig} from '@/utils/elementBind'
import type { ColumnProps } from '@/components/ProTable/interface'
import type { ErrorSystem } from '@/api/device/interface/error'
import errorDataList from '@/api/device/error/errorData'
import type { TableColumnCtx } from 'element-plus'
import { da } from 'element-plus/es/locale';
import { useDictStore } from '@/stores/modules/dict'
const errorData = errorDataList.errordetail
const dictStore = useDictStore()
const errorData = ref<ErrorSystem.Error_detail[]>([]);
const dialogTitle = ref()
const devLevelName = ref<string>('') // 假设 devLevelName 是一个 ref
function useMetaInfo() {
const dialogVisible = ref(false)
const formContent = ref<ErrorSystem.ErrorSystemList>({
@@ -59,68 +66,209 @@ interface SpanMethodProps {
columnIndex: number
}
const spanMethod = ({
const rowClass = ({ row, column, rowIndex, columnIndex }: { row: any; column: any; rowIndex: number; columnIndex: number }): CSSProperties => {
let res: CSSProperties = {
textAlign: 'center' as CSSProperties['textAlign'],
backgroundColor: '#003078',
color: '#fff'
}
if (rowIndex === 1) {
res = { ...res, display: 'none' }
}
return res
}
const spanMethod = computed(() => {
return devLevelName.value === 'A级' ? spanAMethod : spanSMethod
})
const spanAMethod = ({
row,
column,
rowIndex,
columnIndex,
}: SpanMethodProps) => {
if (columnIndex === 0 ) { // 检查是否为第一列
if (rowIndex === 2 || rowIndex === 21) { // 检查是否为第三行
if (columnIndex === 0) {
if (rowIndex <= 1 || rowIndex === 7 || rowIndex == 20) {//0电压偏差1频率偏差7闪变20功率简单的跨两列
return {
rowspan: 2, // 合并行数
colspan: 1, // 单元格列数
};
}else if (rowIndex === 8) { //
return {
rowspan: 8,
colspan: 1,
};
rowspan: 1,
colspan: 2,
}
}
else if (rowIndex === 16) { //
if (rowIndex === 2) {//2三相不平衡跨三行两列
return {
rowspan: 4,
colspan: 1,
};
rowspan: 3,
colspan: 2,
}
}
else if (rowIndex === 3 || rowIndex === 9 || rowIndex === 10|| rowIndex === 11
|| rowIndex === 12|| rowIndex === 13|| rowIndex === 14|| rowIndex === 15
|| rowIndex === 17 || rowIndex === 18|| rowIndex === 19
|| rowIndex === 22) { // 检查是否为第四行
if (rowIndex === 3 || rowIndex === 4 || rowIndex === 6 ||
rowIndex >= 9 && rowIndex <= 15 ||
rowIndex >= 17 && rowIndex <= 19 ||
rowIndex === 22 || rowIndex === 24) {//这些行不显示
return {
rowspan: 0, // 不显示该单元格
rowspan: 0,
colspan: 0,
};
}
}
}
else if(columnIndex === 2) { // 检查是否为第三列
if (rowIndex === 2
|| rowIndex === 8|| rowIndex === 10|| rowIndex === 12|| rowIndex === 14
|| rowIndex === 16|| rowIndex === 18
|| rowIndex === 21) {
if (rowIndex === 5 || rowIndex === 23) {//5电压波动23电压暂降暂升中断跨两列
return {
rowspan: 2,
colspan: 1,
};
}
}
else if (rowIndex === 3
|| rowIndex === 9|| rowIndex === 11|| rowIndex === 13|| rowIndex === 15
|| rowIndex === 17|| rowIndex === 19
|| rowIndex === 22) { // 检查是否为第四行
if (rowIndex === 8) {//谐波和间谐波跨八行两列
return {
rowspan: 0, // 不显示该单元格
colspan: 0,
};
rowspan: 8,
colspan: 2,
}
}
if (rowIndex === 16) {//高频次谐波跨八行两列
return {
rowspan: 4,
colspan: 2,
}
}
if (rowIndex === 21 || rowIndex === 22) {//电流跨两行两列
return {
rowspan: 2,
colspan: 2,
}
}
}
if (columnIndex === 1) {
if (rowIndex <= 4 || rowIndex >= 7 && rowIndex <= 22) {
return {
rowspan: 0,
colspan: 0,
}
}
}
if (columnIndex === 2 || columnIndex === 3) {
if (rowIndex === 2 || rowIndex === 8 || rowIndex === 10 ||
rowIndex === 12 || rowIndex === 14 || rowIndex === 16 ||
rowIndex === 18 || rowIndex === 21) {
return {
rowspan: 2,
colspan: 1,
}
}
if (rowIndex === 3 || rowIndex === 9 || rowIndex === 11 ||
rowIndex === 13 || rowIndex === 15 || rowIndex === 17 ||
rowIndex === 19 || rowIndex === 22) {
return {
rowspan: 0,
colspan: 0,
}
}
}
};
// 关闭弹窗
const close = () => {
dialogVisible.value = false
const spanSMethod = ({
row,
column,
rowIndex,
columnIndex,
}: SpanMethodProps) => {
if (columnIndex === 0) {
if (rowIndex <= 1 || rowIndex === 8 || rowIndex == 17) {//0电压偏差1频率偏差7闪变20功率简单的跨两列
return {
rowspan: 1,
colspan: 2,
}
}
if (rowIndex === 2) {//2三相不平衡跨三行两列
return {
rowspan: 3,
colspan: 2,
}
}
if (rowIndex === 3 || rowIndex === 4 || rowIndex === 6 || rowIndex === 7 ||
rowIndex >= 10 && rowIndex <= 12 ||
rowIndex >= 14 && rowIndex <= 16 ||
rowIndex === 19 || rowIndex === 21 || rowIndex === 22) {//这些行不显示
return {
rowspan: 0,
colspan: 0,
}
}
if (rowIndex === 5 || rowIndex === 20) {//5电压波动23电压暂降暂升中断跨两行
return {
rowspan: 3,
colspan: 1,
}
}
if (rowIndex === 9 || rowIndex === 13) {//谐波和间谐波跨八行两列
return {
rowspan: 4,
colspan: 2,
}
}
if (rowIndex === 18 ) {//电流跨两行两列
return {
rowspan: 2,
colspan: 2,
}
}
}
if (columnIndex === 1) {
if (rowIndex === 6 || rowIndex === 21) {
return {
rowspan: 2,
colspan: 1,
}
}
if (rowIndex <= 4 || rowIndex >= 7 && rowIndex <= 19 || rowIndex === 22) {
return {
rowspan: 0,
colspan: 0,
}
}
}
if (columnIndex === 2) {
if (rowIndex === 2 || rowIndex === 6 || rowIndex === 9 ||
rowIndex === 11 || rowIndex === 13 || rowIndex === 15 ||
rowIndex === 18 || rowIndex === 21) {
return {
rowspan: 2,
colspan: 1,
}
}
if (rowIndex === 3 || rowIndex === 7 ||
rowIndex === 10 || rowIndex === 12 ||
rowIndex === 14 || rowIndex === 16 ||
rowIndex === 19 || rowIndex === 22) {
return {
rowspan: 0,
colspan: 0,
}
}
}
if(columnIndex === 3){
if (rowIndex === 2 || rowIndex === 6 || rowIndex === 9 ||
rowIndex === 11 || rowIndex === 13 ||rowIndex === 15 ||
rowIndex === 18 || rowIndex === 21){
return {
rowspan: 2,
colspan: 1,
}
}
if (rowIndex === 3 || rowIndex === 7 || rowIndex === 10 ||
rowIndex === 12 || rowIndex === 14 ||rowIndex === 16 ||
rowIndex === 19 || rowIndex === 22){
return {
rowspan: 0,
colspan: 0,
}
}
}
};
// 关闭弹窗
const close = () => {
dialogVisible.value = false
}
// 打开弹窗,可能是新增,也可能是编辑
const open = async (sign: string, data: ErrorSystem.ErrorSystemList) => {
@@ -128,6 +276,15 @@ const open = async (sign: string, data: ErrorSystem.ErrorSystemList) => {
dialogVisible.value = true
if (data.id) {
formContent.value = data as ErrorSystem.ErrorSystemList;
devLevelName.value = dictStore.getDictData('Dev_Level').find(item => item.id === data.devLevel)?.name || '';;
if(devLevelName.value === 'A级'){
errorData.value = errorDataList.errorADetail as unknown as ErrorSystem.Error_detail[];
}else{
errorData.value = errorDataList.errorSDetail as unknown as ErrorSystem.Error_detail[];
}
}
}
@@ -150,5 +307,13 @@ const props = defineProps<{
.notes-container {
text-align: center;
width: 100%; /* 确保注释容器宽度与表格一致 */
}
.notes-container label {
display: block; /* 使每个label标签上下排列 */
margin-bottom: 10px; /* 调整两个label之间的间距 */
}
</style>

View File

@@ -1,68 +1,79 @@
<template>
<div class="dialog-footer">
<el-button :icon='CirclePlus' type="primary" @click="openAddDialog">新增</el-button>
<el-button :icon='Delete' type="danger" plain :disabled='!multipleSelection.length' @click="deleteSelectedRows">批量删除</el-button>
<el-button :icon='Delete' type="danger" plain :disabled='!multipleSelection.length' @click="deleteSelectedRows">删除</el-button>
</div>
<div class="table-container">
<el-table :data="tableData"
:header-cell-style="{ textAlign: 'center',backgroundColor: '#003078',color: '#fff' } "
:cell-style="{ textAlign: 'center' }"
style="width: 100%"
@selection-change="handleSelectionChange" >
:style="{ height: '250px',maxHeight: '400px',overflow:'hidden'}"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column prop="nextId" label="序号" width="60" />
<el-table-column prop="type" label="电能质量检测指标类型" width="181">
<el-table-column prop="sort" label="序号" width="60" />
<el-table-column prop="type" label="误差类型" min-width="180">
<template #default="{ row }">
<el-select v-model="row.type" placeholder="选择指标类型" >
<el-option v-for="item in dictStore.getDictData('Pq_Test_Type')"
:key="item.id"
:label="item.name"
:value="item.id"/>
</el-select>
</template>
<el-cascader style="min-width: 180px;"
:options="errorOptions"
v-model="row.errorType"
:props="{ checkStrictly: false, emitPath: false }"
placeholder="请选择误差类型"
@change="handleErrorTypeChange($event, row)"/>
</template>
</el-table-column>
<el-table-column prop="type" label="脚本类型" min-width="230">
<template #default="{ row }">
<el-cascader style="min-width: 230px;"
:options="scriptOptions"
v-model="row.scriptType"
:props="{ checkStrictly: false, emitPath: false }"
placeholder="请选择脚本类型"
/>
</template>
</el-table-column>
<el-table-column label="起止范围" >
<el-table-column label="起始">
<el-table-column label="起始" width="150">
<template #default="{ row }">
<el-row type="flex">
<el-col :span="14">
<el-select v-model="row.startFlag" placeholder="选择起始值" style="width: 70px;">
<el-row type="flex" :gutter="24">
<el-col :span="12">
<el-select v-model="row.startFlag" placeholder="选择起始值" style="width: 70px;" @change="(value) => handleStartFlagChange(row, value)">
<el-option label="无" :value="2"></el-option>
<el-option label=">=" :value="1"></el-option>
<el-option label=">" :value="0"></el-option>
</el-select>
</el-col>
<el-col :span="10">
<el-input v-model= "row.startValue" style="width: 70px;"
<el-col :span="12">
<el-input v-model= "row.startValue" style="width: 60px;" :disabled="isStartValueDisabled[row.sort]"
/>
</el-col>
</el-row>
</template>
</el-table-column>
<el-table-column label="结束">
<el-table-column label="结束" width="150">
<template #default="{ row }">
<el-row type="flex" >
<el-col :span="14">
<el-select v-model="row.endFlag" placeholder="选择结束值" style="width: 70px;">
<el-row type="flex" :gutter="24" >
<el-col :span="12">
<el-select v-model="row.endFlag" placeholder="选择结束值" style="width: 70px;" @change="(value) => handleEndFlagChange(row, value)">
<el-option label="无" :value="2"></el-option>
<el-option label="<=" :value="1"></el-option>
<el-option label="<" :value="0"></el-option>
</el-select>
</el-col>
<el-col :span="10">
<el-input v-model= "row.endValue" style="width: 70px;"/>
<el-col :span="12">
<el-input v-model= "row.endValue" style="width: 60px;" :disabled="isEndValueDisabled[row.sort]"/>
</el-col>
</el-row>
</template>
</el-table-column>
<el-table-column label="单位" width="115">
<el-table-column label="单位" width="130">
<template #default="{ row }">
<el-select v-model="row.conditionType" placeholder="选择单位">
<el-option
v-for="item in dictStore.getDictData('Condition_Type')"
:key="item.id"
:label="item.name"
:value="item.id"
:value="Number(item.value)"
/>
</el-select>
</template>
@@ -74,20 +85,20 @@
<el-input v-model= "row.maxErrorValue" style="width: 70px;"/>
</template>
</el-table-column>
<el-table-column label="误差类型">
<el-table-column label="误差类型" width="180">
<template #default="{ row }">
<el-select v-model="row.errorValueType" placeholder="选择误差类型">
<el-option
v-for="item in dictStore.getDictData('Error_Value_Type')"
:key="item.id"
:label="item.name"
:value="item.id"
:value="Number(item.value)"
/>
</el-select>
</template>
</el-table-column>
</el-table-column>
<el-table-column label="操作" width="150">
<el-table-column label="操作" min-width="150">
<template #default="{ row }">
<el-button type="primary" link :icon='CopyDocument' @click="copyRow(row)">复制</el-button>
<el-button type='primary' link :icon='Delete' @click="deleteRow(row)">删除</el-button>
@@ -101,55 +112,184 @@
import { type ErrorSystem } from '@/api/device/interface/error';
import { useDictStore, } from '@/stores/modules/dict'
import {CirclePlus, Delete, EditPen,CopyDocument} from '@element-plus/icons-vue'
import { FormItemRule } from 'element-plus';
import { onMounted, type PropType, Ref, ref, watch } from 'vue';
import { type CascaderOption, type FormItemRule } from 'element-plus';
import { el } from 'element-plus/es/locale';
import { type PropType, type Ref, ref, watch } from 'vue';
import { defineEmits } from 'vue';
import ProTable from '@/components/ProTable/index.vue'
const emit = defineEmits(['updateTableData']);
const multipleSelection = ref<number[]>([])
const dictStore = useDictStore()
const isStartValueDisabled = ref<{ [key: number]: boolean }>({});
const isEndValueDisabled = ref<{ [key: number]: boolean }>({});
const props = defineProps({
errorOptions: {
type: Array as PropType<CascaderOption[]>,
required: true
},
scriptOptions: {
type: Array as PropType<CascaderOption[]>,
required: true
},
tableData: {
type: Array as PropType<ErrorSystem.ErrorSystemDetail[]>,
default: () => []
}
});
// 监听 props.tableData 的变化,确保每次数据变化时都重新设置 nextId
watch(() => props.tableData, (newTableData) => {
for (let i = 0; i < newTableData.length; i++) {
newTableData[i].nextId = i + 1;
// 定义一个 Map 来存储误差和脚本系统信息
const errSysAndScriptMap = new Map<string, string>([
['Freq_Deviation_Freq','FREQ'],//频率偏差/频率---频率
['Vol_Deviation_Vol','VRMS'],//电压偏差/电压---电压/相电压有效值
['MSQI_V','V_UNBAN'],//三相不平衡/电压---电压/三相电压负序不平衡度
['MSQI_CUR','I_UNBAN'],//三相不平衡/电流---电流/三相电流负序不平衡度
['Voltage Fluctuation_Voltage Amplitude',''],//电压波动/电压幅值---
['Voltage Fluctuation_Duration',''],//电压波动/持续时间---
['Short Time Flicker Item','PST'],//闪变/短时间闪变---闪变/短时间闪变
['Harmonic_Voltage','V2-50'],//谐波/电压---谐波/谐波电压含有率
['Harmonic_Current','I2-50'],//谐波/电流---谐波/谐波电流幅值
['Harmonic_Angle','VA2-50'],//谐波/相角---谐波/谐波电压相角
['Harmonic_Angle','IA2-50'],//谐波/相角---谐波/谐波电流相角
['Harmonic_Power','P2-50'],//谐波/功率---谐波/谐波有功功率
['Interharmonic_Voltage','SV_1-49'],//间谐波/电压---谐波/间谐波电压含有率
['Interharmonic_Current','SI_1-49'],//间谐波/电流---谐波/间谐波电流幅值
['High Frequency Harmonic_Voltage',''],//高频次谐波/电压
['High Frequency Harmonic_Current',''],//高频次谐波/电流
['Power Item','P'],//功率/功率---功率
['Current Item','IRMS'],//电流/电流---电流/电流有效值
['Dip & Swell & Short duration interruption_Voltage','MAG'],//暂态/电压幅值/电压---暂态/电压幅值
['Dip & Swell & Short duration interruption_Duration','DUR'],//暂态/持续时间/时间---暂态/持续时间
]);
const handleErrorTypeChange = (value: any, row: any) =>{
// const matchedRow = findRowById(row.errorType, props.errorOptions);//选中误差id找对应结构中的含chilren的code
// console.log('matchedRow.code',matchedRow.code)
// const code = errSysAndScriptMap.get(matchedRow?.code || '') || ''; // 确保 code 不为 undefined
// console.log('code',code)
// if (code) {
// const matchedRow2 = findRowByCode(code, props.scriptOptions);//误差code映射脚本code找对应脚本结构中含children的id
// console.log('matchedRow2',matchedRow2)
// if (matchedRow2) {
// row.scriptType = matchedRow2.value;
// }else{
// row.scriptType = '';//如果没有找到匹配的脚本,置空
// }
// }else{
// row.scriptType = '';//如果没有找到匹配的脚本,置空
// }
}
// 假设 props.errorOptions 是一个数组,每个元素可能包含 children 属性
const findRowById = (id: string, options: any[]): any | null => {
for (const option of options) {
if (option.value === id) {
return option;
}
if (option.children && option.children.length > 0) {
const result = findRowById(id, option.children);
if (result) {
return result;
}
}
}
return null;
};
// 假设 props.errorOptions 是一个数组,每个元素可能包含 children 属性
const findRowByCode = (code: string, options: any[]): any | null => {
for (const option of options) {
if (option.code === code) {
return option;
}
if (option.children && option.children.length > 0) {
const result = findRowByCode(code, option.children);
if (result) {
return result;
}
}
}
return null;
};
// 监听 props.tableData 的变化,确保每次数据变化时都重新设置 sort
watch(() => props.tableData, async (newTableData) => {
for (let i = 0; i < newTableData.length; i++) {
newTableData[i].sort = i + 1;
if (newTableData[i].startFlag === 2) {
newTableData[i].startValue = null; // 设置 startValue 为 null
}
if (newTableData[i].endFlag === 2) {
newTableData[i].endValue = null; // 设置 endValue 为 null
}
}
// 重新设置 isStartValueDisabled 和 isEndValueDisabled,并清空输入框
props.tableData.forEach(row => {
isStartValueDisabled.value[row.sort] = row.startFlag === 2;
});
props.tableData.forEach(row => {
isEndValueDisabled.value[row.sort] = row.endFlag === 2;
});
}, { immediate: true });
// 定义规则
const rules: Ref<Record<string, Array<FormItemRule>>> = ref({
type: [{ required: true, message: '误差体系名称必填!', trigger: 'blur' }],
});
// 处理 startFlag 变化的方法
const handleStartFlagChange = (row: ErrorSystem.ErrorSystemDetail, value: number) => {
if (value === 2) {
row.startValue = null; // 清空输入框
isStartValueDisabled.value[row.sort] = true; // 禁用输入框
} else {
isStartValueDisabled.value[row.sort] = false; // 启用输入框
}
};
// 处理 endFlag 变化的方法
const handleEndFlagChange = (row: ErrorSystem.ErrorSystemDetail, value: number) => {
if (value === 2) {
row.endValue = null; // 清空输入框
isEndValueDisabled.value[row.sort] = true; // 禁用输入框
} else {
isEndValueDisabled.value[row.sort] = false; // 启用输入框
}
};
//选中
const handleSelectionChange = (selection: ErrorSystem.ErrorSystemDetail[]) => {
multipleSelection.value = selection.map(row => row.nextId); // 更新选中的行
multipleSelection.value = selection.map(row => row.sort); // 更新选中的行
};
//新增
const openAddDialog = () => {
const newRow = {
nextId: props.tableData.length + 1,
id: '',
errorSysId: "",
type: "",
maxErrorValue: 0,
errorValueType: ""
// 获取字典数据
const conditionTypes = dictStore.getDictData('Condition_Type');
const errorValueTypes = dictStore.getDictData('Error_Value_Type');
const newRow = {
sort: props.tableData.length + 1,
id: '',
startFlag:2,
endFlag:2,
conditionType: conditionTypes.length > 0 ? Number(conditionTypes[3].value) : 0, // 设置默认值为第一个选项的值
errorValueType:errorValueTypes.length > 0 ? Number(errorValueTypes[0].value) : 0, // 设置默认值为第一个选项的值
errorSysId: "",
errorType: "",
scriptType: "",
maxErrorValue: 0
};
emit('updateTableData', [...props.tableData, newRow]);
};
const copyRow = (row: ErrorSystem.ErrorSystemDetail) => {
// 深拷贝行数据
const newRow = { ...row };
const maxNextId = Math.max(...props.tableData.map(item => item.nextId), 0);
newRow.nextId = maxNextId + 1;
const maxNextId = Math.max(...props.tableData.map(item => item.sort), 0);
newRow.sort = maxNextId + 1;
emit('updateTableData', [...props.tableData, newRow]);
};
//删除行
@@ -163,7 +303,7 @@ const deleteRow = (row:ErrorSystem.ErrorSystemDetail) => {
};
//批量删除选中行
const deleteSelectedRows = () => {
const newTableData = props.tableData.filter(row => !multipleSelection.value.includes(row.nextId));
const newTableData = props.tableData.filter(row => !multipleSelection.value.includes(row.sort));
multipleSelection.value = []; // 清空已选择的行
emit('updateTableData', newTableData);
};
@@ -176,6 +316,7 @@ const deleteSelectedRows = () => {
display: flex;
justify-content: flex-start;
margin-bottom: 10px; /* 调整这里的值以增加或减少间距 */
margin-top: 10px;
}
.el-table th, .el-table td {

View File

@@ -1,54 +1,42 @@
<template>
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig">
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig" width="1500px">
<el-tabs type="border-card">
<el-tab-pane label="基础信息">
<div class="form-grid">
<el-form :model="formContent" ref='dialogFormRef' :rules='rules'>
<el-row :gutter="24" >
<el-col :span="8">
<el-form-item label="误差体系名称" prop="name" :label-width="110">
<el-input v-model='formContent.name' placeholder="标准号+年份+设备等级"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="参照标准名称" prop="standardName" :label-width="110">
<el-input v-model='formContent.standardName'/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="发布时间" prop="standardTime" :label-width="110">
<el-input v-model="formContent.standardTime" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" >
<el-col :span="8">
<el-form-item label="适用设备等级" prop="devLevel" :label-width="110">
<el-select v-model='formContent.devLevel' placeholder="请选择设备等级">
<el-option
v-for="item in dictStore.getDictData('Dev_Level')"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="状态" prop="enable" :label-width="110">
<el-select v-model='formContent.enable' placeholder="请选择状态">
<el-option label="启用" :value="1"></el-option>
<el-option label="不启用" :value="0"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<div >
<el-form :model="formContent" ref='dialogFormRef' :rules='rules' label-width="auto" class="form-three">
<el-form-item label="标准号" prop="standardName" >
<el-input v-model='formContent.standardName' placeholder="请填写标准号"/>
</el-form-item>
<el-form-item label="标准推行年份" prop="standardTime" >
<el-date-picker
v-model="formContent.standardTime"
type="year"
placeholder="请选择标准推行年份"
/>
</el-form-item>
<el-form-item label="适用设备等级" prop="devLevel" >
<el-select v-model='formContent.devLevel' placeholder="请选择设备等级">
<el-option
v-for="item in dictStore.getDictData('Dev_Level')"
:key="item.id"
:label="item.name"
:value="item.id"/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="enable" >
<el-select v-model='formContent.enable' placeholder="请选择状态">
<el-option label="启用" :value="1"></el-option>
<el-option label="不启用" :value="0"></el-option>
</el-select>
</el-form-item>
</el-form>
</div>
</el-tab-pane>
</el-tabs>
<ErrorSystemDetailTable :tableData="tableData" @updateTableData="handleTableDataUpdate"/>
<ErrorSystemDetailTable :tableData="tableData" :errorOptions="errorOptions" :scriptOptions="scriptOptions" @updateTableData="handleTableDataUpdate" />
<template #footer>
<div >
<el-button @click='close()'> </el-button>
@@ -61,22 +49,26 @@
</template>
<script lang="ts" setup name="ErrorSystemDialog">
import{ElMessage, type FormInstance,type FormItemRule}from'element-plus'
import { defineProps, defineEmits, reactive,watch,ref, Ref, computed } from 'vue';
import{type CascaderOption, ElMessage, type FormInstance,type FormItemRule}from'element-plus'
import { defineProps, defineEmits, reactive,watch,ref, type Ref, computed } from 'vue';
import { dialogBig} from '@/utils/elementBind'
import { addPqErrSys,updatePqErrSys,getPqErrSysListById} from '@/api/device/error/index'
import {CirclePlus, Delete, EditPen,FolderOpened,CopyDocument} from '@element-plus/icons-vue'
import { useDictStore } from '@/stores/modules/dict'
import { type ErrorSystem } from '@/api/device/interface/error';
import ErrorSystemDetailTable from '@/views/machine/errorSystem/components/errorSystemDetailTable.vue';
import {getDictTreeList} from '@/api/system/dictionary/dictTree'
import { type Dict } from '@/api/system/dictionary/interface';
// 定义弹出组件元信息
const dialogFormRef = ref()
const dictStore = useDictStore()
const tableData = ref<ErrorSystem.ErrorSystemDetail[]>([]);
const errorOptions: Ref<CascaderOption[]> = ref([]); // 修改这里
const scriptOptions: Ref<CascaderOption[]> = ref([]); // 修改这里
const handleTableDataUpdate = (newTableData: ErrorSystem.ErrorSystemDetail[]) => {
const handleTableDataUpdate = (newTableData: ErrorSystem.ErrorSystemDetail[]) => {
tableData.value = newTableData;
};
};
function useMetaInfo() {
const dialogVisible = ref(false)
@@ -107,6 +99,7 @@
state:1,
pqErrSysDtlsList:[]
}
tableData.value =[]
}
let dialogTitle = computed(() => {
@@ -117,7 +110,7 @@
const rules: Ref<Record<string, Array<FormItemRule>>> = ref({
name: [{ required: true, message: '误差体系名称必填!', trigger: 'blur' }],
standardName: [{ required: true, message: '参照标准名称必填!', trigger: 'blur' }],
standardTime: [{ required: true, message: '标准推行时间必填', trigger: 'blur' }],
standardTime: [{ required: true, message: '标准推行年份必选', trigger: 'blur' }],
devLevel:[{ required: true, message: '请选择一项设备等级', trigger: 'change' },],
enable:[{ required: true, message: '请选择一项状态', trigger: 'change '},]
});
@@ -137,6 +130,12 @@
try {
dialogFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
// 确保 standardTime 是 Date 对象
if (formContent.value.standardTime) {
const date = new Date(formContent.value.standardTime);
formContent.value.standardTime = date.getFullYear().toString();
}
formContent.value.pqErrSysDtlsList = tableData.value
if (formContent.value.id) {
await updatePqErrSys(formContent.value);
@@ -155,25 +154,90 @@
console.error('验证过程中出现错误', err)
}
}
// 封装提取第二层节点的逻辑
const loadSecondLevelOptions = async () => {
const dictCode = '误差体系指标项'; // 替换为实际需要的字典代码
const dictCode2 = '脚本-误差'; // 替换为实际需要的字典代码
const resDictTree: Dict.ResDictTree = {
name: dictCode,
id: '',
pid: '',
pids: '',
code: '',
sort: 0
};
// 打开弹窗,可能是新增,也可能是编辑
const open = async (sign: string, data: ErrorSystem.ErrorSystemList) => {
titleType.value = sign
dialogVisible.value = true
if (data.id) {
const result = await getPqErrSysListById(data);
if (result && result.data) {
formContent.value = result.data as ErrorSystem.ErrorSystemList;
const resDictTree2: Dict.ResDictTree = {
name: dictCode2,
id: '',
pid: '',
pids: '',
code: '',
sort: 0
};
tableData.value = formContent.value.pqErrSysDtlsList || []
// 并行请求两个字典树列表
const [result, result2] = await Promise.all([
getDictTreeList(resDictTree),
getDictTreeList(resDictTree2)
]);
const allOptions = convertToOptions(result.data as Dict.ResDictTree[]);
const allOptions2 = convertToOptions(result2.data as Dict.ResDictTree[]);
// 提取第二层节点
const secondLevelOptions: any[] = [];
allOptions.forEach(option => {
if (option.children && option.children.length > 0) {
secondLevelOptions.push(...option.children);
}
});
const secondLevelOptions2: any[] = [];
allOptions2.forEach(option => {
if (option.children && option.children.length > 0) {
secondLevelOptions2.push(...option.children);
}
});
// 将第二层节点赋值给 options.value
errorOptions.value = secondLevelOptions;
scriptOptions.value = secondLevelOptions2;
};
// 转换函数
const convertToOptions = (dictTree: Dict.ResDictTree[]): CascaderOption[] => {
return dictTree.map(item => ({
value: item.id,
label: item.name,
code: item.code,
children: item.children ? convertToOptions(item.children) : undefined
}));
};
// 打开弹窗,可能是新增,也可能是编辑
const open = async (sign: string, data: ErrorSystem.ErrorSystemList) => {
titleType.value = sign;
// 并行执行两个异步操作
const loadOptionsPromise = loadSecondLevelOptions();
const fetchDataPromise = data.id ? getPqErrSysListById(data) : Promise.resolve(null);
const [_, result] = await Promise.all([loadOptionsPromise, fetchDataPromise]);
if (result && result.data) {
formContent.value = result.data as ErrorSystem.ErrorSystemList;
tableData.value = formContent.value.pqErrSysDtlsList || [];
} else {
resetFormContent()
resetFormContent();
}
// 重置表单
dialogFormRef.value?.resetFields()
}
dialogFormRef.value?.resetFields();
dialogVisible.value = true;
};
// 对外映射
@@ -183,22 +247,6 @@ const props = defineProps<{
}>()
</script>
<style>
.form-grid {
display: flex;
flex-direction: row; /* 横向排列 */
flex-wrap: wrap; /* 允许换行 */
}
.form-grid .el-form-item {
flex: 1 1 30%; /* 控件宽度 */
margin-right: 20px; /* 控件间距 */
}
.form-grid .el-form-item:last-child {
margin-right: 0; /* 最后一个控件不需要右边距 */
}
.el-tabs {
margin-bottom: 20px; /* 添加底部边距 */
}
</style>

View File

@@ -10,14 +10,14 @@
<el-button type='primary' :icon='CirclePlus' @click="openDialog('add')">新增</el-button>
<el-button v-auth.device="'delete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
@click='batchDelete(scope.selectedListIds)'>
批量删除
删除
</el-button>
</template>
<!-- 表格操作 -->
<template #operation='scope'>
<el-button type='primary' link :icon='View' @click="openDialog('view', scope.row)">查看</el-button>
<el-button type='primary' link :icon='EditPen' @click="openDialog('edit', scope.row)">编辑</el-button>
<el-button type='primary' link :icon='Delete' @click='handleDelete(scope.row)'>删除</el-button>
<el-button v-auth.device="'view'" type='primary' link :icon='View' @click="openDialog('view', scope.row)">查看</el-button>
<el-button v-auth.device="'edit'" type='primary' link :icon='EditPen' @click="openDialog('edit', scope.row)">编辑</el-button>
<el-button v-auth.device="'delete'" type='primary' link :icon='Delete' @click='handleDelete(scope.row)'>删除</el-button>
</template>
</ProTable>
</div>
@@ -48,15 +48,15 @@ const columns = ref<ColumnProps<ErrorSystem.ErrorSystemList>[]>([
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
{
prop: 'name',
label: '误差体系名称',
label: '名称',
},
{
prop: 'standardName',
label: '参照标准名称',
label: '标准号',
},
{
prop: 'standardTime',
label: '标准实施年份',
label: '标准推行年份',
width: 200,
search: { el: 'input' },
},

View File

@@ -123,8 +123,6 @@ const open = (currentMode: string) => {
// 对外映射
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
}>()
</script>

View File

@@ -0,0 +1,13 @@
<template>
<div>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,95 @@
import { ref } from "vue"
<template>
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig" >
<div class='table-box'>
<ProTable
ref='proTable'
:columns='columns'
:request-api="getTableList"
:pagination="false"
:toolButton ='false'
:style="{ height: '250px',maxHeight: '400px',overflow:'hidden'}"
>
<!-- :data='testScriptData' 如果要显示静态数据就切换该配置 -->
<!-- 表格 header 按钮 -->
<template #tableHeader='scope'>
<el-button v-auth.testScript="'add'" type='primary' :icon='CirclePlus' @click="openDialog('add')">新增</el-button>
<el-button v-auth.testScript="'delete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
@click='batchDelete(scope.selectedListIds)'>
删除
</el-button>
</template>
<!-- 表格操作 -->
<template #operation='scope'>
<el-button v-auth.testScript="'upgrade'" type='primary' v-if="scope.row.type !== 1" link :icon='Share' @click='updateType(scope.row)'>复制</el-button>
<el-button v-auth.testScript="'edit'" type='primary' link :icon='EditPen' :model-value="false" @click="openDialog('edit', scope.row)">编辑</el-button>
<el-button v-auth.testScript="'delete'" type='primary' link :icon='Delete' @click='handleDelete(scope.row)'>删除</el-button>
</template>
</ProTable>
</div>
<template #footer>
<div >
<el-button @click='close()'> </el-button>
<el-button type="primary" @click='save()'>保存</el-button>
</div>
</template>
</el-dialog>
<SetValuePopup ref='setValuePopup' />
</template>
<script setup lang="ts">
import type { TestScript } from '@/api/device/interface/testScript'
import type { ColumnProps } from '@/components/ProTable/interface'
import {reactive, ref } from 'vue'
import { dialogBig } from '@/utils/elementBind'
const dialogVisible = ref(false)
const dialogTitle = ref('')
// 表格配置项
const columns = reactive<ColumnProps<TestScript.ResTestScript>[]>([
{ type: 'selection', fixed: 'left', width: 70 },
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
{
prop: 'name',
label: '参考设定值类型',
minWidth: 350,
},
{
prop: 'standardName',
label: '参考设定值子类型',
minWidth: 150,
},
{
prop: 'standardTime',
label: '参考设定值',
minWidth: 150,
},
{ prop: 'operation', label: '操作', fixed: 'right', width: 250 },
])
// 打开弹窗,可能是新增,也可能是编辑
const open = (sign: string,row: any) => {
dialogVisible.value = true
dialogTitle.value = sign === 'add'? '新增检测项目信息' : '编辑检测项目信息'
}
// 关闭弹窗
const close = () => {
dialogVisible.value = false
}
// 对外映射
defineExpose({ open })
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,219 @@
<template>
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig" width="1400px">
<div class="dialog-content" >
<el-tabs type="border-card" class="left-tabs" style="height: 100%;">
<el-tab-pane label="输出菜单">
<!-- 输出菜单内容 -->
<el-table :data="tableData"
:header-cell-style="{ textAlign: 'center',backgroundColor: '#003078',color: '#fff' } "
:cell-style="{ textAlign: 'center' }"
style="width: 100%"
:style="{ height: '295px',overflow:'hidden'}"
:show-header="false"
:span-method="arraySpanMethod">
<el-table-column prop="sort" label="相别" width="60" />
<el-table-column prop="frequency" label="电压/电流" width="90" />
<el-table-column prop="L1" label="值" width="180"/>
<el-table-column label="操作" width="80">
<template #default="{ }">
<el-button type="info" :icon="Bottom"></el-button>
</template>
</el-table-column>
<el-table-column label="操作">
<template #default="{ row, $index }">
<el-button :type="buttonTypes[$index].channel || 'info'" @click="toggleType(row, $index,'channel')">通道使能</el-button>
<el-button :type="buttonTypes[$index]?.harmonic || 'info'" @click="toggleType(row, $index, 'harmonic')">谐波使能</el-button>
<el-button :type="buttonTypes[$index]?.interHarmonic || 'info'" @click="toggleType(row, $index, 'interHarmonic')">间谐波使能</el-button>
<el-button :type="buttonTypes[$index]?.flicker || 'info'" @click="toggleType(row, $index, 'flicker')">闪变使能</el-button>
<el-button :type="buttonTypes[$index]?.transient || 'info'" @click="toggleType(row, $index, 'transient')">暂态使能</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<el-tabs type="border-card" class="right-tabs" style="height: 100%;">
<el-tab-pane label="全局设置菜单">
<!-- 全局设置菜单内容 -->
<div class="form-item-container">
<el-form-item label="频率(Hz)" prop='name'>
<el-input />
</el-form-item>
</div>
<div class="button-label-container">
<label>参考设定值列表:</label>
<el-button type="primary" :icon='EditPen' @click="openDialog">编辑</el-button>
</div>
</el-tab-pane>
</el-tabs>
</div>
<div style="margin-top: 20px;">
<el-tabs type="border-card" class="custom-tabs">
<el-tab-pane label="电压/电流编辑">
<TestScriptVolCurTab/>
</el-tab-pane>
<el-tab-pane label="谐波编辑">
<TestScriptHarmTab/>
</el-tab-pane>
<el-tab-pane label="间谐波编辑">
<TestScriptInHarmTab/>
</el-tab-pane>
<el-tab-pane label="闪变编辑">
<TestScriptFlickerTab/>
</el-tab-pane>
<el-tab-pane label="暂态编辑">
<TestScriptDipTab/>
</el-tab-pane>
</el-tabs>
</div>
<SetValueTable ref="setValueTable"/>
<template #footer>
<div >
<el-button @click='close()'> </el-button>
<el-button type="primary" @click='save()'>保存</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { dialogBig } from '@/utils/elementBind'
import { onMounted, reactive, ref } from 'vue'
import SetValueTable from '@/views/machine/testScript/components/setValueTable.vue';
import {EditPen,ArrowDown, Bottom} from '@element-plus/icons-vue'
import { type TabsInstance } from 'element-plus';
import TestScriptVolCurTab from '@/views/machine/testScript/components/testScriptVolCurTab.vue';
import TestScriptHarmTab from '@/views/machine/testScript/components/testScriptHarmTab.vue';
import TestScriptInHarmTab from '@/views/machine/testScript/components/testScriptInHarmTab.vue';
import TestScriptFlickerTab from '@/views/machine/testScript/components/testScriptFlickerTab.vue';
import TestScriptDipTab from '@/views/machine/testScript/components/testScriptDipTab.vue';
const dialogVisible = ref(false)
const dialogTitle = ref()
const setValueTable = ref()
const buttonTypeOptions = ['default', 'text', 'success', 'warning', 'info', 'primary', 'danger'] as const;
type ButtonType = typeof buttonTypeOptions[number];
// 初始化按钮类型
const buttonTypes = reactive<{ [key: number]: { channel: ButtonType, harmonic: ButtonType, interHarmonic: ButtonType, flicker: ButtonType, transient: ButtonType } }>({});
const tableData= [
{ sort: 'L1', frequency: 'V', L1: '电压:57.75V 相角:0°'},
{ sort: 'L1', frequency: 'I', L1: '电压:57.75V 相角:0°'},
{ sort: 'L2', frequency: 'V', L1: '电压:57.75V 相角:0°'},
{ sort: 'L2', frequency: 'I', L1: '电压:57.75V 相角:0°'},
{ sort: 'L3', frequency: 'V', L1: '电压:57.75V 相角:0°'},
{ sort: 'L3', frequency: 'I', L1: '电压:57.75V 相角:0°'},
]
// 定义 span-method 逻辑
const arraySpanMethod = ({ rowIndex, columnIndex }: { rowIndex: number; columnIndex: number }) => {
if (columnIndex === 0 || columnIndex === 3) { // 第一列
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1
};
} else {
return {
rowspan: 0,
colspan: 0
};
}
}
};
// 切换按钮类型
const toggleType = (row: any, $index: number, buttonType: 'channel' | 'harmonic' | 'interHarmonic' | 'flicker' | 'transient') => {
if ($index !== undefined) {
const currentType = buttonTypes[$index][buttonType];
buttonTypes[$index][buttonType] = currentType === 'info' ? 'primary' : 'info';
}
};
// 关闭弹窗
const close = () => {
dialogVisible.value = false
}
// 保存数据
const save = () => {
}
// 打开弹窗,可能是新增,也可能是编辑
const open = (sign: string,row: any) => {
dialogVisible.value = true
dialogTitle.value = sign === 'add'? '新增检测项目信息' : '编辑检测项目信息'
// 初始化按钮类型
tableData.forEach((_, index) => {
buttonTypes[index] = {
channel: 'info',
harmonic: 'info',
interHarmonic: 'info',
flicker: 'info',
transient: 'info'
};
});
}
// 打开 drawer(新增、编辑)
const openDialog = () => {
setValueTable.value?.open()
}
// 对外映射
defineExpose({ open })
</script>
<style scoped>
.dialog-content {
display: flex;
justify-content: flex-start;
align-items: stretch;
height: 100%;
}
.tabs-container {
display: flex;
flex-direction: row;
height: 100%;
width: 100%;
}
.left-tabs {
flex: 3; /* 左侧 tab 占据 3/4 的宽度 */
margin-right: 10px; /* 可选:添加间距 */
}
.right-tabs {
flex: 1; /* 右侧 tab 占据 1/4 的宽度 */
}
.form-item-container {
display: flex;
justify-content: center; /* 水平居中 */
margin-bottom: 10px; /* 可选:添加间距 */
}
.button-label-container {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
.button-label-container label {
margin-right: 10px; /* 按钮和文字之间的距离 */
}
</style>

View File

@@ -0,0 +1,266 @@
<template>
<div class="divider-container">
<el-divider style="width: 400px">检测脚本信息</el-divider>
<el-divider style="width: 1300px">检测项目概要信息</el-divider>
</div>
<div class="data-check-content">
<div class="content-tree" >
<el-tree
:default-expanded-keys="['0', '0-1', '0-2', '0-3', '1']"
node-key="id"
:data="data"
:props="defaultProps"
@node-click="handleNodeClick" />
</div>
<div class="content-right-Tabs" style="height: 470px;width: 100px;">
<el-tabs type="border-card" style="height: 100%;">
<el-tab-pane
v-for="tab in props.options"
:key="tab.name"
:label="tab.label.replace(/准确度|检测/g, '')"
:name="tab.name">
<!-- 频率tab -->
<el-tabs type="border-card" style="height: 400px;">
<el-tab-pane
v-for="subTab in tab.children || []"
:key="subTab.name"
:label="subTab.label"
:name="subTab.name">
<!-- 子标签页内容 -->
<div class="dialog-footer">
<el-button :icon='CirclePlus' type="primary" @click="openDialog('add')">新增</el-button>
</div>
<div class="table-container">
<el-table :data="tableData"
:header-cell-style="{ textAlign: 'center',backgroundColor: '#003078',color: '#fff' } "
:cell-style="{ textAlign: 'center' }"
style="width: 100%"
:style="{ height: '240px',overflow:'hidden'}">
<el-table-column prop="sort" label="组次" width="60" />
<el-table-column prop="frequency" label="频率(Hz)" width="100" />
<el-table-column prop="L1" label="L1"/>
<el-table-column prop="L2" label="L2"/>
<el-table-column prop="L3" label="L3"/>
<el-table-column label="操作" min-width="100">
<template #default="{ row }">
<el-button type="primary" link :icon='CopyDocument' @click="copyRow(row)">复制</el-button>
<el-button type="primary" link :icon='CopyDocument' @click="openAddDialog('edit',row)">编辑</el-button>
<el-button type='primary' link :icon='Delete' @click="deleteRow(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="dialog-footer" style="margin-top: 20px;">
<el-button :icon='CirclePlus' type="primary" @click="openAddDialog()">保存测试项</el-button>
</div>
</el-tab-pane>
</el-tabs>
</el-tab-pane>
</el-tabs>
</div>
</div>
<TestProjectPopup ref="testProjectPopup" />
</template>
<script setup lang="ts">
import { type PropType, ref } from 'vue';
import { data } from "@/api/plan/autoTest.json";
import type { CascaderOption } from 'element-plus';
import {CirclePlus, Delete, EditPen,CopyDocument} from '@element-plus/icons-vue'
import type { TestScript } from '@/api/device/interface/testScript';
import TestProjectPopup from '@/views/machine/testScript/components/testProjectPopup.vue';
const testProjectPopup = ref()
interface TabOption {
label: string;
name: string;
children?: TabOption[];
}
const props = defineProps({
options: {
type: Array as PropType<TabOption[]>,
required: true
},
});
const tableData= [
{ sort: 1, frequency: 42.5, L1: '电压:57.75V 相角:0°', L2: '电压:57.75V 相角:120°', L3: '电压:57.75V 相角:-120°' },
{ sort: 2, frequency: 50, L1: '电压:57.75V 相角:0°', L2: '电压:57.75V 相角:120°', L3: '电压:57.75V 相角:-120°' },
{ sort: 3, frequency: 50.05, L1: '电压:57.75V 相角:0°', L2: '电压:57.75V 相角:120°', L3: '电压:57.75V 相角:-120°' },
{ sort: 4, frequency: 57.5, L1: '电压:57.75V 相角:0°', L2: '电压:57.75V 相角:120°', L3: '电压:57.75V 相角:-120°' },
{ sort: 5, frequency: 57.5, L1: '电压:57.75V 相角:0°', L2: '电压:57.75V 相角:120°', L3: '电压:57.75V 相角:-120°' },
{ sort: 6, frequency: 57.5, L1: '电压:57.75V 相角:0°', L2: '电压:57.75V 相角:120°', L3: '电压:57.75V 相角:-120°' },
]
const tabs = ref([
{
label: '频率',
name: 'resultTab',
subTabs: [
{ label: '额度工作条件下的检测', name: 'quotaConditionTab' },
{ label: '电压对频率测量的影响', name: 'voltageFrequencyImpactTab' },
{ label: '谐波对频率测量的影响', name: 'harmonicFrequencyImpactTab' }
]
},
{
label: '电压',
name: 'resultTab1',
subTabs: [
{ label: '额度工作条件下的检测', name: 'quotaConditionTab1' },
{ label: '电压对频率测量的影响', name: 'voltageFrequencyImpactTab1' },
{ label: '谐波对频率测量的影响', name: 'harmonicFrequencyImpactTab1' }
]
},
{
label: '电流',
name: 'resultTab2',
subTabs: [
{ label: '额度工作条件下的检测', name: 'quotaConditionTab2' },
{ label: '电压对频率测量的影响', name: 'voltageFrequencyImpactTab2' },
{ label: '谐波对频率测量的影响', name: 'harmonicFrequencyImpactTab2' }
]
},
{
label: '电压不平衡度',
name: 'resultTab3',
subTabs: [
{ label: '额度工作条件下的检测', name: 'quotaConditionTab3' },
{ label: '电压对频率测量的影响', name: 'voltageFrequencyImpactTab3' },
{ label: '谐波对频率测量的影响', name: 'harmonicFrequencyImpactTab3' }
]
},
{
label: '电流不平衡度',
name: 'resultTab4',
subTabs: [
{ label: '额度工作条件下的检测', name: 'quotaConditionTab4' },
{ label: '电压对频率测量的影响', name: 'voltageFrequencyImpactTab4' },
{ label: '谐波对频率测量的影响', name: 'harmonicFrequencyImpactTab4' }
]
},
{
label: '谐波电压',
name: 'resultTab5',
subTabs: [
{ label: '额度工作条件下的检测', name: 'quotaConditionTab5' },
{ label: '电压对频率测量的影响', name: 'voltageFrequencyImpactTab5' },
{ label: '谐波对频率测量的影响', name: 'harmonicFrequencyImpactTab5' }
]
},
{
label: '谐波电流',
name: 'resultTab6',
subTabs: [
{ label: '额度工作条件下的检测', name: 'quotaConditionTab6' },
{ label: '电压对频率测量的影响', name: 'voltageFrequencyImpactTab6' },
{ label: '谐波对频率测量的影响', name: 'harmonicFrequencyImpactTab6' }
]
},
{
label: '间谐波电压',
name: 'resultTab7',
subTabs: [
{ label: '额度工作条件下的检测', name: 'quotaConditionTab7' },
{ label: '电压对频率测量的影响', name: 'voltageFrequencyImpactTab7' },
{ label: '谐波对频率测量的影响', name: 'harmonicFrequencyImpactTab7' }
]
},
{
label: '间谐波电流',
name: 'resultTab8',
subTabs: [
{ label: '额度工作条件下的检测', name: 'quotaConditionTab8' },
{ label: '电压对频率测量的影响', name: 'voltageFrequencyImpactTab8' },
{ label: '谐波对频率测量的影响', name: 'harmonicFrequencyImpactTab8' }
]
},
{
label: '电压暂升暂降',
name: 'resultTab9',
subTabs: [
{ label: '额度工作条件下的检测', name: 'quotaConditionTab9' },
{ label: '电压对频率测量的影响', name: 'voltageFrequencyImpactTab9' },
{ label: '谐波对频率测量的影响', name: 'harmonicFrequencyImpactTab9' }
]
},
{
label: '闪变',
name: 'resultTab10',
subTabs: [
{ label: '额度工作条件下的检测', name: 'quotaConditionTab10' },
{ label: '电压对频率测量的影响', name: 'voltageFrequencyImpactTab10' },
{ label: '谐波对频率测量的影响', name: 'harmonicFrequencyImpactTab10' }
]
}
]);
const defaultProps = {
children: "children",
label: "name",
pid: "pid",
};
const handleNodeClick = (data: any) => {
console.log(data);
};
// 打开 drawer(新增、编辑)
const openDialog = (titleType: string, row: Partial<TestScript.ResTestScript> = {}) => {
testProjectPopup.value?.open(titleType, row)
}
</script>
<style scoped>
.data-check-content {
display: flex;
gap: 10px;
}
.content-tree {
width: 300px;
height: 470px;
border: 1px solid #dcdfe6;
border-radius: 4px;
margin-right: 10px;
overflow: auto; /* 同时启用垂直和水平滚动 */
overflow-x: auto; /* 确保水平滚动条生效 */
}
/* 确保 el-tree 内容可以超出容器宽度 */
.el-tree {
width: fit-content; /* 根据内容自适应宽度 */
}
.content-right-Tabs {
flex: 1; /* 根据需要调整宽度比例 */
}
.dialog-footer{
display: flex;
justify-content: flex-end;
margin-bottom: 10px;
}
.divider-container {
display: flex;
}
.divider-container .el-divider {
margin-right: 30px; /* 根据需要调整间距 */
}
</style>

View File

@@ -0,0 +1,41 @@
<template>
<div class="editor-container">
<div class="left-editor">
<!-- 左侧编辑区域内容 -->
<canvas ref="canvas" width="600" height="165"></canvas>
</div>
<div class="right-editor">
<!-- 右侧编辑区域内容 -->
<el-form-item label="设定幅度(%)">
<el-input v-model="input1" />
</el-form-item>
<el-form-item label="持续时间(周波)">
<el-input v-model="input2" />
</el-form-item>
</div>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
canvas {
border: 1px solid #ccc;
}
.editor-container {
display: flex;
height: 100%;
}
.left-editor {
flex: 3; /* 左侧区域占据 3/4 的宽度 */
margin-right: 10px; /* 可选:添加间距 */
}
.right-editor {
flex: 1; /* 右侧区域占据 1/4 的宽度 */
}
</style>

View File

@@ -0,0 +1,75 @@
<template>
<div class="tabs-container">
<el-tabs type="border-card" class="fixed-width-tabs" style="height: 100%;">
<el-tab-pane label="Modulation">
<!-- 全局设置菜单内容 -->
<div>
<el-form-item label="电压变动幅度(%)" prop='name'>
<el-input style="width: 200px;" />
</el-form-item>
</div>
<div class="form-container">
<el-form-item label="波动频度(/min/Hz)" prop='name'>
<el-input />
</el-form-item>
<el-form-item label="波动类型" prop='name'>
<el-input />
</el-form-item>
</div>
</el-tab-pane>
</el-tabs>
<el-tabs type="border-card" class="fixed-width-tabs" style="height: 100%;">
<el-tab-pane label="WaveForm">
<!-- 全局设置菜单内容 -->
<div >
<el-form-item label="波类型" prop='name'>
<el-input />
</el-form-item>
</div>
<div >
<el-form-item label="占空比(%)" prop='name'>
<el-input />
</el-form-item>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
.form-container {
display: flex;
justify-content: space-between; /* 使两个 el-form-item 之间有间距 */
align-items: center; /* 使两个 el-form-item 垂直居中对齐 */
}
.tabs-container {
display: flex;
justify-content: center; /* 使两个 el-tabs 居中对齐 */
align-items: stretch; /* 使两个 el-tabs 高度拉伸 */
height: 100%;
padding: 0 20px; /* 可选:添加左右间距 */
}
.fixed-width-tabs {
margin-right: 100px; /* 可选:添加右侧间距 */
}
.fixed-width-tabs:last-child {
margin-right: 0; /* 最后一个 el-tabs 不需要右侧间距 */
}
.el-tab-pane {
display: flex;
flex-direction: column; /* 确保内容上下排列 */
}
.el-form-item {
margin-bottom: 20px; /* 可选:添加表单项之间的间距 */
}
</style>

View File

@@ -0,0 +1,135 @@
<template>
<div class="tabs-container">
<el-tabs type="border-card" class="right-tabs" style="height: 100%;">
<el-tab-pane label="电压通道">
<!-- 电压通道内容 -->
<div class="table-container">
<el-table :data="tableData1" border class="half-width-table">
<el-table-column prop="date" label="次数" width="60"/>
<el-table-column prop="date" label="谐波含有率" width="125">
<template #default="scope">
<el-input />
</template>
</el-table-column>
<el-table-column prop="name" label="谐波相角" width="125">
<template #default="scope">
<el-input />
</template>
</el-table-column>
</el-table>
<el-table :data="tableData2" border class="half-width-table">
<el-table-column prop="date" label="次数" width="60"/>
<el-table-column prop="date" label="谐波含有率" width="125">
<template #default="scope">
<el-input />
</template>
</el-table-column>
<el-table-column prop="name" label="谐波相角" width="125">
<template #default="scope">
<el-input />
</template>
</el-table-column>
</el-table>
</div>
</el-tab-pane>
</el-tabs>
<el-tabs type="border-card" style="height: 100%;">
<el-tab-pane label="电流通道">
<!-- 电流通道内容 -->
<div class="table-container">
<el-table :data="tableData1" border class="half-width-table">
<el-table-column prop="date" label="次数" width="60"/>
<el-table-column prop="date" label="谐波含有率" width="125">
<template #default="scope">
<el-input />
<label>123%</label>
</template>
</el-table-column>
<el-table-column prop="name" label="谐波相角" width="125">
<template #default="scope">
<el-input />
</template>
</el-table-column>
</el-table>
<el-table :data="tableData2" border class="half-width-table">
<el-table-column prop="date" label="次数" width="60"/>
<el-table-column prop="date" label="谐波含有率" width="125">
<template #default="scope">
<el-input />
</template>
</el-table-column>
<el-table-column prop="name" label="谐波相角" width="125">
<template #default="scope">
<el-input />
</template>
</el-table-column>
</el-table>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
// 定义表格数据项的类型
interface TableItem {
date: string;
harmonicRate?: string;
harmonicPhase?: string;
name?: string;
}
// 定义并初始化 tableData
const tableData1 = ref<TableItem[]>([]);
const tableData2 = ref<TableItem[]>([]);
for (let i = 1; i <= 25; i++) {
tableData1.value.push({
date: i.toString(),
harmonicRate: `谐波含有率${i}`,
harmonicPhase: `谐波相角${i}`
});
}
for (let i = 26; i <= 50; i++) {
tableData2.value.push({
date: i.toString(),
harmonicRate: `谐波含有率${i}`,
harmonicPhase: `谐波相角${i}`
});
}
</script>
<style scoped>
.tabs-container {
display: flex;
justify-content: space-between; /* 使两个 el-tabs 之间有间距 */
height: 100%;
}
.right-tabs {
flex: 1; /* 使两个 el-tabs 占据相同的空间 */
margin-right: 10px; /* 可选:添加右侧间距 */
}
.el-tabs {
flex: 1; /* 使两个 el-tabs 占据相同的空间 */
}
.table-container {
display: flex;
justify-content: space-between; /* 使两个表格之间有间距 */
width: 100%;
}
.half-width-table {
flex: 1; /* 使两个表格占据相同的空间 */
margin-right: 10px; /* 可选:添加表格之间的间距 */
}
.half-width-table:last-child {
margin-right: 0; /* 最后一个表格不需要右侧间距 */
}
</style>

View File

@@ -0,0 +1,66 @@
<template>
<div class="tabs-container">
<el-tabs type="border-card" class="fixed-width-tabs" style="height: 100%;">
<el-tab-pane label="间谐波A">
<!-- 全局设置菜单内容 -->
<div>
<el-form-item label="含有率(%)" prop='name'>
<el-input />
</el-form-item>
</div>
<div>
<el-form-item label="间谐波次数" prop='name'>
<el-input />
</el-form-item>
</div>
</el-tab-pane>
</el-tabs>
<el-tabs type="border-card" class="fixed-width-tabs" style="height: 100%;">
<el-tab-pane label="间谐波B">
<!-- 全局设置菜单内容 -->
<div>
<el-form-item label="含有率(%)" prop='name'>
<el-input />
</el-form-item>
</div>
<div>
<el-form-item label="间谐波次数" prop='name'>
<el-input />
</el-form-item>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
.tabs-container {
display: flex;
justify-content: center; /* 使两个 el-tabs 居中对齐 */
align-items: stretch; /* 使两个 el-tabs 高度拉伸 */
height: 100%;
padding: 0 20px; /* 可选:添加左右间距 */
}
.fixed-width-tabs {
width: 400px; /* 设置固定的宽度 */
margin-right: 100px; /* 可选:添加右侧间距 */
}
.fixed-width-tabs:last-child {
margin-right: 0; /* 最后一个 el-tabs 不需要右侧间距 */
}
.el-tab-pane {
display: flex;
flex-direction: column; /* 确保内容上下排列 */
}
.el-form-item {
margin-bottom: 20px; /* 可选:添加表单项之间的间距 */
}
</style>

View File

@@ -1,45 +1,87 @@
<template>
<el-dialog title="请确认检测脚本值类型" v-model='dialogVisible' @close="close" v-bind="dialogSmall">
<div>
<el-form :model="formContent" ref='dialogFormRef'>
<el-form-item label="检测脚本值类型" >
<el-select clearable placeholder="请选择类型检测脚本值类型" >
<el-option label="相对值" :value="0"></el-option>
<el-option label="绝对值" :value="1"></el-option>
</el-select>
</el-form-item>
</el-form>
<el-dialog :title="dialogTitle"
v-model='dialogVisible'
@close="close"
v-bind="dialogBig"
width="1400px">
<div class="dialog-content" >
<el-form :model='formContent' label-width="auto" class="form-three ">
<el-divider >基础信息</el-divider>
<el-form-item label="脚本名称" prop='name'>
<el-input v-model='formContent.name' />
</el-form-item>
<el-form-item label="参照标准名称" prop='standardName'>
<el-input v-model='formContent.standardName' />
</el-form-item>
<el-form-item label="标准推行年份" prop='standardTime'>
<el-date-picker
v-model="formContent.standardTime"
type="year"
placeholder="请选择标准推行年份"
/>
</el-form-item>
</el-form>
</div>
<TestScriptDetail :options="secondLevelOptions" />
<template #footer>
<div >
<el-button @click='close()'> </el-button>
<el-button type="primary" @click='save()'>保存脚本</el-button>
<el-button type="primary" @click='save()'>脚本另存为</el-button>
</div>
<template #footer>
<div >
<el-button @click='close()'> </el-button>
<el-button type="primary" @click='save()'>新增</el-button>
</div>
</template>
</el-dialog>
</template>
</el-dialog>
</template>
<script setup lang='ts'>
import { dialogSmall } from '@/utils/elementBind'
import { ElMessage, type FormItemRule } from 'element-plus'
import { computed, reactive, type Ref, ref } from 'vue'
import { CirclePlus, Delete, EditPen } from '@element-plus/icons-vue'
import { dialogBig } from '@/utils/elementBind'
import { computed, ref } from 'vue'
import { useDictStore } from '@/stores/modules/dict'
import TestScriptDetail from '@/views/machine/testScript/components/testScriptDetail.vue';
import { type TestScript } from '@/api/device/interface/testScript';
import type { Dict } from '@/api/system/dictionary/interface';
import {getDictTreeList} from '@/api/system/dictionary/dictTree'
import type { CascaderOption } from 'element-plus';
const modeId = ref()
const secondLevelOptions: any[] = [];
// 定义弹出组件元信息
const dialogFormRef = ref()
const dictStore = useDictStore()
function useMetaInfo() {
const dialogVisible = ref(false)
const formContent = ref()
return { dialogVisible, formContent }
const titleType = ref('add')
const formContent = ref<TestScript.ResTestScript>({
name: '',
type: '',
valueType:'',
pattern: modeId.value,
standardName: '',
standardTime: '',
state:1,
})
return { dialogVisible, titleType,formContent }
}
const { dialogVisible, formContent } = useMetaInfo()
const { dialogVisible, titleType,formContent } = useMetaInfo()
let dialogTitle = computed(() => {
return titleType.value === 'add' ? '新增检测脚本' : '编辑检测脚本'
})
// 清空formContent
const resetFormContent = () => {
formContent.value = {
name: '',
type: '',
valueType:'',
pattern: modeId.value,
standardName: '',
standardTime: '',
state:1,
}
}
@@ -60,16 +102,57 @@ const dialogFormRef = ref()
// 打开弹窗,可能是新增,也可能是编辑
const open = (currentMode: string) => {
const open = async (sign: string,row: any,currentMode: string,id:string) => {
const dictCode = '测试脚本字典表'; // 替换为实际需要的字典代码
const resDictTree: Dict.ResDictTree = {
name: dictCode,
id: '',
pid: '',
pids: '',
code: '',
sort: 0
};
const result = await getDictTreeList(resDictTree);
//allOptions.value = convertToOptions(result.data as Dict.ResDictTree[]);
const allOptions = convertToOptions(result.data as Dict.ResDictTree[]);
// 提取第二层节点
allOptions.forEach(option => {
if (option.children && option.children.length > 0) {
secondLevelOptions.push(...option.children);
}
});
console.log('secondLevelOptions',secondLevelOptions);
if(id != ''){//新增的时候才会重新赋值值类型
formContent.value.valueType = id
}
titleType.value = sign
modeId.value = dictStore.getDictData('Pattern').find(item => item.name === currentMode)?.id;
// 重置表单
dialogFormRef.value?.resetFields()
dialogVisible.value = true
}
// 转换函数
const convertToOptions = (dictTree: Dict.ResDictTree[]): CascaderOption[] => {
return dictTree.map(item => ({
value: item.id,
label: item.name,
children: item.children ? convertToOptions(item.children) : undefined
}));
};
// 对外映射
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
}>()
</script>
<style scoped>
/* .dialog-content {
padding: 10px;
} */
</style>

View File

@@ -0,0 +1,44 @@
<template>
<div class="editor-container">
<div class="left-editor">
<!-- 左侧编辑区域内容 -->
<canvas ref="canvas" width="600" height="165"></canvas>
</div>
<div class="right-editor">
<!-- 右侧编辑区域内容 -->
<el-form-item label="电压有效值(V)">
<el-input v-model="input1" />
</el-form-item>
<el-form-item label="电流有效值(A)">
<el-input v-model="input1" />
</el-form-item>
<el-form-item label="相角(°)">
<el-input v-model="input2" />
</el-form-item>
</div>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
canvas {
border: 1px solid #ccc;
}
.editor-container {
display: flex;
height: 100%;
}
.left-editor {
flex: 3; /* 左侧区域占据 3/4 的宽度 */
margin-right: 10px; /* 可选:添加间距 */
}
.right-editor {
flex: 1; /* 右侧区域占据 1/4 的宽度 */
}
</style>

View File

@@ -0,0 +1,78 @@
<template>
<el-dialog title="请确认检测脚本值类型"
v-model='dialogVisible'
@close="close"
v-bind="dialogSmall"
>
<div class="dialog-content" >
<el-form>
<el-form-item label='值类型'>
<el-select v-model="selectedValue" filterable clearable placeholder="请选择值类型">
<el-option
v-for="item in dictStore.getDictData('Script_Value_Type')"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-form>
</div>
<TestScriptPopup ref='testScriptPopup' />
<template #footer>
<div >
<el-button @click='close()'> </el-button>
<el-button type="primary" @click='save()'>新增</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang='ts'>
import { dialogSmall } from '@/utils/elementBind'
import { ref } from 'vue'
import { useDictStore } from '@/stores/modules/dict'
import { type TestScript } from '@/api/device/interface/testScript';
const mode = ref()
const testScriptPopup = ref()
// 定义弹出组件元信息
const dialogFormRef = ref()
const dictStore = useDictStore()
const dialogVisible = ref(false)
const selectedValue = ref()
// 关闭弹窗
const close = () => {
dialogVisible.value = false
// 重置表单
dialogFormRef.value?.resetFields()
}
// 保存数据
const save = () => {
testScriptPopup.value?.open('新增检测脚本', {}, mode.value,selectedValue.value)
}
// 打开弹窗,可能是新增,也可能是编辑
const open = (sign: string,row: any,currentMode: string) => {
mode.value = currentMode
// 重置表单
dialogFormRef.value?.resetFields()
dialogVisible.value = true
}
// 对外映射
defineExpose({ open })
</script>
<style scoped>
/* .dialog-content {
padding: 10px;
} */
</style>

View File

@@ -9,9 +9,9 @@
<!-- 表格 header 按钮 -->
<template #tableHeader='scope'>
<el-button v-auth.testScript="'add'" type='primary' :icon='CirclePlus' @click="openDialog('add')">新增</el-button>
<el-button v-auth.testScript="'batchDelete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
<el-button v-auth.testScript="'delete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
@click='batchDelete(scope.selectedListIds)'>
批量删除
删除
</el-button>
</template>
<!-- 表格操作 -->
@@ -23,8 +23,9 @@
</ProTable>
</div>
<ComparisonPopup :refresh-table='proTable?.getTableList' ref='comparisonPopup' />
<TestScriptPopup :refresh-table='proTable?.getTableList' ref='testScriptPopup' />
<ComparisonPopup ref='comparisonPopup' />
<ValueTypePopup ref='valueTypePopup' />
<TestScriptPopup ref='testScriptPopup' />
</template>
@@ -37,6 +38,7 @@ import { CirclePlus, Delete, EditPen, Share } from '@element-plus/icons-vue'
import { useDictStore } from '@/stores/modules/dict'
import ComparisonPopup from './components/comparisonPopup.vue'
import TestScriptPopup from './components/testScriptPopup.vue'
import ValueTypePopup from './components/valueTypePopup.vue'
import {
getPqScriptList,updatePqScript,deletePqScript,
} from '@/api/device/testScript/index'
@@ -44,6 +46,7 @@ import { computed, reactive, ref } from 'vue'
import { useModeStore } from '@/stores/modules/mode'; // 引入模式 store
const comparisonPopup = ref()
const testScriptPopup = ref()
const valueTypePopup = ref()
const modeStore = useModeStore();
const dictStore = useDictStore()
@@ -112,9 +115,14 @@ const columns = reactive<ColumnProps<TestScript.ResTestScript>[]>([
// 打开 drawer(新增、编辑)
const openDialog = (titleType: string, row: Partial<TestScript.ResTestScript> = {}) => {
if(modeStore.currentMode == '比对式'){
comparisonPopup.value?.open(titleType, row)
comparisonPopup.value?.open(titleType, row,modeStore.currentMode,)
}else{
testScriptPopup.value?.open(titleType, row)
if(titleType == 'add'){
valueTypePopup.value?.open(titleType, row,modeStore.currentMode)
}else{
testScriptPopup.value?.open(titleType, row,modeStore.currentMode,'')
}
}

View File

@@ -15,15 +15,15 @@
:props="defaultProps"
/>
</el-form-item>
<el-form-item label="源参数描述" :label-width="100" prop="sourceParamDesc">
<el-input v-model="formContent.sourceParamDesc" autocomplete="off"/>
<el-form-item label="源参数描述" :label-width="100" prop="desc">
<el-input v-model="formContent.desc" autocomplete="off"/>
</el-form-item>
<el-form-item label="源参数类型" :label-width="100" prop="sourceParamType">
<el-input v-model="formContent.sourceParamType" autocomplete="off"/>
<el-form-item label="源参数类型" :label-width="100" prop="type">
<el-input v-model="formContent.type" autocomplete="off"/>
</el-form-item>
<el-form-item label="源参数值" :label-width="100"
prop="sourceParamValue">
<el-input v-model="formContent.sourceParamValue" autocomplete="off"/>
prop="value">
<el-input v-model="formContent.value" autocomplete="off"/>
</el-form-item>
<el-form-item label="排序" :label-width="100">
<el-input-number v-model="formContent.sort" :min='1' :max='999'/>
@@ -69,7 +69,7 @@ const displayPid = computed({
// 树形节点配置
const defaultProps = {
children: 'children',
label: 'sourceParamDesc',
label: 'desc',
value: 'id'
};
@@ -82,9 +82,9 @@ function useMetaInfo() {
const formContent = reactive<TestSource.ParameterType>({
id: "",
sourceParamType: "",
sourceParamDesc: "",
sourceParamValue: "",
type: "",
value: null,
desc: "",
sort: 100,
pId: "0",
})
@@ -93,8 +93,8 @@ function useMetaInfo() {
}
const rules: reactive<Record<string, Array<FormItemRule>>> = reactive({
sourceParamDesc: [{required: true, message: '源参数描述必填!', trigger: 'blur'}],
sourceParamType: [{required: true, message: '源参数类型必填!', trigger: 'blur'}],
desc: [{required: true, message: '源参数描述必填!', trigger: 'blur'}],
type: [{required: true, message: '源参数类型必填!', trigger: 'blur'}],
sort: [{required: true, message: '排序必填!', trigger: 'blur'}]
})
@@ -114,9 +114,9 @@ let dialogTitle = computed(() => {
const resetFormContent = () => {
Object.assign(formContent, {
id: "",
sourceParamType: "",
sourceParamDesc: "",
sourceParamValue: "",
type: "",
value: null,
desc: "",
sort: 100,
pId: "0",
})
@@ -140,7 +140,6 @@ const save = () => {
let newUpdateParameter = toRaw({...formContent})
delete newUpdateParameter.children
emit('get-parameter', newUpdateParameter)
ElMessage.success({message: `${dialogTitle.value}成功!`})
close()
}
})

View File

@@ -1,5 +1,5 @@
<template>
<div class='table-box'>
<div class='table-box' >
<ProTable
ref='proTable'
:columns='columns'
@@ -11,18 +11,18 @@
>
<!-- 表格 header 按钮 -->
<template #tableHeader='scope'>
<el-button v-auth.testSource="'add'" type='primary' :icon='CirclePlus' @click="openDialog('add')">新增
<el-button :disabled="isDisable" v-auth.testSource="'add'" type='primary' :icon='CirclePlus' @click="openDialog('add')">新增
</el-button>
<el-button v-auth.testSource="'batchDelete'" type='danger' :icon='Delete'
plain :disabled='!scope.isSelected' @click='batchDelete(scope.selectedListIds)'>
批量删除
<el-button v-auth.testSource="'delete'" type='danger' :icon='Delete'
plain :disabled='isDisable || !scope.isSelected' @click='batchDelete(scope.selectedListIds)'>
删除
</el-button>
</template>
<!-- 表格操作 -->
<template #operation='scope'>
<el-button type="primary" link :icon='CopyDocument' @click="copyRow(scope.row)">复制</el-button>
<el-button type='primary' link :icon='EditPen' @click="openDialog('edit', scope.row)">编辑</el-button>
<el-button type='primary' link :icon='Delete' @click='handleDelete(scope.row.id)'>删除</el-button>
<!-- <el-button type="primary" link :icon='CopyDocument' @click="copyRow(scope.row)">复制</el-button> -->
<el-button :disabled="isDisable" type='primary' link :icon='EditPen' @click="openDialog('edit', scope.row)">编辑</el-button>
<el-button :disabled="isDisable" type='primary' link :icon='Delete' @click='handleDelete(scope.row.id)'>删除</el-button>
</template>
</ProTable>
@@ -40,15 +40,23 @@ import ParameterPopup from '@/views/machine/testSource/components/parameterPopup
import {reactive, ref, watch} from 'vue'
import {generateUUID} from "@/styles";
import {defineEmits} from "vue/dist/vue";
import { ElMessage } from 'element-plus'
const parameterPopup = ref()
const dictStore = useDictStore()
// ProTable 实例
const proTable = ref<ProTableInstance>()
const tableData = ref<any[]>([])
const props = defineProps<{
parameterStr: string;
}>();
const props = defineProps({
parameterStr: {
type: String,
required: true,
},
isDisable: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(['change-parameter'])
@@ -105,20 +113,27 @@ const getTreeData = (data: TestSource.ParameterType[]): TestSource.ParameterType
}
const columns = reactive<ColumnProps<any>[]>([
{type: 'selection', fixed: 'left', width: 70},
{type: 'selection', fixed: 'left', width: 70,
selectable(row, index) {
if (props.isDisable) {
return false;
}
return true;
},
},
{type: 'index', fixed: 'left', width: 70, label: '序号'},
{
prop: 'sourceParamType',
prop: 'type',
label: '参数类型',
minWidth: 180,
},
{
prop: 'sourceParamDesc',
prop: 'desc',
label: '参数描述',
minWidth: 220,
},
{
prop: 'sourceParamValue',
prop: 'value',
label: '值',
minWidth: 150,
},
@@ -162,30 +177,38 @@ const copyRow = (row) => {
let parentIds = originalParameterArr.map(item => item.pId)
if (parentIds.includes(row.id)) {
let newParameterId = generateUUID()
let newParameterId = generateUUID().replaceAll("-","")
let children = originalParameterArr.filter(item => item.pId == row.id).map(item => ({
...item,
id: generateUUID(),
id: generateUUID().replaceAll("-",""),
pId: newParameterId
}))
originalParameterArr.push({...row, id: newParameterId})
originalParameterArr.push(...children)
} else {
originalParameterArr.push({...row, id: generateUUID(), pId: row.pId})
originalParameterArr.push({...row, id: generateUUID().replaceAll("-",""), pId: row.pId})
}
emit('change-parameter', originalParameterArr)
tableData.value = getTreeData(originalParameterArr)
}
const getParameter = (data: TestSource.ParameterType) => {
// if (originalParameterArr.some(item => item.type == data.type)) {
// ElMessage.error({message: '参数类型已存在!'})
// return;
// }
let index = originalParameterArr.findIndex(item => item.id === data.id)
if (index === -1) {
data.id = generateUUID()
data.id = generateUUID().replaceAll("-","")
// 新增
originalParameterArr.push(data)
ElMessage.success({message: '新增成功!'})
} else {
// 编辑
originalParameterArr[index] = data
ElMessage.success({message: '编辑成功!'})
}
emit('change-parameter', originalParameterArr)
tableData.value = getTreeData(originalParameterArr)
@@ -193,7 +216,6 @@ const getParameter = (data: TestSource.ParameterType) => {
//清空数据
const clearData = () => {
console.log('clearData')
originalParameterArr = []
tableData.value = []
}

View File

@@ -1,15 +1,8 @@
<template>
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig" >
<div height="800">
<el-form :model="formContent" ref='dialogFormRef' :rules='rules' >
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="检测源名称" prop="name" >
<el-input v-model='formContent.name' placeholder="检测源类型+设备类型简称+数字"/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="源型号" prop="devType" >
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig">
<div >
<el-form :model="formContent" ref='dialogFormRef' :rules='rules' :disabled="tableIsDisable" label-width="auto" class="form-three">
<el-form-item label="设备类型" prop="devType" >
<el-select v-model='formContent.devType' placeholder="请选择源型号">
<el-option
v-for="item in dictStore.getDictData(dictTypeCode)"
@@ -19,9 +12,7 @@
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="标准源" prop="type">
<el-form-item label="检测源类型" prop="type" >
<el-select v-model='formContent.type' placeholder="请选择检测源类型">
<el-option
v-for="item in dictStore.getDictData('Pq_Source_Type')"
@@ -31,16 +22,14 @@
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<ParameterTable :parameterStr="formContent.parameter" @change-parameter="changeParameter" ref="parameterTable"/>
<ParameterTable :parameterStr="formContent.parameter" @change-parameter="changeParameter" ref="parameterTable" :is-disable="tableIsDisable"/>
<template #footer>
<div>
<el-button @click='close()'> </el-button>
<el-button type="primary" @click='save()'>保存</el-button>
<el-button :disabled="tableIsDisable" @click='close()'> </el-button>
<el-button :disabled="tableIsDisable" type="primary" @click='save()'>保存</el-button>
</div>
</template>
</el-dialog>
@@ -61,14 +50,13 @@ const dictStore = useDictStore()
const mode = ref()
const modeId = ref()
const parameterTable = ref()
const tableIsDisable = ref(true)
function useMetaInfo() {
const dialogVisible = ref(false)
const titleType = ref('add')
const formContent = ref<TestSource.ResTestSource>({
id: '',
name: '',
pattern: modeId.value,
parameter: '',
type: '',
@@ -83,7 +71,6 @@ const {dialogVisible, titleType, formContent} = useMetaInfo()
const resetFormContent = () => {
formContent.value = {
id: '',
name: '',
pattern: modeId.value,
parameter: '',
type: '',
@@ -93,8 +80,20 @@ const resetFormContent = () => {
}
let dialogTitle = computed(() => {
return titleType.value === 'add' ? '新增检测源' : '编辑检测源'
})
switch (titleType.value) {
case 'add':
tableIsDisable.value = false
return '新增检测源';
case 'edit':
tableIsDisable.value = false
return '编辑检测源';
case 'view':
tableIsDisable.value = true
return '查看检测源';
default:
return ''; // 默认情况,可选
}
});
let dictTypeCode = computed(() => {
return 'S_Dev_Type_' + dictStore.getDictData('Pattern').find(item => item.id === modeId.value)?.code
@@ -121,6 +120,7 @@ const close = () => {
const save = () => {
try {
dialogFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
if (formContent.value.id) {
await updateTestSource(formContent.value);
@@ -157,7 +157,7 @@ const open = async (sign: string, data: TestSource.ResTestSource, currentMode: s
dialogFormRef.value?.resetFields()
}
const changeParameter = (parameterArr) => {
const changeParameter = (parameterArr: any) => {
formContent.value.parameter = JSON.stringify(parameterArr)
}

View File

@@ -9,13 +9,14 @@
<!-- 表格 header 按钮 -->
<template #tableHeader='scope'>
<el-button v-auth.testSource="'add'" type='primary' :icon='CirclePlus' @click="openDialog('add')">新增</el-button>
<el-button v-auth.testSource="'batchDelete'" type='danger' :icon='Delete'
<el-button v-auth.testSource="'delete'" type='danger' :icon='Delete'
plain :disabled='!scope.isSelected' @click='batchDelete(scope.selectedListIds)'>
批量删除
删除
</el-button>
</template>
<!-- 表格操作 -->
<template #operation='scope'>
<el-button v-auth.testSource="'view'" type='primary' link :icon='View' @click="openDialog('view', scope.row)">查看</el-button>
<el-button v-auth.testSource="'edit'" type='primary' link :icon='EditPen' @click="openDialog('edit', scope.row)">编辑</el-button>
<el-button v-auth.testSource="'delete'" type='primary' link :icon='Delete' @click='handleDelete(scope.row)'>删除</el-button>
</template>
@@ -49,6 +50,7 @@
const proTable = ref<ProTableInstance>()
const getTableList = (params: any) => {
console.log("getTableList",params)
let newParams = JSON.parse(JSON.stringify(params))
const patternId = dictStore.getDictData('Pattern').find(item=>item.name=== modeStore.currentMode)?.id//获取数据字典中对应的id
newParams.pattern = patternId
@@ -57,25 +59,26 @@
// 表格配置项
const columns = reactive<ColumnProps<TestSource.ResTestSource>[]>([
{ type: 'selection', fixed: 'left', width: 70 },
{ type: 'selection', fixed: 'left', width: 70 ,
},
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
{
prop: 'name',
label: '名称',
search: { el: 'input' },
minWidth: 180,
minWidth: 300,
},
{
prop: 'devType',
label: '源型号',
label: '设备类型',
enum: dictStore.getDictData('S_Dev_Type_'+dictStore.getDictData('Pattern').find(item=>item.name=== modeStore.currentMode)?.code),
fieldNames: { label: 'name', value: 'id' },
search: { el: 'select' },
minWidth: 220,
minWidth: 250,
},
{
prop: 'type',
label: '源类型',
label: '检测源类型',
enum: dictStore.getDictData('Pq_Source_Type'),
fieldNames: { label: 'name', value: 'id' },
search: { el: 'select' },
@@ -87,6 +90,7 @@
// 打开 drawer(新增、编辑)
const openDialog = (titleType: string, row: Partial<TestSource.ResTestSource> = {}) => {
testSourcePopup.value?.open(titleType, row,modeStore.currentMode)
}

View File

@@ -157,7 +157,7 @@ tableHeight.value = window.innerHeight - 630;
//检测状态数据
const checkStatusList = [
{
label: "未检",
label: "未检",
value: 0,
},
{
@@ -385,7 +385,7 @@ const columns = reactive<ColumnProps<User.ResUserList>[]>([
// width: 120,
// render: (scope) => {
// return scope.row.checkStatus == 1
// ? "未检"
// ? "未检"
// : scope.row.checkStatus == 2
// ? "检测中"
// : scope.row.checkStatus == 3

View File

@@ -25,7 +25,7 @@
</template>
<script setup lang='tsx' name='useRole'>
import { Device } from '@/api/device/interface/device.ts';
import { type Device } from '@/api/device/interface/device.ts';
import { useHandleData } from '@/hooks/useHandleData'
import { useDownload } from '@/hooks/useDownload'
import { useAuthButtons } from '@/hooks/useAuthButtons'

View File

@@ -1,12 +1,12 @@
<template>
<!-- 权限信息弹出框 -->
<el-dialog :model-value="dialogVisible" title="设备绑定" v-bind="dialogBig" @close="handleCancel" width="600" draggable>
<el-dialog title="设备绑定" v-model='dialogVisible' @close="close" v-bind="dialogBig" width="600" draggable>
<div>
<el-transfer v-model="value"
filterable
:filter-method="filterMethod"
filter-placeholder="请输入内容搜索"
:data="data"
:data="allData"
:titles="['未绑定设备', '已绑定设备']">
<template #default="{ option }">
<el-tooltip :content="option.tips" placement="top" :show-after=1000>
@@ -18,8 +18,8 @@
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleCancel">
<el-button @click="close()">取消</el-button>
<el-button type="primary" @click="save()">
保存
</el-button>
</div>
@@ -28,94 +28,70 @@
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { computed, ref } from 'vue'
import type { Device } from '@/api/device/interface'
import deviceDataList from '@/api/device/deviceData'
import { dialogBig } from '@/utils/elementBind'
import { getUnboundPqDevList,getBoundPqDevList } from '@/api/plan/plan.ts'
import { type Plan } from '@/api/plan/interface'
import { ElMessage } from 'element-plus'
const unboundPqDevList=ref<Device.ReqPqDevParams[]>([])//指定模式下所有未绑定的设备
const boundPqDevList=ref<Device.ReqPqDevParams[]>([])//根据检测计划id查询出所有已绑定的设备
const dialogVisible = ref(false)
const planData = ref<Plan.ReqPlan | null>(null) // 新增状态管理
const {dialogVisible} = defineProps<{
dialogVisible: boolean;
}>()
const value = ref<string[]>([])
const generateData = () => {
const unboundData = unboundPqDevList.value.map((i: Device.ReqPqDevParams) => ({
key: i.id,
label: i.name,
tips: i.description
}))
const boundData = boundPqDevList.value.map((i: Device.ReqPqDevParams) => ({
key: i.id,
label: i.name,
tips: i.description
}))
interface Option {
key: number
label: string
initial: string
tips: string
}
return [...unboundData, ...boundData]
const generateData = () => {
const data: Option[] = []
const states = [
'模拟装置1',
'模拟装置2',
'模拟装置3',
'模拟装置4',
'中电送检装置',
'易司拓测试装置',
'山大电力测试装置1',
'山大电力测试装置2',
'滚动条测试1',
'滚动条测试2',
'滚动条测试3',
'滚动条测试4',
'滚动条测试5',
'滚动条测试6',
]
const initials = ['CA', 'IL', 'MD', 'TX', 'FL', 'CO', 'CT', 'GT', 'IL', 'MD', 'TX', 'FL', 'CO', 'CT', 'GT']
states.forEach((city, index) => {
data.push({
label: city,
key: index,
initial: initials[index],
tips:"PQS882A 192.16.1.136",
})
})
return data
}
const generateValue = () => {
const data: number[] = []
const states = [
'山大电力测试装置1',
'山大电力测试装置2',
]
const initials = ['AB', 'CD']
states.forEach((city, index) => {
const key = states.indexOf(city)
if (key !== -1) {
data.push(key)
}
})
return data
}
// const generateValue = () => {
// const data: Option[] = []
// const states = [
// '山大电力测试装置1',
// '山大电力测试装置2',
// ]
// const initials = ['AB', 'CD']
// states.forEach((city, index) => {
// data.push({
// label: city,
// key: index,
// initial: initials[index],
// })
// })
// return data
// }
const data = ref<Option[]>(generateData())
const value = ref<number[]>(generateValue())
const emit = defineEmits<{
(e:'update:visible',value:boolean):void;
}>();
const allData = computed(() => generateData())
const handleCancel = () => {
emit('update:visible',false)
const filterMethod = (query: string, item: { label?: string }) => {
return item.label?.toLowerCase().includes(query.toLowerCase()) ?? false
}
// 打开弹窗,可能是新增,也可能是编辑
const open = async (data: Plan.ReqPlan) => {
dialogVisible.value = true
planData.value = data
const pqDevList_Result1 = await getUnboundPqDevList(data);
unboundPqDevList.value = pqDevList_Result1.data as Device.ReqPqDevParams[];
const pqDevList_Result2 = await getBoundPqDevList({'planId': data.id});
boundPqDevList.value = pqDevList_Result2.data as Device.ReqPqDevParams[];
value.value = boundPqDevList.value.map((i: { id: { toString: () => any } }) => i.id.toString());
}
const close = () => {
dialogVisible.value = false
}
const filterMethod = (query, item) => {
return item.label.toLowerCase().includes(query.toLowerCase())
const save = async () => {
if (planData.value) {
//await BindPqDevList({ 'planId': planData.value.id,'pqDevIds': value.value })
ElMessage.success({ message: `设备绑定保存成功成功!` })
}
dialogVisible.value = false
}
// 对外映射
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
}>()
</script>

View File

@@ -1,64 +1,53 @@
<template>
<div class="device-list-container" v-if="isShow">
<el-dropdown @command="handleCommand">
<el-button link type='primary' class='table-operate'>
<div class='table-operate-text'>更多...</div>
</el-button>
<!-- <span class="el-dropdown-link">
更多<el-icon class="el-icon--right"><arrow-down /></el-icon>
</span> -->
<el-dropdown>
<el-link link type='primary' class='table-operate'>
<div>更多...</div>
</el-link>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="高精度设备-PQV520-2">高精度设备-PQV520-2</el-dropdown-item>
<el-dropdown-item command="高精度设备-PQV520-3">高精度设备-PQV520-3</el-dropdown-item>
<el-dropdown-item command="高精度设备-PQV520-4">高精度设备-PQV520-4</el-dropdown-item>
<el-dropdown-item v-for="(name, index) in props.sourceNames" :key="index" @click="handleSourceClick(index)">
<el-link link type="primary">{{ name }}</el-link>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<!-- 查看误差体系详细信息 -->
<ErrorStandardDialog
:visible='detail_dialogFormVisible'
:formData='detail_dialogForm'
:dialogTitle='detail_dialogTitle'
@update:visible='detail_dialogFormVisible = $event'
/>
</div>
</template>
<script lang="ts" setup>
import { ElMessage } from 'element-plus'
import { ArrowDown } from '@element-plus/icons-vue'
import ErrorStandardDialog from '@/views/machine/errorSystem/components/errorStandardPopup.vue' // 导入子组件
import type { ErrorSystem } from '@/api/error/interface'
<script lang="ts" setup>
const detail_dialogFormVisible = ref(false)
const detail_dialogTitle = ref('Q/GDW 10650.2-2021 误差体系')
const detail_dialogForm = ref<ErrorSystem.Error_detail>({
measured: '',//被测量
deviceLevel: '',//检测装置级别
measurementType: '',
condition: '',//测量条件
maxErrorValue: '',//最大误差
})
const props = defineProps({
isShow: {
type: Boolean,
},
sourceNames: {
type: Array as () => string[],
},
sourceIds: {
type: Array as () => string[],
}
});
const props = defineProps<{
isShow: boolean;
}>();
console.log(props.isShow,1111)
const handleCommand = (command: string | number | object) => {
detail_dialogTitle.value = command as string;
detail_dialogFormVisible.value = true // 显示对话框
const emit = defineEmits<{
(e: 'source-clicked', id: string): void;
}>();
const handleSourceClick = (index: number) => {
if (props.sourceIds && props.sourceIds[index]) {
emit('source-clicked', props.sourceIds[index]);
} else {
//console.log('sourceIds is undefined or the index is out of bounds');
}
};
</script>
<style scoped>
.example-showcase .el-dropdown-link {
cursor: pointer;
color: var(--el-button-text-color);
.device-list-container {
display: flex;
justify-content: center;
align-items: center;
margin-left: 10px; /* 调整这个值以达到所需的效果 */
}
</style>

View File

@@ -1,196 +1,409 @@
<template>
<!-- 基础信息弹出框 -->
<el-dialog :model-value="visible" :title="dialogTitle" v-bind="dialogSmall" @close="handleCancel" width="500" draggable>
<div>
<el-form :model="formData" ref='formRuleRef' :rules='rules'>
<el-form-item label="名称" prop="name" :label-width="100">
<el-input v-model="formData.name" placeholder="请输入名称" autocomplete="off" :disabled="isReadOnly"/>
</el-form-item>
<!-- <el-form-item label="父计划" prop="father_Plan_Id" :label-width="100">
<el-select v-model="formData.father_Plan_Id" placeholder="请选择父计划" autocomplete="off" :disabled="isReadOnly" @change="fatherPlanChange">
<el-option
v-for="plan in testFatherPlanList"
:key="plan.id"
:label="plan.label"
:value="plan.id">
</el-option>
</el-select>
</el-form-item> -->
<el-form-item label='检测源' prop='source_Id' :label-width='100'>
<el-select v-model="formData.source_Id" multiple collapse-tags placeholder="请选择检测源">
<el-dialog :title="dialogTitle" v-model='dialogVisible' @close="close" v-bind="dialogBig">
<div>
<el-row :gutter="24">
<el-col :span="12">
<el-form :model="formContent" ref='dialogFormRef' :rules='rules'>
<el-form-item label="名称" prop="name" :label-width="100">
<el-input v-model="formContent.name" placeholder="请输入名称" autocomplete="off"/>
</el-form-item>
<el-form-item label='检测源' prop='sourceIds' :label-width='100'>
<el-select v-model="formContent.sourceIds" :multiple="selectByMode" collapse-tags placeholder="请选择检测源">
<el-option
v-for="plan in sourceDataList"
:key="plan.id"
:label="plan.label"
:value="plan.id"
/>
</el-select>
v-for="(option, index) in pqSourceArray"
:key="index"
:label="option.label"
:value="option.value"
/>
</el-select>
</el-form-item>
<el-form-item label="数据源" prop="dataSource_Id" :label-width="100">
<el-select v-model="formData.dataSource_Id" multiple collapse-tags placeholder="请选择数据源" autocomplete="off" :disabled="isReadOnly">
<el-option
v-for="plan in testSoureDataList"
:key="plan.id"
:label="plan.label"
:value="plan.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="检测脚本" prop="script_Id" :label-width="100">
<el-select v-model="formData.script_Id" placeholder="请选择检测脚本" autocomplete="off" :disabled="isReadOnly">
<el-option
v-for="plan in testScriptDataList"
:key="plan.id"
:label="plan.label"
:value="plan.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="误差体系" prop="error_Sys_Id" :label-width="100">
<el-select v-model="formData.error_Sys_Id" placeholder="请选择误差体系" autocomplete="off" :disabled="isReadOnly">
<el-option
v-for="plan in testErrSystDataList"
:key="plan.id"
:label="plan.label"
:value="plan.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label='被检设备' :label-width='100' prop='device_Id'>
<el-select v-model="formData.device_Id" multiple collapse-tags placeholder="请选择被检设备">
<el-form-item label="数据源" prop="datasourceIds" :label-width="100">
<el-select v-model="formContent.datasourceIds" :multiple="selectByMode" collapse-tags placeholder="请选择数据源" autocomplete="off">
<el-option
v-for="plan in deviceDataList"
:key="plan.id"
:label="plan.label"
:value="plan.id"
/>
</el-select>
v-for="item in dictStore.getDictData(dataSourceType)"
:key="item.id"
:label="item.name"
:value="item.value || ''"
/>
</el-select>
</el-form-item>
<el-form-item label='检测功能' :label-width='100' prop='device_Id'>
<el-checkbox v-model="checked1" label="守时检测" size="large" />
<el-form-item label="检测脚本" prop="scriptId" :label-width="100">
<el-select v-model="formContent.scriptId" placeholder="请选择检测脚本" autocomplete="off">
<el-option
v-for="(option, index) in pqScriptArray"
:key="index"
:label="option.label"
:value="option.value"
/>
</el-select>
</el-form-item>
</el-form>
<el-form-item label="误差体系" prop="errorSysId" :label-width="100">
<el-select v-model="formContent.errorSysId" placeholder="请选择误差体系" autocomplete="off">
<el-option
v-for="(option, index) in pqErrorArray"
:key="index"
:label="option.label"
:value="option.value"
/>
</el-select>
</el-form-item>
<el-form-item label="守时检测" :label-width="100" prop='timeCheck'>
<el-radio-group v-model="formContent.timeCheck">
<el-radio :value="1"></el-radio>
<el-radio :value="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</el-col>
<el-col :span="12">
<el-transfer
v-model="value"
filterable
:filter-method="filterMethod"
filter-placeholder="请输入内容搜索"
:data="allData"
:titles="['未绑定设备', '已绑定设备']">
<template #default="{ option }">
<el-tooltip :content="option.tips" placement="top" :show-after=1000>
<span>{{ option.label }}</span>
</el-tooltip>
</template>
</el-transfer>
</el-col>
</el-row>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click='close()'> </el-button>
<el-button type="primary" @click='save()'> </el-button>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="handleCancel"> </el-button>
<el-button type="primary" @click="handleSubmit" :disabled="isReadOnly"> </el-button>
</div>
</template>
</el-dialog>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import{ElMessage, FormInstance,FormItemRule}from'element-plus'
import { defineProps, defineEmits, reactive,watch,ref, Ref } from 'vue';
import { dialogSmall} from '@/utils/elementBind'
import {dictPattern,dictTestState,dictReportState,dictResult,testPlanDataList,sourceDataList,deviceDataList,testSoureDataList,testScriptDataList,testErrSystDataList,planData,testFatherPlanList} from '@/api/plan/planData'
const props = defineProps<{
visible: boolean;
dialogTitle: string;
isReadOnly: boolean,
formData: {
id:string;
name: string;
pattern: string; //模式,字典表(数字、模拟、比对)
father_Plan_Id: string; //父计划ID
source_Id: string;//检测源ID
dataSource_Id: string; //数据源ID
script_Id: string; //检测脚本ID
error_Sys_Id: string;//误差体系ID
device_Id: string;//被检设备ID
test_State: string; //检测状态
report_State: string; //报告生成状态
result: string;//检测结果
state: number; //状态
};
}>();
const checked1 = ref(false)
const fatherPlanList = [
{ label: '/', value: 'type0' },
{ label: '检测计划1', value: 'type1' },
{ label: '检测计划2', value: 'type2' },
{ label: '检测计划3', value: 'type3' },
{ label: '检测计划4', value: 'type4' },
];
const sourceList = [
{ label: '分钟统计数据最大值', value: 'type0' },
{ label: '分钟统计数据最大值', value: 'type1' },
{ label: '分钟统计数据CP95值', value: 'type2' },
];
const scriptList = [
{ label: '/', value: 'type0' },
{ label: '国网入网检测脚本(单影响量-模拟式)', value: 'type1' },
{ label: '国网入网检测脚本Q/GDW 10650.4 - 2021) 数字式', value: 'type1' },
];
const errorList = [
{ label: 'Q/GDW 1650.2- 2016', value: 'type0' },
{ label: 'Q/GDW 10650.2 - 2021', value: 'type1' },
];
import{ElMessage, type FormInstance,type FormItemRule}from'element-plus'
import { defineProps, defineEmits, reactive,watch,ref, type Ref, computed } from 'vue';
import { dialogBig} from '@/utils/elementBind'
import { type Plan } from '@/api/plan/interface';
import { addPlan, updatePlan,getUnboundPqDevList,getBoundPqDevList,getPqErrSysList,getPqScriptList,getTestSourceList } from '@/api/plan/plan.ts'
import { useDictStore } from '@/stores/modules/dict'
import { type TestSource } from '@/api/device/interface/testSource';
import { type TestScript } from '@/api/device/interface/testScript';
import { type ErrorSystem } from '@/api/device/interface/error';
import { type Device } from '@/api/device/interface/device';
import { Loading } from '@element-plus/icons-vue/dist/types';
const emit = defineEmits<{
(e: 'update:visible', value: boolean): void;
(e: 'submit', data: any): void;
}>();
const dictStore = useDictStore()
// 定义弹出组件元信息
const dialogFormRef = ref()
const mode = ref()
const selectByMode = ref(true)
const pqSourceList=ref<TestSource.ResTestSource[]>([])//获取指定模式下所有检测源
const pqScriptList=ref<TestScript.ResTestScript[]>([])//获取指定模式下所有检测源
const pqErrSysList=ref<ErrorSystem.ErrorSystemList[]>([])//获取指定模式下所有检测源
const pqDevList=ref<Device.ResPqDev[]>([])//获取指定模式下所有检测源
const pqSourceArray = ref<{ label: string; value: string; }[]>()
const pqScriptArray = ref<{ label: string; value: string; }[]>()
const pqErrorArray = ref<{ label: string; value: string; }[]>()
const pqDevArray = ref<{ label: string; value: string; }[]>()
const unboundPqDevList=ref<Device.ResPqDev[]>([])//指定模式下所有未绑定的设备
const boundPqDevList=ref<Device.ResPqDev[]>([])//根据检测计划id查询出所有已绑定的设备
const value = ref<string[]>([])
const allData = computed(() => generateData())
const generateData = () => {
const unboundData = unboundPqDevList.value.map((i: Device.ResPqDev) => ({
key: i.id,
label: i.name,
//tips: i.description
}))
const boundData = boundPqDevList.value.map((i: Device.ResPqDev) => ({
key: i.id,
label: i.name,
//tips: i.description
disabled:i.checkState != 0 ,
}))
return [...unboundData, ...boundData]
}
const filterMethod = (query: string, item: { label?: string }) => {
return item.label?.toLowerCase().includes(query.toLowerCase()) ?? false
}
function useMetaInfo() {
const dialogVisible = ref(false)
const titleType = ref('add')
const formContent = reactive<Plan.ReqPlan>({
id:'',
planId:'',
name: '',
pattern: mode.value,
fatherPlanId: '',
dataSourceId: '',
scriptId: '',
errorSysId: '',
timeCheck:0,
testState: 0,
reportState: 0,
result: 2,
code:1,
state:1,
scriptName:'',
errorSysName:'',
sourceName:'',
devIds:[],
sourceIds:'',
datasourceIds:'',
})
return { dialogVisible, titleType, formContent }
}
const { dialogVisible, titleType, formContent } = useMetaInfo()
// 清空formContent
const resetFormContent = () => {
Object.assign(
formContent,{
id:'',
planId:'',
name: '',
pattern: mode.value,
fatherPlanId: '',
dataSourceId: '',
scriptId: '',
errorSysId: '',
timeCheck:0,
testState: 0,
reportState: 0,
result: 2,
code:1,
state:1,
scriptName:'',
errorSysName:'',
sourceName:'',
devIds:[],
sourceIds:'',
datasourceIds:'',
}
)
}
let dialogTitle = computed(() => {
return titleType.value === 'add' ? '新增检测计划' : '编辑检测计划'
})
// 定义规则
const formRuleRef = ref<FormInstance>()
const rules: Ref<Record<string, Array<FormItemRule>>> = ref({
name: [{ required: true, message: '检测计划名称必填!', trigger: 'blur' }],
source_Id: [{ required: true, message: '检测源必选!', trigger: 'blur' }],
dataSource_Id: [{ required: true, message: '数据源必选!', trigger: 'blur' }],
script_Id: [{ required: true, message: '检测脚本必选!', trigger: 'blur' }],
error_Sys_Id: [{ required: true, message: '误差体系必选!', trigger: 'blur' }],
// name: [{ required: true, message: '检测计划名称必填!', trigger: 'blur' }],
// father_Plan_Id: [{ required: true, message: '参照标准名称必填!', trigger: 'change' }],
sourceIds: [{ required: true, message: '检测源必选!', trigger: 'blur' }],
datasourceIds: [{ required: true, message: '数据源必选!', trigger: 'blur' }],
scriptId: [{ required: true, message: '检测脚本必选!', trigger: 'blur' }],
errorSysId: [{ required: true, message: '误差体系必选!', trigger: 'blur' }],
});
const handleCancel = () => {
//重置表单内容
//取消表单校验状态
formRuleRef.value && formRuleRef.value.resetFields()
emit('update:visible', false); // 关闭对话框
};
// 关闭弹窗
const close = () => {
dialogVisible.value = false
// 清空dialogForm中的值
resetFormContent()
// 重置表单
dialogFormRef.value?.resetFields()
const handleSubmit = () => {
}
// 保存数据
const save = () => {
try {
formRuleRef.value?.validate((valid: boolean) => {
if (valid)
{
// 将表单数据转为json,发送到后端
let confirmFormData = JSON.parse(JSON.stringify(props.formData));
//console.log(confirmFormData)
emit('submit', props.formData); // 提交表单数据
emit('update:visible', false); // 提交后关闭对话框
}
else
{
ElMessage.error('请填选必填项!')
}
dialogFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
formContent.devIds = value.value
// 将 formContent.devIds 转换为 ReqPqDevParams 数组
// boundPqDevList.value = pqDevList.value
// .filter(device => formContent.devIds.includes(device.id))
// .map(device => ({
// id: device.id,
// name: device.name,
// devType: device.devType,
// createTime: device.createDate,
// pattern: device.pattern,
// }));
if (formContent.id) {
if( mode.value === '比对式'){
await updatePlan(formContent)
}else{
await updatePlan({...formContent,'sourceIds':[formContent.sourceIds],'datasourceIds':[formContent.datasourceIds]});
}
ElMessage.success({ message: `${dialogTitle.value}成功!` })
} else {
// 新增需要把设备模式转成字典ID
const patternItem = dictStore.getDictData('Pattern').find(item => item.name === formContent.pattern);
if (patternItem) {
formContent.pattern = patternItem.id;
}
if( mode.value === '比对式'){
await addPlan(formContent);
}else{
await addPlan({...formContent,'sourceIds':[formContent.sourceIds],'datasourceIds':[formContent.datasourceIds]});
}
ElMessage.success({ message: `${dialogTitle.value}成功!` })
}
close()
// 刷新表格
await props.refreshTable!()
}
})
} catch (error) {
console.error('验证过程中发生错误', error)
}
};
} catch (err) {
console.error('验证过程中出现错误', err)
}
}
// 当 props.visible 改变时,更新 formData
watch(() => props.visible, (newVal) => {
if (!newVal) {
// 这里可以重置表单数据,如果需要的话
// 打开弹窗,可能是新增,也可能是编辑
const open = async (sign: string,
data: Plan.ReqPlan,
currentMode: string,) => {
//处理异步调用
const patternId = dictStore.getDictData('Pattern').find(item=>item.name=== currentMode)?.id ?? ''
data.pattern = patternId
mode.value = currentMode
titleType.value = sign
if (data.id) {
Object.assign(formContent,{ ...data })
} else {
resetFormContent()
}
});
// 重置表单
dialogFormRef.value?.resetFields()
if(sign == 'add')
{
const [pqSource_Result, PqScript_Result, PqErrSys_Result,pqDevList_Result] = await Promise.all([
getTestSourceList(data),
getPqScriptList(data),
getPqErrSysList(),
getUnboundPqDevList(data)
]);
pqSourceList.value = pqSource_Result.data as TestSource.ResTestSource[];
pqScriptList.value = PqScript_Result.data as TestScript.ResTestScript[];
pqErrSysList.value = PqErrSys_Result.data as unknown as ErrorSystem.ErrorSystemList[];
pqDevList.value = pqDevList_Result.data as Device.ResPqDev[];
// 初始化 boundPqDevList 为空数组
unboundPqDevList.value = pqDevList.value
boundPqDevList.value = [];
}else{//编辑时先给表单赋值(这会没接收被检设备),需要手动再给被检设备复制后整体表单赋值
const [pqSource_Result, PqScript_Result, PqErrSys_Result,boundPqDevList_Result, unboundPqDevList_Result] = await Promise.all([
getTestSourceList(data),
getPqScriptList(data),
getPqErrSysList(),
getBoundPqDevList({ 'planId': data.id }),
getUnboundPqDevList(data)
]);
pqSourceList.value = pqSource_Result.data as TestSource.ResTestSource[];
pqScriptList.value = PqScript_Result.data as TestScript.ResTestScript[];
pqErrSysList.value = PqErrSys_Result.data as unknown as ErrorSystem.ErrorSystemList[];
const boundData = Array.isArray(boundPqDevList_Result.data) ? boundPqDevList_Result.data : [];
const unboundData = Array.isArray(unboundPqDevList_Result.data) ? unboundPqDevList_Result.data : [];
pqDevList.value = [...boundData,...unboundData] as Device.ResPqDev[];
formContent.devIds = boundData.map(i => i.id );// 已绑定设备id集合
Object.assign(formContent,{ ...data })
//设备绑定显示
unboundPqDevList.value = unboundPqDevList_Result.data as Device.ResPqDev[];
boundPqDevList.value = boundPqDevList_Result.data as Device.ResPqDev[];
}
pqToArray();//将对象转为数组
if( mode.value != '比对式'){
selectByMode.value = false
// 将 formContent.sourceIds 从数组转换为字符串
if (Array.isArray(formContent.sourceIds)) {
formContent.sourceIds = formContent.sourceIds.join(',');
}
// 将 formContent.sourceIds 从数组转换为字符串
if (Array.isArray(formContent.datasourceIds)) {
formContent.datasourceIds = formContent.datasourceIds.join(',');
}
}
value.value = boundPqDevList.value.map((i: { id: { toString: () => any } }) => i.id.toString());
// 所有数据加载完成后显示对话框
dialogVisible.value = true;
}
function pqToArray() {
const sourceArray1 = Array.isArray(pqSourceList.value) ? pqSourceList.value : []
// 将 pqSource_Result 转换成 { label, value } 数组
pqSourceArray.value = sourceArray1.map(item => ({
label: item.name || '',
value: item.id
}));
const sourceArray2 = Array.isArray(pqScriptList.value ) ? pqScriptList.value : []
pqScriptArray.value = sourceArray2.map(item => ({
label: item.name || '',
value: item.id || ''
}));
const sourceArray3 = Array.isArray(pqErrSysList.value) ? pqErrSysList.value : []
pqErrorArray.value = sourceArray3.map(item => ({
label: item.name,
value: item.id
}));
const sourceArray4 = Array.isArray(pqDevList.value) ? pqDevList.value : []
pqDevArray.value = sourceArray4.map(item => ({
label: item.name,
value: item.id
}))
}
const dataSourceType = computed(() => {
switch (mode.value) {
case '模拟式':
return 'Datasource_Simulate'
case '数字式':
return 'Datasource_Digital'
default:
return 'Datasource_Contrast'
}
})
// 对外映射
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
}>()
</script>
<style scoped>
<style scoped lang="scss">
// :deep(.dialog-small .el-dialog__body){
// max-height: 330px !important;
// }
</style>

View File

@@ -14,7 +14,6 @@
:data='testSourceData'
type='selection'
>
<!-- :request-api="getTableList" 如果要显示静态数据就切换该配置-->
<!-- 表格 header 按钮 -->
<template #tableHeader='scope'>
<el-button type='primary' :icon='Download' plain :disabled='!scope.isSelected' @click="exportClick">移入检测计划</el-button>

View File

@@ -3,7 +3,7 @@
<ProTable
ref='proTable'
:columns='columns'
:data='planData'
:request-api='getTableList'
>
<!-- 表格 header 按钮 -->
<template #tableHeader='scope'>
@@ -12,305 +12,269 @@
<el-button type='primary' :icon='ScaleToOriginal' :disabled='!(scope.selectedList.length > 1)' @click='combineClick'>
合并
</el-button>
<el-button type='primary' :icon='CirclePlus' @click='openAddDialog'>新增</el-button>
<el-button type='danger' :icon='Delete' plain :disabled='!scope.isSelected'>
批量删除
<el-button type='primary' :icon='CirclePlus' @click="openDialog('add')">新增</el-button>
<el-button type='danger' :icon='Delete' plain :disabled='!scope.isSelected' @click='batchDelete(scope.selectedListIds)'>
删除
</el-button>
<input type='file' style='display: none' ref='fileInput' @change='handleFiles'>
</template>
<!-- 表格操作 -->
<template #operation='scope'>
<!-- <el-button type='primary' link :icon='View' @click="handleRowClick(scope.row)">查看</el-button> -->
<!-- <el-button type='primary' link :icon='Upload' @click='exportClick'>导出</el-button> -->
<el-button type='primary' link :icon='EditPen' @click='openEditDialog(scope.row)'>编辑</el-button>
<el-button type='primary' link :icon='Delete' @click='openEditDialog(scope.row)'>删除</el-button>
<el-button type='primary' link :icon='List' @click='showDeviceOpen(scope.row)'>设备绑定</el-button>
<!-- <div class='cn-render-buttons'>
<el-dropdown trigger='click'>
<el-button link type='primary' class='table-operate'>
<div class='table-operate-text'>更多</div>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item :style="{color: 'var(--el-color-danger)'}" :icon='Delete'>
删除
</el-dropdown-item>
<el-dropdown-item :icon='List' @click='showDeviceOpen(scope.row)'>
设备绑定
</el-dropdown-item>
<el-dropdown-item :icon='Tools' @click='showtestSourceOpen(scope.row)'>
检测源绑定
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div> -->
<el-button type='primary' link :icon='EditPen' @click="openDialog('edit',scope.row)">编辑</el-button>
<el-button type='primary' link :icon='Delete' @click='handleDelete(scope.row)'>删除</el-button>
<!-- <el-button type='primary' link :icon='List' @click='showDeviceOpen(scope.row)'>设备绑定</el-button> -->
</template>
</ProTable>
<!-- 向计划导入/导出设备对话框 -->
<planPopup
:visible="dialogFormVisible"
:formData="dialogForm"
:dialogTitle="dialogTitle"
:is-read-only="isReadOnly"
@update:visible="dialogFormVisible = $event"
/>
<!-- 查看误差体系详细信息 -->
<ErrorStandardDialog
:visible='detail_dialogFormVisible'
:formData='detail_dialogForm'
:dialogTitle='detail_dialogTitle'
@update:visible='detail_dialogFormVisible = $event'
/>
</div>
<devTransfer
:dialogVisible=devTransferVisible
@update:visible='devTransferVisible = $event'
/>
<sourceTransfer
:dialogVisible=sourceTransferVisible
@update:visible='sourceTransferVisible = $event'
/>
<DeviceOpen :width='viewWidth' :height='viewHeight' ref='openDeviceView' />
<SourceOpen :width='viewWidth' :height='viewHeight' ref='openSourceView' />
<!-- 向计划导入/导出设备对话框 -->
<PlanPopup :refresh-table='proTable?.getTableList' ref='planPopup'/>
<!-- 查看误差体系详细信息 -->
<ErrorStandardPopup :refresh-table='proTable?.getTableList' ref="errorStandardPopup"/>
<!-- 查看检测源 -->
<TestSourcePopup :refresh-table='proTable?.getTableList' ref="testSourcePopup"/>
<!-- 查看设备绑定
<DevTransfer :refresh-table='proTable?.getTableList' ref='devTransferPopup'/> -->
<ImportExcel ref='deviceImportExcel' />
</template>
<script setup lang='tsx' name='useProTable'>
import ProTable from '@/components/ProTable/index.vue'
import TimeControl from '@/components/TimeControl/index.vue'
import type { ProTableInstance, ColumnProps } from '@/components/ProTable/interface'
import { ScaleToOriginal, CirclePlus, Delete, EditPen, View, Upload, Download, List, Tools } from '@element-plus/icons-vue'
import {
dictPattern,
dictTestState,
dictReportState,
dictResult,
testPlanDataList,
testSoureDataList,
testScriptDataList,
testErrSystDataList,
planData,
testFatherPlanList,
} from '@/api/plan/planData'
import { reactive, ref } from 'vue'
import {getPlanList,deletePlan,exportPlan,downloadTemplate,importPlan } from '@/api/plan/plan.ts'
import { computed, onMounted, reactive, ref } from 'vue'
import type { Plan } from '@/api/plan/interface'
import planPopup from '@/views/plan/planList/components/planPopup.vue' // 导入子组件
import PlanPopup from '@/views/plan/planList/components/planPopup.vue' // 导入子组件
import DeviceOpen from '@/views/plan/planList/components/devPopup.vue'
import SourceOpen from '@/views/plan/planList/components/sourcePopup.vue'
import moreButtons from './components/moreButtons.vue'
import devTransfer from './components/devTransfer.vue'
import sourceTransfer from './components/sourceTransfer.vue'
import DevTransfer from './components/devTransfer.vue'
import { useViewSize } from '@/hooks/useViewSize'
import { useRouter } from 'vue-router'
import { useDictStore } from '@/stores/modules/dict'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { Action } from 'element-plus'
import type { ErrorSystem } from '@/api/error/interface'
import ErrorStandardDialog from '@/views/machine/errorSystem/components/errorStandardPopup.vue' // 导入子组件
import ErrorStandardPopup from '@/views/machine/errorSystem/components/errorStandardPopup.vue' // 导入子组件
import TestSourcePopup from '@/views/machine/testSource/components/testSourcePopup.vue' // 导入子组件
import { type TestSource } from '@/api/device/interface/testSource'
import { useModeStore } from '@/stores/modules/mode'; // 引入模式 store
import { useHandleData } from '@/hooks/useHandleData'
import { dictTestState,dictReportState,dictResult } from '@/api/plan/planData.ts'
import {getTestSourceById} from '@/api/device/testSource/index'
import ImportExcel from "@/components/ImportExcel/index.vue";
import {useDownload} from "@/hooks/useDownload";
import {exportPqDev} from "@/api/device/device";
const dictStore = useDictStore()
// 定义包含和排除的单位
const includedUnits = ['日', '周', '月', '自定义'] // 可以根据需要包含的单位
const excludedUnits = ['季度', '年'] // 要排除的单位
const defaultUnits = '日' // 默认的单位
const { popupBaseView, viewWidth, viewHeight } = useViewSize()
const openDeviceView = ref()
const openSourceView = ref()
const devTransferVisible = ref(false)
const sourceTransferVisible = ref(false)
// ProTable 实例
const proTable = ref<ProTableInstance>()
// const planData = planData
const dialogFormVisible = ref(false)
const dialogTitle = ref('')
const isReadOnly = ref(false)
const router = useRouter()
const dialogForm = ref<Plan.PlanBO>({
id: '',
name: '',
pattern: '',
father_Plan_Id: '',
dataSource_Id: '',
script_Id: '',
error_Sys_Id: '',
test_State: '',
report_State: '',
result: '',
const errorStandardPopup = ref()
const testSourcePopup = ref()
const planPopup = ref()
const devTransferPopup = ref()
const modeStore = useModeStore();
const deviceImportExcel = ref<InstanceType<typeof ImportExcel> | null>(null)
const getTableList = async(params: any) => {
let newParams = JSON.parse(JSON.stringify(params))
const patternId = dictStore.getDictData('Pattern').find(item=>item.name=== modeStore.currentMode)?.id//获取数据字典中对应的id
newParams.pattern = patternId
return getPlanList(newParams)
}
const dataSourceType = computed(() => {
switch (modeStore.currentMode) {
case '模拟式':
return 'Datasource_Simulate'
case '数字式':
return 'Datasource_Digital'
default:
return 'Datasource_Contrast'
}
})
const detail_dialogFormVisible = ref(false)
const detail_dialogTitle = ref('Q/GDW 10650.2-2021 误差体系')
const detail_dialogForm = ref<ErrorSystem.Error_detail>({
measured: '',//被测量
deviceLevel: '',//检测装置级别
measurementType: '',
condition: '',//测量条件
maxErrorValue: '',//最大误差
})
// <el-button
// v-for="(button, index) in scope.row.testSourceList"
// :key="index"
// @click="handleClick(button)"
// >
// {{ button.text }}
// </el-button>
// 表格配置项
const columns = reactive<ColumnProps<Plan.PlanAndSourceBO>[]>([
const columns = reactive<ColumnProps<Plan.ReqPlan>[]>([
{ type: 'selection', fixed: 'left', width: 70 },
{ type: 'index', fixed: 'left', width: 70, label: '序号' },
{
prop: 'name',
label: '名称',
width: 200,
width: 220,
search: { el: 'input' },
},
{
prop: 'testSourceName',
prop: 'sourceName',
label: '检测源',
width: 215,
minWidth: 400,
render: scope => {
const sourceNames = Array.isArray(scope.row.sourceName) ? scope.row.sourceName : [];
const sourceIds = Array.isArray(scope.row.sourceIds) ? scope.row.sourceIds : [];
const firstSourceName = sourceNames[0];
const firstSourceId = sourceIds[0];
const remainingSourceNames = sourceNames.slice(1);
const remainingSourceIds = sourceIds.slice(1);
return (
<div class='flx-flex-start'>
<el-button type='primary' link onClick={() => showData(scope.row.testSourceName)}>
{scope.row.testSourceName}
</el-button>
<moreButtons isShow={isVisible(scope.row)} ></moreButtons>
</div>
<div class='flx-flex-start'>
{firstSourceName && (
<el-link type='primary' link onClick={() => showTestSource(firstSourceId)}>
{firstSourceName}
</el-link>
)}
<moreButtons isShow={isVisible(scope.row)}
sourceNames={remainingSourceNames}//长度>1传给更多子组件从第二位开始的名字
sourceIds={remainingSourceIds} //长度>1时传给更多子组件从第二位开始的id
onSource-clicked={showTestSource}
/>
</div>
)
},
},
{
prop: 'script_Id',
prop: 'scriptId',
label: '检测脚本',
width: 350,
enum: testScriptDataList,
fieldNames: { label: 'label', value: 'id' },
width: 360,
render: scope => {
return (
<el-button type='primary' link onClick={() => showData(scope.row.script_Id)}>
{getScriptName(scope.row.script_Id)}
</el-button>
<el-link type='primary' link onClick={() => showTestScript(scope.row.scriptId)}>
{scope.row.scriptName}
</el-link>
)
},
},
{
prop: 'error_Sys_Id',
prop: 'errorSysId',
label: '误差体系',
width: 200,
enum: testErrSystDataList,
fieldNames: { label: 'label', value: 'id' },
render: scope => {
const errSysName = getErrSysName(scope.row.error_Sys_Id)
return (
<el-button type='primary' link onClick={() => showData(errSysName || '')}>
{errSysName}
</el-button>
<el-link type='primary' link onClick={() => showData(scope.row.errorSysName || '')}>
{scope.row.errorSysName}
</el-link>
)
},
},
{
prop: 'dataSource_Ids',
prop: 'datasourceIds',
label: '数据源',
width: 200,
// enum: testSoureDataList,
// fieldNames: { label: 'label', value: 'id' },
enum: dictStore.getDictData(dataSourceType.value),
fieldNames: { label: 'name', value: 'value' },
minWidth: 250,
render: (scope) => {
const codes = scope.row.datasourceIds // 获取当前行的 datasourceIds 字段
if (!codes) {
return '/'
}
// 确保 codes 是一个字符串
const codeString = Array.isArray(codes) ? codes.join(',') : codes
const codeArray = codeString.split(',')
if (codeArray.length > 1) {
// 查找与每个 code 值匹配的 name然后拼接成逗号分割的字符串
const names = codeArray.map(code => {
const dictItem = dictStore.getDictData(dataSourceType.value).find(item => item.value === code)
return dictItem ? dictItem.name : '/' // 如果找到匹配的项,返回对应的 name
})
return names.join(', ') // 用逗号连接所有的 name
}
// 查找单个 code 对应的 name
const dictItem = dictStore.getDictData(dataSourceType.value).find(item => item.value === codeArray[0])
return dictItem ? dictItem.name : '/' // 如果找到匹配的项,返回对应的 name
},
},
{
prop: 'test_State',
prop: 'testState',
label: '检测状态',
width: 100,
enum: dictTestState,
// enum: dictStore.getDictData('planTestState'),
search: { el: 'select', props: { filterable: true } },
width: 120,
enum:dictTestState,
search: { el:'select',props: { filterable: true }},
fieldNames: { label: 'label', value: 'id' },
render: scope => {
return (
scope.row.testState === 0 ? '未检' : scope.row.testState === 1 ? '检测中' : '检测完成'
)
},
},
{
prop: 'report_State',
prop: 'reportState',
label: '检测报告状态',
width: 150,
enum: dictReportState,
// enum: dictStore.getDictData('planReportState'),
width: 120,
enum:dictReportState,
search: { el: 'select', props: { filterable: true } },
fieldNames: { label: 'label', value: 'id' },
render: scope => {
return (
scope.row.reportState === 0 ? '未生成' : scope.row.reportState === 1 ? '部分生成' : '全部生成'
)
},
},
{
prop: 'result',
label: '检测结果',
width: 100,
enum: dictResult,
// enum: dictStore.getDictData('planResult'),
width: 120,
enum:dictResult,
search: { el: 'select', props: { filterable: true } },
fieldNames: { label: 'label', value: 'id' },
render: scope => {
return (
scope.row.result === 0 ? '不符合' : scope.row.result === 1 ? '符合' : '/'
)
},
// {
// prop: 'father_Plan_Id',
// label: '父节点',
// width: 200,
// enum: testFatherPlanList,
// fieldNames: { label: 'label', value: 'id' },
// },
// {
// prop: 'create_Time',
// label: '记录时间',
// minWidth: 180,
// search: {
// span: 2,
// render: () => {
// return (
// <div class='flx-flex-start'>
// </div>
// )
// },
// },
// },
{ prop: 'operation', label: '操作', fixed: 'right', width: 250 },
},
{ prop: 'operation', label: '操作', fixed: 'right', width: 200 },
])
function getScriptName(id: string) {
return testScriptDataList.find(item => item.id == id)?.label
}
const handleSourceClicked = (id: string) => {
function getErrSysName(id: string) {
return testErrSystDataList.find(item => item.id == id)?.label
}
const fileInput = ref<HTMLInputElement | null>(null) // 声明 fileInput
function openFileDialog() {
if (fileInput.value) {
fileInput.value.click()
}
}
};
function isVisible(row: Plan.PlanAndSourceBO) {
console.log(row)
if(!row.hasOwnProperty('testSourceList') || !Array.isArray(row.testSourceList))
function isVisible(row: Plan.ReqPlan) {
if(!row.hasOwnProperty('sourceName') || !Array.isArray(row.sourceName)){
return false
else if(row.testSourceList.length <= 1)
}
else if(row.sourceName.length <= 1){
return false
else
}
else{
return true
}
}
function showData(row: string) {
detail_dialogTitle.value = row
detail_dialogFormVisible.value = true // 显示对话框
// router.push({
// path: "/machine/device",
// query: { id: row }
// });
errorStandardPopup.value?.open(row, row)
}
async function showTestSource(row:string) {
const patternId = dictStore.getDictData('Pattern').find(item=>item.name=== modeStore.currentMode)?.id ?? ''//获取数据字典中对应的id
const params: TestSource.ResTestSource = {
id: row, // 根据实际情况设
pattern: patternId,
type: '',
devType: '',
state: 0
};
const result = await getTestSourceById(params);
testSourcePopup.value?.open('view', result.data, modeStore.currentMode);
}
function showTestScript(row: string) {
}
function handleFiles(event: Event) {
const target = event.target as HTMLInputElement
const files = target.files
@@ -347,11 +311,23 @@ function handleFiles(event: Event) {
// 点击导入按钮
const importClick = () => {
openFileDialog()
const params = {
title: '被检设备',
showCover: false,
patternId: dictStore.getDictData('Pattern').find(item=>item.name=== modeStore.currentMode)?.id ?? '',
tempApi: downloadTemplate,
importApi: importPlan,
getTableList: proTable.value?.getTableList,
}
deviceImportExcel.value?.acceptParams(params)
}
// 点击导出按钮
const exportClick = () => {
openFileDialog()
ElMessageBox.confirm('确认导出检测计划?', '温馨提示', { type: 'warning' }).then(() =>{
const patternId = dictStore.getDictData('Pattern').find(item=>item.name=== modeStore.currentMode)?.id//获取数据字典中对应的id
useDownload(exportPlan,'检测计划导出数据', {...proTable.value?.searchParam,pattern:patternId}, false,'.xlsx')
})
}
// 点击合并按钮
@@ -371,52 +347,32 @@ const combineClick = () => {
})
}
// 打开编辑对话框
const openEditDialog = (planSystem: Plan.PlanBO) => {
dialogForm.value = { ...planSystem }
dialogTitle.value = '编辑检测计划'
isReadOnly.value = false
dialogFormVisible.value = true // 打开对话框
// 打开 drawer(新增、编辑)
const openDialog = (titleType: string, row: Partial<Plan.ReqPlan> = {}) => {
planPopup.value?.open(titleType, row,modeStore.currentMode)
}
const openAddDialog = () => {
dialogForm.value = {
id: '',
name: '',
pattern: '',
father_Plan_Id: '',
dataSource_Id: '',
script_Id: '',
error_Sys_Id: '',
test_State: '',
report_State: '',
result: '',
}
dialogTitle.value = '新增检测计划'
isReadOnly.value = false
dialogFormVisible.value = true // 打开对话框
// 批量删除设备
const batchDelete = async (id: string[]) => {
await useHandleData(deletePlan, id, '删除所选检测计划')
proTable.value?.clearSelection()
proTable.value?.getTableList()
}
const handleRowClick = (planSystem: Plan.PlanBO) => {
dialogForm.value = { ...planSystem }
dialogTitle.value = '查看检测计划'
isReadOnly.value = true
dialogFormVisible.value = true // 打开对话框
// 删除检测计划
const handleDelete = async (params: Plan.ReqPlanParams) => {
await useHandleData(deletePlan, [params.id], `删除【${params.name}】检测计划`)
proTable.value?.getTableList()
}
const showDeviceOpen = (planSystem: Plan.PlanBO) => {
devTransferVisible.value = true
//openDeviceView.value.open('计划设备列表')
const showDeviceOpen = (row: Partial<Plan.ReqPlan> = {}) => {
devTransferPopup.value.open(row)
}
const showtestSourceOpen = (planSystem: Plan.PlanBO) => {
sourceTransferVisible.value = true
// openSourceView.value.open('计划检测源列表')
// router.push({
// path: "/machine/testSource",
// });
}
</script>
<style scoped>

View File

@@ -36,7 +36,7 @@
<el-form-item label="检测状态">
<el-select v-model="searchForm.checkStatus">
<el-option :value="0" label="全部"></el-option>
<el-option :value="1" label="未检"></el-option>
<el-option :value="1" label="未检"></el-option>
<el-option :value="2" label="检测中"></el-option>
<el-option :value="3" label="检测完成"></el-option>
</el-select>
@@ -342,7 +342,7 @@ const columns = reactive<ColumnProps<User.ResUserList>[]>([
width: 120,
render: (scope) => {
return scope.row.checkStatus == 1
? "未检"
? "未检"
: scope.row.checkStatus == 2
? "检测中"
: scope.row.checkStatus == 3

View File

@@ -14,7 +14,7 @@
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label='检最大次数' prop='maxTime' :label-width="110">
<el-form-item label='检最大次数' prop='maxTime' :label-width="110">
<el-input-number v-model='TestConfigForm.maxTime' :min='1' :max='999' />
</el-form-item>
</el-col>
@@ -63,7 +63,7 @@
</div>
</el-tab-pane>
<el-tab-pane label="日志配置">
<div class="form-grid">
<div >
<el-row :gutter="24" >
<el-col :span="8">
<el-form-item label='调试日志配置' :label-width="140">
@@ -99,7 +99,7 @@
</div>
</el-tab-pane>
<el-tab-pane label="数据删除备份配置">
<div class="form-grid">
<div >
<el-row :gutter="24" >
<el-col :span="8">
<el-form-item label='原始数据备份频率' :label-width="140">

View File

@@ -9,9 +9,9 @@
<template #tableHeader="scope">
<el-button v-auth.dict="'show_add'" type="primary" :icon="CirclePlus" @click="openDialog('add')">新增</el-button>
<el-button v-auth.dict="'show_export'" type='primary' :icon='Download' plain @click="downloadFile">导出</el-button>
<el-button v-auth.dict="'show_batchDelete'" type="danger" :icon="Delete" plain :disabled="!scope.isSelected"
<el-button v-auth.dict="'show_delete'" type="danger" :icon="Delete" plain :disabled="!scope.isSelected"
@click="batchDelete(scope.selectedListIds)">
批量删除
删除
</el-button>
</template>

View File

@@ -1,269 +1,331 @@
<template>
<el-dialog v-model='dialogVisible' :title='dialogTitle' v-bind='dialogMiddle' @close="close">
<el-form :model='formContent' ref='dialogFormRef' :rules='rules' class='form-two'>
<el-divider >基础数据</el-divider>
<el-form-item label='数据模型' :label-width='140' prop='dataType'>
<el-select v-model="formContent.dataType" clearable placeholder="请选择数据模型">
<el-option
v-for="item in dictStore.getDictData('Cs_Data_Type')"
:key="item.id"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label='指标名称' :label-width='140' prop='name'>
<el-input v-model='formContent.name' placeholder='请输入' autocomplete='off' />
</el-form-item>
<el-form-item label='别名' :label-width='140' prop='otherName'>
<el-input v-model='formContent.otherName' placeholder='请输入' autocomplete='off' />
</el-form-item>
<el-form-item label='显示名称' :label-width='140' prop='showName'>
<el-input v-model='formContent.showName' placeholder='请输入' autocomplete='off' />
</el-form-item>
<el-form-item label='相别' :label-width='140' prop='phase'>
<el-select v-model="formContent.phase" clearable placeholder="请选择相别">
<el-option
v-for="item in dictStore.getDictData('phase')"
:key="item.id"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label='单位' :label-width='140' prop='unit'>
<el-input v-model='formContent.unit' placeholder='请输入单位' autocomplete='off' />
</el-form-item>
<el-form-item label='指标数据类型' :label-width='140' prop='type'>
<el-input v-model='formContent.type' placeholder='请输入指标数据类型' autocomplete='off' />
</el-form-item>
<el-form-item label='次数' :label-width='140'>
<el-row :gutter="20">
<el-col :span="11">
<el-input v-model="formContent.harmStart" placeholder="请输入起始次数" autocomplete="off" />
</el-col>
<el-col :span="2" class="text-center" style="line-height: 32px;">-</el-col>
<el-col :span="11">
<el-input v-model="formContent.harmEnd" placeholder="请输入结束次数" autocomplete="off" />
</el-col>
</el-row>
</el-form-item>
<el-form-item label='数据统计类型' :label-width='140' prop='statMethod'>
<el-select v-model="selectedStatMethods" multiple placeholder="请选择数据统计类型">
<el-dialog v-model='dialogVisible' :title='dialogTitle' v-bind="dialogBig" @close="close">
<el-form :model='formContent' ref='dialogFormRef' :rules='rules' label-width="auto" class="form-three">
<el-divider>基础数据</el-divider>
<el-form-item label='数据模型' prop='dataType'>
<el-select v-model="formContent.dataType" clearable placeholder="请选择数据模型">
<el-option
v-for="item in dictStore.getDictData('Stat_Method')"
:key="item.value"
:label="item.name"
:value="item.code"
/>
</el-select>
v-for="item in dictStore.getDictData('Cs_Data_Type')"
:key="item.id"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label='系统类别' :label-width='140' prop='systemType'>
<el-input v-model='formContent.systemType' placeholder='请输入' autocomplete='off' />
<el-form-item label='指标名称' prop='name'>
<el-input v-model='formContent.name' placeholder='请输入指标名称' autocomplete='off'/>
</el-form-item>
<el-form-item label='报表数据来源' :label-width='140' prop='resourcesId'>
<el-select v-model="formContent.resourcesId" clearable placeholder="请选择报表数据来源">
<el-option
v-for="item in dictStore.getDictData('Data_Day')"
:key="item.id"
:label="item.name"
:value="item.code"
/>
</el-select>
<el-form-item label='相别' prop='phase'>
<el-select v-model="formContent.phase" clearable placeholder="请选择相别">
<el-option
v-for="item in dictStore.getDictData('phase')"
:key="item.id"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label='数据表表名' :label-width='140' prop='classId'>
<el-select v-model="formContent.classId" clearable placeholder="请选择数据表表名">
<el-option
v-for="item in dictStore.getDictData('Data')"
:key="item.id"
:label="item.name"
:value="item.code"
/>
</el-select>
<el-form-item label='显示名称' prop='showName'>
<el-input v-model='formContent.showName' placeholder='请输入显示名称' autocomplete='off'/>
</el-form-item>
<el-form-item label='限值字段名称' :label-width='140' prop='limitName'>
<el-input v-model='formContent.limitName' placeholder='请输入限值字段名称' autocomplete='off' />
<el-form-item label='别名' prop='otherName'>
<el-input v-model='formContent.otherName' placeholder='请输入别名' autocomplete='off'/>
</el-form-item>
<el-form-item label='限值表名' :label-width='140' prop='limitTable'>
<el-input v-model='formContent.limitTable' placeholder='请输入限值表名' autocomplete='off' />
<el-form-item label='单位' prop='unit'>
<el-select v-model="formContent.unit" clearable placeholder="请选择单位">
<el-option v-for="item in dictStore.getDictData('Unit_Type')" :key="item.id" :label="item.name"
:value="item.code"/>
</el-select>
</el-form-item>
<el-form-item label='超标判断方式' :label-width='140' prop='formula'>
<el-select v-model="formContent.formula" clearable placeholder="请选择超标判断方式">
<el-option
v-for="item in dictStore.getDictData('Limit_Value_Judgment')"
:key="item.id"
:label="item.name"
:value="item.code"
/>
</el-select>
<el-form-item label='指标数据类型' prop='type'>
<el-select v-model="formContent.type" clearable placeholder="请选择指标数据类型">
<el-option
:label="'Number'"
:value="'Number'"
/>
<el-option
:label="'Float'"
:value="'Float'"
/>
<el-option
:label="'Enum'"
:value="'Enum'"
/>
</el-select>
</el-form-item>
<el-form-item label='排序' :label-width='140'>
<el-input-number v-model='formContent.sort' :min='1' :max='999' />
<el-form-item label='次数'>
<el-row :gutter="10">
<el-col :span="11">
<el-input v-model="formContent.harmStart" placeholder="起始次数" autocomplete="off" width="100px" />
</el-col>
<el-col :span="2" style="text-align: center;"></el-col>
<el-col :span="11">
<el-input v-model="formContent.harmEnd" placeholder="结束次数" autocomplete="off" width="100px"/>
</el-col>
</el-row>
</el-form-item>
<el-divider >拓展数据</el-divider>
<el-form-item label='参数缺省值' :label-width='140' prop='defaultValue'>
<el-input v-model='formContent.defaultValue' placeholder='请输入参数缺省值' autocomplete='off' />
<el-form-item label='数据统计类型' prop='statMethod'>
<el-select v-model="selectedStatMethods" multiple placeholder="请选择数据统计类型">
<el-option
v-for="item in dictStore.getDictData('Stat_Method')"
:key="item.value"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label='事件类别' :label-width='140' prop='eventType'>
<el-input v-model='formContent.eventType' placeholder='请输入事件类别' autocomplete='off' />
<el-form-item label='系统类别' prop='systemType'>
<el-input v-model='formContent.systemType' placeholder='请输入系统类别' autocomplete='off'/>
</el-form-item>
<el-form-item label='设置最大值' :label-width='140' prop='maxNum'>
<el-input-number v-model='formContent.maxNum' controls-position="right" style="width: 300px;"/>
<el-form-item label='报表数据来源' prop='resourcesId'>
<el-select v-model="formContent.resourcesId" clearable placeholder="请选择报表数据来源">
<el-option
v-for="item in dictStore.getDictData('Data_Day')"
:key="item.id"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label='设置最小值' :label-width='140' prop='minNum'>
<el-input-number v-model='formContent.minNum' controls-position="right" style="width: 300px;"/>
<el-form-item label='数据表表名' prop='classId'>
<el-select v-model="formContent.classId" clearable placeholder="请选择数据表表名">
<el-option
v-for="item in dictStore.getDictData('Data')"
:key="item.id"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label='枚举序列' :label-width='140' prop='setValue'>
<el-input v-model='formContent.setValue' placeholder='请输入枚举序列' autocomplete='off' />
<el-form-item label='限值字段名称' prop='limitName'>
<el-input v-model='formContent.limitName' placeholder='请输入限值字段名称' autocomplete='off'/>
</el-form-item>
<el-form-item label='字符串长度上限' :label-width='140' prop='strlen'>
<el-input-number v-model='formContent.strlen' controls-position="right" style="width: 300px;"/>
<el-form-item label='限值表名' prop='limitTable'>
<el-input v-model='formContent.limitTable' placeholder='请输入限值表名' autocomplete='off'/>
</el-form-item>
<el-form-item label='上送规则' :label-width='140' prop='tranRule'>
<el-input v-model='formContent.tranRule' placeholder='请输入上送规则' autocomplete='off' />
<el-form-item label='超标判断方式' prop='formula'>
<el-select v-model="formContent.formula" clearable placeholder="请选择超标判断方式">
<el-option
v-for="item in dictStore.getDictData('Limit_Value_Judgment')"
:key="item.id"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label='当前值' :label-width='140' prop='curSts'>
<el-input v-model='formContent.curSts' placeholder='请输入当前值' autocomplete='off' />
<el-form-item label='排序' >
<el-input-number v-model='formContent.sort' :min='1' :max='999' style="width: 300px;"/>
</el-form-item>
<el-form-item label='二次值转一次值公式' :label-width='140' prop='primaryFormula'>
<el-input v-model='formContent.primaryFormula' placeholder='请输入公式' autocomplete='off' />
<el-divider>拓展数据</el-divider>
<el-form-item label='参数缺省值' prop='defaultValue'>
<el-input v-model='formContent.defaultValue' placeholder='请输入参数缺省值' autocomplete='off'/>
</el-form-item>
<el-form-item label="是否可远程控制" :label-width="140">
<el-radio-group v-model="formContent.ctlSts" >
<el-form-item label='事件类别' prop='eventType'>
<el-input v-model='formContent.eventType' placeholder='请输入事件类别' autocomplete='off'/>
</el-form-item>
<el-form-item label='设置最大值' prop='maxNum'>
<el-input-number v-model='formContent.maxNum' controls-position="right" style="width: 300px;"/>
</el-form-item>
<el-form-item label='设置最小值' prop='minNum'>
<el-input-number v-model='formContent.minNum' controls-position="right" style="width: 300px;"/>
</el-form-item>
<el-form-item label='枚举序列' prop='setValue'>
<el-input v-model='formContent.setValue' placeholder='请输入枚举序列' autocomplete='off'/>
</el-form-item>
<el-form-item label='字符串长度上限' prop='strlen'>
<el-input-number v-model='formContent.strlen' controls-position="right" style="width: 300px;"/>
</el-form-item>
<el-form-item label='上送规则' prop='tranRule'>
<el-input v-model='formContent.tranRule' placeholder='请输入上送规则' autocomplete='off'/>
</el-form-item>
<el-form-item label='当前值' prop='curSts'>
<el-input v-model='formContent.curSts' placeholder='请输入当前值' autocomplete='off'/>
</el-form-item>
<el-form-item label='二次值转一次值公式' prop='primaryFormula'>
<el-input v-model='formContent.primaryFormula' placeholder='请输入公式' autocomplete='off'/>
</el-form-item>
<el-form-item label="是否可远程控制" >
<el-radio-group v-model="formContent.ctlSts">
<el-radio label="是" :value="1"></el-radio>
<el-radio label="否" :value="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否存储" :label-width="140">
<el-radio-group v-model="formContent.storeFlag" >
<el-form-item label="是否存储" >
<el-radio-group v-model="formContent.storeFlag">
<el-radio label="是" :value="1"></el-radio>
<el-radio label="否" :value="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="数据是否上送" :label-width="140">
<el-radio-group v-model="formContent.tranFlag" >
<el-form-item label="数据是否上送" >
<el-radio-group v-model="formContent.tranFlag">
<el-radio label="是" :value="1"></el-radio>
<el-radio label="否" :value="0"></el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<div class='dialog-footer'>
<el-button @click='close()'>取消</el-button>
<el-button type='primary' @click='save()'>
保存
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang='ts'>
import { dialogMiddle } from '@/utils/elementBind'
import { type Dict } from '@/api/system/dictionary/interface'
import { ElMessage, type FormItemRule } from 'element-plus'
import { addDictPq, updateDictPq } from '@/api/system/dictionary/dictPq'
import { computed, type Ref, ref } from 'vue';
import { useDictStore } from '@/stores/modules/dict'
const dictStore = useDictStore()
const selectedStatMethods = ref<string[]>([])
// 定义弹出组件元信息
const dialogFormRef = ref()
function useMetaInfo() {
const dialogVisible = ref(false)
const titleType = ref('add')
const formContent = ref<Dict.ResDictPq>({
id: '',
name: '',
phase: '',
sort: 100,
dataType: '',
state: 1,
classId: '',
})
return { dialogVisible, titleType, formContent }
}
const { dialogVisible, titleType, formContent } = useMetaInfo()
// 清空formContent
const resetFormContent = () => {
formContent.value = {
id: '',
name: '',
phase: '',
sort: 100,
dataType: '',
state: 1,
classId: '',
}
}
let dialogTitle = computed(() => {
return titleType.value === 'add' ? '新增字典' : '编辑字典'
</el-form>
<template #footer>
<div class='dialog-footer'>
<el-button @click='close()'>取消</el-button>
<el-button type='primary' @click='save()'>
保存
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang='ts'>
import {dialogBig} from '@/utils/elementBind'
import {type Dict} from '@/api/system/dictionary/interface'
import {ElMessage, type FormItemRule} from 'element-plus'
import {addDictPq, updateDictPq} from '@/api/system/dictionary/dictPq'
import {computed, reactive, type Ref, ref} from 'vue';
import {useDictStore} from '@/stores/modules/dict'
const dictStore = useDictStore()
const selectedStatMethods = ref<string[]>([])
// 定义弹出组件元信息
const dialogFormRef = ref()
function useMetaInfo() {
const dialogVisible = ref(false)
const titleType = ref('add')
const formContent = reactive<Dict.ResDictPq>({
id: '',
dataType: '',
name: '',
otherName: '',
showName: '',
phase: '',
unit: '',
type: 'Number',
harmStart: null,
harmEnd: null,
systemType: '',
resourcesId: '',
classId: '',
limitName: '',
limitTable: '',
formula: '',
sort: 100,
defaultValue: '',
eventType: '',
maxNum: null,
minNum: null,
setValue: '',
strlen: null,
tranRule: '',
curSts: null,
primaryFormula: '',
ctlSts: 0,
storeFlag: '',
tranFlag: 0,
state: 1,
})
return {dialogVisible, titleType, formContent}
}
// 定义表单校验规则
const rules: Ref<Record<string, Array<FormItemRule>>> = ref({
dataType: [{ required: true, message: '数据模型必选!', trigger: 'change' }],
name: [{ required: true, message: '指标名称必填!', trigger: 'blur' }],
phase: [{ required: true, message: '相别必选!', trigger: 'change' }],
classId: [{ required: true, message: '数据库表名必选!', trigger: 'change' }],
const {dialogVisible, titleType, formContent} = useMetaInfo()
// 清空formContent
const resetFormContent = () => {
Object.assign(formContent, {
id: '',
dataType: '',
name: '',
otherName: '',
showName: '',
phase: '',
unit: '',
type: 'Number',
harmStart: '',
harmEnd: '',
systemType: '',
resourcesId: '',
classId: '',
limitName: '',
limitTable: '',
formula: '',
sort: 100,
defaultValue: '',
eventType: '',
maxNum: '',
minNum: '',
setValue: '',
strlen: '',
tranRule: '',
curSts: '',
primaryFormula: '',
ctlSts: 0,
storeFlag: 0,
tranFlag: 0,
state: 1,
})
}
// 关闭弹窗
const close = () => {
dialogVisible.value = false
// 清空dialogForm中的值
resetFormContent()
// 重置表单
dialogFormRef.value?.resetFields()
selectedStatMethods.value = []
}
let dialogTitle = computed(() => {
return titleType.value === 'add' ? '新增字典' : '编辑字典'
})
// 保存数据
const save = () => {
try {
dialogFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
formContent.value.statMethod = selectedStatMethods.value.join(',')
if (formContent.value.id) {
await updateDictPq(formContent.value);
} else {
await addDictPq(formContent.value);
}
ElMessage.success({ message: `${dialogTitle.value}成功!` })
close()
// 刷新表格
await props.refreshTable!()
// 定义表单校验规则
const rules: Ref<Record<string, Array<FormItemRule>>> = ref({
dataType: [{required: true, message: '数据模型必选!', trigger: 'change'}],
name: [{required: true, message: '指标名称必填!', trigger: 'blur'}],
phase: [{required: true, message: '相别必选!', trigger: 'change'}],
classId: [{required: true, message: '数据库表名必选!', trigger: 'change'}],
})
// 关闭弹窗
const close = () => {
dialogVisible.value = false
// 清空dialogForm中的值
resetFormContent()
// 重置表单
dialogFormRef.value?.resetFields()
selectedStatMethods.value = []
}
// 保存数据
const save = () => {
try {
dialogFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
formContent.statMethod = selectedStatMethods.value.join(',')
if (formContent.id) {
await updateDictPq(formContent);
} else {
await addDictPq(formContent);
}
})
} catch (err) {
console.error('验证过程中出现错误', err)
}
ElMessage.success({message: `${dialogTitle.value}成功!`})
close()
// 刷新表格
await props.refreshTable!()
}
})
} catch (err) {
console.error('验证过程中出现错误', err)
}
}
// 打开弹窗,可能是新增,也可能是编辑
const open = (sign: string, data: Dict.ResDictPq) => {
// 重置表单
dialogFormRef.value?.resetFields()
titleType.value = sign
dialogVisible.value = true
selectedStatMethods.value = data.statMethod ? data.statMethod.split(',') : []
if (data.id) {
formContent.value = { ...data }
} else {
resetFormContent()
}
// 打开弹窗,可能是新增,也可能是编辑
const open = (sign: string, data: Dict.ResDictPq) => {
// 重置表单
dialogFormRef.value?.resetFields()
titleType.value = sign
dialogVisible.value = true
selectedStatMethods.value = data.statMethod ? data.statMethod.split(',') : []
if (data.id) {
Object.assign(formContent, {...data})
} else {
resetFormContent()
}
}
// 对外映射
defineExpose({ open })
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
}>()
// 对外映射
defineExpose({open})
const props = defineProps<{
refreshTable: (() => Promise<void>) | undefined;
}>()
</script>
</script>

View File

@@ -7,9 +7,9 @@
>
<template #tableHeader='scope'>
<el-button v-auth.dictPq="'add'" type='primary' :icon='CirclePlus' @click="openDialog('add')">新增</el-button>
<el-button v-auth.dictPq="'batchDelete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
<el-button v-auth.dictPq="'delete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
@click='batchDelete(scope.selectedListIds)'>
批量删除
删除
</el-button>
</template>

View File

@@ -43,7 +43,7 @@
pid: '',
pids: '',
name: '',
code: ' ',
code: '',
sort: 100,
remark: '',
state: 0,
@@ -60,7 +60,7 @@
pid: '0',
pids: '0',
name: '',
code: ' ',
code: '',
sort: 100,
remark: '',
state: 0,

View File

@@ -8,9 +8,9 @@
<template #tableHeader='scope'>
<el-button v-auth.dict="'add'" type='primary' :icon='CirclePlus' @click="openDialog('add')">新增</el-button>
<el-button v-auth.dict="'export'" type='primary' :icon='Download' plain @click='downloadFile()'>导出</el-button>
<el-button v-auth.dict="'batchDelete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
<el-button v-auth.dict="'delete'" type='danger' :icon='Delete' plain :disabled='!scope.isSelected'
@click='batchDelete(scope.selectedListIds)'>
批量删除
删除
</el-button>
</template>

View File

@@ -1,3 +1,4 @@
<template>
<el-dialog v-model="dialogVisible" title="程序激活" v-bind="dialogSmall">
<el-form :model="formContent">