From 63af3321dd98f04328523f2635d0aa8bca43435c Mon Sep 17 00:00:00 2001 From: jacy-dukang Date: Sun, 12 Jul 2026 13:29:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(admin):=20HQ=E6=89=8B=E6=9C=BA=E5=8F=B7?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E3=80=81=E5=90=88=E4=BC=99=E4=BA=BA=E5=AD=90?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E6=97=A5=E5=BF=97=E4=B8=8E=E5=AD=90=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7H5=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 支持 HQ 账户改手机号(格式校验)、合伙人日志包含子账号且子账号不显示主账号信息;改手机号时清除微信绑定。合伙人 H5 子账号页签与我的页、录入门店底部按钮及上传失败提示。 Co-authored-by: Cursor --- apps/admin-web/src/pages/HqAccountsPage.tsx | 11 ++ apps/admin-web/src/pages/PartnerLogsPage.tsx | 18 +++- apps/h5-partner/src/PartnerAppRoutes.tsx | 3 + .../src/components/OssUploadField.tsx | 16 ++- .../src/layouts/SubAccountLayout.tsx | 19 +--- apps/h5-partner/src/lib/partnerAccess.ts | 2 +- apps/h5-partner/src/pages/PartnerMePage.tsx | 102 ++++++++++++++++++ apps/h5-partner/src/pages/StoreCreatePage.tsx | 7 +- apps/h5-partner/src/styles.css | 9 ++ packages/shared-types/src/partner-log.ts | 2 + packages/shared-types/src/partner.ts | 4 + .../modules/ops/admin-hq-accounts.service.ts | 12 +++ .../modules/ops/admin-partner-logs.service.ts | 53 +++++++-- .../src/modules/ops/admin-partners.service.ts | 8 ++ .../src/modules/ops/dto/admin-mutate.dto.ts | 4 + .../settlement/settlement.controller.ts | 29 ++++- 16 files changed, 259 insertions(+), 40 deletions(-) create mode 100644 apps/h5-partner/src/pages/PartnerMePage.tsx diff --git a/apps/admin-web/src/pages/HqAccountsPage.tsx b/apps/admin-web/src/pages/HqAccountsPage.tsx index 3e53760..2c62656 100644 --- a/apps/admin-web/src/pages/HqAccountsPage.tsx +++ b/apps/admin-web/src/pages/HqAccountsPage.tsx @@ -77,6 +77,7 @@ export default function HqAccountsPage() { setDetail(row); editForm.setFieldsValue({ name: row.name, + phone: row.phone, loginName: row.loginName, adminRole: row.adminRole, status: row.status, @@ -128,6 +129,16 @@ export default function HqAccountsPage() { }>
+ + + diff --git a/apps/admin-web/src/pages/PartnerLogsPage.tsx b/apps/admin-web/src/pages/PartnerLogsPage.tsx index 02ba7a8..4855756 100644 --- a/apps/admin-web/src/pages/PartnerLogsPage.tsx +++ b/apps/admin-web/src/pages/PartnerLogsPage.tsx @@ -5,9 +5,11 @@ import { useSearchParams } from 'react-router-dom'; import { PARTNER_LOG_CATEGORY_OPTIONS, PARTNER_LOG_CATEGORY_LABELS, + PARTNER_STAFF_ROLE_LABELS, resolvePartnerLogCategory, type PartnerLogCategory, -} from '../lib/partner-log'; + type PartnerStaffRole, +} from '@dukang/shared-types'; import { request } from '../lib/api'; import { AdminCellLine } from '../components/AdminCellLine'; import { fmtTime } from '../lib/constants'; @@ -20,6 +22,8 @@ type Row = { accountName: string | null; accountPhone: string | null; companyName: string | null; + isSubAccount?: boolean; + staffRole?: string | null; category: PartnerLogCategory | null; eventName: string; clientApp: string | null; @@ -74,7 +78,11 @@ export default function PartnerLogsPage() { width: 180, ellipsis: true, render: (_, r) => ( - + r.isSubAccount ? ( + 子账号 + ) : ( + + ) ), }, { @@ -84,7 +92,11 @@ export default function PartnerLogsPage() { render: (_, r) => ( ), }, diff --git a/apps/h5-partner/src/PartnerAppRoutes.tsx b/apps/h5-partner/src/PartnerAppRoutes.tsx index d673bc9..981ab3f 100644 --- a/apps/h5-partner/src/PartnerAppRoutes.tsx +++ b/apps/h5-partner/src/PartnerAppRoutes.tsx @@ -10,6 +10,7 @@ import StoreCreatePage from './pages/StoreCreatePage'; import OrderListPage from './pages/OrderListPage'; import OrderDetailPage from './pages/OrderDetailPage'; import CenterPage from './pages/CenterPage'; +import PartnerMePage from './pages/PartnerMePage'; import BillsPage from './pages/BillsPage'; import SettlementPage from './pages/SettlementPage'; import ReshipPage from './pages/ReshipPage'; @@ -17,6 +18,7 @@ import WeeklyReportPage from './pages/WeeklyReportPage'; import ProxyOrderPage from './pages/ProxyOrderPage'; import StaffListPage from './pages/StaffListPage'; import StaffCreatePage from './pages/StaffCreatePage'; +import LeaderboardPage from './pages/LeaderboardPage'; function PrimaryRoutes() { return ( @@ -50,6 +52,7 @@ function SubAccountRoutes() { } /> } /> } /> + } /> } /> diff --git a/apps/h5-partner/src/components/OssUploadField.tsx b/apps/h5-partner/src/components/OssUploadField.tsx index a961841..6e82c87 100644 --- a/apps/h5-partner/src/components/OssUploadField.tsx +++ b/apps/h5-partner/src/components/OssUploadField.tsx @@ -10,6 +10,7 @@ import { } from '../lib/wechat-auth'; import { formatChooseImageFailMessage } from '@dukang/weixin-sdk'; import { isWechatEnv, weixinSdk } from '../lib/weixin'; +import { toastError } from '../lib/toast'; import type { ClientRuntimeConfig } from '@dukang/shared-types'; type OssUploadFieldProps = { @@ -61,6 +62,11 @@ export default function OssUploadField({ const [profile, setProfile] = useState(null); const [clientConfig, setClientConfig] = useState(null); + function showUploadError(text: string) { + setError(text); + toastError(text); + } + const resolvedAccept = accept ?? (mediaType === 'VIDEO' ? 'video/*' : mediaType === 'FILE' ? 'image/*,.pdf' : 'image/*'); const inWechat = isWechatEnv(); @@ -91,7 +97,7 @@ export default function OssUploadField({ async function uploadSelectedFile(file: File) { if (file.size > DEFAULT_MAX_MB * 1024 * 1024) { const text = `文件不能超过 ${DEFAULT_MAX_MB}MB`; - setError(text); + showUploadError(text); return; } setUploading(true); @@ -100,7 +106,7 @@ export default function OssUploadField({ const result = await enqueueUpload(() => uploadFileToOss(file, { bizType, mediaType })); onChange?.(result.url); } catch (e) { - setError(e instanceof Error ? e.message : '上传失败'); + showUploadError(e instanceof Error ? e.message : '上传失败'); } finally { setUploading(false); if (inputRef.current) inputRef.current.value = ''; @@ -114,7 +120,7 @@ export default function OssUploadField({ await authorizePartnerWechat(); } catch (e) { const text = e instanceof Error ? e.message : '微信授权失败'; - setError(text); + showUploadError(text); setAuthorizing(false); } } @@ -149,7 +155,7 @@ export default function OssUploadField({ if (useWechatPicker && needsAuth) { const text = '请先完成微信授权后再上传照片'; - setError(text); + showUploadError(text); return; } @@ -159,7 +165,7 @@ export default function OssUploadField({ } catch (e) { const msg = e instanceof Error ? e.message : '无法打开相册'; if (/cancel/i.test(msg)) return; - setError(formatWechatUploadError(e)); + showUploadError(formatWechatUploadError(e)); } return; } diff --git a/apps/h5-partner/src/layouts/SubAccountLayout.tsx b/apps/h5-partner/src/layouts/SubAccountLayout.tsx index 598b7c5..f1cf4f3 100644 --- a/apps/h5-partner/src/layouts/SubAccountLayout.tsx +++ b/apps/h5-partner/src/layouts/SubAccountLayout.tsx @@ -1,27 +1,14 @@ import { NavLink, Outlet } from 'react-router-dom'; -import { usePartnerSession } from '../contexts/PartnerSessionContext'; const TABS = [ - { to: '/stores/new', icon: 'add_business', label: '录入新店' }, - { to: '/stores', end: true, icon: 'store', label: '我的门店' }, + { to: '/stores', end: true, icon: 'store', label: '门店管理' }, + { to: '/stores/new', icon: 'add_business', label: '录入门店' }, + { to: '/me', icon: 'person', label: '我的' }, ] as const; export default function SubAccountLayout() { - const { account, logout } = usePartnerSession(); - return ( <> -
-
-
-

{account?.name || '拓店账号'}

-

{account?.companyName || '门店入驻'}

-
- -
-