<script lang="ts" setup>
|
import type { DmsCompareSession } from '#/api/x/dms/compare';
|
import type { DmsFileCenterItem } from '#/api/x/dms/fileCenter';
|
|
import { computed, ref } from 'vue';
|
|
import { BasicForm, useForm } from '@jnpf/ui/form';
|
import { BasicModal, useModalInner } from '@jnpf/ui/modal';
|
import { formatToDateTime } from '@jnpf/utils';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
import { createDmsCompareSession } from '#/api/x/dms/compare';
|
import { getDocumentVersions } from '#/api/x/dms/fileCenter';
|
|
import { comparableVersions, versionLabel } from './compareRules';
|
|
const emit = defineEmits<{ compare: [session: DmsCompareSession] }>();
|
const current = ref<DmsFileCenterItem>();
|
const versions = ref<DmsFileCenterItem[]>([]);
|
const selectedId = ref<string>();
|
const cursor = ref<string>();
|
const hasMore = ref(false);
|
const loading = ref(false);
|
const submitting = ref(false);
|
const error = ref('');
|
let generation = 0;
|
const options = computed(() =>
|
versions.value.map((item) => ({
|
value: item.id,
|
label: `${versionLabel(item)} · ${formatToDateTime(item.createdAt)}`,
|
})),
|
);
|
const [registerForm, { resetFields, validate }] = useForm({
|
baseColProps: { span: 24 },
|
layout: 'vertical',
|
schemas: [
|
{
|
component: 'Select',
|
componentProps: () => ({
|
disabled: submitting.value,
|
fieldNames: { label: 'label', value: 'value' },
|
loading: loading.value,
|
onChange: (value?: string) => (selectedId.value = value),
|
options: options.value,
|
placeholder: '请选择之前修订的版本',
|
}),
|
field: 'historicalVersionId',
|
label: '历史版本号',
|
rules: [{ message: '请选择历史版本号', required: true, trigger: 'change' }],
|
},
|
],
|
showActionButtonGroup: false,
|
});
|
const [registerModal, { closeModal }] = useModalInner(async (data: { item: DmsFileCenterItem }) => {
|
generation++;
|
current.value = data.item;
|
versions.value = [];
|
selectedId.value = undefined;
|
cursor.value = undefined;
|
hasMore.value = false;
|
submitting.value = false;
|
error.value = '';
|
await resetFields();
|
await loadVersions();
|
});
|
|
async function loadVersions() {
|
const item = current.value;
|
if (!item?.documentId) return;
|
const requestGeneration = generation;
|
loading.value = true;
|
error.value = '';
|
try {
|
const response = await getDocumentVersions('HISTORICAL', item.documentId, { pageSize: 50, cursor: cursor.value });
|
if (requestGeneration !== generation) return;
|
const unique = new Map([...versions.value, ...response.data.list].map((version) => [version.id, version]));
|
versions.value = comparableVersions(item, [...unique.values()]);
|
cursor.value = response.data.nextCursor;
|
hasMore.value = response.data.hasMore && !!response.data.nextCursor;
|
} catch (error_) {
|
if (requestGeneration === generation) error.value = error_ instanceof Error ? error_.message : '历史版本加载失败,请重试';
|
} finally {
|
if (requestGeneration === generation) loading.value = false;
|
}
|
}
|
|
function cancel() {
|
generation++;
|
}
|
|
async function submit() {
|
const item = current.value;
|
if (!item?.documentId || submitting.value) return;
|
const values = await validate();
|
if (!values) return;
|
const historicalVersionId = String(values.historicalVersionId || '');
|
if (!historicalVersionId) return;
|
const requestGeneration = generation;
|
submitting.value = true;
|
error.value = '';
|
try {
|
const session = await createDmsCompareSession({
|
documentId: item.documentId,
|
currentVersionId: item.id,
|
historicalVersionId,
|
operationId: uuidv4(),
|
});
|
if (requestGeneration !== generation) return;
|
closeModal();
|
emit('compare', session);
|
} catch (error_) {
|
if (requestGeneration === generation) error.value = error_ instanceof Error ? error_.message : '无法开始比较,请刷新后重试';
|
} finally {
|
if (requestGeneration === generation) submitting.value = false;
|
}
|
}
|
</script>
|
|
<template>
|
<BasicModal
|
v-bind="$attrs"
|
title="版本比较"
|
:width="560"
|
:confirm-loading="submitting"
|
:ok-button-props="{ disabled: !selectedId || loading || submitting }"
|
@register="registerModal"
|
@ok="submit"
|
@cancel="cancel">
|
<a-descriptions bordered size="small" :column="1" class="mb-[20px]">
|
<a-descriptions-item label="文件名称">{{ current?.fileName || current?.name }}</a-descriptions-item>
|
<a-descriptions-item label="现行版本">{{ versionLabel(current) }}</a-descriptions-item>
|
</a-descriptions>
|
<BasicForm @register="registerForm" />
|
<a-button v-if="hasMore" type="link" :loading="loading" :disabled="submitting" @click="loadVersions">加载更多历史版本</a-button>
|
<jnpf-empty v-if="!loading && !error && versions.length === 0" description="没有可比较的历史 DOCX 版本" />
|
<p v-if="submitting">正在生成版本差异,请稍候…</p>
|
<a-alert v-if="error" type="error" show-icon :message="error" class="mb-[12px]" />
|
<a-button v-if="error && !submitting" type="link" @click="loadVersions">重新加载版本</a-button>
|
<div class="text-secondary">以历史版本为基准,查看现行版本的新增、删除及修改。</div>
|
</BasicModal>
|
</template>
|