模块:
yudao-module-archive(主模块)+yudao-module-archive-api(跨模块归档 RPC)
后端接口前缀:/archive/category、/archive/document、/archive/borrow、/archive/stat
附件关联:recordType = archive_document,application = file
权限点前缀:archive:category:*、archive:document:*、archive:borrow:*、archive:stat:query
| 文件 | 说明 |
|---|---|
src/packages/constants/src/dict-enum.ts |
新增 ARCHIVE_DICT(6 个字典类型)并展开进 DICT_TYPE |
src/api/archive/category/index.ts |
档案分类 API |
src/api/archive/document/index.ts |
档案 API |
src/api/archive/borrow/index.ts |
借阅单 API |
src/api/archive/stat/index.ts |
档案统计 API |
src/views/archive/category/index.vue |
分类树表页(左树右表形态,treeConfig 展开) |
src/views/archive/category/data.ts |
分类表单 + 搜索表单 + 表格列 |
src/views/archive/category/modules/form.vue |
分类新增/编辑弹窗(含「新增下级」) |
src/views/archive/document/index.vue |
档案列表页(检索 + 导出 + 附件标记) |
src/views/archive/document/data.ts |
档案表单 + 搜索表单 + 表格列 |
src/views/archive/document/modules/form.vue |
档案新增/编辑/详情弹窗(实体位置四字段 + 电子附件上传) |
src/views/archive/borrow/index.vue |
借阅列表页(逾期 Tag、提交审批、归还登记) |
src/views/archive/borrow/data.ts |
借阅表单 + 搜索表单 + 表格列 + BorrowStatus 常量 |
src/views/archive/borrow/modules/form.vue |
借阅登记/编辑/详情弹窗 |
src/views/archive/borrow/modules/process-select-modal.vue |
选择审批流程弹窗 |
src/views/archive/borrow/modules/return-form.vue |
归还登记弹窗 |
src/views/archive/borrow/detail/approve/index.vue |
BPM 审批详情页,路径必须与 bpm_process_definition_info.form_custom_view_path 完全一致 |
src/views/archive/stat/index.vue |
档案统计页(4 卡片 + 3 图表) |
src/views/archive/stat/data.ts |
卡片定义 + 饼图/柱图 option 构造 |
字典枚举必须登记到
dict-enum.ts,否则DICT_TYPE.ARCHIVE_*取不到值,列表列与表单下拉会空白。
菜单已配置完成,本项目为动态路由,前端无需手工加路由文件:
| 菜单 | id | 路径 | 组件 | 权限标识 |
|---|---|---|---|---|
档案管理(顶级目录 parent_id=0,path=/archive) |
1075600 | /archive |
— | — |
| 档案分类 | 1075601 | category |
archive/category/index |
archive:category:query |
| 档案管理 | 1075602 | document |
archive/document/index |
archive:document:query |
| 借阅登记 | 1075603 | borrow |
archive/borrow/index |
archive:borrow:query |
| 档案统计 | 1075604 | stat |
archive/stat/index |
archive:stat:query |
按钮权限:archive:category:create/update/delete、archive:document:create/update/delete/export/sensitive、archive:borrow:create/update/delete/submit/return、archive:stat:query。
⚠ 授权易错点:这些菜单与权限点**未授予任何角色**,因此只有超级管理员(
super_admin,代码直返全部菜单)能看到;普通角色需在「系统管理 → 角色」勾选授权。
⚠ 敏感权限:archive:document:sensitive(菜单 1075625「保密档案查看」)决定能否看到密级=保密的档案。**未授权时后端会强制过滤**,不是前端隐藏。
字典已配置完成,前端直接用 getDictOptions / DictTag 取值,无需自建枚举:
| 字典类型 | 名称 | 取值 |
|---|---|---|
archive_category_status |
档案分类状态 | 0 启用 / 1 停用 |
archive_document_status |
档案状态 | 10 在库 / 20 借出中 |
archive_secret_level |
档案密级 | 1 公开 / 2 内部 / 3 保密 |
archive_carrier_type |
档案载体 | 1 电子 / 2 实体 / 3 电子+实体 |
archive_source_type |
档案来源 | 1 手工录入 / 2 课题归档 / 3 会员归档 / 4 财务归档 |
archive_borrow_status |
档案借阅状态 | 0 草稿 / 15 审批中 / 20 借出中 / 30 已归还 / 35 已驳回 |
选择档案分类(树形下拉,默认带出该分类的 default_secret_level)
│
├── 档案标题、密级、载体、归档日期(必填)
├── 实体位置:书架号 / 层号 / 列号 / 册号(档案盒号)/ 存放位置描述
└── 电子文件:走 /system/storage-blob/upload 拿 blobId,随 create/update 一起提交
│
保存(create)
▼
后端生成档案编号 DA+yyyyMMdd+6位流水,落库并 bindAttachments
│
列表可检索(标题/关键词/来源单号/分类/密级/载体/状态/归档日期区间)
blobIds(number[])。**全量替换语义** —— 清空全部附件时必须显式传 [],传 null 视为「不动附件」。attachmentList 映射成上传组件可识别的对象(uid/name/url/status/id),提交时按 valueKey: 'id' 提取为 blobId。no(档案编号)、status(档案状态)、sourceType / sourceNo(来源)、archivistName(归档人)由后端维护,表单只展示不回传。登记借阅(选择在库档案 + 借阅人 + 借阅日期 + 归还期限)
│
保存(草稿 0)
│
提交审批(先调 approve-process-list 拿流程 key,再 submit)
▼
审批中 15 ──[BPM 通过]──► 借出中 20 ──[归还登记]──► 已归还 30
│ │
│ (同时把档案置为「借出中」)
│
└──[BPM 驳回]──► 已驳回 35 ──(改后可重新提交)
关键带入规则:
no + title 形式展示;提交时只传 documentId,档案编号与标题由后端快照到借阅单(documentNo / documentTitle)。approve-process-list,禁止前端写死**。列表为空时应提示「暂无可用审批流程,请先到 BPM 流程设计器发布档案借阅审批流程」。id + returnRemark。归还成功后档案自动回到「在库」,借阅单变「已归还」并写入 returnTime / returnConfirmUserName。page / overdue-page 返回时实时计算:overdue = (status == 20 && returnDeadline < 今天),overdueDays = 今天 - returnDeadline。row.overdue / row.overdueDays 渲染红色 Tag。overdueOnly 不是查询参数,而是独立接口 GET /archive/borrow/overdue-page;前端用「只看逾期」按钮切换调用的接口即可。| 来源模块 | 接口 | 权限点 | 触发前提 |
|---|---|---|---|
| 课题 | POST /research/application/archive?id |
research:application:archive |
申报单 status=20 已立项 且未归档 |
| 会员 | POST /ums/member/archive?id |
ums:member:archive |
会员 status=1 正常 且未归档 |
| 财务 | POST /finance/reimbursement/archive?id |
finance:reimbursement:archive(既有) |
报销单 status=20 已通过 且未归档 |
CommonResult<String>,如 DA20260929000001),前端 toast 直接提示「归档成功,已生成档案 XXX」。archiveDocumentId | number | 归档生成的档案 ID(非空即已归档) |archived | boolean | 是否已归档 |sourceType 为 2 课题 / 3 会员 / 4 财务,sourceNo 取来源单号(立项编号 / 会员编号 / 报销单号),分类固定取 research / member / finance。finance 的 default_secret_level=3),因此财务档案在无 archive:document:sensitive 权限时**在档案列表里看不到**。archiveDocumentId 非空后按钮自动隐藏)。archiveTime,本次在此基础上追加生成档案,两者同事务。/archive/category| 方法 | 路径 | 权限 | 说明 |
|---|---|---|---|
| POST | /archive/category/create |
archive:category:create |
新增分类 |
| PUT | /archive/category/update |
archive:category:update |
修改分类 |
| DELETE | /archive/category/delete?id |
archive:category:delete |
删除(有子分类/有档案时拒绝) |
| GET | /archive/category/get?id |
archive:category:query |
分类详情 |
| GET | /archive/category/list |
archive:category:query |
分类列表(**平铺**,供树表 transform 用) |
| GET | /archive/category/tree |
archive:category:query |
分类树(供左树与下拉用) |
/list 请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
name |
String | 否 | 分类名称,模糊匹配 |
status |
Integer | 否 | 状态:0 启用 / 1 停用 |
新增/修改请求体:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
Long | 修改必填 | 编号 |
parentId |
Long | 是 | 父分类 ID,0=顶级 |
name |
String | 是 | 分类名称 |
code |
String | 是 | 分类编码,唯一(member/research/finance 等,归档联动按此查找) |
sort |
Integer | 否 | 显示排序 |
description |
String | 否 | 分类说明 |
defaultSecretLevel |
Integer | 是 | 默认密级(1/2/3) |
status |
Integer | 否 | 状态(0 启用 / 1 停用) |
remark |
String | 否 | 备注 |
响应字段: id、parentId、name、code、sort、description、defaultSecretLevel、status、remark、createTime、children(树形接口才返回)。
树表接入要点:/list 返回**平铺**数组,前端 VXE 表格用 treeConfig: { parentField: 'parentId', rowField: 'id', transform: true, expandAll: true, reserve: true } 自行转树,pagerConfig.enabled = false,名称列加 treeNode: true。
/archive/document| 方法 | 路径 | 权限 | 说明 |
|---|---|---|---|
| POST | /archive/document/create |
archive:document:create |
新增档案 |
| PUT | /archive/document/update |
archive:document:update |
修改(借出中拒绝) |
| DELETE | /archive/document/delete?id |
archive:document:delete |
删除(借出中/存在未归还借阅单拒绝) |
| GET | /archive/document/get?id |
archive:document:query |
详情(保密档案需 archive:document:sensitive) |
| GET | /archive/document/page |
archive:document:query |
分页(无敏感权限时自动过滤保密档案) |
| GET | /archive/document/export-excel |
archive:document:export |
导出 Excel(同上过滤) |
/page 请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNo / pageSize |
Integer | 是 | 分页 |
no |
String | 否 | 档案编号,模糊匹配 |
title |
String | 否 | 档案标题,模糊匹配 |
categoryId |
Long | 否 | 档案分类 ID |
secretLevel |
Integer | 否 | 密级 |
carrierType |
Integer | 否 | 载体 |
sourceType |
Integer | 否 | 来源类型 |
sourceNo |
String | 否 | 来源单号,模糊匹配 |
tags |
String | 否 | 关键词,模糊匹配 tags 字段 |
status |
Integer | 否 | 档案状态 |
archiveDate |
LocalDate[] | 否 | 归档日期区间,**格式 yyyy-MM-dd**(RangePicker 必须设 valueFormat: 'YYYY-MM-DD',不能带时分秒) |
新增/修改请求体(SaveReqVO 只接受以下字段):
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
Long | 修改必填 | 编号 |
title |
String | 是 | 档案标题 |
categoryId |
Long | 是 | 档案分类 ID |
secretLevel |
Integer | 是 | 密级 |
carrierType |
Integer | 是 | 载体 |
shelfNo / layerNo / columnNo / boxNo |
String | 否 | 实体位置四字段 |
storePlace |
String | 否 | 存放位置描述 |
archiveDate |
String(yyyy-MM-dd) |
是 | 归档日期 |
summary |
String | 否 | 摘要 |
tags |
String | 否 | 关键词,英文逗号分隔 |
remark |
String | 否 | 备注 |
blobIds |
Long[] | 否 | 附件 ID 全量列表,**清空须传 []** |
响应新增/只读字段: no、categoryName、sourceType、sourceNo、sourceId、sourceTitle、archivistUserId、archivistName、status、attachmentList、hasAttachment。
⚠
no/status/source*/archivist*不要在提交体里回传(后端 SaveReqVO 不接收,回传无意义且会被忽略)。
/archive/borrow| 方法 | 路径 | 权限 | 说明 |
|---|---|---|---|
| POST | /archive/borrow/create |
archive:borrow:create |
登记借阅(草稿) |
| PUT | /archive/borrow/update |
archive:borrow:update |
修改(仅草稿/已驳回) |
| DELETE | /archive/borrow/delete?id |
archive:borrow:delete |
删除(仅草稿) |
| GET | /archive/borrow/get?id |
archive:borrow:query |
详情 |
| GET | /archive/borrow/page |
archive:borrow:query |
分页 |
| GET | /archive/borrow/overdue-page |
archive:borrow:query |
逾期未还分页(借出中 且 归还期限已过) |
| POST | /archive/borrow/submit?id&processDefinitionKey |
archive:borrow:submit |
提交审批 |
| GET | /archive/borrow/approve-process-list |
archive:borrow:query |
审批流程定义列表({ id, key, name }) |
| POST | /archive/borrow/return |
archive:borrow:return |
归还登记 |
/page 与 /overdue-page 请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNo / pageSize |
Integer | 是 | 分页 |
no |
String | 否 | 借阅单号,模糊匹配 |
documentNo |
String | 否 | 档案编号,模糊匹配 |
documentTitle |
String | 否 | 档案标题,模糊匹配 |
borrowerName |
String | 否 | 借阅人姓名,模糊匹配 |
status |
Integer | 否 | 状态 |
borrowDate |
LocalDate[] | 否 | 借阅日期区间,yyyy-MM-dd |
returnDeadline |
LocalDate[] | 否 | 归还期限区间,yyyy-MM-dd |
新增/修改请求体:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
Long | 修改必填 | 编号 |
documentId |
Long | 是 | 档案 ID(须为**在库**档案) |
borrowerUserId |
Long | 否 | 借阅人用户 ID |
borrowerName |
String | 是 | 借阅人姓名 |
borrowerDept |
String | 否 | 借阅人部门 |
borrowerPhone |
String | 否 | 联系电话 |
borrowDate |
String(yyyy-MM-dd) |
是 | 借阅日期 |
borrowPurpose |
String | 否 | 借阅目的 |
returnDeadline |
String(yyyy-MM-dd) |
是 | 归还期限(不得早于借阅日期) |
remark |
String | 否 | 备注 |
归还登记请求体:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
Long | 是 | 借阅单编号 |
returnRemark |
String | 否 | 归还备注 |
响应新增只读字段: no、documentNo、documentTitle、approveTime、returnTime、returnConfirmUserId、returnConfirmUserName、rejectReason、rejectTime、overdue、overdueDays、processInstanceId。
响应示例:
{
"code": 0,
"data": {
"list": [
{
"id": 1,
"no": "JY20260929000001",
"documentId": 1,
"documentNo": "DA20260929000001",
"documentTitle": "2026年度学会工作总结",
"borrowerName": "张三",
"borrowerDept": "秘书处",
"borrowDate": "2026-09-20",
"returnDeadline": "2026-10-05",
"status": 20,
"approveTime": "2026-09-20 10:12:33",
"overdue": false,
"overdueDays": 0
}
],
"total": 1
},
"msg": ""
}
/archive/stat| 方法 | 路径 | 权限 | 说明 |
|---|---|---|---|
| GET | /archive/stat/overview |
archive:stat:query |
统计总览(存量 + 流转 + 三组分布) |
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
totalCount |
Long | 档案总数 |
inStockCount |
Long | 在库档案数 |
borrowedCount |
Long | 借出中**档案**数 |
borrowingCount |
Long | 借出中**借阅单**数 |
overdueCount |
Long | 逾期未还借阅单数 |
byCategory |
Array | 分类分布,元素 { categoryId, name, total } |
bySecretLevel |
Array | 密级分布,元素 { value, name, total } |
byCarrierType |
Array | 载体分布,元素 { value, name, total } |
bySecretLevel/byCarrierType的name已由后端转成字典标签,前端**直接当图例名用**,无需再查字典。
| 方法 | 路径 | 权限 | 返回 |
|---|---|---|---|
| POST | /research/application/archive?id |
research:application:archive |
CommonResult<String>(档案编号) |
| POST | /ums/member/archive?id |
ums:member:archive |
CommonResult<String>(档案编号) |
| POST | /finance/reimbursement/archive?id |
finance:reimbursement:archive |
CommonResult<String>(档案编号) |
响应示例:
{ "code": 0, "data": "DA20260929000001", "msg": "" }
| 字段 | 展示位置 | 规则 |
|---|---|---|
no |
档案列表、详情 | 后端生成,只读 |
title |
列表、详情、表单 | 列表可模糊搜索 |
categoryName |
列表 | 后端 join 分类冗余,列表直接展示名称而非 ID |
secretLevel |
列表、表单 | CellDict 取 archive_secret_level;**保密档案无权限时根本不返回** |
carrierType |
列表、表单 | CellDict 取 archive_carrier_type |
sourceType |
列表 | CellDict 取 archive_source_type |
sourceNo |
列表、详情 | 来源单号(立项编号/会员编号/报销单号) |
storePlace + 四位置字段 |
列表、详情 | 实体位置;电子载体时可为空 |
archiveDate |
列表、详情、表单 | yyyy-MM-dd |
status(档案) |
列表、表单(只读) | CellDict 取 archive_document_status |
hasAttachment |
列表 | 用 slot 渲染「有 / 无」Tag |
overdue / overdueDays |
借阅列表、借阅详情 | 用 slot 渲染,逾期时红色 Tag「逾期 N 天」 |
status(借阅) |
借阅列表、审批详情 | CellDict 取 archive_borrow_status |
documentNo / documentTitle |
借阅列表 | 归档时的快照,档案改名不影响历史借阅单 |
approveTime / returnTime |
借阅列表 | formatDateTime 格式化 |
archiveDocumentId |
课题 / 会员 / 财务列表 | 非空即显示「已归档」,并隐藏「归档」按钮 |
| 场景 | 规则 |
|---|---|
| 删除分类 | 有子分类或有档案时拒绝,提示中回显分类名与具体原因 |
| 修改分类父级 | 不能把分类设为自身或其子分类 |
| 修改档案 | 档案处于「借出中」时拒绝修改 |
| 删除档案 | 档案处于「借出中」或存在未归还借阅单时拒绝 |
| 删除借阅单 | 仅「草稿」可删除 |
| 提交借阅审批 | 仅「草稿」「已驳回」可提交;提交前校验同档案无「审批中/借出中」借阅单 |
| 归还期限 | 不得早于借阅日期 |
| 审批通过 | 借阅单 → 借出中并写 approveTime;**同时**把档案置为「借出中」 |
| 审批驳回 | 借阅单 → 已驳回并写 rejectReason / rejectTime,改后可重新提交 |
| 归还登记 | 仅「借出中」可登记;成功后档案回到「在库」 |
| 逾期 | 实时计算,不落库、不发站内信、不建定时任务;仅列表 Tag 与「只看逾期」接口体现 |
| 敏感档案 | 无 archive:document:sensitive 时,/page、/get、/export-excel 三个入口均过滤/拒绝 |
| 归档幂等 | 同一来源单据重复归档会报错,提示中带来源单号与已生成档案编号 |
| 财务归档 | 报销单 20→40(既有)**并**生成「保密」档案(本次新增),同事务 |
POST /system/storage-blob/upload → 拿 blobId;表单字段用全局 FileUpload 组件绑定 blobIds。**禁止**在档案表加 file_url 列、禁止新增上传接口、禁止用 infra 的 FileApi。blobIds 是全量替换语义:编辑时若清空了全部附件,必须提交 [];提交 null 后端会视为「不动附件」。打开编辑弹窗时应把 attachmentList 映射成 { uid, name, url, status: 'done', id } 数组。valueFormat: 'YYYY-MM-DD':后端 LocalDate[] 只接受 yyyy-MM-dd,带时分秒会解析失败。approve-process-list;返回空数组时提示用户先去 BPM 发布流程。src/views/archive/borrow/detail/approve/index.vue 必须与 bpm_process_definition_info.form_custom_view_path 一致,且组件需接受 props: { id: string }(BPM 审批中心通过 businessKey 传入借阅单 ID)。改动路径会导致待办审批页打不开。archived 之外的字段:按钮显隐条件建议用 status === 已通过/已立项/正常 && !archiveDocumentId,归档成功后刷新列表即可自动隐藏。/archive 菜单不出现。