import { useState, type CSSProperties } from 'react'; import { useNavigate, useOutletContext } from 'react-router-dom'; import { QuestionCircleOutlined } from '@ant-design/icons'; import { Button, Card, Col, Descriptions, Form, Input, Modal, Popconfirm, Row, Select, Space, Statistic, Tooltip, Typography, message, } from 'antd'; import { PROMO_CODE_SCENE_LABELS, PROMO_CODE_STATUS_LABELS, promoConversion, } from '@dukang/shared-types'; import { request } from '../../lib/api'; import { fmtTime } from '../../lib/constants'; import type { PromoCodeDetailContext } from './PromoCodeDetailLayout'; import PromoCodeMetricsPanel from './PromoCodeMetricsPanel'; const descLabelStyle: CSSProperties = { whiteSpace: 'nowrap', width: 108, }; const descContentStyle: CSSProperties = { wordBreak: 'break-all', }; const ATTRIBUTION_HINT = '首次触达本推广码的用户。每人只归因一次、只归一个码:已登录用户扫码或带参进入时,若还没有归因记录,则记到本码;之后再扫其他码不会改。与「扫码注册」不同:注册只统计来源仍是自然量并被标记为本码的用户;已有其他来源(如分享)的用户仍可计入归因,但不计入扫码注册。'; async function downloadQrcode(url: string, filename: string) { try { const res = await fetch(url); const blob = await res.blob(); const objectUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = objectUrl; a.download = filename; a.click(); URL.revokeObjectURL(objectUrl); } catch { window.open(url, '_blank'); } } export default function PromoCodeDetailPage() { const navigate = useNavigate(); const { detail, reload } = useOutletContext(); const [editForm] = Form.useForm(); const [editOpen, setEditOpen] = useState(false); const [saving, setSaving] = useState(false); const stats = detail.stats; async function handleEdit(values: Record) { setSaving(true); try { await request(`/admin/promo-codes/${detail.id}`, { method: 'PUT', body: JSON.stringify({ name: values.name, scene: values.scene, ownerUserId: values.ownerUserId?.trim() || null, remark: values.remark?.trim() || null, }), }); message.success('已保存'); setEditOpen(false); await reload(); } catch (e) { message.error(e instanceof Error ? e.message : '保存失败'); } finally { setSaving(false); } } return ( <> { await request(`/admin/promo-codes/${detail.id}/status`, { method: 'PUT', body: JSON.stringify({ status: detail.status === 'ACTIVE' ? 'DISABLED' : 'ACTIVE', }), }); message.success('状态已更新'); await reload(); }} > )} > {detail.name} {detail.code} {PROMO_CODE_SCENE_LABELS[detail.scene] || detail.scene} {PROMO_CODE_STATUS_LABELS[detail.status] || detail.status} {detail.id} {detail.qrcodeId} {detail.qrcodeUrl ? ( {detail.qrcodeUrl} ) : '—'} {detail.ownerUser?.userNo || detail.ownerUser?.phone || '—'} {detail.remark || '—'} {fmtTime(detail.createdAt)} {fmtTime(detail.updatedAt)} {detail.qrcodeUrl ? ( <> 推广小程序码 scene={detail.id} ) : ( 暂无小程序码 )} navigate(`/promo-codes/${detail.id}?eventType=SCAN`)} > 归因用户数 } value={stats?.attributionCount ?? 0} /> navigate(`/orders?promoCodeId=${detail.id}&status=COMPLETED`)} > 订单数 } value={stats?.orderCount ?? detail.orderCount} /> setEditOpen(false)} footer={null} destroyOnClose >
); }