张诺
6 天以前 c8b65690b946b28b179796fbe2f020e732043c58
src/views/collaborativeApproval/notificationManagement/summary/index.vue
@@ -4,157 +4,185 @@
    <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>
          <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="meetingList" 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="meetingList"
                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 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
              type="primary"
            <el-button type="primary"
              link
              @click="addMinutes(scope.row)"
            >
                       @click="viewDetail(scope.row)">查看</el-button>
            <el-button type="primary"
                       link
                       @click="addMinutes(scope.row)">
              添加纪要
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
      <pagination
        v-show="total > 0"
      <pagination v-show="total > 0"
        :total="total"
        v-model:page="queryParams.current"
        v-model:limit="queryParams.size"
        @pagination="getList"
      />
                  @pagination="getList" />
    </el-card>
    <!-- 会议详情对话框 -->
    <el-dialog
      title="会议详情"
    <el-dialog title="会议详情"
      v-model="detailDialogVisible"
      width="800px"
    >
               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"
            <el-tag v-for="participant in currentMeeting.participants"
              :key="participant.id"
              style="margin-right: 10px; margin-bottom: 10px;"
            >
                    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="添加会议纪要"
    <el-dialog title="添加会议纪要"
      v-model="minutesDialogVisible"
      width="80%"
      @close="handleCloseMinutesDialog"
    >
               @close="handleCloseMinutesDialog">
      <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="editor-container">
            <Editor
              v-model="minutesContent"
              :min-height="400"
            />
            <Editor v-model="minutesContent"
                    :min-height="400" />
          </div>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary"
                     @click="submitMinutes">保 存</el-button>
          <el-button @click="minutesDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="submitMinutes">保 存</el-button>
        </div>
      </template>
    </el-dialog>
@@ -162,101 +190,110 @@
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import Pagination from '@/components/Pagination/index.vue'
import Editor from '@/components/Editor/index.vue'
import { getRoomEnum, getMeetingPublish ,getMeetingMinutesByMeetingId,saveMeetingMinutes} from '@/api/collaborativeApproval/meeting.js'
import { getStaffOnJob } from "@/api/personnelManagement/onboarding.js"
import dayjs from "dayjs"
  import { ref, reactive, onMounted } from "vue";
  import { ElMessage } from "element-plus";
  import Pagination from "@/components/Pagination/index.vue";
  import Editor from "@/components/Editor/index.vue";
  import {
    getRoomEnum,
    getMeetingPublish,
    getMeetingMinutesByMeetingId,
    saveMeetingMinutes,
  } 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 total = ref(0);
  const roomEnum = ref([]);
  const staffList = ref([]);
// 会议列表数据
const meetingList = ref([])
  const meetingList = ref([]);
// 查询参数
const queryParams = reactive({
  current: 1,
  size: 10
})
    size: 10,
  });
// 搜索表单
const searchForm = reactive({
  title: '',
  applicant: '',
    title: "",
    applicant: "",
  // status: '1' // 默认只显示已通过审批的会议
})
  });
// 是否显示对话框
const detailDialogVisible = ref(false)
const minutesDialogVisible = ref(false)
  const detailDialogVisible = ref(false);
  const minutesDialogVisible = ref(false);
// 当前查看的会议
const currentMeeting = ref(null)
  const currentMeeting = ref(null);
// 会议纪要内容
const minutesContent = ref('')
const minutesContentId = ref('')
  const minutesContent = ref("");
  const minutesContentId = ref("");
// 查询数据
const getList = async () => {
  loading.value = true
  let resp = await getMeetingPublish({ ...searchForm, ...queryParams })
    loading.value = true;
    let resp = await getMeetingPublish({ ...searchForm, ...queryParams });
  meetingList.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.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 => {
      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.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})`
      }
    })
            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.current = 1
  getList()
}
    queryParams.current = 1;
    getList();
  };
// 重置搜索表单
const resetSearch = () => {
  Object.assign(searchForm, {
    title: '',
    applicant: '',
      title: "",
      applicant: "",
    // status: '1'
  })
  handleSearch()
}
    });
    handleSearch();
  };
// 查看详情
const viewDetail = (row) => {
  currentMeeting.value = row
  detailDialogVisible.value = true
}
  const viewDetail = row => {
    currentMeeting.value = row;
    detailDialogVisible.value = true;
  };
// 添加会议纪要
const addMinutes = async (row) => {
  let resp = await getMeetingMinutesByMeetingId(row.id)
  currentMeeting.value = row
  const addMinutes = async row => {
    let resp = await getMeetingMinutesByMeetingId(row.id);
    currentMeeting.value = row;
  if (resp.data){
    minutesContent.value = resp.data.content
    minutesContentId.value = resp.data.id
      minutesContent.value = resp.data.content;
      minutesContentId.value = resp.data.id;
  }else {
    minutesContent.value = `<h2>${row.title}会议纪要</h2>
<p><strong>会议时间:</strong>${row.meetingTime}</p>
@@ -264,7 +301,7 @@
<p><strong>主持人:</strong>${row.host}</p>
<p><strong>参会人员:</strong></p>
<ol>
  ${row.participants.map(p => `<li>${p.name}</li>`).join('')}
    ${row.participants.map(p => `<li>${p.name}</li>`).join("")}
</ol>
<p><strong>会议内容:</strong></p>
<ol>
@@ -281,72 +318,71 @@
    </ul>
  </li>
</ol>
<p><strong>备注:</strong></p>`
  <p><strong>备注:</strong></p>`;
  }
  minutesDialogVisible.value = true
}
    minutesDialogVisible.value = true;
  };
// 提交会议纪要
const submitMinutes = () => {
  if (!minutesContent.value) {
    ElMessage.warning('请输入会议纪要内容')
    return
      ElMessage.warning("请输入会议纪要内容");
      return;
  }
  saveMeetingMinutes({
    id: minutesContentId.value,
    content: minutesContent.value,
    meetingId: currentMeeting.value.id,
    title: currentMeeting.value.title
      title: currentMeeting.value.title,
  }).then(resp=>{
    console.log('会议纪要内容:', minutesContent.value)
    ElMessage.success('会议纪要保存成功')
    minutesDialogVisible.value = false
  })
}
      console.log("会议纪要内容:", minutesContent.value);
      ElMessage.success("会议纪要保存成功");
      minutesDialogVisible.value = false;
    });
  };
// 关闭会议纪要对话框
const handleCloseMinutesDialog = () => {
  minutesContent.value = ''
}
    minutesContent.value = "";
  };
// 获取状态类型
const getStatusType = (status) => {
  const getStatusType = status => {
  const statusMap = {
    '0': 'info',     // 待审批
    '1': 'success',  // 已通过
    '2': 'warning',  // 未通过
    '3': 'danger'   // 取消
  }
  return statusMap[status] || 'info'
}
      0: "info", // 待审批
      1: "success", // 已通过
      2: "warning", // 未通过
      3: "danger", // 取消
    };
    return statusMap[status] || "info";
  };
// 获取状态文本
const getStatusText = (status) => {
  const getStatusText = status => {
  const statusMap = {
    '0': '待审批',
    '1': '已通过',
    '2': '未通过',
    '3': '已取消'
  }
  return statusMap[status] || '未知'
}
      0: "待审批",
      1: "已通过",
      2: "未通过",
      3: "已取消",
    };
    return statusMap[status] || "未知";
  };
// 格式化日期时间
const formatDateTime = (dateTime) => {
  if (!dateTime) return ''
  return dateTime.replace(' ', '\n')
}
  const formatDateTime = dateTime => {
    if (!dateTime) return "";
    return dateTime.replace(" ", "\n");
  };
// 页面加载时获取数据
onMounted(async () => {
  const [resp1, resp2] = await Promise.all([getRoomEnum(), getStaffOnJob()])
  roomEnum.value = resp1.data
  staffList.value = resp2.data
    const [resp1, resp2] = await Promise.all([getRoomEnum(), getStaffOnJob()]);
    roomEnum.value = resp1.data;
    staffList.value = resp2.data;
  await getList()
})
    await getList();
  });
</script>
<style scoped>