v3.5.8和v3.5.9版本更新
CI / verify (pull_request) Waiting to run

This commit is contained in:
2026-08-25 09:20:32 +08:00
parent 7304c7a8e1
commit 5935024ea8
101 changed files with 7640 additions and 5364 deletions
+46 -23
View File
@@ -39,6 +39,7 @@ import {
type StoreCreateForm,
} from '../lib/storeCreate';
import { useAdminList } from '../lib/useAdminList';
import { useAdminListColumns } from '../lib/useAdminListColumns';
import { resolveRegionBinding } from '../lib/china-region';
import ChinaRegionCascader from '../components/ChinaRegionCascader';
import OssUpload from '../components/OssUpload';
@@ -198,6 +199,9 @@ type StoreRow = {
pendingPackageAuditId?: string | null;
/** 该门店当前待审核信息变更的 requestId(无则为空) */
pendingInfoChangeId?: string | null;
/** 累计核销好客权益(券面额合计) */
totalRedeemedBenefitAmount?: number;
contactPhone?: string | null;
isTest?: boolean;
cityRef?: { name: string; code: string };
partner?: { id?: string; companyName?: string | null; name?: string | null; phone?: string | null };
@@ -720,47 +724,60 @@ export default function StoresPage() {
}
}
const columns: ColumnsType<StoreRow> = [
const baseColumns: ColumnsType<StoreRow> = [
{
key: 'coverUrl',
title: '封面', dataIndex: 'coverUrl', width: 72,
render: (url) => url ? <Image src={url} width={48} height={48} style={{ objectFit: 'cover', borderRadius: 4 }} /> : '—',
},
{
key: 'name',
title: '门店名',
dataIndex: 'name',
width: 180,
ellipsis: { showTitle: false },
render: (v: string, row) => {
const name = v || '—';
return (
<Space size={4} style={{ maxWidth: '100%' }} wrap={false}>
<Typography.Text ellipsis={{ tooltip: name }} style={{ maxWidth: row.isTest ? 110 : 160 }}>
{name}
</Typography.Text>
<Space size={4} wrap={false}>
<span>{name}</span>
{row.isTest ? <Tag color="orange"></Tag> : null}
</Space>
);
},
},
{
key: 'category',
title: '分类',
width: 100,
ellipsis: true,
render: (_, row) => row.category?.name || '—',
},
{ title: '城市', dataIndex: 'cityName', width: 80, ellipsis: true },
{ title: '登录号', dataIndex: 'phone', width: 120 },
{ key: 'cityName', title: '城市', dataIndex: 'cityName', width: 80 },
{ key: 'phone', title: '登录号', dataIndex: 'phone', width: 120 },
{
key: 'contactPhone',
title: '联系电话',
dataIndex: 'contactPhone',
width: 120,
render: (v: string | null | undefined, row) => v || row.phone,
},
{
key: 'status',
title: '营业状态', dataIndex: 'status', width: 90,
render: (s) => <Tag>{STORE_STATUS_LABELS[s] || s}</Tag>,
},
{
key: 'totalRedeemedBenefitAmount',
title: '累计核销好客权益',
dataIndex: 'totalRedeemedBenefitAmount',
width: 150,
align: 'right',
render: (v: number | undefined) => {
const n = Number(v ?? 0);
return n > 0 ? `¥${n.toFixed(2)}` : '—';
},
},
{
key: 'auditStatus',
title: '审核', dataIndex: 'auditStatus', width: 100,
render: (s, row) => {
const status = s || 'APPROVED';
@@ -769,7 +786,7 @@ export default function StoresPage() {
<Space direction="vertical" size={0} style={{ maxWidth: '100%' }}>
<Tag color={color}>{STORE_AUDIT_STATUS_LABELS[status] || status}</Tag>
{status === 'REJECTED' && row.rejectReason ? (
<Typography.Text type="secondary" style={{ fontSize: 12, maxWidth: 88 }} ellipsis={{ tooltip: row.rejectReason }}>
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
{row.rejectReason}
</Typography.Text>
) : null}
@@ -778,32 +795,29 @@ export default function StoresPage() {
},
},
{
key: 'partner',
title: '开城合伙人',
dataIndex: 'partner',
width: 140,
ellipsis: { showTitle: false },
render: (partner: StoreRow['partner']) => {
if (!partner) return '—';
const label = partnerOptionLabel({ id: partner.id ?? '', ...partner });
return (
<Typography.Text ellipsis={{ tooltip: label }} style={{ maxWidth: 124 }}>
{label}
</Typography.Text>
);
return partnerOptionLabel({ id: partner.id ?? '', ...partner });
},
},
{
key: 'visibilityWhitelistEnabled',
title: '可见',
dataIndex: 'visibilityWhitelistEnabled',
width: 90,
render: (v) =>
v ? <Tag color="orange"></Tag> : <Tag></Tag>,
},
{ title: '介绍', dataIndex: 'intro', width: 160, ellipsis: true, render: (v) => v || '—' },
{ title: '排序', dataIndex: 'sortOrder', width: 70 },
{ title: '店长', dataIndex: ['account', 'name'], width: 90, ellipsis: true, render: (v) => v || '—' },
{ title: '创建', dataIndex: 'createdAt', width: 160, render: fmtTime },
{ key: 'intro', title: '介绍', dataIndex: 'intro', width: 160, render: (v) => v || '—' },
{ key: 'sortOrder', title: '排序', dataIndex: 'sortOrder', width: 70 },
{ key: 'accountName', title: '店长', dataIndex: ['account', 'name'], width: 90, render: (v) => v || '—' },
{ key: 'createdAt', title: '创建', dataIndex: 'createdAt', width: 160, render: fmtTime },
{
key: 'actions',
title: '操作',
width: 280,
fixed: 'right',
@@ -850,14 +864,23 @@ export default function StoresPage() {
},
];
const { columns, settingsButton, settingsModal } = useAdminListColumns('stores', baseColumns, {
page,
pageSize,
});
return (
<div>
{settingsModal}
<Space style={{ marginBottom: 16, width: '100%', justifyContent: 'space-between' }}>
<Space direction="vertical" size={0}>
<Typography.Title level={4} style={{ margin: 0 }}></Typography.Title>
<Typography.Text type="secondary"> {data?.total ?? 0} </Typography.Text>
</Space>
<Button type="primary" onClick={openCreateModal}></Button>
<Space>
{settingsButton}
<Button type="primary" onClick={openCreateModal}></Button>
</Space>
</Space>
<Form form={form} layout="inline" style={{ marginBottom: 16 }} onFinish={(v) => { setFilters(v); setPage(1); }}>
<Form.Item name="name" label="名称"><Input allowClear /></Form.Item>
@@ -918,7 +941,7 @@ export default function StoresPage() {
loading={loading}
columns={columns}
dataSource={data?.items ?? []}
scroll={{ x: 1720 }}
scroll={{ x: 'max-content' }}
pagination={{
current: page,
pageSize,