feat(ops): kb doc edit, validation auto-tickets, support batch ops
Add knowledge document GET/PUT and admin edit UI; auto-create support tickets on client 400 validation errors across user/shop/partner apps; batch create tasks and publish from support tickets; restore mini-user store env single-column layout. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -34,6 +34,7 @@ import {
|
||||
type BatchReviewPreviewItem,
|
||||
type BatchReviewPreviewResponse,
|
||||
type DevPlanTaskTypeDto,
|
||||
type DevPlanVersionDto,
|
||||
type SupportTicketDto,
|
||||
type SupportTicketLinkedTaskDto,
|
||||
type SupportTicketStatusDto,
|
||||
@@ -96,6 +97,10 @@ export default function SupportTicketsPage() {
|
||||
const [batchConfirming, setBatchConfirming] = useState(false);
|
||||
const [batchStatusOpen, setBatchStatusOpen] = useState(false);
|
||||
const [batchStatusSaving, setBatchStatusSaving] = useState(false);
|
||||
const [batchCreateSaving, setBatchCreateSaving] = useState(false);
|
||||
const [batchPublishOpen, setBatchPublishOpen] = useState(false);
|
||||
const [batchPublishSaving, setBatchPublishSaving] = useState(false);
|
||||
const [versions, setVersions] = useState<DevPlanVersionDto[]>([]);
|
||||
const [editOpen, setEditOpen] = useState(false);
|
||||
const [editSaving, setEditSaving] = useState(false);
|
||||
const [reviewDecision, setReviewDecision] = useState<'APPROVE' | 'REJECT'>('APPROVE');
|
||||
@@ -114,9 +119,21 @@ export default function SupportTicketsPage() {
|
||||
rejectReason?: string;
|
||||
note?: string;
|
||||
}>();
|
||||
const [batchPublishForm] = Form.useForm<{
|
||||
versionId: string;
|
||||
dispatchToWecom?: boolean;
|
||||
dispatchSupplement?: string;
|
||||
}>();
|
||||
|
||||
const isSuperAdmin = profile?.adminRole === 'SUPER_ADMIN';
|
||||
|
||||
useEffect(() => {
|
||||
if (!batchPublishOpen) return;
|
||||
request<{ items: DevPlanVersionDto[] }>('/admin/dev-plan/versions?pageSize=100')
|
||||
.then((res) => setVersions(res.items ?? []))
|
||||
.catch(() => setVersions([]));
|
||||
}, [batchPublishOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
request<HqProfile>('/admin/auth/me').then(setProfile).catch(() => {});
|
||||
}, []);
|
||||
@@ -257,6 +274,67 @@ export default function SupportTicketsPage() {
|
||||
}
|
||||
}
|
||||
|
||||
async function submitBatchCreateTasks() {
|
||||
if (!selectedRowKeys.length) return;
|
||||
setBatchCreateSaving(true);
|
||||
try {
|
||||
const res = await request<{ successCount: number; failCount: number }>(
|
||||
'/admin/support-tickets/batch-create-tasks',
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ ticketIds: selectedRowKeys }),
|
||||
},
|
||||
);
|
||||
message.success(`已创建 ${res.successCount} 条任务,跳过/失败 ${res.failCount} 条`);
|
||||
setSelectedRowKeys([]);
|
||||
reload();
|
||||
} catch (e) {
|
||||
message.error(e instanceof Error ? e.message : '批量创建任务失败');
|
||||
} finally {
|
||||
setBatchCreateSaving(false);
|
||||
}
|
||||
}
|
||||
|
||||
function openBatchPublish() {
|
||||
batchPublishForm.setFieldsValue({
|
||||
versionId: undefined,
|
||||
dispatchToWecom: localStorage.getItem(DISPATCH_WECOM_STORAGE_KEY) !== 'false',
|
||||
dispatchSupplement: DEFAULT_DISPATCH_SUPPLEMENT,
|
||||
});
|
||||
setBatchPublishOpen(true);
|
||||
}
|
||||
|
||||
async function submitBatchPublish() {
|
||||
const values = await batchPublishForm.validateFields();
|
||||
localStorage.setItem(DISPATCH_WECOM_STORAGE_KEY, values.dispatchToWecom ? 'true' : 'false');
|
||||
setBatchPublishSaving(true);
|
||||
try {
|
||||
const res = await request<{
|
||||
successCount: number;
|
||||
failCount: number;
|
||||
linkedTaskCount: number;
|
||||
}>('/admin/support-tickets/batch-publish', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
ticketIds: selectedRowKeys,
|
||||
versionId: values.versionId,
|
||||
dispatchToWecom: !!values.dispatchToWecom,
|
||||
dispatchSupplement: values.dispatchSupplement?.trim() || undefined,
|
||||
}),
|
||||
});
|
||||
message.success(
|
||||
`已关联 ${res.linkedTaskCount} 条任务到版本,工单成功 ${res.successCount} 条,失败 ${res.failCount} 条`,
|
||||
);
|
||||
setBatchPublishOpen(false);
|
||||
setSelectedRowKeys([]);
|
||||
reload();
|
||||
} catch (e) {
|
||||
message.error(e instanceof Error ? e.message : '批量发布失败');
|
||||
} finally {
|
||||
setBatchPublishSaving(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function submitCreateTasks() {
|
||||
const values = await tasksForm.validateFields();
|
||||
const note = reviewForm.getFieldValue('note') as string | undefined;
|
||||
@@ -440,6 +518,16 @@ export default function SupportTicketsPage() {
|
||||
<Space>
|
||||
{isSuperAdmin ? (
|
||||
<>
|
||||
<Button
|
||||
disabled={!selectedRowKeys.length}
|
||||
loading={batchCreateSaving}
|
||||
onClick={() => void submitBatchCreateTasks()}
|
||||
>
|
||||
一键创建任务
|
||||
</Button>
|
||||
<Button disabled={!selectedRowKeys.length} onClick={openBatchPublish}>
|
||||
一键发布
|
||||
</Button>
|
||||
<Button disabled={!selectedRowKeys.length} loading={acting} onClick={() => void startBatchPreview()}>
|
||||
批量审核
|
||||
</Button>
|
||||
@@ -945,6 +1033,33 @@ export default function SupportTicketsPage() {
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="一键发布"
|
||||
open={batchPublishOpen}
|
||||
onCancel={() => setBatchPublishOpen(false)}
|
||||
onOk={() => void submitBatchPublish()}
|
||||
confirmLoading={batchPublishSaving}
|
||||
destroyOnClose
|
||||
>
|
||||
<Typography.Paragraph type="secondary">
|
||||
已选 {selectedRowKeys.length} 条工单。将把各工单关联的开发任务追加到所选版本;无任务的工单将跳过。
|
||||
</Typography.Paragraph>
|
||||
<Form form={batchPublishForm} layout="vertical">
|
||||
<Form.Item name="versionId" label="开发版本" rules={[{ required: true, message: '请选择开发版本' }]}>
|
||||
<Select
|
||||
placeholder="选择版本"
|
||||
options={versions.map((v) => ({ value: v.id, label: v.versionNo }))}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="dispatchToWecom" valuePropName="checked">
|
||||
<Checkbox>同时发送到企微开发助手</Checkbox>
|
||||
</Form.Item>
|
||||
<Form.Item name="dispatchSupplement" label="派发补充说明">
|
||||
<Input.TextArea rows={2} placeholder={DEFAULT_DISPATCH_SUPPLEMENT} />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
title="批量 AI 审核确认"
|
||||
open={batchPreviewOpen}
|
||||
|
||||
Reference in New Issue
Block a user