gaoluyang
昨天 352fbcfaa09e261918f5a7b50bcd9ba15583b1aa
src/views/salesManagement/returnOrder/components/formDia.vue
@@ -44,11 +44,6 @@
              </el-form-item>
            </el-col>
            <el-col :span="4">
              <el-form-item label="项目阶段:" prop="projectStage">
                <el-input v-model="form.projectStage" placeholder="项目阶段" />
              </el-form-item>
            </el-col>
            <el-col :span="4">
              <el-form-item label="制单人:" prop="maker">
                <el-select v-model="form.maker" filterable placeholder="请选择制单人">
                  <el-option v-for="u in userOptions" :key="u.value" :label="u.label" :value="u.value" />
@@ -61,19 +56,21 @@
              </el-form-item>
            </el-col>
            <el-col :span="4">
              <el-form-item label="结算人:" prop="settler">
                <el-select v-model="form.settler" filterable placeholder="请选择结算人">
                  <el-option v-for="u in userOptions" :key="u.value" :label="u.label" :value="u.value" />
              <el-form-item label="状态:" prop="status">
                <el-select v-model="form.status" placeholder="请选择状态">
                  <el-option label="待处理" :value="0" />
                  <el-option label="已处理" :value="1" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="4">
              <el-form-item label="状态:" prop="status">
                <el-select v-model="form.status" placeholder="请选择状态">
                  <el-option label="待审核" :value="0" />
                  <el-option label="审核中" :value="1" />
                  <el-option label="已审核" :value="2" />
                </el-select>
              <el-form-item label="退货原因:" prop="returnReason">
                <el-input v-model="form.returnReason" placeholder="请输入退货原因" />
              </el-form-item>
            </el-col>
            <el-col :span="4">
              <el-form-item label="退款总额:" prop="refundAmount">
                <el-input v-model="form.refundAmount" disabled placeholder="自动计算" />
              </el-form-item>
            </el-col>
          </el-row>
@@ -92,6 +89,37 @@
                placeholder="请输入" 
                type="number"
                @input="(val) => handleReturnQuantityChange(val, row)"
              />
            </template>
            <template #price="{ row }">
              <el-input
                v-model="row.price"
                style="width:100px"
                placeholder="请输入"
                type="number"
                @input="(val) => handlePriceChange(val, row)"
              />
            </template>
            <template #amount="{ row }">
              <el-input
                v-model="row.amount"
                style="width:100px"
                placeholder="自动计算"
                type="number"
                disabled
              />
            </template>
            <template #isQuality="{ row }">
              <el-select v-model="row.isQuality" placeholder="请选择" style="width:120px">
                <el-option label="是" :value="1" />
                <el-option label="否" :value="2" />
              </el-select>
            </template>
            <template #remark="{ row }">
              <el-input
                v-model="row.remark"
                style="width:130px"
                placeholder="请输入"
              />
            </template>
            <template #action="{ row, index }">
@@ -159,11 +187,11 @@
    customerId: "",
    shippingId: "",
    projectId: "",
    projectStage: "",
    maker: "",
    makeTime: "",
    settler: "",
    status: 0,
    returnReason: "",
    refundAmount: "",
  },
  rules: {
    returnNo: [{
@@ -194,6 +222,10 @@
  {align: "center", label: "已退货数量", prop: "totalReturnNum", width: 120 },
  {align: "center", label: "未退货数量", prop: "unQuantity", width: 120 },
  {align: "center", label: "退货数量", prop: "returnQuantity", dataType: "slot", slot: "returnQuantity", width: 120 },
  {align: "center", label: "退货产品单价", prop: "price", dataType: "slot", slot: "price", width: 120 },
  {align: "center", label: "退货产品金额", prop: "amount", dataType: "slot", slot: "amount", width: 120 },
  {align: "center", label: "是否有质量问题", prop: "isQuality", dataType: "slot", slot: "isQuality", width: 140 },
  {align: "center", label: "备注", prop: "remark", dataType: "slot", slot: "remark", width: 150 },
  {align: "center", label: "操作" , prop: "action", dataType: "slot", slot: "action", width: 120 },
]);
const tableData = ref([]);
@@ -215,8 +247,13 @@
    id: productId,
    returnSaleProductId,
    returnSaleLedgerProductId: productId,
    productModelId: raw?.productModelId,
    num,
    returnQuantity: Number.isFinite(num) ? num : 0,
    price: Number(raw?.taxInclusiveUnitPrice ?? raw?.price ?? 0),
    amount: Number(raw?.amount ?? 0).toFixed(2),
    isQuality: raw?.isQuality ?? 2,
    remark: raw?.remark ?? "",
  };
};
@@ -248,6 +285,8 @@
        return product ? { ...product, ...normalized } : normalized;
      })
    : [];
  calculateTotalRefund();
};
const openDialog = async (type, row) => {
@@ -265,11 +304,11 @@
      customerId: "",
      shippingId: "",
      projectId: "",
      projectStage: "",
      maker: "",
      makeTime: "",
      settler: "",
      status: 0,
      returnReason: "",
      refundAmount: "",
    });
    form.value.maker = userStore.nickName || userStore.name || "";
    form.value.makeTime = new Date().toISOString().replace('T', ' ').split('.')[0]; // Default to now
@@ -282,7 +321,13 @@
    if (!valid) return;
    const returnSaleProducts = (tableData.value || []).map(el => ({
      returnSaleLedgerProductId: el.returnSaleLedgerProductId ?? el.id,
      productModelId: el.productModelId,
      unit: el.unit,
      num: Number(el.num ?? el.returnQuantity ?? 0),
      price: Number(el.price ?? 0),
      amount: Number(el.amount ?? 0),
      isQuality: el.isQuality ?? 2,
      remark: el.remark ?? "",
      id: operationType.value === "edit" ? (el.returnSaleProductId ?? "") : ""
    }));
    const payload = { ...form.value, returnSaleProducts };
@@ -374,7 +419,6 @@
  if(res.code === 200){
    // If backend returns project info, set it
    if (res.data.projectId) form.value.projectId = res.data.projectId;
    if (res.data.projectStage) form.value.projectStage = res.data.projectStage;
    
    // Store available products for selection
    availableProducts.value = res.data.productDtoData || [];
@@ -388,7 +432,6 @@
  const current = Number(val);
  
  if (current > max) {
    // Need nextTick to ensure update if user typed too fast or pasted
    proxy.$nextTick(() => {
      row.returnQuantity = max;
      row.num = max;
@@ -402,6 +445,29 @@
  } else {
    row.num = current;
  }
  calculateRowAmount(row);
  calculateTotalRefund();
};
const handlePriceChange = (val, row) => {
  if (val === "" || val === null) {
    row.price = 0;
  }
  calculateRowAmount(row);
  calculateTotalRefund();
};
const calculateRowAmount = (row) => {
  const quantity = Number(row.returnQuantity || 0);
  const price = Number(row.price || 0);
  row.amount = (quantity * price).toFixed(2);
};
const calculateTotalRefund = () => {
  const total = tableData.value.reduce((sum, row) => {
    return sum + Number(row.amount || 0);
  }, 0);
  form.value.refundAmount = total.toFixed(2);
};
const availableProducts = ref([]);
@@ -429,26 +495,23 @@
// Removed checkSelectable to allow toggling existing items
const confirmProductSelection = () => {
  // Rebuild tableData based on selection, preserving existing data (returnQuantity)
  const newTableData = [];
  
  selectedProducts.value.forEach(product => {
    // Check if product was already in tableData to preserve user input
    const existing = tableData.value.find(item => item.id === product.id);
    if (existing) {
      newTableData.push(existing);
    } else {
      // Create new entry
      newTableData.push({
        ...product, // Keep all product display fields (productName, model, unit, etc.)
        // Map to backend entity structure for submission
        ...product,
        returnSaleLedgerProductId: product.id, 
        returnQuantity: 0, // Default input
        num: 0, // Backend quantity field
        // Ensure display fields are available if they come from 'product'
        // If product has different field names than tableColumn expects, map them here
        productModelId: product.productModelId,
        returnQuantity: 0,
        num: 0,
        price: Number(product.taxInclusiveUnitPrice ?? 0),
        amount: "0.00",
        isQuality: 2,
        remark: "",
        productName: product.productName,
        specificationModel: product.specificationModel,
        unit: product.unit,