WXL
2025-12-29 2431480f5859ef40dfdf0eb19e1ba6ddebbd9ef2
src/views/OfficeRelated/conference/index.vue
@@ -17,7 +17,11 @@
    <el-card class="filter-card">
      <el-form :model="queryParams" inline>
        <el-form-item label="会议类型">
          <el-select v-model="queryParams.meetingType" clearable placeholder="请选择">
          <el-select
            v-model="queryParams.meetingType"
            clearable
            placeholder="请选择"
          >
            <el-option label="科研会议" value="research" />
            <el-option label="日常会议" value="daily" />
            <el-option label="项目会议" value="project" />
@@ -44,7 +48,11 @@
          />
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="queryParams.status" clearable placeholder="请选择">
          <el-select
            v-model="queryParams.status"
            clearable
            placeholder="请选择"
          >
            <el-option label="待开始" value="pending" />
            <el-option label="进行中" value="ongoing" />
            <el-option label="已结束" value="completed" />
@@ -67,51 +75,114 @@
        style="width: 100%"
        @sort-change="handleSortChange"
      >
        <el-table-column prop="id" label="ID" width="80" fixed />
        <el-table-column prop="title" label="会议主题" width="200" fixed>
        <!-- <el-table-column prop="id" label="ID" width="80" fixed /> -->
        <el-table-column
          prop="title"
          align="center"
          label="会议主题"
          width="200"
          fixed
        >
          <template #default="scope">
            <el-button type="text" @click="handleView(scope.row)">
              {{ scope.row.title }}
            </el-button>
          </template>
        </el-table-column>
        <el-table-column prop="meetingType" label="会议类型" width="120">
        <el-table-column
          align="center"
          prop="meetingType"
          label="会议类型"
          width="120"
        >
          <template #default="scope">
            <el-tag :type="getMeetingTypeTag(scope.row.meetingType)">
              {{ getMeetingTypeText(scope.row.meetingType) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="participants" label="参会人员" width="180" show-overflow-tooltip>
          <template #default="scope">
            <span>{{ scope.row.participants.join(', ') }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="location" label="会议地点" width="150" />
        <el-table-column prop="startTime" label="开始时间" width="160" sortable>
          <template #default="scope">
            <span>{{ formatDateTime(scope.row.startTime) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="endTime" label="结束时间" width="160" sortable>
          <template #default="scope">
            <span>{{ formatDateTime(scope.row.endTime) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="duration" label="持续时间" width="100">
          <template #default="scope">
            <span>{{ calculateDuration(scope.row) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="summary" label="会议概要" min-width="200" show-overflow-tooltip />
        <el-table-column prop="status" label="状态" width="100" fixed="right">
        <el-table-column
          align="center"
          prop="status"
          label="状态"
          width="100"
          fixed="right"
        >
          <template #default="scope">
            <el-tag :type="getStatusTag(scope.row.status)">
              {{ getStatusText(scope.row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200" fixed="right">
        <el-table-column
          prop="participants"
          label="参会人员"
          align="center"
          width="180"
          show-overflow-tooltip
        >
          <template #default="scope">
            <span>{{ scope.row.participants.join(", ") }}</span>
          </template>
        </el-table-column>
        <el-table-column
          align="center"
          prop="location"
          label="会议地点"
          width="150"
        />
        <el-table-column
          align="center"
          prop="startTime"
          label="开始时间"
          width="160"
          sortable
        >
          <template #default="scope">
            <span>{{ formatDateTime(scope.row.startTime) }}</span>
          </template>
        </el-table-column>
        <el-table-column
          align="center"
          prop="endTime"
          label="结束时间"
          width="160"
          sortable
        >
          <template #default="scope">
            <span>{{ formatDateTime(scope.row.endTime) }}</span>
          </template>
        </el-table-column>
        <el-table-column
          align="center"
          prop="duration"
          label="持续时间"
          width="100"
        >
          <template #default="scope">
            <span>{{ calculateDuration(scope.row) }}</span>
          </template>
        </el-table-column>
        <el-table-column
          align="center"
          prop="summary"
          label="会议概要"
          min-width="200"
          show-overflow-tooltip
        />
        <el-table-column align="center" label="会议纪要" width="120">
          <template #default="scope">
            <el-button
              size="mini"
              type="text"
              @click="handleViewMinutes(scope.row)"
              :disabled="!scope.row.meetingMinutes"
            >
              {{ scope.row.meetingMinutes ? "查看纪要" : "暂无" }}
            </el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="200" fixed="right">
          <template #default="scope">
            <el-button size="mini" type="text" @click="handleView(scope.row)">
              查看
@@ -151,7 +222,54 @@
        />
      </div>
    </el-card>
    <el-dialog
      title="会议纪要"
      :visible.sync="minutesDialogVisible"
      width="600px"
    >
      <div v-if="currentRecord.meetingMinutes">
        <el-alert
          title="会议纪要详情"
          type="info"
          :closable="false"
          style="margin-bottom: 16px;"
        />
        <div class="minutes-content">
          <el-card>
            <div
              style="white-space: pre-line; line-height: 1.6; max-height: 400px; overflow-y: auto;"
            >
              {{ currentRecord.meetingMinutes }}
            </div>
          </el-card>
        </div>
        <div
          class="minutes-meta"
          style="margin-top: 16px; color: #909399; font-size: 12px;"
        >
          <span
            >创建时间:
            {{ formatDateTime(currentRecord.minutesCreateTime) }}</span
          >
          <span style="margin-left: 16px;"
            >创建人: {{ currentRecord.minutesCreator || "系统" }}</span
          >
        </div>
      </div>
      <div v-else>
        <el-empty description="暂无会议纪要"></el-empty>
      </div>
      <span slot="footer">
        <el-button @click="minutesDialogVisible = false">关闭</el-button>
        <el-button
          type="primary"
          @click="handleEdit(currentRecord)"
          v-if="currentRecord.meetingMinutes"
        >
          编辑纪要
        </el-button>
      </span>
    </el-dialog>
    <!-- 查看详情对话框 -->
    <el-dialog
      :title="`会议详情 - ${currentRecord.title || ''}`"
@@ -160,7 +278,9 @@
      :before-close="handleDetailClose"
    >
      <el-descriptions :column="2" border v-if="currentRecord">
        <el-descriptions-item label="会议主题">{{ currentRecord.title }}</el-descriptions-item>
        <el-descriptions-item label="会议主题">{{
          currentRecord.title
        }}</el-descriptions-item>
        <el-descriptions-item label="会议类型">
          <el-tag :type="getMeetingTypeTag(currentRecord.meetingType)">
            {{ getMeetingTypeText(currentRecord.meetingType) }}
@@ -177,35 +297,58 @@
            {{ participant }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="会议地点">{{ currentRecord.location }}</el-descriptions-item>
        <el-descriptions-item label="会议地点">{{
          currentRecord.location
        }}</el-descriptions-item>
        <el-descriptions-item label="会议状态">
          <el-tag :type="getStatusTag(currentRecord.status)">
            {{ getStatusText(currentRecord.status) }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="开始时间">{{ formatDateTime(currentRecord.startTime) }}</el-descriptions-item>
        <el-descriptions-item label="结束时间">{{ formatDateTime(currentRecord.endTime) }}</el-descriptions-item>
        <el-descriptions-item label="持续时间">{{ calculateDuration(currentRecord) }}</el-descriptions-item>
        <el-descriptions-item label="创建人">{{ currentRecord.creator }}</el-descriptions-item>
        <el-descriptions-item label="开始时间">{{
          formatDateTime(currentRecord.startTime)
        }}</el-descriptions-item>
        <el-descriptions-item label="结束时间">{{
          formatDateTime(currentRecord.endTime)
        }}</el-descriptions-item>
        <el-descriptions-item label="持续时间">{{
          calculateDuration(currentRecord)
        }}</el-descriptions-item>
        <el-descriptions-item label="创建人">{{
          currentRecord.creator
        }}</el-descriptions-item>
        <el-descriptions-item label="会议概要" :span="2">
          {{ currentRecord.summary }}
        </el-descriptions-item>
        <el-descriptions-item label="会议内容" :span="2">
          <div style="white-space: pre-line; max-height: 300px; overflow-y: auto;">
          <div
            style="white-space: pre-line; max-height: 300px; overflow-y: auto;"
          >
            {{ currentRecord.content }}
          </div>
        </el-descriptions-item>
        <el-descriptions-item label="附件" :span="2" v-if="currentRecord.attachments && currentRecord.attachments.length">
          <div v-for="file in currentRecord.attachments" :key="file.id" class="attachment-item">
        <el-descriptions-item
          label="附件"
          :span="2"
          v-if="currentRecord.attachments && currentRecord.attachments.length"
        >
          <div
            v-for="file in currentRecord.attachments"
            :key="file.id"
            class="attachment-item"
          >
            <el-link type="primary" :href="file.url" target="_blank">
              <i class="el-icon-document"></i> {{ file.name }}
            </el-link>
          </div>
        </el-descriptions-item>
      </el-descriptions>
      <span slot="footer">
        <el-button @click="detailDialogVisible = false">关闭</el-button>
        <el-button type="primary" @click="handleEdit(currentRecord)">编辑</el-button>
        <el-button type="primary" @click="handleEdit(currentRecord)"
          >编辑</el-button
        >
      </span>
    </el-dialog>
@@ -228,7 +371,11 @@
        </el-form-item>
        <el-form-item label="会议类型" prop="meetingType">
          <el-select v-model="editForm.meetingType" placeholder="请选择会议类型" style="width: 100%">
          <el-select
            v-model="editForm.meetingType"
            placeholder="请选择会议类型"
            style="width: 100%"
          >
            <el-option label="科研会议" value="research" />
            <el-option label="日常会议" value="daily" />
            <el-option label="项目会议" value="project" />
@@ -313,15 +460,30 @@
            multiple
          >
            <el-button size="small" type="primary">点击上传</el-button>
            <div slot="tip" class="el-upload__tip">支持上传文档、图片等文件,单个文件不超过10MB</div>
            <div slot="tip" class="el-upload__tip">
              支持上传文档、图片等文件,单个文件不超过10MB
            </div>
          </el-upload>
        </el-form-item>
        <el-form-item label="会议纪要" prop="meetingMinutes">
          <el-input
            v-model="editForm.meetingMinutes"
            type="textarea"
            :rows="6"
            placeholder="请输入会议纪要内容,包括会议决议、行动计划、责任人等信息"
            maxlength="1000"
            show-word-limit
          />
          <div style="color: #909399; font-size: 12px; margin-top: 4px;">
            提示:可记录会议讨论要点、决议事项、行动计划等
          </div>
        </el-form-item>
      </el-form>
      <span slot="footer">
        <el-button @click="handleEditClose">取消</el-button>
        <el-button type="primary" @click="handleSave" :loading="saveLoading">
          {{ isEditing ? '保存' : '新增' }}
          {{ isEditing ? "保存" : "新增" }}
        </el-button>
      </span>
    </el-dialog>
@@ -330,15 +492,15 @@
<script>
export default {
  name: 'MeetingManagement',
  name: "MeetingManagement",
  data() {
    return {
      // 查询参数
      queryParams: {
        meetingType: '',
        location: '',
        meetingType: "",
        location: "",
        dateRange: [],
        status: ''
        status: ""
      },
      // 分页参数
      pagination: {
@@ -360,325 +522,436 @@
      tableData: [],
      // 用户列表(用于选择参会人员)
      userList: [
        { id: 1, name: '张三' },
        { id: 2, name: '李四' },
        { id: 3, name: '王五' },
        { id: 4, name: '赵六' },
        { id: 5, name: '钱七' },
        { id: 6, name: '孙八' },
        { id: 7, name: '周九' },
        { id: 8, name: '吴十' }
        { id: 1, name: "张三" },
        { id: 2, name: "李四" },
        { id: 3, name: "王五" },
        { id: 4, name: "赵六" },
        { id: 5, name: "钱七" },
        { id: 6, name: "孙八" },
        { id: 7, name: "周九" },
        { id: 8, name: "吴十" }
      ],
      minutesDialogVisible: false, // 会议纪要对话框显示状态
      // 编辑表单数据
      editForm: {
        title: '',
        meetingType: '',
        title: "",
        meetingType: "",
        participants: [],
        location: '',
        startTime: '',
        endTime: '',
        summary: '',
        content: '',
        location: "",
        startTime: "",
        endTime: "",
        summary: "",
        content: "",
        attachments: []
      },
      // 表单验证规则
      editRules: {
        title: [{ required: true, message: '请输入会议主题', trigger: 'blur' }],
        meetingType: [{ required: true, message: '请选择会议类型', trigger: 'change' }],
        participants: [{ required: true, message: '请选择参会人员', trigger: 'change' }],
        location: [{ required: true, message: '请输入会议地点', trigger: 'blur' }],
        startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
        endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
        summary: [{ required: true, message: '请输入会议概要', trigger: 'blur' }],
        content: [{ required: true, message: '请输入会议内容', trigger: 'blur' }]
        title: [{ required: true, message: "请输入会议主题", trigger: "blur" }],
        meetingType: [
          { required: true, message: "请选择会议类型", trigger: "change" }
        ],
        participants: [
          { required: true, message: "请选择参会人员", trigger: "change" }
        ],
        location: [
          { required: true, message: "请输入会议地点", trigger: "blur" }
        ],
        startTime: [
          { required: true, message: "请选择开始时间", trigger: "change" }
        ],
        endTime: [
          { required: true, message: "请选择结束时间", trigger: "change" }
        ],
        summary: [
          { required: true, message: "请输入会议概要", trigger: "blur" }
        ],
        content: [
          { required: true, message: "请输入会议内容", trigger: "blur" }
        ],
        meetingMinutes: [
          {
            max: 1000,
            message: "会议纪要长度不能超过1000个字符",
            trigger: "blur"
          }
        ]
      }
    }
    };
  },
  mounted() {
    this.loadData()
    this.loadData();
  },
  methods: {
    // 加载数据
    async loadData() {
      this.loading = true
      this.loading = true;
      try {
        // 模拟API调用
        await new Promise(resolve => setTimeout(resolve, 500))
        await new Promise(resolve => setTimeout(resolve, 500));
        // 生成模拟数据
        this.tableData = this.generateMockData()
        this.pagination.total = this.tableData.length
        this.tableData = this.generateMockData();
        this.pagination.total = this.tableData.length;
      } catch (error) {
        console.error('加载数据失败:', error)
        this.$message.error('数据加载失败')
        console.error("加载数据失败:", error);
        this.$message.error("数据加载失败");
      } finally {
        this.loading = false
        this.loading = false;
      }
    },
    // 查看会议纪要
    handleViewMinutes(record) {
      this.currentRecord = { ...record };
      this.minutesDialogVisible = true;
    },
    // 生成模拟数据
    generateMockData() {
      const meetingTypes = ['research', 'daily', 'project', 'department', 'review']
      const statuses = ['pending', 'ongoing', 'completed', 'cancelled']
      const participantsPool = ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十']
      const meetingTypes = [
        "research",
        "daily",
        "project",
        "department",
        "review"
      ];
      const statuses = ["pending", "ongoing", "completed", "cancelled"];
      const participantsPool = [
        "张三",
        "李四",
        "王五",
        "赵六",
        "钱七",
        "孙八",
        "周九",
        "吴十"
      ];
      // 会议纪要示例内容
      const minutesExamples = [
        `会议决议:
1. 项目计划调整至下周一正式启动
2. 技术方案由张三负责完善
3. 下周进行技术评审会议
行动计划:
- 李四:准备技术文档(截止周五)
- 王五:协调资源分配(截止周四)
- 全体:参加技术培训(周三下午)`,
        `讨论要点:
1. 当前项目进度正常,需加强质量管控
2. 客户反馈问题需要优先处理
3. 下阶段工作重点明确
任务分配:
✅ 已完成:需求分析、技术方案
🔷 进行中:开发实施(负责人:赵六)
⏳ 待开始:测试验收`,
        `重要决议:
• 通过预算调整方案
• 确定新成员加入时间
• 批准设备采购申请
后续安排:
📅 下次会议时间:2024-01-15 14:00
📍 会议地点:第一会议室
👥 必须参会人员:张三、李四`
      ];
      return Array.from({ length: 10 }, (_, index) => {
        const participantCount = Math.floor(Math.random() * 5) + 2
        const participants = []
        const participantCount = Math.floor(Math.random() * 5) + 2;
        const participants = [];
        for (let i = 0; i < participantCount; i++) {
          const randomIndex = Math.floor(Math.random() * participantsPool.length)
          participants.push(participantsPool[randomIndex])
          const randomIndex = Math.floor(
            Math.random() * participantsPool.length
          );
          participants.push(participantsPool[randomIndex]);
        }
        // 去重
        const uniqueParticipants = [...new Set(participants)]
        const uniqueParticipants = [...new Set(participants)];
        const startTime = new Date();
        startTime.setDate(
          startTime.getDate() + Math.floor(Math.random() * 30) - 15
        );
        startTime.setHours(
          9 + Math.floor(Math.random() * 8),
          Math.floor(Math.random() * 4) * 15,
          0
        );
        const startTime = new Date()
        startTime.setDate(startTime.getDate() + Math.floor(Math.random() * 30) - 15)
        startTime.setHours(9 + Math.floor(Math.random() * 8), Math.floor(Math.random() * 4) * 15, 0)
        const endTime = new Date(startTime);
        endTime.setHours(
          startTime.getHours() + Math.floor(Math.random() * 3) + 1
        );
        const endTime = new Date(startTime)
        endTime.setHours(startTime.getHours() + Math.floor(Math.random() * 3) + 1)
        // 随机决定是否有会议纪要(60%概率有纪要)
        const hasMinutes = Math.random() > 0.4;
        const meetingMinutes = hasMinutes
          ? minutesExamples[Math.floor(Math.random() * minutesExamples.length)]
          : "";
        return {
          id: index + 1,
          title: `关于${['科研项目', '日常工作', '技术评审', '部门协调'][Math.floor(Math.random() * 4)]}的会议`,
          meetingType: meetingTypes[Math.floor(Math.random() * meetingTypes.length)],
          title: `关于${
            ["科研项目", "日常工作", "技术评审", "部门协调"][
              Math.floor(Math.random() * 4)
            ]
          }的会议`,
          meetingType:
            meetingTypes[Math.floor(Math.random() * meetingTypes.length)],
          participants: uniqueParticipants,
          location: ['第一会议室', '第二会议室', '第三会议室', '线上会议'][Math.floor(Math.random() * 4)],
          location: ["第一会议室", "第二会议室", "第三会议室", "线上会议"][
            Math.floor(Math.random() * 4)
          ],
          startTime: startTime.toISOString(),
          endTime: endTime.toISOString(),
          summary: `本次会议主要讨论${['项目进展', '技术难题', '工作计划', '问题协调'][Math.floor(Math.random() * 4)]}等相关事宜`,
          summary: `本次会议主要讨论${
            ["项目进展", "技术难题", "工作计划", "问题协调"][
              Math.floor(Math.random() * 4)
            ]
          }等相关事宜`,
          content: `会议详细内容:\n1. 议题一讨论\n2. 议题二分析\n3. 下一步工作计划\n4. 任务分配`,
          meetingMinutes: meetingMinutes,
          minutesCreateTime: hasMinutes
            ? new Date(startTime.getTime() + 3600000).toISOString()
            : "",
          minutesCreator: hasMinutes ? participants[0] : "",
          status: statuses[Math.floor(Math.random() * statuses.length)],
          creator: '系统管理员',
          creator: "系统管理员",
          attachments: []
        }
      })
        };
      });
    },
    // 获取会议类型标签样式
    getMeetingTypeTag(type) {
      const typeMap = {
        research: 'primary',
        daily: 'success',
        project: 'warning',
        department: 'info',
        review: 'danger'
      }
      return typeMap[type] || 'info'
        research: "primary",
        daily: "success",
        project: "warning",
        department: "info",
        review: "danger"
      };
      return typeMap[type] || "info";
    },
    // 获取会议类型文本
    getMeetingTypeText(type) {
      const textMap = {
        research: '科研会议',
        daily: '日常会议',
        project: '项目会议',
        department: '部门会议',
        review: '评审会议'
      }
      return textMap[type] || type
        research: "科研会议",
        daily: "日常会议",
        project: "项目会议",
        department: "部门会议",
        review: "评审会议"
      };
      return textMap[type] || type;
    },
    // 获取状态标签样式
    getStatusTag(status) {
      const statusMap = {
        pending: 'primary',
        ongoing: 'success',
        completed: 'info',
        cancelled: 'danger'
      }
      return statusMap[status] || 'info'
        pending: "primary",
        ongoing: "success",
        completed: "info",
        cancelled: "danger"
      };
      return statusMap[status] || "info";
    },
    // 获取状态文本
    getStatusText(status) {
      const textMap = {
        pending: '待开始',
        ongoing: '进行中',
        completed: '已结束',
        cancelled: '已取消'
      }
      return textMap[status] || status
        pending: "待开始",
        ongoing: "进行中",
        completed: "已结束",
        cancelled: "已取消"
      };
      return textMap[status] || status;
    },
    // 格式化日期时间
    formatDateTime(dateTime) {
      if (!dateTime) return ''
      const date = new Date(dateTime)
      return date.toLocaleString('zh-CN')
      if (!dateTime) return "";
      const date = new Date(dateTime);
      return date.toLocaleString("zh-CN");
    },
    // 计算会议持续时间
    calculateDuration(record) {
      if (!record.startTime || !record.endTime) return ''
      const start = new Date(record.startTime)
      const end = new Date(record.endTime)
      const duration = (end - start) / (1000 * 60) // 分钟数
      if (!record.startTime || !record.endTime) return "";
      const start = new Date(record.startTime);
      const end = new Date(record.endTime);
      const duration = (end - start) / (1000 * 60); // 分钟数
      if (duration < 60) {
        return `${Math.round(duration)}分钟`
        return `${Math.round(duration)}分钟`;
      } else {
        const hours = Math.floor(duration / 60)
        const minutes = Math.round(duration % 60)
        return minutes > 0 ? `${hours}小时${minutes}分钟` : `${hours}小时`
        const hours = Math.floor(duration / 60);
        const minutes = Math.round(duration % 60);
        return minutes > 0 ? `${hours}小时${minutes}分钟` : `${hours}小时`;
      }
    },
    // 查询处理
    handleQuery() {
      this.pagination.currentPage = 1
      this.loadData()
      this.pagination.currentPage = 1;
      this.loadData();
    },
    // 重置查询
    handleReset() {
      this.queryParams = {
        meetingType: '',
        location: '',
        meetingType: "",
        location: "",
        dateRange: [],
        status: ''
      }
      this.pagination.currentPage = 1
      this.loadData()
        status: ""
      };
      this.pagination.currentPage = 1;
      this.loadData();
    },
    // 查看详情
    handleView(record) {
      this.currentRecord = { ...record }
      this.detailDialogVisible = true
      this.currentRecord = { ...record };
      this.detailDialogVisible = true;
    },
    // 新增记录
    handleAdd() {
      this.isEditing = false
      this.editForm = this.getDefaultFormData()
      this.editDialogVisible = true
      this.isEditing = false;
      this.editForm = this.getDefaultFormData();
      this.editDialogVisible = true;
      this.$nextTick(() => {
        this.$refs.editForm && this.$refs.editForm.clearValidate()
      })
        this.$refs.editForm && this.$refs.editForm.clearValidate();
      });
    },
    // 编辑记录
    handleEdit(record) {
      this.isEditing = true
      this.currentRecord = record
      this.editForm = { ...record }
      this.editDialogVisible = true
      this.detailDialogVisible = false
      this.isEditing = true;
      this.currentRecord = record;
      this.editForm = { ...record };
      this.editDialogVisible = true;
      this.detailDialogVisible = false;
      this.$nextTick(() => {
        this.$refs.editForm && this.$refs.editForm.clearValidate()
      })
        this.$refs.editForm && this.$refs.editForm.clearValidate();
      });
    },
    // 复制记录
    handleCopy(record) {
      this.isEditing = false
      const copiedRecord = { ...record }
      delete copiedRecord.id
      copiedRecord.title = copiedRecord.title + '(复制)'
      this.editForm = copiedRecord
      this.editDialogVisible = true
      this.isEditing = false;
      const copiedRecord = { ...record };
      delete copiedRecord.id;
      copiedRecord.title = copiedRecord.title + "(复制)";
      this.editForm = copiedRecord;
      this.editDialogVisible = true;
      this.$nextTick(() => {
        this.$refs.editForm && this.$refs.editForm.clearValidate()
      })
        this.$refs.editForm && this.$refs.editForm.clearValidate();
      });
    },
    // 删除记录
    handleDelete(record) {
      this.$confirm('确定要删除这条会议记录吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        // 模拟删除操作
        this.tableData = this.tableData.filter(item => item.id !== record.id)
        this.pagination.total = this.tableData.length
        this.$message.success('删除成功')
      }).catch(() => {})
      this.$confirm("确定要删除这条会议记录吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          // 模拟删除操作
          this.tableData = this.tableData.filter(item => item.id !== record.id);
          this.pagination.total = this.tableData.length;
          this.$message.success("删除成功");
        })
        .catch(() => {});
    },
    // 保存记录
    async handleSave() {
      try {
        const valid = await this.$refs.editForm.validate()
        if (!valid) return
        const valid = await this.$refs.editForm.validate();
        if (!valid) return;
        this.saveLoading = true
        this.saveLoading = true;
        // 模拟API调用
        await new Promise(resolve => setTimeout(resolve, 1000))
        await new Promise(resolve => setTimeout(resolve, 1000));
        this.$message.success(this.isEditing ? '保存成功' : '新增成功')
        this.editDialogVisible = false
        this.loadData()
        this.$message.success(this.isEditing ? "保存成功" : "新增成功");
        this.editDialogVisible = false;
        this.loadData();
      } catch (error) {
        console.error('保存失败:', error)
        this.$message.error('操作失败')
        console.error("保存失败:", error);
        this.$message.error("操作失败");
      } finally {
        this.saveLoading = false
        this.saveLoading = false;
      }
    },
    // 文件上传处理
    handleFileChange(file, fileList) {
      this.editForm.attachments = fileList
      this.editForm.attachments = fileList;
    },
    // 关闭详情对话框
    handleDetailClose() {
      this.detailDialogVisible = false
      this.currentRecord = {}
      this.detailDialogVisible = false;
      this.currentRecord = {};
    },
    // 关闭编辑对话框
    handleEditClose() {
      this.editDialogVisible = false
      this.currentRecord = {}
      this.editDialogVisible = false;
      this.currentRecord = {};
      this.$nextTick(() => {
        this.$refs.editForm && this.$refs.editForm.clearValidate()
      })
        this.$refs.editForm && this.$refs.editForm.clearValidate();
      });
    },
    // 导出数据
    exportData() {
      this.$message.success('导出功能开发中')
      this.$message.success("导出功能开发中");
    },
    // 分页大小变化
    handleSizeChange(size) {
      this.pagination.pageSize = size
      this.pagination.currentPage = 1
      this.loadData()
      this.pagination.pageSize = size;
      this.pagination.currentPage = 1;
      this.loadData();
    },
    // 当前页变化
    handleCurrentChange(page) {
      this.pagination.currentPage = page
      this.loadData()
      this.pagination.currentPage = page;
      this.loadData();
    },
    // 排序变化
    handleSortChange(sort) {
      console.log('排序变化:', sort)
      console.log("排序变化:", sort);
    },
    // 获取默认表单数据
    // 更新默认表单数据
    getDefaultFormData() {
      return {
        title: '',
        meetingType: '',
        title: "",
        meetingType: "",
        participants: [],
        location: '',
        startTime: '',
        endTime: '',
        summary: '',
        content: '',
        location: "",
        startTime: "",
        endTime: "",
        summary: "",
        content: "",
        meetingMinutes: "",
        minutesCreateTime: "",
        minutesCreator: "",
        attachments: []
      }
      };
    }
  }
}
};
</script>
<style scoped>
@@ -711,7 +984,28 @@
.attachment-item {
  margin-bottom: 8px;
}
.minutes-content {
  margin-bottom: 16px;
}
.minutes-meta {
  border-top: 1px solid #e4e7ed;
  padding-top: 12px;
}
/* 会议纪要文本区域样式 */
.minutes-textarea {
  font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
  font-size: 13px;
  line-height: 1.5;
}
/* 响应式调整 */
@media (max-width: 768px) {
  .minutes-content .el-card {
    margin: 0 -20px;
  }
}
/* 响应式设计 */
@media (max-width: 768px) {
  .page-header {