diff --git a/src/api/review/meeting.ts b/src/api/review/meeting.ts new file mode 100644 index 000000000..7e1e534e2 --- /dev/null +++ b/src/api/review/meeting.ts @@ -0,0 +1,114 @@ +import request from '@/config/axios' + +// ============================================================ +// 类型定义 +// ============================================================ + +// 评审项目条目(Excel 导入 & 保存时使用) +export interface ReviewProjectItemVO { + seqNo: number + startTime: string + endTime: string + agendaCategory: string + projectTitle: string + reporter: string + reporterUnit: string +} + +// 会议保存 VO(新增/编辑) +export interface ReviewMeetingSaveReqVO { + id?: number + name: string + startTime: string | number + endTime: string | number + location: string + expertIds: number[] + projects?: ReviewProjectItemVO[] +} + +// 会议列表分页查询 VO +export interface ReviewMeetingPageReqVO { + pageNo?: number + pageSize?: number + name?: string + status?: number + startTime?: string[] +} + +// 会议响应 VO +export interface ReviewMeetingRespVO { + id: number + name: string + startTime: string + endTime: string + location: string + status: number // 0-草稿 1-已邀约 2-已结束 3-已取消 + expertIds: number[] + expertCount: number + projectCount: number + createTime: string +} + +// 短信发送状态 VO +export interface ReviewMeetingSmsLogRespVO { + id: number + expertId: number + expertName: string + mobile: string + status: number // 0-待发送 1-成功 2-失败 + errorMsg: string + retryCount: number + sendTime: string +} + +// ============================================================ +// API 调用 +// ============================================================ + +/** 创建会议(保存草稿) */ +export const createReviewMeeting = (data: ReviewMeetingSaveReqVO) => + request.post({ url: '/project/review-meeting/create', data }) + +/** 更新会议 */ +export const updateReviewMeeting = (data: ReviewMeetingSaveReqVO) => + request.put({ url: '/project/review-meeting/update', data }) + +/** 取消会议 */ +export const cancelReviewMeeting = (id: number) => + request.put({ url: '/project/review-meeting/cancel', params: { id } }) + +/** 结束会议 */ +export const finishReviewMeeting = (id: number) => + request.put({ url: '/project/review-meeting/finish', params: { id } }) + +/** 获取会议详情 */ +export const getReviewMeeting = (id: number) => + request.get({ url: '/project/review-meeting/get', params: { id } }) + +/** 分页查询会议列表 */ +export const getReviewMeetingPage = (params: ReviewMeetingPageReqVO) => + request.get({ url: '/project/review-meeting/page', params }) + +/** 发送短信邀约 */ +export const sendSmsInvitation = (id: number) => + request.post({ url: '/project/review-meeting/send-sms', params: { id } }) + +/** 手动重发失败短信 */ +export const retrySmsLog = (smsLogId: number) => + request.post({ url: '/project/review-meeting/retry-sms', params: { smsLogId } }) + +/** 获取短信发送状态列表 */ +export const getSmsLogList = (reviewMeetingId: number) => + request.get({ url: '/project/review-meeting/sms-log-list', params: { reviewMeetingId } }) + +/** 解析 Excel 导入评审项目(返回项目列表,不落库) */ +export const importProjectsFromExcel = (file: File) => { + const formData = new FormData() + formData.append('file', file) + return request.upload({ url: '/project/review-meeting/import-projects', data: formData }) +} + +/** 下载导入模板 */ +export const getImportTemplate = () => + request.download({ url: '/project/review-meeting/get-import-template' }) + diff --git a/src/api/review/project.ts b/src/api/review/project.ts new file mode 100644 index 000000000..ba8a3b9e1 --- /dev/null +++ b/src/api/review/project.ts @@ -0,0 +1,86 @@ +import request from '@/config/axios' + +// ============================================================ +// 类型定义 +// ============================================================ + +export interface ReviewMeetingProjectRespVO { + id: number + reviewMeetingId: number + seqNo: number + startTime: string + endTime: string + agendaCategory: string + projectTitle: string + reporter: string + reporterUnit: string + host: string +} + +export interface ReviewMeetingProjectPageReqVO { + pageNo?: number + pageSize?: number + reviewMeetingId: number + projectTitle?: string + agendaCategory?: string + reporter?: string +} + +export interface ReviewMeetingFileRespVO { + id: number + reviewMeetingProjectId: number + fileName: string + fileUrl: string + fileSize: number + fileType: string + creator: string + createTime: string +} + +// ============================================================ +// API 调用 +// ============================================================ + +/** 分页查询评审项目列表 */ +export const getReviewProjectPage = (params: ReviewMeetingProjectPageReqVO) => + request.get({ url: '/project/review-project/page', params }) + +/** 创建评审项目 */ +export const createReviewProject = (data: Partial) => + request.post({ url: '/project/review-project/create', data }) + +/** 更新评审项目信息 */ +export const updateReviewProject = (data: Partial) => + request.put({ url: '/project/review-project/update', data }) + +/** 删除评审项目 */ +export const deleteReviewProject = (ids: number[]) => + request.delete({ url: '/project/review-project/delete', params: { ids: ids.join(',') } }) + +/** 更新评审项目主持人 */ +export const updateProjectHost = (projectId: number, host: string) => + request.put({ url: '/project/review-project/update-host', params: { projectId, host } }) + +/** 上传会议文件 */ +export const uploadMeetingFile = ( + reviewMeetingId: number, + reviewMeetingProjectId: number, + file: File +) => { + const formData = new FormData() + formData.append('reviewMeetingId', String(reviewMeetingId)) + formData.append('reviewMeetingProjectId', String(reviewMeetingProjectId)) + formData.append('file', file) + return request.upload({ url: '/project/review-project/upload-file', data: formData }) +} + +/** 获取项目文件列表 */ +export const getMeetingFileList = (reviewMeetingProjectId: number) => + request.get({ + url: '/project/review-project/file-list', + params: { reviewMeetingProjectId } + }) + +/** 删除会议文件 */ +export const deleteMeetingFile = (id: number) => + request.delete({ url: '/project/review-project/delete-file', params: { id } }) diff --git a/src/api/system/user/index.ts b/src/api/system/user/index.ts index 5c5b00ae6..3847391a8 100644 --- a/src/api/system/user/index.ts +++ b/src/api/system/user/index.ts @@ -39,6 +39,11 @@ export const updateUser = (data: UserVO) => { return request.put({ url: '/system/user/update', data }) } +// 获取专家列表 +export const getExpertUserList = () => { + return request.get({ url: '/system/user/expert-list' }) +} + // 删除用户 export const deleteUser = (id: number) => { return request.delete({ url: '/system/user/delete?id=' + id }) diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts index 12c2daf4e..d850c20c4 100644 --- a/src/router/modules/remaining.ts +++ b/src/router/modules/remaining.ts @@ -723,6 +723,18 @@ const remainingRouter: AppRouteRecordRaw[] = [ activeMenu: '/project/acceptance' }, component: () => import('@/views/project/acceptance/detail/index.vue') + }, + { + path: 'review-meeting/project/:meetingId(\\d+)', + name: 'ReviewMeetingProject', + meta: { + title: '评审项目列表', + noCache: true, + hidden: true, + canTo: true, + activeMenu: '/review/meeting' + }, + component: () => import('@/views/review/meeting/ProjectList.vue') } ] }, diff --git a/src/views/review/meeting/FileListDialog.vue b/src/views/review/meeting/FileListDialog.vue new file mode 100644 index 000000000..b87cdfb2f --- /dev/null +++ b/src/views/review/meeting/FileListDialog.vue @@ -0,0 +1,113 @@ + + + diff --git a/src/views/review/meeting/MeetingForm.vue b/src/views/review/meeting/MeetingForm.vue new file mode 100644 index 000000000..e6d90853c --- /dev/null +++ b/src/views/review/meeting/MeetingForm.vue @@ -0,0 +1,243 @@ + + + + + diff --git a/src/views/review/meeting/ProjectList.vue b/src/views/review/meeting/ProjectList.vue new file mode 100644 index 000000000..d55eade86 --- /dev/null +++ b/src/views/review/meeting/ProjectList.vue @@ -0,0 +1,243 @@ + + + + + diff --git a/src/views/review/meeting/SmsStatusDialog.vue b/src/views/review/meeting/SmsStatusDialog.vue new file mode 100644 index 000000000..834942bd4 --- /dev/null +++ b/src/views/review/meeting/SmsStatusDialog.vue @@ -0,0 +1,62 @@ + + + diff --git a/src/views/review/meeting/index.vue b/src/views/review/meeting/index.vue new file mode 100644 index 000000000..3483d410d --- /dev/null +++ b/src/views/review/meeting/index.vue @@ -0,0 +1,200 @@ + + +