<template>
|
<view class="sales-account">
|
<PageHeader title="发货台账"
|
@back="goBack" />
|
<view class="search-section">
|
<view class="search-bar">
|
<view class="search-input">
|
<up-input class="search-text"
|
v-model="query.salesContractNo"
|
placeholder="请输入销售合同号搜索"
|
clearable
|
@change="getList" />
|
</view>
|
<view class="filter-button"
|
@click="showFilter = true">
|
<up-icon name="list"
|
size="24"
|
color="#999"></up-icon>
|
</view>
|
</view>
|
</view>
|
|
<view v-if="deliveryList.length > 0"
|
class="ledger-list">
|
<view v-for="item in deliveryList"
|
:key="item.id"
|
class="ledger-item">
|
<view class="item-header">
|
<view class="item-left">
|
<view class="document-icon">
|
<up-icon name="car"
|
size="16"
|
color="#ffffff"></up-icon>
|
</view>
|
<text class="item-id">{{ item.shippingNo || item.salesContractNo || "-" }}</text>
|
</view>
|
<up-tag :text="statusText(item.status)"
|
:type="statusTagType(item.status)"
|
size="mini"
|
shape="circle" />
|
</view>
|
<up-divider></up-divider>
|
<view class="item-details">
|
<view class="detail-row">
|
<text class="detail-label">销售合同号</text>
|
<text class="detail-value">{{ item.salesContractNo || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">所属项目</text>
|
<text class="detail-value">{{ item.projectName || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">客户名称</text>
|
<text class="detail-value">{{ item.customerName || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">产品名称</text>
|
<text class="detail-value">{{ item.productName || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">规格型号</text>
|
<text class="detail-value">{{ item.specificationModel || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">发货日期</text>
|
<text class="detail-value">{{ item.shippingDate || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">发货数量</text>
|
<text class="detail-value">{{ item.totalQuantity ?? "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">发货车牌号</text>
|
<text class="detail-value">{{ item.shippingCarNumber || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">快递公司</text>
|
<text class="detail-value">{{ item.expressCompany || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">快递单号</text>
|
<text class="detail-value">{{ item.expressNumber || "-" }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">出库批次</text>
|
<text class="detail-value">{{ item.outboundBatches || "-" }}</text>
|
</view>
|
</view>
|
|
<view v-if="returnNos(item).length > 0"
|
class="return-entry"
|
@click="showReturnNos(item)">
|
<up-icon name="arrow-return-left"
|
size="15"
|
color="#ff9900"></up-icon>
|
<text class="return-entry-text">查看 {{ returnNos(item).length }} 个退货单</text>
|
</view>
|
|
<view class="action-buttons">
|
<up-button class="action-btn"
|
size="small"
|
type="primary"
|
:disabled="isLocked(item)"
|
@click="goEdit(item)">补充发货信息</up-button>
|
<up-button class="action-btn"
|
size="small"
|
@click="goDetail(item)">详情</up-button>
|
<up-button class="action-btn"
|
size="small"
|
type="error"
|
plain
|
:disabled="isLocked(item)"
|
@click="handleDelete(item)">删除</up-button>
|
</view>
|
</view>
|
</view>
|
<view v-else
|
class="no-data">
|
<text>暂无发货台账数据</text>
|
</view>
|
|
<FilterPanel v-model:show="showFilter"
|
:model-value="query"
|
title="发货台账筛选"
|
:fields="filterFields"
|
@search="onFilterSearch"
|
@reset="onFilterSearch" />
|
</view>
|
</template>
|
|
<script setup>
|
import { computed, reactive, ref } from "vue";
|
import { onShow } from "@dcloudio/uni-app";
|
import PageHeader from "@/components/PageHeader.vue";
|
import FilterPanel from "@/components/FilterPanel.vue";
|
import {
|
deliveryLedgerListPage,
|
delDeliveryLedger,
|
} from "@/api/salesManagement/deliveryLedger";
|
import { unwrapList } from "@/utils/list";
|
import { loadProjectOptions } from "@/utils/projectOptions";
|
|
// 这两种状态已进入正式流程,不允许再改发货信息或删除
|
const LOCKED_STATUS = ["审核通过", "已发货"];
|
|
const STATUS_TEXT = {
|
0: "待审核",
|
1: "审核中",
|
2: "审核拒绝",
|
3: "审核通过",
|
};
|
|
const deliveryList = ref([]);
|
const showFilter = ref(false);
|
const projectOptions = ref([]);
|
|
const query = reactive({
|
salesContractNo: "",
|
shippingCarNumber: "",
|
expressNumber: "",
|
projectId: "",
|
shippingDateRange: [],
|
});
|
|
const filterFields = computed(() => [
|
{
|
prop: "salesContractNo",
|
label: "销售合同号",
|
type: "input",
|
placeholder: "请输入销售合同号",
|
},
|
{
|
prop: "shippingCarNumber",
|
label: "发货车牌号",
|
type: "input",
|
placeholder: "请输入发货车牌号",
|
},
|
{
|
prop: "expressNumber",
|
label: "快递单号",
|
type: "input",
|
placeholder: "请输入快递单号",
|
},
|
{ prop: "projectId", label: "所属项目", type: "select", options: projectOptions.value },
|
{ prop: "shippingDateRange", label: "发货日期", type: "daterange" },
|
]);
|
|
const goBack = () => uni.navigateBack();
|
|
const statusText = status => {
|
if (status === null || status === undefined || status === "") return "-";
|
return STATUS_TEXT[status] || String(status);
|
};
|
|
const statusTagType = status => {
|
if (status === "已发货" || status === 3 || status === "3") return "success";
|
if (status === 1 || status === "1") return "warning";
|
if (status === 2 || status === "2") return "error";
|
return "info";
|
};
|
|
const isLocked = item => LOCKED_STATUS.includes(item?.status);
|
|
const returnNos = item =>
|
Array.isArray(item?.returnNoList) ? item.returnNoList : [];
|
|
const goDetail = item => {
|
uni.setStorageSync("deliveryDetail", item || {});
|
uni.navigateTo({
|
url: `/pages/sales/deliveryLedger/detail?id=${item.id}`,
|
});
|
};
|
|
const goEdit = item => {
|
if (isLocked(item)) {
|
uni.showToast({ title: "该状态的数据不可编辑发货信息", icon: "none" });
|
return;
|
}
|
uni.setStorageSync("deliveryDetail", item || {});
|
uni.navigateTo({
|
url: `/pages/sales/deliveryLedger/edit?id=${item.id}`,
|
});
|
};
|
|
// 需求六.4:退货统计,弹窗列举退货单号
|
const showReturnNos = item => {
|
const list = returnNos(item);
|
if (list.length === 0) return;
|
uni.showModal({
|
title: "退货单号",
|
content: list.join("\n"),
|
showCancel: false,
|
confirmText: "知道了",
|
});
|
};
|
|
const getList = () => {
|
const [beginShippingDate, endShippingDate] = Array.isArray(
|
query.shippingDateRange
|
)
|
? query.shippingDateRange
|
: [];
|
deliveryLedgerListPage({
|
current: -1,
|
size: -1,
|
salesContractNo: query.salesContractNo || undefined,
|
shippingCarNumber: query.shippingCarNumber || undefined,
|
expressNumber: query.expressNumber || undefined,
|
projectId: query.projectId || undefined,
|
beginShippingDate: beginShippingDate || undefined,
|
endShippingDate: endShippingDate || undefined,
|
})
|
.then(res => {
|
deliveryList.value = unwrapList(res);
|
})
|
.catch(() => {
|
uni.showToast({ title: "查询失败", icon: "none" });
|
});
|
};
|
|
// FilterPanel 只回吐筛选值,写回 query 后统一查询
|
const onFilterSearch = values => {
|
Object.assign(query, values);
|
getList();
|
};
|
|
const handleDelete = item => {
|
if (!item?.id) return;
|
if (isLocked(item)) {
|
uni.showToast({ title: "该状态的数据不可删除", icon: "none" });
|
return;
|
}
|
uni.showModal({
|
title: "删除确认",
|
content: "确认删除该发货台账吗?",
|
success: res => {
|
if (!res.confirm) return;
|
uni.showLoading({ title: "处理中...", mask: true });
|
delDeliveryLedger(item.id)
|
.then(() => {
|
uni.showToast({ title: "删除成功", icon: "success" });
|
getList();
|
})
|
.catch(() => {
|
uni.showToast({ title: "删除失败", icon: "none" });
|
})
|
.finally(() => {
|
uni.hideLoading();
|
});
|
},
|
});
|
};
|
|
let projectsLoaded = false;
|
|
const loadProjects = () => {
|
if (projectsLoaded) return;
|
projectsLoaded = true;
|
loadProjectOptions()
|
.then(options => {
|
projectOptions.value = options;
|
})
|
.catch(() => {
|
projectsLoaded = false;
|
});
|
};
|
|
onShow(() => {
|
getList();
|
loadProjects();
|
});
|
</script>
|
|
<style scoped lang="scss">
|
@import "@/styles/sales-common.scss";
|
|
.detail-value {
|
max-width: 70%;
|
word-break: break-all;
|
}
|
|
.return-entry {
|
display: flex;
|
align-items: center;
|
gap: 6px;
|
margin: 0 12px 10px;
|
padding: 8px 10px;
|
border-radius: 8px;
|
background: #fffaf0;
|
}
|
|
.return-entry-text {
|
font-size: 13px;
|
color: #ff9900;
|
}
|
</style>
|