From c1b5f6edeacfa0326931d06de6773b936dbabe27 Mon Sep 17 00:00:00 2001
From: maven <2163098428@qq.com>
Date: 星期二, 26 八月 2025 15:18:44 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_JLMY' into dev_JLMY

---
 src/views/production/operationScheduling/components/ProductionDialog.vue |  410 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 410 insertions(+), 0 deletions(-)

diff --git a/src/views/production/operationScheduling/components/ProductionDialog.vue b/src/views/production/operationScheduling/components/ProductionDialog.vue
new file mode 100644
index 0000000..4e26ec9
--- /dev/null
+++ b/src/views/production/operationScheduling/components/ProductionDialog.vue
@@ -0,0 +1,410 @@
+<template>
+  <el-dialog
+      v-model="dialogVisible"
+      title="宸ュ簭鎺掍骇"
+      width="1200px"
+      :close-on-click-modal="false"
+      @close="handleClose"
+  >
+    <div class="empty-table">
+      <el-row :gutter="10">
+        <el-col :span="2">
+          <el-button type="primary" @click="addNewRow">
+            <el-icon>
+              <Plus/>
+            </el-icon>
+            鏂板
+          </el-button>
+        </el-col>
+        <el-col :span="4">
+          <div style="font-size: 16px;">寰呮帓浜ф暟閲忥細{{productionQuantity}}</div>
+        </el-col>
+        <!-- <el-col :span="2">
+          <el-button type="danger" @click="clearAllRows">
+            <el-icon>
+              <Delete />
+            </el-icon>
+            娓呯┖
+          </el-button>
+        </el-col> -->
+      </el-row>
+      <ProductionDetailsTable
+          v-model="detailsTableData"
+          :border="false"
+          :show-operations="dialogType !== 'viewRow'"
+          :auto-calculate="true"
+          @input-change="handleDetailsChange"
+          @delete-row="handleDeleteRow"
+          :dialogType="dialogType"
+      />
+    </div>
+
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button
+            @click="handleClose"
+        >{{ dialogType === 'viewRow' ? '鍏� 闂�' : '鍙� 娑�' }}
+        </el-button
+        >
+        <!-- <el-button @click="handleReset" v-if="dialogType === 'edit'"
+          >閲� 缃�</el-button
+        > -->
+        <el-button 
+            v-if="dialogType !== 'viewRow'"
+            type="primary" 
+            :loading="loading" 
+            @click="handleSubmit"
+        >纭� 瀹�
+        </el-button
+        >
+      </div>
+    </template>
+  </el-dialog>
+  <el-dialog
+      v-model="innerVisible"
+      width="1000"
+      title="閫夋嫨閰嶇疆鏁版嵁"
+      center
+      append-to-body
+  >
+    <div style="margin-bottom: 10px">
+      <el-alert
+          v-if="tableData.length > 0"
+          :title="`褰撳墠宸查�夋嫨 ${tableData.length} 鏉℃暟鎹甡"
+          type="info"
+          :closable="false"
+          show-icon
+      />
+    </div>
+    <ETable
+        :showIndex="false"
+        :showOverflowTooltip="false"
+        @selection-change="handleSelectionChange"
+        :showOperations="false"
+        ref="etableRef"
+        :tableData="formalDatabaseData"
+        :defaultSelectedIds="selectedIds"
+        :rowKey="'id'"
+        height="400"
+        @cell-edit="handleCellEdit"
+        :show-selection="true"
+    />
+    <el-row :gutter="24" style="margin-top: 15px">
+      <el-col :span="12">
+        <el-text type="info">
+          宸查�夋嫨 {{ formalDatabaseSelectedData.length }} 鏉℃暟鎹�
+        </el-text>
+      </el-col>
+      <el-col :span="12" style="text-align: right">
+        <el-button @click="innerVisible = false">鍙栨秷</el-button>
+        <el-button
+            type="primary"
+            @click="handleSelectData"
+            :disabled="formalDatabaseSelectedData.length === 0"
+        >
+          纭畾娣诲姞
+        </el-button>
+      </el-col>
+    </el-row>
+  </el-dialog>
+</template>
+
+<script setup>
+import {ref, reactive, watch, onMounted, nextTick, computed} from "vue";
+import ETable from "@/components/Table/ETable.vue";
+import ETableModify from "@/components/Table/EtableModify.vue";
+import ProductionDetailsTable from "./ProductionDetailsTable.vue";
+import {ElMessage, ElMessageBox, ElAlert, ElText} from "element-plus";
+import {Delete, Warning, Plus} from "@element-plus/icons-vue";
+import {validateFormData, validateNumber, deepClone, createDefaultProductionRow} from "@/utils/production";
+import {useCoalData} from "./useCoalData";
+import useUserStore from "@/store/modules/user";
+import {addProductionScheduling} from '@/api/productionScheduling/index'
+
+// Props 鍜� Emits
+const props = defineProps({
+  visible: {type: Boolean, default: false},
+  type: {type: String, default: "add"},
+  rowData: {type: Object, default: () => ({})},
+});
+
+const dialogVisible = defineModel("visible", {type: Boolean, default: false});
+const emit = defineEmits(["update:visible", "success", "update:productionAndProcessing"]);
+
+// 鐢ㄦ埛淇℃伅鍜岀叅绉嶆暟鎹�
+const userStore = useUserStore();
+const {getCoalNameById} = useCoalData();
+let userInfo;
+
+// 瀵硅瘽妗嗙姸鎬�
+const innerVisible = ref(false);
+const dialogType = ref("add");
+const loading = ref(false);
+const etableRef = ref(null);
+
+// 鏁版嵁鐘舵��
+const tableData = ref([]);
+const detailsTableData = ref([]);
+const formalDatabaseData = ref([]);
+const formalDatabaseSelectedData = ref([]);
+const selectedIds = ref([]);
+const currentRow = ref(null);
+const copyForm = ref(null);
+const coalList = ref([])
+const supplierList = ref([]);
+const productionQuantity = ref(0);
+
+// 宸ュ叿鍑芥暟
+const debugIdMatching = () => {
+  if (formalDatabaseData.value.length > 0 && selectedIds.value.length > 0) {
+    const matchedRows = formalDatabaseData.value.filter((row) =>
+        selectedIds.value.includes(row.id)
+    );
+  }
+};
+
+const handleRowClick = (row) => {
+  currentRow.value = row;
+};
+
+// 鎵嬪姩璁剧疆琛ㄦ牸閫変腑鐘舵��
+const setTableSelection = (ids) => {
+  if (!etableRef.value || !Array.isArray(ids) || ids.length === 0) {
+    return;
+  }
+
+  nextTick(() => {
+    setTimeout(() => {
+      try {
+        etableRef.value.clearSelection();
+        const rowsToSelect = formalDatabaseData.value.filter((row) =>
+            ids.includes(row.id)
+        );
+        if (rowsToSelect.length > 0) {
+          etableRef.value.setRowsSelection(rowsToSelect, true);
+        }
+      } catch (error) {
+      }
+    }, 150);
+  });
+};
+
+// 鍒濆鍖栧拰缂栬緫鍒濆鍖�
+const Initialization = async () => {
+  tableData.value = [];
+  detailsTableData.value = [];
+  copyForm.value = null;
+  dialogType.value = "add";
+
+};
+
+const editInitialization = async (type, data) => {
+  productionQuantity.value = data.productionQuantity;
+  copyForm.value = deepClone(data);
+  tableData.value = data.productionInventoryList || [];
+  detailsTableData.value = data.productionList || [];
+  dialogType.value = type;
+  const existingOfficialIds = tableData.value
+      .map((item) => item.officialId)
+      .filter((id) => id);
+  selectedIds.value = existingOfficialIds;
+
+};
+// 鐩戝惉瀵硅瘽妗嗙姸鎬侊紝鍦ㄦ墦寮�鏃惰缃�変腑鐘舵��
+watch(innerVisible, (newVal) => {
+  if (newVal && selectedIds.value.length > 0) {
+    setTimeout(() => setTableSelection(selectedIds.value), 200);
+  }
+  // 瀵硅瘽妗嗗叧闂椂娓呯┖閫夋嫨鐘舵��
+  if (!newVal) {
+    formalDatabaseSelectedData.value = [];
+  }
+});
+
+defineExpose({
+  Initialization,
+  editInitialization,
+});
+const handleSelectData = (row) => {
+  tableData.value = [];
+  if (!innerVisible.value) return;
+  const selectedData = formalDatabaseSelectedData.value;
+  if (selectedData.length === 0) {
+    ElMessage.warning("璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�");
+    return;
+  }
+  let addedCount = 0;
+  let duplicateCount = 0;
+  selectedData.forEach((item) => {
+    const newItem = {
+      ...item, // 澶嶅埗鎵�鏈夊師濮嬫暟鎹�
+      officialId: item.id, // 淇濆瓨鍘熷鐨刬d浣滀负officialId
+      usedQuantity: 0, // 鍒濆浣跨敤鏁伴噺涓�0
+      // 鍙互鏍规嵁闇�瑕佹坊鍔犲叾浠栧瓧娈�
+    };
+    tableData.value.push(newItem);
+    addedCount++;
+  });
+
+  // 鏇存柊selectedIds锛岀‘淇濆寘鍚墍鏈夊綋鍓峵ableData涓殑officialId
+  const allOfficialIds = tableData.value
+      .map((item) => item.officialId)
+      .filter((id) => id);
+  selectedIds.value = allOfficialIds;
+
+  // 鍏抽棴閫夋嫨瀵硅瘽妗�
+  innerVisible.value = false;
+
+  // 鏄剧ず缁撴灉娑堟伅
+  let message = "";
+  if (addedCount > 0) {
+    message += `鎴愬姛娣诲姞 ${addedCount} 鏉℃暟鎹甡;
+  }
+  if (duplicateCount > 0) {
+    message += (message ? "锛�" : "") + `璺宠繃 ${duplicateCount} 鏉¢噸澶嶆暟鎹甡;
+  }
+  if (message) {
+    ElMessage.success(message);
+  } else {
+    ElMessage.info("娌℃湁鏂版暟鎹娣诲姞");
+  }
+};
+const handleSelectionChange = (selection) => {
+  formalDatabaseSelectedData.value = selection;
+};
+// 鎻愪氦琛ㄥ崟 - 浣跨敤宸ュ叿鍑芥暟楠岃瘉
+const handleSubmit = async () => {
+  // 楠岃瘉鐢熶骇鏄庣粏鏁版嵁
+  const detailsValidation = validateFormData(detailsTableData.value, [
+    "process",
+    "unit",
+    "schedulingNum",
+    "workHours",
+    "schedulingDate",
+    "schedulingUserId"
+  ]);
+
+  if (!detailsValidation.isValid) {
+    ElMessage.warning(detailsValidation.message);
+    return;
+  }
+  let num = 0;
+  detailsTableData.value.forEach((row) => {
+    num += row.schedulingNum
+  })
+  if(productionQuantity.value <  num){
+    ElMessage.warning("寰呮帓浜ф暟閲忎笉鑳藉皬浜庣敓浜ф槑缁嗘暟閲�")
+  }
+  console.log(copyForm.value)
+  detailsTableData.value.forEach((row) => {
+    row.type = copyForm.value.type
+    row.productionId = copyForm.value.id
+    row.coalId = copyForm.value.coalId
+  })
+  detailsTableData.value[0].productionQuantity = copyForm.value.productionQuantity
+  try{
+    const res = await addProductionScheduling(detailsTableData.value)
+    if (res.code === 200) {
+      dialogVisible.value = false;
+      emit("success");
+    } else {
+      ElMessage.error("鎻愪氦澶辫触");
+    }
+  }catch (error){
+    ElMessage.error("鎻愪氦澶辫触锛岃閲嶈瘯");
+  }
+};
+// 鍏抽棴寮圭獥
+const handleClose = () => {
+  dialogVisible.value = false;
+};
+
+// 浣跨敤鏁伴噺楠岃瘉 - 浣跨敤宸ュ叿鍑芥暟
+const handleCellEdit = (row, prop, value) => {
+  if (prop === "usedQuantity") {
+    const validation = validateNumber(value, 0, Number(row.inventoryQuantity));
+
+    if (!validation.isValid) {
+      ElMessage.warning(validation.message);
+      row.usedQuantity = validation.value;
+      return;
+    }
+
+    row.usedQuantity = validation.value;
+  }
+};
+
+// 澶勭悊鐢熶骇鏄庣粏琛ㄦ牸鐨勬搷浣� - 浣跨敤宸ュ叿鍑芥暟
+const addNewRow = () => {
+  const newRow = createDefaultProductionRow(userInfo);
+  detailsTableData.value.push(newRow);
+};
+
+// 閲嶇疆鏁版嵁 - 浣跨敤娣辨嫹璐�
+const handleReset = () => {
+  if (copyForm.value) {
+    tableData.value = deepClone(copyForm.value.productionInventoryList) || [];
+    detailsTableData.value = deepClone(copyForm.value.productionList) || [];
+  }
+};
+
+// 鑾峰彇鐢ㄦ埛淇℃伅骞跺姞杞藉熀纭�鏁版嵁
+onMounted(async () => {
+  try {
+    userInfo = await userStore.getInfo();
+  } catch (error) {
+    ElMessage.error("鍒濆鍖栧け璐ワ紝璇烽噸璇�");
+  }
+});
+
+// 绠�鍖栫殑浜嬩欢澶勭悊鍑芥暟
+const handleDetailsChange = (data) => {
+};
+
+const handleDeleteRow = (index) => {
+  ElMessage.success(`宸插垹闄ょ ${index + 1} 琛屾暟鎹甡);
+};
+
+// 鍒犻櫎鍗曚釜宸查�夋暟鎹」
+const handleRemoveItem = (row) => {
+  const index = tableData.value.findIndex(
+      (item) => item.officialId === row.officialId
+  );
+  if (index > -1) {
+    tableData.value.splice(index, 1);
+
+    // 鏇存柊selectedIds
+    const updatedOfficialIds = tableData.value
+        .map((item) => item.officialId)
+        .filter((id) => id);
+    selectedIds.value = updatedOfficialIds;
+    ElMessage.success("宸插垹闄ら�変腑椤�");
+  }
+};
+
+
+// 璁$畻鎬讳娇鐢ㄩ噺
+const totalUsedQuantity = computed(() => {
+  return tableData.value.reduce((total, item) => {
+    const usedQty = Number(item.usedQuantity) || 0;
+    return total + usedQty;
+  }, 0);
+});
+</script>
+
+<style scoped lang="scss">
+.el-form {
+  .el-row {
+    padding-top: 20px;
+    background: rgba($color: #f8fafb, $alpha: 0.5);
+  }
+}
+
+.el-row > .el-col > h1 {
+  font-weight: bolder;
+}
+
+.empty-table > .el-row {
+  margin-bottom: 12px;
+}
+</style>

--
Gitblit v1.9.3