Compare commits

..

26 Commits

Author SHA1 Message Date
70a0fbb170 Merge pull request 'projects/line-new-zhp' (#466) from projects/line-new-zhp into projects/line-new
Reviewed-on: #466
2025-12-17 16:30:30 +08:00
‘937886381’
c86d94ac92 修改 2025-12-17 16:26:21 +08:00
‘937886381’
484ba6ca53 Merge branch 'projects/line-new' into projects/line-new-zhp 2025-12-15 10:45:49 +08:00
‘937886381’
f403375594 修改bug 2025-12-15 10:45:06 +08:00
1cd0b13aae Merge pull request 'projects/line-new-zhp' (#463) from projects/line-new-zhp into projects/line-new
Reviewed-on: #463
2025-12-12 16:54:55 +08:00
‘937886381’
d2b0565cd1 Merge branch 'projects/line-new' into projects/line-new-zhp 2025-12-12 16:53:32 +08:00
‘937886381’
7661dc5691 修改 2025-12-12 16:52:45 +08:00
1d698848c2 Merge pull request 'projects/line-new-zhp' (#461) from projects/line-new-zhp into projects/line-new
Reviewed-on: #461
2025-12-12 14:18:34 +08:00
‘937886381’
6d367b121c Merge branch 'projects/line-new' into projects/line-new-zhp 2025-12-12 14:17:56 +08:00
‘937886381’
e2385cf813 修改 2025-12-12 14:17:21 +08:00
552b1e6d6a Merge pull request '更新' (#460) from projects/line-new-zwq into projects/line-new
Reviewed-on: #460
2025-12-11 12:52:11 +08:00
zwq
4383067eb1 更新 2025-12-11 12:51:41 +08:00
f80644e07c Merge pull request 'projects/line-new-zhp' (#458) from projects/line-new-zhp into projects/line-new
Reviewed-on: #458
2025-12-09 17:03:35 +08:00
‘937886381’
1e12b653d6 Merge branch 'projects/line-new' into projects/line-new-zhp 2025-12-09 16:59:54 +08:00
‘937886381’
b7ba173ca3 修改 2025-12-09 16:57:38 +08:00
c203f1e1dd Merge pull request 'projects/line-new-zhp' (#457) from projects/line-new-zhp into projects/line-new
Reviewed-on: #457
2025-12-09 13:11:32 +08:00
‘937886381’
ccb925003e Merge branch 'projects/line-new' into projects/line-new-zhp 2025-12-09 13:10:45 +08:00
‘937886381’
b9f286005c 生产 2025-12-09 13:07:09 +08:00
0e343279ac Merge pull request '更新' (#456) from projects/line-new-zwq into projects/line-new
Reviewed-on: #456
2025-12-01 14:52:38 +08:00
zwq
00ac3dec45 更新 2025-12-01 14:52:21 +08:00
a84f765e73 Merge pull request '班组bug' (#455) from projects/line-new-zwq into projects/line-new
Reviewed-on: #455
2025-11-28 16:29:25 +08:00
zwq
ffa0b2e8dd 班组bug 2025-11-28 16:29:06 +08:00
1e6c6c5656 Merge pull request '班组bug' (#448) from projects/line-new-zwq into projects/line-new
Reviewed-on: #448
2025-11-11 15:38:56 +08:00
zwq
0e76fe7dbf 班组bug 2025-11-11 15:38:31 +08:00
399e2bc965 Merge pull request '更新班组' (#447) from projects/line-new-zwq into projects/line-new
Reviewed-on: #447
2025-11-05 13:58:22 +08:00
zwq
7bee1f7863 更新班组 2025-11-05 13:57:58 +08:00
440 changed files with 84594 additions and 13081 deletions

View File

@@ -9,13 +9,13 @@
ENV = 'development' ENV = 'development'
# 页面标题 # 页面标题
VUE_APP_TITLE = 上上电缆 VUE_APP_TITLE = 智能监控分析系统
# 芋道管理系统/开发环境 # 芋道管理系统/开发环境
# VUE_APP_BASE_API = 'http://172.16.33.187:48082'
VUE_APP_BASE_API = 'http://line.kszny.picaiba.com'
# VUE_APP_BASE_API = 'http://172.16.32.79:48082'
# VUE_APP_BASE_API = 'http://192.168.0.31:48080'
VUE_APP_BASE_API = 'http://172.16.32.236:48080'
# VUE_APP_BASE_API = 'http://line.kszny.picaiba.com'
# 路由懒加载 # 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true VUE_CLI_BABEL_TRANSPILE_MODULES = true

View File

@@ -2,14 +2,14 @@
# @Author: zwq # @Author: zwq
# @Date: 2024-03-27 15:49:55 # @Date: 2024-03-27 15:49:55
# @LastEditors: zwq # @LastEditors: zwq
# @LastEditTime: 2025-10-31 09:58:40 # @LastEditTime: 2024-10-30 11:08:47
# @Description: # @Description:
### ###
# 生产环境配置 # 生产环境配置
ENV = 'production' ENV = 'production'
# 页面标题 # 页面标题
VUE_APP_TITLE = 上上电缆 VUE_APP_TITLE = 智能监控分析系统
# 芋道管理系统/生产环境 # 芋道管理系统/生产环境
# VUE_APP_BASE_API = '/prod-api' # VUE_APP_BASE_API = '/prod-api'

BIN
dist.zip Normal file

Binary file not shown.

View File

@@ -45,10 +45,11 @@
"@jiaminghi/data-view": "^2.10.0", "@jiaminghi/data-view": "^2.10.0",
"@riophae/vue-treeselect": "0.4.0", "@riophae/vue-treeselect": "0.4.0",
"axios": "0.27.2", "axios": "0.27.2",
"benz-amr-recorder": "^1.1.5",
"bpmn-js-token-simulation": "0.10.0", "bpmn-js-token-simulation": "0.10.0",
"chinese-lunar": "^0.1.4", "chinese-lunar": "^0.1.4",
"clipboard": "2.0.8", "clipboard": "2.0.8",
"code-brick-zj": "^1.0.2", "code-brick-zj": "^1.1.1",
"core-js": "^3.26.0", "core-js": "^3.26.0",
"crypto-js": "^4.0.0", "crypto-js": "^4.0.0",
"diagram-js": "^12.3.0", "diagram-js": "^12.3.0",

View File

@@ -1,49 +0,0 @@
/*
* @Author: zwq
* @Date: 2025-11-17 09:25:12
* @LastEditors: zwq
* @LastEditTime: 2026-01-14 13:53:22
* @Description:
*/
import request from '@/utils/request'
// 获得巷道分页
export function getLanePage(query) {
return request({
url: '/wms/lane/page',
method: 'get',
params: query
})
}
// 获得巷道
export function getLane(id) {
return request({
url: '/wms/lane/get?id=' + id,
method: 'get'
})
}
// 删除巷道
export function deleteLane(id) {
return request({
url: '/wms/lane/delete?id=' + id,
method: 'delete'
})
}
// 更新
export function updateLane(data) {
return request({
url: '/wms/lane/update',
method: 'put',
data: data
})
}
// 创建
export function createLane(data) {
return request({
url: '/wms/lane/create',
method: 'post',
data: data
})
}

View File

@@ -1,74 +0,0 @@
/*
* @Author: zwq
* @Date: 2025-11-17 09:25:12
* @LastEditors: zwq
* @LastEditTime: 2026-01-23 13:42:52
* @Description:
*/
import request from '@/utils/request'
// 获得线边库分页
export function getLineEdgeLibraryPage(query) {
return request({
url: '/wms/line-edge-library/page',
method: 'get',
params: query
})
}
// 获得线边库
export function getLineEdgeLibrary(id) {
return request({
url: '/wms/line-edge-library/get?id=' + id,
method: 'get'
})
}
// 删除线边库
export function deleteLineEdgeLibrary(id) {
return request({
url: '/wms/line-edge-library/delete?id=' + id,
method: 'delete'
})
}
// 更新
export function updateLineEdgeLibrary(data) {
return request({
url: '/wms/line-edge-library/update',
method: 'put',
data: data
})
}
// 更新线边库实时pc --一键清空
export function AllQKLineEdgeLibrary(data) {
return request({
url: '/wms/line-edge-library/lane/cancel/pc',
method: 'put',
data: data
})
}
// 更新线边库实时pc --清空操作
export function QKLineEdgeLibrary(data) {
return request({
url: '/wms/line-edge-library/update/pc',
method: 'put',
data: data
})
}
// 创建
export function createLineEdgeLibrary(data) {
return request({
url: '/wms/line-edge-library/create',
method: 'post',
data: data
})
}
// 获得设备分页
export function getEquipmentPage(query) {
return request({
url: '/wms/equipment/page',
method: 'get',
params: query
})
}

View File

@@ -1,79 +0,0 @@
/*
* @Author: zwq
* @Date: 2026-01-06 15:18:38
* @LastEditors: zwq
* @LastEditTime: 2026-01-15 15:02:04
* @Description:
*/
import request from '@/utils/request'
// 获取区域列表
export function getAreaList(params) {
return request({
url: '/wms/region/page',
method: 'get',
params
})
}
// 获取区域空满数量
export function postAllAreaInfo(data) {
return request({
url: '/wms/region/lsit/count',
method: 'post',
data
})
}
// 获取指定库区库位信息
export function postAreaInfo(params) {
return request({
url: '/wms/line-edge-library/list/region',
method: 'get',
params
})
}
// 获取区域总览
export function postAllAreaOverview(data) {
return request({
url: '/wms/line-edge-library/line/count',
method: 'post',
data
})
}
// 删除能源实时数据库plc相关
export function deleteEnergyPlc(id) {
return request({
url: '/base/energy-plc/delete?id=' + id,
method: 'delete'
})
}
// 获取关联表编码
export function getCode() {
return request({
url: '/base/energy-plc/getCode',
method: 'get'
})
}
// 获得能源实时数据库plc相关分页
export function getEnergyPlcPage(data) {
return request({
url: '/base/energy-plc/page',
method: 'post',
data: data
})
}
// 导出能源实时数据库plc相关 Excel
export function exportEnergyPlcExcel(query) {
return request({
url: '/base/energy-plc/export-excel',
method: 'get',
params: query,
responseType: 'blob'
})
}

View File

@@ -1,63 +0,0 @@
import request from '@/utils/request'
// 获取出入库历史任务分页
export function getRecordPage(params) {
return request({
url: '/wms/job-main-task-history/page',
method: 'get',
params
})
}
// 获取巷道列表
export function getLaneList(params) {
return request({
url: '/wms/lane/page',
method: 'get',
params
})
}
// 更新能源实时数据库plc相关
export function updateEnergyPlc(data) {
return request({
url: '/base/energy-plc/update',
method: 'put',
data: data
})
}
// 删除能源实时数据库plc相关
export function deleteEnergyPlc(id) {
return request({
url: '/base/energy-plc/delete?id=' + id,
method: 'delete'
})
}
// 获取关联表编码
export function getCode() {
return request({
url: '/base/energy-plc/getCode',
method: 'get'
})
}
// 获得能源实时数据库plc相关分页
export function getEnergyPlcPage(data) {
return request({
url: '/base/energy-plc/page',
method: 'post',
data: data
})
}
// 导出能源实时数据库plc相关 Excel
export function exportEnergyPlcExcel(query) {
return request({
url: '/base/energy-plc/export-excel',
method: 'get',
params: query,
responseType: 'blob'
})
}

View File

@@ -1,49 +0,0 @@
/*
* @Author: zwq
* @Date: 2025-11-17 09:25:12
* @LastEditors: zwq
* @LastEditTime: 2026-01-14 13:35:11
* @Description:
*/
import request from '@/utils/request'
// 获得区域分页
export function getRegionPage(query) {
return request({
url: '/wms/region/page',
method: 'get',
params: query
})
}
// 获得区域
export function getRegion(id) {
return request({
url: '/wms/region/get?id=' + id,
method: 'get'
})
}
// 删除区域
export function deleteRegion(id) {
return request({
url: '/wms/region/delete?id=' + id,
method: 'delete'
})
}
// 更新
export function updateRegion(data) {
return request({
url: '/wms/region/update',
method: 'put',
data: data
})
}
// 创建
export function createRegion(data) {
return request({
url: '/wms/region/create',
method: 'post',
data: data
})
}

View File

@@ -59,3 +59,34 @@ export function getEquipmentAll() {
method: 'get' method: 'get'
}) })
} }
export function getTree(query) {
return request({
url: '/base/factory/getTreeSimple',
method: 'get',
params: query,
});
}
export function getEquipmentOverall(data) {
return request({
url: '/monitoring/equipment-overall/get',
method: 'post',
data: data,
});
}
export function getParamMonitor(data) {
return request({
url: '/monitoring/equipment-monitor/paramMonitor',
method: 'post',
data: data,
});
}
export function getAlarmDet(data) {
return request({
url: 'monitoring/equipment-overall/alarmDet',
method: 'post',
data: data,
});
}

View File

@@ -52,3 +52,5 @@ export function exportEquipmentTypeExcel(query) {
responseType: 'blob' responseType: 'blob'
}) })
} }

View File

@@ -50,6 +50,15 @@ export function getPdlAutoReportNewSearchNow(data) {
}); });
} }
export function getPdlAutoReportNewSearchLastGroup(data) {
return request({
url: '/monitoring/production-monitor/getPdlAutoReportNewSearchLastGroup',
method: 'post',
data: data,
timeout: 60000,
});
}
// 班组自动报表分页 // 班组自动报表分页
export function getTeamReportPage(data) { export function getTeamReportPage(data) {
@@ -93,3 +102,17 @@ export function getProcessAutoReportNew(data) {
data: data, data: data,
}); });
} }
export function getPLlistByFactory(data) {
return request({
url: 'base/production-line/listByFactory',
method: 'post',
data: data,
});
}
export function getProcessAutoReportLastGroup(data) {
return request({
url: '/monitoring/production-monitor/getProcessAutoReportLastGroup',
method: 'post',
data: data,
});
}

View File

@@ -141,3 +141,13 @@ export function getPerView(data) {
data:data data:data
}) })
} }
// 导出 Excel
export function exportExcel(query) {
return request({
url: '/base/group-scheduling-plan/export-excel',
method: 'get',
params: query,
responseType: 'blob'
})
}

View File

@@ -26,6 +26,13 @@ export function getGroup(id) {
method: 'get' method: 'get'
}) })
} }
// 检查更新-生产班组
export function updateIsProduction(id) {
return request({
url: '/base/group-team/updateIsProduction?id=' + id,
method: 'get'
})
}
// 获得班组基础信息分页 // 获得班组基础信息分页
export function getGroupPage(query) { export function getGroupPage(query) {

View File

@@ -90,3 +90,29 @@ export function getEnableData() {
method: 'get', method: 'get',
}) })
} }
// 解除继承节假日
export function disExtends(data) {
return request({
url: '/base/group-holiday/disExtends',
method: 'post',
data: data
})
}
// 恢复继承节假日
export function reExtends(data) {
return request({
url: '/base/group-holiday/reExtends',
method: 'post',
data: data
})
}
// 获得部门节假日继承设置信息设置
export function getSet(query) {
return request({
url: '/base/group-holiday-dept-set/getSet',
method: 'get',
params: query
})
}

View File

@@ -0,0 +1,56 @@
import request from '@/utils/request'
// 创建能源监控配置
export function getDefectSummaryTable(data) {
return request({
url: '/extend/check-gaozhun-record/defectSummaryTable',
method: 'post',
data: data,
});
}
export function getTranslucentPage(data) {
return request({
url: '/monitoring/translucent/page',
method: 'get',
params: data,
});
}
export function exportTranslucent(data) {
return request({
url: '/monitoring/translucent/export-excel',
method: 'get',
params: data,
responseType: 'blob',
});
}
export function getDefectAnalysis(data) {
return request({
url: '/extend/check-gaozhun-record/defectAnalysis',
method: 'post',
data: data,
});
}
export function getSectionDefect(data) {
return request({
url: '/extend/check-gaozhun-record/sectionDefect',
method: 'post',
data: data,
});
}
export function getDefectSummaryChart(data) {
return request({
url: '/extend/check-gaozhun-record/defectSummaryChart',
method: 'post',
data: data,
});
}
export function getDefectSummaryDet(data) {
return request({
url: '/extend/check-gaozhun-record/defectSummaryDet',
method: 'post',
data: data,
});
}

View File

@@ -0,0 +1,63 @@
/*
* @Author: zhp
* @Date: 2023-12-08 15:26:59
* @LastEditTime: 2023-12-11 15:21:44
* @LastEditors: zhp
* @Description:
*/
import request from '@/utils/request'
export function getQualityIsraPage(query) {
return request({
url: '/extend/check-isra-statistics/getIsraData',
method: 'get',
params: query,
});
}
export function getQualityIsraDayMap(query) {
return request({
url: '/base/quality-isra-statistics/dayMap',
method: 'get',
params: query
})
}
export function getQualityIsraWeekMap(query) {
return request({
url: '/base/quality-isra-statistics/weekMap',
method: 'get',
params: query
})
}
export function getQualityIsraMonthMap(query) {
return request({
url: '/base/quality-isra-statistics/monthMap',
method: 'get',
params: query
})
}
export function getQualityIsraDayList(query) {
return request({
url: '/base/quality-isra-statistics/dayList',
method: 'get',
params: query
})
}
export function getQualityIsraWeekList(query) {
return request({
url: '/base/quality-isra-statistics/weekList',
method: 'get',
params: query
})
}
export function getQualityIsraMonthList(query) {
return request({
url: '/base/quality-isra-statistics/monthList',
method: 'get',
params: query
})
}

View File

@@ -1,162 +0,0 @@
/*
* @Author: zwq
* @Date: 2025-11-17 09:25:12
* @LastEditors: zwq
* @LastEditTime: 2026-01-13 16:13:53
* @Description:
*/
import request from '@/utils/request'
// 获得原料分页
export function getProductPage(query) {
return request({
url: '/wms/material/page',
method: 'get',
params: query
})
}
// 获得所有原料
export function getAllProductPage(query) {
return request({
url: '/wms/material/list/all/code',
method: 'get',
params: query
})
}
// 获得原料
export function getProduct(id) {
return request({
url: '/wms/material/get?id=' + id,
method: 'get'
})
}
// 删除原料
export function deleteProduct(id) {
return request({
url: '/wms/material/delete?id=' + id,
method: 'delete'
})
}
// 更新
export function updateProduct(data) {
return request({
url: '/wms/material/update',
method: 'put',
data: data
})
}
// 创建
export function createProduct(data) {
return request({
url: '/wms/material/create',
method: 'post',
data: data
})
}
// 获得工艺分页
export function getProcessPage(query) {
return request({
url: '/wms/process/page/group/by',
method: 'get',
params: query
})
}
// 获得工艺点击展开表格
export function getProcessDetailPage(query) {
return request({
url: '/wms/process/page/group/by/detail',
method: 'get',
params: query
})
}
// 删除工艺
export function deleteProcess(id) {
return request({
url: '/wms/process/delete?id=' + id,
method: 'delete'
})
}
// 批量删除工艺
export function deleteProcessList(ids) {
return request({
url: '/wms/process/delete-list?ids=' + ids,
method: 'delete'
})
}
// 更新
export function updateProcess(data) {
return request({
url: '/wms/process/update',
method: 'put',
data: data
})
}
// 创建
export function createProcess(data) {
return request({
url: '/wms/process/create',
method: 'post',
data: data
})
}
// 获得工艺
export function getProcess(id) {
return request({
url: '/wms/process/get?id=' + id,
method: 'get'
})
}
// 工艺设备原料分页
export function getProcessMaterialPage(query) {
return request({
url: '/wms/process-equipment-material/page',
method: 'get',
params: query
})
}
// 删除工艺设备原料
export function deleteProcessMaterial(id) {
return request({
url: '/wms/process-equipment-material/delete?id=' + id,
method: 'delete'
})
}
// 更新
export function updateProcessMaterial(data) {
return request({
url: '/wms/process-equipment-material/update',
method: 'put',
data: data
})
}
// 创建
export function createProcessMaterial(data) {
return request({
url: '/wms/process-equipment-material/create',
method: 'post',
data: data
})
}
// 获得工艺
export function getProcessMaterial(id) {
return request({
url: '/wms/process-equipment-material/get?id=' + id,
method: 'get'
})
}
// 获得设备分页
export function getEquipmentPage(query) {
return request({
url: '/wms/equipment/page',
method: 'get',
params: query
})
}

View File

@@ -1,60 +0,0 @@
/*
* @Author: zwq
* @Date: 2025-11-17 09:25:12
* @LastEditors: zwq
* @LastEditTime: 2025-11-18 15:42:19
* @Description:
*/
import request from '@/utils/request'
// 获得任务分页
export function getTaskPage(query) {
return request({
url: '/wms/job-main-task/page',
method: 'get',
params: query
})
}
// 获得任务
export function getTask(id) {
return request({
url: '/wms/job-main-task/get?id=' + id,
method: 'get'
})
}
// 获得任务日志分页
export function getTaskLogPage(query) {
return request({
url: '/wms/job-main-task-log/page',
method: 'get',
params: query
})
}
// 更新
export function updateTask(data) {
return request({
url: '/wms/job-main-task/update',
method: 'put',
data: data
})
}
// 根据区域id获取该区域下的库位信息
export function getRegion(id) {
return request({
url: '/wms/line-edge-library/get-by-region-id?regionId=' + id,
method: 'get'
})
}
// 创建
export function createPCTask(data) {
return request({
url: '/wms/job-main-task/pc-create-task',
method: 'post',
data: data
})
}

View File

@@ -1,9 +0,0 @@
import request from '@/utils/request'
export function getLineEdgeLibraryList(data) {
return request({
url: '/wms/line-edge-library/list',
method: 'get',
params: data,
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 929 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

View File

@@ -54,7 +54,7 @@ export default {
}; };
}, },
created() { created() {
this.currentMenu = this.menus[0]; // this.currentMenu = this.menus[0];
}, },
watch: { watch: {
currentMenu(val) { currentMenu(val) {

View File

@@ -6,104 +6,48 @@
--> -->
<template> <template>
<el-form <el-form ref="form" :model="form" :label-width="`${labelWidth}px`" :size="size" :label-position="labelPosition"
ref="form" v-loading="formLoading">
:model="form" <el-row :gutter="20" v-for="(row, rindex) in rows" :key="rindex">
:label-width="`${labelWidth}px`" <el-col v-for="col in row" :key="col.label" :span="24 / row.length">
:size="size" <el-form-item :label="col.label" :prop="col.prop" :rules="col.rules">
:label-position="labelPosition" <el-input v-if="col.input" v-model="form[col.prop]" @change="$emit('update', form)"
v-loading="formLoading"> :placeholder="`请输入${col.label}`" v-bind="col.bind" />
<el-row :gutter="20" v-for="(row, rindex) in rows" :key="rindex"> <el-input v-if="col.textarea" type="textarea" v-model="form[col.prop]" @change="$emit('update', form)"
<el-col v-for="col in row" :key="col.label" :span="24 / row.length"> :placeholder="`请输入${col.label}`" v-bind="col.bind" />
<el-form-item :label="col.label" :prop="col.prop" :rules="col.rules"> <el-select v-if="col.select" v-model="form[col.prop]" :placeholder="`请选择${col.label}`"
<el-input @change="$emit('update', form)" v-bind="col.bind">
v-if="col.input" <el-option v-for="opt in optionListOf[col.prop]" :key="opt.value" :label="opt.label" :value="opt.value" />
v-model="form[col.prop]" </el-select>
@change="$emit('update', form)" <el-date-picker v-if="col.datetime" v-model="form[col.prop]" type="datetime" :placeholder="`请选择${col.label}`"
:placeholder="`请输入${col.label}`" value-format="timestamp" v-bind="col.bind"></el-date-picker>
v-bind="col.bind" /> <el-switch v-if="col.switch" v-model="form[col.prop]" active-color="#0b58ff" inactive-color="#e1e1e1"
<el-input v-bind="col.bind" @change="handleSwitchChange(col.prop)"></el-switch>
v-if="col.textarea" <component v-if="col.subcomponent" :key="col.key" :is="col.subcomponent" :inlineStyle="col.style"></component>
type="textarea"
v-model="form[col.prop]"
@change="$emit('update', form)"
:placeholder="`请输入${col.label}`"
v-bind="col.bind" />
<el-select
v-if="col.select"
v-model="form[col.prop]"
:placeholder="`请选择${col.label}`"
@change="$emit('update', form)"
v-bind="col.bind">
<el-option
v-for="opt in optionListOf[col.prop]"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
<el-date-picker
v-if="col.datetime"
v-model="form[col.prop]"
type="datetime"
:placeholder="`请选择${col.label}`"
value-format="timestamp"
v-bind="col.bind"></el-date-picker>
<el-switch
v-if="col.switch"
v-model="form[col.prop]"
active-color="#0b58ff"
inactive-color="#e1e1e1"
v-bind="col.bind"></el-switch>
<component
v-if="col.subcomponent"
:key="col.key"
:is="col.subcomponent"
:inlineStyle="col.style"></component>
<div <div class="upload-area" :class="uploadOpen ? '' : 'height-48'" ref="uploadArea" v-if="col.upload">
class="upload-area" <span class="close-icon" :class="uploadOpen ? 'open' : ''">
:class="uploadOpen ? '' : 'height-48'" <el-button type="text" icon="el-icon-arrow-right" @click="handleFilesOpen" />
ref="uploadArea" </span>
v-if="col.upload"> <!-- :file-list="uploadedFileList" -->
<span class="close-icon" :class="uploadOpen ? 'open' : ''"> <el-upload class="upload-in-dialog" v-if="col.upload" :action="uploadUrl" :headers="uploadHeaders"
<el-button :show-file-list="false" icon="el-icon-upload2" :before-upload="beforeUpload"
type="text" :on-success="handleUploadSuccess" v-bind="col.bind">
icon="el-icon-arrow-right" <el-button size="mini" :disabled="col.bind?.disabled || false">
@click="handleFilesOpen" /> <svg-icon icon-class="icon-upload" style="color: inherit"></svg-icon>
</span> 上传文件
<!-- :file-list="uploadedFileList" --> </el-button>
<el-upload <div class="el-upload__tip" slot="tip" v-if="col.uploadTips">
class="upload-in-dialog" {{ col.uploadTips || '只能上传jpg/png文件, 大小不超过2MB' }}
v-if="col.upload" </div>
:action="uploadUrl" </el-upload>
:headers="uploadHeaders" <uploadedFile class="file" v-for="file in form[col.prop] || []" :file="file" :key="file.fileUrl"
:show-file-list="false" @delete="handleDeleteFile(file)" @Preview="handlePreview(file)" />
icon="el-icon-upload2" </div>
:before-upload="beforeUpload" </el-form-item>
:on-success="handleUploadSuccess" </el-col>
v-bind="col.bind"> </el-row>
<el-button size="mini" :disabled="col.bind?.disabled || false"> </el-form>
<svg-icon
icon-class="icon-upload"
style="color: inherit"></svg-icon>
上传文件
</el-button>
<div class="el-upload__tip" slot="tip" v-if="col.uploadTips">
{{ col.uploadTips || '只能上传jpg/png文件, 大小不超过2MB' }}
</div>
</el-upload>
<uploadedFile
class="file"
v-for="file in form[col.prop] || []"
:file="file"
:key="file.fileUrl"
@delete="handleDeleteFile(file)"
@Preview="handlePreview(file)" />
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template> </template>
<script> <script>
@@ -134,7 +78,8 @@ const uploadedFile = {
data() { data() {
return {}; return {};
}, },
methods: { methods: {
handleDelete() { handleDelete() {
this.$emit('delete', this.file); this.$emit('delete', this.file);
}, },
@@ -251,7 +196,12 @@ export default {
// 处理 options // 处理 options
this.handleOptions(); this.handleOptions();
}, },
methods: { methods: {
handleSwitchChange(prop) {
// 触发 update 事件,将最新的 form 数据传递给父组件
this.$emit('update', { ...this.form });
console.log(`switch ${prop} 变化:`, this.form[prop]);
},
/** 模拟透传 ref */ /** 模拟透传 ref */
validate(cb) { validate(cb) {
return this.$refs.form.validate(cb); return this.$refs.form.validate(cb);

View File

@@ -14,12 +14,7 @@
v-if="collapse" v-if="collapse"
key="collapse" key="collapse"
class="sidebar-logo-link" class="sidebar-logo-link"
:to="{ to="/">
path: '/',
query: {
keyword: 'home',
},
}">
<img v-if="logo" :src="logo" class="sidebar-logo" /> <img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 <h1
v-else v-else
@@ -33,16 +28,7 @@
{{ title }} {{ title }}
</h1> </h1>
</router-link> </router-link>
<router-link <router-link v-else key="expand" class="sidebar-logo-link" to="/">
v-else
key="expand"
class="sidebar-logo-link"
:to="{
path: '/',
query: {
keyword: 'home',
},
}">
<img v-if="logo" :src="logo" class="sidebar-logo" /> <img v-if="logo" :src="logo" class="sidebar-logo" />
<h1 <h1
class="sidebar-title" class="sidebar-title"

View File

@@ -1,10 +1,3 @@
<!--
* @Author: zwq
* @Date: 2026-01-06 15:18:41
* @LastEditors: zwq
* @LastEditTime: 2026-01-15 09:52:23
* @Description:
-->
<template> <template>
<div v-if="!item.hidden"> <div v-if="!item.hidden">
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"> <template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">

View File

@@ -2,7 +2,7 @@
* @Author: zwq * @Author: zwq
* @Date: 2022-08-24 11:19:43 * @Date: 2022-08-24 11:19:43
* @LastEditors: zwq * @LastEditors: zwq
* @LastEditTime: 2025-11-28 09:35:03 * @LastEditTime: 2024-04-02 09:33:29
* @Description: * @Description:
*/ */
export default { export default {
@@ -69,7 +69,7 @@ export default {
this.$refs.addOrUpdate.init(val.data.id); this.$refs.addOrUpdate.init(val.data.id);
}); });
} else if (val.type === "delete") { } else if (val.type === "delete") {
this.deleteHandle(val.data.id, val.data.name, val.data._pageIndex,val.data) this.deleteHandle(val.data.id, val.data.name, val.data._pageIndex)
} else { } else {
this.otherMethods(val) this.otherMethods(val)
} }

View File

@@ -1,10 +1,3 @@
/*
* @Author: zwq
* @Date: 2026-01-06 15:18:38
* @LastEditors: zwq
* @LastEditTime: 2026-01-15 09:54:44
* @Description:
*/
import router from './router' import router from './router'
import store from './store' import store from './store'
import { Message } from 'element-ui' import { Message } from 'element-ui'
@@ -16,7 +9,7 @@ import { isRelogin } from '@/utils/request'
NProgress.configure({ showSpinner: false }) NProgress.configure({ showSpinner: false })
// 增加三方登陆 update by 芋艿 // 增加三方登陆 update by 芋艿
const whiteList = ['/login', '/social-login', 'screenbg', '/auth-redirect', '/bind', '/register', '/oauthLogin/gitee'] const whiteList = ['/login', '/social-login', '/auth-redirect', '/bind', '/register', '/oauthLogin/gitee']
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
NProgress.start() NProgress.start()
@@ -24,12 +17,7 @@ router.beforeEach((to, from, next) => {
to.meta.title && store.dispatch('settings/setTitle', to.meta.title) to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
/* has token*/ /* has token*/
if (to.path === '/login') { if (to.path === '/login') {
next({ next({ path: '/' })
path: '/',
query: {
keyword: 'home',
},
})
NProgress.done() NProgress.done()
} else { } else {
if (store.getters.roles.length === 0) { if (store.getters.roles.length === 0) {
@@ -37,9 +25,9 @@ router.beforeEach((to, from, next) => {
// 获取字典数据 add by 芋艿 // 获取字典数据 add by 芋艿
store.dispatch('dict/loadDictDatas') store.dispatch('dict/loadDictDatas')
// 判断当前用户是否已拉取完 user_info 信息 // 判断当前用户是否已拉取完 user_info 信息
store.dispatch('GetInfo').then(userInfo => { store.dispatch('GetInfo').then(() => {
isRelogin.show = false isRelogin.show = false
store.dispatch('GenerateRoutes', userInfo.menus).then(accessRoutes => { store.dispatch('GenerateRoutes').then(accessRoutes => {
// 根据 roles 权限生成可访问的路由表 // 根据 roles 权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表 router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
@@ -47,12 +35,7 @@ router.beforeEach((to, from, next) => {
}).catch(err => { }).catch(err => {
store.dispatch('LogOut').then(() => { store.dispatch('LogOut').then(() => {
Message.error(err) Message.error(err)
next({ next({ path: '/' })
path: '/',
query: {
keyword: 'home',
},
})
}) })
}) })
} else { } else {

View File

@@ -28,280 +28,223 @@ Vue.use(Router)
// 公共路由 // 公共路由
export const constantRoutes = [ export const constantRoutes = [
{ {
path: '/redirect', path: '/redirect',
component: Layout, component: Layout,
hidden: true, hidden: true,
children: [ children: [
{ {
path: '/redirect/:path(.*)', path: '/redirect/:path(.*)',
component: (resolve) => require(['@/views/redirect'], resolve), component: (resolve) => require(['@/views/redirect'], resolve)
}, }
], ]
}, },
{ {
path: '/login', path: '/login',
component: (resolve) => require(['@/views/login'], resolve), component: (resolve) => require(['@/views/login'], resolve),
// hidden: true, hidden: true
}, },
{
{ path: '/sso',
path: '/sso', component: (resolve) => require(['@/views/sso'], resolve),
component: (resolve) => require(['@/views/sso'], resolve), hidden: true
hidden: true, },
}, {
{ path: '/social-login',
path: '/social-login', component: (resolve) => require(['@/views/socialLogin'], resolve),
component: (resolve) => require(['@/views/socialLogin'], resolve), hidden: true
hidden: true, },
}, {
{ path: '/404',
path: '/404', component: (resolve) => require(['@/views/error/404'], resolve),
component: (resolve) => require(['@/views/error/404'], resolve), hidden: true
hidden: true, },
}, {
{ path: '/401',
path: '/401', component: (resolve) => require(['@/views/error/401'], resolve),
component: (resolve) => require(['@/views/error/401'], resolve), hidden: true
hidden: true, },
}, {
{ path: '/print-design',
path: '/print-design', component: (resolve) => require(['@/views/print/design'], resolve),
component: (resolve) => require(['@/views/print/design'], resolve), hidden: true
hidden: true, },
}, {
{ path: "",
path: '', component: Layout,
component: Layout, redirect: "index",
redirect: 'index', children: [
children: [ {
{ path: "index",
path: 'index', component: (resolve) => require(["@/views/home/index"], resolve),
component: (resolve) => require(['@/views/productionVisualization/equipmentBoard'], resolve), name: "首页",
name: '首页', meta: { title: "首页", icon: "dashboard", affix: true },
meta: { title: '首页', icon: 'dashboard', affix: true }, hidden: true
hidden: true, },
}, ],
], },
props: (route) => ({ {
keyword: 'home', path: '/user',
}) component: Layout,
}, hidden: true,
{ redirect: 'noredirect',
path: '/screenbg', children: [{
component: () => path: 'profile',
import( component: (resolve) => require(['@/views/system/user/profile/index'], resolve),
/* webpackChunkName: "about" */ '@/views/productionVisualization/equipmentBoard' name: 'Profile',
), meta: { title: '个人中心', icon: 'user' }
name: 'screenbg', }, {
meta: { title: '大屏', icon: 'chart' }, path: 'notify-message',
}, component: (resolve) => require(['@/views/system/notify/my/index'], resolve),
{ name: 'MyNotifyMessage',
path: '/user', meta: { title: '我的站内信', icon: 'message' },
component: Layout, }]
hidden: true, },
redirect: 'noredirect', {
children: [ path: '/dict',
{ component: Layout,
path: 'profile', hidden: true,
component: (resolve) => children: [{
require(['@/views/system/user/profile/index'], resolve), path: 'type/data/:dictId(\\d+)',
name: 'Profile', component: (resolve) => require(['@/views/system/dict/data'], resolve),
meta: { title: '个人中心', icon: 'user' }, name: 'SystemDictData',
}, meta: { title: '字典数据', icon: '', activeMenu: '/system/dict' }
{ }
path: 'notify-message', ]
component: (resolve) => },
require(['@/views/system/notify/my/index'], resolve), {
name: 'MyNotifyMessage', path: '/job',
meta: { title: '我的站内信', icon: 'message' }, component: Layout,
}, hidden: true,
], children: [{
}, path: 'log',
{ component: (resolve) => require(['@/views/infra/job/log'], resolve),
path: '/dict', name: 'InfraJobLog',
component: Layout, meta: { title: '调度日志', activeMenu: '/infra/job' }
hidden: true, }
children: [ ]
{ }, {
path: 'type/data/:dictId(\\d+)', path: '/codegen',
component: (resolve) => require(['@/views/system/dict/data'], resolve), component: Layout,
name: 'SystemDictData', hidden: true,
meta: { title: '字典数据', icon: '', activeMenu: '/system/dict' }, children: [{
}, path: 'edit/:tableId(\\d+)',
], component: (resolve) => require(['@/views/infra/codegen/editTable'], resolve),
}, name: 'InfraCodegenEditTable',
{ meta: { title: '修改生成配置', activeMenu: '/infra/codegen' }
path: '/job', }
component: Layout, ]
hidden: true, },
children: [ {
{ path: '/bpm',
path: 'log', component: Layout,
component: (resolve) => require(['@/views/infra/job/log'], resolve), hidden: true,
name: 'InfraJobLog', redirect: 'noredirect',
meta: { title: '调度日志', activeMenu: '/infra/job' }, children: [{
}, path: 'oa/leave/create',
], component: (resolve) => require(['@/views/bpm/oa/leave/create'], resolve),
}, name: 'BpmOALeaveCreate',
{ meta: { title: '发起 OA 请假', icon: 'form', activeMenu: '/bpm/oa/leave' }
path: '/codegen', }, {
component: Layout, path: 'oa/leave/detail',
hidden: true, component: (resolve) => require(['@/views/bpm/oa/leave/detail'], resolve),
children: [ name: 'BpmOALeaveDetail',
{ meta: { title: '查看 OA 请假', icon: 'view', activeMenu: '/bpm/oa/leave' }
path: 'edit/:tableId(\\d+)', }
component: (resolve) => ]
require(['@/views/infra/codegen/editTable'], resolve), },
name: 'InfraCodegenEditTable', {
meta: { title: '修改生成配置', activeMenu: '/infra/codegen' }, path: '/bpm',
}, component: Layout,
], hidden: true,
}, children: [{
{ path: 'manager/form/edit',
path: '/bpm', component: (resolve) => require(['@/views/bpm/form/formEditor'], resolve),
component: Layout, name: 'BpmFormEditor',
hidden: true, meta: { title: '流程表单-编辑', activeMenu: '/bpm/manager/form' }
redirect: 'noredirect', }, {
children: [ path: 'manager/definition',
{ component: (resolve) => require(['@/views/bpm/definition/index'], resolve),
path: 'oa/leave/create', name: 'BpmProcessDefinition',
component: (resolve) => meta: { title: '流程定义', activeMenu: '/bpm/manager/model' }
require(['@/views/bpm/oa/leave/create'], resolve), }, {
name: 'BpmOALeaveCreate', path: 'manager/model/design',
meta: { component: (resolve) => require(['@/views/bpm/model/modelEditor'], resolve),
title: '发起 OA 请假', name: 'BpmModelEditor',
icon: 'form', meta: { title: '设计流程', activeMenu: '/bpm/manager/model' }
activeMenu: '/bpm/oa/leave', }, {
}, path: 'process-instance/create',
}, component: (resolve) => require(['@/views/bpm/processInstance/create'], resolve),
{ name: 'BpmProcessInstanceCreate',
path: 'oa/leave/detail', meta: { title: '发起流程', activeMenu: '/bpm/task/my' }
component: (resolve) => }, {
require(['@/views/bpm/oa/leave/detail'], resolve), path: 'process-instance/detail',
name: 'BpmOALeaveDetail', component: (resolve) => require(['@/views/bpm/processInstance/detail'], resolve),
meta: { name: 'BpmProcessInstanceDetail',
title: '查看 OA 请假', meta: { title: '流程详情', activeMenu: '/bpm/task/my' }
icon: 'view', }
activeMenu: '/bpm/oa/leave', ]
}, },
}, {
], path: '/property',
}, component: Layout,
{ hidden: true,
path: '/bpm', children: [{
component: Layout, path: 'value/:propertyId(\\d+)',
hidden: true, component: (resolve) => require(['@/views/mall/product/property/value'], resolve),
children: [ name: 'ProductPropertyValue',
{ meta: { title: '商品属性值', icon: '', activeMenu: '/product/property' }
path: 'manager/form/edit', }
component: (resolve) => ]
require(['@/views/bpm/form/formEditor'], resolve), },
name: 'BpmFormEditor', {
meta: { title: '流程表单-编辑', activeMenu: '/bpm/manager/form' }, path: '/spu',
}, component: Layout,
{ hidden: true,
path: 'manager/definition', children: [{
component: (resolve) => path: 'edit/:spuId(\\d+)',
require(['@/views/bpm/definition/index'], resolve), component: (resolve) => require(['@/views/mall/product/spu/save'], resolve),
name: 'BpmProcessDefinition', name: 'ProductSpuUpdate',
meta: { title: '流程定义', activeMenu: '/bpm/manager/model' }, meta: { title: '修改商品', activeMenu: '/product/spu' }
}, },
{ {
path: 'manager/model/design', path: 'add',
component: (resolve) => component: (resolve) => require(['@/views/mall/product/spu/save'], resolve),
require(['@/views/bpm/model/modelEditor'], resolve), name: 'ProductSpuCreate',
name: 'BpmModelEditor', meta: { title: '添加商品', activeMenu: '/product/spu' }
meta: { title: '设计流程', activeMenu: '/bpm/manager/model' }, }
}, ]
{ },
path: 'process-instance/create', {
component: (resolve) => path: '/trade/order',
require(['@/views/bpm/processInstance/create'], resolve), component: Layout,
name: 'BpmProcessInstanceCreate', hidden: true,
meta: { title: '发起流程', activeMenu: '/bpm/task/my' }, children: [
}, {
{ path: 'detail',
path: 'process-instance/detail', name: 'TradeOrderDetail',
component: (resolve) => hidden: true,
require(['@/views/bpm/processInstance/detail'], resolve), meta: { title: '订单详情' },
name: 'BpmProcessInstanceDetail', component: (resolve) => require(['@/views/mall/trade/order/detail'], resolve)
meta: { title: '流程详情', activeMenu: '/bpm/task/my' }, }
}, ]
], },
}, {
{ path: '/pay',
path: '/property', component: Layout,
component: Layout, hidden: true,
hidden: true, children: [{
children: [ path: 'order/submit',
{ name: 'PayOrderSubmit',
path: 'value/:propertyId(\\d+)', hidden: true,
component: (resolve) => meta: {
require(['@/views/mall/product/property/value'], resolve), title: '收银台',
name: 'ProductPropertyValue', noCache: true
meta: { },
title: '商品属性值', component: (resolve) => require(['@/views/pay/order/submit'], resolve)
icon: '', }]
activeMenu: '/product/property', }
}, ]
},
],
},
{
path: '/spu',
component: Layout,
hidden: true,
children: [
{
path: 'edit/:spuId(\\d+)',
component: (resolve) =>
require(['@/views/mall/product/spu/save'], resolve),
name: 'ProductSpuUpdate',
meta: { title: '修改商品', activeMenu: '/product/spu' },
},
{
path: 'add',
component: (resolve) =>
require(['@/views/mall/product/spu/save'], resolve),
name: 'ProductSpuCreate',
meta: { title: '添加商品', activeMenu: '/product/spu' },
},
],
},
{
path: '/trade/order',
component: Layout,
hidden: true,
children: [
{
path: 'detail',
name: 'TradeOrderDetail',
hidden: true,
meta: { title: '订单详情' },
component: (resolve) =>
require(['@/views/mall/trade/order/detail'], resolve),
},
],
},
{
path: '/pay',
component: Layout,
hidden: true,
children: [
{
path: 'order/submit',
name: 'PayOrderSubmit',
hidden: true,
meta: {
title: '收银台',
noCache: true,
},
component: (resolve) => require(['@/views/pay/order/submit'], resolve),
},
],
},
];
// 防止连续点击多次路由报错 // 防止连续点击多次路由报错
let routerPush = Router.prototype.push; let routerPush = Router.prototype.push;

View File

@@ -1,4 +1,5 @@
import {constantRoutes} from '@/router' import {constantRoutes} from '@/router'
import {getRouters} from '@/api/menu'
import Layout from '@/layout/index' import Layout from '@/layout/index'
import ParentView from '@/components/ParentView'; import ParentView from '@/components/ParentView';
import {toCamelCase} from "@/utils"; import {toCamelCase} from "@/utils";
@@ -26,25 +27,22 @@ const permission = {
}, },
}, },
actions: { actions: {
/** // 生成路由
* 生成路由 GenerateRoutes({commit}) {
*
* @param commit commit 函数
* @param menus 路由参数
*/
GenerateRoutes({commit}, menus) {
return new Promise(resolve => { return new Promise(resolve => {
// 将 menus 菜单,转换为 route 路由数组 // 向后端请求路由数据(菜单)
const sdata = JSON.parse(JSON.stringify(menus)) // 【重要】用于菜单中的数据 getRouters().then(res => {
const rdata = JSON.parse(JSON.stringify(menus)) // 用于最后添加到 Router 中的数据 const sdata = JSON.parse(JSON.stringify(res.data)) // 【重要】用于菜单中的数据
const sidebarRoutes = filterAsyncRouter(sdata) const rdata = JSON.parse(JSON.stringify(res.data)) // 用于最后添加到 Router 中的数据
const rewriteRoutes = filterAsyncRouter(rdata, false, true) const sidebarRoutes = filterAsyncRouter(sdata)
rewriteRoutes.push({path: '*', redirect: '/404', hidden: true}) const rewriteRoutes = filterAsyncRouter(rdata, false, true)
commit('SET_ROUTES', rewriteRoutes) rewriteRoutes.push({path: '*', redirect: '/404', hidden: true})
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes)) commit('SET_ROUTES', rewriteRoutes)
commit('SET_DEFAULT_ROUTES', sidebarRoutes) commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
commit('SET_TOPBAR_ROUTES', sidebarRoutes) commit('SET_DEFAULT_ROUTES', sidebarRoutes)
resolve(rewriteRoutes) commit('SET_TOPBAR_ROUTES', sidebarRoutes)
resolve(rewriteRoutes)
})
}) })
} }
} }

View File

@@ -1,10 +1,10 @@
import axios from 'axios' import axios from 'axios'
import {Message, MessageBox, Notification, Loading} from 'element-ui' import { Message, MessageBox, Notification, Loading } from 'element-ui'
import store from '@/store' import store from '@/store'
import {getAccessToken, getRefreshToken, getTenantId, setToken} from '@/utils/auth' import { getAccessToken, getRefreshToken, getTenantId, setToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode' import errorCode from '@/utils/errorCode'
import {getPath, getTenantEnable} from "@/utils/ruoyi"; import { getPath, getTenantEnable } from "@/utils/ruoyi";
import {refreshToken} from "@/api/login"; import { refreshToken } from "@/api/login";
// 需要忽略的提示。忽略后,自动 Promise.reject('error') // 需要忽略的提示。忽略后,自动 Promise.reject('error')
const ignoreMsgs = [ const ignoreMsgs = [
@@ -86,7 +86,7 @@ service.interceptors.request.use(config => {
for (const propName of Object.keys(config.params)) { for (const propName of Object.keys(config.params)) {
const value = config.params[propName]; const value = config.params[propName];
const part = encodeURIComponent(propName) + '=' const part = encodeURIComponent(propName) + '='
if (value !== null && typeof(value) !== "undefined") { if (value !== null && typeof (value) !== "undefined") {
if (typeof value === 'object') { if (typeof value === 'object') {
for (const key of Object.keys(value)) { for (const key of Object.keys(value)) {
let params = propName + '[' + key + ']'; let params = propName + '[' + key + ']';
@@ -104,9 +104,9 @@ service.interceptors.request.use(config => {
} }
return config return config
}, error => { }, error => {
tryHideFullScreenLoading() tryHideFullScreenLoading()
console.log(error) console.log(error)
Promise.reject(error) Promise.reject(error)
}) })
// 响应拦截器 // 响应拦截器
@@ -176,36 +176,38 @@ service.interceptors.response.use(async res => {
+ '<div>5 分钟搭建本地环境</div>', + '<div>5 分钟搭建本地环境</div>',
}) })
return Promise.reject(new Error(msg)) return Promise.reject(new Error(msg))
} else if (code === 400) {
//【班组管理】【排班计划】提交的校验按照原型图补充完整,排班计划是否重叠code400 有两个不同的返回信息
return res.data
} else if (code !== 200) { } else if (code !== 200) {
if (msg === '无效的刷新令牌') { // hard coding忽略这个提示直接登出 if (msg === '无效的刷新令牌') { // hard coding忽略这个提示直接登出
console.log(msg) console.log(msg)
} else { } else {
Notification.error({ //【班组管理】【排班计划】提交的校验按照原型图补充完整,排班计划是否重叠code400 有两个不同的返回信息
title: msg return res.data
})
} }
return Promise.reject('error') return Promise.reject('error')
} else { } else {
return res.data return res.data
} }
}, error => { }, error => {
tryHideFullScreenLoading() tryHideFullScreenLoading()
console.log('err' + error) console.log('err' + error)
let {message} = error; let { message } = error;
if (message === "Network Error") { if (message === "Network Error") {
message = "后端接口连接异常"; message = "后端接口连接异常";
} else if (message.includes("timeout")) { } else if (message.includes("timeout")) {
message = "系统接口请求超时"; message = "系统接口请求超时";
} else if (message.includes("Request failed with status code")) { } else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常"; message = "系统接口" + message.substr(message.length - 3) + "异常";
}
Message({
message: message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
} }
Message({
message: message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
) )
export function getBaseHeader() { export function getBaseHeader() {
@@ -219,10 +221,10 @@ function handleAuthorized() {
if (!isRelogin.show) { if (!isRelogin.show) {
isRelogin.show = true; isRelogin.show = true;
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录', confirmButtonText: '重新登录',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
} }
).then(() => { ).then(() => {
isRelogin.show = false; isRelogin.show = false;
store.dispatch('LogOut').then(() => { store.dispatch('LogOut').then(() => {

View File

@@ -1,81 +0,0 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2025-11-28 14:38:31
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="80px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物料编码" prop="materialCode">
<el-input
v-model="dataForm.materialCode"
clearable
placeholder="请输入物料编码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料型号" prop="materialName">
<el-input
v-model="dataForm.materialName"
clearable
placeholder="请输入物料型号" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物料规格" prop="material">
<el-input
v-model="dataForm.material"
clearable
placeholder="请输入物料规格" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '@/mixins/basic-add';
import { createProduct, updateProduct,getProduct } from '@/api/ssdl/product&recipe';
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
createURL: createProduct,
updateURL: updateProduct,
infoURL: getProduct,
},
dataForm: {
id: undefined,
material: undefined,
materialName: undefined,
materialCode: undefined,
},
typeArr: [],
dataRule: {
materialCode: [
{ required: true, message: '物料编码不能为空', trigger: 'blur' },
],
materialName: [
{ required: true, message: '物料型号不能为空', trigger: 'blur' },
],
material: [
{ required: true, message: '规格不能为空', trigger: 'blur' },
],
},
};
},
methods: {},
};
</script>

View File

@@ -1,62 +0,0 @@
<!--
* @Author: zwq
* @Date: 2025-10-11 14:41:12
* @LastEditors: zwq
* @LastEditTime: 2026-01-14 14:15:47
* @Description:
-->
<template>
<el-switch
@change="changeStatus"
size="small"
v-model="injectData.laneState"
:active-value="1"
:inactive-value="2"></el-switch>
</template>
<script>
import { updateLane } from '@/api/areavisual/lane';
export default {
props: {
injectData: {
type: Object,
default: () => ({}),
},
},
data() {
return {};
},
created() {},
methods: {
changeStatus(val) {
const pdata = { ...this.injectData, laneState: val };
this.$confirm(
`是否确认修改${'巷道 [ ' + this.injectData.laneName + ' ] '}的状态?`,
'更新状态',
{
confirmButtonText: '确认修改',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
updateLane(pdata).then((res) => {
if (res.code === 0 || res.code === 200) {
this.$modal.msgSuccess('修改成功');
this.$emit('emitData');
} else {
this.$modal.msg(res.msg);
}
});
})
.catch((res) => {
this.$emit('emitData');
this.$message({
type: 'info',
message: '已取消',
});
});
},
},
};
</script>

View File

@@ -1,324 +0,0 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2026-01-15 09:16:36
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="80px">
<div class="stat-card">
<div class="stat-icon">
<i class="el-icon-s-grid" style="color: #fff"></i>
</div>
<div class="stat-title">库位信息</div>
<div class="stat-content">
<div class="stat-value">{{ lineInfo.lineEdgeLibraryCode }}</div>
<div class="stat-label">{{ lineInfo.lineEdgeLibraryName }}</div>
</div>
</div>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="物料" prop="materialId">
<el-select
style="width: 100%"
v-model="dataForm.materialId"
filterable
@change="setMaterial"
placeholder="请选择物料">
<el-option
v-for="item in productArr"
:key="item.id"
:label="
item.materialCode +
'-' +
item.materialName +
'-' +
item.material
"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="本盘长度" prop="cableLength">
<el-input-number
v-model="dataForm.cableLength"
:min="0"
:precision="2"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备" prop="equipmentId">
<el-select
v-model="dataForm.equipmentId"
@change="setEquipment"
placeholder="请选择绞体">
<el-option
v-for="item in options1"
:key="item.id"
:label="item.equipmentName"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="应用套号" prop="suite">
<el-select v-model="dataForm.suite" placeholder="请选择应用套号">
<el-option
v-for="item in options2"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<span v-if="dataForm.suite == 2">
<el-col :span="8">
<el-form-item label="选择套号" prop="time">
<el-date-picker
v-model="dataForm.time"
value-format="yyyy-MM-dd"
type="date"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="" prop="productionLine">
<el-select v-model="dataForm.productionLine">
<el-option
v-for="item in options3"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="" prop="numb">
<el-select v-model="dataForm.numb">
<el-option
v-for="item in options4"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
</span>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '@/mixins/basic-add';
import { getAllProductPage } from '@/api/ssdl/product&recipe';
import {
QKLineEdgeLibrary,
getEquipmentPage,
} from '@/api/areavisual/lineEdgeLibrary';
import { parseTime } from '@/filter/code-filter';
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
createURL: QKLineEdgeLibrary,
},
dataForm: {
id: undefined,
materialId: undefined,
materialName: undefined,
materialCode: undefined,
material: undefined,
cableLength: undefined,
equipmentId: undefined,
equipmentName: undefined,
suite: undefined, //是否成套
suiteCode: undefined, //套号
time: this.parseTime(new Date(), '{y}-{m}-{d}'),
productionLine: undefined,
numb: undefined,
},
lineInfo: {},
productArr: [],
options1: [],
options2: [
{
value: 2,
label: '是',
},
{
value: 1,
label: '否',
},
],
options3: [
{
value: '6#',
label: '6#',
},
{
value: '7#',
label: '7#',
},
{
value: '8#',
label: '8#',
},
],
options4: [
{
value: 0,
label: '0',
},
{
value: 1,
label: '1',
},
{
value: 2,
label: '2',
},
{
value: 3,
label: '3',
},
{
value: 4,
label: '4',
},
{
value: 5,
label: '5',
},
{
value: 6,
label: '6',
},
],
dataRule: {
materialId: [
{ required: true, message: '物料不能为空', trigger: 'change' },
],
time: [{ required: true, message: '不能为空', trigger: 'change' }],
productionLine: [
{ required: true, message: '不能为空', trigger: 'change' },
],
numb: [{ required: true, message: '不能为空', trigger: 'change' }],
},
};
},
methods: {
showLine(val) {
getAllProductPage().then((res) => {
this.productArr = res.data;
});
getEquipmentPage({ pageNo: 1, pageSize: 100, equipmentType: 2 }).then(
(res) => {
this.options1 = res.data.list;
}
);
this.lineInfo = { ...val };
},
setMaterial() {
const data = this.productArr.find(
(i) => i.id === this.dataForm.materialId
);
this.dataForm.materialName = data.materialName;
this.dataForm.material = data.material;
this.dataForm.materialCode = data.materialCode;
},
setEquipment() {
const data = this.options1.find(
(i) => i.id === this.dataForm.equipmentId
);
this.dataForm.equipmentName = data.equipmentName;
},
// 表单提交
dataFormSubmit() {
this.$refs['dataForm'].validate((valid) => {
if (!valid) {
return false;
}
if (this.dataForm.suite == 2) {
this.dataForm.suiteCode =
this.dataForm.time +
'-' +
this.dataForm.productionLine +
'-' +
this.dataForm.numb;
}
QKLineEdgeLibrary({
...this.lineInfo,
...this.dataForm,
lineEdgeLibraryState: 1,
id: this.lineInfo.id,
}).then((response) => {
this.$modal.msgSuccess('操作成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
});
},
},
};
</script>
<style scoped>
.stat-card {
display: flex;
align-items: center;
padding: 10px;
background: white;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
border-left: 4px solid;
border-color: #1a56db;
margin-bottom: 30px;
}
/* .stat-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
} */
.stat-title {
margin: 0 10px;
color: #0051ff;
font-size: 20px;
}
.stat-icon {
display: flex;
align-items: center;
justify-content: center;
width: 60px;
height: 60px;
border-radius: 12px;
margin-right: 15px;
background: linear-gradient(to right, #1a56db, #0d47a1);
}
.stat-content {
display: flex;
flex-direction: column;
}
.stat-value {
font-size: 28px;
font-weight: 700;
line-height: 1.2;
color: #1a56db;
}
.stat-label {
font-size: 14px;
color: #64748b;
}
</style>

View File

@@ -1,318 +0,0 @@
<template>
<div class="app-container">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:table-data="tableData"
@emitFun="getDataList">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="110"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
destroy-on-close
width="50%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '@/mixins/basic-page';
import { parseTime } from '@/filter/code-filter';
import {
deleteLineEdgeLibrary,
getLineEdgeLibraryPage,
QKLineEdgeLibrary,
} from '@/api/areavisual/lineEdgeLibrary';
const laneRow = [
{
id: '1',
name: '第一排',
},
{
id: '2',
name: '第二排',
},
{
id: '3',
name: '第三排',
},
{
id: '4',
name: '第四排',
},
{
id: '5',
name: '第五排',
},
{
id: '6',
name: '第六排',
},
];
const tableProps = [
{
prop: 'lineEdgeLibraryCode',
label: '线边库编码',
},
{
prop: 'lineEdgeLibraryName',
label: '线边库名称',
},
{
prop: 'agvGroundCode',
label: 'agv码',
},
{
prop: 'lineEdgeLibraryState',
label: '线边库状态',
width: 90,
filter: (val) => {
return val ? '满位' : '空闲';
},
},
{
prop: 'usableState',
label: '是否可用',
width: 90,
filter: (val) => {
return ['', '可用', '不可用', '锁定'][val];
},
},
{
prop: 'trayType',
label: '托盘类型',
width: 90,
filter: (val) => {
return val ? '笼式' : '盘式';
},
},
{
prop: 'productionLine',
label: '产线',
},
{
prop: 'equipmentName',
label: '设备',
},
{
prop: 'suiteCode',
label: '套号',
},
{
prop: 'laneRow',
label: '巷道排',
filter: (val) => {
return laneRow.find((i) => i.id == val)
? laneRow.find((i) => i.id == val).name
: '-';
},
},
{
prop: 'materialCode',
label: '物料',
},
{
prop: 'batch',
label: '批次',
},
{
prop: 'cableLength',
label: '线缆长度',
},
{
prop: 'createTime',
label: '创建时间',
filter: parseTime,
width: 150,
},
];
export default {
mixins: [basicPage],
data() {
return {
urlOptions: {
getDataListURL: getLineEdgeLibraryPage,
deleteURL: deleteLineEdgeLibrary,
},
tableProps,
tableData: [],
tableBtn: [
{
type: 'clear',
btnName: '清空',
},
{
type: 'add',
btnName: '添加',
},
].filter((v) => v),
formConfig: [
{
type: 'input',
label: '线边库名称',
placeholder: '线边库名称',
param: 'name',
},
{
type: 'input',
label: '线边库编码',
placeholder: '线边库编码',
param: 'code',
},
{
type: 'select',
label: '巷道排',
selectOptions: laneRow,
placeholder: '请选择巷道排',
param: 'laneRow',
},
{
type: 'button',
btnName: '搜索',
name: 'search',
color: 'primary',
},
// {
// type: 'separate',
// },
// {
// type: 'button',
// btnName: '重置',
// name: 'reset',
// },
// {
// type: 'separate',
// },
// {
// type: 'button',
// btnName: '新增',
// name: 'add',
// color: 'success',
// plain: true,
// },
// {
// type: this.$auth.hasPermi('base:factory:create') ? 'separate' : '',
// },
// {
// type: this.$auth.hasPermi('base:factory:export') ? 'button' : '',
// btnName: '导出',
// name: 'export',
// color: 'warning',
// },
],
};
},
components: {
AddOrUpdate,
},
created() {},
methods: {
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 20;
this.listQuery.lineEdgeLibraryName = val.name;
this.listQuery.lineEdgeLibraryCode = val.code;
this.listQuery.laneRow = val.laneRow;
this.getDataList();
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.listQuery = {
pageSize: 20,
pageNo: 1,
total: 1,
};
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.addOrUpdateHandle();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
otherMethods(val) {
if (val.type == 'clear') {
if (val.data.usableState == 3) {
this.$confirm(
`当前库位为锁定状态,代表该库位有未完成的任务关联,是否确认清空${
'线边库名称为 ' + val.data.lineEdgeLibraryName + ' '
}的数据项?`,
'锁定库位清空提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
QKLineEdgeLibrary({...val.data,lineEdgeLibraryState:0,usableState:1 }).then(({ data }) => {
this.$message({
message: data,
type: 'success',
duration: 1500,
onClose: () => {
this.getDataList();
},
});
});
})
.catch(() => {});
} else {
QKLineEdgeLibrary({...val.data,lineEdgeLibraryState:0,usableState:1 }).then(({ data }) => {
this.$message({
message: data,
type: 'success',
duration: 1500,
onClose: () => {
this.getDataList();
},
});
});
}
} else if (val.type === 'add') {
this.addOrEditTitle = '添加货物';
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init();
this.$refs.addOrUpdate.showLine(val.data);
});
}
},
},
};
</script>

View File

@@ -1,326 +0,0 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2026-02-03 13:30:54
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="80px">
<div class="stat-card">
<div class="stat-icon">
<i class="el-icon-s-grid" style="color: #fff"></i>
</div>
<div class="stat-title">库位信息</div>
<div class="stat-content">
<div class="stat-value">{{ lineInfo.lineEdgeLibraryCode }}</div>
<div class="stat-label">{{ lineInfo.lineEdgeLibraryName }}</div>
</div>
</div>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="物料" prop="materialId">
<el-select
style="width: 100%"
v-model="dataForm.materialId"
filterable
@change="setMaterial"
placeholder="请选择物料">
<el-option
v-for="item in productArr"
:key="item.id"
:label="
item.materialCode +
'-' +
item.materialName +
'-' +
item.material
"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="本盘长度" prop="cableLength">
<el-input-number
v-model="dataForm.cableLength"
:min="0"
:precision="2"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备" prop="equipmentId">
<el-select
v-model="dataForm.equipmentId"
@change="setEquipment"
placeholder="请选择绞体">
<el-option
v-for="item in options1"
:key="item.id"
:label="item.equipmentName"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="应用套号" prop="suite">
<el-select v-model="dataForm.suite" placeholder="请选择应用套号">
<el-option
v-for="item in options2"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<span v-if="dataForm.suite == 2">
<el-col :span="8">
<el-form-item label="选择套号" prop="time">
<el-date-picker
v-model="dataForm.time"
value-format="yyyy-MM-dd"
type="date"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="" prop="productionLine">
<el-select v-model="dataForm.productionLine">
<el-option
v-for="item in options3"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="" prop="numb">
<el-select v-model="dataForm.numb">
<el-option
v-for="item in options4"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
</span>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '@/mixins/basic-add';
import { getAllProductPage } from '@/api/ssdl/product&recipe';
import {
QKLineEdgeLibrary,
getEquipmentPage,
} from '@/api/areavisual/lineEdgeLibrary';
import { parseTime } from '@/filter/code-filter';
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
createURL: QKLineEdgeLibrary,
},
dataForm: {
id: undefined,
materialId: undefined,
materialName: undefined,
materialCode: undefined,
material: undefined,
cableLength: undefined,
equipmentId: undefined,
equipmentName: undefined,
suite: undefined, //是否成套
suiteCode: undefined, //套号
time: this.parseTime(new Date(), '{y}-{m}-{d}'),
productionLine: undefined,
numb: undefined,
},
lineInfo: {},
productArr: [],
options1: [],
options2: [
{
value: 2,
label: '是',
},
{
value: 1,
label: '否',
},
],
options3: [
{
value: '6#',
label: '6#',
},
{
value: '7#',
label: '7#',
},
{
value: '8#',
label: '8#',
},
],
options4: [
{
value: 0,
label: '0',
},
{
value: 1,
label: '1',
},
{
value: 2,
label: '2',
},
{
value: 3,
label: '3',
},
{
value: 4,
label: '4',
},
{
value: 5,
label: '5',
},
{
value: 6,
label: '6',
},
],
dataRule: {
materialId: [
{ required: true, message: '物料不能为空', trigger: 'change' },
],
time: [{ required: true, message: '不能为空', trigger: 'change' }],
productionLine: [
{ required: true, message: '不能为空', trigger: 'change' },
],
numb: [{ required: true, message: '不能为空', trigger: 'change' }],
equipmentId: [{ required: true, message: '不能为空', trigger: 'change' }],
suite: [{ required: true, message: '不能为空', trigger: 'change' }],
},
};
},
methods: {
showLine(val) {
getAllProductPage().then((res) => {
this.productArr = res.data;
});
getEquipmentPage({ pageNo: 1, pageSize: 100, equipmentType: 2 }).then(
(res) => {
this.options1 = res.data.list;
}
);
this.lineInfo = { ...val };
},
setMaterial() {
const data = this.productArr.find(
(i) => i.id === this.dataForm.materialId
);
this.dataForm.materialName = data.materialName;
this.dataForm.material = data.material;
this.dataForm.materialCode = data.materialCode;
},
setEquipment() {
const data = this.options1.find(
(i) => i.id === this.dataForm.equipmentId
);
this.dataForm.equipmentName = data.equipmentName;
},
// 表单提交
dataFormSubmit() {
this.$refs['dataForm'].validate((valid) => {
if (!valid) {
return false;
}
if (this.dataForm.suite == 2) {
this.dataForm.suiteCode =
this.dataForm.time +
'-' +
this.dataForm.productionLine +
'-' +
this.dataForm.numb;
}
QKLineEdgeLibrary({
...this.lineInfo,
...this.dataForm,
lineEdgeLibraryState: 1,
id: this.lineInfo.id,
}).then((response) => {
this.$modal.msgSuccess('操作成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
});
},
},
};
</script>
<style scoped>
.stat-card {
display: flex;
align-items: center;
padding: 10px;
background: white;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
border-left: 4px solid;
border-color: #1a56db;
margin-bottom: 30px;
}
/* .stat-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
} */
.stat-title {
margin: 0 10px;
color: #0051ff;
font-size: 20px;
}
.stat-icon {
display: flex;
align-items: center;
justify-content: center;
width: 60px;
height: 60px;
border-radius: 12px;
margin-right: 15px;
background: linear-gradient(to right, #1a56db, #0d47a1);
}
.stat-content {
display: flex;
flex-direction: column;
}
.stat-value {
font-size: 28px;
font-weight: 700;
line-height: 1.2;
color: #1a56db;
}
.stat-label {
font-size: 14px;
color: #64748b;
}
</style>

View File

@@ -1,687 +0,0 @@
<template>
<div class="app-container">
<el-row class="overview-container">
<el-col :span="4" class="overview-container-left">
<el-row style="font-size: 18px; font-weight: bold; line-height: 36px">
库区选择
</el-row>
<el-input
v-model="areaSearchForm.regionName"
placeholder="库区名称"
@blur="getArea"
clearable />
<el-tree
:data="areaList"
:node-key="'id'"
:props="{ label: 'regionName' }"
@node-click="nodeClick" />
</el-col>
<el-col
:span="16"
v-if="changeType === 0"
class="overview-container-main">
<el-row>
<el-col
:span="8"
class="allarea-box"
v-for="item in allAreaList"
:key="item.id">
<div class="areainfo-box">
<div class="areainfo-box-header">
{{ item.regionName }}
</div>
<div class="areainfo-box-line">
<div
class="areainfo-box-line-item"
:style="{
width: `${(
(item.occupiedQuantity /
(item.totalInventory + item.transitQuantity)) *
100
).toFixed(2)}%`,
backgroundColor: '#33B36B',
}"></div>
<div
class="areainfo-box-line-item"
:style="{
width: `${(
(item.idleQuantity /
(item.totalInventory + item.transitQuantity)) *
100
).toFixed(2)}%`,
backgroundColor: '#3A8DFF',
}"></div>
<div
class="areainfo-box-line-item"
:style="{
width: `${(
(item.transitQuantity /
(item.totalInventory + item.transitQuantity)) *
100
).toFixed(2)}%`,
backgroundColor: '#F59A23',
}"></div>
</div>
<el-row class="areainfo-box-info">
<el-col class="areainfo-box-info-item" :span="6">
<p class="areainfo-box-info-item-count">
{{ item.totalInventory }}
</p>
<p class="areainfo-box-info-item-title">库位总数</p>
</el-col>
<el-col class="areainfo-box-info-item" :span="6">
<p
class="areainfo-box-info-item-count"
style="color: #33b36b">
{{ item.occupiedQuantity }}
</p>
<p class="areainfo-box-info-item-title"></p>
</el-col>
<el-col class="areainfo-box-info-item" :span="6">
<p
class="areainfo-box-info-item-count"
style="color: #3a8dff">
{{ item.idleQuantity }}
</p>
<p class="areainfo-box-info-item-title"></p>
</el-col>
<el-col class="areainfo-box-info-item" :span="6">
<p
class="areainfo-box-info-item-count"
style="color: #f59a23">
{{ item.transitQuantity }}
</p>
<p class="areainfo-box-info-item-title">在途</p>
</el-col>
</el-row>
</div>
</el-col>
</el-row>
</el-col>
<el-col
:span="4"
v-if="changeType === 0"
class="overview-container-right">
<el-tabs v-model="activeName" @tab-click="handleClickRight">
<el-tab-pane label="概览" name="first">
<el-row class="overview-container-right-alloverview">
<el-col
class="overview-container-right-alloverview-item"
:span="8">
<p class="overview-container-right-alloverview-item-count">
{{ allAreaInfo.totalInventory }}
</p>
<p class="overview-container-right-alloverview-item-title">
库位总数
</p>
</el-col>
<el-col
class="overview-container-right-alloverview-item"
:span="8">
<p class="overview-container-right-alloverview-item-count">
{{ allAreaInfo.occupiedQuantity }}
</p>
<p class="overview-container-right-alloverview-item-title">
当前满位
</p>
</el-col>
<el-col
class="overview-container-right-alloverview-item"
:span="8">
<p class="overview-container-right-alloverview-item-count">
{{ allAreaInfo.idleQuantity }}
</p>
<p class="overview-container-right-alloverview-item-title">
当前空位
</p>
</el-col>
<el-col
class="overview-container-right-alloverview-item"
:span="8">
<p class="overview-container-right-alloverview-item-count">
{{ allAreaInfo.transitQuantity }}
</p>
<p class="overview-container-right-alloverview-item-title">
在途
</p>
</el-col>
</el-row>
<ringChart :ring-data="allAreaInfo" ref="ringChart" />
</el-tab-pane>
<el-tab-pane label="在途任务" name="second">在途任务</el-tab-pane>
</el-tabs>
</el-col>
<el-col
:span="20"
v-if="changeType === 1"
class="overview-container-main">
<div class="stat-card">
<div class="stat-icon">
<i class="el-icon-s-grid" style="color: #fff"></i>
</div>
<div class="stat-title">库区信息</div>
<div class="stat-content">
<div class="stat-value">{{ getAreaInfoInfo.regionName }}</div>
<div class="stat-label">{{ getAreaInfoInfo.regionCode }}</div>
</div>
</div>
<div class="area-body">
<div v-for="item in Object.keys(areaInfo)" :key="item">
<el-button size="mini" style="width:189px;" type="primary" @click="clearAll(item)">
一键清空
</el-button>
<div class="potTitle">{{ item }}</div>
<div class="potList">
<div v-for="sitem in areaInfo[item]" :key="sitem.id">
<div v-if="sitem.empty" class="area-div-empty" />
<div v-else class="area-div" :title="sitem.lineEdgeLibraryName">
<el-popover
placement="top-start"
:title="sitem.lineEdgeLibraryCode"
width="200"
trigger="hover">
<div class="point" />
<span style="font-weight: 600">名称:</span>
{{ sitem.lineEdgeLibraryName }}
<br />
<div class="point" />
<span style="font-weight: 600">状态:</span>
{{
sitem.usableState == 3
? '锁定'
: sitem.usableState == 2
? '不可用'
: sitem.lineEdgeLibraryState == 1
? '满位'
: '空闲'
}}
<br />
<span
v-if="sitem.usableState == 3 ||
(sitem.usableState == 1 &&
sitem.lineEdgeLibraryState == 1)
">
<span style="font-weight: 600">物料:</span>
{{ sitem.materialCode || '' }}
<br />
<span style="font-weight: 600">设备:</span>
{{ sitem.equipmentName || '' }}
<br />
<span style="font-weight: 600">套号:</span>
{{ sitem.suiteCode || '' }}
<br />
</span>
<el-button type="text" @click="clearLine(sitem)">
清空
</el-button>
<el-button type="text" @click="addLine(sitem)">
添加
</el-button>
<div
class="area-icon"
:style="{
backgroundColor:
sitem.usableState == 3
? '#E6A23C'
: sitem.usableState == 2
? 'gray'
: sitem.lineEdgeLibraryState == 1
? '#67C23A'
: '',
}"
slot="reference">
<i
:class="
sitem.usableState == 3
? 'el-icon-lock'
: 'el-icon-s-grid'
"
style="color: #fff"></i>
</div>
</el-popover>
</div>
</div>
</div>
</div>
</div>
</el-col>
</el-row>
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
destroy-on-close
width="50%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
</template>
<script>
// import basicPage from '@/mixins/basic-page';
import ringChart from './components/ringChart.vue';
import AddOrUpdate from './components/add-or-updata';
import basicPage from '@/mixins/basic-page';
import {
getAreaList,
postAllAreaInfo,
postAllAreaOverview,
postAreaInfo,
} from '@/api/areavisual/overview';
import { QKLineEdgeLibrary,AllQKLineEdgeLibrary } from '@/api/areavisual/lineEdgeLibrary';
export default {
name: 'overview',
mixins: [basicPage],
data() {
return {
areaList: [
{
id: 0,
regionName: '全部库区',
},
],
areaSearchForm: {
pageNo: 1,
pageSize: 100,
regionName: '',
},
changeType: 0,
allAreaList: [],
allAreaInfo: {
totalInventory: 0,
occupiedQuantity: 0,
idleQuantity: 0,
transitQuantity: 0,
},
areaInfo: {},
activeName: 'first',
getAreaInfoInfo: {},
};
},
components: {
ringChart,
AddOrUpdate,
},
async created() {
this.getArea();
this.getAllAreaInfo();
this.getAllAreaOverview();
},
watch: {
activeName: (val) => {
if (val === 'first') {
this.getAllAreaOverview();
} else if (val === 'second') {
this.getNowTaskList();
}
},
},
methods: {
// 获取库区列表
async getArea() {
const res = await getAreaList(this.areaSearchForm);
if (res.code === 0 && res.data) {
(this.areaList = [
{
id: 0,
regionName: '全部库区',
},
]),
this.areaList.push(...res.data.list);
}
},
// 库区选择
nodeClick(data, node, components) {
if (data.id === 0) {
this.changeType = 0;
this.activeName = 'first';
this.getAllAreaInfo();
} else {
this.getAreaInfoInfo = data; //把库区存下,方便刷新
this.changeType = 1;
this.getAreaInfo(data.id);
}
},
// 获取全部库区概览信息
async getAllAreaInfo() {
const res = await postAllAreaInfo([]);
console.log(res);
if (res.code === 0 && res.data) {
this.allAreaList = res.data;
}
},
// 获取库区概览
async getAllAreaOverview() {
const res = await postAllAreaOverview([]);
console.log(res);
if (res.code === 0 && res.data) {
this.allAreaInfo = res.data;
this.$refs.ringChart.initChart();
}
},
// 获取在途任务
async getNowTaskList() {},
// 获取单库区信息
async getAreaInfo(id) {
const res = await postAreaInfo({ id });
if (res.code === 0 && res.data) {
// 按巷道号分组
this.areaInfo = res.data.reduce((result, item) => {
// 提取巷道号
const laneNumber = item.lineEdgeLibraryCode.substring(3, 5) + ' 巷道';
// 如果该巷道还没有分组,创建一个空数组
if (!result[laneNumber]) {
result[laneNumber] = [];
}
// 将当前项添加到对应巷道的数组中
result[laneNumber].push(item);
return result;
}, {});
Object.keys(this.areaInfo).forEach((key) => {
const arr = this.areaInfo[key];
let emptyNum = 0;
let insetEmpty = [];
arr.forEach((item, index) => {
if (
!item.empty &&
item.lineEdgeLibraryCode.substring(5, 7) !=
Math.floor(index / 2) + 1 + emptyNum &&
item.lineEdgeLibraryCode[item.lineEdgeLibraryCode.length - 1] ==
'L'
) {
let num =
Number(item.lineEdgeLibraryCode.substring(5, 7)) -
(Math.floor(index / 2) + 1 + emptyNum);
insetEmpty.push({
index,
num,
});
emptyNum += num;
}
});
insetEmpty.forEach((item) => {
const arrEmpty = Array.from({ length: item.num * 2 }, () => ({
empty: true,
}));
arr.splice(item.index, 0, ...arrEmpty);
});
});
}
},
getDataList() {},
// 全部库区右侧分页点击
handleClickRight(tab, event) {
console.log(tab, event);
},
clearLine(val) {
if (val.usableState == 3) {
this.$confirm(
`当前库位为锁定状态,代表该库位有未完成的任务关联,是否确认清空${
'线边库名称为 ' + val.lineEdgeLibraryName + ' '
}的数据项?`,
'锁定库位清空提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
QKLineEdgeLibrary({
...val,
lineEdgeLibraryState: 0,
usableState: 1,
}).then(({ data }) => {
this.$message({
message: data,
type: 'success',
duration: 1500,
onClose: () => {
this.getAreaInfo(this.getAreaInfoInfo.id);
},
});
});
})
.catch(() => {});
} else {
QKLineEdgeLibrary({
...val,
lineEdgeLibraryState: 0,
usableState: 1,
}).then(({ data }) => {
this.$message({
message: data,
type: 'success',
duration: 1500,
onClose: () => {
this.getAreaInfo(this.getAreaInfoInfo.id);
},
});
});
}
},
addLine(val) {
this.addOrEditTitle = '添加货物';
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init();
this.$refs.addOrUpdate.showLine(val);
});
},
// dialog的父组件方法this.$emit("refreshDataList");
successSubmit() {
this.handleCancel();
this.getAreaInfo(this.getAreaInfoInfo.id);
},
clearAll(item) {
if (this.areaInfo[item].length > 0) {
AllQKLineEdgeLibrary({
...this.areaInfo[item][0],
lineEdgeLibraryState: 0,
usableState: 1,
}).then(({ data }) => {
this.$message({
message: data,
type: 'success',
duration: 1500,
onClose: () => {
this.getAreaInfo(this.getAreaInfoInfo.id);
},
});
});
}
},
},
};
</script>
<style lang="scss" scoped>
.overview-container {
max-height: calc(100vh - 120px - 8px);
overflow: scroll;
.overview-container-left {
padding-right: 12px;
}
.overview-container-main {
.allarea-box {
padding: 10px;
.areainfo-box {
border: 1px solid #bbb;
border-radius: 5px;
padding: 10px;
.areainfo-box-header {
font-size: 16px;
font-weight: bold;
white-space: nowrap; /* 禁止换行 */
overflow: hidden; /* 隐藏溢出内容 */
text-overflow: ellipsis; /* 溢出部分显示省略号 */
}
.areainfo-box-line {
width: 100%;
.areainfo-box-line-item {
height: 5px;
display: inline-block;
}
}
.areainfo-box-info {
.areainfo-box-info-item {
text-align: center;
font-size: 12px;
.areainfo-box-info-item-count {
font-weight: bold;
font-size: 14px;
}
}
}
}
}
}
.overview-container-right {
.overview-container-right-alloverview {
.overview-container-right-alloverview-item {
text-align: center;
.overview-container-right-alloverview-item-count {
font-size: 14px;
font-weight: bold;
}
}
}
}
}
</style>
<style lang="scss">
.el-tree-node__content {
height: 40px;
line-height: 40px;
}
.el-tree-node__label {
display: block;
width: calc(100% - 24px);
text-align: center;
white-space: nowrap; /* 禁止换行 */
overflow: hidden; /* 隐藏溢出内容 */
text-overflow: ellipsis; /* 溢出部分显示省略号 */
}
</style>
<style scoped>
.area-body {
margin-top: 10px;
margin-left: 10px;
overflow-x: auto;
display: flex;
}
.potTitle {
width: 190px;
background-color: rgb(169, 235, 249);
border-radius: 3px;
margin-right: 5px;
text-align: center;
color: #000000;
letter-spacing: 1px;
margin-bottom: 10px;
font-size: 16px;
padding: 5px;
}
.potList {
width: 190px;
display: grid;
grid-template-columns: 90px 90px;
gap: 8px;
}
.area-div {
padding: 10px;
background: white;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
border: 4px solid #1a56db;
margin-bottom: 30px;
}
.area-div-empty {
background: white;
width: 90px;
height: 88px;
margin-bottom: 30px;
}
.point {
width: 5px;
height: 5px;
border-radius: 50%;
background-color: #409eff;
float: left;
margin-top: 7px;
margin-right: 5px;
}
.area-icon {
display: flex;
align-items: center;
justify-content: center;
margin: auto;
width: 60px;
height: 60px;
border-radius: 12px;
}
</style>
<style scoped>
.stat-card {
margin-top: 10px;
display: flex;
align-items: center;
padding: 10px;
background: white;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
border-left: 4px solid;
border-color: #1a56db;
margin-bottom: 30px;
}
/* .stat-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
} */
.stat-title {
margin: 0 10px;
color: #0051ff;
font-size: 20px;
}
.stat-icon {
display: flex;
align-items: center;
justify-content: center;
width: 60px;
height: 60px;
border-radius: 12px;
margin-right: 15px;
background: linear-gradient(to right, #1a56db, #0d47a1);
}
.stat-content {
display: flex;
flex-direction: column;
}
.stat-value {
font-size: 28px;
font-weight: 700;
line-height: 1.2;
color: #1a56db;
}
.stat-label {
font-size: 14px;
color: #64748b;
}
</style>

View File

@@ -1,277 +0,0 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
isFold
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 设备 详情 - 编辑 -->
<RecordDrawer
v-if="open"
ref="drawer"
:mode="editMode"
@update-mode="editMode = $event"
:data-id="form.id"
@refreshDataList="getList"
@cancel="cancelEdit"
@destroy="cancelEdit" />
</div>
</template>
<script>
import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import RecordDrawer from './components/RecordDrawer';
import { getRecordPage, getLaneList } from '@/api/areavisual/record';
export default {
name: 'Equipment',
components: {
RecordDrawer,
},
mixins: [basicPageMixin],
data() {
return {
searchBarKeys: ['name', 'code'],
// this.$auth.hasPermi(`base:equipment:update`)
tableBtn: [
{
type: 'detail',
btnName: '详情'
}
].filter((v) => v),
tableProps: [
{
prop: 'recordCode',
label: '出/入库单编号',
fixed: true,
width: 180,
// filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
// showOverflowtooltip: true,
},
{
prop: 'type',
label: '业务类型',
filter: (val) => val === 1 ? '出库' : '入库',
},
{
width: 180,
prop: 'recordTime',
label: '出/入库时间',
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss')
},
{ prop: 'recordArea', label: '出/入库库区' },
{ prop: 'recordLane', label: '出/入库巷道' },
{ prop: 'recordRegion', label: '出/入库库位号' },
{ prop: 'target', label: '搬运对象' },
{ prop: 'productName', label: '产品名称' },
{ prop: 'specification', label: '型号规格' },
{ prop: 'recordMan', label: '出/入库人' },
{ prop: 'remark', label: '备注' }
],
searchBarFormConfig: [
{
type: 'input',
label: '关键字',
placeholder: '请输入出/入库编码、产品名称、规格型号、库位号',
param: 'query',
width: 350
},
{
type: 'select',
label: '业务类型',
selectOptions: [
{
id: '1',
name:'出库'
},
{
id: '2',
name:'入库'
},
],
placeholder: '请选择业务类型',
param: 'type',
},
{
type: 'select',
label: '出/入库巷道',
selectOptions: [],
placeholder: '请选择出/入库巷道',
param: 'recordLane',
},
{
type: 'select',
label: '来源',
selectOptions: [
{
id: '1',
name:'WMS'
},
{
id: '2',
name:'MES'
},
],
placeholder: '请选择来源',
param: 'source',
},
{
type: 'select',
label: '出/入库人',
selectOptions: [],
placeholder: '请选择出/入库人',
param: 'recordMan',
},
{
type: 'datePicker',
label: '出/入库时间',
placeholder: '请选择出/入库时间',
param: 'recordTime',
dateType: 'datetimerange',
rangeSeparator: '至'
},
{
type: 'select',
label: '载具类型',
selectOptions: [
{
id: '1',
name:'AGV'
},
{
id: '2',
name:'人工叉车'
},
],
placeholder: '请选择载具类型',
param: 'vehicleType',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'button',
btnName: '重置',
name: 'reset',
color: 'info',
}
],
editVisible: false,
editMode: 'detail', // 'edit', 'detail'
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNo: 1,
pageSize: 20,
query: '',
type: '',
source: '',
recordLane: '',
recordMan: '',
recordTime: '',
vehicleType: ''
},
form: {}
};
},
created() {
this.getLane()
this.getList();
},
computed: {},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
// 执行查询
getRecordPage(this.queryParams).then((response) => {
console.log(response)
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
async getLane() {
const res = await getLaneList({
pageNo: 1,
pageSize: 100
})
if (res.code === 0 && res.data) {
console.log(res.data)
this.searchBarFormConfig[2].selectOptions = res.data.list.map(item => {
return { id: item.id, name: item.lane }
})
console.log(this.searchBarFormConfig)
}
},
/** 取消按钮 */
cancel() {
this.open = false;
},
// /** 导出按钮操作 */
// handleExport() {
// // 处理查询参数
// let params = { ...this.queryParams };
// params.pageNo = undefined;
// params.pageSize = undefined;
// this.$modal
// .confirm('是否确认导出所有设备数据项?')
// .then(() => {
// this.exportLoading = true;
// return exportEquipmentExcel(params);
// })
// .then((response) => {
// this.$download.excel(response, '设备.xls');
// this.exportLoading = false;
// })
// .catch(() => {});
// },
handleTableBtnClick ({data, type}) {
switch (type) {
case 'detail':
this.viewDetail(data.id)
}
},
// 查看详情
viewDetail(id) {
this.editMode = 'detail';
this.open = true;
this.form.id = id;
this.$nextTick(() => {
this.$refs['drawer'].init();
});
},
},
};
</script>

View File

@@ -1,81 +0,0 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2025-11-28 14:38:31
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="80px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物料编码" prop="materialCode">
<el-input
v-model="dataForm.materialCode"
clearable
placeholder="请输入物料编码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料型号" prop="materialName">
<el-input
v-model="dataForm.materialName"
clearable
placeholder="请输入物料型号" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物料规格" prop="material">
<el-input
v-model="dataForm.material"
clearable
placeholder="请输入物料规格" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
import basicAdd from '@/mixins/basic-add';
import { createProduct, updateProduct,getProduct } from '@/api/ssdl/product&recipe';
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
createURL: createProduct,
updateURL: updateProduct,
infoURL: getProduct,
},
dataForm: {
id: undefined,
material: undefined,
materialName: undefined,
materialCode: undefined,
},
typeArr: [],
dataRule: {
materialCode: [
{ required: true, message: '物料编码不能为空', trigger: 'blur' },
],
materialName: [
{ required: true, message: '物料型号不能为空', trigger: 'blur' },
],
material: [
{ required: true, message: '规格不能为空', trigger: 'blur' },
],
},
};
},
methods: {},
};
</script>

View File

@@ -1,62 +0,0 @@
<!--
* @Author: zwq
* @Date: 2025-10-11 14:41:12
* @LastEditors: zwq
* @LastEditTime: 2026-01-14 14:13:14
* @Description:
-->
<template>
<el-switch
@change="changeStatus"
size="small"
v-model="injectData.regionState"
:active-value="1"
:inactive-value="2"></el-switch>
</template>
<script>
import { updateRegion } from '@/api/areavisual/region';
export default {
props: {
injectData: {
type: Object,
default: () => ({}),
},
},
data() {
return {};
},
created() {},
methods: {
changeStatus(val) {
const pdata = { ...this.injectData, regionState: val };
this.$confirm(
`是否确认修改${'区域 [ ' + this.injectData.regionName + ' ] '}的状态?`,
'更新状态',
{
confirmButtonText: '确认修改',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
updateRegion(pdata).then((res) => {
if (res.code === 0 || res.code === 200) {
this.$modal.msgSuccess('修改成功');
this.$emit('emitData');
} else {
this.$modal.msg(res.msg);
}
});
})
.catch((res) => {
this.$emit('emitData');
this.$message({
type: 'info',
message: '已取消',
});
});
},
},
};
</script>

View File

@@ -1,221 +0,0 @@
<template>
<div class="app-container">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:table-data="tableData"
@emitFun="getDataList">
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
width="50%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '@/mixins/basic-page';
import { parseTime } from '@/filter/code-filter';
import { deleteRegion, getRegionPage } from '@/api/areavisual/region';
import changeStatus from './changeStatus.vue';
const region = [
{
id: '1',
name: 'A区域',
},
{
id: '2',
name: 'B区域',
},
{
id: '3',
name: 'C区域',
},
{
id: '4',
name: 'D区域',
},
{
id: '5',
name: 'E区域',
},
{
id: '6',
name: 'F区域',
},
{
id: '7',
name: 'G区域',
},
{
id: '8',
name: 'H区域',
},
];
const regionType = [
{
id: '1',
name: '拉丝缓存区',
},
{
id: '2',
name: '满盘存储区',
},
{
id: '3',
name: '空盘存储区',
},
{
id: '4',
name: '复绕区',
},
];
const tableProps = [
{
prop: 'regionCode',
label: '区域编码',
},
{
prop: 'regionName',
label: '区域名称',
},
{
prop: 'region',
label: '区域',
filter: (val) => {
return region.find((i) => i.id == val)
? region.find((i) => i.id == val).name
: '-';
},
},
{
prop: 'regionType',
label: '区域类型',
filter: (val) => {
return regionType.find((i) => i.id == val)
? regionType.find((i) => i.id == val).name
: '-';
},
},
{
prop: 'rowNum',
label: '行数',
width:90,
},
{
prop: 'columnNum',
label: '列数',
width:90,
},
{
prop: 'regionState',
label: '区域状态',
width:90,
subcomponent: changeStatus,
},
{
prop: 'createTime',
label: '创建时间',
filter: parseTime,
width: 150,
},
];
export default {
mixins: [basicPage],
data() {
return {
urlOptions: {
getDataListURL: getRegionPage,
deleteURL: deleteRegion,
},
tableProps,
tableData: [],
formConfig: [
{
type: 'input',
label: '名称',
placeholder: '名称',
param: 'name',
},
{
type: 'input',
label: '编码',
placeholder: '编码',
param: 'code',
},
{
type: 'select',
label: '区域',
selectOptions: region,
placeholder: '请选择区域',
param: 'region',
},
{
type: 'button',
btnName: '搜索',
name: 'search',
color: 'primary',
},
],
};
},
components: {
AddOrUpdate,
},
created() {},
methods: {
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 20;
this.listQuery.regionName = val.name;
this.listQuery.regionCode = val.code;
this.listQuery.region = val.region;
this.getDataList();
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.listQuery = {
pageSize: 20,
pageNo: 1,
total: 1,
};
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.addOrUpdateHandle();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
},
};
</script>

View File

@@ -0,0 +1,100 @@
<!--
filename: index.vue
author: liubin
date: 2023-10-11 09:32:04
description: 设备看板
-->
<template>
<div ref="dataBoard" class="data-board">
<el-button type="text" @click="goback" class="go-back--btn">返回</el-button>
</div>
</template>
<script>
export default {
name: 'DataBoard',
components: {},
props: {},
data() {
return {
appMain: null, // dom
parentStyle: {
margin: '8px 14px 0px 16px',
minHeight: 'calc(100vh - 120px - 8px)',
}, // object
mainFooter: null, // dom
};
},
// mounted() {
// this.$nextTick(() => {
// this.modify();
// });
// },
// activated() {
// this.modify();
// },
// deactivated() {
// this.recover();
// },
// beforeDestroy() {
// this.recover();
// },
methods: {
// modify() {
// // 在这个页面临时修改下父类的margin结束时需还原
// this.appMain = document.querySelector('.app-main');
// // this.appMain.style.minHeight = 'calc(100vh - 90px)';
// this.appMain.style.margin = 0;
// // 在这个页面临时删除 main-footer 元素,结束时需还原
// // this.mainFooter = document.querySelector('.main-footer').cloneNode(true);
// // document.querySelector('.main-footer').remove();
// this.$refs.dataBoard.classList.add('data-board');
// },
// recover() {
// this.$refs.dataBoard.classList.remove('data-board');
// this.$nextTick(() => {
// this.appMain.style.margin = this.parentStyle.margin;
// // this.appMain.style.minHeight = this.parentStyle.minHeight;
// // this.appMain.insertAdjacentElement('afterend', this.mainFooter);
// });
// },
goback() {
this.$router.go(-1);
}
},
};
</script>
<style scoped lang="scss">
.data-board {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url('../../../assets/images/DataBoard.png') 100% 100% / contain
no-repeat;
}
.go-back--btn {
position: fixed;
top: 28px;
left: 24px;
color: #fff;
font-size: 18px;
letter-spacing: 6px;
&:hover {
text-decoration: underline;
}
&::after {
content: "\2BAA";
position: absolute;
top: 6px;
right: -26px;
font-size: 24px;
}
}
</style>

View File

@@ -0,0 +1,214 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="设备id" prop="equipmentId">
<el-input v-model="queryParams.equipmentId" placeholder="请输入设备id" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 操作工具栏 -->
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['base:equipment-attr:create']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
v-hasPermi="['base:equipment-attr:export']">导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- 列表 -->
<el-table v-loading="loading" :data="list">
<el-table-column label="ID" align="center" prop="id" />
<el-table-column label="设备id" align="center" prop="equipmentId" />
<el-table-column label="属性名称" align="center" prop="name" />
<el-table-column label="属性值" align="center" prop="value" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-hasPermi="['base:equipment-attr:update']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['base:equipment-attr:delete']">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@pagination="getList"/>
<!-- 对话框(添加 / 修改) -->
<el-dialog :title="title" :visible.sync="open" width="500px" v-dialogDrag append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="设备id" prop="equipmentId">
<el-input v-model="form.equipmentId" placeholder="请输入设备id" />
</el-form-item>
<el-form-item label="属性名称" prop="name">
<el-input v-model="form.name" placeholder="请输入属性名称" />
</el-form-item>
<el-form-item label="属性值" prop="value">
<el-input v-model="form.value" placeholder="请输入属性值" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { createEquipmentAttr, updateEquipmentAttr, deleteEquipmentAttr, getEquipmentAttr, getEquipmentAttrPage, exportEquipmentAttrExcel } from "@/api/base/equipmentAttr";
export default {
name: "EquipmentAttr",
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 导出遮罩层
exportLoading: false,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 设备属性列表
list: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNo: 1,
pageSize: 10,
equipmentId: null,
},
// 表单参数
form: {},
// 表单校验
rules: {
equipmentId: [{ required: true, message: "设备id不能为空", trigger: "blur" }],
}
};
},
created() {
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
// 执行查询
getEquipmentAttrPage(this.queryParams).then(response => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
equipmentId: undefined,
name: undefined,
value: undefined,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加设备属性";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
getEquipmentAttr(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改设备属性";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (!valid) {
return;
}
// 修改的提交
if (this.form.id != null) {
updateEquipmentAttr(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
return;
}
// 添加的提交
createEquipmentAttr(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal.confirm('是否确认删除设备属性编号为"' + id + '"的数据项?').then(function() {
return deleteEquipmentAttr(id);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
// 处理查询参数
let params = {...this.queryParams};
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal.confirm('是否确认导出所有设备属性数据项?').then(() => {
this.exportLoading = true;
return exportEquipmentAttrExcel(params);
}).then(response => {
this.$download.excel(response, '设备属性.xls');
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@@ -0,0 +1,482 @@
<!--
filename: EquipmentDrawer.vue
author: liubin
date: 2023-08-22 14:38:56
description:
-->
<template>
<el-drawer
:visible="visible"
:show-close="false"
:wrapper-closable="false"
class="drawer"
custom-class="mes-drawer"
size="60%"
@closed="$emit('destroy')">
<SmallTitle slot="title">
{{
mode.includes('detail')
? '详情'
: mode.includes('edit')
? '编辑'
: '新增'
}}
</SmallTitle>
<div class="drawer-body flex">
<div class="drawer-body__content">
<section v-for="(section, index) in sections" :key="section.key">
<SmallTitle v-if="index != 0">{{ section.name }}</SmallTitle>
<div class="form-part" v-if="section.key == 'base'">
<el-skeleton v-if="!showForm" animated />
<BaseInfoForm
key="drawer-dialog-form"
v-if="showForm"
ref="form"
:disabled="true"
:dataForm="form"
:rows="formRows" />
</div>
<div v-if="section.key == 'attrs'" style="margin-top: 12px">
<base-table
v-loading="attrListLoading"
:table-props="section.props"
:page="attrQuery?.params.pageNo || 1"
:limit="attrQuery?.params.pageSize || 10"
:table-data="list"
:add-button-show="mode.includes('detail') ? null : '添加属性'"
@emitButtonClick="handleAddAttr"
@emitFun="handleEmitFun">
<method-btn
v-if="section.tableBtn"
slot="handleBtn"
label="操作"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="attrQuery.params.pageNo"
:limit.sync="attrQuery.params.pageSize"
@pagination="getAttrList" />
</div>
</section>
</div>
<div class="drawer-body__footer">
<el-button style="" @click="handleCancel">取消</el-button>
<el-button v-if="mode == 'detail'" type="primary" @click="toggleEdit">
编辑
</el-button>
<el-button v-else type="primary" @click="handleCancel">确定</el-button>
<!-- sections的第二项必须是 属性列表 -->
<!-- <el-button
v-if="sections[1].allowAdd"
type="primary"
@click="handleAddAttr">
添加属性
</el-button> -->
</div>
</div>
<!-- 属性对话框 -->
<base-dialog
v-if="sections[1].allowAdd"
:dialogTitle="attrTitle"
:dialogVisible="attrFormVisible"
width="45%"
:append-to-body="true"
custom-class="baseDialog"
@close="closeAttrForm"
@cancel="closeAttrForm"
@confirm="submitAttrForm">
<DialogForm
v-if="attrFormVisible"
ref="attrForm"
:disabled="mode.includes('detail')"
v-model="attrForm"
:rows="attrRows" />
</base-dialog>
</el-drawer>
</template>
<script>
import BaseInfoForm from '@/components/DialogForm';
import DialogForm from './dialogForm';
const SmallTitle = {
name: 'SmallTitle',
props: ['size'],
data() {
return {};
},
methods: {},
render: function (h) {
return h(
'span',
{
class: 'small-title',
style: {
fontSize: '18px',
lineHeight:
this.size == 'lg' ? '24px' : this.size == 'sm' ? '18px' : '20px',
fontWeight: 500,
fontFamily: '微软雅黑, Microsoft YaHei, Arial, Helvetica, sans-serif',
},
},
this.$slots.default
);
},
};
export default {
components: { SmallTitle, DialogForm, BaseInfoForm },
props: ['sections', 'defaultMode', 'dataId'], // dataId 作为一个通用的存放id的字段
data() {
return {
mode: '',
visible: false,
showForm: false,
total: 0,
form: {},
list: [],
attrTitle: '',
attrForm: {
id: null,
equipmentGroupId: '',
code: '',
type: '',
grade: '',
alarmCode: '',
alarmContent: '',
plcParamName: '',
},
attrFormVisible: false,
attrRows: [
[
{
input: true,
label: '报警编码', // 自动生成
prop: 'code',
url: '/base/equipment-group-alarm/getCode',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
{
select: true,
label: '报警类型', // 固定选项
prop: 'type',
options: [
{ label: '布尔型', value: 2 },
{ label: '字符型', value: 1 },
],
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
[
{
select: true,
label: '报警级别', // 字典
prop: 'grade',
options: this.getDictDatas(this.DICT_TYPE.EQU_ALARM_LEVEL),
},
{
input: true,
label: '设备报警编码', // 对应到设备实际的报警编码
prop: 'alarmCode',
},
],
[
{
input: true,
label: '参数列名', // 在实时数据库的列名
prop: 'plcParamName',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
{
input: true,
label: '报警内容',
prop: 'alarmContent',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
],
attrQuery: {
params: {
pageNo: 1,
pageSize: 10,
},
}, // 属性列表的请求
infoQuery: null, // 基本信息的请求
attrFormSubmitting: false,
attrListLoading: false,
};
},
computed: {
formRows() {
return this.sections[0].rows.map((row) => {
return row.map((col) => {
return {
...col,
bind: {
// 详情 模式下,禁用各种输入
// disabled: this.mode == 'detail',
disabled: true,
},
};
});
});
},
tableBtn() {
return this.mode == 'detail' ? [] : this.sections[1].tableBtn;
},
},
mounted() {
this.mode = this.defaultMode || 'detail';
for (const section of this.sections) {
// 请求具体信息
if ('url' in section) {
const query = {
url: section.url,
method: section.method || 'get',
params: section.queryParams || null,
data: section.data || null,
};
// debugger;
this.$axios(query).then(({ data }) => {
if (section.key == 'base') {
this.form = data;
this.showForm = true;
this.infoQuery = query;
} else if (section.key == 'attrs') {
this.attrQuery = query;
this.list = data.list;
this.total = data.total;
}
});
}
}
},
methods: {
handleTableBtnClick({ type, data }) {
switch (type) {
case 'edit':
this.handleEditAttr(data.id);
break;
case 'delete':
this.handleDeleteAttr(data.id);
break;
}
},
handleEmitFun(val) {
console.log('handleEmitFun', val);
},
init() {
this.visible = true;
},
async getAttrList() {
this.attrListLoading = true;
const res = await this.$axios(this.attrQuery);
if (res.code == 0) {
this.list = res.data.list;
this.total = res.data.total;
}
this.attrListLoading = false;
},
// 保存表单
handleSave() {
this.$refs['form'][0].validate(async (valid) => {
if (valid) {
const isEdit = this.mode == 'edit';
await this.$axios({
url: this.sections[0][isEdit ? 'urlUpdate' : 'urlCreate'],
method: isEdit ? 'put' : 'post',
data: this.form,
});
this.$modal.msgSuccess(`${isEdit ? '更新' : '创建'}成功`);
this.visible = false;
this.$emit('refreshDataList');
}
});
},
handleCancel() {
this.visible = false;
},
// 开启编辑
toggleEdit() {
this.mode = 'edit';
},
// 新增属性
handleAddAttr() {
if (!this.dataId) return this.$message.warning('请先创建设备分组信息');
this.attrForm = {
id: null,
equipmentGroupId: this.dataId,
code: '',
type: '',
grade: '',
alarmCode: '',
alarmContent: '',
plcParamName: '',
};
this.attrTitle = '添加设备分组报警';
this.attrFormVisible = true;
},
// 编辑属性
async handleEditAttr(attrId) {
const res = await this.$axios({
url: this.sections[1].urlDetail,
method: 'get',
params: { id: attrId },
});
if (res.code == 0) {
this.attrForm = res.data;
this.attrTitle = '编辑设备分组报警';
this.attrFormVisible = true;
}
},
// 删除属性
handleDeleteAttr(attrId) {
this.$confirm('确定删除该分组报警?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(async () => {
const res = await this.$axios({
url: this.sections[1].urlDelete,
method: 'delete',
params: { id: attrId },
});
if (res.code == 0) {
this.$message({
message: '删除成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getAttrList();
},
});
}
})
.catch(() => {});
},
// 提交属性表
async submitAttrForm() {
this.$refs['attrForm'].validate((valid) => {
if (!valid) {
return;
}
});
console.log('this.attrform', this.attrForm);
const isEdit = this.attrForm.id != null;
this.attrFormSubmitting = true;
const res = await this.$axios({
url: isEdit ? this.sections[1].urlUpdate : this.sections[1].urlCreate,
method: isEdit ? 'put' : 'post',
data: this.attrForm,
});
if (res.code == 0) {
this.closeAttrForm();
this.$message({
message: `${isEdit ? '更新' : '创建'}成功`,
type: 'success',
duration: 1500,
onClose: () => {
this.getAttrList();
},
});
}
this.attrFormSubmitting = false;
},
closeAttrForm() {
this.attrFormVisible = false;
},
handleClick(raw) {
if (raw.type === 'delete') {
this.$confirm(`确定删除该报警?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
deleteProductAttr(raw.data.id).then(({ data }) => {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getList();
},
});
});
})
.catch(() => {});
} else {
this.addNew(raw.data.id);
}
},
},
};
</script>
<style scoped>
.drawer >>> .el-drawer {
border-radius: 8px 0 0 8px;
}
.drawer >>> .el-drawer__header {
margin: 0;
padding: 32px 32px 24px;
border-bottom: 1px solid #dcdfe6;
margin-bottom: 0px;
}
.small-title::before {
content: '';
display: inline-block;
vertical-align: top;
width: 4px;
height: 22px;
border-radius: 1px;
margin-right: 8px;
background-color: #0b58ff;
}
.drawer-body {
display: flex;
flex-direction: column;
height: 100%;
}
.drawer-body__content {
flex: 1;
/* background: #eee; */
padding: 20px 30px;
overflow-y: auto;
}
.drawer-body__footer {
display: flex;
justify-content: flex-end;
padding: 18px;
}
</style>

View File

@@ -0,0 +1,186 @@
<!--
filename: dialogForm.vue
author: liubin
date: 2023-09-11 15:55:13
description: DialogForm for equipmentBindSection only
-->
<template>
<el-form
ref="form"
:model="dataForm"
label-width="100px"
v-loading="formLoading">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="报警编码"
prop="code"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-input
:disabled="disabled"
v-model="dataForm.code"
@change="$emit('update', dataForm)"
placeholder="请输入工段排序" />
</el-form-item>
<!--
<el-form-item
label="报警编码"
prop="code"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-select
v-model="dataForm.code"
placeholder="请选择产线"
@change="handleProductlineChange">
<el-option
v-for="opt in productionLineList"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item> -->
</el-col>
<el-col :span="12">
<el-form-item
label="报警类型"
prop="type"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-select
:disabled="disabled"
v-model="dataForm.type"
placeholder="请选择报警类型"
@change="handleTypeChange">
<el-option
v-for="opt in [
{ label: '布尔型', value: 2 },
{ label: '字符型', value: 1 },
]"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="报警级别"
prop="grade"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-select
:disabled="disabled"
v-model="dataForm.grade"
placeholder="请选择报警级别"
@change="$emit('update', dataForm)">
<el-option
v-for="opt in getDictDatas(DICT_TYPE.EQU_ALARM_LEVEL)"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
v-if="+dataForm.type == 1"
label="设备报警编码"
prop="alarmCode">
<el-input
:disabled="disabled"
v-model="dataForm.alarmCode"
@change="$emit('update', dataForm)"
placeholder="请输入设备报警编码" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="参数列名"
prop="plcParamName"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-input
:disabled="disabled"
v-model="dataForm.plcParamName"
placeholder="请输入参数列名"
@change="$emit('update', dataForm)"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="报警内容"
prop="alarmContent"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-input
:disabled="disabled"
v-model="dataForm.alarmContent"
placeholder="请输入报警内容"
@change="$emit('update', dataForm)"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
export default {
name: 'DialogForm',
model: {
prop: 'dataForm',
event: 'update',
},
emits: ['update'],
components: {},
props: {
dataForm: {
type: Object,
default: () => ({}),
},
disabled: {
type: Boolean,
default: false,
},
},
data() {
return {
formLoading: true,
};
},
mounted() {
this.getCode('/base/equipment-group-alarm/getCode').then((code) => {
this.formLoading = false;
this.$emit('update', {
...this.dataForm,
code,
});
});
},
methods: {
/** 模拟透传 ref */
validate(cb) {
return this.$refs.form.validate(cb);
},
resetFields(args) {
return this.$refs.form.resetFields(args);
},
async handleTypeChange(id) {
this.dataForm.alarmCode = '';
this.$emit('update', this.dataForm);
},
async getCode(url) {
const response = await this.$axios(url);
return response.data;
},
},
};
</script>
<style scoped lang="scss">
.el-date-editor,
.el-select {
width: 100%;
}
</style>

View File

@@ -0,0 +1,461 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
:width="120"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
width="700px"
@close="cancel"
@cancel="cancel"
@confirm="submitForm">
<DialogForm v-if="open" ref="form" v-model="form" :rows="rows" />
</base-dialog>
<!-- 抽屉 详情 -->
<BasicDrawer
v-if="editVisible"
ref="drawer"
:default-mode="editMode"
:data-id="alarmForm.id"
:sections="[
{
name: '基本信息',
key: 'base',
rows: drawerBaseInfoRows,
url: '/base/equipment-group/get',
urlUpdate: '/base/equipment-group/update',
urlCreate: '/base/equipment-group/create',
queryParams: { id: alarmForm.id },
},
{
name: '属性列表',
key: 'attrs',
props: drawerListProps,
url: '/base/equipment-group-alarm/page',
urlCreate: '/base/equipment-group-alarm/create',
urlUpdate: '/base/equipment-group-alarm/update',
urlDelete: '/base/equipment-group-alarm/delete',
urlDetail: '/base/equipment-group-alarm/get',
queryParams: {
equipmentGroupId: alarmForm.id,
pageNo: 1,
pageSize: 10,
},
tableBtn: [
this.$auth.hasPermi('base:equipment-group:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:equipment-group:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
allowAdd: true,
},
]"
@refreshDataList="getList"
@cancel="editVisible = false"
@destroy="editVisible = false" />
</div>
</template>
<script>
import {
createEquipmentBindGroup,
updateEquipmentBindGroup,
deleteEquipmentBindGroup,
getEquipmentBindGroup,
getEquipmentBindGroupPage,
exportEquipmentBindGroupExcel,
} from '@/api/base/equipmentBindGroup';
import { getEquipmentGroupPage } from '@/api/base/equipmentGroup';
import moment from 'moment';
import { publicFormatter } from '@/utils/dict';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import BasicDrawer from './components/BasicDrawer.vue';
export default {
name: 'EquipmentBindGroup',
components: { BasicDrawer },
mixins: [basicPageMixin],
data() {
return {
searchBarKeys: ['groupId', 'equipmentName'],
tableBtn: [
this.$auth.hasPermi('base:equipment-bind-group:update')
? {
type: 'detail',
btnName: '查看报警',
}
: undefined,
this.$auth.hasPermi('base:equipment-bind-group:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:equipment-bind-group:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
{
prop: 'createTime',
label: '添加时间',
fixed: true,
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ prop: 'equipmentName', label: '设备' },
{ prop: 'groupName', label: '分组' },
// {
// _action: 'equipment-bind-group-show-alert',
// label: '分组报警',
// subcomponent: {
// props: ['injectData'],
// render: function (h) {
// const _this = this;
// return h(
// 'el-button',
// {
// props: { type: 'text' },
// on: {
// click: function () {
// console.log('inejctdata', _this.injectData);
// _this.$emit('emitData', {
// action: _this.injectData._action,
// value: _this.injectData,
// });
// },
// },
// },
// '查看报警'
// );
// },
// },
// },
],
searchBarFormConfig: [
{
type: 'select',
label: '分组',
placeholder: '请选择分组',
param: 'groupId',
filterable: true,
selectOptions: [],
},
{
type: 'input',
label: '设备',
placeholder: '请输入设备',
param: 'equipmentName',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:equipment-bind-group:create')
? 'button'
: '',
btnName: '新增',
name: 'add',
plain: true,
color: 'success',
},
// {
// type: this.$auth.hasPermi('base:equipment-group:export') ? 'button' : '',
// btnName: '导出',
// name: 'export',
// color: 'warning',
// },
],
rows: [
[
{
select: true,
label: '设备',
url: '/base/equipment/page?pageNo=1&pageSize=100',
prop: 'equipmentId',
bind: {
filterable: true,
},
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
[
{
select: true,
label: '报警分组',
url: '/base/equipment-group/listAll', // 根据产线获取
// depends: '__product_line', // 依赖产线获取数据
// depends: 'productionLineId',
prop: 'groupId',
bind: {
filterable: true,
},
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
],
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNo: 1,
pageSize: 10,
equipmentName: null,
groupId: null,
},
// 表单参数
form: {},
// 表单校验
rules: {},
//
alarmForm: {
id: undefined,
equipmentGroupCode: undefined,
equipmentGroupName: undefined,
},
editVisible: false,
editMode: '',
drawerBaseInfoRows: [
[
{
input: true,
label: '设备分组名称',
prop: 'name',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
// bind: {
// disabled: this.editMode == 'detail', // some condition, like detail mode...
// }
},
{
input: true,
label: '设备分组编码',
prop: 'code',
// url: '/base/equipment/getCode',
},
],
],
drawerListProps: [
{
prop: 'createTime',
label: '添加时间',
fixed: true,
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ width: 240, prop: 'code', label: '报警编码' },
{
width: 100,
prop: 'type',
label: '报警类型',
filter: (val) =>
val != null ? ['-', '字符型', '布尔型', '-'][val] : '-',
},
{
width: 90,
prop: 'grade',
label: '报警级别',
filter: publicFormatter(this.DICT_TYPE.EQU_ALARM_LEVEL),
},
{ width: 180, prop: 'alarmCode', label: '设备报警编码' },
{ width: 128, prop: 'plcParamName', label: '参数列名' },
{ width: 128, prop: 'alarmContent', label: '报警内容' },
],
};
},
created() {
this.getList();
getEquipmentGroupPage({ pageNo: 1, pageSize: 100 }).then((res) => {
this.searchBarFormConfig[0].selectOptions = res.data.list;
});
},
methods: {
/** 覆盖 handleEmitFun 的默认实现 */
handleEmitFun({ action, value }) {
const {
groupId: equipmentGroupId,
groupName: equipmentGroupName,
groupCode: equipmentGroupCode,
} = value;
switch (action) {
case 'equipment-bind-group-show-alert':
// this.$router.push({ path: '/equipment/base/equipment-group-alarm' });
this.$router.push({
name: 'EquipmentGroupAlarm',
params: {
equipmentGroupId,
equipmentGroupCode,
equipmentGroupName,
},
});
break;
}
},
/** 查询列表 */
getList() {
this.loading = true;
getEquipmentBindGroupPage(this.queryParams).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
equipmentId: undefined,
groupId: undefined,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = '添加设备与分组绑定';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
getEquipmentBindGroup(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改设备与分组绑定';
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
// 修改的提交
if (this.form.id != null) {
updateEquipmentBindGroup(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
// 添加的提交
createEquipmentBindGroup(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
// 查看报警
handleDetail(row) {
const { equipmentId, equipmentName, groupCode, groupId, groupName, id } =
row;
// 打开抽屉
this.editMode = 'detail';
this.alarmForm.id = groupId;
this.alarmForm.equipmentGroupCode = groupCode;
this.alarmForm.equipmentGroupName = groupName;
this.editVisible = true;
this.$nextTick(() => {
this.$refs['drawer'].init();
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm('是否确认删除该分组绑定?')
.then(function () {
return deleteEquipmentBindGroup(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
// 处理查询参数
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有设备与分组绑定数据项?')
.then(() => {
this.exportLoading = true;
return exportEquipmentBindGroupExcel(params);
})
.then((response) => {
this.$download.excel(response, '设备与分组绑定.xls');
this.exportLoading = false;
})
.catch(() => {});
},
},
};
</script>

View File

@@ -0,0 +1,226 @@
<!--
filename: dialogForm.vue
author: liubin
date: 2023-09-11 15:55:13
description: DialogForm for equipmentBindSection only
-->
<template>
<el-form
ref="form"
:model="dataForm"
label-width="100px"
v-loading="formLoading">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="产线"
prop="productionLineId"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-select
v-model="dataForm.productionLineId"
placeholder="请选择产线"
filterable
@change="handleProductlineChange">
<el-option
v-for="opt in productionLineList"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="工段"
prop="workshopSectionId"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-select
v-model="dataForm.workshopSectionId"
filterable
placeholder="请选择工段"
@change="$emit('update', dataForm)">
<el-option
v-for="opt in worksectionList"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="设备"
prop="equipmentId"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-select
v-model="dataForm.equipmentId"
filterable
placeholder="请选择设备"
@change="$emit('update', dataForm)">
<el-option
v-for="opt in equipmentList"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工段设备排序" prop="sort">
<el-input-number
v-model="dataForm.sort"
filterable
min="0"
max="100"
@change="$emit('update', dataForm)"
placeholder="请输入工段设备排序" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="产线数据类型" prop="lineDataType">
<el-select
v-model="dataForm.lineDataType"
placeholder="请选择产线数据类型"
@change="$emit('update', dataForm)">
<el-option
v-for="opt in [
{ label: '无类型', value: 0 },
{ label: '进口统计', value: 1 },
{ label: '出口统计', value: 2 },
]"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工段数据类型" prop="sectionDataType">
<el-select
v-model="dataForm.sectionDataType"
placeholder="请选择工段数据类型"
@change="$emit('update', dataForm)">
<el-option
v-for="opt in [
{ label: '无类型', value: 0 },
{ label: '进口统计', value: 1 },
{ label: '出口统计', value: 2 },
{ label: '进出口计数', value: 3 },
]"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
export default {
name: 'DialogForm',
model: {
prop: 'dataForm',
event: 'update',
},
emits: ['update'],
components: {},
props: {
dataForm: {
type: Object,
default: () => ({}),
},
},
data() {
return {
formLoading: true,
productionLineList: [],
equipmentList: [],
worksectionList: [],
dataFormCache: null,
};
},
mounted() {
Promise.all([this.getProductLineList(), this.getEquipmentList()]).then(
() => {
this.formLoading = false;
}
);
},
watch: {
'dataForm.productionLineId': {
handler: async function (plId) {
if (plId) await this.getWorksectionList(plId);
},
immediate: true,
},
},
methods: {
/** 模拟透传 ref */
validate(cb) {
return this.$refs.form.validate(cb);
},
resetFields(args) {
return this.$refs.form.resetFields(args);
},
async handleProductlineChange(id) {
await this.getWorksectionList(id);
this.dataForm.workshopSectionId = null;
this.$emit('update', this.dataForm);
},
// getCode
async getCode(url) {
const response = await this.$axios(url);
return response.data;
},
// 获取产线列表
async getProductLineList() {
const response = await this.$axios('/base/production-line/listAll');
this.productionLineList = response.data.map((item) => ({
label: item.name,
value: item.id,
}));
},
// 获取设备列表
async getEquipmentList() {
const response = await this.$axios(
'/base/equipment/page?pageNo=1&pageSize=100'
);
this.equipmentList = response.data.list.map((item) => ({
label: item.name,
value: item.id,
}));
},
// 获取工段列表
async getWorksectionList(plId) {
const response = await this.$axios(
'/base/workshop-section/listByParentId',
{
params: {
id: plId,
},
}
);
this.worksectionList = response.data.map((item) => ({
label: item.name,
value: item.id,
}));
},
},
};
</script>
<style scoped lang="scss">
.el-date-editor,
.el-select {
width: 100%;
}
</style>

View File

@@ -0,0 +1,442 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@select-changed="handleSearchBarChanged"
@headBtnClick="buttonClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
:width="120"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
width="700px"
@close="cancel"
@cancel="cancel"
@confirm="submitForm">
<DialogForm v-if="open" ref="form" v-model="form" :rows="rows" />
</base-dialog>
</div>
</template>
<script>
import {
createEquipmentBindSection,
updateEquipmentBindSection,
deleteEquipmentBindSection,
getEquipmentBindSection,
getEquipmentBindSectionPage,
exportEquipmentBindSectionExcel,
} from '@/api/base/equipmentBindSection';
import { getPdList } from '@/api/core/monitoring/auto';
import { getFactoryPage } from '@/api/core/base/factory';
import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import DialogForm from './dialogForm.vue';
export default {
name: 'EquipmentBindSection',
components: { DialogForm },
mixins: [basicPageMixin],
data() {
return {
searchBarKeys: ['factoryId','productionLineId','workshopSectionId', 'equipmentName'],
tableBtn: [
this.$auth.hasPermi('base:equipment-bind-section:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:equipment-bind-section:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
{
prop: 'createTime',
label: '添加时间',
fixed: true,
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ prop: 'factoryName', label: '工厂' },
{ prop: 'productionLine', label: '产线' },
{ prop: 'workshopSection', label: '工段' },
{ prop: 'equipment', label: '设备名称' },
{ prop: 'sort', label: '工段中排序' },
{
prop: 'lineDataType',
label: '产线数据类型',
filter: (val) =>
val != null ? ['无类型', '进口计数', '出口计数'][val] : '-',
},
{
prop: 'sectionDataType',
label: '工段数据类型',
filter: (val) =>
val != null ? ['无类型', '进口计数', '出口计数', '进出口计数'][val] : '-',
},
// {
// action: 'show-alert',
// label: '报警',
// ,
// subcomponent: {
// props: ['injectData'],
// render: function (h) {
// const _this = this;
// return h(
// 'el-button',
// {
// props: { type: 'text', size: 'mini' },
// on: {
// click: function () {
// console.log('inejctdata', _this.injectData);
// _this.$emit('emitData', {
// action: _this.injectData.action,
// value: _this.injectData.id,
// });
// },
// },
// },
// '查看报警'
// );
// },
// },
// },
],
searchBarFormConfig: [
{
type: 'select',
label: '工厂',
selectOptions: [],
param: 'factoryId',
onchange: true,
},
{
type: 'select',
label: '产线',
selectOptions: [],
param: 'productionLineId',
multiple: true,
},
{
type: 'select',
label: '工段',
placeholder: '请选择工段',
param: 'workshopSectionId',
selectOptions: [],
filterable: true
},
{
type: 'input',
label: '设备',
placeholder: '请输入设备',
param: 'equipmentName',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:equipment-bind-section:create')
? 'button'
: '',
btnName: '新增',
name: 'add',
plain: true,
color: 'success',
},
// {
// type: this.$auth.hasPermi('base:equipment-group:export') ? 'button' : '',
// btnName: '导出',
// name: 'export',
// color: 'warning',
// },
],
rows: [
[
{
select: true,
label: '产线',
url: '/base/production-line/listAll',
// prop: '__product_line', // __开头代表不传递给服务器
prop: 'productionLineId', // 编辑接口返回的产线id所以不能使用上面那种形式
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
{
select: true,
label: '工段',
url: '/base/workshop-section/listByParentId', // 根据产线获取
// depends: '__product_line', // 依赖产线获取数据
depends: 'productionLineId',
prop: 'workshopSectionId',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
[
{
select: true,
label: '设备',
url: '/base/equipment/page?pageNo=1&pageSize=100',
prop: 'equipmentId',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
{
input: true,
label: '工段排序',
prop: 'sort',
// url: '/base/equipment-group/getCode',
},
],
[
{
select: true,
label: '产线数据类型',
options: [
{ label: '无类型', value: 0 },
{ label: '进口计数', value: 1 },
{ label: '出口计数', value: 2 },
],
prop: 'lineDataType',
},
{
select: true,
label: '工段数据类型',
options: [
{ label: '无类型', value: 0 },
{ label: '进口计数', value: 1 },
{ label: '出口计数', value: 2 },
{ label: '进出口计数', value: 3 },
],
prop: 'sectionDataType',
},
],
],
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNo: 1,
pageSize: 10,
workshopSectionId: null,
equipmentId: null,
equipmentName: null,
factoryId: null,
productionLineId: [],
},
// 表单参数
form: {},
};
},
created() {
this.getList();
this.initWorksection();
this.getPdLineList();
},
methods: {
/** 准备工段数据 */
async initWorksection() {
const { code, data } = await this.$axios({
url: '/base/workshop-section/listAll',
method: 'get',
});
if (code == 0) {
this.searchBarFormConfig[2].selectOptions = data.map((item) => {
return {
name: item.name,
id: item.id,
};
});
}
},
getPdLineList() {
getPdList().then((res) => {
this.searchBarFormConfig[1].selectOptions = res.data || [];
});
const params = {
pageSize: 100,
pageNo: 1,
};
getFactoryPage(params).then((res) => {
this.searchBarFormConfig[0].selectOptions = res.data.list || [];
});
},
handleSearchBarChanged({ param, value }) {
this.queryParams.productionLineId = [];
this.$refs['search-bar'].formInline.productionLineId = undefined;
getPdList(value).then((res) => {
this.searchBarFormConfig[1].selectOptions = res.data || [];
});
},
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.queryParams.pageNo = 1;
this.queryParams.pageSize = 10;
this.queryParams.name = val.name;
this.queryParams.workshopSectionId = val.workshopSectionId || undefined;
this.queryParams.equipmentName = val.equipmentName || undefined;
this.queryParams.factoryId = val.factoryId || undefined;
this.queryParams.productionLineId = val.productionLineId || [];
this.handleQuery();
break;
case 'add':
this.handleAdd();
break;
case 'export':
this.handleExport();
break;
case 'reset':
this.$refs['search-bar'].resetForm();
this.resetQuery();
break;
default:
console.log(val);
}
},
/** 查询列表 */
getList() {
this.loading = true;
// 执行查询
getEquipmentBindSectionPage(this.queryParams).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
workshopSectionId: undefined,
equipmentId: undefined,
sort: undefined,
lineDataType: undefined,
sectionDataType: undefined,
remark: undefined,
version: undefined,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = '添加工段设备绑定';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
getEquipmentBindSection(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改工段设备绑定';
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
// 修改的提交
if (this.form.id != null) {
updateEquipmentBindSection(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
// 添加的提交
createEquipmentBindSection(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm('是否确认删除工段设备绑定设备名称为"' + row.equipment + '"的数据项?')
.then(function () {
return deleteEquipmentBindSection(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
// 处理查询参数
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有工段设备绑定数据项?')
.then(() => {
this.exportLoading = true;
return exportEquipmentBindSectionExcel(params);
})
.then((response) => {
this.$download.excel(response, '工段设备绑定.xls');
this.exportLoading = false;
})
.catch(() => {});
},
},
};
</script>

View File

@@ -0,0 +1,225 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="设备ID" prop="equipmentId">
<el-input v-model="queryParams.equipmentId" placeholder="请输入设备ID" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 操作工具栏 -->
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['base:equipment-file:create']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
v-hasPermi="['base:equipment-file:export']">导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- 列表 -->
<el-table v-loading="loading" :data="list">
<el-table-column label="id" align="center" prop="id" />
<el-table-column label="设备ID" align="center" prop="equipmentId" />
<el-table-column label="文件类型 1.图片 2.设备资料" align="center" prop="fileType">
<template v-slot="scope">
<dict-tag :type="DICT_TYPE.EQU_FILE_TYPE" :value="scope.row.fileType" />
</template>
</el-table-column>
<el-table-column label="原始文件名" align="center" prop="fileName" />
<el-table-column label="文件url" align="center" prop="fileUrl" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template v-slot="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-hasPermi="['base:equipment-file:update']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['base:equipment-file:delete']">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@pagination="getList"/>
<!-- 对话框(添加 / 修改) -->
<el-dialog :title="title" :visible.sync="open" width="500px" v-dialogDrag append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="设备ID" prop="equipmentId">
<el-input v-model="form.equipmentId" placeholder="请输入设备ID" />
</el-form-item>
<el-form-item label="文件类型 1.图片 2.设备资料" prop="fileType">
<el-select v-model="form.fileType" placeholder="请选择文件类型 1.图片 2.设备资料">
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.EQU_FILE_TYPE)"
:key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="原始文件名" prop="fileName">
<el-input v-model="form.fileName" placeholder="请输入原始文件名" />
</el-form-item>
<el-form-item label="文件url" prop="fileUrl">
<el-input v-model="form.fileUrl" placeholder="请输入文件url" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { createEquipmentFile, updateEquipmentFile, deleteEquipmentFile, getEquipmentFile, getEquipmentFilePage, exportEquipmentFileExcel } from "@/api/base/equipmentFile";
export default {
name: "EquipmentFile",
components: {
},
data() {
return {
// 遮罩层
loading: true,
// 导出遮罩层
exportLoading: false,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 设备文件对应列表
list: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNo: 1,
pageSize: 10,
equipmentId: null,
},
// 表单参数
form: {},
// 表单校验
rules: {
}
};
},
created() {
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
// 执行查询
getEquipmentFilePage(this.queryParams).then(response => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
equipmentId: undefined,
fileType: undefined,
fileName: undefined,
fileUrl: undefined,
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加设备文件对应";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
getEquipmentFile(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改设备文件对应";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (!valid) {
return;
}
// 修改的提交
if (this.form.id != null) {
updateEquipmentFile(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
return;
}
// 添加的提交
createEquipmentFile(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal.confirm('是否确认删除设备文件对应编号为"' + id + '"的数据项?').then(function() {
return deleteEquipmentFile(id);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
// 处理查询参数
let params = {...this.queryParams};
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal.confirm('是否确认导出所有设备文件对应数据项?').then(() => {
this.exportLoading = true;
return exportEquipmentFileExcel(params);
}).then(response => {
this.$download.excel(response, '设备文件对应.xls');
this.exportLoading = false;
}).catch(() => {});
}
}
};
</script>

View File

@@ -0,0 +1,481 @@
<!--
filename: EquipmentDrawer.vue
author: liubin
date: 2023-08-22 14:38:56
description:
-->
<template>
<el-drawer
:visible="visible"
:show-close="false"
:wrapper-closable="false"
class="drawer"
custom-class="mes-drawer"
size="60%"
@closed="$emit('destroy')">
<SmallTitle slot="title">
{{
mode.includes('detail')
? '详情'
: mode.includes('edit')
? '编辑'
: '新增'
}}
</SmallTitle>
<div class="drawer-body flex">
<div class="drawer-body__content">
<section v-for="(section, index) in sections" :key="section.key">
<SmallTitle v-if="index != 0">{{ section.name }}</SmallTitle>
<div class="form-part" v-if="section.key == 'base'">
<el-skeleton v-if="!showForm" animated />
<BaseInfoForm
key="drawer-dialog-form"
v-if="showForm"
ref="form"
:disabled="mode.includes('detail')"
v-model="form"
:rows="formRows" />
</div>
<div v-if="section.key == 'attrs'" style="margin-top: 12px">
<base-table
v-loading="attrListLoading"
:table-props="section.props"
:page="attrQuery?.params.pageNo || 1"
:limit="attrQuery?.params.pageSize || 10"
:table-data="list"
:add-button-show="mode.includes('detail') ? null : '添加属性'"
@emitButtonClick="handleAddAttr"
@emitFun="handleEmitFun">
<method-btn
v-if="section.tableBtn"
slot="handleBtn"
label="操作"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="attrQuery.params.pageNo"
:limit.sync="attrQuery.params.pageSize"
@pagination="getAttrList" />
</div>
</section>
</div>
<div class="drawer-body__footer">
<el-button style="" @click="handleCancel">取消</el-button>
<el-button v-if="mode == 'detail'" type="primary" @click="toggleEdit">
编辑
</el-button>
<el-button v-else type="primary" @click="handleCancel">确定</el-button>
<!-- sections的第二项必须是 属性列表 -->
<!-- <el-button
v-if="sections[1].allowAdd"
type="primary"
@click="handleAddAttr">
添加属性
</el-button> -->
</div>
</div>
<!-- 属性对话框 -->
<base-dialog
v-if="sections[1].allowAdd"
:dialogTitle="attrTitle"
:dialogVisible="attrFormVisible"
width="45%"
:append-to-body="true"
custom-class="baseDialog"
@close="closeAttrForm"
@cancel="closeAttrForm"
@confirm="submitAttrForm">
<DialogForm
v-if="attrFormVisible"
ref="attrForm"
:disabled="mode.includes('detail')"
v-model="attrForm"
:rows="attrRows" />
</base-dialog>
</el-drawer>
</template>
<script>
import BaseInfoForm from '@/components/DialogForm';
import DialogForm from './dialogForm';
const SmallTitle = {
name: 'SmallTitle',
props: ['size'],
data() {
return {};
},
methods: {},
render: function (h) {
return h(
'span',
{
class: 'small-title',
style: {
fontSize: '18px',
lineHeight:
this.size == 'lg' ? '24px' : this.size == 'sm' ? '18px' : '20px',
fontWeight: 500,
fontFamily: '微软雅黑, Microsoft YaHei, Arial, Helvetica, sans-serif',
},
},
this.$slots.default
);
},
};
export default {
components: { SmallTitle, DialogForm, BaseInfoForm },
props: ['sections', 'defaultMode', 'dataId'], // dataId 作为一个通用的存放id的字段
data() {
return {
mode: '',
visible: false,
showForm: false,
total: 0,
form: {},
list: [],
attrTitle: '',
attrForm: {
id: null,
equipmentGroupId: '',
code: '',
type: '',
grade: '',
alarmCode: '',
alarmContent: '',
plcParamName: '',
},
attrFormVisible: false,
attrRows: [
[
{
input: true,
label: '报警编码', // 自动生成
prop: 'code',
url: '/base/equipment-group-alarm/getCode',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
{
select: true,
label: '报警类型', // 固定选项
prop: 'type',
options: [
{ label: '布尔型', value: 2 },
{ label: '字符型', value: 1 },
],
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
[
{
select: true,
label: '报警级别', // 字典
prop: 'grade',
options: this.getDictDatas(this.DICT_TYPE.EQU_ALARM_LEVEL),
},
{
input: true,
label: '设备报警编码', // 对应到设备实际的报警编码
prop: 'alarmCode',
},
],
[
{
input: true,
label: '参数列名', // 在实时数据库的列名
prop: 'plcParamName',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
{
input: true,
label: '报警内容',
prop: 'alarmContent',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
],
attrQuery: {
params: {
pageNo: 1,
pageSize: 10,
},
}, // 属性列表的请求
infoQuery: null, // 基本信息的请求
attrFormSubmitting: false,
attrListLoading: false,
};
},
computed: {
formRows() {
return this.sections[0].rows.map((row) => {
return row.map((col) => {
return {
...col,
bind: {
// 详情 模式下,禁用各种输入
// disabled: this.mode == 'detail',
disabled: true
},
};
});
});
},
tableBtn() {
return this.mode == 'detail' ? [] : this.sections[1].tableBtn;
},
},
mounted() {
this.mode = this.defaultMode || 'detail';
for (const section of this.sections) {
// 请求具体信息
if ('url' in section) {
const query = {
url: section.url,
method: section.method || 'get',
params: section.queryParams || null,
data: section.data || null,
};
// debugger;
this.$axios(query).then(({ data }) => {
if (section.key == 'base') {
this.form = data;
this.showForm = true;
this.infoQuery = query;
} else if (section.key == 'attrs') {
this.attrQuery = query;
this.list = data.list;
this.total = data.total;
}
});
}
}
},
methods: {
handleTableBtnClick({ type, data }) {
switch (type) {
case 'edit':
this.handleEditAttr(data.id);
break;
case 'delete':
this.handleDeleteAttr(data.id);
break;
}
},
handleEmitFun(val) {
console.log('handleEmitFun', val);
},
init() {
this.visible = true;
},
async getAttrList() {
this.attrListLoading = true;
const res = await this.$axios(this.attrQuery);
if (res.code == 0) {
this.list = res.data.list;
this.total = res.data.total;
}
this.attrListLoading = false;
},
// 保存表单
handleSave() {
this.$refs['form'][0].validate(async (valid) => {
if (valid) {
const isEdit = this.mode == 'edit';
await this.$axios({
url: this.sections[0][isEdit ? 'urlUpdate' : 'urlCreate'],
method: isEdit ? 'put' : 'post',
data: this.form,
});
this.$modal.msgSuccess(`${isEdit ? '更新' : '创建'}成功`);
this.visible = false;
this.$emit('refreshDataList');
}
});
},
handleCancel() {
this.visible = false;
},
// 开启编辑
toggleEdit() {
this.mode = 'edit';
},
// 新增属性
handleAddAttr() {
if (!this.dataId) return this.$message.warning('请先创建设备分组信息');
this.attrForm = {
id: null,
equipmentGroupId: this.dataId,
code: '',
type: '',
grade: '',
alarmCode: '',
alarmContent: '',
plcParamName: '',
};
this.attrTitle = '添加设备分组报警';
this.attrFormVisible = true;
},
// 编辑属性
async handleEditAttr(attrId) {
const res = await this.$axios({
url: this.sections[1].urlDetail,
method: 'get',
params: { id: attrId },
});
if (res.code == 0) {
this.attrForm = res.data;
this.attrTitle = '编辑设备分组报警';
this.attrFormVisible = true;
}
},
// 删除属性
handleDeleteAttr(attrId) {
this.$confirm('确定删除该分组报警?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(async () => {
const res = await this.$axios({
url: this.sections[1].urlDelete,
method: 'delete',
params: { id: attrId },
});
if (res.code == 0) {
this.$message({
message: '删除成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getAttrList();
},
});
}
})
.catch(() => {});
},
// 提交属性表
async submitAttrForm() {
this.$refs['attrForm'].validate((valid) => {
if (!valid) {
return;
}
});
const isEdit = this.attrForm.id != null;
this.attrFormSubmitting = true;
const res = await this.$axios({
url: isEdit ? this.sections[1].urlUpdate : this.sections[1].urlCreate,
method: isEdit ? 'put' : 'post',
data: this.attrForm,
});
if (res.code == 0) {
this.closeAttrForm();
this.$message({
message: `${isEdit ? '更新' : '创建'}成功`,
type: 'success',
duration: 1500,
onClose: () => {
this.getAttrList();
},
});
}
this.attrFormSubmitting = false;
},
closeAttrForm() {
this.attrFormVisible = false;
},
handleClick(raw) {
if (raw.type === 'delete') {
this.$confirm(`确定删除该报警?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
deleteProductAttr(raw.data.id).then(({ data }) => {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getList();
},
});
});
})
.catch(() => {});
} else {
this.addNew(raw.data.id);
}
},
},
};
</script>
<style scoped>
.drawer >>> .el-drawer {
border-radius: 8px 0 0 8px;
}
.drawer >>> .el-drawer__header {
margin: 0;
padding: 32px 32px 24px;
border-bottom: 1px solid #dcdfe6;
margin-bottom: 0px;
}
.small-title::before {
content: '';
display: inline-block;
vertical-align: top;
width: 4px;
height: 22px;
border-radius: 1px;
margin-right: 8px;
background-color: #0b58ff;
}
.drawer-body {
display: flex;
flex-direction: column;
height: 100%;
}
.drawer-body__content {
flex: 1;
/* background: #eee; */
padding: 20px 30px;
overflow-y: auto;
}
.drawer-body__footer {
display: flex;
justify-content: flex-end;
padding: 18px;
}
</style>

View File

@@ -0,0 +1,187 @@
<!--
filename: dialogForm.vue
author: liubin
date: 2023-09-11 15:55:13
description: DialogForm for equipmentBindSection only
-->
<template>
<el-form
ref="form"
:model="dataForm"
label-width="100px"
v-loading="formLoading">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="报警编码"
prop="code"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-input
:disabled="disabled"
v-model="dataForm.code"
@change="$emit('update', dataForm)"
placeholder="请输入工段排序" />
</el-form-item>
<!--
<el-form-item
label="报警编码"
prop="code"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-select
v-model="dataForm.code"
placeholder="请选择产线"
@change="handleProductlineChange">
<el-option
v-for="opt in productionLineList"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item> -->
</el-col>
<el-col :span="12">
<el-form-item
label="报警类型"
prop="type"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-select
:disabled="disabled"
v-model="dataForm.type"
placeholder="请选择报警类型"
@change="handleTypeChange">
<el-option
v-for="opt in [
{ label: '布尔型', value: 2 },
{ label: '字符型', value: 1 },
]"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="报警级别"
prop="grade"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-select
:disabled="disabled"
v-model="dataForm.grade"
placeholder="请选择报警级别"
@change="$emit('update', dataForm)">
<el-option
v-for="opt in getDictDatas(DICT_TYPE.EQU_ALARM_LEVEL)"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
v-if="+dataForm.type == 1"
label="设备报警编码"
prop="alarmCode">
<el-input
:disabled="disabled"
v-model="dataForm.alarmCode"
@change="$emit('update', dataForm)"
placeholder="请输入设备报警编码" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="参数列名"
prop="plcParamName"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-input
:disabled="disabled"
v-model="dataForm.plcParamName"
placeholder="请输入参数列名"
@change="$emit('update', dataForm)"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="报警内容"
prop="alarmContent"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-input
:disabled="disabled"
v-model="dataForm.alarmContent"
placeholder="请输入报警内容"
@change="$emit('update', dataForm)"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
export default {
name: 'DialogForm',
model: {
prop: 'dataForm',
event: 'update',
},
emits: ['update'],
components: {},
props: {
dataForm: {
type: Object,
default: () => ({}),
},
disabled: {
type: Boolean,
default: false,
},
},
data() {
return {
formLoading: true,
};
},
mounted() {
this.getCode('/base/equipment-group-alarm/getCode').then((code) => {
this.formLoading = false;
this.$emit('update', {
...this.dataForm,
code,
});
});
},
methods: {
/** 模拟透传 ref */
validate(cb) {
return this.$refs.form.validate(cb);
},
resetFields(args) {
return this.$refs.form.resetFields(args);
},
async handleTypeChange(id) {
// debugger;
this.dataForm.alarmCode = '';
this.$emit('update', this.dataForm);
},
async getCode(url) {
const response = await this.$axios(url);
return response.data;
},
},
};
</script>
<style scoped lang="scss">
.el-date-editor,
.el-select {
width: 100%;
}
</style>

View File

@@ -0,0 +1,466 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
:width="120"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
width="500px"
@close="cancel"
@cancel="cancel"
@confirm="submitForm">
<DialogForm v-if="open" ref="form" v-model="form" :rows="rows"/>
</base-dialog>
<!-- 抽屉 详情 -->
<BasicDrawer
v-if="editVisible"
ref="drawer"
:default-mode="editMode"
:data-id="alarmForm.id"
:sections="[
{
name: '基本信息',
key: 'base',
rows: drawerBaseInfoRows,
url: '/base/equipment-group/get',
urlUpdate: '/base/equipment-group/update',
urlCreate: '/base/equipment-group/create',
queryParams: { id: alarmForm.id },
},
{
name: '属性列表',
key: 'attrs',
props: drawerListProps,
url: '/base/equipment-group-alarm/page',
urlCreate: '/base/equipment-group-alarm/create',
urlUpdate: '/base/equipment-group-alarm/update',
urlDelete: '/base/equipment-group-alarm/delete',
urlDetail: '/base/equipment-group-alarm/get',
queryParams: {
equipmentGroupId: alarmForm.id,
pageNo: 1,
pageSize: 10,
},
tableBtn: [
this.$auth.hasPermi('base:equipment-group:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:equipment-group:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
allowAdd: true,
},
]"
@refreshDataList="getList"
@cancel="editVisible = false"
@destroy="editVisible = false" />
</div>
</template>
<script>
import {
createEquipmentGroup,
updateEquipmentGroup,
deleteEquipmentGroup,
getEquipmentGroup,
getEquipmentGroupPage,
exportEquipmentGroupExcel,
} from '@/api/base/equipmentGroup';
import moment from 'moment';
import { publicFormatter } from '@/utils/dict';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
// import { getAccessToken } from '@/utils/auth';
import BasicDrawer from './components/BasicDrawer.vue';
export default {
name: 'EquipmentGroup',
mixins: [basicPageMixin],
components: { BasicDrawer },
data() {
return {
editVisible: false,
editMode: '',
searchBarKeys: ['name', 'code'],
tableBtn: [
this.$auth.hasPermi('base:equipment-group:update')
? {
type: 'detail',
btnName: '查看报警',
}
: undefined,
this.$auth.hasPermi('base:equipment-group:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:equipment-group:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
{
prop: 'createTime',
label: '添加时间',
fixed: true,
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ prop: 'name', label: '设备分组名称' },
{ prop: 'code', label: '设备分组编码' },
{ prop: 'remark', label: '备注' },
// {
// _action: 'equipment-group-show-alert',
// label: '报警',
// subcomponent: {
// props: ['injectData'],
// render: function (h) {
// const _this = this;
// return h(
// 'el-button',
// {
// props: { type: 'text' },
// on: {
// click: function () {
// console.log('inejctdata', _this.injectData);
// _this.$emit('emitData', {
// action: _this.injectData._action,
// // value: _this.injectData.id,
// value: _this.injectData,
// });
// },
// },
// },
// '查看报警'
// );
// },
// },
// },
],
drawerBaseInfoRows: [
[
{
input: true,
label: '设备分组名称',
prop: 'name',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
// bind: {
// disabled: this.editMode == 'detail', // some condition, like detail mode...
// }
},
{
input: true,
label: '设备分组编码',
prop: 'code',
// url: '/base/equipment/getCode',
}
]
],
drawerListProps: [
{
prop: 'createTime',
label: '添加时间',
fixed: true,
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ width: 240, prop: 'code', label: '报警编码' },
{
width: 100,
prop: 'type',
label: '报警类型',
filter: (val) =>
val != null ? ['-', '字符型', '布尔型', '-'][val] : '-',
},
{
width: 90,
prop: 'grade',
label: '报警级别',
filter: publicFormatter(this.DICT_TYPE.EQU_ALARM_LEVEL),
},
{ width: 180, prop: 'alarmCode', label: '设备报警编码' },
{ width: 128, prop: 'plcParamName', label: '参数列名' },
{ width: 128, prop: 'alarmContent', label: '报警内容' },
],
alarmForm: {
id: undefined,
equipmentGroupCode: undefined,
equipmentGroupName: undefined,
},
searchBarFormConfig: [
{
type: 'input',
label: '分组名称',
placeholder: '请输入设备分组名称',
param: 'name',
},
{
type: 'input',
label: '分组编码',
placeholder: '请输入设备分组编码',
param: 'code',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:equipment-group:create')
? 'button'
: '',
btnName: '新增',
name: 'add',
plain: true,
color: 'success',
},
// {
// type: this.$auth.hasPermi('base:equipment-group:export') ? 'button' : '',
// btnName: '导出',
// name: 'export',
// color: 'warning',
// },
],
rows: [
[
{
input: true,
label: '分组名称',
prop: 'name',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
// bind: {
// disabled: true, // some condition, like detail mode...
// }
},
],
[
{
input: true,
label: '分组编码',
prop: 'code',
url: '/base/equipment-group/getCode',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
[
{
input: true,
label: '备注',
prop: 'remark',
// rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
bind: {
placeholder: '请输入备注',
},
},
],
],
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNo: 1,
pageSize: 10,
code: null,
name: null,
},
// 表单参数
form: {},
};
},
created() {
this.getList();
},
methods: {
/** 覆盖 handleEmitFun 的默认实现 */
handleEmitFun({ action, value }) {
const {
id: equipmentGroupId,
name: equipmentGroupName,
code: equipmentGroupCode,
} = value;
switch (action) {
case 'equipment-group-show-alert':
// this.$router.push({ path: '/equipment/base/equipment-group-alarm' });
this.$router.push({
name: 'EquipmentGroupAlarm',
params: {
equipmentGroupId,
equipmentGroupCode,
equipmentGroupName,
},
});
break;
}
},
/** 查询列表 */
getList() {
this.loading = true;
// 执行查询
getEquipmentGroupPage(this.queryParams).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
code: undefined,
name: undefined,
remark: undefined,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = '添加设备分组(用于同类型不同厂家的设备区分)';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
getEquipmentGroup(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改设备分组(用于同类型不同厂家的设备区分)';
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
// 修改的提交
if (this.form.id != null) {
updateEquipmentGroup(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
// 添加的提交
createEquipmentGroup(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
// 查看报警
handleDetail(row) {
// debugger;
const { id, code, name, createTime } = row;
// 打开抽屉
this.editMode = 'detail';
this.alarmForm.id = id;
this.alarmForm.equipmentGroupCode = code;
this.alarmForm.equipmentGroupName = name;
this.editVisible = true;
this.$nextTick(() => {
this.$refs['drawer'].init();
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm('是否确认删除设备分组 "' + row.name + '"?')
.then(function () {
return deleteEquipmentGroup(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
// 处理查询参数
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm(
'是否确认导出所有设备分组(用于同类型不同厂家的设备区分)数据项?'
)
.then(() => {
this.exportLoading = true;
return exportEquipmentGroupExcel(params);
})
.then((response) => {
this.$download.excel(
response,
'设备分组(用于同类型不同厂家的设备区分).xls'
);
this.exportLoading = false;
})
.catch(() => {});
},
},
};
</script>

View File

@@ -0,0 +1,187 @@
<!--
filename: dialogForm.vue
author: liubin
date: 2023-09-11 15:55:13
description: DialogForm for equipmentBindSection only
-->
<template>
<el-form
ref="form"
:model="dataForm"
label-width="100px"
v-loading="formLoading">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="报警编码"
prop="code"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-input
:disabled="disabled"
v-model="dataForm.code"
@change="$emit('update', dataForm)"
placeholder="请输入工段排序" />
</el-form-item>
<!--
<el-form-item
label="报警编码"
prop="code"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-select
v-model="dataForm.code"
placeholder="请选择产线"
@change="handleProductlineChange">
<el-option
v-for="opt in productionLineList"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item> -->
</el-col>
<el-col :span="12">
<el-form-item
label="报警类型"
prop="type"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-select
v-model="dataForm.type"
:disabled="disabled"
placeholder="请选择报警类型"
@change="$emit('update', dataForm)">
<el-option
v-for="opt in [
{ label: '布尔型', value: 2 },
{ label: '字符型', value: 1 },
]"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="报警级别"
prop="grade"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-select
:disabled="disabled"
v-model="dataForm.grade"
placeholder="请选择报警级别"
@change="$emit('update', dataForm)">
<el-option
v-for="opt in getDictDatas(DICT_TYPE.EQU_ALARM_LEVEL)"
:key="opt.value"
:label="opt.label"
:value="opt.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
v-if="+dataForm.type == 1"
label="设备报警编码"
prop="alarmCode">
<el-input
:disabled="disabled"
v-model="dataForm.alarmCode"
@change="$emit('update', dataForm)"
placeholder="请输入设备报警编码" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="参数列名"
prop="plcParamName"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-input
:disabled="disabled"
v-model="dataForm.plcParamName"
placeholder="请输入参数列名"
@change="$emit('update', dataForm)"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="报警内容"
prop="alarmContent"
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]">
<el-input
:disabled="disabled"
v-model="dataForm.alarmContent"
placeholder="请输入报警内容"
@change="$emit('update', dataForm)"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
export default {
name: 'DialogForm',
model: {
prop: 'dataForm',
event: 'update',
},
emits: ['update'],
components: {},
props: {
dataForm: {
type: Object,
default: () => ({}),
},
disabled: {
type: Boolean,
default: false,
},
},
data() {
return {
formLoading: true,
};
},
mounted() {
this.getCode('/base/equipment-group-alarm/getCode').then((code) => {
this.formLoading = false;
this.$emit('update', {
...this.dataForm,
code,
});
});
},
methods: {
/** 模拟透传 ref */
validate(cb) {
return this.$refs.form.validate(cb);
},
resetFields(args) {
return this.$refs.form.resetFields(args);
},
async handleProductlineChange(id) {
await this.getWorksectionList(id);
this.dataForm.workshopSectionId = null;
this.$emit('update', this.dataForm);
},
async getCode(url) {
const response = await this.$axios(url);
return response.data;
},
},
};
</script>
<style scoped lang="scss">
.el-date-editor,
.el-select {
width: 100%;
}
</style>

View File

@@ -0,0 +1,361 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
:width="120"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
width="736px"
@close="cancel"
@cancel="cancel"
@confirm="submitForm">
<DialogForm v-if="open" ref="form" v-model="form" :rows="rows" />
</base-dialog>
</div>
</template>
<script>
import {
createEquipmentGroupAlarm,
updateEquipmentGroupAlarm,
deleteEquipmentGroupAlarm,
getEquipmentGroupAlarm,
getEquipmentGroupAlarmPage,
exportEquipmentGroupAlarmExcel,
} from '@/api/base/equipmentGroupAlarm';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import moment from 'moment';
import { publicFormatter } from '@/utils/dict';
import DialogForm from './dialogForm.vue';
export default {
name: 'EquipmentGroupAlarm',
components: { DialogForm },
mixins: [basicPageMixin],
data() {
return {
searchBarKeys: [''],
tableBtn: [
this.$auth.hasPermi('base:equipment-group-alarm:update')
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:equipment-group-alarm:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
{
prop: 'createTime',
label: '添加时间',
fixed: true,
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ width: 240, prop: 'code', label: '报警编码' },
{
prop: 'type',
label: '报警类型',
filter: (val) =>
val != null ? ['-', '字符型', '布尔型', '-'][val] : '-',
},
{
prop: 'grade',
label: '报警级别',
filter: publicFormatter(this.DICT_TYPE.EQU_ALARM_LEVEL),
},
{ prop: 'alarmCode', label: '设备报警编码' },
{ prop: 'plcParamName', label: '参数列名' },
{ prop: 'alarmContent', label: '报警内容' },
],
searchBarFormConfig: [
{
type: 'input',
label: '设备分组编码',
width: '220',
placeholder: '/',
param: 'equipmentGroupCode',
defaultSelect: null,
disabled: true,
},
{
type: 'input',
label: '设备分组名称',
placeholder: '/',
param: 'equipmentGroupName',
defaultSelect: null,
disabled: true,
},
{
type: this.$auth.hasPermi('base:equipment-group-alarm:create')
? 'button'
: '',
btnName: '新增',
name: 'add',
plain: true,
color: 'success',
},
],
rows: [
[
{
input: true,
label: '报警编码', // 自动生成
prop: 'code',
url: '/base/equipment-group-alarm/getCode',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
{
select: true,
label: '报警类型', // 固定选项
prop: 'type',
options: [
{ label: '布尔型', value: 2 },
{ label: '字符型', value: 1 },
],
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
[
{
select: true,
label: '报警级别', // 字典
prop: 'grade',
options: this.getDictDatas(this.DICT_TYPE.EQU_ALARM_LEVEL),
},
{
input: true,
label: '设备报警编码', // 对应到设备实际的报警编码
prop: 'alarmCode',
},
],
[
{
input: true,
label: '参数列名', // 在实时数据库的列名
prop: 'plcParamName',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
{
input: true,
label: '报警内容',
prop: 'alarmContent',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
],
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNo: 1,
pageSize: 10,
equipmentGroupId: null,
},
// 表单参数
form: {
id: null,
equipmentGroupId: null,
code: null,
type: null,
grade: null,
alarmCode: null,
alarmContent: null,
plcParamName: null,
},
// // 表单校验
// rules: {
// equipmentGroupId: [{ required: true, message: "设备分组ID关联base_equipment_group不能为空", trigger: "blur" }],
// type: [{ required: true, message: "报警类型:1.字符型2.布尔型不能为空", trigger: "change" }],
// alarmContent: [{ required: true, message: "报警内容 该条报警具体的解释不能为空", trigger: "blur" }],
// plcParamName: [{ required: true, message: "关联编码对应到plc_param_name的编码用于链接数采不能为空", trigger: "blur" }],
// }
};
},
// watch: {
// $route(value) {
// console.log('new route info', value)
// }
// },
// created() {
// this.getList();
// },
activated() {
// 设置顶部搜索栏信息
const { equipmentGroupName, equipmentGroupCode, equipmentGroupId } =
this.$route.params;
this.setSearchBarFormValue('equipmentGroupName', equipmentGroupName);
this.setSearchBarFormValue('equipmentGroupCode', equipmentGroupCode);
this.queryParams.equipmentGroupId = equipmentGroupId;
// if (!equipmentGroupId) this.getList(); // 拦截
this.getList();
},
deactivated() {
this.setSearchBarFormValue('equipmentGroupName', null);
this.setSearchBarFormValue('equipmentGroupCode', null);
this.queryParams.equipmentGroupId = null;
},
methods: {
/** 设置 searchBarForm 的默认值 - 用得比较少 */
setSearchBarFormValue(param, value) {
this.searchBarFormConfig.forEach((config) => {
if (config.param == param) {
config.defaultSelect = value;
}
});
},
/** 查询列表 */
getList() {
this.loading = true;
// 执行查询
getEquipmentGroupAlarmPage(this.queryParams).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: null,
equipmentGroupId: null,
code: null,
type: null,
grade: null,
alarmCode: null,
alarmContent: null,
plcParamName: null,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
if (this.queryParams.equipmentGroupId == null)
return this.$message.warning('没有检测到设备分组信息');
this.reset();
this.open = true;
this.title = '添加设备分组报警明细';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
getEquipmentGroupAlarm(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改设备分组报警明细';
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
// 修改的提交
if (this.form.id != null) {
updateEquipmentGroupAlarm({
...this.form,
equipmentGroupId: this.queryParams.equipmentGroupId,
}).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
// 添加的提交
createEquipmentGroupAlarm({
...this.form,
equipmentGroupId: this.queryParams.equipmentGroupId,
}).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm('是否确认删除该报警?')
.then(function () {
return deleteEquipmentGroupAlarm(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
// 处理查询参数
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有设备分组报警明细数据项?')
.then(() => {
this.exportLoading = true;
return exportEquipmentGroupAlarmExcel(params);
})
.then((response) => {
this.$download.excel(response, '设备分组报警明细.xls');
this.exportLoading = false;
})
.catch(() => {});
},
},
};
</script>

View File

@@ -0,0 +1,109 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2025-02-26 16:37:29
* @Description:
-->
<template>
<el-row :gutter="20">
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="80px">
<el-col :span="12">
<el-form-item label="关联表名" prop="plcTableName">
<el-input
v-model="dataForm.plcTableName"
clearable
placeholder="请输入关联表名" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="编码" prop="code">
<el-input
v-model="dataForm.code"
clearable
placeholder="请输入编码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="标识" prop="name">
<el-input
v-model="dataForm.name"
clearable
placeholder="请输入标识" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="英文名" prop="enName">
<el-input
v-model="dataForm.enName"
clearable
placeholder="请输入英文名" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="是否采集" prop="collection">
<el-switch
v-model="dataForm.collection"
:active-value="1"
:inactive-value="0"></el-switch>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="描述" prop="description">
<el-input
v-model="dataForm.description"
clearable
placeholder="请输入描述" />
</el-form-item>
</el-col>
</el-form>
</el-row>
</template>
<script>
import basicAdd from '@/mixins/basic-add';
import {
createEquipmentPlc,
updateEquipmentPlc,
getEquipmentPlc,
getCode,
} from '@/api/base/equipmentPlc';
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
isGetCode: true,
codeURL: getCode,
createURL: createEquipmentPlc,
updateURL: updateEquipmentPlc,
infoURL: getEquipmentPlc,
},
dataForm: {
id: undefined,
plcTableName: undefined,
code: undefined,
name: undefined,
enName: undefined,
collection: 1,
description: undefined,
},
dataRule: {
plcTableName: [
{ required: true, message: '关联表名不能为空', trigger: 'blur' },
],
code: [{ required: true, message: '编码不能为空', trigger: 'blur' }],
name: [{ required: true, message: '标识不能为空', trigger: 'blur' }],
},
};
},
methods: {},
};
</script>

View File

@@ -0,0 +1,223 @@
<template>
<div class="app-container">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:table-data="tableData"
@emitFun="handleEmitFun">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList" />
<base-dialog
:dialogTitle="addOrEditTitle"
:dialogVisible="addOrUpdateVisible"
@cancel="handleCancel"
@confirm="handleConfirm"
:before-close="handleCancel"
width="50%">
<add-or-update
ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update>
</base-dialog>
</div>
</template>
<script>
import AddOrUpdate from './add-or-updata';
import basicPage from '@/mixins/basic-page';
import { parseTime } from '@/filter/code-filter';
import {
deleteEquipmentPlc,
getEquipmentPlcPage,
exportEquipmentPlcExcel,
updateEquipmentPlc,
} from '@/api/base/equipmentPlc';
const switchBtn = {
name: 'SwitchBtn',
props: ['injectData'],
data() {
return {};
},
computed: {
active() {
return +this.injectData[this.injectData.prop] == 1 ? true : false;
},
},
methods: {},
render: function (h) {
return h(
'el-switch',
{
props: {
value: this.active,
},
on: {
change: (newVal) => {
this.$emit('emitData', {
action: 'update-collect',
payload: {
...this.injectData,
collection: newVal ? 1 : 0,
},
});
},
},
},
null
);
},
};
const tableProps = [
{ prop: 'code', label: '编码', width: 220 },
{ prop: 'plcTableName', label: '关联表名' },
{ prop: 'name', label: '标识名称' },
{ prop: 'enName', label: '英文名称' },
{
prop: 'collection',
label: '是否采集',
subcomponent: switchBtn,
},
{ prop: 'description', label: '描述' },
];
export default {
mixins: [basicPage],
data() {
return {
urlOptions: {
getDataListURL: getEquipmentPlcPage,
deleteURL: deleteEquipmentPlc,
exportURL: exportEquipmentPlcExcel,
},
tableProps,
tableBtn: [
this.$auth.hasPermi(`base:equipment-plc:update`)
? {
type: 'edit',
btnName: '编辑',
}
: undefined,
this.$auth.hasPermi(`base:equipment-plc:delete`)
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableData: [],
formConfig: [
{
type: 'input',
label: '表名',
placeholder: '请输入表名',
param: 'plcTableName',
},
{
type: 'input',
label: '标识',
placeholder: '请输入标识',
param: 'name',
},
{
type: 'button',
btnName: '搜索',
name: 'search',
color: 'primary',
},
// {
// type: 'separate',
// },
// {
// type: 'button',
// btnName: '重置',
// name: 'reset',
// },
{
type: 'separate',
},
{
type: this.$auth.hasPermi('base:factory:create') ? 'button' : '',
btnName: '新增',
name: 'add',
color: 'success',
plain: true,
},
// {
// type: this.$auth.hasPermi('base:factory:create') ? 'separate' : '',
// },
// {
// type: this.$auth.hasPermi('base:factory:export') ? 'button' : '',
// btnName: '导出',
// name: 'export',
// color: 'warning',
// },
],
};
},
components: {
AddOrUpdate,
},
created() {},
methods: {
/** 覆盖 handleEmitFun 的默认实现 */
handleEmitFun({ action, payload }) {
console.log(payload)
switch (action) {
case 'update-collect':
updateEquipmentPlc(payload).then((response) => {
this.$modal.msgSuccess('修改成功');
this.getDataList();
});
break;
}
},
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 10;
this.listQuery.name = val.name;
this.listQuery.plcTableName = val.plcTableName;
this.getDataList();
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.listQuery = {
pageSize: 10,
pageNo: 1,
total: 1,
};
this.getDataList();
break;
case 'add':
this.addOrEditTitle = '新增';
this.addOrUpdateVisible = true;
this.addOrUpdateHandle();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
},
};
</script>

View File

@@ -0,0 +1,388 @@
<!--
filename: TableConfig.vue
author: liubin
date: 2023-10-30 10:09:03
description:
-->
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 -->
<base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
ref="pageTable"
@emitFun="handleEmitFun"
:max-height="tableH">
<method-btn
v-if="tableBtn.length"
slot="handleBtn"
label="操作"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
<!-- 对话框(添加 / 修改) -->
<base-dialog
:dialogTitle="title"
:dialogVisible="open"
width="700px"
@close="cancel"
@cancel="cancel"
@confirm="submitForm">
<DialogForm v-if="open" ref="form" v-model="form" :rows="rows" />
</base-dialog>
</div>
</template>
<script>
import {
createEquipmentPlc,
updateEquipmentPlc,
deleteEquipmentPlc,
getEquipmentPlc,
getEquipmentPlcPage,
exportEquipmentPlcExcel,
} from '@/api/base/equipmentPlc';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import tableHeightMixin from '@/mixins/lb/tableHeightMixin';
const switchBtn = {
name: 'SwitchBtn',
props: ['injectData'],
data() {
return {};
},
computed: {
active() {
return +this.injectData[this.injectData.prop] == 1 ? true : false;
},
},
methods: {},
render: function (h) {
return h(
'el-switch',
{
props: {
value: this.active,
},
on: {
change: (newVal) => {
this.$emit('emitData', {
action: 'update-collect',
payload: {
...this.injectData,
collection: newVal ? 1 : 0,
},
});
},
},
},
null
);
},
};
export default {
name: 'EquipmentPlc',
mixins: [basicPageMixin, tableHeightMixin],
components: {},
data() {
return {
tableKey: Math.random(),
searchBarKeys: ['name', 'plcTableName'],
tableBtn: [
this.$auth.hasPermiAnd([
'base:equipment-plc:update',
'base:equipment-plc:query'
])
? {
type: 'edit',
btnName: '修改',
}
: undefined,
this.$auth.hasPermi('base:equipment-plc:delete')
? {
type: 'delete',
btnName: '删除',
}
: undefined,
].filter((v) => v),
tableProps: [
// {
// prop: 'createTime',
// label: '添加时间',
// fixed: true,
// width: 180,
// filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
// },
{ prop: 'code', label: '编码', width: 180, showOverflowtooltip: true },
{ prop: 'plcTableName', label: '关联表名', width: 150, showOverflowtooltip: true },
{ prop: 'name', label: '标识名称', width: 150, showOverflowtooltip: true },
{ prop: 'enName', label: '英文名称', width: 150, showOverflowtooltip: true },
{
prop: 'collection',
label: '是否采集',
subcomponent: switchBtn,
},
{ prop: 'description', label: '描述', minWidth: 150, showOverflowtooltip: true },
],
searchBarFormConfig: [
{
type: 'input',
label: '表名',
placeholder: '请输入表名',
param: 'plcTableName',
},
{
type: 'input',
label: '标识',
placeholder: '请输入标识',
param: 'name',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: this.$auth.hasPermi('base:equipment-plc:create')
? 'separate' : '',
},
{
type: this.$auth.hasPermi('base:equipment-plc:create')
? 'button' : '',
btnName: '新增',
name: 'add',
plain: true,
color: 'success',
},
// {
// type: this.$auth.hasPermi('equipment:realtime-table-config:export') ? 'button' : '',
// btnName: '导出',
// name: 'export',
// color: 'warning',
// },
],
rows: [
[
{
input: true,
label: '关联表名',
prop: 'plcTableName',
rules: [{ required: true, message: '关联表名不能为空', trigger: 'blur' }],
// bind: {
// disabled: true, // some condition, like detail mode...
// }
},
{
input: true,
label: '编码',
prop: 'code',
url: '/base/energy-plc/getCode',
rules: [{ required: true, message: '编码不能为空', trigger: 'blur' }],
},
],
[
{
input: true,
label: '标识',
prop: 'name',
rules: [{ required: true, message: '标识不能为空', trigger: 'blur' }],
// bind: {
// disabled: true, // some condition, like detail mode...
// }
},
{
input: true,
label: '英文名',
prop: 'enName',
},
],
[
{
switch: true,
label: '是否采集', // 是否采集 0 代表不采集, 1 代表采集
prop: 'collection',
bind: {
'active-value': 1,
'inactive-value': 0,
value: 1,
},
},
],
[
{
textarea: true,
label: '描述',
prop: 'description',
bind: {
placeholder: '请输入备注',
},
},
],
],
// 是否显示弹出
open: false,
// 查询参数
queryParams: {
pageNo: 1,
pageSize: 20,
plcTableName: null,
name: null,
},
// 表单参数
form: {},
};
},
created() {
this.getList();
},
methods: {
/** 覆盖 handleEmitFun 的默认实现 */
handleEmitFun({ action, payload }) {
switch (action) {
case 'update-collect':
this.reset();
const tempForm = {};
Object.keys(this.form).forEach((key) => {
tempForm[key] = payload[key];
});
updateEquipmentPlc(tempForm).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
break;
}
},
/** 查询列表 */
getList() {
this.loading = true;
// 执行查询
getEquipmentPlcPage(this.queryParams).then((response) => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
// this.tableKey = Math.random(); // method 1
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form = {
id: undefined,
plcTableName: undefined,
code: undefined,
name: undefined,
enName: undefined,
description: undefined,
collection: 1,
};
this.resetForm('form');
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = '添加实时数据采集配置';
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id;
getEquipmentPlc(id).then((response) => {
this.form = response.data;
this.open = true;
this.title = '修改实时数据采集配置';
});
},
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (!valid) {
return;
}
// 修改的提交
if (this.form.id != null) {
updateEquipmentPlc(this.form).then((response) => {
this.$modal.msgSuccess('修改成功');
this.open = false;
this.getList();
});
return;
}
// 添加的提交
createEquipmentPlc(this.form).then((response) => {
this.$modal.msgSuccess('新增成功');
this.open = false;
this.getList();
});
});
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal
.confirm('是否确认删除该配置?')
.then(function () {
return deleteEquipmentPlc(id);
})
.then(() => {
this.getList();
this.$modal.msgSuccess('删除成功');
})
.catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
// 处理查询参数
let params = { ...this.queryParams };
params.pageNo = undefined;
params.pageSize = undefined;
this.$modal
.confirm('是否确认导出所有实时数据采集配置数据项?')
.then(() => {
this.exportLoading = true;
return exportEquipmentPlcExcel(params);
})
.then((response) => {
this.$download.excel(response, '实时数据采集配置.xls');
this.exportLoading = false;
})
.catch(() => {});
},
},
};
</script>

View File

@@ -0,0 +1,151 @@
<!--
* @Author: zwq
* @Date: 2021-11-18 14:16:25
* @LastEditors: zwq
* @LastEditTime: 2025-02-25 16:11:14
* @Description:
-->
<template>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
@keyup.enter.native="dataFormSubmit()"
label-width="100px">
<el-form-item label="设备" prop="equipmentId">
<el-cascader
placeholder="请选择设备"
v-model="dataForm.equipmentId"
:options="plLineList"
:props="{value: 'id', label: 'name', children: 'children'}"
style="width: 100%"
filterable />
</el-form-item>
<el-form-item label="关联表名" prop="plcId">
<el-select
v-model="dataForm.plcId"
filterable
placeholder="请选择关联表"
style="width: 100%">
<el-option
v-for="dict in plcList"
:key="dict.id"
:label="dict.plcTableName"
:value="dict.id" />
</el-select>
</el-form-item>
</el-form>
</template>
<script>
import basicAdd from './components/basic-add';
import { createEquipmentPlcConnect, updateEquipmentPlcConnect } from '@/api/base/equipmentPlcConnect';
import { getplcAllList, getTree } from "@/api/base/equipmentConfig";
export default {
mixins: [basicAdd],
data() {
return {
urlOptions: {
createURL: createEquipmentPlcConnect,
updateURL: updateEquipmentPlcConnect,
},
dataForm: {
id: undefined,
equipmentId: undefined,
plcId: undefined
},
plcList: [],
plLineList: [],
dataRule: {
equipmentId: [{ required: true, message: "设备不能为空", trigger: "blur" }],
plcId: [{ required: true, message: "关联表名不能为空", trigger: "blur" }]
},
options: [{
value: 'zhinan',
label: '指南',
children: [{
value: 'shejiyuanze',
label: '设计原则',
children: [{
value: 'yizhi',
label: '一致'
}, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}]
}, {
value: 'daohang',
label: '导航'
}]
}]
};
},
created() {
this.getDict()
},
methods: {
init() {
this.$nextTick(() => {
this.$refs['dataForm'].resetFields()
})
},
async getDict() {
// 关联表名列表
const res = await getplcAllList();
this.plcList = res.data;
// 树形结构
const res1 = await getTree();
this.plLineList = res1.data;
// const res1 = await getCorePLList();
// this.plLineList = res1.data;
// this.plLineList.forEach(item => {
// listByParentId({ id: item.id }).then(resp => {
// if (resp.data.length > 0) {
// // item.children = resp.data
// this.$set(item, 'children', resp.data)
// // this.$forceUpdate()
// }
// })
// })
},
// 表单提交
dataFormSubmit() {
this.$refs["dataForm"].validate((valid) => {
if (!valid) {
return false;
}
// 修改的提交
if (this.dataForm.id) {
updateEquipmentPlcConnect({
id: this.dataForm.id,
equipmentId: this.dataForm.equipmentId[this.dataForm.equipmentId.length],
plcId: this.dataForm.plcId
}).then(response => {
this.$modal.msgSuccess("修改成功");
this.visible = false;
this.$emit("refreshDataList");
});
return;
}
// 添加的提交
createEquipmentPlcConnect({
id: this.dataForm.id,
equipmentId: this.dataForm.equipmentId[this.dataForm.equipmentId.length - 1],
plcId: this.dataForm.plcId
}).then(response => {
this.$modal.msgSuccess("新增成功");
this.visible = false;
this.$emit("refreshDataList");
});
});
}
}
};
</script>

View File

@@ -0,0 +1,574 @@
<!--
filename: EquipmentDrawer.vue
author: liubin
date: 2023-08-22 14:38:56
description:
-->
<template>
<el-drawer
:visible="visible"
:show-close="false"
:wrapper-closable="false"
class="drawer"
custom-class="mes-drawer"
size="60%"
@closed="$emit('destroy')">
<SmallTitle slot="title">
{{
mode.includes('detail')
? '详情'
: mode.includes('edit')
? '编辑'
: '新增'
}}
</SmallTitle>
<div class="drawer-body flex">
<div class="drawer-body__content">
<section v-for="(section, index) in sections" :key="section.key">
<SmallTitle v-if="index != 0">{{ section.name }}</SmallTitle>
<div class="form-part" v-if="section.key == 'base'">
<el-skeleton v-if="!showForm" animated />
<BaseInfoForm
key="drawer-dialog-form"
v-if="showForm"
ref="form"
:disabled="mode.includes('detail')"
v-model="form"
:rows="formRows" />
</div>
<div v-if="section.key == 'attrs'" style="margin-top: 12px">
<base-table
v-loading="attrListLoading"
:table-props="section.props"
:page="attrQuery?.params.pageNo || 1"
:limit="attrQuery?.params.pageSize || 10"
:table-data="list"
:add-button-show="mode.includes('detail') ? null : '添加属性'"
@emitButtonClick="handleAddAttr"
@emitFun="handleEmitFun">
<method-btn
v-if="section.tableBtn"
slot="handleBtn"
label="操作"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" />
</base-table>
<!-- 分页组件 -->
<pagination
v-show="total > 0"
:total="total"
:page.sync="attrQuery.params.pageNo"
:limit.sync="attrQuery.params.pageSize"
@pagination="getAttrList" />
</div>
</section>
</div>
<div class="drawer-body__footer">
<el-button style="" @click="handleCancel">取消</el-button>
<el-button v-if="mode == 'detail'" type="primary" @click="toggleEdit">
编辑
</el-button>
<el-button v-else type="primary" @click="handleCancel">确定</el-button>
<!-- sections的第二项必须是 属性列表 -->
<!-- <el-button
v-if="sections[1].allowAdd"
type="primary"
@click="handleAddAttr">
添加属性
</el-button> -->
</div>
</div>
<!-- 属性对话框 -->
<base-dialog
v-if="sections[1].allowAdd"
:dialogTitle="attrTitle"
:dialogVisible="attrFormVisible"
width="45%"
:append-to-body="true"
custom-class="baseDialog"
@close="closeAttrForm"
@cancel="closeAttrForm"
@confirm="submitAttrForm">
<DialogForm
v-if="attrFormVisible"
ref="attrForm"
:disabled="mode.includes('detail')"
v-model="attrForm"
:rows="attrRows" />
</base-dialog>
</el-drawer>
</template>
<script>
import BaseInfoForm from '@/components/DialogForm';
const SmallTitle = {
name: 'SmallTitle',
props: ['size'],
data() {
return {};
},
methods: {},
render: function (h) {
return h(
'span',
{
class: 'small-title',
style: {
fontSize: '18px',
lineHeight:
this.size == 'lg' ? '24px' : this.size == 'sm' ? '18px' : '20px',
fontWeight: 500,
fontFamily: '微软雅黑, Microsoft YaHei, Arial, Helvetica, sans-serif',
},
},
this.$slots.default
);
},
};
export default {
components: { SmallTitle, DialogForm: BaseInfoForm, BaseInfoForm },
props: ['sections', 'defaultMode', 'infoData'],
data() {
return {
mode: '',
visible: false,
showForm: false,
total: 0,
form: {},
list: [],
attrTitle: '',
attrForm: {
id: null,
name: '',
plcParamName: '',
unit: '',
collection: 1,
minValue: '',
maxValue: '',
defaultValue: '',
description: '',
remark: '',
alarmContent: '',
equipmentParamType: '',
productionParamType: '',
},
attrFormVisible: false,
attrRows: [
[
{
input: true,
label: '参数列名',
prop: 'plcParamName',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
{
input: true,
label: '参数名称',
prop: 'name',
rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
[
{
select: true,
label: '单位',
prop: 'unit',
options: this.getDictDatas(this.DICT_TYPE.UNIT_DICT),
// rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
{
switch: true,
label: '是否采集',
prop: 'collection',
bind: {
'active-value': 1,
'inactive-value': 0,
},
},
],
[
{
select: true,
label: '设备参数类型',
prop: 'equipmentParamType',
options: [
{ label: '一般参数', value: 1 },
{ label: '工艺参数', value: 2 },
{ label: '报警参数', value: 3 },
],
rules: [
{
required: true,
message: '设备参数类型不能为空',
trigger: 'blur',
},
],
},
{
select: true,
label: '生产参数类型',
prop: 'productionParamType',
options: [
// { label: '进片数量', value: 1 },
// { label: '出片数量', value: 2 },
// { label: '破损数量', value: 3 },
// { label: '无类型', value: 4 },
{ label: '进口计数', value: 1 },
{ label: '出口计数', value: 2 },
{ label: '损耗计数', value: 3 },
{ label: '无类型', value: 4 },
],
rules: [
{
required: true,
message: '生产参数类型不能为空',
trigger: 'blur',
},
],
},
],
[
{
input: true,
label: '最小值',
prop: 'minValue',
rules: [
{
type: 'number',
message: '请输入正确的数字',
trigger: 'change',
transform: (val) => Number(val),
},
],
},
{
input: true,
label: '最大值',
prop: 'maxValue',
rules: [
{
required: false,
},
{
type: 'number',
message: '请输入正确的数字',
trigger: 'change',
transform: (val) => Number(val),
},
],
// rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
[
{
input: true,
label: '标准值',
prop: 'defaultValue',
// rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
{
input: true,
label: '描述',
prop: 'description',
// rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
[
{
input: true,
label: '备注',
prop: 'remark',
// rules: [{ required: true, message: '不能为空', trigger: 'blur' }],
},
],
],
attrQuery: {
params: {
pageNo: 1,
pageSize: 10,
},
}, // 属性列表的请求
infoQuery: null, // 基本信息的请求
attrFormSubmitting: false,
attrListLoading: false,
};
},
computed: {
formRows() {
return this.sections[0].rows.map((row) => {
return row.map((col) => {
return {
...col,
bind: {
// 详情 模式下,禁用各种输入
// disabled: this.mode == 'detail',
disabled: true,
},
};
});
});
},
tableBtn() {
return this.mode == 'detail' ? [] : this.sections[1].tableBtn;
},
},
mounted() {
this.mode = this.defaultMode || 'detail';
for (const section of this.sections) {
// 请求具体信息
if ('url' in section) {
const query = {
url: section.url,
method: section.method || 'get',
params: section.queryParams || null,
data: section.data || null,
};
// debugger;
this.$axios(query).then(({ data }) => {
if (section.key == 'base') {
this.form = data;
this.showForm = true;
this.infoQuery = query;
} else if (section.key == 'attrs') {
this.attrQuery = query;
this.list = data.list;
this.total = data.total;
}
});
} else if (section.key == 'base') {
this.form = this.infoData;
this.showForm = true;
}
}
},
methods: {
handleTableBtnClick({ type, data }) {
switch (type) {
case 'edit':
this.handleEditAttr(data.id);
break;
case 'delete':
this.handleDeleteAttr(data.id);
break;
}
},
handleEmitFun(val) {
console.log('handleEmitFun', val);
},
init() {
this.visible = true;
},
async getAttrList() {
this.attrListLoading = true;
const res = await this.$axios(this.attrQuery);
if (res.code == 0) {
this.list = res.data.list;
this.total = res.data.total;
}
this.attrListLoading = false;
},
// 保存表单
handleSave() {
this.$refs['form'][0].validate(async (valid) => {
if (valid) {
const isEdit = this.mode == 'edit';
await this.$axios({
url: this.sections[0][isEdit ? 'urlUpdate' : 'urlCreate'],
method: isEdit ? 'put' : 'post',
data: this.form,
});
this.$modal.msgSuccess(`${isEdit ? '更新' : '创建'}成功`);
this.visible = false;
this.$emit('refreshDataList');
}
});
},
handleCancel() {
this.visible = false;
},
// 开启编辑
toggleEdit() {
this.mode = 'edit';
},
// 新增属性
handleAddAttr() {
this.attrForm = {
id: null,
name: '',
plcParamName: '',
unit: '',
collection: 1,
minValue: '',
maxValue: '',
defaultValue: '',
description: '',
remark: '',
alarmContent: '',
};
this.attrTitle = '添加设备绑定信息';
this.attrFormVisible = true;
},
// 编辑属性
async handleEditAttr(attrId) {
const res = await this.$axios({
url: this.sections[1].urlDetail,
method: 'get',
params: { id: attrId },
});
if (res.code == 0) {
this.attrForm = res.data;
this.attrTitle = '编辑设备绑定信息';
this.attrFormVisible = true;
}
},
// 删除属性
handleDeleteAttr(attrId) {
this.$confirm('确定删除该分组报警?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(async () => {
const res = await this.$axios({
url: this.sections[1].urlDelete,
method: 'delete',
params: { id: attrId },
});
if (res.code == 0) {
this.$message({
message: '删除成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getAttrList();
},
});
}
})
.catch(() => {});
},
// 提交属性表
async submitAttrForm() {
this.$refs['attrForm'].validate((valid) => {
if (!valid) {
return false;
}
});
const isEdit = this.attrForm.id != null;
this.attrFormSubmitting = true;
const res = await this.$axios({
url: isEdit ? this.sections[1].urlUpdate : this.sections[1].urlCreate,
method: isEdit ? 'put' : 'post',
data: {
...this.attrForm,
connectId: this.infoData.id
},
});
if (res.code == 0) {
this.closeAttrForm();
this.$message({
message: `${isEdit ? '更新' : '创建'}成功`,
type: 'success',
duration: 1500,
onClose: () => {
this.getAttrList();
},
});
}
this.attrFormSubmitting = false;
},
closeAttrForm() {
this.attrFormVisible = false;
},
handleClick(raw) {
if (raw.type === 'delete') {
this.$confirm(`确定删除该报警?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
deleteProductAttr(raw.data.id).then(({ data }) => {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getList();
},
});
});
})
.catch(() => {});
} else {
this.addNew(raw.data.id);
}
},
},
};
</script>
<style scoped>
.drawer >>> .el-drawer {
border-radius: 8px 0 0 8px;
}
.drawer >>> .el-drawer__header {
margin: 0;
padding: 32px 32px 24px;
border-bottom: 1px solid #dcdfe6;
margin-bottom: 0px;
}
.small-title::before {
content: '';
display: inline-block;
vertical-align: top;
width: 4px;
height: 22px;
border-radius: 1px;
margin-right: 8px;
background-color: #0b58ff;
}
.drawer-body {
display: flex;
flex-direction: column;
height: 100%;
}
.drawer-body__content {
flex: 1;
/* background: #eee; */
padding: 20px 30px;
overflow-y: auto;
}
.drawer-body__footer {
display: flex;
justify-content: flex-end;
padding: 18px;
}
</style>

Some files were not shown because too many files have changed in this diff Show More