<template>
|
<div class="app-container">
|
<!-- 页面标题 -->
|
<div class="page-header">
|
<h2>会议发布</h2>
|
</div>
|
<!-- 搜索区域 -->
|
<el-card class="search-card">
|
<el-form :model="searchForm"
|
inline>
|
<el-form-item label="会议主题">
|
<el-input v-model="searchForm.title"
|
placeholder="请输入会议主题"
|
clearable />
|
</el-form-item>
|
<el-form-item label="申请人">
|
<el-input v-model="searchForm.applicant"
|
placeholder="请输入申请人"
|
clearable />
|
</el-form-item>
|
<el-form-item label="发布状态">
|
<el-select style="width: 100px"
|
v-model="searchForm.status"
|
placeholder="请选择发布状态"
|
clearable>
|
<el-option label="待发布"
|
value="0" />
|
<el-option label="已发布"
|
value="1" />
|
</el-select>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary"
|
@click="handleSearch">搜索</el-button>
|
<el-button @click="resetSearch">重置</el-button>
|
</el-form-item>
|
</el-form>
|
</el-card>
|
<!-- 会议发布列表 -->
|
<el-card>
|
<el-table v-loading="loading"
|
:data="approvalList"
|
border>
|
<el-table-column prop="title"
|
label="会议主题"
|
align="center"
|
min-width="200"
|
show-overflow-tooltip />
|
<el-table-column prop="applicant"
|
label="申请人"
|
align="center"
|
width="120" />
|
<el-table-column prop="host"
|
label="主理人"
|
align="center"
|
width="120" />
|
<el-table-column prop="meetingTime"
|
label="会议时间"
|
align="center"
|
width="180">
|
<template #default="scope">
|
{{ formatDateTime(scope.row.meetingTime) }}
|
</template>
|
</el-table-column>
|
<el-table-column prop="location"
|
label="会议地点"
|
align="center"
|
width="150" />
|
<el-table-column prop="participants"
|
label="参会人数"
|
align="center"
|
width="100">
|
<template #default="scope">
|
{{ scope.row.participants.length }}人
|
</template>
|
</el-table-column>
|
<el-table-column prop="status"
|
label="发布状态"
|
align="center"
|
width="120">
|
<template #default="scope">
|
<el-tag :type="getStatusType(scope.row.status)">
|
{{ getStatusText(scope.row.status) }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column label="操作"
|
align="center"
|
width="200"
|
fixed="right">
|
<template #default="scope">
|
<el-button type="primary"
|
link
|
@click="viewDetail(scope.row)">查看</el-button>
|
<el-button v-if="scope.row.status == '0'"
|
type="primary"
|
link
|
@click="handleApproval(scope.row)">
|
发布
|
</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<!-- 分页 -->
|
<pagination v-show="total > 0"
|
:total="total"
|
v-model:page="queryParams.current"
|
v-model:limit="queryParams.size"
|
@pagination="getList" />
|
</el-card>
|
<!-- 会议详情对话框 -->
|
<el-dialog title="会议详情"
|
v-model="detailDialogVisible"
|
width="800px">
|
<div v-if="currentMeeting">
|
<el-descriptions label-width="100px"
|
class="meeting-desc"
|
:column="2"
|
border>
|
<el-descriptions-item label="会议主题"
|
label-class-name="nowrap-label">{{
|
currentMeeting.title
|
}}</el-descriptions-item>
|
<el-descriptions-item label="申请人"
|
label-class-name="nowrap-label">{{
|
currentMeeting.applicant
|
}}</el-descriptions-item>
|
<el-descriptions-item label="主理人"
|
label-class-name="nowrap-label">{{
|
currentMeeting.host
|
}}</el-descriptions-item>
|
<el-descriptions-item label="会议时间"
|
:span="2"
|
label-class-name="nowrap-label">
|
{{ formatDateTime(currentMeeting.meetingTime) }}
|
</el-descriptions-item>
|
<el-descriptions-item label="会议地点"
|
label-class-name="nowrap-label">{{
|
currentMeeting.location
|
}}</el-descriptions-item>
|
<el-descriptions-item label="参会人数"
|
label-class-name="nowrap-label">{{
|
currentMeeting.participants.length
|
}}人</el-descriptions-item>
|
<el-descriptions-item label="发布状态"
|
label-class-name="nowrap-label">
|
<el-tag :type="getStatusType(currentMeeting.status)">
|
{{ getStatusText(currentMeeting.status) }}
|
</el-tag>
|
</el-descriptions-item>
|
<el-descriptions-item label="申请时间"
|
label-class-name="nowrap-label">{{
|
currentMeeting.createTime
|
}}</el-descriptions-item>
|
<el-descriptions-item style="max-height: 400px"
|
label="会议说明"
|
:span="2"
|
label-class-name="nowrap-label">{{ currentMeeting.description }}</el-descriptions-item>
|
</el-descriptions>
|
<div class="content-section mt-20">
|
<h4>参会人员</h4>
|
<div class="participants-list">
|
<el-tag v-for="participant in currentMeeting.participants"
|
:key="participant.id"
|
style="margin-right: 10px; margin-bottom: 10px;">
|
{{ participant.name }}
|
</el-tag>
|
</div>
|
</div>
|
</div>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
<!-- 会议发布对话框 -->
|
<el-dialog title="会议发布"
|
v-model="approvalDialogVisible">
|
<div v-if="currentMeeting">
|
<el-descriptions :column="2"
|
border>
|
<el-descriptions-item label="会议主题">{{ currentMeeting.title }}</el-descriptions-item>
|
<el-descriptions-item label="申请人">{{ currentMeeting.applicant }}</el-descriptions-item>
|
<el-descriptions-item label="主理人">{{ currentMeeting.host }}</el-descriptions-item>
|
<el-descriptions-item label="会议时间"
|
:span="2">
|
{{ formatDateTime(currentMeeting.meetingTime) }}
|
</el-descriptions-item>
|
<el-descriptions-item label="会议地点">{{ currentMeeting.location }}</el-descriptions-item>
|
<el-descriptions-item label="参会人数">{{ currentMeeting.participants.length }}人</el-descriptions-item>
|
</el-descriptions>
|
<div class="content-section mt-20">
|
<h4>参会人员</h4>
|
<div class="participants-list">
|
<el-tag v-for="participant in currentMeeting.participants"
|
:key="participant.id"
|
style="margin-right: 10px; margin-bottom: 10px;">
|
{{ participant.name }}
|
</el-tag>
|
</div>
|
</div>
|
<div class="approval-opinion mt-20">
|
<h4>发布意见</h4>
|
<el-input v-model="publishComment"
|
type="textarea"
|
placeholder="请输入发布意见"
|
:rows="4" />
|
</div>
|
</div>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button type="primary"
|
@click="submitApproval('1')">发 布</el-button>
|
<el-button @click="approvalDialogVisible = false">取 消</el-button>
|
<!-- <el-button type="danger" @click="submitApproval('2')">不通过</el-button>-->
|
</div>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted } from "vue";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
import Pagination from "@/components/Pagination/index.vue";
|
import {
|
getRoomEnum,
|
getMeetingPublish,
|
saveMeetingApplication,
|
} from "@/api/collaborativeApproval/meeting.js";
|
import { getStaffOnJob } from "@/api/personnelManagement/onboarding.js";
|
import dayjs from "dayjs";
|
|
// 数据列表加载状态
|
const loading = ref(false);
|
|
// 总条数
|
const total = ref(0);
|
const roomEnum = ref([]);
|
const staffList = ref([]);
|
// 发布列表数据
|
const approvalList = ref([]);
|
|
// 查询参数
|
const queryParams = reactive({
|
current: 1,
|
size: 10,
|
});
|
|
// 搜索表单
|
const searchForm = reactive({
|
title: "",
|
applicant: "",
|
status: "",
|
});
|
|
// 是否显示对话框
|
const detailDialogVisible = ref(false);
|
const approvalDialogVisible = ref(false);
|
|
// 当前查看的会议
|
const currentMeeting = ref(null);
|
|
// 发布意见
|
const publishComment = ref("");
|
|
// 查询数据
|
const getList = async () => {
|
loading.value = true;
|
let resp = await getMeetingPublish({ ...searchForm, ...queryParams });
|
approvalList.value = resp.data.records.map(it => {
|
let room = roomEnum.value.find(room => it.roomId === room.id);
|
it.location = `${room.name}(${room.location})`;
|
let staffs = JSON.parse(it.participants);
|
it.staffCount = staffs.size;
|
it.status = it.publishStatus;
|
it.meetingTime = `${it.meetingDate} ${dayjs(it.startTime).format(
|
"HH:mm:ss"
|
)} ~ ${dayjs(it.endTime).format("HH:mm:ss")}`;
|
it.participants = staffList.value
|
.filter(staff => staffs.some(id => id === staff.id))
|
.map(staff => {
|
return {
|
id: staff.id,
|
name: `${staff.staffName}(${staff.postJob})`,
|
};
|
});
|
|
return it;
|
});
|
total.value = resp.data.total;
|
loading.value = false;
|
};
|
|
// 搜索按钮操作
|
const handleSearch = () => {
|
queryParams.pageNum = 1;
|
getList();
|
};
|
|
// 重置搜索表单
|
const resetSearch = () => {
|
Object.assign(searchForm, {
|
title: "",
|
applicant: "",
|
status: "",
|
});
|
handleSearch();
|
};
|
|
// 查看详情
|
const viewDetail = row => {
|
currentMeeting.value = row;
|
detailDialogVisible.value = true;
|
};
|
|
// 处理发布
|
const handleApproval = row => {
|
currentMeeting.value = row;
|
publishComment.value = "";
|
approvalDialogVisible.value = true;
|
};
|
|
// 获取状态类型
|
const getStatusType = status => {
|
const statusMap = {
|
0: "info", // 待发布
|
1: "success", // 已通过
|
2: "danger", // 未通过
|
};
|
return statusMap[status] || "info";
|
};
|
|
// 获取状态文本
|
const getStatusText = status => {
|
const statusMap = {
|
0: "待发布",
|
1: "已发布",
|
2: "已取消",
|
};
|
return statusMap[status] || "未知";
|
};
|
|
// 格式化日期时间
|
const formatDateTime = dateTime => {
|
if (!dateTime) return "";
|
return dateTime.replace(" ", "\n");
|
};
|
|
// 提交发布
|
const submitApproval = status => {
|
// if (status === 'approved' && !publishComment.value.trim()) {
|
// ElMessage.warning('请填写发布意见')
|
// return
|
// }
|
|
ElMessageBox.confirm(
|
`确认${status === "1" ? "发布" : "取消"}该会议?`,
|
"发布确认",
|
{
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
}
|
)
|
.then(() => {
|
saveMeetingApplication({
|
id: currentMeeting.value.id,
|
publishStatus: status,
|
publishComment: publishComment.value,
|
}).then(resp => {
|
// 更新会议状态
|
currentMeeting.value.status = status;
|
|
ElMessage.success("发布提交成功");
|
approvalDialogVisible.value = false;
|
getList();
|
});
|
})
|
.catch(() => {});
|
};
|
|
// 页面加载时获取数据
|
onMounted(async () => {
|
const [resp1, resp2] = await Promise.all([getRoomEnum(), getStaffOnJob()]);
|
roomEnum.value = resp1.data;
|
staffList.value = resp2.data;
|
|
await getList();
|
});
|
</script>
|
|
<style scoped>
|
.app-container {
|
padding: 20px;
|
}
|
|
.page-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20px;
|
}
|
|
.page-header h2 {
|
margin: 0;
|
color: #303133;
|
}
|
|
.search-card {
|
margin-bottom: 20px;
|
}
|
|
.dialog-footer {
|
display: flex;
|
justify-content: flex-end;
|
gap: 10px;
|
}
|
|
.content-section h4 {
|
margin: 0 0 15px 0;
|
color: #303133;
|
}
|
|
.mt-20 {
|
margin-top: 20px;
|
}
|
|
.participants-list {
|
min-height: 40px;
|
padding: 15px;
|
border-radius: 4px;
|
line-height: 1.6;
|
}
|
|
.approval-opinion h4 {
|
margin: 0 0 15px 0;
|
color: #303133;
|
}
|
|
.nowrap-label {
|
white-space: nowrap !important;
|
}
|
|
.description-content {
|
white-space: pre-wrap;
|
word-wrap: break-word;
|
line-height: 1.6;
|
padding: 10px;
|
background-color: #f5f7fa;
|
border-radius: 4px;
|
min-height: 60px;
|
}
|
</style>
|