Compare commits
	
		
			10 Commits
		
	
	
		
			projects/r
			...
			projects/l
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					9f3cdcb1c4 | ||
| 
						 | 
					f11dfe04d5 | ||
| 428a0752eb | |||
| 4e801873b9 | |||
| 
						 | 
					463706663a | ||
| 
						 | 
					e8638687b1 | ||
| 6c46083d4a | |||
| ab486dd71b | |||
| 4da1e6f0b1 | |||
| 0b689b5452 | 
							
								
								
									
										2
									
								
								.env.dev
									
									
									
									
									
								
							
							
						
						@@ -13,7 +13,7 @@ VUE_APP_TITLE = 智能监控分析系统
 | 
			
		||||
 | 
			
		||||
# 芋道管理系统/开发环境
 | 
			
		||||
# VUE_APP_BASE_API = 'http://192.168.8.22:48080'
 | 
			
		||||
VUE_APP_BASE_API = 'http://172.16.32.40:48080'
 | 
			
		||||
VUE_APP_BASE_API = 'http://172.16.33.65:48082'
 | 
			
		||||
 | 
			
		||||
# 路由懒加载
 | 
			
		||||
VUE_CLI_BABEL_TRANSPILE_MODULES = true
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "local": "vue-cli-service serve --mode local",
 | 
			
		||||
    "dev": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve --mode dev",
 | 
			
		||||
    "dev": "vue-cli-service serve --mode dev",
 | 
			
		||||
    "front": "vue-cli-service serve --mode front",
 | 
			
		||||
    "build:prod": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build --mode prod",
 | 
			
		||||
    "build:stage": "vue-cli-service build --mode stage",
 | 
			
		||||
@@ -42,16 +42,19 @@
 | 
			
		||||
  },
 | 
			
		||||
  "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",
 | 
			
		||||
    "crypto-js": "^4.0.0",
 | 
			
		||||
    "diagram-js": "^12.3.0",
 | 
			
		||||
    "echarts": "5.4.0",
 | 
			
		||||
    "el-tree-transfer": "^2.4.7",
 | 
			
		||||
    "element-ui": "2.15.12",
 | 
			
		||||
    "file-saver": "^2.0.5",
 | 
			
		||||
    "fuse.js": "6.6.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -27,8 +27,8 @@ export function getNewCTNow(data) {
 | 
			
		||||
  return request({
 | 
			
		||||
		url: '/analysis/production-analysis/getNewCTNow',
 | 
			
		||||
		method: 'post',
 | 
			
		||||
    data: data
 | 
			
		||||
  })
 | 
			
		||||
		data: data,
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
// 获取产线平衡分析数据趋势图(new)
 | 
			
		||||
export function getNewCTCharts(data) {
 | 
			
		||||
@@ -39,9 +39,10 @@ export function getNewCTCharts(data) {
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
// 获取产线平衡分析数据设备list(new)
 | 
			
		||||
export function getNewCTDet(id) {
 | 
			
		||||
export function getNewCTDet(data) {
 | 
			
		||||
  return request({
 | 
			
		||||
    url: '/analysis/production-analysis/getNewCTDet?lineId='+id,
 | 
			
		||||
    method: 'get',
 | 
			
		||||
  })
 | 
			
		||||
		url: '/analysis/production-analysis/getNewCTDet',
 | 
			
		||||
    method: 'post',
 | 
			
		||||
    data:data
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,16 @@ export function getProductAuto(data) {
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getPdlAutoReportNewSearchNow(data) {
 | 
			
		||||
	return request({
 | 
			
		||||
		url: '/monitoring/production-monitor/getPdlAutoReportNewSearchNow',
 | 
			
		||||
		method: 'post',
 | 
			
		||||
		data: data,
 | 
			
		||||
		timeout: 60000,
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 班组自动报表分页
 | 
			
		||||
export function getTeamReportPage(data) {
 | 
			
		||||
  return request({
 | 
			
		||||
@@ -57,3 +67,29 @@ export function getTeamReportPageDet(id) {
 | 
			
		||||
    method: 'get',
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取产品当班数据
 | 
			
		||||
export function getProcessAutoReportGroup(data) {
 | 
			
		||||
	return request({
 | 
			
		||||
		url: '/monitoring/production-monitor/getProcessAutoReportGroup',
 | 
			
		||||
		method: 'post',
 | 
			
		||||
		data: data,
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取产品当天数据
 | 
			
		||||
export function getProcessAutoReportDay(data) {
 | 
			
		||||
	return request({
 | 
			
		||||
		url: '/monitoring/production-monitor/getProcessAutoReportDay',
 | 
			
		||||
		method: 'post',
 | 
			
		||||
		data: data,
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
// 获取产品历史数据
 | 
			
		||||
export function getProcessAutoReportNew(data) {
 | 
			
		||||
	return request({
 | 
			
		||||
		url: '/monitoring/production-monitor/getProcessAutoReportNew',
 | 
			
		||||
		method: 'post',
 | 
			
		||||
		data: data,
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,3 +14,79 @@ export function getSectionDataSearch(data) {
 | 
			
		||||
    data: data
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取下片日志分页数据
 | 
			
		||||
export function getDownLogPage(data) {
 | 
			
		||||
  return request({
 | 
			
		||||
		url: '/base/down-log/page',
 | 
			
		||||
		method: 'get',
 | 
			
		||||
		params: data,
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取下片日志历史数据
 | 
			
		||||
export function getDownLogHisData(data) {
 | 
			
		||||
  return request({
 | 
			
		||||
		url: '/base/down-log/pagehis',
 | 
			
		||||
		method: 'get',
 | 
			
		||||
		params: data,
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 导出下片日志Excel
 | 
			
		||||
export function exportDownLogData(query) {
 | 
			
		||||
	return request({
 | 
			
		||||
		url: '/base/down-log/export-excel',
 | 
			
		||||
		method: 'get',
 | 
			
		||||
		params: query,
 | 
			
		||||
		responseType: 'blob',
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 获得所有工厂产线列表
 | 
			
		||||
export function getPdList() {
 | 
			
		||||
  return request({
 | 
			
		||||
    url: '/base/production-line/listAll',
 | 
			
		||||
    method: 'get'
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
// 获得玻璃型号列表
 | 
			
		||||
export function getThick() {
 | 
			
		||||
	return request({
 | 
			
		||||
		url: '/base/down-log/thick',
 | 
			
		||||
		method: 'get',
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获得原片报表
 | 
			
		||||
export function getCostOriginRadioHisData(data) {
 | 
			
		||||
	return request({
 | 
			
		||||
		url: '/monitoring/cost-origin-ratio-his/page',
 | 
			
		||||
		method: 'get',
 | 
			
		||||
		params: data,
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 修改原片报表
 | 
			
		||||
export function editCostOriginRadioHisData(data) {
 | 
			
		||||
	return request({
 | 
			
		||||
		url: '/monitoring/cost-origin-ratio-his/update',
 | 
			
		||||
		method: 'put',
 | 
			
		||||
		data: data,
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 导出原片报表
 | 
			
		||||
export function exportCostOriginRadioHisData(data) {
 | 
			
		||||
	return request({
 | 
			
		||||
		url: '/monitoring/cost-origin-ratio-his/export-excel',
 | 
			
		||||
		method: 'get',
 | 
			
		||||
		params: data,
 | 
			
		||||
		responseType: 'blob',
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										75
									
								
								src/api/group/Schedule.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,75 @@
 | 
			
		||||
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 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',
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								src/api/group/groupSetting.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,47 @@
 | 
			
		||||
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 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'
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										51
									
								
								src/api/group/holidaySetting.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,51 @@
 | 
			
		||||
/*
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2025-10-18 21:24:37
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2025-10-18 23:07:37
 | 
			
		||||
 * @Description:
 | 
			
		||||
 */
 | 
			
		||||
import request from '@/utils/request'
 | 
			
		||||
 | 
			
		||||
// 获得节假日基础信息分页
 | 
			
		||||
export function deptHolidayList(query) {
 | 
			
		||||
  return request({
 | 
			
		||||
    url: '/base/group-holiday/page',
 | 
			
		||||
    method: 'get',
 | 
			
		||||
    params: query
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 创建节假日基础信息
 | 
			
		||||
export function createHoliday(data) {
 | 
			
		||||
  return request({
 | 
			
		||||
    url: '/base/group-holiday/create',
 | 
			
		||||
    method: 'post',
 | 
			
		||||
    data: data
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 更新节假日基础信息
 | 
			
		||||
export function updateHoliday(data) {
 | 
			
		||||
  return request({
 | 
			
		||||
    url: '/base/group-holiday/update',
 | 
			
		||||
    method: 'put',
 | 
			
		||||
    data: data
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
// 删除
 | 
			
		||||
export function deleteHolidayn(id) {
 | 
			
		||||
  return request({
 | 
			
		||||
    url: '/base/group-holiday/delete?id=' + id,
 | 
			
		||||
    method: 'delete'
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获得节假日变动日志分页
 | 
			
		||||
export function deptHolidayLogList(query) {
 | 
			
		||||
  return request({
 | 
			
		||||
    url: '/base/group-holiday-log/page',
 | 
			
		||||
    method: 'get',
 | 
			
		||||
    params: query
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
@@ -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  | 
							
								
								
									
										12
									
								
								src/assets/icons/svg/refresh.svg
									
									
									
									
									
										Normal 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  | 
							
								
								
									
										18
									
								
								src/assets/icons/svg/unFullscreen.svg
									
									
									
									
									
										Normal 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
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/images/daoban.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/images/lianpai.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/assets/images/xiujia.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.1 KiB  | 
@@ -81,7 +81,7 @@ export default {
 | 
			
		||||
    border: none;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
    border-radius: 8px;
 | 
			
		||||
    padding: 15px;
 | 
			
		||||
    padding: 16px;
 | 
			
		||||
    color: #888;
 | 
			
		||||
    letter-spacing: 2px;
 | 
			
		||||
    flex: 1;
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -77,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';
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -81,7 +81,17 @@ export default {
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
  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',
 | 
			
		||||
					},
 | 
			
		||||
@@ -161,10 +169,13 @@ export default {
 | 
			
		||||
                return value + 'pcs/min';
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
						data: this.barData.edgeCt.map((item) => {
 | 
			
		||||
							return item.ct;
 | 
			
		||||
						}),
 | 
			
		||||
            data: uniqueTimes.map(time => {
 | 
			
		||||
              // 查找当前时间对应的 ct 值,没有则补 null(图表中会显示为断点)
 | 
			
		||||
              const match = this.barData.edgeCt.find(item => item.recordTime === time);
 | 
			
		||||
              return match ? match.ct : 0;
 | 
			
		||||
            })
 | 
			
		||||
          },
 | 
			
		||||
          // 钢化节拍
 | 
			
		||||
          {
 | 
			
		||||
            name: '钢化节拍',
 | 
			
		||||
            type: 'line',
 | 
			
		||||
@@ -173,10 +184,12 @@ export default {
 | 
			
		||||
                return value + 'pcs/min';
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
						data: this.barData.temperCt.map((item) => {
 | 
			
		||||
							return item.ct;
 | 
			
		||||
						}),
 | 
			
		||||
            data: uniqueTimes.map(time => {
 | 
			
		||||
              const match = this.barData.temperCt.find(item => item.recordTime === time);
 | 
			
		||||
              return match ? match.ct : 0;
 | 
			
		||||
            })
 | 
			
		||||
          },
 | 
			
		||||
          // 下片节拍
 | 
			
		||||
          {
 | 
			
		||||
            name: '下片节拍',
 | 
			
		||||
            type: 'line',
 | 
			
		||||
@@ -185,11 +198,12 @@ export default {
 | 
			
		||||
                return value + 'pcs/min';
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
						data: this.barData.downCt.map((item) => {
 | 
			
		||||
							return item.ct;
 | 
			
		||||
						}),
 | 
			
		||||
					},
 | 
			
		||||
				],
 | 
			
		||||
            data: uniqueTimes.map(time => {
 | 
			
		||||
              const match = this.barData.downCt.find(item => item.recordTime === time);
 | 
			
		||||
              return match ? match.ct : 0;
 | 
			
		||||
            })
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
 
 | 
			
		||||
@@ -119,12 +119,12 @@ export default {
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		// 获取数据列表
 | 
			
		||||
		init(lineId, startTime, endTime) {
 | 
			
		||||
		init(lId, startTime, endTime) {
 | 
			
		||||
			this.eqChartData = [];
 | 
			
		||||
			this.time.startTime = startTime;
 | 
			
		||||
			this.time.endTime = endTime;
 | 
			
		||||
			this.dataListLoading = true;
 | 
			
		||||
			getNewCTDet(lineId).then((response) => {
 | 
			
		||||
      getNewCTDet({ lineId: [lId], startTime, endTime }).then((response) => {
 | 
			
		||||
				this.tableData = response.data;
 | 
			
		||||
				this.dataListLoading = false;
 | 
			
		||||
			});
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,7 @@ export default {
 | 
			
		||||
					defaultSelect: [],
 | 
			
		||||
					multiple: true,
 | 
			
		||||
					filterable: true,
 | 
			
		||||
					width: 400,
 | 
			
		||||
					width: 200,
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'datePicker',
 | 
			
		||||
 
 | 
			
		||||
@@ -1,70 +1,40 @@
 | 
			
		||||
<template>
 | 
			
		||||
	<el-drawer
 | 
			
		||||
		:visible.sync="visible"
 | 
			
		||||
		:show-close="false"
 | 
			
		||||
		:wrapper-closable="false"
 | 
			
		||||
		class="drawer"
 | 
			
		||||
		size="60%">
 | 
			
		||||
  <el-drawer :visible.sync="visible" :show-close="false" :wrapper-closable="false" class="drawer" size="60%">
 | 
			
		||||
    <small-title slot="title" :no-padding="true">
 | 
			
		||||
      {{ isdetail ? '详情' : !dataForm.id ? '新增' : '编辑' }}
 | 
			
		||||
    </small-title>
 | 
			
		||||
 | 
			
		||||
    <div class="content">
 | 
			
		||||
      <div class="visual-part">
 | 
			
		||||
				<el-form
 | 
			
		||||
					ref="dataForm"
 | 
			
		||||
					:model="dataForm"
 | 
			
		||||
					:rules="dataRule"
 | 
			
		||||
					label-width="100px"
 | 
			
		||||
					label-position="top"
 | 
			
		||||
        <el-form ref="dataForm" :model="dataForm" :rules="dataRule" label-width="100px" label-position="top"
 | 
			
		||||
          @keyup.enter.native="dataFormSubmit">
 | 
			
		||||
          <el-row :gutter="20">
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="产品编码" prop="code">
 | 
			
		||||
								<el-input
 | 
			
		||||
									v-model="dataForm.code"
 | 
			
		||||
									clearable
 | 
			
		||||
									:disabled="isdetail"
 | 
			
		||||
									placeholder="请输入产品编码" />
 | 
			
		||||
                <el-input v-model="dataForm.code" clearable :disabled="isdetail" placeholder="请输入产品编码" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="产品名称" prop="name">
 | 
			
		||||
								<el-input
 | 
			
		||||
									v-model="dataForm.name"
 | 
			
		||||
									clearable
 | 
			
		||||
									:disabled="isdetail"
 | 
			
		||||
									placeholder="请输入产品名称" />
 | 
			
		||||
                <el-input v-model="dataForm.name" clearable :disabled="isdetail" placeholder="请输入产品名称" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
          </el-row>
 | 
			
		||||
          <el-row :gutter="20">
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="产品类型" prop="typeDictValue">
 | 
			
		||||
								<el-select
 | 
			
		||||
									v-model="dataForm.typeDictValue"
 | 
			
		||||
									style="width: 100%"
 | 
			
		||||
									:disabled="isdetail"
 | 
			
		||||
                <el-select v-model="dataForm.typeDictValue" style="width: 100%" :disabled="isdetail"
 | 
			
		||||
                  placeholder="请选择产品类型">
 | 
			
		||||
									<el-option
 | 
			
		||||
										v-for="dict in getDictDatas(DICT_TYPE.PRODUCT_TYPE)"
 | 
			
		||||
										:key="dict.value"
 | 
			
		||||
										:label="dict.label"
 | 
			
		||||
                  <el-option v-for="dict in getDictDatas(DICT_TYPE.PRODUCT_TYPE)" :key="dict.value" :label="dict.label"
 | 
			
		||||
                    :value="dict.value" />
 | 
			
		||||
                </el-select>
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="单位" prop="unitDictValue">
 | 
			
		||||
								<el-select
 | 
			
		||||
									v-model="dataForm.unitDictValue"
 | 
			
		||||
									style="width: 100%"
 | 
			
		||||
									:disabled="isdetail"
 | 
			
		||||
                <el-select v-model="dataForm.unitDictValue" style="width: 100%" :disabled="isdetail"
 | 
			
		||||
                  placeholder="请选择单位">
 | 
			
		||||
									<el-option
 | 
			
		||||
										v-for="dict in getDictDatas(DICT_TYPE.UNIT_DICT)"
 | 
			
		||||
										:key="dict.value"
 | 
			
		||||
										:label="dict.label"
 | 
			
		||||
                  <el-option v-for="dict in getDictDatas(DICT_TYPE.UNIT_DICT)" :key="dict.value" :label="dict.label"
 | 
			
		||||
                    :value="dict.value" />
 | 
			
		||||
                </el-select>
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
@@ -73,80 +43,57 @@
 | 
			
		||||
          <el-row :gutter="20">
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="原片规格" prop="originalSpecifications">
 | 
			
		||||
								<el-input
 | 
			
		||||
									:disabled="isdetail"
 | 
			
		||||
									v-model="dataForm.originalSpecifications"
 | 
			
		||||
									placeholder="请输入原片规格" />
 | 
			
		||||
                <el-input :disabled="isdetail" v-model="dataForm.originalSpecifications" placeholder="请输入原片规格" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="原片单位平方数" prop="originalArea">
 | 
			
		||||
								<el-input
 | 
			
		||||
									:disabled="isdetail"
 | 
			
		||||
									v-model="dataForm.originalArea"
 | 
			
		||||
									placeholder="请输入原片单位平方数" />
 | 
			
		||||
                <el-input :disabled="isdetail" v-model="dataForm.originalArea" placeholder="请输入原片单位平方数" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
          </el-row>
 | 
			
		||||
          <el-row :gutter="20">
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="深加工规格" prop="specifications">
 | 
			
		||||
								<el-input
 | 
			
		||||
									:disabled="isdetail"
 | 
			
		||||
									v-model="dataForm.specifications"
 | 
			
		||||
									placeholder="请输入深加工规格" />
 | 
			
		||||
                <el-input :disabled="isdetail" v-model="dataForm.specifications" placeholder="请输入深加工规格" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="深加工单位平方数" prop="area">
 | 
			
		||||
								<el-input
 | 
			
		||||
									:disabled="isdetail"
 | 
			
		||||
									v-model="dataForm.area"
 | 
			
		||||
									placeholder="请输入深加工单位平方数" />
 | 
			
		||||
                <el-input :disabled="isdetail" v-model="dataForm.area" placeholder="请输入深加工单位平方数" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
          </el-row>
 | 
			
		||||
          <el-row :gutter="20">
 | 
			
		||||
						<el-col :span="24">
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="完成单位产品用时" prop="processTime">
 | 
			
		||||
								<el-input
 | 
			
		||||
									:disabled="isdetail"
 | 
			
		||||
									v-model="dataForm.processTime"
 | 
			
		||||
									placeholder="请输入完成单位产品用时" />
 | 
			
		||||
                <el-input :disabled="isdetail" v-model="dataForm.processTime" placeholder="请输入完成单位产品用时" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <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>
 | 
			
		||||
          </el-row>
 | 
			
		||||
        </el-form>
 | 
			
		||||
 | 
			
		||||
				<small-title
 | 
			
		||||
					style="margin: 16px 0; padding-left: 8px"
 | 
			
		||||
					:no-padding="true">
 | 
			
		||||
        <small-title style="margin: 16px 0; padding-left: 8px" :no-padding="true">
 | 
			
		||||
          产品属性列表
 | 
			
		||||
        </small-title>
 | 
			
		||||
 | 
			
		||||
        <div class="attr-list">
 | 
			
		||||
					<base-table
 | 
			
		||||
						:table-props="tableProps"
 | 
			
		||||
						:page="listQuery.pageNo"
 | 
			
		||||
						:limit="listQuery.pageSize"
 | 
			
		||||
						:add-button-show="isdetail ? null : '添加属性'"
 | 
			
		||||
						@emitButtonClick="addNew()"
 | 
			
		||||
						:table-data="productAttributeList">
 | 
			
		||||
						<method-btn
 | 
			
		||||
							v-if="!isdetail"
 | 
			
		||||
							slot="handleBtn"
 | 
			
		||||
							:width="120"
 | 
			
		||||
							label="操作"
 | 
			
		||||
							:method-list="tableBtn"
 | 
			
		||||
          <base-table :table-props="tableProps" :page="listQuery.pageNo" :limit="listQuery.pageSize"
 | 
			
		||||
            :add-button-show="isdetail ? null : '添加属性'" @emitButtonClick="addNew()" :table-data="productAttributeList">
 | 
			
		||||
            <method-btn v-if="!isdetail" slot="handleBtn" :width="120" label="操作" :method-list="tableBtn"
 | 
			
		||||
              @clickBtn="handleClick" />
 | 
			
		||||
          </base-table>
 | 
			
		||||
					<pagination
 | 
			
		||||
						v-show="listQuery.total > 0"
 | 
			
		||||
						:total="listQuery.total"
 | 
			
		||||
						:page.sync="listQuery.pageNo"
 | 
			
		||||
						:limit.sync="listQuery.pageSize"
 | 
			
		||||
						:page-sizes="[5, 10, 15]"
 | 
			
		||||
						@pagination="getList" />
 | 
			
		||||
          <pagination v-show="listQuery.total > 0" :total="listQuery.total" :page.sync="listQuery.pageNo"
 | 
			
		||||
            :limit.sync="listQuery.pageSize" :page-sizes="[5, 10, 15]" @pagination="getList" />
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
@@ -177,10 +124,7 @@
 | 
			
		||||
      </el-button>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
		<product-attr-add
 | 
			
		||||
			v-if="addOrUpdateVisible"
 | 
			
		||||
			ref="addOrUpdate"
 | 
			
		||||
			:product-id="dataForm.id"
 | 
			
		||||
    <product-attr-add v-if="addOrUpdateVisible" ref="addOrUpdate" :product-id="dataForm.id"
 | 
			
		||||
      @refreshDataList="getList" />
 | 
			
		||||
  </el-drawer>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -247,12 +191,30 @@ export default {
 | 
			
		||||
				unitDictValue: '', // 单位id
 | 
			
		||||
				originalSpecifications: '', // 原片规格
 | 
			
		||||
        originalArea: 0, // 原片单位平方数
 | 
			
		||||
        processType:undefined,
 | 
			
		||||
			},
 | 
			
		||||
			listQuery: {
 | 
			
		||||
				pageSize: 10,
 | 
			
		||||
				pageNo: 1,
 | 
			
		||||
				total: 0,
 | 
			
		||||
      },
 | 
			
		||||
      processTypeList: [
 | 
			
		||||
        {
 | 
			
		||||
          id: '0',
 | 
			
		||||
          label:'压花丝印'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          id: '1',
 | 
			
		||||
          label: '无印打孔'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          id: '2',
 | 
			
		||||
          label: '单层镀膜'
 | 
			
		||||
        }, {
 | 
			
		||||
          id: '3',
 | 
			
		||||
          label: '双层镀膜'
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
			dataRule: {
 | 
			
		||||
				code: [
 | 
			
		||||
					{
 | 
			
		||||
 
 | 
			
		||||
@@ -7,29 +7,15 @@
 | 
			
		||||
-->
 | 
			
		||||
<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"
 | 
			
		||||
			>
 | 
			
		||||
 | 
			
		||||
    <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"
 | 
			
		||||
		/>
 | 
			
		||||
    <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"
 | 
			
		||||
@@ -39,11 +25,7 @@
 | 
			
		||||
				:table-data="selectedList"
 | 
			
		||||
			/>
 | 
			
		||||
		</div> -->
 | 
			
		||||
		<el-dialog
 | 
			
		||||
			title="提示"
 | 
			
		||||
			:visible.sync="dialogVisible"
 | 
			
		||||
			width="30%"
 | 
			
		||||
			:before-close="handleClose">
 | 
			
		||||
    <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">
 | 
			
		||||
@@ -204,6 +186,7 @@ export default {
 | 
			
		||||
			],
 | 
			
		||||
		};
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
	created() {
 | 
			
		||||
		this.getDataList()
 | 
			
		||||
		this.getPdLineList()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										132
									
								
								src/views/core/monitoring/components/buttonNav.vue
									
									
									
									
									
										Normal 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>
 | 
			
		||||
							
								
								
									
										272
									
								
								src/views/core/monitoring/lineAuto/BarChart.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,272 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div :class="className" :style="{ height: height, width: width, marginLeft: '10px' }" />
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import * as echarts from 'echarts';
 | 
			
		||||
require('echarts/theme/macarons'); // 引入主题
 | 
			
		||||
import resize from '@/utils/chartMixins/resize';
 | 
			
		||||
 | 
			
		||||
const animationDuration = 1000;
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  mixins: [resize], // 混入 resize 逻辑(自适应窗口)
 | 
			
		||||
  props: {
 | 
			
		||||
    className: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'chart',
 | 
			
		||||
    },
 | 
			
		||||
    title: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: '',
 | 
			
		||||
    },
 | 
			
		||||
    width: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: '100%',
 | 
			
		||||
    },
 | 
			
		||||
    height: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: '300px',
 | 
			
		||||
    },
 | 
			
		||||
    barData: {
 | 
			
		||||
      type: Array,
 | 
			
		||||
      default: () => [],
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      chart: null, // 图表实例
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    // 监听 barData 变化(深度监听数组内部元素)
 | 
			
		||||
    barData: {
 | 
			
		||||
      deep: true,
 | 
			
		||||
      handler: 'handleBarDataChange', // 调用处理方法
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    // 组件挂载后初始化图表(确保 DOM 已就绪)
 | 
			
		||||
    this.$nextTick(() => {
 | 
			
		||||
      this.initChart();
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
  beforeDestroy() {
 | 
			
		||||
    // 组件销毁前清理图表实例
 | 
			
		||||
    if (this.chart) {
 | 
			
		||||
      this.chart.dispose();
 | 
			
		||||
      this.chart = null;
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    // barData 变化时的处理方法
 | 
			
		||||
    handleBarDataChange() {
 | 
			
		||||
      // 确保 DOM 存在再更新图表
 | 
			
		||||
      this.$nextTick(() => {
 | 
			
		||||
        // 如果图表未初始化,先初始化;否则直接更新数据
 | 
			
		||||
        if (!this.chart) {
 | 
			
		||||
          this.initChart();
 | 
			
		||||
        } else {
 | 
			
		||||
          this.updateChart();
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 初始化图表
 | 
			
		||||
    initChart() {
 | 
			
		||||
      // 避免重复初始化(先销毁旧实例)
 | 
			
		||||
      if (this.chart) {
 | 
			
		||||
        this.chart.dispose();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 确保 DOM 元素存在
 | 
			
		||||
      if (!this.$el) {
 | 
			
		||||
        console.error('图表容器 DOM 元素不存在');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 初始化图表实例
 | 
			
		||||
      this.chart = echarts.init(this.$el, 'macarons');
 | 
			
		||||
      // 设置图表配置
 | 
			
		||||
      this.setChartOption();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 更新图表数据(复用配置逻辑)
 | 
			
		||||
    updateChart() {
 | 
			
		||||
      if (!this.chart) return;
 | 
			
		||||
      this.setChartOption();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 图表配置项(抽离为单独方法,方便初始化和更新复用)
 | 
			
		||||
    setChartOption() {
 | 
			
		||||
      const dataValues = this.barData.flatMap(item => [item.inputNum || 0, item.outputNum || 0]);
 | 
			
		||||
      const maxData = Math.max(...dataValues, 0); // 加 0 确保无数据时 maxData 为 0
 | 
			
		||||
 | 
			
		||||
      // 2. 计算 Y 轴最大值(留 10% 余量,避免数据顶到顶部)
 | 
			
		||||
      let yMax = 0;
 | 
			
		||||
      if (maxData > 0) {
 | 
			
		||||
        yMax = Math.ceil(maxData * 1.1); // 向上取整,确保刻度为整数
 | 
			
		||||
      } else {
 | 
			
		||||
        yMax = 100; // 无数据时默认最大值为 100,避免 Y 轴消失
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 3. 计算 interval(5 个刻度对应 4 个间隔,向上取整确保间隔为整数)
 | 
			
		||||
      const yInterval = Math.ceil((yMax - 0) / 4); // min 固定为 0,直接减 0
 | 
			
		||||
 | 
			
		||||
      this.chart.setOption({
 | 
			
		||||
        title: {
 | 
			
		||||
          text: this.title
 | 
			
		||||
            ? '{space|}{tip|}{space|}{value|' + this.title + '}'
 | 
			
		||||
            : '',
 | 
			
		||||
          textStyle: {
 | 
			
		||||
            rich: {
 | 
			
		||||
              tip: {
 | 
			
		||||
                width: 6,
 | 
			
		||||
                height: 6,
 | 
			
		||||
                borderRadius: 50,
 | 
			
		||||
                backgroundColor: '#288AFF',
 | 
			
		||||
              },
 | 
			
		||||
              space: {
 | 
			
		||||
                width: 8,
 | 
			
		||||
              },
 | 
			
		||||
              value: {
 | 
			
		||||
                fontSize: 14,
 | 
			
		||||
                color: 'black',
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        color: ['#288AFF', '#8EF0AB', '#FFDC94'],
 | 
			
		||||
        tooltip: {
 | 
			
		||||
          trigger: 'axis',
 | 
			
		||||
          axisPointer: {
 | 
			
		||||
            type: 'cross',
 | 
			
		||||
            crossStyle: {
 | 
			
		||||
              color: '#999',
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        legend: {
 | 
			
		||||
          data: ['投入', '产出', '加工成品率'],
 | 
			
		||||
        },
 | 
			
		||||
        grid: {
 | 
			
		||||
          left: 20,
 | 
			
		||||
          right: 30,
 | 
			
		||||
          top:40,
 | 
			
		||||
          bottom: 10,
 | 
			
		||||
 | 
			
		||||
          containLabel: true,
 | 
			
		||||
          splitArea: {
 | 
			
		||||
            show: false // 关键:关闭网格背景分区(去掉间隔色块)
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        xAxis: {
 | 
			
		||||
          type: 'category',
 | 
			
		||||
          data: this.barData.map((item) => item.lineName),
 | 
			
		||||
          axisLine: {
 | 
			
		||||
            lineStyle: {
 | 
			
		||||
              color: 'rgba(0, 0, 0, 0.45)',
 | 
			
		||||
              width: 1 // 轴线宽度(可选,默认 1,可按需调整)
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          // 2. 控制 X 轴刻度线颜色(与轴线颜色保持一致,视觉统一)
 | 
			
		||||
          axisTick: {
 | 
			
		||||
            lineStyle: {
 | 
			
		||||
              color: 'rgba(0, 0, 0, 0.45)', // 刻度线颜色,需与轴线颜色匹配
 | 
			
		||||
              width: 1 // 刻度线宽度(可选)
 | 
			
		||||
            },
 | 
			
		||||
            alignWithLabel: true // 可选:让刻度线与文字对齐(避免文字偏移时刻度线错位)
 | 
			
		||||
          },
 | 
			
		||||
          // 3. 控制 X 轴文字颜色(如:深灰色 rgba(0, 0, 0, 0.45))
 | 
			
		||||
          axisLabel: {
 | 
			
		||||
            color: 'rgba(0, 0, 0, 0.45)6', // 文字颜色,可自定义
 | 
			
		||||
            fontSize: 12, // 可选:调整文字大小(默认 12,按需修改)
 | 
			
		||||
            // 可选:文字过长时换行/省略(避免文字重叠,按需开启)
 | 
			
		||||
            formatter: (value) => {
 | 
			
		||||
              // 示例:文字超过 6 个字符时换行(可根据需求调整字符数)
 | 
			
		||||
              if (value.length > 6) {
 | 
			
		||||
                return value.slice(0, 6) + '\n' + value.slice(6);
 | 
			
		||||
              }
 | 
			
		||||
              return value;
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          // 原有配置(若需保留可解开注释)
 | 
			
		||||
          // axisPointer: {
 | 
			
		||||
          //   type: 'shadow',
 | 
			
		||||
          // }
 | 
			
		||||
        },
 | 
			
		||||
        yAxis: [
 | 
			
		||||
          {
 | 
			
		||||
            type: 'value',
 | 
			
		||||
            name: '投入/产出 片',
 | 
			
		||||
            min: 0, // 最小值固定为 0
 | 
			
		||||
            max: yMax,
 | 
			
		||||
            interval: yInterval,
 | 
			
		||||
            splitArea: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisLabel: {
 | 
			
		||||
              formatter: '{value}',
 | 
			
		||||
              color: 'rgba(0, 0, 0, 0.45)'
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // 可选:修改 Y 轴名称颜色(与文字颜色保持一致)
 | 
			
		||||
            nameTextStyle: {
 | 
			
		||||
              color: 'rgba(0, 0, 0, 0.45)'
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            type: 'value',
 | 
			
		||||
            name: '加工成品率',
 | 
			
		||||
            min: 0,
 | 
			
		||||
            max: 100, // 成品率固定 0-100%
 | 
			
		||||
            interval: 25, // 100 / 4 = 25,刚好 5 个刻度(0、25、50、75、100)
 | 
			
		||||
            axisLabel: {
 | 
			
		||||
              formatter: '{value} %',
 | 
			
		||||
              color: 'rgba(0, 0, 0, 0.45)'
 | 
			
		||||
            },
 | 
			
		||||
            splitArea: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            // 可选:修改 Y 轴名称颜色
 | 
			
		||||
            nameTextStyle: {
 | 
			
		||||
              color: 'rgba(0, 0, 0, 0.45)'
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
        series: [
 | 
			
		||||
          {
 | 
			
		||||
            name: '投入',
 | 
			
		||||
            type: 'bar',
 | 
			
		||||
            barWidth: '20',
 | 
			
		||||
            data: this.barData.map((item) => item.inputNum),
 | 
			
		||||
            tooltip: {
 | 
			
		||||
              valueFormatter: (value) => `${value} 片`,
 | 
			
		||||
            },
 | 
			
		||||
            animationDuration,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: '产出',
 | 
			
		||||
            type: 'bar',
 | 
			
		||||
            barWidth: '20',
 | 
			
		||||
            data: this.barData.map((item) => item.outputNum),
 | 
			
		||||
            tooltip: {
 | 
			
		||||
              valueFormatter: (value) => `${value} 片`,
 | 
			
		||||
            },
 | 
			
		||||
            animationDuration,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: '加工成品率',
 | 
			
		||||
            type: 'line',
 | 
			
		||||
            yAxisIndex: 1,
 | 
			
		||||
            tooltip: {
 | 
			
		||||
              valueFormatter: (value) => `${value} %`,
 | 
			
		||||
            },
 | 
			
		||||
            data: this.barData.map((item) => item.processingRatio),
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										361
									
								
								src/views/core/monitoring/nextClip/hisData.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,361 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: Do not edit
 | 
			
		||||
 * @Date: 2023-08-29 14:59:29
 | 
			
		||||
 * @LastEditTime: 2024-12-02 13:44:47
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<div class="app-container">
 | 
			
		||||
		<!-- :isFold="true" 控制展开 -->
 | 
			
		||||
		<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"
 | 
			
		||||
			:table-data="showData"
 | 
			
		||||
			>
 | 
			
		||||
			<!-- <method-btn
 | 
			
		||||
				v-if="tableBtn.length"
 | 
			
		||||
				slot="handleBtn"
 | 
			
		||||
				:width="120"
 | 
			
		||||
				label="操作"
 | 
			
		||||
				:method-list="tableBtn"
 | 
			
		||||
				@clickBtn="handleClick" /> -->
 | 
			
		||||
		</base-table>
 | 
			
		||||
		<div v-else class="no-data-bg"></div>
 | 
			
		||||
		<pagination
 | 
			
		||||
			:limit.sync="listQuery.pageSize"
 | 
			
		||||
			:page.sync="listQuery.pageNo"
 | 
			
		||||
			:total="listQuery.total"
 | 
			
		||||
			@pagination="getDataList" />
 | 
			
		||||
		<!-- <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>
 | 
			
		||||
import { parseTime } from '../../mixins/code-filter';
 | 
			
		||||
import { getDownLogHisData, getPdList, getThick  } from '@/api/core/monitoring/index'
 | 
			
		||||
import * as XLSX from 'xlsx'
 | 
			
		||||
import FileSaver from 'file-saver'
 | 
			
		||||
import jsPDF from 'jspdf'
 | 
			
		||||
import html2canvas from 'html2canvas'
 | 
			
		||||
 | 
			
		||||
const tableProps = [
 | 
			
		||||
	{
 | 
			
		||||
    prop: 'productionLineName',
 | 
			
		||||
		label: '产线'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'eqName',
 | 
			
		||||
    label: '下片机械手编号'
 | 
			
		||||
  },
 | 
			
		||||
	{
 | 
			
		||||
    prop: 'pos',
 | 
			
		||||
		label: '工位编号'
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
    prop: 'pallet',
 | 
			
		||||
    label: '托数/托'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'palletNum',
 | 
			
		||||
    label: '下片托数'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'startTime',
 | 
			
		||||
    label: '开始时间',
 | 
			
		||||
    filter: parseTime,
 | 
			
		||||
    width: 160
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'endTime',
 | 
			
		||||
    label: '结束时间',
 | 
			
		||||
    filter: parseTime,
 | 
			
		||||
    width: 160
 | 
			
		||||
  },
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'outputNum',
 | 
			
		||||
    label: '玻璃长度/mm'
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'width',
 | 
			
		||||
    label: '玻璃宽度/mm',
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
    prop: 'thick',
 | 
			
		||||
    label: '玻璃长度/mm'
 | 
			
		||||
	},
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			urlOptions: {
 | 
			
		||||
        getDataListURL: getDownLogHisData
 | 
			
		||||
			},
 | 
			
		||||
      tableData: [],
 | 
			
		||||
      listQuery: {
 | 
			
		||||
        pageSize: 10,
 | 
			
		||||
        pageNo: 1,
 | 
			
		||||
        total: 1,
 | 
			
		||||
        eqName: undefined,
 | 
			
		||||
        productionLineId: undefined,
 | 
			
		||||
        thick:undefined
 | 
			
		||||
      },
 | 
			
		||||
      exportLoading: false,
 | 
			
		||||
      dataListLoading: false,
 | 
			
		||||
			selectedList: [],
 | 
			
		||||
			dialogVisible: false,
 | 
			
		||||
      addOrEditTitle: '',
 | 
			
		||||
      addOrUpdateVisible: false,
 | 
			
		||||
			tableProps,
 | 
			
		||||
      tableBtn: [
 | 
			
		||||
        {
 | 
			
		||||
          type: 'his',
 | 
			
		||||
          btnName: '历史',
 | 
			
		||||
        },
 | 
			
		||||
      ].filter((v) => v),
 | 
			
		||||
			tableData: [],
 | 
			
		||||
			showData: [],
 | 
			
		||||
			fileName: '',
 | 
			
		||||
			formConfig: [
 | 
			
		||||
				{
 | 
			
		||||
					type: 'select',
 | 
			
		||||
					label: '产线',
 | 
			
		||||
					selectOptions: [],
 | 
			
		||||
          param: 'productionLineId'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          type: 'select',
 | 
			
		||||
          label: '玻璃型号',
 | 
			
		||||
          selectOptions: [],
 | 
			
		||||
          param: 'thick'
 | 
			
		||||
        },
 | 
			
		||||
				{
 | 
			
		||||
          type: 'datePicker',
 | 
			
		||||
          label: '统计开始时间',
 | 
			
		||||
          dateType: 'daterange',
 | 
			
		||||
          format: 'yyyy-MM-dd',
 | 
			
		||||
          valueFormat: "yyyy-MM-dd HH:mm:ss",
 | 
			
		||||
          rangeSeparator: '-',
 | 
			
		||||
          startPlaceholder: '开始时间',
 | 
			
		||||
          endPlaceholder: '结束时间',
 | 
			
		||||
          param: 'timeVal',
 | 
			
		||||
          defaultTime: ['00:00:00', '23:59:59'],
 | 
			
		||||
          defaultSelect: []
 | 
			
		||||
        },
 | 
			
		||||
				{
 | 
			
		||||
					type: 'button',
 | 
			
		||||
					btnName: '查询',
 | 
			
		||||
					name: 'search',
 | 
			
		||||
					color: 'primary',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'separate',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					// type: this.$auth.hasPermi('base:factory:export') ? 'button' : '',
 | 
			
		||||
					type: 'button',
 | 
			
		||||
					btnName: '导出',
 | 
			
		||||
					name: 'export',
 | 
			
		||||
					color: 'warning',
 | 
			
		||||
				}
 | 
			
		||||
			],
 | 
			
		||||
		};
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.$refs.searchBarForm.formInline.productionLineId = this.$route.query.productionLineId
 | 
			
		||||
    this.$refs.searchBarForm.formInline.thick = this.$route.query.thick
 | 
			
		||||
    this.listQuery.productionLineId = this.$route.query.productionLineId
 | 
			
		||||
    this.listQuery.thick = this.$route.query.thick
 | 
			
		||||
    this.getDataList()
 | 
			
		||||
    this.getPdLineList()
 | 
			
		||||
    console.log('this.$route.query', this.$route.query);
 | 
			
		||||
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    		handleClick(val) {
 | 
			
		||||
			this.addOrUpdateVisible = true;
 | 
			
		||||
			this.addOrEditTitle =
 | 
			
		||||
				val.data?.factoryName + '-' + val.data?.lineName + ' 详情';
 | 
			
		||||
			this.$nextTick(() => {
 | 
			
		||||
				this.$refs.eqDetail.init(
 | 
			
		||||
					val.data.lineId,
 | 
			
		||||
					this.listQuery.startTime,
 | 
			
		||||
					this.listQuery.endTime
 | 
			
		||||
				);
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		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
 | 
			
		||||
 | 
			
		||||
						// 一页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 {
 | 
			
		||||
        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 || []
 | 
			
		||||
			})
 | 
			
		||||
      getThick().then((res) => {
 | 
			
		||||
        this.formConfig[1].selectOptions = res.data.map((item) => {
 | 
			
		||||
          return {
 | 
			
		||||
            id: item.thick + 'mm',
 | 
			
		||||
            name: item.thick + 'mm'
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
			})
 | 
			
		||||
		},
 | 
			
		||||
		selectChange(val) {
 | 
			
		||||
      console.log(val)
 | 
			
		||||
      this.selectedList = val
 | 
			
		||||
    },
 | 
			
		||||
		buttonClick(val) {
 | 
			
		||||
			switch (val.btnName) {
 | 
			
		||||
				case 'search':
 | 
			
		||||
					this.listQuery.pageNo = 1;
 | 
			
		||||
					this.listQuery.pageSize = 10;
 | 
			
		||||
          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.handleExport();
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					console.log(val);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		// 获取数据列表
 | 
			
		||||
    getDataList() {
 | 
			
		||||
      this.listQuery.eqName = this.$route.query.eqName
 | 
			
		||||
      this.dataListLoading = true;
 | 
			
		||||
      this.urlOptions.getDataListURL(this.listQuery).then(response => {
 | 
			
		||||
        this.tableData = response.data.list
 | 
			
		||||
				this.showData = this.tableData
 | 
			
		||||
        this.listQuery.total = response.data.total;
 | 
			
		||||
        this.dataListLoading = false;
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
    // 每页数
 | 
			
		||||
    sizeChangeHandle(val) {
 | 
			
		||||
      this.listQuery.pageSize = val;
 | 
			
		||||
      this.listQuery.pageNo = 1;
 | 
			
		||||
      this.getDataList();
 | 
			
		||||
    },
 | 
			
		||||
    // 当前页
 | 
			
		||||
    currentChangeHandle(val) {
 | 
			
		||||
      this.listQuery.pageNo = val;
 | 
			
		||||
      this.getDataList();
 | 
			
		||||
    },
 | 
			
		||||
		handleExport() {
 | 
			
		||||
			if (this.selectedList.length > 0) {
 | 
			
		||||
				this.showData = this.selectedList
 | 
			
		||||
			}
 | 
			
		||||
			this.dialogVisible = true
 | 
			
		||||
    }
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										373
									
								
								src/views/core/monitoring/nextClip/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,373 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: Do not edit
 | 
			
		||||
 * @Date: 2023-08-29 14:59:29
 | 
			
		||||
 * @LastEditTime: 2024-12-02 13:44:47
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<div class="app-container">
 | 
			
		||||
		<!-- :isFold="true" 控制展开 -->
 | 
			
		||||
		<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"
 | 
			
		||||
			:table-data="showData"
 | 
			
		||||
			>
 | 
			
		||||
			<method-btn
 | 
			
		||||
				v-if="tableBtn.length"
 | 
			
		||||
				slot="handleBtn"
 | 
			
		||||
				:width="120"
 | 
			
		||||
				label="操作"
 | 
			
		||||
				:method-list="tableBtn"
 | 
			
		||||
				@clickBtn="handleClick" />
 | 
			
		||||
		</base-table>
 | 
			
		||||
		<div v-else class="no-data-bg"></div>
 | 
			
		||||
		<pagination
 | 
			
		||||
			:limit.sync="listQuery.pageSize"
 | 
			
		||||
			:page.sync="listQuery.pageNo"
 | 
			
		||||
			:total="listQuery.total"
 | 
			
		||||
			@pagination="getDataList" />
 | 
			
		||||
		<!-- <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>
 | 
			
		||||
import { parseTime } from '../../mixins/code-filter';
 | 
			
		||||
import { getDownLogPage, getPdList, getThick, exportDownLogData  } from '@/api/core/monitoring/index'
 | 
			
		||||
import * as XLSX from 'xlsx'
 | 
			
		||||
import FileSaver from 'file-saver'
 | 
			
		||||
import jsPDF from 'jspdf'
 | 
			
		||||
import html2canvas from 'html2canvas'
 | 
			
		||||
 | 
			
		||||
const tableProps = [
 | 
			
		||||
	{
 | 
			
		||||
    prop: 'productionLineName',
 | 
			
		||||
		label: '产线'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'eqName',
 | 
			
		||||
    label: '下片机械手编号'
 | 
			
		||||
  },
 | 
			
		||||
	{
 | 
			
		||||
    prop: 'pos',
 | 
			
		||||
		label: '工位编号'
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
    prop: 'pallet',
 | 
			
		||||
    label: '托数/托'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'palletNum',
 | 
			
		||||
    label: '下片托数'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'startTime',
 | 
			
		||||
    label: '开始时间',
 | 
			
		||||
    filter: parseTime,
 | 
			
		||||
    width: 160
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'endTime',
 | 
			
		||||
    label: '结束时间',
 | 
			
		||||
    filter: parseTime,
 | 
			
		||||
    width: 160
 | 
			
		||||
  },
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'outputNum',
 | 
			
		||||
    label: '玻璃长度/mm'
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'width',
 | 
			
		||||
    label: '玻璃宽度/mm',
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
    prop: 'thick',
 | 
			
		||||
    label: '玻璃厚度/mm'
 | 
			
		||||
	},
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			urlOptions: {
 | 
			
		||||
				getDataListURL: getDownLogPage
 | 
			
		||||
			},
 | 
			
		||||
      tableData: [],
 | 
			
		||||
      listQuery: {
 | 
			
		||||
        pageSize: 10,
 | 
			
		||||
        pageNo: 1,
 | 
			
		||||
        total: 1,
 | 
			
		||||
        productionLineId: undefined,
 | 
			
		||||
        thick: undefined,
 | 
			
		||||
 | 
			
		||||
      },
 | 
			
		||||
      exportLoading: false,
 | 
			
		||||
      dataListLoading: false,
 | 
			
		||||
			selectedList: [],
 | 
			
		||||
			dialogVisible: false,
 | 
			
		||||
      addOrEditTitle: '',
 | 
			
		||||
      addOrUpdateVisible: false,
 | 
			
		||||
			tableProps,
 | 
			
		||||
      tableBtn: [
 | 
			
		||||
        {
 | 
			
		||||
          type: 'his',
 | 
			
		||||
          btnName: '历史',
 | 
			
		||||
        },
 | 
			
		||||
      ].filter((v) => v),
 | 
			
		||||
			tableData: [],
 | 
			
		||||
			showData: [],
 | 
			
		||||
			fileName: '',
 | 
			
		||||
			formConfig: [
 | 
			
		||||
				{
 | 
			
		||||
					type: 'select',
 | 
			
		||||
					label: '产线',
 | 
			
		||||
					selectOptions: [],
 | 
			
		||||
          param: 'productionLineId'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          type: 'select',
 | 
			
		||||
          label: '玻璃型号',
 | 
			
		||||
          selectOptions: [],
 | 
			
		||||
          param: 'thick'
 | 
			
		||||
        },
 | 
			
		||||
				{
 | 
			
		||||
          type: 'datePicker',
 | 
			
		||||
          label: '统计开始时间',
 | 
			
		||||
          dateType: 'daterange',
 | 
			
		||||
          format: 'yyyy-MM-dd',
 | 
			
		||||
          valueFormat: "yyyy-MM-dd HH:mm:ss",
 | 
			
		||||
          rangeSeparator: '-',
 | 
			
		||||
          startPlaceholder: '开始时间',
 | 
			
		||||
          endPlaceholder: '结束时间',
 | 
			
		||||
          param: 'timeVal',
 | 
			
		||||
          defaultTime: ['00:00:00', '23:59:59'],
 | 
			
		||||
          defaultSelect: []
 | 
			
		||||
        },
 | 
			
		||||
				{
 | 
			
		||||
					type: 'button',
 | 
			
		||||
					btnName: '查询',
 | 
			
		||||
					name: 'search',
 | 
			
		||||
					color: 'primary',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'separate',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					// type: this.$auth.hasPermi('base:factory:export') ? 'button' : '',
 | 
			
		||||
					type: 'button',
 | 
			
		||||
					btnName: '导出',
 | 
			
		||||
					name: 'export',
 | 
			
		||||
					color: 'warning',
 | 
			
		||||
				}
 | 
			
		||||
			],
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	created() {
 | 
			
		||||
		this.getDataList()
 | 
			
		||||
		this.getPdLineList()
 | 
			
		||||
	},
 | 
			
		||||
  methods: {
 | 
			
		||||
    handleClick(val) {
 | 
			
		||||
      console.log(val);
 | 
			
		||||
      if (val.type === 'his') {
 | 
			
		||||
        this.$router.push({
 | 
			
		||||
          path: 'nextClipHis',
 | 
			
		||||
          query: {
 | 
			
		||||
            eqName: val.data.eqName,
 | 
			
		||||
            productionLineId: this.listQuery.productionLineId,
 | 
			
		||||
            thick: this.listQuery.thick,
 | 
			
		||||
          },
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
			// this.addOrUpdateVisible = true;
 | 
			
		||||
			// this.addOrEditTitle =
 | 
			
		||||
			// 	val.data?.factoryName + '-' + val.data?.lineName + ' 详情';
 | 
			
		||||
			// this.$nextTick(() => {
 | 
			
		||||
			// 	this.$refs.eqDetail.init(
 | 
			
		||||
			// 		val.data.lineId,
 | 
			
		||||
			// 		this.listQuery.startTime,
 | 
			
		||||
			// 		this.listQuery.endTime
 | 
			
		||||
			// 	);
 | 
			
		||||
			// });
 | 
			
		||||
		},
 | 
			
		||||
		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
 | 
			
		||||
 | 
			
		||||
						// 一页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 {
 | 
			
		||||
        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 || []
 | 
			
		||||
			})
 | 
			
		||||
      getThick().then((res) => {
 | 
			
		||||
        this.formConfig[1].selectOptions = res.data.map((item) => {
 | 
			
		||||
          return {
 | 
			
		||||
            id: item.thick + 'mm',
 | 
			
		||||
            name: item.thick + 'mm'
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
			})
 | 
			
		||||
		},
 | 
			
		||||
		selectChange(val) {
 | 
			
		||||
      console.log(val)
 | 
			
		||||
      this.selectedList = val
 | 
			
		||||
    },
 | 
			
		||||
		buttonClick(val) {
 | 
			
		||||
			switch (val.btnName) {
 | 
			
		||||
				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.reportEndTime = val.timeVal ? [new Date(val.timeVal[1]).getTime()] : undefined;
 | 
			
		||||
					this.getDataList();
 | 
			
		||||
					break;
 | 
			
		||||
				case 'export':
 | 
			
		||||
					this.handleExport();
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					console.log(val);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		// 获取数据列表
 | 
			
		||||
    getDataList() {
 | 
			
		||||
      this.dataListLoading = true;
 | 
			
		||||
      this.urlOptions.getDataListURL(this.listQuery).then(response => {
 | 
			
		||||
        this.tableData = response.data.list
 | 
			
		||||
				this.showData = this.tableData
 | 
			
		||||
        this.listQuery.total = response.data.total;
 | 
			
		||||
        this.dataListLoading = false;
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
    // 每页数
 | 
			
		||||
    sizeChangeHandle(val) {
 | 
			
		||||
      this.listQuery.pageSize = val;
 | 
			
		||||
      this.listQuery.pageNo = 1;
 | 
			
		||||
      this.getDataList();
 | 
			
		||||
    },
 | 
			
		||||
    // 当前页
 | 
			
		||||
    currentChangeHandle(val) {
 | 
			
		||||
      this.listQuery.pageNo = val;
 | 
			
		||||
      this.getDataList();
 | 
			
		||||
    },
 | 
			
		||||
    handleExport() {
 | 
			
		||||
      // 处理查询参数
 | 
			
		||||
      let params = { ...this.listQuery };
 | 
			
		||||
      params.pageNo = undefined;
 | 
			
		||||
      params.pageSize = undefined;
 | 
			
		||||
      this.$modal.confirm('是否确认导出下片日志?').then(() => {
 | 
			
		||||
        this.exportLoading = true;
 | 
			
		||||
        return exportDownLogData(params);
 | 
			
		||||
      }).then(response => {
 | 
			
		||||
        this.$download.excel(response, '下片日志.xls');
 | 
			
		||||
        this.exportLoading = false;
 | 
			
		||||
      }).catch(() => { });
 | 
			
		||||
    }
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										272
									
								
								src/views/core/monitoring/productAuto/BarChart.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,272 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div :class="className" :style="{ height: height, width: width, marginLeft: '10px' }" />
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import * as echarts from 'echarts';
 | 
			
		||||
require('echarts/theme/macarons'); // 引入主题
 | 
			
		||||
import resize from '@/utils/chartMixins/resize';
 | 
			
		||||
 | 
			
		||||
const animationDuration = 1000;
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  mixins: [resize], // 混入 resize 逻辑(自适应窗口)
 | 
			
		||||
  props: {
 | 
			
		||||
    className: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'chart',
 | 
			
		||||
    },
 | 
			
		||||
    title: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: '',
 | 
			
		||||
    },
 | 
			
		||||
    width: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: '100%',
 | 
			
		||||
    },
 | 
			
		||||
    height: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: '300px',
 | 
			
		||||
    },
 | 
			
		||||
    barData: {
 | 
			
		||||
      type: Array,
 | 
			
		||||
      default: () => [],
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      chart: null, // 图表实例
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    // 监听 barData 变化(深度监听数组内部元素)
 | 
			
		||||
    barData: {
 | 
			
		||||
      deep: true,
 | 
			
		||||
      handler: 'handleBarDataChange', // 调用处理方法
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    // 组件挂载后初始化图表(确保 DOM 已就绪)
 | 
			
		||||
    this.$nextTick(() => {
 | 
			
		||||
      this.initChart();
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
  beforeDestroy() {
 | 
			
		||||
    // 组件销毁前清理图表实例
 | 
			
		||||
    if (this.chart) {
 | 
			
		||||
      this.chart.dispose();
 | 
			
		||||
      this.chart = null;
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    // barData 变化时的处理方法
 | 
			
		||||
    handleBarDataChange() {
 | 
			
		||||
      // 确保 DOM 存在再更新图表
 | 
			
		||||
      this.$nextTick(() => {
 | 
			
		||||
        // 如果图表未初始化,先初始化;否则直接更新数据
 | 
			
		||||
        if (!this.chart) {
 | 
			
		||||
          this.initChart();
 | 
			
		||||
        } else {
 | 
			
		||||
          this.updateChart();
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 初始化图表
 | 
			
		||||
    initChart() {
 | 
			
		||||
      // 避免重复初始化(先销毁旧实例)
 | 
			
		||||
      if (this.chart) {
 | 
			
		||||
        this.chart.dispose();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 确保 DOM 元素存在
 | 
			
		||||
      if (!this.$el) {
 | 
			
		||||
        console.error('图表容器 DOM 元素不存在');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 初始化图表实例
 | 
			
		||||
      this.chart = echarts.init(this.$el, 'macarons');
 | 
			
		||||
      // 设置图表配置
 | 
			
		||||
      this.setChartOption();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 更新图表数据(复用配置逻辑)
 | 
			
		||||
    updateChart() {
 | 
			
		||||
      if (!this.chart) return;
 | 
			
		||||
      this.setChartOption();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 图表配置项(抽离为单独方法,方便初始化和更新复用)
 | 
			
		||||
    setChartOption() {
 | 
			
		||||
      const dataValues = this.barData.flatMap(item => [item.inputNum || 0, item.outputNum || 0]);
 | 
			
		||||
      const maxData = Math.max(...dataValues, 0); // 加 0 确保无数据时 maxData 为 0
 | 
			
		||||
 | 
			
		||||
      // 2. 计算 Y 轴最大值(留 10% 余量,避免数据顶到顶部)
 | 
			
		||||
      let yMax = 0;
 | 
			
		||||
      if (maxData > 0) {
 | 
			
		||||
        yMax = Math.ceil(maxData * 1.1); // 向上取整,确保刻度为整数
 | 
			
		||||
      } else {
 | 
			
		||||
        yMax = 100; // 无数据时默认最大值为 100,避免 Y 轴消失
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 3. 计算 interval(5 个刻度对应 4 个间隔,向上取整确保间隔为整数)
 | 
			
		||||
      const yInterval = Math.ceil((yMax - 0) / 4); // min 固定为 0,直接减 0
 | 
			
		||||
 | 
			
		||||
      this.chart.setOption({
 | 
			
		||||
        title: {
 | 
			
		||||
          text: this.title
 | 
			
		||||
            ? '{space|}{tip|}{space|}{value|' + this.title + '}'
 | 
			
		||||
            : '',
 | 
			
		||||
          textStyle: {
 | 
			
		||||
            rich: {
 | 
			
		||||
              tip: {
 | 
			
		||||
                width: 6,
 | 
			
		||||
                height: 6,
 | 
			
		||||
                borderRadius: 50,
 | 
			
		||||
                backgroundColor: '#288AFF',
 | 
			
		||||
              },
 | 
			
		||||
              space: {
 | 
			
		||||
                width: 8,
 | 
			
		||||
              },
 | 
			
		||||
              value: {
 | 
			
		||||
                fontSize: 14,
 | 
			
		||||
                color: 'black',
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        color: ['#288AFF', '#8EF0AB', '#FFDC94'],
 | 
			
		||||
        tooltip: {
 | 
			
		||||
          trigger: 'axis',
 | 
			
		||||
          axisPointer: {
 | 
			
		||||
            type: 'cross',
 | 
			
		||||
            crossStyle: {
 | 
			
		||||
              color: '#999',
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        legend: {
 | 
			
		||||
          data: ['投入', '产出', '加工成品率'],
 | 
			
		||||
        },
 | 
			
		||||
        grid: {
 | 
			
		||||
          left: 20,
 | 
			
		||||
          right: 30,
 | 
			
		||||
          top:40,
 | 
			
		||||
          bottom: 10,
 | 
			
		||||
 | 
			
		||||
          containLabel: true,
 | 
			
		||||
          splitArea: {
 | 
			
		||||
            show: false // 关键:关闭网格背景分区(去掉间隔色块)
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        xAxis: {
 | 
			
		||||
          type: 'category',
 | 
			
		||||
          data: this.barData.map((item) => item.lineName),
 | 
			
		||||
          axisLine: {
 | 
			
		||||
            lineStyle: {
 | 
			
		||||
              color: 'rgba(0, 0, 0, 0.45)',
 | 
			
		||||
              width: 1 // 轴线宽度(可选,默认 1,可按需调整)
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          // 2. 控制 X 轴刻度线颜色(与轴线颜色保持一致,视觉统一)
 | 
			
		||||
          axisTick: {
 | 
			
		||||
            lineStyle: {
 | 
			
		||||
              color: 'rgba(0, 0, 0, 0.45)', // 刻度线颜色,需与轴线颜色匹配
 | 
			
		||||
              width: 1 // 刻度线宽度(可选)
 | 
			
		||||
            },
 | 
			
		||||
            alignWithLabel: true // 可选:让刻度线与文字对齐(避免文字偏移时刻度线错位)
 | 
			
		||||
          },
 | 
			
		||||
          // 3. 控制 X 轴文字颜色(如:深灰色 rgba(0, 0, 0, 0.45))
 | 
			
		||||
          axisLabel: {
 | 
			
		||||
            color: 'rgba(0, 0, 0, 0.45)6', // 文字颜色,可自定义
 | 
			
		||||
            fontSize: 12, // 可选:调整文字大小(默认 12,按需修改)
 | 
			
		||||
            // 可选:文字过长时换行/省略(避免文字重叠,按需开启)
 | 
			
		||||
            formatter: (value) => {
 | 
			
		||||
              // 示例:文字超过 6 个字符时换行(可根据需求调整字符数)
 | 
			
		||||
              if (value.length > 6) {
 | 
			
		||||
                return value.slice(0, 6) + '\n' + value.slice(6);
 | 
			
		||||
              }
 | 
			
		||||
              return value;
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          // 原有配置(若需保留可解开注释)
 | 
			
		||||
          // axisPointer: {
 | 
			
		||||
          //   type: 'shadow',
 | 
			
		||||
          // }
 | 
			
		||||
        },
 | 
			
		||||
        yAxis: [
 | 
			
		||||
          {
 | 
			
		||||
            type: 'value',
 | 
			
		||||
            name: '投入/产出 片',
 | 
			
		||||
            min: 0, // 最小值固定为 0
 | 
			
		||||
            max: yMax,
 | 
			
		||||
            interval: yInterval,
 | 
			
		||||
            splitArea: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            axisLabel: {
 | 
			
		||||
              formatter: '{value}',
 | 
			
		||||
              color: 'rgba(0, 0, 0, 0.45)'
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // 可选:修改 Y 轴名称颜色(与文字颜色保持一致)
 | 
			
		||||
            nameTextStyle: {
 | 
			
		||||
              color: 'rgba(0, 0, 0, 0.45)'
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            type: 'value',
 | 
			
		||||
            name: '加工成品率',
 | 
			
		||||
            min: 0,
 | 
			
		||||
            max: 100, // 成品率固定 0-100%
 | 
			
		||||
            interval: 25, // 100 / 4 = 25,刚好 5 个刻度(0、25、50、75、100)
 | 
			
		||||
            axisLabel: {
 | 
			
		||||
              formatter: '{value} %',
 | 
			
		||||
              color: 'rgba(0, 0, 0, 0.45)'
 | 
			
		||||
            },
 | 
			
		||||
            splitArea: {
 | 
			
		||||
              show: false
 | 
			
		||||
            },
 | 
			
		||||
            // 可选:修改 Y 轴名称颜色
 | 
			
		||||
            nameTextStyle: {
 | 
			
		||||
              color: 'rgba(0, 0, 0, 0.45)'
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
        series: [
 | 
			
		||||
          {
 | 
			
		||||
            name: '投入',
 | 
			
		||||
            type: 'bar',
 | 
			
		||||
            barWidth: '20',
 | 
			
		||||
            data: this.barData.map((item) => item.inputNum),
 | 
			
		||||
            tooltip: {
 | 
			
		||||
              valueFormatter: (value) => `${value} 片`,
 | 
			
		||||
            },
 | 
			
		||||
            animationDuration,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: '产出',
 | 
			
		||||
            type: 'bar',
 | 
			
		||||
            barWidth: '20',
 | 
			
		||||
            data: this.barData.map((item) => item.outputNum),
 | 
			
		||||
            tooltip: {
 | 
			
		||||
              valueFormatter: (value) => `${value} 片`,
 | 
			
		||||
            },
 | 
			
		||||
            animationDuration,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: '加工成品率',
 | 
			
		||||
            type: 'line',
 | 
			
		||||
            yAxisIndex: 1,
 | 
			
		||||
            tooltip: {
 | 
			
		||||
              valueFormatter: (value) => `${value} %`,
 | 
			
		||||
            },
 | 
			
		||||
            data: this.barData.map((item) => item.processingRatio),
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										273
									
								
								src/views/core/monitoring/productAuto/baseTable.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,273 @@
 | 
			
		||||
<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;
 | 
			
		||||
}
 | 
			
		||||
</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>
 | 
			
		||||
							
								
								
									
										65
									
								
								src/views/core/monitoring/rawFilmReport/SmallTitle.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,65 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2023-08-01 15:27:31
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2023-08-01 16:25:54
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<div :class="[className, { 'p-0': noPadding }]">
 | 
			
		||||
		<slot />
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
	props: {
 | 
			
		||||
		size: {
 | 
			
		||||
			// 取值范围:  xl lg md sm
 | 
			
		||||
			type: String,
 | 
			
		||||
			default: 'de',
 | 
			
		||||
			validator: function (val) {
 | 
			
		||||
				return ['xl', 'lg', 'de', 'md', 'sm'].indexOf(val) !== -1;
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		noPadding: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			default: false,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	computed: {
 | 
			
		||||
		className: function () {
 | 
			
		||||
			return `${this.size}-title`;
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
$pxls: (xl, 28px) (lg, 24px) (de, 20px) (md, 18px) (sm, 16px);
 | 
			
		||||
$mgr: 8px;
 | 
			
		||||
@each $size, $height in $pxls {
 | 
			
		||||
	.#{$size}-title {
 | 
			
		||||
		font-size: 18px;
 | 
			
		||||
		line-height: $height;
 | 
			
		||||
		color: #000;
 | 
			
		||||
		font-weight: 500;
 | 
			
		||||
		font-family: '微软雅黑', 'Microsoft YaHei', Arial, Helvetica, sans-serif;
 | 
			
		||||
 | 
			
		||||
		&::before {
 | 
			
		||||
			content: '';
 | 
			
		||||
			display: inline-block;
 | 
			
		||||
			vertical-align: top;
 | 
			
		||||
			width: 4px;
 | 
			
		||||
			height: $height + 2px;
 | 
			
		||||
			border-radius: 1px;
 | 
			
		||||
			margin-right: $mgr;
 | 
			
		||||
			background-color: #0b58ff;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.p-0 {
 | 
			
		||||
	padding: 0;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										221
									
								
								src/views/core/monitoring/rawFilmReport/add-or-updata.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,221 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <el-dialog :visible.sync="visible" width="40%">
 | 
			
		||||
    <small-title slot="title" :no-padding="true">
 | 
			
		||||
      {{ !dataForm.id ? '新增' : '编辑' }}
 | 
			
		||||
    </small-title>
 | 
			
		||||
 | 
			
		||||
    <div class="content">
 | 
			
		||||
      <div class="visual-part">
 | 
			
		||||
        <el-form ref="dataForm" :model="dataForm" :rules="dataRule" label-width="100px"
 | 
			
		||||
          @keyup.enter.native="dataFormSubmit">
 | 
			
		||||
          <el-row :gutter="20">
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="维度" prop="statisticType">
 | 
			
		||||
                <el-select v-model="dataForm.statisticType" style="width: 100%" placeholder="请选择维度">
 | 
			
		||||
                  <el-option v-for="item in statisticTypeList" :key="item.id" :label="item.name" :value="item.id" />
 | 
			
		||||
                </el-select>
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="厚度" prop="modifyThick">
 | 
			
		||||
                <el-input v-model="dataForm.modifyThick" placeholder="请输入厚度" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
          </el-row>
 | 
			
		||||
          <el-row :gutter="20">
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="在线速度" prop="modifySpeed">
 | 
			
		||||
                <el-input v-model="dataForm.modifySpeed" placeholder="请输入在线速度" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="宽度" prop="modifyWidth">
 | 
			
		||||
                <el-input v-model="dataForm.modifyWidth" placeholder="请输入宽度" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
          </el-row>
 | 
			
		||||
          <el-row :gutter="20">
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="拉引量" prop="modifyInArea">
 | 
			
		||||
                <el-input v-model="dataForm.modifyInArea" placeholder="请输入拉引量" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="下片面积" prop="modifyOutArea">
 | 
			
		||||
                <el-input v-model="dataForm.modifyOutArea" placeholder="请输入下片面积" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
          </el-row>
 | 
			
		||||
          <el-row :gutter="20">
 | 
			
		||||
            <el-col :span="12">
 | 
			
		||||
              <el-form-item label="良品率" prop="modifyRatio">
 | 
			
		||||
                <el-input v-model="dataForm.modifyRatio" placeholder="请输入良品率" />
 | 
			
		||||
              </el-form-item>
 | 
			
		||||
            </el-col>
 | 
			
		||||
          </el-row>
 | 
			
		||||
        </el-form>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div slot="footer" class="dialog-footer">
 | 
			
		||||
      <el-button style="" @click="goback()">取消</el-button>
 | 
			
		||||
      <el-button  type="primary" @click="dataFormSubmit()">
 | 
			
		||||
        确定
 | 
			
		||||
      </el-button>
 | 
			
		||||
    </div>
 | 
			
		||||
  </el-dialog>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { editCostOriginRadioHisData } from '@/api/core/monitoring/index'
 | 
			
		||||
import { parseTime } from '../../mixins/code-filter';
 | 
			
		||||
import SmallTitle from './SmallTitle';
 | 
			
		||||
export default {
 | 
			
		||||
	components: { SmallTitle },
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			visible: false,
 | 
			
		||||
			addOrUpdateVisible: false,
 | 
			
		||||
      statisticTypeList: [
 | 
			
		||||
        {
 | 
			
		||||
          id: '0',
 | 
			
		||||
          name: '班组'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          id: '1',
 | 
			
		||||
          name: '日'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          id: '2',
 | 
			
		||||
          name: '周'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          id: '3',
 | 
			
		||||
          name: '月'
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          id: '4',
 | 
			
		||||
          name: '年'
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
			dataForm: {
 | 
			
		||||
				id: null,
 | 
			
		||||
        statisticType:undefined,
 | 
			
		||||
        modifyThick: undefined,
 | 
			
		||||
        modifySpeed: undefined,
 | 
			
		||||
        modifyWidth: undefined,
 | 
			
		||||
        modifyInArea: undefined,
 | 
			
		||||
        modifyOutArea: undefined,
 | 
			
		||||
        modifyRatio: undefined,
 | 
			
		||||
			},
 | 
			
		||||
			dataRule: {
 | 
			
		||||
        statisticType: [
 | 
			
		||||
					{
 | 
			
		||||
						required: true,
 | 
			
		||||
						message: '维度不能为空',
 | 
			
		||||
						trigger: 'blur',
 | 
			
		||||
					},
 | 
			
		||||
					// {
 | 
			
		||||
					// 	type: 'number',
 | 
			
		||||
					// 	message: '产品编码为数字类型',
 | 
			
		||||
					// 	trigger: 'blur',
 | 
			
		||||
					// 	transfom: 'val => Number(val)',
 | 
			
		||||
					// },
 | 
			
		||||
				],
 | 
			
		||||
			},
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
    init(data) {
 | 
			
		||||
      console.log(data,'data');
 | 
			
		||||
 | 
			
		||||
			this.dataForm.id = data.id || null;
 | 
			
		||||
			this.visible = true;
 | 
			
		||||
			this.$nextTick(() => {
 | 
			
		||||
        this.$refs['dataForm'].resetFields();
 | 
			
		||||
        this.dataForm = {
 | 
			
		||||
          id: data.id || null,
 | 
			
		||||
          statisticType: data.statisticType || undefined,
 | 
			
		||||
          modifyThick: data.thick || undefined, // 厚度对应
 | 
			
		||||
          modifySpeed: data.speed || undefined, // 在线速度对应
 | 
			
		||||
          modifyWidth: data.width || undefined, // 掰边宽度对应
 | 
			
		||||
          modifyInArea: data.inArea || undefined, // 拉引量对应
 | 
			
		||||
          modifyOutArea: data.outArea || undefined, // 下片面积对应
 | 
			
		||||
          modifyRatio: data.ratio || undefined, // 良品率对应
 | 
			
		||||
        };
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		// 表单提交
 | 
			
		||||
		dataFormSubmit() {
 | 
			
		||||
			this.$refs['dataForm'].validate((valid) => {
 | 
			
		||||
				if (valid) {
 | 
			
		||||
					// 修改的提交
 | 
			
		||||
					if (this.dataForm.id) {
 | 
			
		||||
            editCostOriginRadioHisData(this.dataForm).then((response) => {
 | 
			
		||||
							this.$modal.msgSuccess('修改成功');
 | 
			
		||||
							this.visible = false;
 | 
			
		||||
							this.$emit('refreshDataList');
 | 
			
		||||
						});
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		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-form-item__label {
 | 
			
		||||
	padding: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.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 >>> .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 >>> .el-form,
 | 
			
		||||
.drawer >>> .attr-list {
 | 
			
		||||
	padding: 0 16px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.drawer-body__footer {
 | 
			
		||||
	display: flex;
 | 
			
		||||
	justify-content: flex-end;
 | 
			
		||||
	padding: 18px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										281
									
								
								src/views/core/monitoring/rawFilmReport/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,281 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: Do not edit
 | 
			
		||||
 * @Date: 2023-08-29 14:59:29
 | 
			
		||||
 * @LastEditTime: 2024-12-02 13:44:47
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="app-container">
 | 
			
		||||
    <!-- :isFold="true" 控制展开 -->
 | 
			
		||||
    <search-bar :formConfigs="formConfig" ref="searchBarForm" @headBtnClick="buttonClick" />
 | 
			
		||||
    <base-table v-if="tableData.length" class="right-aside" v-loading="dataListLoading" :table-props="tableProps"
 | 
			
		||||
      :page="listQuery.pageNo" :limit="listQuery.pageSize" :table-data="tableData">
 | 
			
		||||
      <method-btn v-if="tableBtn.length" slot="handleBtn" :width="120" label="操作" :method-list="tableBtn"
 | 
			
		||||
        @clickBtn="handleClick" />
 | 
			
		||||
    </base-table>
 | 
			
		||||
    <div v-else class="no-data-bg"></div>
 | 
			
		||||
    <pagination :limit.sync="listQuery.pageSize" :page.sync="listQuery.pageNo" :total="listQuery.total"
 | 
			
		||||
      @pagination="getDataList" />
 | 
			
		||||
    <!-- <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> -->
 | 
			
		||||
    <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList" />
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import AddOrUpdate from './add-or-updata';
 | 
			
		||||
import { parseTime } from '../../mixins/code-filter';
 | 
			
		||||
import { getCostOriginRadioHisData, getPdList  } from '@/api/core/monitoring/index'
 | 
			
		||||
import * as XLSX from 'xlsx'
 | 
			
		||||
import FileSaver from 'file-saver'
 | 
			
		||||
import jsPDF from 'jspdf'
 | 
			
		||||
import html2canvas from 'html2canvas'
 | 
			
		||||
import { exportCostOriginRadioHisData } from '../../../../api/core/monitoring';
 | 
			
		||||
 | 
			
		||||
const tableProps = [
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'reportType',
 | 
			
		||||
    label: '报表类型'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'time',
 | 
			
		||||
    label: '日期',
 | 
			
		||||
    // filter: parseTime,
 | 
			
		||||
    width: 160
 | 
			
		||||
  },
 | 
			
		||||
	{
 | 
			
		||||
    prop: 'bindObjectName',
 | 
			
		||||
		label: '产线'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'thick',
 | 
			
		||||
    label: '厚度'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'speed',
 | 
			
		||||
    label: '在线速度'
 | 
			
		||||
  },
 | 
			
		||||
	{
 | 
			
		||||
    prop: 'width',
 | 
			
		||||
    label: '掰边宽度'
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
    prop: 'inArea',
 | 
			
		||||
    label: '拉引量/㎡'
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    prop: 'outArea',
 | 
			
		||||
    label: '下片面积/㎡'
 | 
			
		||||
  },
 | 
			
		||||
	{
 | 
			
		||||
    prop: 'ratio',
 | 
			
		||||
    label: '良品率'
 | 
			
		||||
	},
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  components: {
 | 
			
		||||
    AddOrUpdate
 | 
			
		||||
  },
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			urlOptions: {
 | 
			
		||||
				getDataListURL: getCostOriginRadioHisData
 | 
			
		||||
			},
 | 
			
		||||
      tableData: [],
 | 
			
		||||
      listQuery: {
 | 
			
		||||
        pageSize: 10,
 | 
			
		||||
        pageNo: 1,
 | 
			
		||||
        total: 1,
 | 
			
		||||
        bindObjectId: undefined,
 | 
			
		||||
        statisticType: undefined,
 | 
			
		||||
      },
 | 
			
		||||
      pdLineList:[],
 | 
			
		||||
      exportLoading: false,
 | 
			
		||||
      dataListLoading: false,
 | 
			
		||||
			selectedList: [],
 | 
			
		||||
			dialogVisible: false,
 | 
			
		||||
      addOrEditTitle: '',
 | 
			
		||||
      addOrUpdateVisible: false,
 | 
			
		||||
			tableProps,
 | 
			
		||||
      tableBtn: [
 | 
			
		||||
        {
 | 
			
		||||
          type: 'edit',
 | 
			
		||||
          btnName: '编辑',
 | 
			
		||||
        },
 | 
			
		||||
      ].filter((v) => v),
 | 
			
		||||
			tableData: [],
 | 
			
		||||
			fileName: '',
 | 
			
		||||
      formConfig: [
 | 
			
		||||
        {
 | 
			
		||||
          type: 'select',
 | 
			
		||||
          label: '维度',
 | 
			
		||||
          selectOptions: [
 | 
			
		||||
            {
 | 
			
		||||
              id: '0',
 | 
			
		||||
              name:'班组'
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              id: '1',
 | 
			
		||||
              name: '日'
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              id: '2',
 | 
			
		||||
              name: '周'
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              id: '3',
 | 
			
		||||
              name: '月'
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              id: '4',
 | 
			
		||||
              name: '年'
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          param: 'statisticType'
 | 
			
		||||
        },
 | 
			
		||||
				{
 | 
			
		||||
					type: 'select',
 | 
			
		||||
					label: '产线',
 | 
			
		||||
					selectOptions: [],
 | 
			
		||||
          param: 'bindObjectId'
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
				{
 | 
			
		||||
          type: 'datePicker',
 | 
			
		||||
          label: '统计开始时间',
 | 
			
		||||
          dateType: 'daterange',
 | 
			
		||||
          format: 'yyyy-MM-dd',
 | 
			
		||||
          valueFormat: "yyyy-MM-dd HH:mm:ss",
 | 
			
		||||
          rangeSeparator: '-',
 | 
			
		||||
          startPlaceholder: '开始时间',
 | 
			
		||||
          endPlaceholder: '结束时间',
 | 
			
		||||
          param: 'timeVal',
 | 
			
		||||
          defaultTime: ['00:00:00', '23:59:59'],
 | 
			
		||||
          defaultSelect: []
 | 
			
		||||
        },
 | 
			
		||||
				{
 | 
			
		||||
					type: 'button',
 | 
			
		||||
					btnName: '查询',
 | 
			
		||||
					name: 'search',
 | 
			
		||||
					color: 'primary',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'separate',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					// type: this.$auth.hasPermi('base:factory:export') ? 'button' : '',
 | 
			
		||||
					type: 'button',
 | 
			
		||||
					btnName: '导出',
 | 
			
		||||
					name: 'export',
 | 
			
		||||
					color: 'warning',
 | 
			
		||||
				}
 | 
			
		||||
			],
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.$refs.searchBarForm.formInline.statisticType = '1';
 | 
			
		||||
    this.listQuery.statisticType = '1';
 | 
			
		||||
		this.getDataList()
 | 
			
		||||
    this.getPdLineList()
 | 
			
		||||
	},
 | 
			
		||||
  methods: {
 | 
			
		||||
    handleClick(val) {
 | 
			
		||||
      console.log(val);
 | 
			
		||||
      if (val.type === 'edit') {
 | 
			
		||||
        this.addOrUpdateVisible= true
 | 
			
		||||
        this.$nextTick(() => {
 | 
			
		||||
          this.$refs.addOrUpdate.init(val.data);
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		getPdLineList() {
 | 
			
		||||
			getPdList().then((res) => {
 | 
			
		||||
        this.formConfig[1].selectOptions = res.data || []
 | 
			
		||||
        this.pdLineList = res.data || []; // 保存产线数据
 | 
			
		||||
			})
 | 
			
		||||
		},
 | 
			
		||||
		selectChange(val) {
 | 
			
		||||
      console.log(val)
 | 
			
		||||
      this.selectedList = val
 | 
			
		||||
    },
 | 
			
		||||
    buttonClick(val) {
 | 
			
		||||
      console.log('val', val);
 | 
			
		||||
 | 
			
		||||
			switch (val.btnName) {
 | 
			
		||||
				case 'search':
 | 
			
		||||
					this.listQuery.pageNo = 1;
 | 
			
		||||
					this.listQuery.pageSize = 10;
 | 
			
		||||
          this.listQuery.bindObjectId = val.bindObjectId ? val.bindObjectId : undefined;
 | 
			
		||||
          this.listQuery.statisticType = val.statisticType ? val.statisticType : 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.handleExport();
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					console.log(val);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		// 获取数据列表
 | 
			
		||||
    getDataList() {
 | 
			
		||||
      this.dataListLoading = true;
 | 
			
		||||
      this.urlOptions.getDataListURL(this.listQuery).then(response => {
 | 
			
		||||
        const arr = ['班组','日', '周', '月', '年'];
 | 
			
		||||
        this.tableData = response.data?.list?.map((item) => {
 | 
			
		||||
          item.reportType = arr[this.listQuery.statisticType];
 | 
			
		||||
          item.statisticType = this.listQuery.statisticType
 | 
			
		||||
 | 
			
		||||
          // 匹配 bindObjectName
 | 
			
		||||
          const targetLine = this.pdLineList.find(line => line.id === item.bindObjectId);
 | 
			
		||||
          item.bindObjectName = targetLine ? targetLine.name : ''; // 赋值名称,无匹配则为空
 | 
			
		||||
          return item;
 | 
			
		||||
        });
 | 
			
		||||
        this.listQuery.total = response.data.total;
 | 
			
		||||
        this.dataListLoading = false;
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
    // 每页数
 | 
			
		||||
    sizeChangeHandle(val) {
 | 
			
		||||
      this.listQuery.pageSize = val;
 | 
			
		||||
      this.listQuery.pageNo = 1;
 | 
			
		||||
      this.getDataList();
 | 
			
		||||
    },
 | 
			
		||||
    // 当前页
 | 
			
		||||
    currentChangeHandle(val) {
 | 
			
		||||
      this.listQuery.pageNo = val;
 | 
			
		||||
      this.getDataList();
 | 
			
		||||
    },
 | 
			
		||||
    handleExport() {
 | 
			
		||||
      // 处理查询参数
 | 
			
		||||
      let params = { ...this.listQuery };
 | 
			
		||||
      params.pageNo = undefined;
 | 
			
		||||
      params.pageSize = undefined;
 | 
			
		||||
      this.$modal.confirm('是否确认导出原片报表?').then(() => {
 | 
			
		||||
        this.exportLoading = true;
 | 
			
		||||
        return exportCostOriginRadioHisData(params);
 | 
			
		||||
      }).then(response => {
 | 
			
		||||
        this.$download.excel(response, '原片报表.xls');
 | 
			
		||||
        this.exportLoading = false;
 | 
			
		||||
      }).catch(() => { });
 | 
			
		||||
    }
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										65
									
								
								src/views/group/Schedule/SmallTitle.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,65 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2023-08-01 15:27:31
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2023-08-01 16:25:54
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<div :class="[className, { 'p-0': noPadding }]">
 | 
			
		||||
		<slot />
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
	props: {
 | 
			
		||||
		size: {
 | 
			
		||||
			// 取值范围:  xl lg md sm
 | 
			
		||||
			type: String,
 | 
			
		||||
			default: 'de',
 | 
			
		||||
			validator: function (val) {
 | 
			
		||||
				return ['xl', 'lg', 'de', 'md', 'sm'].indexOf(val) !== -1;
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		noPadding: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			default: false,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	computed: {
 | 
			
		||||
		className: function () {
 | 
			
		||||
			return `${this.size}-title`;
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss" scoped>
 | 
			
		||||
$pxls: (xl, 28px) (lg, 24px) (de, 20px) (md, 18px) (sm, 16px);
 | 
			
		||||
$mgr: 8px;
 | 
			
		||||
@each $size, $height in $pxls {
 | 
			
		||||
	.#{$size}-title {
 | 
			
		||||
		font-size: $height;
 | 
			
		||||
		line-height: $height;
 | 
			
		||||
		color: #000;
 | 
			
		||||
		font-weight: 500;
 | 
			
		||||
		font-family: '微软雅黑', 'Microsoft YaHei', Arial, Helvetica, sans-serif;
 | 
			
		||||
 | 
			
		||||
		&::before {
 | 
			
		||||
			content: '';
 | 
			
		||||
			display: inline-block;
 | 
			
		||||
			vertical-align: top;
 | 
			
		||||
			width: 4px;
 | 
			
		||||
			height: $height + 2px;
 | 
			
		||||
			border-radius: 1px;
 | 
			
		||||
			margin-right: $mgr;
 | 
			
		||||
			background-color: #0b58ff;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.p-0 {
 | 
			
		||||
	padding: 0;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										125
									
								
								src/views/group/Schedule/add-group.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,125 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2025-10-11 14:27:37
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2025-10-15 16:47:28
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<div class="app-container">
 | 
			
		||||
		<search-bar
 | 
			
		||||
			:formConfigs="formConfig"
 | 
			
		||||
			ref="searchBarForm"
 | 
			
		||||
			@headBtnClick="buttonClick" />
 | 
			
		||||
		<base-table
 | 
			
		||||
			:selectWidth="55"
 | 
			
		||||
			@selection-change="selectChange"
 | 
			
		||||
			:table-props="tableProps"
 | 
			
		||||
			:page="1"
 | 
			
		||||
			:limit="999"
 | 
			
		||||
			:table-data="tableData"></base-table>
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { listByDeptId } from '@/api/group/Schedule';
 | 
			
		||||
 | 
			
		||||
const tableProps = [
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'code',
 | 
			
		||||
		label: '班组编号',
 | 
			
		||||
		width: 140,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'name',
 | 
			
		||||
		label: '班组名称',
 | 
			
		||||
		width: 100,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'deptId',
 | 
			
		||||
		label: '所属部门',
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'leaderName',
 | 
			
		||||
		label: '组长',
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'remark',
 | 
			
		||||
		label: '备注',
 | 
			
		||||
	},
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			urlOptions: {
 | 
			
		||||
				getDataListURL: listByDeptId,
 | 
			
		||||
			},
 | 
			
		||||
			tableProps,
 | 
			
		||||
			tableData: [],
 | 
			
		||||
			formConfig: [
 | 
			
		||||
				{
 | 
			
		||||
					type: 'input',
 | 
			
		||||
					label: '班组编号',
 | 
			
		||||
					placeholder: '班组编号',
 | 
			
		||||
					param: 'code',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'input',
 | 
			
		||||
					label: '班组名称',
 | 
			
		||||
					placeholder: '班组名称',
 | 
			
		||||
					param: 'name',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'button',
 | 
			
		||||
					btnName: '查询',
 | 
			
		||||
					name: 'search',
 | 
			
		||||
					color: 'primary',
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
			formInline: {
 | 
			
		||||
				pageNo: 1,
 | 
			
		||||
				pageSize: 100,
 | 
			
		||||
				code: '',
 | 
			
		||||
				name: '',
 | 
			
		||||
			},
 | 
			
		||||
			selectedList: [],
 | 
			
		||||
      deptId: undefined
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	created() {},
 | 
			
		||||
	methods: {
 | 
			
		||||
    init(id){
 | 
			
		||||
      this.deptId = id
 | 
			
		||||
      this.getDataList()
 | 
			
		||||
    },
 | 
			
		||||
		// 获取数据列表
 | 
			
		||||
		getDataList() {
 | 
			
		||||
			this.urlOptions
 | 
			
		||||
				.getDataListURL(this.deptId)
 | 
			
		||||
				.then((response) => {
 | 
			
		||||
					this.tableData = response.data;
 | 
			
		||||
				});
 | 
			
		||||
		},
 | 
			
		||||
		buttonClick(val) {
 | 
			
		||||
			switch (val.btnName) {
 | 
			
		||||
				case 'search':
 | 
			
		||||
					this.formInline.name = val.name;
 | 
			
		||||
					this.formInline.code = val.code;
 | 
			
		||||
					this.getDataList();
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					console.log(val);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		selectChange(val) {
 | 
			
		||||
			this.selectedList = val;
 | 
			
		||||
		},
 | 
			
		||||
		dataFormSubmit() {
 | 
			
		||||
			if (this.selectedList && this.selectedList.length > 0) {
 | 
			
		||||
				this.$emit('refreshTableData', this.selectedList);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										806
									
								
								src/views/group/Schedule/add-or-updata.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,806 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2025-10-13 15:07:24
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2025-10-17 17:01:35
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<div>
 | 
			
		||||
		<!-- 产线信息-工艺工序圆圈 -->
 | 
			
		||||
		<div class="circle-container">
 | 
			
		||||
			<div v-for="(item, index) in dotArr" :key="index" class="circle-wrapper">
 | 
			
		||||
				<div
 | 
			
		||||
					class="circle"
 | 
			
		||||
					:style="{
 | 
			
		||||
						background: stepNum == index + 1 ? '#0B58FF' : '',
 | 
			
		||||
					}">
 | 
			
		||||
					{{ index + 1 }}
 | 
			
		||||
				</div>
 | 
			
		||||
				<div
 | 
			
		||||
					class="circle-text"
 | 
			
		||||
					:style="{
 | 
			
		||||
						color: stepNum == index + 1 ? '#0B58FF' : '',
 | 
			
		||||
					}">
 | 
			
		||||
					{{ item.name }}
 | 
			
		||||
				</div>
 | 
			
		||||
				<!-- 圆点后面的虚线 -->
 | 
			
		||||
				<div v-if="index < 2" class="connector" />
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div v-if="stepNum == 1">
 | 
			
		||||
			<el-form
 | 
			
		||||
				:model="dataForm"
 | 
			
		||||
				:rules="dataRule"
 | 
			
		||||
				ref="dataForm"
 | 
			
		||||
				@keyup.enter.native="dataFormSubmit()"
 | 
			
		||||
				label-position="top"
 | 
			
		||||
				label-width="80px">
 | 
			
		||||
				<el-row :gutter="10">
 | 
			
		||||
					<el-col :span="6">
 | 
			
		||||
						<el-form-item label="计划编号" prop="code">
 | 
			
		||||
							<el-input
 | 
			
		||||
								v-model="dataForm.code"
 | 
			
		||||
								clearable
 | 
			
		||||
								placeholder="请输入计划编号" />
 | 
			
		||||
						</el-form-item>
 | 
			
		||||
					</el-col>
 | 
			
		||||
					<el-col :span="6">
 | 
			
		||||
						<el-form-item label="计划名称" prop="name">
 | 
			
		||||
							<el-input
 | 
			
		||||
								v-model="dataForm.name"
 | 
			
		||||
								clearable
 | 
			
		||||
								placeholder="请输入计划名称" />
 | 
			
		||||
						</el-form-item>
 | 
			
		||||
					</el-col>
 | 
			
		||||
					<el-col :span="6">
 | 
			
		||||
						<el-form-item label="部门">
 | 
			
		||||
							<dept-select
 | 
			
		||||
								style="width: 100%"
 | 
			
		||||
								ref="deptSelect"
 | 
			
		||||
								@DeptId="setDeptId"></dept-select>
 | 
			
		||||
						</el-form-item>
 | 
			
		||||
					</el-col>
 | 
			
		||||
					<el-col :span="6">
 | 
			
		||||
						<el-form-item label="周末休假方式" prop="weekType">
 | 
			
		||||
							<el-select
 | 
			
		||||
								style="width: 100%"
 | 
			
		||||
								v-model="dataForm.weekType"
 | 
			
		||||
								placeholder="请选择周末休假方式">
 | 
			
		||||
								<el-option
 | 
			
		||||
									v-for="item in options1"
 | 
			
		||||
									:key="item.value"
 | 
			
		||||
									:label="item.label"
 | 
			
		||||
									:value="item.value"></el-option>
 | 
			
		||||
							</el-select>
 | 
			
		||||
						</el-form-item>
 | 
			
		||||
					</el-col>
 | 
			
		||||
				</el-row>
 | 
			
		||||
				<el-row :gutter="10">
 | 
			
		||||
					<el-col :span="6">
 | 
			
		||||
						<el-form-item label="开始时间" prop="startDay">
 | 
			
		||||
							<el-date-picker
 | 
			
		||||
								style="width: 100%"
 | 
			
		||||
								v-model="dataForm.startDay"
 | 
			
		||||
								type="datetime"
 | 
			
		||||
								value-format="timestamp"
 | 
			
		||||
								placeholder="选择日期时间"></el-date-picker>
 | 
			
		||||
						</el-form-item>
 | 
			
		||||
					</el-col>
 | 
			
		||||
					<el-col :span="6">
 | 
			
		||||
						<el-form-item label="结束时间" prop="endDay">
 | 
			
		||||
							<el-date-picker
 | 
			
		||||
								style="width: 100%"
 | 
			
		||||
								v-model="dataForm.endDay"
 | 
			
		||||
								type="datetime"
 | 
			
		||||
								value-format="timestamp"
 | 
			
		||||
								placeholder="选择日期时间"></el-date-picker>
 | 
			
		||||
						</el-form-item>
 | 
			
		||||
					</el-col>
 | 
			
		||||
					<el-col :span="6">
 | 
			
		||||
						<el-form-item label="倒班方式" prop="shiftType">
 | 
			
		||||
							<el-select
 | 
			
		||||
								style="width: 100%"
 | 
			
		||||
								v-model="dataForm.shiftType"
 | 
			
		||||
								placeholder="请选择倒班方式">
 | 
			
		||||
								<el-option
 | 
			
		||||
									v-for="item in options2"
 | 
			
		||||
									:key="item.value"
 | 
			
		||||
									:label="item.label"
 | 
			
		||||
									:value="item.value"></el-option>
 | 
			
		||||
							</el-select>
 | 
			
		||||
						</el-form-item>
 | 
			
		||||
					</el-col>
 | 
			
		||||
					<el-col :span="6">
 | 
			
		||||
						<el-form-item label="同班次连排" prop="shiftSustainedNum">
 | 
			
		||||
							<el-input
 | 
			
		||||
								v-model="dataForm.shiftSustainedNum"
 | 
			
		||||
								oninput="value=value.replace(/^(0+)|[^\d]+/g,'')">
 | 
			
		||||
								<el-select
 | 
			
		||||
									style="width: 80px"
 | 
			
		||||
									v-model="dataForm.shiftSustainedType"
 | 
			
		||||
									slot="append">
 | 
			
		||||
									<el-option label="日" :value="1"></el-option>
 | 
			
		||||
									<el-option label="周" :value="2"></el-option>
 | 
			
		||||
									<el-option label="月" :value="3"></el-option>
 | 
			
		||||
									<el-option label="季" :value="4"></el-option>
 | 
			
		||||
								</el-select>
 | 
			
		||||
							</el-input>
 | 
			
		||||
						</el-form-item>
 | 
			
		||||
					</el-col>
 | 
			
		||||
					<el-col :span="24">
 | 
			
		||||
						<el-form-item label="备注" prop="remark">
 | 
			
		||||
							<el-input
 | 
			
		||||
								v-model="dataForm.remark"
 | 
			
		||||
								clearable
 | 
			
		||||
								placeholder="请输入备注" />
 | 
			
		||||
						</el-form-item>
 | 
			
		||||
					</el-col>
 | 
			
		||||
				</el-row>
 | 
			
		||||
			</el-form>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div v-if="stepNum == 2">
 | 
			
		||||
			<small-title style="margin: 16px 0" size="sm" :no-padding="true">
 | 
			
		||||
				班次
 | 
			
		||||
			</small-title>
 | 
			
		||||
			<base-table
 | 
			
		||||
				:table-props="tableProps1"
 | 
			
		||||
				:page="1"
 | 
			
		||||
				:limit="10"
 | 
			
		||||
				:table-data="tableData1">
 | 
			
		||||
				<method-btn
 | 
			
		||||
					v-if="tableBtn1.length"
 | 
			
		||||
					slot="handleBtn"
 | 
			
		||||
					:width="80"
 | 
			
		||||
					label="操作"
 | 
			
		||||
					:method-list="tableBtn1"
 | 
			
		||||
					@clickBtn="handleClick1" />
 | 
			
		||||
			</base-table>
 | 
			
		||||
			<small-title style="margin: 16px 0" size="sm" :no-padding="true">
 | 
			
		||||
				班组
 | 
			
		||||
			</small-title>
 | 
			
		||||
			<base-table
 | 
			
		||||
				:table-props="tableProps2"
 | 
			
		||||
				:page="1"
 | 
			
		||||
				:limit="10"
 | 
			
		||||
				:table-data="tableData2"
 | 
			
		||||
				:add-button-show="'新增'"
 | 
			
		||||
				@emitButtonClick="addNewGroup">
 | 
			
		||||
				<method-btn
 | 
			
		||||
					v-if="tableBtn2.length"
 | 
			
		||||
					slot="handleBtn"
 | 
			
		||||
					:width="110"
 | 
			
		||||
					label="操作"
 | 
			
		||||
					:method-list="tableBtn2"
 | 
			
		||||
					@clickBtn="handleClick2" />
 | 
			
		||||
			</base-table>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div v-if="stepNum == 3">
 | 
			
		||||
			<small-title style="margin: 16px 0" size="sm" :no-padding="true">
 | 
			
		||||
				排班计划预览
 | 
			
		||||
				<span style="font-size: 14px; color: #ff1c15">
 | 
			
		||||
					系统将根据以下设置,按班组轮班顺序依次循环每日班次,生成正式排班计划,请确认。
 | 
			
		||||
 | 
			
		||||
					<el-popover
 | 
			
		||||
						placement="right"
 | 
			
		||||
						title="比如三班两倒,同班次连排2天,不休周末排班如下"
 | 
			
		||||
						width="300"
 | 
			
		||||
						trigger="hover">
 | 
			
		||||
						<el-table :data="gridData">
 | 
			
		||||
							<el-table-column property="date"></el-table-column>
 | 
			
		||||
							<el-table-column
 | 
			
		||||
								property="class1"
 | 
			
		||||
								label="班次一"></el-table-column>
 | 
			
		||||
							<el-table-column
 | 
			
		||||
								property="class2"
 | 
			
		||||
								label="班次二"></el-table-column>
 | 
			
		||||
						</el-table>
 | 
			
		||||
						<i
 | 
			
		||||
							slot="reference"
 | 
			
		||||
							class="el-icon-warning-outline"
 | 
			
		||||
							style="color: #ff1c15"></i>
 | 
			
		||||
					</el-popover>
 | 
			
		||||
				</span>
 | 
			
		||||
			</small-title>
 | 
			
		||||
			<el-tag>
 | 
			
		||||
				{{
 | 
			
		||||
					'计划时间:' +
 | 
			
		||||
					parseTime(dataForm.startDay) +
 | 
			
		||||
					' 至 ' +
 | 
			
		||||
					parseTime(dataForm.endDay)
 | 
			
		||||
				}}
 | 
			
		||||
			</el-tag>
 | 
			
		||||
			<div
 | 
			
		||||
				style="
 | 
			
		||||
					display: grid;
 | 
			
		||||
					grid-template-columns: 1fr 1fr 1fr 1fr;
 | 
			
		||||
					gap: 10px;
 | 
			
		||||
					margin: 15px;
 | 
			
		||||
				">
 | 
			
		||||
				<div style="display: grid; grid-template-columns: 40px auto; gap: 10px">
 | 
			
		||||
					<div class="daobanpng" />
 | 
			
		||||
					<div>
 | 
			
		||||
						<div style="color: rgba(0, 0, 0, 0.6)">倒班方式</div>
 | 
			
		||||
						<div style="color: #000000">
 | 
			
		||||
							{{ ['长白班', '两班倒', '三班倒'][dataForm.shiftType - 1] }}
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div style="display: grid; grid-template-columns: 40px auto; gap: 10px">
 | 
			
		||||
					<div class="lianpaipng" />
 | 
			
		||||
					<div>
 | 
			
		||||
						<div style="color: rgba(0, 0, 0, 0.6)">同班次连排</div>
 | 
			
		||||
						<div style="color: #000000">
 | 
			
		||||
							{{
 | 
			
		||||
								dataForm.shiftSustainedNum +
 | 
			
		||||
								['日', '周', '月', '季'][dataForm.shiftSustainedType - 1]
 | 
			
		||||
							}}
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div style="display: grid; grid-template-columns: 40px auto; gap: 10px">
 | 
			
		||||
					<div class="xiujiapng" />
 | 
			
		||||
					<div>
 | 
			
		||||
						<div style="color: rgba(0, 0, 0, 0.6)">周末休假方式</div>
 | 
			
		||||
						<div style="color: #000000">
 | 
			
		||||
							{{ ['双休', '周六休', '周日休', '不休'][dataForm.weekType - 1] }}
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div style="display: grid; grid-template-columns: 40px auto; gap: 10px">
 | 
			
		||||
					<div class="banzupng" />
 | 
			
		||||
					<div>
 | 
			
		||||
						<div style="color: rgba(0, 0, 0, 0.6)">参与班组</div>
 | 
			
		||||
						<div style="color: #000000">
 | 
			
		||||
							{{
 | 
			
		||||
								tableData2
 | 
			
		||||
									.map((item) => {
 | 
			
		||||
										return item.name;
 | 
			
		||||
									})
 | 
			
		||||
									.join('/')
 | 
			
		||||
							}}
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<base-dialog
 | 
			
		||||
			:dialogTitle="'修改班次'"
 | 
			
		||||
			:dialogVisible="addOrUpdateVisible1"
 | 
			
		||||
			@cancel="cancel1"
 | 
			
		||||
			@confirm="handleConfirm1"
 | 
			
		||||
			:destroy-on-close="true"
 | 
			
		||||
			append-to-body
 | 
			
		||||
			width="40%">
 | 
			
		||||
			<edit-class
 | 
			
		||||
				ref="editClassRef"
 | 
			
		||||
				@refreshTableData="refreshTableData1"></edit-class>
 | 
			
		||||
		</base-dialog>
 | 
			
		||||
		<base-dialog
 | 
			
		||||
			:dialogTitle="'班组选择'"
 | 
			
		||||
			:dialogVisible="addOrUpdateVisible2"
 | 
			
		||||
			@cancel="cancel2"
 | 
			
		||||
			@confirm="handleConfirm2"
 | 
			
		||||
			:destroy-on-close="true"
 | 
			
		||||
			append-to-body
 | 
			
		||||
			width="40%">
 | 
			
		||||
			<add-group
 | 
			
		||||
				ref="addGroupRef"
 | 
			
		||||
				@refreshTableData="refreshTableData2"></add-group>
 | 
			
		||||
		</base-dialog>
 | 
			
		||||
		<base-dialog
 | 
			
		||||
			:dialogTitle="'绑定产线'"
 | 
			
		||||
			:dialogVisible="addOrUpdateVisible3"
 | 
			
		||||
			@cancel="cancel3"
 | 
			
		||||
			@confirm="handleConfirm3"
 | 
			
		||||
			:destroy-on-close="true"
 | 
			
		||||
			append-to-body
 | 
			
		||||
			width="50%">
 | 
			
		||||
			<bind-line
 | 
			
		||||
				ref="bindLineRef"
 | 
			
		||||
				@refreshTableData="refreshTableData3"></bind-line>
 | 
			
		||||
		</base-dialog>
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import deptSelect from './../deptSelect.vue';
 | 
			
		||||
import SmallTitle from './SmallTitle';
 | 
			
		||||
import { parseTime } from '@/filter/code-filter';
 | 
			
		||||
import editClass from './edit-class.vue';
 | 
			
		||||
import addGroup from './add-group.vue';
 | 
			
		||||
import bindLine from './bind-line.vue';
 | 
			
		||||
import { getCode, createStepOne, returnStepOne } from '@/api/group/Schedule';
 | 
			
		||||
 | 
			
		||||
const tableProps1 = [
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'name',
 | 
			
		||||
		label: '班次名称',
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'startDay',
 | 
			
		||||
		label: '开始时间',
 | 
			
		||||
		// filter: (val) => {
 | 
			
		||||
		// 	parseTime(val, '{H}:{mm}');
 | 
			
		||||
		// },
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'endDay',
 | 
			
		||||
		label: '结束时间',
 | 
			
		||||
		// filter: (val) => {
 | 
			
		||||
		// 	parseTime(val, '{H}:{mm}');
 | 
			
		||||
		// },
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'remark',
 | 
			
		||||
		label: '备注',
 | 
			
		||||
	},
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
const tableProps2 = [
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'code',
 | 
			
		||||
		label: '班组编号',
 | 
			
		||||
		width: 140,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'name',
 | 
			
		||||
		label: '班组名称',
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'isProduction',
 | 
			
		||||
		label: '是否生产班组',
 | 
			
		||||
		filter: (val) => {
 | 
			
		||||
			return val ? '是' : '否';
 | 
			
		||||
		},
 | 
			
		||||
		width: 110,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'code1',
 | 
			
		||||
		label: '产线及工段',
 | 
			
		||||
	},
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	components: {
 | 
			
		||||
		deptSelect,
 | 
			
		||||
		SmallTitle,
 | 
			
		||||
		editClass,
 | 
			
		||||
		addGroup,
 | 
			
		||||
		bindLine,
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			dotArr: [
 | 
			
		||||
				{
 | 
			
		||||
					name: '基础信息',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					name: '班组班次',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					name: '计划确认',
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
			stepNum: 1, // 当前第几步
 | 
			
		||||
			//第一步参数
 | 
			
		||||
			dataForm: {
 | 
			
		||||
				id: undefined,
 | 
			
		||||
				code: undefined,
 | 
			
		||||
				name: undefined,
 | 
			
		||||
				startDay: undefined,
 | 
			
		||||
				endDay: undefined,
 | 
			
		||||
				deptId: undefined,
 | 
			
		||||
				weekType: undefined,
 | 
			
		||||
				shiftType: undefined,
 | 
			
		||||
				shiftSustainedNum: undefined,
 | 
			
		||||
				shiftSustainedType: 1,
 | 
			
		||||
				remark: undefined,
 | 
			
		||||
			},
 | 
			
		||||
			options1: [
 | 
			
		||||
				{
 | 
			
		||||
					value: 1,
 | 
			
		||||
					label: '双休',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					value: 2,
 | 
			
		||||
					label: '周六休',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					value: 3,
 | 
			
		||||
					label: '周日休',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					value: 4,
 | 
			
		||||
					label: '不休',
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
			options2: [
 | 
			
		||||
				{
 | 
			
		||||
					value: 1,
 | 
			
		||||
					label: '长白班',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					value: 2,
 | 
			
		||||
					label: '两班倒',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					value: 3,
 | 
			
		||||
					label: '三班倒',
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
			dataRule: {
 | 
			
		||||
				code: [
 | 
			
		||||
					{ required: true, message: '计划编号不能为空', trigger: 'blur' },
 | 
			
		||||
				],
 | 
			
		||||
				name: [
 | 
			
		||||
					{ required: true, message: '计划名称不能为空', trigger: 'blur' },
 | 
			
		||||
				],
 | 
			
		||||
				startDay: [
 | 
			
		||||
					{ required: true, message: '开始时间不能为空', trigger: 'change' },
 | 
			
		||||
				],
 | 
			
		||||
				endDay: [
 | 
			
		||||
					{ required: true, message: '结束时间不能为空', trigger: 'change' },
 | 
			
		||||
				],
 | 
			
		||||
				weekType: [
 | 
			
		||||
					{
 | 
			
		||||
						required: true,
 | 
			
		||||
						message: '周末休假方式不能为空',
 | 
			
		||||
						trigger: 'change',
 | 
			
		||||
					},
 | 
			
		||||
				],
 | 
			
		||||
				shiftType: [
 | 
			
		||||
					{
 | 
			
		||||
						required: true,
 | 
			
		||||
						message: '倒班方式方式不能为空',
 | 
			
		||||
						trigger: 'change',
 | 
			
		||||
					},
 | 
			
		||||
				],
 | 
			
		||||
				shiftSustainedNum: [
 | 
			
		||||
					{ required: true, message: '同班次连排不能为空', trigger: 'blur' },
 | 
			
		||||
				],
 | 
			
		||||
			},
 | 
			
		||||
			//第二步参数
 | 
			
		||||
			tableProps1,
 | 
			
		||||
			tableBtn1: [
 | 
			
		||||
				{
 | 
			
		||||
					type: 'edit',
 | 
			
		||||
					btnName: '编辑',
 | 
			
		||||
				},
 | 
			
		||||
			].filter((v) => v),
 | 
			
		||||
			tableData1: [],
 | 
			
		||||
			tableProps2,
 | 
			
		||||
			tableBtn2: [
 | 
			
		||||
				{
 | 
			
		||||
					type: 'bind',
 | 
			
		||||
					btnName: '绑定产线',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'delete',
 | 
			
		||||
					btnName: '删除',
 | 
			
		||||
				},
 | 
			
		||||
			].filter((v) => v),
 | 
			
		||||
			tableData2: [],
 | 
			
		||||
			addOrUpdateVisible1: false,
 | 
			
		||||
			addOrUpdateVisible2: false,
 | 
			
		||||
			addOrUpdateVisible3: false,
 | 
			
		||||
			//第三步参数
 | 
			
		||||
			gridData: [
 | 
			
		||||
				{
 | 
			
		||||
					date: '第1天',
 | 
			
		||||
					class1: 'A',
 | 
			
		||||
					class2: 'B',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					date: '第2天',
 | 
			
		||||
					class1: 'A',
 | 
			
		||||
					class2: 'B',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					date: '第3天',
 | 
			
		||||
					class1: 'C',
 | 
			
		||||
					class2: 'A',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					date: '第4天',
 | 
			
		||||
					class1: 'C',
 | 
			
		||||
					class2: 'A',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					date: '第5天',
 | 
			
		||||
					class1: 'B',
 | 
			
		||||
					class2: 'C',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					date: '第6天',
 | 
			
		||||
					class1: 'B',
 | 
			
		||||
					class2: 'C',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					date: '第7天',
 | 
			
		||||
					class1: 'A',
 | 
			
		||||
					class2: 'B',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					date: '第8天',
 | 
			
		||||
					class1: 'A',
 | 
			
		||||
					class2: 'B',
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		//子组件获取的部门id
 | 
			
		||||
		setDeptId(val) {
 | 
			
		||||
			this.dataForm.deptId = val;
 | 
			
		||||
		},
 | 
			
		||||
		//详情时传给子组件的部门id
 | 
			
		||||
		setDataForm() {
 | 
			
		||||
			this.$refs.deptSelect.setID(this.dataForm.deptId);
 | 
			
		||||
		},
 | 
			
		||||
		init() {
 | 
			
		||||
			this.$nextTick(() => {
 | 
			
		||||
				this.$refs['dataForm'].resetFields();
 | 
			
		||||
				getCode().then((res) => {
 | 
			
		||||
					this.dataForm.code = res.data;
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		handleClick1(val) {
 | 
			
		||||
			this.addOrUpdateVisible1 = true;
 | 
			
		||||
			this.$nextTick(() => {
 | 
			
		||||
				this.$refs.editClassRef.init(val.data);
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		handleClick2(val) {
 | 
			
		||||
			if (val.type === 'bind') {
 | 
			
		||||
				this.addOrUpdateVisible3 = true;
 | 
			
		||||
				this.$nextTick(() => {
 | 
			
		||||
					this.$refs.bindLineRef.init(val.data.id);
 | 
			
		||||
				});
 | 
			
		||||
			} else if (val.type === 'delete') {
 | 
			
		||||
				this.tableData2.splice(val.data._pageIndex - 1, 1);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		upSubmit() {
 | 
			
		||||
			if (this.stepNum == 2) {
 | 
			
		||||
				returnStepOne(this.dataForm.id).then((res) => {
 | 
			
		||||
					this.stepNum -= 1;
 | 
			
		||||
					this.$emit('setSN', this.stepNum);
 | 
			
		||||
					this.$nextTick(() => {
 | 
			
		||||
						this.setDataForm();
 | 
			
		||||
					});
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		nextSubmit() {
 | 
			
		||||
			if (this.stepNum == 1) {
 | 
			
		||||
				this.$refs['dataForm'].validate((valid) => {
 | 
			
		||||
					if (!valid) {
 | 
			
		||||
						return false;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (!this.dataForm.deptId) {
 | 
			
		||||
						this.$message('部门不能为空');
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
					createStepOne(this.dataForm).then((res) => {
 | 
			
		||||
						this.dataForm.id = res.data;
 | 
			
		||||
						this.stepNum += 1;
 | 
			
		||||
						this.$emit('setSN', this.stepNum);
 | 
			
		||||
						this.setTWOclass(); // 第一步提交后,根据倒班方式设置第二部班次
 | 
			
		||||
					});
 | 
			
		||||
				});
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			if (this.stepNum == 2) {
 | 
			
		||||
        let data = {}
 | 
			
		||||
        data.planId = this.dataForm.id
 | 
			
		||||
        data.groupPlanClassesBaseVOList = [] //排班-班次信息list
 | 
			
		||||
        this.tableData1.forEach((item,index)=>{
 | 
			
		||||
          const obj = {
 | 
			
		||||
            sort: index+1,
 | 
			
		||||
            name : item.name,
 | 
			
		||||
            remark: item.remark,
 | 
			
		||||
            startTime: {
 | 
			
		||||
              hour:item.startDay.split(':')[0],
 | 
			
		||||
              minute:item.startDay.split(':')[1],
 | 
			
		||||
            },
 | 
			
		||||
            endTime: {
 | 
			
		||||
              hour:item.endDay.split(':')[0],
 | 
			
		||||
              minute:item.endDay.split(':')[1],
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          data.groupPlanClassesBaseVOList.push(obj)
 | 
			
		||||
        })
 | 
			
		||||
        data.groupPlanTeamBaseVOList = [] //排班-班组信息list
 | 
			
		||||
        this.tableData2.forEach(item=>{
 | 
			
		||||
          const obj = {
 | 
			
		||||
            teamId:item.id,
 | 
			
		||||
            bindData: ''
 | 
			
		||||
          }
 | 
			
		||||
          data.groupPlanTeamBaseVOList.push(obj)
 | 
			
		||||
        })
 | 
			
		||||
				this.stepNum += 1;
 | 
			
		||||
				this.$emit('setSN', this.stepNum);
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			if (this.stepNum == 3) {
 | 
			
		||||
				this.stepNum = 1;
 | 
			
		||||
				this.$emit('setSN', this.stepNum);
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		//设置第二部班次
 | 
			
		||||
		setTWOclass() {
 | 
			
		||||
			this.tableData1 = [];
 | 
			
		||||
			if (this.dataForm.shiftType == 1) {
 | 
			
		||||
				const obj = {
 | 
			
		||||
					name: '长白班',
 | 
			
		||||
					startDay: '8:00',
 | 
			
		||||
					endDay: '17:00',
 | 
			
		||||
				};
 | 
			
		||||
				this.tableData1.push(obj);
 | 
			
		||||
			} else if (this.dataForm.shiftType == 2) {
 | 
			
		||||
				const obj1 = {
 | 
			
		||||
					name: '白班',
 | 
			
		||||
					startDay: '8:00',
 | 
			
		||||
					endDay: '20:00',
 | 
			
		||||
				};
 | 
			
		||||
				const obj2 = {
 | 
			
		||||
					name: '夜班',
 | 
			
		||||
					startDay: '20:00',
 | 
			
		||||
					endDay: '8:00',
 | 
			
		||||
				};
 | 
			
		||||
				this.tableData1.push(obj1, obj2);
 | 
			
		||||
			} else if (this.dataForm.shiftType == 3) {
 | 
			
		||||
				const obj1 = {
 | 
			
		||||
					name: '早班',
 | 
			
		||||
					startDay: '8:00',
 | 
			
		||||
					endDay: '16:00',
 | 
			
		||||
				};
 | 
			
		||||
				const obj2 = {
 | 
			
		||||
					name: '中班',
 | 
			
		||||
					startDay: '16:00',
 | 
			
		||||
					endDay: '00:00',
 | 
			
		||||
				};
 | 
			
		||||
				const obj3 = {
 | 
			
		||||
					name: '夜班',
 | 
			
		||||
					startDay: '00:00',
 | 
			
		||||
					endDay: '8:00',
 | 
			
		||||
				};
 | 
			
		||||
				this.tableData1.push(obj1, obj2, obj3);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		// 新增班组
 | 
			
		||||
		addNewGroup() {
 | 
			
		||||
			this.addOrUpdateVisible2 = true;
 | 
			
		||||
			this.$nextTick(() => {
 | 
			
		||||
				this.$refs.addGroupRef.init(this.dataForm.deptId);
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		cancel1() {
 | 
			
		||||
			this.addOrUpdateVisible1 = false;
 | 
			
		||||
		},
 | 
			
		||||
		cancel2() {
 | 
			
		||||
			this.addOrUpdateVisible2 = false;
 | 
			
		||||
		},
 | 
			
		||||
		cancel3() {
 | 
			
		||||
			this.addOrUpdateVisible3 = false;
 | 
			
		||||
		},
 | 
			
		||||
		handleConfirm1() {
 | 
			
		||||
			this.$refs.editClassRef.dataFormSubmit();
 | 
			
		||||
		},
 | 
			
		||||
		handleConfirm2() {
 | 
			
		||||
			this.$refs.addGroupRef.dataFormSubmit();
 | 
			
		||||
		},
 | 
			
		||||
		handleConfirm3() {
 | 
			
		||||
			this.$refs.bindLineRef.dataFormSubmit();
 | 
			
		||||
		},
 | 
			
		||||
		refreshTableData1(index, val) {
 | 
			
		||||
			this.tableData1.splice(index, 1, val);
 | 
			
		||||
			this.cancel1();
 | 
			
		||||
		},
 | 
			
		||||
		refreshTableData2(val) {
 | 
			
		||||
			this.tableData2.push(...val);
 | 
			
		||||
			this.cancel2();
 | 
			
		||||
		},
 | 
			
		||||
		refreshTableData3(val) {
 | 
			
		||||
			console.log(val);
 | 
			
		||||
			this.cancel3();
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scoped>
 | 
			
		||||
.daobanpng {
 | 
			
		||||
	width: 40px;
 | 
			
		||||
	height: 40px;
 | 
			
		||||
	background-image: url('~@/assets/images/daoban.png');
 | 
			
		||||
	background-size: 100% 100%;
 | 
			
		||||
}
 | 
			
		||||
.lianpaipng {
 | 
			
		||||
	width: 40px;
 | 
			
		||||
	height: 40px;
 | 
			
		||||
	background-image: url('~@/assets/images/lianpai.png');
 | 
			
		||||
	background-size: 100% 100%;
 | 
			
		||||
}
 | 
			
		||||
.xiujiapng {
 | 
			
		||||
	width: 40px;
 | 
			
		||||
	height: 40px;
 | 
			
		||||
	background-image: url('~@/assets/images/xiujia.png');
 | 
			
		||||
	background-size: 100% 100%;
 | 
			
		||||
}
 | 
			
		||||
.banzupng {
 | 
			
		||||
	width: 40px;
 | 
			
		||||
	height: 40px;
 | 
			
		||||
	background-image: url('~@/assets/images/banzu.png');
 | 
			
		||||
	background-size: 100% 100%;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
<!-- //序号圆点 -->
 | 
			
		||||
<style scoped>
 | 
			
		||||
.circle-container {
 | 
			
		||||
	height: 110px;
 | 
			
		||||
	display: flex;
 | 
			
		||||
	align-items: center;
 | 
			
		||||
	justify-content: center;
 | 
			
		||||
	padding: 20px;
 | 
			
		||||
	width: 90%;
 | 
			
		||||
	overflow-x: auto;
 | 
			
		||||
	margin: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.circle-wrapper {
 | 
			
		||||
	position: relative;
 | 
			
		||||
	display: flex;
 | 
			
		||||
	align-items: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.circle {
 | 
			
		||||
	width: 52px;
 | 
			
		||||
	height: 52px;
 | 
			
		||||
	border-radius: 50%;
 | 
			
		||||
	background: #8db1ff;
 | 
			
		||||
	font-weight: 500;
 | 
			
		||||
	font-size: 31px;
 | 
			
		||||
	color: #ffffff;
 | 
			
		||||
	display: flex;
 | 
			
		||||
	justify-content: center;
 | 
			
		||||
	align-items: center;
 | 
			
		||||
	position: relative;
 | 
			
		||||
	z-index: 2;
 | 
			
		||||
	cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
.circle-text {
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	top: 60px;
 | 
			
		||||
	left: -15px;
 | 
			
		||||
	color: #8db1ff;
 | 
			
		||||
	width: 82px;
 | 
			
		||||
	text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 下半圆虚线边框 */
 | 
			
		||||
.circle::after {
 | 
			
		||||
	content: '';
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	bottom: -6px; /* 2px边框 + 2px间隙 */
 | 
			
		||||
	left: -4px;
 | 
			
		||||
	right: -4px;
 | 
			
		||||
	height: 30px; /* 半圆高度 */
 | 
			
		||||
	border-radius: 0 0 60px 60px;
 | 
			
		||||
	border: 1px dashed #0b58ff;
 | 
			
		||||
	border-top: none;
 | 
			
		||||
	z-index: 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.connector {
 | 
			
		||||
	width: 160px; /* 计算连接线长度 */
 | 
			
		||||
	height: 2px;
 | 
			
		||||
	border-bottom: 1px dashed rgb(11, 88, 255, 1);
 | 
			
		||||
	margin: 0 5px;
 | 
			
		||||
	z-index: 1;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										69
									
								
								src/views/group/Schedule/bind-line.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,69 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2021-11-18 14:16:25
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2025-10-16 16:37:40
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<div style="width: 100%; display: flex; justify-content: center">
 | 
			
		||||
		<tree-transfer
 | 
			
		||||
			:title="title"
 | 
			
		||||
			:from_data="fromData"
 | 
			
		||||
			:to_data="toData"
 | 
			
		||||
			@add-btn="add"
 | 
			
		||||
			@remove-btn="remove"
 | 
			
		||||
			pid="pid"
 | 
			
		||||
			:defaultProps="{ label: 'name' }"
 | 
			
		||||
			height="450px"
 | 
			
		||||
      style="padding-bottom:20px"
 | 
			
		||||
			:mode="mode"
 | 
			
		||||
			filter
 | 
			
		||||
			openAll></tree-transfer>
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import treeTransfer from 'el-tree-transfer';
 | 
			
		||||
import { getGroupPlanTree } from '@/api/group/Schedule';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	components: { treeTransfer },
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			groupId: undefined,
 | 
			
		||||
			title: ['待选', '已选'],
 | 
			
		||||
			mode: 'transfer',
 | 
			
		||||
			fromData: [], //左边内容
 | 
			
		||||
			toData: [], //右边已选内容
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		init(id) {
 | 
			
		||||
			this.fromData = [];
 | 
			
		||||
			this.toData = [];
 | 
			
		||||
			this.groupId = id;
 | 
			
		||||
			getGroupPlanTree().then((res) => {
 | 
			
		||||
				this.fromData = res.data;
 | 
			
		||||
				this.fromData.forEach((item) => {
 | 
			
		||||
					item.productionLineId = 0;
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		// 监听穿梭框组件添加
 | 
			
		||||
		add(fromData, toData, obj) {
 | 
			
		||||
			console.log('fromData:', fromData);
 | 
			
		||||
			console.log('toData:', toData,obj);
 | 
			
		||||
		},
 | 
			
		||||
		// 监听穿梭框组件移除
 | 
			
		||||
		remove(fromData, toData, obj) {
 | 
			
		||||
			console.log('fromData:', fromData);
 | 
			
		||||
			console.log('toData:', toData);
 | 
			
		||||
		},
 | 
			
		||||
		// 表单提交
 | 
			
		||||
		dataFormSubmit() {
 | 
			
		||||
			this.$emit('refreshTableData',this.toData);
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										114
									
								
								src/views/group/Schedule/edit-class.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,114 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2021-11-18 14:16:25
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2025-10-15 16:31:11
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<el-form
 | 
			
		||||
		:model="dataForm"
 | 
			
		||||
		:rules="dataRule"
 | 
			
		||||
		ref="dataForm"
 | 
			
		||||
		@keyup.enter.native="dataFormSubmit()"
 | 
			
		||||
		label-position="top"
 | 
			
		||||
		label-width="80px">
 | 
			
		||||
		<el-row :gutter="20">
 | 
			
		||||
			<el-col :span="12">
 | 
			
		||||
				<el-form-item label="序号" prop="index">
 | 
			
		||||
					<el-input-number
 | 
			
		||||
						v-model="dataForm.index"
 | 
			
		||||
						:step="1"
 | 
			
		||||
						:min="1"
 | 
			
		||||
						step-strictly />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="12">
 | 
			
		||||
				<el-form-item label="班次名称" prop="name">
 | 
			
		||||
					<el-input
 | 
			
		||||
						v-model="dataForm.name"
 | 
			
		||||
						clearable
 | 
			
		||||
						placeholder="请输入班次名称" />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="12">
 | 
			
		||||
				<el-form-item label="开始时间" prop="startDay">
 | 
			
		||||
					<el-time-picker
 | 
			
		||||
						style="width: 100%"
 | 
			
		||||
						format="H:mm"
 | 
			
		||||
						value-format="H:mm"
 | 
			
		||||
						v-model="dataForm.startDay"
 | 
			
		||||
						placeholder="选择日期时间"></el-time-picker>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="12">
 | 
			
		||||
				<el-form-item label="结束时间" prop="endDay">
 | 
			
		||||
					<el-time-picker
 | 
			
		||||
						style="width: 100%"
 | 
			
		||||
						format="H:mm"
 | 
			
		||||
						value-format="H:mm"
 | 
			
		||||
						v-model="dataForm.endDay"
 | 
			
		||||
						placeholder="选择日期时间"></el-time-picker>
 | 
			
		||||
				</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>
 | 
			
		||||
export default {
 | 
			
		||||
	components: {},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			dataForm: {
 | 
			
		||||
				id: undefined,
 | 
			
		||||
				index: undefined,
 | 
			
		||||
				name: undefined,
 | 
			
		||||
				startDay: undefined,
 | 
			
		||||
				endDay: undefined,
 | 
			
		||||
				remark: undefined,
 | 
			
		||||
			},
 | 
			
		||||
			_pageIndex: 1,
 | 
			
		||||
			dataRule: {
 | 
			
		||||
				index: [{ required: true, message: '序号不能为空', trigger: 'blur' }],
 | 
			
		||||
				name: [
 | 
			
		||||
					{ required: true, message: '班次名称不能为空', trigger: 'blur' },
 | 
			
		||||
				],
 | 
			
		||||
				startDay: [
 | 
			
		||||
					{ required: true, message: '开始时间不能为空', trigger: 'change' },
 | 
			
		||||
				],
 | 
			
		||||
				endDay: [
 | 
			
		||||
					{ required: true, message: '结束时间不能为空', trigger: 'change' },
 | 
			
		||||
				],
 | 
			
		||||
			},
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		init(val) {
 | 
			
		||||
			this._pageIndex = val._pageIndex-1;
 | 
			
		||||
			this.dataForm.index = val._pageIndex || 1;
 | 
			
		||||
			this.dataForm.name = val.name || undefined;
 | 
			
		||||
			this.dataForm.startDay = val.startDay || undefined;
 | 
			
		||||
			this.dataForm.endDay = val.endDay || undefined;
 | 
			
		||||
			this.dataForm.remark = val.remark || undefined;
 | 
			
		||||
		},
 | 
			
		||||
		// 表单提交
 | 
			
		||||
		dataFormSubmit() {
 | 
			
		||||
			this.$refs['dataForm'].validate((valid) => {
 | 
			
		||||
				if (!valid) {
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				this.$emit('refreshTableData', this._pageIndex, this.dataForm);
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										469
									
								
								src/views/group/Schedule/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,469 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2025-10-11 14:27:37
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2025-10-15 16:42:28
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<div class="app-container">
 | 
			
		||||
		<div class="searchBarBox">
 | 
			
		||||
			<el-form
 | 
			
		||||
				:inline="true"
 | 
			
		||||
				ref="searchBarForm"
 | 
			
		||||
				:model="formInline"
 | 
			
		||||
				class="searchBar">
 | 
			
		||||
				<span class="blue-block" />
 | 
			
		||||
				<el-form-item label="计划编号" prop="code">
 | 
			
		||||
					<el-input
 | 
			
		||||
						v-model="formInline.code"
 | 
			
		||||
						clearable
 | 
			
		||||
						size="small"
 | 
			
		||||
						placeholder="请输入计划编号" />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item label="计划名称" prop="name">
 | 
			
		||||
					<el-input
 | 
			
		||||
						v-model="formInline.name"
 | 
			
		||||
						clearable
 | 
			
		||||
						size="small"
 | 
			
		||||
						placeholder="请输入计划名称" />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item label="开始时间" prop="startDay">
 | 
			
		||||
					<el-date-picker
 | 
			
		||||
						v-model="formInline.startDay"
 | 
			
		||||
						type="datetime"
 | 
			
		||||
						placeholder="选择日期时间"></el-date-picker>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item label="结束时间" prop="endDay">
 | 
			
		||||
					<el-date-picker
 | 
			
		||||
						v-model="formInline.endDay"
 | 
			
		||||
						type="datetime"
 | 
			
		||||
						placeholder="选择日期时间"></el-date-picker>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item label="部门" prop="deptId">
 | 
			
		||||
					<dept-select
 | 
			
		||||
						style="width: 200px"
 | 
			
		||||
						ref="deptSelect"
 | 
			
		||||
						@DeptId="setDeptId"></dept-select>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item label="状态" prop="leaderName">
 | 
			
		||||
					<el-select v-model="formInline.status" placeholder="请选择状态">
 | 
			
		||||
						<el-option
 | 
			
		||||
							v-for="item in options"
 | 
			
		||||
							:key="item.value"
 | 
			
		||||
							:label="item.label"
 | 
			
		||||
							:value="item.value"></el-option>
 | 
			
		||||
					</el-select>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item>
 | 
			
		||||
					<el-button
 | 
			
		||||
						type="primary"
 | 
			
		||||
						size="small"
 | 
			
		||||
						@click="buttonClick({ btnName: 'search' })">
 | 
			
		||||
						查询
 | 
			
		||||
					</el-button>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item>
 | 
			
		||||
					<span class="separateStyle"></span>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item>
 | 
			
		||||
					<el-button size="small" @click="buttonClick({ btnName: 'reset' })">
 | 
			
		||||
						重置
 | 
			
		||||
					</el-button>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item>
 | 
			
		||||
					<span class="separateStyle"></span>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item>
 | 
			
		||||
					<el-button
 | 
			
		||||
						type="success"
 | 
			
		||||
						size="small"
 | 
			
		||||
						:plain="true"
 | 
			
		||||
						@click="buttonClick({ btnName: 'add' })">
 | 
			
		||||
						新增
 | 
			
		||||
					</el-button>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-form>
 | 
			
		||||
		</div>
 | 
			
		||||
		<base-table
 | 
			
		||||
			v-loading="dataListLoading"
 | 
			
		||||
			:table-props="tableProps"
 | 
			
		||||
			:page="listQuery.pageNo"
 | 
			
		||||
			:limit="listQuery.pageSize"
 | 
			
		||||
			:table-data="tableData"
 | 
			
		||||
			@emitFun="getDataList">
 | 
			
		||||
			<method-btn
 | 
			
		||||
				v-if="tableBtn.length"
 | 
			
		||||
				slot="handleBtn"
 | 
			
		||||
				:width="80"
 | 
			
		||||
				label="操作"
 | 
			
		||||
				:method-list="tableBtn"
 | 
			
		||||
				@clickBtn="handleClick" />
 | 
			
		||||
		</base-table>
 | 
			
		||||
		<pagination
 | 
			
		||||
			:limit.sync="listQuery.pageSize"
 | 
			
		||||
			:page.sync="listQuery.pageNo"
 | 
			
		||||
			:total="listQuery.total"
 | 
			
		||||
			@pagination="getDataList" />
 | 
			
		||||
		<base-dialog
 | 
			
		||||
			:dialogTitle="addOrEditTitle"
 | 
			
		||||
			:dialogVisible="addOrUpdateVisible"
 | 
			
		||||
			@cancel="handleCancel"
 | 
			
		||||
			@confirm="handleConfirm"
 | 
			
		||||
			:before-close="handleCancel"
 | 
			
		||||
			:destroy-on-close="true"
 | 
			
		||||
      append-to-body
 | 
			
		||||
			width="60%">
 | 
			
		||||
			<add-or-update
 | 
			
		||||
				ref="addOrUpdate"
 | 
			
		||||
				@setSN="setStepNum"
 | 
			
		||||
				@refreshDataList="successSubmit"></add-or-update>
 | 
			
		||||
			<template #footer>
 | 
			
		||||
				<slot name="footer">
 | 
			
		||||
					<el-row slot="footer" type="flex" justify="end">
 | 
			
		||||
						<el-col :span="24">
 | 
			
		||||
							<el-button
 | 
			
		||||
								v-if="stepNum > 1"
 | 
			
		||||
								size="small"
 | 
			
		||||
								class="btnTextStyle"
 | 
			
		||||
								@click="handleConfirm('up')">
 | 
			
		||||
								上一步
 | 
			
		||||
							</el-button>
 | 
			
		||||
							<el-button
 | 
			
		||||
								size="small"
 | 
			
		||||
								class="btnTextStyle"
 | 
			
		||||
								@click="handleCancel">
 | 
			
		||||
								取消
 | 
			
		||||
							</el-button>
 | 
			
		||||
							<el-button
 | 
			
		||||
								v-if="stepNum == 3"
 | 
			
		||||
								type="primary"
 | 
			
		||||
								class="btnTextStyle"
 | 
			
		||||
								size="small"
 | 
			
		||||
								plain
 | 
			
		||||
								@click="handleConfirm">
 | 
			
		||||
								保存草稿
 | 
			
		||||
							</el-button>
 | 
			
		||||
							<el-button
 | 
			
		||||
								type="primary"
 | 
			
		||||
								class="btnTextStyle"
 | 
			
		||||
								size="small"
 | 
			
		||||
								@click="handleConfirm">
 | 
			
		||||
								{{ stepNum < 3 ? '下一步' : '确认并执行' }}
 | 
			
		||||
							</el-button>
 | 
			
		||||
						</el-col>
 | 
			
		||||
					</el-row>
 | 
			
		||||
				</slot>
 | 
			
		||||
			</template>
 | 
			
		||||
		</base-dialog>
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import AddOrUpdate from './add-or-updata';
 | 
			
		||||
import deptSelect from './../deptSelect.vue';
 | 
			
		||||
import basicPage from '@/mixins/basic-page';
 | 
			
		||||
import subSpan from './subSpan.vue';
 | 
			
		||||
import subStatus from './subStatus.vue';
 | 
			
		||||
import { parseTime } from '@/filter/code-filter';
 | 
			
		||||
import { getGroupPlanPage, deleteGroupPlan } from '@/api/group/Schedule';
 | 
			
		||||
 | 
			
		||||
const tableProps = [
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'code',
 | 
			
		||||
		label: '计划编号',
 | 
			
		||||
		width: 140,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'name',
 | 
			
		||||
		label: '计划名称',
 | 
			
		||||
		width: 100,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'startDay',
 | 
			
		||||
		label: '开始时间',
 | 
			
		||||
		filter: parseTime,
 | 
			
		||||
		width: 150,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'endDay',
 | 
			
		||||
		label: '结束时间',
 | 
			
		||||
		filter: parseTime,
 | 
			
		||||
		width: 150,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'shiftType',
 | 
			
		||||
		label: '倒班方式',
 | 
			
		||||
		filter: (val) => {
 | 
			
		||||
			return val ? ['', '长白班', '两班倒', '三班倒'][val] : '-';
 | 
			
		||||
		},
 | 
			
		||||
		width: 110,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'shiftSustainedNum',
 | 
			
		||||
		label: '同班次连排',
 | 
			
		||||
		width: 110,
 | 
			
		||||
		subcomponent: subSpan,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'deptId',
 | 
			
		||||
		label: '部门',
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'status',
 | 
			
		||||
		label: '计划状态',
 | 
			
		||||
		width: 110,
 | 
			
		||||
		subcomponent: subStatus,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'createTime',
 | 
			
		||||
		label: '创建时间',
 | 
			
		||||
		filter: parseTime,
 | 
			
		||||
		width: 150,
 | 
			
		||||
	},
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	mixins: [basicPage],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			urlOptions: {
 | 
			
		||||
				getDataListURL: getGroupPlanPage,
 | 
			
		||||
				deleteURL: deleteGroupPlan,
 | 
			
		||||
			},
 | 
			
		||||
			tableProps,
 | 
			
		||||
			tableBtn: [
 | 
			
		||||
				{
 | 
			
		||||
					type: 'edit',
 | 
			
		||||
					btnName: '编辑',
 | 
			
		||||
					showParam: {
 | 
			
		||||
						type: '&',
 | 
			
		||||
						data: [
 | 
			
		||||
							{
 | 
			
		||||
								type: 'equal',
 | 
			
		||||
								name: 'status',
 | 
			
		||||
								value: 1,
 | 
			
		||||
							},
 | 
			
		||||
						],
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'delete',
 | 
			
		||||
					btnName: '删除',
 | 
			
		||||
					showParam: {
 | 
			
		||||
						type: '&',
 | 
			
		||||
						data: [
 | 
			
		||||
							{
 | 
			
		||||
								type: 'equal',
 | 
			
		||||
								name: 'status',
 | 
			
		||||
								value: 1,
 | 
			
		||||
							},
 | 
			
		||||
						],
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'detail',
 | 
			
		||||
					btnName: '查看',
 | 
			
		||||
					showParam: {
 | 
			
		||||
						type: '&',
 | 
			
		||||
						data: [
 | 
			
		||||
							{
 | 
			
		||||
								type: 'unequal',
 | 
			
		||||
								name: 'status',
 | 
			
		||||
								value: 1,
 | 
			
		||||
							},
 | 
			
		||||
						],
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'cancel',
 | 
			
		||||
					btnName: '作废',
 | 
			
		||||
					showParam: {
 | 
			
		||||
						type: '&',
 | 
			
		||||
						data: [
 | 
			
		||||
							{
 | 
			
		||||
								type: 'equal',
 | 
			
		||||
								name: 'status',
 | 
			
		||||
								value: 2,
 | 
			
		||||
							},
 | 
			
		||||
						],
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'sync',
 | 
			
		||||
					btnName: '同步节假日',
 | 
			
		||||
					showParam: {
 | 
			
		||||
						type: '&',
 | 
			
		||||
						data: [
 | 
			
		||||
							{
 | 
			
		||||
								type: 'equal',
 | 
			
		||||
								name: 'status',
 | 
			
		||||
								value: 2,
 | 
			
		||||
							},
 | 
			
		||||
							{
 | 
			
		||||
								type: 'updateFlag',
 | 
			
		||||
								name: 'status',
 | 
			
		||||
								value: true,
 | 
			
		||||
							},
 | 
			
		||||
						],
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'copy',
 | 
			
		||||
					btnName: '复制',
 | 
			
		||||
				},
 | 
			
		||||
			].filter((v) => v),
 | 
			
		||||
			tableData: [],
 | 
			
		||||
			options: [
 | 
			
		||||
				{
 | 
			
		||||
					value: '1',
 | 
			
		||||
					label: '草稿',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					value: '2',
 | 
			
		||||
					label: '已确认',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					value: '3',
 | 
			
		||||
					label: '已作废',
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
			formInline: {
 | 
			
		||||
				code: '',
 | 
			
		||||
				name: '',
 | 
			
		||||
				startDay: '',
 | 
			
		||||
				endDay: '',
 | 
			
		||||
				deptId: '',
 | 
			
		||||
				status: '',
 | 
			
		||||
			},
 | 
			
		||||
			stepNum: 1, // 新增编辑时当前第几步
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	components: {
 | 
			
		||||
		AddOrUpdate,
 | 
			
		||||
		deptSelect,
 | 
			
		||||
	},
 | 
			
		||||
	created() {},
 | 
			
		||||
	methods: {
 | 
			
		||||
		buttonClick(val) {
 | 
			
		||||
			switch (val.btnName) {
 | 
			
		||||
				case 'search':
 | 
			
		||||
					const date1 = new Date(this.formInline.startDay).getTime();
 | 
			
		||||
					const date2 = new Date(this.formInline.endDay).getTime();
 | 
			
		||||
 | 
			
		||||
					if (date1 > date2) {
 | 
			
		||||
						this.$message('开始时间不得晚于结束时间');
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
					this.listQuery = {
 | 
			
		||||
						pageNo: 1,
 | 
			
		||||
						pageSize: 10,
 | 
			
		||||
						total: 1,
 | 
			
		||||
						...this.formInline,
 | 
			
		||||
					};
 | 
			
		||||
					this.getDataList();
 | 
			
		||||
					break;
 | 
			
		||||
				case 'reset':
 | 
			
		||||
					this.formInline.name = null;
 | 
			
		||||
					this.formInline.code = null;
 | 
			
		||||
					this.formInline.deptId = null;
 | 
			
		||||
					this.$refs.deptSelect.clear();
 | 
			
		||||
					this.formInline.leaderName = null;
 | 
			
		||||
					this.listQuery = {
 | 
			
		||||
						pageSize: 10,
 | 
			
		||||
						pageNo: 1,
 | 
			
		||||
						total: 1,
 | 
			
		||||
					};
 | 
			
		||||
					this.getDataList();
 | 
			
		||||
					break;
 | 
			
		||||
				case 'add':
 | 
			
		||||
					this.addOrEditTitle = '添加排班计划';
 | 
			
		||||
					this.addOrUpdateVisible = true;
 | 
			
		||||
					this.$nextTick(() => {
 | 
			
		||||
						this.$refs.addOrUpdate.init();
 | 
			
		||||
					});
 | 
			
		||||
					break;
 | 
			
		||||
				case 'export':
 | 
			
		||||
					this.handleExport();
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					console.log(val);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		setDeptId(val) {
 | 
			
		||||
			this.formInline.deptId = val;
 | 
			
		||||
		},
 | 
			
		||||
		setStepNum(val) {
 | 
			
		||||
			this.stepNum = val;
 | 
			
		||||
		},
 | 
			
		||||
		// dialog取消
 | 
			
		||||
		handleCancel() {
 | 
			
		||||
			this.addOrUpdateVisible = false;
 | 
			
		||||
			this.addOrEditTitle = '';
 | 
			
		||||
		},
 | 
			
		||||
		handleConfirm(val) {
 | 
			
		||||
			if (val == 'up') {
 | 
			
		||||
				this.$refs.addOrUpdate.upSubmit();
 | 
			
		||||
			} else {
 | 
			
		||||
				this.$refs.addOrUpdate.nextSubmit();
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scope>
 | 
			
		||||
.searchBarBox {
 | 
			
		||||
	width: 100%;
 | 
			
		||||
	position: relative;
 | 
			
		||||
	margin-bottom: 8px;
 | 
			
		||||
}
 | 
			
		||||
.searchBarBox::after {
 | 
			
		||||
	content: '';
 | 
			
		||||
	display: block;
 | 
			
		||||
	clear: both;
 | 
			
		||||
}
 | 
			
		||||
.searchBar .blue-block {
 | 
			
		||||
	display: inline-block;
 | 
			
		||||
	float: left;
 | 
			
		||||
	width: 4px;
 | 
			
		||||
	height: 16px;
 | 
			
		||||
	background-color: #0b58ff;
 | 
			
		||||
	border-radius: 1px;
 | 
			
		||||
	margin-right: 8px;
 | 
			
		||||
	margin-top: 12px;
 | 
			
		||||
}
 | 
			
		||||
.searchBar .el-form-item {
 | 
			
		||||
	margin-bottom: 4px;
 | 
			
		||||
}
 | 
			
		||||
.searchBar .separateStyle {
 | 
			
		||||
	display: inline-block;
 | 
			
		||||
	width: 1px;
 | 
			
		||||
	height: 24px;
 | 
			
		||||
	background: #e8e8e8;
 | 
			
		||||
	vertical-align: middle;
 | 
			
		||||
}
 | 
			
		||||
.searchBar .vue-treeselect__control {
 | 
			
		||||
	height: 32px !important;
 | 
			
		||||
	line-height: 32px !important;
 | 
			
		||||
	margin: 4px 0;
 | 
			
		||||
}
 | 
			
		||||
body .el-dialog__header {
 | 
			
		||||
  font-size: 16px;
 | 
			
		||||
  color: rgba(0, 0, 0, 0.85);
 | 
			
		||||
  font-weight: 500;
 | 
			
		||||
  padding: 13px 24px;
 | 
			
		||||
  border-bottom: 1px solid #e9e9e9;
 | 
			
		||||
}
 | 
			
		||||
body .el-dialog__header .titleStyle::before{
 | 
			
		||||
  content: '';
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  width: 4px;
 | 
			
		||||
  height: 16px;
 | 
			
		||||
  background-color: #0B58FF;
 | 
			
		||||
  border-radius: 1px;
 | 
			
		||||
  margin-right: 8px;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  top: 2px;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										26
									
								
								src/views/group/Schedule/subSpan.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,26 @@
 | 
			
		||||
<template>
 | 
			
		||||
	<span>
 | 
			
		||||
		{{
 | 
			
		||||
			injectData.shiftSustainedNum +
 | 
			
		||||
			(injectDatashiftSustainedType
 | 
			
		||||
				? ['', '日', '周', '月', '季'][injectDatashiftSustainedType]
 | 
			
		||||
				: '')
 | 
			
		||||
		}}
 | 
			
		||||
	</span>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
	props: {
 | 
			
		||||
		injectData: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
			default: () => ({}),
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {};
 | 
			
		||||
	},
 | 
			
		||||
	created() {},
 | 
			
		||||
	methods: {},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										31
									
								
								src/views/group/Schedule/subStatus.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,31 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2025-10-13 16:40:08
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2025-10-13 16:43:11
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<el-tag
 | 
			
		||||
		v-if="injectData.status"
 | 
			
		||||
     size="medium"
 | 
			
		||||
		:type="['', '', 'success', 'warning'][injectData.status]">
 | 
			
		||||
		{{ ['', '草稿', '已确认', '已作废'][injectData.status] }}
 | 
			
		||||
	</el-tag>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
	props: {
 | 
			
		||||
		injectData: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
			default: () => ({}),
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {};
 | 
			
		||||
	},
 | 
			
		||||
	created() {},
 | 
			
		||||
	methods: {},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										64
									
								
								src/views/group/deptSelect.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,64 @@
 | 
			
		||||
<template>
 | 
			
		||||
	<treeselect
 | 
			
		||||
		v-model="deptId"
 | 
			
		||||
		:options="deptOptions"
 | 
			
		||||
		:show-count="true"
 | 
			
		||||
		sise="small"
 | 
			
		||||
		ref="treeselect"
 | 
			
		||||
		placeholder="请选择归属部门"
 | 
			
		||||
		@input="setId"
 | 
			
		||||
		:normalizer="normalizer" />
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import Treeselect from '@riophae/vue-treeselect';
 | 
			
		||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css';
 | 
			
		||||
import { listSimpleDepts } from '@/api/system/dept';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	components: { Treeselect },
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			deptId: undefined,
 | 
			
		||||
			deptOptions: undefined,
 | 
			
		||||
			defaultProps: {
 | 
			
		||||
				children: 'children',
 | 
			
		||||
				label: 'name',
 | 
			
		||||
			},
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	created() {
 | 
			
		||||
		this.getTreeselect();
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		/** 查询部门下拉树结构  */
 | 
			
		||||
		getTreeselect() {
 | 
			
		||||
			listSimpleDepts().then((response) => {
 | 
			
		||||
				// 处理 deptOptions 参数
 | 
			
		||||
				this.deptOptions = [];
 | 
			
		||||
				this.deptOptions.push(...this.handleTree(response.data, 'id'));
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
    // 子组件返回id
 | 
			
		||||
		setId(val) {
 | 
			
		||||
			this.$emit('DeptId', val);
 | 
			
		||||
		},
 | 
			
		||||
    // 父组件赋值id
 | 
			
		||||
		setID(id) {
 | 
			
		||||
			this.deptId = id;
 | 
			
		||||
		},
 | 
			
		||||
		clear() {
 | 
			
		||||
			console.log(this.$refs.treeselect);
 | 
			
		||||
			this.$refs.treeselect.clear();
 | 
			
		||||
		},
 | 
			
		||||
		// 格式化部门的下拉框
 | 
			
		||||
		normalizer(node) {
 | 
			
		||||
			return {
 | 
			
		||||
				id: node.id,
 | 
			
		||||
				label: node.name,
 | 
			
		||||
				children: node.children,
 | 
			
		||||
			};
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										214
									
								
								src/views/group/groupSetting/add-or-updata.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,214 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2021-11-18 14:16:25
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2025-10-13 15:44:18
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<el-form
 | 
			
		||||
		:model="dataForm"
 | 
			
		||||
		:rules="dataRule"
 | 
			
		||||
		ref="dataForm"
 | 
			
		||||
		@keyup.enter.native="dataFormSubmit()"
 | 
			
		||||
		label-position="top"
 | 
			
		||||
		label-width="80px">
 | 
			
		||||
		<el-row :gutter="20">
 | 
			
		||||
			<el-col :span="8">
 | 
			
		||||
				<el-form-item label="班组编号" prop="code">
 | 
			
		||||
					<el-input
 | 
			
		||||
						v-model="dataForm.code"
 | 
			
		||||
						clearable
 | 
			
		||||
						placeholder="请输入班组编号" />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="8">
 | 
			
		||||
				<el-form-item label="班组名称" prop="name">
 | 
			
		||||
					<el-input
 | 
			
		||||
						v-model="dataForm.name"
 | 
			
		||||
						clearable
 | 
			
		||||
						placeholder="请输入班组名称" />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="8">
 | 
			
		||||
				<el-form-item label="部门">
 | 
			
		||||
					<dept-select
 | 
			
		||||
						style="width: 200px"
 | 
			
		||||
						ref="deptSelect"
 | 
			
		||||
						@DeptId="setDeptId"></dept-select>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="8">
 | 
			
		||||
				<el-form-item label="组长" prop="leaderId">
 | 
			
		||||
					<el-select
 | 
			
		||||
						v-model="dataForm.leaderId"
 | 
			
		||||
						@change="setLeaderName"
 | 
			
		||||
						placeholder="请选择组长">
 | 
			
		||||
						<el-option
 | 
			
		||||
							v-for="item in leaderArr"
 | 
			
		||||
							:key="item.id"
 | 
			
		||||
							:label="item.nickname"
 | 
			
		||||
							:value="item.id"></el-option>
 | 
			
		||||
					</el-select>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="8">
 | 
			
		||||
				<el-form-item label="组长电话" prop="leaderPhone">
 | 
			
		||||
					<el-input
 | 
			
		||||
						v-model="dataForm.leaderPhone"
 | 
			
		||||
						clearable
 | 
			
		||||
						placeholder="请输入组长电话" />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="8">
 | 
			
		||||
				<el-form-item label="班组人数" prop="num">
 | 
			
		||||
					<el-input-number
 | 
			
		||||
						v-model="dataForm.num"
 | 
			
		||||
						:step="1"
 | 
			
		||||
						:min="0"
 | 
			
		||||
						step-strictly />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="8">
 | 
			
		||||
				<el-form-item label="生产班组" prop="isProduction">
 | 
			
		||||
					<el-select
 | 
			
		||||
						v-model="dataForm.isProduction"
 | 
			
		||||
						placeholder="请选择是否为生产班组">
 | 
			
		||||
						<el-option
 | 
			
		||||
							v-for="item in options"
 | 
			
		||||
							:key="item.value"
 | 
			
		||||
							:label="item.label"
 | 
			
		||||
							:value="item.value"></el-option>
 | 
			
		||||
					</el-select>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="8">
 | 
			
		||||
				<el-form-item label="备注" prop="remark">
 | 
			
		||||
					<el-input
 | 
			
		||||
						v-model="dataForm.remark"
 | 
			
		||||
						clearable
 | 
			
		||||
						placeholder="请输入备注" />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
		</el-row>
 | 
			
		||||
	</el-form>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import basicAdd from '@/mixins/basic-add';
 | 
			
		||||
import deptSelect from './../deptSelect.vue';
 | 
			
		||||
import { listSimpleUsers } from '@/api/system/user';
 | 
			
		||||
import {
 | 
			
		||||
	createGroup,
 | 
			
		||||
	updateGroup,
 | 
			
		||||
	getGroup,
 | 
			
		||||
	getCode,
 | 
			
		||||
} from '@/api/group/groupSetting';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	mixins: [basicAdd],
 | 
			
		||||
	components: {
 | 
			
		||||
		deptSelect,
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			urlOptions: {
 | 
			
		||||
				isGetCode: true,
 | 
			
		||||
				codeURL: getCode,
 | 
			
		||||
				createURL: createGroup,
 | 
			
		||||
				updateURL: updateGroup,
 | 
			
		||||
				infoURL: getGroup,
 | 
			
		||||
				optionArrUrl: [listSimpleUsers], //需要获取下拉框的方法数组
 | 
			
		||||
			},
 | 
			
		||||
			dataForm: {
 | 
			
		||||
				id: undefined,
 | 
			
		||||
				code: undefined,
 | 
			
		||||
				name: undefined,
 | 
			
		||||
				leaderId: undefined,
 | 
			
		||||
				leaderName: undefined,
 | 
			
		||||
				leaderPhone: undefined,
 | 
			
		||||
				deptId: undefined,
 | 
			
		||||
				isProduction: undefined,
 | 
			
		||||
				num: undefined,
 | 
			
		||||
				remark: undefined,
 | 
			
		||||
			},
 | 
			
		||||
      setData: true,
 | 
			
		||||
			leaderArr: [],
 | 
			
		||||
			options: [
 | 
			
		||||
				{
 | 
			
		||||
					value: true,
 | 
			
		||||
					label: '是',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					value: false,
 | 
			
		||||
					label: '否',
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
			dataRule: {
 | 
			
		||||
				code: [
 | 
			
		||||
					{ required: true, message: '班组编码不能为空', trigger: 'blur' },
 | 
			
		||||
				],
 | 
			
		||||
				name: [
 | 
			
		||||
					{ required: true, message: '班组名称不能为空', trigger: 'blur' },
 | 
			
		||||
				],
 | 
			
		||||
				leaderId: [
 | 
			
		||||
					{ required: true, message: '组长不能为空', trigger: 'change' },
 | 
			
		||||
				],
 | 
			
		||||
				isProduction: [
 | 
			
		||||
					{ required: true, message: '生产班组不能为空', trigger: 'change' },
 | 
			
		||||
				],
 | 
			
		||||
			},
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		setDeptId(val) {
 | 
			
		||||
			this.dataForm.deptId = val;
 | 
			
		||||
		},
 | 
			
		||||
		/** 获取下拉框数组 */
 | 
			
		||||
		getArr() {
 | 
			
		||||
			this.urlOptions.optionArrUrl[0]()
 | 
			
		||||
				.then(({ data: res }) => {
 | 
			
		||||
					this.leaderArr = res;
 | 
			
		||||
				})
 | 
			
		||||
				.catch(() => {});
 | 
			
		||||
		},
 | 
			
		||||
    setDataForm(){
 | 
			
		||||
      this.$refs.deptSelect.setID(this.dataForm.deptId)
 | 
			
		||||
    },
 | 
			
		||||
		setLeaderName(val) {
 | 
			
		||||
			this.leaderArr.map((item) => {
 | 
			
		||||
				if (val === item.id) {
 | 
			
		||||
					this.dataForm.leaderName = item.nickname;
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
    // 表单提交
 | 
			
		||||
    dataFormSubmit() {
 | 
			
		||||
      this.$refs["dataForm"].validate((valid) => {
 | 
			
		||||
        if (!valid) {
 | 
			
		||||
          return false;
 | 
			
		||||
        }
 | 
			
		||||
        if(!this.dataForm.deptId){
 | 
			
		||||
						this.$message('部门不能为空');
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        // 修改的提交
 | 
			
		||||
        if (this.dataForm.id) {
 | 
			
		||||
          this.urlOptions.updateURL(this.dataForm).then(response => {
 | 
			
		||||
            this.$modal.msgSuccess("修改成功");
 | 
			
		||||
            this.visible = false;
 | 
			
		||||
            this.$emit("refreshDataList");
 | 
			
		||||
          });
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        // 添加的提交
 | 
			
		||||
        this.urlOptions.createURL(this.dataForm).then(response => {
 | 
			
		||||
          this.$modal.msgSuccess("新增成功");
 | 
			
		||||
          this.visible = false;
 | 
			
		||||
          this.$emit("refreshDataList");
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										35
									
								
								src/views/group/groupSetting/changeStatus.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,35 @@
 | 
			
		||||
<template>
 | 
			
		||||
	<el-switch
 | 
			
		||||
		@change="changeStatus"
 | 
			
		||||
		size="small"
 | 
			
		||||
		v-model="list.enabled"
 | 
			
		||||
		:active-value="1"
 | 
			
		||||
		:inactive-value="0"></el-switch>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { updateGroup } from '@/api/group/groupSetting';
 | 
			
		||||
export default {
 | 
			
		||||
	props: {
 | 
			
		||||
		injectData: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
			default: () => ({}),
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			list: this.injectData,
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	created() {},
 | 
			
		||||
	methods: {
 | 
			
		||||
		changeStatus(val) {
 | 
			
		||||
			const data = { ...this.injectData, enabled: val };
 | 
			
		||||
			updateGroup(data).then((res) => {
 | 
			
		||||
				this.$modal.msgSuccess('修改成功');
 | 
			
		||||
					this.$emit('emitData');
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										277
									
								
								src/views/group/groupSetting/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,277 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2025-10-11 14:27:37
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2025-10-13 14:44:29
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<div class="app-container">
 | 
			
		||||
		<div class="searchBarBox">
 | 
			
		||||
			<el-form
 | 
			
		||||
				:inline="true"
 | 
			
		||||
				ref="searchBarForm"
 | 
			
		||||
				:model="formInline"
 | 
			
		||||
				class="searchBar">
 | 
			
		||||
				<span class="blue-block" />
 | 
			
		||||
				<el-form-item label="班组编号" prop="code">
 | 
			
		||||
					<el-input
 | 
			
		||||
						v-model="formInline.code"
 | 
			
		||||
						clearable
 | 
			
		||||
						size="small"
 | 
			
		||||
						placeholder="请输入班组编号" />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item label="部门" prop="deptId">
 | 
			
		||||
					<dept-select
 | 
			
		||||
						style="width: 200px"
 | 
			
		||||
						ref="deptSelect"
 | 
			
		||||
            @DeptId="setDeptId"></dept-select>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item label="班组名称" prop="name">
 | 
			
		||||
					<el-input
 | 
			
		||||
						v-model="formInline.name"
 | 
			
		||||
						clearable
 | 
			
		||||
						size="small"
 | 
			
		||||
						placeholder="请输入班组名称" />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item label="组长" prop="leaderName">
 | 
			
		||||
					<el-input
 | 
			
		||||
						v-model="formInline.leaderName"
 | 
			
		||||
						clearable
 | 
			
		||||
						size="small"
 | 
			
		||||
						placeholder="请输入组长" />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item>
 | 
			
		||||
					<el-button
 | 
			
		||||
						type="primary"
 | 
			
		||||
						size="small"
 | 
			
		||||
						@click="buttonClick({ btnName: 'search' })">
 | 
			
		||||
						查询
 | 
			
		||||
					</el-button>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item>
 | 
			
		||||
					<span class="separateStyle"></span>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item>
 | 
			
		||||
					<el-button size="small" @click="buttonClick({ btnName: 'reset' })">
 | 
			
		||||
						重置
 | 
			
		||||
					</el-button>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item>
 | 
			
		||||
					<span class="separateStyle"></span>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
				<el-form-item>
 | 
			
		||||
					<el-button
 | 
			
		||||
						type="success"
 | 
			
		||||
						size="small"
 | 
			
		||||
						:plain="true"
 | 
			
		||||
						@click="buttonClick({ btnName: 'add' })">
 | 
			
		||||
						新增
 | 
			
		||||
					</el-button>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-form>
 | 
			
		||||
		</div>
 | 
			
		||||
		<base-table
 | 
			
		||||
			v-loading="dataListLoading"
 | 
			
		||||
			:table-props="tableProps"
 | 
			
		||||
			:page="listQuery.pageNo"
 | 
			
		||||
			:limit="listQuery.pageSize"
 | 
			
		||||
			:table-data="tableData"
 | 
			
		||||
			@emitFun="getDataList">
 | 
			
		||||
			<method-btn
 | 
			
		||||
				v-if="tableBtn.length"
 | 
			
		||||
				slot="handleBtn"
 | 
			
		||||
				:width="80"
 | 
			
		||||
				label="操作"
 | 
			
		||||
				:method-list="tableBtn"
 | 
			
		||||
				@clickBtn="handleClick" />
 | 
			
		||||
		</base-table>
 | 
			
		||||
		<pagination
 | 
			
		||||
			:limit.sync="listQuery.pageSize"
 | 
			
		||||
			:page.sync="listQuery.pageNo"
 | 
			
		||||
			:total="listQuery.total"
 | 
			
		||||
			@pagination="getDataList" />
 | 
			
		||||
		<base-dialog
 | 
			
		||||
			:dialogTitle="addOrEditTitle"
 | 
			
		||||
			:dialogVisible="addOrUpdateVisible"
 | 
			
		||||
			@cancel="handleCancel"
 | 
			
		||||
			@confirm="handleConfirm"
 | 
			
		||||
			:before-close="handleCancel"
 | 
			
		||||
      :destroy-on-close="true"
 | 
			
		||||
			width="50%">
 | 
			
		||||
			<add-or-update
 | 
			
		||||
				ref="addOrUpdate"
 | 
			
		||||
				@refreshDataList="successSubmit"></add-or-update>
 | 
			
		||||
		</base-dialog>
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import AddOrUpdate from './add-or-updata';
 | 
			
		||||
import deptSelect from './../deptSelect.vue';
 | 
			
		||||
import basicPage from '@/mixins/basic-page';
 | 
			
		||||
import changeStatus from './changeStatus.vue';
 | 
			
		||||
import { parseTime } from '@/filter/code-filter';
 | 
			
		||||
import { getGroupPage } from '@/api/group/groupSetting';
 | 
			
		||||
 | 
			
		||||
const tableProps = [
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'code',
 | 
			
		||||
		label: '班组编号',
 | 
			
		||||
		width: 140,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'name',
 | 
			
		||||
		label: '班组名称',
 | 
			
		||||
		width: 100,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'deptId',
 | 
			
		||||
		label: '所属部门',
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'leaderName',
 | 
			
		||||
		label: '组长',
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'leaderPhone',
 | 
			
		||||
		label: '组长电话',
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'num',
 | 
			
		||||
		label: '人数',
 | 
			
		||||
		width: 70,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'isProduction',
 | 
			
		||||
		label: '是否生产班组',
 | 
			
		||||
    filter: val=>{return val?'是':'否'},
 | 
			
		||||
		width: 110,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'remark',
 | 
			
		||||
		label: '备注',
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'createTime',
 | 
			
		||||
		label: '创建时间',
 | 
			
		||||
		filter: parseTime,
 | 
			
		||||
		width: 150,
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'enabled',
 | 
			
		||||
		label: '班组状态',
 | 
			
		||||
		subcomponent: changeStatus,
 | 
			
		||||
		width: 80,
 | 
			
		||||
	},
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	mixins: [basicPage],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			urlOptions: {
 | 
			
		||||
				getDataListURL: getGroupPage,
 | 
			
		||||
			},
 | 
			
		||||
			tableProps,
 | 
			
		||||
			tableBtn: [
 | 
			
		||||
				{
 | 
			
		||||
					type: 'edit',
 | 
			
		||||
					btnName: '编辑',
 | 
			
		||||
				},
 | 
			
		||||
			].filter((v) => v),
 | 
			
		||||
			tableData: [],
 | 
			
		||||
			formInline: {
 | 
			
		||||
				code: '',
 | 
			
		||||
				name: '',
 | 
			
		||||
				deptId: '',
 | 
			
		||||
				leaderName: '',
 | 
			
		||||
			},
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	components: {
 | 
			
		||||
		AddOrUpdate,
 | 
			
		||||
		deptSelect,
 | 
			
		||||
	},
 | 
			
		||||
	created() {},
 | 
			
		||||
	methods: {
 | 
			
		||||
		buttonClick(val) {
 | 
			
		||||
			switch (val.btnName) {
 | 
			
		||||
				case 'search':
 | 
			
		||||
					this.listQuery = {
 | 
			
		||||
						pageNo: 1,
 | 
			
		||||
						pageSize: 10,
 | 
			
		||||
						total: 1,
 | 
			
		||||
						...this.formInline,
 | 
			
		||||
					};
 | 
			
		||||
					this.getDataList();
 | 
			
		||||
					break;
 | 
			
		||||
				case 'reset':
 | 
			
		||||
					this.formInline.name = null;
 | 
			
		||||
					this.formInline.code = null;
 | 
			
		||||
					this.formInline.deptId = null;
 | 
			
		||||
					this.$refs.deptSelect.clear();
 | 
			
		||||
					this.formInline.leaderName = null;
 | 
			
		||||
					this.listQuery = {
 | 
			
		||||
						pageSize: 10,
 | 
			
		||||
						pageNo: 1,
 | 
			
		||||
						total: 1,
 | 
			
		||||
					};
 | 
			
		||||
					this.getDataList();
 | 
			
		||||
					break;
 | 
			
		||||
				case 'add':
 | 
			
		||||
					this.addOrEditTitle = '新增';
 | 
			
		||||
					this.addOrUpdateVisible = true;
 | 
			
		||||
					this.addOrUpdateHandle();
 | 
			
		||||
					break;
 | 
			
		||||
				case 'export':
 | 
			
		||||
					this.handleExport();
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					console.log(val);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
    setDeptId(val){
 | 
			
		||||
      this.formInline.deptId = val
 | 
			
		||||
    }
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style scope>
 | 
			
		||||
.searchBarBox {
 | 
			
		||||
	width: 100%;
 | 
			
		||||
	position: relative;
 | 
			
		||||
	margin-bottom: 8px;
 | 
			
		||||
}
 | 
			
		||||
.searchBarBox::after {
 | 
			
		||||
	content: '';
 | 
			
		||||
	display: block;
 | 
			
		||||
	clear: both;
 | 
			
		||||
}
 | 
			
		||||
.searchBar .blue-block {
 | 
			
		||||
	display: inline-block;
 | 
			
		||||
	float: left;
 | 
			
		||||
	width: 4px;
 | 
			
		||||
	height: 16px;
 | 
			
		||||
	background-color: #0b58ff;
 | 
			
		||||
	border-radius: 1px;
 | 
			
		||||
	margin-right: 8px;
 | 
			
		||||
	margin-top: 12px;
 | 
			
		||||
}
 | 
			
		||||
.searchBar .el-form-item {
 | 
			
		||||
	margin-bottom: 4px;
 | 
			
		||||
}
 | 
			
		||||
.searchBar .separateStyle {
 | 
			
		||||
	display: inline-block;
 | 
			
		||||
	width: 1px;
 | 
			
		||||
	height: 24px;
 | 
			
		||||
	background: #e8e8e8;
 | 
			
		||||
	vertical-align: middle;
 | 
			
		||||
}
 | 
			
		||||
.searchBar .vue-treeselect__control {
 | 
			
		||||
	height: 32px !important;
 | 
			
		||||
	line-height: 32px !important;
 | 
			
		||||
	margin: 4px 0;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										209
									
								
								src/views/group/holidaySetting/add-or-updata.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,209 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2021-11-18 14:16:25
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2025-10-19 00:09:11
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<el-form
 | 
			
		||||
		:model="dataForm"
 | 
			
		||||
		:rules="dataRule"
 | 
			
		||||
		ref="dataForm"
 | 
			
		||||
		@keyup.enter.native="dataFormSubmit()"
 | 
			
		||||
		label-position="top"
 | 
			
		||||
		label-width="80px">
 | 
			
		||||
		<el-row :gutter="20">
 | 
			
		||||
			<el-col :span="12">
 | 
			
		||||
				<el-form-item label="节假日名称" prop="name">
 | 
			
		||||
					<el-input
 | 
			
		||||
						v-model="dataForm.name"
 | 
			
		||||
						clearable
 | 
			
		||||
						:disabled="detail"
 | 
			
		||||
						placeholder="请输入节假日名称" />
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="12">
 | 
			
		||||
				<el-form-item label="日历类型" prop="calendarType">
 | 
			
		||||
					<el-select
 | 
			
		||||
						v-model="dataForm.calendarType"
 | 
			
		||||
						:disabled="detail"
 | 
			
		||||
						style="width: 100%">
 | 
			
		||||
						<el-option
 | 
			
		||||
							v-for="item in options1"
 | 
			
		||||
							:key="item.value"
 | 
			
		||||
							:label="item.label"
 | 
			
		||||
							:value="item.value"></el-option>
 | 
			
		||||
					</el-select>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="12">
 | 
			
		||||
				<el-form-item label="日期类型" prop="dateType">
 | 
			
		||||
					<el-select
 | 
			
		||||
						style="width: 100%"
 | 
			
		||||
						:disabled="detail"
 | 
			
		||||
						v-model="dataForm.dateType">
 | 
			
		||||
						<el-option
 | 
			
		||||
							v-for="item in options2"
 | 
			
		||||
							:key="item.value"
 | 
			
		||||
							:label="item.label"
 | 
			
		||||
							:value="item.value"></el-option>
 | 
			
		||||
					</el-select>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="12">
 | 
			
		||||
				<el-form-item label="日期" prop="dateTime">
 | 
			
		||||
					<el-date-picker
 | 
			
		||||
						:disabled="detail"
 | 
			
		||||
						style="width: 100%"
 | 
			
		||||
						v-if="dataForm.dateType == 1"
 | 
			
		||||
						key="date"
 | 
			
		||||
						v-model="dataForm.dateDay"
 | 
			
		||||
						type="date"
 | 
			
		||||
						placeholder="选择日期"
 | 
			
		||||
						format="yyyy-MM-dd"
 | 
			
		||||
						value-format="yyyy-MM-dd"></el-date-picker>
 | 
			
		||||
					<el-date-picker
 | 
			
		||||
						:disabled="detail"
 | 
			
		||||
						style="width: 100%"
 | 
			
		||||
						v-else
 | 
			
		||||
						key="daterange"
 | 
			
		||||
						v-model="dataForm.dateDayArr"
 | 
			
		||||
						type="daterange"
 | 
			
		||||
						format="yyyy-MM-dd"
 | 
			
		||||
						value-format="yyyy-MM-dd"
 | 
			
		||||
						range-separator="至"
 | 
			
		||||
						start-placeholder="开始日期"
 | 
			
		||||
						end-placeholder="结束日期"></el-date-picker>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
			<el-col :span="12">
 | 
			
		||||
				<el-form-item label="是否每年重复" prop="repeat">
 | 
			
		||||
					<el-select
 | 
			
		||||
						v-model="dataForm.repeat"
 | 
			
		||||
						:disabled="detail"
 | 
			
		||||
						style="width: 100%">
 | 
			
		||||
						<el-option
 | 
			
		||||
							v-for="item in options3"
 | 
			
		||||
							:key="item.value"
 | 
			
		||||
							:label="item.label"
 | 
			
		||||
							:value="item.value"></el-option>
 | 
			
		||||
					</el-select>
 | 
			
		||||
				</el-form-item>
 | 
			
		||||
			</el-col>
 | 
			
		||||
		</el-row>
 | 
			
		||||
	</el-form>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { createHoliday, updateHoliday,deleteHolidayn } from '@/api/group/holidaySetting';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	components: {},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			dataForm: {
 | 
			
		||||
				id: undefined,
 | 
			
		||||
				name: undefined,
 | 
			
		||||
				calendarType: 1,
 | 
			
		||||
				dateType: 1,
 | 
			
		||||
				dateDay: undefined,
 | 
			
		||||
				dateDayArr: [],
 | 
			
		||||
				repeat: true,
 | 
			
		||||
			},
 | 
			
		||||
			detail: false,
 | 
			
		||||
			options1: [
 | 
			
		||||
				{
 | 
			
		||||
					value: 1,
 | 
			
		||||
					label: '公历(阳历)',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					value: 2,
 | 
			
		||||
					label: '农历(阴历)',
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
			options2: [
 | 
			
		||||
				{
 | 
			
		||||
					value: 1,
 | 
			
		||||
					label: '单天',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					value: 2,
 | 
			
		||||
					label: '时间段',
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
			options3: [
 | 
			
		||||
				{
 | 
			
		||||
					value: false,
 | 
			
		||||
					label: '否,本年度有效',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					value: true,
 | 
			
		||||
					label: '是,每年循环生效',
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
			dataRule: {
 | 
			
		||||
				name: [
 | 
			
		||||
					{ required: true, message: '节假日名称不能为空', trigger: 'blur' },
 | 
			
		||||
				],
 | 
			
		||||
				calendarType: [
 | 
			
		||||
					{ required: true, message: '日历类型不能为空', trigger: 'change' },
 | 
			
		||||
				],
 | 
			
		||||
				dateType: [
 | 
			
		||||
					{ required: true, message: '日期类型不能为空', trigger: 'change' },
 | 
			
		||||
				],
 | 
			
		||||
				dateDay: [
 | 
			
		||||
					{ required: true, message: '日期不能为空', trigger: 'change' },
 | 
			
		||||
				],
 | 
			
		||||
				dateDayArr: [
 | 
			
		||||
					{ required: true, message: '日期不能为空', trigger: 'change' },
 | 
			
		||||
				],
 | 
			
		||||
				repeat: [
 | 
			
		||||
					{
 | 
			
		||||
						required: true,
 | 
			
		||||
						message: '是否每年重复不能为空',
 | 
			
		||||
						trigger: 'change',
 | 
			
		||||
					},
 | 
			
		||||
				],
 | 
			
		||||
			},
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		init(id, detail) {
 | 
			
		||||
			this.dataForm.id = id || undefined;
 | 
			
		||||
			this.detail = detail || false;
 | 
			
		||||
		},
 | 
			
		||||
    editHoliday(){
 | 
			
		||||
      this.detail = false
 | 
			
		||||
    },
 | 
			
		||||
    deleteHoliday(){
 | 
			
		||||
      deleteHolidayn(this.dataForm.id).then(res=>{
 | 
			
		||||
        console.log(res)
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
		// 表单提交
 | 
			
		||||
		dataFormSubmit() {
 | 
			
		||||
			this.$refs['dataForm'].validate((valid) => {
 | 
			
		||||
				if (!valid) {
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				// 修改的提交
 | 
			
		||||
				if (this.dataForm.id) {
 | 
			
		||||
					updateHoliday(this.dataForm).then((response) => {
 | 
			
		||||
						this.$modal.msgSuccess('修改成功');
 | 
			
		||||
						this.visible = false;
 | 
			
		||||
						this.$emit('refreshPage');
 | 
			
		||||
					});
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				// 添加的提交
 | 
			
		||||
				createHoliday(this.dataForm).then((response) => {
 | 
			
		||||
					this.$modal.msgSuccess('新增成功');
 | 
			
		||||
					this.visible = false;
 | 
			
		||||
					this.$emit('refreshPage');
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										181
									
								
								src/views/group/holidaySetting/holidayLog.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,181 @@
 | 
			
		||||
<template>
 | 
			
		||||
	<div class="app-container">
 | 
			
		||||
		<search-bar
 | 
			
		||||
			:formConfigs="formConfig"
 | 
			
		||||
			ref="searchBarForm"
 | 
			
		||||
			@headBtnClick="buttonClick" />
 | 
			
		||||
		<base-table
 | 
			
		||||
			:table-props="tableProps"
 | 
			
		||||
			:page="listQuery.pageNo"
 | 
			
		||||
			:limit="listQuery.pageSize"
 | 
			
		||||
			:table-data="tableData">
 | 
			
		||||
		</base-table>
 | 
			
		||||
		<pagination
 | 
			
		||||
			:limit.sync="listQuery.pageSize"
 | 
			
		||||
			:page.sync="listQuery.pageNo"
 | 
			
		||||
			:total="listQuery.total"
 | 
			
		||||
			@pagination="getDataList" />
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { parseTime } from '@/filter/code-filter';
 | 
			
		||||
import { deptHolidayLogList } from '@/api/group/holidaySetting';
 | 
			
		||||
 | 
			
		||||
const tableProps = [
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'createTime',
 | 
			
		||||
		label: '操作时间',
 | 
			
		||||
		filter: parseTime
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'opPeopleName',
 | 
			
		||||
		label: '操作人'
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'opType',
 | 
			
		||||
		label: '操作类型',
 | 
			
		||||
    filter: (val)=>{return val?['','创建','删除','修改','-','-'][val]:'-'}
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'name',
 | 
			
		||||
		label: '节假日名称'
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'opDet',
 | 
			
		||||
		label: '修改内容'
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		prop: 'planType',
 | 
			
		||||
		label: '更新排班计划',
 | 
			
		||||
    filter: (val)=>{return val?['','是','否','无排班计划'][val]:'-'}
 | 
			
		||||
	},
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
      listQuery: { //分页
 | 
			
		||||
        pageSize: 10,
 | 
			
		||||
        pageNo: 1,
 | 
			
		||||
        total: 1,
 | 
			
		||||
      },
 | 
			
		||||
			tableProps,
 | 
			
		||||
			tableData: [],
 | 
			
		||||
			formConfig: [
 | 
			
		||||
				{
 | 
			
		||||
					type: 'datePicker',
 | 
			
		||||
					label: '时间范围',
 | 
			
		||||
					dateType: 'daterange',
 | 
			
		||||
					format: 'yyyy-MM-dd',
 | 
			
		||||
					valueFormat: 'yyyy-MM-dd HH:mm:ss',
 | 
			
		||||
					rangeSeparator: '-',
 | 
			
		||||
					startPlaceholder: '开始时间',
 | 
			
		||||
					endPlaceholder: '结束时间',
 | 
			
		||||
					param: 'createTime',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'input',
 | 
			
		||||
					label: '操作人',
 | 
			
		||||
					placeholder: '操作人',
 | 
			
		||||
					param: 'opPeopleName',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'select',
 | 
			
		||||
					label: '操作类型',
 | 
			
		||||
					selectOptions: [
 | 
			
		||||
						{
 | 
			
		||||
							id: 1,
 | 
			
		||||
							name: '创建',
 | 
			
		||||
						},
 | 
			
		||||
						{
 | 
			
		||||
							id: 2,
 | 
			
		||||
							name: '删除',
 | 
			
		||||
						},
 | 
			
		||||
						{
 | 
			
		||||
							id: 3,
 | 
			
		||||
							name: '修改',
 | 
			
		||||
						},
 | 
			
		||||
						{
 | 
			
		||||
							id: 4,
 | 
			
		||||
							name: '解除继承',
 | 
			
		||||
						},
 | 
			
		||||
						{
 | 
			
		||||
							id: 5,
 | 
			
		||||
							name: '恢复继承',
 | 
			
		||||
						},
 | 
			
		||||
					],
 | 
			
		||||
					param: 'opType',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'select',
 | 
			
		||||
					label: '更新排班计划',
 | 
			
		||||
					selectOptions: [
 | 
			
		||||
						{
 | 
			
		||||
							id: 1,
 | 
			
		||||
							name: '是',
 | 
			
		||||
						},
 | 
			
		||||
						{
 | 
			
		||||
							id: 2,
 | 
			
		||||
							name: '否',
 | 
			
		||||
						},
 | 
			
		||||
						{
 | 
			
		||||
							id: 3,
 | 
			
		||||
							name: '无排班计划',
 | 
			
		||||
						},
 | 
			
		||||
					],
 | 
			
		||||
					param: 'planType',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'button',
 | 
			
		||||
					btnName: '搜索',
 | 
			
		||||
					name: 'search',
 | 
			
		||||
					color: 'primary',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'separate',
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					type: 'button',
 | 
			
		||||
					btnName: '重置',
 | 
			
		||||
					name: 'reset',
 | 
			
		||||
				},
 | 
			
		||||
			],
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	created() {},
 | 
			
		||||
	methods: {
 | 
			
		||||
    // 获取数据列表
 | 
			
		||||
    getDataList() {
 | 
			
		||||
      deptHolidayLogList(this.listQuery).then(response => {
 | 
			
		||||
        this.tableData = response.data.list;
 | 
			
		||||
        this.listQuery.total = response.data.total;
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
		buttonClick(val) {
 | 
			
		||||
			switch (val.btnName) {
 | 
			
		||||
				case 'search':
 | 
			
		||||
					this.listQuery.pageNo = 1;
 | 
			
		||||
					this.listQuery.pageSize = 10;
 | 
			
		||||
					this.listQuery.createTime = val.createTime || [];
 | 
			
		||||
					this.listQuery.planType = val.planType || undefined;
 | 
			
		||||
					this.listQuery.opType = val.opType || undefined;
 | 
			
		||||
					this.listQuery.opPeopleName = val.opPeopleName || undefined;
 | 
			
		||||
					this.getDataList();
 | 
			
		||||
					break;
 | 
			
		||||
				case 'reset':
 | 
			
		||||
					this.$refs.searchBarForm.resetForm();
 | 
			
		||||
					this.listQuery = {
 | 
			
		||||
						pageSize: 10,
 | 
			
		||||
						pageNo: 1,
 | 
			
		||||
						total: 1,
 | 
			
		||||
					};
 | 
			
		||||
					this.getDataList();
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					console.log(val);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										473
									
								
								src/views/group/holidaySetting/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,473 @@
 | 
			
		||||
<!--
 | 
			
		||||
 * @Author: zwq
 | 
			
		||||
 * @Date: 2024-07-01 14:54:06
 | 
			
		||||
 * @LastEditors: zwq
 | 
			
		||||
 * @LastEditTime: 2025-10-19 00:35:24
 | 
			
		||||
 * @Description:
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
	<el-row :gutter="10" style="background-color: #f2f4f9">
 | 
			
		||||
		<!--部门数据-->
 | 
			
		||||
		<el-col :span="4">
 | 
			
		||||
			<div class="head-container">
 | 
			
		||||
				<el-input
 | 
			
		||||
					v-model="deptName"
 | 
			
		||||
					placeholder="请输入部门名称"
 | 
			
		||||
					clearable
 | 
			
		||||
					size="small"
 | 
			
		||||
					prefix-icon="el-icon-search"
 | 
			
		||||
					style="margin-bottom: 20px" />
 | 
			
		||||
				<el-tree
 | 
			
		||||
					:data="deptOptions"
 | 
			
		||||
					:props="defaultProps"
 | 
			
		||||
					:expand-on-click-node="false"
 | 
			
		||||
					:filter-node-method="filterNode"
 | 
			
		||||
					ref="tree"
 | 
			
		||||
					default-expand-all
 | 
			
		||||
					highlight-current
 | 
			
		||||
					@node-click="handleNodeClick" />
 | 
			
		||||
			</div>
 | 
			
		||||
		</el-col>
 | 
			
		||||
		<el-col :span="20">
 | 
			
		||||
			<div class="groupTeamScheduling">
 | 
			
		||||
				<div class="operationArea">
 | 
			
		||||
					<el-row>
 | 
			
		||||
						<el-col :span="16">
 | 
			
		||||
							<div style="height: 40px; font-size: 16px">
 | 
			
		||||
								<span style="color: #409eff; font-weight: 600">
 | 
			
		||||
									{{ showDeptName }}
 | 
			
		||||
								</span>
 | 
			
		||||
								节假日设置
 | 
			
		||||
							</div>
 | 
			
		||||
						</el-col>
 | 
			
		||||
						<el-col :span="8">
 | 
			
		||||
							<div style="float: right">
 | 
			
		||||
								<el-button
 | 
			
		||||
									size="small"
 | 
			
		||||
									type="primary"
 | 
			
		||||
									style="margin-right: 10px"
 | 
			
		||||
									@click="addHoliday">
 | 
			
		||||
									新增节假日
 | 
			
		||||
								</el-button>
 | 
			
		||||
								<el-button size="small" @click="holidayLog">
 | 
			
		||||
									节假日变更记录
 | 
			
		||||
								</el-button>
 | 
			
		||||
							</div>
 | 
			
		||||
						</el-col>
 | 
			
		||||
					</el-row>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="operationArea">
 | 
			
		||||
					<el-form :inline="true" class="demo-form-inline">
 | 
			
		||||
						<span class="blue-block"></span>
 | 
			
		||||
						<el-form-item label="月份选择">
 | 
			
		||||
							<el-date-picker
 | 
			
		||||
								v-model="startDay"
 | 
			
		||||
								type="month"
 | 
			
		||||
								placeholder="选择月"
 | 
			
		||||
								size="small"
 | 
			
		||||
								@change="selectMonth"
 | 
			
		||||
								:clearable="false"
 | 
			
		||||
								style="width: 120px"></el-date-picker>
 | 
			
		||||
						</el-form-item>
 | 
			
		||||
						<el-form-item style="float: right">
 | 
			
		||||
							<el-button
 | 
			
		||||
								size="small"
 | 
			
		||||
								type="primary"
 | 
			
		||||
								@click="startDay = new Date()">
 | 
			
		||||
								跳转到今天
 | 
			
		||||
							</el-button>
 | 
			
		||||
						</el-form-item>
 | 
			
		||||
					</el-form>
 | 
			
		||||
					<el-tag
 | 
			
		||||
						type="warning"
 | 
			
		||||
						closable
 | 
			
		||||
						style="margin-bottom: 10px; color: black">
 | 
			
		||||
						<i class="el-icon-warning" style="color: #ffbd02"></i>
 | 
			
		||||
						当前节假日设置为组织架构中最高层级配置,默认自动继承至下属部门。子部门可选择
 | 
			
		||||
						<span style="color: red">解除继承</span>
 | 
			
		||||
						设置后进行独立修改,复制后不再继承上级设置
 | 
			
		||||
					</el-tag>
 | 
			
		||||
				</div>
 | 
			
		||||
				<!-- 日历区域 -->
 | 
			
		||||
				<div class="calenderArea">
 | 
			
		||||
					<el-calendar v-model="startDay">
 | 
			
		||||
						<template slot="dateCell" slot-scope="{ data }">
 | 
			
		||||
							<div v-if="data.type === 'current-month'" @click="showDetail">
 | 
			
		||||
								<!-- 日期 -->
 | 
			
		||||
								<div class="dateStyle">
 | 
			
		||||
									<el-row :gutter="20">
 | 
			
		||||
										<el-col :span="18">
 | 
			
		||||
											{{ Number(data.day.split('-')[2]) }}
 | 
			
		||||
											<div class="lunar-date">{{ getLunarDate(data.day) }}</div>
 | 
			
		||||
										</el-col>
 | 
			
		||||
										<el-col :span="6"><div class="work-tip">班</div></el-col>
 | 
			
		||||
									</el-row>
 | 
			
		||||
								</div>
 | 
			
		||||
							</div>
 | 
			
		||||
							<div
 | 
			
		||||
								v-else
 | 
			
		||||
								style="font-size: 20px; font-weight: 500; text-align: left">
 | 
			
		||||
								<el-row :gutter="20">
 | 
			
		||||
									<el-col :span="24">
 | 
			
		||||
										{{ Number(data.day.split('-')[2]) }}
 | 
			
		||||
										<span style="font-size: 12px">
 | 
			
		||||
											{{ getLunarDate(data.day) }}
 | 
			
		||||
										</span>
 | 
			
		||||
									</el-col>
 | 
			
		||||
								</el-row>
 | 
			
		||||
							</div>
 | 
			
		||||
						</template>
 | 
			
		||||
					</el-calendar>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</el-col>
 | 
			
		||||
		<base-dialog
 | 
			
		||||
			:dialogTitle="dialogTitle"
 | 
			
		||||
			:dialogVisible="addOrUpdateVisible"
 | 
			
		||||
			@cancel="cancel"
 | 
			
		||||
			@confirm="handleConfirm"
 | 
			
		||||
			:destroy-on-close="true"
 | 
			
		||||
			width="40%">
 | 
			
		||||
			<add-or-updata
 | 
			
		||||
				ref="addOrUpdataRef"
 | 
			
		||||
				@refreshPage="getHolidayPage"></add-or-updata>
 | 
			
		||||
			<template #footer>
 | 
			
		||||
				<slot name="footer">
 | 
			
		||||
					<el-row slot="footer" type="flex" justify="end">
 | 
			
		||||
						<el-col :span="24">
 | 
			
		||||
							<el-button
 | 
			
		||||
								v-if="!detail"
 | 
			
		||||
								size="small"
 | 
			
		||||
								class="btnTextStyle"
 | 
			
		||||
								@click="cancel">
 | 
			
		||||
								取消
 | 
			
		||||
							</el-button>
 | 
			
		||||
							<el-button
 | 
			
		||||
								v-if="!detail"
 | 
			
		||||
								type="primary"
 | 
			
		||||
								class="btnTextStyle"
 | 
			
		||||
								size="small"
 | 
			
		||||
								@click="handleConfirm">
 | 
			
		||||
								确定
 | 
			
		||||
							</el-button>
 | 
			
		||||
							<el-button
 | 
			
		||||
								v-if="detail"
 | 
			
		||||
								size="small"
 | 
			
		||||
								type="primary"
 | 
			
		||||
								class="btnTextStyle"
 | 
			
		||||
								@click="editHoliday">
 | 
			
		||||
								修改
 | 
			
		||||
							</el-button>
 | 
			
		||||
							<el-button
 | 
			
		||||
								v-if="detail"
 | 
			
		||||
								class="btnTextStyle"
 | 
			
		||||
								size="small"
 | 
			
		||||
								@click="deleteHoliday">
 | 
			
		||||
								删除
 | 
			
		||||
							</el-button>
 | 
			
		||||
						</el-col>
 | 
			
		||||
					</el-row>
 | 
			
		||||
				</slot>
 | 
			
		||||
			</template>
 | 
			
		||||
		</base-dialog>
 | 
			
		||||
		<base-dialog
 | 
			
		||||
			dialogTitle="节假日变更记录"
 | 
			
		||||
			:dialogVisible="logVisible"
 | 
			
		||||
			@cancel="cancelLog"
 | 
			
		||||
			:destroy-on-close="true"
 | 
			
		||||
			width="70%">
 | 
			
		||||
			<holiday-log ref="holidayLogRef"></holiday-log>
 | 
			
		||||
			<template #footer>
 | 
			
		||||
				<slot name="footer">
 | 
			
		||||
					<el-row slot="footer" type="flex" justify="end">
 | 
			
		||||
						<el-col :span="24">
 | 
			
		||||
							<el-button size="small" class="btnTextStyle" @click="cancelLog">
 | 
			
		||||
								取消
 | 
			
		||||
							</el-button>
 | 
			
		||||
						</el-col>
 | 
			
		||||
					</el-row>
 | 
			
		||||
				</slot>
 | 
			
		||||
			</template>
 | 
			
		||||
		</base-dialog>
 | 
			
		||||
	</el-row>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import moment from 'moment';
 | 
			
		||||
import { solarToLunar } from 'chinese-lunar';
 | 
			
		||||
 | 
			
		||||
import { listSimpleDepts } from '@/api/system/dept';
 | 
			
		||||
import { getUserProfile } from '@/api/system/user';
 | 
			
		||||
import { deptHolidayList } from '@/api/group/holidaySetting';
 | 
			
		||||
 | 
			
		||||
import addOrUpdata from './add-or-updata.vue';
 | 
			
		||||
import holidayLog from './holidayLog';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	name: '',
 | 
			
		||||
	components: {
 | 
			
		||||
		addOrUpdata,
 | 
			
		||||
		holidayLog,
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			startDay: '', // 查询参数
 | 
			
		||||
			// 部门树选项
 | 
			
		||||
			deptOptions: undefined,
 | 
			
		||||
			// 查询的部门名称
 | 
			
		||||
			deptName: undefined,
 | 
			
		||||
			// 选择的部门名称
 | 
			
		||||
			showDeptName: undefined,
 | 
			
		||||
			deptId: undefined,
 | 
			
		||||
			defaultProps: {
 | 
			
		||||
				children: 'children',
 | 
			
		||||
				label: 'name',
 | 
			
		||||
			},
 | 
			
		||||
			dialogTitle: undefined,
 | 
			
		||||
			addOrUpdateVisible: false,
 | 
			
		||||
			detail: false,
 | 
			
		||||
			logVisible: false,
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	watch: {
 | 
			
		||||
		// 根据名称筛选部门树
 | 
			
		||||
		deptName(val) {
 | 
			
		||||
			this.$refs.tree.filter(val);
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	created() {
 | 
			
		||||
		this.startDay = new Date();
 | 
			
		||||
		// 查询用户个人信息
 | 
			
		||||
		getUserProfile().then((response) => {
 | 
			
		||||
			this.showDeptName = response.data.dept.name || '';
 | 
			
		||||
			this.deptId = response.data.dept.id || '';
 | 
			
		||||
			this.getHolidayPage();
 | 
			
		||||
		});
 | 
			
		||||
		this.getTreeselect();
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		getHolidayPage() {
 | 
			
		||||
			deptHolidayList({ deptId: this.deptId }).then((response) => {});
 | 
			
		||||
		},
 | 
			
		||||
		// 切换月份
 | 
			
		||||
		selectMonth() {
 | 
			
		||||
			console.log(this.startDay);
 | 
			
		||||
			this.getHolidayPage();
 | 
			
		||||
		},
 | 
			
		||||
		/** 查询部门下拉树结构 */
 | 
			
		||||
		getTreeselect() {
 | 
			
		||||
			listSimpleDepts().then((response) => {
 | 
			
		||||
				// 处理 deptOptions 参数
 | 
			
		||||
				this.deptOptions = [];
 | 
			
		||||
				this.deptOptions.push(...this.handleTree(response.data, 'id'));
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		// 筛选节点
 | 
			
		||||
		filterNode(value, data) {
 | 
			
		||||
			if (!value) return true;
 | 
			
		||||
			return data.name.indexOf(value) !== -1;
 | 
			
		||||
		},
 | 
			
		||||
		// 节点单击事件
 | 
			
		||||
		handleNodeClick(data) {
 | 
			
		||||
			this.deptId = data.id;
 | 
			
		||||
			this.showDeptName = data.name;
 | 
			
		||||
			this.getHolidayPage();
 | 
			
		||||
		},
 | 
			
		||||
		//获取农历
 | 
			
		||||
		getLunarDate(solarDate) {
 | 
			
		||||
			try {
 | 
			
		||||
				const [year, month, day] = solarDate.split('-').map(Number);
 | 
			
		||||
 | 
			
		||||
				const date = new Date(year, month - 1, day);
 | 
			
		||||
				const lunar = solarToLunar(date);
 | 
			
		||||
 | 
			
		||||
				// 将数字月份和日期转换为中文
 | 
			
		||||
				const monthMap = {
 | 
			
		||||
					1: '正',
 | 
			
		||||
					2: '二',
 | 
			
		||||
					3: '三',
 | 
			
		||||
					4: '四',
 | 
			
		||||
					5: '五',
 | 
			
		||||
					6: '六',
 | 
			
		||||
					7: '七',
 | 
			
		||||
					8: '八',
 | 
			
		||||
					9: '九',
 | 
			
		||||
					10: '十',
 | 
			
		||||
					11: '冬',
 | 
			
		||||
					12: '腊',
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				const dayMap = {
 | 
			
		||||
					1: '初一',
 | 
			
		||||
					2: '初二',
 | 
			
		||||
					3: '初三',
 | 
			
		||||
					4: '初四',
 | 
			
		||||
					5: '初五',
 | 
			
		||||
					6: '初六',
 | 
			
		||||
					7: '初七',
 | 
			
		||||
					8: '初八',
 | 
			
		||||
					9: '初九',
 | 
			
		||||
					10: '初十',
 | 
			
		||||
					11: '十一',
 | 
			
		||||
					12: '十二',
 | 
			
		||||
					13: '十三',
 | 
			
		||||
					14: '十四',
 | 
			
		||||
					15: '十五',
 | 
			
		||||
					16: '十六',
 | 
			
		||||
					17: '十七',
 | 
			
		||||
					18: '十八',
 | 
			
		||||
					19: '十九',
 | 
			
		||||
					20: '二十',
 | 
			
		||||
					21: '廿一',
 | 
			
		||||
					22: '廿二',
 | 
			
		||||
					23: '廿三',
 | 
			
		||||
					24: '廿四',
 | 
			
		||||
					25: '廿五',
 | 
			
		||||
					26: '廿六',
 | 
			
		||||
					27: '廿七',
 | 
			
		||||
					28: '廿八',
 | 
			
		||||
					29: '廿九',
 | 
			
		||||
					30: '三十',
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				// 返回 "三月初四" 格式
 | 
			
		||||
				return `${monthMap[lunar.month]}月${dayMap[lunar.day]}`;
 | 
			
		||||
			} catch (error) {
 | 
			
		||||
				console.log(error);
 | 
			
		||||
				return '';
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		addHoliday() {
 | 
			
		||||
			this.addOrUpdateVisible = true;
 | 
			
		||||
			this.detail = false;
 | 
			
		||||
			this.dialogTitle = '新增节假日';
 | 
			
		||||
			this.$nextTick(() => {
 | 
			
		||||
				this.$refs.addOrUpdataRef.init();
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		holidayLog() {
 | 
			
		||||
			this.logVisible = true;
 | 
			
		||||
			this.$nextTick(() => {
 | 
			
		||||
				this.$refs.holidayLogRef.getDataList();
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		cancel() {
 | 
			
		||||
			this.addOrUpdateVisible = false;
 | 
			
		||||
		},
 | 
			
		||||
		handleConfirm() {
 | 
			
		||||
			this.$refs.addOrUpdataRef.dataFormSubmit();
 | 
			
		||||
		},
 | 
			
		||||
		showDetail(id) {
 | 
			
		||||
			this.addOrUpdateVisible = true;
 | 
			
		||||
			this.detail = true;
 | 
			
		||||
			this.dialogTitle = '节假日详情';
 | 
			
		||||
			this.$nextTick(() => {
 | 
			
		||||
				this.$refs.addOrUpdataRef.init(id, true);
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		editHoliday() {
 | 
			
		||||
			this.detail = false;
 | 
			
		||||
			this.$nextTick(() => {
 | 
			
		||||
				this.$refs.addOrUpdataRef.editHoliday();
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		deleteHoliday() {
 | 
			
		||||
			this.$nextTick(() => {
 | 
			
		||||
				this.$refs.addOrUpdataRef.deleteHoliday();
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		cancelLog() {
 | 
			
		||||
			this.logVisible = false;
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
.head-container {
 | 
			
		||||
	padding: 20px 10px 0;
 | 
			
		||||
	background-color: #fff;
 | 
			
		||||
	min-height: calc(100vh - 120px - 8px);
 | 
			
		||||
	border-radius: 8px;
 | 
			
		||||
}
 | 
			
		||||
.groupTeamScheduling {
 | 
			
		||||
	.operationArea {
 | 
			
		||||
		padding: 14px 10px 0 16px;
 | 
			
		||||
		margin-bottom: 8px;
 | 
			
		||||
		background-color: #fff;
 | 
			
		||||
		border-radius: 8px;
 | 
			
		||||
		.blue-block {
 | 
			
		||||
			display: inline-block;
 | 
			
		||||
			width: 4px;
 | 
			
		||||
			height: 16px;
 | 
			
		||||
			background-color: #0b58ff;
 | 
			
		||||
			border-radius: 1px;
 | 
			
		||||
			margin-right: 8px;
 | 
			
		||||
			margin-top: 10px;
 | 
			
		||||
		}
 | 
			
		||||
		.el-form-item {
 | 
			
		||||
			margin-bottom: 10px;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// 日历
 | 
			
		||||
	.calenderArea {
 | 
			
		||||
		padding: 14px 10px 0 20px;
 | 
			
		||||
		background-color: #fff;
 | 
			
		||||
		border-radius: 8px;
 | 
			
		||||
		min-height: calc(100vh - 120px - 8px - 168px);
 | 
			
		||||
		.el-calendar__body {
 | 
			
		||||
			padding: 10px 16px 16px 0;
 | 
			
		||||
		}
 | 
			
		||||
		.el-calendar__header {
 | 
			
		||||
			display: none;
 | 
			
		||||
		}
 | 
			
		||||
		.el-calendar-table > thead {
 | 
			
		||||
			height: 48px;
 | 
			
		||||
			font-size: 20px;
 | 
			
		||||
			font-weight: 500;
 | 
			
		||||
			color: #000000;
 | 
			
		||||
			background-color: rgba(242, 244, 249, 1);
 | 
			
		||||
		}
 | 
			
		||||
		.el-calendar-table__row {
 | 
			
		||||
			height: 133px;
 | 
			
		||||
			.prev,
 | 
			
		||||
			.next {
 | 
			
		||||
				pointer-events: none;
 | 
			
		||||
			}
 | 
			
		||||
			.is-selected,
 | 
			
		||||
			.is-today {
 | 
			
		||||
				background-color: #e4f0fd;
 | 
			
		||||
			}
 | 
			
		||||
			.el-calendar-day {
 | 
			
		||||
				padding: 0;
 | 
			
		||||
				height: 100%;
 | 
			
		||||
				:hover {
 | 
			
		||||
					background-color: #e4f0fd;
 | 
			
		||||
				}
 | 
			
		||||
				.dateStyle {
 | 
			
		||||
					font-size: 20px;
 | 
			
		||||
					font-weight: 500;
 | 
			
		||||
					color: #000000;
 | 
			
		||||
					text-align: left;
 | 
			
		||||
					height: 133px;
 | 
			
		||||
					line-height: 28px;
 | 
			
		||||
					padding: 10px;
 | 
			
		||||
 | 
			
		||||
					.lunar-date {
 | 
			
		||||
						display: inline-block;
 | 
			
		||||
						font-size: 12px;
 | 
			
		||||
						color: #909399;
 | 
			
		||||
					}
 | 
			
		||||
					.work-tip {
 | 
			
		||||
						background: #87c1ff;
 | 
			
		||||
						color: white;
 | 
			
		||||
						font-size: 18px;
 | 
			
		||||
						width: 30px;
 | 
			
		||||
						text-align: center;
 | 
			
		||||
						float: right;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/views/home/assets/img/1-1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/views/home/assets/img/1-2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/views/home/assets/img/1-3.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/views/home/assets/img/2-1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/views/home/assets/img/2-2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.0 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/views/home/assets/img/3-1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/views/home/assets/img/arrow-green.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.6 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/views/home/assets/img/arrow-red.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/views/home/assets/img/title-bg.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.6 KiB  | 
							
								
								
									
										152
									
								
								src/views/home/components/Count.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,152 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <ModelBox name='1-3'>
 | 
			
		||||
    <div class='count-box'>
 | 
			
		||||
      <div class='count-tip-box'>
 | 
			
		||||
        <div class='item'>
 | 
			
		||||
          <p class='num'> {{ totalDownLoadNumClass ? totalDownLoadNumClass  : 0}}</p>
 | 
			
		||||
          <p class='title'>本班合计</p>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class='split'></div>
 | 
			
		||||
        <div class='item'>
 | 
			
		||||
          <p class='num'>{{ totalDownLoadNumDay ? totalDownLoadNumDay : 0 }} </p>
 | 
			
		||||
          <p class='title'>本日合计</p>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <dv-scroll-board ref="locationScrollBoardTable" :config="config" style="width:580px;height:180px;margin-top: 10px;"
 | 
			
		||||
        class='count-table' />
 | 
			
		||||
      <span class='split-line' style='left: 70px;'></span>
 | 
			
		||||
      <span class='split-line' style='left: 195px;'></span>
 | 
			
		||||
      <span class='split-line' style='left: 320px;'></span>
 | 
			
		||||
      <span class='split-line' style='left: 445px;'></span>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ModelBox>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import ModelBox from './ModelBox.vue';
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'Count',
 | 
			
		||||
  components: {
 | 
			
		||||
    ModelBox
 | 
			
		||||
  },
 | 
			
		||||
    props: {
 | 
			
		||||
    dataObj: {
 | 
			
		||||
      type: Array,
 | 
			
		||||
      default: () => []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    dataObj: {
 | 
			
		||||
      handler(newVal, oldVal) {
 | 
			
		||||
        console.log(newVal, 'newVal');
 | 
			
		||||
        if (newVal) {
 | 
			
		||||
          this.totalGlassNum = 0;
 | 
			
		||||
          this.tableData = [];
 | 
			
		||||
          // 累加所有项目的downLoadNumDay
 | 
			
		||||
          this.totalDownLoadNumDay = 0;
 | 
			
		||||
          this.totalDownLoadNumClass = 0
 | 
			
		||||
          // 遍历每条产线数据
 | 
			
		||||
          newVal.forEach(item => {
 | 
			
		||||
            // 计算当前项目的glassNum总和
 | 
			
		||||
            const glassArray = JSON.parse(item.glassNum);
 | 
			
		||||
            const itemGlassSum = glassArray.reduce((sum, num) => sum + num, 0);
 | 
			
		||||
            this.tableData.push({
 | 
			
		||||
              lineName: item.lineName,
 | 
			
		||||
              glassSum: itemGlassSum,
 | 
			
		||||
              downLoadNumDay:item.downLoadNumDay,
 | 
			
		||||
              downLoadNumClass: item.downLoadNumClass
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // 累加downLoadNumDay
 | 
			
		||||
            this.totalDownLoadNumDay += item.downLoadNumDay;
 | 
			
		||||
            this.totalDownLoadNumClass += item.downLoadNumClass;
 | 
			
		||||
 | 
			
		||||
          });
 | 
			
		||||
          let eqArr = this.tableData.map((item, index) => [
 | 
			
		||||
            `<span style="color:#000;" >${index+1 || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            `<span style="color:#000;" >${item.lineName || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            // formatDate(item.planStartTime) || '',
 | 
			
		||||
            `
 | 
			
		||||
          <span style="color:#000;" >${item.downLoadNumClass || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            `<span style="color:#000;">${item.downLoadNumDay || ''}</span>`,
 | 
			
		||||
            `<span style="color:#000;">${item.glassSum || ''}</span>`,
 | 
			
		||||
          ])
 | 
			
		||||
          this.config.data = eqArr
 | 
			
		||||
          this.$refs['locationScrollBoardTable'].updateRows(eqArr)
 | 
			
		||||
        }
 | 
			
		||||
        // this.getChart(this.todayClass)
 | 
			
		||||
      },
 | 
			
		||||
      deep: true  // 深度监听
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      totalDownLoadNumDay: 0,
 | 
			
		||||
      totalDownLoadNumClass:0,
 | 
			
		||||
      config:{
 | 
			
		||||
        header: ['<span style="color:#000;">序号</span>', '<span style="color:#000;">产线</span>', '<span style="color:#000;">本班</span>', '<span style="color:#000;">本日</span>', '<span style="color:#000;">一托玻璃数量</span>'],
 | 
			
		||||
        headerHeight: 30,
 | 
			
		||||
        headerBGC: '#E8EDF8',
 | 
			
		||||
        oddRowBGC:'#E8EDF8',
 | 
			
		||||
        evenRowBGC:'#fff',
 | 
			
		||||
        rowNum: 5,
 | 
			
		||||
        columnWidth: [70, 125, 125, 125, 130],
 | 
			
		||||
        align	: ['center', 'center', 'center', 'center', 'center'],
 | 
			
		||||
        data: [
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    init() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang='scss' scoped>
 | 
			
		||||
.count-box {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  .count-tip-box {
 | 
			
		||||
    margin-bottom: 20px;
 | 
			
		||||
    .split {
 | 
			
		||||
      width: 2px;
 | 
			
		||||
      height: 40px;
 | 
			
		||||
      background: #CDD3DF;
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
    }
 | 
			
		||||
    .item {
 | 
			
		||||
      display: inline-block;
 | 
			
		||||
      width: 290px;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      p{
 | 
			
		||||
        margin: 0;
 | 
			
		||||
      }
 | 
			
		||||
      .num {
 | 
			
		||||
        font-weight: 500;
 | 
			
		||||
        font-size: 28px;
 | 
			
		||||
        color: #155EFF;
 | 
			
		||||
        margin-bottom: 5px;
 | 
			
		||||
      }
 | 
			
		||||
      .title {
 | 
			
		||||
        font-size: 14px;
 | 
			
		||||
        color: rgba(0,0,0,0.5);
 | 
			
		||||
        line-height: 14px;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  .count-table {
 | 
			
		||||
    box-shadow: 0px 2px 4px 0px #D5DAE6;
 | 
			
		||||
  }
 | 
			
		||||
  .split-line {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 77px;
 | 
			
		||||
    width: 1px;
 | 
			
		||||
    height: 180px;
 | 
			
		||||
    background: #CDD3DF;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										102
									
								
								src/views/home/components/EqAlarm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,102 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <ModelBox name='1-2'>
 | 
			
		||||
    <div class='eq-alarm'>
 | 
			
		||||
      <dv-scroll-board ref='locationScrollBoard' :config="config" style="width:580px;height:250px;margin-top: 10px;" />
 | 
			
		||||
      <span class='split-line' style='left: 66px;'></span>
 | 
			
		||||
      <span class='split-line' style='left: 226px;'></span>
 | 
			
		||||
      <span class='split-line' style='left: 366px;'></span>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ModelBox>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import ModelBox from './ModelBox.vue';
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'EqAlarm',
 | 
			
		||||
  components: {
 | 
			
		||||
    ModelBox
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    dataObj: {
 | 
			
		||||
      type: Array,
 | 
			
		||||
      default: () => []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    dataObj: {
 | 
			
		||||
      handler(newVal, oldVal) {
 | 
			
		||||
        console.log(newVal, 'newVal');
 | 
			
		||||
        if (newVal) {
 | 
			
		||||
          this.tableData = newVal
 | 
			
		||||
          let eqArr = this.tableData.map((item, index) => [
 | 
			
		||||
            `<span style="color:#000;" >${index + 1 || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            // formatDate(item.planStartTime) || '',
 | 
			
		||||
            `
 | 
			
		||||
          <span style="color:#000;" >${this.formatDate(item.time)  || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            `<span style="color:#000;">${item.equipmentName || ''}</span>`,
 | 
			
		||||
            `<span style="color:#000;">${item.content || ''}</span>`,
 | 
			
		||||
          ])
 | 
			
		||||
          this.config.data = eqArr
 | 
			
		||||
          this.$refs['locationScrollBoard'].updateRows(eqArr)
 | 
			
		||||
        }
 | 
			
		||||
        // this.getChart(this.todayClass)
 | 
			
		||||
      },
 | 
			
		||||
      deep: true  // 深度监听
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      tableData:[],
 | 
			
		||||
      config:{
 | 
			
		||||
        header: ['<span style="color:#000;">序号</span>', '<span style="color:#000;">报警时间</span>', '<span style="color:#000;">报警设备</span>', '<span style="color:#000;">报警内容</span>'],
 | 
			
		||||
        headerHeight: 25,
 | 
			
		||||
        headerBGC: '#E8EDF8',
 | 
			
		||||
        oddRowBGC:'#E8EDF8',
 | 
			
		||||
        evenRowBGC:'#fff',
 | 
			
		||||
        rowNum: 8,
 | 
			
		||||
        columnWidth: [66, 160, 140, 214],
 | 
			
		||||
        align	: ['center', 'center', 'center', 'center'],
 | 
			
		||||
        data: [
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    init() {
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    formatDate(time) {
 | 
			
		||||
      if (!time) return '';
 | 
			
		||||
 | 
			
		||||
      // 如果是时间戳格式
 | 
			
		||||
      if (typeof time === 'number' || !isNaN(time)) {
 | 
			
		||||
        const date = new Date(parseInt(time));
 | 
			
		||||
        return `${date.getFullYear()}/${(date.getMonth() + 1).toString().padStart(2, '0')}/${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 如果是ISO字符串格式
 | 
			
		||||
      if (typeof time === 'string') {
 | 
			
		||||
        const date = new Date(time);
 | 
			
		||||
        if (!isNaN(date.getTime())) {
 | 
			
		||||
          return `${date.getFullYear()}/${(date.getMonth() + 1).toString().padStart(2, '0')}/${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return time;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang='scss' scoped>
 | 
			
		||||
.eq-alarm {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  .split-line {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 0;
 | 
			
		||||
    width: 1px;
 | 
			
		||||
    height: 250px;
 | 
			
		||||
    background: #CDD3DF;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										60
									
								
								src/views/home/components/HomeHeader.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,60 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class='header'>
 | 
			
		||||
    <span class='title'>生产驾驶舱</span>
 | 
			
		||||
    <span class='time'>刷新时间:{{time}}</span>
 | 
			
		||||
    <svg-icon icon-class="refresh" class='refresh-btn' @click='refreshData'/>
 | 
			
		||||
    <el-button type="text" class="screen-btn" @click="changeFullScreen">
 | 
			
		||||
			<svg-icon v-if="isFullScreen" icon-class="unFullscreen" />
 | 
			
		||||
			<svg-icon v-else icon-class="fullscreen" />
 | 
			
		||||
		</el-button>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import moment from 'moment/moment';
 | 
			
		||||
export default {
 | 
			
		||||
  props: {
 | 
			
		||||
		isFullScreen: false
 | 
			
		||||
	},
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      time: moment().format('HH:mm:ss YYYY.MM.DD')
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    changeFullScreen() {
 | 
			
		||||
      this.$emit('screenfullChange');
 | 
			
		||||
    },
 | 
			
		||||
    refreshData() {
 | 
			
		||||
      this.time = moment().format('HH:mm:ss YYYY.MM.DD')
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang='scss' scoped>
 | 
			
		||||
.header {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  .title {
 | 
			
		||||
    font-size: 28px;
 | 
			
		||||
    color:'#000';
 | 
			
		||||
    letter-spacing: 2px;
 | 
			
		||||
    margin-right: 10px;
 | 
			
		||||
  }
 | 
			
		||||
  .time {
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    color:'#000';
 | 
			
		||||
    margin-right: 8px;
 | 
			
		||||
  }
 | 
			
		||||
  .refresh-btn {
 | 
			
		||||
    font-size: 16px;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
  }
 | 
			
		||||
  .screen-btn {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    right: 15px;
 | 
			
		||||
    top: 50%;
 | 
			
		||||
    transform: translateY(-50%);
 | 
			
		||||
    font-size: 32px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										260
									
								
								src/views/home/components/LineInpurAndOutput.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,260 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <ModelBox name='2-2'>
 | 
			
		||||
    <div class='line-container'>
 | 
			
		||||
      <div class='table-box'>
 | 
			
		||||
        <div class='title'>本班次</div>
 | 
			
		||||
        <dv-scroll-board ref="classToday" :config="classConfig" style="width:600px;height:242px;margin-top: 10px;" />
 | 
			
		||||
        <span class='split-line' style='left: 66px;'></span>
 | 
			
		||||
        <span class='split-line' style='left: 186px;'></span>
 | 
			
		||||
        <span class='split-line' style='left: 311px;'></span>
 | 
			
		||||
        <span class='split-line' style='left: 437px;'></span>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class='table-box'>
 | 
			
		||||
        <div class='title'>本日</div>
 | 
			
		||||
        <dv-scroll-board ref="day" :config="dayConfig" style="width:600px;height:242px;margin-top: 10px;" />
 | 
			
		||||
        <span class='split-line' style='left: 66px;'></span>
 | 
			
		||||
        <span class='split-line' style='left: 186px;'></span>
 | 
			
		||||
        <span class='split-line' style='left: 311px;'></span>
 | 
			
		||||
        <span class='split-line' style='left: 437px;'></span>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class='table-box'>
 | 
			
		||||
        <div class='title'>本周</div>
 | 
			
		||||
        <dv-scroll-board ref="week" :config="weekConfig" style="width:600px;height:242px;margin-top: 10px;" />
 | 
			
		||||
        <span class='split-line' style='left: 66px;'></span>
 | 
			
		||||
        <span class='split-line' style='left: 186px;'></span>
 | 
			
		||||
        <span class='split-line' style='left: 311px;'></span>
 | 
			
		||||
        <span class='split-line' style='left: 437px;'></span>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class='table-box'>
 | 
			
		||||
        <div class='title'>本月</div>
 | 
			
		||||
        <dv-scroll-board ref="month" :config="monthConfig" style="width:600px;height:242px;margin-top: 10px;" />
 | 
			
		||||
        <span class='split-line' style='left: 66px;'></span>
 | 
			
		||||
        <span class='split-line' style='left: 186px;'></span>
 | 
			
		||||
        <span class='split-line' style='left: 311px;'></span>
 | 
			
		||||
        <span class='split-line' style='left: 437px;'></span>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ModelBox>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import ModelBox from './ModelBox.vue';
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'LineInpurAndOutput',
 | 
			
		||||
  components: {
 | 
			
		||||
    ModelBox
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    dataObj: {
 | 
			
		||||
      type: Object,
 | 
			
		||||
      default: () => {}
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    dataObj: {
 | 
			
		||||
      handler(newVal, oldVal) {
 | 
			
		||||
        console.log(newVal, 'newVal');
 | 
			
		||||
        if (newVal) {
 | 
			
		||||
          this.nowMonth = newVal.todayClass ? newVal.nowMonth.map((item, index) => [
 | 
			
		||||
            `<span style="color:#000;" >${index + 1 || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            `<span style="color:#000;" >${item.name || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            // formatDate(item.planStartTime) || '',
 | 
			
		||||
            `
 | 
			
		||||
          <span style="color:#000;" >${item.inputNum || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            `<span style="color:#000;">${item.outputNum || ''}</span>`,
 | 
			
		||||
            `<div style="width:136px; margin:0px;">
 | 
			
		||||
          <div style="display:inline-block;height:8px; background:#D8DEEB; border-radius:4px; overflow:hidden;text-align:left;width:90px">
 | 
			
		||||
            <div style="width:${item.inputOutputRate}%; height:100%; background:#0B58FF;border-radius:4px;"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <span style="display:inline-block;margin-left:10px; color:#000; font-size:14px;">${item.inputOutputRate}%</span>
 | 
			
		||||
        </div>`,
 | 
			
		||||
          ]) : []
 | 
			
		||||
          this.monthConfig.data = this.nowMonth
 | 
			
		||||
          this.$refs['month'].updateRows(this.nowMonth)
 | 
			
		||||
          this.nowWeek = newVal.nowWeek ? newVal.nowWeek.map((item, index) => [
 | 
			
		||||
            `<span style="color:#000;" >${index + 1 || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            `<span style="color:#000;" >${item.name || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            // formatDate(item.planStartTime) || '',
 | 
			
		||||
            `
 | 
			
		||||
          <span style="color:#000;" >${item.inputNum || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            `<span style="color:#000;">${item.outputNum || ''}</span>`,
 | 
			
		||||
            `<div style="width:136px; margin:0px;">
 | 
			
		||||
          <div style="display:inline-block;height:8px; background:#D8DEEB; border-radius:4px; overflow:hidden;text-align:left;width:90px">
 | 
			
		||||
            <div style="width:${item.inputOutputRate}%; height:100%; background:#0B58FF;border-radius:4px;"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <span style="display:inline-block;margin-left:10px; color:#000; font-size:14px;">${item.inputOutputRate}%</span>
 | 
			
		||||
        </div>`,
 | 
			
		||||
          ]) : []
 | 
			
		||||
          this.weekConfig.data = this.nowWeek
 | 
			
		||||
          this.$refs['week'].updateRows(this.nowWeek)
 | 
			
		||||
          this.oneDay = newVal.oneDay ? newVal.oneDay.map((item, index) => [
 | 
			
		||||
            `<span style="color:#000;" >${index + 1 || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            `<span style="color:#000;" >${item.name || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            // formatDate(item.planStartTime) || '',
 | 
			
		||||
            `
 | 
			
		||||
          <span style="color:#000;" >${item.inputNum || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            `<span style="color:#000;">${item.outputNum || ''}</span>`,
 | 
			
		||||
            `<div style="width:136px; margin:0px;">
 | 
			
		||||
          <div style="display:inline-block;height:8px; background:#D8DEEB; border-radius:4px; overflow:hidden;text-align:left;width:90px">
 | 
			
		||||
            <div style="width:${item.inputOutputRate}%; height:100%; background:#0B58FF;border-radius:4px;"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <span style="display:inline-block;margin-left:10px; color:#000; font-size:14px;">${item.inputOutputRate}%</span>
 | 
			
		||||
        </div>`,
 | 
			
		||||
          ]) : []
 | 
			
		||||
          this.dayConfig.data = this.oneDay
 | 
			
		||||
          this.$refs['day'].updateRows(this.oneDay)
 | 
			
		||||
          this.todayClass = newVal.todayClass ? newVal.todayClass.map((item, index) => [
 | 
			
		||||
            `<span style="color:#000;" >${index + 1 || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            `<span style="color:#000;" >${item.name || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            // formatDate(item.planStartTime) || '',
 | 
			
		||||
            `
 | 
			
		||||
          <span style="color:#000;" >${item.inputNum || ''}
 | 
			
		||||
            </span>`,
 | 
			
		||||
            `<span style="color:#000;">${item.outputNum || ''}</span>`,
 | 
			
		||||
            `<div style="width:136px; margin:0px;">
 | 
			
		||||
          <div style="display:inline-block;height:8px; background:#D8DEEB; border-radius:4px; overflow:hidden;text-align:left;width:90px">
 | 
			
		||||
            <div style="width:${item.inputOutputRate}%; height:100%; background:#0B58FF;border-radius:4px;"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <span style="display:inline-block;margin-left:10px; color:#000; font-size:14px;">${item.inputOutputRate}%</span>
 | 
			
		||||
        </div>`,
 | 
			
		||||
          ]) : []
 | 
			
		||||
          this.classConfig.data = this.todayClass
 | 
			
		||||
          this.$refs['classToday'].updateRows(this.todayClass)
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      deep: true  // 深度监听
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      nowMonth: [],
 | 
			
		||||
      nowWeek: [],
 | 
			
		||||
      oneDay: [],
 | 
			
		||||
      todayClass: [],
 | 
			
		||||
      classConfig:{
 | 
			
		||||
        header: ['<span style="color:#000;">序号</span>', '<span style="color:#000;">工段</span>', '<span style="color:#000;">投入数量/片</span>', '<span style="color:#000;">产出数量/片</span>','<span style="color:#000;">产出率/%</span>'],
 | 
			
		||||
        headerHeight: 25,
 | 
			
		||||
        headerBGC: '#E8EDF8',
 | 
			
		||||
        oddRowBGC:'#E8EDF8',
 | 
			
		||||
        evenRowBGC:'#fff',
 | 
			
		||||
        rowNum: 8,
 | 
			
		||||
        columnWidth: [66, 120, 125, 126, 174],
 | 
			
		||||
        align	: ['center', 'center', 'center', 'center', 'center'],
 | 
			
		||||
        data: []
 | 
			
		||||
      },
 | 
			
		||||
      monthConfig: {
 | 
			
		||||
        header: ['<span style="color:#000;">序号</span>', '<span style="color:#000;">工段</span>', '<span style="color:#000;">投入数量/片</span>', '<span style="color:#000;">产出数量/片</span>', '<span style="color:#000;">产出率/%</span>'],
 | 
			
		||||
        headerHeight: 25,
 | 
			
		||||
        headerBGC: '#E8EDF8',
 | 
			
		||||
        oddRowBGC: '#E8EDF8',
 | 
			
		||||
        evenRowBGC: '#fff',
 | 
			
		||||
        rowNum: 8,
 | 
			
		||||
        columnWidth: [66, 120, 125, 126, 174],
 | 
			
		||||
        align: ['center', 'center', 'center', 'center', 'center'],
 | 
			
		||||
        data: []
 | 
			
		||||
      },
 | 
			
		||||
      dayConfig: {
 | 
			
		||||
        header: ['<span style="color:#000;">序号</span>', '<span style="color:#000;">工段</span>', '<span style="color:#000;">投入数量/片</span>', '<span style="color:#000;">产出数量/片</span>', '<span style="color:#000;">产出率/%</span>'],
 | 
			
		||||
        headerHeight: 25,
 | 
			
		||||
        headerBGC: '#E8EDF8',
 | 
			
		||||
        oddRowBGC: '#E8EDF8',
 | 
			
		||||
        evenRowBGC: '#fff',
 | 
			
		||||
        rowNum: 8,
 | 
			
		||||
        columnWidth: [66, 120, 125, 126, 174],
 | 
			
		||||
        align: ['center', 'center', 'center', 'center', 'center'],
 | 
			
		||||
        data: []
 | 
			
		||||
      },
 | 
			
		||||
      weekConfig: {
 | 
			
		||||
        header: ['<span style="color:#000;">序号</span>', '<span style="color:#000;">工段</span>', '<span style="color:#000;">投入数量/片</span>', '<span style="color:#000;">产出数量/片</span>', '<span style="color:#000;">产出率/%</span>'],
 | 
			
		||||
        headerHeight: 25,
 | 
			
		||||
        headerBGC: '#E8EDF8',
 | 
			
		||||
        oddRowBGC: '#E8EDF8',
 | 
			
		||||
        evenRowBGC: '#fff',
 | 
			
		||||
        rowNum: 8,
 | 
			
		||||
        columnWidth: [66, 120, 125, 126, 174],
 | 
			
		||||
        align: ['center', 'center', 'center', 'center', 'center'],
 | 
			
		||||
        data: []
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.getData()
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    getData() {
 | 
			
		||||
      // let arr1 = []
 | 
			
		||||
      // let arr2 = []
 | 
			
		||||
      // let data = [
 | 
			
		||||
      //   [1,'A1-磨边',234344,234333,100],
 | 
			
		||||
      //   [2,'A1-磨边',234344,234333,10],
 | 
			
		||||
      //   [3,'A1-磨边',234344,234333,96],
 | 
			
		||||
      //   [4,'A1-磨边',234344,234333,20],
 | 
			
		||||
      //   [5,'A1-磨边',234344,234333,40],
 | 
			
		||||
      //   [6,'A1-磨边',234344,234333,90],
 | 
			
		||||
      //   [7,'A1-磨边',234344,234333,80],
 | 
			
		||||
      //   [8,'A1-磨边',234344,234333,80],
 | 
			
		||||
      // ]
 | 
			
		||||
      // for (let i =0; i < data.length; i++) {
 | 
			
		||||
      //   arr1.push(`<span style="color:#000;">${data[i][0]}</span>`)
 | 
			
		||||
      //   arr1.push(`<span style="color:#000;">${data[i][1]}</span>`)
 | 
			
		||||
      //   arr1.push(`<span style="color:#000;">${data[i][2]}</span>`)
 | 
			
		||||
      //   arr1.push(`<span style="color:#000;">${data[i][3]}</span>`)
 | 
			
		||||
      //   arr1.push(`<div style="width:136px; margin:0px;">
 | 
			
		||||
      //     <div style="display:inline-block;height:8px; background:#D8DEEB; border-radius:4px; overflow:hidden;text-align:left;width:90px">
 | 
			
		||||
      //       <div style="width:${data[i][4]}%; height:100%; background:#0B58FF;border-radius:4px;"></div>
 | 
			
		||||
      //     </div>
 | 
			
		||||
      //     <span style="display:inline-block;margin-left:10px; color:#000; font-size:14px;">${data[i][4]}%</span>
 | 
			
		||||
      //   </div>`)
 | 
			
		||||
      //   arr2.push(arr1)
 | 
			
		||||
      //   arr1 = []
 | 
			
		||||
      // }
 | 
			
		||||
      // this.config.data = arr2
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang='scss' scoped>
 | 
			
		||||
.line-container {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  height: 600px;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  align-content: space-between;
 | 
			
		||||
  flex-wrap: wrap;
 | 
			
		||||
  .table-box {
 | 
			
		||||
    width: 601px;
 | 
			
		||||
    height: 300px;
 | 
			
		||||
    position: relative;
 | 
			
		||||
    padding-top: 16px;
 | 
			
		||||
    .title {
 | 
			
		||||
      width: 271px;
 | 
			
		||||
      height: 27px;
 | 
			
		||||
      line-height: 27px;
 | 
			
		||||
      font-size: 20px;
 | 
			
		||||
      color: #000000;
 | 
			
		||||
      letter-spacing: 4px;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      background-image: url(../assets/img/title-bg.png);
 | 
			
		||||
      background-size: 100% 100%;
 | 
			
		||||
      margin: 0 auto;
 | 
			
		||||
    }
 | 
			
		||||
    .split-line {
 | 
			
		||||
      position: absolute;
 | 
			
		||||
      top: 53px;
 | 
			
		||||
      width: 1px;
 | 
			
		||||
      height: 242px;
 | 
			
		||||
      background: #CDD3DF;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										210
									
								
								src/views/home/components/LineRate.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,210 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <ModelBox name='3-1'>
 | 
			
		||||
    <div class='line-rate'>
 | 
			
		||||
      <div class='legend-box'>
 | 
			
		||||
        <div class='legend-item' v-for='(item, index) in legendArr' :key='index'>
 | 
			
		||||
          <span class='dot' :style='{backgroundColor: item.color,"--dot-color": item.color}'></span>
 | 
			
		||||
          <span class='name'>{{item.name}}</span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div id='lineRate' style='width: 584px; height: 270px;'></div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ModelBox>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import * as echarts from 'echarts';
 | 
			
		||||
import ModelBox from './ModelBox.vue';
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'LineRate',
 | 
			
		||||
  components: {
 | 
			
		||||
    ModelBox
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      legendArr:[
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    dataObj: {
 | 
			
		||||
      handler(newVal, oldVal) {
 | 
			
		||||
        console.log(newVal, 'newVal');
 | 
			
		||||
        if (newVal) {
 | 
			
		||||
          let xData = []
 | 
			
		||||
          newVal.forEach(ele => {
 | 
			
		||||
            xData.push(this.formatDate(ele.time))
 | 
			
		||||
          });
 | 
			
		||||
          // console.log(, 'xData');
 | 
			
		||||
          const series = this.convertToSeries(newVal)
 | 
			
		||||
          this.getChart([...new Set(xData)], series)
 | 
			
		||||
          // this.nowMonth = newVal.nowMonth ? newVal.nowMonth : []
 | 
			
		||||
          // this.nowWeek = newVal.nowWeek ? newVal.nowWeek : []
 | 
			
		||||
          // this.oneDay = newVal.oneDay ? newVal.oneDay : []
 | 
			
		||||
          // this.todayClass = newVal.todayClass ? newVal.todayClass : []
 | 
			
		||||
        }
 | 
			
		||||
        // this.getChart(this.todayClass)
 | 
			
		||||
      },
 | 
			
		||||
      deep: true,  // 深度监听
 | 
			
		||||
      immediate: true
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    dataObj: {
 | 
			
		||||
      type: Array,
 | 
			
		||||
      default: () => []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.getChart()
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    init() {
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    formatDate(time) {
 | 
			
		||||
      if (!time) return '';
 | 
			
		||||
 | 
			
		||||
      // 如果是时间戳格式
 | 
			
		||||
      if (typeof time === 'number' || !isNaN(time)) {
 | 
			
		||||
        const date = new Date(parseInt(time));
 | 
			
		||||
        return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 如果是ISO字符串格式
 | 
			
		||||
      if (typeof time === 'string') {
 | 
			
		||||
        const date = new Date(time);
 | 
			
		||||
        if (!isNaN(date.getTime())) {
 | 
			
		||||
          return `$${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return time;
 | 
			
		||||
    },
 | 
			
		||||
    convertToSeries(data) {
 | 
			
		||||
      this.legendArr = []
 | 
			
		||||
      // 1. 按产线ID分组
 | 
			
		||||
      const colorArr = ['#FFCE6A', '#21CECD', '#77B4FD', '#29BDFA', '#5A7DDA', '#FFB49D', '#C5A6FC', '#7164FF', '#98B0C7', '#5D7092']
 | 
			
		||||
      const grouped = {};
 | 
			
		||||
 | 
			
		||||
      data.forEach(item => {
 | 
			
		||||
        if (!grouped[item.id]) {
 | 
			
		||||
          grouped[item.id] = {
 | 
			
		||||
            id: item.id,
 | 
			
		||||
            name: item.name,
 | 
			
		||||
            data: []
 | 
			
		||||
          };
 | 
			
		||||
        }
 | 
			
		||||
        // 将数据存入对应产线,并保留时间信息用于排序
 | 
			
		||||
        grouped[item.id].data.push({
 | 
			
		||||
          value: item.inputOutputRate,
 | 
			
		||||
          time: item.time
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // 2. 转换为series格式,并按时间排序数据点
 | 
			
		||||
      // let legendArr= []
 | 
			
		||||
      return Object.values(grouped)
 | 
			
		||||
        .sort((a, b) => a.id - b.id) // 按产线ID排序
 | 
			
		||||
        .map((line,index) => {
 | 
			
		||||
          // 按时间排序每个产线的数据点
 | 
			
		||||
          line.data.sort((a, b) => a.time - b.time);
 | 
			
		||||
          this.legendArr.push({
 | 
			
		||||
            name: line.name, // 产线名称(与series.name一致)
 | 
			
		||||
            color: colorArr[index] // 匹配colorArr中对应索引的颜色
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          // 提取value作为数据,保持ECharts series格式
 | 
			
		||||
          return {
 | 
			
		||||
            name: line.name,
 | 
			
		||||
            type: 'line',
 | 
			
		||||
            symbol: 'circle',
 | 
			
		||||
            symbolSize: 6,
 | 
			
		||||
            data: line.data.map(item => item.value)
 | 
			
		||||
          };
 | 
			
		||||
        });
 | 
			
		||||
    },
 | 
			
		||||
    getChart(xData, series) {
 | 
			
		||||
      var chartDom = document.getElementById('lineRate');
 | 
			
		||||
      var myChart = echarts.init(chartDom);
 | 
			
		||||
      var option;
 | 
			
		||||
      option = {
 | 
			
		||||
        color: ['#FFCE6A', '#21CECD', '#77B4FD', '#29BDFA', '#5A7DDA', '#FFB49D', '#C5A6FC', '#7164FF', '#98B0C7', '#5D7092'],
 | 
			
		||||
        tooltip: {
 | 
			
		||||
          trigger: 'axis'
 | 
			
		||||
        },
 | 
			
		||||
        grid: {
 | 
			
		||||
          top: 32,
 | 
			
		||||
          left: 10,
 | 
			
		||||
          right: 15,
 | 
			
		||||
          bottom: 5,
 | 
			
		||||
          containLabel: true
 | 
			
		||||
        },
 | 
			
		||||
        xAxis: {
 | 
			
		||||
          type: 'category',
 | 
			
		||||
          boundaryGap: false,
 | 
			
		||||
          axisLine: {
 | 
			
		||||
            show:true,
 | 
			
		||||
            lineStyle:{
 | 
			
		||||
              color: 'rgba(0,0,0,0.45)'
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          data: xData ? xData: [],
 | 
			
		||||
        },
 | 
			
		||||
        yAxis: {
 | 
			
		||||
          type: 'value',
 | 
			
		||||
          axisLabel: {
 | 
			
		||||
            formatter: '{value}%'
 | 
			
		||||
          },
 | 
			
		||||
          axisLine: {
 | 
			
		||||
            show:false,
 | 
			
		||||
            lineStyle:{
 | 
			
		||||
              color: 'rgba(0,0,0,0.45)'
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        series: series ? series: []
 | 
			
		||||
      };
 | 
			
		||||
      option && myChart.setOption(option);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang='scss' scoped>
 | 
			
		||||
.line-rate {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  .legend-box {
 | 
			
		||||
    width: 340px;
 | 
			
		||||
    height: 35px;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    right: 0;
 | 
			
		||||
    top:-20px;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-flow: row wrap;
 | 
			
		||||
    .legend-item {
 | 
			
		||||
      width: 100px;
 | 
			
		||||
      .dot {
 | 
			
		||||
        display: inline-block;
 | 
			
		||||
        width: 8px;
 | 
			
		||||
        height: 8px;
 | 
			
		||||
        border-radius: 50%;
 | 
			
		||||
        margin-right: 8px;
 | 
			
		||||
        position: relative;
 | 
			
		||||
      }
 | 
			
		||||
      .dot::before {
 | 
			
		||||
        content: '';
 | 
			
		||||
        display: inline-block;
 | 
			
		||||
        width: 14px;
 | 
			
		||||
        height: 2px;
 | 
			
		||||
        background-color: var(--dot-color);
 | 
			
		||||
        position: absolute;
 | 
			
		||||
        top:3px;
 | 
			
		||||
        left: -3px;
 | 
			
		||||
      }
 | 
			
		||||
      .name{
 | 
			
		||||
        font-size: 14px;
 | 
			
		||||
        color: #8C8C8C;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										223
									
								
								src/views/home/components/LossSum.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,223 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <ModelBox name='1-1'>
 | 
			
		||||
    <div class='loss-sum'>
 | 
			
		||||
      <SwitchBtn class='switch-btn' @chooseBtn='chooseBtn'/>
 | 
			
		||||
      <div id='lossSum' style='width: 584px; height: 270px;'></div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ModelBox>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import * as echarts from 'echarts';
 | 
			
		||||
import ModelBox from './ModelBox.vue';
 | 
			
		||||
import SwitchBtn from './SwitchBtn.vue';
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'LossSum',
 | 
			
		||||
  components: {
 | 
			
		||||
    ModelBox,
 | 
			
		||||
    SwitchBtn
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      nowMonth:[],
 | 
			
		||||
      nowWeek: [],
 | 
			
		||||
      oneDay: [],
 | 
			
		||||
      todayClass: []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    dataObj: {
 | 
			
		||||
      type: Object,
 | 
			
		||||
      default: () => {}
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    // this.getChart()
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    dataObj: {
 | 
			
		||||
      handler(newVal, oldVal) {
 | 
			
		||||
        console.log(newVal,'newVal');
 | 
			
		||||
        if (newVal) {
 | 
			
		||||
          this.nowMonth = newVal.nowMonth ? newVal.nowMonth : []
 | 
			
		||||
          this.nowWeek = newVal.nowWeek ? newVal.nowWeek : []
 | 
			
		||||
          this.oneDay = newVal.oneDay ? newVal.oneDay :[]
 | 
			
		||||
          this.todayClass = newVal.todayClass ? newVal.todayClass : []
 | 
			
		||||
        }
 | 
			
		||||
        this.getChart(this.todayClass)
 | 
			
		||||
      },
 | 
			
		||||
      deep: true  // 深度监听
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    getChart(val) {
 | 
			
		||||
      console.log(val, 'val');
 | 
			
		||||
      let series = []
 | 
			
		||||
      const lineNames = [...new Set(val.map(item => item.lineName))].sort();
 | 
			
		||||
      // const types = [...new Set(val.map(item => item.type))].sort();
 | 
			
		||||
      // lineNames.forEach(lineName => {
 | 
			
		||||
      //   series.push({
 | 
			
		||||
      //     name: lineName,
 | 
			
		||||
      //     type: 'bar',
 | 
			
		||||
      //     barGap: '30%',
 | 
			
		||||
      //     barWidth: 15,
 | 
			
		||||
      //     data: []
 | 
			
		||||
      //   });
 | 
			
		||||
      // });
 | 
			
		||||
      const types = ['上片', '磨边', '打孔', '丝印', '镀膜', '钢化', '包装']
 | 
			
		||||
      const typeMap = { 1: '上片', 2: '磨边', 3: '打孔',4:'丝印', 5: '镀膜', 6: '钢化', 7: '包装' };
 | 
			
		||||
      types.forEach(typeName => {
 | 
			
		||||
        series.push({
 | 
			
		||||
          name: typeName,
 | 
			
		||||
          type: 'bar',
 | 
			
		||||
          barGap: '30%',
 | 
			
		||||
          barWidth: 15,
 | 
			
		||||
          data: []
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
      types.forEach((type, index) => {
 | 
			
		||||
        const typeValue = parseInt(Object.keys(typeMap).find(key => typeMap[key] === type));
 | 
			
		||||
        console.log(typeValue,'typeValue');
 | 
			
		||||
 | 
			
		||||
        const itemSeries = series.find(s => s.name === type);
 | 
			
		||||
        lineNames.forEach(lineName => {
 | 
			
		||||
          const item = val.find(d => d.lineName === lineName && d.type === typeValue);
 | 
			
		||||
          if (item) {
 | 
			
		||||
            itemSeries.data.push(item.lossNum);
 | 
			
		||||
          } else {
 | 
			
		||||
            // 如果没有数据,添加0
 | 
			
		||||
            itemSeries.data.push(0);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
        // lineSeries.data.push(lineSeries.lossNum)
 | 
			
		||||
        // types.forEach(type => {
 | 
			
		||||
        //   // 查找对应产线和工序类型的数据
 | 
			
		||||
        //   const item = oneDay.find(d => d.lineName === lineName && d.type === type);
 | 
			
		||||
        //   if (item) {
 | 
			
		||||
        //     // 将lossNum添加到对应的系列中
 | 
			
		||||
        //     lineSeries.data.push(item.lossNum);
 | 
			
		||||
        //   } else {
 | 
			
		||||
        //     // 如果没有数据,添加0
 | 
			
		||||
        //     lineSeries.data.push(0);
 | 
			
		||||
        //   }
 | 
			
		||||
        // });
 | 
			
		||||
      });
 | 
			
		||||
      console.log('series', series);
 | 
			
		||||
 | 
			
		||||
      // const lineNames = [...new Set(val.map(item => item.lineName))].sort();
 | 
			
		||||
      // // let xData = []
 | 
			
		||||
      // lineNames.forEach(line => {
 | 
			
		||||
      //   // sectionNames.forEach(section => {
 | 
			
		||||
      //     // 查找对应产线和工段的数据
 | 
			
		||||
      //     const item = val.find(d => d.lineName === line);
 | 
			
		||||
      //     if (item) {
 | 
			
		||||
      //       // 将lossNum添加到对应的系列中
 | 
			
		||||
      //       this.series[item.type - 1].data.push(item.lossNum);
 | 
			
		||||
      //     } else {
 | 
			
		||||
      //       // 如果没有数据,添加0
 | 
			
		||||
      //       this.series.forEach(s => s.data.push(0));
 | 
			
		||||
      //     }
 | 
			
		||||
      //   // });
 | 
			
		||||
      // });
 | 
			
		||||
      // val.forEach((ele) => {
 | 
			
		||||
      //   console.log(ele.lineName,ele.type);
 | 
			
		||||
 | 
			
		||||
      //   if (!xData.includes(ele.lineName)) {
 | 
			
		||||
      //     xData.push(ele.lineName)
 | 
			
		||||
      //   }
 | 
			
		||||
      // })
 | 
			
		||||
      // console.log('xData', xData);
 | 
			
		||||
 | 
			
		||||
      var chartDom = document.getElementById('lossSum');
 | 
			
		||||
      var myChart = echarts.init(chartDom);
 | 
			
		||||
      var option;
 | 
			
		||||
      option = {
 | 
			
		||||
        color: ['#FFCE6A', '#96F0B1', '#63BDFF', '#288AFF', '#AC8BFF', '#7164FF', '#3B2BFD'],
 | 
			
		||||
        legend: {
 | 
			
		||||
          top:18,
 | 
			
		||||
          right:5,
 | 
			
		||||
          itemWidth:8,
 | 
			
		||||
          itemHeight: 8,
 | 
			
		||||
          // data: [ '上片', '磨边','打孔','镀膜','钢化','包装'],
 | 
			
		||||
          textStyle:{
 | 
			
		||||
            color: '#8C8C8C',
 | 
			
		||||
            fontSize: '14px'
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        grid: {
 | 
			
		||||
          top: 50,
 | 
			
		||||
          left: 10,
 | 
			
		||||
          right: 5,
 | 
			
		||||
          bottom: 5,
 | 
			
		||||
          containLabel: true
 | 
			
		||||
        },
 | 
			
		||||
        tooltip: {
 | 
			
		||||
          trigger: 'axis',
 | 
			
		||||
          axisPointer: {
 | 
			
		||||
            type: 'shadow'
 | 
			
		||||
          },
 | 
			
		||||
          formatter: function(params) {
 | 
			
		||||
            let result = `<span>${params[0].name}</span><br/>`;
 | 
			
		||||
            params.forEach(item => {
 | 
			
		||||
              result += `<div style="display:flex;align-items:center;">
 | 
			
		||||
                <span style="display:inline-block;width:8px;height:8px;background:${item.color};margin-right:5px;"></span>
 | 
			
		||||
                <span style="display:inline-block;margin-right:20px;">${item.seriesName}</span>
 | 
			
		||||
                <span style="font-weight:bold;">${item.value}</span><br/>
 | 
			
		||||
              </div>`;
 | 
			
		||||
            });
 | 
			
		||||
            return result;
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        xAxis: {
 | 
			
		||||
          type: 'category',
 | 
			
		||||
          axisLine: {
 | 
			
		||||
            show:true,
 | 
			
		||||
            lineStyle:{
 | 
			
		||||
              color: 'rgba(0,0,0,0.45)'
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          axisTick: {
 | 
			
		||||
            show:false
 | 
			
		||||
          },
 | 
			
		||||
          data: lineNames
 | 
			
		||||
        },
 | 
			
		||||
        yAxis: {
 | 
			
		||||
          name:'单位/片',
 | 
			
		||||
          nameTextStyle:{
 | 
			
		||||
            color: 'rgba(0,0,0,0.45)',
 | 
			
		||||
            fontSize: '14px'
 | 
			
		||||
          },
 | 
			
		||||
          axisLine: {
 | 
			
		||||
            show:true,
 | 
			
		||||
            lineStyle:{
 | 
			
		||||
              color: 'rgba(0,0,0,0.45)'
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        series: series
 | 
			
		||||
      };
 | 
			
		||||
      option && myChart.setOption(option);
 | 
			
		||||
    },
 | 
			
		||||
    chooseBtn(val) {
 | 
			
		||||
      if (val ===3) {
 | 
			
		||||
        this.getChart(this.nowMonth)
 | 
			
		||||
      } else if (val === 2) {
 | 
			
		||||
        this.getChart(this.nowWeek)
 | 
			
		||||
      } else if (val === 1) {
 | 
			
		||||
        this.getChart(this.oneDay)
 | 
			
		||||
      } else if (val === 0) {
 | 
			
		||||
        this.getChart(this.todayClass)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang='scss' scoped>
 | 
			
		||||
.loss-sum {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  .switch-btn {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    right: -3px;
 | 
			
		||||
    top: -27px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										85
									
								
								src/views/home/components/ModelBox.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,85 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class='model-box' :style='{width: width + "px", height: height + "px"}'>
 | 
			
		||||
    <div>
 | 
			
		||||
      <img :src="icon" alt="" width='24' height='24' class='icon'>
 | 
			
		||||
      <span class='model-title'>{{title}}</span>
 | 
			
		||||
    </div>
 | 
			
		||||
    <slot></slot>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import img1 from './../assets/img/1-1.png';
 | 
			
		||||
import img2 from './../assets/img/1-2.png';
 | 
			
		||||
import img3 from './../assets/img/1-3.png';
 | 
			
		||||
import img4 from './../assets/img/2-1.png';
 | 
			
		||||
import img5 from './../assets/img/2-2.png';
 | 
			
		||||
import img6 from './../assets/img/3-1.png';
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'ModelBox',
 | 
			
		||||
  props: {
 | 
			
		||||
    name: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: ''
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data () {
 | 
			
		||||
    return {
 | 
			
		||||
      title: '',
 | 
			
		||||
      icon:'',
 | 
			
		||||
      width: 618,
 | 
			
		||||
      height: 322
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted () {
 | 
			
		||||
    this.getTitle()
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    getTitle () {
 | 
			
		||||
      switch (this.name) {
 | 
			
		||||
        case '1-1':
 | 
			
		||||
          this.title = '工段损耗汇总'
 | 
			
		||||
          this.icon = img1
 | 
			
		||||
          break;
 | 
			
		||||
        case '1-2':
 | 
			
		||||
          this.title = '设备报警'
 | 
			
		||||
          this.icon = img2
 | 
			
		||||
          break;
 | 
			
		||||
        case '1-3':
 | 
			
		||||
          this.title = '托数统计'
 | 
			
		||||
          this.icon = img3
 | 
			
		||||
          break;
 | 
			
		||||
        case '2-1':
 | 
			
		||||
          this.title = '工段投入和产出'
 | 
			
		||||
          this.icon = img4
 | 
			
		||||
          break;
 | 
			
		||||
        case '3-1':
 | 
			
		||||
          this.title = '产线加工成品率'
 | 
			
		||||
          this.icon = img6
 | 
			
		||||
          break;
 | 
			
		||||
        default:
 | 
			
		||||
          this.title = '产线投入和产出'
 | 
			
		||||
          this.icon = img5
 | 
			
		||||
          this.width = 1253
 | 
			
		||||
          this.height = 660
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang='scss' scoped>
 | 
			
		||||
.model-box {
 | 
			
		||||
  background: #FFFFFF;
 | 
			
		||||
  border-radius: 8px;
 | 
			
		||||
  border: 1px solid #FFFFFF;
 | 
			
		||||
  padding: 14px 16px;
 | 
			
		||||
  .icon {
 | 
			
		||||
    vertical-align: bottom;
 | 
			
		||||
    margin-right: 5px;
 | 
			
		||||
  }
 | 
			
		||||
  .model-title{
 | 
			
		||||
    font-size: 20px;
 | 
			
		||||
    color: #000000;
 | 
			
		||||
    line-height: 24px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										231
									
								
								src/views/home/components/SectionInputAndOutput.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,231 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <ModelBox name='2-1'>
 | 
			
		||||
    <div class='section-content'>
 | 
			
		||||
      <SwitchBtn class='switch-btn' @chooseBtn='chooseBtn' />
 | 
			
		||||
      <div class='section-list'>
 | 
			
		||||
        <div v-for='item in sectionArr' :key='item.id' class='section-item'
 | 
			
		||||
          :class='{active: sectionActive === item.id}' @click='sectionActive = item.id'>{{item.name}}</div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <dv-scroll-board  ref="showTable" :config="config" style="width:583px;height:220px;" class='section-table' />
 | 
			
		||||
      <span class='split-line' style='left: 66px;'></span>
 | 
			
		||||
      <span class='split-line' style='left: 186px;'></span>
 | 
			
		||||
      <span class='split-line' style='left: 306px;'></span>
 | 
			
		||||
      <span class='split-line' style='left: 426px;'></span>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ModelBox>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import ModelBox from './ModelBox.vue';
 | 
			
		||||
import SwitchBtn from './SwitchBtn.vue';
 | 
			
		||||
import arrowGreen from '../assets/img/arrow-green.png';
 | 
			
		||||
import arrowRed from '../assets/img/arrow-red.png';
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'SectionInputAndOutput',
 | 
			
		||||
  components: {
 | 
			
		||||
    ModelBox,
 | 
			
		||||
    SwitchBtn
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
    dataObj: {
 | 
			
		||||
      handler(newVal, oldVal) {
 | 
			
		||||
        console.log(newVal, 'newVal');
 | 
			
		||||
        if (newVal) {
 | 
			
		||||
          this.nowMonth = newVal.nowMonth ? newVal.nowMonth : []
 | 
			
		||||
          this.nowWeek = newVal.nowWeek ? newVal.nowWeek : []
 | 
			
		||||
          this.oneDay = newVal.oneDay ? newVal.oneDay : []
 | 
			
		||||
          this.todayClass = newVal.todayClass ? newVal.todayClass : []
 | 
			
		||||
        }
 | 
			
		||||
        // this.getChart(this.todayClass)
 | 
			
		||||
      },
 | 
			
		||||
      deep: true,  // 深度监听
 | 
			
		||||
      immediate: true
 | 
			
		||||
    },
 | 
			
		||||
    sectionActive: {
 | 
			
		||||
      handler(newVal) {
 | 
			
		||||
        if (newVal) {
 | 
			
		||||
          console.log(newVal, 'sectionActive');
 | 
			
		||||
          this.updateChartData();
 | 
			
		||||
        }
 | 
			
		||||
        // this.updateChartData();
 | 
			
		||||
      },
 | 
			
		||||
      deep: true,
 | 
			
		||||
      immediate: true
 | 
			
		||||
    },
 | 
			
		||||
    time: {
 | 
			
		||||
      handler(newVal) {
 | 
			
		||||
        if (newVal) {
 | 
			
		||||
          console.log(newVal, 'sectionActive');
 | 
			
		||||
          this.updateChartData();
 | 
			
		||||
        }
 | 
			
		||||
        // this.updateChartData();
 | 
			
		||||
      },
 | 
			
		||||
      deep: true,
 | 
			
		||||
      immediate: true
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    dataObj: {
 | 
			
		||||
      type: Object,
 | 
			
		||||
      default: () => {}
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      sectionArr:[
 | 
			
		||||
        {id:1, name:'上片'},
 | 
			
		||||
        {id:2, name:'磨边'},
 | 
			
		||||
        {id:3, name:'打孔'},
 | 
			
		||||
        {id:4, name:'丝印'},
 | 
			
		||||
        {id:5, name:'镀膜'},
 | 
			
		||||
        {id:6, name:'钢化'},
 | 
			
		||||
        {id:7, name:'包装'}
 | 
			
		||||
      ],
 | 
			
		||||
      nowMonth: [],
 | 
			
		||||
      nowWeek: [],
 | 
			
		||||
      oneDay: [],
 | 
			
		||||
      todayClass: [],
 | 
			
		||||
      time: 0,
 | 
			
		||||
      showData: [],
 | 
			
		||||
      sectionActive: '1',
 | 
			
		||||
      config:{
 | 
			
		||||
        header: ['<span style="color:#000;">序号</span>', '<span style="color:#000;">工段</span>', '<span style="color:#000;">投入数量/片</span>', '<span style="color:#000;">产出数量/片</span>','<span style="color:#000;">产出率/%</span>'],
 | 
			
		||||
        headerHeight: 25,
 | 
			
		||||
        headerBGC: '#E8EDF8',
 | 
			
		||||
        oddRowBGC:'#E8EDF8',
 | 
			
		||||
        evenRowBGC:'#fff',
 | 
			
		||||
        rowNum: 7,
 | 
			
		||||
        columnWidth: [60, 120, 120, 120, 163],
 | 
			
		||||
        align	: ['center', 'center', 'center', 'center', 'center'],
 | 
			
		||||
        data:[]
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.updateChartData()
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
    updateChartData() {
 | 
			
		||||
      const data = this.getDataByTimeAndType();
 | 
			
		||||
      this.getData(data);
 | 
			
		||||
    },
 | 
			
		||||
    getDataByTimeAndType() {
 | 
			
		||||
      // console.log(this.time,'time');
 | 
			
		||||
      console.log(this.sectionActive, this.time, 'sectionActive');
 | 
			
		||||
 | 
			
		||||
      // 确定当前时间范围的数据源
 | 
			
		||||
      let dataSource;
 | 
			
		||||
      switch (this.time) {
 | 
			
		||||
        case 3: // 本月
 | 
			
		||||
          dataSource = this.nowMonth;
 | 
			
		||||
          break;
 | 
			
		||||
        case 2: // 本周
 | 
			
		||||
          dataSource = this.nowWeek;
 | 
			
		||||
          break;
 | 
			
		||||
        case 1: // 今日
 | 
			
		||||
          dataSource = this.oneDay;
 | 
			
		||||
          break;
 | 
			
		||||
        case 0: // 今日班次
 | 
			
		||||
        default:
 | 
			
		||||
          dataSource = this.todayClass;
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
      console.log(dataSource,'dataSource');
 | 
			
		||||
 | 
			
		||||
      // 如果没有数据,返回空数组
 | 
			
		||||
      if (!dataSource || dataSource.length === 0) {
 | 
			
		||||
        return [];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 根据sectionActive(对应type)筛选数据
 | 
			
		||||
      const filteredData = dataSource.filter(item => item.type === parseInt(this.sectionActive));
 | 
			
		||||
 | 
			
		||||
      // 按产出率排序
 | 
			
		||||
      return filteredData
 | 
			
		||||
    },
 | 
			
		||||
    getData(data) {
 | 
			
		||||
      console.log(data,'ryf');
 | 
			
		||||
      this.showData = data ? data.map((item, index) => [
 | 
			
		||||
        // `<span style="color:#000;" >${index + 1 || ''}
 | 
			
		||||
        //     </span>`,
 | 
			
		||||
        `<span style="color:#000;">${index + 1 }</span>`,
 | 
			
		||||
        // `<span style="color:#000;" >${item.sectionName || ''}
 | 
			
		||||
        //     </span>`,
 | 
			
		||||
        `<span style="color:#000;">${item.sectionName}</span>`,
 | 
			
		||||
        // formatDate(item.planStartTime) || '',
 | 
			
		||||
        `<span style="color:#000;" >${item.inputNum || ''}
 | 
			
		||||
          </span>`,
 | 
			
		||||
        // `<span style="color:#000;">${data[i][3]}</span>`
 | 
			
		||||
        `<span style="color:#000;">${item.outputNum || ''}</span>`,
 | 
			
		||||
        `<div style="width:136px; margin:0px;">
 | 
			
		||||
          <div style="display:inline-block;height:8px; background:#D8DEEB; border-radius:4px; overflow:hidden;text-align:left;width:90px">
 | 
			
		||||
            <div style="width:${item.inputOutputRate}%; height:100%; background:#0B58FF;border-radius:4px;"></div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <span style="display:inline-block;margin-left:10px; color:#000; font-size:14px;">${item.inputOutputRate }%</span>
 | 
			
		||||
        </div>`,
 | 
			
		||||
     ]) : []
 | 
			
		||||
 | 
			
		||||
      this.config = {
 | 
			
		||||
        ...this.config,
 | 
			
		||||
        data: this.showData
 | 
			
		||||
      };
 | 
			
		||||
      console.log(this.showData, 'arr', this.config.data);
 | 
			
		||||
      // console.log(this.$refs['showTable'])
 | 
			
		||||
 | 
			
		||||
      this.$nextTick(() => {
 | 
			
		||||
        if (this.$refs.showTable) {
 | 
			
		||||
          this.$refs.showTable.updateRows(this.showData);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
      // this.$forceUpdate()
 | 
			
		||||
      // this.config.data = arr2
 | 
			
		||||
    },
 | 
			
		||||
    chooseBtn(val) {
 | 
			
		||||
      this.time = val
 | 
			
		||||
      console.log(this.time,' this.time');
 | 
			
		||||
 | 
			
		||||
      this.updateChartData()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang='scss' scoped>
 | 
			
		||||
.section-content {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  .switch-btn {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    right: -3px;
 | 
			
		||||
    top: -27px;
 | 
			
		||||
  }
 | 
			
		||||
  .section-list {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-flow: row wrap;
 | 
			
		||||
    justify-content: space-between;
 | 
			
		||||
    padding-top: 20px;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    .section-item {
 | 
			
		||||
      height: 24px;
 | 
			
		||||
      line-height: 24px;
 | 
			
		||||
      width: 81px;
 | 
			
		||||
      text-align: center;
 | 
			
		||||
      letter-spacing: 4px;
 | 
			
		||||
      background-color: #E8EDF8;
 | 
			
		||||
    }
 | 
			
		||||
    .active {
 | 
			
		||||
      background-color: #0B58FF;
 | 
			
		||||
      color: #fff;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  .section-table {
 | 
			
		||||
    margin-top: 2px;
 | 
			
		||||
    box-shadow: 0px 2px 4px 0px #D5DAE6;
 | 
			
		||||
  }
 | 
			
		||||
  .split-line {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 46px;
 | 
			
		||||
    width: 1px;
 | 
			
		||||
    height: 221px;
 | 
			
		||||
    background: #CDD3DF;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										57
									
								
								src/views/home/components/SwitchBtn.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,57 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class='button-box'>
 | 
			
		||||
    <span v-for='(item, index) in btnArr' :key='index' style='display: inline-block;'>
 | 
			
		||||
      <span class='split' v-if='index > 0' :class='{ "split-active": activeIndex === index || activeIndex === index - 1}'>|</span>
 | 
			
		||||
      <span class='button-item' @click='chooseBtn(index)' :class='{ "item-active": activeIndex === index}'>{{item}}</span>
 | 
			
		||||
    </span>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'SwitchBtn',
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      activeIndex: 1,
 | 
			
		||||
      btnArr: ['本班次', '本日', '本周', '本月']
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    chooseBtn(index) {
 | 
			
		||||
      this.activeIndex = index
 | 
			
		||||
      this.$emit('chooseBtn', index)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang='scss' scoped>
 | 
			
		||||
.button-box {
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  color: #000;
 | 
			
		||||
  background: #F2F4F9;
 | 
			
		||||
  border-radius: 40px;
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  .button-item {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    font-size: 16px;
 | 
			
		||||
    height: 32px;
 | 
			
		||||
    line-height: 32px;
 | 
			
		||||
    padding: 0 12px;
 | 
			
		||||
  }
 | 
			
		||||
  .item-active {
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    background: #0B58FF;
 | 
			
		||||
    border-radius: 40px;
 | 
			
		||||
  }
 | 
			
		||||
  .split {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    height: 32px;
 | 
			
		||||
    line-height: 32px;
 | 
			
		||||
    vertical-align: top;
 | 
			
		||||
    color: #686868;
 | 
			
		||||
  }
 | 
			
		||||
  .split-active {
 | 
			
		||||
    color: #F2F4F9;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										249
									
								
								src/views/home/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,249 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class='home-box'>
 | 
			
		||||
    <div id="homeComtainerB" ref="homeComtainerB">
 | 
			
		||||
      <div class='home-comtainer' id="homeComtainer" style="width: 1920px; height: 1080px"
 | 
			
		||||
        :style="{ transform: 'scale(' + scaleNum + ')' }">
 | 
			
		||||
        <HomeHeader :isFullScreen="isFullScreen" @screenfullChange="screenfullChange" />
 | 
			
		||||
        <div class='line-one'>
 | 
			
		||||
          <LossSum style='margin-right: 16px;' :dataObj="dataObj.workShopData" />
 | 
			
		||||
          <EqAlarm style='margin-right: 16px;' :dataObj="dataObj.alarmData" />
 | 
			
		||||
          <Count :dataObj="dataObj.downLoadNum" />
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class='line-two'>
 | 
			
		||||
          <div>
 | 
			
		||||
            <SectionInputAndOutput style='margin-bottom: 16px;' :dataObj="dataObj.workShopData" />
 | 
			
		||||
            <LineRate  :dataObj="dataObj.lineHours"/>
 | 
			
		||||
          </div>
 | 
			
		||||
          <LineInpurAndOutput :dataObj="dataObj.productionLineData" style='margin-left: 16px;' />
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
</template>
 | 
			
		||||
<script>
 | 
			
		||||
import HomeHeader from './components/HomeHeader.vue';
 | 
			
		||||
import LossSum from './components/LossSum.vue';
 | 
			
		||||
import EqAlarm from './components/EqAlarm.vue';
 | 
			
		||||
import Count from './components/Count.vue';
 | 
			
		||||
import SectionInputAndOutput from './components/SectionInputAndOutput.vue';
 | 
			
		||||
import LineRate from './components/LineRate.vue';
 | 
			
		||||
import LineInpurAndOutput from './components/LineInpurAndOutput.vue';
 | 
			
		||||
import { debounce } from '@/utils/debounce';
 | 
			
		||||
import screenfull from 'screenfull';
 | 
			
		||||
import { getAccessToken } from '@/utils/auth';
 | 
			
		||||
import store from "@/store";
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'Home',
 | 
			
		||||
  components: {
 | 
			
		||||
    HomeHeader,
 | 
			
		||||
    LossSum,
 | 
			
		||||
    EqAlarm,
 | 
			
		||||
    Count,
 | 
			
		||||
    SectionInputAndOutput,
 | 
			
		||||
    LineRate,
 | 
			
		||||
    LineInpurAndOutput
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      isFullScreen: false,
 | 
			
		||||
      scaleNum: 1,
 | 
			
		||||
      dataObj: {},
 | 
			
		||||
      sseReader: null,        // 保存流读取器
 | 
			
		||||
      abortController: null,  // 用于中止 fetch 请求
 | 
			
		||||
      retryCount: 0,          // 当前重试次数
 | 
			
		||||
      isDestroyed: false      // 标记组件是否已销毁
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    this.init();
 | 
			
		||||
    this.getData()
 | 
			
		||||
	},
 | 
			
		||||
  mounted() {
 | 
			
		||||
		this.boxReset();
 | 
			
		||||
    window.addEventListener('resize', this.boxReset);
 | 
			
		||||
    // this.boxReset = debounce(() => {
 | 
			
		||||
    //   this.resetSize()
 | 
			
		||||
    // }, 300)
 | 
			
		||||
    // this.boxReset()
 | 
			
		||||
    // window.addEventListener('resize', () => {
 | 
			
		||||
    //   this.boxReset()
 | 
			
		||||
    // })
 | 
			
		||||
    this.getData()
 | 
			
		||||
	},
 | 
			
		||||
	destroyed() {
 | 
			
		||||
		window.removeEventListener('resize', this.boxReset);
 | 
			
		||||
	},
 | 
			
		||||
  methods: {
 | 
			
		||||
    boxReset() {
 | 
			
		||||
			debounce(() => {
 | 
			
		||||
				this.resetSize();
 | 
			
		||||
			}, 300)();
 | 
			
		||||
    },
 | 
			
		||||
    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();
 | 
			
		||||
 | 
			
		||||
        // 持续读取流数据
 | 
			
		||||
        while (true) {
 | 
			
		||||
          const { done, value } = await _this.sseReader.read();
 | 
			
		||||
          if (done) {
 | 
			
		||||
            console.log('SSE 连接正常关闭');
 | 
			
		||||
            _this.handleReconnect(); // 触发重连
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
          // 处理 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) {
 | 
			
		||||
				screenfull.on('change', this.change);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		destroy() {
 | 
			
		||||
			if (screenfull.isEnabled) {
 | 
			
		||||
				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.homeComtainerB);
 | 
			
		||||
		},
 | 
			
		||||
    resetSize() {
 | 
			
		||||
			let coldContainerBox = document.getElementById('homeComtainer');
 | 
			
		||||
			let rw = parseFloat(window.innerWidth);
 | 
			
		||||
			let rh = parseFloat(window.innerHeight);
 | 
			
		||||
			let bw = parseFloat(coldContainerBox.style.width);
 | 
			
		||||
			let bh = parseFloat(coldContainerBox.style.height);
 | 
			
		||||
			let wx = 0;
 | 
			
		||||
			let hx = 0;
 | 
			
		||||
			if (screenfull.isFullscreen) {
 | 
			
		||||
				wx = rw / bw;
 | 
			
		||||
				hx = rh / bh;
 | 
			
		||||
			} else {
 | 
			
		||||
				if (this.$store.state.app.sidebar.opened) {
 | 
			
		||||
					wx = (rw - 280) / bw;
 | 
			
		||||
					hx = (rh - 116) / bh;
 | 
			
		||||
				} else {
 | 
			
		||||
					wx = (rw - 85) / bw;
 | 
			
		||||
					hx = (rh - 116) / bh;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			this.scaleNum = wx;
 | 
			
		||||
		},
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
  '$store.state.app.sidebar.opened': {
 | 
			
		||||
    handler(newVal, oldVal) {
 | 
			
		||||
      this.boxReset();
 | 
			
		||||
    },
 | 
			
		||||
    immediate: true
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
<style lang='scss' scoped>
 | 
			
		||||
.home-box {
 | 
			
		||||
  min-height: calc(100vh - 56px - 72px);
 | 
			
		||||
  min-width: calc(100vh - 280px);
 | 
			
		||||
  background-color: #F2F4F9;
 | 
			
		||||
}
 | 
			
		||||
.home-comtainer{
 | 
			
		||||
  background-color: #F2F4F9;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  transform-origin: 16px 8px;
 | 
			
		||||
  top: 0px;
 | 
			
		||||
	left: 0px;
 | 
			
		||||
  padding-left: 16px;
 | 
			
		||||
  padding-top: 10px;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  .line-one {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    margin-top: 16px;
 | 
			
		||||
  }
 | 
			
		||||
  .line-two {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    margin-top: 16px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||