From cb07563b69fc86095db2825df1340c47ba3f8f84 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期三, 12 十一月 2025 18:01:04 +0800
Subject: [PATCH] 新疆-生产流程定制化

---
 src/views/productionManagement/productionDispatching/index.vue |  321 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 314 insertions(+), 7 deletions(-)

diff --git a/src/views/productionManagement/productionDispatching/index.vue b/src/views/productionManagement/productionDispatching/index.vue
index 527880f..6a61e6e 100644
--- a/src/views/productionManagement/productionDispatching/index.vue
+++ b/src/views/productionManagement/productionDispatching/index.vue
@@ -1,5 +1,22 @@
 <template>
 	<div class="app-container">
+		<!-- 鐐掓満1-4 灞曠ず锛堟�婚噺 / 姝e湪鐢熶骇閲� / 绌轰綑閲忥級 -->
+		<div class="machines-grid">
+			<div v-for="machine in machines" :key="machine.id" class="machine-card">
+				<div class="machine-title">{{ machine.name }}</div>
+				<div class="machine-metrics">
+				<div class="machine-control">
+					<span>鎬婚噺(kg)锛�</span>
+					<el-input-number v-model="machineData[machine.name].workLoad" :min="0" :step="1" size="small" />
+				</div>
+				<div><span>姝e湪宸ヤ綔閲�(kg)锛�</span><span>{{ machineData[machine.name].currentWorkLoad }}</span></div>
+				<div><span>绌轰綑宸ヤ綔閲�(kg)锛�</span><span>{{ machineData[machine.name].vacant }}</span></div>
+			</div>
+			</div>
+			<div class="save-button-container">
+				<el-button type="primary" @click="saveMachineTotals" size="small">淇濆瓨璁剧疆</el-button>
+			</div>
+		</div>
 		<div class="search_form">
 			<div>
 				<span class="search_title">瀹㈡埛鍚嶇О锛�</span>
@@ -22,13 +39,14 @@
 				/>
 				<span class="search_title ml10">褰曞叆鏃ユ湡锛�</span>
 				<el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
-												placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+										placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
 				<el-button type="primary" @click="handleQuery" style="margin-left: 10px">鎼滅储</el-button>
 			</div>
 			<div>
-				<el-button type="primary" @click="openForm('add')">鐢熶骇娲惧伐</el-button>
-				<el-button @click="handleOut">瀵煎嚭</el-button>
-			</div>
+			<el-button type="primary" @click="openForm('add')">鐢熶骇娲惧伐</el-button>
+			<el-button type="success" @click="openAutoDispatch">鑷姩娲惧伐</el-button>
+			<el-button @click="handleOut">瀵煎嚭</el-button>
+		</div>
 		</div>
 		<div class="table_list">
 			<PIMTable
@@ -44,14 +62,16 @@
 			></PIMTable>
 		</div>
 		<form-dia ref="formDia" @close="handleQuery"></form-dia>
+		<auto-dispatch-dia ref="autoDispatchDia" @close="handleQuery"></auto-dispatch-dia>
 	</div>
 </template>
 
 <script setup>
-import {onMounted, ref} from "vue";
+import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick, computed, watch} from "vue";
 import FormDia from "@/views/productionManagement/productionDispatching/components/formDia.vue";
+import AutoDispatchDia from "@/views/productionManagement/productionDispatching/components/autoDispatchDia.vue";
 import dayjs from "dayjs";
-import {schedulingListPage} from "@/api/productionManagement/productionOrder.js";
+import {schedulingListPage, schedulingList, addSpeculatTrading, updateSpeculatTrading} from "@/api/productionManagement/productionOrder.js";
 import { ElMessageBox } from "element-plus";
 
 const data = reactive({
@@ -93,6 +113,11 @@
 	{
 		label: "瑙勬牸鍨嬪彿",
 		prop: "specificationModel",
+		width: 120,
+	},
+	{
+		label: "缁戝畾鏈哄櫒",
+		prop: "speculativeTradingName",
 		width: 220,
 	},
 	{
@@ -129,7 +154,115 @@
 	total: 0,
 });
 const formDia = ref()
+const autoDispatchDia = ref()
 const { proxy } = getCurrentInstance()
+
+// 鐐掓満鏁版嵁
+const machineData = reactive({
+	"鐐掓満1": { workLoad: 0, currentWorkLoad: 0, vacant: 0 },
+	"鐐掓満2": { workLoad: 0, currentWorkLoad: 0, vacant: 0 },
+	"鐐掓満3": { workLoad: 0, currentWorkLoad: 0, vacant: 0 },
+	"鐐掓満4": { workLoad: 0, currentWorkLoad: 0, vacant: 0 }
+})
+
+// 鐐掓満閰嶇疆鏁扮粍
+const machines = [
+	{ id: 1, name: '鐐掓満1' },
+	{ id: 2, name: '鐐掓満2' },
+	{ id: 3, name: '鐐掓満3' },
+	{ id: 4, name: '鐐掓満4' }
+]
+
+// 淇濆瓨鐐掓満鎬婚噺璁剧疆
+const saveMachineTotals = () => {
+	// 鏋勯�犱繚瀛樻暟鎹暟缁勶紝浣跨敤machines鏁扮粍寰幆鏋勫缓
+	const saveData = machines.map(machine => {
+		const saveItem = {
+			name: machine.name, // 鐐掓満鍚嶇О
+			workLoad: machineData[machine.name].workLoad,  // 鎬婚噺
+			currentWorkLoad: machineData[machine.name].currentWorkLoad, // 姝e湪宸ヤ綔閲�
+			vacant: machineData[machine.name].vacant   // 绌轰綑閲�
+		};
+		
+		// 濡傛灉鏄慨鏀规搷浣滐紝闇�瑕佷紶閫抜d瀛楁
+		if (hasQueryData.value) {
+			// 杩欓噷闇�瑕佷粠鏌ヨ鏁版嵁涓幏鍙栧搴旂殑id
+			// 鍋囪鏌ヨ鏁版嵁涓瘡涓倰鏈烘暟鎹兘鏈塱d瀛楁
+			const queryData = getMachineQueryData(machine.id);
+			if (queryData && queryData.id) {
+				saveItem.id = queryData.id;
+			}
+		}
+		
+		return saveItem;
+	});
+	
+	console.log('淇濆瓨鐐掓満璁剧疆鏁版嵁:', saveData);
+	
+	// 鏍规嵁鏄惁鏈夋煡璇㈡暟鎹喅瀹氳皟鐢ㄦ柊澧炴帴鍙h繕鏄慨鏀规帴鍙�
+	const saveApi = hasQueryData.value ? updateSpeculatTrading : addSpeculatTrading;
+	const successMessage = hasQueryData.value ? '鐐掓満璁剧疆淇敼鎴愬姛' : '鐐掓満璁剧疆鏂板鎴愬姛';
+	
+	console.log(`璋冪敤鎺ュ彛: ${hasQueryData.value ? '淇敼' : '鏂板'}`);
+	
+	// 璋冪敤鍚庣API淇濆瓨
+	saveApi(saveData).then(res => {
+		proxy.$message.success(successMessage);
+		console.log('淇濆瓨鎴愬姛:', res);
+		
+		// 淇濆瓨鎴愬姛鍚庯紝璁剧疆hasQueryData涓簍rue锛屼笅娆′繚瀛樺皢璋冪敤淇敼鎺ュ彛
+		if (!hasQueryData.value) {
+			hasQueryData.value = true;
+		}
+	}).catch(err => {
+		proxy.$message.error('淇濆瓨澶辫触');
+		console.error('淇濆瓨澶辫触:', err);
+	});
+}
+
+// 鑾峰彇鐐掓満鏌ヨ鏁版嵁
+const machineQueryData = ref([]);
+
+const getMachineQueryData = (machineId) => {
+	return machineQueryData.value.find(item => item.id === machineId);
+};
+
+const getMachineIndex = (item) => {
+	// 鍏煎澶氱瀛楁鍛藉悕锛岃繑鍥� 1-4 涔嬩竴锛屽惁鍒欒繑鍥� 0锛堟湭鐭ワ級
+	const candidates = [item.machineId, item.machineNo, item.machine, item.deviceNo, item.deviceId]
+	for (const v of candidates) {
+		if (v === undefined || v === null) continue
+		const n = Number(String(v).replace(/[^\d]/g, "")) // 鎶藉彇鏁板瓧
+		if ([1,2,3,4].includes(n)) return n
+	}
+	return 0
+}
+
+const computeTodaySummary = () => {
+	const todayStr = dayjs().format("YYYY-MM-DD")
+	
+	// 閲嶇疆鎵�鏈夌倰鏈烘暟鎹�
+	machines.forEach(machine => {
+		machineData[machine.name] = { workLoad: 0, currentWorkLoad: 0, vacant: 0 }
+	})
+	
+	tableData.value.forEach(item => {
+		// 浠呯粺璁″綋澶�
+		const isToday = dayjs(item.entryDate).format("YYYY-MM-DD") === todayStr
+		if (!isToday) return
+		
+		// 浣跨敤姝g‘鐨勫瓧娈靛悕锛歸orkLoad锛堢倰鏈哄伐浣滈噺锛�, currentWorkLoad锛堢倰鏈烘鍦ㄥ伐浣滈噺锛�
+		const workLoad = Number(item.workLoad) || 0
+		const currentWorkLoad = Number(item.currentWorkLoad) || 0
+		const machineName = item.speculativeTradingName || '鐐掓満1'
+		
+		if (machineData[machineName]) {
+			machineData[machineName].workLoad += workLoad
+			machineData[machineName].currentWorkLoad += currentWorkLoad
+			machineData[machineName].vacant = machineData[machineName].workLoad - machineData[machineName].currentWorkLoad
+		}
+	})
+}
 
 // 鏌ヨ鍒楄〃
 /** 鎼滅储鎸夐挳鎿嶄綔 */
@@ -137,6 +270,55 @@
 	page.current = 1;
 	getList();
 };
+
+// 鏄惁鏈夋煡璇㈡暟鎹�
+const hasQueryData = ref(false)
+
+// 鑾峰彇鐐掓満姝e湪宸ヤ綔閲忔暟鎹�
+const getMachineProductionData = () => {
+	schedulingList().then((res) => {
+		// 澶勭悊鐐掓満姝e湪宸ヤ綔閲忔暟鎹�
+		if (res.data && Array.isArray(res.data)) {
+			// 璁剧疆鏄惁鏈夋煡璇㈡暟鎹�
+			hasQueryData.value = res.data.length > 0
+			
+			// 淇濆瓨鏌ヨ鏁版嵁鍒癿achineQueryData
+			machineQueryData.value = res.data;
+			
+			// 閲嶇疆鎵�鏈夌倰鏈烘暟鎹�
+			machines.forEach(machine => {
+				machineData[machine.name] = { workLoad: 0, currentWorkLoad: 0, vacant: 0 }
+			});
+			
+			// 閬嶅巻鏁版嵁锛屾牴鎹煡璇㈣繑鍥炵殑鏁版嵁缁撴瀯澶勭悊
+			res.data.forEach(item => {
+				// 鏍规嵁name瀛楁纭畾鐐掓満
+				const machineName = item.name || '鐐掓満1';
+				
+				if (machineData[machineName]) {
+					// 濡傛灉鏌ヨ鏁版嵁涓湁workLoad锛屽垯鍒濆鍖栫倰鏈烘�婚噺
+					if (item.workLoad !== null && item.workLoad !== undefined) {
+						machineData[machineName].workLoad = Number(item.workLoad) || 0;
+					}
+					
+					// 濡傛灉鏌ヨ鏁版嵁涓湁currentWorkLoad锛屽垯璁剧疆姝e湪宸ヤ綔閲�
+					if (item.currentWorkLoad !== null && item.currentWorkLoad !== undefined) {
+						machineData[machineName].currentWorkLoad = Number(item.currentWorkLoad) || 0;
+					}
+					
+					// 璁$畻绌轰綑宸ヤ綔閲�
+					machineData[machineName].vacant = machineData[machineName].workLoad - machineData[machineName].currentWorkLoad;
+				}
+			});
+			
+			console.log('鐐掓満鏁版嵁鍒濆鍖栧畬鎴�:', machineData);
+			console.log('鐐掓満鏌ヨ鏁版嵁:', machineQueryData.value);
+		}
+	}).catch(err => {
+		console.error('鑾峰彇鐐掓満姝e湪宸ヤ綔閲忔暟鎹け璐�:', err);
+	});
+};
+
 const changeDaterange = (value) => {
 	if (value) {
 		searchForm.value.entryDateStart = value[0];
@@ -165,6 +347,10 @@
 			pendingQuantity: (Number(item.quantity) || 0) - (Number(item.schedulingNum) || 0)
 		}));
 		page.total = res.data.total;
+		computeTodaySummary()
+		
+		// 鍚屾椂鑾峰彇鐐掓満姝e湪宸ヤ綔閲忔暟鎹�
+		getMachineProductionData();
 	}).catch(() => {
 		tableLoading.value = false;
 	})
@@ -189,6 +375,26 @@
 	})
 };
 
+// 鎵撳紑鑷姩娲惧伐寮规
+const openAutoDispatch = () => {
+	if (selectedRows.value.length === 0) {
+		proxy.$message.error("璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�");
+		return;
+	}
+	
+	// 杩囨护鎺夊緟鎺掍骇鏁伴噺涓�0鐨勬暟鎹�
+	const validRows = selectedRows.value.filter(row => row.pendingQuantity > 0);
+	
+	if (validRows.length === 0) {
+		proxy.$message.warning("閫変腑鐨勬暟鎹棤闇�娲惧伐");
+		return;
+	}
+	
+	nextTick(() => {
+		autoDispatchDia.value?.openDialog('auto', validRows)
+	})
+};
+
 // 瀵煎嚭
 const handleOut = () => {
 	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
@@ -209,4 +415,105 @@
 });
 </script>
 
-<style scoped></style>
+<style scoped>
+.summary-bar{
+	display: flex;
+	gap: 16px;
+	margin: 10px 0 16px 0;
+}
+.summary-item{
+	background: #f5f7fa;
+	border: 1px solid #ebeef5;
+	border-radius: 6px;
+	padding: 10px 16px;
+	min-width: 160px;
+}
+.summary-label{
+	color: #909399;
+	font-size: 12px;
+	margin-bottom: 6px;
+}
+.summary-value{
+	color: #303133;
+	font-size: 20px;
+	font-weight: 600;
+}
+.summary-control{
+	display: flex;
+	align-items: center;
+	height: 28px;
+}
+.machines-grid{
+	display: grid;
+	grid-template-columns: repeat(4, 1fr);
+	gap: 16px;
+	margin-bottom: 20px;
+	padding: 16px;
+	background: #f8f9fa;
+	border-radius: 8px;
+	border: 1px solid #e9ecef;
+}
+.machine-card{
+	border: 1px solid #dee2e6;
+	border-radius: 8px;
+	padding: 16px;
+	background: #fff;
+	box-shadow: 0 2px 4px rgba(0,0,0,0.05);
+	transition: all 0.3s ease;
+}
+.machine-card:hover{
+	transform: translateY(-2px);
+	box-shadow: 0 4px 8px rgba(0,0,0,0.1);
+}
+.machine-title{
+	font-weight: 600;
+	font-size: 16px;
+	margin-bottom: 12px;
+	color: #2c3e50;
+	text-align: center;
+	padding-bottom: 8px;
+	border-bottom: 2px solid #3498db;
+}
+.machine-metrics{
+	display: flex;
+	flex-direction: column;
+	gap: 10px;
+	color: #495057;
+}
+.machine-control{
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	gap: 8px;
+	padding: 8px 0;
+	border-bottom: 1px solid #f1f3f4;
+}
+.machine-control span{
+	font-size: 14px;
+	white-space: nowrap;
+	color: #6c757d;
+	font-weight: 500;
+}
+.machine-metrics > div:not(.machine-control) {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding: 4px 0;
+	font-size: 14px;
+}
+.machine-metrics > div:not(.machine-control) span:first-child {
+	color: #6c757d;
+}
+.machine-metrics > div:not(.machine-control) span:last-child {
+	font-weight: 600;
+	color: #2c3e50;
+}
+.save-button-container{
+	grid-column: 1 / -1;
+	display: flex;
+	justify-content: center;
+	margin-top: 16px;
+	padding-top: 16px;
+	border-top: 1px solid #e9ecef;
+}
+</style>

--
Gitblit v1.9.3