zhangwencui
22 小时以前 ad3ecc9167a5f837e0a6292d8e697b799eb6bfc2
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">
@@ -22,31 +22,88 @@
    <view class="detail-list"
          v-if="tableData.length > 0">
      <view v-for="(item, index) in tableData"
            :key="index"
            :key="rowKey(item, index)"
            class="detail-item">
        <view class="item-header">
        <view class="item-header"
              @click="toggleRow(item, index)">
          <view class="item-left">
            <view class="record-icon">
              <up-icon name="file-text"
                       size="16"
                       color="#ffffff"></up-icon>
            </view>
            <text class="item-index">{{ item.productCategory }}</text>
            <view class="item-title-wrap">
              <text class="item-index">{{ item.productCategory || "产品" }}</text>
            </view>
          </view>
          <view class="item-header-right">
            <text class="toggle-text">{{ rowExpanded(item, index) ? "收起" : "展开" }}</text>
            <up-icon :name="rowExpanded(item, index) ? 'arrow-up' : 'arrow-down'"
                     size="16"
                     color="#999999"></up-icon>
          </view>
        </view>
        <up-divider></up-divider>
        <view class="item-details">
        <view v-if="!rowExpanded(item, index)"
              class="item-preview">
          <view class="detail-row">
            <text class="detail-label">产品大类</text>
            <text class="detail-value">{{ item.productCategory }}</text>
            <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.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.quantity) }}</text>
          </view>
        </view>
        <view v-else
              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">{{ dv(item.productCategory) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">规格型号</text>
            <text class="detail-value">{{ dv(item.specificationModel) }}</text>
          </view>
          <view class="detail-row">
            <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 +113,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 +131,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 +164,7 @@
</template>
<script setup>
  import { ref, computed, onMounted } from "vue";
  import { ref, onMounted } from "vue";
  import { productList } from "@/api/salesManagement/salesLedger";
  // 客户信息
@@ -129,63 +173,34 @@
  // 表格数据
  const tableData = ref([]);
  /** 每条明细折叠状态:仅一条时默认展开,多条时默认收起 */
  const expandedRows = ref({});
  const rowKey = (item, index) =>
    item?.id != null && item?.id !== "" ? `id-${item.id}` : `idx-${index}`;
  const rowExpanded = (item, index) => !!expandedRows.value[rowKey(item, index)];
  const toggleRow = (item, index) => {
    const k = rowKey(item, index);
    expandedRows.value = {
      ...expandedRows.value,
      [k]: !expandedRows.value[k],
    };
  };
  const dv = v => {
    if (v === null || v === undefined || v === "") return "-";
    if (typeof v === "boolean") return v ? "是" : "否";
    return 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 +209,6 @@
      supplierId.value = storedSupplierId;
    }
  };
  const goout = item => {
    uni.setStorageSync("goOutData", JSON.stringify(item));
    uni.navigateTo({
      url: "/pages/sales/salesAccount/goOut",
    });
  };
  // 查询列表
  const getList = () => {
    showLoadingToast("加载中...");
@@ -209,7 +217,14 @@
      type: 1,
    })
      .then(res => {
        tableData.value = res.data;
        const list = res.data || res.records || [];
        tableData.value = list;
        if (list.length === 1) {
          const k = rowKey(list[0], 0);
          expandedRows.value = { [k]: true };
        } else {
          expandedRows.value = {};
        }
        closeToast();
      })
      .catch(() => {
@@ -220,25 +235,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({
@@ -331,12 +327,49 @@
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
  }
  .item-title-wrap {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
  }
  .item-header-right {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
  }
  .toggle-text {
    font-size: 12px;
    color: #2979ff;
  }
  .item-left {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    flex: 1;
  }
  .item-preview {
    padding: 12px 0 16px;
  }
  .preview-tip {
    margin-top: 8px;
    margin-bottom: 0 !important;
    justify-content: center;
  }
  .preview-tip-text {
    font-size: 11px;
    color: #bbb;
  }
  .record-icon {