From eb5d2e32f490a069307ecdd964669f3d1575dedc Mon Sep 17 00:00:00 2001
From: 张诺 <zhang_12370@163.com>
Date: 星期三, 29 四月 2026 10:19:45 +0800
Subject: [PATCH] feat(productionManagement): 添加工单管理页面功能 修改生产排产只允许排产没有历史 排产记录修改为历史的排产记录
---
src/views/productionManagement/workOrder/index.vue | 203 +++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 159 insertions(+), 44 deletions(-)
diff --git a/src/views/productionManagement/workOrder/index.vue b/src/views/productionManagement/workOrder/index.vue
index 2b56480..4a4f9bb 100644
--- a/src/views/productionManagement/workOrder/index.vue
+++ b/src/views/productionManagement/workOrder/index.vue
@@ -326,21 +326,19 @@
</template>
</el-dialog>
<el-dialog v-model="scheduleDialogVisible"
- :title="`鐢熶骇鎺掍骇(宸ュ崟缂栧彿:${currentReportRowData?.workOrderNo || '-'})`"
+ :title="scheduleDialogTitle"
width="1000px"
:close-on-click-modal="false">
<div class="schedule-panel">
- <el-row style="margin-bottom: 12px;">
+ <el-row v-if="!isScheduleHistoryMode" style="margin-bottom: 12px;">
<el-col>
<el-button type="primary" plain :disabled="scheduleLoading || scheduleSaving" @click="addScheduleRow">
鏂板涓�琛�
</el-button>
</el-col>
</el-row>
-
<el-table :data="scheduleRows" border style="width: 100%" v-loading="scheduleLoading">
- <el-table-column type="index" label="搴忓彿" width="70" align="center" />
-
+ <el-table-column type="index" label="搴忓彿" width="70" align="center" :index="indexMethod" />
<el-table-column label="鏈涓婃満鏈哄彴" min-width="220">
<template #default="{ row }">
<el-select
@@ -349,7 +347,7 @@
filterable
clearable
style="width: 100%"
- :disabled="scheduleSaving"
+ :disabled="scheduleSaving || isScheduleHistoryMode"
@change="val => handleScheduleDeviceChange(val, row)"
>
<el-option
@@ -364,7 +362,18 @@
<el-table-column label="鏈涓婃満浜�" min-width="220">
<template #default="{ row }">
+ <div v-if="isScheduleHistoryMode" class="schedule-user-tags">
+ <el-tag
+ v-for="(userId, index) in row.userIds"
+ :key="`${userId}-${index}`"
+ type="primary"
+ >
+ {{ resolveScheduleUserName(userId) }}
+ </el-tag>
+ <span v-if="!row.userIds?.length">-</span>
+ </div>
<el-select
+ v-else
v-model="row.userIds"
placeholder="璇烽�夋嫨涓婃満浜�"
filterable
@@ -394,12 +403,12 @@
format="YYYY-MM-DD HH:mm:ss"
placeholder="璇烽�夋嫨涓婃満鏃堕棿"
style="width: 100%"
- :disabled="scheduleSaving"
+ :disabled="scheduleSaving || isScheduleHistoryMode"
/>
</template>
</el-table-column>
- <el-table-column label="鎿嶄綔" width="110" align="center">
+ <el-table-column v-if="!isScheduleHistoryMode" label="鎿嶄綔" width="110" align="center">
<template #default="{ row }">
<el-button
link
@@ -415,7 +424,7 @@
</el-table>
<Pagination
- v-show="schedulePage.total > 0"
+ v-show="isScheduleHistoryMode && schedulePage.total > 0"
style="margin-top: 12px"
:total="schedulePage.total"
:page="schedulePage.current"
@@ -426,8 +435,13 @@
<template #footer>
<span class="dialog-footer">
- <el-button type="primary" :loading="scheduleSaving" @click="handleSaveSchedule">淇濆瓨鎺掍骇</el-button>
- <el-button :disabled="scheduleSaving" @click="scheduleDialogVisible = false">鍙栨秷</el-button>
+ <template v-if="isScheduleHistoryMode">
+ <el-button @click="scheduleDialogVisible = false">鍏抽棴</el-button>
+ </template>
+ <template v-else>
+ <el-button type="primary" :loading="scheduleSaving" @click="handleSaveSchedule">淇濆瓨鎺掍骇</el-button>
+ <el-button :disabled="scheduleSaving" @click="scheduleDialogVisible = false">鍙栨秷</el-button>
+ </template>
</span>
</template>
</el-dialog>
@@ -441,6 +455,7 @@
import {ElMessageBox, ElMessage} from "element-plus";
import Pagination from "@/components/PIMTable/Pagination.vue";
import dayjs from "dayjs";
+import { processList } from '@/api/productionManagement/productionProcess.js'
import {
productWorkOrderPage,
updateProductWorkOrder,
@@ -624,17 +639,12 @@
return;
}
- const first = scheduleRows.value[0] || {};
- const deviceId = first.deviceId || currentReportRowData.value?.deviceId || "";
- const userOptions = deviceId ? buildScheduleUserOptionsByDeviceId(deviceId) : [...baseScheduleUsers.value];
- const defaultUserId = userOptions[0]?.userId ? String(userOptions[0].userId) : "";
-
scheduleRows.value.push(
createScheduleRow({
id: "",
- deviceId,
- deviceName: first.deviceName || currentReportRowData.value?.deviceName || "",
- userIds: defaultUserId ? [defaultUserId] : [],
+ deviceId:"",
+ deviceName:"",
+ userIds: [],
startTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
})
);
@@ -646,7 +656,7 @@
if (!workOrderRow?.id) {
schedulePage.current = 1;
schedulePage.total = 0;
- scheduleRows.value = [createScheduleRow({})];
+ scheduleRows.value = [];
return;
}
@@ -672,13 +682,12 @@
return;
}
- const rows = buildScheduleRowsFromRecords(records);
-
- scheduleRows.value = rows.length > 0 ? rows : [createScheduleRow({})];
+ const rows = records.map(record => mapMachineRecordToScheduleRow(record));
+ scheduleRows.value = rows;
} catch (error) {
console.error("鑾峰彇鎺掍骇璁板綍澶辫触", error);
schedulePage.total = 0;
- scheduleRows.value = [createScheduleRow({})];
+ scheduleRows.value = [];
ElMessage.error("鑾峰彇鎺掍骇璁板綍澶辫触");
} finally {
scheduleLoading.value = false;
@@ -686,12 +695,12 @@
};
const removeScheduleRow = async (row) => {
- if (!row) return;
+ if (!row || isScheduleHistoryMode.value) return;
if (!row.id) {
scheduleRows.value = scheduleRows.value.filter((item) => item !== row);
if (!scheduleRows.value.length) {
- scheduleRows.value = [createScheduleRow({})];
+ addScheduleRow();
}
return;
}
@@ -742,6 +751,7 @@
};
const handleSchedulePagination = ({page, limit}) => {
+ if (!isScheduleHistoryMode.value) return;
schedulePage.current = page;
schedulePage.size = limit;
refreshScheduleRows();
@@ -816,6 +826,16 @@
return payload;
};
+const indexMethod = (index) => {
+ return (schedulePage.current - 1) * schedulePage.size + index + 1;
+};
+
+const scheduleDialogMode = ref("create");
+const isScheduleHistoryMode = computed(() => scheduleDialogMode.value === "history");
+const scheduleDialogTitle = computed(() =>
+ `${isScheduleHistoryMode.value ? "鎺掍骇璁板綍" : "鐢熶骇鎺掍骇"}(宸ュ崟缂栧彿:${currentReportRowData.value?.workOrderNo || "-"})`
+);
+
const mapMachineRecordToScheduleRow = (record) => {
const id = record?.id ?? "";
const deviceId = record?.machineId ?? record?.deviceId ?? "";
@@ -861,11 +881,29 @@
);
};
+const resetCreateScheduleRows = () => {
+ schedulePage.current = 1;
+ schedulePage.total = 0;
+ scheduleRows.value = [];
+ addScheduleRow();
+};
+
const openScheduleDialog = async (row) => {
+ scheduleDialogMode.value = "create";
+ currentReportRowData.value = row;
+ baseScheduleUsers.value = buildBaseScheduleUsersByRow(row);
+ userTemp.value = [...baseScheduleUsers.value];
+ scheduleDialogVisible.value = true;
+ resetCreateScheduleRows();
+};
+
+const openHistoryTimelineDialog = async (row) => {
+ scheduleDialogMode.value = "history";
currentReportRowData.value = row;
baseScheduleUsers.value = buildBaseScheduleUsersByRow(row);
userTemp.value = [...baseScheduleUsers.value];
schedulePage.current = 1;
+ schedulePage.total = 0;
scheduleRows.value = [];
scheduleDialogVisible.value = true;
@@ -873,6 +911,7 @@
};
const handleSaveSchedule = async () => {
+ if (isScheduleHistoryMode.value) return;
if (scheduleSaving.value) return;
if (!validateScheduleRows()) return;
@@ -897,7 +936,7 @@
}
proxy.$modal.msgSuccess("鎺掍骇宸蹭繚瀛�");
- await refreshScheduleRows();
+ resetCreateScheduleRows();
getList();
} catch (error) {
console.error("淇濆瓨鎺掍骇澶辫触", error);
@@ -979,7 +1018,7 @@
},
{
label: "鎿嶄綔",
- width: "200",
+ width: "220",
align: "center",
dataType: "action",
fixed: "right",
@@ -1008,15 +1047,31 @@
showReportDialog(row);
},
// 鐢ㄦ埛褰撳墠id
- disabled: row => row.completeQuantity === row.planQuantity ||
+ disabled: row => row.completeQuantity >= row.planQuantity ||
!isCurrentUserInUserIds(row)
},
{
name: "鐢熶骇鎺掍骇",
clickFun: row => {
+ if (!row.canSchedule) {
+ ElMessage.warning("褰撳墠鐢ㄦ埛涓嶅湪璇ュ伐搴忎汉鍛樹腑锛屼笉鑳界敓浜ф帓浜�");
+ return;
+ }
openScheduleDialog(row);
},
+ disabled: row => !row.canSchedule || row.completeQuantity >= row.planQuantity
},
+ {
+ name: "鎺掍骇璁板綍",
+ clickFun: row => {
+ if (!row.canSchedule) {
+ ElMessage.warning("褰撳墠鐢ㄦ埛涓嶅湪璇ュ伐搴忎汉鍛樹腑锛屼笉鑳芥煡鐪嬫帓浜ц褰�");
+ return;
+ }
+ openHistoryTimelineDialog(row);
+ },
+ disabled: row => !row.canSchedule
+ }
// {
// name:"瀹℃牳",
// color: "#f56c6c",
@@ -1177,6 +1232,12 @@
if (isNaN(num)) {
return;
}
+ // 濡傛灉瓒呰繃寰呯敓浜ф暟閲�
+ if (num > reportForm.planQuantity) {
+ proxy.$modal.msgWarning("鏈鐢熶骇鏁伴噺涓嶈兘澶т簬寰呯敓浜ф暟閲�");
+ reportForm.quantity = reportForm.planQuantity;
+ return;
+ }
// 濡傛灉灏忎簬1锛屾竻闄�
if (num < 1) {
reportForm.quantity = null;
@@ -1260,18 +1321,27 @@
page.size = obj.limit;
getList();
};
-const getList = () => {
+const getList = async () => {
tableLoading.value = true;
- const params = {...searchForm.value, ...page};
- productWorkOrderPage(params)
- .then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records;
- page.total = res.data.total;
- })
- .catch(() => {
- tableLoading.value = false;
- });
+
+ try {
+ await ensureCurrentUser();
+ await processLists();
+
+ const params = { ...searchForm.value, ...page };
+ const res = await productWorkOrderPage(params);
+
+ const records = Array.isArray(res?.data?.records) ? res.data.records : [];
+
+ tableData.value = records.map(row => ({
+ ...row,
+ canSchedule: canScheduleByWorkOrderNo(row)
+ }));
+
+ page.total = res?.data?.total || 0;
+ } finally {
+ tableLoading.value = false;
+ }
};
// 涓嬭浇骞舵墦鍗板伐鍗曟祦杞崱锛堟枃浠舵祦锛�
@@ -1362,13 +1432,15 @@
};
const showReportDialog = row => {
+
currentReportRowData.value = row;
reportForm.planQuantity = row.planQuantity - row.completeQuantity;
- reportForm.quantity = row.quantity !== undefined && row.quantity !== null ? row.quantity : null;
+ reportForm.quantity = row.planQuantity !== undefined && row.planQuantity !== null ? row.planQuantity : null;
reportForm.productProcessRouteItemId = row.productProcessRouteItemId;
reportForm.workOrderId = row.id;
reportForm.reportWork = row.reportWork;
reportForm.productMainId = row.productMainId;
+ reportForm.planQuantity = row.planQuantity;
reportForm.startTime = "";
reportForm.endTime = "";
reportForm.replenishQty = 0;
@@ -1520,9 +1592,44 @@
}
}
-onMounted(() => {
- ensureCurrentUser();
- getList();
+const processData = ref([]);
+
+// 鏌ヨ鎵�鏈夊伐搴�
+const processLists = async () => {
+ console.log(processData.value)
+ if (processData.value.length > 0) {
+ return processData.value;
+ }
+ const res = await processList();
+
+ processData.value = Array.isArray(res?.data) ? res.data : [];
+ return processData.value;
+};
+
+// 鍒ゆ柇褰撳墠鐢ㄦ埛鏄惁鑳芥帓浜�
+const canScheduleByWorkOrderNo = (row) => {
+ if (!row) return false;
+
+ const uid = String(currentUserId.value || "");
+ if (!uid) return false;
+
+ const currentProcess = processData.value.find(item =>
+ String(item.id) === String(row.processId)
+ );
+
+ if (!currentProcess) return false;
+
+ const ids = normalizeArray(currentProcess.userIds)
+ .map(id => String(id).trim())
+ .filter(Boolean);
+
+ return ids.includes(uid);
+};
+
+onMounted(async () => {
+ await ensureCurrentUser();
+ await processLists();
+ await getList();
getUserList();
getDeviceList();
});
@@ -1590,6 +1697,14 @@
justify-content: flex-start;
}
}
+
+.schedule-user-tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ min-height: 32px;
+ align-items: center;
+}
</style>
<style lang="scss">
--
Gitblit v1.9.3