feat: 读标可以走完一份文件;审计待确认区,修规则缺陷、提示词出新版本
读标操作(FR-M2-07、08) - 后端:清单项详情(ETag)、修改(If-Match 选填,记 edited_fields 和 AI 原值)、 采纳(补出处或声明「人工确认、无出处」,可带修改)、删除 / 丢弃与恢复、人工新增、 替换出处、人工建出处(选同一页的句子)、修改记录(来自审计)、确认清单(不可变版本, 内容没变复用上一版)、版本列表;正式清单有变化时已确认的清单回到草稿;项目已递交只读 - 重新解析不推翻人工决定:丢弃的不再冒出来,采纳的留在正式清单,人工补过的出处不被覆盖 - 前端:待确认区采纳 / 补上出处后采纳 / 修改后采纳 / 丢弃,正式清单修改、补出处、删除 (可撤销)、修改记录、新增条目、确认清单;pdf.js 原文查看器(点出处跳页、按坐标框高亮、 选句补出处),整屏对照布局,J / K 上下条;跨页的一句话合成一处出处显示 待确认审计(架构 §13 SK11) - 规则只修真正的缺陷:表格框线不算下划线(文字层 v3);句号后的右括号并进同一句 (切句 s3-v3);中文编号小节和冒号编号条目的上级条款,依据沿上级链核对;取值认中文 数字、同一行单元格和评分因素标题;补几种无效写法;比对引文前去掉我们加进输入的标记 - 不放宽:引文最短 8 个字、编号必须对、证据全部通过 - 提示词新版本:substantive v3,qualification / scoring / schedule / tech_param v2; 引文复制整句、并列多项不拆、跨页只引上一行,除实质性条款外输入改成纯文本 - BD_AI_MODELS 按提示词声明的能力选模型;离线评测工具 evals/run_extract.py - 待确认:国动 46 → 4,S02 17 → 13,S06 174 → 57 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
86
apps/web/src/components/HistoryDialog.vue
Normal file
86
apps/web/src/components/HistoryDialog.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 修改记录(全程留痕,红线 1):谁在何时做了什么、改前、改后。数据来自审计事件,按时间倒序。
|
||||
*/
|
||||
import { useQuery } from "@tanstack/vue-query";
|
||||
import { X } from "@lucide/vue";
|
||||
import { DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogRoot, DialogTitle } from "reka-ui";
|
||||
import { computed } from "vue";
|
||||
import { errorTitle } from "@/lib/api";
|
||||
import { fetchHistory } from "@/lib/checklistOps";
|
||||
import { fmtDateTime, HISTORY_FIELD, historyAction, historyValue } from "@/lib/labels";
|
||||
import type { ChecklistItem } from "@/lib/queries";
|
||||
|
||||
const props = defineProps<{ item: ChecklistItem | null }>();
|
||||
const open = defineModel<boolean>("open", { required: true });
|
||||
|
||||
const q = useQuery({
|
||||
queryKey: computed(() => ["checklist-history", props.item?.id ?? ""] as const),
|
||||
queryFn: () => fetchHistory(props.item!.id),
|
||||
enabled: computed(() => open.value && !!props.item),
|
||||
staleTime: 0,
|
||||
});
|
||||
|
||||
/** 每个改动的字段一行;没有字段改动的操作(删除、恢复)也占一行 */
|
||||
const rows = computed(() =>
|
||||
(q.data.value?.items ?? []).flatMap((h, n) => {
|
||||
const changes = (h.changes ?? []).filter((c) => c.field !== "pending_reason" && (h.action !== "checklist_item.extract" || c.field === "title"));
|
||||
const what = h.action === "checklist_item.extract" && props.item?.origin === "rule" ? "规则提取" : historyAction(h.action);
|
||||
const base = { key: `${n}`, at: fmtDateTime(h.at), who: h.actor.name || "—", what };
|
||||
if (!changes.length) return [{ ...base, field: "", before: "", after: "" }];
|
||||
return changes.map((c, i) => ({
|
||||
...base,
|
||||
key: `${n}-${i}`,
|
||||
field: HISTORY_FIELD[c.field] ?? c.field,
|
||||
before: historyValue(c.field, c.before),
|
||||
after: historyValue(c.field, c.after),
|
||||
first: i === 0,
|
||||
}));
|
||||
}),
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogRoot v-model:open="open">
|
||||
<DialogPortal>
|
||||
<DialogOverlay class="scrim">
|
||||
<DialogContent class="dialog wide" :aria-describedby="undefined">
|
||||
<DialogTitle as="h2">修改记录</DialogTitle>
|
||||
<DialogClose class="icon-btn sm x" aria-label="关闭"><X class="ic" :stroke-width="1.5" /></DialogClose>
|
||||
<p class="muted sub">{{ item?.title }}</p>
|
||||
<p v-if="q.isPending.value" class="muted">正在加载…</p>
|
||||
<p v-else-if="q.error.value" class="hint-warn">{{ errorTitle(q.error.value) }}</p>
|
||||
<table v-else class="data hist">
|
||||
<thead><tr><th>时间</th><th>操作人</th><th>操作</th><th>改前</th><th>改后</th></tr></thead>
|
||||
<tbody>
|
||||
<tr v-for="r in rows" :key="r.key">
|
||||
<td><span class="fig">{{ r.at }}</span></td>
|
||||
<td>{{ r.who }}</td>
|
||||
<td>{{ r.what }}<span v-if="r.field" class="muted"> · {{ r.field }}</span></td>
|
||||
<td><span v-if="r.before" class="old">{{ r.before }}</span><span v-else class="muted">—</span></td>
|
||||
<td>{{ r.after || "—" }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="foot"><DialogClose class="btn">关闭</DialogClose></div>
|
||||
</DialogContent>
|
||||
</DialogOverlay>
|
||||
</DialogPortal>
|
||||
</DialogRoot>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.sub {
|
||||
margin: 0 0 var(--sp-3);
|
||||
}
|
||||
.hist td:nth-child(-n + 3) {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.hist td {
|
||||
word-break: break-word;
|
||||
}
|
||||
.hist td:nth-child(4),
|
||||
.hist td:nth-child(5) {
|
||||
min-width: 5em;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user