feat(documents): 接入文档库真实接口
This commit is contained in:
@@ -8,7 +8,9 @@ import {
|
||||
deleteTemplate,
|
||||
getDocuments,
|
||||
getTemplateContent,
|
||||
getTemplateVersionDetail,
|
||||
getTemplateVersions,
|
||||
readVersionContentHtml,
|
||||
updateTemplate,
|
||||
updateTemplateContent,
|
||||
updateTemplateVersionStatus,
|
||||
@@ -18,6 +20,7 @@ import { getCampuses, getDepartments } from '@/api/management/organization'
|
||||
import type {
|
||||
CampusRecord,
|
||||
CreateTemplateRequest,
|
||||
CreateTemplateVersionRequest,
|
||||
DocumentRecord,
|
||||
DepartmentRecord,
|
||||
TemplateVersionResponseDto,
|
||||
@@ -56,8 +59,8 @@ import type {
|
||||
/**
|
||||
* 文档库数据来源。
|
||||
*
|
||||
* - 演示模式(VITE_MOCK_DOCUMENTS 开启,缺省开启):读本地演示文书库,可随意增删改;
|
||||
* - 真实模式:读模板接口。列表只给模板元数据(含 currentVersionId),
|
||||
* - 演示模式(显式开启 VITE_MOCK_DOCUMENTS):读本地演示文书库,可随意增删改;
|
||||
* - 真实模式:读模板接口。列表只给模板元数据(含发布/最新版本指针),
|
||||
* 正文要再取一次版本详情——这是接入时最容易被忽略的一步,
|
||||
* 缺了它文档库会显示一堆没有正文、无法预览的"空壳模板"。
|
||||
*
|
||||
@@ -78,7 +81,8 @@ const canCreateTemplate = computed(
|
||||
const canEditTemplate = computed(
|
||||
() =>
|
||||
!loginStore.isReadOnly &&
|
||||
(useMockLibrary || loginStore.hasWritePermission('sign:template:version:create')),
|
||||
(useMockLibrary ||
|
||||
loginStore.hasWritePermission(['sign:template:update', 'sign:template:version:create'])),
|
||||
)
|
||||
const canArchiveTemplate = computed(
|
||||
() =>
|
||||
@@ -89,6 +93,22 @@ const canInitiateSigning = computed(
|
||||
() =>
|
||||
!loginStore.isReadOnly && (useMockLibrary || loginStore.hasWritePermission('sign:task:create')),
|
||||
)
|
||||
|
||||
const workflowPermissions: Record<TemplateVersionAction, string> = {
|
||||
'submit-review': 'sign:template:review:submit',
|
||||
reject: 'sign:template:review:reject',
|
||||
approve: 'sign:template:review:approve',
|
||||
publish: 'sign:template:publish',
|
||||
disable: 'sign:template:disable',
|
||||
archive: 'sign:template:archive',
|
||||
}
|
||||
|
||||
function canRunTemplateWorkflow(action: TemplateVersionAction) {
|
||||
return (
|
||||
!loginStore.isReadOnly &&
|
||||
(useMockLibrary || loginStore.hasWritePermission(workflowPermissions[action]))
|
||||
)
|
||||
}
|
||||
/** 真实模式下的加载状态:区分"正在加载"与"确实没有模板" */
|
||||
const libraryLoading = ref(false)
|
||||
const libraryError = ref('')
|
||||
@@ -177,8 +197,7 @@ const filteredTemplates = computed(() => {
|
||||
|
||||
return allTemplates.value.filter((template) => {
|
||||
const matchesDepartment = !filters.department || template.departmentKey === filters.department
|
||||
const matchesStatus =
|
||||
filters.status === 'all' || readBackendStatus(template) === filters.status
|
||||
const matchesStatus = filters.status === 'all' || readBackendStatus(template) === filters.status
|
||||
const matchesKeyword =
|
||||
!keyword ||
|
||||
[template.name, template.code, template.department].join(' ').toLowerCase().includes(keyword)
|
||||
@@ -364,7 +383,7 @@ async function handlePreview(template: DocumentTemplate) {
|
||||
previewError.value = false
|
||||
|
||||
try {
|
||||
const contentHtml = await getTemplateContent(template.id)
|
||||
const contentHtml = await getTemplateContent(template.id, template.versionId)
|
||||
|
||||
// 用户在等待期间可能已经切到别的文书,回填前确认仍是同一份
|
||||
if (selectedTemplate.value?.id === template.id) {
|
||||
@@ -422,7 +441,7 @@ async function showEditMessage(template: DocumentTemplate) {
|
||||
wordEditorLoading.value = true
|
||||
|
||||
try {
|
||||
const contentHtml = await getTemplateContent(template.id)
|
||||
const contentHtml = await getTemplateContent(template.id, template.versionId)
|
||||
|
||||
if (!contentHtml) {
|
||||
ElMessage.error('未能取到该文书的正文内容,请确认模板版本内容接口可访问')
|
||||
@@ -512,9 +531,11 @@ function toCreatePayload(form: TemplateEditorForm): CreateTemplateRequest {
|
||||
}
|
||||
}
|
||||
|
||||
function toVersionPayload(form: TemplateEditorForm) {
|
||||
function toVersionPayload(
|
||||
form: TemplateEditorForm,
|
||||
): Omit<CreateTemplateVersionRequest, 'signatureFields'> {
|
||||
return {
|
||||
versionNo: form.versionNo,
|
||||
...(useMockLibrary && form.versionNo ? { versionNo: form.versionNo } : {}),
|
||||
contentHtml: form.contentHtml,
|
||||
}
|
||||
}
|
||||
@@ -537,6 +558,8 @@ async function saveTemplate(form: TemplateEditorForm) {
|
||||
return
|
||||
}
|
||||
|
||||
let versionCreated = false
|
||||
|
||||
try {
|
||||
let savedId = form.id
|
||||
|
||||
@@ -545,6 +568,7 @@ async function saveTemplate(form: TemplateEditorForm) {
|
||||
// 新版本的状态由后端决定,前端不在这里「顺带发布」——发布是需要留痕的正式动作,
|
||||
// 要由人显式触发(见 handleWorkflow),否则「谁把这份文书放行到可签署」无从追溯。
|
||||
await updateTemplateContent(form.id, toVersionPayload(form))
|
||||
versionCreated = true
|
||||
await updateTemplate(form.id, {
|
||||
name: form.name,
|
||||
description: form.description,
|
||||
@@ -573,7 +597,11 @@ async function saveTemplate(form: TemplateEditorForm) {
|
||||
)
|
||||
}
|
||||
} catch {
|
||||
ElMessage.error(form.id ? '文书更新失败,请稍后重试' : '文书创建失败,请稍后重试')
|
||||
if (form.id && versionCreated) {
|
||||
ElMessage.error('新版本已保存,但文书名称、说明或分类更新失败;请刷新后重试基本信息')
|
||||
} else {
|
||||
ElMessage.error(form.id ? '文书更新失败,请稍后重试' : '文书创建失败,请稍后重试')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,6 +655,11 @@ async function handleWorkflow(template: DocumentTemplate, action: TemplateVersio
|
||||
return
|
||||
}
|
||||
|
||||
if (!canRunTemplateWorkflow(action)) {
|
||||
ElMessage.warning(`当前账号没有${workflowActionLabels[action]}权限`)
|
||||
return
|
||||
}
|
||||
|
||||
const label = workflowActionLabels[action]
|
||||
let reason: string | undefined
|
||||
|
||||
@@ -777,10 +810,23 @@ async function removeTemplate(template: DocumentTemplate) {
|
||||
* 与模板无关的空文书。因此这里在缺正文时先取回,取不到就拒绝发起。
|
||||
*/
|
||||
async function toSigningTemplate(template: DocumentTemplate): Promise<SigningTemplate | null> {
|
||||
let contentHtml = template.contentHtml
|
||||
if (!useMockLibrary && !template.currentVersionId) {
|
||||
ElMessage.error('该文书还没有已发布版本,无法发起签署')
|
||||
return null
|
||||
}
|
||||
|
||||
if (!useMockLibrary && !contentHtml) {
|
||||
contentHtml = await getTemplateContent(template.id)
|
||||
let contentHtml = template.contentHtml
|
||||
let versionNo = template.version
|
||||
let contentSha256 = template.contentSha256
|
||||
const signingVersionId = useMockLibrary
|
||||
? (template.versionId ?? template.id)
|
||||
: template.currentVersionId!
|
||||
|
||||
if (!useMockLibrary) {
|
||||
const version = await getTemplateVersionDetail(template.id, signingVersionId)
|
||||
contentHtml = readVersionContentHtml(version)
|
||||
versionNo = version?.versionNo ?? versionNo
|
||||
contentSha256 = version?.contentSha256 ?? contentSha256
|
||||
|
||||
if (!contentHtml) {
|
||||
ElMessage.error('未能取到该文书的正文内容,无法发起签署')
|
||||
@@ -790,10 +836,10 @@ async function toSigningTemplate(template: DocumentTemplate): Promise<SigningTem
|
||||
|
||||
return {
|
||||
id: template.id,
|
||||
versionId: template.versionId ?? template.id,
|
||||
versionId: signingVersionId,
|
||||
name: template.name,
|
||||
code: template.code ?? '',
|
||||
version: template.version,
|
||||
version: versionNo,
|
||||
department: template.department,
|
||||
departmentId: template.departmentId,
|
||||
campusId: template.campusId ?? undefined,
|
||||
@@ -801,7 +847,7 @@ async function toSigningTemplate(template: DocumentTemplate): Promise<SigningTem
|
||||
description: template.description ?? '',
|
||||
supportedMethods: ['pad', 'sms'],
|
||||
contentHtml,
|
||||
contentSha256: template.contentSha256,
|
||||
contentSha256,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -930,6 +976,7 @@ onMounted(() => {
|
||||
:template="template"
|
||||
:can-edit="canEditTemplate"
|
||||
:can-initiate="canInitiateSigning"
|
||||
:can-workflow="canRunTemplateWorkflow"
|
||||
:can-remove="canArchiveTemplate"
|
||||
:is-mock="useMockLibrary"
|
||||
@preview="handlePreview"
|
||||
@@ -978,6 +1025,7 @@ onMounted(() => {
|
||||
:template="wordEditingTemplate"
|
||||
:campuses="campuses"
|
||||
:departments="departments"
|
||||
:is-mock="useMockLibrary"
|
||||
@close="wordEditorVisible = false"
|
||||
@save="saveTemplate"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user