gaoluyang
13 小时以前 10a8da68d9db10313c67e0f193c160e9740d95cd
src/views/salesManagement/salesLedger/index.vue
@@ -46,11 +46,63 @@
              <el-table-column label="产品大类" prop="productCategory" />
              <el-table-column label="规格型号" prop="specificationModel" />
              <el-table-column label="单位" prop="unit" />
                     <el-table-column label="产品状态"
                                              width="100px"
                                              align="center">
                <template #default="scope">
                           <el-tag v-if="scope.row.approveStatus === 1 && (!scope.row.shippingDate || !scope.row.shippingCarNumber)"
                                       type="success">充足</el-tag>
                           <el-tag v-else-if="scope.row.approveStatus === 0 && (scope.row.shippingDate || scope.row.shippingCarNumber)"
                                       type="success">已出库</el-tag>
                           <el-tag v-else type="danger">不足</el-tag>
                </template>
              </el-table-column>
                     <el-table-column label="发货状态" width="140" align="center">
                        <template #default="scope">
                           <el-tag :type="getShippingStatusType(scope.row)" size="small">
                              {{ getShippingStatusText(scope.row) }}
                           </el-tag>
                        </template>
                     </el-table-column>
                     <el-table-column label="快递公司" prop="expressCompany" show-overflow-tooltip />
                     <el-table-column label="快递单号" prop="expressNumber" show-overflow-tooltip />
              <el-table-column label="发货车牌" minWidth="100px" align="center">
                <template #default="scope">
                  <div>
                    <el-tag type="success" v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}</el-tag>
                    <el-tag v-else type="info">-</el-tag>
                  </div>
                </template>
              </el-table-column>
                     <el-table-column label="发货日期"
                                              minWidth="100px"
                                              align="center">
                <template #default="scope">
                  <div>
                    <div v-if="scope.row.shippingDate">{{ scope.row.shippingDate }}</div>
                              <el-tag v-else
                                          type="info">-</el-tag>
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="数量" prop="quantity" />
              <el-table-column label="税率(%)" prop="taxRate" />
              <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
              <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
              <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
              <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="sensitiveAmountFormatter" />
              <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="sensitiveAmountFormatter" />
              <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="sensitiveAmountFormatter" />
            <!--操作-->
              <el-table-column Width="60px" label="操作" align="center">
                <template #default="scope">
                  <el-button
                    link
                    type="primary"
                    :disabled="!canShip(scope.row)"
                    @click="openDeliveryForm(scope.row)">
                    发货
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
          </template>
        </el-table-column>
@@ -71,27 +123,10 @@
        <el-table-column label="录入人" prop="entryPersonName" width="100" show-overflow-tooltip />
        <el-table-column label="录入日期" prop="entryDate" width="120" show-overflow-tooltip />
        <el-table-column label="签订日期" prop="executionDate" width="120" show-overflow-tooltip />
        <el-table-column label="发货状态" prop="shippingStatus" width="140" align="center" show-overflow-tooltip />
        <el-table-column label="发货日期" prop="shippingDate" width="140" align="center" show-overflow-tooltip />
        <el-table-column fixed="right" label="操作" min-width="140" align="center">
          <template #default="scope">
            <el-button
              link
              type="primary"
              size="small"
              @click="openForm('edit', scope.row)"
              :disabled="scope.row.approvalStatus === 3 && scope.row.entryPerson !== userStore.id"
            >编辑</el-button>
            <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">附件</el-button>
            <el-button
              link
              type="primary"
              size="small"
              @click="openDeliveryForm(scope.row)"
              :disabled="scope.row.shippingStatus === '已发货'"
            >
              发货
            </el-button>
            <el-button link type="primary" @click="openForm('edit', scope.row)" :disabled="!scope.row.isEdit || scope.row.hasProductionRecord">编辑</el-button>
            <el-button link type="primary" @click="downLoadFile(scope.row)">附件</el-button>
          </template>
        </el-table-column>
      </el-table>
@@ -496,86 +531,10 @@
                        v-model="deliveryForm.type"
                        placeholder="请选择发货类型"
                        style="width: 100%"
                        @change="handleShippingTypeChange"
                     >
                        <el-option label="货车" value="货车" />
                        <el-option label="快递" value="快递" />
                     </el-select>
                  </el-form-item>
               </el-col>
            </el-row>
            <el-row :gutter="30">
               <el-col :span="24">
                  <el-form-item label="发货日期:" prop="shippingDate">
                     <el-date-picker
                        style="width: 100%"
                        v-model="deliveryForm.shippingDate"
                        value-format="YYYY-MM-DD"
                        format="YYYY-MM-DD"
                        type="date"
                        placeholder="请选择发货日期"
                        clearable
                     />
                  </el-form-item>
               </el-col>
            </el-row>
            <el-row :gutter="30">
               <el-col :span="24" v-if="deliveryForm.type === '货车'">
                  <el-form-item label="发货车牌号:" prop="shippingCarNumber">
                     <el-input
                        v-model="deliveryForm.shippingCarNumber"
                        placeholder="请输入发货车牌号"
                        clearable
                     />
                  </el-form-item>
               </el-col>
               <el-col :span="24" v-else>
                  <el-form-item label="快递公司:" prop="expressCompany">
                     <el-input
                        v-model="deliveryForm.expressCompany"
                        placeholder="请输入快递公司"
                        clearable
                     />
                  </el-form-item>
               </el-col>
            </el-row>
            <el-row :gutter="30" v-if="deliveryForm.type === '快递'">
               <el-col :span="24">
                  <el-form-item label="快递单号:" prop="expressNumber">
                     <el-input
                        v-model="deliveryForm.expressNumber"
                        placeholder="请输入快递单号"
                        clearable
                     />
                  </el-form-item>
               </el-col>
            </el-row>
               <el-row :gutter="30">
                  <el-col :span="24">
                     <el-form-item label="发货图片:">
                        <el-upload
                           v-model:file-list="deliveryFileList"
                           :action="upload.url"
                           multiple
                           ref="deliveryFileUpload"
                           auto-upload
                           :headers="upload.headers"
                           :data="{ type: 9 }"
                           :before-upload="handleDeliveryBeforeUpload"
                           :on-error="handleDeliveryUploadError"
                           :on-success="handleDeliveryUploadSuccess"
                           :on-remove="handleDeliveryRemove"
                           list-type="picture-card"
                           :limit="9"
                           accept="image/png,image/jpeg,image/jpg"
                        >
                           <el-icon class="avatar-uploader-icon"><Plus /></el-icon>
                           <template #tip>
                              <div class="el-upload__tip">
                                 支持 jpg、jpeg、png 格式,最多上传 9 张,单张大小不超过 10MB
                              </div>
                           </template>
                        </el-upload>
                     </el-form-item>
                  </el-col>
               </el-row>
@@ -694,7 +653,6 @@
});
const total = ref(0);
const fileList = ref([]);
const deliveryFileList = ref([]);
// 审批人节点(仿采购台账审批人)
const approverNodes = ref([{ id: 1, userId: null }]);
@@ -810,25 +768,11 @@
const currentDeliveryRow = ref(null);
const deliveryFormData = reactive({
  deliveryForm: {
    type: "货车", // 货车, 快递
    shippingDate: "",
    shippingCarNumber: "",
    expressCompany: "",
    expressNumber: "", // 快递单号
    shippingImages: "", // 发货图片,多个用逗号分隔
    type: "", // 货车, 快递
  },
  deliveryRules: {
    type: [
      { required: true, message: "请选择发货类型", trigger: "change" }
    ],
    shippingDate: [
      { required: true, message: "请选择发货日期", trigger: "change" }
    ],
    shippingCarNumber: [
      { validator: (_, value, callback) => validateShippingCarNumber(value, callback), trigger: "blur" }
    ],
    expressCompany: [
      { validator: (_, value, callback) => validateExpressCompany(value, callback), trigger: "blur" }
    ],
  },
});
@@ -1220,47 +1164,6 @@
    delLedgerFile(ids).then((res) => {
      proxy.$modal.msgSuccess("删除成功");
    });
  }
}
// 发货图片上传前校检
function handleDeliveryBeforeUpload(file) {
  // 校检文件类型
  const isImage = file.type === 'image/png' || file.type === 'image/jpeg' || file.type === 'image/jpg';
  if (!isImage) {
    proxy.$modal.msgError("只能上传 jpg、jpeg、png 格式的图片!");
    return false;
  }
  // 校检文件大小
  const isLt10M = file.size / 1024 / 1024 < 10;
  if (!isLt10M) {
    proxy.$modal.msgError("上传图片大小不能超过 10MB!");
    return false;
  }
  proxy.$modal.loading("正在上传图片,请稍候...");
  return true;
}
// 发货图片上传失败
function handleDeliveryUploadError(err) {
  proxy.$modal.msgError("上传图片失败");
  proxy.$modal.closeLoading();
}
// 发货图片上传成功回调
function handleDeliveryUploadSuccess(res, file, uploadFiles) {
  proxy.$modal.closeLoading();
  if (res.code === 200) {
    file.tempId = res.data.tempId;
    proxy.$modal.msgSuccess("上传成功");
  } else {
    proxy.$modal.msgError(res.msg);
    proxy.$refs.deliveryFileUpload.handleRemove(file);
  }
}
// 移除发货图片
function handleDeliveryRemove(file) {
  // 从文件列表中移除
  const index = deliveryFileList.value.findIndex(item => item.uid === file.uid);
  if (index > -1) {
    deliveryFileList.value.splice(index, 1);
  }
}
// 提交表单
@@ -1828,19 +1731,7 @@
   return total.toFixed(2);
};
// 发货类型校验:货车时要求车牌,快递时要求快递公司
const validateShippingCarNumber = (value, callback) => {
  if (deliveryForm.value.type === "货车") {
    if (!value) return callback(new Error("请输入发货车牌号"));
  }
  callback();
};
const validateExpressCompany = (value, callback) => {
  if (deliveryForm.value.type === "快递") {
    if (!value) return callback(new Error("请输入快递公司"));
  }
  callback();
};
const mathNum = () => {
   console.log("productForm.value", productForm.value);
@@ -2017,6 +1908,92 @@
  isCalculating.value = false;
};
/**
 * 获取发货状态文本
 * @param row 行数据
 */
const getShippingStatusText = (row) => {
   // 如果已发货(有发货日期或车牌号),显示"已发货"
   if (row.shippingDate || row.shippingCarNumber) {
      return '已发货';
   }
   // 获取发货状态字段
   const status = row.shippingStatus;
   // 如果状态为空或未定义,默认为"待发货"
   if (status === null || status === undefined || status === '') {
      return '待发货';
   }
   // 状态是字符串
   const statusStr = String(status).trim();
   const statusTextMap = {
      '待发货': '待发货',
      '待审核': '待审核',
      '审核中': '审核中',
      '审核拒绝': '审核拒绝',
      '审核通过': '审核通过',
      '已发货': '已发货'
   };
   return statusTextMap[statusStr] || '待发货';
};
/**
 * 获取发货状态标签类型(颜色)
 * @param row 行数据
 */
const getShippingStatusType = (row) => {
   // 如果已发货(有发货日期或车牌号),显示绿色
   if (row.shippingDate || row.shippingCarNumber) {
      return 'success';
   }
   // 获取发货状态字段
   const status = row.shippingStatus;
   // 如果状态为空或未定义,默认为灰色(待发货)
   if (status === null || status === undefined || status === '') {
      return 'info';
   }
   // 状态是字符串
   const statusStr = String(status).trim();
   const typeTextMap = {
      '待发货': 'info',
      '待审核': 'info',
      '审核中': 'warning',
      '审核拒绝': 'danger',
      '审核通过': 'success',
      '已发货': 'success'
   };
   return typeTextMap[statusStr] || 'info';
};
/**
 * 判断是否可以发货
 * 只有在产品状态是充足,发货状态是待发货和审核拒绝的时候才可以发货
 * @param row 行数据
 */
const canShip = (row) => {
   // 产品状态必须是充足(approveStatus === 1)
   if (row.approveStatus !== 1) {
      return false;
   }
   // 获取发货状态
   const shippingStatus = row.shippingStatus;
   // 如果已发货(有发货日期或车牌号),不能再次发货
   if (row.shippingDate || row.shippingCarNumber) {
      return false;
   }
   // 发货状态必须是"待发货"或"审核拒绝"
   const statusStr = shippingStatus ? String(shippingStatus).trim() : '';
   return statusStr === '待发货' || statusStr === '审核拒绝';
};
/**
 * 下载文件
 *
 * @param row 下载文件的相关信息对象
@@ -2030,16 +2007,16 @@
// 打开发货弹框
const openDeliveryForm = (row) => {
   // 检查是否可以发货
   if (!canShip(row)) {
      proxy.$modal.msgWarning("只有在产品状态是充足,发货状态是待发货或审核拒绝的时候才可以发货");
      return;
   }
   currentDeliveryRow.value = row;
  deliveryForm.value = {
    type: "货车",
    shippingDate: getCurrentDate(),
    shippingCarNumber: "",
    expressCompany: "",
    expressNumber: "", // 初始化快递单号为空
    shippingImages: "", // 初始化图片为空
    type: "",
  };
  deliveryFileList.value = []; // 初始化文件列表为空
   deliveryFormVisible.value = true;
};
@@ -2047,27 +2024,37 @@
const submitDelivery = () => {
  proxy.$refs["deliveryFormRef"].validate((valid) => {
    if (valid) {
      let tempFileIds = [];
      if (deliveryFileList.value !== null && deliveryFileList.value.length > 0) {
        tempFileIds = deliveryFileList.value.map((item) => item.tempId);
      }
      // 保存当前展开的行ID,以便发货后重新加载子表格数据
      const currentExpandedKeys = [...expandedRowKeys.value];
      const salesLedgerId = currentDeliveryRow.value.salesLedgerId;
      addShippingInfo({
        salesLedgerId: currentDeliveryRow.value.id,
        salesLedgerId: salesLedgerId,
        salesLedgerProductId: currentDeliveryRow.value.id,
        type: deliveryForm.value.type,
        shippingDate: deliveryForm.value.shippingDate,
        shippingCarNumber: deliveryForm.value.type === "货车" ? deliveryForm.value.shippingCarNumber : "",
        expressCompany: deliveryForm.value.type === "快递" ? deliveryForm.value.expressCompany : "",
        expressNumber: deliveryForm.value.type === "快递" ? deliveryForm.value.expressNumber : "",
        tempFileIds: tempFileIds,
      })
        .then(() => {
          proxy.$modal.msgSuccess("发货成功");
          closeDeliveryDia();
          getList();
        })
        .catch(() => {
          proxy.$modal.msgError("发货失败,请重试");
          // 刷新主表数据
          getList().then(() => {
            // 如果之前有展开的行,重新加载这些行的子表格数据
            if (currentExpandedKeys.length > 0) {
              // 使用 Promise.all 并行加载所有展开行的子表格数据
              const loadPromises = currentExpandedKeys.map(ledgerId => {
                return productList({ salesLedgerId: ledgerId, type: 1 }).then((res) => {
                  const index = tableData.value.findIndex((item) => item.id === ledgerId);
                  if (index > -1) {
                    tableData.value[index].children = res.data;
                  }
        });
              });
              Promise.all(loadPromises).then(() => {
                // 恢复展开状态
                expandedRowKeys.value = currentExpandedKeys;
              });
            }
          });
        })
    }
  });
};
@@ -2075,21 +2062,13 @@
// 关闭发货弹框
const closeDeliveryDia = () => {
  proxy.resetForm("deliveryFormRef");
  deliveryFileList.value = []; // 清空文件列表
  deliveryForm.value.shippingImages = ""; // 清空图片
  deliveryForm.value.expressNumber = ""; // 清空快递单号
  deliveryFormVisible.value = false;
  currentDeliveryRow.value = null;
};
// 发货类型切换时清空对应字段
const handleShippingTypeChange = (val) => {
  if (val === "货车") {
    deliveryForm.value.expressCompany = "";
    deliveryForm.value.expressNumber = "";
  } else {
    deliveryForm.value.shippingCarNumber = "";
  }
const currentFactoryName = ref("");
const getCurrentFactoryName = async () => {
   let res = await userStore.getInfo();
   currentFactoryName.value = res.user.currentFactoryName;
};
onMounted(() => {