feat: add intelligent support workflow
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user