v4.0.20版本迭代推广码增加渠道负责人

This commit is contained in:
2026-09-17 09:06:29 +08:00
parent 1867e7ea55
commit b9921b1a75
36 changed files with 12138 additions and 112 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@dukang/h5-partner",
"version": "4.0.19",
"version": "4.0.20",
"private": true,
"type": "module",
"scripts": {
+2
View File
@@ -26,6 +26,7 @@ import UsersManagePage from './pages/UsersManagePage';
import AssocOrdersPage from './pages/AssocOrdersPage';
import CommissionOrdersPage from './pages/CommissionOrdersPage';
import ActivityPostersPage from './pages/ActivityPostersPage';
import PromoCodesPage from './pages/PromoCodesPage';
import BankAccountPage from './pages/BankAccountPage';
function PrimaryRoutes() {
@@ -45,6 +46,7 @@ function PrimaryRoutes() {
<Route path="/center/staff/new" element={<StaffCreatePage />} />
<Route path="/center/bank" element={<BankAccountPage />} />
<Route path="/center/activity-posters" element={<ActivityPostersPage />} />
<Route path="/center/promo-codes" element={<PromoCodesPage />} />
<Route path="/center/assoc" element={<Navigate to="/users" replace />} />
<Route path="/center/assoc/users" element={<Navigate to="/users" replace />} />
<Route path="/users/orders" element={<AssocOrdersPage />} />
+9
View File
@@ -258,6 +258,15 @@ export default function CenterPage({ variant = 'primary', roleLabel }: CenterPag
</div>
<span className="material-symbols-outlined text-muted">chevron_right</span>
</Link>
<Link to="/center/promo-codes" className="partner-menu-item">
<div className="partner-menu-item-left">
<div className="partner-menu-icon">
<span className="material-symbols-outlined">qr_code_2</span>
</div>
<span className="body-md" style={{ fontSize: 16 }}>推广码数据</span>
</div>
<span className="material-symbols-outlined text-muted">chevron_right</span>
</Link>
<Link to="/users" className="partner-menu-item">
<div className="partner-menu-item-left">
<div className="partner-menu-icon">
@@ -0,0 +1,77 @@
import { useCallback, useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import PageHeader from '@dukang/shared-ui/PageHeader';
import PullToRefresh from '@dukang/shared-ui/PullToRefresh';
import { PROMO_CODE_STATUS_LABELS, type PartnerPromoCodeItem } from '@dukang/shared-types';
import { request } from '../lib/api';
import { toastError } from '../lib/toast';
import { usePartnerPageView } from '../lib/usePageView';
type ListRes = { items: PartnerPromoCodeItem[] };
export default function PromoCodesPage() {
usePartnerPageView('partner_promo_codes_view');
const navigate = useNavigate();
const [items, setItems] = useState<PartnerPromoCodeItem[]>([]);
const [loading, setLoading] = useState(true);
const load = useCallback(async () => {
setLoading(true);
try {
const res = await request<ListRes>('PARTNER_H5', '/partner/promo-codes');
setItems(res.items ?? []);
} catch (e) {
toastError(e instanceof Error ? e.message : '加载失败');
setItems([]);
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
document.title = '推广码数据';
}, []);
useEffect(() => {
void load();
}, [load]);
return (
<PullToRefresh onRefresh={load}>
<PageHeader title="推广码数据" onBack={() => navigate(-1)} />
<div style={{ padding: '0 20px 24px' }}>
<p className="label-md text-muted" style={{ margin: '12px 0' }}>
{loading ? '加载中…' : `仅展示扫码人数、归因人数、订单数量`}
</p>
{!loading && items.length === 0 && <div className="empty">暂无负责的推广码</div>}
{items.map((row) => (
<div key={row.id} className="partner-store-card" style={{ marginBottom: 12 }}>
<div className="partner-store-card-header">
<div>
<p className="body-md">{row.name}</p>
<p className="label-md text-muted">
{row.code}
{row.status !== 'ACTIVE' ? ` · ${PROMO_CODE_STATUS_LABELS[row.status] || row.status}` : ''}
</p>
</div>
</div>
<div style={{ display: 'flex', gap: 16, marginTop: 8 }}>
<div>
<p className="label-md text-muted">扫码人数</p>
<p className="body-md">{row.scanCount}</p>
</div>
<div>
<p className="label-md text-muted">归因人数</p>
<p className="body-md">{row.attributionCount}</p>
</div>
<div>
<p className="label-md text-muted">订单数量</p>
<p className="body-md">{row.orderCount}</p>
</div>
</div>
</div>
))}
</div>
</PullToRefresh>
);
}
+1 -1
View File
@@ -16,7 +16,7 @@ export default defineConfig({
host: true,
port: 5175,
proxy: {
'/api': process.env.VITE_API_TARGET ?? 'http://localhost:3010',
'/api': process.env.VITE_API_TARGET ?? 'http://127.0.0.1:3010',
},
},
});