| | |
| | | <template> |
| | | <view class="receipt-payment-detail"> |
| | | <!-- 使用通用页面头部组件 --> |
| | | <PageHeader title="发货状态" |
| | | <PageHeader title="产品明细" |
| | | @back="goBack" /> |
| | | <!-- 统计信息 --> |
| | | <view class="summary-info"> |
| | |
| | | <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> |
| | |
| | | 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> |
| | |
| | | </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> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, onMounted } from "vue"; |
| | | import { ref, onMounted } from "vue"; |
| | | import { productList } from "@/api/salesManagement/salesLedger"; |
| | | |
| | | // 客户信息 |
| | |
| | | // 表格数据 |
| | | 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 |
| | |
| | | supplierId.value = storedSupplierId; |
| | | } |
| | | }; |
| | | const goout = item => { |
| | | uni.setStorageSync("goOutData", JSON.stringify(item)); |
| | | uni.navigateTo({ |
| | | url: "/pages/sales/salesAccount/goOut", |
| | | }); |
| | | }; |
| | | |
| | | // 查询列表 |
| | | const getList = () => { |
| | | showLoadingToast("加载中..."); |
| | |
| | | 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(() => { |
| | |
| | | }); |
| | | }); |
| | | }; |
| | | 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({ |
| | |
| | | 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 { |