feat: connect knowledge base publish workflow UI
This commit is contained in:
@@ -6,9 +6,19 @@ import { Alert, Button, Card, Empty, Form, Input, List, Select, Space, Table, Ta
|
||||
import type { UploadFile } from "antd/es/upload/interface";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
|
||||
import { createKnowledgeBase, listKnowledgeBaseDocuments, listKnowledgeBases, retryKnowledgeBaseDocument, uploadKnowledgeBaseDocument } from "@/services/knowledge-base";
|
||||
import {
|
||||
createKnowledgeBase,
|
||||
listKnowledgeBaseDocuments,
|
||||
listKnowledgeBaseVersions,
|
||||
listKnowledgeBases,
|
||||
publishKnowledgeBase,
|
||||
retryKnowledgeBaseDocument,
|
||||
rollbackKnowledgeBase,
|
||||
unpublishKnowledgeBase,
|
||||
uploadKnowledgeBaseDocument,
|
||||
} from "@/services/knowledge-base";
|
||||
import { useAuthStore } from "@/stores/auth.store";
|
||||
import type { KnowledgeBaseDocumentItem, KnowledgeBaseItem } from "@/types/api";
|
||||
import type { KnowledgeBaseDocumentItem, KnowledgeBaseItem, KnowledgeBaseVersionItem } from "@/types/api";
|
||||
|
||||
const { Dragger } = Upload;
|
||||
const { Title, Text } = Typography;
|
||||
@@ -23,6 +33,10 @@ type KnowledgeBaseFormValues = {
|
||||
region?: string;
|
||||
tags?: string;
|
||||
};
|
||||
type KnowledgeBaseRollbackFormValues = {
|
||||
target_version_label: string;
|
||||
change_summary?: string;
|
||||
};
|
||||
|
||||
const DOCUMENT_STATUS_META: Record<string, { color: string; label: string }> = {
|
||||
pending: { color: "gold", label: "待处理" },
|
||||
@@ -91,6 +105,20 @@ function getRetrievalModeMeta(value: string | null | undefined) {
|
||||
return { color: "default", label: value || "Default" };
|
||||
}
|
||||
|
||||
function getKnowledgeBaseStatusMeta(value: string | null | undefined) {
|
||||
const normalized = (value || "").toLowerCase();
|
||||
if (normalized === "active") {
|
||||
return { color: "green", label: "已发布" };
|
||||
}
|
||||
if (normalized === "archived") {
|
||||
return { color: "default", label: "已下线" };
|
||||
}
|
||||
if (normalized === "draft") {
|
||||
return { color: "gold", label: "草稿" };
|
||||
}
|
||||
return { color: "blue", label: value || "未命名状态" };
|
||||
}
|
||||
|
||||
function getErrorMessage(error: unknown, fallback: string) {
|
||||
return error instanceof Error && error.message ? error.message : fallback;
|
||||
}
|
||||
@@ -170,9 +198,13 @@ export default function KnowledgeBasesPage() {
|
||||
const currentUser = useAuthStore((state) => state.currentUser);
|
||||
const [createForm] = Form.useForm<KnowledgeBaseFormValues>();
|
||||
const [uploadForm] = Form.useForm<KnowledgeBaseFormValues>();
|
||||
const [rollbackForm] = Form.useForm<KnowledgeBaseRollbackFormValues>();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [uploading, setUploading] = useState(false);
|
||||
const [publishing, setPublishing] = useState(false);
|
||||
const [unpublishing, setUnpublishing] = useState(false);
|
||||
const [rollingBack, setRollingBack] = useState(false);
|
||||
const [refreshingDocuments, setRefreshingDocuments] = useState(false);
|
||||
const [retryingDocumentId, setRetryingDocumentId] = useState<string | null>(null);
|
||||
const [listError, setListError] = useState<string | null>(null);
|
||||
@@ -180,6 +212,8 @@ export default function KnowledgeBasesPage() {
|
||||
const [items, setItems] = useState<KnowledgeBaseItem[]>([]);
|
||||
const [selectedId, setSelectedId] = useState<string | null>(null);
|
||||
const [documents, setDocuments] = useState<KnowledgeBaseDocumentItem[]>([]);
|
||||
const [versions, setVersions] = useState<KnowledgeBaseVersionItem[]>([]);
|
||||
const [versionsLoading, setVersionsLoading] = useState(false);
|
||||
const [sourceTypeFilter, setSourceTypeFilter] = useState<string>("all");
|
||||
const [regionFilter, setRegionFilter] = useState<string>("all");
|
||||
const [documentsLoading, setDocumentsLoading] = useState(false);
|
||||
@@ -224,6 +258,16 @@ export default function KnowledgeBasesPage() {
|
||||
return [{ value: "all", label: "全部适用区域" }, ...values.map((value) => ({ value, label: value }))];
|
||||
}, [documents]);
|
||||
|
||||
const selectedKnowledgeBaseStatus = getKnowledgeBaseStatusMeta(selectedKnowledgeBase?.status);
|
||||
const rollbackVersionOptions = useMemo(
|
||||
() =>
|
||||
versions.map((item) => ({
|
||||
value: item.version_label,
|
||||
label: `${item.version_label} · ${item.status}`,
|
||||
})),
|
||||
[versions],
|
||||
);
|
||||
|
||||
const loadKnowledgeBases = useCallback(async () => {
|
||||
if (currentUser?.role !== "admin") {
|
||||
setLoading(false);
|
||||
@@ -283,6 +327,29 @@ export default function KnowledgeBasesPage() {
|
||||
}
|
||||
}, [messageApi]);
|
||||
|
||||
const loadVersions = useCallback(async (knowledgeBaseId: string) => {
|
||||
setVersionsLoading(true);
|
||||
try {
|
||||
const result = await listKnowledgeBaseVersions(knowledgeBaseId);
|
||||
if (result.code !== 0) {
|
||||
messageApi.error(result.message || "获取知识库版本失败");
|
||||
setVersions([]);
|
||||
rollbackForm.resetFields(["target_version_label", "change_summary"]);
|
||||
return;
|
||||
}
|
||||
setVersions(result.data);
|
||||
rollbackForm.setFieldsValue({
|
||||
target_version_label: result.data[0]?.version_label,
|
||||
});
|
||||
} catch (error: unknown) {
|
||||
messageApi.error(getErrorMessage(error, "获取知识库版本失败,请稍后重试"));
|
||||
setVersions([]);
|
||||
rollbackForm.resetFields(["target_version_label", "change_summary"]);
|
||||
} finally {
|
||||
setVersionsLoading(false);
|
||||
}
|
||||
}, [messageApi, rollbackForm]);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = window.setTimeout(() => {
|
||||
void loadKnowledgeBases();
|
||||
@@ -296,14 +363,15 @@ export default function KnowledgeBasesPage() {
|
||||
if (!selectedId || currentUser?.role !== "admin") {
|
||||
setDocuments([]);
|
||||
setDocumentsError(null);
|
||||
setVersions([]);
|
||||
return;
|
||||
}
|
||||
|
||||
void loadDocuments(selectedId);
|
||||
void Promise.all([loadDocuments(selectedId), loadVersions(selectedId)]);
|
||||
}, 0);
|
||||
|
||||
return () => window.clearTimeout(timer);
|
||||
}, [currentUser?.role, loadDocuments, selectedId]);
|
||||
}, [currentUser?.role, loadDocuments, loadVersions, selectedId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedId || currentUser?.role !== "admin") {
|
||||
@@ -421,6 +489,74 @@ export default function KnowledgeBasesPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const handlePublishKnowledgeBase = async () => {
|
||||
if (!selectedId) {
|
||||
return;
|
||||
}
|
||||
setPublishing(true);
|
||||
try {
|
||||
const result = await publishKnowledgeBase(selectedId);
|
||||
if (result.code !== 0) {
|
||||
messageApi.error(result.message || "发布知识库失败");
|
||||
return;
|
||||
}
|
||||
messageApi.success("知识库已发布");
|
||||
await Promise.all([loadKnowledgeBases(), loadVersions(selectedId)]);
|
||||
} catch (error: unknown) {
|
||||
messageApi.error(getErrorMessage(error, "发布知识库失败,请稍后重试"));
|
||||
} finally {
|
||||
setPublishing(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleUnpublishKnowledgeBase = async () => {
|
||||
if (!selectedId) {
|
||||
return;
|
||||
}
|
||||
setUnpublishing(true);
|
||||
try {
|
||||
const result = await unpublishKnowledgeBase(selectedId);
|
||||
if (result.code !== 0) {
|
||||
messageApi.error(result.message || "下线知识库失败");
|
||||
return;
|
||||
}
|
||||
messageApi.success("知识库已下线");
|
||||
await Promise.all([loadKnowledgeBases(), loadVersions(selectedId)]);
|
||||
} catch (error: unknown) {
|
||||
messageApi.error(getErrorMessage(error, "下线知识库失败,请稍后重试"));
|
||||
} finally {
|
||||
setUnpublishing(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRollbackKnowledgeBase = async () => {
|
||||
if (!selectedId) {
|
||||
return;
|
||||
}
|
||||
const values = await rollbackForm.validateFields();
|
||||
setRollingBack(true);
|
||||
try {
|
||||
const result = await rollbackKnowledgeBase(selectedId, {
|
||||
target_version_label: values.target_version_label,
|
||||
change_summary: values.change_summary?.trim() || undefined,
|
||||
});
|
||||
if (result.code !== 0) {
|
||||
messageApi.error(result.message || "回滚知识库失败");
|
||||
return;
|
||||
}
|
||||
messageApi.success(`知识库已回滚到 ${values.target_version_label}`);
|
||||
await Promise.all([loadKnowledgeBases(), loadVersions(selectedId)]);
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error && error.message === "Validation failed") {
|
||||
setRollingBack(false);
|
||||
return;
|
||||
}
|
||||
messageApi.error(getErrorMessage(error, "回滚知识库失败,请稍后重试"));
|
||||
} finally {
|
||||
setRollingBack(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (currentUser?.role !== "admin") {
|
||||
return (
|
||||
<main className="page-shell review-history-page">
|
||||
@@ -514,6 +650,75 @@ export default function KnowledgeBasesPage() {
|
||||
</Space>
|
||||
|
||||
<Space direction="vertical" size="middle" style={{ width: "100%" }}>
|
||||
<Card className="review-surface-card" title="发布治理">
|
||||
<Space direction="vertical" size="middle" style={{ width: "100%" }}>
|
||||
{selectedKnowledgeBase ? (
|
||||
<>
|
||||
<Space wrap size={[8, 8]}>
|
||||
<Tag color={selectedKnowledgeBaseStatus.color}>{selectedKnowledgeBaseStatus.label}</Tag>
|
||||
<Tag color={getRetrievalModeMeta(selectedKnowledgeBase.retrieval_mode).color}>
|
||||
{getRetrievalModeMeta(selectedKnowledgeBase.retrieval_mode).label}
|
||||
</Tag>
|
||||
{selectedKnowledgeBase.current_version_label ? <Tag>当前版本 {selectedKnowledgeBase.current_version_label}</Tag> : null}
|
||||
</Space>
|
||||
<Text>{selectedKnowledgeBase.description || "当前知识库暂无说明。"}</Text>
|
||||
<Space direction="vertical" size={4}>
|
||||
<Text type="secondary">发布人:{selectedKnowledgeBase.published_by || "-"}</Text>
|
||||
<Text type="secondary">发布时间:{selectedKnowledgeBase.published_at ? formatDateTime(selectedKnowledgeBase.published_at) : "-"}</Text>
|
||||
</Space>
|
||||
<Space wrap>
|
||||
<Button type="primary" loading={publishing} onClick={() => void handlePublishKnowledgeBase()}>
|
||||
发布知识库
|
||||
</Button>
|
||||
<Button loading={unpublishing} onClick={() => void handleUnpublishKnowledgeBase()}>
|
||||
下线知识库
|
||||
</Button>
|
||||
</Space>
|
||||
<Form form={rollbackForm} layout="vertical">
|
||||
<Form.Item label="回滚到版本" name="target_version_label" rules={[{ required: true, message: "请选择目标版本" }]}>
|
||||
<Select
|
||||
placeholder="选择历史版本"
|
||||
loading={versionsLoading}
|
||||
options={rollbackVersionOptions}
|
||||
disabled={!rollbackVersionOptions.length}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="回滚说明" name="change_summary">
|
||||
<Input placeholder="例如:恢复到稳定知识库版本" />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<Button loading={rollingBack} disabled={!rollbackVersionOptions.length} onClick={() => void handleRollbackKnowledgeBase()}>
|
||||
回滚知识库
|
||||
</Button>
|
||||
<List
|
||||
header="版本历史"
|
||||
loading={versionsLoading}
|
||||
locale={{ emptyText: "当前知识库还没有发布历史。" }}
|
||||
dataSource={versions}
|
||||
renderItem={(item) => (
|
||||
<List.Item>
|
||||
<Space direction="vertical" size={2} style={{ width: "100%" }}>
|
||||
<Space wrap size={[8, 8]}>
|
||||
<Text strong>{item.version_label}</Text>
|
||||
<Tag color={getKnowledgeBaseStatusMeta(item.status).color}>{getKnowledgeBaseStatusMeta(item.status).label}</Tag>
|
||||
</Space>
|
||||
<Text type="secondary">{item.change_summary || "无变更说明"}</Text>
|
||||
<Text type="secondary">
|
||||
{item.published_at ? formatDateTime(item.published_at) : formatDateTime(item.created_at)}
|
||||
{" · "}
|
||||
{item.published_by || "-"}
|
||||
</Text>
|
||||
</Space>
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<Alert showIcon type="info" message="请先从左侧选择知识库,再进行发布、下线或回滚。" />
|
||||
)}
|
||||
</Space>
|
||||
</Card>
|
||||
|
||||
<Card className="review-surface-card" title="上传文档">
|
||||
<Space direction="vertical" size="middle" style={{ width: "100%" }}>
|
||||
<Alert showIcon type="info" message={selectedKnowledgeBase ? `当前知识库:${selectedKnowledgeBase.name}` : "请先从左侧选择知识库"} />
|
||||
|
||||
@@ -4,6 +4,8 @@ import type {
|
||||
KnowledgeBaseCreatePayload,
|
||||
KnowledgeBaseDocumentItem,
|
||||
KnowledgeBaseItem,
|
||||
KnowledgeBaseRollbackPayload,
|
||||
KnowledgeBaseVersionItem,
|
||||
PageResponse,
|
||||
} from "@/types/api";
|
||||
|
||||
@@ -41,6 +43,31 @@ export async function createKnowledgeBase(payload: KnowledgeBaseCreatePayload) {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function listKnowledgeBaseVersions(knowledgeBaseId: string) {
|
||||
const response = await http.get<ApiResponse<KnowledgeBaseVersionItem[]>>(`/knowledge-bases/${knowledgeBaseId}/versions`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function publishKnowledgeBase(knowledgeBaseId: string) {
|
||||
const response = await http.post<ApiResponse<KnowledgeBaseItem>>(`/knowledge-bases/${knowledgeBaseId}/publish`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function unpublishKnowledgeBase(knowledgeBaseId: string) {
|
||||
const response = await http.post<ApiResponse<KnowledgeBaseItem>>(`/knowledge-bases/${knowledgeBaseId}/unpublish`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function rollbackKnowledgeBase(knowledgeBaseId: string, payload: KnowledgeBaseRollbackPayload) {
|
||||
const formData = new FormData();
|
||||
formData.append("target_version_label", payload.target_version_label);
|
||||
if (payload.change_summary) {
|
||||
formData.append("change_summary", payload.change_summary);
|
||||
}
|
||||
const response = await http.post<ApiResponse<KnowledgeBaseItem>>(`/knowledge-bases/${knowledgeBaseId}/rollback`, formData);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function listKnowledgeBaseDocuments(knowledgeBaseId: string, page = 1, pageSize = 20) {
|
||||
const response = await http.get<ApiResponse<PageResponse<KnowledgeBaseDocumentItem>>>(`/knowledge-bases/${knowledgeBaseId}/documents`, {
|
||||
params: {
|
||||
|
||||
@@ -232,10 +232,27 @@ export type KnowledgeBaseItem = {
|
||||
status: string;
|
||||
document_count: number;
|
||||
retrieval_mode?: string | null;
|
||||
current_version_label?: string | null;
|
||||
published_at?: string | null;
|
||||
published_by?: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
|
||||
export type KnowledgeBaseVersionItem = {
|
||||
id: string;
|
||||
knowledge_base_id: string;
|
||||
version_label: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
retrieval_mode?: string | null;
|
||||
status: string;
|
||||
published_at?: string | null;
|
||||
published_by?: string | null;
|
||||
change_summary?: string | null;
|
||||
created_at: string;
|
||||
};
|
||||
|
||||
export type KnowledgeBaseDocumentItem = {
|
||||
id: string;
|
||||
knowledge_base_id: string;
|
||||
@@ -274,6 +291,11 @@ export type KnowledgeBaseCreatePayload = {
|
||||
description?: string;
|
||||
};
|
||||
|
||||
export type KnowledgeBaseRollbackPayload = {
|
||||
target_version_label: string;
|
||||
change_summary?: string;
|
||||
};
|
||||
|
||||
export type KnowledgeBaseListResponse = PageResponse<KnowledgeBaseItem>;
|
||||
export type KnowledgeBaseDocumentListResponse = PageResponse<KnowledgeBaseDocumentItem>;
|
||||
|
||||
|
||||
@@ -1579,17 +1579,57 @@
|
||||
- 从代码链角度看,`knowledge_bases` 的远端发布链已经补齐:
|
||||
- 共享平台有真实端点
|
||||
- 合同平台有 SDK / client / backend API 桥接
|
||||
- 但当前 `shared-ai-platform-java` 仓库存在用户已有的未提交改动,不适合未经确认直接把整个仓库工作树部署到远端运行环境。
|
||||
- 因此这轮状态定义为:
|
||||
- 代码实现:已完成
|
||||
- 本地 / smoke 验证:已完成
|
||||
- 运行中 shared-ai 服务部署:待单独确认
|
||||
- 合同平台前端知识库页已接上发布治理面板
|
||||
- 运行中的 shared-ai Java 服务也已更新到包含这组端点的版本:
|
||||
- 远端仓库 `/opt/shared-ai-platform-java` 已 `git pull --ff-only` 到 `f925913`
|
||||
- `docker compose -f docker-compose.server.yml up -d --build shared-ai-platform-java` 已执行
|
||||
- `/health` 正常
|
||||
- 远端 HTTP smoke 已通过:
|
||||
- `publish -> versions -> unpublish -> rollback`
|
||||
- 当前可将 `knowledge_bases` 发布链定义为:
|
||||
- 代码实现:完成
|
||||
- 本地 / smoke 验证:完成
|
||||
- 远端运行时验证:完成
|
||||
|
||||
### 当前阻塞项
|
||||
- `knowledge_bases` 发布链当前已不再是代码缺口。
|
||||
- 目前剩下的是发布层面阻塞:
|
||||
- `D:\shared-ai-platform-java` 工作区含用户已有未提交改动,直接部署会混入无关变更
|
||||
- 若要把运行中的 shared-ai Java 服务也切到新端点,需要先确认是否允许按当前工作树部署,或先整理 shared repo 交付边界
|
||||
- `knowledge_bases` 发布链已无代码级或运行级阻塞。
|
||||
|
||||
## 2026-05-15 knowledge-bases 页面已接上发布链
|
||||
|
||||
### 本轮完成项
|
||||
- `frontend/src/services/knowledge-base.ts`
|
||||
- 已补齐知识库发布链前端服务:
|
||||
- `listKnowledgeBaseVersions`
|
||||
- `publishKnowledgeBase`
|
||||
- `unpublishKnowledgeBase`
|
||||
- `rollbackKnowledgeBase`
|
||||
- `frontend/src/types/api.ts`
|
||||
- 已补齐知识库发布链前端类型:
|
||||
- `KnowledgeBaseVersionItem`
|
||||
- `KnowledgeBaseRollbackPayload`
|
||||
- `KnowledgeBaseItem.current_version_label / published_at / published_by`
|
||||
- `frontend/src/app/knowledge-bases/page.tsx`
|
||||
- 已新增“发布治理”面板:
|
||||
- 展示当前知识库发布状态、当前版本、发布人、发布时间
|
||||
- 支持“发布知识库”
|
||||
- 支持“下线知识库”
|
||||
- 支持查看版本历史
|
||||
- 支持选择历史版本并执行“回滚知识库”
|
||||
- 保持现有上传文档、异常文档恢复、索引状态表不变,避免把本页重新做成另一套管理台
|
||||
|
||||
### 本轮验证
|
||||
- 前端检查:
|
||||
- `npm --prefix frontend run lint`
|
||||
- 结果:通过
|
||||
- `npm --prefix frontend run build`
|
||||
- 结果:通过
|
||||
- 说明:
|
||||
- `ai-contract-platform` 的前端与 backend bridge 已经接上
|
||||
- `shared-ai-platform-java` 的知识库发布端点 smoke 也已在上一轮通过
|
||||
|
||||
### 当前状态更新
|
||||
- `knowledge_bases` 发布链现在已经形成“共享平台远端端点 -> 合同平台 SDK/client/backend -> 合同平台前端页面”的完整代码闭环。
|
||||
- 当前运行中的 shared-ai Java 服务已经切到包含这组新端点的版本,前端按钮可以按新链路继续验证。
|
||||
|
||||
## 2026-05-15 默认无参正式流程验证与治理状态刷新
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ batch,priority,area,task_id,title,current_gap,target_deliverable,depends_on,acce
|
||||
5B,P0,backend_api,GOV-API-004,新增证据上传绑定接口,当前系统没有专门的治理证据绑定接口,新增 /governance/evidences 上传绑定替换校验接口,GOV-DB-004,系统可阻止模板证据进入已批准状态,COMPLETED
|
||||
5B,P0,backend_api,GOV-API-005,新增上线批准汇总接口,当前没有系统内 release approval summary,新增 /governance/releases/summary 和 /governance/releases/{id} 接口,GOV-DB-005,前端可直接展示当前上线阻断项与通过项,COMPLETED
|
||||
5B,P0,backend_api,GOV-API-006,新增CSV台账导入接口,当前正式上线台账只靠仓库脚本导入,新增 /governance/imports/formal-launch 接口读取既有 CSV 映射到治理表,GOV-DB-001;GOV-DB-002;GOV-DB-003;GOV-DB-004,旧台账可一次性导入数据库且保留来源信息,COMPLETED
|
||||
5B,P1,backend_api,GOV-API-007,模板规则知识库发布接口,当前内容模块没有生产发布动作,为 templates review-rules knowledge-bases 增加 publish/unpublish/rollback 接口,GOV-DB-005;GOV-DB-006,已批准资产才能被发布到生产可用集合,IN_PROGRESS
|
||||
5B,P1,backend_api,GOV-API-007,模板规则知识库发布接口,当前内容模块没有生产发布动作,为 templates review-rules knowledge-bases 增加 publish/unpublish/rollback 接口,GOV-DB-005;GOV-DB-006,已批准资产才能被发布到生产可用集合,COMPLETED
|
||||
5C,P0,frontend,GOV-WEB-001,新增复核总控中心页面,当前没有统一治理控制台,新增 /governance 页面展示资产统计阻断项角色视图和发布批次,GOV-API-001;GOV-API-005,管理员可在单页看到当前正式上线治理全貌,COMPLETED
|
||||
5C,P0,frontend,GOV-WEB-002,新增复核人工作台页面,当前真实法务业务运营没有系统内待办页,新增 /governance/workbench 页面支持按角色查看待处理任务,GOV-API-001;GOV-API-002;GOV-API-003,复核人可只看到与自己相关的任务包,COMPLETED
|
||||
5C,P0,frontend,GOV-WEB-003,新增资产详情与证据页,当前无法在系统内查看单资产的签署链和证据链,新增治理资产详情页和证据面板,GOV-API-001;GOV-API-003;GOV-API-004,可在页面内查看每个资产的复核记录和证据状态,COMPLETED
|
||||
|
||||
|
Reference in New Issue
Block a user