fix SalesOrderList.vue filter
This commit is contained in:
@@ -1,7 +1,17 @@
|
||||
<template>
|
||||
<div v-can="permissionCodes.salesOrder.read" class="sales-order-list">
|
||||
<div class="filters">
|
||||
<t-input v-model.trim="keyword" class="keyword" type="search" borderless clearable placeholder="搜索订单号、客户" />
|
||||
<div class="search-status">
|
||||
<t-input v-model.trim="keyword" class="keyword" type="search" borderless clearable placeholder="搜索订单号、客户" />
|
||||
<t-dropdown-menu class="status">
|
||||
<t-dropdown-item
|
||||
v-model="status"
|
||||
label="订单状态"
|
||||
:options="statusOptions"
|
||||
@change="selectStatus"
|
||||
/>
|
||||
</t-dropdown-menu>
|
||||
</div>
|
||||
<t-dropdown-menu class="menus">
|
||||
<t-dropdown-item
|
||||
v-model="orderType"
|
||||
@@ -9,18 +19,18 @@
|
||||
:options="orderTypeOptions"
|
||||
@change="selectOrderType"
|
||||
/>
|
||||
<t-dropdown-item
|
||||
v-model="status"
|
||||
label="订单状态"
|
||||
:options="statusOptions"
|
||||
@change="selectStatus"
|
||||
/>
|
||||
<t-dropdown-item
|
||||
v-model="paymentStatus"
|
||||
label="收款状态"
|
||||
:options="paymentOptions"
|
||||
@change="selectPaymentStatus"
|
||||
/>
|
||||
<t-dropdown-item
|
||||
v-model="refundStatus"
|
||||
label="退款状态"
|
||||
:options="refundOptions"
|
||||
@change="selectRefundStatus"
|
||||
/>
|
||||
</t-dropdown-menu>
|
||||
</div>
|
||||
<t-pull-down-refresh
|
||||
@@ -30,15 +40,10 @@
|
||||
@refresh="refresh"
|
||||
@scrolltolower="loadMore"
|
||||
>
|
||||
<div
|
||||
v-if="viewMode"
|
||||
class="view-tip"
|
||||
v-text="viewMode === 'pending-receive' ? '当前显示未收清订单' : '当前显示待处理退款订单'"
|
||||
/>
|
||||
<div v-if="displayList.length" class="items">
|
||||
<div v-if="list.length" class="items">
|
||||
<sales-order-list-cell
|
||||
class="item"
|
||||
v-for="(item, index) in displayList"
|
||||
v-for="(item, index) in list"
|
||||
:key="item.id"
|
||||
:order="item"
|
||||
:can-receive="canReceive"
|
||||
@@ -65,7 +70,7 @@ import SalesOrderAPI from "@/api/SalesOrderAPI";
|
||||
import NavBarActionMenu from "@/components/NavBarActionMenu.vue";
|
||||
import SalesOrderListCell from "@/pages/salesOrder/components/SalesOrderListCell.vue";
|
||||
import { useNavBarStore } from "@/store/navBarStore";
|
||||
import type { SalesOrder, SalesOrderStatus, SalesOrderType, SalesPaymentStatus } from "@/types/SalesOrder";
|
||||
import type { SalesOrder, SalesOrderPage, SalesOrderStatus, SalesOrderType, SalesPaymentStatus, SalesRefundStatus } from "@/types/SalesOrder";
|
||||
import { getErrorMessage } from "@/utils/error";
|
||||
import { Message } from "@/utils/message";
|
||||
import { permissionCodes } from "@/utils/permission";
|
||||
@@ -88,9 +93,12 @@ const actions = computed(() => canCreate.value ? [{
|
||||
}] : []);
|
||||
const keyword = ref("");
|
||||
const orderType = ref("ALL");
|
||||
const viewMode = computed(() => route.query.view === "pending-receive" || route.query.view === "pending-refund" ? String(route.query.view) : "");
|
||||
const status = ref(viewMode.value === "pending-refund" ? "CANCELLED" : "ALL");
|
||||
const paymentStatus = ref("ALL");
|
||||
type PaymentFilter = "ALL" | SalesPaymentStatus | "PENDING_RECEIVE";
|
||||
type RefundFilter = "ALL" | SalesRefundStatus;
|
||||
|
||||
const status = ref("ALL");
|
||||
const paymentStatus = ref<PaymentFilter>("ALL");
|
||||
const refundStatus = ref<RefundFilter>("ALL");
|
||||
const list = ref<SalesOrder[]>([]);
|
||||
const pageIndex = ref(0);
|
||||
const total = ref(0);
|
||||
@@ -100,26 +108,49 @@ const noMore = ref(false);
|
||||
const pageSize = 15;
|
||||
const orderTypeOptions = [{ label: "全部类型", value: "ALL" }, { label: "套餐订单", value: "PACKAGE" }, { label: "直接产品", value: "DIRECT_PRODUCT" }];
|
||||
const statusOptions = [{ label: "全部状态", value: "ALL" }, { label: "进行中", value: "ACTIVE" }, { label: "已履约", value: "FULFILLED" }, { label: "已取消", value: "CANCELLED" }];
|
||||
const paymentOptions = [{ label: "全部收款", value: "ALL" }, { label: "未收款", value: "UNPAID" }, { label: "部分收款", value: "PARTIALLY_PAID" }, { label: "已收款", value: "PAID" }];
|
||||
const displayList = computed(() => list.value.filter(item => {
|
||||
if (viewMode.value === "pending-receive") return item.paymentStatus !== "PAID";
|
||||
if (viewMode.value === "pending-refund") return item.status === "CANCELLED" && item.refundStatus === "PENDING";
|
||||
return true;
|
||||
}));
|
||||
const paymentOptions = [{ label: "全部收款", value: "ALL" }, { label: "未收清", value: "PENDING_RECEIVE" }, { label: "未收款", value: "UNPAID" }, { label: "部分收款", value: "PARTIALLY_PAID" }, { label: "已收款", value: "PAID" }];
|
||||
const refundOptions = [{ label: "全部退款", value: "ALL" }, { label: "无需退款", value: "NOT_REQUIRED" }, { label: "待退款", value: "PENDING" }, { label: "已退款", value: "REFUNDED" }];
|
||||
|
||||
const routeFilterKey = computed(() => [
|
||||
route.query.orderType,
|
||||
route.query.status,
|
||||
route.query.paymentStatus,
|
||||
route.query.refundStatus,
|
||||
route.query.pendingReceive
|
||||
].map(queryValue).join("|"));
|
||||
|
||||
function queryValue(value: unknown): string {
|
||||
return Array.isArray(value) ? "" : typeof value === "string" ? value : "";
|
||||
}
|
||||
|
||||
function applyRouteFilters(): void {
|
||||
const pendingReceive = queryValue(route.query.pendingReceive) === "true";
|
||||
orderType.value = queryValue(route.query.orderType) || "ALL";
|
||||
status.value = queryValue(route.query.status) || "ALL";
|
||||
paymentStatus.value = pendingReceive ? "PENDING_RECEIVE" : queryValue(route.query.paymentStatus) as PaymentFilter || "ALL";
|
||||
refundStatus.value = queryValue(route.query.refundStatus) as RefundFilter || "ALL";
|
||||
}
|
||||
|
||||
function buildPageFilter(): SalesOrderPage {
|
||||
const pendingReceive = paymentStatus.value === "PENDING_RECEIVE";
|
||||
return {
|
||||
keyword: keyword.value || undefined,
|
||||
orderType: orderType.value === "ALL" ? undefined : orderType.value as SalesOrderType,
|
||||
status: status.value === "ALL" ? undefined : status.value as SalesOrderStatus,
|
||||
paymentStatus: pendingReceive || paymentStatus.value === "ALL" ? undefined : paymentStatus.value as SalesPaymentStatus,
|
||||
refundStatus: refundStatus.value === "ALL" ? undefined : refundStatus.value as SalesRefundStatus,
|
||||
pendingReceive: pendingReceive ? true : undefined,
|
||||
index: pageIndex.value,
|
||||
size: pageSize
|
||||
};
|
||||
}
|
||||
|
||||
async function fetchList(reset: boolean): Promise<void> {
|
||||
if (loading.value || (!reset && noMore.value)) return;
|
||||
if (reset) { pageIndex.value = 0; total.value = 0; noMore.value = false; list.value = []; }
|
||||
loading.value = true;
|
||||
try {
|
||||
const result = await SalesOrderAPI.list({
|
||||
index: pageIndex.value,
|
||||
size: pageSize,
|
||||
keyword: keyword.value || undefined,
|
||||
orderType: orderType.value === "ALL" ? undefined : orderType.value as SalesOrderType,
|
||||
status: status.value === "ALL" ? undefined : status.value as SalesOrderStatus,
|
||||
paymentStatus: paymentStatus.value === "ALL" ? undefined : paymentStatus.value as SalesPaymentStatus
|
||||
});
|
||||
const result = await SalesOrderAPI.list(buildPageFilter());
|
||||
const rows = result.list || [];
|
||||
list.value = reset ? rows : list.value.concat(rows);
|
||||
total.value = result.total || 0;
|
||||
@@ -162,7 +193,14 @@ async function selectStatus(value: DropdownValue): Promise<void> {
|
||||
|
||||
async function selectPaymentStatus(value: DropdownValue): Promise<void> {
|
||||
if (!Array.isArray(value)) {
|
||||
paymentStatus.value = String(value);
|
||||
paymentStatus.value = String(value) as PaymentFilter;
|
||||
await fetchList(true);
|
||||
}
|
||||
}
|
||||
|
||||
async function selectRefundStatus(value: DropdownValue): Promise<void> {
|
||||
if (!Array.isArray(value)) {
|
||||
refundStatus.value = String(value) as RefundFilter;
|
||||
await fetchList(true);
|
||||
}
|
||||
}
|
||||
@@ -191,12 +229,16 @@ const search = Toolkit.debounce(async () => {
|
||||
}
|
||||
}, false);
|
||||
watch(keyword, () => search());
|
||||
watch(viewMode, async value => {
|
||||
status.value = value === "pending-refund" ? "CANCELLED" : "ALL";
|
||||
paymentStatus.value = "ALL";
|
||||
watch(routeFilterKey, async () => {
|
||||
applyRouteFilters();
|
||||
await fetchList(true);
|
||||
});
|
||||
onMounted(async () => { navBarStore.clearRight(); navBarStore.setCustomRightVisible(canCreate.value); try { await fetchList(true); } catch (error) { Message.error(getErrorMessage(error, "销售订单加载失败")); } });
|
||||
onMounted(async () => {
|
||||
navBarStore.clearRight();
|
||||
navBarStore.setCustomRightVisible(canCreate.value);
|
||||
applyRouteFilters();
|
||||
try { await fetchList(true); } catch (error) { Message.error(getErrorMessage(error, "销售订单加载失败")); }
|
||||
});
|
||||
onUnmounted(() => { navBarStore.clearRight(); search.cancel(); });
|
||||
</script>
|
||||
|
||||
@@ -216,13 +258,34 @@ onUnmounted(() => { navBarStore.clearRight(); search.cancel(); });
|
||||
box-shadow: var(--td-shadow-1);
|
||||
flex-direction: column;
|
||||
|
||||
.keyword {
|
||||
--td-input-vertical-padding: 8px 14px;
|
||||
.search-status {
|
||||
display: flex;
|
||||
|
||||
border: 1px solid var(--td-component-border);
|
||||
z-index: 1;
|
||||
background: var(--td-bg-color-container);
|
||||
border-radius: 1rem;
|
||||
.keyword {
|
||||
--td-input-vertical-padding: .25rem 1rem;
|
||||
|
||||
flex: 1;
|
||||
border: 1px solid var(--td-component-border);
|
||||
z-index: 2;
|
||||
background: var(--td-bg-color-container);
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.status {
|
||||
--td-spacer: 4px;
|
||||
--td-spacer-1: 6px;
|
||||
|
||||
border: 1px solid rgba(148, 163, 184, .18);
|
||||
z-index: 1;
|
||||
margin-left: -2.5rem;
|
||||
padding-left: 3rem;
|
||||
padding-right: .7rem;
|
||||
border-radius: 1rem;
|
||||
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menus {
|
||||
@@ -232,8 +295,9 @@ onUnmounted(() => { navBarStore.clearRight(); search.cancel(); });
|
||||
border: 1px solid rgba(148, 163, 184, .18);
|
||||
overflow: hidden;
|
||||
margin-top: -1rem;
|
||||
padding-top: .8rem;
|
||||
background: #fff;
|
||||
border-top: none;
|
||||
padding-top: .8rem;
|
||||
border-radius: 0 0 1rem 1rem;
|
||||
|
||||
&:after {
|
||||
@@ -255,12 +319,6 @@ onUnmounted(() => { navBarStore.clearRight(); search.cancel(); });
|
||||
.list-wrap {
|
||||
padding-top: 1rem;
|
||||
|
||||
.view-tip {
|
||||
color: var(--td-text-color-secondary);
|
||||
padding: .75rem 1rem 0;
|
||||
font-size: .8125rem;
|
||||
}
|
||||
|
||||
.items {
|
||||
gap: 1rem;
|
||||
display: flex;
|
||||
|
||||
@@ -64,6 +64,8 @@ export type SalesOrderPage = {
|
||||
orderType?: SalesOrderType;
|
||||
status?: SalesOrderStatus;
|
||||
paymentStatus?: SalesPaymentStatus;
|
||||
refundStatus?: SalesRefundStatus;
|
||||
pendingReceive?: boolean;
|
||||
fulfilledButUnpaid?: boolean;
|
||||
keyword?: string;
|
||||
beginAt?: number;
|
||||
|
||||
Reference in New Issue
Block a user