Browse Source

外部计划接口列表

dev-V1.0.7
vincent 6 days ago
parent
commit
fb9f42e211
  1. 421
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/externalInterface/LongGangInterfaceController.java
  2. 2
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeCpPlanBo.java
  3. 4
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeCpTaskBo.java
  4. 24
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/externalInterface/LongGangBindPlanBo.java
  5. 14
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/externalInterface/LongGangDeletePlanBo.java
  6. 15
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/externalInterface/LongGangUnbindPlanBo.java
  7. 23
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/externalInterface/LongGangCreatePlanVo.java
  8. 3
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IOutEfcodeCpPlanService.java
  9. 29
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/OutEfcodeCpPlanServiceImpl.java
  10. 5
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/OutEfcodeCpTaskServiceImpl.java

421
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/externalInterface/LongGangInterfaceController.java

@ -7,8 +7,13 @@ import com.zdxt.enforcementcode.common.util.StringUtils;
import com.zdxt.enforcementcode.domain.EfcodeCpPlan;
import com.zdxt.enforcementcode.domain.SysApiPlatformConfigEntity;
import com.zdxt.enforcementcode.domain.bo.EfcodeCpPlanBo;
import com.zdxt.enforcementcode.domain.bo.EfcodeCpTaskBo;
import com.zdxt.enforcementcode.domain.bo.externalInterface.LongGangBindPlanBo;
import com.zdxt.enforcementcode.domain.bo.externalInterface.LongGangCreateTaskBo;
import com.zdxt.enforcementcode.domain.bo.externalInterface.LongGangDeletePlanBo;
import com.zdxt.enforcementcode.domain.bo.externalInterface.LongGangUnbindPlanBo;
import com.zdxt.enforcementcode.domain.vo.EfcodeCpPlanVo;
import com.zdxt.enforcementcode.domain.vo.EfcodeCpTaskVo;
import com.zdxt.enforcementcode.domain.vo.EnterpriseInformationVo;
import com.zdxt.enforcementcode.domain.vo.SrzDeptVo;
import com.zdxt.enforcementcode.domain.vo.externalInterface.LongGangCreateTaskVo;
@ -25,6 +30,7 @@ import org.dromara.system.service.ISysDeptService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@ -32,7 +38,7 @@ import java.util.List;
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/external/api")
@RequestMapping("/external/api/lg")
public class LongGangInterfaceController {
private static final String HEADER_APP_KEY = "X-App-Key";
@ -44,203 +50,332 @@ public class LongGangInterfaceController {
private final ISysDeptService sysDeptService;
/**
* 外部接口-新增执法检查任务龙岗渠道
* <p>
* 通过 appKey 识别调用渠道接收执法检查计划参数完成以下流程
* <ol>
* <li>渠道认证校验 appKey 有效性获取 channelNo</li>
* <li>部门校验校验 deptId sys_dept 中存在并通过虚拟单位表查找所属执法单位bureauDeptId</li>
* <li>市认证机构映射通过 deptId srz_dept 中递归查找 unittypecode=10 的顶层机构organId</li>
* <li>企业匹配通过 enterpriseNumber统一社会信用代码查询 enterprise_information
* 存在则设置 enterpriseId不存在则置空</li>
* <li>计划入库通过 insertPlanOnly 插入执法计划不触发自动任务生成</li>
* <li>任务生成调用 forceGenerateTask 生成检查任务回写 plan.taskId reserveStatus=3</li>
* </ol>
* 渠道认证校验 appKey 并返回 channelNo
*
* @param appKey 请求头 X-App-Key用于识别调用渠道
* @param bo 创建任务请求参数
* @return 包含 planIdtaskIdoutSerialNo 的响应结果
* @param appKey 请求头 X-App-Key
* @return 认证成功返回 R.ok(channelNo)失败返回 R.fail(原因)
*/
@SaIgnore
@RepeatSubmit()
@Log(title = "外部接口-新增计划", businessType = BusinessType.INSERT)
@PostMapping("/createPlan")
public R<LongGangCreateTaskVo> createPlan(
@RequestHeader(value = HEADER_APP_KEY, required = false) String appKey,
@Validated @RequestBody LongGangCreateTaskBo bo) {
// ========== 1. 渠道认证:校验 appKey 并获取 channelNo ==========
private R<String> authenticateChannel(String appKey) {
if (StrUtil.isBlank(appKey)) {
return R.fail("缺少请求头: " + HEADER_APP_KEY);
}
SysApiPlatformConfigEntity consumer = sysApiPlatformConfigService.findByAppKey(appKey).orElse(null);
if (consumer == null) {
return R.fail("无效的 appKey");
}
String channelNo = consumer.getChannelNo();
if (StrUtil.isBlank(channelNo)) {
return R.fail("渠道未配置 channelNo");
}
return R.ok(channelNo);
}
// ========== 流水号唯一校验:同一渠道下 outSerialNo 不可重复 ==========
if (StrUtil.isNotBlank(bo.getOutSerialNo())) {
EfcodeCpPlanBo queryBo = new EfcodeCpPlanBo();
queryBo.setOutSerialNo(bo.getOutSerialNo());
queryBo.setChannelNo(channelNo);
List<EfcodeCpPlanVo> existing = outEfcodeCpPlanService.queryList(queryBo);
if (!existing.isEmpty()) {
return R.fail("外部流水号重复: " + bo.getOutSerialNo());
}
/**
* 外部接口-新增或修改执法检查计划龙岗渠道
* <p>
* 通过 appKey 识别调用渠道根据 outSerialNo 判断新增或修改
* <ul>
* <li>outSerialNo 已存在修改已有计划 reserveStatus=0/1 允许修改</li>
* <li>outSerialNo 不存在新增计划并生成任务</li>
* </ul>
*
* @param appKey 请求头 X-App-Key用于识别调用渠道
* @param bo 请求参数outSerialNo 必填用于幂等判断
* @return 包含 planIdtaskIdoutSerialNo 的响应结果
*/
@SaIgnore
@RepeatSubmit()
@Log(title = "外部接口-新增或修改计划", businessType = BusinessType.OTHER)
@PostMapping("/plan/saveOrUpdatePlan")
public R<LongGangCreateTaskVo> saveOrUpdatePlan(
@RequestHeader(value = HEADER_APP_KEY, required = false) String appKey,
@Validated @RequestBody LongGangCreateTaskBo bo) {
// ========== 1. 渠道认证 ==========
R<String> authResult = authenticateChannel(appKey);
if (!R.isSuccess(authResult)) {
return R.fail(authResult.getMsg());
}
String channelNo = authResult.getData();
// ========== 2. 部门校验:校验 deptId 在 sys_dept 表中存在 ==========
// ========== 2. 外部流水号校验 ==========
if (StrUtil.isBlank(bo.getOutSerialNo())) {
return R.fail("外部流水号不能为空");
}
// ========== 3. 公共校验:部门、执法单位、市认证机构、企业 ==========
SysDeptVo deptVo = sysDeptService.selectDeptById(bo.getDeptId());
if (deptVo == null) {
return R.fail("部门不存在: " + bo.getDeptId());
}
// ========== 3. 市认证机构映射:通过 deptId(srz_dept.organizationid) 递归查找 unittypecode=10 的执法机构 ==========
SrzDeptVo srzDeptVo = DataFilterUtil.getOrganIdByDeptId(bo.getDeptId());
// ========== 4. 执法单位查找:通过虚拟单位表向上查找所属执法单位(zone!=0 且 zone!=2) ==========
SysDeptVo bureauDeptVo = DataFilterUtil.getBureauDeptByDeptId(bo.getDeptId());
if (bureauDeptVo == null) {
return R.fail("执法单位不存在");
}
// ========== 5. 企业匹配:通过统一社会信用代码查询 enterprise_information 表 ==========
EnterpriseInformationVo enterprise = enterpriseInformationService.queryByEnterpriseNumber(bo.getEnterpriseNumber());
String enterpriseId;
if (enterprise != null) {
enterpriseId = enterprise.getId();
} else {
enterpriseId = "";
}
// ========== 6. 构建计划对象并设置默认值 ==========
EfcodeCpPlanBo planBo = MapstructUtils.convert(bo, EfcodeCpPlanBo.class);
planBo.setChannelNo(channelNo);
if(StringUtils.isEmpty(bo.getTaskId())){
planBo.setTaskId("");
}
planBo.setReserveStatus(0L);
planBo.setSystemReserved(0L);
planBo.setManualReserved(0L);
planBo.setIsDelete(0L);
planBo.setEnforceUserCodes("-");
// 设置执法单位(bureauDeptId 来自 sys_dept,是本地系统的局级执法单位)
planBo.setBureauDeptId(bureauDeptVo.getDeptId());
planBo.setBureauDeptName(bureauDeptVo.getDeptName());
// 设置企业ID(存在则取主键,不存在则置空)
planBo.setEnterpriseId(enterpriseId);
// 设置市认证机构(organId 来自 srz_dept,是市认证系统的顶层执法单位)
if(srzDeptVo != null){
planBo.setOrganId(srzDeptVo.getOrganizationid());
planBo.setOrganName(srzDeptVo.getName());
}else{
planBo.setOrganId("");
planBo.setOrganName("");
}
// ========== 7. 计划入库:仅插入计划,不触发 afterInsert 中的自动任务生成 ==========
outEfcodeCpPlanService.insertPlanOnly(planBo);
// ========== 8. 生成任务:创建 task 记录,回写 plan.taskId 和 plan.reserveStatus=3 ==========
EfcodeCpPlanVo planVo = outEfcodeCpPlanService.queryById(planBo.getId());
EfcodeCpPlan plan = MapstructUtils.convert(planVo, EfcodeCpPlan.class);
String taskId = outEfcodeCpTaskService.forceGenerateTask(plan);
// ========== 9. 构建返回结果 ==========
String enterpriseId = (enterprise != null) ? enterprise.getId() : "";
// ========== 4. 通过 outSerialNo + channelNo 判断新增或修改 ==========
EfcodeCpPlanBo queryBo = new EfcodeCpPlanBo();
queryBo.setOutSerialNo(bo.getOutSerialNo());
queryBo.setChannelNo(channelNo);
List<EfcodeCpPlanVo> existingList = outEfcodeCpPlanService.queryList(queryBo);
boolean isUpdate = !existingList.isEmpty();
LongGangCreateTaskVo vo = new LongGangCreateTaskVo();
vo.setPlanId(planBo.getId());
vo.setTaskId(taskId);
vo.setOutSerialNo(bo.getOutSerialNo());
log.info("[外部接口] 新增任务, appKey={}, channelNo={}, planId={}, taskId={}",
appKey, channelNo, planBo.getId(), taskId);
if (isUpdate) {
// ==================== 修改分支 ====================
EfcodeCpPlanVo existingPlan = existingList.get(0);
EfcodeCpPlanBo planBo = MapstructUtils.convert(bo, EfcodeCpPlanBo.class);
planBo.setId(existingPlan.getId());
planBo.setChannelNo(channelNo);
planBo.setBureauDeptId(bureauDeptVo.getDeptId());
planBo.setBureauDeptName(bureauDeptVo.getDeptName());
planBo.setEnterpriseId(enterpriseId);
if (srzDeptVo != null) {
planBo.setOrganId(srzDeptVo.getOrganizationid());
planBo.setOrganName(srzDeptVo.getName());
} else {
planBo.setOrganId("");
planBo.setOrganName("");
}
outEfcodeCpPlanService.updateByBo(planBo);
vo.setPlanId(existingPlan.getId());
vo.setTaskId(existingPlan.getTaskId());
log.info("[外部接口] 修改计划, appKey={}, channelNo={}, outSerialNo={}, planId={}",
appKey, channelNo, bo.getOutSerialNo(), existingPlan.getId());
} else {
// ==================== 新增分支 ====================
EfcodeCpPlanBo planBo = MapstructUtils.convert(bo, EfcodeCpPlanBo.class);
planBo.setChannelNo(channelNo);
if (StringUtils.isEmpty(bo.getTaskId())) {
planBo.setTaskId("");
}
planBo.setReserveStatus(0L);
planBo.setSystemReserved(0L);
planBo.setManualReserved(0L);
planBo.setIsDelete(0L);
planBo.setEnforceUserCodes("-");
planBo.setBureauDeptId(bureauDeptVo.getDeptId());
planBo.setBureauDeptName(bureauDeptVo.getDeptName());
planBo.setEnterpriseId(enterpriseId);
if (srzDeptVo != null) {
planBo.setOrganId(srzDeptVo.getOrganizationid());
planBo.setOrganName(srzDeptVo.getName());
} else {
planBo.setOrganId("");
planBo.setOrganName("");
}
outEfcodeCpPlanService.insertPlanOnly(planBo);
EfcodeCpPlan plan = MapstructUtils.convert(
outEfcodeCpPlanService.queryById(planBo.getId()), EfcodeCpPlan.class);
String taskId = outEfcodeCpTaskService.forceGenerateTask(plan);
vo.setPlanId(planBo.getId());
vo.setTaskId(taskId);
log.info("[外部接口] 新增计划并生成任务, appKey={}, channelNo={}, outSerialNo={}, planId={}, taskId={}",
appKey, channelNo, bo.getOutSerialNo(), planBo.getId(), taskId);
}
return R.ok(vo);
}
/**
* 外部接口-修改执法检查计划
* 外部接口-删除执法检查计划
* <p>
* 通过 planId 定位已有计划校验状态后更新字段
* reserveStatus=0(草稿) 1(待预约) 的计划允许修改
* 通过外部流水号列表批量定位计划直接物理删除计划及其关联的任务和参与人员记录
*
* @param appKey 请求头 X-App-Key用于识别调用渠道
* @param bo 修改计划请求参数planId 必填
* @return 修改结果
* @param bo 删除请求参数流水号列表
* @return 删除结果
*/
@SaIgnore
@RepeatSubmit()
@Log(title = "外部接口-修改计划", businessType = BusinessType.UPDATE)
@PostMapping("/updatePlan")
public R<Void> updatePlan(
@Log(title = "外部接口-删除计划", businessType = BusinessType.DELETE)
@PostMapping("/plan/deletePlan")
public R<Void> deletePlan(
@RequestHeader(value = HEADER_APP_KEY, required = false) String appKey,
@Validated @RequestBody LongGangCreateTaskBo bo) {
@Validated @RequestBody LongGangDeletePlanBo bo) {
// ========== 1. 渠道认证 ==========
if (StrUtil.isBlank(appKey)) {
return R.fail("缺少请求头: " + HEADER_APP_KEY);
R<String> authResult = authenticateChannel(appKey);
if (!R.isSuccess(authResult)) {
return R.fail(authResult.getMsg());
}
SysApiPlatformConfigEntity consumer = sysApiPlatformConfigService.findByAppKey(appKey).orElse(null);
if (consumer == null) {
return R.fail("无效的 appKey");
String channelNo = authResult.getData();
// ========== 2. 逐个查找并收集待删除的计划ID ==========
List<String> planIds = new ArrayList<>();
List<String> notFoundSerialNos = new ArrayList<>();
for (String outSerialNo : bo.getOutSerialNos()) {
EfcodeCpPlanBo queryBo = new EfcodeCpPlanBo();
queryBo.setOutSerialNo(outSerialNo);
queryBo.setChannelNo(channelNo);
List<EfcodeCpPlanVo> plans = outEfcodeCpPlanService.queryList(queryBo);
if (plans.isEmpty()) {
notFoundSerialNos.add(outSerialNo);
} else {
planIds.add(plans.get(0).getId());
}
}
String channelNo = consumer.getChannelNo();
if (StrUtil.isBlank(channelNo)) {
return R.fail("渠道未配置 channelNo");
if (!notFoundSerialNos.isEmpty()) {
return R.fail("以下计划流水号不存在: " + String.join(", ", notFoundSerialNos));
}
// ========== 2. 校验 planId ==========
if (StrUtil.isBlank(bo.getPlanId())) {
return R.fail("计划ID不能为空");
// ========== 3. 批量删除计划(级联删除关联任务和参与人员) ==========
outEfcodeCpPlanService.deleteWithValidByIds(planIds);
log.info("[外部接口] 批量删除计划, appKey={}, channelNo={}, count={}, planIds={}",
appKey, channelNo, planIds.size(), planIds);
return R.ok();
}
/**
* 外部接口-绑定执法检查计划
* <p>
* 将新计划与已有计划进行绑定先校验绑定列表中的计划是否均存在
* 如果存在不存在的流水号则直接返回不执行绑定
*
* @param appKey 请求头 X-App-Key用于识别调用渠道
* @param bo 绑定请求参数
* @return 绑定结果若有不存在的流水号则返回缺失列表
*/
@SaIgnore
@RepeatSubmit()
@Log(title = "外部接口-绑定计划", businessType = BusinessType.OTHER)
@PostMapping("/plan/bindPlan")
public R<Void> bindPlan(
@RequestHeader(value = HEADER_APP_KEY, required = false) String appKey,
@Validated @RequestBody LongGangBindPlanBo bo) {
// ========== 1. 渠道认证 ==========
R<String> authResult = authenticateChannel(appKey);
if (!R.isSuccess(authResult)) {
return R.fail(authResult.getMsg());
}
EfcodeCpPlanVo existingPlan = outEfcodeCpPlanService.queryById(bo.getPlanId());
if (existingPlan == null) {
return R.fail("计划不存在: " + bo.getPlanId());
String channelNo = authResult.getData();
// ========== 2. 校验新计划流水号 ==========
if (StrUtil.isBlank(bo.getOutSerialNo())) {
return R.fail("新计划流水号不能为空");
}
// 仅草稿(0)和待预约(1)状态允许修改
// Long reserveStatus = existingPlan.getReserveStatus();
// if (reserveStatus == null || (reserveStatus != 0L && reserveStatus != 1L)) {
// return R.fail("当前计划状态不允许修改");
// }
// ========== 3. 部门校验 ==========
SysDeptVo deptVo = sysDeptService.selectDeptById(bo.getDeptId());
if (deptVo == null) {
return R.fail("部门不存在: " + bo.getDeptId());
// ========== 3. 批量查询绑定列表中的计划,校验是否均存在 ==========
List<String> bindOutSerialNos = bo.getBindOutSerialNos();
List<String> missingSerialNos = new ArrayList<>();
for (String serialNo : bindOutSerialNos) {
EfcodeCpPlanBo queryBo = new EfcodeCpPlanBo();
queryBo.setOutSerialNo(serialNo);
queryBo.setChannelNo(channelNo);
List<EfcodeCpPlanVo> found = outEfcodeCpPlanService.queryList(queryBo);
if (found.isEmpty()) {
missingSerialNos.add(serialNo);
}
}
SrzDeptVo srzDeptVo = DataFilterUtil.getOrganIdByDeptId(bo.getDeptId());
SysDeptVo bureauDeptVo = DataFilterUtil.getBureauDeptByDeptId(bo.getDeptId());
if (bureauDeptVo == null) {
return R.fail("执法单位不存在");
if (!missingSerialNos.isEmpty()) {
return R.fail("以下计划流水号不存在: " + String.join(", ", missingSerialNos));
}
// ========== 4. 企业匹配 ==========
EnterpriseInformationVo enterprise = enterpriseInformationService.queryByEnterpriseNumber(bo.getEnterpriseNumber());
String enterpriseId = (enterprise != null) ? enterprise.getId() : "";
// ========== 4. 查询绑定计划,取第一条的执法单位信息 ==========
List<EfcodeCpPlanVo> boundPlans = new ArrayList<>();
for (String serialNo : bindOutSerialNos) {
EfcodeCpPlanBo q = new EfcodeCpPlanBo();
q.setOutSerialNo(serialNo);
q.setChannelNo(channelNo);
boundPlans.addAll(outEfcodeCpPlanService.queryList(q));
}
if (boundPlans.isEmpty()) {
return R.fail("绑定计划不存在");
}
// ========== 5. 构建更新对象 ==========
EfcodeCpPlanBo planBo = MapstructUtils.convert(bo, EfcodeCpPlanBo.class);
planBo.setId(bo.getPlanId());
planBo.setChannelNo(channelNo);
planBo.setBureauDeptId(bureauDeptVo.getDeptId());
planBo.setBureauDeptName(bureauDeptVo.getDeptName());
planBo.setEnterpriseId(enterpriseId);
if (srzDeptVo != null) {
planBo.setOrganId(srzDeptVo.getOrganizationid());
planBo.setOrganName(srzDeptVo.getName());
} else {
planBo.setOrganId("");
planBo.setOrganName("");
// ========== 5. 直接生成新任务(基于企业信息 + 绑定计划的执法单位) ==========
EfcodeCpTaskBo taskBo = new EfcodeCpTaskBo();
taskBo.setTaskName(bo.getEnterpriseName() + " - 执法检查任务");
taskBo.setBureauDeptId(boundPlans.get(0).getBureauDeptId());
taskBo.setChannelNo(channelNo);
taskBo.setOutSerialNo(bo.getOutSerialNo());
outEfcodeCpTaskService.insertByBo(taskBo);
String taskId = taskBo.getId();
// ========== 6. 将新任务ID回写到所有绑定的计划 ==========
EfcodeCpPlanBo taskUpdateBo = new EfcodeCpPlanBo();
taskUpdateBo.setTaskId(taskId);
taskUpdateBo.setIsUnion(1L);
taskUpdateBo.setReserveStatus(3L);
for (EfcodeCpPlanVo boundPlan : boundPlans) {
taskUpdateBo.setId(boundPlan.getId());
outEfcodeCpPlanService.updateByBo(taskUpdateBo);
}
// ========== 6. 执行更新 ==========
outEfcodeCpPlanService.updateByBo(planBo);
log.info("[外部接口] 绑定计划, appKey={}, channelNo={}, outSerialNo={}, taskId={}, bindCount={}, enterprise={}",
appKey, channelNo, bo.getOutSerialNo(), taskId, boundPlans.size(), bo.getEnterpriseName());
return R.ok();
}
log.info("[外部接口] 修改计划, appKey={}, channelNo={}, planId={}",
appKey, channelNo, bo.getPlanId());
/**
* 外部接口-解除计划绑定
* <p>
* 根据流水号列表逐个解绑查找原任务 生成新任务并回写计划 判断原任务是否还有其他计划若无则删除
*
* @param appKey 请求头 X-App-Key用于识别调用渠道
* @param bo 解绑请求参数流水号列表
* @return 解绑结果
*/
@SaIgnore
@RepeatSubmit()
@Log(title = "外部接口-解除计划绑定", businessType = BusinessType.UPDATE)
@PostMapping("/plan/unbindPlan")
public R<Void> unbindPlan(
@RequestHeader(value = HEADER_APP_KEY, required = false) String appKey,
@Validated @RequestBody LongGangUnbindPlanBo bo) {
// ========== 1. 渠道认证 ==========
R<String> authResult = authenticateChannel(appKey);
if (!R.isSuccess(authResult)) {
return R.fail(authResult.getMsg());
}
String channelNo = authResult.getData();
// ========== 2. 逐个处理解绑流水号 ==========
for (String outSerialNo : bo.getOutSerialNos()) {
// 2a. 根据流水号查询计划表,获取 oldTaskId
EfcodeCpPlanBo planQuery = new EfcodeCpPlanBo();
planQuery.setOutSerialNo(outSerialNo);
planQuery.setChannelNo(channelNo);
List<EfcodeCpPlanVo> plans = outEfcodeCpPlanService.queryList(planQuery);
if (plans.isEmpty()) {
continue;
}
EfcodeCpPlanVo currentPlan = plans.get(0);
String oldTaskId = currentPlan.getTaskId();
if (StrUtil.isBlank(oldTaskId)) {
continue;
}
// 2b. 为该计划生成新任务(自动回写 plan.taskId + reserveStatus=3)
EfcodeCpPlan planEntity = MapstructUtils.convert(currentPlan, EfcodeCpPlan.class);
planEntity.setIsUnion(0L);
String newTaskId = outEfcodeCpTaskService.forceGenerateTask(planEntity);
log.info("[外部接口] 解绑-生成独立任务, outSerialNo={}, planId={}, newTaskId={}, oldTaskId={}",
outSerialNo, currentPlan.getId(), newTaskId, oldTaskId);
// 2c. 检查原 taskId 是否还有其他计划关联,若无则删除原任务
EfcodeCpPlanBo checkQuery = new EfcodeCpPlanBo();
checkQuery.setTaskId(oldTaskId);
List<EfcodeCpPlanVo> remainingPlans = outEfcodeCpPlanService.queryList(checkQuery);
if (remainingPlans.isEmpty()) {
outEfcodeCpTaskService.deleteWithValidByIds(List.of(oldTaskId), false);
log.info("[外部接口] 解绑-原任务无其他计划关联,已删除, oldTaskId={}", oldTaskId);
}
}
log.info("[外部接口] 解除计划绑定完成, appKey={}, channelNo={}, outSerialNos={}",
appKey, channelNo, bo.getOutSerialNos());
return R.ok();
}
}

2
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeCpPlanBo.java

@ -133,7 +133,7 @@ public class EfcodeCpPlanBo extends BaseEntity {
/**
* 预约状态:0=草稿,1=待预约,2=预约中,3=预约完成
*/
@NotNull(message = "预约状态:0=草稿,1=待预约,2=预约中,3=预约完成不能为空", groups = { AddGroup.class, EditGroup.class })
@NotNull(message = "预约状态:0=草稿,1=待预约,2=预约中,3=预约完成 不能为空", groups = { AddGroup.class, EditGroup.class })
private Long reserveStatus;
/**

4
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeCpTaskBo.java

@ -38,5 +38,9 @@ public class EfcodeCpTaskBo extends BaseEntity {
@NotBlank(message = "执法单位ID不能为空", groups = { AddGroup.class, EditGroup.class })
private String bureauDeptId;
private String channelNo;
private String outSerialNo;
private int isRead;
}

24
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/externalInterface/LongGangBindPlanBo.java

@ -0,0 +1,24 @@
// 文件路径: E:\work\code\EnforcementCode-2.0\zdxt-modules\zdxt-enforcement-code\src\main\java\com\zdxt\enforcementcode\domain\bo\externalInterface\LongGangBindPlanBo.java
package com.zdxt.enforcementcode.domain.bo.externalInterface;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
@Data
public class LongGangBindPlanBo {
@NotBlank(message = "新计划流水号不能为空")
private String outSerialNo;
@NotEmpty(message = "绑定计划流水列表不能为空")
private List<String> bindOutSerialNos;
@NotBlank(message = "企业名称不能为空")
private String enterpriseName;
@NotBlank(message = "企业统一社会信用代码不能为空")
private String enterpriseNumber;
}

14
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/externalInterface/LongGangDeletePlanBo.java

@ -0,0 +1,14 @@
// 文件路径: E:\work\code\EnforcementCode-2.0\zdxt-modules\zdxt-enforcement-code\src\main\java\com\zdxt\enforcementcode\domain\bo\externalInterface\LongGangDeletePlanBo.java
package com.zdxt.enforcementcode.domain.bo.externalInterface;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
@Data
public class LongGangDeletePlanBo {
@NotEmpty(message = "删除流水号列表不能为空")
private List<String> outSerialNos;
}

15
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/externalInterface/LongGangUnbindPlanBo.java

@ -0,0 +1,15 @@
// 文件路径: E:\work\code\EnforcementCode-2.0\zdxt-modules\zdxt-enforcement-code\src\main\java\com\zdxt\enforcementcode\domain\bo\externalInterface\LongGangUnbindPlanBo.java
package com.zdxt.enforcementcode.domain.bo.externalInterface;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
@Data
public class LongGangUnbindPlanBo {
@NotEmpty(message = "解绑流水号列表不能为空")
private List<String> outSerialNos;
}

23
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/externalInterface/LongGangCreatePlanVo.java

@ -0,0 +1,23 @@
package com.zdxt.enforcementcode.domain.vo.externalInterface;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
public class LongGangCreatePlanVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 计划ID
*/
private String planId;
/**
* 计划流水号
*/
private String outSerialNo;
}

3
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IOutEfcodeCpPlanService.java

@ -92,10 +92,9 @@ public interface IOutEfcodeCpPlanService {
* 校验并批量删除行政执法检查计划-计划信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid);
Boolean deleteWithValidByIds(Collection<String> ids);
/**
* 计划自动匹配预约定时任务调用

29
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/OutEfcodeCpPlanServiceImpl.java

@ -317,7 +317,7 @@ public class OutEfcodeCpPlanServiceImpl implements IOutEfcodeCpPlanService {
lqw.eq(bo.getIsDelete() != null, EfcodeCpPlan::getIsDelete, bo.getIsDelete());
lqw.eq(StringUtils.isNotBlank(bo.getMyRemark()), EfcodeCpPlan::getMyRemark, bo.getMyRemark());
lqw.eq(StringUtils.isNotBlank(bo.getChannelNo()), EfcodeCpPlan::getChannelNo, bo.getChannelNo());
lqw.eq(StringUtils.isNotBlank(bo.getOutSerialNo()), EfcodeCpPlan::getOutSerialNo, bo.getOutSerialNo());
lqw.eq(StringUtils.isNotBlank(bo.getTaskId()), EfcodeCpPlan::getTaskId, bo.getTaskId());
return lqw;
}
@ -548,37 +548,16 @@ public class OutEfcodeCpPlanServiceImpl implements IOutEfcodeCpPlanService {
* 校验并批量删除行政执法检查计划-计划信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
// ... existing code ...
@Transactional(rollbackFor = Exception.class)
@Override
public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
public Boolean deleteWithValidByIds(Collection<String> ids) {
if (ids == null || ids.isEmpty()) {
return false;
}
// 查询待删除的计划记录
List<EfcodeCpPlan> 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<String> taskIds = plans.stream()
.map(EfcodeCpPlan::getTaskId)
@ -595,7 +574,7 @@ public class OutEfcodeCpPlanServiceImpl implements IOutEfcodeCpPlanService {
);
return baseMapper.deleteByIds(ids) > 0;
}
// ... existing code ...
/**
* 计划自动匹配预约定时任务调用
* <p>扫描待预约状态的计划按规则自动匹配并生成预约记录</p>

5
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/OutEfcodeCpTaskServiceImpl.java

@ -82,6 +82,8 @@ public class OutEfcodeCpTaskServiceImpl implements IOutEfcodeCpTaskService {
lqw.orderByAsc(EfcodeCpTask::getId);
lqw.like(StringUtils.isNotBlank(bo.getTaskName()), EfcodeCpTask::getTaskName, bo.getTaskName());
lqw.eq(StringUtils.isNotBlank(bo.getBureauDeptId()), EfcodeCpTask::getBureauDeptId, bo.getBureauDeptId());
lqw.eq(StringUtils.isNotBlank(bo.getChannelNo()), EfcodeCpTask::getChannelNo, bo.getChannelNo());
lqw.eq(StringUtils.isNotBlank(bo.getOutSerialNo()), EfcodeCpTask::getOutSerialNo, bo.getOutSerialNo());
return lqw;
}
@ -282,6 +284,9 @@ public class OutEfcodeCpTaskServiceImpl implements IOutEfcodeCpTaskService {
planUpdate.setId(plan.getId());
planUpdate.setTaskId(task.getId());
planUpdate.setReserveStatus(3L);
if(plan.getIsUnion() != null){
planUpdate.setIsUnion(plan.getIsUnion());
}
cpPlanMapper.updateById(planUpdate);
return task.getId();

Loading…
Cancel
Save