gaoluyang
6 天以前 71a9eef518f2f2f1a1eb2fb90f2eb8ab7b155bc8
src/views/collaborativeApproval/notificationManagement/meetPublish/index.vue
@@ -4,184 +4,216 @@
    <div class="page-header">
      <h2>会议发布</h2>
    </div>
    <!-- 搜索区域 -->
    <el-card class="search-card">
      <el-form :model="searchForm" inline>
      <el-form :model="searchForm"
               inline>
        <el-form-item label="会议主题">
          <el-input v-model="searchForm.title" placeholder="请输入会议主题" clearable/>
          <el-input v-model="searchForm.title"
                    placeholder="请输入会议主题"
                    clearable />
        </el-form-item>
        <el-form-item label="申请人">
          <el-input v-model="searchForm.applicant" placeholder="请输入申请人" clearable/>
          <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 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 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">
      <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">
        <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">
        <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">
        <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 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"
      />
      <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"
    >
    <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">{{
        <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">{{
          <el-descriptions-item label="申请人"
                                label-class-name="nowrap-label">{{
              currentMeeting.applicant
            }}</el-descriptions-item>
          <el-descriptions-item label="主理人" label-class-name="nowrap-label">{{
          <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">
          <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">{{
          <el-descriptions-item label="会议地点"
                                label-class-name="nowrap-label">{{
              currentMeeting.location
            }}</el-descriptions-item>
          <el-descriptions-item label="参会人数" label-class-name="nowrap-label">{{
          <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-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">{{
          <el-descriptions-item label="申请时间"
                                label-class-name="nowrap-label">{{
              currentMeeting.createTime
            }}</el-descriptions-item>
          <el-descriptions-item style="max-height: 400px" label="会议说明" :span="2"
          <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;"
            >
            <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"
    >
    <el-dialog title="会议发布"
               v-model="approvalDialogVisible">
      <div v-if="currentMeeting">
        <el-descriptions :column="2" border>
        <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">
          <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;"
            >
            <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"
          />
          <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>-->
          <el-button type="primary" @click="submitApproval('1')">发 布</el-button>
          <!--          <el-button type="danger" @click="submitApproval('2')">不通过</el-button>-->
        </div>
      </template>
    </el-dialog>
@@ -189,228 +221,235 @@
</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";
  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 loading = ref(false);
// 总条数
const total = ref(0)
const roomEnum = ref([])
const staffList = ref([])
// 发布列表数据
const approvalList = ref([])
  // 总条数
  const total = ref(0);
  const roomEnum = ref([]);
  const staffList = ref([]);
  // 发布列表数据
  const approvalList = ref([]);
// 查询参数
const queryParams = reactive({
  current: 1,
  size: 10
})
  // 查询参数
  const queryParams = reactive({
    current: 1,
    size: 10,
  });
// 搜索表单
const searchForm = reactive({
  title: '',
  applicant: '',
  status: ''
})
  // 搜索表单
  const searchForm = reactive({
    title: "",
    applicant: "",
    status: "",
  });
// 是否显示对话框
const detailDialogVisible = ref(false)
const approvalDialogVisible = ref(false)
  // 是否显示对话框
  const detailDialogVisible = ref(false);
  const approvalDialogVisible = ref(false);
// 当前查看的会议
const currentMeeting = ref(null)
  // 当前查看的会议
  const currentMeeting = ref(null);
// 发布意见
const publishComment = ref('')
  // 发布意见
  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})`
      }
    })
  // 查询数据
  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;
  };
    return it
  })
  total.value = resp.data.total
  loading.value = false
}
  // 搜索按钮操作
  const handleSearch = () => {
    queryParams.pageNum = 1;
    getList();
  };
// 搜索按钮操作
const handleSearch = () => {
  queryParams.pageNum = 1
  getList()
}
  // 重置搜索表单
  const resetSearch = () => {
    Object.assign(searchForm, {
      title: "",
      applicant: "",
      status: "",
    });
    handleSearch();
  };
// 重置搜索表单
const resetSearch = () => {
  Object.assign(searchForm, {
    title: '',
    applicant: '',
    status: ''
  })
  handleSearch()
}
  // 查看详情
  const viewDetail = row => {
    currentMeeting.value = row;
    detailDialogVisible.value = true;
  };
// 查看详情
const viewDetail = (row) => {
  currentMeeting.value = row
  detailDialogVisible.value = true
}
  // 处理发布
  const handleApproval = row => {
    currentMeeting.value = row;
    publishComment.value = "";
    approvalDialogVisible.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 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 getStatusText = (status) => {
  const statusMap = {
    '0': '待发布',
    '1': '已发布',
    '2': '已取消',
  }
  return statusMap[status] || '未知'
}
  // 格式化日期时间
  const formatDateTime = dateTime => {
    if (!dateTime) return "";
    return dateTime.replace(" ", "\n");
  };
// 格式化日期时间
const formatDateTime = (dateTime) => {
  if (!dateTime) return ''
  return dateTime.replace(' ', '\n')
}
  // 提交发布
  const submitApproval = status => {
    // if (status === 'approved' && !publishComment.value.trim()) {
    //   ElMessage.warning('请填写发布意见')
    //   return
    // }
// 提交发布
const submitApproval = (status) => {
  // if (status === 'approved' && !publishComment.value.trim()) {
  //   ElMessage.warning('请填写发布意见')
  //   return
  // }
  ElMessageBox.confirm(
      `确认${status === '1' ? '发布' : '取消'}该会议?`,
      '发布确认',
    ElMessageBox.confirm(
      `确认${status === "1" ? "发布" : "取消"}该会议?`,
      "发布确认",
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }
  ).then(() => {
    saveMeetingApplication({
      id: currentMeeting.value.id,
      publishStatus: status,
      publishComment: publishComment.value
    }).then(resp=>{
      // 更新会议状态
      currentMeeting.value.status = status
    )
      .then(() => {
        saveMeetingApplication({
          id: currentMeeting.value.id,
          publishStatus: status,
          publishComment: publishComment.value,
        }).then(resp => {
          // 更新会议状态
          currentMeeting.value.status = status;
      ElMessage.success('发布提交成功')
      approvalDialogVisible.value = false
      getList()
    })
          ElMessage.success("发布提交成功");
          approvalDialogVisible.value = false;
          getList();
        });
      })
      .catch(() => {});
  };
  }).catch(() => {
  })
}
  // 页面加载时获取数据
  onMounted(async () => {
    const [resp1, resp2] = await Promise.all([getRoomEnum(), getStaffOnJob()]);
    roomEnum.value = resp1.data;
    staffList.value = resp2.data;
// 页面加载时获取数据
onMounted(async () => {
  const [resp1, resp2]= await Promise.all([getRoomEnum(), getStaffOnJob()])
  roomEnum.value = resp1.data
  staffList.value = resp2.data
  await getList()
})
    await getList();
  });
</script>
<style scoped>
.app-container {
  padding: 20px;
}
  .app-container {
    padding: 20px;
  }
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}
  .page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
  }
.page-header h2 {
  margin: 0;
  color: #303133;
}
  .page-header h2 {
    margin: 0;
    color: #303133;
  }
.search-card {
  margin-bottom: 20px;
}
  .search-card {
    margin-bottom: 20px;
  }
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
  .dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
  }
.content-section h4 {
  margin: 0 0 15px 0;
  color: #303133;
}
  .content-section h4 {
    margin: 0 0 15px 0;
    color: #303133;
  }
.mt-20 {
  margin-top: 20px;
}
  .mt-20 {
    margin-top: 20px;
  }
.participants-list {
  min-height: 40px;
  padding: 15px;
  border-radius: 4px;
  line-height: 1.6;
}
  .participants-list {
    min-height: 40px;
    padding: 15px;
    border-radius: 4px;
    line-height: 1.6;
  }
.approval-opinion h4 {
  margin: 0 0 15px 0;
  color: #303133;
}
  .approval-opinion h4 {
    margin: 0 0 15px 0;
    color: #303133;
  }
.nowrap-label {
  white-space: nowrap !important;
}
  .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;
}
  .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>