张诺
6 天以前 c8b65690b946b28b179796fbe2f020e732043c58
src/views/collaborativeApproval/notificationManagement/index.vue
@@ -3,300 +3,314 @@
    <div class="search_form">
      <div>
        <span class="search_title">通知标题:</span>
        <el-input
          v-model="searchForm.title"
          style="width: 240px"
          placeholder="请输入通知标题搜索"
          @change="handleQuery"
          clearable
          :prefix-icon="Search"
        />
        <el-input v-model="searchForm.title"
                  style="width: 240px"
                  placeholder="请输入通知标题搜索"
                  @change="handleQuery"
                  clearable
                  :prefix-icon="Search" />
        <span class="search_title ml10">通知类型:</span>
        <el-select v-model="searchForm.type" clearable @change="handleQuery" style="width: 240px">
          <el-option label="放假通知" :value="'holiday'" />
          <el-option label="处罚通知" :value="'penalty'" />
          <el-option label="开会通知" :value="'meeting'" />
          <el-option label="临时通知" :value="'temporary'" />
          <el-option label="正式通知" :value="'formal'" />
        <el-select v-model="searchForm.type"
                   clearable
                   @change="handleQuery"
                   style="width: 240px">
          <el-option label="放假通知"
                     :value="'holiday'" />
          <el-option label="处罚通知"
                     :value="'penalty'" />
          <el-option label="开会通知"
                     :value="'meeting'" />
          <el-option label="临时通知"
                     :value="'temporary'" />
          <el-option label="正式通知"
                     :value="'formal'" />
        </el-select>
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">
        <el-button type="primary"
                   @click="handleQuery"
                   style="margin-left: 10px">
          搜索
        </el-button>
      </div>
      <div>
        <el-button type="primary" @click="openForm('add')">新增通知</el-button>
        <el-button type="success" @click="openMeetingDialog">在线会议</el-button>
        <el-button type="warning" @click="openFileShareDialog">文件共享</el-button>
        <el-button type="primary"
                   @click="openForm('add')">新增通知</el-button>
        <el-button type="success"
                   @click="openMeetingDialog">在线会议</el-button>
        <el-button type="warning"
                   @click="openFileShareDialog">文件共享</el-button>
        <!-- <el-button type="info" @click="refreshEmployees">刷新员工</el-button> -->
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
        <el-button type="danger"
                   plain
                   @click="handleDelete">删除</el-button>
      </div>
    </div>
    <div class="table_list">
      <PIMTable
        rowKey="id"
        :column="tableColumn"
        :tableData="tableData"
        :page="page"
        :isSelection="true"
        @selection-change="handleSelectionChange"
        :tableLoading="tableLoading"
        @pagination="pagination"
        :total="page.total"
      ></PIMTable>
      <PIMTable rowKey="id"
                :column="tableColumn"
                :tableData="tableData"
                :page="page"
                :isSelection="true"
                @selection-change="handleSelectionChange"
                :tableLoading="tableLoading"
                @pagination="pagination"
                :total="page.total"></PIMTable>
    </div>
    <!-- 新增/编辑通知弹窗 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="800px"
      :close-on-click-modal="false"
    >
      <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
    <el-dialog v-model="dialogVisible"
               :title="dialogTitle"
               width="800px"
               :close-on-click-modal="false">
      <el-form ref="formRef"
               :model="form"
               :rules="rules"
               label-width="120px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="通知标题" prop="title">
              <el-input v-model="form.title" placeholder="请输入通知标题" />
            <el-form-item label="通知标题"
                          prop="title">
              <el-input v-model="form.title"
                        placeholder="请输入通知标题" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="通知类型" prop="type">
              <el-select v-model="form.type" placeholder="请选择通知类型" style="width: 100%">
                <el-option label="放假通知" value="holiday" />
                <el-option label="处罚通知" value="penalty" />
                <el-option label="开会通知" value="meeting" />
                <el-option label="临时通知" value="temporary" />
                <el-option label="正式通知" value="formal" />
            <el-form-item label="通知类型"
                          prop="type">
              <el-select v-model="form.type"
                         placeholder="请选择通知类型"
                         style="width: 100%">
                <el-option label="放假通知"
                           value="holiday" />
                <el-option label="处罚通知"
                           value="penalty" />
                <el-option label="开会通知"
                           value="meeting" />
                <el-option label="临时通知"
                           value="temporary" />
                <el-option label="正式通知"
                           value="formal" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="优先级" prop="priority">
              <el-select v-model="form.priority" placeholder="请选择优先级" style="width: 100%">
                <el-option label="普通" value="low" />
                <el-option label="重要" value="medium" />
                <el-option label="紧急" value="high" />
            <el-form-item label="优先级"
                          prop="priority">
              <el-select v-model="form.priority"
                         placeholder="请选择优先级"
                         style="width: 100%">
                <el-option label="普通"
                           value="low" />
                <el-option label="重要"
                           value="medium" />
                <el-option label="紧急"
                           value="high" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="有效期至" prop="expireDate">
              <el-date-picker
                v-model="form.expireDate"
                type="date"
                placeholder="请选择有效期"
                value-format="YYYY-MM-DD"
                format="YYYY-MM-DD"
                style="width: 100%"
              />
            <el-form-item label="有效期至"
                          prop="expireDate">
              <el-date-picker v-model="form.expireDate"
                              type="date"
                              placeholder="请选择有效期"
                              value-format="YYYY-MM-DD"
                              format="YYYY-MM-DD"
                              style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="接收部门" prop="departments">
          <el-select
            v-model="form.departments"
            multiple
            placeholder="请选择接收部门"
            style="width: 100%"
          >
            <el-option
              v-for="dept in departments"
              :key="dept"
              :label="dept"
              :value="dept"
            />
        <el-form-item label="接收部门"
                      prop="departments">
          <el-select v-model="form.departments"
                     multiple
                     placeholder="请选择接收部门"
                     style="width: 100%">
            <el-option v-for="dept in departments"
                       :key="dept"
                       :label="dept"
                       :value="dept" />
          </el-select>
        </el-form-item>
        <el-form-item label="同步方式" prop="syncMethods">
        <el-form-item label="同步方式"
                      prop="syncMethods">
          <el-checkbox-group v-model="form.syncMethods">
            <el-checkbox
              v-for="method in syncMethods"
              :key="method.value"
              :label="method.value"
            >
            <el-checkbox v-for="method in syncMethods"
                         :key="method.value"
                         :label="method.value">
              {{ method.label }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="通知内容" prop="content">
          <el-input
            v-model="form.content"
            type="textarea"
            :rows="4"
            placeholder="请输入通知内容"
          />
        <el-form-item label="通知内容"
                      prop="content">
          <el-input v-model="form.content"
                    type="textarea"
                    :rows="4"
                    placeholder="请输入通知内容" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary"
                     @click="submitForm">确定</el-button>
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitForm">确定</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 在线会议弹窗 -->
    <el-dialog
      v-model="meetingDialogVisible"
      title="创建在线会议"
      width="700px"
      :close-on-click-modal="false"
    >
      <el-form ref="meetingFormRef" :model="meetingForm" :rules="meetingRules" label-width="120px">
        <el-form-item label="会议标题" prop="title">
          <el-input v-model="meetingForm.title" placeholder="请输入会议标题" />
    <el-dialog v-model="meetingDialogVisible"
               title="创建在线会议"
               width="700px"
               :close-on-click-modal="false">
      <el-form ref="meetingFormRef"
               :model="meetingForm"
               :rules="meetingRules"
               label-width="120px">
        <el-form-item label="会议标题"
                      prop="title">
          <el-input v-model="meetingForm.title"
                    placeholder="请输入会议标题" />
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="开始时间" prop="startTime">
              <el-date-picker
                v-model="meetingForm.startTime"
                type="datetime"
                value-format="YYYY-MM-DD HH:mm:ss"
                format="YYYY-MM-DD HH:mm:ss"
                placeholder="请选择开始时间"
                style="width: 100%"
              />
            <el-form-item label="开始时间"
                          prop="startTime">
              <el-date-picker v-model="meetingForm.startTime"
                              type="datetime"
                              value-format="YYYY-MM-DD HH:mm:ss"
                              format="YYYY-MM-DD HH:mm:ss"
                              placeholder="请选择开始时间"
                              style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="会议时长" prop="duration">
              <el-input-number
                v-model="meetingForm.duration"
                :min="15"
                :max="480"
                :step="15"
                style="width: 100%"
              />
            <el-form-item label="会议时长"
                          prop="duration">
              <el-input-number v-model="meetingForm.duration"
                               :min="15"
                               :max="480"
                               :step="15"
                               style="width: 100%" />
              <span style="margin-left: 10px">分钟</span>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="会议平台" prop="platform">
          <el-select v-model="meetingForm.platform" placeholder="请选择会议平台" style="width: 100%">
            <el-option
              v-for="platform in meetingPlatforms"
              :key="platform.value"
              :label="platform.label"
              :value="platform.value"
            />
        <el-form-item label="会议平台"
                      prop="platform">
          <el-select v-model="meetingForm.platform"
                     placeholder="请选择会议平台"
                     style="width: 100%">
            <el-option v-for="platform in meetingPlatforms"
                       :key="platform.value"
                       :label="platform.label"
                       :value="platform.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="参会人员" prop="participants">
          <el-select
            v-model="meetingForm.participants"
            multiple
            filterable
            remote
            :remote-method="filterEmployees"
            :loading="employeesLoading"
            placeholder="请选择参会人员"
            style="width: 100%"
          >
            <el-option-group
              v-for="group in employeeGroups"
              :key="group.label"
              :label="group.label"
            >
                             <el-option
                 v-for="employee in group.options"
                 :key="employee.value"
                 :label="`${employee.label} (${employee.dept})`"
                 :value="employee.value"
               >
                 <div style="display: flex; justify-content: space-between; align-items: center;">
                   <div>
                     <div style="font-weight: 500;">{{ employee.label }}</div>
                     <div style="color: #909399; font-size: 12px;">{{ employee.dept }}</div>
                   </div>
                   <div style="text-align: right; font-size: 12px; color: #909399;">
                     <div v-if="employee.phone">{{ employee.phone }}</div>
                     <div v-if="employee.email">{{ employee.email }}</div>
                   </div>
                 </div>
               </el-option>
        <el-form-item label="参会人员"
                      prop="participants">
          <el-select v-model="meetingForm.participants"
                     multiple
                     filterable
                     remote
                     :remote-method="filterEmployees"
                     :loading="employeesLoading"
                     placeholder="请选择参会人员"
                     style="width: 100%">
            <el-option-group v-for="group in employeeGroups"
                             :key="group.label"
                             :label="group.label">
              <el-option v-for="employee in group.options"
                         :key="employee.value"
                         :label="`${employee.label} (${employee.dept})`"
                         :value="employee.value">
                <div style="display: flex; justify-content: space-between; align-items: center;">
                  <div>
                    <div style="font-weight: 500;">{{ employee.label }}</div>
                    <div style="color: #909399; font-size: 12px;">{{ employee.dept }}</div>
                  </div>
                  <div style="text-align: right; font-size: 12px; color: #909399;">
                    <div v-if="employee.phone">{{ employee.phone }}</div>
                    <div v-if="employee.email">{{ employee.email }}</div>
                  </div>
                </div>
              </el-option>
            </el-option-group>
          </el-select>
          <div style="margin-top: 8px; color: #909399; font-size: 12px;">
            已选择 {{ meetingForm.participants.length }} 人
          </div>
          <!-- 已选择人员详情 -->
          <div v-if="meetingForm.participants.length > 0" style="margin-top: 10px;">
            <el-tag
              v-for="participantId in meetingForm.participants"
              :key="participantId"
              closable
              @close="removeParticipant(participantId)"
              style="margin-right: 8px; margin-bottom: 8px;"
            >
          <div v-if="meetingForm.participants.length > 0"
               style="margin-top: 10px;">
            <el-tag v-for="participantId in meetingForm.participants"
                    :key="participantId"
                    closable
                    @close="removeParticipant(participantId)"
                    style="margin-right: 8px; margin-bottom: 8px;">
              {{ getEmployeeName(participantId) }}
            </el-tag>
          </div>
        </el-form-item>
        <el-form-item label="会议描述" prop="description">
          <el-input
            v-model="meetingForm.description"
            type="textarea"
            :rows="3"
            placeholder="请输入会议描述"
          />
        <el-form-item label="会议描述"
                      prop="description">
          <el-input v-model="meetingForm.description"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入会议描述" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary"
                     @click="createMeeting">创建会议</el-button>
          <el-button @click="meetingDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="createMeeting">创建会议</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 文件共享弹窗 -->
    <el-dialog
      v-model="fileShareDialogVisible"
      title="文件共享"
      width="700px"
      :close-on-click-modal="false"
    >
      <el-form ref="fileShareFormRef" :model="fileShareForm" :rules="fileShareRules" label-width="120px">
        <el-form-item label="共享标题" prop="title">
          <el-input v-model="fileShareForm.title" placeholder="请输入共享标题" />
    <el-dialog v-model="fileShareDialogVisible"
               title="文件共享"
               width="700px"
               :close-on-click-modal="false">
      <el-form ref="fileShareFormRef"
               :model="fileShareForm"
               :rules="fileShareRules"
               label-width="120px">
        <el-form-item label="共享标题"
                      prop="title">
          <el-input v-model="fileShareForm.title"
                    placeholder="请输入共享标题" />
        </el-form-item>
        <el-form-item label="共享描述" prop="description">
          <el-input
            v-model="fileShareForm.description"
            type="textarea"
            :rows="3"
            placeholder="请输入共享描述"
          />
        <el-form-item label="共享描述"
                      prop="description">
          <el-input v-model="fileShareForm.description"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入共享描述" />
        </el-form-item>
        <el-form-item label="接收部门" prop="departments">
          <el-select
            v-model="fileShareForm.departments"
            multiple
            placeholder="请选择接收部门"
            style="width: 100%"
          >
            <el-option
              v-for="dept in departments"
              :key="dept"
              :label="dept"
              :value="dept"
            />
        <el-form-item label="接收部门"
                      prop="departments">
          <el-select v-model="fileShareForm.departments"
                     multiple
                     placeholder="请选择接收部门"
                     style="width: 100%">
            <el-option v-for="dept in departments"
                       :key="dept"
                       :label="dept"
                       :value="dept" />
          </el-select>
        </el-form-item>
        <el-form-item label="上传文件" prop="files">
          <el-upload
            ref="uploadRef"
            :auto-upload="false"
            :on-change="handleFileChange"
            :on-remove="removeFile"
            :file-list="fileList"
            multiple
            :limit="10"
            accept=".doc,.docx,.pdf,.xls,.xlsx,.ppt,.pptx,.txt,.jpg,.jpeg,.png,.gif"
          >
        <el-form-item label="上传文件"
                      prop="files">
          <el-upload ref="uploadRef"
                     :auto-upload="false"
                     :on-change="handleFileChange"
                     :on-remove="removeFile"
                     :file-list="fileList"
                     multiple
                     :limit="10"
                     accept=".doc,.docx,.pdf,.xls,.xlsx,.ppt,.pptx,.txt,.jpg,.jpeg,.png,.gif">
            <el-button type="primary">选择文件</el-button>
            <template #tip>
              <div class="el-upload__tip">
@@ -308,8 +322,9 @@
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary"
                     @click="shareFiles">共享文件</el-button>
          <el-button @click="fileShareDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="shareFiles">共享文件</el-button>
        </span>
      </template>
    </el-dialog>
@@ -317,537 +332,872 @@
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
import { onMounted, ref, reactive, toRefs, computed } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import PIMTable from "@/components/PIMTable/PIMTable.vue";
import { userListNoPageByTenantId } from "@/api/system/user.js";
import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
import { listNotification, addNotification, updateNotification, delNotification,addOnlineMeeting,addFileSharing } from "@/api/collaborativeApproval/notificationManagement.js";
import { id } from "element-plus/es/locales.mjs";
  import { Search } from "@element-plus/icons-vue";
  import { onMounted, ref, reactive, toRefs, computed } from "vue";
  import { ElMessage, ElMessageBox } from "element-plus";
  import PIMTable from "@/components/PIMTable/PIMTable.vue";
  import { userListNoPageByTenantId } from "@/api/system/user.js";
  import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
  import {
    listNotification,
    addNotification,
    updateNotification,
    delNotification,
    addOnlineMeeting,
    addFileSharing,
  } from "@/api/collaborativeApproval/notificationManagement.js";
  import { id } from "element-plus/es/locales.mjs";
// 表单验证规则
const rules = {
  title: [
    { required: true, message: "请输入通知标题", trigger: "blur" }
  ],
  type: [
    { required: true, message: "请选择通知类型", trigger: "change" }
  ],
  content: [
    { required: true, message: "请输入通知内容", trigger: "blur" }
  ]
};
const meetingRules = {
  title: [
    { required: true, message: "请输入会议标题", trigger: "blur" }
  ],
  startTime: [
    { required: true, message: "请选择会议开始时间", trigger: "change" }
  ],
  participants: [
    { required: true, message: "请选择参会人员", trigger: "change" }
  ]
};
const fileShareRules = {
  title: [
    { required: true, message: "请输入共享标题", trigger: "blur" }
  ],
  description: [
    { required: true, message: "请输入共享描述", trigger: "blur" }
  ]
};
// 响应式数据
const data = reactive({
  searchForm: {
    title: "",
    type: "",
    status: "",
  },
  tableLoading: false,
  page: {
    current: 1,
    size: 20,
    total: 0,
  },
  tableData: [],
  selectedIds: [],
  // 新增通知相关
  form: {
    title: "",
    type: "",
    priority: "",
    content: "",
    departments: [],
    expireDate: "",
    syncMethods: []
  },
  dialogVisible: false,
  dialogTitle: "",
  dialogType: "add",
  // 在线会议相关
  meetingDialogVisible: false,
  meetingForm: {
    title: "",
    startTime: "",
    duration: 60,
    participants: [],
    description: "",
    platform: "wechat"
  },
  // 文件共享相关
  fileShareDialogVisible: false,
  fileShareForm: {
    title: "",
    description: "",
    departments: [],
    files: []
  },
  fileList: []
});
const {
  searchForm,
  tableLoading,
  page,
  tableData,
  selectedIds,
  form,
  dialogVisible,
  dialogTitle,
  dialogType,
  meetingDialogVisible,
  meetingForm,
  fileShareDialogVisible,
  fileShareForm,
  fileList
} = toRefs(data);
// 表单引用
const formRef = ref();
const meetingFormRef = ref();
const fileShareFormRef = ref();
// 表格列配置
const tableColumn = ref([
  {
    label: "通知标题",
    prop: "title",
    showOverflowTooltip: true,
  },
  {
    label: "通知类型",
    prop: "type",
    dataType: "tag",
    formatData: (params) => {
      const typeMap = {
        holiday: "放假通知",
        penalty: "处罚通知",
        meeting: "开会通知",
        temporary: "临时通知",
        formal: "正式通知"
      };
      return typeMap[params] || params;
    },
    formatType: (params) => {
      const typeMap = {
        holiday: "success",
        penalty: "danger",
        meeting: "warning",
        temporary: "info",
        formal: "primary"
      };
      return typeMap[params] || "info";
    }
  },
  {
    label: "优先级",
    prop: "priority",
    dataType: "tag",
    formatData: (params) => {
      const priorityMap = {
        low: "普通",
        medium: "重要",
        high: "紧急"
      };
      return priorityMap[params] || params;
    },
    formatType: (params) => {
      const typeMap = {
        low: "info",
        medium: "warning",
        high: "danger"
      };
      return typeMap[params] || "info";
    }
  },
  {
    label: "状态",
    prop: "status",
    dataType: "tag",
    formatData: (params) => {
      const statusMap = {
        draft: "草稿",
        published: "已发布",
        expired: "已过期"
      };
      return statusMap[params] || params;
    },
    formatType: (params) => {
      const typeMap = {
        draft: "info",
        published: "success",
        expired: "danger"
      };
      return typeMap[params] || "info";
    }
  },
  {
    label: "接收部门",
    prop: "departments",
    width: 150,
    showOverflowTooltip: true,
    formatData: (params) => {
      if (!params || params.length === 0) return "全部部门";
      return params.join(", ");
    }
  },
  {
    label: "有效期至",
    prop: "expireDate",
    width: 150,
    formatData: (params) => {
      if (!params) return "永久有效";
      return params;
    }
  },
  {
    label: "创建时间",
    prop: "createTime",
    width: 180,
  },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    fixed: "right",
    width: 280,
    operation: [
      {
        name: "编辑",
        type: "text",
        clickFun: (row) => {
          openForm("edit", row);
        }
      },
      {
        name: "发布",
        type: "text",
        clickFun: (row) => {
          publishNotification(row);
        },
      },
      {
        name: "撤回",
        type: "text",
        clickFun: (row) => {
          revokeNotification(row);
        },
      }
    ]
  }
]);
// 通知标题模板
const titleTemplates = [
  "关于{year}年{holiday}放假安排的通知",
  "{dept}部门{meeting}会议通知",
  "员工{behavior}行为规范提醒",
  "{company}重要事项通知",
  "{dept}部门工作安排通知",
  "关于{project}项目进度的通知",
  "{dept}部门人员调整通知",
  "公司{policy}政策更新通知"
];
// 通知类型配置
const notificationTypes = [
  { type: "holiday", label: "放假通知", priority: "high" },
  { type: "meeting", label: "开会通知", priority: "medium" },
  { type: "penalty", label: "处罚通知", priority: "high" },
  { type: "temporary", label: "临时通知", priority: "low" },
  { type: "formal", label: "正式通知", priority: "medium" }
];
// 部门列表
const departments = ["技术部", "销售部", "人事部", "财务部", "运营部", "市场部", "客服部"];
// 人员列表
const employees = ref([]);
const employeesLoading = ref(false);
// 获取在职员工列表
const getEmployeesList = async () => {
  try {
    employeesLoading.value = true;
    // 优先使用系统用户接口(按租户获取)
    const userResponse = await userListNoPageByTenantId();
    if (userResponse.data) {
      employees.value = userResponse.data.map(user => ({
        label: user.nickName || user.userName || '未知姓名',
        value: user.userId || user.id,
        dept: user.dept?.deptName || '未知部门',
        phone: user.phonenumber || '',
        email: user.email || '',
        status: user.status || '0'
      })).filter(user => user.status === '0'); // 只显示正常状态的用户
    } else {
      // 如果系统用户接口失败,使用员工台账接口
      const response = await staffOnJobListPage({
        pageNum: 1,
        pageSize: 1000,
        staffState: 1 // 在职状态
      });
      if (response.data && response.data.records) {
        employees.value = response.data.records.map(employee => ({
          label: employee.staffName || employee.name || '未知姓名',
          value: employee.staffNo || employee.id || employee.staffId,
          dept: employee.deptName || employee.department || '未知部门',
          phone: employee.phone || employee.mobile || '',
          email: employee.email || '',
          status: '0'
        }));
      }
    }
  } catch (error) {
    console.error('获取员工列表失败:', error);
    // 如果接口都失败,使用默认数据
    employees.value = [
      { label: "张三", value: "001", dept: "技术部", phone: "13800138001", email: "zhangsan@company.com", status: "0" },
      { label: "李四", value: "002", dept: "销售部", phone: "13800138002", email: "lisi@company.com", status: "0" },
      { label: "王五", value: "003", dept: "人事部", phone: "13800138003", email: "wangwu@company.com", status: "0" }
    ];
  } finally {
    employeesLoading.value = false;
  }
};
// 员工分组
const employeeGroups = computed(() => {
  const groups = {};
  employees.value.forEach(employee => {
    const dept = employee.dept || '其他部门';
    if (!groups[dept]) {
      groups[dept] = [];
    }
    groups[dept].push(employee);
  });
  // 按部门名称排序,确保显示顺序一致
  return Object.keys(groups)
    .sort()
    .map(dept => ({
      label: dept,
      options: groups[dept].sort((a, b) => a.label.localeCompare(b.label, 'zh-CN'))
    }));
});
// 过滤员工(远程搜索)
const filterEmployees = (query) => {
  if (query !== '') {
    const lowerQuery = query.toLowerCase();
    return employees.value.filter(employee =>
      employee.label.toLowerCase().includes(lowerQuery) ||
      employee.dept.toLowerCase().includes(lowerQuery) ||
      (employee.phone && employee.phone.includes(query)) ||
      (employee.email && employee.email.toLowerCase().includes(lowerQuery))
    );
  } else {
    return employees.value;
  }
};
// 刷新员工列表
const refreshEmployees = async () => {
  ElMessage.info("正在刷新员工列表...");
  await getEmployeesList();
  // 统计各部门人数
  const deptStats = {};
  employees.value.forEach(emp => {
    const dept = emp.dept || '其他部门';
    deptStats[dept] = (deptStats[dept] || 0) + 1;
  });
  const deptInfo = Object.entries(deptStats)
    .map(([dept, count]) => `${dept}: ${count}人`)
    .join(', ');
  ElMessage.success(`员工列表刷新完成,共 ${employees.value.length} 人 (${deptInfo})`);
};
// 获取员工姓名
const getEmployeeName = (employeeId) => {
  const employee = employees.value.find(emp => emp.value === employeeId);
  return employee ? employee.label : '未知人员';
};
// 获取员工详细信息
const getEmployeeInfo = (employeeId) => {
  const employee = employees.value.find(emp => emp.value === employeeId);
  if (!employee) return null;
  return {
    name: employee.label,
    dept: employee.dept,
    phone: employee.phone,
    email: employee.email
  };
};
// 移除参会人员
const removeParticipant = (participantId) => {
  const index = meetingForm.value.participants.indexOf(participantId);
  if (index > -1) {
    meetingForm.value.participants.splice(index, 1);
  }
};
// 同步方式选项
const syncMethods = [
  { label: "企业微信", value: "wechat" },
  { label: "钉钉", value: "dingtalk" },
  { label: "邮件", value: "email" },
  { label: "短信", value: "sms" }
];
// 会议平台选项
const meetingPlatforms = [
  { label: "企业微信会议", value: "wechat" },
  { label: "钉钉会议", value: "dingtalk" },
  { label: "腾讯会议", value: "tencent" },
  { label: "Zoom", value: "zoom" }
];
// 自动生成新数据
const generateNewData = () => {
  const newId = (mockData.length + 1).toString();
  const now = new Date();
  const randomType = notificationTypes[Math.floor(Math.random() * notificationTypes.length)];
  const randomDept = departments[Math.floor(Math.random() * departments.length)];
  // 生成随机标题
  let title = titleTemplates[Math.floor(Math.random() * titleTemplates.length)];
  title = title
    .replace('{year}', now.getFullYear())
    .replace('{holiday}', ['春节', '国庆', '中秋', '元旦'][Math.floor(Math.random() * 4)])
    .replace('{dept}', randomDept)
    .replace('{meeting}', ['周例会', '月度总结', '项目评审', '培训会议'][Math.floor(Math.random() * 4)])
    .replace('{behavior}', ['考勤', '着装', '工作态度', '团队协作'][Math.floor(Math.random() * 4)])
    .replace('{company}', ['公司', '集团', '总部'][Math.floor(Math.random() * 4)])
    .replace('{project}', ['数字化转型', '产品升级', '市场拓展', '人才培养'][Math.floor(Math.random() * 4)])
    .replace('{policy}', ['考勤', '薪酬', '福利', '晋升'][Math.floor(Math.random() * 4)]);
  // 随机状态
  const statuses = ['draft', 'published'];
  const randomStatus = statuses[Math.floor(Math.random() * statuses.length)];
  // 随机优先级
  const priorities = ['low', 'medium', 'high'];
  const randomPriority = priorities[Math.floor(Math.random() * priorities.length)];
  const newNotification = {
    id: newId,
    title: title,
    type: randomType.type,
    priority: randomPriority,
    status: randomStatus,
    content: `这是${title}的详细内容,请相关人员注意查看...`,
    departments: [randomDept],
    expireDate: new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], // 30天后过期
    syncMethods: ["wechat", "dingtalk"],
    createTime: now.toLocaleString()
  // 表单验证规则
  const rules = {
    title: [{ required: true, message: "请输入通知标题", trigger: "blur" }],
    type: [{ required: true, message: "请选择通知类型", trigger: "change" }],
    content: [{ required: true, message: "请输入通知内容", trigger: "blur" }],
  };
  // 添加到数据开头
  mockData.unshift(newNotification);
  const meetingRules = {
    title: [{ required: true, message: "请输入会议标题", trigger: "blur" }],
    startTime: [
      { required: true, message: "请选择会议开始时间", trigger: "change" },
    ],
    participants: [
      { required: true, message: "请选择参会人员", trigger: "change" },
    ],
  };
  // 保持数据量在合理范围内(最多保留20条)
  if (mockData.length > 20) {
    mockData = mockData.slice(0, 20);
  }
  const fileShareRules = {
    title: [{ required: true, message: "请输入共享标题", trigger: "blur" }],
    description: [{ required: true, message: "请输入共享描述", trigger: "blur" }],
  };
  console.log(`[${new Date().toLocaleString()}] 自动生成新通知: ${title}`);
};
// 生命周期
onMounted(() => {
  getList();
  getEmployeesList(); // 获取员工列表
  startAutoRefresh();
});
// 开始自动刷新
const startAutoRefresh = () => {
  setInterval(() => {
    generateNewData();
    getList();
  }, 600000); // 10分钟刷新一次 (10 * 60 * 1000 = 600000ms)
};
// 查询数据
const handleQuery = () => {
  page.value.current = 1;
  getList();
};
const getList = () => {
  tableLoading.value = true;
  listNotification({...page.value, ...searchForm.value})
  .then(res => {
    tableLoading.value = false;
    tableData.value = res.data.records
    page.value.total = res.data.total;
  }).catch(err => {
    tableLoading.value = false;
  })
};
// 分页处理
const pagination = (obj) => {
  page.value.current = obj.page;
  page.value.size = obj.limit;
  handleQuery();
};
// 选择变化处理
const handleSelectionChange = (selection) => {
  selectedIds.value = selection.map(item => item.id);
};
// 打开表单
const openForm = (type, row = null) => {
  dialogType.value = type;
  if (type === "add") {
    dialogTitle.value = "新增通知";
    // 重置表单
    Object.assign(form.value, {
      id: "",
  // 响应式数据
  const data = reactive({
    searchForm: {
      title: "",
      type: "",
      status: "",
    },
    tableLoading: false,
    page: {
      current: 1,
      size: 20,
      total: 0,
    },
    tableData: [],
    selectedIds: [],
    // 新增通知相关
    form: {
      title: "",
      type: "",
      priority: "",
      content: "",
      departments: [],
      expireDate: "",
      status: "draft",
      syncMethods: []
      syncMethods: [],
    },
    dialogVisible: false,
    dialogTitle: "",
    dialogType: "add",
    // 在线会议相关
    meetingDialogVisible: false,
    meetingForm: {
      title: "",
      startTime: "",
      duration: 60,
      participants: [],
      description: "",
      platform: "wechat",
    },
    // 文件共享相关
    fileShareDialogVisible: false,
    fileShareForm: {
      title: "",
      description: "",
      departments: [],
      files: [],
    },
    fileList: [],
  });
  const {
    searchForm,
    tableLoading,
    page,
    tableData,
    selectedIds,
    form,
    dialogVisible,
    dialogTitle,
    dialogType,
    meetingDialogVisible,
    meetingForm,
    fileShareDialogVisible,
    fileShareForm,
    fileList,
  } = toRefs(data);
  // 表单引用
  const formRef = ref();
  const meetingFormRef = ref();
  const fileShareFormRef = ref();
  // 表格列配置
  const tableColumn = ref([
    {
      label: "通知标题",
      prop: "title",
      showOverflowTooltip: true,
    },
    {
      label: "通知类型",
      prop: "type",
      dataType: "tag",
      formatData: params => {
        const typeMap = {
          holiday: "放假通知",
          penalty: "处罚通知",
          meeting: "开会通知",
          temporary: "临时通知",
          formal: "正式通知",
        };
        return typeMap[params] || params;
      },
      formatType: params => {
        const typeMap = {
          holiday: "success",
          penalty: "danger",
          meeting: "warning",
          temporary: "info",
          formal: "primary",
        };
        return typeMap[params] || "info";
      },
    },
    {
      label: "优先级",
      prop: "priority",
      dataType: "tag",
      formatData: params => {
        const priorityMap = {
          low: "普通",
          medium: "重要",
          high: "紧急",
        };
        return priorityMap[params] || params;
      },
      formatType: params => {
        const typeMap = {
          low: "info",
          medium: "warning",
          high: "danger",
        };
        return typeMap[params] || "info";
      },
    },
    {
      label: "状态",
      prop: "status",
      dataType: "tag",
      formatData: params => {
        const statusMap = {
          draft: "草稿",
          published: "已发布",
          expired: "已过期",
        };
        return statusMap[params] || params;
      },
      formatType: params => {
        const typeMap = {
          draft: "info",
          published: "success",
          expired: "danger",
        };
        return typeMap[params] || "info";
      },
    },
    {
      label: "接收部门",
      prop: "departments",
      width: 150,
      showOverflowTooltip: true,
      formatData: params => {
        if (!params || params.length === 0) return "全部部门";
        return params.join(", ");
      },
    },
    {
      label: "有效期至",
      prop: "expireDate",
      width: 150,
      formatData: params => {
        if (!params) return "永久有效";
        return params;
      },
    },
    {
      label: "创建时间",
      prop: "createTime",
      width: 180,
    },
    {
      dataType: "action",
      label: "操作",
      align: "center",
      fixed: "right",
      width: 280,
      operation: [
        {
          name: "编辑",
          type: "text",
          clickFun: row => {
            openForm("edit", row);
          },
        },
        {
          name: "发布",
          type: "text",
          clickFun: row => {
            publishNotification(row);
          },
          // disabled: (row) => row.status === "published"
        },
        {
          name: "撤回",
          type: "text",
          clickFun: row => {
            revokeNotification(row);
          },
          // disabled: (row) => row.status !== "published"
        },
      ],
    },
  ]);
  // 通知标题模板
  const titleTemplates = [
    "关于{year}年{holiday}放假安排的通知",
    "{dept}部门{meeting}会议通知",
    "员工{behavior}行为规范提醒",
    "{company}重要事项通知",
    "{dept}部门工作安排通知",
    "关于{project}项目进度的通知",
    "{dept}部门人员调整通知",
    "公司{policy}政策更新通知",
  ];
  // 通知类型配置
  const notificationTypes = [
    { type: "holiday", label: "放假通知", priority: "high" },
    { type: "meeting", label: "开会通知", priority: "medium" },
    { type: "penalty", label: "处罚通知", priority: "high" },
    { type: "temporary", label: "临时通知", priority: "low" },
    { type: "formal", label: "正式通知", priority: "medium" },
  ];
  // 部门列表
  const departments = [
    "技术部",
    "销售部",
    "人事部",
    "财务部",
    "运营部",
    "市场部",
    "客服部",
  ];
  // 人员列表
  const employees = ref([]);
  const employeesLoading = ref(false);
  // 获取在职员工列表
  const getEmployeesList = async () => {
    try {
      employeesLoading.value = true;
      // 优先使用系统用户接口(按租户获取)
      const userResponse = await userListNoPageByTenantId();
      if (userResponse.data) {
        employees.value = userResponse.data
          .map(user => ({
            label: user.nickName || user.userName || "未知姓名",
            value: user.userId || user.id,
            dept: user.dept?.deptName || "未知部门",
            phone: user.phonenumber || "",
            email: user.email || "",
            status: user.status || "0",
          }))
          .filter(user => user.status === "0"); // 只显示正常状态的用户
      } else {
        // 如果系统用户接口失败,使用员工台账接口
        const response = await staffOnJobListPage({
          pageNum: 1,
          pageSize: 1000,
          staffState: 1, // 在职状态
        });
        if (response.data && response.data.records) {
          employees.value = response.data.records.map(employee => ({
            label: employee.staffName || employee.name || "未知姓名",
            value: employee.staffNo || employee.id || employee.staffId,
            dept: employee.deptName || employee.department || "未知部门",
            phone: employee.phone || employee.mobile || "",
            email: employee.email || "",
            status: "0",
          }));
        }
      }
    } catch (error) {
      console.error("获取员工列表失败:", error);
      // 如果接口都失败,使用默认数据
      employees.value = [
        {
          label: "张三",
          value: "001",
          dept: "技术部",
          phone: "13800138001",
          email: "zhangsan@company.com",
          status: "0",
        },
        {
          label: "李四",
          value: "002",
          dept: "销售部",
          phone: "13800138002",
          email: "lisi@company.com",
          status: "0",
        },
        {
          label: "王五",
          value: "003",
          dept: "人事部",
          phone: "13800138003",
          email: "wangwu@company.com",
          status: "0",
        },
      ];
    } finally {
      employeesLoading.value = false;
    }
  };
  // 员工分组
  const employeeGroups = computed(() => {
    const groups = {};
    employees.value.forEach(employee => {
      const dept = employee.dept || "其他部门";
      if (!groups[dept]) {
        groups[dept] = [];
      }
      groups[dept].push(employee);
    });
  } else if (type === "edit" && row) {
    dialogTitle.value = "编辑通知";
    // 按部门名称排序,确保显示顺序一致
    return Object.keys(groups)
      .sort()
      .map(dept => ({
        label: dept,
        options: groups[dept].sort((a, b) =>
          a.label.localeCompare(b.label, "zh-CN")
        ),
      }));
  });
  // 过滤员工(远程搜索)
  const filterEmployees = query => {
    if (query !== "") {
      const lowerQuery = query.toLowerCase();
      return employees.value.filter(
        employee =>
          employee.label.toLowerCase().includes(lowerQuery) ||
          employee.dept.toLowerCase().includes(lowerQuery) ||
          (employee.phone && employee.phone.includes(query)) ||
          (employee.email && employee.email.toLowerCase().includes(lowerQuery))
      );
    } else {
      return employees.value;
    }
  };
  // 刷新员工列表
  const refreshEmployees = async () => {
    ElMessage.info("正在刷新员工列表...");
    await getEmployeesList();
    // 统计各部门人数
    const deptStats = {};
    employees.value.forEach(emp => {
      const dept = emp.dept || "其他部门";
      deptStats[dept] = (deptStats[dept] || 0) + 1;
    });
    const deptInfo = Object.entries(deptStats)
      .map(([dept, count]) => `${dept}: ${count}人`)
      .join(", ");
    ElMessage.success(
      `员工列表刷新完成,共 ${employees.value.length} 人 (${deptInfo})`
    );
  };
  // 获取员工姓名
  const getEmployeeName = employeeId => {
    const employee = employees.value.find(emp => emp.value === employeeId);
    return employee ? employee.label : "未知人员";
  };
  // 获取员工详细信息
  const getEmployeeInfo = employeeId => {
    const employee = employees.value.find(emp => emp.value === employeeId);
    if (!employee) return null;
    return {
      name: employee.label,
      dept: employee.dept,
      phone: employee.phone,
      email: employee.email,
    };
  };
  // 移除参会人员
  const removeParticipant = participantId => {
    const index = meetingForm.value.participants.indexOf(participantId);
    if (index > -1) {
      meetingForm.value.participants.splice(index, 1);
    }
  };
  // 同步方式选项
  const syncMethods = [
    { label: "企业微信", value: "wechat" },
    { label: "钉钉", value: "dingtalk" },
    { label: "邮件", value: "email" },
    { label: "短信", value: "sms" },
  ];
  // 会议平台选项
  const meetingPlatforms = [
    { label: "企业微信会议", value: "wechat" },
    { label: "钉钉会议", value: "dingtalk" },
    { label: "腾讯会议", value: "tencent" },
    { label: "Zoom", value: "zoom" },
  ];
  // 自动生成新数据
  const generateNewData = () => {
    const newId = (mockData.length + 1).toString();
    const now = new Date();
    const randomType =
      notificationTypes[Math.floor(Math.random() * notificationTypes.length)];
    const randomDept =
      departments[Math.floor(Math.random() * departments.length)];
    // 生成随机标题
    let title = titleTemplates[Math.floor(Math.random() * titleTemplates.length)];
    title = title
      .replace("{year}", now.getFullYear())
      .replace(
        "{holiday}",
        ["春节", "国庆", "中秋", "元旦"][Math.floor(Math.random() * 4)]
      )
      .replace("{dept}", randomDept)
      .replace(
        "{meeting}",
        ["周例会", "月度总结", "项目评审", "培训会议"][
          Math.floor(Math.random() * 4)
        ]
      )
      .replace(
        "{behavior}",
        ["考勤", "着装", "工作态度", "团队协作"][Math.floor(Math.random() * 4)]
      )
      .replace(
        "{company}",
        ["公司", "集团", "总部"][Math.floor(Math.random() * 4)]
      )
      .replace(
        "{project}",
        ["数字化转型", "产品升级", "市场拓展", "人才培养"][
          Math.floor(Math.random() * 4)
        ]
      )
      .replace(
        "{policy}",
        ["考勤", "薪酬", "福利", "晋升"][Math.floor(Math.random() * 4)]
      );
    // 随机状态
    const statuses = ["draft", "published"];
    const randomStatus = statuses[Math.floor(Math.random() * statuses.length)];
    // 随机优先级
    const priorities = ["low", "medium", "high"];
    const randomPriority =
      priorities[Math.floor(Math.random() * priorities.length)];
    const newNotification = {
      id: newId,
      title: title,
      type: randomType.type,
      priority: randomPriority,
      status: randomStatus,
      content: `这是${title}的详细内容,请相关人员注意查看...`,
      departments: [randomDept],
      expireDate: new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000)
        .toISOString()
        .split("T")[0], // 30天后过期
      syncMethods: ["wechat", "dingtalk"],
      createTime: now.toLocaleString(),
    };
    // 添加到数据开头
    mockData.unshift(newNotification);
    // 保持数据量在合理范围内(最多保留20条)
    if (mockData.length > 20) {
      mockData = mockData.slice(0, 20);
    }
    console.log(`[${new Date().toLocaleString()}] 自动生成新通知: ${title}`);
  };
  // 生命周期
  onMounted(() => {
    getList();
    getEmployeesList(); // 获取员工列表
    startAutoRefresh();
  });
  // 开始自动刷新
  const startAutoRefresh = () => {
    setInterval(() => {
      generateNewData();
      getList();
    }, 600000); // 10分钟刷新一次 (10 * 60 * 1000 = 600000ms)
  };
  // 查询数据
  const handleQuery = () => {
    page.value.current = 1;
    getList();
  };
  const getList = () => {
    tableLoading.value = true;
    listNotification({ ...page.value, ...searchForm.value })
      .then(res => {
        tableLoading.value = false;
        tableData.value = res.data.records;
        page.value.total = res.data.total;
      })
      .catch(err => {
        tableLoading.value = false;
      });
  };
  // 分页处理
  const pagination = obj => {
    page.value.current = obj.page;
    page.value.size = obj.limit;
    handleQuery();
  };
  // 选择变化处理
  const handleSelectionChange = selection => {
    selectedIds.value = selection.map(item => item.id);
  };
  // 打开表单
  const openForm = (type, row = null) => {
    dialogType.value = type;
    if (type === "add") {
      dialogTitle.value = "新增通知";
      // 重置表单
      Object.assign(form.value, {
        id: "",
        title: "",
        type: "",
        priority: "",
        content: "",
        departments: [],
        expireDate: "",
        status: "draft",
        syncMethods: [],
      });
    } else if (type === "edit" && row) {
      dialogTitle.value = "编辑通知";
      Object.assign(form.value, {
        id: row.id,
        title: row.title,
        type: row.type,
        priority: row.priority,
        content: row.content || "",
        departments: row.departments || [],
        expireDate: row.expireDate || "",
        status: row.status,
        syncMethods: row.syncMethods || [],
      });
    }
    dialogVisible.value = true;
  };
  // 打开在线会议弹窗
  const openMeetingDialog = () => {
    // 重置表单
    Object.assign(meetingForm.value, {
      title: "",
      startTime: "",
      duration: 60,
      participants: [],
      description: "",
      platform: "wechat",
    });
    meetingDialogVisible.value = true;
  };
  // 打开文件共享弹窗
  const openFileShareDialog = () => {
    // 重置表单
    Object.assign(fileShareForm.value, {
      title: "",
      description: "",
      departments: [],
      files: [],
    });
    fileList.value = [];
    fileShareDialogVisible.value = true;
  };
  // 手动刷新数据
  const manualRefresh = () => {
    generateNewData();
    getList();
    ElMessage.success("手动刷新完成,已生成新通知");
  };
  // 提交通知表单
  const submitForm = async () => {
    try {
      await formRef.value.validate();
      if (dialogType.value === "add") {
        // 新增通知
        addNotification({ ...form.value })
          .then(res => {
            if (res.code == 200) {
              ElMessage.success("添加成功");
              dialogVisible.value = false;
              getList();
            }
          })
          .catch(err => {
            ElMessage.error(err.msg);
          });
      } else {
        // 编辑通知
        updateNotification({ ...form.value })
          .then(res => {
            if (res.code == 200) {
              ElMessage.success("更新成功");
              dialogVisible.value = false;
              getList();
            }
          })
          .catch(err => {
            ElMessage.error(err.msg);
          });
      }
    } catch (error) {
      console.error("表单验证失败:", error);
    }
  };
  // 创建会议
  const createMeeting = async () => {
    try {
      await meetingFormRef.value.validate();
      // 模拟创建会议
      const meetingInfo = {
        title: meetingForm.value.title,
        startTime: meetingForm.value.startTime,
        duration: meetingForm.value.duration,
        participants: meetingForm.value.participants,
        description: meetingForm.value.description,
        platform: meetingForm.value.platform,
      };
      // 新增会议
      addOnlineMeeting({ ...meetingInfo })
        .then(res => {
          if (res.code == 200) {
            ElMessage.success("会议添加成功");
            meetingDialogVisible.value = false;
            getList();
          }
        })
        .catch(err => {
          ElMessage.error(err.msg);
        });
      // 模拟发送到企业微信/钉钉
      // const platformName = meetingPlatforms.find(p => p.value === meetingForm.value.platform)?.label || "未知平台";
      // ElMessage.success(`会议创建成功!会议ID: ${meetingInfo.meetingId},将通过${platformName}发送通知`);
      // 获取参会人员信息
      const participantNames = meetingForm.value.participants
        .map(participantId => {
          const employee = employees.value.find(
            emp => emp.value === participantId
          );
          return employee ? employee.label : "未知人员";
        })
        .join("、");
      // 获取参会人员详细信息
      const participantDetails = meetingForm.value.participants
        .map(participantId => {
          const employee = employees.value.find(
            emp => emp.value === participantId
          );
          return employee
            ? {
                name: employee.label,
                dept: employee.dept,
                phone: employee.phone,
                email: employee.email,
              }
            : null;
        })
        .filter(Boolean);
      // 将会议信息添加到通知列表
      const meetingNotification = {
        title: `[会议通知] ${meetingInfo.title}`,
        type: "meeting",
        priority: "high",
        status: "published",
        content: `会议时间: ${meetingInfo.startTime},时长: ${
          meetingInfo.duration
        }分钟,平台: ${
          meetingPlatforms.find(p => p.value === meetingForm.value.platform)
            ?.label || "未知平台"
        },参会人员: ${participantNames},共${participantDetails.length}人`,
        departments: [],
        expireDate: "",
        syncMethods: [meetingForm.value.platform],
      };
      addNotification({ ...meetingNotification })
        .then(res => {
          if (res.code == 200) {
            ElMessage.success("添加成功");
            // dialogVisible.value = false;
            getList();
          }
        })
        .catch(err => {
          ElMessage.error(err.msg);
        });
      // mockData.unshift(meetingNotification);
      // getList();
    } catch (error) {
      console.error("会议表单验证失败:", error);
    }
  };
  // 文件上传处理
  const handleFileChange = file => {
    const isLt10M = file.size / 1024 / 1024 < 10;
    if (!isLt10M) {
      ElMessage.error("上传文件大小不能超过 10MB!");
      return false;
    }
    const fileInfo = {
      name: file.name,
      size: file.size,
      type: file.type,
      uid: file.uid,
    };
    fileList.value.push(fileInfo);
    fileShareForm.value.files.push(fileInfo.name);
    return false; // 阻止自动上传
  };
  // 移除文件
  const removeFile = file => {
    const index = fileList.value.findIndex(item => item.uid === file.uid);
    if (index !== -1) {
      const index2 = fileShareForm.value.files.findIndex(
        item => item.uid === file.uid
      );
      if (index2 !== -1) {
        fileShareForm.value.files.splice(index2, 1);
      }
      fileList.value.splice(index, 1);
    }
  };
  // 共享文件
  const shareFiles = async () => {
    try {
      await fileShareFormRef.value.validate();
      if (fileShareForm.value.files.length === 0) {
        ElMessage.warning("请至少选择一个文件");
        return;
      }
      // 模拟文件共享
      const shareInfo = {
        title: fileShareForm.value.title,
        description: fileShareForm.value.description,
        departments: fileShareForm.value.departments,
        files: fileShareForm.value.files,
      };
      addFileSharing({ ...shareInfo })
        .then(res => {
          if (res.code == 200) {
            ElMessage.success("文件共享成功");
            fileShareDialogVisible.value = false;
            getList();
          }
        })
        .catch(err => {
          ElMessage.error(err.msg);
        });
      // ElMessage.success(`文件共享成功!共享ID: ${shareInfo.shareId},已通知相关部门`);
      // 将文件共享信息添加到通知列表
      const fileShareNotification = {
        title: `[文件共享] ${shareInfo.title}`,
        type: "temporary",
        priority: "medium",
        status: "published",
        content: `共享描述: ${shareInfo.description},文件数量: ${shareInfo.files.length}个`,
        departments: shareInfo.departments,
        expireDate: "",
        syncMethods: ["wechat", "dingtalk"],
      };
      addNotification({ ...fileShareNotification })
        .then(res => {
          if (res.code == 200) {
            ElMessage.success("添加成功");
            // dialogVisible.value = false;
            getList();
          }
        })
        .catch(err => {
          ElMessage.error(err.msg);
        });
      // mockData.unshift(fileShareNotification);
      // getList();
    } catch (error) {
      console.error("文件共享表单验证失败:", error);
    }
  };
  // 发布通知
  const publishNotification = row => {
    Object.assign(form.value, {
      id: row.id,
      title: row.title,
@@ -857,344 +1207,106 @@
      departments: row.departments || [],
      expireDate: row.expireDate || "",
      status: row.status,
      syncMethods: row.syncMethods || []
      syncMethods: row.syncMethods || [],
    });
  }
  dialogVisible.value = true;
};
// 打开在线会议弹窗
const openMeetingDialog = () => {
  // 重置表单
  Object.assign(meetingForm.value, {
    title: "",
    startTime: "",
    duration: 60,
    participants: [],
    description: "",
    platform: "wechat"
  });
  meetingDialogVisible.value = true;
};
// 打开文件共享弹窗
const openFileShareDialog = () => {
  // 重置表单
  Object.assign(fileShareForm.value, {
    title: "",
    description: "",
    departments: [],
    files: []
  });
  fileList.value = [];
  fileShareDialogVisible.value = true;
};
// 手动刷新数据
const manualRefresh = () => {
  generateNewData();
  getList();
  ElMessage.success("手动刷新完成,已生成新通知");
};
// 提交通知表单
const submitForm = async () => {
  try {
    await formRef.value.validate();
    if (dialogType.value === "add") {
      // 新增通知
      addNotification({...form.value}).then(res => {
        if(res.code == 200){
          ElMessage.success("添加成功");
          dialogVisible.value = false;
          getList();
        }
      }).catch(err => {
        ElMessage.error(err.msg);
      })
    } else {
      // 编辑通知
      updateNotification({...form.value}).then(res => {
        if(res.code == 200){
          ElMessage.success("更新成功");
          dialogVisible.value = false;
          getList();
        }
      }).catch(err => {
        ElMessage.error(err.msg);
      })
    }
  } catch (error) {
    console.error("表单验证失败:", error);
  }
};
// 创建会议
const createMeeting = async () => {
  try {
    await meetingFormRef.value.validate();
    // 模拟创建会议
    const meetingInfo = {
      title: meetingForm.value.title,
      startTime: meetingForm.value.startTime,
      duration: meetingForm.value.duration,
      participants: meetingForm.value.participants,
      description: meetingForm.value.description,
      platform: meetingForm.value.platform
    };
    // 新增会议
    addOnlineMeeting({...meetingInfo}).then(res => {
      if(res.code == 200){
        ElMessage.success("会议添加成功");
        meetingDialogVisible.value = false;
        getList();
      }
    }).catch(err => {
      ElMessage.error(err.msg);
    })
    // 模拟发送到企业微信/钉钉
    // const platformName = meetingPlatforms.find(p => p.value === meetingForm.value.platform)?.label || "未知平台";
    // ElMessage.success(`会议创建成功!会议ID: ${meetingInfo.meetingId},将通过${platformName}发送通知`);
    // 获取参会人员信息
     const participantNames = meetingForm.value.participants.map(participantId => {
       const employee = employees.value.find(emp => emp.value === participantId);
       return employee ? employee.label : '未知人员';
     }).join('、');
     // 获取参会人员详细信息
     const participantDetails = meetingForm.value.participants.map(participantId => {
       const employee = employees.value.find(emp => emp.value === participantId);
       return employee ? {
         name: employee.label,
         dept: employee.dept,
         phone: employee.phone,
         email: employee.email
       } : null;
     }).filter(Boolean);
    // 将会议信息添加到通知列表
    const meetingNotification = {
      title: `[会议通知] ${meetingInfo.title}`,
      type: "meeting",
      priority: "high",
      status: "published",
      content: `会议时间: ${meetingInfo.startTime},时长: ${meetingInfo.duration}分钟,平台: ${meetingPlatforms.find(p => p.value === meetingForm.value.platform)?.label || "未知平台"},参会人员: ${participantNames},共${participantDetails.length}人`,
      departments: [],
      expireDate: "",
      syncMethods: [meetingForm.value.platform]
    };
    addNotification({...meetingNotification}).then(res => {
        if(res.code == 200){
          ElMessage.success("添加成功");
          // dialogVisible.value = false;
          getList();
        }
      }).catch(err => {
        ElMessage.error(err.msg);
      })
    // mockData.unshift(meetingNotification);
    // getList();
  } catch (error) {
    console.error("会议表单验证失败:", error);
  }
};
// 文件上传处理
const handleFileChange = (file) => {
  const isLt10M = file.size / 1024 / 1024 < 10;
  if (!isLt10M) {
    ElMessage.error("上传文件大小不能超过 10MB!");
    return false;
  }
  const fileInfo = {
    name: file.name,
    size: file.size,
    type: file.type,
    uid: file.uid
  };
  fileList.value.push(fileInfo);
  fileShareForm.value.files.push(fileInfo.name);
  return false; // 阻止自动上传
};
// 移除文件
const removeFile = (file) => {
  const index = fileList.value.findIndex(item => item.uid === file.uid);
  if (index !== -1) {
    const index2 = fileShareForm.value.files.findIndex(item => item.uid === file.uid);
    if (index2 !== -1) {
      fileShareForm.value.files.splice(index2, 1);
    }
    fileList.value.splice(index, 1);
  }
};
// 共享文件
const shareFiles = async () => {
  try {
    await fileShareFormRef.value.validate();
    if (fileShareForm.value.files.length === 0) {
      ElMessage.warning("请至少选择一个文件");
      return;
    }
    // 模拟文件共享
    const shareInfo = {
      title: fileShareForm.value.title,
      description: fileShareForm.value.description,
      departments: fileShareForm.value.departments,
      files: fileShareForm.value.files,
    };
    addFileSharing({...shareInfo}).then(res => {
      if(res.code == 200){
        ElMessage.success("文件共享成功");
        fileShareDialogVisible.value = false;
        getList();
      }
    }).catch(err => {
      ElMessage.error(err.msg);
    })
    // ElMessage.success(`文件共享成功!共享ID: ${shareInfo.shareId},已通知相关部门`);
    // 将文件共享信息添加到通知列表
    const fileShareNotification = {
      title: `[文件共享] ${shareInfo.title}`,
      type: "temporary",
      priority: "medium",
      status: "published",
      content: `共享描述: ${shareInfo.description},文件数量: ${shareInfo.files.length}个`,
      departments: shareInfo.departments,
      expireDate: "",
      syncMethods: ["wechat", "dingtalk"],
    };
    addNotification({...fileShareNotification}).then(res => {
      if(res.code == 200){
        ElMessage.success("添加成功");
        // dialogVisible.value = false;
        getList();
      }
    }).catch(err => {
      ElMessage.error(err.msg);
    })
    // mockData.unshift(fileShareNotification);
    // getList();
  } catch (error) {
    console.error("文件共享表单验证失败:", error);
  }
};
// 发布通知
const publishNotification = (row) => {
  Object.assign(form.value, {
    id: row.id,
    title: row.title,
    type: row.type,
    priority: row.priority,
    content: row.content || "",
    departments: row.departments || [],
    expireDate: row.expireDate || "",
    status: row.status,
    syncMethods: row.syncMethods || []
  });
  form.value.status = "published";
  updateNotification({...form.value}).then(res => {
        if(res.code == 200){
    form.value.status = "published";
    updateNotification({ ...form.value })
      .then(res => {
        if (res.code == 200) {
          ElMessage.success("通知发布成功");
          getList();
        }
      }).catch(err => {
        ElMessage.error(err.msg);
      })
};
      .catch(err => {
        ElMessage.error(err.msg);
      });
  };
// 撤回通知
const revokeNotification = (row) => {
  // 撤回通知
  const revokeNotification = row => {
    Object.assign(form.value, {
    id: row.id,
    title: row.title,
    type: row.type,
    priority: row.priority,
    content: row.content || "",
    departments: row.departments || [],
    expireDate: row.expireDate || "",
    status: row.status,
    syncMethods: row.syncMethods || []
  });
  form.value.status = "draft";
  updateNotification({...form.value}).then(res => {
        if(res.code == 200){
      id: row.id,
      title: row.title,
      type: row.type,
      priority: row.priority,
      content: row.content || "",
      departments: row.departments || [],
      expireDate: row.expireDate || "",
      status: row.status,
      syncMethods: row.syncMethods || [],
    });
    form.value.status = "draft";
    updateNotification({ ...form.value })
      .then(res => {
        if (res.code == 200) {
          ElMessage.success("通知已撤回");
          getList();
        }
      }).catch(err => {
        ElMessage.error(err.msg);
      })
};
      .catch(err => {
        ElMessage.error(err.msg);
      });
  };
// 删除通知
const handleDelete = () => {
  let ids = [];
  if (selectedIds.value.length > 0) {
    ids = selectedIds.value;
  }else{
    ElMessage.warning("请选择要删除的通知");
    return;
  }
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "删除", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  }).then(() => {
    delNotification(ids).then(res => {
      if(res.code == 200){
        ElMessage.success("删除成功");
        selectedIds.value = [];
        getList();
      }
    }).catch(err => {
      ElMessage.error(err.msg);
  // 删除通知
  const handleDelete = () => {
    let ids = [];
    if (selectedIds.value.length > 0) {
      ids = selectedIds.value;
    } else {
      ElMessage.warning("请选择要删除的通知");
      return;
    }
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "删除", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
  }).catch(() => {
    // 用户取消
  });
};
      .then(() => {
        delNotification(ids)
          .then(res => {
            if (res.code == 200) {
              ElMessage.success("删除成功");
              selectedIds.value = [];
              getList();
            }
          })
          .catch(err => {
            ElMessage.error(err.msg);
          });
      })
      .catch(() => {
        // 用户取消
      });
  };
</script>
<style scoped>
.auto-refresh-info {
  margin-bottom: 15px;
}
  .auto-refresh-info {
    margin-bottom: 15px;
  }
.auto-refresh-info .el-alert {
  border-radius: 8px;
}
  .auto-refresh-info .el-alert {
    border-radius: 8px;
  }
.dialog-footer {
  text-align: right;
}
  .dialog-footer {
    text-align: right;
  }
.el-upload__tip {
  color: #909399;
  font-size: 12px;
  margin-top: 8px;
}
  .el-upload__tip {
    color: #909399;
    font-size: 12px;
    margin-top: 8px;
  }
.el-checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
  .el-checkbox-group {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
  }
.el-checkbox {
  margin-right: 0;
}
  .el-checkbox {
    margin-right: 0;
  }
</style>