Browse Source

执法端-计划

dev-V1.0.1
庄锐波 3 months ago
parent
commit
c9e3b8302a
  1. 2
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/EnterpriseSearchController.java
  2. 8
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpPlanService.java
  3. 12
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpPlanServiceImpl.java
  4. 69
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpReserveServiceImpl.java
  5. 2
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EnterpriseInformationServiceImpl.java
  6. 13
      zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/reserve.js
  7. 6
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_edit.vue
  8. 5
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_manual.vue
  9. 1
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_system.vue
  10. 58
      zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/rest/test/cp/AppEnfCpPlanDeadlineGenTaskTest.java

2
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<List<EnterpriseSearchVo>> searchUnionByEnterpriseName(@RequestParam String enterpriseName) {

8
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);
}

12
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<EfcodeCpPlan> 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));

69
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<EfcodeCpReserve> allGroupReserves = baseMapper.selectList(
Wrappers.<EfcodeCpReserve>lambdaQuery()
.eq(EfcodeCpReserve::getPlanGroupId, reserve.getPlanGroupId())
);
// 2. 筛选已同意的记录
List<EfcodeCpReserve> 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.<EfcodeCpReserve>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());
}
}
/**
* 同意/拒绝操作后置处理
*

2
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);

13
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);

6
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_edit.vue

@ -220,7 +220,7 @@
</div>
<van-search
v-model="enterpriseSearchKeyword"
placeholder="输入≥ 3 个字符检索企业,不要输入深圳,深圳市"
placeholder="输入≥ 2 个字符检索企业,不要输入深圳,深圳市"
shape="round"
@update:model-value="onEnterpriseSearchInput"
/>
@ -238,7 +238,7 @@
<div class="enterprise-item-name">{{ item.enterpriseName }}</div>
<div class="enterprise-item-number">{{ item.enterpriseNumber }}</div>
</div>
<van-empty v-if="enterpriseSearchKeyword.length >= 3 && !enterpriseOptions.length" description="未检索到匹配企业" image-size="80" />
<van-empty v-if="enterpriseSearchKeyword.length >= 2 && !enterpriseOptions.length" description="未检索到匹配企业" image-size="80" />
</template>
</div>
</div>
@ -536,7 +536,7 @@ const onEnterpriseSearchInput = (val) => {
clearTimeout(enterpriseSearchTimer);
}
const keyword = (val || '').trim();
if (keyword.length < 3) {
if (keyword.length < 2) {
enterpriseOptions.value = [];
return;
}

5
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_manual.vue

@ -98,7 +98,7 @@
<script setup name="cpReserveManual">
import { showConfirmDialog, showSuccessToast, showDialog } from 'vant';
import { getReserveList, approveReserve, rejectReserveByManual } from '@/api/enforcement/reserve';
import { getReserveList, approveReserveByManual, rejectReserveByManual } from '@/api/enforcement/reserve';
const selectedId = ref(null);
const reserveList = ref([]);
@ -221,6 +221,7 @@ const onShowMessage = (item) => {
title: '预约留言',
message: item.opMessage,
confirmButtonText: '关闭',
width: '80vw',
});
};
@ -230,7 +231,7 @@ const onApprove = (item) => {
title: '提示',
message: '确定同意该预约申请吗?',
}).then(() => {
approveReserve(item.id, (res) => {
approveReserveByManual(item.id, (res) => {
if (res.code === 200) {
showSuccessToast('已同意');
afterOperate(item, 'approve');

1
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_system.vue

@ -292,6 +292,7 @@ const onShowMessage = (item) => {
title: '备注信息',
message: item.opMessage,
confirmButtonText: '关闭',
width: '80vw',
});
};

58
zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/rest/test/cp/AppEnfCpPlanDeadlineGenTaskTest.java

@ -0,0 +1,58 @@
package com.zdxt.rest.test.cp;
import com.zdxt.enforcementcode.service.IEfcodeCpPlanService;
import org.dromara.ZdxtAdminApplication;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
/**
* 计划到期自动生成任务测试
* <p>
* 调用 ignoreTime=true 模式忽略时间窗口限制
* 将所有未生成任务的计划全部处理取消待确认预约并生成任务
* </p>
*/
@SpringBootTest(classes = ZdxtAdminApplication.class)
@ActiveProfiles({"dev", "dev-cust-zrb"})
@DisplayName("计划到期自动生成任务测试")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class AppEnfCpPlanDeadlineGenTaskTest {
@Autowired
private IEfcodeCpPlanService cpPlanService;
/**
* 忽略时间 - 处理所有未生成任务的计划
* <p>将所有符合条件的计划reserveStatus{1,2,4,5,6}且无taskId全部处理
* 取消待确认预约为已同意的生成共享任务为无联合记录的生成独立任务</p>
*/
@DisplayName("忽略时间 - 计划到期自动生成任务")
@Test
@Order(1)
public void testProcessPlanDeadline_ignoreTime() {
System.out.println("========== 开始执行计划到期自动生成任务(忽略时间) ==========");
int processedCount = cpPlanService.processPlanDeadlineAutoGenTask(true);
System.out.println("处理计划数: " + processedCount);
System.out.println("========== 计划到期自动生成任务完毕 ==========");
}
/**
* 正常模式 - 仅处理到期窗口内的计划
* <p> CP_SETTING_MANUAL_MATCH_DAYS 配置的天数窗口处理即将到期的计划</p>
*/
@DisplayName("正常模式 - 仅处理到期窗口内的计划")
@Test
@Order(2)
public void testProcessPlanDeadline_normal() {
System.out.println("========== 开始执行计划到期自动生成任务(正常模式) ==========");
int processedCount = cpPlanService.processPlanDeadlineAutoGenTask(false);
System.out.println("处理计划数: " + processedCount);
System.out.println("========== 计划到期自动生成任务完毕 ==========");
}
}
Loading…
Cancel
Save