From dbfeaca33730631b89fca2c5d0c3844c85ca8c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=84=E9=94=90=E6=B3=A2?= <10549902+zhuangruibo@user.noreply.gitee.com> Date: Tue, 26 May 2026 19:45:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=A7=E6=B3=95=E7=AB=AF-=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enforcement/AppEnfCpTaskController.java | 51 ++ .../domain/vo/EfcodeCpPlanVo.java | 7 + .../domain/vo/EfcodeCpTaskVo.java | 92 +++ .../mapper/EfcodeCpTaskMapper.java | 30 + .../service/IEfcodeCpTaskService.java | 37 ++ .../service/impl/EfcodeCpPlanServiceImpl.java | 88 ++- .../impl/EfcodeCpReserveServiceImpl.java | 50 +- .../service/impl/EfcodeCpTaskServiceImpl.java | 53 ++ .../enforcementcode/EfcodeCpTaskMapper.xml | 81 +++ .../src/api/enforcement/plan.js | 7 +- .../router/enforcement-app/enf-main-router.js | 18 + .../views/enforcement/my/enforcementMy.vue | 4 +- .../enforcement/my/plan/cp_plan_edit.vue | 63 +- .../enforcement/my/plan/cp_plan_mine.vue | 14 +- .../enforcement/my/plan/cp_plan_other.vue | 10 +- .../enforcement/my/task/cp_task_detail.vue | 392 ++++++++++++ .../enforcement/my/task/cp_task_mine.vue | 578 ++++++++++++++++++ 17 files changed, 1551 insertions(+), 24 deletions(-) create mode 100644 zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/task/cp_task_detail.vue create mode 100644 zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/task/cp_task_mine.vue diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfCpTaskController.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfCpTaskController.java index d65227a6..4d1af96e 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfCpTaskController.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfCpTaskController.java @@ -1,10 +1,18 @@ package com.zdxt.enforcementcode.controller.app.enforcement; import com.zdxt.enforcementcode.controller.web.supervision.EfcodeCpTaskController; +import com.zdxt.enforcementcode.domain.vo.EfcodeCpTaskVo; import com.zdxt.enforcementcode.service.IEfcodeCpTaskService; +import org.dromara.common.core.domain.R; +import org.dromara.common.satoken.utils.LoginHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.format.annotation.DateTimeFormat; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.Date; +import java.util.List; + /** * 行政执法检查计划-任务 * @@ -16,7 +24,50 @@ import org.springframework.web.bind.annotation.*; @RequestMapping("/app-enf/cpTask") public class AppEnfCpTaskController extends EfcodeCpTaskController { + @Autowired + private IEfcodeCpTaskService cpTaskService; + public AppEnfCpTaskController(IEfcodeCpTaskService efcodeCpTaskService) { super(efcodeCpTaskService); + this.cpTaskService = efcodeCpTaskService; + } + + /** + * 查询我的任务列表(指定日期) + * + * @param planDate 计划执行日期(可选,格式 yyyy-MM-dd) + * @return 任务列表 + */ + @GetMapping("/myList") + public R> myList( + @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date planDate) { + Long userId = LoginHelper.getUserId(); + List list = cpTaskService.queryMyTaskList(userId, planDate); + return R.ok(list); + } + + /** + * 查询指定月份中有任务的日期列表(用于日历打点) + * + * @param yearMonth 年月,格式如 "2026-03" + * @return 日期字符串列表 + */ + @GetMapping("/myTaskDates") + public R> myTaskDates(@RequestParam String yearMonth) { + Long userId = LoginHelper.getUserId(); + List dates = cpTaskService.queryMyTaskDates(userId, yearMonth); + return R.ok(dates); + } + + /** + * 查询我的任务详情(通过 planId 查询任务+计划完整信息) + * + * @param planId 计划ID + * @return 任务详情 + */ + @GetMapping("/myDetail") + public R myDetail(@RequestParam String planId) { + EfcodeCpTaskVo detail = cpTaskService.queryMyTaskDetail(planId); + return R.ok(detail); } } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpPlanVo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpPlanVo.java index 3d0e8bb3..b8006d4a 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpPlanVo.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpPlanVo.java @@ -169,6 +169,13 @@ public class EfcodeCpPlanVo implements Serializable { @com.baomidou.mybatisplus.annotation.TableField(exist = false) private Long editEnable; + /** + * 是否可以删除:1=是,0=否(非数据库字段,后置计算) + *

规则:可编辑时可删除;不联合执法且执行时间未到时也可删除

+ */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private Long deleteEnable; + /** * 执法单位ID */ diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpTaskVo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpTaskVo.java index 936a26f2..d4bb9cab 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpTaskVo.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpTaskVo.java @@ -46,5 +46,97 @@ public class EfcodeCpTaskVo implements Serializable { @ExcelProperty(value = "执法单位ID") private String bureauDeptId; + // ========== 以下为关联计划表字段,通过 SQL JOIN 填充,非数据库字段 ========== + + /** + * 关联计划ID + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private String planId; + + /** + * 计划执行日期 + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private Date planDate; + + /** + * 执行时段:1=上午,2=下午,3=其他 + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private Long planTime; + + /** + * 经过预约后最终的计划执行日期 + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private Date planActualDate; + + /** + * 经过预约后最终的执行时段:1=上午,2=下午,3=其他 + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private Long planActualTime; + + /** + * 执法事项 + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private String enforceContent; + + /** + * 被检查企业/机构名称 + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private String enterpriseName; + + /** + * 是否联合执法:1=是,0=否 + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private Long isUnion; + + /** + * 执法单位名称 + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private String bureauDeptName; + + /** + * 计划类别:1=日常计划,2=专项计划 + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private Long planType; + + /** + * 执法人员姓名(多个逗号分隔) + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private String enforceUserNames; + + /** + * 被检查企业/机构信用代码 + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private String enterpriseNumber; + + /** + * 联合执法单位(多个逗号分隔) + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private String unionBureauDeptNames; + + /** + * 预约状态:0=草稿,1=待预约,2=预约中,3=预约完成 + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private Long reserveStatus; + + /** + * 备注 + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private String remark; + } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/EfcodeCpTaskMapper.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/EfcodeCpTaskMapper.java index bdea1a75..cc7e2e88 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/EfcodeCpTaskMapper.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/EfcodeCpTaskMapper.java @@ -2,8 +2,12 @@ package com.zdxt.enforcementcode.mapper; import com.zdxt.enforcementcode.domain.EfcodeCpTask; import com.zdxt.enforcementcode.domain.vo.EfcodeCpTaskVo; +import org.apache.ibatis.annotations.Param; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import java.util.Date; +import java.util.List; + /** * 行政执法检查计划-任务Mapper接口 * @@ -12,4 +16,30 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; */ public interface EfcodeCpTaskMapper extends BaseMapperPlus { + /** + * 查询我的任务列表(通过计划表关联,筛选当前用户参与的任务) + * + * @param userId 当前用户ID + * @param planDate 计划执行日期(可为null) + * @return 任务列表 + */ + List selectMyTaskList(@Param("userId") Long userId, @Param("planDate") Date planDate); + + /** + * 查询指定月份中有任务的日期列表(用于日历打点) + * + * @param userId 当前用户ID + * @param yearMonth 年月,格式如 "2026-03" + * @return 日期字符串列表,格式如 ["2026-03-02", "2026-03-10"] + */ + List selectMyTaskDates(@Param("userId") Long userId, @Param("yearMonth") String yearMonth); + + /** + * 查询我的任务详情(通过 planId 查询任务+计划完整信息) + * + * @param planId 计划ID + * @return 任务详情 + */ + EfcodeCpTaskVo selectMyTaskDetail(@Param("planId") String planId); + } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpTaskService.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpTaskService.java index 9c432b16..0b6d7909 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpTaskService.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpTaskService.java @@ -5,7 +5,10 @@ import com.zdxt.enforcementcode.domain.bo.EfcodeCpTaskBo; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; +import com.zdxt.enforcementcode.domain.EfcodeCpPlan; + import java.util.Collection; +import java.util.Date; import java.util.List; /** @@ -65,4 +68,38 @@ public interface IEfcodeCpTaskService { * @return 是否删除成功 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 查询我的任务列表(通过计划表关联,筛选当前用户参与的任务) + * + * @param userId 当前用户ID + * @param planDate 计划执行日期(可为null) + * @return 任务列表 + */ + List queryMyTaskList(Long userId, Date planDate); + + /** + * 查询指定月份中有任务的日期列表(用于日历打点) + * + * @param userId 当前用户ID + * @param yearMonth 年月,格式如 "2026-03" + * @return 日期字符串列表 + */ + List queryMyTaskDates(Long userId, String yearMonth); + + /** + * 查询我的任务详情(通过 planId 查询任务+计划完整信息) + * + * @param planId 计划ID + * @return 任务详情 + */ + EfcodeCpTaskVo queryMyTaskDetail(String planId); + + /** + * 强制创建任务(忽略其他条件),根据计划信息直接生成任务记录并回写 plan.task_id + * + * @param plan 来源计划 + * @return 新建任务ID + */ + String forceGenerateTask(EfcodeCpPlan plan); } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpPlanServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpPlanServiceImpl.java index d2458359..64cbc8be 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpPlanServiceImpl.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpPlanServiceImpl.java @@ -21,6 +21,7 @@ import com.zdxt.enforcementcode.service.IEfcodeCpPlanService; import java.time.LocalDate; import java.time.ZoneId; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -37,6 +38,7 @@ import com.zdxt.enforcementcode.domain.EfcodeCpReserve; import com.zdxt.enforcementcode.domain.EfcodeCpSetting; import com.zdxt.enforcementcode.mapper.EfcodeCpReserveMapper; import com.zdxt.enforcementcode.mapper.EfcodeCpSettingMapper; +import com.zdxt.enforcementcode.service.IEfcodeCpTaskService; /** * 行政执法检查计划-计划Service业务层处理 @@ -53,6 +55,7 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService { private final EfcodeCpPlanUsersMapper efcodeCpPlanUsersMapper; private final EfcodeCpReserveMapper efcodeCpReserveMapper; private final EfcodeCpSettingMapper efcodeCpSettingMapper; + private final IEfcodeCpTaskService cpTaskService; /** * 查询行政执法检查计划-计划 @@ -130,8 +133,9 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService { } /** - * 后置计算 editEnable:判断记录是否可编辑 - *

规则:预约状态为草稿(0)或待预约(1)时可编辑,其他状态不可编辑

+ * 后置计算 editEnable / deleteEnable:判断记录是否可编辑、可删除 + *

editEnable 规则:预约状态为草稿(0)或待预约(1)时可编辑,其他状态不可编辑

+ *

deleteEnable 规则:可编辑时可删除;或者不联合执法(isUnion=0)且计划执行时间还未到时也可删除

* * @param records 查询结果列表 */ @@ -139,10 +143,22 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService { if (records == null || records.isEmpty()) { return; } + LocalDate today = LocalDate.now(); for (EfcodeCpPlanVo vo : records) { Long status = vo.getReserveStatus(); // 草稿(0)或待预约(1)可编辑,其他状态不可编辑 - vo.setEditEnable(status != null && status <= 1L ? 1L : 0L); + boolean canEdit = status != null && status <= 1L; + vo.setEditEnable(canEdit ? 1L : 0L); + + // 删除条件:可编辑 OR (不联合执法 AND 执行时间未到) + boolean canDelete = canEdit; + if (!canDelete && vo.getIsUnion() != null && vo.getIsUnion() == 0L && vo.getPlanDate() != null) { + LocalDate planLocalDate = vo.getPlanDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + if (planLocalDate.isAfter(today)) { + canDelete = true; + } + } + vo.setDeleteEnable(canDelete ? 1L : 0L); } } @@ -234,7 +250,27 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService { * @param entity 已持久化的实体 */ private void afterInsert(EfcodeCpPlanBo bo, EfcodeCpPlan entity) { - // TODO 后续扩展:如发送通知、记录日志等 + // 条件1:不联合的计划,直接生成任务 + if (entity.getIsUnion() != null && entity.getIsUnion() == 0L) { + log.info("[计划提交] 不联合计划,直接生成任务, planId={}", entity.getId()); + cpTaskService.forceGenerateTask(entity); + return; + } + // 条件2:执行时间距今天 <= CP_SETTING_MANUAL_MATCH_DAYS,直接生成任务 + if (entity.getPlanDate() != null) { + String manualMatchDaysStr = getSettingValue("CP_SETTING_MANUAL_MATCH_DAYS"); + int manualMatchDays = 3; // 默认值 + if (StringUtils.isNotBlank(manualMatchDaysStr)) { + try { manualMatchDays = Integer.parseInt(manualMatchDaysStr.trim()); } catch (NumberFormatException ignored) {} + } + LocalDate planLocalDate = entity.getPlanDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + long daysUntilPlan = ChronoUnit.DAYS.between(LocalDate.now(), planLocalDate); + if (daysUntilPlan <= manualMatchDays) { + log.info("[计划提交] 执行时间距今{}<={}(CP_SETTING_MANUAL_MATCH_DAYS),直接生成任务, planId={}", + daysUntilPlan, manualMatchDays, entity.getId()); + cpTaskService.forceGenerateTask(entity); + } + } } /** @@ -345,15 +381,45 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService { @Transactional(rollbackFor = Exception.class) @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if(isValid){ - //TODO 做一些业务上的校验,判断是否需要校验 + if (ids == null || ids.isEmpty()) { + return false; } - // 先级联删除计划参与人员表关联记录 - if (ids != null && !ids.isEmpty()) { - efcodeCpPlanUsersMapper.delete( - Wrappers.lambdaQuery().in(EfcodeCpPlanUsers::getPlanId, ids) - ); + // 查询待删除的计划记录 + List plans = baseMapper.selectByIds(ids); + if (isValid) { + LocalDate today = LocalDate.now(); + for (EfcodeCpPlan plan : plans) { + Long status = plan.getReserveStatus(); + boolean canEdit = status != null && status <= 1L; + boolean canDelete = canEdit; + // 不联合执法且执行时间未到,也允许删除 + if (!canDelete && plan.getIsUnion() != null && plan.getIsUnion() == 0L && plan.getPlanDate() != null) { + LocalDate planLocalDate = plan.getPlanDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + if (planLocalDate.isAfter(today)) { + canDelete = true; + } + } + if (!canDelete) { + throw new ServiceException("计划[" + + (plan.getEnterpriseName() != null ? plan.getEnterpriseName() : plan.getId()) + + "]当前状态不允许删除"); + } + } } + // 级联删除关联的任务记录 + List taskIds = plans.stream() + .map(EfcodeCpPlan::getTaskId) + .filter(StringUtils::isNotBlank) + .distinct() + .collect(Collectors.toList()); + if (!taskIds.isEmpty()) { + log.info("[删除计划] 级联删除任务记录, taskIds={}", taskIds); + cpTaskService.deleteWithValidByIds(taskIds, false); + } + // 级联删除计划参与人员表关联记录 + efcodeCpPlanUsersMapper.delete( + Wrappers.lambdaQuery().in(EfcodeCpPlanUsers::getPlanId, ids) + ); return baseMapper.deleteByIds(ids) > 0; } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpReserveServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpReserveServiceImpl.java index 1c05ea7c..6a25dc1b 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpReserveServiceImpl.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpReserveServiceImpl.java @@ -21,6 +21,7 @@ import com.zdxt.enforcementcode.mapper.EfcodeCpReserveMapper; import com.zdxt.enforcementcode.mapper.EfcodeCpPlanMapper; import com.zdxt.enforcementcode.service.IEfcodeCpReserveService; import com.zdxt.enforcementcode.service.IEfcodeCpSettingService; +import com.zdxt.enforcementcode.service.IEfcodeCpTaskService; import java.util.*; import java.util.stream.Collectors; @@ -39,6 +40,7 @@ public class EfcodeCpReserveServiceImpl implements IEfcodeCpReserveService { private final EfcodeCpReserveMapper baseMapper; private final EfcodeCpPlanMapper cpPlanMapper; private final IEfcodeCpSettingService cpSettingService; + private final IEfcodeCpTaskService cpTaskService; /** * 查询行政执法检查计划-预约 @@ -242,6 +244,28 @@ public class EfcodeCpReserveServiceImpl implements IEfcodeCpReserveService { // 插入1条记录 insertReserveRecord(myPlan.getId(), planGroupId, opMessage, targetPlan.getPlanDate(), targetPlan.getPlanTime(), 0L); } + + // ===== 插入预约记录后:更新两个计划的 reserve_status ===== + + // 1. 我的计划 → 2=预约中 + EfcodeCpPlan myPlanUpdate = new EfcodeCpPlan(); + myPlanUpdate.setId(myPlan.getId()); + myPlanUpdate.setReserveStatus(2L); + cpPlanMapper.updateById(myPlanUpdate); + + // 2. 对方计划 → 根据当前活跃预约数决定状态 + // 活跃数 < maxUnionUnit → 5=待预约(还有位置可以加入) + // 活跃数 = maxUnionUnit → 6=待预约(人数已满) + long currentActiveCount = countActiveReserves(planGroupId); + long newTargetStatus = (currentActiveCount >= maxUnionUnit) ? 6L : 5L; + EfcodeCpPlan targetPlanUpdate = new EfcodeCpPlan(); + targetPlanUpdate.setId(targetPlanId); + targetPlanUpdate.setReserveStatus(newTargetStatus); + cpPlanMapper.updateById(targetPlanUpdate); + + log.info("[doReserve] 我的计划[{}]→reserve_status=2, 对方计划[{}]→reserve_status={}, 活跃数={}, 最大联合数={}", + myPlan.getId(), targetPlanId, newTargetStatus, currentActiveCount, maxUnionUnit); + return R.ok(); } @@ -356,7 +380,31 @@ public class EfcodeCpReserveServiceImpl implements IEfcodeCpReserveService { * @param action 操作类型: "approve" 或 "reject" */ private void afterOperate(EfcodeCpReserve reserve, String action) { - // TODO: 可在此处扩展后置逻辑,如通知、状态同步等 log.info("预约记录[{}]执行{}操作后置处理, planGroupId={}", reserve.getId(), action, reserve.getPlanGroupId()); + // 同意操作后:检查同一 planGroupId 已同意数量是否达到最大联合单位数 + if ("approve".equals(action) && StringUtils.isNotBlank(reserve.getPlanGroupId())) { + int maxUnionUnit = cpSettingService.getMaxUnionUnit(); + long approvedCount = baseMapper.selectCount( + Wrappers.lambdaQuery() + .eq(EfcodeCpReserve::getPlanGroupId, reserve.getPlanGroupId()) + .eq(EfcodeCpReserve::getOpStatus, 1L) // 1=已同意 + ); + log.info("[预约后置] planGroupId={}, 已同意数量={}, 最大联合数={}", reserve.getPlanGroupId(), approvedCount, maxUnionUnit); + if (approvedCount >= maxUnionUnit) { + // 达标:为该分组所有计划生成任务 + List groupReserves = baseMapper.selectList( + Wrappers.lambdaQuery() + .eq(EfcodeCpReserve::getPlanGroupId, reserve.getPlanGroupId()) + .eq(EfcodeCpReserve::getOpStatus, 1L) + ); + for (EfcodeCpReserve r : groupReserves) { + EfcodeCpPlan plan = cpPlanMapper.selectById(r.getPlanId()); + if (plan != null && StringUtils.isBlank(plan.getTaskId())) { + cpTaskService.forceGenerateTask(plan); + } + } + log.info("[预约后置] planGroupId={} 联合数量达标,已为{}条计划生成任务", reserve.getPlanGroupId(), groupReserves.size()); + } + } } } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpTaskServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpTaskServiceImpl.java index fd5c5d91..7605c9ed 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpTaskServiceImpl.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpTaskServiceImpl.java @@ -13,9 +13,12 @@ import org.springframework.stereotype.Service; import com.zdxt.enforcementcode.domain.bo.EfcodeCpTaskBo; import com.zdxt.enforcementcode.domain.vo.EfcodeCpTaskVo; import com.zdxt.enforcementcode.domain.EfcodeCpTask; +import com.zdxt.enforcementcode.domain.EfcodeCpPlan; import com.zdxt.enforcementcode.mapper.EfcodeCpTaskMapper; +import com.zdxt.enforcementcode.mapper.EfcodeCpPlanMapper; import com.zdxt.enforcementcode.service.IEfcodeCpTaskService; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Collection; @@ -32,6 +35,7 @@ import java.util.Collection; public class EfcodeCpTaskServiceImpl implements IEfcodeCpTaskService { private final EfcodeCpTaskMapper baseMapper; + private final EfcodeCpPlanMapper cpPlanMapper; /** * 查询行政执法检查计划-任务 @@ -128,6 +132,55 @@ public class EfcodeCpTaskServiceImpl implements IEfcodeCpTaskService { return true; } + /** + * 查询我的任务列表 + */ + @Override + public List queryMyTaskList(Long userId, Date planDate) { + return baseMapper.selectMyTaskList(userId, planDate); + } + + /** + * 查询指定月份中有任务的日期列表 + */ + @Override + public List queryMyTaskDates(Long userId, String yearMonth) { + return baseMapper.selectMyTaskDates(userId, yearMonth); + } + + /** + * 查询我的任务详情 + */ + @Override + public EfcodeCpTaskVo queryMyTaskDetail(String planId) { + return baseMapper.selectMyTaskDetail(planId); + } + + /** + * 强制创建任务(忽略其他条件),根据计划信息直接生成任务记录并回写 plan.task_id + * + * @param plan 来源计划 + * @return 新建任务ID + */ + @Override + public String forceGenerateTask(EfcodeCpPlan plan) { + // 1. 创建任务记录 + EfcodeCpTask task = new EfcodeCpTask(); + task.setTaskName(plan.getEnterpriseName() + " - 执法检查任务"); + task.setBureauDeptId(plan.getBureauDeptId()); + baseMapper.insert(task); + log.info("[强制创建任务] 新建任务 taskId={}, planId={}, 企业={}", task.getId(), plan.getId(), plan.getEnterpriseName()); + + // 2. 回写计划的 task_id,同时将 reserve_status 设为 3(预约完成/形成任务) + EfcodeCpPlan planUpdate = new EfcodeCpPlan(); + planUpdate.setId(plan.getId()); + planUpdate.setTaskId(task.getId()); + planUpdate.setReserveStatus(3L); + cpPlanMapper.updateById(planUpdate); + + return task.getId(); + } + /** * 校验并批量删除行政执法检查计划-任务信息 * diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpTaskMapper.xml b/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpTaskMapper.xml index 657786c0..cfb5288d 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpTaskMapper.xml +++ b/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpTaskMapper.xml @@ -3,4 +3,85 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> + + + + + + + + + + diff --git a/zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/plan.js b/zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/plan.js index 0d5c16df..824a8ecd 100644 --- a/zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/plan.js +++ b/zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/plan.js @@ -32,7 +32,7 @@ export const doReservePlan = (params, success, error) => _post(planBaseUrl + "/r // region 计划-设置接口 -const settingBaseUrl = "/api/app-enf/cpSetting"; +const settingBaseUrl = "/app-enf/cpSetting"; // 下阶段计划提交最晚时间(每月几号前需提交下阶段计划<=) export const getSubmitDeadline = (success, error) => _get(settingBaseUrl + "/submitDeadline", {}, success, error); @@ -40,11 +40,14 @@ export const getSubmitDeadline = (success, error) => _get(settingBaseUrl + "/sub // 单位内部单次计划最多参与人数(>=3) export const getMaxInnerUnitAcPersonNum = (success, error) => _get(settingBaseUrl + "/maxInnerUnitAcPersonNum", {}, success, error); +// 手工匹配距计划开始天数 +export const getManualMatchDays = (success, error) => _get(settingBaseUrl + "/manualMatchDays", {}, success, error); + // endregion // region 企业检索接口 -const enterpriseSearchBaseUrl = "/api/enforcementcode/enterpriseSearch"; +const enterpriseSearchBaseUrl = "/enforcementcode/enterpriseSearch"; // 按企业名称联合检索(>=3字符) export const searchUnionByEnterpriseName = (enterpriseName, success, error) => diff --git a/zdxt-web-client/zdxt-efcode-enforcement-app/src/router/enforcement-app/enf-main-router.js b/zdxt-web-client/zdxt-efcode-enforcement-app/src/router/enforcement-app/enf-main-router.js index 54c21aeb..8ee94406 100644 --- a/zdxt-web-client/zdxt-efcode-enforcement-app/src/router/enforcement-app/enf-main-router.js +++ b/zdxt-web-client/zdxt-efcode-enforcement-app/src/router/enforcement-app/enf-main-router.js @@ -98,6 +98,24 @@ const routes = [ isKeepAlive: false, }, }, + // 执法端-我的任务列表 + { + path: "/enforcement/task", + name: "cpTaskMine", + component: () => import("@/views/enforcement/my/task/cp_task_mine.vue"), + meta: { + isKeepAlive: false, + }, + }, + // 执法端-任务详情 + { + path: "/enforcement/task/detail", + name: "cpTaskDetail", + component: () => import("@/views/enforcement/my/task/cp_task_detail.vue"), + meta: { + isKeepAlive: false, + }, + }, // 执法端-预约处理列表 { path: "/enforcement/reserve", diff --git a/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/enforcementMy.vue b/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/enforcementMy.vue index 4e5b58b1..92dc5992 100644 --- a/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/enforcementMy.vue +++ b/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/enforcementMy.vue @@ -119,13 +119,15 @@ const settingItem = { const onMenuClick = (item) => { switch (item.key) { case 'notice': - case 'task': // 跳至消息中心待办 tab,并带类型过滤参数 router.push({ path: '/enforcement/message', query: { tab: 'todo', type: item.key }, }); break; + case 'task': + router.push({ path: '/enforcement/task' }); + break; case 'appointment': router.push({ path: '/enforcement/reserve' }); break; diff --git a/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_edit.vue b/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_edit.vue index 284a96de..83f638c0 100644 --- a/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_edit.vue +++ b/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_edit.vue @@ -228,8 +228,8 @@ + + diff --git a/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/task/cp_task_mine.vue b/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/task/cp_task_mine.vue new file mode 100644 index 00000000..2ec96ce5 --- /dev/null +++ b/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/task/cp_task_mine.vue @@ -0,0 +1,578 @@ + + + + +