Commit b914ba26 by HoMeTown

feat: 文档集管理

parent 5fc78b41
import { request } from '../request';
/**
* 文档列表
*/
export function fetchQueryDocList<T>(params: T) {
return request.post(`/product/pc/v1/docSet/query_document_list`, params);
}
/**
* 新增 文档集文档
*/
export function fetchAddSetDoc<T>(params: T) {
return request.post(`/product/pc/v1/docSet/add_document`, params);
}
/**
* 新增 文档集文档
*/
export function fetchUpdateSetDoc<T>(params: T) {
return request.post(`/product/pc/v1/docSet/update_document`, params);
}
/**
* 删除 文档集文档
*/
export function fetchDeleteSetDoc<T>(params: T) {
return request.post(`/product/pc/v1/docSet/delete_document`, params);
}
/**
* 提交 文档集文档
*/
export function fetchSubmitSetDoc<T>(params: T) {
return request.post(`/product/pc/v1/docSet/submit_document`, params);
}
/**
* 审核 文档
*/
export function fetchAuditSetDoc<T>(params: T) {
return request.post(`/product/pc/v1/docSet/audit_document`, params);
}
/**
* 撤回解析 文档集文档
*/
export function fetchBackOffSetDoc<T>(params: T) {
return request.post(`/product/pc/v1/docSet/analysis_backOff_document`, params);
}
/**
* 重新解析 文档集文档
*/
export function fetchAnalysisSetDoc<T>(params: T) {
return request.post(`/product/pc/v1/docSet/analysis_document`, params);
}
/**
* 文档集列表
*/
export function fetchGetDocSetList<T>(params: T) {
return request.post(`/product/pc/v1/docSet/query_documentSet_list`, params);
}
......@@ -5,3 +5,4 @@ export * from './users';
export * from './order';
export * from './channel';
export * from './product';
export * from './doc';
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import { PAGINATION_PAGE_SIZES } from '@/const/index'
import { Icon } from '@iconify/vue';
import { objectClean } from '@/utils';
import {
fetchQueryDocList,
fetchAddSetDoc,
fetchUpdateSetDoc,
fetchDeleteSetDoc,
fetchBackOffSetDoc,
fetchAnalysisSetDoc,
fetchUploadImgFile,
fetchGetDocSetList,
fetchSubmitSetDoc,
fetchAuditSetDoc
} from '@/service/api';
const docTypeCodeOptions = [
{ label: '渠道业务规则文档', value: '01' },
{ label: '产品相关监管规定文档', value: '02' },
{ label: '产品相关宣传素材文档', value: '03' },
{ label: '个养-商养产品信息文档', value: '04' },
]
const docStatusOptions = [
{ label: '草稿', value: '00' },
{ label: '待审核', value: '01' },
{ label: '审核通过', value: '02' },
{ label: '驳回', value: '03' },
]
const auditDocStatusOptions = [
{ label: '审核通过', value: '02' },
{ label: '驳回', value: '03' },
]
const analyzeStatusOptions = [
{ label: '待解析', value: '00' },
{ label: '解析中', value: '01' },
{ label: '解析完成', value: '02' },
{ label: '解析失败', value: '03' },
{ label: '撤回解析', value: '04' },
]
const pagination = ref({
pageSize: 10,
itemCount: 0,
pageNum: 1
});
function handlePageUpdate(page: number) {
pagination.value.pageNum = page;
getListData();
}
function handlePageSizeUpdate(pageSize: number) {
pagination.value.pageNum = 1;
pagination.value.pageSize = pageSize;
getListData();
}
function createQueryParams() {
return {
docName: '',
docTypeCode: null,
docStatus: null,
analyzeStatus: null,
createTime: null,
createTimeStart: '',
createTimeEnd: '',
auditTime: null,
auditTimeStart: '',
auditTimeEnd: ''
};
}
const loading = ref(false);
const listData = ref([]);
const queryParams = ref(createQueryParams());
/** 检索 */
function handleQuery() {
getListData();
}
/** 重置检索 */
function handleResetQuery() {
queryParams.value = { ...createQueryParams() };
pagination.value = {
pageSize: 10,
itemCount: 0,
pageNum: 1
}
getListData();
}
async function getListData() {
loading.value = true;
const { pageNum, pageSize } = pagination.value;
const { docName, docTypeCode, docStatus, analyzeStatus, createTime, auditTime } = queryParams.value;
const params = {
docName,
docTypeCode,
docStatus,
analyzeStatus,
createTimeStart: createTime ? `${createTime[0]} 00:00:00` : '',
createTimeEnd: createTime ? `${createTime[1]} 23:59:59` : '',
auditTimeStart: auditTime ? `${auditTime[0]} 00:00:00` : '',
auditTimeEnd: auditTime ? `${auditTime[1]} 23:59:59` : '',
pageNum,
pageSize
};
const { data } = await fetchQueryDocList(objectClean(params));
if (data?.ok) {
listData.value = data.data.records;
pagination.value.itemCount = data.data.total;
}
loading.value = false;
}
// 00-待解析 01-解析中 02-解析完成 03-解析失败 04-撤回解析
function filterAnalyzeStatus(status: string) {
switch (status) {
case '00':
return '待解析'
break;
case '01':
return '解析中'
break;
case '02':
return '解析完成'
break;
case '03':
return '解析失败'
break;
case '04':
return '撤回解析'
break;
default:
return '未知'
break;
}
}
// 00-草稿 01-待审核 02-审核通过 03-审核驳回
function filterDocStatus(status: string) {
switch (status) {
case '00':
return '草稿 '
break;
case '01':
return '待审核 '
break;
case '02':
return '审核通过'
break;
case '03':
return '审核驳回'
break;
default:
return '未知'
break;
}
}
const isShowAddDocModal = ref(false)
const addDocForm = ref({
docTypeCode: null,
docUrl: '',
docName: '',
docCode: ''
})
const addDocRules = ref({
docTypeCode: {
required: true,
trigger: ['blur', 'change'],
message: '请选择 文档类型'
},
docUrl: {
required: true,
trigger: ['blur', 'change'],
message: '请选择 上传文件'
},
docStatus: {
required: true,
trigger: ['blur', 'change'],
message: '请选择 审核结论'
},
})
const addDocFormRef = ref()
function onCloseAddDocModal() {
addDocForm.value = {
docTypeCode: null,
docUrl: '',
docName: '',
docCode: ''
}
isShowAddDocModal.value = false
}
const addDocLoading = ref(false)
function handleValidateAddDocForm() {
addDocFormRef.value?.validate((errors) => {
if (!errors) {
submitAddProdcutDoc()
}
else {
console.log(errors)
}
})
}
const defaultFileList = ref([])
const operateType = ref('')
function onAddDoc() {
operateType.value = 'add'
defaultFileList.value = []
addDocForm.value = {
docTypeCode: null,
docUrl: '',
docName: '',
docCode: ''
}
isShowAddDocModal.value = true
}
function onEditDoc(data: any) {
operateType.value = 'edit'
addDocForm.value = {
...data
}
defaultFileList.value = [
{
id: addDocForm.value.docCode,
name: addDocForm.value.docName,
status: 'finished'
}
]
isShowAddDocModal.value = true
}
function onPreDoc(data: any) {
operateType.value = 'preview'
addDocForm.value = {
...data
}
defaultFileList.value = [
{
id: addDocForm.value.docCode,
name: addDocForm.value.docName,
status: 'finished'
}
]
isShowAddDocModal.value = true
}
const ossConfig = ref(null)
async function handlePreview(file: any) {
window.open(addDocForm.value.tempDocUrl)
}
async function submitAddProdcutDoc() {
addDocLoading.value = true
const params = {
docTypeCode: addDocForm.value.docTypeCode,
docUrl: addDocForm.value.docUrl,
docName: addDocForm.value.docName,
docCode: addDocForm.value.docCode,
docStatus: addDocForm.value.docStatus,
auditDesc: addDocForm.value.auditDesc
}
const apis = {
add: fetchAddSetDoc,
edit: fetchUpdateSetDoc,
audit: fetchAuditSetDoc
}
const res = await apis[operateType.value](params)
if (res.data) {
getListData()
onCloseAddDocModal()
window.$message?.success('成功');
}
addDocLoading.value = false
}
async function customRequest({
file,
data,
headers,
withCredentials,
action,
onFinish,
onError,
onProgress
}: UploadCustomRequestOptions) {
const fm = new FormData()
fm.append('file', file.file)
fm.append('scene', 'product')
const res = await fetchUploadImgFile(fm, {
withCredentials,
onUploadProgress: ({ percent }) => {
onProgress({ percent: Math.ceil(percent) })
}
})
if (res.data) {
addDocForm.value.docUrl = res.data.data.fullUrl
addDocForm.value.docName = file.name
onFinish()
} else {
onError()
}
}
function onDeleteProductDoc(data: any) {
window.$dialog?.info({
title: '提示',
content: '您确定要删除当前产品文档吗?',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: async () => {
const res = await fetchDeleteSetDoc({
...data,
});
if (res?.data?.ok) {
window.$message?.success('操作成功');
getListData()
}
}
});
}
async function onSubmitProductDoc(data: any) {
const res = await fetchSubmitSetDoc({
...data
})
if (res.data) {
window.$message?.success('操作成功');
getListData()
}
}
async function onBackOffDoc(data: any) {
const res = await fetchBackOffSetDoc({
...data
})
if (res.data) {
window.$message?.success('操作成功');
getListData()
}
}
async function onAnalysisDoc(data: any) {
const res = await fetchAnalysisSetDoc({
...data
})
if (res.data) {
window.$message?.success('操作成功');
getListData()
}
}
function onAuditDoc(data: any) {
operateType.value = 'audit'
addDocForm.value = {
...data,
docStatus: null,
auditDesc: ''
}
defaultFileList.value = [
{
id: addDocForm.value.docCode,
name: addDocForm.value.docName,
status: 'finished'
}
]
isShowAddDocModal.value = true
}
onMounted(() => {
getListData()
})
</script>
<template>
<n-card class="h-full shadow-sm rounded-8px">文档集管理</n-card>
<div>
<n-card class="h-full shadow-sm rounded-8px">
<n-grid cols="1 s:2 m:3 l:4 xl:5 2xl:6" responsive="screen" x-gap="12" y-gap="12">
<n-grid-item>
<p class="mb-6px">文档名称:</p>
<n-input clearable v-model:value="queryParams.docName" placeholder="文档名称"></n-input>
</n-grid-item>
<n-grid-item>
<p class="mb-6px">文档类型:</p>
<n-select v-model:value="queryParams.docTypeCode" clearable placeholder="文档类型"
:options="docTypeCodeOptions" />
</n-grid-item>
<n-grid-item>
<p class="mb-6px">文档状态:</p>
<n-select v-model:value="queryParams.docStatus" clearable placeholder="文档状态" :options="docStatusOptions" />
</n-grid-item>
<n-grid-item>
<p class="mb-6px">解析状态:</p>
<n-select v-model:value="queryParams.analyzeStatus" clearable placeholder="解析状态"
:options="analyzeStatusOptions" />
</n-grid-item>
<n-grid-item>
<p class="mb-6px">创建时间:</p>
<n-date-picker v-model:formatted-value="queryParams.createTime" :actions="[]" close-on-select
value-format="yyyy-MM-dd" placeholder="创建时间" type="daterange" start-placeholder="开始" end-placeholder="结束"
clearable />
</n-grid-item>
<n-grid-item>
<p class="mb-6px">审核时间:</p>
<n-date-picker v-model:formatted-value="queryParams.auditTime" :actions="[]" close-on-select
value-format="yyyy-MM-dd" placeholder="审核时间" type="daterange" start-placeholder="开始" end-placeholder="结束"
clearable />
</n-grid-item>
<n-grid-item class="flex items-end">
<n-space>
<n-button secondary strong type="primary" @click="handleQuery"> 查 询 </n-button>
<n-button secondary strong @click="handleResetQuery">重 置</n-button>
</n-space>
</n-grid-item>
</n-grid>
</n-card>
<n-card class="shadow-sm rounded-8px mt-12px">
<n-space class="mb-12px">
<n-button strong type="primary" @click="onAddDoc"> 新增文档 </n-button>
</n-space>
<n-spin :show="loading">
<vxe-table :column-config="{ resizable: true }"
:seq-config="{ startIndex: (pagination.pageNum - 1) * pagination.pageSize }" auto-resize
:row-config="{ isHover: true }" stripe border :data="listData">
<vxe-column type="seq" title="序号" width="60"></vxe-column>
<vxe-column min-width="200" field="docName" title="文档名称"></vxe-column>
<vxe-column min-width="200" field="docTypeName" title="文档类型"></vxe-column>
<vxe-column min-width="120" field="docStatus" title="文档状态">
<template #default="{ row }">
<span>{{ filterDocStatus(row.docStatus) }}</span>
</template>
</vxe-column>
<vxe-column min-width="120" field="analyzeStatus" title="解析状态">
<template #default="{ row }">
<span>{{ filterAnalyzeStatus(row.analyzeStatus) }}</span>
</template>
</vxe-column>
<vxe-column min-width="200" field="createBy" title="创建人"></vxe-column>
<vxe-column min-width="200" field="createTime" title="创建时间"></vxe-column>
<vxe-column min-width="200" field="auditBy" title="审核人"></vxe-column>
<vxe-column min-width="200" field="auditTime" title="审核时间"></vxe-column>
<vxe-column field="title" title="操作" fixed="right" min-width="120">
<template #default="{ row }">
<n-space>
<n-button @click="onEditDoc(row)" v-if="row.docStatus === '00' || row.docStatus === '03'" strong text
type="info">编辑</n-button>
<n-button @click="onSubmitProductDoc(row)" v-if="row.docStatus === '00' || row.docStatus === '03'"
strong text type="info">提交</n-button>
<n-button v-if="row.docStatus === '00' || row.docStatus === '03'" strong text type="info"
@click="onDeleteProductDoc(row)">删除</n-button>
<n-button @click="onPreDoc(row)" v-if="row.docStatus !== '00' && row.docStatus !== '03'" strong text
type="info">预览文档</n-button>
<n-button @click="onAuditDoc(row)" v-if="row.docStatus === '01'" strong text type="info">审核</n-button>
<n-button @click="onBackOffDoc(row)" v-if="row.analyzeStatus && row.analyzeStatus === '02'" strong text
type="info">撤回解析</n-button>
<n-button @click="onAnalysisDoc(row)"
v-if="row.analyzeStatus && row.analyzeStatus !== '00' && row.analyzeStatus !== '01'" strong text
type="info">重新解析</n-button>
</n-space>
</template>
</vxe-column>
</vxe-table>
</n-spin>
<div v-if="pagination.itemCount !== 0" class="w-full flex justify-end mt-4">
<n-pagination v-model:page="pagination.pageNum" v-model:page-size="pagination.pageSize"
:item-count="pagination.itemCount" :page-sizes="PAGINATION_PAGE_SIZES" :on-update:page="handlePageUpdate"
:on-update:page-size="handlePageSizeUpdate" show-size-picker>
<template #prefix="{ itemCount, startIndex }">
<div class="text-[#333]"><span class="text-primary">{{ pagination.itemCount }}</span></div>
</template>
</n-pagination>
</div>
</n-card>
<n-modal v-model:show="showAddProductModal">
<n-card style="max-width: 600px;" title="新增产品" :bordered="false" size="huge" role="dialog" aria-modal="true">
<template #header-extra>
<Icon icon="ic:sharp-close" class="text-size-22px cursor-pointer" @click="showAddProductModal = false" />
</template>
<n-form ref="addProductFormRef" :model="addFormModal" :rules="rules" label-placement="left" label-width="auto"
require-mark-placement="right-hanging" :size="size" :style="{
maxWidth: '640px',
}">
<n-form-item label="产品编码" path="productCode">
<n-input show-count maxlength="16" v-model:value="addFormModal.productCode" placeholder="产品编码" />
</n-form-item>
<n-form-item label="产品名称" path="productName">
<n-input show-count maxlength="32" v-model:value="addFormModal.productName" placeholder="产品名称" />
</n-form-item>
<n-form-item label="产品类别" path="productTypeId">
<n-select label-field="typeName" value-field="typeId" v-model:value="addFormModal.productTypeId" clearable
placeholder="产品类别" :options="productTypeList" />
</n-form-item>
<n-form-item label="产品介绍" path="description">
<n-input type="textarea" v-model:value="addFormModal.description" placeholder="产品介绍" />
</n-form-item>
</n-form>
<template #footer>
<n-space justify="center">
<n-button @click="onCloseAddForm">取消</n-button>
<n-button :loading="addProductLoading" type="primary" @click="handleValidateAddForm">确定</n-button>
</n-space>
</template>
</n-card>
</n-modal>
<n-modal v-model:show="isShowAddDocModal">
<n-card style="max-width: 600px;" title="新增文档" :bordered="false" size="huge" role="dialog" aria-modal="true">
<template #header-extra>
<Icon icon="ic:sharp-close" class="text-size-22px cursor-pointer" @click="isShowAddDocModal = false" />
</template>
<n-form ref="addDocFormRef" :model="addDocForm" :rules="addDocRules" label-placement="left" label-width="auto"
require-mark-placement="right-hanging" :size="size" :style="{
maxWidth: '640px',
}">
<n-form-item label="文档类型" path="docTypeCode">
<n-select :disabled="operateType === 'preview'" v-model:value="addDocForm.docTypeCode" clearable
placeholder="文档类型" :options="docTypeCodeOptions" />
</n-form-item>
<n-form-item label="上传文档" path="docTypeCode">
<div>
<n-alert type="info" :bordered="false">
<div>支持上传单个.txt/.docx/pdf/.doc/.wps/.ett/.xls/.xlsx格式文件</div>
</n-alert>
<br />
<n-upload :disabled="operateType === 'preview'" @preview="handlePreview"
:default-file-list="defaultFileList" accept="'.txt, .docx, .pdf, .doc, .wps, .ett, .xls, .xlsx'"
:max="1" action="https://naive-upload.free.beeceptor.com/" :headers="{
'naive-info': 'hello!',
}" :data="{
'naive-data': 'cool! naive!',
}" :custom-request="customRequest">
<n-button>上传文件</n-button>
</n-upload>
</div>
</n-form-item>
<n-form-item
v-if="operateType === 'audit' || operateType === 'preview' && (addDocForm.docStatus === '02' || addDocForm.docStatus === '03')"
label="审核结论" path="docStatus">
<n-select :disabled="operateType === 'preview'" v-model:value="addDocForm.docStatus" clearable
placeholder="审核结论" :options="auditDocStatusOptions" />
</n-form-item>
<n-form-item
v-if="operateType === 'audit' || operateType === 'preview' && (addDocForm.docStatus === '02' || addDocForm.docStatus === '03')"
label="审核意见" path="auditDesc">
<n-input :disabled="operateType === 'preview'" type="textarea" v-model:value="addDocForm.auditDesc"
placeholder="审核意见" />
</n-form-item>
</n-form>
<template #footer v-if="operateType !== 'preview'">
<n-space justify="center">
<n-button @click="onCloseAddDocModal">取消</n-button>
<n-button :loading="addDocLoading" type="primary" @click="handleValidateAddDocForm">
<span v-if="operateType === 'audit'">确定</span>
<span v-else>保存</span>
</n-button>
</n-space>
</template>
</n-card>
</n-modal>
</div>
</template>
......@@ -357,12 +357,11 @@ function onAuditDoc(data: any) {
}
]
isShowAddDocModal.value = true
console.log(123)
}
const ossConfig = ref(null)
async function handlePreview(file: any) {
window.open(addDocForm.value.docUrl)
window.open(addDocForm.value.tempDocUrl)
}
async function submitAddProdcutDoc() {
addDocLoading.value = true
......@@ -601,13 +600,13 @@ onMounted(() => {
<vxe-column field="title" title="操作" fixed="right" min-width="120">
<template #default="{ row }">
<n-space>
<n-button @click="onEditDoc(row)" v-if="row.docStatus === '00'" strong text
type="info">编辑</n-button>
<n-button @click="onSubmitProductDoc(row)" v-if="row.docStatus === '00'" strong text
type="info">提交</n-button>
<n-button v-if="row.docStatus === '00'" strong text type="info"
<n-button @click="onEditDoc(row)" v-if="row.docStatus === '00' || row.docStatus === '03'" strong
text type="info">编辑</n-button>
<n-button @click="onSubmitProductDoc(row)" v-if="row.docStatus === '00' || row.docStatus === '03'"
strong text type="info">提交</n-button>
<n-button v-if="row.docStatus === '00' || row.docStatus === '03'" strong text type="info"
@click="onDeleteProductDoc(row)">删除</n-button>
<n-button @click="onPreDoc(row)" v-if="row.docStatus !== '00'" strong text
<n-button @click="onPreDoc(row)" v-if="row.docStatus !== '00' && row.docStatus !== '03'" strong text
type="info">预览文档</n-button>
<n-button @click="onAuditDoc(row)" v-if="row.docStatus === '01'" strong text
type="info">审核</n-button>
......@@ -693,13 +692,13 @@ onMounted(() => {
</div>
</n-form-item>
<n-form-item
v-if="operateType === 'audit' || operateType === 'preview' && addDocForm.docStatus === '02' || addDocForm.docStatus === '03'"
v-if="operateType === 'audit' || operateType === 'preview' && (addDocForm.docStatus === '02' || addDocForm.docStatus === '03')"
label="审核结论" path="docStatus">
<n-select :disabled="operateType === 'preview'" v-model:value="addDocForm.docStatus" clearable
placeholder="审核结论" :options="docStatusOptions" />
</n-form-item>
<n-form-item
v-if="operateType === 'audit' || operateType === 'preview' && addDocForm.docStatus === '02' || addDocForm.docStatus === '03'"
v-if="operateType === 'audit' || operateType === 'preview' && (addDocForm.docStatus === '02' || addDocForm.docStatus === '03')"
label="审核意见" path="auditDesc">
<n-input :disabled="operateType === 'preview'" type="textarea" v-model:value="addDocForm.auditDesc"
placeholder="审核意见" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment