34 changed files with 2850 additions and 569 deletions
@ -0,0 +1,57 @@ |
|||||
|
import { defHttp } from '@/utils/http/axios'; |
||||
|
import { ID, IDS, commonExport } from '@/api/base'; |
||||
|
import { SchemEvaluationVO, SchemEvaluationForm, SchemEvaluationQuery } from './model'; |
||||
|
|
||||
|
/** |
||||
|
* 查询方案评价任务列表 |
||||
|
* @param params |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function SchemEvaluationList(params?: SchemEvaluationQuery) { |
||||
|
return defHttp.get<SchemEvaluationVO[]>({ url: '/productManagement/SchemEvaluation/list', params }); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 导出方案评价任务列表 |
||||
|
* @param params |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function SchemEvaluationExport(params?: SchemEvaluationQuery) { |
||||
|
return commonExport('/productManagement/SchemEvaluation/export', params ?? {}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询方案评价任务详细 |
||||
|
* @param id id |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function SchemEvaluationInfo(id: ID) { |
||||
|
return defHttp.get<SchemEvaluationVO>({ url: '/productManagement/SchemEvaluation/' + id }); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 新增方案评价任务 |
||||
|
* @param data |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function SchemEvaluationAdd(data: SchemEvaluationForm) { |
||||
|
return defHttp.postWithMsg<void>({ url: '/productManagement/SchemEvaluation', data }); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 更新方案评价任务 |
||||
|
* @param data |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function SchemEvaluationUpdate(data: SchemEvaluationForm) { |
||||
|
return defHttp.putWithMsg<void>({ url: '/productManagement/SchemEvaluation', data }); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除方案评价任务 |
||||
|
* @param id id |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function SchemEvaluationRemove(id: ID | IDS) { |
||||
|
return defHttp.deleteWithMsg<void>({ url: '/productManagement/SchemEvaluation/' + id },); |
||||
|
} |
@ -0,0 +1,105 @@ |
|||||
|
import { BaseEntity, PageQuery } from '@/api/base'; |
||||
|
|
||||
|
export interface SchemEvaluationVO { |
||||
|
/** |
||||
|
* 模型所属行业 |
||||
|
*/ |
||||
|
taskIndustry: string; |
||||
|
|
||||
|
/** |
||||
|
* 模型所属区域 |
||||
|
*/ |
||||
|
taskRegion: string; |
||||
|
|
||||
|
/** |
||||
|
* 任务名称 |
||||
|
*/ |
||||
|
taskName: string; |
||||
|
|
||||
|
/** |
||||
|
* 文档名称 |
||||
|
*/ |
||||
|
documentName: string; |
||||
|
|
||||
|
/** |
||||
|
* ossid |
||||
|
*/ |
||||
|
ossId: string | number; |
||||
|
|
||||
|
/** |
||||
|
* 当前状态 |
||||
|
*/ |
||||
|
progressStatus: string; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export interface SchemEvaluationForm extends BaseEntity { |
||||
|
/** |
||||
|
* 模型所属行业 |
||||
|
*/ |
||||
|
taskIndustry?: string; |
||||
|
|
||||
|
/** |
||||
|
* 模型所属区域 |
||||
|
*/ |
||||
|
taskRegion?: string; |
||||
|
|
||||
|
/** |
||||
|
* 任务名称 |
||||
|
*/ |
||||
|
taskName?: string; |
||||
|
|
||||
|
/** |
||||
|
* 文档名称 |
||||
|
*/ |
||||
|
documentName?: string; |
||||
|
|
||||
|
/** |
||||
|
* ossid |
||||
|
*/ |
||||
|
ossId?: string | number; |
||||
|
|
||||
|
/** |
||||
|
* 当前状态 |
||||
|
*/ |
||||
|
progressStatus?: string; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export interface SchemEvaluationQuery extends PageQuery { |
||||
|
|
||||
|
/** |
||||
|
* 模型所属行业 |
||||
|
*/ |
||||
|
taskIndustry?: string; |
||||
|
|
||||
|
/** |
||||
|
* 模型所属区域 |
||||
|
*/ |
||||
|
taskRegion?: string; |
||||
|
|
||||
|
/** |
||||
|
* 任务名称 |
||||
|
*/ |
||||
|
taskName?: string; |
||||
|
|
||||
|
/** |
||||
|
* 文档名称 |
||||
|
*/ |
||||
|
documentName?: string; |
||||
|
|
||||
|
/** |
||||
|
* ossid |
||||
|
*/ |
||||
|
ossId?: string | number; |
||||
|
|
||||
|
/** |
||||
|
* 当前状态 |
||||
|
*/ |
||||
|
progressStatus?: string; |
||||
|
|
||||
|
/** |
||||
|
* 日期范围参数 |
||||
|
*/ |
||||
|
params?: any; |
||||
|
} |
@ -0,0 +1,57 @@ |
|||||
|
import { defHttp } from '@/utils/http/axios'; |
||||
|
import { ID, IDS, commonExport } from '@/api/base'; |
||||
|
import { TenderTaskVO, TenderTaskForm, TenderTaskQuery } from './model'; |
||||
|
|
||||
|
/** |
||||
|
* 查询招标摘要任务列表 |
||||
|
* @param params |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function TenderTaskList(params?: TenderTaskQuery) { |
||||
|
return defHttp.get<TenderTaskVO[]>({ url: '/productManagement/TenderTask/list', params }); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 导出招标摘要任务列表 |
||||
|
* @param params |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function TenderTaskExport(params?: TenderTaskQuery) { |
||||
|
return commonExport('/productManagement/TenderTask/export', params ?? {}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询招标摘要任务详细 |
||||
|
* @param id id |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function TenderTaskInfo(id: ID) { |
||||
|
return defHttp.get<TenderTaskVO>({ url: '/productManagement/TenderTask/' + id }); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 新增招标摘要任务 |
||||
|
* @param data |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function TenderTaskAdd(data: TenderTaskForm) { |
||||
|
return defHttp.postWithMsg<void>({ url: '/productManagement/TenderTask', data }); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 更新招标摘要任务 |
||||
|
* @param data |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function TenderTaskUpdate(data: TenderTaskForm) { |
||||
|
return defHttp.putWithMsg<void>({ url: '/productManagement/TenderTask', data }); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 删除招标摘要任务 |
||||
|
* @param id id |
||||
|
* @returns |
||||
|
*/ |
||||
|
export function TenderTaskRemove(id: ID | IDS) { |
||||
|
return defHttp.deleteWithMsg<void>({ url: '/productManagement/TenderTask/' + id },); |
||||
|
} |
@ -0,0 +1,108 @@ |
|||||
|
import { BaseEntity, PageQuery } from '@/api/base'; |
||||
|
|
||||
|
export interface TenderTaskVO { |
||||
|
/** |
||||
|
* 模型所属行业 |
||||
|
*/ |
||||
|
taskIndustry: string; |
||||
|
|
||||
|
/** |
||||
|
* 模型所属区域 |
||||
|
*/ |
||||
|
taskRegion: string; |
||||
|
|
||||
|
/** |
||||
|
* 任务名称 |
||||
|
*/ |
||||
|
taskName: string; |
||||
|
|
||||
|
/** |
||||
|
* 文档名称 |
||||
|
*/ |
||||
|
documentName: string; |
||||
|
|
||||
|
/** |
||||
|
* ossid |
||||
|
*/ |
||||
|
ossId: string | number; |
||||
|
|
||||
|
/** |
||||
|
* 当前状态 |
||||
|
|
||||
|
*/ |
||||
|
progressStatus: string; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export interface TenderTaskForm extends BaseEntity { |
||||
|
/** |
||||
|
* 模型所属行业 |
||||
|
*/ |
||||
|
taskIndustry?: string; |
||||
|
|
||||
|
/** |
||||
|
* 模型所属区域 |
||||
|
*/ |
||||
|
taskRegion?: string; |
||||
|
|
||||
|
/** |
||||
|
* 任务名称 |
||||
|
*/ |
||||
|
taskName?: string; |
||||
|
|
||||
|
/** |
||||
|
* 文档名称 |
||||
|
*/ |
||||
|
documentName?: string; |
||||
|
|
||||
|
/** |
||||
|
* ossid |
||||
|
*/ |
||||
|
ossId?: string | number; |
||||
|
|
||||
|
/** |
||||
|
* 当前状态 |
||||
|
|
||||
|
*/ |
||||
|
progressStatus?: string; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
export interface TenderTaskQuery extends PageQuery { |
||||
|
|
||||
|
/** |
||||
|
* 模型所属行业 |
||||
|
*/ |
||||
|
taskIndustry?: string; |
||||
|
|
||||
|
/** |
||||
|
* 模型所属区域 |
||||
|
*/ |
||||
|
taskRegion?: string; |
||||
|
|
||||
|
/** |
||||
|
* 任务名称 |
||||
|
*/ |
||||
|
taskName?: string; |
||||
|
|
||||
|
/** |
||||
|
* 文档名称 |
||||
|
*/ |
||||
|
documentName?: string; |
||||
|
|
||||
|
/** |
||||
|
* ossid |
||||
|
*/ |
||||
|
ossId?: string | number; |
||||
|
|
||||
|
/** |
||||
|
* 当前状态 |
||||
|
|
||||
|
*/ |
||||
|
progressStatus?: string; |
||||
|
|
||||
|
/** |
||||
|
* 日期范围参数 |
||||
|
*/ |
||||
|
params?: any; |
||||
|
} |
@ -0,0 +1,115 @@ |
|||||
|
// 任务类型枚举
|
||||
|
export const TaskType = { |
||||
|
SCHEME_REVIEW: { |
||||
|
value: 'scheme_review', |
||||
|
label: '方案审核', |
||||
|
icon: 'mdi:file-document-check-outline', |
||||
|
color: '#2F54EB', |
||||
|
path:"/documentReview/DocumentTasks" |
||||
|
}, |
||||
|
CONTRACT_REVIEW: { |
||||
|
value: 'contract_review', |
||||
|
label: '合同审核', |
||||
|
icon: 'fluent-mdl2:document-approval', |
||||
|
color: '#722ED1', |
||||
|
path:"/contractReview/ContractualTasks" |
||||
|
}, |
||||
|
TENDER_REVIEW: { |
||||
|
value: 'tender_review', |
||||
|
label: '招投标审核', |
||||
|
icon: 'heroicons:clipboard-document-check-20-solid', |
||||
|
color: '#13C2C2', |
||||
|
path:"/tenderReview/TenderSummaryTask" |
||||
|
}, |
||||
|
SCHEME_EVALUATION: { // 新增方案评价
|
||||
|
value: 'scheme_evaluation', |
||||
|
label: '方案评价', |
||||
|
icon: 'mdi:file-document-edit-outline', // 使用文档编辑图标
|
||||
|
color: '#FA8C16', // 使用橙色系
|
||||
|
path:"/schemEvaluation/SchemeEvaluation" |
||||
|
}, |
||||
|
PROJECT_DOCUMENT_REVIEW: { // 新增项目文档审核
|
||||
|
value: 'project_document_review', |
||||
|
label: '项目文档审核', |
||||
|
icon: 'mdi:folder-text-outline', // 使用文件夹文档图标
|
||||
|
color: '#1890FF', // 使用蓝色系
|
||||
|
path:"/projectDocumentReview/ProjectDocumentReview" |
||||
|
} |
||||
|
} as const; |
||||
|
|
||||
|
// 方案审核子任务
|
||||
|
export const SchemeTask = { |
||||
|
DOCUMENT_SIMILARITY: { |
||||
|
value: 'checkRepeatText', |
||||
|
label: '文档相似性检查', |
||||
|
icon: 'arcticons:onlyoffice-documents', |
||||
|
color: '#1890FF' |
||||
|
}, |
||||
|
DOCUMENT_ERROR: { |
||||
|
value: 'checkDocumentError', |
||||
|
label: '文档纠错', |
||||
|
icon: 'solar:document-medicine-bold-duotone', |
||||
|
color: '#F5222D' |
||||
|
}, |
||||
|
|
||||
|
PLACE_CHECK: { |
||||
|
value: 'checkPlaceName', |
||||
|
label: '地名检查', |
||||
|
icon: 'solar:map-point-search-bold-duotone', |
||||
|
color: '#52C41A' |
||||
|
}, |
||||
|
COMPANY_CHECK: { |
||||
|
value: 'checkCompanyName', |
||||
|
label: '公司名称检查', |
||||
|
icon: 'mdi:company', |
||||
|
color: '#2F54EB' |
||||
|
}, |
||||
|
TITLE_CHECK: { |
||||
|
value: 'checkTitleName', |
||||
|
label: '文档结构检查', |
||||
|
icon: 'mdi:file-tree-outline', |
||||
|
color: '#722ED1' |
||||
|
} |
||||
|
} as const; |
||||
|
|
||||
|
// 合同审核子任务
|
||||
|
export const ContractTask = { |
||||
|
CONTRACT_REVIEW: { |
||||
|
value: 'contractReview', |
||||
|
label: '合同审核', |
||||
|
icon: 'fluent-mdl2:document-approval', |
||||
|
color: '#722ED1' |
||||
|
} |
||||
|
} as const; |
||||
|
|
||||
|
// 招标审核子任务
|
||||
|
export const TenderTask = { |
||||
|
TENDER_SUMMARY: { |
||||
|
value: 'tenderSummary', |
||||
|
label: '招标摘要', |
||||
|
icon: 'mdi:text-box-outline', |
||||
|
color: '#2B7DE9' |
||||
|
} |
||||
|
} as const; |
||||
|
|
||||
|
// 招标审核子任务
|
||||
|
export const SchemeEvaluation = { |
||||
|
SCHEME_EVALUATION: { |
||||
|
value: 'schemEvaluation', |
||||
|
label: '方案评价', |
||||
|
icon: 'iconoir:doc-star', |
||||
|
color: '#13C2C2' |
||||
|
}, |
||||
|
} as const; |
||||
|
/** |
||||
|
* 从对象中提取指定键的值 |
||||
|
* @param obj 要提取的对象 |
||||
|
* @param key 要提取的键名 |
||||
|
* @returns any[] 提取的值数组 |
||||
|
*/ |
||||
|
export const extractValues = <T extends Record<string, { [key: string]: any }>>( |
||||
|
obj: T, |
||||
|
key: string |
||||
|
): any[] => { |
||||
|
return Object.values(obj).map(item => item[key]); |
||||
|
}; |
@ -0,0 +1,286 @@ |
|||||
|
<template> |
||||
|
<BasicTable @register="registerTable" @expand="tabelexpand"> |
||||
|
<template #toolbar v-if="props.showToolbar"> |
||||
|
<div > |
||||
|
<a-button |
||||
|
id="how-to-edit" |
||||
|
class="font-bold" |
||||
|
type="link" |
||||
|
@click="openDrawer(true, { value: '', type: 'def' })" |
||||
|
>👉如何新增任务? |
||||
|
</a-button> |
||||
|
<a-button type="primary" @click="handleAdd">新增</a-button> |
||||
|
</div> |
||||
|
</template> |
||||
|
<template #bodyCell="{ column, record }"> |
||||
|
<template v-if="column.key === 'action'"> |
||||
|
<TableAction |
||||
|
stopButtonPropagation |
||||
|
:actions="[ |
||||
|
{ |
||||
|
label: record.childrenTasks.length > 1 ? '下载全部' : '下载', |
||||
|
icon: IconEnum.DOWNLOAD, |
||||
|
type: 'primary', |
||||
|
color: 'success', |
||||
|
ghost: true, |
||||
|
ifShow: () => { |
||||
|
if (record.progress.includes('100%')) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
onClick: handleDownload.bind(null, record), |
||||
|
}, |
||||
|
]" |
||||
|
/> |
||||
|
</template> |
||||
|
</template> |
||||
|
<template #expandedRowRender> |
||||
|
<BasicTable @register="registerChildTable"> |
||||
|
<template #bodyCell="{ column, record }"> |
||||
|
<template v-if="column.key === 'action'"> |
||||
|
<TableAction |
||||
|
stopButtonPropagation |
||||
|
:actions="[ |
||||
|
{ |
||||
|
label: '详情', |
||||
|
icon: IconEnum.EDIT, |
||||
|
type: 'primary', |
||||
|
ghost: true, |
||||
|
ifShow: () => { |
||||
|
if ( |
||||
|
record.progressStatus != 'PENDING' && |
||||
|
record.progressStatus != 'STARTED' && |
||||
|
record.progressStatus != 'REVOKED' |
||||
|
) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
onClick: handleDetail.bind(null, record), |
||||
|
}, |
||||
|
{ |
||||
|
label: '下载', |
||||
|
icon: IconEnum.DOWNLOAD, |
||||
|
type: 'primary', |
||||
|
color: 'success', |
||||
|
ghost: true, |
||||
|
ifShow: () => { |
||||
|
if ( |
||||
|
record.progressStatus != 'PENDING' && |
||||
|
record.progressStatus != 'STARTED' && |
||||
|
record.progressStatus != 'REVOKED' |
||||
|
) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
onClick: handleDownload.bind(null, record), |
||||
|
}, |
||||
|
{ |
||||
|
label: '终止任务', |
||||
|
icon: IconEnum.DELETE, |
||||
|
type: 'primary', |
||||
|
danger: true, |
||||
|
ghost: true, |
||||
|
ifShow: () => { |
||||
|
if (record.progressStatus == 'PENDING') { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
popConfirm: { |
||||
|
placement: 'left', |
||||
|
title: '是否终止当前任务?', |
||||
|
confirm: handleStop.bind(null, record), |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
/> |
||||
|
</template> |
||||
|
</template> |
||||
|
</BasicTable> |
||||
|
</template> |
||||
|
</BasicTable> |
||||
|
<DocumentTasksModal @register="registerModal" @reload="reload" /> |
||||
|
<DocsDrawer @register="registerDrawer" /> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { BasicTable, useTable, TableAction } from '@/components/Table'; |
||||
|
import { DocumentTasksList, DocumentTasksStop } from '@/api/documentReview/DocumentTasks'; |
||||
|
import { getTasksPermissionsByUserId } from '@/api/taskPermissions/DocumentTasksPermissions'; |
||||
|
import { |
||||
|
DocumentTaskResultsInfoByTaskId, |
||||
|
DocumentTaskResultDownload, |
||||
|
} from '@/api/documentReview/DocumentTaskResults'; |
||||
|
import { useModal } from '@/components/Modal'; |
||||
|
import DocumentTasksModal from './DocumentTasksModal.vue'; |
||||
|
import { formSchemas, columns, childColumns } from './DocumentTasks.data'; |
||||
|
import { IconEnum } from '@/enums/appEnum'; |
||||
|
import { useDrawer } from '@/components/Drawer'; |
||||
|
import DocsDrawer from '@/views/documentReview/DocumentTasks/DocsDrawer.vue'; |
||||
|
import { onMounted, ref } from 'vue'; |
||||
|
import { DocumentTasksPermissionsVO } from '@/api/taskPermissions/DocumentTasksPermissions/model'; |
||||
|
let props = defineProps(['useSearchForm', 'showTableSetting', 'showToolbar', 'pagination']); |
||||
|
defineOptions({ name: 'DocumentTasks' }); |
||||
|
const documentData = ref<DocumentTasksPermissionsVO>(); |
||||
|
const [registerDrawer, { openDrawer }] = useDrawer(); |
||||
|
const childTableData = ref([]); |
||||
|
const [registerTable, { reload }] = useTable({ |
||||
|
api: DocumentTasksList, |
||||
|
showIndexColumn: false, |
||||
|
clickToRowSelect: false, |
||||
|
rowKey: 'id', |
||||
|
title: props.showTableSetting?"方案审核任务列表":'', |
||||
|
expandRowByClick: false, |
||||
|
useSearchForm: props.useSearchForm, |
||||
|
showTableSetting: props.showTableSetting, |
||||
|
beforeFetch: async (record) => { |
||||
|
if (props.pagination == false) { |
||||
|
(record.pageNum = 1), (record.pageSize = 5); |
||||
|
} |
||||
|
}, |
||||
|
pagination: props.pagination, |
||||
|
formConfig: { |
||||
|
schemas: formSchemas, |
||||
|
baseColProps: { |
||||
|
xs: 24, |
||||
|
sm: 24, |
||||
|
md: 24, |
||||
|
lg: 6, |
||||
|
}, |
||||
|
}, |
||||
|
columns: columns, |
||||
|
actionColumn: { |
||||
|
width: 200, |
||||
|
title: '操作', |
||||
|
key: 'action', |
||||
|
fixed: 'right', |
||||
|
}, |
||||
|
}); |
||||
|
const [registerChildTable, { setProps: setChildProps }] = useTable({ |
||||
|
size: 'small', //紧凑型表格 |
||||
|
api: getchildTableData, |
||||
|
columns: childColumns, |
||||
|
rowKey: 'id', |
||||
|
useSearchForm: false, |
||||
|
showIndexColumn: false, |
||||
|
showTableSetting: false, |
||||
|
pagination: false, |
||||
|
maxHeight: 50, |
||||
|
actionColumn: { |
||||
|
width: 200, |
||||
|
title: '操作', |
||||
|
key: 'action', |
||||
|
fixed: 'right', |
||||
|
}, |
||||
|
}); |
||||
|
// //定时器变量 方便在页面销毁的时候清楚定时器 |
||||
|
// const timer = ref<any>(null); |
||||
|
// //页面在刷新的时候可以加loading显示 方便页面展示 |
||||
|
// const loading = ref(false); |
||||
|
// //使countdown定时增加 如果增加到我们想要的时间 也就是变量autoRefreshTime 执行刷新 |
||||
|
// const countdown = ref(0); |
||||
|
// //定时刷新的时间 现在设置的为6 也就是6秒刷新一次数据 |
||||
|
// const autoRefreshTime = ref(30); |
||||
|
const [registerModal, { openModal }] = useModal(); |
||||
|
onMounted(async () => { |
||||
|
documentData.value = await getTasksPermissionsByUserId(); |
||||
|
// timer.value = window.setInterval(() => { |
||||
|
// //不loading的时候才会执行 |
||||
|
// if (!loading.value) { |
||||
|
// //countdown小于我们想要的定时时间的时候 定时器也是一秒执行一次 就继续+1 |
||||
|
// if (countdown.value < autoRefreshTime.value) { |
||||
|
// countdown.value = countdown.value + 1; |
||||
|
// //当定时器到时间的时候 去干我们想干的事情 refresh() |
||||
|
// if (countdown.value === autoRefreshTime.value) { |
||||
|
// countdown.value = 0; |
||||
|
// reload(); |
||||
|
// } |
||||
|
// } |
||||
|
// } |
||||
|
// }, 1000); |
||||
|
}); |
||||
|
const cleanHtml = (content) => { |
||||
|
// 移除DOCTYPE和html标签 |
||||
|
content = content.replace(/<!DOCTYPE[^>]*>/i, ''); |
||||
|
content = content.replace(/<html[^>]*>/i, ''); |
||||
|
content = content.replace(/<\/html>/i, ''); |
||||
|
|
||||
|
// 移除head部分 |
||||
|
content = content.replace(/<head>[\s\S]*?<\/head>/i, ''); |
||||
|
|
||||
|
// 移除body标签 |
||||
|
content = content.replace(/<body[^>]*>/i, ''); |
||||
|
content = content.replace(/<\/body>/i, ''); |
||||
|
|
||||
|
return content.trim(); |
||||
|
}; |
||||
|
async function handleDetail(record: Recordable) { |
||||
|
try { |
||||
|
let res = await DocumentTaskResultsInfoByTaskId(record.id); |
||||
|
if (record.taskName == 'schemEvaluation') { |
||||
|
// res.result=generateTable(JSON.parse(res.result as string)) |
||||
|
const updatedHtmlText = res.result?.replace( |
||||
|
/文件名称:\S+/g, |
||||
|
`文件名称:${record.documentName}`, |
||||
|
); |
||||
|
|
||||
|
openDrawer(true, { value: cleanHtml(updatedHtmlText), type: 'markdown' }); |
||||
|
} else if (record.taskName == 'checkDocumentError') { |
||||
|
openDrawer(true, { value: res.result, type: 'markdown' }); |
||||
|
} else { |
||||
|
openDrawer(true, { value: res.result, type: 'markdown' }); |
||||
|
} |
||||
|
console.log('res', res); |
||||
|
} catch (ex) { |
||||
|
openDrawer(true, { value: '加载失败,请刷新页面', type: 'markdown' }); |
||||
|
} |
||||
|
//根据record.id查询结果详情 |
||||
|
} |
||||
|
|
||||
|
async function handleStop(record: Recordable) { |
||||
|
await DocumentTasksStop(record.id); |
||||
|
await reload(); |
||||
|
} |
||||
|
|
||||
|
function handleAdd() { |
||||
|
openModal(true, { update: false }); |
||||
|
} |
||||
|
function tabelexpand(expanded, record) { |
||||
|
if (expanded) { |
||||
|
childTableData.value = record.childrenTasks; |
||||
|
// reloadChildTable() |
||||
|
console.log('expanded, record', expanded, record); |
||||
|
} |
||||
|
} |
||||
|
// 修改后的 getchildTableData 函数 |
||||
|
function getchildTableData() { |
||||
|
console.log('childTableData', childTableData.value); |
||||
|
const height = 50 * childTableData.value.length; |
||||
|
setChildProps({ maxHeight: height }); |
||||
|
|
||||
|
// 返回一个 Promise 对象,包含预期的数据结构 |
||||
|
return Promise.resolve(childTableData.value); |
||||
|
} |
||||
|
async function handleDownload(record: Recordable) { |
||||
|
if (record.childrenTasks?.length > 1) { |
||||
|
await DocumentTaskResultDownload(record.childrenTasks.map((item) => item.id)); |
||||
|
await reload(); |
||||
|
} else if (record.childrenTasks?.length == 1) { |
||||
|
await DocumentTaskResultDownload([record.childrenTasks[0].id]); |
||||
|
|
||||
|
await reload(); |
||||
|
} else { |
||||
|
await DocumentTaskResultDownload([record.id]); |
||||
|
await reload(); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped></style> |
@ -1,241 +1,14 @@ |
|||||
<template> |
<template> |
||||
<PageWrapper dense> |
<PageWrapper dense> |
||||
<BasicTable @register="registerTable"> |
<DocumentTasksTable :show-table-setting="true" :show-toolbar="true" :use-search-form="true" /> |
||||
<template #toolbar> |
|
||||
<a-button id="how-to-edit" class="font-bold" type="link" @click="openDrawer(true,{ value: '', type: 'def' })" |
|
||||
>👉如何新增任务? |
|
||||
</a-button> |
|
||||
<!-- <a-button |
|
||||
@click="downloadExcel(DocumentTasksExport, '文档任务数据', getForm().getFieldsValue())" |
|
||||
v-auth="'productManagement:DocumentTasks:export'" |
|
||||
>导出</a-button |
|
||||
> |
|
||||
<a-button |
|
||||
type="primary" |
|
||||
danger |
|
||||
@click="multipleRemove(DocumentTasksRemove)" |
|
||||
:disabled="!selected" |
|
||||
v-auth="'productManagement:DocumentTasks:remove'" |
|
||||
>删除</a-button |
|
||||
> --> |
|
||||
<a-button type="primary" @click="handleAdd">新增</a-button> |
|
||||
</template> |
|
||||
<template #bodyCell="{ column, record }"> |
|
||||
<template v-if="column.key === 'action'"> |
|
||||
<TableAction |
|
||||
stopButtonPropagation |
|
||||
:actions="[ |
|
||||
{ |
|
||||
label: '详情', |
|
||||
icon: IconEnum.EDIT, |
|
||||
type: 'primary', |
|
||||
ghost: true, |
|
||||
ifShow: () => { |
|
||||
if ( |
|
||||
record.progressStatus != 'PENDING' && |
|
||||
record.progressStatus != 'STARTED' && |
|
||||
record.progressStatus != 'REVOKED' |
|
||||
) { |
|
||||
return true; |
|
||||
} else { |
|
||||
return false; |
|
||||
} |
|
||||
}, |
|
||||
onClick: handleDetail.bind(null, record), |
|
||||
}, |
|
||||
{ |
|
||||
label: '终止任务', |
|
||||
icon: IconEnum.DELETE, |
|
||||
type: 'primary', |
|
||||
danger: true, |
|
||||
ghost: true, |
|
||||
ifShow: () => { |
|
||||
if (record.progressStatus == 'PENDING') { |
|
||||
return true; |
|
||||
} else { |
|
||||
return false; |
|
||||
} |
|
||||
}, |
|
||||
popConfirm: { |
|
||||
placement: 'left', |
|
||||
title: '是否终止当前任务?', |
|
||||
confirm: handleStop.bind(null, record), |
|
||||
}, |
|
||||
}, |
|
||||
]" |
|
||||
/> |
|
||||
</template> |
|
||||
</template> |
|
||||
<!-- <template #headerTop> |
|
||||
<div class="container mx-auto mt-4 mb-4 h-20"> |
|
||||
<div class="grid grid-cols-3 gap-3 h-full"> |
|
||||
<div class="bg-[#1890FF] opacity-100 h-full"> |
|
||||
<div class="grid grid-cols-4 gap-1 h-full"> |
|
||||
<div class="col-span-3 mt-4 ml-4 text-white">每日文档数</div> |
|
||||
<div |
|
||||
class="col-span-1 flex justify-center items-center text-white text-4xl font-bold" |
|
||||
>{{ documentData?.dailyDocumentCount }}</div |
|
||||
> |
|
||||
</div> |
|
||||
</div> |
|
||||
<div class="bg-[#1890FF] opacity-100 h-full"> |
|
||||
<div class="grid grid-cols-4 gap-1 h-full"> |
|
||||
<div class="col-span-3 mt-4 ml-4 text-white">当日剩余文档数</div> |
|
||||
<div |
|
||||
class="col-span-1 flex justify-center items-center text-white text-4xl font-bold" |
|
||||
>{{ documentData?.remainingTasksToday }}</div |
|
||||
> |
|
||||
</div> |
|
||||
</div> |
|
||||
<div class="bg-[#1890FF] opacity-100 h-full"> |
|
||||
<div class="grid grid-cols-4 gap-1 h-full"> |
|
||||
<div class="col-span-3 mt-4 ml-4 text-white">优先级</div> |
|
||||
<div |
|
||||
class="col-span-1 flex justify-center items-center text-white text-4xl font-bold" |
|
||||
>{{ documentData?.priority }}</div |
|
||||
> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
|
|
||||
</div> |
|
||||
</div> |
|
||||
</template> --> |
|
||||
</BasicTable> |
|
||||
<DocumentTasksModal @register="registerModal" @reload="reload" /> |
|
||||
<DocsDrawer @register="registerDrawer" /> |
|
||||
</PageWrapper> |
</PageWrapper> |
||||
</template> |
</template> |
||||
|
|
||||
<script setup lang="ts"> |
<script setup lang="ts"> |
||||
import { PageWrapper } from '@/components/Page'; |
import { PageWrapper } from '@/components/Page'; |
||||
import { BasicTable, useTable, TableAction } from '@/components/Table'; |
import DocumentTasksTable from './DocumentTasksTable.vue'; |
||||
import { |
|
||||
DocumentTasksList, |
|
||||
DocumentTasksExport, |
|
||||
DocumentTasksRemove, |
|
||||
DocumentTasksStop, |
|
||||
} from '@/api/documentReview/DocumentTasks'; |
|
||||
import { getTasksPermissionsByUserId } from '@/api/taskPermissions/DocumentTasksPermissions'; |
|
||||
|
|
||||
import { DocumentTaskResultsInfoByTaskId } from '@/api/documentReview/DocumentTaskResults'; |
|
||||
import { useModal } from '@/components/Modal'; |
|
||||
import DocumentTasksModal from './DocumentTasksModal.vue'; |
|
||||
import { formSchemas, columns } from './DocumentTasks.data'; |
|
||||
import { IconEnum } from '@/enums/appEnum'; |
|
||||
import { useDrawer } from '@/components/Drawer'; |
|
||||
import DocsDrawer from '@/views/documentReview/DocumentTasks/DocsDrawer.vue'; |
|
||||
import { onMounted, ref } from 'vue'; |
|
||||
import { DocumentTasksPermissionsVO } from '@/api/taskPermissions/DocumentTasksPermissions/model'; |
|
||||
|
|
||||
defineOptions({ name: 'DocumentTasks' }); |
|
||||
const documentData = ref<DocumentTasksPermissionsVO>(); |
|
||||
const [registerDrawer, { openDrawer }] = useDrawer(); |
|
||||
|
|
||||
const [registerTable, { reload, multipleRemove, selected, getForm }] = useTable({ |
|
||||
rowSelection: { |
|
||||
type: 'checkbox', |
|
||||
}, |
|
||||
title: '文档任务列表', |
|
||||
api: DocumentTasksList, |
|
||||
showIndexColumn: false, |
|
||||
rowKey: 'id', |
|
||||
useSearchForm: true, |
|
||||
formConfig: { |
|
||||
schemas: formSchemas, |
|
||||
baseColProps: { |
|
||||
xs: 24, |
|
||||
sm: 24, |
|
||||
md: 24, |
|
||||
lg: 6, |
|
||||
}, |
|
||||
}, |
|
||||
columns: columns, |
|
||||
actionColumn: { |
|
||||
width: 200, |
|
||||
title: '操作', |
|
||||
key: 'action', |
|
||||
fixed: 'right', |
|
||||
}, |
|
||||
}); |
|
||||
//定时器变量 方便在页面销毁的时候清楚定时器 |
|
||||
const timer = ref<any>(null); |
|
||||
//页面在刷新的时候可以加loading显示 方便页面展示 |
|
||||
const loading = ref(false); |
|
||||
//使countdown定时增加 如果增加到我们想要的时间 也就是变量autoRefreshTime 执行刷新 |
|
||||
const countdown = ref(0); |
|
||||
//定时刷新的时间 现在设置的为6 也就是6秒刷新一次数据 |
|
||||
const autoRefreshTime = ref(30); |
|
||||
const [registerModal, { openModal }] = useModal(); |
|
||||
onMounted(async () => { |
|
||||
documentData.value = await getTasksPermissionsByUserId(); |
|
||||
timer.value = window.setInterval(() => { |
|
||||
//不loading的时候才会执行 |
|
||||
if (!loading.value) { |
|
||||
//countdown小于我们想要的定时时间的时候 定时器也是一秒执行一次 就继续+1 |
|
||||
if (countdown.value < autoRefreshTime.value) { |
|
||||
countdown.value = countdown.value + 1; |
|
||||
//当定时器到时间的时候 去干我们想干的事情 refresh() |
|
||||
if (countdown.value === autoRefreshTime.value) { |
|
||||
countdown.value =0 |
|
||||
reload() |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}, 1000); |
|
||||
}); |
|
||||
const cleanHtml = (content) => { |
|
||||
// 移除DOCTYPE和html标签 |
|
||||
content = content.replace(/<!DOCTYPE[^>]*>/i, '') |
|
||||
content = content.replace(/<html[^>]*>/i, '') |
|
||||
content = content.replace(/<\/html>/i, '') |
|
||||
|
|
||||
// 移除head部分 |
|
||||
content = content.replace(/<head>[\s\S]*?<\/head>/i, '') |
|
||||
|
|
||||
// 移除body标签 |
|
||||
content = content.replace(/<body[^>]*>/i, '') |
|
||||
content = content.replace(/<\/body>/i, '') |
|
||||
|
|
||||
return content.trim() |
|
||||
} |
|
||||
async function handleDetail(record: Recordable) { |
|
||||
try { |
|
||||
let res = await DocumentTaskResultsInfoByTaskId(record.id); |
|
||||
if (record.taskName == 'schemEvaluation') { |
|
||||
// res.result=generateTable(JSON.parse(res.result as string)) |
|
||||
const updatedHtmlText = res.result?.replace( |
|
||||
/文件名称:\S+/g, |
|
||||
`文件名称:${record.documentName}`, |
|
||||
); |
|
||||
|
|
||||
openDrawer(true, { value: cleanHtml(updatedHtmlText), type: 'markdown' }); |
|
||||
}else if(record.taskName =="checkDocumentError"){ |
|
||||
openDrawer(true, { value: res.result, type: 'markdown' }); |
|
||||
} |
|
||||
else { |
|
||||
openDrawer(true, { value: res.result, type: 'markdown' }); |
|
||||
} |
|
||||
console.log('res', res); |
|
||||
} catch (ex) { |
|
||||
openDrawer(true, { value: '加载失败,请刷新页面', type: 'markdown' }); |
|
||||
} |
|
||||
//根据record.id查询结果详情 |
|
||||
} |
|
||||
|
|
||||
async function handleStop(record: Recordable) { |
|
||||
await DocumentTasksStop(record.id); |
|
||||
await reload(); |
|
||||
} |
|
||||
|
|
||||
function handleAdd() { |
|
||||
openModal(true, { update: false }); |
|
||||
} |
|
||||
|
|
||||
async function handleDelete(record: Recordable) { |
|
||||
await DocumentTasksRemove([record.id]); |
|
||||
await reload(); |
|
||||
} |
|
||||
</script> |
</script> |
||||
|
|
||||
<style scoped></style> |
<style scoped></style> |
||||
|
@ -0,0 +1,150 @@ |
|||||
|
import { BasicColumn } from '@/components/Table'; |
||||
|
import { FormSchema } from '@/components/Form'; |
||||
|
import { getDictOptions } from '@/utils/dict'; |
||||
|
import { useRender } from '@/hooks/component/useRender'; |
||||
|
import { uploadDocument } from '@/api/documentReview/DocumentTasks'; |
||||
|
import { useUserStore } from '@/store/modules/user'; |
||||
|
import { RoleEnum } from '@/enums/roleEnum'; |
||||
|
|
||||
|
const { roleList } = useUserStore(); |
||||
|
export const formSchemas: FormSchema[] = [ |
||||
|
// {
|
||||
|
// label: '模型所属行业',
|
||||
|
// field: 'taskIndustry',
|
||||
|
// component: 'Select',
|
||||
|
// componentProps: {
|
||||
|
// options: getDictOptions('model_industry')
|
||||
|
// },
|
||||
|
// },
|
||||
|
// {
|
||||
|
// label: '模型所属区域',
|
||||
|
// field: 'taskRegion',
|
||||
|
// component: 'Select',
|
||||
|
// componentProps: {
|
||||
|
// options: getDictOptions('model_region')
|
||||
|
// },
|
||||
|
// },
|
||||
|
{ |
||||
|
label: '任务名称', |
||||
|
field: 'taskNameList', |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options: getDictOptions('scheme_evaluation'), |
||||
|
mode: 'multiple', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
label: '文档名称', |
||||
|
field: 'documentName', |
||||
|
component: 'Input', |
||||
|
}, |
||||
|
{ |
||||
|
label: '状态', |
||||
|
field: 'progressStatus', |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options: getDictOptions('document_task_status'), |
||||
|
}, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
const { renderDict } = useRender(); |
||||
|
export const columns: BasicColumn[] = [ |
||||
|
{ |
||||
|
title: '任务名称', |
||||
|
dataIndex: 'taskName', |
||||
|
customRender: ({ value }) => renderDict(value, 'scheme_evaluation'), |
||||
|
|
||||
|
}, |
||||
|
{ |
||||
|
title: '文档名称', |
||||
|
dataIndex: 'documentName', |
||||
|
}, |
||||
|
{ |
||||
|
title: '模型所属区域', |
||||
|
dataIndex: 'taskRegion', |
||||
|
customRender: ({ value }) => renderDict(value, 'model_region'), |
||||
|
}, |
||||
|
{ |
||||
|
title: '模型所属行业', |
||||
|
dataIndex: 'taskIndustry', |
||||
|
customRender: ({ value }) => renderDict(value, 'model_industry'), |
||||
|
}, |
||||
|
{ |
||||
|
title: '上传时间', |
||||
|
dataIndex: 'createTime', |
||||
|
}, |
||||
|
{ |
||||
|
title: '提交人', |
||||
|
dataIndex: 'createUser', |
||||
|
auth: 'documentReview:DocumentTasks:tableShow', |
||||
|
}, |
||||
|
{ |
||||
|
title: '任务耗时', |
||||
|
dataIndex: 'taskDuration', |
||||
|
}, |
||||
|
{ |
||||
|
title: '状态', |
||||
|
dataIndex: 'progressStatus', |
||||
|
customRender: ({ value }) => renderDict(value, 'document_task_status'), |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const modalSchemas: FormSchema[] = [ |
||||
|
{ |
||||
|
label: '模型所属区域', |
||||
|
field: 'taskRegion', |
||||
|
required: true, |
||||
|
component: 'Select', |
||||
|
// componentProps: {
|
||||
|
// options: taskRegionPermission(),
|
||||
|
// defaultValue:"normal",
|
||||
|
// },
|
||||
|
componentProps: () => { |
||||
|
const isSuperAdmin = roleList.includes(RoleEnum.SUPER_ADMIN); |
||||
|
let options = getDictOptions('model_region'); |
||||
|
if (!isSuperAdmin) { |
||||
|
// 如果不是超级管理员,移除 label 带有 '#' 的项
|
||||
|
options = options.filter((option) => !option.label.includes('#')); |
||||
|
} |
||||
|
return { |
||||
|
options: options, |
||||
|
defaultValue: 'normal', |
||||
|
}; |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
label: '模型所属行业', |
||||
|
field: 'taskIndustry', |
||||
|
required: true, |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options: getDictOptions('model_industry'), |
||||
|
defaultValue: 'normal', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
label: '任务名称', |
||||
|
field: 'taskNameList', |
||||
|
required: true, |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options:getDictOptions('scheme_evaluation'), |
||||
|
mode: 'multiple', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
label: '文档名称', |
||||
|
field: 'ossId', |
||||
|
required: true, |
||||
|
component: 'Upload', |
||||
|
componentProps: { |
||||
|
accept: ['.docx', '.doc', '.wps'], |
||||
|
maxSize: 500, |
||||
|
multiple: false, |
||||
|
resultField: 'ossId', |
||||
|
api: uploadDocument, |
||||
|
beforeUploadPrompt:"严禁在本互联网非涉密平台处理、传输国家秘密。请再次确认您上传的文件资料不涉及国家秘密。" |
||||
|
}, |
||||
|
}, |
||||
|
]; |
@ -0,0 +1,67 @@ |
|||||
|
<template> |
||||
|
<BasicModal |
||||
|
v-bind="$attrs" |
||||
|
:title="title" |
||||
|
@register="registerInnerModal" |
||||
|
@ok="handleSubmit" |
||||
|
@cancel="resetForm" |
||||
|
> |
||||
|
<BasicForm @register="registerForm" /> |
||||
|
</BasicModal> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { BasicModal, useModalInner } from '@/components/Modal'; |
||||
|
import { BasicForm, useForm } from '@/components/Form'; |
||||
|
import { computed, ref, unref } from 'vue'; |
||||
|
import { SchemEvaluationInfo, SchemEvaluationAdd, SchemEvaluationUpdate } from '@/api/schemEvaluation/SchemEvaluation'; |
||||
|
import { modalSchemas } from './SchemEvaluation.data'; |
||||
|
import { ModelUserPromptssettingInfoByUserId } from '@/api/modelConfiguration/ModelUserPromptssetting/index'; |
||||
|
import { TaskType } from '@/enums/taskEnum'; |
||||
|
defineOptions({ name: 'SchemEvaluationModal' }); |
||||
|
|
||||
|
const emit = defineEmits(['register', 'reload']); |
||||
|
|
||||
|
const isUpdate = ref<boolean>(false); |
||||
|
const title = computed<string>(() => { |
||||
|
return isUpdate.value ? '新增方案评价任务' : '新增方案评价任务'; |
||||
|
}); |
||||
|
|
||||
|
const [registerInnerModal, { modalLoading, closeModal }] = useModalInner( |
||||
|
async (data: { record?: Recordable; update: boolean }) => { |
||||
|
modalLoading(true); |
||||
|
const settings = await ModelUserPromptssettingInfoByUserId({taskType:TaskType.CONTRACT_REVIEW.value}); |
||||
|
await setFieldsValue(settings); |
||||
|
const { record, update } = data; |
||||
|
isUpdate.value = update; |
||||
|
if (update && record) { |
||||
|
await setFieldsValue(record); |
||||
|
} |
||||
|
modalLoading(false); |
||||
|
}, |
||||
|
); |
||||
|
|
||||
|
const [registerForm, { setFieldsValue, resetForm, validate }] = useForm({ |
||||
|
labelWidth: 100, |
||||
|
showActionButtonGroup: false, |
||||
|
baseColProps: { span: 24 }, |
||||
|
schemas: modalSchemas, |
||||
|
}); |
||||
|
|
||||
|
async function handleSubmit() { |
||||
|
try { |
||||
|
modalLoading(true); |
||||
|
const data = await validate(); |
||||
|
data['ossId'] = data['ossId'][0]; |
||||
|
await SchemEvaluationAdd(data); |
||||
|
emit('reload'); |
||||
|
closeModal(); |
||||
|
await resetForm(); |
||||
|
} catch (e) { |
||||
|
} finally { |
||||
|
modalLoading(false); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped></style> |
@ -0,0 +1,195 @@ |
|||||
|
<template> |
||||
|
<PageWrapper dense> |
||||
|
<BasicTable @register="registerTable"> |
||||
|
<template #toolbar> |
||||
|
<!-- <a-button |
||||
|
@click="downloadExcel(SchemEvaluationExport, '方案评价任务数据', getForm().getFieldsValue())" |
||||
|
v-auth="'productManagement:SchemEvaluation:export'" |
||||
|
>导出</a-button |
||||
|
> |
||||
|
<a-button |
||||
|
type="primary" |
||||
|
danger |
||||
|
@click="multipleRemove(SchemEvaluationRemove)" |
||||
|
:disabled="!selected" |
||||
|
v-auth="'productManagement:SchemEvaluation:remove'" |
||||
|
>删除</a-button |
||||
|
> --> |
||||
|
<a-button |
||||
|
type="primary" |
||||
|
@click="handleAdd" |
||||
|
v-auth="'productManagement:SchemEvaluation:add'" |
||||
|
>新增</a-button |
||||
|
> |
||||
|
</template> |
||||
|
<template #bodyCell="{ column, record }"> |
||||
|
<template v-if="column.key === 'action'"> |
||||
|
<TableAction |
||||
|
stopButtonPropagation |
||||
|
:actions="[ |
||||
|
|
||||
|
{ |
||||
|
label: '详情', |
||||
|
icon: IconEnum.EDIT, |
||||
|
type: 'primary', |
||||
|
ghost: true, |
||||
|
ifShow: () => { |
||||
|
if ( |
||||
|
record.progressStatus != 'PENDING' && |
||||
|
record.progressStatus != 'STARTED' && |
||||
|
record.progressStatus != 'REVOKED' |
||||
|
) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
onClick: handleDetail.bind(null, record), |
||||
|
}, |
||||
|
{ |
||||
|
label: '下载', |
||||
|
icon: IconEnum.DOWNLOAD, |
||||
|
type: 'primary', |
||||
|
color: 'success', |
||||
|
ghost: true, |
||||
|
ifShow: () => { |
||||
|
if ( |
||||
|
record.progressStatus != 'PENDING' && |
||||
|
record.progressStatus != 'STARTED' && |
||||
|
record.progressStatus != 'REVOKED' |
||||
|
) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
onClick: handleDownload.bind(null, record), |
||||
|
}, |
||||
|
{ |
||||
|
label: '终止任务', |
||||
|
icon: IconEnum.DELETE, |
||||
|
type: 'primary', |
||||
|
danger: true, |
||||
|
ghost: true, |
||||
|
ifShow: () => { |
||||
|
if (record.progressStatus == 'PENDING') { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
popConfirm: { |
||||
|
placement: 'left', |
||||
|
title: '是否终止当前任务?', |
||||
|
confirm: handleStop.bind(null, record), |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
/> |
||||
|
</template> |
||||
|
</template> |
||||
|
</BasicTable> |
||||
|
<SchemEvaluationModal @register="registerModal" @reload="reload" /> |
||||
|
<DocsDrawer @register="registerDrawer" /> |
||||
|
</PageWrapper> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { PageWrapper } from '@/components/Page'; |
||||
|
import { BasicTable, useTable, TableAction } from '@/components/Table'; |
||||
|
import { SchemEvaluationList, SchemEvaluationExport, SchemEvaluationRemove } from '@/api/schemEvaluation/SchemEvaluation'; |
||||
|
import { downloadExcel } from '@/utils/file/download'; |
||||
|
import { useModal } from '@/components/Modal'; |
||||
|
import SchemEvaluationModal from './SchemEvaluationModal.vue'; |
||||
|
import { formSchemas, columns } from './SchemEvaluation.data'; |
||||
|
import { IconEnum } from '@/enums/appEnum'; |
||||
|
import DocsDrawer from '@/views/documentReview/DocumentTasks/DocsDrawer.vue'; |
||||
|
import { useDrawer } from '@/components/Drawer'; |
||||
|
import { DocumentTasksStop } from '@/api/documentReview/DocumentTasks'; |
||||
|
import { |
||||
|
DocumentTaskResultsInfoByTaskId, |
||||
|
DocumentTaskResultDownload, |
||||
|
} from '@/api/documentReview/DocumentTaskResults'; |
||||
|
|
||||
|
const [registerDrawer, { openDrawer }] = useDrawer(); |
||||
|
defineOptions({ name: 'SchemEvaluation' }); |
||||
|
|
||||
|
const [registerTable, { reload, multipleRemove, selected, getForm }] = useTable({ |
||||
|
rowSelection: { |
||||
|
type: 'checkbox', |
||||
|
}, |
||||
|
title: '方案评价任务列表', |
||||
|
api: SchemEvaluationList, |
||||
|
showIndexColumn: false, |
||||
|
rowKey: 'id', |
||||
|
useSearchForm: true, |
||||
|
formConfig: { |
||||
|
schemas: formSchemas, |
||||
|
baseColProps: { |
||||
|
xs: 24, |
||||
|
sm: 24, |
||||
|
md: 24, |
||||
|
lg: 6, |
||||
|
}, |
||||
|
}, |
||||
|
columns: columns, |
||||
|
actionColumn: { |
||||
|
width: 200, |
||||
|
title: '操作', |
||||
|
key: 'action', |
||||
|
fixed: 'right', |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const [registerModal, { openModal }] = useModal(); |
||||
|
|
||||
|
const cleanHtml = (content) => { |
||||
|
// 移除DOCTYPE和html标签 |
||||
|
content = content.replace(/<!DOCTYPE[^>]*>/i, ''); |
||||
|
content = content.replace(/<html[^>]*>/i, ''); |
||||
|
content = content.replace(/<\/html>/i, ''); |
||||
|
|
||||
|
// 移除head部分 |
||||
|
content = content.replace(/<head>[\s\S]*?<\/head>/i, ''); |
||||
|
|
||||
|
// 移除body标签 |
||||
|
content = content.replace(/<body[^>]*>/i, ''); |
||||
|
content = content.replace(/<\/body>/i, ''); |
||||
|
|
||||
|
return content.trim(); |
||||
|
}; |
||||
|
async function handleDetail(record: Recordable) { |
||||
|
try { |
||||
|
let res = await DocumentTaskResultsInfoByTaskId(record.id); |
||||
|
if (record.taskName == 'schemEvaluation') { |
||||
|
// res.result=generateTable(JSON.parse(res.result as string)) |
||||
|
const updatedHtmlText = res.result?.replace( |
||||
|
/文件名称:\S+/g, |
||||
|
`文件名称:${record.documentName}`, |
||||
|
); |
||||
|
|
||||
|
openDrawer(true, { value: cleanHtml(updatedHtmlText), type: 'markdown' }); |
||||
|
} |
||||
|
console.log('res', res); |
||||
|
} catch (ex) { |
||||
|
openDrawer(true, { value: '加载失败,请刷新页面', type: 'markdown' }); |
||||
|
} |
||||
|
//根据record.id查询结果详情 |
||||
|
} |
||||
|
|
||||
|
function handleAdd() { |
||||
|
openModal(true, { update: false }); |
||||
|
} |
||||
|
|
||||
|
async function handleStop(record: Recordable) { |
||||
|
await DocumentTasksStop(record.id); |
||||
|
await reload(); |
||||
|
} |
||||
|
|
||||
|
async function handleDownload(record: Recordable) { |
||||
|
await DocumentTaskResultDownload([record.id]); |
||||
|
await reload(); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped></style> |
@ -0,0 +1,150 @@ |
|||||
|
import { BasicColumn } from '@/components/Table'; |
||||
|
import { FormSchema } from '@/components/Form'; |
||||
|
import { getDictOptions } from '@/utils/dict'; |
||||
|
import { useRender } from '@/hooks/component/useRender'; |
||||
|
import { uploadDocument } from '@/api/documentReview/DocumentTasks'; |
||||
|
import { useUserStore } from '@/store/modules/user'; |
||||
|
import { RoleEnum } from '@/enums/roleEnum'; |
||||
|
|
||||
|
const { roleList } = useUserStore(); |
||||
|
export const formSchemas: FormSchema[] = [ |
||||
|
// {
|
||||
|
// label: '模型所属行业',
|
||||
|
// field: 'taskIndustry',
|
||||
|
// component: 'Select',
|
||||
|
// componentProps: {
|
||||
|
// options: getDictOptions('model_industry')
|
||||
|
// },
|
||||
|
// },
|
||||
|
// {
|
||||
|
// label: '模型所属区域',
|
||||
|
// field: 'taskRegion',
|
||||
|
// component: 'Select',
|
||||
|
// componentProps: {
|
||||
|
// options: getDictOptions('model_region')
|
||||
|
// },
|
||||
|
// },
|
||||
|
{ |
||||
|
label: '任务名称', |
||||
|
field: 'taskNameList', |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options: getDictOptions('tender_review'), |
||||
|
mode: 'multiple', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
label: '文档名称', |
||||
|
field: 'documentName', |
||||
|
component: 'Input', |
||||
|
}, |
||||
|
{ |
||||
|
label: '状态', |
||||
|
field: 'progressStatus', |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options: getDictOptions('document_task_status'), |
||||
|
}, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
const { renderDict } = useRender(); |
||||
|
export const columns: BasicColumn[] = [ |
||||
|
{ |
||||
|
title: '任务名称', |
||||
|
dataIndex: 'taskName', |
||||
|
customRender: ({ value }) => renderDict(value, 'tender_review'), |
||||
|
|
||||
|
}, |
||||
|
{ |
||||
|
title: '文档名称', |
||||
|
dataIndex: 'documentName', |
||||
|
}, |
||||
|
{ |
||||
|
title: '模型所属区域', |
||||
|
dataIndex: 'taskRegion', |
||||
|
customRender: ({ value }) => renderDict(value, 'model_region'), |
||||
|
}, |
||||
|
{ |
||||
|
title: '模型所属行业', |
||||
|
dataIndex: 'taskIndustry', |
||||
|
customRender: ({ value }) => renderDict(value, 'model_industry'), |
||||
|
}, |
||||
|
{ |
||||
|
title: '上传时间', |
||||
|
dataIndex: 'createTime', |
||||
|
}, |
||||
|
{ |
||||
|
title: '提交人', |
||||
|
dataIndex: 'createUser', |
||||
|
auth: 'documentReview:DocumentTasks:tableShow', |
||||
|
}, |
||||
|
{ |
||||
|
title: '任务耗时', |
||||
|
dataIndex: 'taskDuration', |
||||
|
}, |
||||
|
{ |
||||
|
title: '状态', |
||||
|
dataIndex: 'progressStatus', |
||||
|
customRender: ({ value }) => renderDict(value, 'document_task_status'), |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const modalSchemas: FormSchema[] = [ |
||||
|
{ |
||||
|
label: '模型所属区域', |
||||
|
field: 'taskRegion', |
||||
|
required: true, |
||||
|
component: 'Select', |
||||
|
// componentProps: {
|
||||
|
// options: taskRegionPermission(),
|
||||
|
// defaultValue:"normal",
|
||||
|
// },
|
||||
|
componentProps: () => { |
||||
|
const isSuperAdmin = roleList.includes(RoleEnum.SUPER_ADMIN); |
||||
|
let options = getDictOptions('model_region'); |
||||
|
if (!isSuperAdmin) { |
||||
|
// 如果不是超级管理员,移除 label 带有 '#' 的项
|
||||
|
options = options.filter((option) => !option.label.includes('#')); |
||||
|
} |
||||
|
return { |
||||
|
options: options, |
||||
|
defaultValue: 'normal', |
||||
|
}; |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
label: '模型所属行业', |
||||
|
field: 'taskIndustry', |
||||
|
required: true, |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options: getDictOptions('model_industry'), |
||||
|
defaultValue: 'normal', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
label: '任务名称', |
||||
|
field: 'taskNameList', |
||||
|
required: true, |
||||
|
component: 'Select', |
||||
|
componentProps: { |
||||
|
options: getDictOptions('tender_review') , |
||||
|
mode: 'multiple', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
label: '文档名称', |
||||
|
field: 'ossId', |
||||
|
required: true, |
||||
|
component: 'Upload', |
||||
|
componentProps: { |
||||
|
accept: ['.docx', '.doc', '.wps'], |
||||
|
maxSize: 500, |
||||
|
multiple: false, |
||||
|
resultField: 'ossId', |
||||
|
api: uploadDocument, |
||||
|
beforeUploadPrompt:"严禁在本互联网非涉密平台处理、传输国家秘密。请再次确认您上传的文件资料不涉及国家秘密。" |
||||
|
}, |
||||
|
}, |
||||
|
]; |
@ -0,0 +1,72 @@ |
|||||
|
<template> |
||||
|
<BasicModal |
||||
|
v-bind="$attrs" |
||||
|
:title="title" |
||||
|
@register="registerInnerModal" |
||||
|
@ok="handleSubmit" |
||||
|
@cancel="resetForm" |
||||
|
> |
||||
|
<BasicForm @register="registerForm" /> |
||||
|
|
||||
|
</BasicModal> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { BasicModal, useModalInner } from '@/components/Modal'; |
||||
|
import { BasicForm, useForm } from '@/components/Form'; |
||||
|
import { computed, ref, unref } from 'vue'; |
||||
|
import { TenderTaskInfo, TenderTaskAdd, TenderTaskUpdate } from '@/api/tenderReview/TenderTask'; |
||||
|
import { modalSchemas } from './TenderTask.data'; |
||||
|
import { ModelUserPromptssettingInfoByUserId } from '@/api/modelConfiguration/ModelUserPromptssetting/index'; |
||||
|
|
||||
|
defineOptions({ name: 'TenderTaskModal' }); |
||||
|
|
||||
|
const emit = defineEmits(['register', 'reload']); |
||||
|
|
||||
|
const isUpdate = ref<boolean>(false); |
||||
|
const title = computed<string>(() => { |
||||
|
return isUpdate.value ? '编辑招标审核任务' : '新增招标审核任务'; |
||||
|
}); |
||||
|
|
||||
|
const [registerInnerModal, { modalLoading, closeModal }] = useModalInner( |
||||
|
async (data: { record?: Recordable; update: boolean }) => { |
||||
|
modalLoading(true); |
||||
|
const settings = await ModelUserPromptssettingInfoByUserId(); |
||||
|
await setFieldsValue(settings); |
||||
|
const { record, update } = data; |
||||
|
isUpdate.value = update; |
||||
|
if (update && record) { |
||||
|
await setFieldsValue(record); |
||||
|
} |
||||
|
modalLoading(false); |
||||
|
}, |
||||
|
); |
||||
|
|
||||
|
const [registerForm, { setFieldsValue, resetForm, validate }] = useForm({ |
||||
|
labelWidth: 100, |
||||
|
showActionButtonGroup: false, |
||||
|
baseColProps: { span: 24 }, |
||||
|
schemas: modalSchemas, |
||||
|
}); |
||||
|
|
||||
|
async function handleSubmit() { |
||||
|
try { |
||||
|
modalLoading(true); |
||||
|
const data = await validate(); |
||||
|
data['ossId'] = data['ossId'][0]; |
||||
|
if (unref(isUpdate)) { |
||||
|
await TenderTaskUpdate(data); |
||||
|
} else { |
||||
|
await TenderTaskAdd(data); |
||||
|
} |
||||
|
emit('reload'); |
||||
|
closeModal(); |
||||
|
await resetForm(); |
||||
|
} catch (e) { |
||||
|
} finally { |
||||
|
modalLoading(false); |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped></style> |
@ -0,0 +1,181 @@ |
|||||
|
<template> |
||||
|
<PageWrapper dense> |
||||
|
<BasicTable @register="registerTable"> |
||||
|
<template #toolbar> |
||||
|
<a-button |
||||
|
@click=" |
||||
|
downloadExcel(TenderTaskExport, '招标摘要任务数据', getForm().getFieldsValue()) |
||||
|
" |
||||
|
v-auth="'productManagement:TenderTask:export'" |
||||
|
>导出</a-button |
||||
|
> |
||||
|
<a-button |
||||
|
type="primary" |
||||
|
danger |
||||
|
@click="multipleRemove(TenderTaskRemove)" |
||||
|
:disabled="!selected" |
||||
|
v-auth="'productManagement:TenderTask:remove'" |
||||
|
>删除</a-button |
||||
|
> |
||||
|
<a-button |
||||
|
type="primary" |
||||
|
@click="handleAdd" |
||||
|
v-auth="'productManagement:TenderTask:add'" |
||||
|
>新增</a-button |
||||
|
> |
||||
|
</template> |
||||
|
<template #bodyCell="{ column, record }"> |
||||
|
<template v-if="column.key === 'action'"> |
||||
|
<TableAction |
||||
|
stopButtonPropagation |
||||
|
:actions="[ |
||||
|
{ |
||||
|
label: '详情', |
||||
|
icon: IconEnum.EDIT, |
||||
|
type: 'primary', |
||||
|
ghost: true, |
||||
|
ifShow: () => { |
||||
|
if ( |
||||
|
record.progressStatus != 'PENDING' && |
||||
|
record.progressStatus != 'STARTED' && |
||||
|
record.progressStatus != 'REVOKED' |
||||
|
) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
onClick: handleDetail.bind(null, record), |
||||
|
}, |
||||
|
{ |
||||
|
label: '下载', |
||||
|
icon: IconEnum.DOWNLOAD, |
||||
|
type: 'primary', |
||||
|
color: 'success', |
||||
|
ghost: true, |
||||
|
ifShow: () => { |
||||
|
if ( |
||||
|
record.progressStatus != 'PENDING' && |
||||
|
record.progressStatus != 'STARTED' && |
||||
|
record.progressStatus != 'REVOKED' |
||||
|
) { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
onClick: handleDownload.bind(null, record), |
||||
|
}, |
||||
|
{ |
||||
|
label: '终止任务', |
||||
|
icon: IconEnum.DELETE, |
||||
|
type: 'primary', |
||||
|
danger: true, |
||||
|
ghost: true, |
||||
|
ifShow: () => { |
||||
|
if (record.progressStatus == 'PENDING') { |
||||
|
return true; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
popConfirm: { |
||||
|
placement: 'left', |
||||
|
title: '是否终止当前任务?', |
||||
|
confirm: handleStop.bind(null, record), |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
/> |
||||
|
</template> |
||||
|
</template> |
||||
|
</BasicTable> |
||||
|
<TenderTaskModal @register="registerModal" @reload="reload" /> |
||||
|
<DocsDrawer @register="registerDrawer" /> |
||||
|
</PageWrapper> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { PageWrapper } from '@/components/Page'; |
||||
|
import { BasicTable, useTable, TableAction } from '@/components/Table'; |
||||
|
import { |
||||
|
TenderTaskList, |
||||
|
TenderTaskExport, |
||||
|
TenderTaskRemove, |
||||
|
} from '@/api/tenderReview/TenderTask'; |
||||
|
import { downloadExcel } from '@/utils/file/download'; |
||||
|
import { useModal } from '@/components/Modal'; |
||||
|
import TenderTaskModal from './TenderTaskModal.vue'; |
||||
|
import { formSchemas, columns } from './TenderTask.data'; |
||||
|
import { IconEnum } from '@/enums/appEnum'; |
||||
|
import DocsDrawer from '@/views/documentReview/DocumentTasks/DocsDrawer.vue'; |
||||
|
import { useDrawer } from '@/components/Drawer'; |
||||
|
import { DocumentTasksStop } from '@/api/documentReview/DocumentTasks'; |
||||
|
import { |
||||
|
DocumentTaskResultsInfoByTaskId, |
||||
|
DocumentTaskResultDownload, |
||||
|
} from '@/api/documentReview/DocumentTaskResults'; |
||||
|
const [registerDrawer, { openDrawer }] = useDrawer(); |
||||
|
|
||||
|
defineOptions({ name: 'TenderTask' }); |
||||
|
|
||||
|
const [registerTable, { reload, multipleRemove, selected, getForm }] = useTable({ |
||||
|
rowSelection: { |
||||
|
type: 'checkbox', |
||||
|
}, |
||||
|
title: '招标审核任务列表', |
||||
|
api: TenderTaskList, |
||||
|
showIndexColumn: false, |
||||
|
rowKey: 'id', |
||||
|
useSearchForm: true, |
||||
|
formConfig: { |
||||
|
schemas: formSchemas, |
||||
|
baseColProps: { |
||||
|
xs: 24, |
||||
|
sm: 24, |
||||
|
md: 24, |
||||
|
lg: 6, |
||||
|
}, |
||||
|
}, |
||||
|
columns: columns, |
||||
|
actionColumn: { |
||||
|
width: 200, |
||||
|
title: '操作', |
||||
|
key: 'action', |
||||
|
fixed: 'right', |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const [registerModal, { openModal }] = useModal(); |
||||
|
|
||||
|
async function handleDetail(record: Recordable) { |
||||
|
try { |
||||
|
let res = await DocumentTaskResultsInfoByTaskId(record.id); |
||||
|
|
||||
|
openDrawer(true, { value: res.result, type: 'markdown' }); |
||||
|
console.log('res', res); |
||||
|
} catch (ex) { |
||||
|
openDrawer(true, { value: '加载失败,请刷新页面', type: 'markdown' }); |
||||
|
} |
||||
|
//根据record.id查询结果详情 |
||||
|
} |
||||
|
|
||||
|
async function handleStop(record: Recordable) { |
||||
|
await DocumentTasksStop(record.id); |
||||
|
await reload(); |
||||
|
} |
||||
|
|
||||
|
function handleAdd() { |
||||
|
openModal(true, { update: false }); |
||||
|
} |
||||
|
async function handleDownload(record: Recordable) { |
||||
|
await DocumentTaskResultDownload([record.id]); |
||||
|
await reload(); |
||||
|
} |
||||
|
async function handleDelete(record: Recordable) { |
||||
|
await TenderTaskRemove([record.id]); |
||||
|
await reload(); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped></style> |
@ -0,0 +1,31 @@ |
|||||
|
<template> |
||||
|
<Card title="最新动态" v-bind="$attrs"> |
||||
|
<template #extra> |
||||
|
<a-button type="link" size="small">更多</a-button> |
||||
|
</template> |
||||
|
<List item-layout="horizontal" :data-source="dynamicInfoItems"> |
||||
|
<template #renderItem="{ item }"> |
||||
|
<ListItem> |
||||
|
<ListItemMeta> |
||||
|
<template #description> |
||||
|
{{ item.date }} |
||||
|
</template> |
||||
|
<!-- eslint-disable-next-line --> |
||||
|
<template #title> {{ item.name }} <span v-html="item.desc"> </span> </template> |
||||
|
<template #avatar> |
||||
|
<Icon :icon="item.avatar" :size="30" /> |
||||
|
</template> |
||||
|
</ListItemMeta> |
||||
|
</ListItem> |
||||
|
</template> |
||||
|
</List> |
||||
|
</Card> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import { Card, List } from 'ant-design-vue'; |
||||
|
import { dynamicInfoItems } from './data'; |
||||
|
import Icon from '@/components/Icon/Icon.vue'; |
||||
|
|
||||
|
const ListItem = List.Item; |
||||
|
const ListItemMeta = List.Item.Meta; |
||||
|
</script> |
@ -0,0 +1,69 @@ |
|||||
|
<template> |
||||
|
<Card title="AI任务" v-bind="$attrs" :style="{ height: '100%' }"> |
||||
|
<template #extra> |
||||
|
<!-- <a-button type="link" size="small">更多</a-button> --> |
||||
|
</template> |
||||
|
|
||||
|
<CardGrid |
||||
|
v-for="item in groupItems" |
||||
|
:key="item.title" |
||||
|
class="!md:w-1/3 !w-full" |
||||
|
:style=item.style |
||||
|
:hoverable=!Boolean(item.style) |
||||
|
@click="handleClick(item)" |
||||
|
> |
||||
|
<span class="flex" > |
||||
|
<Icon :icon="item.icon" :color="item.color" size="50" /> |
||||
|
<span class="text-lg ml-4">{{ item.title }}</span> |
||||
|
</span> |
||||
|
</CardGrid> |
||||
|
</Card> |
||||
|
<DocumentTasksModal @register="registerDocumentTasksModal" /> |
||||
|
<ContractualTasksModal @register="registerContractualTasksModal" /> |
||||
|
<SchemEvaluationModal @register="registerSchemEvaluationModal" /> |
||||
|
|
||||
|
<TenderTaskModal @register="registerTenderTaskModal" /> |
||||
|
|
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import { Card, CardGrid } from 'ant-design-vue'; |
||||
|
import Icon from '@/components/Icon/Icon.vue'; |
||||
|
import { groupItems } from './data'; |
||||
|
import { useModal } from '@/components/Modal'; |
||||
|
import DocumentTasksModal from '@/views/documentReview/DocumentTasks/DocumentTasksModal.vue'; |
||||
|
import ContractualTasksModal from '@/views/contractReview/ContractualTasks/ContractualTasksModal.vue'; |
||||
|
import SchemEvaluationModal from '@/views/schemeEvaluation/SchemeEvaluation/SchemEvaluationModal.vue'; |
||||
|
|
||||
|
import TenderTaskModal from '@/views/tenderReview/TenderTask/TenderTaskModal.vue'; |
||||
|
import { useMessage } from '@/hooks/web/useMessage'; |
||||
|
import { TaskType } from '@/enums/taskEnum'; |
||||
|
|
||||
|
const { notification } = useMessage(); |
||||
|
|
||||
|
const [registerDocumentTasksModal, { openModal: openDocumentTasksModal }] = useModal(); |
||||
|
const [registerContractualTasksModal, { openModal: openContractualTasksModal }] = useModal(); |
||||
|
const [registerTenderTaskModal, { openModal: openTenderTaskModal }] = useModal(); |
||||
|
const [registerSchemEvaluationModal, { openModal: openSchemEvaluationModal }] = useModal(); |
||||
|
|
||||
|
function handleClick(item: any) { |
||||
|
if (item.key == TaskType.SCHEME_REVIEW.value) { |
||||
|
openDocumentTasksModal(true, { update: false }); |
||||
|
} else if (item.key == TaskType.CONTRACT_REVIEW.value) { |
||||
|
openContractualTasksModal(true, { update: false }); |
||||
|
} |
||||
|
else if (item.key == TaskType.SCHEME_EVALUATION.value) { |
||||
|
openSchemEvaluationModal(true, { update: false }); |
||||
|
} |
||||
|
else if (item.key == TaskType.TENDER_REVIEW.value) { |
||||
|
openTenderTaskModal(true, { update: false }); |
||||
|
} |
||||
|
else { |
||||
|
//通知提醒弹窗,内容开发中.居中显示 |
||||
|
notification.info({ |
||||
|
message: '通知', |
||||
|
description: `${item.title}正在测试中,敬请期待`, |
||||
|
placement: 'top', |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,53 @@ |
|||||
|
<template> |
||||
|
<Card title="常用功能" :style="{ height: '100%' }"> |
||||
|
<CardGrid v-for="item in navItems" :key="item.title" @click="handleClick(item)"> |
||||
|
<span class="flex flex-col items-center"> |
||||
|
<Icon :icon="item.icon" :color="item.color" size="20" /> |
||||
|
<span class="text-md mt-2 truncate">{{ item.title }}</span> |
||||
|
</span> |
||||
|
</CardGrid> |
||||
|
</Card> |
||||
|
<DocumentTasksModal @register="registerDocumentTasksModal" /> |
||||
|
<ContractualTasksModal @register="registerContractualTasksModal" /> |
||||
|
<SchemEvaluationModal @register="registerSchemEvaluationModal" /> |
||||
|
|
||||
|
<TenderTaskModal @register="registerTenderTaskModal" /> |
||||
|
|
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import { Card, CardGrid } from 'ant-design-vue'; |
||||
|
import { navItems } from './data'; |
||||
|
import Icon from '@/components/Icon/Icon.vue'; |
||||
|
import { useModal } from '@/components/Modal'; |
||||
|
import DocumentTasksModal from '@/views/documentReview/DocumentTasks/DocumentTasksModal.vue'; |
||||
|
import ContractualTasksModal from '@/views/contractReview/ContractualTasks/ContractualTasksModal.vue'; |
||||
|
import SchemEvaluationModal from '@/views/schemeEvaluation/SchemeEvaluation/SchemEvaluationModal.vue'; |
||||
|
|
||||
|
import TenderTaskModal from '@/views/tenderReview/TenderTask/TenderTaskModal.vue'; |
||||
|
import { useMessage } from '@/hooks/web/useMessage'; |
||||
|
const { notification } = useMessage(); |
||||
|
|
||||
|
const [registerTenderTaskModal, { openModal:openTenderTaskModal }] = useModal(); |
||||
|
const [registerDocumentTasksModal, { openModal:openDocumentTasksModal }] = useModal(); |
||||
|
const [registerSchemEvaluationModal, { openModal: openSchemEvaluationModal }] = useModal(); |
||||
|
|
||||
|
const [registerContractualTasksModal, { openModal:openContractualTasksModal }] = useModal(); |
||||
|
import { SchemeEvaluation,SchemeTask,ContractTask,extractValues } from "@/enums/taskEnum"; |
||||
|
const solutionApprovalList = extractValues(SchemeTask,"value"); |
||||
|
function handleClick(item: any) { |
||||
|
if(solutionApprovalList.includes(item.key)){ |
||||
|
openDocumentTasksModal(true, { update: true,record: { taskNameList: [item.key] } }); |
||||
|
}else if(item.key == ContractTask.CONTRACT_REVIEW.value){ |
||||
|
openContractualTasksModal(true, {update: true,record: { taskNameList: [item.key] } }); |
||||
|
}else if(item.key ==SchemeEvaluation.SCHEME_EVALUATION.value){ |
||||
|
openSchemEvaluationModal(true, {update: true,record: { taskNameList: [item.key] } }); |
||||
|
}else{ |
||||
|
//通知提醒弹窗,内容开发中.居中显示 |
||||
|
notification.info({ |
||||
|
message: '通知', |
||||
|
description: `${item.title}正在测试中,敬请期待`, |
||||
|
placement: 'top', |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
</script> |
@ -0,0 +1,94 @@ |
|||||
|
<template> |
||||
|
<Card title="销售统计" :loading="loading"> |
||||
|
<div ref="chartRef" :style="{ width, height }"></div> |
||||
|
</Card> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import { Ref, ref, watch } from 'vue'; |
||||
|
import { Card } from 'ant-design-vue'; |
||||
|
import { useECharts } from '@/hooks/web/useECharts'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
loading: Boolean, |
||||
|
width: { |
||||
|
type: String as PropType<string>, |
||||
|
default: '100%', |
||||
|
}, |
||||
|
height: { |
||||
|
type: String as PropType<string>, |
||||
|
default: '400px', |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const chartRef = ref<HTMLDivElement | null>(null); |
||||
|
const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>); |
||||
|
watch( |
||||
|
() => props.loading, |
||||
|
() => { |
||||
|
if (props.loading) { |
||||
|
return; |
||||
|
} |
||||
|
setOptions({ |
||||
|
legend: { |
||||
|
bottom: 0, |
||||
|
data: ['Visits', 'Sales'], |
||||
|
}, |
||||
|
tooltip: {}, |
||||
|
radar: { |
||||
|
radius: '60%', |
||||
|
splitNumber: 8, |
||||
|
indicator: [ |
||||
|
{ |
||||
|
name: '2017', |
||||
|
}, |
||||
|
{ |
||||
|
name: '2017', |
||||
|
}, |
||||
|
{ |
||||
|
name: '2018', |
||||
|
}, |
||||
|
{ |
||||
|
name: '2019', |
||||
|
}, |
||||
|
{ |
||||
|
name: '2020', |
||||
|
}, |
||||
|
{ |
||||
|
name: '2021', |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'radar', |
||||
|
symbolSize: 0, |
||||
|
areaStyle: { |
||||
|
shadowBlur: 0, |
||||
|
shadowColor: 'rgba(0,0,0,.2)', |
||||
|
shadowOffsetX: 0, |
||||
|
shadowOffsetY: 10, |
||||
|
opacity: 1, |
||||
|
}, |
||||
|
data: [ |
||||
|
{ |
||||
|
value: [90, 50, 86, 40, 50, 20], |
||||
|
name: 'Visits', |
||||
|
itemStyle: { |
||||
|
color: '#b6a2de', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
value: [70, 75, 70, 76, 20, 85], |
||||
|
name: 'Sales', |
||||
|
itemStyle: { |
||||
|
color: '#67e0e3', |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
], |
||||
|
}); |
||||
|
}, |
||||
|
{ immediate: true }, |
||||
|
); |
||||
|
</script> |
@ -0,0 +1,80 @@ |
|||||
|
<template> |
||||
|
<Card hoverable :loading="loading" style="width: 100%;height: 100%;"> |
||||
|
<template #cover> |
||||
|
<img v-if="task.coverImage" :src="task.coverImage" :alt="task.title" /> |
||||
|
</template> |
||||
|
<CardMeta :title="task.title" style="width: 100%;height: 100%;"> |
||||
|
<template #description> |
||||
|
<div class="task-info"> |
||||
|
<p>{{ task.description }}</p> |
||||
|
<!-- <div class="task-meta flex items-center justify-between mt-2"> |
||||
|
<a-tag :color="getStatusColor(task.status)">{{ task.status }}</a-tag> |
||||
|
<span class="text-gray-500">截止日期: {{ task.deadline }}</span> |
||||
|
</div> --> |
||||
|
<Row :gutter="[8, 8]"> |
||||
|
<Col v-for="task in task.taskList" > |
||||
|
<a-button type="link"> |
||||
|
<Icon |
||||
|
:icon="task.icon" |
||||
|
/> |
||||
|
{{ task.text }} |
||||
|
</a-button> |
||||
|
</Col> |
||||
|
</Row> |
||||
|
</div> |
||||
|
</template> |
||||
|
</CardMeta> |
||||
|
</Card> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup> |
||||
|
import { withDefaults, defineProps,defineEmits } from 'vue'; |
||||
|
import { Card, CardMeta,AvatarGroup, Avatar,Row, Col } from 'ant-design-vue'; |
||||
|
import Icon from '@/components/Icon/Icon.vue'; |
||||
|
|
||||
|
|
||||
|
interface TaskInterface { |
||||
|
id: string | number; |
||||
|
title: string; |
||||
|
description: string; |
||||
|
taskList:any[]; |
||||
|
status: 'pending' | 'inProgress' | 'completed' | 'delayed'; |
||||
|
deadline: string; |
||||
|
coverImage?: string; |
||||
|
members: { |
||||
|
id: string | number; |
||||
|
name: string; |
||||
|
avatar: string; |
||||
|
}[]; |
||||
|
} |
||||
|
// 定义 props |
||||
|
interface Props { |
||||
|
task: TaskInterface; |
||||
|
loading?: boolean; |
||||
|
} |
||||
|
|
||||
|
const props = withDefaults(defineProps<Props>(), { |
||||
|
loading: false, |
||||
|
}); |
||||
|
|
||||
|
// 定义 emits |
||||
|
const emit = defineEmits<{ |
||||
|
(e: 'click', task: TaskInterface): void; |
||||
|
}>(); |
||||
|
|
||||
|
// 状态颜色映射 |
||||
|
const getStatusColor = (status: string) => { |
||||
|
const statusMap: Record<string, string> = { |
||||
|
pending: 'orange', |
||||
|
inProgress: 'blue', |
||||
|
completed: 'green', |
||||
|
delayed: 'red', |
||||
|
}; |
||||
|
return statusMap[status] || 'default'; |
||||
|
}; |
||||
|
|
||||
|
// 处理任务点击 |
||||
|
const handleTaskClick = () => { |
||||
|
emit('click', props.task); |
||||
|
}; |
||||
|
</script> |
@ -0,0 +1,59 @@ |
|||||
|
<template> |
||||
|
<div class="rounded-lg bg-white h-full flex "> |
||||
|
<div class="font-mono mt-4 ml-4"> |
||||
|
进行中 |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup> |
||||
|
import { withDefaults, defineProps,defineEmits } from 'vue'; |
||||
|
import { List, CardMeta,AvatarGroup, Avatar,Row, Col } from 'ant-design-vue'; |
||||
|
import Icon from '@/components/Icon/Icon.vue'; |
||||
|
|
||||
|
|
||||
|
interface TaskInterface { |
||||
|
id: string | number; |
||||
|
title: string; |
||||
|
description: string; |
||||
|
taskList:any[]; |
||||
|
status: 'pending' | 'inProgress' | 'completed' | 'delayed'; |
||||
|
deadline: string; |
||||
|
coverImage?: string; |
||||
|
members: { |
||||
|
id: string | number; |
||||
|
name: string; |
||||
|
avatar: string; |
||||
|
}[]; |
||||
|
} |
||||
|
// 定义 props |
||||
|
interface Props { |
||||
|
task: TaskInterface; |
||||
|
loading?: boolean; |
||||
|
} |
||||
|
|
||||
|
const props = withDefaults(defineProps<Props>(), { |
||||
|
loading: false, |
||||
|
}); |
||||
|
|
||||
|
// 定义 emits |
||||
|
const emit = defineEmits<{ |
||||
|
(e: 'click', task: TaskInterface): void; |
||||
|
}>(); |
||||
|
|
||||
|
// 状态颜色映射 |
||||
|
const getStatusColor = (status: string) => { |
||||
|
const statusMap: Record<string, string> = { |
||||
|
pending: 'orange', |
||||
|
inProgress: 'blue', |
||||
|
completed: 'green', |
||||
|
delayed: 'red', |
||||
|
}; |
||||
|
return statusMap[status] || 'default'; |
||||
|
}; |
||||
|
|
||||
|
// 处理任务点击 |
||||
|
const handleTaskClick = () => { |
||||
|
emit('click', props.task); |
||||
|
}; |
||||
|
</script> |
@ -0,0 +1,33 @@ |
|||||
|
<template> |
||||
|
<div class="lg:flex"> |
||||
|
<Avatar :src="userinfo.avatar || headerImg" :size="72" class="!mx-auto !block" /> |
||||
|
<div class="md:ml-6 flex flex-col justify-center md:mt-0 mt-2"> |
||||
|
<h1 class="md:text-lg text-md">早安, {{ userinfo.nickName }}, 开始您一天的工作吧!</h1> |
||||
|
<!-- <span class="text-secondary"> 今日晴,20℃ - 32℃! </span> --> |
||||
|
</div> |
||||
|
<div class="flex flex-1 justify-end md:mt-0 mt-4"> |
||||
|
<!-- <div class="flex flex-col justify-center text-right"> |
||||
|
<span class="text-secondary"> 待办 </span> |
||||
|
<span class="text-2xl">2/10</span> |
||||
|
</div> |
||||
|
|
||||
|
<div class="flex flex-col justify-center text-right md:mx-16 mx-12"> |
||||
|
<span class="text-secondary"> 项目 </span> |
||||
|
<span class="text-2xl">8</span> |
||||
|
</div> |
||||
|
<div class="flex flex-col justify-center text-right md:mr-10 mr-4"> |
||||
|
<span class="text-secondary"> 团队 </span> |
||||
|
<span class="text-2xl">300</span> |
||||
|
</div> --> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import { computed } from 'vue'; |
||||
|
import { Avatar } from 'ant-design-vue'; |
||||
|
import { useUserStore } from '@/store/modules/user'; |
||||
|
import headerImg from '@/assets/images/header.jpg'; |
||||
|
|
||||
|
const userStore = useUserStore(); |
||||
|
const userinfo = computed(() => userStore.getUserInfo); |
||||
|
</script> |
@ -0,0 +1,140 @@ |
|||||
|
import { TaskType, SchemeTask, ContractTask, SchemeEvaluation } from '@/enums/taskEnum'; |
||||
|
|
||||
|
interface GroupItem { |
||||
|
title: string; |
||||
|
icon: string; |
||||
|
key: string; |
||||
|
color: string; |
||||
|
style: string; |
||||
|
path:string; |
||||
|
} |
||||
|
|
||||
|
interface NavItem { |
||||
|
title: string; |
||||
|
icon: string; |
||||
|
color: string; |
||||
|
key: string; |
||||
|
} |
||||
|
|
||||
|
interface DynamicInfoItem { |
||||
|
avatar: string; |
||||
|
name: string; |
||||
|
date: string; |
||||
|
desc: string; |
||||
|
} |
||||
|
|
||||
|
// 导航项配置
|
||||
|
export const navItems: NavItem[] = [ |
||||
|
{ |
||||
|
title: SchemeTask.DOCUMENT_SIMILARITY.label, |
||||
|
icon: SchemeTask.DOCUMENT_SIMILARITY.icon, |
||||
|
color: SchemeTask.DOCUMENT_SIMILARITY.color, |
||||
|
key: SchemeTask.DOCUMENT_SIMILARITY.value, |
||||
|
}, |
||||
|
{ |
||||
|
title: SchemeTask.DOCUMENT_ERROR.label, |
||||
|
icon: SchemeTask.DOCUMENT_ERROR.icon, |
||||
|
color: SchemeTask.DOCUMENT_ERROR.color, |
||||
|
key: SchemeTask.DOCUMENT_ERROR.value, |
||||
|
}, |
||||
|
{ |
||||
|
title: ContractTask.CONTRACT_REVIEW.label, |
||||
|
icon: ContractTask.CONTRACT_REVIEW.icon, |
||||
|
color: ContractTask.CONTRACT_REVIEW.color, |
||||
|
key: ContractTask.CONTRACT_REVIEW.value, |
||||
|
}, |
||||
|
{ |
||||
|
title: SchemeEvaluation.SCHEME_EVALUATION.label, |
||||
|
icon: SchemeEvaluation.SCHEME_EVALUATION.icon, |
||||
|
color: SchemeEvaluation.SCHEME_EVALUATION.color, |
||||
|
key: SchemeEvaluation.SCHEME_EVALUATION.value, |
||||
|
}, |
||||
|
{ |
||||
|
title: SchemeTask.PLACE_CHECK.label, |
||||
|
icon: SchemeTask.PLACE_CHECK.icon, |
||||
|
color: SchemeTask.PLACE_CHECK.color, |
||||
|
key: SchemeTask.PLACE_CHECK.value, |
||||
|
}, |
||||
|
{ |
||||
|
title: SchemeTask.COMPANY_CHECK.label, |
||||
|
icon: SchemeTask.COMPANY_CHECK.icon, |
||||
|
color: SchemeTask.COMPANY_CHECK.color, |
||||
|
key: SchemeTask.COMPANY_CHECK.value, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
export const dynamicInfoItems: DynamicInfoItem[] = []; |
||||
|
|
||||
|
// 分组项配置
|
||||
|
export const groupItems: GroupItem[] = [ |
||||
|
// {
|
||||
|
// title: '方案生成',
|
||||
|
// icon: 'solar:document-add-bold-duotone',
|
||||
|
// key: 'solutionGenerate',
|
||||
|
// color: '#52C41A',
|
||||
|
// style:"!md:w-1/3 !w-full"
|
||||
|
|
||||
|
// },
|
||||
|
{ |
||||
|
title: TaskType.SCHEME_REVIEW.label, |
||||
|
icon: TaskType.SCHEME_REVIEW.icon, |
||||
|
key: TaskType.SCHEME_REVIEW.value, |
||||
|
color: TaskType.SCHEME_REVIEW.color, |
||||
|
style:"", |
||||
|
path:TaskType.SCHEME_REVIEW.path, |
||||
|
}, |
||||
|
{ |
||||
|
title: TaskType.SCHEME_EVALUATION.label, |
||||
|
icon: TaskType.SCHEME_EVALUATION.icon, |
||||
|
key: TaskType.SCHEME_EVALUATION.value, |
||||
|
color: TaskType.SCHEME_EVALUATION.color, |
||||
|
style:"", |
||||
|
path:TaskType.SCHEME_EVALUATION.path, |
||||
|
|
||||
|
}, |
||||
|
{ |
||||
|
title: TaskType.CONTRACT_REVIEW.label, |
||||
|
icon: TaskType.CONTRACT_REVIEW.icon, |
||||
|
key: TaskType.CONTRACT_REVIEW.value, |
||||
|
color: TaskType.CONTRACT_REVIEW.color, |
||||
|
style:"", |
||||
|
path:TaskType.CONTRACT_REVIEW.path, |
||||
|
|
||||
|
}, |
||||
|
{ |
||||
|
title: TaskType.TENDER_REVIEW.label, |
||||
|
icon: TaskType.TENDER_REVIEW.icon, |
||||
|
key: TaskType.TENDER_REVIEW.value, |
||||
|
color: TaskType.TENDER_REVIEW.color, |
||||
|
style:"", |
||||
|
path:TaskType.TENDER_REVIEW.path, |
||||
|
|
||||
|
}, |
||||
|
// {
|
||||
|
// title: '投标审核',
|
||||
|
// icon: 'heroicons:clipboard-document-check',
|
||||
|
// key: 'bidApproval',
|
||||
|
// color: '#36CFC9',
|
||||
|
// style:"!md:w-1/3 !w-full bg-red-50"
|
||||
|
|
||||
|
// },
|
||||
|
|
||||
|
{ |
||||
|
title: '公文审核', |
||||
|
icon: 'mdi:file-document-check', |
||||
|
key: 'documentTranslate', |
||||
|
color: '#722ED1', |
||||
|
style:"background-color: #CECECE;", |
||||
|
path:"", |
||||
|
|
||||
|
}, |
||||
|
{ |
||||
|
title: TaskType.PROJECT_DOCUMENT_REVIEW.label, |
||||
|
icon: TaskType.PROJECT_DOCUMENT_REVIEW.icon, |
||||
|
key: TaskType.PROJECT_DOCUMENT_REVIEW.value, |
||||
|
color: TaskType.PROJECT_DOCUMENT_REVIEW.color, |
||||
|
style:"background-color: #CECECE;", |
||||
|
path:TaskType.PROJECT_DOCUMENT_REVIEW.path, |
||||
|
|
||||
|
}, |
||||
|
]; |
@ -0,0 +1,76 @@ |
|||||
|
<template> |
||||
|
<PageWrapper> |
||||
|
<template #headerContent> <WorkbenchHeader /> </template> |
||||
|
<div class="workbench"> |
||||
|
<div class="h-1/4"> |
||||
|
<div class="grid grid-cols-5 gap-4"> |
||||
|
<div class="col-span-3 h-full"> |
||||
|
<ProjectCard :loading="loading" class="enter-y" /> |
||||
|
</div> |
||||
|
<div class="col-span-2 h-full"> |
||||
|
<QuickNav :loading="loading" class="enter-y" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="h-1/2 mt-4"> |
||||
|
<Card title="任务看板" :bordered="false" style="width: 100%; height: 100%"> |
||||
|
<template #extra> |
||||
|
<!-- 将按钮改为下拉菜单 --> |
||||
|
<Dropdown> |
||||
|
<a-button> |
||||
|
更多 |
||||
|
<DownOutlined /> |
||||
|
</a-button> |
||||
|
<template #overlay> |
||||
|
<Menu @click="handleMenuClick" mode="vertical"> |
||||
|
<MenuItem v-for="item in groupItems" |
||||
|
:key="item.path" |
||||
|
> |
||||
|
{{ item.title }} |
||||
|
</MenuItem> |
||||
|
</Menu> |
||||
|
</template> |
||||
|
</Dropdown> |
||||
|
</template> |
||||
|
|
||||
|
<DocumentTasksTable |
||||
|
:show-table-setting="false" |
||||
|
:show-toolbar="false" |
||||
|
:use-search-form="false" |
||||
|
:pagination="false" |
||||
|
/> |
||||
|
</Card> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</PageWrapper> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import { ref, onMounted } from 'vue'; |
||||
|
import { PageWrapper } from '@/components/Page'; |
||||
|
import WorkbenchHeader from './components/WorkbenchHeader.vue'; |
||||
|
import { Card, Dropdown, Menu, MenuItem } from 'ant-design-vue'; |
||||
|
import ProjectCard from './components/ProjectCard.vue'; |
||||
|
import QuickNav from './components/QuickNav.vue'; |
||||
|
import DocumentTasksTable from '@/views/documentReview/DocumentTasks/DocumentTasksTable.vue'; |
||||
|
import { useRouter } from 'vue-router'; |
||||
|
import { DownOutlined, UserOutlined } from '@ant-design/icons-vue'; |
||||
|
import { groupItems } from './components/data'; |
||||
|
|
||||
|
const router = useRouter(); |
||||
|
// 状态定义 |
||||
|
const loading = ref(false); |
||||
|
const handleMenuClick = ({ key }) => { |
||||
|
console.log(key); |
||||
|
router.push({ path: key }); |
||||
|
}; |
||||
|
// 获取任务列表 |
||||
|
const fetchTaskList = async () => {}; |
||||
|
|
||||
|
// 页面加载时获取数据 |
||||
|
onMounted(() => { |
||||
|
fetchTaskList(); |
||||
|
}); |
||||
|
setTimeout(() => { |
||||
|
loading.value = false; |
||||
|
}, 1500); |
||||
|
</script> |
Loading…
Reference in new issue