Newspaper před 3 měsíci
rodič
revize
e023cddbe4
56 změnil soubory, kde provedl 1866 přidání a 94 odebrání
  1. 6 6
      app-admin/pom.xml
  2. 142 0
      app-admin/src/main/java/com/ruoyi/web/controller/system/EventController.java
  3. 24 0
      app-admin/src/main/java/com/ruoyi/web/controller/system/ProjectsController.java
  4. 3 4
      app-admin/src/main/java/com/ruoyi/web/domain/dto/VillageService/VillageServiceAddRequest.java
  5. 3 4
      app-admin/src/main/java/com/ruoyi/web/domain/dto/VillageService/VillageServiceEditRequest.java
  6. 3 4
      app-admin/src/main/java/com/ruoyi/web/domain/dto/VillageService/VillageServiceQueryRequest.java
  7. 49 0
      app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventAddRequest.java
  8. 38 0
      app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventAssignAddRequest.java
  9. 42 0
      app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventAssignEditRequest.java
  10. 38 0
      app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventAssignQueryRequest.java
  11. 73 0
      app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventEditRequest.java
  12. 33 0
      app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventHandleRequest.java
  13. 51 0
      app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventQueryRequest.java
  14. 29 0
      app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventReassignRequest.java
  15. 27 0
      app-admin/src/main/java/com/ruoyi/web/domain/dto/projects/ProjectsCompletedRequest.java
  16. 1 1
      app-admin/src/main/java/com/ruoyi/web/domain/dto/villageSpecial/VillageSpecialAddRequest.java
  17. 1 1
      app-admin/src/main/java/com/ruoyi/web/domain/dto/villageSpecial/VillageSpecialEditRequest.java
  18. 1 1
      app-admin/src/main/java/com/ruoyi/web/domain/dto/villageSpecial/VillageSpecialQueryRequest.java
  19. 1 1
      app-admin/src/main/java/com/ruoyi/web/domain/dto/villageTradition/VillageTraditionAddRequest.java
  20. 1 1
      app-admin/src/main/java/com/ruoyi/web/domain/dto/villageTradition/VillageTraditionEditRequest.java
  21. 1 1
      app-admin/src/main/java/com/ruoyi/web/domain/dto/villageTradition/VillageTraditionQueryRequest.java
  22. 88 0
      app-admin/src/main/java/com/ruoyi/web/domain/entity/Event.java
  23. 58 0
      app-admin/src/main/java/com/ruoyi/web/domain/entity/EventAssign.java
  24. 1 1
      app-admin/src/main/java/com/ruoyi/web/domain/entity/VillageService.java
  25. 1 1
      app-admin/src/main/java/com/ruoyi/web/domain/entity/VillageSpecial.java
  26. 1 1
      app-admin/src/main/java/com/ruoyi/web/domain/entity/VillageTradition.java
  27. 2 2
      app-admin/src/main/java/com/ruoyi/web/domain/vo/VillageServiceVO.java
  28. 1 1
      app-admin/src/main/java/com/ruoyi/web/domain/vo/VillageSpecial/BaseVillageSpecialVO.java
  29. 4 4
      app-admin/src/main/java/com/ruoyi/web/domain/vo/VillageSpecial/SpecialVOFactory.java
  30. 72 0
      app-admin/src/main/java/com/ruoyi/web/domain/vo/event/EventPersonInfoVO.java
  31. 90 0
      app-admin/src/main/java/com/ruoyi/web/domain/vo/event/EventVO.java
  32. 16 0
      app-admin/src/main/java/com/ruoyi/web/mapper/EventAssignMapper.java
  33. 15 0
      app-admin/src/main/java/com/ruoyi/web/mapper/EventMapper.java
  34. 12 0
      app-admin/src/main/java/com/ruoyi/web/service/EventAssignService.java
  35. 38 0
      app-admin/src/main/java/com/ruoyi/web/service/EventService.java
  36. 6 0
      app-admin/src/main/java/com/ruoyi/web/service/ProjectsService.java
  37. 20 0
      app-admin/src/main/java/com/ruoyi/web/service/impl/EventAssignServiceImpl.java
  38. 488 0
      app-admin/src/main/java/com/ruoyi/web/service/impl/EventServiceImpl.java
  39. 28 0
      app-admin/src/main/java/com/ruoyi/web/service/impl/ProjectsServiceImpl.java
  40. 6 22
      app-admin/src/main/java/com/ruoyi/web/service/impl/VillageServiceServiceImpl.java
  41. 7 7
      app-admin/src/main/java/com/ruoyi/web/service/impl/VillageSpecialServiceImpl.java
  42. 4 4
      app-admin/src/main/java/com/ruoyi/web/service/impl/VillageTraditionServiceImpl.java
  43. 86 0
      app-admin/src/main/java/generator/domain/VillageService.java
  44. 15 0
      app-admin/src/main/java/generator/mapper/VillageServiceMapper.java
  45. 11 0
      app-admin/src/main/java/generator/service/VillageServiceService.java
  46. 20 0
      app-admin/src/main/java/generator/service/impl/VillageServiceServiceImpl.java
  47. 22 0
      app-admin/src/main/resources/mapper/web/EventAssignMapper.xml
  48. 30 0
      app-admin/src/main/resources/mapper/web/EventMapper.xml
  49. 1 1
      app-admin/src/main/resources/mapper/web/VillageSpecialMapper.xml
  50. 1 1
      app-admin/src/main/resources/mapper/web/VillageTraditionMapper.xml
  51. 21 2
      app-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
  52. 12 1
      app-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
  53. 24 10
      app-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
  54. 31 3
      app-system/src/main/resources/mapper/system/SysUserMapper.xml
  55. 6 5
      pom.xml
  56. 61 4
      sql/sql.sql

+ 6 - 6
app-admin/pom.xml

@@ -120,15 +120,15 @@
                     </execution>
                 </executions>
             </plugin>
-            <plugin>   
-                <groupId>org.apache.maven.plugins</groupId>   
-                <artifactId>maven-war-plugin</artifactId>   
-                <version>3.1.0</version>   
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <version>3.1.0</version>
                 <configuration>
                     <failOnMissingWebXml>false</failOnMissingWebXml>
                     <warName>${project.artifactId}</warName>
-                </configuration>   
-           </plugin>   
+                </configuration>
+            </plugin>
         </plugins>
         <finalName>${project.artifactId}</finalName>
 

+ 142 - 0
app-admin/src/main/java/com/ruoyi/web/controller/system/EventController.java

@@ -0,0 +1,142 @@
+package com.ruoyi.web.controller.system;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.web.domain.dto.event.*;
+import com.ruoyi.web.domain.entity.Event;
+import com.ruoyi.web.domain.vo.event.EventVO;
+import com.ruoyi.web.service.EventService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 事件管理控制器
+ */
+@Api(tags = "事件管理")
+@RestController
+@RequestMapping("/system/event")
+public class EventController extends BaseController {
+
+    @Autowired
+    private EventService eventService;
+
+    /**
+     * 添加事件
+     */
+    @ApiOperation("添加事件")
+    @PostMapping("/add")
+    public AjaxResult addEvent(@RequestBody EventAddRequest eventAddRequest) {
+        if (eventAddRequest == null) {
+            return error("请求参数为空");
+        }
+        Integer id = eventService.addEvent(eventAddRequest);
+        return success(id);
+    }
+
+    /**
+     * 删除事件
+     */
+    @ApiOperation("删除事件")
+    @PostMapping("/delete")
+    public AjaxResult deleteEvent(@RequestBody Map<String, String> paramsMap) {
+        String ids = paramsMap.get("ids");
+        if (StrUtil.isBlank(ids)) {
+            return error("请求参数为空");
+        }
+        boolean b = eventService.deleteEvent(ids);
+        if (b) {
+            return success("删除成功");
+        }
+        return error("删除失败");
+    }
+
+    /**
+     * 编辑事件
+     */
+    @ApiOperation("编辑事件")
+    @PutMapping("/edit")
+    public AjaxResult editEvent(@RequestBody EventEditRequest eventEditRequest) {
+        if (eventEditRequest == null) {
+            return error("请求参数为空");
+        }
+        eventService.editEvent(eventEditRequest);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 根据ID查询事件详情(支持管理员和负责人查询)
+     */
+    @ApiOperation("查询事件详情")
+    @GetMapping("/get")
+    public AjaxResult getEventById(@RequestParam int id) {
+        if (ObjectUtil.isEmpty(id)) {
+            return error("请求参数为空");
+        }
+        EventVO eventVO = eventService.getEventById(id);
+        return success(eventVO);
+    }
+
+    /**
+     * 分页查询事件列表(支持管理员和负责人查询)
+     */
+    @ApiOperation("分页查询事件列表")
+    @PostMapping("/list/page")
+    public AjaxResult listEventByPage(@RequestBody EventQueryRequest eventQueryRequest) {
+        if (eventQueryRequest == null) {
+            return error("请求参数为空");
+        }
+        Page<EventVO> listEventVOByPage = eventService.getListEventByPage(eventQueryRequest);
+        return success(listEventVOByPage);
+    }
+
+    /**
+     * 处理事件
+     */
+    @ApiOperation("处理事件")
+    @PostMapping("/handle")
+    public AjaxResult handleEvent(@RequestBody EventHandleRequest eventHandleRequest) {
+        try {
+            Integer eventId = eventHandleRequest.getEventId();
+            Integer personId = eventHandleRequest.getPersonId();
+            String processResult = eventHandleRequest.getProcessResult();
+            Event event = eventService.getById(eventId);
+            if(ObjectUtil.isEmpty(event)){
+                return error("事件不存在");
+            }
+            boolean result = eventService.handleEvent(eventId, personId, processResult);
+            if (result) {
+                return success("事件处理成功");
+            } else {
+                return error("事件已被他人处理");
+            }
+        } catch (Exception e) {
+            return error(e.getMessage());
+        }
+    }
+
+    /**
+     * 重新派发事件
+     */
+    @ApiOperation("重新派发事件")
+    @PostMapping("/reassign")
+    @PreAuthorize("@ss.hasPermi('system:role:admin')")
+    public AjaxResult reassignEvent(@RequestBody EventReassignRequest eventReassignRequest) {
+        try {
+            Integer eventId = eventReassignRequest.getEventId();
+            List<Integer> personIds = eventReassignRequest.getPersonIds();
+            eventService.reassignEvent(eventId, personIds);
+            return success("重新派发成功");
+        } catch (Exception e) {
+            return error(e.getMessage());
+        }
+    }
+} 

+ 24 - 0
app-admin/src/main/java/com/ruoyi/web/controller/system/ProjectsController.java

@@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.web.domain.dto.projects.ProjectsAddRequest;
+import com.ruoyi.web.domain.dto.projects.ProjectsCompletedRequest;
 import com.ruoyi.web.domain.dto.projects.ProjectsEditRequest;
 import com.ruoyi.web.domain.dto.projects.ProjectsQueryRequest;
 import com.ruoyi.web.domain.vo.ProjectsVO;
@@ -14,6 +15,7 @@ import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Date;
 import java.util.Map;
 
 import static com.ruoyi.common.core.domain.AjaxResult.error;
@@ -80,6 +82,28 @@ public class ProjectsController {
         return AjaxResult.success();
     }
 
+    /**
+     * 项目建成
+     *
+     * @param projectsCompletedRequest
+     * @return
+     */
+    @ApiOperation("项目建成")
+    @PostMapping("/completed")
+    public AjaxResult completedProjects(@RequestBody ProjectsCompletedRequest projectsCompletedRequest) {
+        Integer id = projectsCompletedRequest.getId();
+        Date actualCompletionDate = projectsCompletedRequest.getActualCompletionDate();
+        if (id <= 0 || actualCompletionDate == null) {
+            return error("请求参数为空");
+        }
+        boolean b = projectsService.completedProjects(id, actualCompletionDate);
+        if (b) {
+            return AjaxResult.success("操作成功");
+        } else {
+            return AjaxResult.error("操作失败");
+        }
+
+    }
 
     /**
      * 根据id获取项目

+ 3 - 4
app-admin/src/main/java/com/ruoyi/web/domain/dto/VillageService/VillageServiceAddRequest.java

@@ -4,7 +4,6 @@ import io.swagger.annotations.ApiModel;
 import lombok.Data;
 
 import java.io.Serializable;
-import java.util.List;
 
 /**
  * 乡村振兴产业服务与支持添加请求
@@ -21,14 +20,14 @@ public class VillageServiceAddRequest implements Serializable {
     private String title;
 
     /**
-     * 标签 ["1","2"]
+     * 标签
      */
-    private List<String> tag;
+    private String tag;
 
     /**
      * 类型 1-图文,2-视频
      */
-    private Integer type;
+    private String type;
 
     /**
      * 内容

+ 3 - 4
app-admin/src/main/java/com/ruoyi/web/domain/dto/VillageService/VillageServiceEditRequest.java

@@ -4,7 +4,6 @@ import io.swagger.annotations.ApiModel;
 import lombok.Data;
 
 import java.io.Serializable;
-import java.util.List;
 
 /**
  * 乡村振兴产业服务与支持编辑请求
@@ -25,14 +24,14 @@ public class VillageServiceEditRequest implements Serializable {
     private String title;
 
     /**
-     * 标签 ["1","2"]
+     * 标签
      */
-    private List<String> tag;
+    private String tag;
 
     /**
      * 类型 1-图文,2-视频
      */
-    private Integer type;
+    private String type;
 
     /**
      * 内容

+ 3 - 4
app-admin/src/main/java/com/ruoyi/web/domain/dto/VillageService/VillageServiceQueryRequest.java

@@ -7,7 +7,6 @@ import lombok.EqualsAndHashCode;
 
 import java.io.Serializable;
 import java.util.Date;
-import java.util.List;
 
 /**
  * 乡村振兴产业服务与支持查询请求
@@ -20,12 +19,12 @@ import java.util.List;
 public class VillageServiceQueryRequest extends PageRequest implements Serializable {
 
     /**
-     * 标签 ["1","2"]
+     * 标签
      */
-    private List<String> tag;
+    private String tag;
 
     /**
-     * 关键词(标题或标签或内容)
+     * 关键词(标题或内容)
      */
     private String keyword;
 

+ 49 - 0
app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventAddRequest.java

@@ -0,0 +1,49 @@
+package com.ruoyi.web.domain.dto.event;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 事件添加请求
+ *
+ * @TableName event
+ */
+@ApiModel(value = "EventAddRequest", description = "事件添加请求参数")
+@Data
+public class EventAddRequest implements Serializable {
+
+    /**
+     * 事发时间
+     */
+    private Date occurTime;
+
+    /**
+     * 事件类别,0-矛盾纠纷类/1-消防隐患类/2-安全隐患类/3-社会治安类/4-环境治理类/5-反诈宣传类
+     */
+    private Integer type;
+
+    /**
+     * 事发地点
+     */
+    private String location;
+
+    /**
+     * 事件描述
+     */
+    private String description;
+
+    /**
+     * 照片
+     */
+    private String photoUrl;
+
+    /**
+     * 填报人ID(村民id)
+     */
+    private Integer submitterId;
+
+    private static final long serialVersionUID = 1L;
+}

+ 38 - 0
app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventAssignAddRequest.java

@@ -0,0 +1,38 @@
+package com.ruoyi.web.domain.dto.event;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 事件分配添加请求
+ *
+ * @TableName event
+ */
+@ApiModel(value = "EventAssignAddRequest", description = "事件分配添加请求参数")
+@Data
+public class EventAssignAddRequest implements Serializable {
+
+    /**
+     * 事件ID
+     */
+    private Integer eventId;
+
+    /**
+     * 负责人ID
+     */
+    private Integer personId;
+
+    /**
+     * 状态(0未完结 1本人已完结 2其他人已完结)
+     */
+    private String status;
+
+    /**
+     * 是否重新分配(0否 1是)
+     */
+    private String isReassign;
+
+    private static final long serialVersionUID = 1L;
+}

+ 42 - 0
app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventAssignEditRequest.java

@@ -0,0 +1,42 @@
+package com.ruoyi.web.domain.dto.event;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 事件分配 编辑请求
+ *
+ * @TableName event
+ */
+@ApiModel(value = "EventAssignEditRequest", description = "事件分配编辑请求")
+@Data
+public class EventAssignEditRequest implements Serializable {
+    /**
+     * 分配ID
+     */
+    private Integer id;
+
+    /**
+     * 事件ID
+     */
+    private Integer eventId;
+
+    /**
+     * 负责人ID
+     */
+    private Integer personId;
+
+    /**
+     * 状态(0未完结 1本人已完结 2其他人已完结)
+     */
+    private String status;
+
+    /**
+     * 是否重新分配(0否 1是)
+     */
+    private String isReassign;
+
+    private static final long serialVersionUID = 1L;
+}

+ 38 - 0
app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventAssignQueryRequest.java

@@ -0,0 +1,38 @@
+package com.ruoyi.web.domain.dto.event;
+
+import com.ruoyi.web.common.PageRequest;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * 事件分配查询请求参数
+ */
+@ApiModel(value = "EventAssignQueryRequest", description = "事件分配查询请求参数")
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class EventAssignQueryRequest extends PageRequest implements Serializable {
+    /**
+     * 事件ID
+     */
+    private Integer eventId;
+
+    /**
+     * 负责人ID
+     */
+    private Integer personId;
+
+    /**
+     * 状态(0未完结 1本人已完结 2其他人已完结)
+     */
+    private String status;
+
+    /**
+     * 是否重新分配(0否 1是)
+     */
+    private String isReassign;
+
+    private static final long serialVersionUID = 1L;
+}

+ 73 - 0
app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventEditRequest.java

@@ -0,0 +1,73 @@
+package com.ruoyi.web.domain.dto.event;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 事件主表
+ *
+ * @TableName event
+ */
+@ApiModel(value = "EventEditRequest", description = "事件编辑请求参数")
+@Data
+public class EventEditRequest implements Serializable {
+    /**
+     * 事件ID
+     */
+    private Integer id;
+
+    /**
+     * 事发时间
+     */
+    private Date occurTime;
+
+    /**
+     * 事件类别,0-矛盾纠纷类/1-消防隐患类/2-安全隐患类/3-社会治安类/4-环境治理类/5-反诈宣传类
+     */
+    private Integer type;
+
+    /**
+     * 事发地点
+     */
+    private String location;
+
+    /**
+     * 事件描述
+     */
+    private String description;
+
+    /**
+     * 照片
+     */
+    private String photoUrl;
+
+    /**
+     * 状态(0-未完结 1-已完结)
+     */
+    private String status;
+
+    /**
+     * 填报人ID(村民id)
+     */
+    private Integer submitterId;
+
+    /**
+     * 处理结果
+     */
+    private String processResult;
+
+    /**
+     * 处理时间
+     */
+    private Date processTime;
+
+    /**
+     * 修改时间 (用于乐观锁)
+     */
+    private Date updateTime;
+
+    private static final long serialVersionUID = 1L;
+}

+ 33 - 0
app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventHandleRequest.java

@@ -0,0 +1,33 @@
+package com.ruoyi.web.domain.dto.event;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 事件处理请求
+ *
+ * @TableName event
+ */
+@ApiModel(value = "EventHandleRequest", description = "事件处理请求参数")
+@Data
+public class EventHandleRequest implements Serializable {
+
+    /**
+     * 事件id
+     */
+    private Integer eventId;
+
+    /**
+     * 负责人id
+     */
+    private Integer personId;
+
+    /**
+     * 处理结果
+     */
+    private String processResult;
+
+    private static final long serialVersionUID = 1L;
+}

+ 51 - 0
app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventQueryRequest.java

@@ -0,0 +1,51 @@
+package com.ruoyi.web.domain.dto.event;
+
+import com.ruoyi.web.common.PageRequest;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 事件查询请求
+ */
+@ApiModel(value = "EventQueryRequest", description = "事件查询请求参数")
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class EventQueryRequest extends PageRequest implements Serializable {
+
+    /**
+     * 事发开始时间
+     */
+    private Date startTime;
+
+    /**
+     * 事发结束时间
+     */
+    private Date endTime;
+
+    /**
+     * 事件类别,0-矛盾纠纷类/1-消防隐患类/2-安全隐患类/3-社会治安类/4-环境治理类/5-反诈宣传类
+     */
+    private Integer type;
+
+    /**
+     * 事发地点
+     */
+    private String location;
+
+    /**
+     * 状态(0-未完结 1-已完结)
+     */
+    private String status;
+
+    /**
+     * 填报人ID(村民id)
+     */
+    private Integer submitterId;
+
+
+    private static final long serialVersionUID = 1L;
+}

+ 29 - 0
app-admin/src/main/java/com/ruoyi/web/domain/dto/event/EventReassignRequest.java

@@ -0,0 +1,29 @@
+package com.ruoyi.web.domain.dto.event;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 事件重新派发请求
+ *
+ * @TableName event
+ */
+@ApiModel(value = "EventReassignRequest", description = "事件重新派发请求参数")
+@Data
+public class EventReassignRequest implements Serializable {
+
+    /**
+     * 事务id
+     */
+    private Integer eventId;
+
+    /**
+     * 负责人id列表
+     */
+    private List<Integer> personIds;
+
+    private static final long serialVersionUID = 1L;
+}

+ 27 - 0
app-admin/src/main/java/com/ruoyi/web/domain/dto/projects/ProjectsCompletedRequest.java

@@ -0,0 +1,27 @@
+package com.ruoyi.web.domain.dto.projects;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 项目建成请求
+ */
+@Data
+@ApiModel(value = "ProjectsCompletedRequest", description = "项目建成请求参数")
+public class ProjectsCompletedRequest implements Serializable {
+
+    /**
+     * id
+     */
+    private Integer id;
+
+    /**
+     * 实际建成日期
+     */
+    private Date actualCompletionDate;
+
+    private static final long serialVersionUID = 1L;
+}

+ 1 - 1
app-admin/src/main/java/com/ruoyi/web/domain/dto/villageSpecial/VillageSpecialAddRequest.java

@@ -19,7 +19,7 @@ public class VillageSpecialAddRequest implements Serializable {
     /**
      * 产业类别(0-保安腰刀产业、1-农家乐产业、2-民宿产业)
      */
-    private Integer category;
+    private String category;
 
     /**
      * 产业名称

+ 1 - 1
app-admin/src/main/java/com/ruoyi/web/domain/dto/villageSpecial/VillageSpecialEditRequest.java

@@ -21,7 +21,7 @@ public class VillageSpecialEditRequest implements Serializable {
     /**
      * 产业类别(0-保安腰刀产业、1-农家乐产业、2-民宿产业)
      */
-    private Integer category;
+    private String category;
 
     /**
      * 产业名称

+ 1 - 1
app-admin/src/main/java/com/ruoyi/web/domain/dto/villageSpecial/VillageSpecialQueryRequest.java

@@ -20,7 +20,7 @@ public class VillageSpecialQueryRequest extends PageRequest implements Serializa
     /**
      * 产业类别(0-保安腰刀产业、1-农家乐产业、2-民宿产业)
      */
-    private Integer category;
+    private String category;
 
     /**
      * 名称

+ 1 - 1
app-admin/src/main/java/com/ruoyi/web/domain/dto/villageTradition/VillageTraditionAddRequest.java

@@ -16,7 +16,7 @@ public class VillageTraditionAddRequest implements Serializable {
     /**
      * 产业类别(0-种植业、1-养殖业)
      */
-    private Integer category;
+    private String category;
 
     /**
      * 基地名称

+ 1 - 1
app-admin/src/main/java/com/ruoyi/web/domain/dto/villageTradition/VillageTraditionEditRequest.java

@@ -21,7 +21,7 @@ public class VillageTraditionEditRequest implements Serializable {
     /**
      * 产业类别(0-种植业、1-养殖业)
      */
-    private Integer category;
+    private String category;
 
     /**
      * 基地名称

+ 1 - 1
app-admin/src/main/java/com/ruoyi/web/domain/dto/villageTradition/VillageTraditionQueryRequest.java

@@ -20,7 +20,7 @@ public class VillageTraditionQueryRequest extends PageRequest implements Seriali
     /**
      * 产业类别(0-种植业、1-养殖业)
      */
-    private Integer category;
+    private String category;
 
     /**
      * 基地名称

+ 88 - 0
app-admin/src/main/java/com/ruoyi/web/domain/entity/Event.java

@@ -0,0 +1,88 @@
+package com.ruoyi.web.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 事件主表
+ *
+ * @TableName event
+ */
+@TableName(value = "event")
+@Data
+public class Event implements Serializable{
+    /**
+     * 事件ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 事发时间
+     */
+    private Date occurTime;
+
+    /**
+     * 事件类别,0-矛盾纠纷类/1-消防隐患类/2-安全隐患类/3-社会治安类/4-环境治理类/5-反诈宣传类
+     */
+    private Integer type;
+
+    /**
+     * 事发地点
+     */
+    private String location;
+
+    /**
+     * 事件描述
+     */
+    private String description;
+
+    /**
+     * 照片
+     */
+    private String photoUrl;
+
+    /**
+     * 状态(0-未完结 1-已完结)
+     */
+    private String status;
+
+    /**
+     * 填报人ID(村民id)
+     */
+    private Integer submitterId;
+
+    /**
+     * 处理结果
+     */
+    private String processResult;
+
+    /**
+     * 处理时间
+     */
+    private Date processTime;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    private Date updateTime;
+
+    /**
+     * 删除标志
+     */
+    @TableLogic
+    @JsonIgnore
+    private String delFlag;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 58 - 0
app-admin/src/main/java/com/ruoyi/web/domain/entity/EventAssign.java

@@ -0,0 +1,58 @@
+package com.ruoyi.web.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 事件负责人分配表
+ *
+ * @TableName event_assign
+ */
+@TableName(value = "event_assign")
+@Data
+public class EventAssign implements Serializable {
+    /**
+     * 分配ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 事件ID
+     */
+    private Integer eventId;
+
+    /**
+     * 负责人ID
+     */
+    private Integer personId;
+
+    /**
+     * 状态(0未完结 1本人已完结 2其他人已完结)
+     */
+    private String status;
+
+    /**
+     * 是否重新分配(0否 1是)
+     */
+    private String isReassign;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    private Date updateTime;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 1 - 1
app-admin/src/main/java/com/ruoyi/web/domain/entity/VillageService.java

@@ -34,7 +34,7 @@ public class VillageService implements Serializable {
     /**
      * 类型 1-图文,2-视频
      */
-    private Integer type;
+    private String type;
 
     /**
      * 内容

+ 1 - 1
app-admin/src/main/java/com/ruoyi/web/domain/entity/VillageSpecial.java

@@ -24,7 +24,7 @@ public class VillageSpecial implements Serializable {
     /**
      * 产业类别(0-保安腰刀产业、1-农家乐产业、2-民宿产业)
      */
-    private Integer category;
+    private String category;
 
     /**
      * 产业名称

+ 1 - 1
app-admin/src/main/java/com/ruoyi/web/domain/entity/VillageTradition.java

@@ -24,7 +24,7 @@ public class VillageTradition implements Serializable {
     /**
      * 产业类别(0-种植业、1-养殖业)
      */
-    private Integer category;
+    private String category;
 
     /**
      * 基地名称

+ 2 - 2
app-admin/src/main/java/com/ruoyi/web/domain/vo/VillageServiceVO.java

@@ -24,14 +24,14 @@ public class VillageServiceVO  {
     private String title;
 
     /**
-     * 标签 ["1","2"]
+     * 标签
      */
     private String tag;
 
     /**
      * 类型 1-图文,2-视频
      */
-    private Integer type;
+    private String type;
 
     /**
      * 内容

+ 1 - 1
app-admin/src/main/java/com/ruoyi/web/domain/vo/VillageSpecial/BaseVillageSpecialVO.java

@@ -14,7 +14,7 @@ public class BaseVillageSpecialVO {
     /**
      * 产业类别(0-保安腰刀产业、1-农家乐产业、2-民宿产业)
      */
-    private Integer category;
+    private String category;
 
     /**
      * 产业名称

+ 4 - 4
app-admin/src/main/java/com/ruoyi/web/domain/vo/VillageSpecial/SpecialVOFactory.java

@@ -17,24 +17,24 @@ public class SpecialVOFactory {
     @Autowired
     private VillageSpecialService villageSpecialService;
 
-    private static final Map<Integer, Function<VillageSpecial, ? extends BaseVillageSpecialVO>> CONVERTERS =
+    private static final Map<String, Function<VillageSpecial, ? extends BaseVillageSpecialVO>> CONVERTERS =
             new HashMap<>();
 
     //0-保安腰刀产业、1-农家乐产业、2-民宿产业
     static {
-        CONVERTERS.put(0, entity -> {
+        CONVERTERS.put("0", entity -> {
             BaoAnVO vo = new BaoAnVO();
             BeanUtils.copyProperties(entity, vo);
             return vo;
         });
 
-        CONVERTERS.put(1, entity -> {
+        CONVERTERS.put("1", entity -> {
             FarmHouseVO vo = new FarmHouseVO();
             BeanUtils.copyProperties(entity, vo);
             return vo;
         });
 
-        CONVERTERS.put(2, entity -> {
+        CONVERTERS.put("2", entity -> {
             BAndBVO vo = new BAndBVO();
             BeanUtils.copyProperties(entity, vo);
             return vo;

+ 72 - 0
app-admin/src/main/java/com/ruoyi/web/domain/vo/event/EventPersonInfoVO.java

@@ -0,0 +1,72 @@
+package com.ruoyi.web.domain.vo.event;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 事件负责人员信息视图
+ */
+@Data
+@ApiModel(value = "PersonInfoVO", description = "事件负责人员信息视图")
+public class EventPersonInfoVO implements Serializable {
+
+    /**
+     * 用户ID
+     */
+    @ApiModelProperty(value = "userId")
+    private Integer userId;
+
+    /**
+     * 部门id
+     */
+    @ApiModelProperty(value = "部门id")
+    private Integer deptId;
+
+    /**
+     * 姓名
+     */
+    @ApiModelProperty(value = "姓名")
+    private String userName;
+
+    /**
+     * 昵称
+     */
+    @ApiModelProperty(value = "昵称")
+    private String nickName;
+
+    /**
+     * 邮箱
+     */
+    @ApiModelProperty(value = "邮箱")
+    private String email;
+
+    /**
+     * 性别: 1-男, 2-女, 0-未知
+     */
+    @ApiModelProperty(value = "性别: 1-男, 2-女, 0-未知")
+    private Integer sex;
+
+//    /**
+//     * 电话
+//     */
+//    @ApiModelProperty(value = "电话")
+//    private String phone;
+
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    @ApiModelProperty(value = "修改时间")
+    private Date updateTime;
+
+    private static final long serialVersionUID = 1L;
+}

+ 90 - 0
app-admin/src/main/java/com/ruoyi/web/domain/vo/event/EventVO.java

@@ -0,0 +1,90 @@
+package com.ruoyi.web.domain.vo.event;
+
+import com.ruoyi.common.core.domain.entity.SysUser;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 事件视图类
+ *
+ * @TableName house_info
+ */
+@Data
+@ApiModel(value = "EventVO", description = "事件视图类")
+public class EventVO implements Serializable {
+    /**
+     * 事件ID
+     */
+    private Integer id;
+
+    /**
+     * 事发时间
+     */
+    private Date occurTime;
+
+    /**
+     * 事件类别,0-矛盾纠纷类/1-消防隐患类/2-安全隐患类/3-社会治安类/4-环境治理类/5-反诈宣传类
+     */
+    private Integer type;
+
+    /**
+     * 事发地点
+     */
+    private String location;
+
+    /**
+     * 事件描述
+     */
+    private String description;
+
+    /**
+     * 照片
+     */
+    private String photoUrl;
+
+    /**
+     * 状态(0-未完结 1-已完结)
+     */
+    private String status;
+
+    /**
+     * 填报人ID(村民id)
+     */
+    private Integer submitterId;
+
+    /**
+     * 处理结果
+     */
+    private String processResult;
+
+    /**
+     * 处理时间
+     */
+    private Date processTime;
+
+    /**
+     * 负责人 列表
+     */
+    private List<SysUser> chargeUserList;
+
+    /**
+     * 处理人
+     */
+    private SysUser processUser;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    private Date updateTime;
+
+    private static final long serialVersionUID = 1L;
+}

+ 16 - 0
app-admin/src/main/java/com/ruoyi/web/mapper/EventAssignMapper.java

@@ -0,0 +1,16 @@
+package com.ruoyi.web.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.web.domain.entity.EventAssign;
+
+
+/**
+ * @Entity generator.domain.EventAssign
+ */
+public interface EventAssignMapper extends BaseMapper<EventAssign> {
+
+}
+
+
+
+

+ 15 - 0
app-admin/src/main/java/com/ruoyi/web/mapper/EventMapper.java

@@ -0,0 +1,15 @@
+package com.ruoyi.web.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.web.domain.entity.Event;
+
+/**
+ * @Entity generator.domain.Event
+ */
+public interface EventMapper extends BaseMapper<Event> {
+
+}
+
+
+
+

+ 12 - 0
app-admin/src/main/java/com/ruoyi/web/service/EventAssignService.java

@@ -0,0 +1,12 @@
+package com.ruoyi.web.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.web.domain.entity.EventAssign;
+
+
+/**
+ *
+ */
+public interface EventAssignService extends IService<EventAssign> {
+
+}

+ 38 - 0
app-admin/src/main/java/com/ruoyi/web/service/EventService.java

@@ -0,0 +1,38 @@
+package com.ruoyi.web.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.web.domain.dto.event.EventAddRequest;
+import com.ruoyi.web.domain.dto.event.EventEditRequest;
+import com.ruoyi.web.domain.dto.event.EventQueryRequest;
+import com.ruoyi.web.domain.entity.Event;
+import com.ruoyi.web.domain.vo.event.EventVO;
+
+import java.util.List;
+
+/**
+ *
+ */
+public interface EventService extends IService<Event> {
+
+    Integer addEvent(EventAddRequest eventAddRequest);
+
+    boolean deleteEvent(String ids);
+
+    void editEvent(EventEditRequest eventEditRequest);
+
+    EventVO getEventById(int id);
+
+    EventVO getEventVO(Event event);
+
+    Page<EventVO> getListEventByPage(EventQueryRequest eventQueryRequest);
+
+    QueryWrapper<Event> getQueryWrapper(EventQueryRequest eventQueryRequest, Integer userId);
+
+    // 处理事件:返回是否成功抢占并完成(true 表示当前负责人成为处理人)
+    boolean handleEvent(Integer eventId, Integer personId, String processResult);
+
+    // 再次派发:将给定负责人设为未完结(存在则更新,不存在则插入);仅当事件未完结时允许
+    void reassignEvent(Integer eventId, List<Integer> personIds);
+}

+ 6 - 0
app-admin/src/main/java/com/ruoyi/web/service/ProjectsService.java

@@ -10,6 +10,8 @@ import com.ruoyi.web.domain.dto.projects.ProjectsQueryRequest;
 import com.ruoyi.web.domain.entity.Projects;
 import com.ruoyi.web.domain.vo.ProjectsVO;
 
+import java.util.Date;
+
 /**
  * 项目接口
  */
@@ -21,6 +23,8 @@ public interface ProjectsService extends IService<Projects> {
 
     void editProjects(ProjectsEditRequest projectsEditRequest);
 
+    boolean completedProjects(int id, Date date);
+
 
     /**
      * 根据id获取项目
@@ -48,4 +52,6 @@ public interface ProjectsService extends IService<Projects> {
      * @return
      */
     QueryWrapper<Projects> getQueryWrapper(ProjectsQueryRequest projectsQueryRequest);
+
+
 }

+ 20 - 0
app-admin/src/main/java/com/ruoyi/web/service/impl/EventAssignServiceImpl.java

@@ -0,0 +1,20 @@
+package com.ruoyi.web.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.web.domain.entity.EventAssign;
+import com.ruoyi.web.mapper.EventAssignMapper;
+import com.ruoyi.web.service.EventAssignService;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ */
+@Service
+public class EventAssignServiceImpl extends ServiceImpl<EventAssignMapper, EventAssign>
+        implements EventAssignService {
+
+}
+
+
+
+

+ 488 - 0
app-admin/src/main/java/com/ruoyi/web/service/impl/EventServiceImpl.java

@@ -0,0 +1,488 @@
+package com.ruoyi.web.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.bean.BeanUtils;
+import com.ruoyi.system.mapper.SysUserMapper;
+import com.ruoyi.system.service.ISysRoleService;
+import com.ruoyi.system.service.ISysUserService;
+import com.ruoyi.web.domain.dto.event.EventAddRequest;
+import com.ruoyi.web.domain.dto.event.EventEditRequest;
+import com.ruoyi.web.domain.dto.event.EventQueryRequest;
+import com.ruoyi.web.domain.entity.Event;
+import com.ruoyi.web.domain.entity.EventAssign;
+import com.ruoyi.web.domain.vo.event.EventVO;
+import com.ruoyi.web.mapper.EventAssignMapper;
+import com.ruoyi.web.mapper.EventMapper;
+import com.ruoyi.web.service.EventService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ *
+ */
+@Service
+public class EventServiceImpl extends ServiceImpl<EventMapper, Event>
+        implements EventService {
+
+    @Resource
+    private EventAssignMapper eventAssignMapper;
+
+    @Resource
+    private ISysUserService sysUserService;
+
+    @Resource
+    private ISysRoleService sysRoleService;
+
+    @Autowired
+    private SysUserMapper sysUserMapper;
+
+    /**
+     * 添加事件并分配给对应负责人
+     *
+     * @param eventAddRequest
+     * @return
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Integer addEvent(EventAddRequest eventAddRequest) {
+        if (eventAddRequest == null) {
+            throw new ServiceException("请求参数为空");
+        }
+        try {
+            // 转换为实体对象
+            Event event = new Event();
+            BeanUtil.copyProperties(eventAddRequest, event);
+            //数据校验
+            validEvent(event, BusinessType.INSERT);
+
+            // 保存到事件表
+            this.save(event);
+
+            // 根据事件类型分配负责人
+            assignEventToPersons(event.getId(), event.getType());
+            return event.getId();
+        } catch (Exception e) {
+            log.error("添加事件失败", e);
+            throw new ServiceException("添加事件失败");
+        }
+    }
+
+    /**
+     * 根据事件类型分配负责人
+     *
+     * @param eventId   事件ID
+     * @param eventType 事件类型
+     */
+    private void assignEventToPersons(Integer eventId, Integer eventType) {
+        // 根据事件类型查找对应的负责人
+        List<Integer> personIds = getPersonIdsByEventType(eventType);
+
+        if (personIds.isEmpty()) {
+            throw new ServiceException("未找到事件类型对应的负责人");
+        }
+
+        Date now = new Date();
+        for (Integer personId : personIds) {
+            EventAssign eventAssign = new EventAssign();
+            eventAssign.setEventId(eventId);
+            eventAssign.setPersonId(personId);
+            eventAssign.setStatus("0"); // 未完结
+            eventAssign.setIsReassign("0"); // 非重新分配
+            eventAssign.setCreateTime(now);
+            eventAssign.setUpdateTime(now);
+            eventAssignMapper.insert(eventAssign);
+        }
+    }
+
+    /**
+     * 根据事件类型获取负责人ID列表
+     *
+     * @param eventType 事件类型
+     * @return 负责人ID列表
+     */
+    private List<Integer> getPersonIdsByEventType(Integer eventType) {
+        // 约定基于角色来选择负责人:通用命名:event_type_{n}
+        // 角色:event_type_0 -> 矛盾纠纷类 、 event_type_2 -> 消防隐患类
+        String key = "event_type_" + eventType;
+
+        // 使用专门的方法查询用户ID,避免数据权限问题
+        List<String> roleKeys = Arrays.asList(key);
+        List<Long> userIds = sysUserService.selectUserIdsByRoleKeysForEvent(roleKeys);
+
+        List<Integer> matchedUserIds = userIds.stream()
+                .map(Long::intValue)
+                .distinct()
+                .collect(Collectors.toList());
+
+        // 同时包含超级管理员(user_id = 1)
+        if (!matchedUserIds.contains(1)) {
+            matchedUserIds.add(1);
+        }
+        return matchedUserIds;
+    }
+
+    /**
+     * 删除
+     *
+     * @param ids
+     * @return
+     */
+    @Override
+    public boolean deleteEvent(String ids) {
+        if (StrUtil.isBlank(ids)) {
+            throw new ServiceException("id不能为空或id异常");
+        }
+
+        // 2. 分割ID字符串为List<Integer>
+        List<Long> idList = Arrays.stream(ids.split(","))
+                .map(String::trim)
+                .filter(StrUtil::isNotBlank)
+                .map(Long::parseLong)
+                .collect(Collectors.toList());
+
+        if (idList.isEmpty()) {
+            throw new ServiceException("ID格式异常");
+        }
+
+        // 3. 构建删除条件
+        QueryWrapper<Event> queryWrapper = new QueryWrapper<>();
+        queryWrapper.in("id", idList);
+
+        // 4. 执行删除(返回是否删除成功)
+        return remove(queryWrapper);
+
+    }
+
+    /**
+     * 编辑
+     *
+     * @param eventEditRequest
+     */
+    @Override
+    public void editEvent(EventEditRequest eventEditRequest) {
+        // 判断是否存在
+        Integer id = eventEditRequest.getId();
+        Event oldEvent = this.getById(id);
+        if (oldEvent == null) {
+            throw new ServiceException("没有找到事件");
+        }
+        Event event = new Event();
+        BeanUtil.copyProperties(eventEditRequest, event);
+        event.setUpdateTime(new Date());
+        // 数据校验
+        validEvent(event, BusinessType.UPDATE);
+
+        // 操作数据库
+        boolean result = this.updateById(event);
+        if (!result) {
+            throw new ServiceException("修改事件操作失败");
+        }
+    }
+
+    /**
+     * 校验数据
+     *
+     * @param event
+     */
+    public void validEvent(Event event, BusinessType type) {
+        if (ObjectUtil.isEmpty(event)) {
+            throw new ServiceException("数据为空");
+        }
+        // 从对象中取值
+        Integer id = event.getId();
+        Date occurTime = event.getOccurTime();
+        Integer eventType = event.getType();
+        String location = event.getLocation();
+        String description = event.getDescription();
+        String photoUrl = event.getPhotoUrl();
+        String status = event.getStatus();
+        Integer submitterId = event.getSubmitterId();
+        String processResult = event.getProcessResult();
+        Date processTime = event.getProcessTime();
+
+
+        // 添加id无需校验,修改时,id 不能为空
+        if (type != BusinessType.INSERT && ObjectUtil.isEmpty(id)) {
+            throw new ServiceException("id不能为空");
+        }
+        if (ObjectUtil.isEmpty(occurTime)) {
+            throw new ServiceException("事件时间不能为空");
+        }
+        if (ObjectUtil.isEmpty(eventType)) {
+            throw new ServiceException("事件类别不能为空");
+        }
+        if (StrUtil.isBlank(location)) {
+            throw new ServiceException("事件地点不能为空");
+        }
+        if (ObjectUtil.isEmpty(submitterId)) {
+            throw new ServiceException("填报人不能为空");
+        }
+    }
+
+    /**
+     * 根据id查询
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public EventVO getEventById(int id) {
+        if (id <= 0) {
+            throw new ServiceException("id不能为空或id异常");
+        }
+        // 获取登录用户id
+        Long userId = SecurityUtils.getUserId();
+        Event event = new Event();
+        // 若不是管理员 指定查询的 负责人id 为当前登录用户id (负责人只能查询自己的事件)
+        if (SecurityUtils.isAdmin(userId)) {
+            // 管理员查询
+            event = this.getById(id);
+        } else {
+            // 负责人查询
+            QueryWrapper<Event> wrapper = new QueryWrapper<>();
+            wrapper.eq("id", id)
+                    .exists("SELECT 1 FROM event_assign ea WHERE ea.event_id = event.id AND ea.person_id = " + userId);
+            event = this.getOne(wrapper);
+        }
+        return getEventVO(event);
+    }
+
+    /**
+     * 获取事件包装类
+     *
+     * @param event
+     * @return
+     */
+    @Override
+    public EventVO getEventVO(Event event) {
+        if (ObjectUtil.isEmpty(event)) {
+            throw new ServiceException("请求参数不存在");
+        }
+        EventVO eventVO = new EventVO();
+        BeanUtils.copyProperties(event, eventVO);
+
+        // 查询事件的负责人信息
+        QueryWrapper<EventAssign> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("event_id", event.getId());
+        // 获取事件分配信息列表
+        List<EventAssign> eventAssigns = eventAssignMapper.selectList(queryWrapper);
+        // 3. 提取负责人ID列表
+        List<Integer> userIds = eventAssigns.stream()
+                .map(EventAssign::getPersonId)
+                .collect(Collectors.toList());
+
+        // 4. 批量查询有效的用户信息
+        List<SysUser> chargeUserList = userIds.isEmpty() ?
+                Collections.emptyList() :
+                sysUserMapper.selectUserListForEvent(userIds);
+
+        // 实际项目中需要根据personId查询用户信息
+        eventVO.setChargeUserList(chargeUserList);
+
+        // 5. 查询处理人
+//        queryWrapper.eq()
+
+        return eventVO;
+    }
+
+    /**
+     * 分页获取事件列表
+     *
+     * @param eventQueryRequest
+     * @return
+     */
+    @Override
+    public Page<EventVO> getListEventByPage(EventQueryRequest eventQueryRequest) {
+        long current = eventQueryRequest.getPageNum();
+        long size = eventQueryRequest.getPageSize();
+        // 获取登录用户id
+        Long userId = SecurityUtils.getUserId();
+        Page<Event> page;
+        // 若不是管理员 指定查询的 负责人id 为当前登录用户id (负责人只能查询自己的事件)
+        if (SecurityUtils.isAdmin(userId)) {
+            // 管理员查询
+            page = this.page(new Page<>(current, size),
+                    getQueryWrapper(eventQueryRequest, null));
+        } else {
+            // 负责人查询
+            page = this.page(new Page<>(current, size),
+                    getQueryWrapper(eventQueryRequest, Math.toIntExact(userId)));
+        }
+        Page<EventVO> eventVOPage = new Page<>();
+        BeanUtils.copyProperties(page, eventVOPage, "records");
+        List<EventVO> voList = page.getRecords().stream()
+                .map(event -> {
+                    EventVO vo = getEventVO(event);
+                    return vo;
+                })
+                .collect(Collectors.toList());
+        eventVOPage.setRecords(voList);
+        return eventVOPage;
+    }
+
+
+    /**
+     * 获取查询条件
+     *
+     * @param eventQueryRequest
+     * @return
+     */
+    @Override
+    public QueryWrapper<Event> getQueryWrapper(EventQueryRequest eventQueryRequest, Integer userId) {
+        QueryWrapper<Event> queryWrapper = new QueryWrapper<>();
+        if (eventQueryRequest == null) {
+            return queryWrapper;
+        }
+
+        // 从对象中取值
+        Date startTime = eventQueryRequest.getStartTime();
+        Date endTime = eventQueryRequest.getEndTime();
+        Integer type = eventQueryRequest.getType();
+        String location = eventQueryRequest.getLocation();
+        String status = eventQueryRequest.getStatus();
+        Integer submitterId = eventQueryRequest.getSubmitterId();
+        String sortField = eventQueryRequest.getSortField();
+        String sortOrder = eventQueryRequest.getSortOrder();
+
+        // 事件类别、事发地点、填报人、状态
+        queryWrapper.eq(ObjectUtil.isNotEmpty(type), "type", type);
+        queryWrapper.eq(StrUtil.isNotBlank(location), "location", location);
+        queryWrapper.eq(StringUtils.isNotBlank(status), "status", status);
+        // 修正列名:submitter_id
+        queryWrapper.eq(ObjectUtil.isNotEmpty(submitterId), "submitter_id", submitterId);
+
+        // 如果负责人查询,则查询负责人的事件
+        if (ObjectUtil.isNotEmpty(userId)) {
+            queryWrapper.exists("SELECT 1 FROM event_assign ea WHERE ea.event_id = event.id AND ea.person_id = " + userId);
+        }
+
+        // 事发时间范围查询(优先判断范围)
+        if (startTime != null && endTime != null) {
+            queryWrapper.between("occur_time", startTime, endTime);
+        } else if (startTime != null) {
+            queryWrapper.ge("occur_time", startTime); // >= 开始日期
+        } else if (endTime != null) {
+            queryWrapper.le("occur_time", endTime);   // <= 结束日期
+        }
+
+        // 排序
+        queryWrapper.orderBy(StrUtil.isNotEmpty(sortField), "ascend".equals(sortOrder), sortField);
+        return queryWrapper;
+    }
+
+    /**
+     * 任一负责人处理事件:主表CAS(状态) + 分配表同步
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean handleEvent(Integer eventId, Integer personId, String processResult) {
+        if (eventId == null || personId == null) {
+            throw new ServiceException("参数不能为空");
+        }
+        // 1. 事件主表CAS:尝试抢占锁,只能修改状态为 0 的事件
+        UpdateWrapper<Event> casUpdate = new UpdateWrapper<>();
+        casUpdate.eq("id", eventId)
+                .eq("status", "0")
+                .set("status", "1")
+                .set("process_result", processResult)
+                .set("process_time", new Date())
+                .set("update_time", new Date());
+        int w = this.baseMapper.update(null, casUpdate);
+
+        if (w == 1) {
+            // 抢到锁:当前负责人状态 -> 1;其他事件负责人状态 -> 2
+            UpdateWrapper<EventAssign> meDone = new UpdateWrapper<>();
+            meDone.eq("event_id", eventId)
+                    .eq("person_id", personId)
+                    .eq("status", "0")
+                    .set("status", "1")
+                    .set("update_time", new Date());
+            eventAssignMapper.update(null, meDone);
+
+            UpdateWrapper<EventAssign> othersDone = new UpdateWrapper<>();
+            othersDone.eq("event_id", eventId)
+                    .ne("person_id", personId)
+                    .eq("status", "0")
+                    .set("status", "2")
+                    .set("update_time", new Date());
+            eventAssignMapper.update(null, othersDone);
+            return true;
+        } else {
+            // 抢锁失败:将当前负责人状态-> 2
+            UpdateWrapper<EventAssign> meLose = new UpdateWrapper<>();
+            meLose.eq("event_id", eventId)
+                    .eq("person_id", personId)
+                    .eq("status", "0")
+                    .set("status", "2")
+                    .set("update_time", new Date());
+            eventAssignMapper.update(null, meLose);
+            return false;
+        }
+    }
+
+    /**
+     * 再次派发:仅在事件未完结时允许;存在则重置为未完结并标记再派发,不存在则插入
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void reassignEvent(Integer eventId, List<Integer> personIds) {
+        if (eventId == null || personIds == null || personIds.isEmpty()) {
+            throw new ServiceException("参数不能为空");
+        }
+        // 校验事件未完结
+        Event event = this.getById(eventId);
+        if (event == null) {
+            throw new ServiceException("事件不存在");
+        }
+        if (!"0".equals(event.getStatus())) {
+            throw new ServiceException("事件已完结,无法再次派发");
+        }
+
+        Date now = new Date();
+        for (Integer uid : personIds) {
+            // 先尝试更新存在的数据
+            UpdateWrapper<EventAssign> reset = new UpdateWrapper<>();
+            reset.eq("event_id", eventId)
+                    .eq("person_id", uid)
+                    .set("status", "0")
+                    .set("is_reassign", "1")
+                    .set("update_time", now);
+            int a = eventAssignMapper.update(null, reset);
+            // 如果不是原来的事件负责人,添加分配记录
+            if (a == 0) {
+                // 插入新记录
+                EventAssign add = new EventAssign();
+                add.setEventId(eventId);
+                add.setPersonId(uid);
+                add.setStatus("0");
+                add.setIsReassign("1");
+                add.setCreateTime(now);
+                add.setUpdateTime(now);
+                eventAssignMapper.insert(add);
+            }
+        }
+    }
+}
+
+
+
+

+ 28 - 0
app-admin/src/main/java/com/ruoyi/web/service/impl/ProjectsServiceImpl.java

@@ -124,6 +124,34 @@ public class ProjectsServiceImpl extends ServiceImpl<ProjectsMapper, Projects>
     }
 
     /**
+     * 建成
+     *
+     * @param id
+     * @param date
+     * @return
+     */
+    @Override
+    public boolean completedProjects(int id, Date date) {
+        Projects projects = this.getById(id);
+        if (projects == null) {
+            throw new ServiceException("没有找到项目");
+        }
+        // 如果有实际建成日期 更新项目进度
+        if (ObjectUtil.isNotNull(date)) {
+            if (date.after(new Date())) {
+                throw new ServiceException("实际建成日期不能是未来日期");
+            }
+            projects.setActualCompletionDate(date);
+            projects.setProgress(1);
+        }
+        boolean result = this.updateById(projects);
+        if (!result) {
+            throw new ServiceException("操作失败");
+        }
+        return true;
+    }
+
+    /**
      * 校验数据
      *
      * @param projects

+ 6 - 22
app-admin/src/main/java/com/ruoyi/web/service/impl/VillageServiceServiceImpl.java

@@ -1,10 +1,8 @@
 package com.ruoyi.web.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -50,8 +48,6 @@ public class VillageServiceServiceImpl extends ServiceImpl<VillageServiceMapper,
             // 转换为实体对象
             VillageService villageService = new VillageService();
             BeanUtil.copyProperties(villageServiceAddRequest, villageService);
-            // 将 标签 List 转为 String
-            villageService.setTag(JSONUtil.toJsonStr(villageServiceAddRequest.getTag()));
             //数据校验
             validVillageService(villageService, BusinessType.INSERT);
 
@@ -99,8 +95,6 @@ public class VillageServiceServiceImpl extends ServiceImpl<VillageServiceMapper,
         }
         VillageService villageService = new VillageService();
         BeanUtil.copyProperties(villageServiceEditRequest, villageService);
-        // 将 标签 List 转为 String
-        villageService.setTag(JSONUtil.toJsonStr(villageServiceEditRequest.getTag()));
         villageService.setUpdateTime(new Date());
 
         //如果修改状态为 发布 时,填充 发布日期 和 发布人
@@ -109,7 +103,6 @@ public class VillageServiceServiceImpl extends ServiceImpl<VillageServiceMapper,
             villageService.setDate(new Date()); // 设置发布日期为当前时间
             Long userId = SecurityUtils.getUserId();
             villageService.setIssuerId(userId.intValue());// 设置发布人ID
-            
         }
 
         // 数据校验
@@ -134,7 +127,7 @@ public class VillageServiceServiceImpl extends ServiceImpl<VillageServiceMapper,
         Integer id = villageService.getId();
         String title = villageService.getTitle();
         String tag = villageService.getTag();
-        Integer serviceType = villageService.getType();
+        String serviceType = villageService.getType();
         String content = villageService.getContent();
 
         // 添加id无需校验,修改时,id 不能为空
@@ -147,7 +140,7 @@ public class VillageServiceServiceImpl extends ServiceImpl<VillageServiceMapper,
         if (StrUtil.isBlank(tag)) {
             throw new ServiceException("标签不能为空");
         }
-        if (ObjectUtil.isEmpty(serviceType)) {
+        if (StrUtil.isBlank(serviceType)) {
             throw new ServiceException("类型不能为空");
         }
         if (StrUtil.isBlank(content)) {
@@ -224,7 +217,7 @@ public class VillageServiceServiceImpl extends ServiceImpl<VillageServiceMapper,
         }
 
         // 从对象中取值
-        List<String> tag = villageServiceQueryRequest.getTag();
+        String tag = villageServiceQueryRequest.getTag();
         String keyword = villageServiceQueryRequest.getKeyword();
         Date startTime = villageServiceQueryRequest.getStartTime();
         Date endTime = villageServiceQueryRequest.getEndTime();
@@ -232,24 +225,15 @@ public class VillageServiceServiceImpl extends ServiceImpl<VillageServiceMapper,
         String sortField = villageServiceQueryRequest.getSortField();
         String sortOrder = villageServiceQueryRequest.getSortOrder();
 
-        queryWrapper.eq(ObjectUtil.isNotEmpty(status), "status", status);
+        queryWrapper.eq(ObjectUtil.isNotEmpty(status), "status", status)
+                .eq(StrUtil.isNotEmpty(tag), "tag", tag);
 
-        // 标签 JSON 数组查询
-        if (CollUtil.isNotEmpty(tag)) {
-            for (String t : tag) {
-                queryWrapper.like("tag", "\"" + t + "\"");
-            }
-        }
-
-        // 如果关键字不为空,添加模糊查询条件  标题或标签或内容
+        // 如果关键字不为空,添加模糊查询条件  标题或内容
         if (StrUtil.isNotBlank(keyword)) {
             queryWrapper.like("title", keyword)
                     .or()
-                    .like("tag", keyword)
-                    .or()
                     .like("content",keyword);
         }
-
         // 日期范围查询(优先判断范围)
         if (startTime != null && endTime != null) {
             queryWrapper.between("date", startTime, endTime);

+ 7 - 7
app-admin/src/main/java/com/ruoyi/web/service/impl/VillageSpecialServiceImpl.java

@@ -171,7 +171,7 @@ public class VillageSpecialServiceImpl extends ServiceImpl<VillageSpecialMapper,
             throw new ServiceException("数据为空");
         }
         Integer id = villageSpecial.getId();
-        Integer category = villageSpecial.getCategory();
+        String category = villageSpecial.getCategory();
         String name = villageSpecial.getName();
         String location = villageSpecial.getLocation();
 
@@ -179,7 +179,7 @@ public class VillageSpecialServiceImpl extends ServiceImpl<VillageSpecialMapper,
         if (type != BusinessType.INSERT && ObjectUtil.isEmpty(id)) {
             throw new ServiceException("id不能为空");
         }
-        if (ObjectUtil.isEmpty(category)) {
+        if (StrUtil.isBlank(category)) {
             throw new ServiceException("产业类别不能为空");
         }
         if (StrUtil.isBlank(name)) {
@@ -208,8 +208,8 @@ public class VillageSpecialServiceImpl extends ServiceImpl<VillageSpecialMapper,
         BaseVillageSpecialVO villageSpecialVO = SpecialVOFactory.convert(villageSpecial);
 
         // 判断是保安腰刀产业或农家乐产业,需要填充产品数量
-        Integer category = villageSpecialVO.getCategory();
-        if (category == 0 || category == 1) {
+        String category = villageSpecialVO.getCategory();
+        if ("0".equals(category) || "1".equals(category)) {
             String ids = villageSpecial.getIds();
             if (StringUtils.isNotBlank(ids)) {
                 // 分割ID字符串为List<Integer>
@@ -226,7 +226,7 @@ public class VillageSpecialServiceImpl extends ServiceImpl<VillageSpecialMapper,
                     long count = productionDataService.count(queryWrapper);
 
                     // 填充产品数量到VO
-                    if (category == 0) {
+                    if ("0".equals(category)) {
                         ((BaoAnVO) villageSpecialVO).setProduceNum((int) count);
                     } else {
                         ((FarmHouseVO) villageSpecialVO).setVegetable((int) count);
@@ -266,12 +266,12 @@ public class VillageSpecialServiceImpl extends ServiceImpl<VillageSpecialMapper,
         }
 
         // 从对象中取值
-        Integer category = villageSpecialQueryRequest.getCategory();
+        String category = villageSpecialQueryRequest.getCategory();
         String name = villageSpecialQueryRequest.getName();
         String sortField = villageSpecialQueryRequest.getSortField();
         String sortOrder = villageSpecialQueryRequest.getSortOrder();
 
-        queryWrapper.eq(ObjectUtil.isNotEmpty(category), "category", category);
+        queryWrapper.eq(StringUtils.isNotBlank(category), "category", category);
         queryWrapper.like(StringUtils.isNotBlank(name), "name", name);
 
         // 排序

+ 4 - 4
app-admin/src/main/java/com/ruoyi/web/service/impl/VillageTraditionServiceImpl.java

@@ -107,7 +107,7 @@ public class VillageTraditionServiceImpl extends ServiceImpl<VillageTraditionMap
             throw new ServiceException("数据为空");
         }
         Integer id = villageTradition.getId();
-        Integer category = villageTradition.getCategory();
+        String category = villageTradition.getCategory();
         String name = villageTradition.getName();
         String location = villageTradition.getLocation();
         String area = villageTradition.getArea();
@@ -118,7 +118,7 @@ public class VillageTraditionServiceImpl extends ServiceImpl<VillageTraditionMap
         if (type != BusinessType.INSERT && ObjectUtil.isEmpty(id)) {
             throw new ServiceException("id不能为空");
         }
-        if (ObjectUtil.isEmpty(category)) {
+        if (StrUtil.isBlank(category)) {
             throw new ServiceException("产业类别不能为空");
         }
         if (StrUtil.isBlank(name)) {
@@ -160,12 +160,12 @@ public class VillageTraditionServiceImpl extends ServiceImpl<VillageTraditionMap
         }
 
         // 从对象中取值
-        Integer category = villageTraditionQueryRequest.getCategory();
+        String category = villageTraditionQueryRequest.getCategory();
         String name = villageTraditionQueryRequest.getName();
         String sortField = villageTraditionQueryRequest.getSortField();
         String sortOrder = villageTraditionQueryRequest.getSortOrder();
 
-        queryWrapper.eq(ObjectUtil.isNotEmpty(category), "category", category);
+        queryWrapper.eq(StringUtils.isNotBlank(category), "category", category);
         queryWrapper.like(StringUtils.isNotBlank(name), "name", name);
 
         // 排序

+ 86 - 0
app-admin/src/main/java/generator/domain/VillageService.java

@@ -0,0 +1,86 @@
+package generator.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 乡村振兴产业服务与支持
+ * @TableName village_service
+ */
+@TableName(value ="village_service")
+@Data
+public class VillageService implements Serializable {
+    /**
+     * 
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 标题
+     */
+    private String title;
+
+    /**
+     * 标签
+     */
+    private String tag;
+
+    /**
+     * 类型 0-图文,1-视频
+     */
+    private String type;
+
+    /**
+     * 内容
+     */
+    private String content;
+
+    /**
+     * 封面图
+     */
+    private String photoUrl;
+
+    /**
+     * 来源
+     */
+    private String source;
+
+    /**
+     * 发布状态 0-未发布 1-已发布 2-下架
+     */
+    private Integer status;
+
+    /**
+     * 发布日期
+     */
+    private Date date;
+
+    /**
+     * 发布人id
+     */
+    private Integer issuerId;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    private Date updateTime;
+
+    /**
+     * 删除标志
+     */
+    private String delFlag;
+
+    @TableField(exist = false)
+    private static final long serialVersionUID = 1L;
+}

+ 15 - 0
app-admin/src/main/java/generator/mapper/VillageServiceMapper.java

@@ -0,0 +1,15 @@
+package generator.mapper;
+
+import generator.domain.VillageService;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @Entity generator.domain.VillageService
+ */
+public interface VillageServiceMapper extends BaseMapper<VillageService> {
+
+}
+
+
+
+

+ 11 - 0
app-admin/src/main/java/generator/service/VillageServiceService.java

@@ -0,0 +1,11 @@
+package generator.service;
+
+import generator.domain.VillageService;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ *
+ */
+public interface VillageServiceService extends IService<VillageService> {
+
+}

+ 20 - 0
app-admin/src/main/java/generator/service/impl/VillageServiceServiceImpl.java

@@ -0,0 +1,20 @@
+package generator.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import generator.domain.VillageService;
+import generator.service.VillageServiceService;
+import generator.mapper.VillageServiceMapper;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ */
+@Service
+public class VillageServiceServiceImpl extends ServiceImpl<VillageServiceMapper, VillageService>
+    implements VillageServiceService{
+
+}
+
+
+
+

+ 22 - 0
app-admin/src/main/resources/mapper/web/EventAssignMapper.xml

@@ -0,0 +1,22 @@
+<?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.web.mapper.EventAssignMapper">
+
+    <resultMap id="BaseResultMap" type="com.ruoyi.web.domain.entity.EventAssign">
+            <id property="id" column="id" jdbcType="INTEGER"/>
+            <result property="eventId" column="event_id" jdbcType="INTEGER"/>
+            <result property="personId" column="person_id" jdbcType="INTEGER"/>
+            <result property="status" column="status" jdbcType="CHAR"/>
+            <result property="isReassign" column="is_reassign" jdbcType="CHAR"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,event_id,person_id,
+        status,is_reassign,create_time,
+        update_time
+    </sql>
+</mapper>

+ 30 - 0
app-admin/src/main/resources/mapper/web/EventMapper.xml

@@ -0,0 +1,30 @@
+<?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.web.mapper.EventMapper">
+
+    <resultMap id="BaseResultMap" type="com.ruoyi.web.domain.entity.Event">
+            <id property="id" column="id" jdbcType="INTEGER"/>
+            <result property="occurTime" column="occur_time" jdbcType="TIMESTAMP"/>
+            <result property="type" column="type" jdbcType="INTEGER"/>
+            <result property="location" column="location" jdbcType="VARCHAR"/>
+            <result property="description" column="description" jdbcType="VARCHAR"/>
+            <result property="photoUrl" column="photo_url" jdbcType="VARCHAR"/>
+            <result property="status" column="status" jdbcType="CHAR"/>
+            <result property="submitterId" column="submitter_id" jdbcType="INTEGER"/>
+            <result property="processResult" column="process_result" jdbcType="VARCHAR"/>
+            <result property="processTime" column="process_time" jdbcType="TIMESTAMP"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+            <result property="delFlag" column="del_flag" jdbcType="CHAR"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,occur_time,type,
+        location,description,photo_url,
+        status,submitter_id,process_result,
+        process_time,create_time,update_time,
+        del_flag
+    </sql>
+</mapper>

+ 1 - 1
app-admin/src/main/resources/mapper/web/VillageSpecialMapper.xml

@@ -6,7 +6,7 @@
 
     <resultMap id="BaseResultMap" type="com.ruoyi.web.domain.entity.VillageSpecial">
             <id property="id" column="id" jdbcType="INTEGER"/>
-            <result property="category" column="category" jdbcType="INTEGER"/>
+            <result property="category" column="category" jdbcType="VARCHAR"/>
             <result property="name" column="name" jdbcType="VARCHAR"/>
             <result property="location" column="location" jdbcType="VARCHAR"/>
             <result property="peopleNum" column="people_num" jdbcType="VARCHAR"/>

+ 1 - 1
app-admin/src/main/resources/mapper/web/VillageTraditionMapper.xml

@@ -6,7 +6,7 @@
 
     <resultMap id="BaseResultMap" type="com.ruoyi.web.domain.entity.VillageTradition">
             <id property="id" column="id" jdbcType="INTEGER"/>
-            <result property="category" column="category" jdbcType="INTEGER"/>
+            <result property="category" column="category" jdbcType="VARCHAR"/>
             <result property="name" column="name" jdbcType="VARCHAR"/>
             <result property="location" column="location" jdbcType="VARCHAR"/>
             <result property="area" column="area" jdbcType="VARCHAR"/>

+ 21 - 2
app-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java

@@ -1,8 +1,9 @@
 package com.ruoyi.system.mapper;
 
-import java.util.List;
-import org.apache.ibatis.annotations.Param;
 import com.ruoyi.common.core.domain.entity.SysUser;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * 用户表 数据层
@@ -11,6 +12,7 @@ import com.ruoyi.common.core.domain.entity.SysUser;
  */
 public interface SysUserMapper
 {
+
     /**
      * 根据条件分页查询用户列表
      * 
@@ -124,4 +126,21 @@ public interface SysUserMapper
      * @return 结果
      */
     public SysUser checkEmailUnique(String email);
+
+    /**
+     * 根据角色键查询用户ID列表
+     *
+     * @param roleKeys 角色键列表
+     * @return 用户ID列表
+     */
+    List<Long> selectUserIdsByRoleKeys(@Param("roleKeys") List<String> roleKeys);
+
+
+    /**
+     * 根据用户ID集合查询有效的用户列表(用于事件)
+     *
+     * @param userIds 用户ID集合(非空)
+     * @return 有效的用户列表(状态正常且未删除)
+     */
+    List<SysUser> selectUserListForEvent(@Param("userIds") List<Integer> userIds);
 }

+ 12 - 1
app-system/src/main/java/com/ruoyi/system/service/ISysUserService.java

@@ -1,8 +1,9 @@
 package com.ruoyi.system.service;
 
-import java.util.List;
 import com.ruoyi.common.core.domain.entity.SysUser;
 
+import java.util.List;
+
 /**
  * 用户 业务层
  * 
@@ -203,4 +204,14 @@ public interface ISysUserService
      * @return 结果
      */
     public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName);
+
+    /**
+     * 根据角色键查询用户ID列表(忽略数据权限,用于事件分配)
+     *
+     * @param roleKeys 角色键列表
+     * @return 用户ID列表
+     */
+    List<Long> selectUserIdsByRoleKeysForEvent(List<String> roleKeys);
+
+
 }

+ 24 - 10
app-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java

@@ -1,15 +1,5 @@
 package com.ruoyi.system.service.impl;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-import javax.validation.Validator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
 import com.ruoyi.common.annotation.DataScope;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.entity.SysRole;
@@ -27,6 +17,17 @@ import com.ruoyi.system.mapper.SysUserMapper;
 import com.ruoyi.system.mapper.SysUserRoleMapper;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.service.ISysUserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.validation.Validator;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * 用户 业务层处理
@@ -506,4 +507,17 @@ public class SysUserServiceImpl implements ISysUserService
         }
         return successMsg.toString();
     }
+
+    /**
+     * 根据角色键查询用户ID列表(忽略数据权限,用于事件分配)
+     *
+     * @param roleKeys 角色键列表
+     * @return 用户ID列表
+     */
+    @Override
+    public List<Long> selectUserIdsByRoleKeysForEvent(List<String> roleKeys) {
+        return userMapper.selectUserIdsByRoleKeys(roleKeys);
+    }
+
+
 }

+ 31 - 3
app-system/src/main/resources/mapper/system/SysUserMapper.xml

@@ -33,8 +33,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="dataScope"    column="data_scope"     />
         <result property="status"       column="role_status"    />
     </resultMap>
-	
-	<sql id="selectUserVo">
+
+
+    <sql id="selectUserVo">
         select u.user_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
         r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
         from sys_user u
@@ -197,5 +198,32 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			#{userId}
         </foreach> 
  	</delete>
-	
+
+    <select id="selectUserIdsByRoleKeys" resultType="long">
+        select distinct u.user_id
+        from sys_user u
+        left join sys_user_role ur on u.user_id = ur.user_id
+        left join sys_role r on r.role_id = ur.role_id
+        where u.del_flag = '0'
+        and r.role_key in
+        <foreach collection="roleKeys" item="roleKey" open="(" separator="," close=")">
+            #{roleKey}
+        </foreach>
+    </select>
+
+    <select id="selectUserListForEvent" resultType="com.ruoyi.common.core.domain.entity.SysUser">
+        SELECT
+        user_id, user_name, nick_name, avatar,
+        phonenumber, email, sex, status
+        FROM sys_user
+        WHERE
+        del_flag = '0'
+        AND status = '0'
+        AND user_id IN
+        <foreach collection="userIds" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+        ORDER BY user_id
+    </select>
+
 </mapper> 

+ 6 - 5
pom.xml

@@ -187,11 +187,11 @@
             </dependency>
 
             <!-- 代码生成-->
-            <dependency>
-                <groupId>com.ruoyi</groupId>
-                <artifactId>app-generator</artifactId>
-                <version>${ruoyi.version}</version>
-            </dependency>
+            <!--            <dependency>-->
+            <!--                <groupId>com.ruoyi</groupId>-->
+            <!--                <artifactId>app-generator</artifactId>-->
+            <!--                <version>${ruoyi.version}</version>-->
+            <!--            </dependency>-->
 
             <!-- 核心模块-->
             <dependency>
@@ -214,6 +214,7 @@
                 <version>${ruoyi.version}</version>
             </dependency>
 
+
         </dependencies>
     </dependencyManagement>
 

+ 61 - 4
sql/sql.sql

@@ -221,7 +221,7 @@ create table employment_data
 create table village_tradition
 (
     id                int auto_increment primary key,
-    category int          null          comment '产业类别(0-种植业、1-养殖业)',
+    category varchar(10)          null          comment '产业类别(0-种植业、1-养殖业)',
     name         varchar(255) null      comment '基地名称',
     location     varchar(255) null      comment '位置',
     area     varchar(255) null          comment '种植面积/养殖规模',
@@ -239,7 +239,7 @@ create table village_tradition
 create table village_special
 (
     id                int auto_increment primary key,
-    category int          null comment '产业类别(0-保安腰刀产业、1-农家乐产业、2-民宿产业)',
+    category varchar(10)          null comment '产业类别(0-保安腰刀产业、1-农家乐产业、2-民宿产业)',
     name        varchar(255) null comment '产业名称',
     location          varchar(255) null comment '位置',
     people_num        varchar(255) null comment '传承人数',
@@ -274,8 +274,8 @@ create table village_service
 (
     id      int auto_increment primary key,
     title   varchar(11)   null comment '标题',
-    tag   varchar(512)   null   comment '标签',
-    type   int default 0 null comment '类型 0-图文,1-视频',
+    tag   varchar(10)   null   comment '标签',
+    type   varchar(10) default 0 null comment '类型 0-图文,1-视频',
     content varchar(255)  null comment '内容',
     photo_url varchar(255)  null comment '封面图',
     source varchar(255)  null   comment '来源',
@@ -345,3 +345,60 @@ CREATE TABLE media_propaganda (
   INDEX idx_publish_date (publish_date),
   INDEX idx_extract_date (extract_date)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='媒体宣传内容收集表';
+
+-- 事件表
+CREATE TABLE event (
+  id int PRIMARY KEY AUTO_INCREMENT COMMENT '事件ID',
+  occur_time datetime NOT NULL COMMENT '事发时间',
+  type int NOT NULL COMMENT '事件类别,0-矛盾纠纷类/1-消防隐患类/2-安全隐患类/3-社会治安类/4-环境治理类/5-反诈宣传类',
+  location varchar(200) NOT NULL COMMENT '事发地点',
+  description varchar(512)  COMMENT '事件描述',
+  photo_url    VARCHAR(255)     COMMENT '照片',
+  status char(1) DEFAULT '0' COMMENT '状态(0-未完结 1-已完结)',
+  submitter_id int NOT NULL COMMENT '填报人ID(村民id)',
+  process_result  VARCHAR(512) COMMENT '处理结果',
+  process_time datetime COMMENT '处理时间',
+  create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
+  update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '修改时间',
+  del_flag char default '0' null comment '删除标志',
+  KEY idx_type (`type`),
+  KEY idx_status (`status`),
+  KEY idx_submitter (`submitter_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='事件主表';
+
+-- 事件负责人分配表
+CREATE TABLE event_assign (
+  id int PRIMARY KEY AUTO_INCREMENT COMMENT '分配ID',
+  event_id int NOT NULL COMMENT '事件ID',
+  person_id int NOT NULL COMMENT '负责人ID',
+  status char(1) DEFAULT '0' COMMENT '状态(0未完结 1本人已完结 2其他人已完结)',
+  is_reassign char(1) DEFAULT '0' COMMENT '是否重新分配(0否 1是)',
+  create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
+  update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '修改时间',
+  UNIQUE KEY `uk_event_user` (`event_id`, `person_id`),  -- 联合唯一索引
+  KEY `idx_event_status` (`event_id`, `status`),
+  KEY `idx_user_status` (`person_id`, `status`)
+) ENGINE=InnoDB COMMENT='事件负责人分配表';
+
+-- 某个事件的处理人 只需要在  查询时 查询 事件id 且 状态为1的即可 因为其他负责人的数据状态为2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+