lululu 1 day ago
parent
commit
125ac7fbc0
24 changed files with 2057 additions and 30 deletions
  1. 5 0
      pom.xml
  2. 5 0
      ruoyi-common/pom.xml
  3. 104 0
      ruoyi-meeting/src/main/java/com/ruoyi/controller/MeetingRoomController.java
  4. 104 0
      ruoyi-meeting/src/main/java/com/ruoyi/controller/MeetingTopicController.java
  5. 104 0
      ruoyi-meeting/src/main/java/com/ruoyi/controller/MembersController.java
  6. 43 7
      ruoyi-meeting/src/main/java/com/ruoyi/domain/Meeting.java
  7. 102 0
      ruoyi-meeting/src/main/java/com/ruoyi/domain/MeetingRoom.java
  8. 63 0
      ruoyi-meeting/src/main/java/com/ruoyi/domain/MeetingTopic.java
  9. 63 0
      ruoyi-meeting/src/main/java/com/ruoyi/domain/Members.java
  10. 15 1
      ruoyi-meeting/src/main/java/com/ruoyi/domain/TopicLibrary.java
  11. 61 0
      ruoyi-meeting/src/main/java/com/ruoyi/mapper/MeetingRoomMapper.java
  12. 61 0
      ruoyi-meeting/src/main/java/com/ruoyi/mapper/MeetingTopicMapper.java
  13. 61 0
      ruoyi-meeting/src/main/java/com/ruoyi/mapper/MembersMapper.java
  14. 61 0
      ruoyi-meeting/src/main/java/com/ruoyi/service/IMeetingRoomService.java
  15. 61 0
      ruoyi-meeting/src/main/java/com/ruoyi/service/IMeetingTopicService.java
  16. 61 0
      ruoyi-meeting/src/main/java/com/ruoyi/service/IMembersService.java
  17. 93 0
      ruoyi-meeting/src/main/java/com/ruoyi/service/impl/MeetingRoomServiceImpl.java
  18. 93 0
      ruoyi-meeting/src/main/java/com/ruoyi/service/impl/MeetingTopicServiceImpl.java
  19. 93 0
      ruoyi-meeting/src/main/java/com/ruoyi/service/impl/MembersServiceImpl.java
  20. 41 2
      ruoyi-meeting/src/main/resources/mapper/meeting/MeetingMapper.xml
  21. 59 0
      ruoyi-meeting/src/main/resources/mapper/members/MembersMapper.xml
  22. 71 0
      ruoyi-meeting/src/main/resources/mapper/room/MeetingRoomMapper.xml
  23. 59 0
      ruoyi-meeting/src/main/resources/mapper/topic/MeetingTopicMapper.xml
  24. 574 20
      ruoyi-ui/src/views/meeting/meet/index.vue

+ 5 - 0
pom.xml

@@ -224,6 +224,11 @@
                 <version>${ruoyi.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>mybatis-plus-boot-starter</artifactId>
+                <version>3.5.2</version>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 

+ 5 - 0
ruoyi-common/pom.xml

@@ -35,6 +35,11 @@
             <artifactId>spring-boot-starter-security</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+        </dependency>
+
         <!-- pagehelper 分页插件 -->
         <dependency>
             <groupId>com.github.pagehelper</groupId>

+ 104 - 0
ruoyi-meeting/src/main/java/com/ruoyi/controller/MeetingRoomController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.controller;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.domain.MeetingRoom;
+import com.ruoyi.service.IMeetingRoomService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 会议室Controller
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+@RestController
+@RequestMapping("/room/room")
+public class MeetingRoomController extends BaseController
+{
+    @Autowired
+    private IMeetingRoomService meetingRoomService;
+
+    /**
+     * 查询会议室列表
+     */
+    @PreAuthorize("@ss.hasPermi('room:room:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(MeetingRoom meetingRoom)
+    {
+        startPage();
+        List<MeetingRoom> list = meetingRoomService.selectMeetingRoomList(meetingRoom);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出会议室列表
+     */
+    @PreAuthorize("@ss.hasPermi('room:room:export')")
+    @Log(title = "会议室", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, MeetingRoom meetingRoom)
+    {
+        List<MeetingRoom> list = meetingRoomService.selectMeetingRoomList(meetingRoom);
+        ExcelUtil<MeetingRoom> util = new ExcelUtil<MeetingRoom>(MeetingRoom.class);
+        util.exportExcel(response, list, "会议室数据");
+    }
+
+    /**
+     * 获取会议室详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('room:room:query')")
+    @GetMapping(value = "/{roomId}")
+    public AjaxResult getInfo(@PathVariable("roomId") Long roomId)
+    {
+        return success(meetingRoomService.selectMeetingRoomByRoomId(roomId));
+    }
+
+    /**
+     * 新增会议室
+     */
+    @PreAuthorize("@ss.hasPermi('room:room:add')")
+    @Log(title = "会议室", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody MeetingRoom meetingRoom)
+    {
+        return toAjax(meetingRoomService.insertMeetingRoom(meetingRoom));
+    }
+
+    /**
+     * 修改会议室
+     */
+    @PreAuthorize("@ss.hasPermi('room:room:edit')")
+    @Log(title = "会议室", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody MeetingRoom meetingRoom)
+    {
+        return toAjax(meetingRoomService.updateMeetingRoom(meetingRoom));
+    }
+
+    /**
+     * 删除会议室
+     */
+    @PreAuthorize("@ss.hasPermi('room:room:remove')")
+    @Log(title = "会议室", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{roomIds}")
+    public AjaxResult remove(@PathVariable Long[] roomIds)
+    {
+        return toAjax(meetingRoomService.deleteMeetingRoomByRoomIds(roomIds));
+    }
+}

+ 104 - 0
ruoyi-meeting/src/main/java/com/ruoyi/controller/MeetingTopicController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.controller;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.domain.MeetingTopic;
+import com.ruoyi.service.IMeetingTopicService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 会议议题关联表Controller
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+@RestController
+@RequestMapping("/topic/topic")
+public class MeetingTopicController extends BaseController
+{
+    @Autowired
+    private IMeetingTopicService meetingTopicService;
+
+    /**
+     * 查询会议议题关联表列表
+     */
+    @PreAuthorize("@ss.hasPermi('topic:topic:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(MeetingTopic meetingTopic)
+    {
+        startPage();
+        List<MeetingTopic> list = meetingTopicService.selectMeetingTopicList(meetingTopic);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出会议议题关联表列表
+     */
+    @PreAuthorize("@ss.hasPermi('topic:topic:export')")
+    @Log(title = "会议议题关联表", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, MeetingTopic meetingTopic)
+    {
+        List<MeetingTopic> list = meetingTopicService.selectMeetingTopicList(meetingTopic);
+        ExcelUtil<MeetingTopic> util = new ExcelUtil<MeetingTopic>(MeetingTopic.class);
+        util.exportExcel(response, list, "会议议题关联表数据");
+    }
+
+    /**
+     * 获取会议议题关联表详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('topic:topic:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(meetingTopicService.selectMeetingTopicById(id));
+    }
+
+    /**
+     * 新增会议议题关联表
+     */
+    @PreAuthorize("@ss.hasPermi('topic:topic:add')")
+    @Log(title = "会议议题关联表", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody MeetingTopic meetingTopic)
+    {
+        return toAjax(meetingTopicService.insertMeetingTopic(meetingTopic));
+    }
+
+    /**
+     * 修改会议议题关联表
+     */
+    @PreAuthorize("@ss.hasPermi('topic:topic:edit')")
+    @Log(title = "会议议题关联表", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody MeetingTopic meetingTopic)
+    {
+        return toAjax(meetingTopicService.updateMeetingTopic(meetingTopic));
+    }
+
+    /**
+     * 删除会议议题关联表
+     */
+    @PreAuthorize("@ss.hasPermi('topic:topic:remove')")
+    @Log(title = "会议议题关联表", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(meetingTopicService.deleteMeetingTopicByIds(ids));
+    }
+}

+ 104 - 0
ruoyi-meeting/src/main/java/com/ruoyi/controller/MembersController.java

@@ -0,0 +1,104 @@
+package com.ruoyi.controller;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.domain.Members;
+import com.ruoyi.service.IMembersService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 入会人员关联表Controller
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+@RestController
+@RequestMapping("/members/members")
+public class MembersController extends BaseController
+{
+    @Autowired
+    private IMembersService membersService;
+
+    /**
+     * 查询入会人员关联表列表
+     */
+    @PreAuthorize("@ss.hasPermi('members:members:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(Members members)
+    {
+        startPage();
+        List<Members> list = membersService.selectMembersList(members);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出入会人员关联表列表
+     */
+    @PreAuthorize("@ss.hasPermi('members:members:export')")
+    @Log(title = "入会人员关联表", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, Members members)
+    {
+        List<Members> list = membersService.selectMembersList(members);
+        ExcelUtil<Members> util = new ExcelUtil<Members>(Members.class);
+        util.exportExcel(response, list, "入会人员关联表数据");
+    }
+
+    /**
+     * 获取入会人员关联表详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('members:members:query')")
+    @GetMapping(value = "/{membersId}")
+    public AjaxResult getInfo(@PathVariable("membersId") Long membersId)
+    {
+        return success(membersService.selectMembersByMembersId(membersId));
+    }
+
+    /**
+     * 新增入会人员关联表
+     */
+    @PreAuthorize("@ss.hasPermi('members:members:add')")
+    @Log(title = "入会人员关联表", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody Members members)
+    {
+        return toAjax(membersService.insertMembers(members));
+    }
+
+    /**
+     * 修改入会人员关联表
+     */
+    @PreAuthorize("@ss.hasPermi('members:members:edit')")
+    @Log(title = "入会人员关联表", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody Members members)
+    {
+        return toAjax(membersService.updateMembers(members));
+    }
+
+    /**
+     * 删除入会人员关联表
+     */
+    @PreAuthorize("@ss.hasPermi('members:members:remove')")
+    @Log(title = "入会人员关联表", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{membersIds}")
+    public AjaxResult remove(@PathVariable Long[] membersIds)
+    {
+        return toAjax(membersService.deleteMembersByMembersIds(membersIds));
+    }
+}

+ 43 - 7
ruoyi-meeting/src/main/java/com/ruoyi/domain/Meeting.java

@@ -1,6 +1,9 @@
 package com.ruoyi.domain;
 
 import java.util.Date;
+import java.util.List;
+
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
@@ -46,6 +49,9 @@ public class Meeting extends BaseEntity
     @Excel(name = "会议室(外键)")
     private Long roomId;
 
+    @TableField(exist = false)
+    private MeetingRoom meetingRoom;
+
     /** 会议地址(选择会议室填充) */
     @Excel(name = "会议地址(选择会议室填充)")
     private String roomDetail;
@@ -57,7 +63,10 @@ public class Meeting extends BaseEntity
 
     /** 入会人员id(外键入会人员表) */
     @Excel(name = "入会人员id(外键入会人员表)")
-    private Long membersId;
+    private String membersId;
+
+    @TableField(exist = false)
+    private List<Members> members;
 
     /** 会议签到(0否1是) */
     @Excel(name = "会议签到(0否1是)")
@@ -89,7 +98,10 @@ public class Meeting extends BaseEntity
 
     /** 议题id(外键议题表) */
     @Excel(name = "议题id(外键议题表)")
-    private Long topicId;
+    private String topicId;
+
+    @TableField(exist = false)
+    private List<MeetingTopic> meetingTopic;
 
     /** 发布时间 */
     @JsonFormat(pattern = "yyyy-MM-dd")
@@ -99,7 +111,31 @@ public class Meeting extends BaseEntity
     /** 删除标识 */
     private Long delFlag;
 
-    public void setMeetingId(Long meetingId) 
+    public MeetingRoom getMeetingRoom() {
+        return meetingRoom;
+    }
+
+    public void setMeetingRoom(MeetingRoom meetingRoom) {
+        this.meetingRoom = meetingRoom;
+    }
+
+    public List<Members> getMembers() {
+        return members;
+    }
+
+    public void setMembers(List<Members> members) {
+        this.members = members;
+    }
+
+    public List<MeetingTopic> getMeetingTopic() {
+        return meetingTopic;
+    }
+
+    public void setMeetingTopic(List<MeetingTopic> meetingTopic) {
+        this.meetingTopic = meetingTopic;
+    }
+
+    public void setMeetingId(Long meetingId)
     {
         this.meetingId = meetingId;
     }
@@ -180,12 +216,12 @@ public class Meeting extends BaseEntity
     {
         return enterTime;
     }
-    public void setMembersId(Long membersId) 
+    public void setMembersId(String membersId)
     {
         this.membersId = membersId;
     }
 
-    public Long getMembersId() 
+    public String getMembersId()
     {
         return membersId;
     }
@@ -252,12 +288,12 @@ public class Meeting extends BaseEntity
     {
         return selectText;
     }
-    public void setTopicId(Long topicId) 
+    public void setTopicId(String topicId)
     {
         this.topicId = topicId;
     }
 
-    public Long getTopicId() 
+    public String getTopicId()
     {
         return topicId;
     }

+ 102 - 0
ruoyi-meeting/src/main/java/com/ruoyi/domain/MeetingRoom.java

@@ -0,0 +1,102 @@
+package com.ruoyi.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 会议室对象 meeting_room
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+public class MeetingRoom extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 会议室id */
+    private Long roomId;
+
+    /** 会议室名称 */
+    private String roomName;
+
+    /** 会议室地址(填充) */
+    private String roomDetail;
+
+    /** 会议室类型 */
+    private Long roomType;
+
+    /** 会议室规模 */
+    private Long roomScale;
+
+    /** 会议室状态(是否占用) */
+    private Long roomState;
+
+    public void setRoomId(Long roomId) 
+    {
+        this.roomId = roomId;
+    }
+
+    public Long getRoomId() 
+    {
+        return roomId;
+    }
+    public void setRoomName(String roomName) 
+    {
+        this.roomName = roomName;
+    }
+
+    public String getRoomName() 
+    {
+        return roomName;
+    }
+    public void setRoomDetail(String roomDetail) 
+    {
+        this.roomDetail = roomDetail;
+    }
+
+    public String getRoomDetail() 
+    {
+        return roomDetail;
+    }
+    public void setRoomType(Long roomType) 
+    {
+        this.roomType = roomType;
+    }
+
+    public Long getRoomType() 
+    {
+        return roomType;
+    }
+    public void setRoomScale(Long roomScale) 
+    {
+        this.roomScale = roomScale;
+    }
+
+    public Long getRoomScale() 
+    {
+        return roomScale;
+    }
+    public void setRoomState(Long roomState) 
+    {
+        this.roomState = roomState;
+    }
+
+    public Long getRoomState() 
+    {
+        return roomState;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("roomId", getRoomId())
+            .append("roomName", getRoomName())
+            .append("roomDetail", getRoomDetail())
+            .append("roomType", getRoomType())
+            .append("roomScale", getRoomScale())
+            .append("roomState", getRoomState())
+            .toString();
+    }
+}

+ 63 - 0
ruoyi-meeting/src/main/java/com/ruoyi/domain/MeetingTopic.java

@@ -0,0 +1,63 @@
+package com.ruoyi.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 会议议题关联表对象 meeting_topic
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+public class MeetingTopic extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** $column.columnComment */
+    private Long id;
+
+    /** 会议ID */
+    private Long meetingId;
+
+    /** 议题库ID */
+    private Long topicId;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+    public void setMeetingId(Long meetingId) 
+    {
+        this.meetingId = meetingId;
+    }
+
+    public Long getMeetingId() 
+    {
+        return meetingId;
+    }
+    public void setTopicId(Long topicId) 
+    {
+        this.topicId = topicId;
+    }
+
+    public Long getTopicId() 
+    {
+        return topicId;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("meetingId", getMeetingId())
+            .append("topicId", getTopicId())
+            .toString();
+    }
+}

+ 63 - 0
ruoyi-meeting/src/main/java/com/ruoyi/domain/Members.java

@@ -0,0 +1,63 @@
+package com.ruoyi.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 入会人员关联表对象 members
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+public class Members extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 入会id */
+    private Long membersId;
+
+    /** 入会角色(字典值) */
+    private Long membersRole;
+
+    /** 入会人员名称 */
+    private String membersName;
+
+    public void setMembersId(Long membersId) 
+    {
+        this.membersId = membersId;
+    }
+
+    public Long getMembersId() 
+    {
+        return membersId;
+    }
+    public void setMembersRole(Long membersRole) 
+    {
+        this.membersRole = membersRole;
+    }
+
+    public Long getMembersRole() 
+    {
+        return membersRole;
+    }
+    public void setMembersName(String membersName) 
+    {
+        this.membersName = membersName;
+    }
+
+    public String getMembersName() 
+    {
+        return membersName;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("membersId", getMembersId())
+            .append("membersRole", getMembersRole())
+            .append("membersName", getMembersName())
+            .toString();
+    }
+}

+ 15 - 1
ruoyi-meeting/src/main/java/com/ruoyi/domain/TopicLibrary.java

@@ -1,6 +1,9 @@
 package com.ruoyi.domain;
 
 import java.util.Date;
+import java.util.List;
+
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
@@ -44,6 +47,9 @@ public class TopicLibrary extends BaseEntity
     @Excel(name = "上传人")
     private String uplpadUser;
 
+    @TableField(exist = false)
+    private List<Members> members;
+
     /** 上传时间 */
     @JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "上传时间", width = 30, dateFormat = "yyyy-MM-dd")
@@ -64,7 +70,15 @@ public class TopicLibrary extends BaseEntity
     @Excel(name = "议题状态")
     private Long topicState;
 
-    public void setTopicId(Long topicId) 
+    public List<Members> getMembers() {
+        return members;
+    }
+
+    public void setMembers(List<Members> members) {
+        this.members = members;
+    }
+
+    public void setTopicId(Long topicId)
     {
         this.topicId = topicId;
     }

+ 61 - 0
ruoyi-meeting/src/main/java/com/ruoyi/mapper/MeetingRoomMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.mapper;
+
+import java.util.List;
+import com.ruoyi.domain.MeetingRoom;
+
+/**
+ * 会议室Mapper接口
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+public interface MeetingRoomMapper 
+{
+    /**
+     * 查询会议室
+     * 
+     * @param roomId 会议室主键
+     * @return 会议室
+     */
+    public MeetingRoom selectMeetingRoomByRoomId(Long roomId);
+
+    /**
+     * 查询会议室列表
+     * 
+     * @param meetingRoom 会议室
+     * @return 会议室集合
+     */
+    public List<MeetingRoom> selectMeetingRoomList(MeetingRoom meetingRoom);
+
+    /**
+     * 新增会议室
+     * 
+     * @param meetingRoom 会议室
+     * @return 结果
+     */
+    public int insertMeetingRoom(MeetingRoom meetingRoom);
+
+    /**
+     * 修改会议室
+     * 
+     * @param meetingRoom 会议室
+     * @return 结果
+     */
+    public int updateMeetingRoom(MeetingRoom meetingRoom);
+
+    /**
+     * 删除会议室
+     * 
+     * @param roomId 会议室主键
+     * @return 结果
+     */
+    public int deleteMeetingRoomByRoomId(Long roomId);
+
+    /**
+     * 批量删除会议室
+     * 
+     * @param roomIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteMeetingRoomByRoomIds(Long[] roomIds);
+}

+ 61 - 0
ruoyi-meeting/src/main/java/com/ruoyi/mapper/MeetingTopicMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.mapper;
+
+import java.util.List;
+import com.ruoyi.domain.MeetingTopic;
+
+/**
+ * 会议议题关联表Mapper接口
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+public interface MeetingTopicMapper 
+{
+    /**
+     * 查询会议议题关联表
+     * 
+     * @param id 会议议题关联表主键
+     * @return 会议议题关联表
+     */
+    public MeetingTopic selectMeetingTopicById(Long id);
+
+    /**
+     * 查询会议议题关联表列表
+     * 
+     * @param meetingTopic 会议议题关联表
+     * @return 会议议题关联表集合
+     */
+    public List<MeetingTopic> selectMeetingTopicList(MeetingTopic meetingTopic);
+
+    /**
+     * 新增会议议题关联表
+     * 
+     * @param meetingTopic 会议议题关联表
+     * @return 结果
+     */
+    public int insertMeetingTopic(MeetingTopic meetingTopic);
+
+    /**
+     * 修改会议议题关联表
+     * 
+     * @param meetingTopic 会议议题关联表
+     * @return 结果
+     */
+    public int updateMeetingTopic(MeetingTopic meetingTopic);
+
+    /**
+     * 删除会议议题关联表
+     * 
+     * @param id 会议议题关联表主键
+     * @return 结果
+     */
+    public int deleteMeetingTopicById(Long id);
+
+    /**
+     * 批量删除会议议题关联表
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteMeetingTopicByIds(Long[] ids);
+}

+ 61 - 0
ruoyi-meeting/src/main/java/com/ruoyi/mapper/MembersMapper.java

@@ -0,0 +1,61 @@
+package com.ruoyi.mapper;
+
+import java.util.List;
+import com.ruoyi.domain.Members;
+
+/**
+ * 入会人员关联表Mapper接口
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+public interface MembersMapper 
+{
+    /**
+     * 查询入会人员关联表
+     * 
+     * @param membersId 入会人员关联表主键
+     * @return 入会人员关联表
+     */
+    public Members selectMembersByMembersId(Long membersId);
+
+    /**
+     * 查询入会人员关联表列表
+     * 
+     * @param members 入会人员关联表
+     * @return 入会人员关联表集合
+     */
+    public List<Members> selectMembersList(Members members);
+
+    /**
+     * 新增入会人员关联表
+     * 
+     * @param members 入会人员关联表
+     * @return 结果
+     */
+    public int insertMembers(Members members);
+
+    /**
+     * 修改入会人员关联表
+     * 
+     * @param members 入会人员关联表
+     * @return 结果
+     */
+    public int updateMembers(Members members);
+
+    /**
+     * 删除入会人员关联表
+     * 
+     * @param membersId 入会人员关联表主键
+     * @return 结果
+     */
+    public int deleteMembersByMembersId(Long membersId);
+
+    /**
+     * 批量删除入会人员关联表
+     * 
+     * @param membersIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteMembersByMembersIds(Long[] membersIds);
+}

+ 61 - 0
ruoyi-meeting/src/main/java/com/ruoyi/service/IMeetingRoomService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.service;
+
+import java.util.List;
+import com.ruoyi.domain.MeetingRoom;
+
+/**
+ * 会议室Service接口
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+public interface IMeetingRoomService 
+{
+    /**
+     * 查询会议室
+     * 
+     * @param roomId 会议室主键
+     * @return 会议室
+     */
+    public MeetingRoom selectMeetingRoomByRoomId(Long roomId);
+
+    /**
+     * 查询会议室列表
+     * 
+     * @param meetingRoom 会议室
+     * @return 会议室集合
+     */
+    public List<MeetingRoom> selectMeetingRoomList(MeetingRoom meetingRoom);
+
+    /**
+     * 新增会议室
+     * 
+     * @param meetingRoom 会议室
+     * @return 结果
+     */
+    public int insertMeetingRoom(MeetingRoom meetingRoom);
+
+    /**
+     * 修改会议室
+     * 
+     * @param meetingRoom 会议室
+     * @return 结果
+     */
+    public int updateMeetingRoom(MeetingRoom meetingRoom);
+
+    /**
+     * 批量删除会议室
+     * 
+     * @param roomIds 需要删除的会议室主键集合
+     * @return 结果
+     */
+    public int deleteMeetingRoomByRoomIds(Long[] roomIds);
+
+    /**
+     * 删除会议室信息
+     * 
+     * @param roomId 会议室主键
+     * @return 结果
+     */
+    public int deleteMeetingRoomByRoomId(Long roomId);
+}

+ 61 - 0
ruoyi-meeting/src/main/java/com/ruoyi/service/IMeetingTopicService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.service;
+
+import java.util.List;
+import com.ruoyi.domain.MeetingTopic;
+
+/**
+ * 会议议题关联表Service接口
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+public interface IMeetingTopicService 
+{
+    /**
+     * 查询会议议题关联表
+     * 
+     * @param id 会议议题关联表主键
+     * @return 会议议题关联表
+     */
+    public MeetingTopic selectMeetingTopicById(Long id);
+
+    /**
+     * 查询会议议题关联表列表
+     * 
+     * @param meetingTopic 会议议题关联表
+     * @return 会议议题关联表集合
+     */
+    public List<MeetingTopic> selectMeetingTopicList(MeetingTopic meetingTopic);
+
+    /**
+     * 新增会议议题关联表
+     * 
+     * @param meetingTopic 会议议题关联表
+     * @return 结果
+     */
+    public int insertMeetingTopic(MeetingTopic meetingTopic);
+
+    /**
+     * 修改会议议题关联表
+     * 
+     * @param meetingTopic 会议议题关联表
+     * @return 结果
+     */
+    public int updateMeetingTopic(MeetingTopic meetingTopic);
+
+    /**
+     * 批量删除会议议题关联表
+     * 
+     * @param ids 需要删除的会议议题关联表主键集合
+     * @return 结果
+     */
+    public int deleteMeetingTopicByIds(Long[] ids);
+
+    /**
+     * 删除会议议题关联表信息
+     * 
+     * @param id 会议议题关联表主键
+     * @return 结果
+     */
+    public int deleteMeetingTopicById(Long id);
+}

+ 61 - 0
ruoyi-meeting/src/main/java/com/ruoyi/service/IMembersService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.service;
+
+import java.util.List;
+import com.ruoyi.domain.Members;
+
+/**
+ * 入会人员关联表Service接口
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+public interface IMembersService 
+{
+    /**
+     * 查询入会人员关联表
+     * 
+     * @param membersId 入会人员关联表主键
+     * @return 入会人员关联表
+     */
+    public Members selectMembersByMembersId(Long membersId);
+
+    /**
+     * 查询入会人员关联表列表
+     * 
+     * @param members 入会人员关联表
+     * @return 入会人员关联表集合
+     */
+    public List<Members> selectMembersList(Members members);
+
+    /**
+     * 新增入会人员关联表
+     * 
+     * @param members 入会人员关联表
+     * @return 结果
+     */
+    public int insertMembers(Members members);
+
+    /**
+     * 修改入会人员关联表
+     * 
+     * @param members 入会人员关联表
+     * @return 结果
+     */
+    public int updateMembers(Members members);
+
+    /**
+     * 批量删除入会人员关联表
+     * 
+     * @param membersIds 需要删除的入会人员关联表主键集合
+     * @return 结果
+     */
+    public int deleteMembersByMembersIds(Long[] membersIds);
+
+    /**
+     * 删除入会人员关联表信息
+     * 
+     * @param membersId 入会人员关联表主键
+     * @return 结果
+     */
+    public int deleteMembersByMembersId(Long membersId);
+}

+ 93 - 0
ruoyi-meeting/src/main/java/com/ruoyi/service/impl/MeetingRoomServiceImpl.java

@@ -0,0 +1,93 @@
+package com.ruoyi.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.mapper.MeetingRoomMapper;
+import com.ruoyi.domain.MeetingRoom;
+import com.ruoyi.service.IMeetingRoomService;
+
+/**
+ * 会议室Service业务层处理
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+@Service
+public class MeetingRoomServiceImpl implements IMeetingRoomService 
+{
+    @Autowired
+    private MeetingRoomMapper meetingRoomMapper;
+
+    /**
+     * 查询会议室
+     * 
+     * @param roomId 会议室主键
+     * @return 会议室
+     */
+    @Override
+    public MeetingRoom selectMeetingRoomByRoomId(Long roomId)
+    {
+        return meetingRoomMapper.selectMeetingRoomByRoomId(roomId);
+    }
+
+    /**
+     * 查询会议室列表
+     * 
+     * @param meetingRoom 会议室
+     * @return 会议室
+     */
+    @Override
+    public List<MeetingRoom> selectMeetingRoomList(MeetingRoom meetingRoom)
+    {
+        return meetingRoomMapper.selectMeetingRoomList(meetingRoom);
+    }
+
+    /**
+     * 新增会议室
+     * 
+     * @param meetingRoom 会议室
+     * @return 结果
+     */
+    @Override
+    public int insertMeetingRoom(MeetingRoom meetingRoom)
+    {
+        return meetingRoomMapper.insertMeetingRoom(meetingRoom);
+    }
+
+    /**
+     * 修改会议室
+     * 
+     * @param meetingRoom 会议室
+     * @return 结果
+     */
+    @Override
+    public int updateMeetingRoom(MeetingRoom meetingRoom)
+    {
+        return meetingRoomMapper.updateMeetingRoom(meetingRoom);
+    }
+
+    /**
+     * 批量删除会议室
+     * 
+     * @param roomIds 需要删除的会议室主键
+     * @return 结果
+     */
+    @Override
+    public int deleteMeetingRoomByRoomIds(Long[] roomIds)
+    {
+        return meetingRoomMapper.deleteMeetingRoomByRoomIds(roomIds);
+    }
+
+    /**
+     * 删除会议室信息
+     * 
+     * @param roomId 会议室主键
+     * @return 结果
+     */
+    @Override
+    public int deleteMeetingRoomByRoomId(Long roomId)
+    {
+        return meetingRoomMapper.deleteMeetingRoomByRoomId(roomId);
+    }
+}

+ 93 - 0
ruoyi-meeting/src/main/java/com/ruoyi/service/impl/MeetingTopicServiceImpl.java

@@ -0,0 +1,93 @@
+package com.ruoyi.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.mapper.MeetingTopicMapper;
+import com.ruoyi.domain.MeetingTopic;
+import com.ruoyi.service.IMeetingTopicService;
+
+/**
+ * 会议议题关联表Service业务层处理
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+@Service
+public class MeetingTopicServiceImpl implements IMeetingTopicService 
+{
+    @Autowired
+    private MeetingTopicMapper meetingTopicMapper;
+
+    /**
+     * 查询会议议题关联表
+     * 
+     * @param id 会议议题关联表主键
+     * @return 会议议题关联表
+     */
+    @Override
+    public MeetingTopic selectMeetingTopicById(Long id)
+    {
+        return meetingTopicMapper.selectMeetingTopicById(id);
+    }
+
+    /**
+     * 查询会议议题关联表列表
+     * 
+     * @param meetingTopic 会议议题关联表
+     * @return 会议议题关联表
+     */
+    @Override
+    public List<MeetingTopic> selectMeetingTopicList(MeetingTopic meetingTopic)
+    {
+        return meetingTopicMapper.selectMeetingTopicList(meetingTopic);
+    }
+
+    /**
+     * 新增会议议题关联表
+     * 
+     * @param meetingTopic 会议议题关联表
+     * @return 结果
+     */
+    @Override
+    public int insertMeetingTopic(MeetingTopic meetingTopic)
+    {
+        return meetingTopicMapper.insertMeetingTopic(meetingTopic);
+    }
+
+    /**
+     * 修改会议议题关联表
+     * 
+     * @param meetingTopic 会议议题关联表
+     * @return 结果
+     */
+    @Override
+    public int updateMeetingTopic(MeetingTopic meetingTopic)
+    {
+        return meetingTopicMapper.updateMeetingTopic(meetingTopic);
+    }
+
+    /**
+     * 批量删除会议议题关联表
+     * 
+     * @param ids 需要删除的会议议题关联表主键
+     * @return 结果
+     */
+    @Override
+    public int deleteMeetingTopicByIds(Long[] ids)
+    {
+        return meetingTopicMapper.deleteMeetingTopicByIds(ids);
+    }
+
+    /**
+     * 删除会议议题关联表信息
+     * 
+     * @param id 会议议题关联表主键
+     * @return 结果
+     */
+    @Override
+    public int deleteMeetingTopicById(Long id)
+    {
+        return meetingTopicMapper.deleteMeetingTopicById(id);
+    }
+}

+ 93 - 0
ruoyi-meeting/src/main/java/com/ruoyi/service/impl/MembersServiceImpl.java

@@ -0,0 +1,93 @@
+package com.ruoyi.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.mapper.MembersMapper;
+import com.ruoyi.domain.Members;
+import com.ruoyi.service.IMembersService;
+
+/**
+ * 入会人员关联表Service业务层处理
+ * 
+ * @author lu
+ * @date 2025-10-15
+ */
+@Service
+public class MembersServiceImpl implements IMembersService 
+{
+    @Autowired
+    private MembersMapper membersMapper;
+
+    /**
+     * 查询入会人员关联表
+     * 
+     * @param membersId 入会人员关联表主键
+     * @return 入会人员关联表
+     */
+    @Override
+    public Members selectMembersByMembersId(Long membersId)
+    {
+        return membersMapper.selectMembersByMembersId(membersId);
+    }
+
+    /**
+     * 查询入会人员关联表列表
+     * 
+     * @param members 入会人员关联表
+     * @return 入会人员关联表
+     */
+    @Override
+    public List<Members> selectMembersList(Members members)
+    {
+        return membersMapper.selectMembersList(members);
+    }
+
+    /**
+     * 新增入会人员关联表
+     * 
+     * @param members 入会人员关联表
+     * @return 结果
+     */
+    @Override
+    public int insertMembers(Members members)
+    {
+        return membersMapper.insertMembers(members);
+    }
+
+    /**
+     * 修改入会人员关联表
+     * 
+     * @param members 入会人员关联表
+     * @return 结果
+     */
+    @Override
+    public int updateMembers(Members members)
+    {
+        return membersMapper.updateMembers(members);
+    }
+
+    /**
+     * 批量删除入会人员关联表
+     * 
+     * @param membersIds 需要删除的入会人员关联表主键
+     * @return 结果
+     */
+    @Override
+    public int deleteMembersByMembersIds(Long[] membersIds)
+    {
+        return membersMapper.deleteMembersByMembersIds(membersIds);
+    }
+
+    /**
+     * 删除入会人员关联表信息
+     * 
+     * @param membersId 入会人员关联表主键
+     * @return 结果
+     */
+    @Override
+    public int deleteMembersByMembersId(Long membersId)
+    {
+        return membersMapper.deleteMembersByMembersId(membersId);
+    }
+}

+ 41 - 2
ruoyi-meeting/src/main/resources/mapper/meeting/MeetingMapper.xml

@@ -29,7 +29,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </resultMap>
 
     <sql id="selectMeetingVo">
-        select meeting_id, meeting_type, meeting_state, meeting_name, start_time, end_time, room_id, room_detail, enter_time, members_id, meeting_check, check_mode, meeting_notice, notice_text, maintenance, check_organization, select_text, topic_id, meeting_time, remark, del_flag from meeting
+        SELECT
+            m.meeting_id,
+            m.meeting_type,
+            m.meeting_state,
+            m.meeting_name,
+            m.start_time,
+            m.end_time,
+            m.room_id,
+            mr.room_name,
+            mr.room_detail AS room_detail_info,
+            mr.room_type,
+            mr.room_scale,
+            mr.room_state,
+            m.room_detail,
+            m.enter_time,
+            m.members_id,
+            m.meeting_check,
+            m.check_mode,
+            m.meeting_notice,
+            m.notice_text,
+            m.maintenance,
+            m.check_organization,
+            m.select_text,
+            m.topic_id,
+            m.meeting_time,
+            m.remark,
+            m.del_flag,
+            mt.topic_id AS meeting_topic_id,
+            tl.topic_name,
+            tl.uplpad_user,
+            tl.upload_time,
+            tl.up_dept,
+            tl.report,
+            tl.topic_state AS topic_state
+        FROM meeting m
+                 LEFT JOIN meeting_room mr ON m.room_id = mr.room_id
+                 LEFT JOIN meeting_topic mt ON m.meeting_id = mt.meeting_id
+                 LEFT JOIN topic_library tl ON mt.topic_id = tl.topic_id
+                 LEFT JOIN members ms ON m.meeting_id = ms.members_id
+        WHERE m.del_flag = 0
     </sql>
 
     <select id="selectMeetingList" parameterType="Meeting" resultMap="MeetingResult">
@@ -47,7 +86,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     
     <select id="selectMeetingByMeetingId" parameterType="Long" resultMap="MeetingResult">
         <include refid="selectMeetingVo"/>
-        where meeting_id = #{meetingId}
+        where m.meeting_id = #{meetingId}
     </select>
 
     <insert id="insertMeeting" parameterType="Meeting" useGeneratedKeys="true" keyProperty="meetingId">

+ 59 - 0
ruoyi-meeting/src/main/resources/mapper/members/MembersMapper.xml

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.mapper.MembersMapper">
+    
+    <resultMap type="Members" id="MembersResult">
+        <result property="membersId"    column="members_id"    />
+        <result property="membersRole"    column="members_role"    />
+        <result property="membersName"    column="members_name"    />
+    </resultMap>
+
+    <sql id="selectMembersVo">
+        select members_id, members_role, members_name from members
+    </sql>
+
+    <select id="selectMembersList" parameterType="Members" resultMap="MembersResult">
+        <include refid="selectMembersVo"/>
+        <where>  
+        </where>
+    </select>
+    
+    <select id="selectMembersByMembersId" parameterType="Long" resultMap="MembersResult">
+        <include refid="selectMembersVo"/>
+        where members_id = #{membersId}
+    </select>
+
+    <insert id="insertMembers" parameterType="Members" useGeneratedKeys="true" keyProperty="membersId">
+        insert into members
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="membersRole != null">members_role,</if>
+            <if test="membersName != null">members_name,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="membersRole != null">#{membersRole},</if>
+            <if test="membersName != null">#{membersName},</if>
+         </trim>
+    </insert>
+
+    <update id="updateMembers" parameterType="Members">
+        update members
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="membersRole != null">members_role = #{membersRole},</if>
+            <if test="membersName != null">members_name = #{membersName},</if>
+        </trim>
+        where members_id = #{membersId}
+    </update>
+
+    <delete id="deleteMembersByMembersId" parameterType="Long">
+        delete from members where members_id = #{membersId}
+    </delete>
+
+    <delete id="deleteMembersByMembersIds" parameterType="String">
+        delete from members where members_id in 
+        <foreach item="membersId" collection="array" open="(" separator="," close=")">
+            #{membersId}
+        </foreach>
+    </delete>
+</mapper>

+ 71 - 0
ruoyi-meeting/src/main/resources/mapper/room/MeetingRoomMapper.xml

@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.mapper.MeetingRoomMapper">
+    
+    <resultMap type="MeetingRoom" id="MeetingRoomResult">
+        <result property="roomId"    column="room_id"    />
+        <result property="roomName"    column="room_name"    />
+        <result property="roomDetail"    column="room_detail"    />
+        <result property="roomType"    column="room_type"    />
+        <result property="roomScale"    column="room_scale"    />
+        <result property="roomState"    column="room_state"    />
+    </resultMap>
+
+    <sql id="selectMeetingRoomVo">
+        select room_id, room_name, room_detail, room_type, room_scale, room_state from meeting_room
+    </sql>
+
+    <select id="selectMeetingRoomList" parameterType="MeetingRoom" resultMap="MeetingRoomResult">
+        <include refid="selectMeetingRoomVo"/>
+        <where>  
+        </where>
+    </select>
+    
+    <select id="selectMeetingRoomByRoomId" parameterType="Long" resultMap="MeetingRoomResult">
+        <include refid="selectMeetingRoomVo"/>
+        where room_id = #{roomId}
+    </select>
+
+    <insert id="insertMeetingRoom" parameterType="MeetingRoom" useGeneratedKeys="true" keyProperty="roomId">
+        insert into meeting_room
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="roomName != null">room_name,</if>
+            <if test="roomDetail != null">room_detail,</if>
+            <if test="roomType != null">room_type,</if>
+            <if test="roomScale != null">room_scale,</if>
+            <if test="roomState != null">room_state,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="roomName != null">#{roomName},</if>
+            <if test="roomDetail != null">#{roomDetail},</if>
+            <if test="roomType != null">#{roomType},</if>
+            <if test="roomScale != null">#{roomScale},</if>
+            <if test="roomState != null">#{roomState},</if>
+         </trim>
+    </insert>
+
+    <update id="updateMeetingRoom" parameterType="MeetingRoom">
+        update meeting_room
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="roomName != null">room_name = #{roomName},</if>
+            <if test="roomDetail != null">room_detail = #{roomDetail},</if>
+            <if test="roomType != null">room_type = #{roomType},</if>
+            <if test="roomScale != null">room_scale = #{roomScale},</if>
+            <if test="roomState != null">room_state = #{roomState},</if>
+        </trim>
+        where room_id = #{roomId}
+    </update>
+
+    <delete id="deleteMeetingRoomByRoomId" parameterType="Long">
+        delete from meeting_room where room_id = #{roomId}
+    </delete>
+
+    <delete id="deleteMeetingRoomByRoomIds" parameterType="String">
+        delete from meeting_room where room_id in 
+        <foreach item="roomId" collection="array" open="(" separator="," close=")">
+            #{roomId}
+        </foreach>
+    </delete>
+</mapper>

+ 59 - 0
ruoyi-meeting/src/main/resources/mapper/topic/MeetingTopicMapper.xml

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.mapper.MeetingTopicMapper">
+    
+    <resultMap type="MeetingTopic" id="MeetingTopicResult">
+        <result property="id"    column="id"    />
+        <result property="meetingId"    column="meeting_id"    />
+        <result property="topicId"    column="topic_id"    />
+    </resultMap>
+
+    <sql id="selectMeetingTopicVo">
+        select id, meeting_id, topic_id from meeting_topic
+    </sql>
+
+    <select id="selectMeetingTopicList" parameterType="MeetingTopic" resultMap="MeetingTopicResult">
+        <include refid="selectMeetingTopicVo"/>
+        <where>  
+        </where>
+    </select>
+    
+    <select id="selectMeetingTopicById" parameterType="Long" resultMap="MeetingTopicResult">
+        <include refid="selectMeetingTopicVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertMeetingTopic" parameterType="MeetingTopic" useGeneratedKeys="true" keyProperty="id">
+        insert into meeting_topic
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="meetingId != null">meeting_id,</if>
+            <if test="topicId != null">topic_id,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="meetingId != null">#{meetingId},</if>
+            <if test="topicId != null">#{topicId},</if>
+         </trim>
+    </insert>
+
+    <update id="updateMeetingTopic" parameterType="MeetingTopic">
+        update meeting_topic
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="meetingId != null">meeting_id = #{meetingId},</if>
+            <if test="topicId != null">topic_id = #{topicId},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteMeetingTopicById" parameterType="Long">
+        delete from meeting_topic where id = #{id}
+    </delete>
+
+    <delete id="deleteMeetingTopicByIds" parameterType="String">
+        delete from meeting_topic where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 574 - 20
ruoyi-ui/src/views/meeting/meet/index.vue

@@ -46,13 +46,15 @@
       <el-form-item label="会议状态" prop="meetingState">
         <el-select v-model="queryParams.meetingState" placeholder="请选择会议状态" clearable>
           <el-option
-            v-for="dict in dict.type.metting_state"
+            v-for="dict in dict.type.meeting_state"
             :key="dict.value"
             :label="dict.label"
             :value="dict.value"
           />
         </el-select>
-      </el-form-item><el-form-item label="会议时间">
+      </el-form-item>
+
+      <el-form-item label="会议时间">
         <el-date-picker
           v-model="queryParams.startTime"
           type="datetime"
@@ -120,7 +122,7 @@
           v-hasPermi="['meeting:meeting:export']"
         >导出</el-button>
       </el-col>
-      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"> </right-toolbar>
     </el-row>
 
     <el-table v-loading="loading" :data="meetingList" @selection-change="handleSelectionChange">
@@ -191,7 +193,7 @@
               :key="dict.value"
               :label="dict.label"
               :value="parseInt(dict.value)"
-            ></el-option>
+            > </el-option>
           </el-select>
         </el-form-item>
         <!-- <el-form-item label="会议状态" prop="meetingState">
@@ -316,31 +318,102 @@
           <el-cascader
             v-model="form.checkOrganization"
             :options="userTreeOptions"
-            :props="{ multiple: false, checkStrictly: true }"
+            :props="{ multiple: true, 
+                      checkStrictly: true }"
             placeholder="请选择承办组织"
             style="width: 300px; margin-right: 10px;"
             clearable
           />
         </el-form-item>
         <el-form-item label="会后查阅附件" prop="selectText">
-          <el-input v-model="form.selectText" placeholder="请输入会后查阅附件" />
+          <el-switch
+            v-model="form.selectText"
+            active-value="1"
+            inactive-value="0"
+            active-text="启用"
+            inactive-text="禁用"
+          />
         </el-form-item>
-        <el-form-item label="发布时间" prop="meetingTime">
+        <!-- <el-form-item label="发布时间" prop="meetingTime">
           <el-date-picker clearable
             v-model="form.meetingTime"
-            type="date"
+            type="datetime"
             value-format="yyyy-MM-dd"
             placeholder="请选择发布时间">
           </el-date-picker>
-        </el-form-item>
-        <el-form-item label="删除标识" prop="delFlag">
-          <el-input v-model="form.delFlag" placeholder="请输入删除标识0正常1删除" />
-        </el-form-item>
+        </el-form-item> -->
         <el-form-item label="备注" prop="remark">
           <el-input v-model="form.remark" placeholder="请输入备注" />
         </el-form-item>
-        <el-form-item label="议题" prop="topicId">
-          <el-input v-model="form.topicId" placeholder="请输入议题id" />
+        <el-form-item label="议题设置" prop="topicList">
+          <div class="topic-list-container">
+            <!-- 添加议题按钮 -->
+            <el-button
+              type="primary"
+              plain
+              size="mini"
+              icon="el-icon-plus"
+              @click="handleAddTopic()"
+            >
+              添加议题
+            </el-button>
+
+            <!-- 右侧操作按钮 -->
+            <div style="float: right; margin-left: 10px;">
+              <el-button type="primary" size="mini" @click="handleTopicLibrary">议题库</el-button>
+              <el-button type="primary" size="mini" @click="handleDownloadTemplate">下载模板</el-button>
+              <el-button type="primary" size="mini" @click="handleImport">导入</el-button>
+            </div>
+
+            <!-- 已添加议题列表 -->
+            <div v-if="form.topicList.length > 0" class="topic-items">
+              <div
+                v-for="(topic, index) in form.topicList"
+                :key="index"
+                class="topic-item"
+              >
+                <!-- 展开/收起图标 -->
+                <el-button
+                  type="text"
+                  size="small"
+                  @click="toggleTopic(index)"
+                >
+                  <i :class="['el-icon-arrow-right', { 'el-icon-arrow-down': topic.expanded }]"> </i>
+                </el-button>
+
+                <!-- 议题名称 -->
+                <span class="topic-name">{{ topic.topicName }}</span>
+
+                <!-- 操作按钮(右对齐) -->
+                <div class="topic-actions">
+                  <el-button
+                    type="text"
+                    size="mini"
+                    icon="el-icon-edit"
+                    @click="editTopic(index)"
+                  />
+                  <el-button
+                    type="text"
+                    size="mini"
+                    icon="el-icon-delete"
+                    @click="deleteTopic(index)"
+                  />
+                  <el-button
+                    type="text"
+                    size="mini"
+                    icon="el-icon-view"
+                    v-if="topic.filePath"
+                    @click="previewFile(topic)"
+                  />
+                </div>
+
+                <!-- 内容详情(展开后显示) -->
+                <div v-show="topic.expanded" class="topic-details">
+                  <p> <strong>议题密码:</strong>{{ topic.topicName || '无' }}</p>
+                </div>
+              </div>
+            </div>
+          </div>
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -348,11 +421,132 @@
         <el-button @click="cancel">取 消</el-button>
       </div>
     </el-dialog>
+
+
+    <!-- 议题库弹窗 -->
+    <el-dialog :title="'议题库'" :visible.sync="topicDialogVisible" width="800px" append-to-body>
+      <el-form :model="topicQuery" inline size="small">
+        <el-form-item label="议题名称">
+          <el-input
+            v-model="topicQuery.topicName"
+            placeholder="请输入议题名称"
+            clearable
+            @keyup.enter.native="handleTopicSearch"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleTopicSearch">搜索</el-button>
+          <el-button icon="el-icon-refresh" size="mini" @click="resetTopicQuery">重置</el-button>
+        </el-form-item>
+      </el-form>
+
+      <el-table
+        :data="topicList"
+        style="width: 100%"
+        @selection-change="handleTopicSelectionChange"
+        border
+      >
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="议题名称" prop="topicName" />
+        <el-table-column label="议题状态" prop="topicState">
+          <template slot-scope="scope">
+            <span>{{ scope.row.topicState === '1' ? '待上会' : '已上会' }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination
+        v-show="topicTotal > 0"
+        :total="topicTotal"
+        :page.sync="topicQuery.pageNum"
+        :limit.sync="topicQuery.pageSize"
+        @pagination="getTopicList"
+      />
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="topicDialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="confirmTopicSelect">确 定</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 议题新增 -->
+      <el-dialog :title="topicModalTitle" :visible.sync="topicManageVisible" width="600px" append-to-body>
+      <el-form ref="topicFormRef" :model="formTopic" :rules="topicRules" label-width="120px" label-position="left">
+        <el-form-item label="议题名称" prop="topicName">
+          <el-input v-model="formTopic.topicName" placeholder="请输入议题名称" />
+        </el-form-item>
+
+        <el-form-item label="议题密码" prop="topicPassword">
+          <el-input v-model="formTopic.topicPassword" placeholder="请输入议题密码" />
+          <div style="font-size: 12px; color: #999; margin-top: 4px;">不填就无密码</div>
+        </el-form-item>
+
+        <el-form-item label="议题内容" prop="topicText">
+          <el-input v-model="formTopic.topicText" type="textarea" placeholder="请输入议题内容" />
+        </el-form-item>
+
+        <!-- 文件上传 -->
+        <el-form-item label="文件上传">
+          <el-upload
+            action=""
+            :auto-upload="false"
+            :on-change="handleFileChange"
+            :file-list="fileList"
+            accept=".pdf,.doc,.docx,.ppt,.pptx"
+            show-file-list
+            list-type="text"
+          >
+            <el-button size="small" type="primary">点击上传</el-button>
+          </el-upload>
+        </el-form-item>
+
+        <!-- 添加与会人员 -->
+        <el-form-item label="添加与会人员" prop="members">
+          <div class="attendees-container">
+            <div v-for="(item, index) in formTopic.members" :key="index" class="attendee-item">
+              <el-select
+                v-model="item.role"
+                placeholder="请选择角色"
+                style="width: 120px; margin-right: 10px;"
+                clearable
+              >
+                <el-option
+                  v-for="dict in dict.type.members"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                />
+              </el-select>
+
+              <treeselect
+                v-model="item.userIds"
+                :options="deptOptions"
+                :normalizer="normalizer"
+                :multiple="true"
+                :disable-branch-nodes="true"
+                placeholder="请选择员工"
+                style="width: 300px; margin-right: 10px;"
+              />
+
+              <el-button type="text" icon="el-icon-delete" @click="removeTopicMember(index)" />
+            </div>
+            <el-button type="text" icon="el-icon-plus" @click="addTopicMember" style="margin-top: 10px;" />
+          </div>
+        </el-form-item>
+      </el-form>
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="cancel">取 消</el-button>
+        <el-button type="primary" @click="submitTopicForm">确 定</el-button>
+      </div>
+    </el-dialog>
+    
   </div>
 </template>
 
 <script>
 import { listMeeting, getMeeting, delMeeting, addMeeting, updateMeeting } from "@/api/meeting/meeting";
+import { listLibrary, getLibrary, delLibrary, addLibrary, updateLibrary } from "@/api/meeting/library";
 import { deptTreeSelect } from "@/api/system/user"
 import { listDept } from '@/api/system/dept'
 import Treeselect from '@riophae/vue-treeselect'
@@ -383,6 +577,30 @@ export default {
       meetingList: [],
       userTreeOptions: [], // 用户树形数据,需从接口获取
       deptOptions: [],
+      fileList: [],
+      topicDialogVisible: false,
+      topicManageVisible: false,
+      topicModalTitle: '议题管理',
+      topicQuery: {
+        pageNum: 1,
+        pageSize: 10,
+        topicName: null
+      },
+      selectedTopicId: null,     // 单个选中议题ID(用于编辑)
+      selectedTopics: [],        // 多选议题(用于删除或最终确认)
+      topicSingle: true,         // 非单个禁用
+      topicMultiple: true,       // 非多个禁用
+      formTopic: {
+        topicName: '',
+        topicPassword: '',
+        topicText: '',
+        filePath: '',
+        fileName: '',
+        members: []
+      },
+      topicList: [],
+      topic:null,
+      topicTotal: 0,
       // 弹出层标题
       title: "",
       // 是否显示弹出层
@@ -401,8 +619,45 @@ export default {
         endTime:null,
       },
       // 表单参数
-      form: {},
+      form: {
+        meetingId: null,
+        meetingType: null,
+        meetingState: null,
+        meetingName: null,
+        startTime: null,
+        endTime: null,
+        roomId: null,
+        roomDetail: null,
+        enterTime: null,
+        members: [],
+        checkmode: null,
+        meetingCheck: null,
+        meetingNotice: "0",
+        noticeText: null,
+        maintenance: null,
+        checkOrganization: null,
+        selectText: null,
+        meetingTime: this.getCurrentDateTime(),
+        delFlag: null,
+        remark: null,
+        topicId: null,
+        topicList: []
+      },
       // 表单校验
+      topicRules: {
+        topicName: [
+          { required: true, message: '议题名称不能为空', trigger: 'blur' }
+        ],
+        members: [
+          { validator: (rule, value, callback) => {
+            if (!value || value.length === 0) {
+              callback(new Error('请至少添加一名与会人员'));
+            } else {
+              callback();
+            }
+          }, trigger: 'blur' }
+        ]
+      },
       rules: {
         meetingType: [
           { required: true, message: "会议类型不能为空", trigger: "blur" }
@@ -439,8 +694,239 @@ export default {
     this.loadUserTree();
   },
   methods: {
+    // 添加议题与会人员
+    addTopicMember() {
+      this.formTopic.members.push({ role: null, userIds: [] });
+    },
+
+    // 删除议题与会人员
+    removeTopicMember(index) {
+      if (this.formTopic.members.length > 1) {
+        this.formTopic.members.splice(index, 1);
+      } else {
+        this.$message.warning("至少保留一位与会人员");
+      }
+    },
+    toggleTopic(index) {
+      this.form.topicList[index].expanded = !this.form.topicList[index].expanded;
+    },
+
+    // 编辑议题
+    editTopic(index) {
+      const topic = { ...this.form.topicList[index] };
+      this.formTopic = topic;
+      this.openTopicForm('修改议题');
+    },
+
+    // 删除议题
+    deleteTopic(index) {
+      this.$modal.confirm(`是否确认删除该议题?`).then(() => {
+        this.form.topicList.splice(index, 1);
+        this.$message.success('删除成功');
+      });
+    },
+
+    // 预览文件
+    previewFile(topic) {
+      const url = `/meeting/library/download/${topic.filePath}`;
+      window.open(url, '_blank');
+    },
+
+    // 打开议题管理弹窗
+    handleAddTopic() {
+      this.getTopicList();
+      this.topicManageVisible = true;
+    },
+
+    // 获取议题列表
+    getTopicList() {
+      listLibrary(this.topicQuery).then(response => {
+        this.topicList = response.rows;
+        this.topicTotal = response.total;
+      });
+    },
+
+    // 重置查询条件
+    resetTopicQuery() {
+      this.resetForm('topicQuery');
+      this.getTopicList();
+    },
+
+    // 多选处理
+    handleTopicSelectionChange(selection) {
+      this.selectedTopics = selection;
+      this.topicMultiple = !selection.length;
+      this.topicSingle = selection.length !== 1;
+    },
+
+    // 新增议题
+    handleTopicAdd() {
+      this.formTopic = { members: [] };
+      this.openTopicForm('添加议题');
+    },
+
+    // 编辑议题
+    handleTopicEdit(row) {
+      const topicId = row.topicId || this.selectedTopicId;
+      getLibrary(topicId).then(res => {
+        this.formTopic = res.data;
+        this.openTopicForm('修改议题');
+      });
+    },
+
+    // 删除议题
+    handleTopicDelete(row) {
+      const ids = row.topicId || this.selectedTopics.map(item => item.topicId).join(',');
+      this.$modal.confirm(`是否确认删除议题编号为 "${ids}" 的数据项?`).then(() => {
+        delLibrary(ids).then(() => {
+          this.$modal.msgSuccess("删除成功");
+          this.getTopicList();
+        });
+      });
+    },
+
+    // 提交议题表单(新增/修改)
+    submitTopicForm() {
+      this.$refs.topicFormRef.validate(valid => {
+        if (valid) {
+          if (this.formTopic.topicId != null) {
+            updateLibrary(this.formTopic).then(() => {
+              this.$modal.msgSuccess("更新成功");
+              this.closeTopicForm();
+              this.getTopicList(); // 刷新议题库列表
+            });
+          } else {
+            addLibrary(this.formTopic).then(response => {
+              this.$modal.msgSuccess("新增成功");
+              this.closeTopicForm();
+              this.getTopicList();
+
+              // 将新创建的议题添加到当前会议的 topicList
+              const newTopic = { ...this.formTopic, topicId: response.data.topicId };
+              this.form.topicList.push(newTopic);
+            });
+          }
+        }
+      });
+    },
+    handleFileChange(file, fileList) {
+      // 限制只保留一个文件
+      if (fileList.length > 1) {
+        this.fileList = [fileList[fileList.length - 1]]; // 保留最新上传的
+      } else {
+        this.fileList = fileList;
+      }
+
+      // 可选:读取文件内容(如需预览或校验)
+      const reader = new FileReader();
+      reader.onload = (e) => {
+        // 例如:打印文件内容(适用于文本文件)
+        console.log('文件内容:', e.target.result);
+      };
+      reader.readAsText(file.raw);
+
+      // 存储文件到 form 对象中(用于提交)
+      this.form.file = file.raw; // raw 是原始 File 对象
+    },
+    // 确认选取议题
+    confirmSelectedTopic() {
+      if (this.selectedTopics.length === 0) {
+        this.$message.warning('请至少选择一个议题');
+        return;
+      }
+     const selected = this.selectedTopics.map(item => ({
+        topicId: item.topicId,
+        topicName: item.topicName,
+        topicPassword: item.topicPassword,
+        topicText: item.topicText,
+        filePath: item.filePath,
+        fileName: item.fileName,
+        members: item.members || []
+      }));
+      // 添加到本地 topicList
+      this.form.topicList.push(...selected);
+
+      this.topicManageVisible = false;
+      this.$message.success('议题已添加');
+    },
+
+    // 打开议题表单弹窗(可抽离为单独弹窗)
+    openTopicForm(title) {
+       this.formTopic = {
+        topicName: '',
+        topicPassword: '',
+        topicText: '',
+        filePath: '',
+        fileName: '',
+        members: [{ role: null, userIds: [] }] // 默认一条
+      };
+      this.topicModalTitle = title;
+      this.$nextTick(() => {
+        this.$refs.topicFormRef?.clearValidate();
+      });
+    },
+    closeTopicForm() {
+      this.topicModalTitle = '';
+      this.formTopic = {};
+    },
+    // 打开议题库
+    handleLibrary() {
+      this.getTopicList();
+      this.topicDialogVisible = true;
+    },
+
+    // 查询议题列表
+    getTopicList() {
+      listLibrary(this.topicQuery).then(response => {
+        this.topicList = response.rows;
+        this.topicTotal = response.total;
+      });
+    },
+
+    // 搜索议题
+    handleTopicSearch() {
+      this.topicQuery.pageNum = 1;
+      this.getTopicList();
+    },
+
+    // 重置查询条件
+    resetTopicQuery() {
+      this.resetForm('topicQuery');
+      this.handleTopicSearch();
+    },
+
+    // 处理选中变化
+    handleTopicSelectionChange(selection) {
+      this.selectedTopics = selection;
+    },
+
+    // 确认选择议题
+    confirmTopicSelect() {
+      if (this.selectedTopics.length === 0) {
+        this.$message.warning('请至少选择一个议题');
+        return;
+      }
+
+      // 将选中的议题 ID 添加到 form.topicId
+      const topicIds = this.selectedTopics.map(item => item.topicId);
+      this.form.topicId = topicIds.join(',');
+      console.log(this.form.topicId);
+
+      this.topicDialogVisible = false;
+      this.$message.success('已成功添加议题');
+    },
+    handleTopicLibrary() {
+      this.handleLibrary();
+    },
+    handleDownloadTemplate() {
+      this.$message.info('开始下载模板');
+    },
+    handleImport() {
+      this.$message.info('开始导入');
+    },
     loadUserTree() {
       deptTreeSelect().then(response => {
+        console.log(response.data)
         this.userTreeOptions = response.data;
       });
       listDept().then(response => {
@@ -520,13 +1006,25 @@ export default {
         maintenance: null,
         checkOrganization: null,
         selectText: null,
-        topicId: null,
-        meetingTime: null,
+        meetingTime: this.getCurrentDateTime(),
         delFlag: null,
-        remark: null
+        remark: null,
+        topicId: null,
+        topicList: []
       };
       this.resetForm("form");
     },
+    // 获取当前日期时间字符串
+    getCurrentDateTime() {
+      const now = new Date();
+      const year = now.getFullYear();
+      const month = String(now.getMonth() + 1).padStart(2, '0');
+      const day = String(now.getDate()).padStart(2, '0');
+      const hour = String(now.getHours()).padStart(2, '0');
+      const minute = String(now.getMinutes()).padStart(2, '0');
+      const second = String(now.getSeconds()).padStart(2, '0');
+      return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
+    },
     /** 搜索按钮操作 */
     handleQuery() {
       this.queryParams.pageNum = 1;
@@ -596,15 +1094,24 @@ export default {
       }, `meeting_${new Date().getTime()}.xlsx`)
     },
     normalizer(node) {
+      if (node.userId) {
+        return {
+          id: node.userId,
+          label: node.userName || node.nickName,
+          children: null
+        };
+      }
+      // 否则作为部门节点处理
       if (node.children && !node.children.length) {
-        delete node.children
+        delete node.children;
       }
       return {
         id: node.deptId,
         label: node.deptName,
         children: node.children
       }
-    }
+    },
+    
   }
 };
 </script>
@@ -621,4 +1128,51 @@ export default {
   align-items: center;
   gap: 10px;
 }
+
+.topic-setting-container {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 10px 0;
+  border-bottom: 1px solid #e4e7ed;
+}
+.topic-list-container {
+  margin-top: 10px;
+}
+
+.topic-items {
+  margin-top: 10px;
+  border: 1px solid #e4e7ed;
+  border-radius: 4px;
+}
+
+.topic-item {
+  padding: 10px 15px;
+  border-bottom: 1px solid #f0f0f0;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.topic-item:last-child {
+  border-bottom: none;
+}
+
+.topic-name {
+  flex: 1;
+  font-weight: 500;
+}
+
+.topic-actions {
+  display: flex;
+  gap: 8px;
+}
+
+.topic-details {
+  margin-top: 8px;
+  padding: 8px 0;
+  border-top: 1px dashed #e4e7ed;
+  color: #666;
+  font-size: 12px;
+}
 </style>