92 lines
4.0 KiB
Vue
92 lines
4.0 KiB
Vue
<script setup lang="ts">
|
||
import { computed, reactive, watch } from 'vue'
|
||
|
||
const props = defineProps<{ planId: string; plan: Record<string, unknown>; loading?: boolean }>()
|
||
const emit = defineEmits<{ confirm: [plan: Record<string, unknown>] }>()
|
||
|
||
const form = reactive({
|
||
coreDirection: '',
|
||
collaborationDirection: '',
|
||
factoryName: '',
|
||
planningYears: 3,
|
||
investmentRange: '',
|
||
scenarioCount: 1,
|
||
aiScenarioCount: 0,
|
||
note: ''
|
||
})
|
||
|
||
watch(
|
||
() => [props.planId, props.plan] as const,
|
||
([planId, plan]) => {
|
||
const stored = localStorage.getItem(`plan-draft:${planId}`)
|
||
const draft = stored ? JSON.parse(stored) as Partial<typeof form> : {}
|
||
Object.assign(form, {
|
||
coreDirection: String(plan.coreDirection || ''),
|
||
collaborationDirection: String(plan.collaborationDirection || ''),
|
||
factoryName: String(plan.factoryName || ''),
|
||
planningYears: Number(plan.planningYears || 3),
|
||
investmentRange: String(plan.investmentRange || ''),
|
||
scenarioCount: Number(plan.scenarioCount || (Array.isArray(plan.scenarios) ? plan.scenarios.length : 1)),
|
||
aiScenarioCount: Number(plan.aiScenarioCount || 0),
|
||
note: String(plan.note || '')
|
||
}, draft)
|
||
},
|
||
{ immediate: true }
|
||
)
|
||
|
||
watch(form, value => localStorage.setItem(`plan-draft:${props.planId}`, JSON.stringify(value)), { deep: true })
|
||
|
||
const summary = computed(() => {
|
||
return `${form.planningYears} 年 · ${form.investmentRange} · ${form.scenarioCount} 个场景 · ${form.aiScenarioCount} 个 AI 场景`
|
||
})
|
||
const valid = computed(() => Boolean(
|
||
form.coreDirection.trim() && form.collaborationDirection.trim() && form.factoryName.trim()
|
||
&& form.investmentRange.trim() && form.planningYears > 0 && form.scenarioCount > 0
|
||
&& form.aiScenarioCount >= 0 && form.aiScenarioCount <= form.scenarioCount
|
||
))
|
||
|
||
function confirm() {
|
||
if (!valid.value) return
|
||
emit('confirm', { ...props.plan, ...form })
|
||
}
|
||
|
||
function restore() {
|
||
localStorage.removeItem(`plan-draft:${props.planId}`)
|
||
Object.assign(form, {
|
||
coreDirection: String(props.plan.coreDirection || ''),
|
||
collaborationDirection: String(props.plan.collaborationDirection || ''),
|
||
factoryName: String(props.plan.factoryName || ''),
|
||
planningYears: Number(props.plan.planningYears || 3),
|
||
investmentRange: String(props.plan.investmentRange || ''),
|
||
scenarioCount: Number(props.plan.scenarioCount || (Array.isArray(props.plan.scenarios) ? props.plan.scenarios.length : 1)),
|
||
aiScenarioCount: Number(props.plan.aiScenarioCount || 0),
|
||
note: String(props.plan.note || '')
|
||
})
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<section class="ask-card" aria-labelledby="plan-title">
|
||
<h3 id="plan-title">确认建设规划</h3>
|
||
<p>确认后 Agent 将自主完成编写与评审</p>
|
||
<div class="plan-fields">
|
||
<label><span>核心建设方向</span><el-input v-model="form.coreDirection" /></label>
|
||
<label><span>协同建设方向</span><el-input v-model="form.collaborationDirection" /></label>
|
||
<label><span>智能工厂名称</span><el-input v-model="form.factoryName" /></label>
|
||
<label><span>规划周期</span><el-input-number v-model="form.planningYears" :min="1" :max="10" controls-position="right" /></label>
|
||
<label><span>投资范围</span><el-input v-model="form.investmentRange" /></label>
|
||
<label><span>重点场景</span><el-input-number v-model="form.scenarioCount" :min="1" :max="60" controls-position="right" /></label>
|
||
<label><span>AI 场景</span><el-input-number v-model="form.aiScenarioCount" :min="0" :max="form.scenarioCount" controls-position="right" /></label>
|
||
</div>
|
||
<div class="plan-summary">规划期 {{ summary }}</div>
|
||
<label class="plan-note">
|
||
<span>补充规划约束(选填)</span>
|
||
<el-input v-model="form.note" type="textarea" :rows="3" maxlength="300" show-word-limit />
|
||
</label>
|
||
<div class="ask-actions">
|
||
<el-button type="primary" :loading="loading" :disabled="!valid" @click="confirm">确认并开始编写</el-button>
|
||
<el-button @click="restore">恢复 Agent 建议</el-button>
|
||
</div>
|
||
</section>
|
||
</template>
|