diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/EnterpriseSearchController.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/EnterpriseSearchController.java index ae77101a..fe09117a 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/EnterpriseSearchController.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/EnterpriseSearchController.java @@ -36,7 +36,7 @@ public class EnterpriseSearchController extends BaseController { /** * 根据企业名称模糊搜索 * - * @param enterpriseName 企业名称关键字(>=3个字符) + * @param enterpriseName 企业名称关键字(>=2个字符) */ @GetMapping("/searchUnionByEnterpriseName") public R> searchUnionByEnterpriseName(@RequestParam String enterpriseName) { diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpPlanService.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpPlanService.java index b5f486e2..3691c4ca 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpPlanService.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpPlanService.java @@ -112,4 +112,12 @@ public interface IEfcodeCpPlanService { * @return 处理的计划数量 */ int processPlanDeadlineAutoGenTask(); + + /** + * 计划到期自动生成任务(支持忽略时间) + * + * @param ignoreTime true=忽略时间窗口限制,处理所有未生成任务的计划;false=仅处理到期窗口内的计划 + * @return 处理的计划数量 + */ + int processPlanDeadlineAutoGenTask(boolean ignoreTime); } 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 2cfcf7d8..81efa1d7 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 @@ -1122,14 +1122,22 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService { @Transactional(rollbackFor = Exception.class) @Override public int processPlanDeadlineAutoGenTask() { + return processPlanDeadlineAutoGenTask(false); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public int processPlanDeadlineAutoGenTask(boolean ignoreTime) { int manualMatchDays = cpSettingService.getManualMatchDays(); LocalDate today = LocalDate.now(); LocalDate deadlineDate = today.plusDays(manualMatchDays); // 1. 查找即将到期的计划:plan_date <= today + manualMatchDays,且未生成任务 LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.le(EfcodeCpPlan::getPlanDate, java.sql.Date.valueOf(deadlineDate)); - lqw.ge(EfcodeCpPlan::getPlanDate, java.sql.Date.valueOf(today)); + if (!ignoreTime) { + lqw.le(EfcodeCpPlan::getPlanDate, java.sql.Date.valueOf(deadlineDate)); + lqw.ge(EfcodeCpPlan::getPlanDate, java.sql.Date.valueOf(today)); + } lqw.eq(EfcodeCpPlan::getIsDelete, 0L); lqw.and(w -> w.isNull(EfcodeCpPlan::getTaskId).or().eq(EfcodeCpPlan::getTaskId, "")); lqw.in(EfcodeCpPlan::getReserveStatus, Arrays.asList(1L, 2L, 4L, 5L, 6L)); 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 fcaef5c3..971f041e 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 @@ -549,18 +549,45 @@ public class EfcodeCpReserveServiceImpl implements IEfcodeCpReserveService { } /** - * 手动预约后置检查:同意后直接为该计划生成任务 + * 手动预约后置检查:同组内同意数量 >= CP_MAX_UNION_UNIT 时生成共享任务 */ private void afterManualMatchComplete(EfcodeCpReserve reserve) { - if (StringUtils.isBlank(reserve.getPlanId())) { + if (StringUtils.isBlank(reserve.getPlanGroupId())) { return; } - EfcodeCpPlan plan = cpPlanMapper.selectById(reserve.getPlanId()); - if (plan == null || StringUtils.isNotBlank(plan.getTaskId())) { + // 1. 查询同组全部记录 + List allGroupReserves = baseMapper.selectList( + Wrappers.lambdaQuery() + .eq(EfcodeCpReserve::getPlanGroupId, reserve.getPlanGroupId()) + ); + // 2. 筛选已同意的记录 + List approvedReserves = allGroupReserves.stream() + .filter(r -> Long.valueOf(1L).equals(r.getOpStatus())) + .collect(Collectors.toList()); + // 3. 判断是否达到最大联合单位数 + int maxUnionUnit = cpSettingService.getMaxUnionUnit(); + if (approvedReserves.size() < maxUnionUnit) { + log.info("[手动预约后置] planGroupId={} 已同意{}家,未达到最大联合数{},暂不生成任务", + reserve.getPlanGroupId(), approvedReserves.size(), maxUnionUnit); return; } - //String taskId = cpTaskService.forceGenerateTask(plan); - //log.info("[手动预约后置] 计划[{}] 同意后生成任务taskId={}", reserve.getPlanId(), taskId); + // 4. 达到条件,生成共享任务,绑定回所有已同意计划的 task_id + String sharedTaskId = null; + for (EfcodeCpReserve r : approvedReserves) { + EfcodeCpPlan plan = cpPlanMapper.selectById(r.getPlanId()); + if (plan == null || StringUtils.isNotBlank(plan.getTaskId())) continue; + if (sharedTaskId == null) { + sharedTaskId = cpTaskService.forceGenerateTask(plan); + } else { + EfcodeCpPlan planUpdate = new EfcodeCpPlan(); + planUpdate.setId(plan.getId()); + planUpdate.setTaskId(sharedTaskId); + planUpdate.setReserveStatus(3L); + cpPlanMapper.updateById(planUpdate); + } + } + log.info("[手动预约后置] planGroupId={} 已同意{}家 >= maxUnionUnit={},生成共享任务taskId={}", + reserve.getPlanGroupId(), approvedReserves.size(), maxUnionUnit, sharedTaskId); } /** @@ -634,9 +661,39 @@ public class EfcodeCpReserveServiceImpl implements IEfcodeCpReserveService { reserve.setOpTime(new Date()); baseMapper.updateById(reserve); afterOperate(reserve, "reject"); + // 后置处理:目标计划若为状态6(人数已满)则回退5(还有位置) + afterManualRejectUpdateTargetPlan(reserve); return R.ok(); } + /** + * 手动预约拒绝后置:目标计划 reserveStatus=6 → 5 + */ + private void afterManualRejectUpdateTargetPlan(EfcodeCpReserve reserve) { + if (StringUtils.isBlank(reserve.getPlanGroupId())) { + return; + } + // 查找同组中 sender=manual_system_sender 的记录(目标计划的自动记录) + EfcodeCpReserve targetReserve = baseMapper.selectOne( + Wrappers.lambdaQuery() + .eq(EfcodeCpReserve::getPlanGroupId, reserve.getPlanGroupId()) + .eq(EfcodeCpReserve::getSenderId, "manual_system_sender") + .last("LIMIT 1") + ); + if (targetReserve == null || StringUtils.isBlank(targetReserve.getPlanId())) { + return; + } + // 查询目标计划 + EfcodeCpPlan targetPlan = cpPlanMapper.selectById(targetReserve.getPlanId()); + if (targetPlan != null && Long.valueOf(6L).equals(targetPlan.getReserveStatus())) { + EfcodeCpPlan planUpdate = new EfcodeCpPlan(); + planUpdate.setId(targetPlan.getId()); + planUpdate.setReserveStatus(5L); // 从"人数已满"回退5"还有位置" + cpPlanMapper.updateById(planUpdate); + log.info("[手动拒绝后置] 目标计划[{}] reserveStatus 从6更新为5", targetPlan.getId()); + } + } + /** * 同意/拒绝操作后置处理 * diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EnterpriseInformationServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EnterpriseInformationServiceImpl.java index 7550bb4e..1b261ad6 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EnterpriseInformationServiceImpl.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EnterpriseInformationServiceImpl.java @@ -294,7 +294,7 @@ public class EnterpriseInformationServiceImpl implements IEnterpriseInformationS String keyword = enterpriseName.trim() .replace("深圳市", "") .replace("深圳", ""); - if (keyword.length() < 3) { + if (keyword.length() < 2) { return List.of(); } return baseMapper.searchUnionByEnterpriseName(keyword); diff --git a/zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/reserve.js b/zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/reserve.js index 74c7d88c..5fb40521 100644 --- a/zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/reserve.js +++ b/zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/reserve.js @@ -11,7 +11,7 @@ export const getReserveList = (params, success, error) => _get(reserveBaseUrl + export const getReserveDetail = (id, success, error) => _get(reserveBaseUrl + "/detail/" + id, {}, success, error); // 预约处理:同意(系统匹配专用,支持传选择的时间参数) -export const approveReserve = (id, params, success, error) => { +export const approveReserveBySystem = (id, params, success, error) => { let url = reserveBaseUrl + "/approveBySystem/" + id; if (params) { const qs = Object.entries(params).filter(([, v]) => v != null).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join('&'); @@ -20,6 +20,17 @@ export const approveReserve = (id, params, success, error) => { return _put(url, {}, success, error); }; +// 预约处理:同意(手动预约专用) +export const approveReserveByManual = (id, success, error) => _put(reserveBaseUrl + "/approveByManual/" + id, {}, success, error); + +// 兼容旧调用:根据 resFrom 自动分派到对应接口 +export const approveReserve = (id, params, success, error, resFrom) => { + if (resFrom === 0 || resFrom === '0') { + return approveReserveByManual(id, success, error); + } + return approveReserveBySystem(id, params, success, error); +}; + // 预约处理:拒绝(系统匹配专用) export const rejectReserveBySystem = (id, success, error) => _put(reserveBaseUrl + "/rejectBySystem/" + id, {}, success, error); 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 24326bf2..e503c8a2 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 @@ -220,7 +220,7 @@ @@ -238,7 +238,7 @@
{{ item.enterpriseName }}
{{ item.enterpriseNumber }}
- + @@ -536,7 +536,7 @@ const onEnterpriseSearchInput = (val) => { clearTimeout(enterpriseSearchTimer); } const keyword = (val || '').trim(); - if (keyword.length < 3) { + if (keyword.length < 2) { enterpriseOptions.value = []; return; } diff --git a/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_manual.vue b/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_manual.vue index fa1a5733..412b3fc4 100644 --- a/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_manual.vue +++ b/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_manual.vue @@ -98,7 +98,7 @@