From 8f25f823d5a0608c9715918f7f1df2e10743c40c Mon Sep 17 00:00:00 2001 From: jacy <18049821889@163.com> Date: Tue, 8 Sep 2026 14:23:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=97=A8=E5=BA=97=E7=9A=84?= =?UTF-8?q?=E5=A4=9A=E9=93=B6=E8=A1=8C=E8=B4=A6=E6=88=B7=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/StoreBankAccountsPanel.tsx | 178 ------------- apps/admin-web/src/layouts/AdminLayout.tsx | 2 +- apps/admin-web/src/pages/BankAccountsPage.tsx | 54 +++- apps/admin-web/src/pages/CityPartnersPage.tsx | 12 +- .../src/pages/FulfillmentProvidersPage.tsx | 15 +- apps/admin-web/src/pages/StoresPage.tsx | 20 +- .../src/pages/SystemSettingsPage.tsx | 30 ++- apps/h5-shop/src/App.tsx | 2 - apps/h5-shop/src/pages/BankAccountsPage.tsx | 252 ------------------ apps/h5-shop/src/pages/MinePage.tsx | 6 - docs/杜康好客-v4-PRD.md | 24 +- docs/杜康好客-v4-现状对照.md | 9 +- docs/杜康好客-v4.0.18-开发文档.md | 75 +++--- packages/shared-types/src/settlement.ts | 22 +- .../migrate-drop-store-bank-account-v4018.sql | 5 + server/dukang-api/prisma/schema.prisma | 20 -- .../src/common/store/store-bank.util.ts | 116 ++------ .../finance-bank-account.service.ts | 41 +-- .../settlement/finance-bank-export.util.ts | 11 +- .../modules/store/store-bank.controller.ts | 93 ------- .../src/modules/store/store-bank.service.ts | 121 --------- .../src/modules/store/store.module.ts | 8 +- 22 files changed, 214 insertions(+), 902 deletions(-) delete mode 100644 apps/admin-web/src/components/StoreBankAccountsPanel.tsx delete mode 100644 apps/h5-shop/src/pages/BankAccountsPage.tsx create mode 100644 server/dukang-api/prisma/migrate-drop-store-bank-account-v4018.sql delete mode 100644 server/dukang-api/src/modules/store/store-bank.controller.ts delete mode 100644 server/dukang-api/src/modules/store/store-bank.service.ts diff --git a/apps/admin-web/src/components/StoreBankAccountsPanel.tsx b/apps/admin-web/src/components/StoreBankAccountsPanel.tsx deleted file mode 100644 index 123b377..0000000 --- a/apps/admin-web/src/components/StoreBankAccountsPanel.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import { useCallback, useEffect, useState } from 'react'; -import { Button, Form, Input, Modal, Popconfirm, Space, Table, Tag, message } from 'antd'; -import type { ColumnsType } from 'antd/es/table'; -import type { StoreBankAccountDto } from '@dukang/shared-types'; -import { request } from '../lib/api'; - -type Props = { storeId: string }; - -type FormValues = { bankAccountName: string; bankAccountNo: string; bankBranch?: string }; - -export default function StoreBankAccountsPanel({ storeId }: Props) { - const [form] = Form.useForm(); - const [items, setItems] = useState([]); - const [loading, setLoading] = useState(false); - const [editingId, setEditingId] = useState(null); - const [modalOpen, setModalOpen] = useState(false); - const [submitting, setSubmitting] = useState(false); - - const load = useCallback(async () => { - setLoading(true); - try { - const res = await request(`/admin/stores/${storeId}/bank-accounts`); - setItems(res ?? []); - } catch (e) { - message.error(e instanceof Error ? e.message : '加载失败'); - } finally { - setLoading(false); - } - }, [storeId]); - - useEffect(() => { - void load(); - }, [load]); - - function openCreate() { - setEditingId(null); - form.resetFields(); - setModalOpen(true); - } - - function openEdit(item: StoreBankAccountDto) { - setEditingId(item.id); - form.setFieldsValue({ - bankAccountName: item.bankAccountName, - bankAccountNo: item.bankAccountNo, - bankBranch: item.bankBranch ?? '', - }); - setModalOpen(true); - } - - async function submit() { - const v = await form.validateFields(); - setSubmitting(true); - try { - const body = JSON.stringify({ - bankAccountName: v.bankAccountName.trim(), - bankAccountNo: v.bankAccountNo.replace(/\s+/g, ''), - bankBranch: v.bankBranch?.trim() || undefined, - }); - if (editingId) { - await request(`/admin/stores/${storeId}/bank-accounts/${editingId}`, { method: 'PUT', body }); - } else { - await request(`/admin/stores/${storeId}/bank-accounts`, { method: 'POST', body }); - } - message.success('已保存'); - setModalOpen(false); - void load(); - } catch (e) { - message.error(e instanceof Error ? e.message : '保存失败'); - } finally { - setSubmitting(false); - } - } - - async function setDefault(id: string) { - try { - await request(`/admin/stores/${storeId}/bank-accounts/${id}/default`, { method: 'POST' }); - message.success('已设为默认打款账户'); - void load(); - } catch (e) { - message.error(e instanceof Error ? e.message : '设置失败'); - } - } - - async function remove(id: string) { - try { - await request(`/admin/stores/${storeId}/bank-accounts/${id}`, { method: 'DELETE' }); - message.success('已删除'); - void load(); - } catch (e) { - message.error(e instanceof Error ? e.message : '删除失败'); - } - } - - const columns: ColumnsType = [ - { title: '收款人', dataIndex: 'bankAccountName', width: 140 }, - { title: '银行账号', dataIndex: 'bankAccountNo', width: 180 }, - { title: '开户行', dataIndex: 'bankBranch', render: (v) => v || '—' }, - { - title: '默认', - dataIndex: 'isDefault', - width: 80, - render: (v) => (v ? 默认 : null), - }, - { - title: '操作', - width: 220, - render: (_, row) => ( - - - {!row.isDefault ? ( - - ) : null} - {!row.isDefault ? ( - void remove(row.id)} - > - - - ) : null} - - ), - }, - ]; - - return ( -
- - - 每门店可维护多个收款账户,标记「默认」的账户用于核销结算与提现打款;切换即时生效、无需重启服务。 - - - - - setModalOpen(false)} - onOk={() => void submit()} - okText="保存" - > -
- - - - - - - - - - -
- - ); -} diff --git a/apps/admin-web/src/layouts/AdminLayout.tsx b/apps/admin-web/src/layouts/AdminLayout.tsx index 55bf212..9deb398 100644 --- a/apps/admin-web/src/layouts/AdminLayout.tsx +++ b/apps/admin-web/src/layouts/AdminLayout.tsx @@ -86,7 +86,7 @@ const MENU_ITEMS: MenuProps['items'] = [ { key: '/finance/partner-bills', label: '合伙人账单' }, { key: '/finance/winery-bills', label: '酒厂账单' }, { key: '/finance/logistics-bills', label: '物流对账' }, - { key: '/finance/bank-accounts', label: '银行账户' }, + { key: '/finance/bank-accounts', label: '全部银行账户' }, ], }, { diff --git a/apps/admin-web/src/pages/BankAccountsPage.tsx b/apps/admin-web/src/pages/BankAccountsPage.tsx index 99f4a75..ccc9cd3 100644 --- a/apps/admin-web/src/pages/BankAccountsPage.tsx +++ b/apps/admin-web/src/pages/BankAccountsPage.tsx @@ -1,4 +1,5 @@ import { useEffect, useMemo, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; import { Button, Form, @@ -24,6 +25,7 @@ import { downloadBase64File } from '../lib/exportExcel'; import { useAdminList } from '../lib/useAdminList'; import { useAdminListColumns } from '../lib/useAdminListColumns'; import { AdminListHeader } from '../components/AdminListHeader'; +import { AdminPrimaryLink } from '../components/AdminPrimaryLink'; type CityOption = { id: string; name: string }; @@ -55,6 +57,7 @@ function otherNumericId(id: string) { } export default function BankAccountsPage() { + const navigate = useNavigate(); const [filterForm] = Form.useForm<{ type?: FinanceBankAccountType; cityId?: string; @@ -198,17 +201,42 @@ export default function BankAccountsPage() { {FINANCE_BANK_ACCOUNT_TYPE_LABELS[type]} ), }, - { title: '归属', dataIndex: 'ownerName', width: 180 }, - { title: '城市', dataIndex: 'cityName', width: 100, render: (v?: string | null) => v || '—' }, - { title: '户名', dataIndex: 'bankAccountName', width: 140 }, - { title: '银行账号', dataIndex: 'bankAccountNo', width: 180 }, - { title: '开户行', dataIndex: 'bankBranch', width: 180, render: (v?: string | null) => v || '—' }, { - title: '默认', - dataIndex: 'isDefault', - width: 72, - render: (v: boolean | undefined, row) => (row.type === 'STORE' ? (v ? '是' : '否') : '—'), + title: '归属', + dataIndex: 'ownerName', + width: 180, + render: (name: string, row) => ( + { + if (row.type === 'STORE' && row.ownerId) { + navigate(`/stores?storeId=${encodeURIComponent(row.ownerId)}&tab=settlement`); + return; + } + if (row.type === 'WINERY') { + navigate('/system-settings?group=winery_bank'); + return; + } + if (row.type === 'PARTNER' && row.ownerId) { + navigate(`/city-partners?partnerId=${encodeURIComponent(row.ownerId)}`); + return; + } + if (row.type === 'LOGISTICS' && row.ownerId) { + navigate(`/fulfillment-providers?id=${encodeURIComponent(row.ownerId)}`); + return; + } + if (row.type === 'OTHER') { + openEdit(row); + } + }} + > + {name} + + ), }, + { title: '城市', dataIndex: 'cityName', width: 100, render: (v?: string | null) => v || '—' }, + { title: '结算户名', dataIndex: 'bankAccountName', width: 140 }, + { title: '银行账号', dataIndex: 'bankAccountNo', width: 180 }, + { title: '开户银行', dataIndex: 'bankBranch', width: 180, render: (v?: string | null) => v || '—' }, { title: '备注', dataIndex: 'remark', width: 200, render: (v?: string | null) => v || '—' }, { title: '操作', @@ -251,8 +279,8 @@ export default function BankAccountsPage() {
{settingsModal} @@ -287,7 +315,7 @@ export default function BankAccountsPage() { /> - + -

收款账户

- - -
-

- 用于总部打款,可维护多个账户;标记「默认」的账户用于提现打款,切换即时生效、无需重启。 -

- - {loading ? ( -

加载中…

- ) : items.length === 0 ? ( -

暂无收款账户{isPrimary ? ',请新增' : ''}

- ) : ( -
- {items.map((it) => ( -
-
-
-
- 收款人 - {it.bankAccountName} - {it.isDefault ? ( - 默认 - ) : null} -
-

账号: {it.bankAccountNo}

- {it.bankBranch ?

开户行: {it.bankBranch}

: null} -
-
- {isPrimary ? ( -
- - {!it.isDefault ? ( - - ) : null} - {!it.isDefault ? ( - - ) : null} -
- ) : null} -
- ))} -
- )} - - {isPrimary ? ( -
-

- {editing ? '编辑账户' : '新增账户'} -

-
- - setForm({ ...form, bankAccountName: e.target.value })} - /> - {fieldErrors.bankAccountName ? ( -

{fieldErrors.bankAccountName}

- ) : null} - - - setForm({ ...form, bankAccountNo: e.target.value.replace(/[^\d]/g, '') })} - /> - {fieldErrors.bankAccountNo ? ( -

{fieldErrors.bankAccountNo}

- ) : null} - - - setForm({ ...form, bankBranch: e.target.value })} - /> - -
- - {editing ? ( - - ) : null} -
-
-
- ) : ( -

仅主账号可维护收款账户

- )} - - {msg ?

{msg}

: null} -
-
- ); -} diff --git a/apps/h5-shop/src/pages/MinePage.tsx b/apps/h5-shop/src/pages/MinePage.tsx index 304c8a9..471cf12 100644 --- a/apps/h5-shop/src/pages/MinePage.tsx +++ b/apps/h5-shop/src/pages/MinePage.tsx @@ -153,12 +153,6 @@ export default function MinePage() { account_balance_wallet 结算提现 - {profile?.isPrimary ? ( - - ) : null} {profile?.isPrimary ? (