update cascase filter
This commit is contained in:
@@ -9,19 +9,26 @@ export interface CascadeValue {
|
|||||||
|
|
||||||
const model = defineModel<CascadeValue>({ default: () => ({ company_id: undefined, platform_id: undefined, store_id: undefined }) })
|
const model = defineModel<CascadeValue>({ default: () => ({ company_id: undefined, platform_id: undefined, store_id: undefined }) })
|
||||||
|
|
||||||
const companies = ref<{ id: number; name: string; label: string }[]>([])
|
const companies = ref<{ id: number; name: string; label: string | null }[]>([])
|
||||||
const platforms = ref<{ id: number; developer_id: number }[]>([])
|
const platforms = ref<{ id: number; name: string; label: string | null; developer_id?: number }[]>([])
|
||||||
const stores = ref<{ id: number; company_id: number; platform_id: number; name: string; label: string }[]>([])
|
const stores = ref<{ id: number; company_id: number; platform_id: number; name: string; label: string | null }[]>([])
|
||||||
|
|
||||||
|
/** 清洗 label:过滤 "null" 字符串,优先 label 其次 name */
|
||||||
|
function cleanLabel(label: string | null | undefined, name: string | undefined, fallback: string): string {
|
||||||
|
if (label && label !== 'null') return label
|
||||||
|
if (name) return name
|
||||||
|
return fallback
|
||||||
|
}
|
||||||
|
|
||||||
const loadingCompanies = ref(false)
|
const loadingCompanies = ref(false)
|
||||||
const loadingStores = ref(false)
|
const loadingStores = ref(false)
|
||||||
|
|
||||||
const companyOptions = computed(() =>
|
const companyOptions = computed(() =>
|
||||||
companies.value.map((c) => ({ value: c.id, label: c.label || c.name })),
|
companies.value.map((c) => ({ value: c.id, label: cleanLabel(c.label, c.name, `公司 #${c.id}`) })),
|
||||||
)
|
)
|
||||||
|
|
||||||
const platformOptions = computed(() =>
|
const platformOptions = computed(() =>
|
||||||
platforms.value.map((p) => ({ value: p.id, label: `平台 #${p.id}` })),
|
platforms.value.map((p) => ({ value: p.id, label: cleanLabel(p.label, p.name, `平台 #${p.id}`) })),
|
||||||
)
|
)
|
||||||
|
|
||||||
const storeOptions = computed(() => {
|
const storeOptions = computed(() => {
|
||||||
@@ -32,7 +39,7 @@ const storeOptions = computed(() => {
|
|||||||
if (model.value.platform_id) {
|
if (model.value.platform_id) {
|
||||||
filtered = filtered.filter((s) => s.platform_id === model.value.platform_id)
|
filtered = filtered.filter((s) => s.platform_id === model.value.platform_id)
|
||||||
}
|
}
|
||||||
return filtered.map((s) => ({ value: s.id, label: s.label || s.name }))
|
return filtered.map((s) => ({ value: s.id, label: cleanLabel(s.label, s.name, `店铺 #${s.id}`) }))
|
||||||
})
|
})
|
||||||
|
|
||||||
function handleCompanyChange(val: unknown) {
|
function handleCompanyChange(val: unknown) {
|
||||||
@@ -85,44 +92,53 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex gap-2 items-center">
|
<div class="flex gap-4 items-center">
|
||||||
<a-select
|
<div class="flex items-center gap-1">
|
||||||
:value="model.company_id"
|
<span class="text-gray-600 text-sm whitespace-nowrap">公司</span>
|
||||||
:options="companyOptions"
|
<a-select
|
||||||
placeholder="选择公司"
|
:value="model.company_id"
|
||||||
allow-clear
|
:options="companyOptions"
|
||||||
show-search
|
placeholder="选择公司"
|
||||||
:filter-option="(input: string, option: unknown) =>
|
allow-clear
|
||||||
((option as { label: string }).label ?? '').toLowerCase().includes(input.toLowerCase())
|
show-search
|
||||||
"
|
:filter-option="(input: string, option: unknown) =>
|
||||||
:loading="loadingCompanies"
|
((option as { label: string }).label ?? '').toLowerCase().includes(input.toLowerCase())
|
||||||
style="min-width: 160px"
|
"
|
||||||
@change="handleCompanyChange"
|
:loading="loadingCompanies"
|
||||||
/>
|
style="min-width: 160px"
|
||||||
<a-select
|
@change="handleCompanyChange"
|
||||||
:value="model.platform_id"
|
/>
|
||||||
:options="platformOptions"
|
</div>
|
||||||
placeholder="选择平台"
|
<div class="flex items-center gap-1">
|
||||||
allow-clear
|
<span class="text-gray-600 text-sm whitespace-nowrap">平台</span>
|
||||||
show-search
|
<a-select
|
||||||
:filter-option="(input: string, option: unknown) =>
|
:value="model.platform_id"
|
||||||
((option as { label: string }).label ?? '').toLowerCase().includes(input.toLowerCase())
|
:options="platformOptions"
|
||||||
"
|
placeholder="选择平台"
|
||||||
style="min-width: 160px"
|
allow-clear
|
||||||
@change="handlePlatformChange"
|
show-search
|
||||||
/>
|
:filter-option="(input: string, option: unknown) =>
|
||||||
<a-select
|
((option as { label: string }).label ?? '').toLowerCase().includes(input.toLowerCase())
|
||||||
:value="model.store_id"
|
"
|
||||||
:options="storeOptions"
|
style="min-width: 160px"
|
||||||
placeholder="选择店铺"
|
@change="handlePlatformChange"
|
||||||
allow-clear
|
/>
|
||||||
show-search
|
</div>
|
||||||
:filter-option="(input: string, option: unknown) =>
|
<div class="flex items-center gap-1">
|
||||||
((option as { label: string }).label ?? '').toLowerCase().includes(input.toLowerCase())
|
<span class="text-gray-600 text-sm whitespace-nowrap">店铺</span>
|
||||||
"
|
<a-select
|
||||||
:loading="loadingStores"
|
:value="model.store_id"
|
||||||
style="min-width: 160px"
|
:options="storeOptions"
|
||||||
@change="handleStoreChange"
|
placeholder="选择店铺"
|
||||||
/>
|
allow-clear
|
||||||
|
show-search
|
||||||
|
:filter-option="(input: string, option: unknown) =>
|
||||||
|
((option as { label: string }).label ?? '').toLowerCase().includes(input.toLowerCase())
|
||||||
|
"
|
||||||
|
:loading="loadingStores"
|
||||||
|
style="min-width: 160px"
|
||||||
|
@change="handleStoreChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ async function handleViewDetail(record: { id: number }) {
|
|||||||
<h2 class="text-xl font-semibold mb-4">订单管理</h2>
|
<h2 class="text-xl font-semibold mb-4">订单管理</h2>
|
||||||
|
|
||||||
<!-- Filter area -->
|
<!-- Filter area -->
|
||||||
<a-card class="mb-4">
|
<a-card class="mb-6">
|
||||||
<a-form layout="inline" @submit.prevent="handleSearch">
|
<a-form layout="inline" @submit.prevent="handleSearch">
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<CascadeFilter v-model="store.cascadeValue" />
|
<CascadeFilter v-model="store.cascadeValue" />
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ async function handleViewDetail(record: { id: number }) {
|
|||||||
<h2 class="text-xl font-semibold mb-4">产品管理</h2>
|
<h2 class="text-xl font-semibold mb-4">产品管理</h2>
|
||||||
|
|
||||||
<!-- Filter area -->
|
<!-- Filter area -->
|
||||||
<a-card class="mb-4">
|
<a-card class="mb-6">
|
||||||
<a-form layout="inline" @submit.prevent="handleSearch">
|
<a-form layout="inline" @submit.prevent="handleSearch">
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<CascadeFilter v-model="store.cascadeValue" />
|
<CascadeFilter v-model="store.cascadeValue" />
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ async function handleViewDetail(record: { id: number }) {
|
|||||||
<h2 class="text-xl font-semibold mb-4">退款管理</h2>
|
<h2 class="text-xl font-semibold mb-4">退款管理</h2>
|
||||||
|
|
||||||
<!-- Filter area -->
|
<!-- Filter area -->
|
||||||
<a-card class="mb-4">
|
<a-card class="mb-6">
|
||||||
<a-form layout="inline" @submit.prevent="handleSearch">
|
<a-form layout="inline" @submit.prevent="handleSearch">
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<CascadeFilter v-model="store.cascadeValue" />
|
<CascadeFilter v-model="store.cascadeValue" />
|
||||||
|
|||||||
@@ -127,24 +127,24 @@ export const useOrderStore = defineStore('order', () => {
|
|||||||
|
|
||||||
// 名称映射数据
|
// 名称映射数据
|
||||||
const companies = ref<LookupItem[]>([])
|
const companies = ref<LookupItem[]>([])
|
||||||
const platforms = ref<{ id: number; developer_id: number }[]>([])
|
const platforms = ref<{ id: number; name: string; label?: string; developer_id: number }[]>([])
|
||||||
const stores = ref<(LookupItem & { company_id: number; platform_id: number })[]>([])
|
const stores = ref<(LookupItem & { company_id: number; platform_id: number })[]>([])
|
||||||
|
|
||||||
const companyMap = computed(
|
const companyMap = computed(
|
||||||
() => new Map(companies.value.map((c) => [c.id, c.label || c.name])),
|
() => new Map(companies.value.map((c) => [c.id, (c.label && c.label !== 'null') ? c.label : c.name])),
|
||||||
)
|
)
|
||||||
const platformMap = computed(
|
const platformMap = computed(
|
||||||
() => new Map(platforms.value.map((p) => [p.id, `平台 #${p.id}`])),
|
() => new Map(platforms.value.map((p) => [p.id, (p.label && p.label !== 'null') ? p.label : (p.name || `平台 #${p.id}`)])),
|
||||||
)
|
)
|
||||||
const storeMap = computed(
|
const storeMap = computed(
|
||||||
() => new Map(stores.value.map((s) => [s.id, s.label || s.name])),
|
() => new Map(stores.value.map((s) => [s.id, (s.label && s.label !== 'null') ? s.label : s.name])),
|
||||||
)
|
)
|
||||||
|
|
||||||
async function loadLookups() {
|
async function loadLookups() {
|
||||||
try {
|
try {
|
||||||
const [c, p, s] = await Promise.all([
|
const [c, p, s] = await Promise.all([
|
||||||
api.get<LookupItem[]>('/api/v1/companies'),
|
api.get<LookupItem[]>('/api/v1/companies'),
|
||||||
api.get<{ id: number; developer_id: number }[]>('/api/v1/platforms'),
|
api.get<{ id: number; name: string; label?: string; developer_id: number }[]>('/api/v1/platforms'),
|
||||||
api.get<(LookupItem & { company_id: number; platform_id: number })[]>(
|
api.get<(LookupItem & { company_id: number; platform_id: number })[]>(
|
||||||
'/api/v1/stores',
|
'/api/v1/stores',
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -85,19 +85,18 @@ export const useProductStore = defineStore('product', () => {
|
|||||||
|
|
||||||
// 名称映射数据
|
// 名称映射数据
|
||||||
const companies = ref<LookupItem[]>([])
|
const companies = ref<LookupItem[]>([])
|
||||||
const platforms = ref<{ id: number; developer_id: number }[]>([])
|
const platforms = ref<{ id: number; name: string; label?: string; developer_id: number }[]>([])
|
||||||
const stores = ref<(LookupItem & { company_id: number; platform_id: number })[]>([])
|
const stores = ref<(LookupItem & { company_id: number; platform_id: number })[]>([])
|
||||||
|
|
||||||
const companyMap = computed(() => new Map(companies.value.map((c) => [c.id, c.label || c.name])))
|
const companyMap = computed(() => new Map(companies.value.map((c) => [c.id, (c.label && c.label !== 'null') ? c.label : c.name])))
|
||||||
// platforms API 不返回 name 字段,使用 ID 作为显示标签
|
const platformMap = computed(() => new Map(platforms.value.map((p) => [p.id, (p.label && p.label !== 'null') ? p.label : (p.name || `平台 #${p.id}`)])))
|
||||||
const platformMap = computed(() => new Map(platforms.value.map((p) => [p.id, `平台 #${p.id}`])))
|
const storeMap = computed(() => new Map(stores.value.map((s) => [s.id, (s.label && s.label !== 'null') ? s.label : s.name])))
|
||||||
const storeMap = computed(() => new Map(stores.value.map((s) => [s.id, s.label || s.name])))
|
|
||||||
|
|
||||||
async function loadLookups() {
|
async function loadLookups() {
|
||||||
try {
|
try {
|
||||||
const [c, p, s] = await Promise.all([
|
const [c, p, s] = await Promise.all([
|
||||||
api.get<LookupItem[]>('/api/v1/companies'),
|
api.get<LookupItem[]>('/api/v1/companies'),
|
||||||
api.get<{ id: number; developer_id: number }[]>('/api/v1/platforms'),
|
api.get<{ id: number; name: string; label?: string; developer_id: number }[]>('/api/v1/platforms'),
|
||||||
api.get<(LookupItem & { company_id: number; platform_id: number })[]>('/api/v1/stores'),
|
api.get<(LookupItem & { company_id: number; platform_id: number })[]>('/api/v1/stores'),
|
||||||
])
|
])
|
||||||
companies.value = c
|
companies.value = c
|
||||||
|
|||||||
@@ -33,24 +33,24 @@ export const useRefundStore = defineStore('refund', () => {
|
|||||||
|
|
||||||
// 名称映射数据
|
// 名称映射数据
|
||||||
const companies = ref<LookupItem[]>([])
|
const companies = ref<LookupItem[]>([])
|
||||||
const platforms = ref<{ id: number; developer_id: number }[]>([])
|
const platforms = ref<{ id: number; name: string; label?: string; developer_id: number }[]>([])
|
||||||
const stores = ref<(LookupItem & { company_id: number; platform_id: number })[]>([])
|
const stores = ref<(LookupItem & { company_id: number; platform_id: number })[]>([])
|
||||||
|
|
||||||
const companyMap = computed(
|
const companyMap = computed(
|
||||||
() => new Map(companies.value.map((c) => [c.id, c.label || c.name])),
|
() => new Map(companies.value.map((c) => [c.id, (c.label && c.label !== 'null') ? c.label : c.name])),
|
||||||
)
|
)
|
||||||
const platformMap = computed(
|
const platformMap = computed(
|
||||||
() => new Map(platforms.value.map((p) => [p.id, `平台 #${p.id}`])),
|
() => new Map(platforms.value.map((p) => [p.id, (p.label && p.label !== 'null') ? p.label : (p.name || `平台 #${p.id}`)])),
|
||||||
)
|
)
|
||||||
const storeMap = computed(
|
const storeMap = computed(
|
||||||
() => new Map(stores.value.map((s) => [s.id, s.label || s.name])),
|
() => new Map(stores.value.map((s) => [s.id, (s.label && s.label !== 'null') ? s.label : s.name])),
|
||||||
)
|
)
|
||||||
|
|
||||||
async function loadLookups() {
|
async function loadLookups() {
|
||||||
try {
|
try {
|
||||||
const [c, p, s] = await Promise.all([
|
const [c, p, s] = await Promise.all([
|
||||||
api.get<LookupItem[]>('/api/v1/companies'),
|
api.get<LookupItem[]>('/api/v1/companies'),
|
||||||
api.get<{ id: number; developer_id: number }[]>('/api/v1/platforms'),
|
api.get<{ id: number; name: string; label?: string; developer_id: number }[]>('/api/v1/platforms'),
|
||||||
api.get<(LookupItem & { company_id: number; platform_id: number })[]>(
|
api.get<(LookupItem & { company_id: number; platform_id: number })[]>(
|
||||||
'/api/v1/stores',
|
'/api/v1/stores',
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user