From ea6ad9ddc3d5b33897e93276282245f7023836ff Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期四, 28 八月 2025 17:45:28 +0800
Subject: [PATCH] 大数据市场分析

---
 src/views/sales/components/PurchaseReturnDialog.vue |  453 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 453 insertions(+), 0 deletions(-)

diff --git a/src/views/sales/components/PurchaseReturnDialog.vue b/src/views/sales/components/PurchaseReturnDialog.vue
new file mode 100644
index 0000000..3914ad7
--- /dev/null
+++ b/src/views/sales/components/PurchaseReturnDialog.vue
@@ -0,0 +1,453 @@
+<template>
+  <el-dialog
+    :model-value="dialogFormVisible"
+    @update:model-value="$emit('update:dialogFormVisible', $event)"
+    :title="title"
+    width="1000px"
+    :close-on-click-modal="false"
+    @close="handleClose"
+  >
+         <el-form
+       ref="formRef"
+       :model="formData"
+       :rules="rules"
+       label-width="120px"
+       class="purchase-return-form"
+     >
+      <el-row :gutter="20">
+        <el-col :span="12">
+                     <el-form-item label="渚涘簲鍟�" prop="supplierId">
+             <el-select
+               v-model="formData.supplierId"
+               placeholder="璇烽�夋嫨渚涘簲鍟�"
+               style="width: 100%"
+               filterable
+             >
+              <el-option
+                :label="item.label"
+                v-for="item in supplierList"
+                :key="item.value"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+                     <el-form-item label="鍗曟嵁鏃ユ湡" prop="returnDate">
+             <el-date-picker
+               v-model="formData.returnDate"
+               type="date"
+               placeholder="璇烽�夋嫨鍗曟嵁鏃ユ湡"
+               format="YYYY-MM-DD"
+               value-format="YYYY-MM-DD"
+               style="width: 100%"
+             />
+           </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="20">
+        <el-col :span="12">
+                     <el-form-item label="鎿嶄綔鍛�" prop="operatorId">
+             <el-select
+               v-model="formData.operatorId"
+               placeholder="璇烽�夋嫨鎿嶄綔鍛�"
+               style="width: 100%"
+               filterable
+             >
+              <el-option
+                :label="item.label"
+                v-for="item in operatorList"
+                :key="item.value"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+                     <el-form-item label="閫�璐у師鍥�" prop="returnReason">
+             <el-select
+               v-model="formData.returnReason"
+               placeholder="璇烽�夋嫨閫�璐у師鍥�"
+               style="width: 100%"
+               filterable
+               allow-create
+             >
+              <el-option
+                :label="item.label"
+                v-for="item in returnReasonList"
+                :key="item.value"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="20">
+        <el-col :span="12">
+                     <el-form-item label="閫�璐ф暟閲�" prop="returnQuantity">
+             <el-input
+               v-model.number="formData.returnQuantity"
+               placeholder="璇疯緭鍏ラ��璐ф暟閲�"
+               style="width: 100%"
+             >
+              <template v-slot:suffix>
+                <span>鍚�</span>
+              </template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+                     <el-form-item label="閫�璐ч噾棰�" prop="returnAmount">
+             <el-input
+               v-model.number="formData.returnAmount"
+               placeholder="璇疯緭鍏ラ��璐ч噾棰�"
+               style="width: 100%"
+             >
+              <template v-slot:suffix>
+                <span>鍏�</span>
+              </template>
+            </el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-form-item label="閫�璐у晢鍝佷俊鎭�" prop="returnItems">
+        <div class="return-items-container">
+          <div class="return-items-header">
+            <span>鍟嗗搧鏄庣粏</span>
+            <el-button type="primary" size="small" @click="addReturnItem">
+              娣诲姞鍟嗗搧
+            </el-button>
+          </div>
+                     <el-table :data="formData.returnItems" border style="width: 100%">
+            <el-table-column label="鍟嗗搧鍚嶇О" width="180">
+              <template #default="scope">
+                <el-select
+                  v-model="scope.row.coalId"
+                  placeholder="璇烽�夋嫨鍟嗗搧"
+                  style="width: 100%"
+                  filterable
+                >
+                  <el-option
+                    :label="item.label"
+                    v-for="item in coalList"
+                    :key="item.value"
+                    :value="item.value"
+                  />
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column label="瑙勬牸鍨嬪彿" width="120">
+              <template #default="scope">
+                <el-input
+                  v-model="scope.row.specification"
+                  placeholder="瑙勬牸鍨嬪彿"
+                />
+              </template>
+            </el-table-column>
+            <el-table-column label="鏁伴噺" width="120">
+              <template #default="scope">
+                <el-input
+                  v-model.number="scope.row.quantity"
+                  placeholder="鏁伴噺"
+                  type="number"
+                >
+                  <template v-slot:suffix>
+                    <span>鍚�</span>
+                  </template>
+                </el-input>
+              </template>
+            </el-table-column>
+            <el-table-column label="鍗曚环" width="120">
+              <template #default="scope">
+                <el-input
+                  v-model.number="scope.row.unitPrice"
+                  placeholder="鍗曚环"
+                  type="number"
+                >
+                  <template v-slot:suffix>
+                    <span>鍏�/鍚�</span>
+                  </template>
+                </el-input>
+              </template>
+            </el-table-column>
+            <el-table-column label="灏忚" width="120">
+              <template #default="scope">
+                <span>{{ (scope.row.quantity * scope.row.unitPrice).toFixed(2) }} 鍏�</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="鎿嶄綔" width="80">
+              <template #default="scope">
+                <el-button
+                  type="danger"
+                  size="small"
+                  @click="removeReturnItem(scope.$index)"
+                >
+                  鍒犻櫎
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </el-form-item>
+
+                 <el-form-item label="澶囨敞" prop="remark">
+             <el-input
+               v-model="formData.remark"
+               type="textarea"
+               :rows="3"
+               placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+             />
+           </el-form-item>
+    </el-form>
+
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="handleClose">鍙栨秷</el-button>
+        <el-button type="primary" @click="handleSubmit" :loading="submitLoading">
+          鎻愪氦瀹℃牳
+        </el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { ref, reactive, watch, nextTick } from "vue";
+import { ElMessage } from "element-plus";
+
+// Props
+const props = defineProps({
+  dialogFormVisible: {
+    type: Boolean,
+    default: false
+  },
+  form: {
+    type: Object,
+    default: () => ({})
+  },
+  title: {
+    type: String,
+    default: ""
+  },
+  isEdit: {
+    type: Boolean,
+    default: false
+  }
+});
+
+// Emits
+const emit = defineEmits(['update:dialogFormVisible', 'update:form', 'submit', 'success']);
+
+// 鍝嶅簲寮忔暟鎹�
+const formRef = ref(null);
+const submitLoading = ref(false);
+
+// 琛ㄥ崟鏁版嵁
+const formData = reactive({
+  supplierId: "",
+  returnDate: "",
+  operatorId: "",
+  returnReason: "",
+  returnQuantity: "",
+  returnAmount: "",
+  returnItems: [],
+  remark: ""
+});
+
+// 鍒濆鍖栬〃鍗曟暟鎹�
+const initFormData = () => {
+  Object.assign(formData, {
+    supplierId: "",
+    returnDate: "",
+    operatorId: "",
+    returnReason: "",
+    returnQuantity: "",
+    returnAmount: "",
+    returnItems: [],
+    remark: ""
+  });
+};
+
+// 渚涘簲鍟嗗垪琛�
+const supplierList = ref([
+  { value: "1", label: "渚涘簲鍟咥" },
+  { value: "2", label: "渚涘簲鍟咮" },
+  { value: "3", label: "渚涘簲鍟咰" }
+]);
+
+// 鎿嶄綔鍛樺垪琛�
+const operatorList = ref([
+  { value: "1", label: "闄堝織寮�" },
+  { value: "2", label: "鍒樼編鐜�" },
+  { value: "3", label: "鐜嬪缓鍥�" }
+]);
+
+// 閫�璐у師鍥犲垪琛�
+const returnReasonList = ref([
+  { value: "璐ㄩ噺涓嶅悎鏍�", label: "璐ㄩ噺涓嶅悎鏍�" },
+  { value: "浜よ揣婊炲悗", label: "浜よ揣婊炲悗" },
+  { value: "瑙勬牸涓嶇", label: "瑙勬牸涓嶇" },
+  { value: "鏁伴噺涓嶇", label: "鏁伴噺涓嶇" },
+  { value: "鍏朵粬鍘熷洜", label: "鍏朵粬鍘熷洜" }
+]);
+
+// 鍟嗗搧鍒楄〃
+const coalList = ref([
+  { value: "1", label: "鏃犵儫鐓�" },
+  { value: "2", label: "鐑熺叅" },
+  { value: "3", label: "瑜愮叅" },
+  { value: "4", label: "鐒︾叅" }
+]);
+
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const rules = {
+  supplierId: [
+    { required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }
+  ],
+  returnDate: [
+    { required: true, message: "璇烽�夋嫨鍗曟嵁鏃ユ湡", trigger: "change" }
+  ],
+  operatorId: [
+    { required: true, message: "璇烽�夋嫨鎿嶄綔鍛�", trigger: "change" }
+  ],
+  returnReason: [
+    { required: true, message: "璇烽�夋嫨閫�璐у師鍥�", trigger: "change" }
+  ],
+  returnQuantity: [
+    { required: true, message: "璇疯緭鍏ラ��璐ф暟閲�", trigger: "blur" },
+    { type: "number", min: 0, message: "鏁伴噺蹇呴』澶т簬0", trigger: "blur" }
+  ],
+  returnItems: [
+    { 
+      type: "array", 
+      required: true, 
+      message: "璇疯嚦灏戞坊鍔犱竴涓��璐у晢鍝�", 
+      trigger: "change",
+      validator: (rule, value, callback) => {
+        if (!value || value.length === 0) {
+          callback(new Error("璇疯嚦灏戞坊鍔犱竴涓��璐у晢鍝�"));
+        } else {
+          callback();
+        }
+      }
+    }
+  ]
+};
+
+// 鐩戝惉琛ㄥ崟鏁版嵁鍙樺寲
+watch(() => props.form, (newVal) => {
+  Object.assign(formData, newVal);
+  if (!formData.returnItems || formData.returnItems.length === 0) {
+    formData.returnItems = [];
+  }
+}, { deep: true, immediate: true });
+
+// 娣诲姞閫�璐у晢鍝�
+const addReturnItem = () => {
+  formData.returnItems.push({
+    coalId: "",
+    specification: "",
+    quantity: 0,
+    unitPrice: 0
+  });
+};
+
+// 鍒犻櫎閫�璐у晢鍝�
+const removeReturnItem = (index) => {
+  formData.returnItems.splice(index, 1);
+};
+
+// 鍏抽棴瀵硅瘽妗�
+const handleClose = () => {
+  emit('update:dialogFormVisible', false);
+  formRef.value?.resetFields();
+};
+
+// 鎻愪氦琛ㄥ崟
+const handleSubmit = async () => {
+  if (!formRef.value) return;
+  
+  try {
+    await formRef.value.validate();
+    
+    // 楠岃瘉閫�璐у晢鍝佷俊鎭�
+    if (formData.returnItems.length === 0) {
+      ElMessage.warning("璇疯嚦灏戞坊鍔犱竴涓��璐у晢鍝�");
+      return;
+    }
+    
+    for (let item of formData.returnItems) {
+      if (!item.coalId) {
+        ElMessage.warning("璇烽�夋嫨鍟嗗搧");
+        return;
+      }
+      if (!item.quantity || item.quantity <= 0) {
+        ElMessage.warning("璇疯緭鍏ユ湁鏁堢殑鍟嗗搧鏁伴噺");
+        return;
+      }
+    }
+    
+    submitLoading.value = true;
+    
+    // 妯℃嫙鎻愪氦
+    setTimeout(() => {
+      submitLoading.value = false;
+      ElMessage.success("鎻愪氦鎴愬姛");
+      emit('submit', { ...formData });
+      handleClose();
+    }, 1000);
+    
+  } catch (error) {
+    console.error('琛ㄥ崟楠岃瘉澶辫触:', error);
+  }
+};
+
+// 璁$畻鎬绘暟閲�
+const calculateTotalQuantity = () => {
+  return formData.returnItems.reduce((total, item) => total + (item.quantity || 0), 0);
+};
+
+// 璁$畻鎬婚噾棰�
+const calculateTotalAmount = () => {
+  return formData.returnItems.reduce((total, item) => {
+    return total + ((item.quantity || 0) * (item.unitPrice || 0));
+  }, 0);
+};
+
+// 鐩戝惉閫�璐у晢鍝佸彉鍖栵紝鑷姩璁$畻鎬绘暟閲忓拰鎬婚噾棰�
+watch(() => formData.returnItems, () => {
+  formData.returnQuantity = calculateTotalQuantity();
+  formData.returnAmount = calculateTotalAmount();
+}, { deep: true });
+</script>
+
+<style scoped>
+.purchase-return-form {
+  padding: 20px 0;
+}
+
+.return-items-container {
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  padding: 15px;
+}
+
+.return-items-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+  font-weight: bold;
+}
+
+.dialog-footer {
+  text-align: right;
+}
+
+.el-table {
+  margin-top: 10px;
+}
+</style>

--
Gitblit v1.9.3