diff --git a/apps/admin-web/src/components/RedeemRecordDetailDescriptions.tsx b/apps/admin-web/src/components/RedeemRecordDetailDescriptions.tsx index 39f7b42..0aa30ca 100644 --- a/apps/admin-web/src/components/RedeemRecordDetailDescriptions.tsx +++ b/apps/admin-web/src/components/RedeemRecordDetailDescriptions.tsx @@ -15,7 +15,13 @@ type Props = { export default function RedeemRecordDetailDescriptions({ detail, maskUserPhone = false }: Props) { const user = detail.user as - | { userNo?: string; nickname?: string | null; phone?: string | null } + | { + id?: string; + userNo?: string; + nickname?: string | null; + phone?: string | null; + hqRemark?: string | null; + } | undefined; const store = detail.store as | { @@ -41,7 +47,13 @@ export default function RedeemRecordDetailDescriptions({ detail, maskUserPhone = ¥{Number(detail.settleAmount ?? 0).toFixed(2)} {fmtTime(String(detail.createdAt ?? ''))} {user?.userNo ?? '—'} - {user?.nickname?.trim() || '—'} + + {(() => { + const name = user?.nickname?.trim() || '—'; + const remark = user?.hqRemark?.trim(); + return remark ? `${name}(${remark})` : name; + })()} + {maskUserPhone ? maskPhone(user?.phone) : user?.phone || '—'} diff --git a/apps/admin-web/src/pages/BenefitCouponsPage.tsx b/apps/admin-web/src/pages/BenefitCouponsPage.tsx index 19e4b31..e37c9d5 100644 --- a/apps/admin-web/src/pages/BenefitCouponsPage.tsx +++ b/apps/admin-web/src/pages/BenefitCouponsPage.tsx @@ -1,5 +1,5 @@ -import { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; +import { useEffect, useRef, useState } from 'react'; +import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'; import { Button, Descriptions, @@ -111,9 +111,16 @@ type CouponDetail = Row & { export default function BenefitCouponsPage() { const navigate = useNavigate(); + const location = useLocation(); + const [searchParams] = useSearchParams(); + const initialCouponNo = searchParams.get('couponNo')?.trim() || ''; const [form] = Form.useForm(); const [grantForm] = Form.useForm(); - const [filters, setFilters] = useState>({}); + const [filters, setFilters] = useState>(() => { + const init: Record = {}; + if (initialCouponNo) init.couponNo = initialCouponNo; + return init; + }); const [grantOpen, setGrantOpen] = useState(false); const [granting, setGranting] = useState(false); const { data, loading, page, pageSize, setPage, setPageSize, reload } = useAdminList( @@ -132,6 +139,35 @@ export default function BenefitCouponsPage() { const [redeemDetail, setRedeemDetail] = useState | null>(null); const [redeemDrawerOpen, setRedeemDrawerOpen] = useState(false); const [redeemDetailLoading, setRedeemDetailLoading] = useState(false); + const deepLinkOpenedRef = useRef(false); + + async function openCouponDetail(id: string) { + setDetail(await request(`/admin/benefit/coupons/${id}`)); + setDrawerOpen(true); + } + + useEffect(() => { + if (initialCouponNo) form.setFieldsValue({ couponNo: initialCouponNo }); + }, [form, initialCouponNo]); + + useEffect(() => { + const openCouponId = (location.state as { openCouponId?: string } | null)?.openCouponId; + if (openCouponId && !deepLinkOpenedRef.current) { + deepLinkOpenedRef.current = true; + void openCouponDetail(openCouponId).catch((e) => { + message.error(e instanceof Error ? e.message : '加载权益券失败'); + }); + return; + } + if (!initialCouponNo || deepLinkOpenedRef.current || loading) return; + const first = data?.items?.[0]; + if (first && String(first.couponNo) === initialCouponNo) { + deepLinkOpenedRef.current = true; + void openCouponDetail(first.id).catch((e) => { + message.error(e instanceof Error ? e.message : '加载权益券失败'); + }); + } + }, [data, initialCouponNo, loading, location.state]); async function openRedeemDetail(redeemId: string) { setRedeemDetailLoading(true); @@ -154,12 +190,7 @@ export default function BenefitCouponsPage() { width: 200, ellipsis: false, render: (v, row) => ( - { - setDetail(await request(`/admin/benefit/coupons/${row.id}`)); - setDrawerOpen(true); - }} - > + void openCouponDetail(row.id)}> {v} ), @@ -211,10 +242,7 @@ export default function BenefitCouponsPage() { diff --git a/apps/admin-web/src/pages/DevPlanTasksPage.tsx b/apps/admin-web/src/pages/DevPlanTasksPage.tsx index 809aaf4..c3d23de 100644 --- a/apps/admin-web/src/pages/DevPlanTasksPage.tsx +++ b/apps/admin-web/src/pages/DevPlanTasksPage.tsx @@ -71,11 +71,11 @@ export default function DevPlanTasksPage() { const [batchForm] = Form.useForm<{ status?: DevPlanTaskStatusDto; versionId?: string }>(); useEffect(() => { - if (!batchEditOpen) return; + if (!modalOpen && !batchEditOpen) return; request<{ items: DevPlanVersionDto[] }>('/admin/dev-plan/versions?pageSize=100') .then((res) => setVersions(res.items ?? [])) .catch(() => setVersions([])); - }, [batchEditOpen]); + }, [modalOpen, batchEditOpen]); useEffect(() => { if (!modalOpen || editing) return; @@ -108,6 +108,7 @@ export default function DevPlanTasksPage() { content: row.content, type: row.type, status: row.status, + versionIds: row.versionIds?.length ? row.versionIds : row.versions?.map((v) => v.id) ?? [], attachmentUrls: row.attachmentUrls?.length ? row.attachmentUrls : [''], }); setModalOpen(true); @@ -121,7 +122,11 @@ export default function DevPlanTasksPage() { if (editing) { await request(`/admin/dev-plan/tasks/${editing.id}`, { method: 'PUT', - body: JSON.stringify({ ...values, attachmentUrls }), + body: JSON.stringify({ + ...values, + attachmentUrls, + versionIds: values.versionIds ?? [], + }), }); message.success('已更新'); } else { @@ -285,6 +290,21 @@ export default function DevPlanTasksPage() { ), }, { title: '来源工单', dataIndex: 'supportTicketNo', width: 140, render: (v) => v || '—' }, + { + title: '关联版本', + dataIndex: 'versions', + width: 140, + render: (_, row) => + row.versions?.length ? ( + + {row.versions.map((v) => ( + {v.versionNo} + ))} + + ) : ( + '—' + ), + }, { title: '创建人', dataIndex: 'creatorName', width: 90 }, { title: '创建时间', dataIndex: 'createdAt', width: 160, render: fmtTime }, { @@ -405,9 +425,21 @@ export default function DevPlanTasksPage() { - + <> + + ({ value: v.id, label: v.versionNo }))} + /> + + ) : (