feat(project): 项目基本信息修改和分包选择(FR-M2-03、04)
- 字段修改:人工值优先、撤销恢复 AI 值、按字段校验(金额可写「286万」,按元存)、 冗余列同步、审计留痕、只读项目 409;关键日期显示改后的投标截止时间 - 分包:增删改、选包(至少一个)、一键「不分包」;删包时条目归为通用,删到一个不剩回到不分包 - 清单列表 lot_scope 默认只列通用 + 所投的包,响应带 hidden_count - 检查记下当时用的项目依据(截止时间、限价、所投的包、法律体系):报告按它写, 之后改了信息检查结果接口给 basis_changed,查标页提示重新检查 - 前端:概览标签页(项目要点、采购包、关键日期)、字段修改对话框、选包页和手工调整; 解析完识别到多个包时进选包页;读标页清单范围和所属采购包;查标页写明查哪几个包 - 决策 PI1–PI7;方案和落地记录 docs/architecture/project-info-plan.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,13 +12,14 @@ import { computed, ref, watch } from "vue";
|
||||
import { errorTitle, isApiError } from "@/lib/api";
|
||||
import type { ItemFields } from "@/lib/checklistOps";
|
||||
import { category, CATEGORY_ORDER, IMPORTANCE_MARK, IMPORTANCE_NAME } from "@/lib/labels";
|
||||
import type { ChecklistItem } from "@/lib/queries";
|
||||
import type { ChecklistItem, Lot } from "@/lib/queries";
|
||||
|
||||
type Mode = "edit" | "accept" | "create";
|
||||
type Cat = ChecklistItem["categories"][number];
|
||||
type Imp = ChecklistItem["importance"];
|
||||
|
||||
const props = defineProps<{ mode: Mode; item?: ChecklistItem | null; defaultCategory?: Cat }>();
|
||||
/** lots:项目的分包(不含默认包);有 2 个及以上时可以改条目归属哪个包(FR-M2-04) */
|
||||
const props = defineProps<{ mode: Mode; item?: ChecklistItem | null; defaultCategory?: Cat; lots?: Lot[] }>();
|
||||
const open = defineModel<boolean>("open", { required: true });
|
||||
const emit = defineEmits<{
|
||||
/** 提交:changes 只含改过的字段;ack = 人工确认、无出处 */
|
||||
@@ -32,6 +33,7 @@ const cats = ref<Cat[]>([]);
|
||||
const imp = ref<Imp>("normal");
|
||||
const evidence = ref("");
|
||||
const reqText = ref("");
|
||||
const lotId = ref<string | null>(null);
|
||||
const ack = ref(false);
|
||||
const busy = ref(false);
|
||||
const err = ref("");
|
||||
@@ -46,6 +48,7 @@ watch(open, (v) => {
|
||||
imp.value = i?.importance ?? "normal";
|
||||
evidence.value = i?.evidence_required ?? "";
|
||||
reqText.value = i?.requirement_text ?? "";
|
||||
lotId.value = i?.lot_id ?? null;
|
||||
ack.value = false;
|
||||
err.value = titleErr.value = catErr.value = "";
|
||||
});
|
||||
@@ -75,6 +78,7 @@ function changes(): ItemFields {
|
||||
if (!i || imp.value !== i.importance) out.importance = imp.value;
|
||||
const ev = evidence.value.trim() || null;
|
||||
if (ev !== (i?.evidence_required ?? null)) out.evidence_required = ev;
|
||||
if ((props.lots?.length ?? 0) > 1 && lotId.value !== (i?.lot_id ?? null)) out.lot_id = lotId.value;
|
||||
const rt = reqText.value.trim() || null;
|
||||
if (reqEditable.value && rt !== (i?.requirement_text ?? null)) out.requirement_text = rt;
|
||||
return out;
|
||||
@@ -129,6 +133,13 @@ function submit() {
|
||||
</div>
|
||||
<span v-if="imp === 'substantive'" class="msg">★ 条款不满足就会被判无效,已同时归在「无效条款」</span>
|
||||
</div>
|
||||
<div v-if="(lots?.length ?? 0) > 1" class="field fill">
|
||||
<label for="it-lot">所属采购包</label>
|
||||
<select id="it-lot" v-model="lotId" class="input">
|
||||
<option :value="null">各包通用</option>
|
||||
<option v-for="l in lots" :key="l.id" :value="l.id">采购包 {{ l.lot_no }}<template v-if="l.name"> · {{ l.name }}</template></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field fill">
|
||||
<label for="it-ev">证明材料 <small>(选填)</small></label>
|
||||
<input id="it-ev" v-model="evidence" class="input" placeholder="如「提供营业执照副本复印件并加盖公章」" />
|
||||
|
||||
Reference in New Issue
Block a user