Compare commits

..

24 Commits

Author SHA1 Message Date
zwq
4383067eb1 更新 2025-12-11 12:51:41 +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
0e1e813dc2 Merge pull request '更新班组' (#446) from projects/line-new-zwq into projects/line-new
Reviewed-on: #446
2025-10-30 13:39:06 +08:00
zwq
c9c8f82910 更新 2025-10-30 13:37:52 +08:00
d859ba62c8 Merge pull request '更新班组' (#446) from projects/line-new-zwq into projects/line-new
Reviewed-on: #446
2025-10-24 11:43:01 +08:00
zwq
31bafae4aa 更新班组 2025-10-24 11:42:24 +08:00
67b6b88863 Merge pull request 'projects/line-new-zhp' (#445) from projects/line-new-zhp into projects/line-new
Reviewed-on: #445
2025-10-24 11:21:24 +08:00
‘937886381’
9f3cdcb1c4 Merge branch 'projects/line-new' into projects/line-new-zhp 2025-10-24 11:20:40 +08:00
‘937886381’
f11dfe04d5 生产管理 2025-10-24 11:19:34 +08:00
428a0752eb Merge pull request '更新班组' (#444) from projects/line-new-zwq into projects/line-new
Reviewed-on: #444
2025-10-19 00:40:20 +08:00
zwq
4e801873b9 更新班组 2025-10-19 00:38:48 +08:00
‘937886381’
463706663a xiugai 2025-08-21 08:44:24 +08:00
‘937886381’
e8638687b1 xiugai 2025-07-08 10:36:47 +08:00
6c46083d4a Merge pull request '首页样式调整' (#441) from projects/line-new-zjl into projects/line-new
Reviewed-on: #441
2025-07-07 15:49:44 +08:00
ab486dd71b 首页样式调整 2025-07-07 15:49:00 +08:00
4da1e6f0b1 Merge pull request '首页样式' (#440) from projects/line-new-zjl into projects/line-new
Reviewed-on: #440
2025-07-04 17:03:31 +08:00
0b689b5452 首页样式 2025-07-04 17:02:20 +08:00
190 changed files with 22652 additions and 24759 deletions

View File

@@ -12,9 +12,8 @@ ENV = 'development'
VUE_APP_TITLE = 智能监控分析系统
# 芋道管理系统/开发环境
VUE_APP_BASE_API = 'http://172.16.32.79:48080'
# VUE_APP_BASE_API = 'http://line.kszny.picaiba.com'
# VUE_APP_BASE_API = 'http://192.168.8.22:48080'
VUE_APP_BASE_API = 'http://172.16.33.65:48082'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true
@@ -23,7 +22,7 @@ VUE_CLI_BABEL_TRANSPILE_MODULES = true
VUE_APP_TENANT_ENABLE = true
# 验证码的开关
VUE_APP_CAPTCHA_ENABLE = true
VUE_APP_CAPTCHA_ENABLE = true
# 文档的开关
VUE_APP_DOC_ENABLE = true

BIN
dist.rar

Binary file not shown.

View File

@@ -42,10 +42,12 @@
},
"dependencies": {
"@babel/parser": "7.18.4",
"@jiaminghi/data-view": "^2.10.0",
"@riophae/vue-treeselect": "0.4.0",
"axios": "0.27.2",
"benz-amr-recorder": "^1.1.5",
"bpmn-js-token-simulation": "0.10.0",
"chinese-lunar": "^0.1.4",
"clipboard": "2.0.8",
"code-brick-zj": "^1.0.2",
"core-js": "^3.26.0",

Binary file not shown.

View File

@@ -59,33 +59,3 @@ export function getEquipmentAll() {
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

@@ -25,10 +25,10 @@ export function getCT(data) {
// 获取产线平衡分析数据new
export function getNewCTNow(data) {
return request({
url: '/analysis/production-analysis/getNewCTNow',
method: 'post',
data: data
})
url: '/analysis/production-analysis/getNewCTNow',
method: 'post',
data: data,
});
}
// 获取产线平衡分析数据趋势图new
export function getNewCTCharts(data) {
@@ -40,9 +40,9 @@ export function getNewCTCharts(data) {
}
// 获取产线平衡分析数据设备listnew
export function getNewCTDet(data) {
return request({
return request({
url: '/analysis/production-analysis/getNewCTDet',
method: 'post',
data: data,
method: 'post',
data:data
});
}

View File

@@ -61,9 +61,9 @@ export function exportFactoryExcel(query) {
// 获取产线设备状态
export function getLineEqStatus(data) {
return request({
url: '/monitoring/equipment-monitor/getLineEqStatus',
method: 'post',
data: data,
});
url: '/base/production-line/getLineEqStatus',
method: 'post',
data: data
})
}

View File

@@ -5,40 +5,40 @@
* @LastEditors: zwq
* @Description:
*/
import request from '@/utils/request';
import request from '@/utils/request'
// 获得工厂分页
export function getPdlAutoReport(data) {
return request({
url: '/monitoring/production-monitor/getPdlAutoReport',
method: 'post',
data: data,
});
return request({
url: '/monitoring/production-monitor/getPdlAutoReport',
method: 'post',
data: data
})
}
// 获得所有工厂产线列表
export function getPdList(id) {
return request({
url: '/base/production-line/listAll' + (id ? '?id=' + id : ''),
method: 'get',
});
return request({
url: '/base/production-line/listAll' + (id ? '?id=' + id : ''),
method: 'get'
})
}
// 获得产线自动报表
export function getLineAuto(data) {
return request({
url: '/monitoring/production-monitor/getPdlAutoReportNew',
method: 'post',
data: data,
});
return request({
url: '/monitoring/production-monitor/getPdlAutoReportNew',
method: 'post',
data: data
})
}
// 获得产品自动报表
export function getProductAuto(data) {
return request({
url: '/monitoring/production-monitor/getProcessAutoReportNew',
method: 'post',
data: data,
});
return request({
url: '/monitoring/production-monitor/getProcessAutoReportNew',
method: 'post',
data: data
})
}
export function getPdlAutoReportNewSearchNow(data) {
@@ -50,42 +50,24 @@ 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) {
return request({
url: '/monitoring/group-off-record/page',
method: 'post',
data: data,
});
url: '/monitoring/team-auto-report/page',
method: 'post',
data: data
})
}
// 班组自动报表分页详细
export function getTeamReportPageDet(id) {
return request({
url: '/monitoring/group-off-record/get?id=' + id,
url: '/monitoring/team-auto-report/pageDet?id=' + id,
method: 'get',
})
}
export function exportGroupProductReportExcel(data) {
return request({
url: '/monitoring/group-off-record/export-det-excel',
method: 'get',
params: data,
responseType: 'blob',
});
}
// 获取产品当班数据
export function getProcessAutoReportGroup(data) {
return request({

View File

@@ -14,6 +14,7 @@ export function getSectionDataSearch(data) {
data: data
})
}
// 获取下片日志分页数据
export function getDownLogPage(data) {
return request({

153
src/api/group/Schedule.js Normal file
View File

@@ -0,0 +1,153 @@
import request from '@/utils/request'
// 删除排班计划配置基础信息
export function deleteGroupPlan(id) {
return request({
url: '/base/group-scheduling-plan/delete?id=' + id,
method: 'delete'
})
}
// 获得排班计划配置基础信息分页
export function getGroupPlanPage(query) {
return request({
url: '/base/group-scheduling-plan/page',
method: 'get',
params: query
})
}
// 获取code
export function getCode() {
return request({
url: '/base/group-scheduling-plan/getCode',
method: 'get'
})
}
// 获得产线工段树形结构
export function getGroupPlanTree() {
return request({
url: '/base/factory/getTreeSimple',
method: 'get'
})
}
// 基础信息下一步至班组班次
export function createStepOne(data) {
return request({
url: '/base/group-scheduling-plan/createStepOne',
method: 'post',
data:data
})
}
// 班组班次上一步至基础信息
export function returnStepOne(id) {
return request({
url: '/base/group-scheduling-plan/returnStepOne?id='+id,
method: 'delete',
})
}
// 获取部门下可用班组
export function listByDeptId(id) {
return request({
url: '/base/group-team/listByDeptId?id='+id,
method: 'get'
})
}
// 作废计划
export function disablePlan(id) {
return request({
url: '/base/group-scheduling-plan/disablePlan?id='+id,
method: 'delete',
})
}
// 同步节假日
export function updateScheduleLater(data) {
return request({
url: '/base/group-holiday/updateScheduleLater',
method: 'post',
data:data
})
}
// 复制计划
export function copyPlan(id) {
return request({
url: '/base/group-scheduling-plan/copyPlan?id='+id,
method: 'get'
})
}
// 列表草稿编辑
export function draftEditing(id) {
return request({
url: '/base/group-scheduling-plan/draftEditing?id='+id,
method: 'get'
})
}
// 排班计划-详情
export function getPlan(id) {
return request({
url: '/base/group-scheduling-plan/get?id='+id,
method: 'get'
})
}
// 弹窗-取消
export function cancelStepThree(id) {
return request({
url: '/base/group-scheduling-plan/cancelStepThree?id='+id,
method: 'delete',
})
}
// 第三步确认并执行 检查计划时间是否冲突,如果有,返回冲突的计划列表
export function checkPlan(data) {
return request({
url: '/base/group-scheduling-plan/checkPlan',
method: 'post',
data:data
})
}
// 第三步确认并执行 执行
export function createStepFour(id) {
return request({
url: '/base/group-scheduling-plan/createStepFour',
method: 'post',
data:id
})
}
// 班组班次下一步至获取预览
export function createStepTwo(data) {
return request({
url: '/base/group-scheduling-plan/createStepTwo',
method: 'post',
data:data
})
}
// 获取预览上一步至班组班次
export function returnStepTwo(id) {
return request({
url: '/base/group-scheduling-plan/returnStepTwo?id='+id,
method: 'delete',
})
}
// 第三步获取预览
export function getPerView(data) {
return request({
url: '/base/group-scheduling-plan/getPerView',
method: 'post',
data:data
})
}
// 导出 Excel
export function exportExcel(query) {
return request({
url: '/base/group-scheduling-plan/export-excel',
method: 'get',
params: query,
responseType: 'blob'
})
}

18
src/api/group/calendar.js Normal file
View File

@@ -0,0 +1,18 @@
import request from '@/utils/request'
// 获取部门及下级部门排班list
export function getDeptSchedulingList(data) {
return request({
url: '/base/group-team-scheduling/getDeptSchedulingList',
method: 'post',
data: data
})
}
// 某个班组的排班list
export function getClassSchedulingList(data) {
return request({
url: '/base/group-team-scheduling/getClassSchedulingList',
method: 'post',
data: data
})
}

View File

@@ -0,0 +1,54 @@
import request from '@/utils/request'
// 创建班组基础信息
export function createGroup(data) {
return request({
url: '/base/group-team/create',
method: 'post',
data: data
})
}
// 更新班组基础信息
export function updateGroup(data) {
return request({
url: '/base/group-team/update',
method: 'put',
data: data
})
}
// 获得班组基础信息
export function getGroup(id) {
return request({
url: '/base/group-team/get?id=' + id,
method: 'get'
})
}
// 检查更新-生产班组
export function updateIsProduction(id) {
return request({
url: '/base/group-team/updateIsProduction?id=' + id,
method: 'get'
})
}
// 获得班组基础信息分页
export function getGroupPage(query) {
return request({
url: '/base/group-team/page',
method: 'get',
params: query
})
}
// 获取班组code
export function getCode() {
return request({
url: '/base/group-team/getCode',
method: 'get'
})
}

View File

@@ -0,0 +1,118 @@
/*
* @Author: zwq
* @Date: 2025-10-18 21:24:37
* @LastEditors: zwq
* @LastEditTime: 2025-10-22 14:34:29
* @Description:
*/
import request from '@/utils/request'
// 获得节假日基础信息分页
export function deptHolidayPage(query) {
return request({
url: '/base/group-holiday/page',
method: 'get',
params: query
})
}
// 获得部门节假日信息
export function deptHolidayList(data) {
return request({
url: '/base/group-holiday/deptHolidayList',
method: 'post',
data: data
})
}
// 创建节假日基础信息
export function createHoliday(data) {
return request({
url: '/base/group-holiday/create',
method: 'post',
data: data
})
}
// 节假日操作后直接更新排班日历
export function updateSchedule(data) {
return request({
url: '/base/group-holiday/updateSchedule',
method: 'post',
data: data
})
}
// 更新节假日基础信息
export function updateHoliday(data) {
return request({
url: '/base/group-holiday/update',
method: 'put',
data: data
})
}
// 删除节假日基础信息前校验是否影响排班
export function checkDeleteHoliday(id) {
return request({
url: '/base/group-holiday/checkDelete?id=' + id,
method: 'delete'
})
}
// 删除
export function deleteHoliday(id) {
return request({
url: '/base/group-holiday/delete?id=' + id,
method: 'delete'
})
}
// 获得节假日基础信息
export function getHoliday(id) {
return request({
url: '/base/group-holiday/get?id=' + id,
method: 'get'
})
}
// 获得节假日变动日志分页
export function deptHolidayLogList(query) {
return request({
url: '/base/group-holiday-log/page',
method: 'get',
params: query
})
}
// 获得用户本人及以下的部门扁平化结构
export function getEnableData() {
return request({
url: '/base/group-team-scheduling/getEnableData',
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

@@ -1,56 +0,0 @@
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

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组备份</title>
<g id="秦皇岛/北方压延" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="现场看板tc—整体产线" transform="translate(-38.175000, -126.808988)">
<g id="编组备份" transform="translate(38.175000, 126.808988)">
<polygon id="Fill-1" fill="#CAE5DD" opacity="0" points="0 32 32 32 32 0 0 0"></polygon>
<path d="M24.1201333,5.07973333 L22.1468,5.07973333 L22.1468,6.3064 L24.1201333,6.3064 C24.7308,6.3064 25.2268,6.8024 25.2268,7.41306667 L25.2268,25.4530667 C25.2268,26.0650667 24.7308,26.5597333 24.1201333,26.5597333 L7.93346667,26.5597333 C7.32146667,26.5597333 6.8268,26.0650667 6.8268,25.4530667 L6.8268,7.41306667 C6.8268,6.8024 7.32146667,6.3064 7.93346667,6.3064 L10.2001333,6.3064 L10.2001333,5.07973333 L7.93346667,5.07973333 C6.64813333,5.08773333 5.6068,6.12773333 5.60013333,7.41306667 L5.60013333,25.4530667 C5.6068,26.7384 6.64813333,27.7797333 7.93346667,27.7864 L24.1334667,27.7864 C25.4188,27.7797333 26.4588,26.7384 26.4668,25.4530667 L26.4668,7.41306667 C26.4588,6.1224 25.4108,5.07973333 24.1201333,5.07973333" id="Fill-3" fill="#6EF9DE"></path>
<path d="M7.93333333,5.56026667 C6.90933333,5.56026667 6.08,6.3896 6.08,7.4136 L6.08,25.4536 C6.08,26.4776 6.90933333,27.3069333 7.93333333,27.3069333 L24.1333333,27.3069333 C25.156,27.3069333 25.9866667,26.4776 25.9866667,25.4536 L25.9866667,7.4136 C25.9866667,6.3896 25.156,5.56026667 24.1333333,5.56026667 L22.6,5.56026667 L22.6,5.78693333 L24.0933333,5.78693333 C24.9613333,5.78693333 25.6666667,6.49093333 25.6666667,7.36026667 L25.6666667,25.4002667 C25.6666667,26.2682667 24.9613333,26.9736 24.0933333,26.9736 L7.93333333,26.9736 C7.064,26.9736 6.36,26.2682667 6.36,25.4002667 L6.36,7.4136 C6.33066667,6.54426667 7.01066667,5.81626667 7.87866667,5.78693333 C7.89733333,5.78693333 7.91466667,5.78693333 7.93333333,5.78693333 L9.73333333,5.78693333 L9.73333333,5.50693333 L7.93333333,5.56026667 Z M24.8266667,28.2536 L7.21333333,28.2536 C6.05733333,28.2536 5.12,27.3162667 5.12,26.1602667 L5.12,6.70693333 C5.12,5.55093333 6.05733333,4.6136 7.21333333,4.6136 L10.6666667,4.6136 L10.6666667,6.78693333 L8.81333333,6.78693333 C7.97333333,6.78693333 7.29333333,7.46693333 7.29333333,8.30693333 L7.29333333,24.5602667 C7.29333333,25.3989333 7.97333333,26.0802667 8.81333333,26.0802667 L23.2266667,26.0802667 C24.0666667,26.0802667 24.7466667,25.3989333 24.7466667,24.5602667 L24.7466667,8.30693333 C24.7466667,7.46693333 24.0666667,6.78693333 23.2266667,6.78693333 L21.68,6.78693333 L21.68,4.6136 L24.8266667,4.6136 C25.9826667,4.6136 26.92,5.55093333 26.92,6.70693333 L26.92,26.1602667 C26.92,27.3162667 25.9826667,28.2536 24.8266667,28.2536 L24.8266667,28.2536 Z" id="Fill-5" fill="#6EF9DE"></path>
<path d="M11.3468,3.3864 L20.9068,3.3864 C21.7534667,3.3864 22.4401333,4.07306667 22.4401333,4.91973333 L22.4401333,6.1864 C22.4401333,7.03306667 21.7534667,7.71973333 20.9068,7.71973333 L11.3468,7.71973333 C10.5001333,7.71973333 9.81346667,7.03306667 9.81346667,6.1864 L9.81346667,4.91973333 C9.81346667,4.07306667 10.5001333,3.3864 11.3468,3.3864" id="Fill-7" fill="#6EF9DE"></path>
<path d="M21.7732,11.3864 C21.7732,12.0530667 21.5065333,12.3864 20.9598667,12.3864 L13.1065333,12.3864 C12.5732,12.3864 12.2932,12.0530667 12.2932,11.3864 C12.2932,10.7197333 12.5732,10.3997333 13.1065333,10.3997333 L20.9598667,10.3997333 C21.5065333,10.3997333 21.7732,10.7330667 21.7732,11.3864" id="Fill-9" fill="#6EF9E1"></path>
<path d="M10.2666667,10.4130667 L10.28,10.4130667 C10.824,10.4130667 11.2666667,10.8557333 11.2666667,11.3997333 L11.2666667,11.4130667 C11.2666667,11.9584 10.824,12.3997333 10.28,12.3997333 L10.2666667,12.3997333 C9.72133333,12.3997333 9.28,11.9584 9.28,11.4130667 L9.28,11.3997333 C9.28,10.8557333 9.72133333,10.4130667 10.2666667,10.4130667" id="Fill-11" fill="#6DF8E1"></path>
<path d="M21.7732,16.3597333 C21.7732,17.0264 21.3998667,17.3597333 20.6398667,17.3597333 L13.4398667,17.3597333 C12.6798667,17.3597333 12.2932,17.0264 12.2932,16.3597333 C12.2932,15.6930667 12.6798667,15.3597333 13.4398667,15.3597333 L20.6398667,15.3597333 C21.3998667,15.3597333 21.7732,15.6930667 21.7732,16.3597333" id="Fill-13" fill="#6EF9E1"></path>
<path d="M10.2666667,15.4130667 L10.28,15.4130667 C10.824,15.4130667 11.2666667,15.8557333 11.2666667,16.3997333 L11.2666667,16.4130667 C11.2666667,16.9584 10.824,17.3997333 10.28,17.3997333 L10.2666667,17.3997333 C9.72133333,17.3997333 9.28,16.9584 9.28,16.4130667 L9.28,16.3997333 C9.28,15.8557333 9.72133333,15.4130667 10.2666667,15.4130667" id="Fill-15" fill="#6DF8E1"></path>
<path d="M21.7732,21.3597333 C21.7732,22.0264 21.5065333,22.3597333 20.9598667,22.3597333 L13.1065333,22.3597333 C12.5732,22.3597333 12.2932,22.0264 12.2932,21.3597333 C12.2932,20.6930667 12.5732,20.3597333 13.1065333,20.3597333 L20.9598667,20.3597333 C21.5065333,20.3597333 21.7732,20.6930667 21.7732,21.3597333" id="Fill-17" fill="#6EF9E1"></path>
<path d="M10.2666667,20.3864 L10.28,20.3864 C10.824,20.3864 11.2666667,20.8290667 11.2666667,21.3730667 L11.2666667,21.3864 C11.2666667,21.9317333 10.824,22.3730667 10.28,22.3730667 L10.2666667,22.3730667 C9.72133333,22.3730667 9.28,21.9317333 9.28,21.3864 L9.28,21.3730667 C9.28,20.8290667 9.72133333,20.3864 10.2666667,20.3864" id="Fill-19" fill="#6DF8E1"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>切片</title>
<defs>
<linearGradient x1="100%" y1="81.9999999%" x2="20.318998%" y2="18.0000001%" id="linearGradient-1">
<stop stop-color="#4BFFC8" offset="0%"></stop>
<stop stop-color="#45F2EC" offset="100%"></stop>
</linearGradient>
</defs>
<g id="秦皇岛/北方压延" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="现场看板tc—整体产线" transform="translate(-35.000000, -741.000000)" fill-rule="nonzero">
<g id="icon/可视化/柱状图" transform="translate(35.000000, 741.000000)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="32" height="32"></rect>
<path d="M6.07816026,6.07816026 L6.07816026,23.4413798 L28.4022997,23.4413798 L28.4022997,25.9218397 L3.5977003,25.9218397 L3.5977003,6.07816026 L6.07816026,6.07816026 Z M13.5195401,6.07816026 L13.5195401,22.2011498 L8.55862018,22.2011498 L8.55862018,6.07816026 L13.5195401,6.07816026 Z M20.9609199,11.0390801 L20.9609199,22.2011498 L16,22.2011498 L16,11.0390801 L20.9609199,11.0390801 Z M28.4022997,16 L28.4022997,22.2011498 L23.4413798,22.2011498 L23.4413798,16 L28.4022997,16 Z" id="形状" fill="url(#linearGradient-1)"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="27px" height="32px" viewBox="0 0 27 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>产线备份 3</title>
<defs>
<linearGradient x1="100%" y1="84.4142661%" x2="20.318998%" y2="15.5857339%" id="linearGradient-1">
<stop stop-color="#4BFFC8" offset="0%"></stop>
<stop stop-color="#45F2EC" offset="100%"></stop>
</linearGradient>
</defs>
<g id="秦皇岛/北方压延" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="现场看板tc—整体产线" transform="translate(-456.000000, -740.000000)" fill-rule="nonzero">
<g id="产线备份-3" transform="translate(456.000000, 740.000000)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="27" height="32"></rect>
<path d="M5.9634842,21.3256682 C5.8209113,21.3358884 5.67787363,21.3358884 5.53530073,21.3256682 L5.53152795,21.3256682 C4.70985419,21.2655042 3.9028068,20.8665317 3.27496659,20.1284294 C1.90834447,18.5219016 1.90834447,15.9172034 3.27496659,14.3106756 C3.5291373,14.011848 3.81269745,13.7686207 4.11471142,13.5809616 L4.11389125,13.5765264 L4.1789034,13.5420735 C4.26583759,13.4907514 4.35456706,13.4437443 4.44485723,13.4011765 L16.0336968,7.2612301 L16.0353372,7.27016472 C18.3137697,6.10911436 21.061777,6.62333696 22.9243013,8.8128968 C25.3585662,11.6745456 25.3585662,16.314119 22.9243013,19.1757678 C21.7290674,20.580881 20.1691859,21.2960361 18.6027704,21.3212973 L18.6035632,21.3256682 L5.9634842,21.3256682 Z M5.625,20 C6.86761875,20 7.875,18.8061 7.875,17.3333333 C7.875,15.8605667 6.86761875,14.6666667 5.625,14.6666667 C4.382325,14.6666667 3.375,15.8605667 3.375,17.3333333 C3.375,18.8061 4.382325,20 5.625,20 Z M18.5625,18.6666667 C20.737088,18.6666667 22.5,16.5773202 22.5,14 C22.5,11.4226798 20.737088,9.33333333 18.5625,9.33333333 C16.3878602,9.33333333 14.625,11.4226798 14.625,14 C14.625,16.5773202 16.3878602,18.6666667 18.5625,18.6666667 Z M4.92857143,22.6666667 L22.5,22.6666667 L22.5,24.8888889 C22.5,25.1343611 22.3081339,25.3333333 22.0714286,25.3333333 L4.5,25.3333333 L4.5,23.1111111 C4.5,22.8656389 4.69186607,22.6666667 4.92857143,22.6666667 Z" id="形状" fill="url(#linearGradient-1)"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>切片</title>
<defs>
<linearGradient x1="99.4683184%" y1="100%" x2="20.6346149%" y2="7.84095011e-14%" id="linearGradient-1">
<stop stop-color="#4BFFC8" offset="0%"></stop>
<stop stop-color="#45F2EC" offset="100%"></stop>
</linearGradient>
</defs>
<g id="秦皇岛/北方压延" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="现场看板tc—整体产线" transform="translate(-1514.000000, -127.000000)" fill-rule="nonzero">
<g id="icon/可视化/模块" transform="translate(1514.000000, 127.000000)">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="7.10542736e-14" width="32" height="32"></rect>
<path d="M25.7527221,14.1816202 L24.188579,14.1816202 L24.188579,9.49373791 C24.1860753,8.90287145 23.7063759,8.4252046 23.1155041,8.42520991 L17.3681876,8.42520991 L17.3681876,6.56551655 C17.370851,5.66122185 17.0084214,4.79412914 16.363022,4.1607133 C15.7176226,3.52729745 14.8438903,3.18118084 13.9398043,3.20079015 C12.066652,3.28658042 10.6006443,4.84522051 10.629641,6.72011209 L10.629641,8.42520991 L4.88232453,8.42520991 C4.29145277,8.4252046 3.81175331,8.90287145 3.80921104,9.49373791 L3.80921104,13.0994515 C3.80682438,13.385621 3.9188086,13.6609038 4.12031265,13.8641155 C4.32181669,14.0673272 4.59614473,14.1816305 4.88232453,14.1816202 L5.48251897,14.1816202 C7.35572581,14.1525356 8.91367406,15.6158797 9.00184091,17.4872366 C9.01900932,18.3913465 8.67055578,19.2641187 8.03543236,19.9078018 C7.40030895,20.5514848 6.53227944,20.9115903 5.62802066,20.9065261 L4.88232453,20.9065261 C4.28968163,20.9065261 3.80921104,21.3869581 3.80921104,21.979601 L3.80921104,27.7269175 C3.80921104,28.3195604 4.28968163,28.8000021 4.88232453,28.8000021 L9.55656609,28.8000021 C9.84153405,28.8012076 10.1151815,28.6885421 10.3166861,28.4870375 C10.5181907,28.2855329 10.6308562,28.0118854 10.629641,27.7269175 L10.629641,27.1949269 C10.6006443,25.3200353 12.066652,23.7613953 13.9398043,23.675605 C14.8438903,23.6559957 15.7176226,24.0021123 16.363022,24.6355281 C17.0084214,25.268944 17.370851,26.1360367 17.3681876,27.0403314 L17.3681876,27.7269175 C17.3669784,28.0110957 17.479021,28.2840495 17.6795401,28.4854219 C17.8800592,28.6867943 18.1525348,28.8000021 18.4367156,28.8000021 L23.1155041,28.8000021 C23.708147,28.8000021 24.188579,28.3195604 24.188579,27.7269175 L24.188579,20.9065261 L25.9027707,20.9065261 C26.8070472,20.910389 27.6746078,20.5491212 28.3088772,19.9045802 C28.9431467,19.2600392 29.290432,18.3867874 29.272044,17.4826896 C29.1815049,15.6131286 27.6242468,14.1524446 25.7527221,14.1816202 Z" id="路径" fill="url(#linearGradient-1)"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="22px" height="22px" viewBox="0 0 22 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="驾驶舱" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="运营总览_生产线监控驾驶舱" transform="translate(-1866.000000, -36.000000)">
<g id="编组-54" transform="translate(1866.000000, 36.000000)">
<rect id="矩形" stroke="#979797" fill="#D8D8D8" opacity="0" x="0.5" y="0.5" width="21" height="21"></rect>
<path d="M18.4001211,1 L18.574731,1.00571398 C18.8641421,1.02474925 19.1451559,1.09128771 19.4122178,1.20447947 C19.7221027,1.33395436 19.9991094,1.52058631 20.2392616,1.76073844 C20.4776764,1.99915325 20.6652172,2.27804627 20.7953442,2.58736464 C20.9313506,2.90825642 21,3.24882158 21,3.59987893 L21,3.59987893 L21,18.4001211 L20.994286,18.574731 C20.9752507,18.8641421 20.9087123,19.1451559 20.7955205,19.4122178 C20.6660456,19.7221027 20.4794137,19.9991094 20.2392616,20.2392616 C20.0008468,20.4776764 19.7219537,20.6652172 19.4126354,20.7953442 C19.0917436,20.9313506 18.7511784,21 18.4001211,21 L18.4001211,21 L3.59987893,21 L3.42526905,20.994286 C3.13585794,20.9752507 2.85484405,20.9087123 2.58778224,20.7955205 C2.2778973,20.6660456 2.00089057,20.4794137 1.76073844,20.2392616 C1.52232363,20.0008468 1.33478285,19.7219537 1.20465581,19.4126354 C1.06864936,19.0917436 1,18.7511784 1,18.4001211 L1,18.4001211 L1,3.59987893 L1.00571398,3.42526905 C1.02474925,3.13585794 1.09128771,2.85484405 1.20447947,2.58778224 C1.33395436,2.2778973 1.52058631,2.00089057 1.76073844,1.76073844 C1.99915325,1.52232363 2.27804627,1.33478285 2.58736464,1.20465581 C2.90825642,1.06864936 3.24882158,1 3.59987893,1 L3.59987893,1 L18.4001211,1 Z M18.4001211,2.29539952 L3.59987893,2.29539952 L3.49797651,2.2993263 C2.82542992,2.35136056 2.29539952,2.9140495 2.29539952,3.59987893 L2.29539952,3.59987893 L2.29539952,18.4001211 L2.2993263,18.5020235 C2.35136056,19.1745701 2.9140495,19.7046005 3.59987893,19.7046005 L3.59987893,19.7046005 L18.4001211,19.7046005 L18.5020235,19.7006737 C19.1745701,19.6486394 19.7046005,19.0859505 19.7046005,18.4001211 L19.7046005,18.4001211 L19.7046005,3.59987893 L19.7006737,3.49797651 C19.6486394,2.82542992 19.0859505,2.29539952 18.4001211,2.29539952 L18.4001211,2.29539952 Z M4.56580299,11.8731508 L4.63987359,11.8789244 C4.95620444,11.9219442 5.20096852,12.1943435 5.20096852,12.5208838 L5.20096852,12.5208838 L5.20096852,15.8606113 L8.39814764,12.6634321 L8.45892035,12.6098356 C8.71226443,12.4133149 9.08161636,12.4311804 9.3138681,12.6634321 C9.56547415,12.9150382 9.56547415,13.3275466 9.3138681,13.5791526 L9.3138681,13.5791526 L6.09149511,16.7990315 L9.4155569,16.7990315 L9.49368756,16.8035151 C9.82695229,16.8420028 10.0864105,17.123441 10.081435,17.4601165 C10.0742517,17.8119637 9.78624591,18.094431 9.43371671,18.094431 L9.43371671,18.094431 L4.5691586,18.094431 L4.49163938,18.0899766 C4.16113157,18.051728 3.90556901,17.7718105 3.90556901,17.4308414 L3.90556901,17.4308414 L3.90556901,12.5367736 L3.91007171,12.4587841 C3.94871707,12.1260764 4.23118526,11.8665247 4.56580299,11.8731508 L4.56580299,11.8731508 Z M17.4353814,3.90556901 L17.512257,3.91000958 C17.8400885,3.94813523 18.094431,4.22707005 18.094431,4.56461864 L18.094431,4.56461864 L18.094431,9.46095642 L18.0899283,9.53894589 C18.0512829,9.87165361 17.7688147,10.1312053 17.434197,10.1245792 C17.0828999,10.1173731 16.7990315,9.82850504 16.7990315,9.47684625 L16.7990315,9.47684625 L16.7990315,6.13938874 L13.6018524,9.33656786 L13.5410796,9.39016441 C13.2877356,9.58668512 12.9183836,9.5688196 12.6861319,9.33656786 C12.4345258,9.08496181 12.4345258,8.67245345 12.6861319,8.4208474 L12.6861319,8.4208474 L15.9060108,5.20096852 L12.5821731,5.20096852 L12.5040246,5.19648608 C12.170734,5.1580095 11.9119308,4.876675 11.9185506,4.54071802 C11.9257483,4.18803625 12.2137541,3.90556901 12.5662833,3.90556901 L12.5662833,3.90556901 L17.4353814,3.90556901 Z" id="形状结合" fill="#52FFF1" fill-rule="nonzero" opacity="0.79078311"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -1 +1,18 @@
<svg width="128" height="128" xmlns="http://www.w3.org/2000/svg"><path d="M38.47 52L52 38.462l-23.648-23.67L43.209 0H.035L0 43.137l14.757-14.865L38.47 52zm74.773 47.726L89.526 76 76 89.536l23.648 23.672L84.795 128h43.174L128 84.863l-14.757 14.863zM89.538 52l23.668-23.648L128 43.207V.038L84.866 0 99.73 14.76 76 38.472 89.538 52zM38.46 76L14.792 99.651 0 84.794v43.173l43.137.033-14.865-14.757L52 89.53 38.46 76z"/></svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>全屏</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="首页" transform="translate(-1865.000000, -106.000000)" fill="#0B58FF">
<g id="全屏" transform="translate(1865.000000, 106.000000)">
<g>
<rect id="矩形" stroke="#0B58FF" opacity="0" x="0.5" y="0.5" width="31" height="31"></rect>
<path d="M27.3264942,0.842105263 L27.583814,0.850525866 C28.0103146,0.878577843 28.4244403,0.976634518 28.8180051,1.14344343 C29.2746777,1.33424853 29.6828981,1.60928508 30.0368065,1.96319349 C30.3881547,2.31454163 30.6645305,2.72554187 30.8562967,3.18137947 C31.0567273,3.65427262 31.1578947,4.15615812 31.1578947,4.6735058 L31.1578947,26.4843889 L31.1494741,26.7417088 C31.1214222,27.1682093 31.0233655,27.5823351 30.8565566,27.9758999 C30.6657515,28.4325724 30.3907149,28.8407928 30.0368065,29.1947013 C29.6854584,29.5460494 29.2744581,29.8224253 28.8186205,30.0141914 C28.3457274,30.214622 27.8438419,30.3157895 27.3264942,30.3157895 L5.51561106,30.3157895 L5.25829123,30.3073689 C4.83179065,30.2793169 4.41766492,30.1812602 4.02410014,30.0144513 C3.5674276,29.8236462 3.15920715,29.5486097 2.80529875,29.1947013 C2.45395061,28.8433531 2.17757472,28.4323529 1.98580856,27.9765153 C1.785378,27.5036221 1.68421053,27.0017366 1.68421053,26.4843889 L1.68421053,4.6735058 L1.69263113,4.41618596 C1.72068311,3.98968539 1.81873978,3.57555966 1.98554869,3.18199488 C2.17635379,2.72532234 2.45139035,2.31710189 2.80529875,1.96319349 C3.15664689,1.61184534 3.56764713,1.33546946 4.02348473,1.1437033 C4.49637788,0.943272735 4.99826338,0.842105263 5.51561106,0.842105263 L27.3264942,0.842105263 Z M27.3264942,2.75111508 L5.51561106,2.75111508 L5.36543907,2.75690192 C4.37431777,2.83358398 3.59322034,3.6628098 3.59322034,4.6735058 L3.59322034,26.4843889 L3.59900719,26.6345609 C3.67568924,27.6256822 4.50491506,28.4067797 5.51561106,28.4067797 L27.3264942,28.4067797 L27.4766662,28.4009928 C28.4677875,28.3243108 29.2488849,27.4950849 29.2488849,26.4843889 L29.2488849,4.6735058 L29.2430981,4.52333381 C29.166416,3.53221251 28.3371902,2.75111508 27.3264942,2.75111508 Z M6.93907808,16.8656959 L7.04823476,16.8742044 C7.51440654,16.9376019 7.87511151,17.3390325 7.87511151,17.8202498 L7.87511151,22.7419534 L12.5867439,18.0303211 L12.6763037,17.9513367 C13.0496528,17.6617272 13.593961,17.6880553 13.9362267,18.0303211 C14.3070145,18.4011089 14.3070145,19.009016 13.9362267,19.3798038 L9.18746648,24.1248885 L14.0860839,24.1248885 L14.2012238,24.1314959 C14.6923507,24.1882147 15.0747102,24.6029657 15.0673779,25.0991191 C15.056792,25.6176308 14.6323624,26.0338983 14.1128457,26.0338983 L6.94402319,26.0338983 L6.82978436,26.0273339 C6.34272021,25.9709676 5.96610169,25.5584576 5.96610169,25.0559768 L5.96610169,17.8436664 L5.97273726,17.7287345 C6.02968832,17.2384284 6.44595722,16.8559311 6.93907808,16.8656959 Z M25.9047725,5.12399643 L26.0180629,5.13054044 C26.501183,5.1867256 26.8760036,5.59778744 26.8760036,6.09522748 L26.8760036,13.3108831 L26.869368,13.425815 C26.8124169,13.9161211 26.396148,14.2986184 25.9030272,14.2888536 C25.3853261,14.278234 24.9669938,13.8525337 24.9669938,13.3342997 L24.9669938,8.4159413 L20.2553614,13.1275737 L20.1658016,13.2065581 C19.7924524,13.4961675 19.2481443,13.4698394 18.9058786,13.1275737 C18.5350907,12.7567858 18.5350907,12.1488788 18.9058786,11.7780909 L23.6509632,7.03300624 L18.7526762,7.03300624 L18.6375099,7.02640054 C18.1463449,6.96969821 17.7649507,6.5551 17.7747062,6.0600055 C17.7853132,5.54026395 18.2097429,5.12399643 18.7292596,5.12399643 L25.9047725,5.12399643 Z" id="形状结合" fill-rule="nonzero" opacity="0.79078311"></path>
</g>
<g>
<rect id="矩形" stroke="#0B58FF" opacity="0" x="0.5" y="0.5" width="31" height="31"></rect>
<path d="M27.3264942,0.842105263 L27.583814,0.850525866 C28.0103146,0.878577843 28.4244403,0.976634518 28.8180051,1.14344343 C29.2746777,1.33424853 29.6828981,1.60928508 30.0368065,1.96319349 C30.3881547,2.31454163 30.6645305,2.72554187 30.8562967,3.18137947 C31.0567273,3.65427262 31.1578947,4.15615812 31.1578947,4.6735058 L31.1578947,26.4843889 L31.1494741,26.7417088 C31.1214222,27.1682093 31.0233655,27.5823351 30.8565566,27.9758999 C30.6657515,28.4325724 30.3907149,28.8407928 30.0368065,29.1947013 C29.6854584,29.5460494 29.2744581,29.8224253 28.8186205,30.0141914 C28.3457274,30.214622 27.8438419,30.3157895 27.3264942,30.3157895 L5.51561106,30.3157895 L5.25829123,30.3073689 C4.83179065,30.2793169 4.41766492,30.1812602 4.02410014,30.0144513 C3.5674276,29.8236462 3.15920715,29.5486097 2.80529875,29.1947013 C2.45395061,28.8433531 2.17757472,28.4323529 1.98580856,27.9765153 C1.785378,27.5036221 1.68421053,27.0017366 1.68421053,26.4843889 L1.68421053,4.6735058 L1.69263113,4.41618596 C1.72068311,3.98968539 1.81873978,3.57555966 1.98554869,3.18199488 C2.17635379,2.72532234 2.45139035,2.31710189 2.80529875,1.96319349 C3.15664689,1.61184534 3.56764713,1.33546946 4.02348473,1.1437033 C4.49637788,0.943272735 4.99826338,0.842105263 5.51561106,0.842105263 L27.3264942,0.842105263 Z M27.3264942,2.75111508 L5.51561106,2.75111508 L5.36543907,2.75690192 C4.37431777,2.83358398 3.59322034,3.6628098 3.59322034,4.6735058 L3.59322034,26.4843889 L3.59900719,26.6345609 C3.67568924,27.6256822 4.50491506,28.4067797 5.51561106,28.4067797 L27.3264942,28.4067797 L27.4766662,28.4009928 C28.4677875,28.3243108 29.2488849,27.4950849 29.2488849,26.4843889 L29.2488849,4.6735058 L29.2430981,4.52333381 C29.166416,3.53221251 28.3371902,2.75111508 27.3264942,2.75111508 Z M6.93907808,16.8656959 L7.04823476,16.8742044 C7.51440654,16.9376019 7.87511151,17.3390325 7.87511151,17.8202498 L7.87511151,22.7419534 L12.5867439,18.0303211 L12.6763037,17.9513367 C13.0496528,17.6617272 13.593961,17.6880553 13.9362267,18.0303211 C14.3070145,18.4011089 14.3070145,19.009016 13.9362267,19.3798038 L9.18746648,24.1248885 L14.0860839,24.1248885 L14.2012238,24.1314959 C14.6923507,24.1882147 15.0747102,24.6029657 15.0673779,25.0991191 C15.056792,25.6176308 14.6323624,26.0338983 14.1128457,26.0338983 L6.94402319,26.0338983 L6.82978436,26.0273339 C6.34272021,25.9709676 5.96610169,25.5584576 5.96610169,25.0559768 L5.96610169,17.8436664 L5.97273726,17.7287345 C6.02968832,17.2384284 6.44595722,16.8559311 6.93907808,16.8656959 Z M25.9047725,5.12399643 L26.0180629,5.13054044 C26.501183,5.1867256 26.8760036,5.59778744 26.8760036,6.09522748 L26.8760036,13.3108831 L26.869368,13.425815 C26.8124169,13.9161211 26.396148,14.2986184 25.9030272,14.2888536 C25.3853261,14.278234 24.9669938,13.8525337 24.9669938,13.3342997 L24.9669938,8.4159413 L20.2553614,13.1275737 L20.1658016,13.2065581 C19.7924524,13.4961675 19.2481443,13.4698394 18.9058786,13.1275737 C18.5350907,12.7567858 18.5350907,12.1488788 18.9058786,11.7780909 L23.6509632,7.03300624 L18.7526762,7.03300624 L18.6375099,7.02640054 C18.1463449,6.96969821 17.7649507,6.5551 17.7747062,6.0600055 C17.7853132,5.54026395 18.2097429,5.12399643 18.7292596,5.12399643 L25.9047725,5.12399643 Z" id="形状结合" fill-rule="nonzero" opacity="0.79078311"></path>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 421 B

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>更新</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="首页" transform="translate(-474.000000, -116.000000)" fill="#0B58FF" fill-rule="nonzero">
<g id="更新" transform="translate(474.000000, 116.000000)">
<rect id="矩形" opacity="0" x="0" y="0" width="16" height="16"></rect>
<path d="M14.9793977,2.67910156 L13.9879914,3.45429687 C12.6362336,1.72636719 10.5338899,0.6171875 8.17314768,0.6171875 C4.09678049,0.6171875 0.797366431,3.91308594 0.792086694,7.99121094 C0.786819556,12.0728516 4.09326487,15.3828125 8.17314768,15.3828125 C11.3600617,15.3828125 14.0758821,13.3613281 15.1094758,10.5294922 C15.135843,10.4556641 15.0971711,10.3730469 15.023343,10.3484375 L14.0266633,10.0056641 C13.954593,9.98105469 13.8754914,10.0179688 13.8491242,10.0900391 C13.8174836,10.1779297 13.7823274,10.2658203 13.7454133,10.3519531 C13.4413117,11.0726562 13.0053742,11.7195312 12.4499055,12.275 C11.8944367,12.8304687 11.2475617,13.2664062 10.5286164,13.5722656 C9.78506174,13.8869141 8.99228831,14.046875 8.17666331,14.046875 C7.35928049,14.046875 6.56826487,13.8869141 5.82471018,13.5722656 C5.10576487,13.2681641 4.45888987,12.8322266 3.90342112,12.275 C3.34795237,11.7195312 2.91201487,11.0726562 2.60791331,10.3519531 C2.29326487,9.60664063 2.13330393,8.815625 2.13330393,7.99824219 C2.13330393,7.18085937 2.29326487,6.38984375 2.60791331,5.64453125 C2.91201487,4.92382812 3.34795237,4.27695312 3.90342112,3.72148438 C4.45888987,3.16601563 5.10576487,2.73007813 5.82471018,2.42421875 C6.56826487,2.10957031 7.36103831,1.94960938 8.17666331,1.94960938 C8.99404612,1.94960938 9.78506174,2.10957031 10.5286164,2.42421875 C11.2475617,2.72832031 11.8944367,3.16425781 12.4499055,3.72148438 C12.6239289,3.89550781 12.7874055,4.08007812 12.9385774,4.2734375 L11.8803742,5.09960938 C11.7872102,5.17167969 11.8188508,5.31933594 11.9331086,5.34746094 L15.0198274,6.10332031 C15.107718,6.12441406 15.1938508,6.05761719 15.1938508,5.96796875 L15.2079133,2.78808594 C15.2061555,2.67207031 15.0708039,2.60703125 14.9793977,2.67910156 L14.9793977,2.67910156 Z" id="路径" stroke="#0B58FF" stroke-width="0.5"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="22px" height="22px" viewBox="0 0 22 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="驾驶舱" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组-54备份">
<rect id="矩形" stroke="#979797" fill="#D8D8D8" opacity="0" x="0.5" y="0.5" width="21" height="21"></rect>
<path d="M18.4001211,1 L18.574731,1.00571398 C18.8641421,1.02474925 19.1451559,1.09128771 19.4122178,1.20447947 C19.7221027,1.33395436 19.9991094,1.52058631 20.2392616,1.76073844 C20.4776764,1.99915325 20.6652172,2.27804627 20.7953442,2.58736464 C20.9313506,2.90825642 21,3.24882158 21,3.59987893 L21,3.59987893 L21,18.4001211 L20.994286,18.574731 C20.9752507,18.8641421 20.9087123,19.1451559 20.7955205,19.4122178 C20.6660456,19.7221027 20.4794137,19.9991094 20.2392616,20.2392616 C20.0008468,20.4776764 19.7219537,20.6652172 19.4126354,20.7953442 C19.0917436,20.9313506 18.7511784,21 18.4001211,21 L18.4001211,21 L3.59987893,21 L3.42526905,20.994286 C3.13585794,20.9752507 2.85484405,20.9087123 2.58778224,20.7955205 C2.2778973,20.6660456 2.00089057,20.4794137 1.76073844,20.2392616 C1.52232363,20.0008468 1.33478285,19.7219537 1.20465581,19.4126354 C1.06864936,19.0917436 1,18.7511784 1,18.4001211 L1,18.4001211 L1,3.59987893 L1.00571398,3.42526905 C1.02474925,3.13585794 1.09128771,2.85484405 1.20447947,2.58778224 C1.33395436,2.2778973 1.52058631,2.00089057 1.76073844,1.76073844 C1.99915325,1.52232363 2.27804627,1.33478285 2.58736464,1.20465581 C2.90825642,1.06864936 3.24882158,1 3.59987893,1 L3.59987893,1 L18.4001211,1 Z M18.4001211,2.29539952 L3.59987893,2.29539952 L3.49797651,2.2993263 C2.82542992,2.35136056 2.29539952,2.9140495 2.29539952,3.59987893 L2.29539952,3.59987893 L2.29539952,18.4001211 L2.2993263,18.5020235 C2.35136056,19.1745701 2.9140495,19.7046005 3.59987893,19.7046005 L3.59987893,19.7046005 L18.4001211,19.7046005 L18.5020235,19.7006737 C19.1745701,19.6486394 19.7046005,19.0859505 19.7046005,18.4001211 L19.7046005,18.4001211 L19.7046005,3.59987893 L19.7006737,3.49797651 C19.6486394,2.82542992 19.0859505,2.29539952 18.4001211,2.29539952 L18.4001211,2.29539952 Z M9.43538136,11.905569 L9.512257,11.9100096 C9.84008849,11.9481352 10.094431,12.2270701 10.094431,12.5646186 L10.094431,12.5646186 L10.094431,17.4609564 L10.0899283,17.5389459 C10.0512829,17.8716536 9.76881474,18.1312053 9.43419701,18.1245792 C9.08289988,18.1173731 8.79903148,17.828505 8.79903148,17.4768462 L8.79903148,17.4768462 L8.79903148,14.1393887 L5.60185236,17.3365679 L5.54107965,17.3901644 C5.28773557,17.5866851 4.91838364,17.5688196 4.6861319,17.3365679 C4.43452585,17.0849618 4.43452585,16.6724534 4.6861319,16.4208474 L4.6861319,16.4208474 L7.90601077,13.2009685 L4.58217312,13.2009685 L4.50402457,13.1964861 C4.17073404,13.1580095 3.9119308,12.876675 3.91855064,12.540718 C3.92574827,12.1880363 4.21375409,11.905569 4.56628329,11.905569 L4.56628329,11.905569 L9.43538136,11.905569 Z M12.565803,3.8731508 L12.6398736,3.87892442 C12.9562044,3.92194416 13.2009685,4.19434347 13.2009685,4.52088378 L13.2009685,4.52088378 L13.2009685,7.86061126 L16.3981476,4.66343214 L16.4589204,4.60983559 C16.7122644,4.41331488 17.0816164,4.4311804 17.3138681,4.66343214 C17.5654742,4.91503819 17.5654742,5.32754655 17.3138681,5.5791526 L17.3138681,5.5791526 L14.0914951,8.79903148 L17.4155569,8.79903148 L17.4936876,8.80351509 C17.8269523,8.84200281 18.0864105,9.12344101 18.081435,9.46011654 C18.0742517,9.81196375 17.7862459,10.094431 17.4337167,10.094431 L17.4337167,10.094431 L12.5691586,10.094431 L12.4916394,10.0899766 C12.1611316,10.051728 11.905569,9.77181051 11.905569,9.4308414 L11.905569,9.4308414 L11.905569,4.53677361 L11.9100717,4.45878413 C11.9487171,4.12607641 12.2311853,3.86652471 12.565803,3.8731508 L12.565803,3.8731508 Z" id="形状结合" fill="#52FFF1" fill-rule="nonzero" opacity="0.79078311"></path>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>推出全屏</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="首页" transform="translate(-1815.000000, -103.000000)" fill="#0B58FF">
<g id="推出全屏" transform="translate(1815.000000, 103.000000)">
<g id="全屏">
<rect id="矩形" stroke="#0B58FF" opacity="0" x="0.5" y="0.5" width="31" height="31"></rect>
<path d="M26.7638125,1.45454545 L27.0177905,1.4628567 C27.4387521,1.49054436 27.8474996,1.58732758 28.2359531,1.75197014 C28.6866948,1.94029725 29.0896137,2.2117619 29.4389259,2.56107409 C29.7857111,2.90785927 30.0584977,3.31352185 30.2477734,3.76343947 C30.4456009,4.23019115 30.5454545,4.72555866 30.5454545,5.23618754 L30.5454545,26.7638125 L30.5371433,27.0177905 C30.5094556,27.4387521 30.4126724,27.8474996 30.2480299,28.2359531 C30.0597028,28.6866948 29.7882381,29.0896137 29.4389259,29.4389259 C29.0921407,29.7857111 28.6864782,30.0584977 28.2365605,30.2477734 C27.7698088,30.4456009 27.2744413,30.5454545 26.7638125,30.5454545 L5.23618754,30.5454545 L4.98220952,30.5371433 C4.56124792,30.5094556 4.15250044,30.4126724 3.7640469,30.2480299 C3.31330516,30.0597028 2.91038628,29.7882381 2.56107409,29.4389259 C2.21428891,29.0921407 1.94150232,28.6864782 1.75222663,28.2365605 C1.55439906,27.7698088 1.45454545,27.2744413 1.45454545,26.7638125 L1.45454545,5.23618754 L1.4628567,4.98220952 C1.49054436,4.56124792 1.58732758,4.15250044 1.75197014,3.7640469 C1.94029725,3.31330516 2.2117619,2.91038628 2.56107409,2.56107409 C2.90785927,2.21428891 3.31352185,1.94150232 3.76343947,1.75222663 C4.23019115,1.55439906 4.72555866,1.45454545 5.23618754,1.45454545 L26.7638125,1.45454545 Z M26.7638125,3.33876293 L5.23618754,3.33876293 L5.08796584,3.34447462 C4.10971624,3.42016081 3.33876293,4.23861746 3.33876293,5.23618754 L3.33876293,26.7638125 L3.34447462,26.9120342 C3.42016081,27.8902838 4.23861746,28.6612371 5.23618754,28.6612371 L26.7638125,28.6612371 L26.9120342,28.6555254 C27.8902838,28.5798392 28.6612371,27.7613825 28.6612371,26.7638125 L28.6612371,5.23618754 L28.6555254,5.08796584 C28.5798392,4.10971624 27.7613825,3.33876293 26.7638125,3.33876293 Z M13.6987866,17.269857 L13.8115418,17.2763362 C14.2922804,17.3319705 14.6640078,17.7391232 14.6640078,18.2350783 L14.6640078,25.3537223 L14.6574584,25.4671616 C14.6012469,25.9511001 14.1903841,26.3286298 13.7036674,26.3189919 L13.5959284,26.3105939 C13.1358108,26.2480197 12.7797903,25.8518025 12.7797903,25.3768348 L12.7797903,20.5190494 L8.12934794,25.1694917 L8.04095127,25.2474504 C7.67245079,25.5332987 7.13521162,25.5073124 6.79739091,25.1694917 C6.43141847,24.8035193 6.43141847,24.2035071 6.79739091,23.8375347 L11.4844789,19.1540745 L6.64947993,19.1540745 L6.53583534,19.1475529 C6.05108664,19.0915708 5.67369292,18.6822061 5.68093001,18.1924962 C5.69137836,17.6807185 6.11029591,17.269857 6.62306566,17.269857 L13.6987866,17.269857 Z M18.2962333,5.68100813 C18.807211,5.69148979 19.2201105,6.11166149 19.2201105,6.62316519 L19.2201105,11.4776488 L23.8705528,6.82720649 L23.9589495,6.74924786 C24.32745,6.46339956 24.8646892,6.48938577 25.2025099,6.82720649 C25.5684823,7.19317893 25.5684823,7.79319108 25.2025099,8.15916352 L20.5190497,12.8426237 L25.3537226,12.8426237 L25.4673933,12.8491436 C25.9521795,12.9051095 26.3286206,13.3143234 26.3189917,13.8029881 C26.3085224,14.3159797 25.8896049,14.7268412 25.3768351,14.7268412 L18.2945107,14.7268412 L18.1826915,14.7203822 C17.7058457,14.6649267 17.335893,14.2592033 17.335893,13.7682235 L17.335893,6.64627767 L17.3424424,6.53283844 C17.3986538,6.04889994 17.8095166,5.67137018 18.2962333,5.68100813 Z" id="形状结合" fill-rule="nonzero" opacity="0.79078311"></path>
</g>
<g id="全屏">
<rect id="矩形" stroke="#0B58FF" opacity="0" x="0.5" y="0.5" width="31" height="31"></rect>
<path d="M26.7638125,1.45454545 L27.0177905,1.4628567 C27.4387521,1.49054436 27.8474996,1.58732758 28.2359531,1.75197014 C28.6866948,1.94029725 29.0896137,2.2117619 29.4389259,2.56107409 C29.7857111,2.90785927 30.0584977,3.31352185 30.2477734,3.76343947 C30.4456009,4.23019115 30.5454545,4.72555866 30.5454545,5.23618754 L30.5454545,26.7638125 L30.5371433,27.0177905 C30.5094556,27.4387521 30.4126724,27.8474996 30.2480299,28.2359531 C30.0597028,28.6866948 29.7882381,29.0896137 29.4389259,29.4389259 C29.0921407,29.7857111 28.6864782,30.0584977 28.2365605,30.2477734 C27.7698088,30.4456009 27.2744413,30.5454545 26.7638125,30.5454545 L5.23618754,30.5454545 L4.98220952,30.5371433 C4.56124792,30.5094556 4.15250044,30.4126724 3.7640469,30.2480299 C3.31330516,30.0597028 2.91038628,29.7882381 2.56107409,29.4389259 C2.21428891,29.0921407 1.94150232,28.6864782 1.75222663,28.2365605 C1.55439906,27.7698088 1.45454545,27.2744413 1.45454545,26.7638125 L1.45454545,5.23618754 L1.4628567,4.98220952 C1.49054436,4.56124792 1.58732758,4.15250044 1.75197014,3.7640469 C1.94029725,3.31330516 2.2117619,2.91038628 2.56107409,2.56107409 C2.90785927,2.21428891 3.31352185,1.94150232 3.76343947,1.75222663 C4.23019115,1.55439906 4.72555866,1.45454545 5.23618754,1.45454545 L26.7638125,1.45454545 Z M26.7638125,3.33876293 L5.23618754,3.33876293 L5.08796584,3.34447462 C4.10971624,3.42016081 3.33876293,4.23861746 3.33876293,5.23618754 L3.33876293,26.7638125 L3.34447462,26.9120342 C3.42016081,27.8902838 4.23861746,28.6612371 5.23618754,28.6612371 L26.7638125,28.6612371 L26.9120342,28.6555254 C27.8902838,28.5798392 28.6612371,27.7613825 28.6612371,26.7638125 L28.6612371,5.23618754 L28.6555254,5.08796584 C28.5798392,4.10971624 27.7613825,3.33876293 26.7638125,3.33876293 Z M13.6987866,17.269857 L13.8115418,17.2763362 C14.2922804,17.3319705 14.6640078,17.7391232 14.6640078,18.2350783 L14.6640078,25.3537223 L14.6574584,25.4671616 C14.6012469,25.9511001 14.1903841,26.3286298 13.7036674,26.3189919 L13.5959284,26.3105939 C13.1358108,26.2480197 12.7797903,25.8518025 12.7797903,25.3768348 L12.7797903,20.5190494 L8.12934794,25.1694917 L8.04095127,25.2474504 C7.67245079,25.5332987 7.13521162,25.5073124 6.79739091,25.1694917 C6.43141847,24.8035193 6.43141847,24.2035071 6.79739091,23.8375347 L11.4844789,19.1540745 L6.64947993,19.1540745 L6.53583534,19.1475529 C6.05108664,19.0915708 5.67369292,18.6822061 5.68093001,18.1924962 C5.69137836,17.6807185 6.11029591,17.269857 6.62306566,17.269857 L13.6987866,17.269857 Z M18.2962333,5.68100813 C18.807211,5.69148979 19.2201105,6.11166149 19.2201105,6.62316519 L19.2201105,11.4776488 L23.8705528,6.82720649 L23.9589495,6.74924786 C24.32745,6.46339956 24.8646892,6.48938577 25.2025099,6.82720649 C25.5684823,7.19317893 25.5684823,7.79319108 25.2025099,8.15916352 L20.5190497,12.8426237 L25.3537226,12.8426237 L25.4673933,12.8491436 C25.9521795,12.9051095 26.3286206,13.3143234 26.3189917,13.8029881 C26.3085224,14.3159797 25.8896049,14.7268412 25.3768351,14.7268412 L18.2945107,14.7268412 L18.1826915,14.7203822 C17.7058457,14.6649267 17.335893,14.2592033 17.335893,13.7682235 L17.335893,6.64627767 L17.3424424,6.53283844 C17.3986538,6.04889994 17.8095166,5.67137018 18.2962333,5.68100813 Z" id="形状结合" fill-rule="nonzero" opacity="0.79078311"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.3 KiB

BIN
src/assets/images/banzu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/assets/img/home-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 936 B

View File

@@ -54,7 +54,7 @@ export default {
};
},
created() {
// this.currentMenu = this.menus[0];
this.currentMenu = this.menus[0];
},
watch: {
currentMenu(val) {
@@ -81,7 +81,7 @@ export default {
border: none;
background: #fff;
border-radius: 8px;
padding: 15px;
padding: 16px;
color: #888;
letter-spacing: 2px;
flex: 1;

View File

@@ -6,48 +6,104 @@
-->
<template>
<el-form ref="form" :model="form" :label-width="`${labelWidth}px`" :size="size" :label-position="labelPosition"
v-loading="formLoading">
<el-row :gutter="20" v-for="(row, rindex) in rows" :key="rindex">
<el-col v-for="col in row" :key="col.label" :span="24 / row.length">
<el-form-item :label="col.label" :prop="col.prop" :rules="col.rules">
<el-input v-if="col.input" v-model="form[col.prop]" @change="$emit('update', form)"
:placeholder="`请输入${col.label}`" v-bind="col.bind" />
<el-input v-if="col.textarea" 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" @change="handleSwitchChange(col.prop)"></el-switch>
<component v-if="col.subcomponent" :key="col.key" :is="col.subcomponent" :inlineStyle="col.style"></component>
<el-form
ref="form"
:model="form"
:label-width="`${labelWidth}px`"
:size="size"
:label-position="labelPosition"
v-loading="formLoading">
<el-row :gutter="20" v-for="(row, rindex) in rows" :key="rindex">
<el-col v-for="col in row" :key="col.label" :span="24 / row.length">
<el-form-item :label="col.label" :prop="col.prop" :rules="col.rules">
<el-input
v-if="col.input"
v-model="form[col.prop]"
@change="$emit('update', form)"
:placeholder="`请输入${col.label}`"
v-bind="col.bind" />
<el-input
v-if="col.textarea"
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 class="upload-area" :class="uploadOpen ? '' : 'height-48'" ref="uploadArea" v-if="col.upload">
<span class="close-icon" :class="uploadOpen ? 'open' : ''">
<el-button type="text" icon="el-icon-arrow-right" @click="handleFilesOpen" />
</span>
<!-- :file-list="uploadedFileList" -->
<el-upload class="upload-in-dialog" v-if="col.upload" :action="uploadUrl" :headers="uploadHeaders"
:show-file-list="false" icon="el-icon-upload2" :before-upload="beforeUpload"
:on-success="handleUploadSuccess" v-bind="col.bind">
<el-button size="mini" :disabled="col.bind?.disabled || false">
<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>
<div
class="upload-area"
:class="uploadOpen ? '' : 'height-48'"
ref="uploadArea"
v-if="col.upload">
<span class="close-icon" :class="uploadOpen ? 'open' : ''">
<el-button
type="text"
icon="el-icon-arrow-right"
@click="handleFilesOpen" />
</span>
<!-- :file-list="uploadedFileList" -->
<el-upload
class="upload-in-dialog"
v-if="col.upload"
:action="uploadUrl"
:headers="uploadHeaders"
:show-file-list="false"
icon="el-icon-upload2"
:before-upload="beforeUpload"
:on-success="handleUploadSuccess"
v-bind="col.bind">
<el-button size="mini" :disabled="col.bind?.disabled || false">
<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>
<script>
@@ -59,353 +115,346 @@ import tupleImg from '@/assets/images/tuple.png';
* @param {*} options
*/
function findMaxLabelWidth(rows) {
let max = 0;
rows.forEach((row) => {
row.forEach((opt) => {
// debugger;
if (!opt.label) return 0;
if (opt.label.length > max) {
max = opt.label.length;
}
});
});
return max;
let max = 0;
rows.forEach((row) => {
row.forEach((opt) => {
// debugger;
if (!opt.label) return 0;
if (opt.label.length > max) {
max = opt.label.length;
}
});
});
return max;
}
const uploadedFile = {
name: 'UploadedFile',
props: ['file'],
data() {
return {};
},
methods: {
handleDelete() {
this.$emit('delete', this.file);
},
handlePreview() {
this.$emit('Preview', this.file);
},
},
mounted() { },
render: function (h) {
return (
<div
title={this.file.fileName}
style={{
background: `url(${tupleImg}) no-repeat`,
backgroundSize: '14px',
backgroundPosition: '0 55%',
paddingLeft: '20px',
paddingRight: '24px',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
cursor: 'pointer',
display: 'inline-block',
}}>
<el-button onClick={this.handlePreview}>{this.file.fileName}</el-button>
<el-button
type="text"
icon="el-icon-close"
style="float: right; position: relative; top: 2px; left: 8px; z-index: 100"
class="dialog__upload_component__close"
onClick={this.handleDelete}
/>
</div>
);
},
name: 'UploadedFile',
props: ['file'],
data() {
return {};
},
methods: {
handleDelete() {
this.$emit('delete', this.file);
},
handlePreview() {
this.$emit('Preview', this.file);
},
},
mounted() {},
render: function (h) {
return (
<div
title={this.file.fileName}
style={{
background: `url(${tupleImg}) no-repeat`,
backgroundSize: '14px',
backgroundPosition: '0 55%',
paddingLeft: '20px',
paddingRight: '24px',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
cursor: 'pointer',
display: 'inline-block',
}}>
<el-button onClick={this.handlePreview}>{this.file.fileName}</el-button>
<el-button
type="text"
icon="el-icon-close"
style="float: right; position: relative; top: 2px; left: 8px; z-index: 100"
class="dialog__upload_component__close"
onClick={this.handleDelete}
/>
</div>
);
},
};
export default {
name: 'DialogForm',
model: {
prop: 'dataForm',
event: 'update',
},
emits: ['update'],
components: { uploadedFile },
props: {
rows: {
type: Array,
default: () => [],
},
dataForm: {
type: Object,
default: () => ({}),
},
disabled: {
type: Boolean,
default: false,
},
hasFile: {
type: Boolean,
default: false,
},
labelPosition: {
type: String,
default: 'right',
},
size: {
type: String,
default: '',
},
},
data() {
return {
uploadOpen: false,
form: {},
formLoading: true,
optionListOf: {},
uploadedFileList: [],
dataLoaded: false,
uploadHeaders: { Authorization: 'Bearer ' + getAccessToken() },
uploadUrl: process.env.VUE_APP_BASE_API + '/admin-api/infra/file/upload', // 上传有关的headersurl都是固定的
};
},
computed: {
labelWidth() {
let max = findMaxLabelWidth(this.rows);
// 每个汉字占20px
return max * 20;
// return max * 20 + 'px';
},
},
watch: {
rows: {
handler() {
this.$nextTick(() => {
this.handleOptions('watch');
});
},
deep: true,
immediate: false,
},
dataForm: {
handler(val) {
this.form = JSON.parse(JSON.stringify(val));
if (this.hasFile) {
this.form.files = this.form.files ?? [];
}
},
deep: true,
immediate: true,
},
},
mounted() {
// 处理 options
this.handleOptions();
},
methods: {
handleSwitchChange(prop) {
// 触发 update 事件,将最新的 form 数据传递给父组件
this.$emit('update', { ...this.form });
console.log(`switch ${prop} 变化:`, this.form[prop]);
},
/** 模拟透传 ref */
validate(cb) {
return this.$refs.form.validate(cb);
},
resetFields(args) {
return this.$refs.form.resetFields(args);
},
async handlePreview(file) {
const data = await this.$axios({
url: file.fileUrl,
method: 'get',
responseType: 'blob',
});
const link = document.createElement('a');
link.href = window.URL.createObjectURL(new Blob([data]));
link.download = file.fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(link.href);
},
// getCode
async getCode(url) {
const response = await this.$axios(url);
return response.data;
},
async handleOptions(trigger = 'monuted') {
console.log('[dialogForm:handleOptions]');
const promiseList = [];
this.rows.forEach((cols) => {
cols.forEach((opt) => {
if (opt.value && !this.form[opt.prop]) {
// 默认值
this.form[opt.prop] = opt.value;
}
name: 'DialogForm',
model: {
prop: 'dataForm',
event: 'update',
},
emits: ['update'],
components: { uploadedFile },
props: {
rows: {
type: Array,
default: () => [],
},
dataForm: {
type: Object,
default: () => ({}),
},
disabled: {
type: Boolean,
default: false,
},
hasFile: {
type: Boolean,
default: false,
},
labelPosition: {
type: String,
default: 'right',
},
size: {
type: String,
default: '',
},
},
data() {
return {
uploadOpen: false,
form: {},
formLoading: true,
optionListOf: {},
uploadedFileList: [],
dataLoaded: false,
uploadHeaders: { Authorization: 'Bearer ' + getAccessToken() },
uploadUrl: process.env.VUE_APP_BASE_API + '/admin-api/infra/file/upload', // 上传有关的headersurl都是固定的
};
},
computed: {
labelWidth() {
let max = findMaxLabelWidth(this.rows);
// 每个汉字占20px
return max * 20;
// return max * 20 + 'px';
},
},
watch: {
rows: {
handler() {
this.$nextTick(() => {
this.handleOptions('watch');
});
},
deep: true,
immediate: false,
},
dataForm: {
handler(val) {
this.form = JSON.parse(JSON.stringify(val));
if (this.hasFile) {
this.form.files = this.form.files ?? [];
}
},
deep: true,
immediate: true,
},
},
mounted() {
// 处理 options
this.handleOptions();
},
methods: {
/** 模拟透传 ref */
validate(cb) {
return this.$refs.form.validate(cb);
},
resetFields(args) {
return this.$refs.form.resetFields(args);
},
async handlePreview(file) {
const data = await this.$axios({
url: file.fileUrl,
method: 'get',
responseType: 'blob',
});
const link = document.createElement('a');
link.href = window.URL.createObjectURL(new Blob([data]));
link.download = file.fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(link.href);
},
// getCode
async getCode(url) {
const response = await this.$axios(url);
return response.data;
},
async handleOptions(trigger = 'monuted') {
console.log('[dialogForm:handleOptions]');
const promiseList = [];
this.rows.forEach((cols) => {
cols.forEach((opt) => {
if (opt.value && !this.form[opt.prop]) {
// 默认值
this.form[opt.prop] = opt.value;
}
if (opt.options) {
this.$set(this.optionListOf, opt.prop, opt.options);
} else if (opt.url) {
// 如果有 depends则暂时先不获取注册一个watcher
if (opt.depends) {
console.log('[handleOptions] setting watch');
this.$watch(
() => this.form[opt.depends],
(id) => {
console.log('<', opt.depends, '>', 'changed', id);
if (id == null) return;
// 清空原有选项
this.form[opt.prop] = null;
// 获取新的选项
this.$axios({
url: `${opt.url}?id=${id}`,
}).then((res) => {
this.$set(
this.optionListOf,
opt.prop,
res.data.map((item) => ({
label: item[opt.labelKey ?? 'name'],
value: item[opt.valueKey ?? 'id'],
}))
);
});
},
{
immediate: true,
}
);
return;
}
// 如果是下拉框,或者新增模式下的输入框,才去请求
if (opt.select || (opt.input && !this.form?.id)) {
promiseList.push(async () => {
const response = await this.$axios(opt.url, {
method: opt.method ?? 'get',
});
console.log('[dialogForm:handleOptions:response]', response);
if (opt.select) {
// 处理下拉框选项
const list =
'list' in response.data
? response.data.list
: response.data;
this.$set(
this.optionListOf,
opt.prop,
list.map((item) => ({
label: item[opt.labelKey ?? 'name'],
value: item[opt.valueKey ?? 'id'],
}))
);
} else if (opt.input) {
console.log('setting code: ', response.data);
// 处理输入框数据
this.form[opt.prop] = response.data;
}
});
}
}
});
});
if (opt.options) {
this.$set(this.optionListOf, opt.prop, opt.options);
} else if (opt.url) {
// 如果有 depends则暂时先不获取注册一个watcher
if (opt.depends) {
console.log('[handleOptions] setting watch');
this.$watch(
() => this.form[opt.depends],
(id) => {
console.log('<', opt.depends, '>', 'changed', id);
if (id == null) return;
// 清空原有选项
this.form[opt.prop] = null;
// 获取新的选项
this.$axios({
url: `${opt.url}?id=${id}`,
}).then((res) => {
this.$set(
this.optionListOf,
opt.prop,
res.data.map((item) => ({
label: item[opt.labelKey ?? 'name'],
value: item[opt.valueKey ?? 'id'],
}))
);
});
},
{
immediate: true,
}
);
return;
}
// 如果是下拉框,或者新增模式下的输入框,才去请求
if (opt.select || (opt.input && !this.form?.id)) {
promiseList.push(async () => {
const response = await this.$axios(opt.url, {
method: opt.method ?? 'get',
});
console.log('[dialogForm:handleOptions:response]', response);
if (opt.select) {
// 处理下拉框选项
const list =
'list' in response.data
? response.data.list
: response.data;
this.$set(
this.optionListOf,
opt.prop,
list.map((item) => ({
label: item[opt.labelKey ?? 'name'],
value: item[opt.valueKey ?? 'id'],
}))
);
} else if (opt.input) {
console.log('setting code: ', response.data);
// 处理输入框数据
this.form[opt.prop] = response.data;
}
});
}
}
});
});
console.log('[dialogForm:handleOptions] done!');
console.log('[dialogForm:handleOptions] done!');
// 如果是 watch 触发的,不需要执行进一步的请求
if (trigger == 'watch') {
this.formLoading = false;
return;
}
try {
await Promise.all(promiseList.map((fn) => fn()));
this.formLoading = false;
this.dataLoaded = true;
// console.log("[dialogForm:handleOptions:optionListOf]", this.optionListOf)
} catch (error) {
console.log('[dialogForm:handleOptions:error]', error);
this.formLoading = false;
}
if (!promiseList.length) this.formLoading = false;
},
// 上传成功的特殊处理
beforeUpload(file) {
// 如果是 watch 触发的,不需要执行进一步的请求
if (trigger == 'watch') {
this.formLoading = false;
return;
}
try {
await Promise.all(promiseList.map((fn) => fn()));
this.formLoading = false;
this.dataLoaded = true;
// console.log("[dialogForm:handleOptions:optionListOf]", this.optionListOf)
} catch (error) {
console.log('[dialogForm:handleOptions:error]', error);
this.formLoading = false;
}
if (!promiseList.length) this.formLoading = false;
},
// 上传成功的特殊处理
beforeUpload(file) {
console.log(file)
},
// 上传前的验证规则可通过 bind 属性传入
handleUploadSuccess(response, file, fileList) {
this.form.files.push({
fileName: file.name,
fileUrl: response.data,
fileType: 2,
});
this.$modal.msgSuccess('上传成功');
this.$emit('update', this.form);
},
// 上传前的验证规则可通过 bind 属性传入
handleUploadSuccess(response, file, fileList) {
this.form.files.push({
fileName: file.name,
fileUrl: response.data,
fileType: 2,
});
this.$modal.msgSuccess('上传成功');
this.$emit('update', this.form);
},
getFileName(fileUrl) {
return fileUrl.split('/').pop();
},
getFileName(fileUrl) {
return fileUrl.split('/').pop();
},
handleFilesOpen() {
this.uploadOpen = !this.uploadOpen;
},
handleFilesOpen() {
this.uploadOpen = !this.uploadOpen;
},
handleDeleteFile(file) {
this.form.files = this.form.files.filter(
(item) => item.fileUrl != file.fileUrl
);
this.$emit('update', this.form);
},
},
handleDeleteFile(file) {
this.form.files = this.form.files.filter(
(item) => item.fileUrl != file.fileUrl
);
this.$emit('update', this.form);
},
},
};
</script>
<style scoped lang="scss">
.el-date-editor,
.el-select {
width: 100%;
width: 100%;
}
.upload-area {
// background: #ccc;
// display: grid;
// grid-auto-rows: 34px;
// grid-template-columns: repeat(6, minmax(32px, max-content));
// gap: 8px;
// align-items: center;
position: relative;
overflow: hidden;
transition: height 0.3s ease-out;
// background: #ccc;
// display: grid;
// grid-auto-rows: 34px;
// grid-template-columns: repeat(6, minmax(32px, max-content));
// gap: 8px;
// align-items: center;
position: relative;
overflow: hidden;
transition: height 0.3s ease-out;
}
.upload-in-dialog {
// display: inline-block;
margin-right: 24px;
// background: #ccc;
position: relative;
// top: -13px;
float: left;
// display: inline-block;
margin-right: 24px;
// background: #ccc;
position: relative;
// top: -13px;
float: left;
}
.close-icon {
// background: #ccc;
position: absolute;
top: 0;
right: 12px;
z-index: 100;
transition: transform 0.3s ease-out;
// background: #ccc;
position: absolute;
top: 0;
right: 12px;
z-index: 100;
transition: transform 0.3s ease-out;
}
.close-icon.open {
transform: rotateZ(90deg);
transform: rotateZ(90deg);
}
</style>
<style>
.dialog__upload_component__close {
color: #ccc;
color: #ccc;
}
.dialog__upload_component__close:hover {
/* color: #777; */
color: red;
/* color: #777; */
color: red;
}
.height-48 {
height: 35px !important;
height: 35px !important;
}
</style>

View File

@@ -91,4 +91,4 @@ export default function (dictTable) {
return function (val) {
return table?.[dictTable]?.[val]
}
}
}

View File

@@ -9,6 +9,7 @@ import store from './store';
import router from './router';
import directive from './directive'; // directive
import plugins from './plugins'; // plugins
import dataV from '@jiaminghi/data-view'
import './assets/icons'; // icon
import './permission'; // permission control
@@ -21,7 +22,6 @@ import {
handleTree,
addBeginAndEndTime,
divide,
formatThousands
} from '@/utils/ruoyi';
import Pagination from '@/components/Pagination';
// 自定义表格工具扩展
@@ -46,7 +46,6 @@ Vue.prototype.resetForm = resetForm;
Vue.prototype.getDictDatas = getDictDatas;
Vue.prototype.getDictDatas2 = getDictDatas2;
Vue.prototype.getDictDataLabel = getDictDataLabel;
Vue.prototype.formatThousands = formatThousands;
Vue.prototype.DICT_TYPE = DICT_TYPE;
Vue.prototype.handleTree = handleTree;
Vue.prototype.addBeginAndEndTime = addBeginAndEndTime;
@@ -79,6 +78,7 @@ Vue.use(directive);
Vue.use(plugins);
Vue.use(VueMeta);
// Vue.use(hljs.vuePlugin);
Vue.use(dataV);
// bpmnProcessDesigner 需要引入
import MyPD from '@/components/bpmnProcessDesigner/package/index.js';

View File

@@ -16,7 +16,7 @@ export default {
},
tableData: [], //table数据
listQuery: { //分页
pageSize: 10,
pageSize: 20,
pageNo: 1,
total: 1,
},

View File

@@ -76,7 +76,7 @@ export const constantRoutes = [
children: [
{
path: "index",
component: (resolve) => require(["@/views/core/base/factory/index"], resolve),
component: (resolve) => require(["@/views/home/index"], resolve),
name: "首页",
meta: { title: "首页", icon: "dashboard", affix: true },
hidden: true

View File

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

View File

@@ -295,15 +295,3 @@ export function getPath(path) {
}
return Math.floor(divisor/dividend*100)/100;
}
// 通用千分位格式化函数
export function formatThousands(value) {
if (value === null || value === undefined) return '0'
// 清理已有逗号并转为数字
const numValue = Number(String(value).replace(/,/g, ''))
if (isNaN(numValue)) return '0'
// 支持小数处理
return numValue.toLocaleString('en-US')
}

View File

@@ -1,116 +0,0 @@
<template>
<div class='centerBottomL'>
<div class='title'>
<svg-icon icon-class="dataBoard3" class='icon'/>
<span>本月数据</span>
</div>
<div class='dataBox' style='top:50px'>
<p>
<span class='text'>总投入片数</span>
<span class='precent' :class='{precentR:monthData?.inputNumChange>=0,precentG:monthData?.inputNumChange<0}'>{{monthData?.inputNumChange || '-'}}%</span>
<img v-show='monthData?.inputNumChange<0' src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
<img v-show='monthData?.inputNumChange>=0' src="../../../../assets/images/dataBoard/arrUp.png" alt="" width='5' height='15'>
</p>
<p class='num'>{{monthData?.inputNum ? formatThousands(monthData.inputNum) : '-'}}</p>
</div>
<div class='dataBox'style='top:180px'>
<p>
<span class='text'>总生产片数</span>
<span class='precent' :class='{precentR:monthData?.outputNumChange>=0,precentG:monthData?.outputNumChange<0}'>{{monthData?.outputNumChange || '-'}}%</span>
<img v-show='monthData?.outputNumChange<0' src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
<img v-show='monthData?.outputNumChange>=0' src="../../../../assets/images/dataBoard/arrUp.png" alt="" width='5' height='15'>
</p>
<p class='num'>{{monthData?.outputNum ? formatThousands(monthData.outputNum) : '-'}}</p>
</div>
</div>
</template>
<script>
export default {
name: 'CenterBottomL',
props: {
dataObj: {
type: Object,
default: () => {}
}
},
watch: {
dataObj(val) {
val.monthAndLastMonth && val.monthAndLastMonth.forEach(item => {
if (item.dataType === "本月") {
this.monthData = item
}
})
}
},
data() {
return {
monthData:{}
}
},
methods: {}
}
</script>
<style lang="scss" scoped>
.centerBottomL {
width: 337px;
height: 332px;
background: url('../../../../assets/images/dataBoard/center-bottom.png') no-repeat;
background-size: 100%;
position: absolute;
left: 440px;
bottom:23px;
.title {
margin: 7px 0 0 15px;
.icon {
width: 33px;
height: 33px;
margin-right: 5px;
vertical-align:middle;
margin-top: 5px;
}
span {
font-size: 24px;
color: #52FFF1;
line-height: 24px;
vertical-align:middle;
}
}
.dataBox {
width: 290px;
height: 135px;
background: url('../../../../assets/images/dataBoard/numberBox.png') no-repeat;
background-size: 100%;
position: absolute;
padding:22px 0 0 16px;
left: 24px;
p{
margin: 0;
}
.text {
font-weight: 500;
font-size: 20px;
color: #FFFFFF;
letter-spacing: 2px;
margin-right: 8px;
}
.precent {
font-size: 18px;
margin-right: 5px;
}
.precentR {
color: #FF271D;
}
.precentG {
color: #34F716;
}
.num {
font-weight: 500;
font-size: 38px;
color: #FFFFFF;
margin-top: 5px;
}
}
}
</style>

View File

@@ -1,100 +0,0 @@
<template>
<div class='centerBottomR'>
<div class='title'>
<svg-icon icon-class="dataBoard3" class='icon'/>
<span>上月数据</span>
</div>
<div class='dataBox' style='top:50px'>
<p>
<span class='text'>总投入片数</span>
</p>
<p class='num'>{{lastMonthData?.inputNum ? formatThousands(lastMonthData.inputNum) : '-'}}</p>
</div>
<div class='dataBox'style='top:180px'>
<p>
<span class='text'>总生产片数</span>
</p>
<p class='num'>{{lastMonthData?.outputNum ? formatThousands(lastMonthData.outputNum) : '-'}}</p>
</div>
</div>
</template>
<script>
export default {
name: 'CenterBottomR',
props: {
dataObj: {
type: Object,
default: () => {}
}
},
watch: {
dataObj(val) {
val.monthAndLastMonth && val.monthAndLastMonth.forEach(item => {
if (item.dataType === "上月") {
this.lastMonthData = item
}
})
}
},
data() {
return {
lastMonthData:{}
}
},
methods: {}
}
</script>
<style lang="scss" scoped>
.centerBottomR {
width: 337px;
height: 332px;
background: url('../../../../assets/images/dataBoard/center-bottom.png') no-repeat;
background-size: 100%;
position: absolute;
left: 791px;
bottom:23px;
.title {
margin: 7px 0 0 15px;
.icon {
width: 33px;
height: 33px;
margin-right: 5px;
vertical-align:middle;
margin-top: 5px;
}
span {
font-size: 24px;
color: #52FFF1;
line-height: 24px;
vertical-align:middle;
}
}
.dataBox {
width: 290px;
height: 135px;
background: url('../../../../assets/images/dataBoard/numberBox.png') no-repeat;
background-size: 100%;
position: absolute;
padding:22px 0 0 16px;
left: 24px;
p{
margin: 0;
}
.text {
font-weight: 500;
font-size: 20px;
color: #FFFFFF;
letter-spacing: 2px;
margin-right: 8px;
}
.num {
font-weight: 500;
font-size: 38px;
color: #FFFFFF;
margin-top: 5px;
}
}
}
</style>

View File

@@ -1,352 +0,0 @@
<template>
<div ref="centerTopBox" class='centerTopBox'>
<div>
<video src="/static/videos/01.webm" muted autoplay loop class='videoStyle'></video>
<div
class='eqTipBox'
v-show='showTooltip'
:style="'left:'+tooltipStyle.left+'px;top:'+tooltipStyle.top+'px;'"
>
<p><span class='eqTipTitle'>设备名称:</span><span class='eqTipNum'>{{eqTipMsg.name}}</span></p>
<p><span class='eqTipTitle'>进口数量:</span><span class='eqTipNum'>{{eqTipMsg.input}}</span></p>
<p><span class='eqTipTitle'>出口数量:</span><span class='eqTipNum'>{{eqTipMsg.output}}</span></p>
<p><span class='eqTipTitle'>报警状态:</span>
<span class='eqTipNum'>
<img v-show='eqTipMsg.alarm' :src='dotY' width='16'/>
<img v-show='!eqTipMsg.alarm' :src='dotG' width='16'/>
{{eqTipMsg.alarm?'报警':'未报警'}}
</span>
</p>
<p><span class='eqTipTitle'>在线状态:</span>
<span class='eqTipNum'>
<img v-show='eqTipMsg.status' :src='dotG' width='16'/>
<img v-show='!eqTipMsg.status' :src='dotR' width='16'/>
{{eqTipMsg.status?'在线':'离线'}}
</span>
</p>
</div>
<!-- 设备 -->
<div class='eqBox'>
<!-- line-从上到下-从右往左 -->
<span
v-for='(item,index) in eqList'
:key='index'
:style="'width:'+item.w+'px;height:'+item.h+'px;left:'+item.l+'px;top:'+item.t+'px'"
@mouseenter="handleMouseEnter(item, $event)"
@mouseleave="handleMouseLeave"
></span>
</div>
</div>
<div class='centerTopTopBox'>
<div style='display: inline-block;'>
<img src="../../../../assets/images/dataBoard/centerNumB.png" alt="" width='203'>
<p class='num'>{{dataObj?.productRate || '-'}}%</p>
<p class='title'>成品率</p>
</div>
<div style='display: inline-block;'>
<img src="../../../../assets/images/dataBoard/centerNumY.png" alt="" width='261'>
<p class='num' style='width: 260px;padding-left: 20px;'>{{dataObj?.todayProduct ? formatThousands(dataObj.todayProduct) : '-'}}</p>
<p class='title' style='color:#FFB625'>今日产量</p>
</div>
<div style='display: inline-block;'>
<img src="../../../../assets/images/dataBoard/centerNumY.png" alt="" width='261'>
<p class='num' style='width: 260px;padding-left: 20px;'>{{dataObj?.monthProduct ? formatThousands(dataObj.monthProduct) : '-'}}</p>
<p class='title' style='color:#FFB625'>本月产量</p>
</div>
<div style='display: inline-block;'>
<img src="../../../../assets/images/dataBoard/centerNumB.png" alt="" width='203'>
<p class='num'>{{dataObj?.alarmNum ? formatThousands(dataObj.alarmNum) : '-'}}</p>
<p class='title'>设备报警数</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CenterTop',
data() {
return {
showTooltip:false,
tooltipStyle: {
left: 0,
top: 0
},
dotY:require('../../../../assets/images/dataBoard/dotY.png'),
dotR:require('../../../../assets/images/dataBoard/dotR.png'),
dotG:require('../../../../assets/images/dataBoard/dotG.png'),
eqList:[
{name:'A1-磨边机-1',id:100301,w:70,h:18,l:830,t:160},
{name:'A1-磨边机-2',id:100302,w:70,h:18,l:830,t:183},
{name:'A1-磨边机-3',id:100303,w:70,h:18,l:832,t:206},
{name:'A1-磨边后清洗机-1',id:100401,w:30,h:15,l:798,t:160},
{name:'A1-磨边后清洗机-2',id:100402,w:30,h:15,l:798,t:183},
{name:'A1-磨边后清洗机-3',id:100403,w:30,h:15,l:800,t:206},
{name:'A1-打孔机-1',id:100501,w:13,h:12,l:730,t:163},
{name:'A1-打孔机-2',id:100502,w:13,h:12,l:730,t:187},
{name:'A1-打孔机-3',id:100503,w:13,h:12,l:730,t:210},
{name:'A1-打孔后清洗机-1',id:100601,w:32,h:15,l:665,t:160},
{name:'A1-打孔后清洗机-2',id:100602,w:32,h:15,l:665,t:183},
{name:'A1-打孔后清洗机-3',id:100603,w:32,h:15,l:665,t:206},
{name:'A1-丝印机-1',id:100701,w:30,h:12,l:605,t:163},
{name:'A1-丝印机-2',id:100702,w:30,h:12,l:605,t:187},
{name:'A1-丝印机-3',id:100703,w:30,h:12,l:605,t:210},
{name:'A1-丝印后固化机-1',id:101301,w:37,h:12,l:558,t:163},
{name:'A1-丝印后固化机-2',id:101302,w:37,h:12,l:558,t:187},
{name:'A1-丝印后固化机-3',id:101303,w:37,h:12,l:558,t:210},
{name:'A1-钢化炉',id:101401,w:75,h:15,l:382,t:209},
{name:'A1-包装清洗机-1',id:101501,w:30,h:15,l:228,t:173},
{name:'A1-包装清洗机-2',id:101502,w:30,h:15,l:228,t:206},
{name:'A1-铺纸机-1',id:101601,w:18,h:15,l:188,t:175},
{name:'A1-铺纸机-2',id:101602,w:18,h:15,l:188,t:206},
{name:'A2-磨边机-1',id:200301,w:70,h:18,l:832,t:233},
{name:'A2-磨边机-2',id:200302,w:70,h:18,l:833,t:257},
{name:'A2-磨边机-3',id:200303,w:70,h:18,l:834,t:281},
{name:'A2-磨边后清洗机-1',id:200401,w:30,h:15,l:800,t:233},
{name:'A2-磨边后清洗机-2',id:200402,w:30,h:15,l:801,t:257},
{name:'A2-磨边后清洗机-3',id:200403,w:30,h:15,l:802,t:281},
{name:'A2-打孔机-1',id:200501,w:13,h:12,l:731,t:240},
{name:'A2-打孔机-2',id:200502,w:13,h:12,l:731,t:262},
{name:'A2-打孔机-3',id:200503,w:13,h:12,l:731,t:285},
{name:'A2-打孔后清洗机-1',id:200601,w:32,h:15,l:666,t:234},
{name:'A2-打孔后清洗机-2',id:200602,w:32,h:15,l:666,t:258},
{name:'A2-打孔后清洗机-3',id:200603,w:32,h:15,l:666,t:282},
{name:'A2-丝印机-1',id:200701,w:30,h:12,l:605,t:238},
{name:'A2-丝印机-2',id:200702,w:30,h:12,l:605,t:262},
{name:'A2-丝印机-3',id:200703,w:30,h:12,l:605,t:286},
{name:'A2-丝印后固化机-1',id:201301,w:37,h:12,l:558,t:238},
{name:'A2-丝印后固化机-2',id:201302,w:37,h:12,l:558,t:262},
{name:'A2-丝印后固化机-3',id:201303,w:37,h:12,l:558,t:286},
{name:'A2-钢化炉',id:201401,w:75,h:15,l:382,t:238},
{name:'A2-包装清洗机-1',id:201501,w:30,h:15,l:228,t:234},
{name:'A2-包装清洗机-2',id:201502,w:30,h:15,l:228,t:267},
{name:'A2-铺纸机-1',id:201601,w:18,h:15,l:187,t:234},
{name:'A2-铺纸机-2',id:201602,w:18,h:15,l:186,t:267},
{name:'A3-磨边机-1',id:300301,w:70,h:18,l:834,t:318},
{name:'A3-磨边机-2',id:300302,w:70,h:18,l:834,t:342},
{name:'A3-磨边后清洗机-1',id:300401,w:30,h:15,l:802,t:319},
{name:'A3-磨边后清洗机-2',id:300402,w:30,h:15,l:802,t:342},
{name:'A3-打孔机-1',id:300501,w:13,h:12,l:731,t:324},
{name:'A3-打孔机-2',id:300502,w:13,h:12,l:731,t:348},
{name:'A3-打孔后清洗机-1',id:300601,w:32,h:15,l:666,t:320},
{name:'A3-打孔后清洗机-2',id:300602,w:32,h:15,l:666,t:342},
{name:'A3-丝印机-1',id:300701,w:30,h:12,l:605,t:324},
{name:'A3-丝印机-2',id:300702,w:30,h:12,l:605,t:348},
{name:'A3-一次镀膜机-1',id:300801,w:20,h:15,l:553,t:322},
{name:'A3-一次镀膜机-2',id:300802,w:20,h:15,l:553,t:346},
{name:'A3-丝印后固化机-1',id:301301,w:37,h:12,l:506,t:324},
{name:'A3-丝印后固化机-2',id:301302,w:37,h:12,l:506,t:347},
{name:'A3-钢化炉',id:301401,w:75,h:15,l:340,t:346},
{name:'A3-包装清洗机-1',id:301501,w:30,h:15,l:240,t:343},
{name:'A3-铺纸机-1',id:301601,w:18,h:15,l:200,t:343},
{name:'A3-铺纸机-2',id:301602,w:18,h:15,l:170,t:343},
{name:'A4-磨边机-1',id:400301,w:70,h:18,l:838,t:380},
{name:'A4-磨边机-2',id:400302,w:70,h:18,l:838,t:405},
{name:'A4-磨边机-3',id:400303,w:70,h:18,l:839,t:428},
{name:'A4-磨边后清洗机-1',id:400401,w:30,h:15,l:804,t:380},
{name:'A4-磨边后清洗机-2',id:400402,w:30,h:15,l:805,t:405},
{name:'A4-磨边后清洗机-3',id:400403,w:30,h:15,l:806,t:427},
{name:'A4-一次镀膜机-1',id:400801,w:20,h:15,l:707,t:381},
{name:'A4-一次镀膜机-2',id:400802,w:20,h:15,l:707,t:407},
{name:'A4-一次镀膜机-3',id:400803,w:20,h:15,l:707,t:429},
{name:'A4-一次固化机-1',id:401001,w:37,h:12,l:660,t:383},
{name:'A4-一次固化机-2',id:401002,w:37,h:12,l:660,t:409},
{name:'A4-一次固化机-3',id:401003,w:37,h:12,l:660,t:431},
{name:'A4-二次镀膜机-1',id:401101,w:20,h:15,l:605,t:382},
{name:'A4-二次镀膜机-2',id:401102,w:20,h:15,l:605,t:408},
{name:'A4-二次镀膜机-3',id:401103,w:20,h:15,l:605,t:430},
{name:'A4-二次固化机-1',id:401201,w:37,h:12,l:557,t:383},
{name:'A4-二次固化机-2',id:401202,w:37,h:12,l:557,t:409},
{name:'A4-二次固化机-3',id:401203,w:37,h:12,l:557,t:431},
{name:'A4-钢化炉',id:401401,w:75,h:15,l:379,t:381},
{name:'A4-包装清洗机-1',id:401501,w:30,h:15,l:220,t:379},
{name:'A4-包装清洗机-2',id:401502,w:30,h:18,l:220,t:410},
{name:'A4-铺纸机-1',id:401601,w:18,h:15,l:180,t:381},
{name:'A4-铺纸机-2',id:401602,w:18,h:15,l:180,t:414},
{name:'A5-磨边机-1',id:500301,w:70,h:18,l:817,t:465},
{name:'A5-磨边机-2',id:500302,w:70,h:18,l:817,t:488},
{name:'A5-磨边机-3',id:500303,w:70,h:18,l:819,t:512},
{name:'A5-磨边后清洗机-1',id:500401,w:30,h:15,l:784,t:462},
{name:'A5-磨边后清洗机-2',id:500402,w:30,h:15,l:784,t:488},
{name:'A5-磨边后清洗机-3',id:500403,w:30,h:15,l:785,t:512},
{name:'A5-一次镀膜机-1',id:500801,w:20,h:15,l:685,t:466},
{name:'A5-一次镀膜机-2',id:500802,w:20,h:15,l:685,t:490},
{name:'A5-一次镀膜机-3',id:500803,w:20,h:15,l:685,t:513},
{name:'A5-一次固化机-1',id:501001,w:37,h:12,l:638,t:468},
{name:'A5-一次固化机-2',id:501002,w:37,h:12,l:638,t:491},
{name:'A5-一次固化机-3',id:501003,w:37,h:12,l:638,t:514},
{name:'A5-二次镀膜机-1',id:501101,w:20,h:15,l:584,t:468},
{name:'A5-二次镀膜机-2',id:501102,w:20,h:15,l:584,t:490},
{name:'A5-二次镀膜机-3',id:501103,w:20,h:15,l:584,t:513},
{name:'A5-二次固化机-1',id:501201,w:37,h:12,l:535,t:468},
{name:'A5-二次固化机-2',id:501202,w:37,h:12,l:535,t:492},
{name:'A5-二次固化机-3',id:501203,w:37,h:12,l:535,t:514},
{name:'A5-钢化炉',id:501401,w:75,h:15,l:344,t:513},
{name:'A5-包装清洗机-1',id:501501,w:30,h:18,l:185,t:473},
{name:'A5-包装清洗机-2',id:501502,w:30,h:18,l:185,t:511},
{name:'A5-铺纸机-1',id:501601,w:18,h:15,l:144,t:475},
{name:'A5-铺纸机-2',id:501602,w:18,h:15,l:144,t:511}
],
eqTipMsg:{
name:'',
input:null,
output:null,
alarm:'未报警',
status:'在线'
}
}
},
props: {
scaleNum: {
type: Number,
default: 1
},
dataObj: {
type: Object,
default: () => {}
}
},
watch: {
scaleNum(val) {
this.scaleNum = val
},
dataObj(val) {
val.equipmentDets && val.equipmentDets.forEach(item => {
this.eqList.forEach(eq => {
if (eq.id == item.id) {
eq.name = item.name
eq.input = item.input
eq.output = item.output
eq.alarm = item.isError
eq.status = item.isRun
}
})
})
}
},
mounted() {},
methods: {
// 鼠标hover事件
handleMouseEnter(item, event) {
this.showTooltip = true;
this.eqTipMsg.name = item.name;
this.eqTipMsg.input = item.input;
this.eqTipMsg.output = item.output;
this.eqTipMsg.alarm = item.alarm;
this.eqTipMsg.status = item.status;
this.updateTooltipPosition(event);
},
handleMouseLeave() {
this.showTooltip = false;
},
updateTooltipPosition(event) {
const rect = this.$refs.centerTopBox.getBoundingClientRect()
const offset = 15;
const tooltipWidth = 315*this.scaleNum;
const tooltipHeight = 170*this.scaleNum;
const startX = rect.left;
const startY = rect.top;
const endX = rect.width;
const endY = rect.height;
let posX = event.clientX-startX + offset;
let posY = event.clientY-startY + offset;
if (posX + tooltipWidth > endX) {
posX = event.clientX-startX - tooltipWidth - offset;
}
if (posY + tooltipHeight > endY) {
posY = event.clientY -startY - tooltipHeight - offset;
}
this.tooltipStyle.left = posX/this.scaleNum;
this.tooltipStyle.top = posY/this.scaleNum;
}
}
}
</script>
<style lang="scss" scoped>
p{
margin: 0;
}
.centerTopBox {
width: 1041px;
height: 600px;
background: url('../../../../assets/images/dataBoard/center-top.png') no-repeat;
background-size: 100%;
position: absolute;
left: 440px;
top:113px;
overflow: hidden;
.videoStyle {
width: 1920px;
height: 1080px;
position: absolute;
left:-440px;
top:-113px;
}
.eqTipBox {
width: 315px;
height: 170px;
background: url('../../../../assets/images/dataBoard/eq-tip.png') no-repeat;
background-size: 100%;
position: absolute;
padding-top: 10px;
z-index: 1;
span{
display: inline-block;
font-size: 20px;
color: #FFFFFF;
letter-spacing: 1px;
vertical-align: middle;
}
.eqTipTitle {
width: 112px;
height: 30px;
padding-left: 15px;
}
.eqTipNum {
width: 190px;
height: 30px;
line-height: 30px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.eqBox {
span{
display: inline-block;
// border: 1px solid red;
position: absolute;
}
}
.centerTopTopBox {
padding-left: 48px;
position: absolute;
top:30px;
.num {
width: 203px;
height: 65px;
line-height: 65px;
padding-left: 10px;
box-sizing: border-box;
font-weight: 500;
font-size: 38px;
color: #FFFFFF;
text-shadow: 0px 5px 2px rgba(0,0,0,0.62);
text-align: center;
position: absolute;
top:0px;
}
.title {
font-weight: 500;
font-size: 20px;
color: #00C8F7;
letter-spacing: 2px;
text-shadow: 0px 5px 2px rgba(0,0,0,0.62);
text-align: center;
}
}
}
</style>

View File

@@ -1,108 +0,0 @@
<template>
<header class="dataBoardHeader">
<div class='topTitle'></div>
<!-- <div class='time-chsoose'>
<span class='title'>时间选择</span>
<span class='time-show'>{{time}}</span>
<el-date-picker
v-model="time"
type="date"
value-format='yyyy-MM-dd'
:clearable='false'
style='position: absolute;right: 0px;width: 119px;top:-2px;opacity: 0;'
>
</el-date-picker>
</div> -->
<div
type="text"
class="screen-btn"
:title="isFullScreen?'退出全屏':'全屏'"
@click="changeFullScreen"
>
<svg-icon v-if="isFullScreen" icon-class="unFullScreenView" />
<svg-icon v-else icon-class="fullScreenView" />
</div>
</header>
</template>
<script>
// import moment from 'moment'
export default {
name: 'DataBoardHeader',
props: {
isFullScreen: {
type: Boolean,
default: () => {
return false
}
},
},
data() {
return {
// time: moment().format('YYYY-MM-DD')
}
},
computed: {},
methods: {
changeFullScreen() {
this.$emit('screenfullChange')
},
exportPDF() {
this.$emit('exportPDF')
}
}
}
</script>
<style scoped lang="scss">
.dataBoardHeader {
background: url('../../../../assets/images/dataBoard/head.png') no-repeat;
height: 99px;
background-size: 100%;
background-position: 0 0;
position: relative;
.topTitle{
width: 465px;
height: 77px;
background: url('../../../../assets/images/dataBoard/data-board-title.png') no-repeat;
background-size: 100%;
position: absolute;
left: 731px;
top:19px;
}
.time-chsoose {
width: 212px;
height: 33px;
background: url('../../../../assets/images/dataBoard/time-choose.png') no-repeat;
background-size: 100%;
position: absolute;
right: 63px;
top:49px;
.title {
font-size: 18px;
color: #082049;
letter-spacing: 1px;
position: relative;
top: 4px;
left: 8px
}
.time-show {
font-size: 18px;
color: #FFFFFF;
line-height: 18px;
position: relative;
top: 4px;
left: 28px;
}
}
.screen-btn{
color: #00fff0;
height: 32px;
line-height: 32px;
font-size: 32px;
position: absolute;
right: 22px;
top:47px;
}
}
</style>

View File

@@ -1,286 +0,0 @@
<template>
<div class='leftBottomBox'>
<div class='title'>
<svg-icon icon-class="dataBoard2" class='icon'/>
<span>投入产出及良品率</span>
</div>
<div v-if='xData.length === 0' class='noData'>暂无数据</div>
<div v-else>
<div class="top_legend">
<span class="chart_legend_icon1">投入</span>
<span class="chart_legend_icon2">产出</span>
<span><span class="chart_legend_icon3"></span>良品率</span>
</div>
<div id='inOutputChart' style='width: 400px;height: 290px;'></div>
</div>
</div>
</template>
<script>
import * as echarts from 'echarts';
export default {
name: 'LeftBottom',
props: {
dataObj: {
type: Object,
default: () => {}
}
},
watch: {
dataObj(val) {
this.xData = []
this.inputData = []
this.outputData = []
this.goodRateData = []
val.monthBar && val.monthBar.forEach(item => {
this.xData.push(item.dataType)
this.inputData.push(item.inputNum)
this.outputData.push(item.outputNum)
this.goodRateData.push(item.goodRate)
})
this.$nextTick(()=>{
this.initChart();
})
}
},
data() {
return {
chartDom: '',
chart: '',
xData:[],
inputData:[],
outputData:[],
goodRateData:[],
}
},
mounted() {},
methods: {
initChart() {
if (
this.chart !== null &&
this.chart !== '' &&
this.chart !== undefined
) {
this.chart.dispose() // 页面多次刷新会出现警告Dom已经初始化了一个实例这是销毁实例
}
this.chartDom = document.getElementById('inOutputChart')
this.chart = echarts.init(this.chartDom)
var option;
option = {
grid: { top: 40, right: 10, bottom: 5, left: 10, containLabel: true },
legend: {
show: false,
},
xAxis: {
type: "category",
data: this.xData,
axisLabel: {
color: "#fff",
fontSize: 10,
interval: 0,
rotate:30
},
axisTick: { show: false },
axisLine: {
lineStyle: {
width: 2,
color: "#5982B2",
},
},
},
yAxis: [{
name: "单位/片",
nameTextStyle: {
color: "#DFF1FE",
fontSize: 12,
},
type: "value",
axisLabel: {
color: "#DFF1FE",
fontSize: 12,
formatter: "{value}",
},
axisLine: {
show: true,
lineStyle: {
width: 2,
color: "#5982B2",
},
},
splitLine: {
lineStyle: {
width: 2,
color: "#5982B2",
},
},
},{
name: "良品率/%",
nameTextStyle: {
color: "#DFF1FE",
fontSize: 12,
},
type: "value",
axisLabel: {
color: "#DFF1FE",
fontSize: 12,
formatter: "{value}",
},
axisLine: {
show: true,
lineStyle: {
width: 2,
color: "#5982B2",
},
},
splitLine: {
lineStyle: {
width: 2,
color: "#5982B2",
},
},
}],
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
className: "qhd-chart-tooltip",
show: true,
},
series: [
{
data: this.inputData,
type: "bar",
barWidth: 10,
barGap:0,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(157, 234, 245, 1)' },
{ offset: 1, color: 'rgba(110, 249, 222, 1)' },
]),
},
},
{
data:this.outputData,
type: "bar",
barWidth: 10,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(92, 183, 255, 1)' },
{ offset: 1, color: 'rgba(54, 75, 254, 1)' },
]),
},
},
{
data:this.goodRateData,
type: "line",
yAxisIndex: 1,
symbol:'circle',
symbolSize: 7,
color:'rgba(18, 255, 245, 1)',
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(18, 255, 245, 0.8)' },
{ offset: 0.2, color: 'rgba(18, 255, 245, 0.2)' },
{ offset: 0.4, color: 'rgba(18, 255, 245, 0)' },
]),
}
}
],
}
option && this.chart.setOption(option);
}
}
}
</script>
<style lang='scss' scoped>
.leftBottomBox {
width: 402px;
height: 332px;
background: url('../../../../assets/images/dataBoard/left-bottom.png') no-repeat;
background-size: 100%;
position: absolute;
left: 23px;
bottom:23px;
.title {
margin: 7px 0 0 15px;
.icon {
width: 32px;
height: 32px;
margin-right: 5px;
vertical-align:middle;
margin-top: 5px;
}
span {
font-size: 24px;
color: #52FFF1;
line-height: 24px;
vertical-align:middle;
}
}
.top_legend {
color: #fff;
font-size: 14px;
position: absolute;
left:120px;
top:50px;
.chart_legend_icon1{
margin-right: 10px;
}
.chart_legend_icon2{
margin-right: 14px;
}
.chart_legend_icon1:before {
display: inline-block;
content: "";
width: 10px;
height: 10px;
margin-right: 5px;
border-radius: 2px;
background: #73F8E0;
}
.chart_legend_icon2:before {
display: inline-block;
content: "";
width: 10px;
height: 10px;
margin-right: 5px;
border-radius: 2px;
background: #497EFF;
}
.chart_legend_icon3 {
display: inline-block;
width: 8px;
height: 8px;
margin-right: 8px;
border-radius: 4px;
background: #73F8E0;
position:relative;
}
.chart_legend_icon3:before {
display: inline-block;
content: "";
width: 16px;
height:2px;
background: #73F8E0;
position:absolute;
top:3px;
left:-4px;
}
}
}
.noData {
font-size: 24px;
text-align: center;
padding-top: 100px;
}
</style>
<style>
.qhd-chart-tooltip {
background: #0a2b4f77 !important;
border: none !important;
backdrop-filter: blur(12px);
}
.qhd-chart-tooltip * {
color: #fff !important;
}
</style>

View File

@@ -1,162 +0,0 @@
<template>
<div class='leftTopBox'>
<div class='title'>
<svg-icon icon-class="dataBoard1" class='icon'/>
<span>近期数据对比</span>
</div>
<div class='title-split'>
<img src="../../../../assets//images/dataBoard/leftbar.png" alt="">
<span class='text'>本日</span>
<img src="../../../../assets//images/dataBoard/rightbar.png" alt="">
</div>
<div class='data-box'>
<div class='left-icon' style="top:19px;">
<img src="../../../../assets//images/dataBoard/leftTopIcon1.png" alt="" width='54'>
<div>总投入</div>
</div>
<div class='left-icon' style="top:139px;">
<img src="../../../../assets//images/dataBoard/leftTopIcon2.png" alt="" width='48'>
<div>总生产</div>
</div>
<div class='right-data' style="top:15px;">
<p><span class='num'>{{todayData?.inputNum ? formatThousands(todayData.inputNum) : '-'}}</span><span class='text'>片数</span></p>
<p><span class='num'>{{todayData?.inputArea ? formatThousands(todayData.inputArea) : '-'}}</span><span class='text'>面积/</span></p>
</div>
<div class='right-data' style="top:132px;">
<p><span class='num'>{{todayData?.outputNum ? formatThousands(todayData.outputNum) : '-'}}</span><span class='text'>片数</span></p>
<p><span class='num'>{{todayData?.outputArea ? formatThousands(todayData.outputArea) : '-'}}</span><span class='text'>面积/</span></p>
</div>
</div>
<div class='title-split'>
<img src="../../../../assets//images/dataBoard/leftbar.png" alt="">
<span class='text'>昨日</span>
<img src="../../../../assets//images/dataBoard/rightbar.png" alt="">
</div>
<div class='data-box'>
<div class='left-icon' style="top:19px;">
<img src="../../../../assets//images/dataBoard/leftTopIcon1.png" alt="" width='54'>
<div>总投入</div>
</div>
<div class='left-icon' style="top:139px;">
<img src="../../../../assets//images/dataBoard/leftTopIcon2.png" alt="" width='48'>
<div>总生产</div>
</div>
<div class='right-data' style="top:15px;">
<p><span class='num'>{{yesterdayData?.inputNum ? formatThousands(yesterdayData.inputNum) : '-'}}</span><span class='text'>片数</span></p>
<p><span class='num'>{{yesterdayData?.inputArea ? formatThousands(yesterdayData.inputArea) : '-'}}</span><span class='text'>面积/</span></p>
</div>
<div class='right-data' style="top:132px;">
<p><span class='num'>{{yesterdayData?.outputNum ? formatThousands(yesterdayData.outputNum) : '-'}}</span><span class='text'>片数</span></p>
<p><span class='num'>{{yesterdayData?.outputArea ? formatThousands(yesterdayData.outputArea) : '-'}}</span><span class='text'>面积/</span></p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'LeftTop',
props: {
dataObj: {
type: Object,
default: () => {}
}
},
watch: {
dataObj(val) {
val.todayAndYesterday && val.todayAndYesterday.forEach(item => {
if (item.dataType === "今日") {
this.todayData = item
} else {
this.yesterdayData = item
}
})
}
},
data() {
return {
todayData:{},
yesterdayData:{}
}
},
methods: {}
}
</script>
<style lang='scss' scoped>
.leftTopBox {
width: 402px;
height: 600px;
background: url('../../../../assets/images/dataBoard/left-top.png') no-repeat;
background-size: 100%;
position: absolute;
left: 23px;
top:113px;
.title {
margin: 10px 0 0 15px;
.icon {
width: 33px;
height: 33px;
margin-right: 5px;
vertical-align:middle;
}
span {
font-size: 24px;
color: #52FFF1;
line-height: 24px;
vertical-align:middle;
}
}
.title-split {
margin-left: 95px;
margin-top: 10px;
.text{
display: inline-block;
width: 100px;
font-size: 22px;
color: #01CFCC;
line-height: 24px;
letter-spacing: 7px;
text-align: center;
}
}
.data-box {
width: 358px;
height: 230px;
background: url('../../../../assets/images/dataBoard/leftTopDataBox.png') no-repeat;
background-size: 100%;
margin-top: 8px;
position: relative;
left: 24px;
.left-icon {
font-weight: 500;
font-size: 16px;
color: #9DEAF5;
line-height: 22px;
letter-spacing: 1px;
text-shadow: 0px 4px 2px rgba(0,0,0,0.62);
position: absolute;
left: 30px;
}
.right-data {
position: absolute;
left: 100px;
p{
margin: 0;
};
.num {
font-weight: 500;
font-size: 32px;
color: #FFFFFF;
text-shadow: 0px 4px 2px rgba(0,0,0,0.62);
margin-right: 5px;
}
.text {
font-weight: 500;
font-size: 16px;
color: #FFFFFF;
letter-spacing: 1px;
text-shadow: 0px 4px 2px rgba(0,0,0,0.62);
}
}
}
}
</style>

View File

@@ -1,198 +0,0 @@
<template>
<div class='rightBottomBox'>
<div class='title'>
<svg-icon icon-class="dataBoard3" class='icon'/>
<span>本月<span class='dotted'></span>班组生产排名</span>
</div>
<div class='rankingLeft'>
<div class='rankingLeftTitle'>产量</div>
<div class='rankingTypeBox'>
<div style='margin-bottom: 10px;' v-for='(item,index) in teamProductionRank' :key='index'>
<img :src="require(`../../../../assets/images/dataBoard/ranking${index+1}.png`)" alt="" width="50">
<div class='rankingTextBox'>
<p class='text1'>{{item.name}}/</p>
<p class='text2'>{{item?.value ? formatThousands(item.value) : '-'}}</p>
</div>
</div>
</div>
</div>
<div class='rankingRight'>
<div class='rankingRightTitle'>
成品率
</div>
<div class='rankingTypeBox' style='left: 120px;'>
<div style='margin-bottom: 10px;' v-for='(item,index) in teamRateRank' :key='index'>
<img :src="require(`../../../../assets/images/dataBoard/ranking${index+1}.png`)" alt="" width="50">
<div class='rankingTextBox'>
<p class='text1'>{{item.name}}</p>
<p class='text2'>{{Math.trunc(item.value)}}<span style='font-size: 20px;'>.{{item.value1}}%</span></p>
</div>
</div>
<!-- <div>
<img src="../../../../assets//images//dataBoard/ranking2.png" alt="" width='50'>
<div class='rankingTextBox'>
<p class='text1'>班组1</p>
<p class='text2'>94<span style='font-size: 20px;'>.13%</span></p>
</div>
</div>
<div>
<img src="../../../../assets//images//dataBoard/ranking3.png" alt="" width='50'>
<div class='rankingTextBox'>
<p class='text1'>班组1</p>
<p class='text2'>90<span style='font-size: 20px;'>.42%</span></p>
</div>
</div> -->
</div>
</div>
</div>
</template>
<script>
export default {
name: 'RightBottom',
props: {
dataObj: {
type: Object,
default: () => {}
}
},
watch: {
dataObj(val) {
this.teamProductionRank = []
this.teamRateRank = []
val.teamProductionRank && val.teamProductionRank.forEach(item => {
let obj = {
name: item.name,
value: item.value,
rank: item.rank,
}
this.teamProductionRank.push(obj)
})
val.teamRateRank && val.teamRateRank.forEach(item => {
let obj = {
name: item.name,
value: item.value,
rank: item.rank,
value1: this.getPositiveDecimal(item.value)
}
this.teamRateRank.push(obj)
})
}
},
data() {
return {
teamProductionRank:[],
teamRateRank:[]
}
},
mounted() {},
methods: {
getPositiveDecimal(num) {
const str = Math.abs(num).toString();
const [, decimal] = str.split('.');
return decimal || '00';
}
}
}
</script>
<style lang='scss' scoped>
p{
margin: 0;
}
.rightBottomBox {
width: 755px;
height: 332px;
background: url('../../../../assets/images/dataBoard/right-bottom.png') no-repeat;
background-size: 100%;
position: absolute;
right: 23px;
bottom:23px;
.title {
margin: 10px 0 0 15px;
.icon {
width: 33px;
height: 33px;
margin-right: 5px;
vertical-align:middle;
}
span {
font-size: 24px;
color: #52FFF1;
line-height: 24px;
vertical-align:middle;
.dotted {
display: inline-block;
width: 4px;
height: 4px;
border-radius: 2px;
background-color: #52FFF1;
margin: 0 8px;
}
}
}
.rankingLeft {
width: 405px;
height: 265px;
background: url('../../../../assets/images/dataBoard/rankingBg1.png') no-repeat;
background-size: 100%;
position: absolute;
left: 12px;
top: 48px;
.rankingLeftTitle {
width: 24px;
height: 73px;
font-weight: 500;
font-size: 24px;
color: #52FFF1;
line-height: 55px;
position: relative;
left: 37px;
top: 63px;
}
}
.rankingRight {
width: 338px;
height: 265px;
background: url('../../../../assets/images/dataBoard/rankingBg2.png') no-repeat;
background-size: 100%;
position: absolute;
right: 12px;
top: 48px;
.rankingRightTitle {
width: 24px;
height: 132px;
font-weight: 500;
font-size: 24px;
color: #52FFF1;
line-height: 55px;
position: relative;
left: 37px;
top: 43px;
}
}
.rankingTypeBox {
position: absolute;
left: 100px;
top:13px;
.rankingTextBox {
display: inline-block;
margin-left: 16px;
vertical-align: top;
.text1 {
font-weight: 500;
font-size: 17px;
color: #FFFFFF;
line-height: 22px;
letter-spacing: 1px;
padding-top: 5px;
}
.text2 {
font-weight: 500;
font-size: 32px;
color: #FFFFFF;
line-height: 22px;
margin-top: 8px;
}
}
}
}
</style>

View File

@@ -1,352 +0,0 @@
<template>
<div class='rightTopBox'>
<div class='title'>
<svg-icon icon-class="dataBoard4" class='icon'/>
<span>缺陷情况</span>
</div>
<div class='title-split'>
<img src="../../../../assets//images/dataBoard/leftbar.png" alt="">
<span class='text'>总数</span>
<img src="../../../../assets//images/dataBoard/rightbar.png" alt="">
</div>
<div class='dataBox'>
<div class='row'>
<div class='box' style='width: 105px;'>
<p class='name'>
<span style='margin-right: 3px;'>当日</span>
<img v-show='nokSumDet.today >= nokSumDet.yesterday' src="../../../../assets/images/dataBoard/arrUp.png" alt="" width='5' height='15'>
<img v-show='nokSumDet.today < nokSumDet.yesterday' src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
</p>
<p class='num'>{{nokSumDet?.today ? formatThousands(nokSumDet.today) : '-'}}</p>
</div>
<div class='box' style='width: 115px;'>
<p class='name'>
<span style='margin-right: 3px;'>本月</span>
<img v-show='nokSumDet.month >= nokSumDet.lastMonth' src="../../../../assets/images/dataBoard/arrUp.png" alt="" width='5' height='15'>
<img v-show='nokSumDet.month < nokSumDet.lastMonth' src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
</p>
<p class='num'>{{nokSumDet?.month ? formatThousands(nokSumDet.month) : '-'}}</p>
</div>
<div class='box' style='width: 110px;'>
<p class='name'>
<span style='margin-right: 3px;'>本年</span>
<img v-show='nokSumDet.year >= nokSumDet.lastYear' src="../../../../assets/images/dataBoard/arrUp.png" alt="" width='5' height='15'>
<img v-show='nokSumDet.year < nokSumDet.lastYear' src="../../../../assets/images/dataBoard/arrDown.png" alt="" width='5' height='15'>
</p>
<p class='num'>{{nokSumDet?.year ? formatThousands(nokSumDet.year) : '-'}}</p>
</div>
</div>
<div class='row' style='padding-top: 5px;'>
<div class='box' style='width: 105px;'>
<p class='name'>
<span>昨日</span>
</p>
<p class='num'>{{nokSumDet?.yesterday ? formatThousands(nokSumDet.yesterday) : '-'}}</p>
</div>
<div class='box' style='width: 115px;'>
<p class='name'>
<span>上月</span>
</p>
<p class='num'>{{nokSumDet?.lastMonth ? formatThousands(nokSumDet.lastMonth) : '-'}}</p>
</div>
<div class='box' style='width: 110px;'>
<p class='name'>
<span>上年</span>
</p>
<p class='num'>{{nokSumDet?.lastYear ? formatThousands(nokSumDet.lastYear) : '-'}}</p>
</div>
</div>
</div>
<div class='title-split2'>
<img src="../../../../assets//images/dataBoard/leftbar.png" alt="">
<span class='text'>全厂缺陷汇总</span>
<img src="../../../../assets//images/dataBoard/rightbar.png" alt="">
</div>
<div id='defectSumChart' style='width: 400px;height: 315px;'></div>
</div>
</template>
<script>
import * as echarts from 'echarts';
const colors = [
"rgb(39, 96, 255)",
"rgb(91, 155, 255)",
"rgb(153, 214, 108)",
"rgb(18, 255, 245)",
"rgb(221, 177, 18)",
];
export default {
name: 'RightTop',
props: {
dataObj: {
type: Object,
default: () => {}
}
},
watch: {
dataObj(val) {
this.nokSumDet = val.nokSumDet
this.dataProps = []
val.nokPieDet && val.nokPieDet.forEach(item => {
let obj = {
value: item.num,
name: item.type
}
this.dataProps.push(obj)
})
this.initChart()
}
},
data() {
return {
nokSumDet:{},
chartDom: '',
chart: '',
dataProps:[],
rangArrValue:[],
dataList:[],
totalValue:0
}
},
mounted() {},
methods: {
initChart() {
if (
this.chart !== null &&
this.chart !== '' &&
this.chart !== undefined
) {
this.chart.dispose() // 页面多次刷新会出现警告Dom已经初始化了一个实例这是销毁实例
}
this.chartDom = document.getElementById('defectSumChart')
this.chart = echarts.init(this.chartDom)
var option;
this.getPersonnelList(this.dataProps)
option = {
color: colors,
graphic: [
{
type: "text",
left: "center",
top: "44%",
style: {
text: this.totalValue,
fill: "#fff",
width: 150,
height: 44,
fontSize: 31,
fontWeight: 400,
},
},
{
type: "text",
left: "center",
top: "55%",
style: {
text: "总数/件",
fill: "rgba(255, 255, 255, 0.70)",
width: 32,
height: 16,
fontSize: 16,
fontWeight: 400,
},
},
],
series: [
{
name: "产线缺陷分类",
type: "pie",
radius: ["45%", "60%"],
center: ["50%", "50%"],
label:{
formatter:function(params){
return `{color${params.dataIndex}|${params.percent}%}\n{style2|${params.name}}`
},
rich:{
color0:{color:'rgb(39, 96, 255)',fontSize:22},
color1:{color:'rgb(91, 155, 255)',fontSize:22},
color2:{color:'rgb(153, 214, 108)',fontSize:22},
color3:{color:'rgb(18, 255, 245)',fontSize:22},
color4:{color:'rgb(221, 177, 18)',fontSize:22},
color5:{color:'rgb(39, 96, 255)',fontSize:22},
color6:{color:'rgb(91, 155, 255)',fontSize:22},
color7:{color:'rgb(153, 214, 108)',fontSize:22},
color8:{color:'rgb(18, 255, 245)',fontSize:22},
color9:{color:'rgb(221, 177, 18)',fontSize:22},
style2:{
color:'#fff',
fontSize:14
}
}
},
data: this.dataList,
},
],
}
option && this.chart.setOption(option);
},
getCoordinates(startArc, endArc) {
const posi = [
Math.sin(startArc),
-Math.cos(startArc),
Math.sin(endArc),
-Math.cos(endArc),
];
const dx = posi[2] - posi[0];
const dy = posi[3] - posi[1];
return this.getLocation(dx, dy);
},
getLocation(dx,dy) {
const tanV = dx / dy;
const directSign = Math.abs(tanV) < 1;
const t = directSign ? tanV : 1 / tanV;
const sign1 = t > 0 ? 1 : -1;
const sign2 = dx > 0 ? 1 : -1;
const sign = directSign ? sign1 * sign2 : sign2;
const group1 = [0.5 - (sign * t) / 2, 0.5 + (sign * t) / 2];
const group2 = sign > 0 ? [0, 1] : [1, 0];
const group = [...group1, ...group2];
const keys = directSign ? ["x", "x2", "y", "y2"] : ["y", "y2", "x", "x2"];
let res = {};
keys.forEach((k, idx) => {
res[k] = group[idx];
});
return res;
},
async getPersonnelList(dataProps){
this.rangArrValue = [];
this.totalValue = 0;
this.dataList = [];
this.totalValue = dataProps.reduce(
(total, value) => total + value.value,
0
);
let cacheNum = 0;
for (let i = 0; i < dataProps.length; i++) {
const endNum = cacheNum + dataProps[i].value;
this.rangArrValue.push([cacheNum, endNum]);
cacheNum = endNum;
}
const angleArr = this.rangArrValue.map((arr) =>
arr.map((num) => (num / this.totalValue) * Math.PI * 2)
);
this.dataList = dataProps.map((item, index) => {
const range = this.getCoordinates(angleArr[index][0], angleArr[index][1]);
const startColor = colors[index%5];
const color = {
type: "linear",
x: range.x,
x2: range.x2,
y: range.y,
y2: range.y2,
colorStops: [
{
offset: 0,
color: startColor, // 起始颜色
},
{
offset: 1,
color: `${startColor.substring(0, startColor.length - 1)}, 0.2)`, // 终点颜色
},
],
global: false,
};
return {
name: item.name,
value: item.value,
itemStyle: {
color: color,
},
};
});
}
}
}
</script>
<style lang='scss' scoped>
p{
margin: 0;
}
.rightTopBox {
width: 402px;
height: 600px;
background: url('../../../../assets/images/dataBoard/left-top.png') no-repeat;
background-size: 100%;
position: absolute;
right: 23px;
top:113px;
.title {
margin: 10px 0 0 15px;
.icon {
width: 33px;
height: 33px;
margin-right: 5px;
vertical-align:middle;
}
span {
font-size: 24px;
color: #52FFF1;
line-height: 24px;
vertical-align:middle;
}
}
.title-split {
margin-left: 95px;
margin-top: 10px;
.text{
display: inline-block;
width: 100px;
font-size: 22px;
color: #01CFCC;
line-height: 24px;
letter-spacing: 7px;
text-align: center;
}
}
.title-split2 {
margin-left: 66px;
margin-top: 20px;
.text{
display: inline-block;
width: 160px;
font-size: 22px;
color: #01CFCC;
line-height: 24px;
letter-spacing: 2px;
text-align: center;
}
}
.dataBox {
width: 358px;
height: 160px;
background: url('../../../../assets/images/dataBoard/defectNum.png') no-repeat;
background-size: 100%;
position: relative;
left: 21px;
top:8px;
padding-left: 24px;
.row {
.box{
display: inline-block;
padding-top: 10px;
.name {
font-weight: 500;
font-size: 20px;
color: #FFFFFF;
letter-spacing: 2px;
}
.num {
font-weight: 500;
font-size: 28px;
color: #FFFFFF;
text-shadow: 0px 5px 2px rgba(0,0,0,0.62);
}
}
}
}
}
</style>

View File

@@ -1,279 +1,100 @@
<!--
filename: index.vue
author: liubin
date: 2023-10-11 09:32:04
description: 设备看板
-->
<template>
<div ref="dataBoardBoxB" class="dataBoardBoxB">
<div
id="dataBoardBox"
class="dataBoardBox"
style="width: 1920px; height: 1080px"
:style="{ transform: 'scale(' + scaleNum + ')' }">
<DataBoardHeader
:is-full-screen="isFullScreen"
@screenfullChange="screenfullChange" />
<LeftTop :dataObj="dataObj" />
<LeftBottom :dataObj="dataObj" />
<CenterTop :scaleNum="scaleNum" :dataObj="dataObj" />
<CenterBottomL :dataObj="dataObj" />
<CenterBottomR :dataObj="dataObj" />
<RightTop :dataObj="dataObj" />
<RightBottom :dataObj="dataObj" />
</div>
<div ref="dataBoard" class="data-board">
<el-button type="text" @click="goback" class="go-back--btn">返回</el-button>
</div>
</template>
<script>
import DataBoardHeader from './components/Header.vue';
import LeftTop from './components/LeftTop.vue';
import LeftBottom from './components/LeftBottom.vue';
import CenterTop from './components/CenterTop.vue';
import CenterBottomL from './components/CenterBottomL.vue';
import CenterBottomR from './components/CenterBottomR.vue';
import RightTop from './components/RightTop.vue';
import RightBottom from './components/RightBottom.vue';
import { debounce } from '@/utils/debounce';
import screenfull from 'screenfull';
import { getAccessToken } from '@/utils/auth';
import store from '@/store';
export default {
name: 'DataBoard',
components: {
DataBoardHeader,
LeftTop,
LeftBottom,
CenterTop,
CenterBottomL,
CenterBottomR,
RightTop,
RightBottom,
},
components: {},
props: {},
data() {
return {
isFullScreen: false,
scaleNum: 0.8,
dataObj: {},
sseReader: null, // 保存流读取器
abortController: null, // 用于中止 fetch 请求
retryCount: 0, // 当前重试次数
isDestroyed: false, // 标记组件是否已销毁
appMain: null, // dom
parentStyle: {
margin: '8px 14px 0px 16px',
minHeight: 'calc(100vh - 120px - 8px)',
}, // object
mainFooter: null, // dom
};
},
created() {
this.init();
},
mounted() {
this.boxReset = debounce(() => {
this.resetSize();
}, 300);
this.boxReset();
window.addEventListener('resize', () => {
this.boxReset();
});
this.getData();
},
beforeDestroy() {
this.closeSSE();
},
destroyed() {
window.removeEventListener('resize', this.boxReset);
},
computed: {
sidebarOpened() {
return this.$store.state.app.sidebar.opened;
},
},
watch: {
sidebarOpened(newVal, oldVal) {
this.boxReset();
},
},
// mounted() {
// this.$nextTick(() => {
// this.modify();
// });
// },
// activated() {
// this.modify();
// },
// deactivated() {
// this.recover();
// },
// beforeDestroy() {
// this.recover();
// },
methods: {
async getData() {
let _this = this;
if (_this.isDestroyed) return;
const url =
process.env.VUE_APP_BASE_API +
'/admin-api/monitoring/message/subscribe/' +
store.getters.userId +
'-' +
Date.now();
const token = getAccessToken();
const headers = new Headers({
Authorization: `Bearer ${token}`,
'Content-Type': 'text/event-stream',
});
try {
// 创建中止控制器
this.abortController = new AbortController();
// 发起 fetch 请求(替换为你的接口地址)
const response = await fetch(url, {
method: 'GET',
headers: headers,
signal: _this.abortController.signal, // 绑定中止信号
});
// 获取流读取器
_this.sseReader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
let receivedBytes = 0;
// 持续读取流数据
while (true) {
const { done, value } = await _this.sseReader.read();
if (done) {
console.log('SSE 连接正常关闭');
_this.handleReconnect(); // 触发重连
break;
}
// const data = decoder.decode(value);
// console.log('收到消息:', data);
receivedBytes += value.length;
console.log(
`收到数据块: ${value.length} 字节, 累计: ${receivedBytes} 字节`
);
const chunk = decoder.decode(value, { stream: true });
buffer += chunk;
// 处理完整的消息
const messages = buffer.split('\n\n'); // SSE 消息以双换行分隔
buffer = messages.pop() || ''; // 保留最后一个不完整的消息
for (const message of messages) {
if (_this.isValidData(message)) {
// console.log('完整 SSE 消息:', message);
_this.upDateMsg(message);
}
}
// 处理 SSE 事件数据
// const data = decoder.decode(value);
// console.log('收到消息:', data);
// if (_this.isValidData(data)){
// _this.upDateMsg(data);
// }
}
} catch (error) {
// 主动中止的请求不报错
if (error.name === 'AbortError') return;
console.error('SSE 连接异常:', error);
_this.handleReconnect(); // 触发重连
}
},
closeSSE() {
this.isDestroyed = true; // 标记销毁
if (this.abortController) {
this.abortController.abort(); // 中止 fetch 请求
}
if (this.sseReader) {
this.sseReader.cancel(); // 关闭流读取器
this.sseReader = null;
}
console.log('SSE 连接已强制关闭');
},
handleReconnect() {
if (this.isDestroyed) return;
// 指数退避策略(最大重试 5 次)
const maxRetries = 5;
if (this.retryCount < maxRetries) {
const delay = Math.pow(2, this.retryCount) * 1000;
setTimeout(() => {
this.retryCount++;
this.initSSE();
}, delay);
} else {
console.error('SSE 重连次数已达上限');
}
},
isValidData(data) {
return data.trim().startsWith('data:{') && !data.includes('heartbeat');
},
upDateMsg(data) {
const jsonStr = data.replace(/^data:/, '').trim();
console.log('jsonStr', jsonStr);
try {
const dataObj = JSON.parse(jsonStr);
this.dataObj = dataObj;
console.log('dataObj', this.dataObj);
} catch (e) {
console.error('JSON 解析失败:', e);
}
},
change() {
this.isFullScreen = screenfull.isFullscreen;
},
init() {
if (!screenfull.isEnabled) {
this.$message({
message: 'you browser can not work',
type: 'warning',
});
return false;
}
screenfull.on('change', this.change);
},
destroy() {
if (!screenfull.isEnabled) {
this.$message({
message: 'you browser can not work',
type: 'warning',
});
return false;
}
screenfull.off('change', this.change);
},
// 全屏
screenfullChange() {
if (!screenfull.isEnabled) {
this.$message({
message: 'you browser can not work',
type: 'warning',
});
return false;
}
screenfull.toggle(this.$refs.dataBoardBoxB);
},
resetSize() {
const dataBoardBox = document.getElementById('dataBoardBox');
const rw = parseFloat(window.innerWidth);
const rh = parseFloat(window.innerHeight);
const bw = parseFloat(dataBoardBox.style.width);
const bh = parseFloat(dataBoardBox.style.height);
let wx = 0;
let hy = 0;
if (screenfull.isFullscreen) {
wx = rw / bw;
hy = rh / bh;
} else {
if (this.$store.state.app.sidebar.opened) {
wx = (rw - 283) / bw;
} else {
wx = (rw - 88) / bw;
}
hy = (rh - 150) / bh;
}
this.scaleNum = wx < hy ? wx : hy;
},
// 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">
.dataBoardBoxB {
.data-board {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: calc(100vh - 150px);
position: relative;
overflow: auto;
.dataBoardBox {
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;
transform-origin: 16px 8px;
font-size: 16px;
top: 0px;
left: 0px;
background: url('../../../assets/images/dataBoard/background.png') no-repeat;
background-size: cover;
background-position: 0 0;
overflow: auto;
top: 6px;
right: -26px;
font-size: 24px;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -6,47 +6,77 @@
* @Description:
-->
<template>
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" v-if="visible" @keyup.enter.native="dataFormSubmit()"
label-width="100px" label-position="top">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="原料名称" prop="materialId">
<el-select v-model="dataForm.materialId" filterable @change="setCode" :style="{ width: '100%' }"
placeholder="请选择原料名称">
<el-option v-for="item in MaterialList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="原料编码" prop="code">
<el-input v-model="dataForm.code" clearable readonly />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生效开始时间" prop="startTime">
<el-date-picker v-model="dataForm.startTime" type="date" value-format="timestamp" :style="{ width: '100%' }"
placeholder="选择开始时间"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生效结束时间" prop="endTime">
<el-date-picker v-model="dataForm.endTime" type="date" value-format="timestamp" :style="{ width: '100%' }"
placeholder="选择结束时间"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单价" prop="price">
<el-input-number :min="0" style="width: 75%" v-model="dataForm.price" clearable placeholder="请输入单价" />
{{ unit }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注" prop="remark">
<el-input v-model="dataForm.remark" clearable placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-form
:model="dataForm"
:rules="dataRule"
ref="dataForm"
v-if="visible"
@keyup.enter.native="dataFormSubmit()"
label-width="100px"
label-position="top">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="原料名称" prop="materialId">
<el-select
v-model="dataForm.materialId"
filterable
@change="setCode"
:style="{ width: '100%' }"
placeholder="请选择原料名称">
<el-option
v-for="item in MaterialList"
:key="item.id"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="原料编码" prop="code">
<el-input v-model="dataForm.code" clearable readonly />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生效开始时间" prop="startTime">
<el-date-picker
v-model="dataForm.startTime"
type="date"
value-format="timestamp"
:style="{ width: '100%' }"
placeholder="选择开始时间"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生效结束时间" prop="endTime">
<el-date-picker
v-model="dataForm.endTime"
type="date"
value-format="timestamp"
:style="{ width: '100%' }"
placeholder="选择结束时间"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单价" prop="price">
<el-input-number
:min="0"
style="width: 75%"
v-model="dataForm.price"
clearable
placeholder="请输入允许留存时间" />
{{ unit }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注" prop="remark">
<el-input
v-model="dataForm.remark"
clearable
placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
@@ -116,7 +146,7 @@ export default {
this.dataForm.code = item.code;
this.unit =
'元/' +
this.urlOptions.dictArr.dict0.find((d) => d.value == item.unit)
this.urlOptions.dictArr.dict0.find((d) => d.value === item.unit)
.label;
}
});

View File

@@ -80,8 +80,18 @@ export default {
immediate: true,
},
},
methods: {
initChart() {
methods: {
getUniqueTimes() {
const { edgeCt, temperCt, downCt } = this.barData;
// 合并所有包含时间的数组
const allTimeEntries = [...(edgeCt || []), ...(temperCt || []), ...(downCt || [])];
// 提取时间戳并去重(使用 Set
const uniqueTimes = [...new Set(allTimeEntries.map(item => item.recordTime))];
// 按时间戳排序(确保时间顺序正确)
return uniqueTimes.sort((a, b) => a - b);
},
initChart() {
const uniqueTimes = this.getUniqueTimes();
const _this = this;
this.chart.setOption({
title: {
@@ -124,9 +134,7 @@ export default {
},
xAxis: {
type: 'category',
data: this.barData.edgeCt.map((item) => {
return parseTime(item.recordTime, '{m}-{d} {h}:{i}');
}),
data: uniqueTimes.map(time => parseTime(time, '{m}-{d} {h}:{i}')),
axisPointer: {
type: 'shadow',
},
@@ -152,44 +160,50 @@ export default {
end: 100,
},
],
series: [
{
name: '磨边节拍',
type: 'line',
tooltip: {
valueFormatter: function (value) {
return value + 'pcs/min';
},
},
data: this.barData.edgeCt.map((item) => {
return item.ct;
}),
},
{
name: '钢化节拍',
type: 'line',
tooltip: {
valueFormatter: function (value) {
return value + 'pcs/min';
},
},
data: this.barData.temperCt.map((item) => {
return item.ct;
}),
},
{
name: '下片节拍',
type: 'line',
tooltip: {
valueFormatter: function (value) {
return value + 'pcs/min';
},
},
data: this.barData.downCt.map((item) => {
return item.ct;
}),
},
],
series: [
{
name: '磨边节拍',
type: 'line',
tooltip: {
valueFormatter: function (value) {
return value + 'pcs/min';
},
},
data: uniqueTimes.map(time => {
// 查找当前时间对应的 ct 值,没有则补 null图表中会显示为断点
const match = this.barData.edgeCt.find(item => item.recordTime === time);
return match ? match.ct : 0;
})
},
// 钢化节拍
{
name: '钢化节拍',
type: 'line',
tooltip: {
valueFormatter: function (value) {
return value + 'pcs/min';
},
},
data: uniqueTimes.map(time => {
const match = this.barData.temperCt.find(item => item.recordTime === time);
return match ? match.ct : 0;
})
},
// 下片节拍
{
name: '下片节拍',
type: 'line',
tooltip: {
valueFormatter: function (value) {
return value + 'pcs/min';
},
},
data: uniqueTimes.map(time => {
const match = this.barData.downCt.find(item => item.recordTime === time);
return match ? match.ct : 0;
})
}
]
});
},
},

View File

@@ -47,15 +47,15 @@ const tableProps = [
prop: 'equipmentName',
label: '设备',
},
// {
// prop: 'size',
// label: '规格',
// showOverflowtooltip: true,
// },
// {
// prop: 'process',
// label: '产品工艺',
// },
{
prop: 'size',
label: '规格',
showOverflowtooltip: true,
},
{
prop: 'process',
label: '产品工艺',
},
{
prop: 'standardCt',
label: '标准节拍pcs/min',
@@ -119,16 +119,16 @@ export default {
},
methods: {
// 获取数据列表
init(lId, startTime, endTime) {
this.eqChartData = [];
this.time.startTime = startTime;
this.time.endTime = endTime;
this.dataListLoading = true;
init(lId, startTime, endTime) {
this.eqChartData = [];
this.time.startTime = startTime;
this.time.endTime = endTime;
this.dataListLoading = true;
getNewCTDet({ lineId: [lId], startTime, endTime }).then((response) => {
this.tableData = response.data;
this.dataListLoading = false;
});
},
this.tableData = response.data;
this.dataListLoading = false;
});
},
handleClick(val) {
const data = {
...this.time,

View File

@@ -183,7 +183,7 @@ export default {
// 获取当前时间
const now = new Date();
// 获取前一天的同一时间
const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);
const yesterday = new Date(now.getTime());
// 设置为00:00:00
yesterday.setHours(0, 0, 0, 0);
// 设置为23:59:59

View File

@@ -80,7 +80,7 @@ export default {
defaultSelect: [],
multiple: true,
filterable: true,
width: 400,
width: 200,
},
{
type: 'datePicker',

View File

@@ -92,7 +92,7 @@ export default {
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ prop: 'name', label: '设备类型名称' },
{ prop: 'code', label: '设备类型编码' },
{ prop: 'code', label: '检测类型编码' },
{ prop: 'remark', label: '备注' },
],
searchBarFormConfig: [

View File

@@ -66,26 +66,16 @@
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="完成单位产品用时(S)" prop="processTime">
<el-input :disabled="isdetail" v-model="dataForm.processTime" placeholder="请输入完成单位产品用时(S)" />
<el-form-item label="完成单位产品用时" prop="processTime">
<el-input :disabled="isdetail" v-model="dataForm.processTime" placeholder="请输入完成单位产品用时" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label=" 产品工艺" prop="processTypes">
<el-select :disabled="isdetail" collapse-tags multiple v-model="dataForm.processTypes" clearable
style="width: 100%" placeholder="请选择产品工艺">
<el-option v-for="dict in processTypeList" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label=" 基板类型" prop="typeDictValue">
<el-select :disabled="isdetail" v-model="dataForm.typeDictValue" clearable style="width: 100%"
placeholder="请选择基板类型">
<el-option v-for="dict in typeList" :key="dict.value" :label="dict.label" :value="dict.value" />
<el-form-item label=" 加工属性" prop="processType">
<el-select v-model="dataForm.processType" clearable style="width: 100%" :disabled="isdetail"
placeholder="请选择加工属性">
<el-option v-for="dict in processTypeList" :key="dict.id" :label="dict.label"
:value="dict.id" />
</el-select>
</el-form-item>
</el-col>
@@ -141,361 +131,317 @@
<script>
import {
deleteProductAttr,
getProductAttrPage,
deleteProductAttr,
getProductAttrPage,
} from '@/api/core/base/productAttr';
import {
createProduct,
updateProduct,
getProduct,
getCode,
createProduct,
updateProduct,
getProduct,
getCode,
} from '@/api/core/base/product';
import productAttrAdd from './attr-add';
import { parseTime } from '../../mixins/code-filter';
import SmallTitle from './SmallTitle';
import { listData } from "@/api/system/dict/data"; //数据字典接口
const tableBtn = [
{
type: 'edit',
btnName: '编辑',
},
{
type: 'delete',
btnName: '删除',
},
{
type: 'edit',
btnName: '编辑',
},
{
type: 'delete',
btnName: '删除',
},
];
const tableProps = [
{
prop: 'createTime',
label: '添加时间',
filter: parseTime,
},
{
prop: 'name',
label: '属性名',
},
{
prop: 'value',
label: '属性值',
},
{
prop: 'createTime',
label: '添加时间',
filter: parseTime,
},
{
prop: 'name',
label: '属性名',
},
{
prop: 'value',
label: '属性值',
},
];
export default {
components: { productAttrAdd, SmallTitle },
data() {
return {
visible: false,
addOrUpdateVisible: false,
tableBtn,
tableProps,
productAttributeList: [],
dataForm: {
id: null,
name: '', // 产品名称
code: '', // 产品编码
area: 0, // 深加工单位平方数(float only)
typeDictValue: null, // 产品类型id
processTime: null, // 单位产品用时 (s)
specifications: '', // 深加工规格
unitDictValue: '', // 单位id
originalSpecifications: '', // 原片规格
components: { productAttrAdd, SmallTitle },
data() {
return {
visible: false,
addOrUpdateVisible: false,
tableBtn,
tableProps,
productAttributeList: [],
dataForm: {
id: null,
name: '', // 产品名称
code: '', // 产品编码
area: 0, // 深加工单位平方数(float only)
typeDictValue: null, // 产品类型id
processTime: null, // 单位产品用时 (s)
specifications: '', // 深加工规格
unitDictValue: '', // 单位id
originalSpecifications: '', // 原片规格
originalArea: 0, // 原片单位平方数
processTypes: [],
typeDictValue: null,
},
typeList: [],
listQuery: {
pageSize: 10,
pageNo: 1,
total: 0,
processType:undefined,
},
listQuery: {
pageSize: 10,
pageNo: 1,
total: 0,
},
processTypeList: [
// {
// value: '1',
// label: '压花丝印'
// },
// {
// value: '2',
// label: '无印打孔'
// },
// {
// value: '3',
// label: '单层镀膜'
// }, {
// value: '4',
// label: '双层镀膜'
// }
{
id: '0',
label:'压花丝印'
},
{
id: '1',
label: '无印打孔'
},
{
id: '2',
label: '单层镀膜'
}, {
id: '3',
label: '双层镀膜'
}
],
dataRule: {
code: [
{
required: true,
message: '产品编码不能为空',
trigger: 'blur',
},
// {
// type: 'number',
// message: '产品编码为数字类型',
// trigger: 'blur',
// transfom: 'val => Number(val)',
// },
],
name: [
{
required: true,
message: '产品名称不能为空',
trigger: 'blur',
},
],
typeDictValue: [
{
required: true,
message: '产品类型不能为空',
trigger: 'blur',
},
],
area: [
{
type: 'number',
message: '请输入正确的数值',
trigger: 'change',
transform: (val) => Number(val),
},
],
processTime: [
{
required: true,
message: '完成单位产品用时不能为空',
trigger: 'blur',
},
{
type: 'number',
message: '请输入正确的数值',
trigger: 'blur',
transform: (val) => Number(val),
},
],
},
isdetail: false,
};
},
methods: {
async initData() {
this.productAttributeList.splice(0);
this.listQuery.total = 0;
const typeRes = await listData({
pageNo:
1,
pageSize
: 10,
dictType
: 'product_type'
})
dataRule: {
code: [
{
required: true,
message: '产品编码不能为空',
trigger: 'blur',
},
// {
// type: 'number',
// message: '产品编码为数字类型',
// trigger: 'blur',
// transfom: 'val => Number(val)',
// },
],
name: [
{
required: true,
message: '产品名称不能为空',
trigger: 'blur',
},
],
typeDictValue: [
{
required: true,
message: '产品类型不能为空',
trigger: 'blur',
},
],
area: [
{
type: 'number',
message: '请输入正确的数值',
trigger: 'change',
transform: (val) => Number(val),
},
],
processTime: [
{
required: true,
message: '完成单位产品用时不能为空',
trigger: 'blur',
},
{
type: 'number',
message: '请输入正确的数值',
trigger: 'blur',
transform: (val) => Number(val),
},
],
},
isdetail: false,
};
},
methods: {
initData() {
this.productAttributeList.splice(0);
this.listQuery.total = 0;
},
init(id, isdetail) {
this.initData();
this.isdetail = isdetail || false;
this.dataForm.id = id || null;
this.visible = true;
this.typeList = typeRes.data.list
console.log('typeRes', this.typeList);
const processTypeRes = await listData({
pageNo:
1,
pageSize
: 10,
dictType
: 'process_type'
})
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
this.processTypeList = processTypeRes.data.list
console.log('typeRes', this.typeList);
},
init(id, isdetail) {
this.initData();
this.isdetail = isdetail || false;
this.dataForm.id = id || null;
// this.dataForm.processTypes = [] // 清空工艺选择
this.visible = true;
if (this.dataForm.id) {
// 获取产品详情
getProduct(id).then((response) => {
this.dataForm = response.data;
});
// 获取产品的属性列表
this.getList();
} else {
getCode().then((res) => {
this.dataForm.code = res.data;
});
}
});
},
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
if (this.dataForm.id) {
// 获取产品详情
getProduct(id).then((res) => {
const resData = res.data || {};
// 逐个字段赋值(保留响应式)
this.dataForm.name = resData.name || '';
this.dataForm.code = resData.code || '';
this.dataForm.area = resData.area || 0;
this.dataForm.typeDictValue = resData.typeDictValue || null;
this.dataForm.processTime = resData.processTime || null;
this.dataForm.specifications = resData.specifications || '';
this.dataForm.unitDictValue = resData.unitDictValue || '';
this.dataForm.originalSpecifications = resData.originalSpecifications || '';
this.dataForm.originalArea = resData.originalArea || 0;
// 处理工艺列表:确保是数组,过滤空值
this.dataForm.processTypes = resData.processType
? resData.processType.split(',').filter(Boolean)
: [];
console.log('工艺列表(编辑时):', this.dataForm.processTypes); // 验证是否为 ["1","2"] 格式
});
// 获取产品的属性列表
this.getList();
} else {
getCode().then((res) => {
this.dataForm.code = res.data;
});
}
});
},
getList() {
// 获取产品的属性列表
getProductAttrPage({
...this.listQuery,
productId: this.dataForm.id,
}).then((response) => {
this.productAttributeList = response.data.list;
this.listQuery.total = response.data.total;
});
},
handleClick(raw) {
if (raw.type === 'delete') {
this.$confirm(
`确定对${raw.data.name
? '[名称=' + raw.data.name + ']'
: '[序号=' + raw.data._pageIndex + ']'
}进行删除操作?`,
'提示',
{
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);
}
},
// 表单提交
dataFormSubmit() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
// 修改的提交
if (this.dataForm.id) {
updateProduct(this.dataForm).then((response) => {
this.$modal.msgSuccess('修改成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
}
// 添加的提交
createProduct(this.dataForm).then((response) => {
this.$modal.msgSuccess('新增成功');
this.$confirm(`是否新增产品属性?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
getList() {
// 获取产品的属性列表
getProductAttrPage({
...this.listQuery,
productId: this.dataForm.id,
}).then((response) => {
this.productAttributeList = response.data.list;
this.listQuery.total = response.data.total;
});
},
handleClick(raw) {
if (raw.type === 'delete') {
this.$confirm(
`确定对${
raw.data.name
? '[名称=' + raw.data.name + ']'
: '[序号=' + raw.data._pageIndex + ']'
}进行删除操作?`,
'提示',
{
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);
}
},
// 表单提交
dataFormSubmit() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
// 修改的提交
if (this.dataForm.id) {
updateProduct(this.dataForm).then((response) => {
this.$modal.msgSuccess('修改成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
}
// 添加的提交
createProduct(this.dataForm).then((response) => {
this.$modal.msgSuccess('新增成功');
this.$confirm(`是否新增产品属性?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
this.dataForm.id = response.data
this.addNew();
})
.catch(() => {
this.visible = false;
this.$emit('refreshDataList');
});
});
}
});
},
goEdit() {
this.isdetail = false;
},
// 新增 / 修改
addNew(id) {
if (this.dataForm.id) {
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id);
});
} else {
this.$message('请先创建产品!');
}
},
goback() {
this.$emit('refreshDataList');
this.visible = false;
this.initData();
},
},
this.addNew();
})
.catch(() => {
this.visible = false;
this.$emit('refreshDataList');
});
});
}
});
},
goEdit() {
this.isdetail = false;
},
// 新增 / 修改
addNew(id) {
if (this.dataForm.id) {
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id);
});
} else {
this.$message('请先创建产品!');
}
},
goback() {
this.$emit('refreshDataList');
this.visible = false;
this.initData();
},
},
};
</script>
<style scoped>
.drawer>>>.el-drawer {
border-radius: 8px 0 0 8px;
display: flex;
flex-direction: column;
.drawer >>> .el-drawer {
border-radius: 8px 0 0 8px;
display: flex;
flex-direction: column;
}
.drawer>>>.el-form-item__label {
padding: 0;
.drawer >>> .el-form-item__label {
padding: 0;
}
.drawer>>>.el-drawer__header {
margin: 0;
padding: 32px 32px 24px;
border-bottom: 1px solid #dcdfe6;
.drawer >>> .el-drawer__header {
margin: 0;
padding: 32px 32px 24px;
border-bottom: 1px solid #dcdfe6;
}
.drawer >>> .el-drawer__body {
flex: 1;
height: 1px;
display: flex;
flex-direction: column;
}
.drawer>>>.el-drawer__body {
flex: 1;
height: 1px;
display: flex;
flex-direction: column;
.drawer >>> .content {
padding: 30px 24px;
flex: 1;
display: flex;
flex-direction: column;
/* height: 100%; */
}
.drawer>>>.content {
padding: 30px 24px;
flex: 1;
display: flex;
flex-direction: column;
/* height: 100%; */
.drawer >>> .visual-part {
flex: 1 auto;
max-height: 76vh;
overflow: hidden;
overflow-y: scroll;
padding-right: 10px; /* 调整滚动条样式 */
}
.drawer>>>.visual-part {
flex: 1 auto;
max-height: 76vh;
overflow: hidden;
overflow-y: scroll;
padding-right: 10px;
/* 调整滚动条样式 */
}
.drawer>>>.el-form,
.drawer>>>.attr-list {
padding: 0 16px;
.drawer >>> .el-form,
.drawer >>> .attr-list {
padding: 0 16px;
}
.drawer-body__footer {
display: flex;
justify-content: flex-end;
padding: 18px;
display: flex;
justify-content: flex-end;
padding: 18px;
}
</style>

View File

@@ -6,31 +6,17 @@
* @Description:
-->
<template>
<div class="app-container">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table
v-if="showData.length"
class="right-aside"
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:selectWidth="55"
:table-data="showData"
@selection-change="selectChange"
>
</base-table>
<div v-else class="no-data-bg"></div>
<pagination
:limit.sync="listQuery.pageSize"
:page.sync="listQuery.pageNo"
:total="listQuery.total"
@pagination="getDataList"
/>
<!-- <div v-show="false" ref="pdf">
<div class="app-container">
<search-bar :formConfigs="formConfig" ref="searchBarForm" @headBtnClick="buttonClick" />
<base-table v-if="showData.length" class="right-aside" v-loading="dataListLoading" :table-props="tableProps"
:page="listQuery.pageNo" :limit="listQuery.pageSize" :selectWidth="55" :table-data="showData"
@selection-change="selectChange">
</base-table>
<div v-else class="no-data-bg"></div>
<pagination :limit.sync="listQuery.pageSize" :page.sync="listQuery.pageNo" :total="listQuery.total"
@pagination="getDataList" />
<!-- <div v-show="false" ref="pdf">
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
@@ -39,19 +25,15 @@
:table-data="selectedList"
/>
</div> -->
<el-dialog
title="提示"
:visible.sync="dialogVisible"
width="30%"
:before-close="handleClose">
<el-button type="primary" @click="exportXlsx">xlsx</el-button>
<el-button type="success" @click="exportPdf">pdf</el-button>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="dialogVisible = false"> </el-button>
</span>
</el-dialog>
</div>
<el-dialog title="提示" :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
<el-button type="primary" @click="exportXlsx">xlsx</el-button>
<el-button type="success" @click="exportPdf">pdf</el-button>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="dialogVisible = false"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
@@ -203,7 +185,8 @@ export default {
}
],
};
},
},
created() {
this.getDataList()
this.getPdLineList()

View File

@@ -0,0 +1,132 @@
<!--
* @Author: zhp
* @Date: 2024-10-21 08:43:35
* @LastEditTime: 2024-10-21 09:10:09
* @LastEditors: zhp
* @Description: Vue2版本的标签切换组件
-->
<template>
<!-- 按钮切换 -->
<div v-if="buttonMode" class="button-nav">
<button v-for="m in menus" :key="m" :class="{ active: m === currentMenu }" :data-text="m"
@click="handleMenuChange(m)"></button>
</div>
<!-- 标签切换 -->
<div v-else class="custom-tabs" style="height: 100%; width: 100%">
<el-tabs v-model="currentMenu" class="tag-nav" style="height: 100%">
<el-tab-pane v-for="(m, idx) in menus" :key="m" :label="idx == 0 ? `\u2002${m}\u2002` : `\u3000${m}\u3000`"
:name="m">
<slot :name="`tab${idx + 1}`"></slot>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
export default {
props: {
menus: {
type: Array,
required: true,
default: () => [],
validator(val) {
return val.length > 0;
}
},
buttonMode: {
type: Boolean,
default: true
}
},
data() {
return {
currentMenu: this.menus[0] || ''
};
},
methods: {
handleMenuChange(menu) {
this.currentMenu = menu;
this.$emit('change', menu);
}
},
watch: {
currentMenu(val) {
this.$emit('change', val);
}
},
mounted() {
if (this.menus.length > 0) {
this.currentMenu = this.menus[0];
}
}
};
</script>
<style scoped>
.button-nav {
width: 100%;
padding: 12px 0;
display: flex;
gap: 12px;
}
.button-nav * {
user-select: none;
}
.button-nav button {
cursor: pointer;
appearance: none;
outline: none;
border: none;
background: #fff;
border-radius: 8px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
padding: 20px;
color: #888;
letter-spacing: 2px;
flex: 1;
box-sizing: padding-box;
position: relative;
}
.button-nav button::after {
content: attr(data-text);
position: absolute;
top: 10px;
left: 50%;
font-size: 18px;
font-weight: 500;
transform: translate(-50%);
}
.button-nav button.active {
color: #111;
border-bottom: 4px solid #0b58ff;
}
.custom-tabs /deep/ .el-tabs__header {
margin-bottom: 8px;
display: inline-block;
}
.custom-tabs /deep/ .el-tabs__item {
padding-left: 0px !important;
padding-right: 0px !important;
line-height: 36px !important;
height: 36px;
}
.custom-tabs /deep/ .el-tabs__content {
height: calc(100% - 42px);
}
.custom-tabs /deep/ .el-tab-pane {
box-sizing: border-box;
height: 100%;
padding: 20px;
border: 10px solid #f002;
}
</style>

View File

@@ -95,7 +95,7 @@ const tableProps = [
prop: 'inputN',
label: '投入',
align: 'center',
children: [
children: [
{
prop: 'inputNum',
label: '投入数量/片',

View File

@@ -1,278 +0,0 @@
<template>
<div class="baseTable">
<el-table
:ref="id"
:data="renderData"
v-bind="$attrs"
:border="cancelBorder ? false : true"
@current-change="currentChange"
@selection-change="handleSelectionChange"
style="width: 100%"
:header-cell-style="{
background: '#F2F4F9',
color: '#606266',
}">
<!-- 多选 -->
<el-table-column
v-if="selectWidth"
type="selection"
:width="selectWidth" />
<!-- 序号 -->
<el-table-column
v-if="page && limit"
prop="_pageIndex"
:width="pageWidth"
align="center"
:fixed="cancelPageFixed ? false : true">
<template slot="header">
<el-popover placement="bottom-start" width="300" trigger="click">
<div
class="setting-box"
style="max-height: 400px; overflow-y: auto">
<el-checkbox
v-for="(item, index) in tableProps"
:key="'cb' + index"
v-model="selectedBox[index]"
:label="item.label" />
</div>
<i slot="reference" class="el-icon-s-tools" />
</el-popover>
</template>
</el-table-column>
<el-table-column
v-for="item in renderTableHeadList"
:key="item.prop"
v-bind="item"
:label="item.label"
:prop="item.prop"
:fixed="item.fixed || false"
:show-overflow-tooltip="item.showOverflowtooltip || false"
:sortable="item.sortable || false">
<template slot="header">
<span>{{ item.label }}</span>
</template>
<!-- 多表头 -->
<template v-if="item.children">
<el-table-column
v-for="sub in item.children"
:prop="sub.prop"
:key="sub.prop"
v-bind="sub"
:label="sub.label">
<template v-if="sub.children">
<el-table-column
v-for="ssub in sub.children"
:prop="ssub.prop"
:key="ssub.prop"
v-bind="ssub"
:label="ssub.label">
<template slot-scope="sscopeInner">
<component
:is="ssub.subcomponent"
v-if="ssub.subcomponent"
:key="sscopeInner.row.id"
:inject-data="{ ...sscopeInner.row, ...ssub }"
@emitData="emitData" />
<span v-else>
{{ sscopeInner.row[ssub.prop] | commonFilter(ssub.filter) }}
</span>
</template>
</el-table-column>
</template>
<template slot-scope="scopeInner">
<component
:is="sub.subcomponent"
v-if="sub.subcomponent"
:key="scopeInner.row.id"
:inject-data="{ ...scopeInner.row, ...sub }"
@emitData="emitData" />
<span v-else>
{{ scopeInner.row[sub.prop] | commonFilter(sub.filter) }}
</span>
</template>
</el-table-column>
</template>
<template slot-scope="scope">
<component
:is="item.subcomponent"
v-if="item.subcomponent"
:key="scope.row.id"
:itemProp="item.prop"
:inject-data="{ ...scope.row, ...item }"
@emitData="emitData" />
<span v-else>
{{ scope.row[item.prop] | commonFilter(item.filter) }}
</span>
</template>
</el-table-column>
<slot name="handleBtn" />
</el-table>
<!-- 表格底部加号 -->
<el-button
v-if="addButtonShow"
class="addButton"
icon="el-icon-plus"
@click="emitButtonClick">
{{ addButtonShow }}
</el-button>
</div>
</template>
<script>
export default {
name: 'BaseTable',
filters: {
commonFilter: (source, filterType = (a) => a) => {
return filterType(source);
},
},
props: {
cancelBorder: {
type: Boolean,
default: false,
},
cancelPageFixed: {
type: Boolean,
default: false,
},
tableData: {
type: Array,
required: true,
default: () => {
return [];
},
},
tableProps: {
type: Array,
default: () => {
return [];
},
},
id: {
type: String,
required: false,
default: '',
},
page: {
type: Number,
required: false,
default: 0,
},
pageWidth: {
type: Number,
required: false,
default: 70,
},
limit: {
type: Number,
required: false,
default: 0,
},
selectWidth: {
type: Number,
required: false,
default: 0,
},
addButtonShow: {
type: String,
required: false,
default: '',
},
},
data() {
return {
selectedBox: new Array(100).fill(true),
};
},
computed: {
renderTableHeadList() {
return this.tableProps.filter((item, index) => {
return this.selectedBox[index];
});
},
renderData() {
return this.tableData.map((item, index) => {
return {
...item,
_pageIndex: (this.page - 1) * this.limit + index + 1,
};
});
},
},
beforeMount() {
this.selectedBox = new Array(100).fill(true);
},
methods: {
currentChange(newVal, oldVal) {
this.$emit('current-change', { newVal, oldVal });
},
handleSelectionChange(val) {
this.$emit('selection-change', val);
},
emitData(val) {
this.$emit('emitFun', val);
},
emitButtonClick() {
this.$emit('emitButtonClick');
},
setCurrent(name, index) {
let _this = this;
let obj = _this.$refs[name].data[index];
_this.$refs[name].setCurrentRow(obj);
},
doLayout(name) {
this.$refs[name].doLayout();
},
},
};
</script>
<!-- <style scoped>
.baseTable .show-col-btn {
margin-right: 5px;
line-height: inherit;
cursor: pointer;
}
.baseTable .el-icon-refresh {
cursor: pointer;
}
.baseTable >>> .el-table .el-table__cell {
padding: 0;
height: 35px;
border: 1px solid rgb(220, 220, 220);
}
</style>
<style>
.baseTable .el-table__body tr.current-row > td.el-table__cell {
background-color: #eaf1fc;
}
.baseTable .el-table .el-table__cell {
padding: 0;
height: 35px;
}
.baseTable .addButton {
width: 100%;
height: 35px;
border-top: none;
color: #0b58ff;
border-color: #ebeef5;
border-radius: 0;
}
.baseTable .addButton:hover {
color: #0b58ff;
border-color: #ebeef5;
background-color: #fff;
}
.baseTable .addButton:focus {
border-color: #ebeef5;
background-color: #fff;
}
.el-tooltip__popper.is-dark {
background: rgba(0, 0, 0, 0.6) !important;
}
.el-tooltip__popper .popper__arrow,
.el-tooltip__popper .popper__arrow::after {
border-top-color: rgba(0, 0, 0, 0.4) !important;
}
</style> -->

View File

@@ -1,331 +0,0 @@
<!--
* @Author: zwq
* @Date: 2023-08-24 14:47:58
* @LastEditors: zwq
* @LastEditTime: 2025-02-25 14:03:40
* @Description:
-->
<template>
<div>
<search-bar :formConfigs="formConfig" ref="searchBarForm" @headBtnClick="buttonClick" />
<el-table id="detail" :data="tableData" :header-cell-style="{
background: '#F2F4F9',
color: '#606266',
}" border v-loading="dataListLoading" style="width: 100%" ref="dataList">
<el-table-column prop="lineName" label="产线" align="center" />
<!-- <el-table-column prop="sizes" width="105" showOverflowtooltip align="center" label="规格" /> -->
<!-- <el-table-column prop="process" label="产品工艺" align="center" /> -->
<el-table-column prop="inputN" label="磨边" align="center">
<el-table-column prop="edgeNum" label="投入数量/片" />
<el-table-column prop="edgeTime" label="数据上报时间">
<template v-slot="scope">
<span>
{{
scope.row.reportType === 0
? parseTime(scope.row.edgeTime)
: '-'
}}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="outputN" label="打孔/丝印" align="center">
<el-table-column prop="drillCoating" label="投入数量">
<template v-slot="scope">
<span>
{{
(scope.row.drillNum ?? '-')
+ '/'
+ (scope.row.coatingNum ?? '-')
}}
</span>
</template>
</el-table-column>
<el-table-column prop="coatingTime" label="数据上报时间">
<template v-slot="scope">
<span>
{{
scope.row.reportType === 0
? parseTime(scope.row.coatingTime)
: '-'
}}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="lossN" label="镀膜" align="center">
<el-table-column prop="silkNum" label="投入数量" />
<el-table-column prop="silkTime" label="数据上报时间">
<template v-slot="scope">
<span>
{{
scope.row.reportType === 0
? parseTime(scope.row.silkTime)
: '-'
}}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="lossN" label="钢化" align="center">
<el-table-column prop="temperingNum" label="投入数量" />
<el-table-column prop="temperingTime" label="数据上报时间">
<template v-slot="scope">
<span>
{{
scope.row.reportType === 0
? parseTime(scope.row.temperingTime)
: '-'
}}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="lossN" label="包装" align="center">
<el-table-column prop="packingNum" label="投入数量" />
<el-table-column prop="packingTime" label="数据上报时间">
<template v-slot="scope">
<span>
{{
scope.row.reportType === 0
? parseTime(scope.row.packingTime)
: '-'
}}
</span>
</template>
</el-table-column>
</el-table-column>
<!-- <el-table-column prop="lossRatio" label="不良率/%">
<template v-slot="scope">
<span>
{{
scope.row.lossRatio != null ? scope.row.lossRatio.toFixed(2) : '-'
}}
</span>
</template>
</el-table-column>
<el-table-column prop="outputRatio" label="投入产出率/%">
<template v-slot="scope">
<span>
{{
scope.row.outputRatio != null
? scope.row.outputRatio.toFixed(2)
: '-'
}}
</span>
</template>
</el-table-column>
<el-table-column prop="processingRatio" label="加工成品率/%">
<template v-slot="scope">
<span>
{{
scope.row.processingRatio != null
? scope.row.processingRatio.toFixed(2)
: '-'
}}
</span>
</template>
</el-table-column>
<el-table-column prop="lossD" label="不良详情" align="center">
<el-table-column prop="original" label="原片" align="center">
<el-table-column prop="originalLossNum" label="原片不良/片" />
<el-table-column prop="originalLossArea" label="原片不良/m²">
<template v-slot="scope">
<span>
{{
scope.row.originalLossArea != null
? scope.row.originalLossArea.toFixed(2)
: '-'
}}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="edge" label="磨边" align="center">
<el-table-column prop="edgeLossNum" label="磨边不良/片" />
<el-table-column prop="edgeLossArea" label="磨边不良/m²">
<template v-slot="scope">
<span>
{{
scope.row.edgeLossArea != null
? scope.row.edgeLossArea.toFixed(2)
: '-'
}}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="drill" label="打孔" align="center">
<el-table-column prop="drillLossNum" label="打孔不良/片" />
<el-table-column prop="drillLossArea" label="打孔不良/m²">
<template v-slot="scope">
<span>
{{
scope.row.drillLossArea != null
? scope.row.drillLossArea.toFixed(2)
: '-'
}}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="coating" label="镀膜" align="center">
<el-table-column prop="coatingLossNum" label="镀膜不良/片" />
<el-table-column prop="coatingLossArea" label="镀膜不良/m²">
<template v-slot="scope">
<span>
{{
scope.row.coatingLossArea != null
? scope.row.coatingLossArea.toFixed(2)
: '-'
}}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="silk" label="丝印" align="center">
<el-table-column prop="silkLossNum" label="丝印不良/片" />
<el-table-column prop="silkLossArea" label="丝印不良/m²">
<template v-slot="scope">
<span>
{{
scope.row.silkLossArea != null
? scope.row.silkLossArea.toFixed(2)
: '-'
}}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="tempering" label="钢化" align="center">
<el-table-column prop="temperingLossNum" label="钢化不良/片" />
<el-table-column prop="temperingLossArea" label="钢化不良/m²">
<template v-slot="scope">
<span>
{{
scope.row.temperingLossArea != null
? scope.row.temperingLossArea.toFixed(2)
: '-'
}}
</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column prop="down" label="下片" align="center">
<el-table-column prop="downNum" label="成品数量" />
<el-table-column prop="scrapNum" label="废片数量" />
<el-table-column prop="inputOutputRate" label="投入产出率" />
<el-table-column prop="yieldRate" label="加工成品率" />
</el-table-column>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { getTeamReportPageDet, exportGroupProductReportExcel } from '@/api/core/monitoring/auto';
import * as XLSX from 'xlsx';
import FileSaver from 'file-saver';
export default {
components: {},
data() {
return {
tableData: [],
id:null,
dataListLoading: false,
formConfig: [
{
// type: this.$auth.hasPermi('base:factory:export') ? 'button' : '',
type: 'button',
btnName: '导出',
name: 'export',
color: 'warning',
},
],
};
},
components: {},
created() {},
mounted() {},
methods: {
// 获取数据列表
init(id) {
this.id = id
this.dataListLoading = true;
getTeamReportPageDet(id).then((response) => {
this.tableData = response.data?.map((item, index) => {
item.originalLossNum = item.original?.lossNum;
item.originalLossArea = item.original?.lossArea;
item.edgeLossNum = item.edge?.lossNum;
item.edgeLossArea = item.edge?.lossArea;
item.drillLossNum = item.drill?.lossNum;
item.drillLossArea = item.drill?.lossArea;
item.coatingLossNum = item.coating?.lossNum;
item.coatingLossArea = item.coating?.lossArea;
item.silkLossNum = item.silk?.lossNum;
item.silkLossArea = item.silk?.lossArea;
item.temperingLossNum = item.tempering?.lossNum;
item.temperingLossArea = item.tempering?.lossArea;
item.packingLossNum = item.packing?.lossNum;
item.packingLossArea = item.packing?.lossArea;
if (item.isSummaryReport) {
item.lineName = '合计';
}
return item;
});
this.dataListLoading = false;
});
},
// arraySpanMethod({ row, column, rowIndex, columnIndex }) {
// if (row.isSummaryReport) {
// if (columnIndex === 0) {
// return [1, 3];
// } else if (columnIndex === 1) {
// return [0, 0];
// } else if (columnIndex === 2) {
// return [0, 0];
// }
// }
// },
buttonClick(val) {
switch (val.btnName) {
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
handleExport() {
this.$modal.confirm('是否确认导出').then(() => {
return exportGroupProductReportExcel({id:this.id});
}).then(response => {
console.log(response)
this.$download.excel(response, '班组生产报表-详情.xls');
}).catch(() => {})
// let tables = document.querySelector('#detail').cloneNode(true);
// let exportTable = XLSX.utils.table_to_book(tables);
// var exportTableOut = XLSX.write(exportTable, {
// bookType: 'xlsx',
// bookSST: true,
// type: 'array',
// });
// // sheetjs.xlsx为导出表格的标题名称
// try {
// FileSaver.saveAs(
// new Blob([exportTableOut], {
// type: 'application/octet-stream',
// }),
// '班组生产报表-详情.xlsx'
// );
// } catch (e) {
// if (typeof console !== 'undefined') console.log(e, exportTableOut);
// }
// return exportTableOut;
},
},
};
</script>

View File

@@ -1,594 +0,0 @@
<!--
* @Author: Do not edit
* @Date: 2023-08-29 14:59:29
* @LastEditTime: 2025-02-25 14:26:04
* @LastEditors: zwq
* @Description:
-->
<template>
<div class="app-container">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<base-table-s
v-if="showData.length"
class="right-aside"
v-loading="dataListLoading"
:table-props="tableProps"
:page="listQuery.pageNo"
:limit="listQuery.pageSize"
:table-data="showData">
<method-btn
v-if="showData.length"
slot="handleBtn"
:width="80"
label="操作"
:method-list="tableBtn"
@clickBtn="handleClick" />
</base-table-s>
<div v-else class="no-data-bg"></div>
<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"
close-on-click-modal
top="0"
width="80%">
<gr-detail ref="grDetail" />
<slot name="footer">
<el-row slot="footer" type="flex" justify="end">
<el-col :span="24">
<el-button size="small" class="btnTextStyle" @click="handleCancel">
取消
</el-button>
</el-col>
</el-row>
</slot>
</base-dialog>
</div>
</template>
<script>
import grDetail from './gr-detail';
import { getTeamReportPage } from '@/api/core/monitoring/auto';
import { getFactoryPage } from '@/api/core/base/factory';
import { getGroupTeamPage } from '@/api/base/groupTeam';
// import codeFilter from '../../mixins/code-filter'
import * as XLSX from 'xlsx';
import FileSaver from 'file-saver';
import baseTableS from './baseTable.vue';
import { parseTime } from '@/filter/code-filter';
const tableProps = [
{
prop: 'reportType',
label: '报表类型',
fixed: true
},
{
prop: 'reportDate',
label: '日期',
width: 180,
fixed: true
},
{
prop: 'factoryName',
label: '工厂',
fixed: true
},
{
prop: 'teamName',
label: '班组',
fixed: true
},
{
prop: 'edgeNum',
label: '磨边',
fixed: true
}, {
prop: 'drillOrCoating',
label: '打孔/丝印',
fixed: true
}, {
prop: 'silkNum',
label: '镀膜',
fixed: true
}, {
prop: 'temperingNum',
label: '钢化',
fixed: true
}, {
prop: 'packingNum',
label: '包装',
fixed: true
},
{
prop: 'inputN',
label: '下片',
align: 'center',
children: [
{
prop: 'downNum',
label: '成品数量',
width:100
},
{
prop: 'scrapNum',
label: '废片数量',
width:100
},
{
prop: 'inputOutputRate',
label: '投入产出率',
width: 100
},
{
prop: 'yieldRate',
label: '加工成品率',
width: 100
},
],
},
// {
// prop: 'outputN',
// label: '产出',
// align: 'center',
// children: [
// {
// prop: 'outputNum',
// label: '产出数量/片',
// width:100
// },
// {
// prop: 'outputArea',
// label: '产出面积/㎡',
// filter: (val) => (val != null ? val.toFixed(2) : '-'),
// width:100
// },
// ],
// },
// {
// prop: 'lossN',
// label: '不良',
// align: 'center',
// children: [
// {
// prop: 'lossNum',
// label: '不良数量/片',
// width:100
// },
// {
// prop: 'lossArea',
// label: '不良面积/㎡',
// filter: (val) => (val != null ? val.toFixed(2) : '-'),
// width:100
// },
// ],
// },
// {
// prop: 'lossRatio',
// label: '不良率/%',
// filter: (val) => (val != null ? val.toFixed(2) : '-'),
// width:100
// },
// {
// prop: 'outputRatio',
// label: '投入产出率/%',
// filter: (val) => (val != null ? val.toFixed(2) : '-'),
// width:110
// },
// {
// prop: 'processingRatio',
// label: '加工成品率/%',
// filter: (val) => (val != null ? val.toFixed(2) : '-'),
// width:110
// },
// {
// prop: 'lossD',
// label: '不良详情',
// align: 'center',
// children: [
// {
// prop: 'original',
// label: '原片',
// align: 'center',
// children: [
// {
// prop: 'originalLossNum',
// label: '原片不良/片',
// width:100
// },
// {
// prop: 'originalLossArea',
// label: '原片不良/㎡',
// filter: (val) => (val != null ? val.toFixed(2) : '-'),
// width:100
// },
// ],
// },
// {
// prop: 'edge',
// label: '磨边',
// align: 'center',
// children: [
// {
// prop: 'edgeLossNum',
// label: '磨边不良/片',
// width:100
// },
// {
// prop: 'edgeLossArea',
// label: '磨边不良/㎡',
// filter: (val) => (val != null ? val.toFixed(2) : '-'),
// width:100
// },
// ],
// },
// {
// prop: 'drill',
// label: '打孔',
// align: 'center',
// children: [
// {
// prop: 'drillLossNum',
// label: '打孔不良/片',
// width:100
// },
// {
// prop: 'drillLossArea',
// label: '打孔不良/㎡',
// filter: (val) => (val != null ? val.toFixed(2) : '-'),
// width:100
// },
// ],
// },
// {
// prop: 'coating',
// label: '镀膜',
// align: 'center',
// children: [
// {
// prop: 'coatingLossNum',
// label: '镀膜不良/片',
// width:100
// },
// {
// prop: 'coatingLossArea',
// label: '镀膜不良/㎡',
// filter: (val) => (val != null ? val.toFixed(2) : '-'),
// width:100
// },
// ],
// },
// {
// prop: 'silk',
// label: '丝印',
// align: 'center',
// children: [
// {
// prop: 'silkLossNum',
// label: '丝印不良/片',
// width:100
// },
// {
// prop: 'silkLossArea',
// label: '丝印不良/㎡',
// filter: (val) => (val != null ? val.toFixed(2) : '-'),
// width:100
// },
// ],
// },
// {
// prop: 'tempering',
// label: '钢化',
// align: 'center',
// children: [
// {
// prop: 'temperingLossNum',
// label: '钢化不良/片',
// width:100
// },
// {
// prop: 'temperingLossArea',
// label: '钢化不良/㎡',
// filter: (val) => (val != null ? val.toFixed(2) : '-'),
// width:100
// },
// ],
// },
// {
// prop: 'packing',
// label: '包装',
// align: 'center',
// children: [
// {
// prop: 'packingLossNum',
// label: '包装不良/片',
// width:100
// },
// {
// prop: 'packingLossArea',
// label: '包装不良/㎡',
// filter: (val) => (val != null ? val.toFixed(2) : '-'),
// width:100
// },
// ],
// },
// ],
// },
];
export default {
components: {
baseTableS,
grDetail,
},
data() {
return {
urlOptions: {
getDataListURL: getTeamReportPage,
},
listQuery: {
reportType: 1,
pageSize: 10,
pageNo: 1,
startTime: undefined,
endTime: undefined,
total: 1,
},
fileName: '',
dataListLoading: false,
tableProps,
tableBtn: [
this.$auth.hasPermi(`monitoring:group-off:update`)
? {
type: 'eq',
btnName: '详情',
}
: undefined,
].filter((v) => v),
showData: [],
tableData: [],
formConfig: [
{
type: 'select',
label: '工厂',
selectOptions: [],
param: 'factoryId',
},
{
type: 'select',
label: '班组',
selectOptions: [],
param: 'teamId',
},
{
type: 'select',
label: '报表类型',
selectOptions: [
{
id: 0,
name: '班',
},
{
id: 1,
name: '日',
},
// {
// id: 2,
// name: '周',
// },
{
id: 3,
name: '月',
},
{
id: 4,
name: '年',
},
],
defaultSelect: 1,
param: 'reportType',
},
{
type: 'datePicker',
label: '时间范围',
dateType: 'daterange',
format: 'yyyy-MM-dd',
valueFormat: 'timestamp',
rangeSeparator: '-',
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
param: 'timeVal',
},
{
type: this.$auth.hasPermi('monitoring:group-off:query') ? 'button' : '',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: this.$auth.hasPermi('monitoring:group-off:export') ? 'button' : '',
// type: 'button',
btnName: '导出',
name: 'export',
color: 'warning',
},
],
addOrEditTitle: '',
addOrUpdateVisible: false,
};
},
created() {
// 获取当前时间
const now = new Date();
// 获取前一天的同一时间
const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);
// 设置为00:00:00
yesterday.setHours(0, 0, 0, 0);
// 设置为23:59:59
const end = new Date(yesterday.getTime());
end.setHours(23, 59, 59, 59);
this.listQuery.startTime = yesterday.getTime(), [end.getTime()];
this.listQuery.endTime = end.getTime()
this.$nextTick(() => {
this.$refs.searchBarForm.formInline.timeVal = [yesterday.getTime(),end.getTime()];
});
this.getDataList();
this.getPdLineList();
},
methods: {
handleExport() {
let tables = document.querySelector('.el-table').cloneNode(true);
const fix = tables.querySelector('.el-table__fixed');
const fixRight = tables.querySelector('.el-table__fixed-right');
if (fix) {
tables.removeChild(tables.querySelector('.el-table__fixed'));
}
if (fixRight) {
tables.removeChild(tables.querySelector('.el-table__fixed-right'));
}
let exportTable = XLSX.utils.table_to_book(tables);
exportTable.Sheets.Sheet1.A1.v = '序号' //导出表格第一列表头为序号
var exportTableOut = XLSX.write(exportTable, {
bookType: 'xlsx',
bookSST: true,
type: 'array',
});
// sheetjs.xlsx为导出表格的标题名称
try {
FileSaver.saveAs(
new Blob([exportTableOut], {
type: 'application/octet-stream',
}),
this.fileName + '班组生产报表.xlsx'
);
} catch (e) {
if (typeof console !== 'undefined') console.log(e, exportTableOut);
}
return exportTableOut;
},
getPdLineList() {
const params = {
pageSize: 100,
pageNo: 1,
};
getGroupTeamPage(params).then((res) => {
this.formConfig[1].selectOptions = res.data.list || [];
});
getFactoryPage(params).then((res) => {
this.formConfig[0].selectOptions = res.data.list || [];
});
},
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 10;
this.listQuery.factoryId = val.factoryId || undefined;
this.listQuery.teamId = val.teamId || undefined;
this.listQuery.reportType = val.reportType || undefined;
this.listQuery.startTime = val.timeVal
? val.timeVal[0]
: undefined;
this.listQuery.endTime = val.timeVal
? val.timeVal[1]
: undefined;
this.getDataList();
break;
case 'export':
this.handleExport();
break;
default:
console.log(val);
}
},
// 获取数据列表
getDataList() {
this.dataListLoading = true;
console.log(this.listQuery);
const arr = ['班', '日', '', '月', '年']; // 索引0对应班1对应日3对应月4对应年索引2留空
this.urlOptions.getDataListURL(this.listQuery).then((response) => {
if (!response.data.list) {
this.showData = [];
this.dataListLoading = false;
return;
}
this.tableData = response.data?.list.map((item, index) => {
item.reportType = arr[item.reportType] || item.reportType;
item.drillOrCoating = item.drillNum + "/" + item.coatingNum
item.originalLossNum = item.original?.lossNum;
item.originalLossArea = item.original?.lossArea;
item.edgeLossNum = item.edge?.lossNum;
item.edgeLossArea = item.edge?.lossArea;
item.drillLossNum = item.drill?.lossNum;
item.drillLossArea = item.drill?.lossArea;
item.coatingLossNum = item.coating?.lossNum;
item.coatingLossArea = item.coating?.lossArea;
item.silkLossNum = item.silk?.lossNum;
item.silkLossArea = item.silk?.lossArea;
item.temperingLossNum = item.tempering?.lossNum;
item.temperingLossArea = item.tempering?.lossArea;
item.packingLossNum = item.packing?.lossNum;
item.packingLossArea = item.packing?.lossArea;
return item;
});
this.listQuery.total = response.data?.total;
this.dataListLoading = false;
this.showData = this.tableData;
});
},
handleClick(val) {
this.addOrUpdateVisible = true;
const time = val.data.timeVal ? parseTime(val.data.timeVal[0]) + '-' + parseTime(val.data.timeVal[1]) : '- '
const teamName = val.data.teamName?val.data.teamName:'- '
const teamLeader = val.data.teamLeader?val.data.teamLeader:'- '
this.addOrEditTitle =
'时间:' +
time +
' 班组:' +
teamName +
' 组长:' +
teamLeader +
' 详情';
this.$nextTick(() => {
this.$refs.grDetail.init(val.data.id);
});
},
handleCancel() {
this.addOrUpdateVisible = false;
this.addOrEditTitle = '';
},
handleConfirm() {
this.handleCancel();
},
// 每页数
sizeChangeHandle(val) {
this.listQuery.pageSize = val;
this.listQuery.pageNo = 1;
this.getDataList();
},
// 当前页
currentChangeHandle(val) {
this.listQuery.pageNo = val;
this.getDataList();
},
},
};
</script>

View File

@@ -262,14 +262,6 @@ export default {
tooltip: {
valueFormatter: (value) => `${value} %`,
},
label: {
show: true,
position: 'top',
distance: 6,
fontSize: 11,
color: '#333333',
formatter: (params) => `${params.value}` // 显示单位
},
data: this.barData.map((item) => item.processingRatio),
},
],

View File

@@ -34,7 +34,7 @@
<el-tabs v-model="activeLabel" :stretch="true" @tab-click="handleTabClick">
<el-tab-pane :label="'全部数据'" name="table">
<base-table-s ref="lineCurrentShiftTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'"
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData" :max-height="300" />
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData" :max-height="210" />
</el-tab-pane>
<el-tab-pane :label="'\u3000当天生产折线图\u3000'" name="graph">
<div style="height: 230px;" v-if="activeLabel == 'graph'" class="graph">
@@ -57,7 +57,7 @@
<el-tabs v-model="activeLabelDay" :stretch="true" @tab-click="handleTabClick">
<el-tab-pane :label="'全部数据'" name="table">
<base-table-s ref="lineTodayTable" style="margin-bottom: 16px;" v-if="activeLabelDay == 'table'"
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData2" :max-height="300" />
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData2" :max-height="210" />
</el-tab-pane>
<el-tab-pane :label="'\u3000当天生产折线图\u3000'" name="graph">
<div style="height: 230px;" v-if="activeLabelDay == 'graph'" class="graph">
@@ -71,55 +71,9 @@
</el-row>
</div>
</div>
<div class="content-inner" v-if="listQuery.timeType === 3">
<!-- 当班数据占1/2剩余高度 -->
<div class="content-card energyOverlimitLog">
<span class="blue-block"></span>
<span class="tip">上一班数据</span>
<el-row style="margin-top: 10px;">
<el-col class="custom-tabs">
<el-tabs v-model="activeLabel" :stretch="true" @tab-click="handleTabClick">
<el-tab-pane :label="'全部数据'" name="table">
<base-table-s ref="lineCurrentShiftTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'"
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData" :max-height="300" />
</el-tab-pane>
<el-tab-pane :label="'\u3000当天生产折线图\u3000'" name="graph">
<div style="height: 230px;" v-if="activeLabel == 'graph'" class="graph">
<barChart v-if="tableData && tableData.length > 0" ref="barChart" height="230px"
:bar-data="tableData" />
<div v-else class="no-data-bg"></div>
</div>
</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
</div>
<!-- 当天数据占1/2剩余高度 -->
<div class="content-card energyOverlimitLog">
<span class="blue-block"></span>
<span class="tip">当天数据</span>
<el-row style="margin-top: 10px;">
<el-col class="custom-tabs">
<el-tabs v-model="activeLabelDay" :stretch="true" @tab-click="handleTabClick">
<el-tab-pane :label="'全部数据'" name="table">
<base-table-s ref="lineTodayTable" style="margin-bottom: 16px;" v-if="activeLabelDay == 'table'"
:page="1" :limit="100" :table-props="tableProps" :table-data="tableData2" :max-height="300" />
</el-tab-pane>
<el-tab-pane :label="'\u3000当天生产折线图\u3000'" name="graph">
<div style="height: 230px;" v-if="activeLabelDay == 'graph'" class="graph">
<barChart v-if="tableData2 && tableData2.length > 0" ref="barChart" height="230px"
:bar-data="tableData2" />
<div v-else class="no-data-bg"></div>
</div>
</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
</div>
</div>
<!-- 3.2 时间维度为自定义时的内容两个平分高度的div -->
<div class="content-inner" v-if="listQuery.timeType === 2">
<div class="content-inner" v-else>
<div class="content-card energyOverlimitLog">
<span class="blue-block"></span>
<span class="tip" v-if="listQuery.startTime && listQuery.endTime">
@@ -132,7 +86,7 @@
<span class="tip" v-else>生产表格数据 </span>
<div class="graph">
<base-table-s ref="lineCustomTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'" :page="1"
:limit="100" :table-props="tableProps" :max-height="300" :table-data="tableDataCustom" />
:limit="100" :table-props="tableProps" :max-height="210" :table-data="tableDataCustom" />
</div>
</div>
@@ -159,7 +113,7 @@
<span class="tip">当班数据</span>
<base-table-s ref="productCurrentShiftTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'"
:page="1" :limit="100" :table-props="productTableProps" :table-data="productTableData"
:max-height="300" />
:max-height="210" />
</div>
<!-- 当天数据占1/2剩余高度 -->
@@ -168,7 +122,7 @@
<span class="tip">当天数据</span>
<base-table-s ref="productTodayTable" style="margin-bottom: 16px;" v-if="activeLabelDay == 'table'"
:page="1" :limit="100" :table-props="productTablePropsDay" :table-data="productTableDataDay"
:max-height="300" />
:max-height="210" />
</div>
</div>
</div>
@@ -188,7 +142,7 @@
</span>
<span class="tip" v-else>生产表格数据 </span>
<base-table-s ref="productCustomTable" style="margin-bottom: 16px;" v-if="activeLabel == 'table'" :page="1"
:limit="100" :table-props="productTableProps" :table-data="productTableData" :max-height="300" />
:limit="100" :table-props="productTableProps" :table-data="productTableData" :max-height="210" />
</div>
</div>
</div>
@@ -200,7 +154,7 @@
import { parseTime } from '@/filter/code-filter';
import {
getLineAuto, getPdList, getPdlAutoReportNewSearchNow, getProductAuto,
getProcessAutoReportGroup, getProcessAutoReportDay, getProcessAutoReportNew, getPdlAutoReportNewSearchLastGroup
getProcessAutoReportGroup, getProcessAutoReportDay, getProcessAutoReportNew
} from '@/api/core/monitoring/auto';
import { getFactoryPage } from '@/api/core/base/factory';
import * as XLSX from 'xlsx';
@@ -211,11 +165,11 @@ import ButtonNav from '@/components/ButtonNav';
import { listData } from '@/api/system/dict/data';
// 表格列配置
const tableProps = [
{
prop: 'factoryName',
label: '工厂',
fixed: true
},
// {
// prop: 'factoryName',
// label: '工厂',
// fixed: true
// },
{
prop: 'lineName',
label: '产线',
@@ -414,27 +368,15 @@ export default {
productTableDataDay: [],
tableDataCustom: [],
list: [], // 折线图数据
timeTypeOptions: {
productLine: [ // 按产线监控(包含上一班)
{ id: 1, name: '当天' },
{ id: 2, name: '自定义' },
{ id: 3, name: '上一班' }
],
product: [ // 按产品监控(不含上一班)
{ id: 1, name: '当天' },
{ id: 2, name: '自定义' }
]
},
formConfig: [
{
type: 'select',
label: '时间维度',
selectOptions: [
{ id: 1, name: '当天' },
{ id: 2, name: '自定义' },
{ id: 3, name: '上一班' }
{ id: 2, name: '自定义' }
],
width: 100,
width: 80,
onchange: true,
// defaultSelect: 1,
clearable: false,
@@ -495,7 +437,6 @@ export default {
{ id: 3, name: '月' },
{ id: 4, name: '年' }
],
onchange: true,
width: 80,
param: 'reportType'
},
@@ -519,12 +460,6 @@ export default {
btnName: '重置',
name: 'reset',
},
// {
// type: 'label', // 初始隐藏
// label: '刷新时间', // 自定义标识
// // slot: 'currentTimeSlot', // 自定义插槽名
// // width: 200, // 宽度适配
// },
]
};
},
@@ -532,13 +467,6 @@ export default {
productTableProps() {
// 当班数据的完整表头(基础列 + 当班动态表头)
const baseColumns = [
{
prop: 'sizes',
label: '规格',
width: 105,
showOverflowtooltip: true,
fixed: true
},
{
prop: 'process',
label: '产品工艺',
@@ -547,9 +475,8 @@ export default {
{
prop: 'processType',
label: '产品类型',
filter: (val) => (val === 1 ? '面板' : '背板'),
fixed: true,
sortable: true,
filter: (val) => (val != 1 ? '面板' : '背板'),
fixed: true
},
{
prop: 'factoryName',
@@ -586,20 +513,17 @@ export default {
this.$nextTick(() => {
if (this.$refs.buttonNav) {
this.$refs.buttonNav.currentMenu = '按产线监控';
this.formConfig[0].selectOptions = this.timeTypeOptions.productLine;
}
if (this.$refs.searchBarForm) {
// this.$refs.searchBarForm.formInline.timeVal = [
// yesterday.getTime(),
// end.getTime()
// ];
this.$refs.searchBarForm.formInline.timeType = 3
this.$refs.searchBarForm.formInline.timeType = 1
}
});
// this.getLastDayDataList();
this.getDayDataList();
this.getPdLineList();
const queryParams = {
pageNo: 1,
@@ -648,65 +572,22 @@ export default {
this.formConfig[1].type = ''; // 隐藏查询类型
this.formConfig[6].type = ''; // 隐藏报表类型
this.formConfig[7].type = ''; // 隐藏时间范围
const timeItemIndex = this.formConfig.findIndex(item =>
item.label?.includes('刷新时间')
);
if (timeItemIndex > -1) {
this.formConfig.splice(timeItemIndex, 1);
}
};
// 3. 执行公共重置
resetCommon();
// if (this.activeName === 'productLine') {
// } else {
// }
// 4. 根据类型设置差异化的表单配置(仅处理不同的部分)
if (isProductLine) {
// 按产线监控:显示产线,隐藏产品工艺和类型,时间维度包含上一班
this.formConfig[0].selectOptions = this.timeTypeOptions.productLine; // 恢复上一班选项
// 按产线监控:显示产线,隐藏产品工艺和类型
this.formConfig[3].type = 'select'; // 显示产线
this.formConfig[4].type = ''; // 隐藏产品工艺
this.formConfig[5].type = ''; // 隐藏产品类型
this.listQuery.timeType = 3;
if (this.$refs.searchBarForm) {
this.$refs.searchBarForm.formInline.timeType = 3;
}
// 主动调用上一班数据接口
this.getLastDayDataList();
const timeItemIndex = this.formConfig.findIndex(item =>
item.label?.includes('刷新时间')
);
const timeLabel = {
type: 'label',
label: `刷新时间: ${this.formatCurrentTime()}`,
};
if (timeItemIndex > -1) {
this.formConfig.splice(timeItemIndex, 1, timeLabel);
} else {
this.formConfig.push(timeLabel);
}
} else {
// 按产品监控:显示产品工艺和类型,隐藏产线,时间维度移除上一班
this.formConfig[0].selectOptions = this.timeTypeOptions.product; // 不含上一班
// 按产品监控:显示产品工艺和类型,隐藏产线
this.formConfig[3].type = ''; // 隐藏产线
this.formConfig[4].type = 'select'; // 显示产品工艺
this.formConfig[5].type = 'select'; // 显示产品类型
const timeItemIndex = this.formConfig.findIndex(item =>
item.label?.includes('刷新时间')
);
const timeLabel = {
type: 'label',
label: `刷新时间: ${this.formatCurrentTime()}`,
};
if (timeItemIndex > -1) {
this.formConfig.splice(timeItemIndex, 1, timeLabel);
} else {
this.formConfig.push(timeLabel);
}
this.getProductList();
}
},
@@ -720,12 +601,6 @@ export default {
{ ref: 'lineCurrentShiftTable', name: '产线监控_当班数据' },
{ ref: 'lineTodayTable', name: '产线监控_当天数据' }
], '产线监控_当班及当天数据汇总'); // 传入自定义汇总文件名
} else if (this.listQuery.timeType === 1) {
// 产线-当天:导出当班 + 当天两个表格(自定义汇总文件名)
this.exportMultipleTables([
{ ref: 'lineCurrentShiftTable', name: '产线监控_上一班数据' },
{ ref: 'lineTodayTable', name: '产线监控_当天数据' }
], '产线监控_当班及当天数据汇总'); // 传入自定义汇总文件名
} else {
// 产线-自定义:导出一个表格(自定义文件名)
this.exportSingleTable('lineCustomTable', '产线监控_自定义时间数据');
@@ -926,146 +801,31 @@ export default {
this.formConfig[2].selectOptions = res.data.list || [];
});
},
getWeekTimeRange(date) {
const targetDate = new Date(date);
const day = targetDate.getDay() || 7; // 周日转为7
const year = targetDate.getFullYear();
const month = targetDate.getMonth();
const dateNum = targetDate.getDate();
// 本周一 00:00:00
const startDate = new Date(year, month, dateNum - day + 1);
startDate.setHours(0, 0, 0, 0);
// 本周日 23:59:59
const endDate = new Date(year, month, dateNum - day + 7);
endDate.setHours(23, 59, 59, 999);
return {
startTime: startDate.getTime(),
endTime: endDate.getTime()
};
},
// 辅助函数获取本年的开始和结束时间戳1月1日00:00:00 到 12月31日23:59:59
getYearTimeRange(date) {
const targetDate = new Date(date);
const year = targetDate.getFullYear();
// 本年1月1日 00:00:00
const startDate = new Date(year, 0, 1);
startDate.setHours(0, 0, 0, 0);
// 本年12月31日 23:59:59
const endDate = new Date(year, 11, 31);
endDate.setHours(23, 59, 59, 999);
return {
startTime: startDate.getTime(),
endTime: endDate.getTime()
};
},
// 搜索/导出按钮点击
buttonClick(val) {
if (this.activeName === 'productLine') {
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 10;
this.listQuery.factoryId = val.factoryId || undefined;
this.listQuery.process = val.process ? val.process : [];
this.listQuery.lineId = val.lineId ? val.lineId : [];
this.listQuery.processType = val.processType ? val.processType : [];
this.listQuery.reportType = val.reportType || undefined;
this.listQuery.timeType = val.timeType || undefined;
this.listQuery.searchType = val.searchType || undefined;
// 处理不同时间选择类型
if (val.timeVal) {
this.listQuery.startTime = val.timeVal[0];
this.listQuery.endTime = val.timeVal[1];
} else if (val.timeValWeek) {
// 周选择器
const { startTime, endTime } = this.getWeekTimeRange(val.timeValWeek);
this.listQuery.startTime = startTime;
this.listQuery.endTime = endTime;
} else if (val.timeValMonth) {
// 月选择器
this.listQuery.startTime = val.timeValMonth[0];
this.listQuery.endTime = val.timeValMonth[1];
} else if (val.timeValYear) {
// 年选择器
const { startTime, endTime } = this.getYearTimeRange(val.timeValYear);
this.listQuery.startTime = startTime;
this.listQuery.endTime = endTime;
} else {
this.listQuery.startTime = undefined;
this.listQuery.endTime = undefined;
}
} else {
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 10;
this.listQuery.factoryId = val.factoryId || []
this.listQuery.process = val.process ? val.process : [];
this.listQuery.lineId = undefined;
this.listQuery.processType = val.processType ? val.processType : [];
this.listQuery.reportType = val.reportType || undefined;
this.listQuery.timeType = val.timeType || undefined;
this.listQuery.searchType = val.searchType || undefined;
// 处理不同时间选择类型
if (val.timeVal) {
this.listQuery.startTime = val.timeVal[0];
this.listQuery.endTime = val.timeVal[1];
} else if (val.timeValWeek) {
// 周选择器
const { startTime, endTime } = this.getWeekTimeRange(val.timeValWeek);
this.listQuery.startTime = startTime;
this.listQuery.endTime = endTime;
} else if (val.timeValMonth) {
// 月选择器
this.listQuery.startTime = val.timeValMonth[0];
this.listQuery.endTime = val.timeValMonth[1];
} else if (val.timeValYear) {
// 年选择器
const { startTime, endTime } = this.getYearTimeRange(val.timeValYear);
this.listQuery.startTime = startTime;
this.listQuery.endTime = endTime;
} else {
this.listQuery.startTime = undefined;
this.listQuery.endTime = undefined;
}
}
switch (val.btnName) {
case 'search':
const timeItemIndex = this.formConfig.findIndex(item =>
item.label?.includes('刷新时间')
);
// 仅当时间维度为【当天】时,添加/更新刷新时间
if (this.listQuery.timeType === 1 || this.listQuery.timeType === 3) {
const timeLabel = {
type: 'label',
label: `刷新时间: ${this.formatCurrentTime()}`,
};
if (timeItemIndex > -1) {
this.formConfig.splice(timeItemIndex, 1, timeLabel);
} else {
this.formConfig.push(timeLabel);
}
} else if (timeItemIndex > -1) {
// 非当天时,移除刷新时间
this.formConfig.splice(timeItemIndex, 1);
}
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 10;
this.listQuery.factoryId = val.factoryId || undefined;
this.listQuery.process = val.process ? val.process : [];
this.listQuery.lineId = val.lineId ? val.lineId : [];
this.listQuery.processType = val.processType ? val.processType : [];
this.listQuery.reportType = val.reportType || undefined;
this.listQuery.timeType = val.timeType || undefined;
this.listQuery.searchType = val.searchType || undefined;
this.listQuery.startTime = val.timeVal ? val.timeVal[0] : undefined;
this.listQuery.endTime = val.timeVal ? val.timeVal[1] : undefined;
if (this.activeName === 'productLine') {
if (this.listQuery.timeType === 1) {
this.getDayDataList();
} else if (this.listQuery.timeType === 3) {
this.getLastDayDataList();
} else {
this.getDataList();
}
} else {
this.getProductList();
}
break;
case 'export':
@@ -1073,34 +833,21 @@ export default {
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
this.$refs.searchBarForm.formInline.timeType = 3;
this.formConfig[0].selectOptions = this.activeName === 'productLine'
? this.timeTypeOptions.productLine
: this.timeTypeOptions.product;
this.$refs.searchBarForm.formInline.timeType = 1;
this.listQuery = {
pageSize: 100,
pageNo: 1,
total: 0,
timeType: this.activeName === 'productLine' ? 3 : 1,
timeType: 1,
};
// 重置后默认是当天,添加刷新时间
const resetTimeIndex = this.formConfig.findIndex(item =>
item.label?.includes('刷新时间')
);
const resetTimeLabel = {
type: 'label',
label: `刷新时间: ${this.formatCurrentTime()}`,
};
if (resetTimeIndex > -1) {
this.formConfig.splice(resetTimeIndex, 1, resetTimeLabel);
} else {
this.formConfig.push(resetTimeLabel);
}
if (this.activeName === 'productLine') {
this.getLastDayDataList();
this.getDayDataList();
} else {
this.getProductList();
}
break;
default:
console.log(val);
@@ -1350,28 +1097,6 @@ export default {
return [...lineColumns, totalColumn];
},
// 为当天时调用的接口
getLastDayDataList() {
getPdlAutoReportNewSearchLastGroup().then((response) => {
this.tableData = response.data.classData.map((item, index) => {
item.originalLossNum = item.original?.lossNum;
item.originalLossArea = item.original?.lossArea;
item.edgeLossNum = item.edge?.lossNum;
item.edgeLossArea = item.edge?.lossArea;
item.drillLossNum = item.drill?.lossNum;
item.drillLossArea = item.drill?.lossArea;
item.coatingLossNum = item.coating?.lossNum;
item.coatingLossArea = item.coating?.lossArea;
item.silkLossNum = item.silk?.lossNum;
item.silkLossArea = item.silk?.lossArea;
item.temperingLossNum = item.tempering?.lossNum;
item.temperingLossArea = item.tempering?.lossArea;
item.packingLossNum = item.packing?.lossNum;
item.packingLossArea = item.packing?.lossArea;
return item;
});
// console.log(this.tableData, this.tableData2);
});
},
getDayDataList() {
getPdlAutoReportNewSearchNow().then((response) => {
this.tableData = response.data.classData.map((item, index) => {
@@ -1424,48 +1149,32 @@ export default {
this.listQuery.pageNo = val;
this.getDataList();
},
formatCurrentTime() {
const date = new Date();
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${hours}:${minutes}:${seconds} ${year}.${month}.${day}`;
},
// 搜索栏下拉选择变化
handleSearchBarChanged({ param, value }) {
if (param === 'timeType') {
console.log(value);
this.listQuery.timeType = value;
const timeItemIndex = this.formConfig.findIndex(item =>
item.label?.includes('刷新时间')
);
// 仅移除,不添加(查询时才添加)
if (value !== 1 && value !== 3 && timeItemIndex > -1) {
this.formConfig.splice(timeItemIndex, 1);
}
this.$refs.searchBarForm.formInline.timeType = value;
this.$refs.searchBarForm.formInline.searchType = undefined;
this.$refs.searchBarForm.formInline.reportType = undefined;
this.$refs.searchBarForm.formInline.timeVal = undefined;
if (value === 1) {
// 切换为“当天”:隐藏查询类型、报表类型、时间范围
this.formConfig[1].type = '';
this.formConfig[6].type = '';
this.formConfig[7].type = '';
} else if (value === 2) {
this.formConfig[1].type = 'select';
this.$refs.searchBarForm.formInline.searchType = 1;
this.formConfig[7].type = 'datePicker';
} else {
this.formConfig[1].type = '';
this.formConfig[6].type = '';
this.formConfig[7].type = '';
}
this.$refs.searchBarForm.formInline.timeType = value;
this.listQuery.timeType = value;
this.$refs.searchBarForm.formInline.searchType = undefined;
this.$refs.searchBarForm.formInline.reportType = undefined;
this.$refs.searchBarForm.formInline.timeVal = undefined;
} else {
// 切换为“自定义”:显示查询类型和时间范围
this.formConfig[1].type = 'select';
this.$refs.searchBarForm.formInline.timeType = value;
this.listQuery.timeType = value;
this.formConfig[7].type = 'datePicker';
}
} else if (param === 'searchType') {
if (value === 1) {
// 统计数据:显示时间范围,隐藏报表类型
@@ -1478,77 +1187,7 @@ export default {
this.formConfig[7].type = 'datePicker';
}
} else if (param === 'reportType') {
if (this.$refs.searchBarForm && this.$refs.searchBarForm.formInline) {
const formInline = this.$refs.searchBarForm.formInline;
// 精准判断只有字段存在时才置为undefined不存在则不处理
if ('timeVal' in formInline) {
formInline.timeVal = undefined;
}
if ('timeValWeek' in formInline) {
formInline.timeValWeek = undefined;
}
if ('timeValMonth' in formInline) {
formInline.timeValMonth = undefined;
}
if ('timeValYear' in formInline) {
formInline.timeValYear = undefined;
}
}
this.listQuery.startTime = undefined;
this.listQuery.endTime = undefined;
if (value === 1) {
this.formConfig[7] = {
type: 'datePicker',
label: '时间范围',
dateType: 'datetimerange',
format: 'yyyy-MM-dd HH:mm:ss',
valueFormat: 'timestamp',
rangeSeparator: '-',
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
param: 'timeVal',
width: 350
};
} else if (value === 2) {
this.formConfig[7] = {
type: 'datePicker',
label: '时间范围',
dateType: 'week',
placeholder: '选择日期',
format: 'yyyy 第 WW 周',
pickerOptions: {
firstDayOfWeek: 1 // 数字1表示周一作为周的第一天0=周日1=周一,依此类推)
},
valueFormat: 'yyyy-MM-dd',
param: 'timeValWeek',
width: 250,
};
} else if (value === 3) {
this.formConfig[7] = {
type: 'datePicker',
label: '时间范围',
dateType: 'monthrange',
format: 'yyyy-MM-dd',
valueFormat: 'timestamp',
rangeSeparator: '-',
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
param: 'timeValMonth',
defaultTime: ['00:00:00', '23:59:59'],
width: 250,
};
} else if (value === 4) {
this.formConfig[7] = {
type: 'datePicker',
label: '时间范围',
dateType: 'year',
placeholder: '选择年份',
format: 'yyyy',
valueFormat: 'timestamp',
param: 'timeValYear',
width: 250,
};
}
this.$refs.searchBarForm.formInline.timeVal = undefined;
} else if (param === 'factoryId') {
// 切换工厂时刷新产线列表
this.listQuery.lineId = [];
@@ -1595,7 +1234,7 @@ export default {
.content-wrapper {
// flex: 1;
width: 100%;
height: calc(100vh - 280px);
height: calc(100vh - 303px);
// overflow: hidden;
}

View File

@@ -77,7 +77,7 @@ const tableProps = [
},
{
prop: 'palletNum',
label: '一托玻璃数量/片'
label: '下片托数'
},
{
prop: 'startTime',
@@ -92,7 +92,7 @@ const tableProps = [
width: 160
},
{
prop: 'length',
prop: 'outputNum',
label: '玻璃长度/mm'
},
{
@@ -204,88 +204,94 @@ export default {
);
});
},
exportXlsx() {
if (!this.showData.length) {
this.$message.warning('暂无数据可导出');
return;
}
test() {
var target = document.getElementsByClassName("right-aside")[0]
target.style.background = '#FFFFFF'
var that = this
setTimeout(() => {
html2canvas(target).then(function(canvas) {
var contentWidth = canvas.width
var contentHeight = canvas.height
this.exportLoading = true;
// 一页pdf显示html页面生成的canvas高度
var pageHeight = contentHeight / 592.28 * 841.89
// 未生成pdf的html页面高度
var leftHeight = contentHeight
// 页面偏移
var position = 0
// a4纸的尺寸[595.28,841.89]html页面生成的canvas在pdf中图片的高度
var imgWidth = 595.28
var imgHeight = 592.28 / contentWidth * contentHeight
var pageData = canvas.toDataURL('image/jpeg', 1.0)
console.log('nihc URL', leftHeight, pageHeight)
var pdf = new jsPDF('', 'pt', 'a4')
if (leftHeight < pageHeight) {
pdf.addImage(pageData, 'JPEG', 0, 20, imgWidth, imgHeight)
} else {
while(leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
// 避免空白页
if (leftHeight > 0) {
pdf.addPage()
}
}
}
pdf.save(that.fileName + '工段统计.pdf')
})
}, 300)
},
exportECL() {
let tables = document.querySelector('.el-table').cloneNode(true)
const fix = tables.querySelector('.el-table__fixed')
const fixRight = tables.querySelector('.el-table__fixed-right')
if (fix) {
tables.removeChild(tables.querySelector('.el-table__fixed'))
}
if (fixRight) {
tables.removeChild(tables.querySelector('.el-table__fixed-right'))
}
let exportTable = XLSX.utils.table_to_book(tables)
var exportTableOut = XLSX.write(exportTable, {
bookType: 'xlsx', bookSST: true, type: 'array'
})
// sheetjs.xlsx为导出表格的标题名称
try {
// 1. 处理导出数据(格式化时间字段)
const exportData = this.showData.map(item => {
const formatItem = { ...item };
// 格式化时间字段
if (formatItem.startTime) formatItem.startTime = parseTime(formatItem.startTime);
if (formatItem.endTime) formatItem.endTime = parseTime(formatItem.endTime);
return formatItem;
});
// 2. 构建表头映射:{ prop: label },只保留表格配置中存在的列
const headerMap = {};
this.tableProps.forEach(col => {
if (col.prop && col.label) {
headerMap[col.prop] = col.label;
}
});
// 3. 转换数据将prop键名替换为label按tableProps顺序排列列
const formattedData = exportData.map(item => {
const newItem = {};
// 按表格配置顺序遍历列确保Excel列顺序与表格一致
this.tableProps.forEach(col => {
const prop = col.prop;
const label = col.label;
if (prop && label) {
// 处理可能的undefined值避免导出为空字符串
newItem[label] = item[prop] ?? '';
}
});
return newItem;
});
// 4. 创建工作表使用处理后的带label表头的数据
const worksheet = XLSX.utils.json_to_sheet(formattedData);
// 5. 创建工作簿并添加工作表
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, '下片日志数据');
// 6. 生成Excel文件
const excelBuffer = XLSX.write(workbook, {
bookType: 'xlsx',
type: 'array'
});
// 7. 保存文件
const blob = new Blob([excelBuffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
});
// 8. 生成文件名(包含查询条件信息)
let fileName = '下片历史';
if (this.listQuery.productionLineId) {
const lineItem = this.formConfig[0].selectOptions.find(
item => item.id === this.listQuery.productionLineId
);
if (lineItem) fileName += lineItem.name + '_';
}
if (this.listQuery.thick) {
fileName += this.listQuery.thick + '_';
}
// 添加时间戳避免文件名重复
fileName += + '.xlsx';
FileSaver.saveAs(blob, fileName);
this.$message.success('导出成功');
} catch (error) {
console.error('导出失败:', error);
this.$message.error('导出失败,请重试');
} finally {
this.exportLoading = false;
FileSaver.saveAs(new Blob([exportTableOut], {
type: 'application/octet-stream'
}), this.fileName + '工段统计.xlsx')
} catch (e) {
if (typeof console !== 'undefined') console.log(e, exportTableOut)
}
return exportTableOut
},
exportPdf() {
this.test()
setTimeout(() =>{
this.dialogVisible = false
this.showData = this.tableData
}, 600)
},
exportXlsx() {
this.exportECL()
this.dialogVisible = false
this.showData = this.tableData
},
handleClose(done) {
this.$confirm('确认关闭?')
.then(_ => {
done();
})
.catch(_ => {});
},
getPdLineList() {
getPdList().then((res) => {
this.formConfig[0].selectOptions = res.data || []
@@ -308,16 +314,15 @@ export default {
case 'search':
this.listQuery.pageNo = 1;
this.listQuery.pageSize = 10;
this.listQuery.productionLineId = val.productionLineId ? val.productionLineId : undefined;
this.listQuery.thick = val.thick ? val.thick : undefined;
this.listQuery.startTime = val.timeVal ? val.timeVal[0] : undefined;
this.listQuery.endTime = val.timeVal ? val.timeVal[1] : undefined;
this.listQuery.productId = val.productId ? val.productId : undefined;
this.listQuery.startTime = val.timeVal ? val.timeVal[0]: undefined;
this.listQuery.endTime = val.timeVal ? val.timeVal[1]: undefined;
//this.listQuery.reportEndTime = val.timeVal ? [new Date(val.timeVal[1]).getTime()] : undefined;
this.getDataList();
break;
case 'export':
this.exportXlsx();
this.handleExport();
break;
default:
console.log(val);
@@ -345,6 +350,12 @@ export default {
this.listQuery.pageNo = val;
this.getDataList();
},
handleExport() {
if (this.selectedList.length > 0) {
this.showData = this.selectedList
}
this.dialogVisible = true
}
},
};
</script>

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