yyb
2 天以前 0fd269224211075e9657d6cb285b10805cd5d24f
refactor: 更新发货状态页面和相关逻辑

- 修改发货状态页面标题为“产品明细”
- 在销售账户页面中添加发货状态的详细信息展示
- 优化发货逻辑,增加发货状态的处理和标签显示
- 统一处理空值显示,提升用户体验
已修改3个文件
278 ■■■■■ 文件已修改
src/pages.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/salesAccount/index.vue 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/salesAccount/out.vue 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages.json
@@ -82,7 +82,7 @@
    {
      "path": "pages/sales/salesAccount/out",
      "style": {
        "navigationBarTitleText": "发货状态",
        "navigationBarTitleText": "产品明细",
        "navigationStyle": "custom"
      }
    },
src/pages/sales/salesAccount/index.vue
@@ -26,7 +26,8 @@
          v-if="ledgerList.length > 0">
      <view v-for="(item, index) in ledgerList"
            :key="index">
        <view class="ledger-item">
        <view class="ledger-item"
              @click="openOut(item)">
          <view class="item-header">
            <view class="item-left">
              <view class="document-icon">
@@ -66,6 +67,13 @@
              <text class="detail-label">签订日期</text>
              <text class="detail-value">{{ item.executionDate }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">发货状态</text>
              <u-tag size="mini"
                     :type="getLedgerShippingTagType(item)">{{
                getLedgerShippingLabel(item)
              }}</u-tag>
            </view>
            <up-divider></up-divider>
            <view class="detail-info">
              <view class="detail-row">
@@ -83,8 +91,9 @@
                        size="small"
                        type="primary"
                        plain
                        @click.stop="openOut(item)">
                发货状态
                        :disabled="!canLedgerShip(item)"
                        @click.stop="handleShip(item)">
                发货
              </u-button>
              <!-- <u-button class="detail-button"
                        size="small"
@@ -164,6 +173,106 @@
    });
  };
  // 台账发货状态:1-未发货,2-审批中,3-审批不通过,4-已发货(与后端枚举对齐,兼容多种字段名)
  const LEDGER_SHIPPING_LABELS = {
    1: "未发货",
    2: "审批中",
    3: "审批不通过",
    4: "已发货",
  };
  const normalizeShippingStatusToCode = v => {
    if (v === null || v === undefined || v === "") return 1;
    const n = Number(v);
    if (!Number.isNaN(n) && n >= 1 && n <= 4) return n;
    const s = String(v).trim();
    const textMap = {
      未发货: 1,
      待发货: 1,
      审批中: 2,
      审核中: 2,
      待审核: 2,
      审批不通过: 3,
      审核拒绝: 3,
      已发货: 4,
    };
    return textMap[s] ?? 1;
  };
  const getLedgerShippingStatusCode = item => {
    if (!item) return 1;
    const raw =
      item.deliveryStatus ??
      item.shippingApprovalStatus ??
      item.shipmentApproveStatus ??
      item.ledgerShippingStatus;
    if (raw !== null && raw !== undefined && raw !== "") {
      return normalizeShippingStatusToCode(raw);
    }
    if (item.shippingStatus !== null && item.shippingStatus !== undefined && item.shippingStatus !== "") {
      return normalizeShippingStatusToCode(item.shippingStatus);
    }
    return 1;
  };
  const getLedgerShippingLabel = item =>
    LEDGER_SHIPPING_LABELS[getLedgerShippingStatusCode(item)] ?? "未发货";
  const getLedgerShippingTagType = item => {
    const t = { 1: "info", 2: "warning", 3: "error", 4: "success" };
    return t[getLedgerShippingStatusCode(item)] ?? "info";
  };
  const canLedgerShip = item => {
    const c = getLedgerShippingStatusCode(item);
    return c === 1 || c === 3;
  };
  // 与明细页原逻辑一致:仅库存充足、未实际发货、状态为未发货/审批不通过时可提交发货审批
  const canShipProduct = row => {
    if (!row || row.approveStatus !== 1) return false;
    if (row.shippingDate || row.shippingCarNumber) return false;
    const code = normalizeShippingStatusToCode(row.shippingStatus);
    if (code === 1 || code === 3) return true;
    const s = row.shippingStatus ? String(row.shippingStatus).trim() : "";
    return s === "待发货" || s === "未发货" || s === "审核拒绝" || s === "审批不通过";
  };
  const handleShip = async item => {
    if (!canLedgerShip(item)) {
      uni.showToast({
        title: "仅未发货或审批不通过时可发货",
        icon: "none",
      });
      return;
    }
    if (!item?.id) return;
    showLoadingToast("加载中...");
    try {
      const res = await productList({ salesLedgerId: item.id, type: 1 });
      const products = res.data || res.records || [];
      const row = products.find(p => canShipProduct(p));
      closeToast();
      if (!row) {
        uni.showToast({
          title: "没有可发货的产品",
          icon: "none",
        });
        return;
      }
      uni.setStorageSync("goOutData", JSON.stringify(row));
      uni.navigateTo({
        url: "/pages/sales/salesAccount/goOut",
      });
    } catch (e) {
      closeToast();
      uni.showToast({
        title: "加载产品失败",
        icon: "none",
      });
    }
  };
  // 返回上一页
  const goBack = () => {
    uni.navigateBack();
src/pages/sales/salesAccount/out.vue
@@ -1,7 +1,7 @@
<template>
  <view class="receipt-payment-detail">
    <!-- 使用通用页面头部组件 -->
    <PageHeader title="发货状态"
    <PageHeader title="产品明细"
                @back="goBack" />
    <!-- 统计信息 -->
    <view class="summary-info">
@@ -37,16 +37,48 @@
        <up-divider></up-divider>
        <view class="item-details">
          <view class="detail-row">
            <text class="detail-label">楼层编号</text>
            <text class="detail-value">{{ dv(item.floorCode) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">产品大类</text>
            <text class="detail-value">{{ item.productCategory }}</text>
            <text class="detail-value">{{ dv(item.productCategory) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">规格型号</text>
            <text class="detail-value">{{ item.specificationModel }}</text>
            <text class="detail-value">{{ dv(item.specificationModel) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">单位</text>
            <text class="detail-value">{{ item.unit }}</text>
            <text class="detail-label">厚度</text>
            <text class="detail-value">{{ dv(item.thickness) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">宽(mm)</text>
            <text class="detail-value">{{ dv(item.width) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">高(mm)</text>
            <text class="detail-value">{{ dv(item.height) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">周长(cm)</text>
            <text class="detail-value">{{ dv(item.perimeter) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">总面积(cm²)</text>
            <text class="detail-value">{{ dv(item.actualTotalArea) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">加工要求</text>
            <text class="detail-value">{{ dv(item.processRequirement) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">备注</text>
            <text class="detail-value">{{ dv(item.remark) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">重箱</text>
            <text class="detail-value">{{ dv(item.heavyBox) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">产品状态</text>
@@ -56,17 +88,12 @@
                  class="detail-value danger">不足</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">发货状态</text>
            <u-tag size="mini"
                   :type="getShippingStatusType(item)">{{ getShippingStatusText(item) }}</u-tag>
          </view>
          <view class="detail-row">
            <text class="detail-label">快递公司</text>
            <text class="detail-value">{{ item.expressCompany }}</text>
            <text class="detail-value">{{ dv(item.expressCompany) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">快递单号</text>
            <text class="detail-value">{{ item.expressNumber }}</text>
            <text class="detail-value">{{ dv(item.expressNumber) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">发货车牌</text>
@@ -79,36 +106,28 @@
          </view>
          <view class="detail-row">
            <text class="detail-label">发货日期</text>
            <text class="detail-value">{{ item.shippingDate || '-' }}</text>
            <text class="detail-value">{{ dv(item.shippingDate) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">数量</text>
            <text class="detail-value">{{ item.quantity }}</text>
            <text class="detail-value">{{ dv(item.quantity) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">税率(%)</text>
            <text class="detail-value">{{ item.taxRate }}</text>
            <text class="detail-label">税率(%)</text>
            <text class="detail-value">{{ dv(item.taxRate) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">含税单价(元)</text>
            <text class="detail-value">{{ item.taxInclusiveUnitPrice }}</text>
            <text class="detail-label">含税单价(元)</text>
            <text class="detail-value">{{ dv(item.taxInclusiveUnitPrice) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">含税总价(元)</text>
            <text class="detail-value">{{ item.taxInclusiveTotalPrice }}</text>
            <text class="detail-label">含税总价(元)</text>
            <text class="detail-value">{{ dv(item.taxInclusiveTotalPrice) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">不含税总价(元)</text>
            <text class="detail-value">{{ item.taxExclusiveTotalPrice }}</text>
            <text class="detail-label">不含税总价(元)</text>
            <text class="detail-value">{{ dv(item.taxExclusiveTotalPrice) }}</text>
          </view>
          <up-divider></up-divider>
          <u-button class="detail-button"
                    size="small"
                    type="primary"
                    :disabled="!canShip(item)"
                    @click="goout(item)">
            发货
          </u-button>
        </view>
      </view>
    </view>
@@ -120,7 +139,7 @@
</template>
<script setup>
  import { ref, computed, onMounted } from "vue";
  import { ref, onMounted } from "vue";
  import { productList } from "@/api/salesManagement/salesLedger";
  // 客户信息
@@ -129,63 +148,15 @@
  // 表格数据
  const tableData = ref([]);
  const dv = v =>
    v === null || v === undefined || v === "" ? "-" : v;
  // 返回上一页
  const goBack = () => {
    uni.removeStorageSync("supplierId");
    uni.navigateBack();
  };
  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";
  };
  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] || "待发货";
  };
  // 获取页面参数
  const getPageParams = () => {
    // 从本地存储获取供应商ID
@@ -194,13 +165,6 @@
      supplierId.value = storedSupplierId;
    }
  };
  const goout = item => {
    uni.setStorageSync("goOutData", JSON.stringify(item));
    uni.navigateTo({
      url: "/pages/sales/salesAccount/goOut",
    });
  };
  // 查询列表
  const getList = () => {
    showLoadingToast("加载中...");
@@ -220,25 +184,6 @@
        });
      });
  };
  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 === "审核拒绝";
  };
  // 显示加载提示
  const showLoadingToast = message => {
    uni.showLoading({