233 lines
8.9 KiB
Vue
233 lines
8.9 KiB
Vue
<template>
|
|
<ContentWrap>
|
|
<!-- 搜索栏 -->
|
|
<el-form ref="queryFormRef" :model="queryParams" label-width="80px" :inline="true">
|
|
<el-form-item label="会议名称" prop="name">
|
|
<el-input v-model="queryParams.name" placeholder="请输入会议名称" clearable @keyup.enter="handleQuery" />
|
|
</el-form-item>
|
|
<el-form-item label="状态" prop="status">
|
|
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
|
|
<el-option v-for="item in MEETING_STATUS_OPTIONS" :key="item.value" :label="item.label" :value="item.value" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="会议时间" prop="startTime">
|
|
<el-date-picker
|
|
v-model="queryParams.startTime"
|
|
type="datetimerange"
|
|
range-separator="至"
|
|
start-placeholder="开始时间"
|
|
end-placeholder="结束时间"
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button type="primary" @click="handleQuery">查询</el-button>
|
|
<el-button @click="resetQuery">重置</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
|
|
<!-- 操作按钮 -->
|
|
<el-row :gutter="10" class="mb8">
|
|
<el-col :span="1.5">
|
|
<el-button v-hasPermi="['review:meeting:create']" type="primary" plain @click="goToEdit()">
|
|
<el-icon><Plus /></el-icon> 新建会议
|
|
</el-button>
|
|
</el-col>
|
|
</el-row>
|
|
|
|
<!-- 列表 -->
|
|
<el-table v-loading="loading" :data="list">
|
|
<el-table-column label="编号" prop="id" width="80" align="center" />
|
|
<el-table-column label="会议名称" min-width="180">
|
|
<template #default="{ row }">
|
|
<el-link type="primary" @click="goToProjectList(row)">{{ row.name }}</el-link>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="开始时间" width="145">
|
|
<template #default="{ row }">
|
|
{{ formatDate(row.startTime, 'YYYY-MM-DD HH:mm') }}
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="结束时间" width="145">
|
|
<template #default="{ row }">
|
|
{{ formatDate(row.endTime, 'YYYY-MM-DD HH:mm') }}
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="会议地点" prop="location" show-overflow-tooltip />
|
|
<el-table-column label="参会专家数" prop="expertCount" width="100" align="center" />
|
|
<el-table-column label="评审项目数" prop="projectCount" width="100" align="center" />
|
|
<el-table-column label="状态" prop="status" width="100" align="center">
|
|
<template #default="{ row }">
|
|
<el-tag :type="STATUS_TAG_TYPE[row.status]">{{ STATUS_LABEL[row.status] }}</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column label="操作" width="380" align="center" fixed="right">
|
|
<template #default="{ row }">
|
|
<!-- 待召开 -->
|
|
<template v-if="row.status === 0">
|
|
<el-button v-hasPermi="['review:meeting:update']" type="primary" link @click="goToEdit(row.id)">编辑</el-button>
|
|
<el-button type="primary" link @click="goToProjectList(row)">项目列表</el-button>
|
|
<el-button v-hasPermi="['review:meeting:send-sms']" type="success" link @click="handleSendSms(row)">发送短信邀约</el-button>
|
|
<el-button v-hasPermi="['review:meeting:cancel']" type="danger" link @click="handleCancel(row)">取消</el-button>
|
|
</template>
|
|
<!-- 正在召开 -->
|
|
<template v-else-if="row.status === 1">
|
|
<el-button type="info" link @click="goToEdit(row.id, 'view')">查看</el-button>
|
|
<el-button type="primary" link @click="goToProjectList(row)">项目列表</el-button>
|
|
<el-button v-hasPermi="['review:meeting:send-sms']" type="info" link @click="openSmsStatus(row)">短信状态</el-button>
|
|
<el-button
|
|
v-if="row.mailSent"
|
|
v-hasPermi="['review:meeting:send-mail']"
|
|
type="info"
|
|
link
|
|
@click="openMailStatus(row)"
|
|
>
|
|
邮件状态
|
|
</el-button>
|
|
<el-button
|
|
v-else
|
|
v-hasPermi="['review:meeting:send-mail']"
|
|
type="primary"
|
|
link
|
|
@click="handleSendMail(row)"
|
|
>
|
|
发送议程
|
|
</el-button>
|
|
<el-button v-hasPermi="['review:meeting:finish']" type="warning" link @click="handleFinish(row)">结束</el-button>
|
|
<el-button v-hasPermi="['review:meeting:cancel']" type="danger" link @click="handleCancel(row)">取消</el-button>
|
|
</template>
|
|
<!-- 终态(已结束/已取消) -->
|
|
<template v-else>
|
|
<el-button type="info" link @click="goToEdit(row.id, 'view')">查看</el-button>
|
|
<el-button type="primary" link @click="goToProjectList(row)">项目列表</el-button>
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
|
|
<!-- 分页 -->
|
|
<Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
|
|
|
<!-- 短信状态弹窗 -->
|
|
<SmsStatusDialog ref="smsStatusRef" />
|
|
|
|
<!-- 邮件状态弹窗 -->
|
|
<MailStatusDialog ref="mailStatusRef" />
|
|
</ContentWrap>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, reactive, onMounted } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { ElMessageBox, ElMessage } from 'element-plus'
|
|
import { Plus } from '@element-plus/icons-vue'
|
|
import {
|
|
getReviewMeetingPage,
|
|
cancelReviewMeeting,
|
|
finishReviewMeeting,
|
|
sendSmsInvitation,
|
|
sendMailInvitation,
|
|
type ReviewMeetingRespVO,
|
|
type ReviewMeetingPageReqVO
|
|
} from '@/api/review/meeting'
|
|
import SmsStatusDialog from './SmsStatusDialog.vue'
|
|
import MailStatusDialog from './MailStatusDialog.vue'
|
|
import { formatDate } from '@/utils/formatTime'
|
|
|
|
defineOptions({ name: 'ReviewMeeting' })
|
|
|
|
const router = useRouter()
|
|
const loading = ref(false)
|
|
const list = ref<ReviewMeetingRespVO[]>([])
|
|
const total = ref(0)
|
|
|
|
const MEETING_STATUS_OPTIONS = [
|
|
{ value: 0, label: '待召开' },
|
|
{ value: 1, label: '正在召开' },
|
|
{ value: 2, label: '已结束' },
|
|
{ value: 3, label: '已取消' }
|
|
]
|
|
const STATUS_LABEL: Record<number, string> = { 0: '待召开', 1: '正在召开', 2: '已结束', 3: '已取消' }
|
|
const STATUS_TAG_TYPE: Record<number, string> = { 0: 'warning', 1: 'success', 2: 'info', 3: 'danger' }
|
|
|
|
const queryParams = reactive<ReviewMeetingPageReqVO & { pageNo: number; pageSize: number }>({
|
|
pageNo: 1,
|
|
pageSize: 10,
|
|
name: undefined,
|
|
status: undefined,
|
|
startTime: undefined
|
|
})
|
|
|
|
const queryFormRef = ref()
|
|
const smsStatusRef = ref()
|
|
const mailStatusRef = ref()
|
|
|
|
const getList = async () => {
|
|
loading.value = true
|
|
try {
|
|
const data = await getReviewMeetingPage(queryParams)
|
|
list.value = data.list
|
|
total.value = data.total
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
const handleQuery = () => { queryParams.pageNo = 1; getList() }
|
|
const resetQuery = () => { queryFormRef.value?.resetFields(); handleQuery() }
|
|
|
|
const goToEdit = (id?: number, mode?: string) => {
|
|
router.push({ name: 'ReviewMeetingEdit', params: id ? { id } : {}, query: mode ? { mode } : {} })
|
|
}
|
|
|
|
const goToProjectList = (row: ReviewMeetingRespVO) => {
|
|
router.push({ name: 'ReviewMeetingProject', params: { meetingId: row.id }, query: { meetingName: row.name } })
|
|
}
|
|
|
|
const handleCancel = async (row: ReviewMeetingRespVO) => {
|
|
await ElMessageBox.confirm(`确定要取消会议「${row.name}」吗?`, '提示', { type: 'warning' })
|
|
await cancelReviewMeeting(row.id)
|
|
ElMessage.success('取消成功')
|
|
getList()
|
|
}
|
|
|
|
const handleFinish = async (row: ReviewMeetingRespVO) => {
|
|
await ElMessageBox.confirm(`确定要结束会议「${row.name}」吗?`, '提示', { type: 'warning' })
|
|
await finishReviewMeeting(row.id)
|
|
ElMessage.success('已结束')
|
|
getList()
|
|
}
|
|
|
|
const handleSendSms = async (row: ReviewMeetingRespVO) => {
|
|
await ElMessageBox.confirm(
|
|
`确认向 ${row.expertCount} 位专家发送「${row.name}」会议邀约短信?`,
|
|
'发送确认',
|
|
{ type: 'info', confirmButtonText: '确认发送' }
|
|
)
|
|
await sendSmsInvitation(row.id)
|
|
ElMessage.success('短信发送已触发,请稍后通过"发送状态"查看结果')
|
|
getList()
|
|
}
|
|
|
|
const handleSendMail = async (row: ReviewMeetingRespVO) => {
|
|
await ElMessageBox.confirm(
|
|
`确认向 ${row.expertCount} 位专家发送「${row.name}」邮件邀请函(含议程附件)?`,
|
|
'发送确认',
|
|
{ type: 'info', confirmButtonText: '确认发送' }
|
|
)
|
|
await sendMailInvitation(row.id)
|
|
row.mailSent = true
|
|
ElMessage.success('邮件邀请函发送任务已触发,请点击"邮件状态"查看结果')
|
|
}
|
|
|
|
const openSmsStatus = (row: ReviewMeetingRespVO) => {
|
|
smsStatusRef.value?.open(row.id, row.name)
|
|
}
|
|
|
|
const openMailStatus = (row: ReviewMeetingRespVO) => {
|
|
mailStatusRef.value?.open(row.id, row.name)
|
|
}
|
|
|
|
onMounted(() => getList())
|
|
</script>
|