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