From e0699ce1a404b1d819d7ef0b40cfd2631bb964d1 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期四, 12 三月 2026 17:56:06 +0800
Subject: [PATCH] 问题修改
---
src/views/productionPlan/productionPlan/index.vue | 1231 ++++++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 900 insertions(+), 331 deletions(-)
diff --git a/src/views/productionPlan/productionPlan/index.vue b/src/views/productionPlan/productionPlan/index.vue
index 7c475ce..e70fa22 100644
--- a/src/views/productionPlan/productionPlan/index.vue
+++ b/src/views/productionPlan/productionPlan/index.vue
@@ -3,46 +3,69 @@
<div class="search_form">
<el-form :model="searchForm"
:inline="true">
- <el-form-item label="杞﹂棿:">
- <el-select v-model="searchForm.workshop"
- placeholder="璇烽�夋嫨"
- clearable
- style="width: 160px;"
- @change="handleQuery">
- <el-option label="杞﹂棿1"
- value="1" />
- <el-option label="杞﹂棿2"
- value="2" />
- <el-option label="杞﹂棿3"
- value="3" />
- </el-select>
+ <el-form-item label="瀹㈡埛鍚嶇О:">
+ <el-input v-model="searchForm.customerName"
+ placeholder="璇疯緭鍏�"
+ clearable
+ style="width: 160px;"
+ @keyup.enter="handleQuery" />
</el-form-item>
- <el-form-item label="鐘舵��:">
- <el-select v-model="searchForm.status"
- placeholder="璇烽�夋嫨"
- clearable
- style="width: 160px;"
- @change="handleQuery">
- <el-option label="寰呭鐞�"
- value="pending" />
- <el-option label="杩涜涓�"
- value="processing" />
- <el-option label="宸插畬鎴�"
- value="completed" />
- </el-select>
+ <el-form-item label="浜у搧鍚嶇О:">
+ <el-input v-model="searchForm.productName"
+ placeholder="璇疯緭鍏�"
+ clearable
+ style="width: 160px;"
+ @keyup.enter="handleQuery" />
+ </el-form-item>
+ <el-form-item label="浜у搧瑙勬牸:">
+ <el-input v-model="searchForm.specification"
+ placeholder="璇疯緭鍏�"
+ clearable
+ style="width: 160px;"
+ @keyup.enter="handleQuery" />
+ </el-form-item>
+ <el-form-item label="鐗╂枡缂栫爜:">
+ <el-input v-model="searchForm.materialCode"
+ placeholder="璇疯緭鍏�"
+ clearable
+ style="width: 160px;"
+ @keyup.enter="handleQuery" />
+ </el-form-item>
+ <el-form-item label="鐢宠鍗曠紪鍙�:">
+ <el-input v-model="searchForm.applyNo"
+ placeholder="璇疯緭鍏�"
+ clearable
+ style="width: 160px;"
+ @keyup.enter="handleQuery" />
+ </el-form-item>
+ <el-form-item label="璁″垝鏃ユ湡鑼冨洿:">
+ <el-date-picker v-model="searchForm.dateRange"
+ type="daterange"
+ range-separator="鑷�"
+ start-placeholder="寮�濮嬫棩鏈�"
+ end-placeholder="缁撴潫鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ style="width: 240px;"
+ @change="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary"
@click="handleQuery">鎼滅储</el-button>
+ <el-button type="info"
+ @click="handleReset">閲嶇疆</el-button>
+ <el-button type="primary"
+ @click="handleAdd">鏂板</el-button>
+ <el-button type="warning"
+ @click="getLoadProdData">鎷夊彇鏁版嵁</el-button>
+ <el-button type="warning"
+ @click="handleMerge">鍚堝苟涓嬪彂</el-button>
+ <el-button type="warning"
+ @click="handleImport">瀵煎叆</el-button>
+ <el-button type="warning"
+ @click="handleExport">瀵煎嚭</el-button>
</el-form-item>
</el-form>
<div>
- <el-button type="primary"
- @click="handleMerge">鍜屽苟涓嬪彂</el-button>
- <el-button type="info"
- @click="showCategorySummaryDialog = true">浜у搧绫诲埆姹囨��</el-button>
- <!-- <el-button type="danger"
- @click="handleDelete">鍒犻櫎</el-button> -->
</div>
</div>
<div class="table_list">
@@ -61,23 +84,50 @@
<!-- 鍚堝苟涓嬪彂寮圭獥 -->
<el-dialog v-model="isShowNewModal"
title="鍚堝苟涓嬪彂"
- width="500px">
+ width="600px">
<el-form :model="mergeForm"
label-width="120px">
- <el-form-item label="搴忓垪鍙�">
- <el-input v-model="mergeForm.serialNo"
- disabled />
+ <el-row :gutter="20">
+ <el-col :span="10">
+ <el-form-item label="鐗╂枡缂栫爜">
+ <div class="info-display">{{ mergeForm.materialCode || '-' }}</div>
+ </el-form-item>
+ </el-col>
+ <el-col :span="10">
+ <el-form-item label="浜у搧鍚嶇О">
+ <el-tag class="info-display">{{ mergeForm.productName || '-' }}</el-tag>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="10">
+ <el-form-item label="浜у搧瑙勬牸">
+ <div class="info-display">{{ mergeForm.specification || '-' }}</div>
+ </el-form-item>
+ </el-col>
+ <el-col :span="10">
+ <el-form-item label="闀�*瀹�*楂�">
+ <div class="info-display">{{ mergeForm.length || '-' }}*{{ mergeForm.width || '-' }}*{{ mergeForm.height || '-' }}</div>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="璁″垝瀹屾垚鏃堕棿">
+ <el-date-picker v-model="mergeForm.planCompleteTime"
+ type="date"
+ value-format="YYYY-MM-DD"
+ style="width: 100%" />
</el-form-item>
- <el-form-item label="鐢熶骇璁″垝鏁伴噺">
- <el-input-number v-model="mergeForm.totalquantity"
- :min="1"
- :step="1"
+ <el-form-item label="鐢熶骇鏂规暟">
+ <el-input-number v-model="mergeForm.totalAssignedQuantity"
+ :min="0"
+ :max="sumAssignedQuantity"
+ @change="onBlur"
style="width: 100%" />
</el-form-item>
- <el-form-item label="澶囨敞">
+ <!-- <el-form-item label="澶囨敞">
<el-input v-model="mergeForm.remark"
type="textarea" />
- </el-form-item>
+ </el-form-item> -->
</el-form>
<template #footer>
<span class="dialog-footer">
@@ -87,35 +137,14 @@
</span>
</template>
</el-dialog>
- <!-- 浜у搧绫诲埆姹囨�诲脊绐� -->
- <el-dialog v-model="showCategorySummaryDialog"
- title="浜у搧绫诲埆姹囨�荤粺璁�"
- width="400px">
- <el-table :data="categorySummary"
- border
- style="width: 100%">
- <el-table-column prop="materialCategory"
- label="浜у搧绫诲埆"
- align="center"
- width="150" />
- <el-table-column prop="totalquantity"
- label="鎬诲埗閫犳暟閲�"
- align="center" />
- </el-table>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="showCategorySummaryDialog = false">鍏抽棴</el-button>
- </span>
- </template>
- </el-dialog>
<!-- 杩借釜杩涘害寮圭獥 -->
<el-dialog v-model="showTrackProgressDialog"
- :title="`杩借釜杩涘害 - ${trackProgressForm.serialNo || ''}`"
+ :title="`杩借釜杩涘害 - ${trackProgressForm.materialCode || ''}`"
width="600px">
<el-form :model="trackProgressForm"
label-width="120px">
- <el-form-item label="搴忓垪鍙�">
- <el-input v-model="trackProgressForm.serialNo"
+ <el-form-item label="鐗╂枡缂栫爜">
+ <el-input v-model="trackProgressForm.materialCode"
disabled />
</el-form-item>
<el-form-item label="褰撳墠鐘舵��">
@@ -174,140 +203,304 @@
</span>
</template>
</el-dialog>
+ <!-- 瀵煎叆寮圭獥 -->
+ <ImportDialog ref="importDialogRef"
+ v-model="importDialogVisible"
+ title="瀵煎叆鐢熶骇璁″垝"
+ :action="importAction"
+ :headers="importHeaders"
+ :auto-upload="false"
+ :on-success="handleImportSuccess"
+ :on-error="handleImportError"
+ @confirm="handleImportConfirm"
+ @download-template="handleDownloadTemplate"
+ @close="handleImportClose" />
+ <!-- 鏂板/缂栬緫寮圭獥 -->
+ <el-dialog v-model="dialogVisible"
+ :title="operationType === 'add' ? '鏂板鐢熶骇璁″垝' : '缂栬緫鐢熶骇璁″垝'"
+ width="600px">
+ <el-form ref="formRef"
+ :model="form"
+ :rules="rules"
+ label-width="120px">
+ <el-form-item label="鐢宠鍗曠紪鍙�"
+ prop="applyNo">
+ <el-input v-model="form.applyNo"
+ placeholder="璇疯緭鍏ョ敵璇峰崟缂栧彿" />
+ </el-form-item>
+ <el-form-item label="瀹㈡埛鍚嶇О"
+ prop="customerName">
+ <el-input v-model="form.customerName"
+ placeholder="璇疯緭鍏ュ鎴峰悕绉�" />
+ </el-form-item>
+ <el-form-item label="浜у搧鍚嶇О"
+ prop="productMaterialId">
+ <el-tree-select v-model="form.productMaterialId"
+ placeholder="璇烽�夋嫨"
+ clearable
+ :data="productOptions"
+ :render-after-expand="false"
+ filterable
+ @change="handleProductChange"
+ style="width: 100%" />
+ </el-form-item>
+ <el-form-item label="浜у搧瑙勬牸"
+ prop="productMaterialSkuId">
+ <el-select v-model="form.productMaterialSkuId"
+ @change="handleChangeSpecification"
+ placeholder="璇烽�夋嫨">
+ <el-option v-for="item in specificationOptions"
+ :key="item.skuId"
+ :label="item.specification"
+ :value="item.skuId" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鍧楁暟"
+ prop="quantity">
+ <el-input-number v-model="form.quantity"
+ :min="0"
+ placeholder="璇疯緭鍏ュ潡鏁�" />
+ </el-form-item>
+ <el-form-item label="鏂规暟"
+ prop="volume">
+ <el-input-number v-model="form.volume"
+ :min="0"
+ placeholder="璇疯緭鍏ユ柟鏁�" />
+ </el-form-item>
+ <el-form-item label="闀�"
+ prop="length">
+ <el-input-number v-model="form.length"
+ :min="0"
+ placeholder="璇疯緭鍏ラ暱搴�" />
+ </el-form-item>
+ <el-form-item label="瀹�"
+ prop="width">
+ <el-input-number v-model="form.width"
+ :min="0"
+ placeholder="璇疯緭鍏ュ搴�" />
+ </el-form-item>
+ <el-form-item label="楂�"
+ prop="height">
+ <el-input-number v-model="form.height"
+ :min="0"
+ placeholder="璇疯緭鍏ラ珮搴�" />
+ </el-form-item>
+ <el-form-item label="璁″垝寮�濮嬫棩鏈�"
+ prop="startDate">
+ <el-date-picker v-model="form.startDate"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="璇烽�夋嫨璁″垝寮�濮嬫棩鏈�" />
+ </el-form-item>
+ <el-form-item label="璁″垝缁撴潫鏃ユ湡"
+ prop="endDate">
+ <el-date-picker v-model="form.endDate"
+ type="date"
+ value-format="YYYY-MM-DD"
+ placeholder="璇烽�夋嫨璁″垝缁撴潫鏃ユ湡" />
+ </el-form-item>
+ <el-form-item label="寮哄害"
+ prop="strength">
+ <el-input v-model="form.strength"
+ placeholder="璇疯緭鍏ュ己搴�" />
+ </el-form-item>
+ <el-form-item label="澶囨敞 1"
+ prop="remarkOne">
+ <el-input v-model="form.remarkOne"
+ placeholder="璇疯緭鍏ュ娉� 1" />
+ </el-form-item>
+ <el-form-item label="澶囨敞 2"
+ prop="remarkTwo">
+ <el-input v-model="form.remarkTwo"
+ placeholder="璇疯緭鍏ュ娉� 2" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary"
+ @click="handleSubmit">纭畾</el-button>
+ </span>
+ </template>
+ </el-dialog>
</div>
</template>
<script setup>
- import { onMounted, ref } from "vue";
+ import { onMounted, ref, reactive, getCurrentInstance } from "vue";
import { ElMessage } from "element-plus";
import dayjs from "dayjs";
- import { productionPlanListPage } from "@/api/productionPlan/productionPlan.js";
+ import ImportDialog from "@/components/Dialog/ImportDialog.vue";
+ import { getToken } from "@/utils/auth";
+ import {
+ productionPlanListPage,
+ loadProdData,
+ exportProductionPlan,
+ productionPlanAdd,
+ productionPlanUpdate,
+ productionPlanDelete,
+ productionPlanCombine,
+ } from "@/api/productionPlan/productionPlan.js";
import PIMTable from "./components/PIMTable.vue";
+ import { modelListPage, productTreeList } from "@/api/basicData/newProduct.js";
+
+ const { proxy } = getCurrentInstance();
const tableColumn = ref([
{
- label: "鏉ユ簮",
- prop: "source",
- width: "100px",
+ label: "鐢宠鍗曠紪鍙�",
+ prop: "applyNo",
+ width: "150px",
+ className: "code-cell",
},
{
- label: "鐘舵��",
- prop: "status",
- width: "80px",
- },
- {
- label: "瀹℃牳鐘舵��",
- prop: "auditStatus",
- width: "100px",
- },
- {
- label: "璁㈠崟鍙�",
- prop: "orderNo",
- width: "120px",
- },
- {
- label: "搴忓垪鍙�",
- prop: "serialNo",
- width: "140px",
- },
- {
- label: "闆朵欢鍙�",
- prop: "partNo",
- width: "120px",
- },
- {
- label: "闆朵欢",
- prop: "partName",
- width: "120px",
- },
- {
- label: "浜у搧绫诲埆",
- prop: "materialCategory",
- width: "100px",
- },
- {
- label: "宸ヨ壓鏂囦欢鍙�",
- prop: "processFileNo",
- width: "140px",
- },
- {
- label: "閿�鍞暟閲�",
- prop: "salesQuantity",
- width: "100px",
- align: "right",
- },
- {
- label: "鍒堕�犳暟閲�",
- prop: "quantity",
- width: "100px",
- align: "right",
- },
- {
- label: "闆朵欢鍗曚綅",
- prop: "partUnit",
- width: "80px",
- },
- {
- label: "涓昏鍒掗渶姹傛棩鏈�",
- prop: "mainPlanDemandDate",
- formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
- width: "140px",
- },
- {
- label: "鎵胯鏃ユ湡",
- prop: "commitmentDate",
- formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
- width: "120px",
- },
- {
- label: "鍒堕�犲睘鎬�",
- prop: "manufactureProperty",
- width: "100px",
- },
- {
- label: "澶囨敞",
- prop: "remark",
+ label: "瀹㈡埛鍚嶇О",
+ prop: "customerName",
width: "150px",
},
{
- label: "鏇存柊鏃堕棿",
- prop: "updateTime",
- formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
- width: "120px",
- },
- {
- label: "鏇存柊浜�",
- prop: "updateBy",
+ label: "浜у搧鍚嶇О",
+ prop: "productName",
width: "100px",
+ dataType: "tag",
+ formatType: params => {
+ const typeMap = {
+ 鏉挎潗: "primary",
+ 鐮屽潡: "info",
+ };
+ return typeMap[params] || "info";
+ },
},
{
- label: "鍒涘缓鏃堕棿",
- prop: "createTime",
- formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
- width: "120px",
+ label: "浜у搧瑙勬牸",
+ prop: "specification",
+ width: "150px",
+ className: "spec-cell",
},
{
- label: "鍒涘缓浜�",
- prop: "createBy",
- width: "100px",
+ label: "鐗╂枡缂栫爜",
+ prop: "materialCode",
+ width: "150px",
+ className: "code-cell",
},
+ {
+ label: "鍧楁暟",
+ prop: "quantity",
+ className: "quantity-cell",
+ },
+ {
+ label: "鏂规暟",
+ prop: "volume",
+ width: "150px",
+ className: "volume-cell",
+ },
+ {
+ label: "宸蹭笅鍙戞柟鏁�",
+ prop: "assignedQuantity",
+ width: "150px",
+ className: "spec-cell",
+ },
+ {
+ label: "闀�",
+ prop: "length",
+ className: "dimension-cell",
+ },
+ {
+ label: "瀹�",
+ prop: "width",
+ className: "dimension-cell",
+ },
+ {
+ label: "楂�",
+ prop: "height",
+ className: "dimension-cell",
+ },
+ {
+ label: "娴佹按鍙�",
+ prop: "serialNo",
+ width: "150px",
+ className: "code-cell",
+ },
+ {
+ label: "璁″垝寮�濮嬫棩鏈�",
+ prop: "startDate",
+ width: "150px",
+ className: "date-cell",
+ formatData: cell => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""),
+ },
+ {
+ label: "璁″垝缁撴潫鏃ユ湡",
+ prop: "endDate",
+ width: "150px",
+ className: "date-cell",
+ formatData: cell => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""),
+ },
+ {
+ label: "寮哄害",
+ prop: "strength",
+ },
+ // {
+ // label: "鏁版嵁鏉ユ簮",
+ // width: "100px",
+ // prop: "dataSourceType",
+ // formatData: cell => (cell == 1 ? "鍚屾" : "鎵嬪姩"),
+ // },
+ {
+ label: "澶囨敞 1",
+ prop: "remarkOne",
+ },
+ {
+ label: "澶囨敞 2",
+ prop: "remarkTwo",
+ },
+
{
dataType: "action",
label: "鎿嶄綔",
align: "center",
fixed: "right",
- width: 200,
+ width: 300,
operation: [
+ {
+ name: "缂栬緫",
+ type: "primary",
+ link: true,
+ clickFun: row => {
+ handleEdit(row);
+ },
+ },
+ {
+ name: "鍒犻櫎",
+ type: "danger",
+ link: true,
+ clickFun: row => {
+ handleDelete(row);
+ },
+ },
{
name: "涓嬪彂",
type: "text",
+ disabled: row => {
+ // 璁$畻鍓╀綑鏂规暟
+ const remainingVolume =
+ (row.volume || 0) - (row.assignedQuantity || 0);
+ // 濡傛灉鍓╀綑鏂规暟灏忎簬绛変簬0锛岀姝㈤�夋嫨
+ return remainingVolume <= 0;
+ },
clickFun: row => {
// 鍗曠嫭涓嬪彂鎿嶄綔
// 璁剧疆琛ㄥ崟鏁版嵁
- mergeForm.serialNo = row.serialNo;
- mergeForm.totalquantity = row.quantity;
- mergeForm.remark = "";
-
+ mergeForm.ids = [row.id];
+ mergeForm.materialCode = row.materialCode;
+ mergeForm.productName = row.productName || "";
+ mergeForm.specification = row.specification || "";
+ mergeForm.length = row.length || 0;
+ mergeForm.width = row.width || 0;
+ mergeForm.height = row.height || 0;
+ mergeForm.totalAssignedQuantity =
+ (Number(row.volume) - Number(row.assignedQuantity)).toFixed(4) || 0;
+ mergeForm.planCompleteTime = row.planCompleteTime || "";
+ sumAssignedQuantity.value = mergeForm.totalAssignedQuantity;
// 鎵撳紑寮圭獥
isShowNewModal.value = true;
},
@@ -340,26 +533,79 @@
const isShowNewModal = ref(false);
// 鍚堝苟涓嬪彂琛ㄥ崟鏁版嵁
const mergeForm = reactive({
- serialNo: "",
- totalquantity: 0,
- remark: "",
+ materialCode: "",
+ productName: "",
+ specification: "",
+ length: 0,
+ width: 0,
+ height: 0,
+ totalAssignedQuantity: 0,
+ planCompleteTime: "",
});
// 杩借釜杩涘害寮圭獥鎺у埗
const showTrackProgressDialog = ref(false);
// 杩借釜杩涘害琛ㄥ崟鏁版嵁
const trackProgressForm = reactive({
- serialNo: "",
+ materialCode: "",
currentStatus: "",
completionRate: 0,
progressDetails: [],
remark: "",
});
+ // 瀵煎叆鐩稿叧
+ const importDialogRef = ref(null);
+ const importDialogVisible = ref(false);
+ const importAction =
+ import.meta.env.VITE_APP_BASE_API + "/productionPlan/import";
+ const importHeaders = ref({
+ Authorization: `Bearer ${getToken()}`,
+ });
+
+ // 鏂板/缂栬緫鐩稿叧
+ const dialogVisible = ref(false);
+ const operationType = ref("add"); // add | edit
+ const productOptions = ref([]);
+ const specificationOptions = ref([]);
+ const formRef = ref(null);
+ const form = reactive({
+ id: undefined,
+ applyNo: "",
+ customerName: "",
+ productMaterialId: undefined,
+ productMaterialSkuId: undefined,
+ productName: "",
+ specification: "",
+ materialCode: "",
+ quantity: 0,
+ volume: 0,
+ length: 0,
+ width: 0,
+ height: 0,
+ startDate: "",
+ endDate: "",
+ strength: "",
+ remarkOne: "",
+ remarkTwo: "",
+ });
+ const rules = reactive({
+ applyNo: [{ required: true, message: "璇疯緭鍏ョ敵璇峰崟缂栧彿", trigger: "blur" }],
+ customerName: [
+ { required: true, message: "璇疯緭鍏ュ鎴峰悕绉�", trigger: "blur" },
+ ],
+ productMaterialSkuId: [
+ { required: true, message: "璇烽�夋嫨浜у搧瑙勬牸", trigger: "change" },
+ ],
+ productMaterialId: [
+ { required: true, message: "璇烽�夋嫨浜у搧", trigger: "change" },
+ ],
+ });
+
// 澶勭悊杩借釜杩涘害鎸夐挳鐐瑰嚮
const handleTrackProgress = row => {
// 璁剧疆琛ㄥ崟鏁版嵁
- trackProgressForm.serialNo = row.serialNo;
+ trackProgressForm.materialCode = row.materialCode;
trackProgressForm.currentStatus = row.status;
// 鐢熸垚妯℃嫙杩涘害鏁版嵁
@@ -373,6 +619,59 @@
// 鎵撳紑寮圭獥
showTrackProgressDialog.value = true;
+ };
+ const onBlur = value => {
+ // 闄愬埗鍥涗綅灏忔暟
+ mergeForm.totalAssignedQuantity = Number(value.toFixed(4));
+ };
+
+ const fetchProductOptions = () => {
+ return productTreeList().then(res => {
+ productOptions.value = convertIdToValue(res.data);
+ return res;
+ });
+ };
+
+ const convertIdToValue = data => {
+ return data.map(item => {
+ const newItem = {
+ value: `config_${item.configId}`, // 浣跨敤config_鍓嶇紑纭繚鍞竴鎬�
+ label: item.configName,
+ disabled: item.materialList.length === 0,
+ };
+ if (item.materialList && item.materialList.length > 0) {
+ newItem.children = item.materialList.map(material => ({
+ value: material.id, // 浣跨敤material鐨刬d浣滀负value
+ label: material.materialName, // 浣跨敤materialName浣滀负label
+ }));
+ }
+
+ return newItem;
+ });
+ };
+
+ const handleProductChange = value => {
+ form.productMaterialSkuId = undefined;
+ fetchSpecificationOptions(value);
+ };
+
+ const fetchSpecificationOptions = materialId => {
+ specificationOptions.value = [];
+ if (materialId) {
+ modelListPage({ materialId: materialId }).then(res => {
+ specificationOptions.value = res.data;
+ });
+ }
+ };
+
+ const handleChangeSpecification = value => {
+ form.materialCode = undefined;
+ const selectedModel = specificationOptions.value.find(
+ item => item.id === value
+ );
+ if (selectedModel) {
+ form.materialCode = selectedModel.materialCode;
+ }
};
// 鐢熸垚妯℃嫙杩涘害璇︽儏鏁版嵁
@@ -449,10 +748,11 @@
const data = reactive({
searchForm: {
customerName: "",
- salesContractNo: "",
- projectName: "",
- materialCategory: "",
- specificationModel: "",
+ productName: "",
+ specification: "",
+ materialCode: "",
+ applyNo: "",
+ dateRange: [],
},
});
const { searchForm } = toRefs(data);
@@ -460,6 +760,20 @@
// 鏌ヨ鍒楄〃
/** 鎼滅储鎸夐挳鎿嶄綔 */
const handleQuery = () => {
+ page.current = 1;
+ getList();
+ };
+
+ /** 閲嶇疆鎸夐挳鎿嶄綔 */
+ const handleReset = () => {
+ Object.assign(searchForm.value, {
+ customerName: "",
+ productName: "",
+ specification: "",
+ materialCode: "",
+ applyNo: "",
+ dateRange: [],
+ });
page.current = 1;
getList();
};
@@ -474,14 +788,16 @@
// 閬嶅巻琛ㄦ牸鏁版嵁锛屾寜浜у搧绫诲埆姹囨��
tableData.value.forEach(row => {
- const category = row.materialCategory;
+ const category = row.materialCode;
if (!summary[category]) {
summary[category] = {
- materialCategory: category,
- totalquantity: 0,
+ materialCode: category,
+ totalAssignedQuantity: 0,
};
}
- summary[category].totalquantity += row.quantity;
+ summary[category].totalAssignedQuantity += (
+ Number(row.volume) - Number(row.assignedQuantity)
+ ).toFixed(4);
});
// 杞崲涓烘暟缁勬牸寮�
@@ -490,130 +806,11 @@
const getList = () => {
tableLoading.value = true;
- // 鏋勯�犱竴涓柊鐨勫璞★紝涓嶅寘鍚玡ntryDate瀛楁
+ // 鏋勯�犳悳绱㈠弬鏁�
const params = { ...searchForm.value, ...page };
- params.entryDate = undefined;
- // tableData.value = [
- // {
- // id: 1,
- // source: "閿�鍞鍗�",
- // status: "寰呭鐞�",
- // auditStatus: "宸插鏍�",
- // orderNo: "SO20260301001",
- // serialNo: "PP20260301001",
- // partNo: "P001",
- // partName: "闆朵欢A",
- // materialCategory: "绫诲埆1",
- // processFileNo: "PF20260301001",
- // salesQuantity: 100,
- // quantity: 105,
- // partUnit: "涓�",
- // mainPlanDemandDate: "2026-03-15",
- // commitmentDate: "2026-03-10",
- // manufactureProperty: "甯歌",
- // remark: "",
- // updateTime: "2026-03-01",
- // updateBy: "admin",
- // createTime: "2026-03-01",
- // createBy: "admin",
- // },
- // {
- // id: 2,
- // source: "閿�鍞鍗�",
- // status: "寰呭鐞�",
- // auditStatus: "宸插鏍�",
- // orderNo: "SO20260301002",
- // serialNo: "PP20260301001",
- // partNo: "P002",
- // partName: "闆朵欢B",
- // materialCategory: "绫诲埆1",
- // processFileNo: "PF20260301002",
- // salesQuantity: 200,
- // quantity: 210,
- // partUnit: "涓�",
- // mainPlanDemandDate: "2026-03-15",
- // commitmentDate: "2026-03-10",
- // manufactureProperty: "甯歌",
- // remark: "",
- // updateTime: "2026-03-01",
- // updateBy: "admin",
- // createTime: "2026-03-01",
- // createBy: "admin",
- // },
- // {
- // id: 3,
- // source: "閿�鍞鍗�",
- // status: "杩涜涓�",
- // auditStatus: "宸插鏍�",
- // orderNo: "SO20260301003",
- // serialNo: "PP20260301002",
- // partNo: "P003",
- // partName: "闆朵欢C",
- // materialCategory: "绫诲埆2",
- // processFileNo: "PF20260301003",
- // salesQuantity: 150,
- // quantity: 155,
- // partUnit: "涓�",
- // mainPlanDemandDate: "2026-03-20",
- // commitmentDate: "2026-03-15",
- // manufactureProperty: "甯歌",
- // remark: "",
- // updateTime: "2026-03-01",
- // updateBy: "admin",
- // createTime: "2026-03-01",
- // createBy: "admin",
- // },
- // {
- // id: 4,
- // source: "閿�鍞鍗�",
- // status: "杩涜涓�",
- // auditStatus: "宸插鏍�",
- // orderNo: "SO20260301004",
- // serialNo: "PP20260301002",
- // partNo: "P004",
- // partName: "闆朵欢D",
- // materialCategory: "绫诲埆2",
- // processFileNo: "PF20260301004",
- // salesQuantity: 300,
- // quantity: 315,
- // partUnit: "涓�",
- // mainPlanDemandDate: "2026-03-20",
- // commitmentDate: "2026-03-15",
- // manufactureProperty: "甯歌",
- // remark: "",
- // updateTime: "2026-03-01",
- // updateBy: "admin",
- // createTime: "2026-03-01",
- // createBy: "admin",
- // },
- // {
- // id: 5,
- // source: "閿�鍞鍗�",
- // status: "宸插畬鎴�",
- // auditStatus: "宸插鏍�",
- // orderNo: "SO20260301005",
- // serialNo: "PP20260301003",
- // partNo: "P005",
- // partName: "闆朵欢E",
- // materialCategory: "绫诲埆3",
- // processFileNo: "PF20260301005",
- // salesQuantity: 250,
- // quantity: 260,
- // partUnit: "涓�",
- // mainPlanDemandDate: "2026-03-10",
- // commitmentDate: "2026-03-05",
- // manufactureProperty: "甯歌",
- // remark: "",
- // updateTime: "2026-03-01",
- // updateBy: "admin",
- // createTime: "2026-03-01",
- // createBy: "admin",
- // },
- // ];
- // tableLoading.value = false;
- // page.total = tableData.value.length;
- // // 璁$畻浜у搧绫诲埆姹囨�荤粺璁�
- // calculateCategorySummary();
+ params.startDate = params.dateRange ? params.dateRange[0] : "";
+ params.endDate = params.dateRange ? params.dateRange[1] : "";
+ delete params.dateRange;
productionPlanListPage(params)
.then(res => {
tableLoading.value = false;
@@ -636,7 +833,7 @@
selectedRows.value = selection;
// 濡傛灉鏈夐�変腑鐨勮锛岃褰曠涓�涓�変腑琛岀殑搴忓垪鍙�
if (selection.length > 0) {
- selectedserialNo.value = selection[0].serialNo;
+ selectedserialNo.value = selection[0].materialCode;
} else {
// 濡傛灉娌℃湁閫変腑鐨勮锛屾竻绌哄簭鍒楀彿
selectedserialNo.value = "";
@@ -645,30 +842,57 @@
// 鍒ゆ柇琛屾槸鍚﹀彲閫夋嫨
const isSelectable = row => {
+ // 璁$畻鍓╀綑鏂规暟
+ const remainingVolume = (row.volume || 0) - (row.assignedQuantity || 0);
+ // 濡傛灉鍓╀綑鏂规暟灏忎簬绛変簬0锛岀姝㈤�夋嫨
+ if (remainingVolume <= 0) {
+ return false;
+ }
// 濡傛灉娌℃湁閫変腑鐨勮锛屾墍鏈夎閮藉彲閫夋嫨
if (!selectedserialNo.value) {
return true;
}
// 濡傛灉鏈夐�変腑鐨勮锛屽彧鏈夊簭鍒楀彿鐩稿悓鐨勮鎵嶅彲閫夋嫨
- return row.serialNo === selectedserialNo.value;
+ return row.materialCode === selectedserialNo.value;
};
-
+ // 鎷夊彇鏁版嵁鎸夐挳鎿嶄綔
+ const getLoadProdData = () => {
+ loadProdData()
+ .then(res => {
+ getList();
+ })
+ .catch(() => {});
+ };
+ const sumAssignedQuantity = ref(0);
// 澶勭悊鍚堝苟涓嬪彂鎸夐挳鐐瑰嚮
const handleMerge = () => {
if (selectedRows.value.length === 0) {
ElMessage.warning("璇烽�夋嫨瑕佸悎骞朵笅鍙戠殑鐢熶骇璁″垝");
return;
}
-
+ console.log(selectedRows.value);
// 璁$畻鎬诲埗閫犳暟閲�
- const totalQuantity = selectedRows.value.reduce((sum, row) => {
- return sum + row.quantity;
+ const totalAssignedQuantity = selectedRows.value.reduce((sum, row) => {
+ return (
+ sum +
+ (row.volume == null
+ ? 0
+ : (Number(row.volume) - Number(row.assignedQuantity)).toFixed(4))
+ );
}, 0);
-
+ sumAssignedQuantity.value = totalAssignedQuantity;
+ console.log(totalAssignedQuantity);
// 璁剧疆琛ㄥ崟鏁版嵁
- mergeForm.serialNo = selectedserialNo.value;
- mergeForm.totalquantity = totalQuantity;
- mergeForm.remark = "";
+ const firstRow = selectedRows.value[0];
+ mergeForm.materialCode = selectedserialNo.value;
+ mergeForm.productName = firstRow.productName || "";
+ mergeForm.specification = firstRow.specification || "";
+ mergeForm.length = firstRow.length || 0;
+ mergeForm.width = firstRow.width || 0;
+ mergeForm.height = firstRow.height || 0;
+ mergeForm.totalAssignedQuantity = totalAssignedQuantity;
+ mergeForm.planCompleteTime = firstRow.planCompleteTime || "";
+ mergeForm.ids = selectedRows.value.map(row => row.id);
// 鎵撳紑寮圭獥
isShowNewModal.value = true;
@@ -676,10 +900,231 @@
// 澶勭悊鍚堝苟涓嬪彂鎻愪氦
const handleMergeSubmit = () => {
- // 杩欓噷鍙互娣诲姞涓嬪彂閫昏緫
- ElMessage.success("鍚堝苟涓嬪彂鎴愬姛");
- isShowNewModal.value = false;
+ if (mergeForm.totalAssignedQuantity === 0) {
+ ElMessage.warning("璇疯緭鍏ョ敓浜ф柟鏁�");
+ return;
+ }
+ console.log(sumAssignedQuantity.value, "sumAssignedQuantity");
+ // 璁$畻褰撳墠閫変腑琛岀殑鎬绘柟鏁�
+ const totalVolume = selectedRows.value.reduce((sum, row) => {
+ return sum + (Number(row.volume) - Number(row.assignedQuantity) || 0);
+ }, 0);
+
+ // 楠岃瘉totalAssignedQuantity涓嶈兘澶т簬鎬绘柟鏁�
+ if (mergeForm.totalAssignedQuantity > sumAssignedQuantity.value) {
+ ElMessage.error("鐢熶骇鏂规暟涓嶈兘澶т簬褰撳墠璁$畻鐨勬�诲��");
+ return;
+ }
+
+ console.log(mergeForm, "mergeForm");
+ productionPlanCombine(mergeForm)
+ .then(res => {
+ if (res.code === 200) {
+ ElMessage.success("涓嬪彂鎴愬姛");
+ getList();
+ isShowNewModal.value = false;
+ // 鍙互閫夋嫨鍒锋柊鍒楄〃鎴栧叾浠栨搷浣�
+ getList();
+ } else {
+ ElMessage.error(res.message || "涓嬪彂澶辫触");
+ }
+ })
+ .catch(err => {
+ console.error("鍚堝苟涓嬪彂寮傚父锛�", err);
+ ElMessage.error("绯荤粺寮傚父锛屽悎骞朵笅鍙戝け璐�");
+ });
// 鍙互閫夋嫨鍒锋柊鍒楄〃鎴栧叾浠栨搷浣�
+ };
+
+ // 瀵煎叆
+ const handleImport = () => {
+ importDialogVisible.value = true;
+ };
+
+ // 瀵煎嚭
+ const handleExport = () => {
+ const fileName = `鐢熶骇璁″垝.xlsx`;
+ exportProductionPlan()
+ .then(res => {
+ // 杩斿洖鐨勬暟鎹槸鍚︿负绌�
+ if (!res) {
+ proxy.$modal.msgError("瀵煎嚭澶辫触锛岃繑鍥炴暟鎹负绌�");
+ return;
+ }
+
+ const blob = new Blob([res], {
+ type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ });
+ const downloadElement = document.createElement("a");
+ const href = window.URL.createObjectURL(blob);
+
+ downloadElement.style.display = "none";
+ downloadElement.href = href;
+ downloadElement.download = fileName;
+
+ document.body.appendChild(downloadElement);
+ downloadElement.click();
+
+ document.body.removeChild(downloadElement);
+ window.URL.revokeObjectURL(href);
+
+ proxy.$modal.msgSuccess("瀵煎嚭鎴愬姛");
+ })
+ .catch(err => {
+ console.error("瀵煎嚭寮傚父锛�", err);
+ proxy.$modal.msgError("绯荤粺寮傚父锛屽鍑哄け璐�");
+ });
+ };
+
+ // 瀵煎叆鎴愬姛
+ const handleImportSuccess = response => {
+ if (response.code === 200) {
+ ElMessage.success("瀵煎叆鎴愬姛");
+ importDialogVisible.value = false;
+ getList();
+ } else {
+ ElMessage.error(response.message || "瀵煎叆澶辫触");
+ }
+ };
+
+ // 瀵煎叆澶辫触
+ const handleImportError = error => {
+ ElMessage.error("瀵煎叆澶辫触锛岃妫�鏌ユ枃浠舵牸寮忔槸鍚︽纭�");
+ };
+
+ // 纭瀵煎叆
+ const handleImportConfirm = () => {
+ if (importDialogRef.value) {
+ importDialogRef.value.submit();
+ }
+ };
+
+ // 涓嬭浇妯℃澘
+ const handleDownloadTemplate = () => {
+ proxy.download(
+ "/productionPlan/downloadTemplate",
+ {},
+ "鐢熶骇璁″垝瀵煎叆妯℃澘.xlsx"
+ );
+ };
+
+ // 鍏抽棴瀵煎叆寮圭獥
+ const handleImportClose = () => {
+ importDialogVisible.value = false;
+ };
+
+ // 鏂板
+ const handleAdd = () => {
+ operationType.value = "add";
+ Object.assign(form, {
+ applyNo: "",
+ customerName: "",
+ productName: "",
+ productMaterialId: undefined,
+ productMaterialSkuId: undefined,
+ specification: "",
+ materialCode: "",
+ quantity: 0,
+ volume: 0,
+ length: 0,
+ width: 0,
+ height: 0,
+ startDate: "",
+ endDate: "",
+ strength: "",
+ remarkOne: "",
+ remarkTwo: "",
+ });
+ dialogVisible.value = true;
+ fetchProductOptions();
+ };
+
+ // 缂栬緫
+ const handleEdit = row => {
+ operationType.value = "edit";
+ Object.assign(form, {
+ id: row.id,
+ applyNo: row.applyNo || "",
+ customerName: row.customerName || "",
+ productName: row.productName || "",
+ productMaterialId: row.productMaterialId || undefined,
+ productMaterialSkuId: row.productMaterialSkuId || undefined,
+ specification: row.specification || "",
+ materialCode: row.materialCode || "",
+ quantity: row.quantity || 0,
+ volume: row.volume || 0,
+ length: row.length || 0,
+ width: row.width || 0,
+ height: row.height || 0,
+ startDate: row.startDate || "",
+ endDate: row.endDate || "",
+ strength: row.strength || "",
+ remarkOne: row.remarkOne || "",
+ remarkTwo: row.remarkTwo || "",
+ });
+ dialogVisible.value = true;
+ fetchProductOptions();
+ fetchSpecificationOptions(row.productMaterialId);
+ };
+
+ // 鍒犻櫎
+ const handleDelete = row => {
+ proxy.$modal
+ .confirm("纭鍒犻櫎璇ョ敓浜ц鍒掞紵", "鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ productionPlanDelete([row.id])
+ .then(() => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getList();
+ })
+ .catch(() => {
+ proxy.$modal.msgError("鍒犻櫎澶辫触");
+ });
+ })
+ .catch(() => {});
+ };
+
+ // 鎻愪氦琛ㄥ崟
+ const handleSubmit = () => {
+ formRef.value.validate(valid => {
+ if (valid) {
+ const payload = { ...form };
+ if (operationType.value === "add") {
+ productionPlanAdd(payload)
+ .then(() => {
+ proxy.$modal.msgSuccess(
+ operationType.value === "add" ? "鏂板鎴愬姛" : "淇敼鎴愬姛"
+ );
+ dialogVisible.value = false;
+ getList();
+ })
+ .catch(() => {
+ proxy.$modal.msgError(
+ operationType.value === "add" ? "鏂板澶辫触" : "淇敼澶辫触"
+ );
+ });
+ }
+ if (operationType.value === "edit") {
+ productionPlanUpdate(payload)
+ .then(() => {
+ proxy.$modal.msgSuccess(
+ operationType.value === "add" ? "鏂板鎴愬姛" : "淇敼鎴愬姛"
+ );
+ dialogVisible.value = false;
+ getList();
+ })
+ .catch(() => {
+ proxy.$modal.msgError(
+ operationType.value === "add" ? "鏂板澶辫触" : "淇敼澶辫触"
+ );
+ });
+ }
+ }
+ });
};
onMounted(() => {
@@ -723,16 +1168,19 @@
border: none;
border-radius: 6px;
overflow: hidden;
+ box-shadow: 0 4px 16px rgba(102, 126, 234, 0.1);
.el-table__header-wrapper {
- background-color: #fafafa;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
th {
- background-color: #fafafa;
+ background: transparent;
font-weight: 600;
- color: #303133;
- border-bottom: 1px solid #ebeef5;
- padding: 14px 0;
+ color: #ffffff;
+ border-bottom: none;
+ padding: 16px 0;
+ font-size: 14px;
+ letter-spacing: 0.5px;
}
}
@@ -741,23 +1189,144 @@
transition: all 0.3s ease;
&:hover {
- background-color: #f5f7fa;
+ background: linear-gradient(
+ 90deg,
+ rgba(102, 126, 234, 0.05) 0%,
+ rgba(118, 75, 162, 0.05) 100%
+ );
+ transform: scale(1.002);
+ box-shadow: 0 2px 8px rgba(102, 126, 234, 0.1);
}
td {
- border-bottom: 1px solid #ebeef5;
- padding: 12px 0;
+ border-bottom: 1px solid #f0f0f0;
+ padding: 14px 0;
+ color: #303133;
+ font-size: 13px;
}
}
tr.current-row {
- background-color: #ecf5ff;
+ background: linear-gradient(
+ 90deg,
+ rgba(102, 126, 234, 0.08) 0%,
+ rgba(118, 75, 162, 0.08) 100%
+ );
+ }
+
+ // 鏁板�煎瓧娈垫牱寮�
+ .quantity-cell,
+ .volume-cell,
+ .dimension-cell {
+ font-weight: 600;
+ color: #409eff;
+ font-family: "Courier New", monospace;
+ font-size: 14px;
+ text-shadow: 0 1px 2px rgba(64, 158, 255, 0.2);
+ }
+
+ // 瑙勬牸瀛楁鏍峰紡
+ .spec-cell {
+ color: #67c23a;
+ font-weight: 500;
+
+ padding: 4px 8px;
+ border-radius: 4px;
+ }
+
+ // 缂栫爜瀛楁鏍峰紡
+ .code-cell {
+ color: #e6a23c;
+ font-family: "Courier New", monospace;
+ font-weight: 500;
+ padding: 4px 8px;
+ border-radius: 4px;
+ }
+
+ // 鏃ユ湡瀛楁鏍峰紡
+ .date-cell {
+ color: #909399;
+ font-size: 12px;
+ font-style: italic;
+ }
+
+ // 鐘舵�佹爣绛炬牱寮�
+ .status-tag {
+ &.pending {
+ background: linear-gradient(135deg, #ffeaa7 0%, #fdcb6e 100%);
+ color: #d63031;
+ padding: 4px 12px;
+ border-radius: 12px;
+ font-weight: 500;
+ box-shadow: 0 2px 4px rgba(253, 203, 110, 0.3);
+ }
+
+ &.processing {
+ background: linear-gradient(135deg, #74b9ff 0%, #0984e3 100%);
+ color: #ffffff;
+ padding: 4px 12px;
+ border-radius: 12px;
+ font-weight: 500;
+ box-shadow: 0 2px 4px rgba(9, 132, 227, 0.3);
+ }
+
+ &.completed {
+ background: linear-gradient(135deg, #55efc4 0%, #00b894 100%);
+ color: #ffffff;
+ padding: 4px 12px;
+ border-radius: 12px;
+ font-weight: 500;
+ box-shadow: 0 2px 4px rgba(0, 184, 148, 0.3);
+ }
}
}
.el-table__empty-block {
- padding: 40px 0;
+ padding: 60px 0;
+ background-color: #fafafa;
}
+ }
+
+ // 鎿嶄綔鎸夐挳鏍峰紡
+ :deep(.el-table .cell .el-button--text) {
+ padding: 6px 10px;
+ border-radius: 4px;
+ transition: all 0.3s ease;
+ font-weight: 500;
+
+ &:hover {
+ background-color: rgba(64, 158, 255, 0.1);
+ transform: translateY(-1px);
+ box-shadow: 0 2px 4px rgba(64, 158, 255, 0.2);
+ }
+
+ &:nth-of-type(1) {
+ color: #409eff;
+ background: linear-gradient(
+ 135deg,
+ rgba(64, 158, 255, 0.1) 0%,
+ rgba(64, 158, 255, 0.05) 100%
+ );
+ }
+
+ &:nth-of-type(2) {
+ color: #67c23a;
+ background: linear-gradient(
+ 135deg,
+ rgba(103, 194, 58, 0.1) 0%,
+ rgba(103, 194, 58, 0.05) 100%
+ );
+ }
+ }
+
+ // 淇℃伅灞曠ず鏍峰紡
+ .info-display {
+ border-radius: 6px;
+ color: #303133;
+ font-size: 14px;
+ min-height: 32px;
+ display: flex;
+ align-items: center;
}
.pagination-container {
@@ -891,9 +1460,9 @@
color: #909399;
margin-left: 4px;
}
- .search_form {
- :deep(.el-form-item) {
- margin-bottom: 0px !important;
- }
- }
+ // .search_form {
+ // :deep(.el-form-item) {
+ // margin-bottom: 0px !important;
+ // }
+ // }
</style>
--
Gitblit v1.9.3