feat: add intelligent support workflow

This commit is contained in:
hailin
2026-07-27 19:00:35 +08:00
parent 93065c0a00
commit 1a49ce4eae
38 changed files with 5644 additions and 33 deletions

View File

@@ -7,8 +7,9 @@ import { AppPageHeader } from '@/components/app/AppPageHeader'
import { AppSection } from '@/components/app/AppSection'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import { Button } from '@/components/ui/button'
import { Field, FieldContent, FieldDescription, FieldGroup, FieldLabel, FieldLegend, FieldSet } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Switch } from '@/components/ui/switch'
import { Textarea } from '@/components/ui/textarea'
import { getTicket } from '@/features/tickets/api'
@@ -23,7 +24,11 @@ const initialForm: SolutionInput = {
root_cause: '',
solution: '',
risk_note: '',
status: 'draft'
status: 'draft',
allow_auto_resolve: false,
requires_human_action: false,
requires_external_confirmation: false,
requires_production_change: false
}
function getSourceTicketId() {
@@ -65,7 +70,7 @@ export function SolutionCreatePage() {
try {
const solution = await createSolution(form)
if (sourceTicketId) {
await linkSolutionToTicket(solution.id, sourceTicketId, 'adopted')
await linkSolutionToTicket(solution.id, sourceTicketId, 'referenced')
window.location.hash = `/tickets/${sourceTicketId}`
return
}
@@ -106,19 +111,6 @@ export function SolutionCreatePage() {
onChange={(event) => updateField('title', event.target.value)}
/>
</AppField>
<AppField label="状态" required>
<Select value={form.status} onValueChange={(value) => updateField('status', value)}>
<SelectTrigger className="w-full">
<SelectValue placeholder="选择状态" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="draft">草稿</SelectItem>
<SelectItem value="published">发布</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</AppField>
<AppField label="关联系统" htmlFor="solution-related-system">
<Input
id="solution-related-system"
@@ -174,25 +166,65 @@ export function SolutionCreatePage() {
</AppSection>
<AppSection title="风险提示">
<AppField label="风险提示" htmlFor="solution-risk-note">
<Textarea
id="solution-risk-note"
placeholder="可选:说明操作风险、影响范围或上线前确认事项。"
value={form.risk_note}
onChange={(event) => updateField('risk_note', event.target.value)}
/>
</AppField>
<div className="grid gap-5">
<AppField label="风险提示" htmlFor="solution-risk-note">
<Textarea
id="solution-risk-note"
placeholder="可选:说明操作风险、影响范围或上线前确认事项。"
value={form.risk_note}
onChange={(event) => updateField('risk_note', event.target.value)}
/>
</AppField>
<FieldSet>
<FieldLegend>自动化边界</FieldLegend>
<FieldGroup>
<PolicySwitch
id="allow-auto-resolve"
label="允许自动解决"
description="仅代表该方案具备自动复用资格,仍需同时满足范围、阈值、权限和全局策略。"
checked={form.allow_auto_resolve}
onCheckedChange={(checked) => updateField('allow_auto_resolve', checked)}
/>
<PolicySwitch
id="requires-human-action"
label="需要人工操作"
description="勾选后该方案只能作为人工建议,不能自动解决。"
checked={form.requires_human_action}
onCheckedChange={(checked) => updateField('requires_human_action', checked)}
/>
<PolicySwitch
id="requires-external-confirmation"
label="需要外部确认"
description="需要客户、第三方或外部系统确认时禁止自动解决。"
checked={form.requires_external_confirmation}
onCheckedChange={(checked) =>
updateField('requires_external_confirmation', checked)}
/>
<PolicySwitch
id="requires-production-change"
label="涉及生产变更"
description="任何生产变更都必须人工处理和确认。"
checked={form.requires_production_change}
onCheckedChange={(checked) =>
updateField('requires_production_change', checked)}
/>
</FieldGroup>
</FieldSet>
</div>
</AppSection>
</div>
<div className="grid content-start gap-4">
<AppSection title="提交">
<div className="grid gap-3">
<p className="text-sm text-muted-foreground">
方案固定保存为草稿,需在知识治理中心提交并由另一名审核人发布。
</p>
{sourceTicketId ? (
<p className="text-sm text-muted-foreground">保存后会自动关联到当前工单,并标记为已采纳方案。</p>
<p className="text-sm text-muted-foreground">保存后会关联到当前工单,审核发布后可由处理人正式采纳。</p>
) : null}
<Button type="submit" disabled={submitting}>
<Save className="size-4" />
<Save data-icon="inline-start" />
{submitting ? '保存中...' : '保存方案'}
</Button>
</div>
@@ -202,3 +234,27 @@ export function SolutionCreatePage() {
</AppPage>
)
}
function PolicySwitch({
id,
label,
description,
checked,
onCheckedChange
}: {
id: string
label: string
description: string
checked: boolean
onCheckedChange: (checked: boolean) => void
}) {
return (
<Field orientation="horizontal">
<FieldContent>
<FieldLabel htmlFor={id}>{label}</FieldLabel>
<FieldDescription>{description}</FieldDescription>
</FieldContent>
<Switch id={id} checked={checked} onCheckedChange={onCheckedChange} />
</Field>
)
}