From 490c26a7e1289615e2c98d579fdea1549db94f0d Mon Sep 17 00:00:00 2001 From: jacy <18049821889@163.com> Date: Wed, 5 Aug 2026 08:08:17 +0800 Subject: [PATCH] feat(admin): unrestricted support ticket batch select and task ticket bind Allow selecting support tickets of any status for batch actions; add optional support ticket binding when creating a dev plan task. Co-authored-by: Cursor --- apps/admin-web/src/pages/DevPlanTasksPage.tsx | 33 +++++++++++++++++-- .../src/pages/SupportTicketsPage.tsx | 6 +--- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/apps/admin-web/src/pages/DevPlanTasksPage.tsx b/apps/admin-web/src/pages/DevPlanTasksPage.tsx index 73115f8..b203c5d 100644 --- a/apps/admin-web/src/pages/DevPlanTasksPage.tsx +++ b/apps/admin-web/src/pages/DevPlanTasksPage.tsx @@ -16,10 +16,12 @@ import type { ColumnsType } from 'antd/es/table'; import { DEV_PLAN_TASK_STATUS_LABELS, DEV_PLAN_TASK_TYPE_LABELS, + SUPPORT_TICKET_STATUS_LABELS, type DevPlanTaskDto, type DevPlanTaskStatusDto, type DevPlanTaskTypeDto, type DevPlanVersionDto, + type SupportTicketDto, } from '@dukang/shared-types'; import { request } from '../lib/api'; import { fmtTime } from '../lib/constants'; @@ -50,6 +52,7 @@ export default function DevPlanTasksPage() { const [batchEditOpen, setBatchEditOpen] = useState(false); const [batchSaving, setBatchSaving] = useState(false); const [versions, setVersions] = useState([]); + const [supportTickets, setSupportTickets] = useState([]); const [editing, setEditing] = useState(null); const [saving, setSaving] = useState(false); const [dispatching, setDispatching] = useState(false); @@ -64,6 +67,13 @@ export default function DevPlanTasksPage() { .catch(() => setVersions([])); }, [batchEditOpen]); + useEffect(() => { + if (!modalOpen || editing) return; + request<{ items: SupportTicketDto[] }>('/admin/support-tickets?pageSize=100') + .then((res) => setSupportTickets(res.items ?? [])) + .catch(() => setSupportTickets([])); + }, [modalOpen, editing]); + const { data, loading, page, pageSize, setPage, setPageSize, reload } = useAdminList( '/admin/dev-plan/tasks', () => { @@ -78,7 +88,7 @@ export default function DevPlanTasksPage() { function openCreate() { setEditing(null); - form.setFieldsValue({ content: '', type: 'BUG', status: 'TODO' }); + form.setFieldsValue({ content: '', type: 'BUG', status: 'TODO', supportTicketId: undefined }); setModalOpen(true); } @@ -101,7 +111,11 @@ export default function DevPlanTasksPage() { } else { await request('/admin/dev-plan/tasks', { method: 'POST', - body: JSON.stringify({ content: values.content, type: values.type }), + body: JSON.stringify({ + content: values.content, + type: values.type, + supportTicketId: values.supportTicketId || undefined, + }), }); message.success('已创建'); } @@ -305,7 +319,20 @@ export default function DevPlanTasksPage() { ({ + value: t.id, + label: `${t.ticketNo} · ${SUPPORT_TICKET_STATUS_LABELS[t.status]} · ${t.title}`, + }))} + /> + + )} diff --git a/apps/admin-web/src/pages/SupportTicketsPage.tsx b/apps/admin-web/src/pages/SupportTicketsPage.tsx index f192f84..4bc7a9d 100644 --- a/apps/admin-web/src/pages/SupportTicketsPage.tsx +++ b/apps/admin-web/src/pages/SupportTicketsPage.tsx @@ -577,11 +577,7 @@ export default function SupportTicketsPage() { isSuperAdmin ? { selectedRowKeys, - onChange: (keys, rows) => { - const pending = rows.filter((r) => r.status === 'PENDING_REVIEW').map((r) => String(r.id)); - setSelectedRowKeys(pending.length === rows.length ? (keys as string[]) : pending); - }, - getCheckboxProps: (row) => ({ disabled: row.status !== 'PENDING_REVIEW' }), + onChange: (keys) => setSelectedRowKeys(keys as string[]), } : undefined }