优化线下结算筛选
This commit is contained in:
@@ -157,6 +157,7 @@ type AdminOrderQuery struct {
|
||||
HandoffStatus string
|
||||
HandoffMode string
|
||||
SettlementStatus string
|
||||
OfflineSettlementStatus string
|
||||
}
|
||||
|
||||
type AuditMeta = auditlog.Meta
|
||||
|
||||
@@ -62,5 +62,6 @@ func parseAdminOrderQuery(c *gin.Context) AdminOrderQuery {
|
||||
HandoffStatus: strings.TrimSpace(c.Query("handoff_status")),
|
||||
HandoffMode: strings.TrimSpace(c.Query("handoff_mode")),
|
||||
SettlementStatus: strings.TrimSpace(c.Query("settlement_status")),
|
||||
OfflineSettlementStatus: strings.TrimSpace(c.Query("offline_settlement_status")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,9 @@ func applyAdminOrderFilters(db *gorm.DB, query AdminOrderQuery) *gorm.DB {
|
||||
if query.SettlementStatus != "" {
|
||||
db = db.Where("o.settlement_status = ?", query.SettlementStatus)
|
||||
}
|
||||
if query.OfflineSettlementStatus != "" {
|
||||
db = db.Where("COALESCE(NULLIF(o.offline_settlement_status, ''), 'none') = ?", query.OfflineSettlementStatus)
|
||||
}
|
||||
if keyword := strings.TrimSpace(query.Keyword); keyword != "" {
|
||||
like := "%" + keyword + "%"
|
||||
if id, err := strconv.ParseUint(keyword, 10, 64); err == nil {
|
||||
|
||||
@@ -142,6 +142,7 @@ type AdminPickupQuery struct {
|
||||
Status string
|
||||
ShopName string
|
||||
AccountSource string
|
||||
OfflineSettlementStatus string
|
||||
}
|
||||
|
||||
type SellerPickupQuery struct {
|
||||
|
||||
@@ -60,6 +60,7 @@ func parseAdminQuery(c *gin.Context) AdminPickupQuery {
|
||||
Status: c.Query("status"),
|
||||
ShopName: c.Query("shop_name"),
|
||||
AccountSource: c.Query("account_source"),
|
||||
OfflineSettlementStatus: c.Query("offline_settlement_status"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -687,6 +687,9 @@ func (r *Repository) ListAdmin(ctx context.Context, query AdminPickupQuery) (*Pa
|
||||
if accountSource := strings.TrimSpace(query.AccountSource); accountSource != "" {
|
||||
db = db.Where("p.account_source = ?", accountSource)
|
||||
}
|
||||
if offlineSettlementStatus := strings.TrimSpace(query.OfflineSettlementStatus); offlineSettlementStatus != "" {
|
||||
db = db.Where("p.offline_settlement_status = ?", offlineSettlementStatus)
|
||||
}
|
||||
if kw := strings.TrimSpace(query.Keyword); kw != "" {
|
||||
like := "%" + kw + "%"
|
||||
db = db.Where(
|
||||
|
||||
@@ -175,6 +175,32 @@ func TestRepositoryListAdminFiltersOwnerPhone(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepositoryListAdminFiltersOfflineSettlementStatus(t *testing.T) {
|
||||
repo, db := newPickupTestRepo(t)
|
||||
first := seedPickup(t, db, StatusCompleted)
|
||||
if err := db.Model(&first).Updates(map[string]any{
|
||||
"settlement_mode": SettlementModePlatformManaged,
|
||||
"offline_settlement_status": OfflineSettlementStatusPending,
|
||||
}).Error; err != nil {
|
||||
t.Fatalf("设置待线下结算提号失败: %v", err)
|
||||
}
|
||||
second := first
|
||||
second.ID = 0
|
||||
second.PickupNo = "PK-OFFLINE-SETTLED-001"
|
||||
second.OfflineSettlementStatus = OfflineSettlementStatusSettled
|
||||
if err := db.Create(&second).Error; err != nil {
|
||||
t.Fatalf("创建已线下结算提号失败: %v", err)
|
||||
}
|
||||
|
||||
result, err := repo.ListAdmin(t.Context(), AdminPickupQuery{OfflineSettlementStatus: OfflineSettlementStatusPending})
|
||||
if err != nil {
|
||||
t.Fatalf("ListAdmin() error = %v", err)
|
||||
}
|
||||
if result.Total != 1 || len(result.Items) != 1 || result.Items[0].OfflineSettlementStatus != OfflineSettlementStatusPending {
|
||||
t.Fatalf("待线下结算筛选结果 = %+v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepositoryListShopNamesReturnsDistinctPlatformOptions(t *testing.T) {
|
||||
repo, db := newPickupTestRepo(t)
|
||||
first := seedPickup(t, db, StatusPickingUp)
|
||||
|
||||
@@ -127,6 +127,7 @@ export interface AdminPickupListQuery {
|
||||
status?: string
|
||||
shop_name?: string
|
||||
account_source?: PickupAccountSource | ''
|
||||
offline_settlement_status?: PickupOfflineSettlementStatus | ''
|
||||
}
|
||||
|
||||
function cleanParams(query: object) {
|
||||
|
||||
@@ -21,6 +21,7 @@ const filters = reactive<AdminOrderQuery>({
|
||||
handoff_status: '',
|
||||
handoff_mode: '',
|
||||
settlement_status: '',
|
||||
offline_settlement_status: '',
|
||||
})
|
||||
const loading = ref(false)
|
||||
const orders = ref<Order[]>([])
|
||||
@@ -92,6 +93,7 @@ async function loadOrders() {
|
||||
handoff_status: filters.handoff_status,
|
||||
handoff_mode: filters.handoff_mode,
|
||||
settlement_status: filters.settlement_status,
|
||||
offline_settlement_status: filters.offline_settlement_status,
|
||||
})
|
||||
orders.value = result.items
|
||||
total.value = result.total
|
||||
@@ -115,6 +117,7 @@ function resetFilters() {
|
||||
filters.handoff_status = ''
|
||||
filters.handoff_mode = ''
|
||||
filters.settlement_status = ''
|
||||
filters.offline_settlement_status = ''
|
||||
void queryOrders()
|
||||
}
|
||||
|
||||
@@ -225,6 +228,18 @@ function isPlatformManaged(row: Order) {
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="线下结算">
|
||||
<el-select
|
||||
v-model="filters.offline_settlement_status"
|
||||
clearable
|
||||
placeholder="全部"
|
||||
style="width: 150px"
|
||||
@change="queryOrders"
|
||||
>
|
||||
<el-option label="待确认线下结算" value="pending" />
|
||||
<el-option label="已确认线下结算" value="settled" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="Search" :loading="loading" @click="queryOrders"
|
||||
>查询</el-button
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
type AvailableListing,
|
||||
type AvailableListingSourceType,
|
||||
type PickupAccountSource,
|
||||
type PickupOfflineSettlementStatus,
|
||||
} from '@/features/admin/api/adminPickup'
|
||||
import { centToYuan, formatCentWithSymbol, yuanToCent } from '@/shared/utils/money'
|
||||
import { formatDateTime } from '@/shared/utils/time'
|
||||
@@ -32,6 +33,7 @@ const filters = reactive({
|
||||
status: '',
|
||||
shop_name: '',
|
||||
account_source: '' as PickupAccountSource | '',
|
||||
offline_settlement_status: '' as PickupOfflineSettlementStatus | '',
|
||||
})
|
||||
|
||||
const createDialogVisible = ref(false)
|
||||
@@ -100,6 +102,16 @@ function handleSearch() {
|
||||
filters.page = 1
|
||||
loadList()
|
||||
}
|
||||
|
||||
function resetFilters() {
|
||||
filters.keyword = ''
|
||||
filters.status = ''
|
||||
filters.shop_name = ''
|
||||
filters.account_source = ''
|
||||
filters.offline_settlement_status = ''
|
||||
filters.page = 1
|
||||
loadList()
|
||||
}
|
||||
function handlePageChange(p: number) {
|
||||
filters.page = p
|
||||
loadList()
|
||||
@@ -441,39 +453,63 @@ function listingOptionLabel(item: AvailableListing) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter-bar">
|
||||
<div class="pickup-filter-bar">
|
||||
<el-form inline @submit.prevent>
|
||||
<el-form-item label="关键词" class="pickup-keyword-filter">
|
||||
<el-input
|
||||
v-model="filters.keyword"
|
||||
placeholder="提号编号 / 上架编号 / 账号标题 / 手机号"
|
||||
clearable
|
||||
style="width: 300px"
|
||||
@keyup.enter="handleSearch"
|
||||
@clear="handleSearch"
|
||||
/>
|
||||
<el-select v-model="filters.status" placeholder="状态" clearable style="width: 130px">
|
||||
</el-form-item>
|
||||
<el-form-item label="提号状态">
|
||||
<el-select v-model="filters.status" clearable placeholder="全部" @change="handleSearch">
|
||||
<el-option label="提号中" value="picking_up" />
|
||||
<el-option label="已完成" value="completed" />
|
||||
<el-option label="已取消" value="cancelled" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺">
|
||||
<el-select
|
||||
v-model="filters.shop_name"
|
||||
placeholder="店铺名称"
|
||||
filterable
|
||||
clearable
|
||||
style="width: 160px"
|
||||
placeholder="全部"
|
||||
@change="handleSearch"
|
||||
>
|
||||
<el-option v-for="name in shopOptions" :key="name" :label="name" :value="name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="账号来源">
|
||||
<el-select
|
||||
v-model="filters.account_source"
|
||||
placeholder="账号来源"
|
||||
clearable
|
||||
style="width: 190px"
|
||||
placeholder="全部"
|
||||
@change="handleSearch"
|
||||
>
|
||||
<el-option label="外部上传 · 平台代管" value="external_platform_managed" />
|
||||
<el-option label="站内上传" value="internal" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="线下结算">
|
||||
<el-select
|
||||
v-model="filters.offline_settlement_status"
|
||||
clearable
|
||||
placeholder="全部"
|
||||
@change="handleSearch"
|
||||
>
|
||||
<el-option label="待确认" value="pending" />
|
||||
<el-option label="已确认" value="settled" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item class="pickup-filter-actions">
|
||||
<el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
|
||||
<el-button @click="resetFilters">重置</el-button>
|
||||
<el-button :icon="Refresh" @click="loadList">刷新</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<el-table v-loading="loading" :data="items" class="table-panel">
|
||||
@@ -872,6 +908,70 @@ function listingOptionLabel(item: AvailableListing) {
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
}
|
||||
.pickup-filter-bar {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.pickup-filter-bar :deep(.el-form) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 10px 16px;
|
||||
}
|
||||
|
||||
.pickup-filter-bar :deep(.el-form-item) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.pickup-filter-bar :deep(.el-form-item__label) {
|
||||
padding-right: 7px;
|
||||
color: #52616f;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.pickup-filter-bar :deep(.el-select) {
|
||||
width: 128px;
|
||||
}
|
||||
|
||||
.pickup-filter-bar :deep(.el-form-item:nth-child(3) .el-select) {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.pickup-filter-bar :deep(.el-form-item:nth-child(4) .el-select) {
|
||||
width: 175px;
|
||||
}
|
||||
|
||||
.pickup-keyword-filter :deep(.el-input) {
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
.pickup-filter-actions :deep(.el-form-item__content) {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.pickup-filter-bar :deep(.el-form) {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.pickup-filter-bar :deep(.el-form-item),
|
||||
.pickup-filter-bar :deep(.el-select),
|
||||
.pickup-keyword-filter :deep(.el-input) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pickup-filter-bar :deep(.el-form-item__content) {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.pickup-filter-bar :deep(.el-form) {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
}
|
||||
.text-muted {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
@@ -196,6 +196,7 @@ export interface AdminOrderQuery {
|
||||
handoff_status?: string
|
||||
handoff_mode?: string
|
||||
settlement_status?: string
|
||||
offline_settlement_status?: 'pending' | 'settled' | ''
|
||||
}
|
||||
|
||||
interface SubmitCheckoutRequest {
|
||||
|
||||
Reference in New Issue
Block a user