Browse Source

执法端-计划

dev-V1.0.1
庄锐波 4 months ago
parent
commit
f35478e937
  1. 13
      script/sql/zfjd-refactoring-v1/013-计划任务表设计.sql
  2. 36
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfCpPlanController.java
  3. 3
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/EfcodeCpNoticeMessage.java
  4. 5
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/EfcodeCpNoticeUsers.java
  5. 5
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/EfcodeCpPlan.java
  6. 5
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/EfcodeCpPlanUsers.java
  7. 3
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/EfcodeCpReserve.java
  8. 2
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeCpNoticeMessageBo.java
  9. 5
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeCpNoticeUsersBo.java
  10. 5
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeCpPlanBo.java
  11. 5
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeCpPlanUsersBo.java
  12. 2
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeCpReserveBo.java
  13. 2
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpNoticeMessageVo.java
  14. 6
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpNoticeUsersVo.java
  15. 6
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpPlanUsersVo.java
  16. 6
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpPlanVo.java
  17. 2
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpReserveVo.java
  18. 13
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/EfcodeCpPlanMapper.java
  19. 19
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpReserveService.java
  20. 2
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpNoticeMessageServiceImpl.java
  21. 44
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpPlanServiceImpl.java
  22. 162
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpReserveServiceImpl.java
  23. 47
      zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpPlanMapper.xml
  24. 6
      zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/plan.js
  25. 17
      zdxt-web-client/zdxt-efcode-enforcement-app/src/assets/style/index.less
  26. 53
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_edit.vue
  27. 67
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_mine.vue
  28. 131
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_other.vue
  29. 2
      zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/rest/test/cp/AppEnfCpPlanControllerTest.java

13
script/sql/zfjd-refactoring-v1/013-计划任务表设计.sql

@ -17,6 +17,7 @@ CREATE TABLE `efcode_cp_plan`
`enforce_user_names` varchar(512) NOT NULL COMMENT '执法人员姓名(多个逗号分隔)',
`enforce_user_ids` varchar(512) NOT NULL COMMENT '执法人员姓名(多个逗号分隔)',
`enforce_user_tels` varchar(512) NULL COMMENT '执法人员电话号码(多个逗号分隔)',
`enforce_user_codes` varchar(512) NOT NULL COMMENT '执法人员证件编号(多个逗号分隔)',
`is_public` tinyint NOT NULL DEFAULT 1 COMMENT '是否公开:1=是,0=否',
@ -63,6 +64,7 @@ CREATE TABLE `efcode_cp_plan_users`
`plan_id` varchar(50) NOT NULL COMMENT '计划ID',
`user_id` varchar(50) NOT NULL COMMENT '用户ID',
`user_name` varchar(100) NOT NULL COMMENT '用户名称',
`user_tel` varchar(50) NULL COMMENT '执法人员电话号码',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_dept` varchar(64) DEFAULT NULL COMMENT '创建人部门',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
@ -79,12 +81,12 @@ CREATE TABLE `efcode_cp_reserve`
`op_status` tinyint NOT NULL COMMENT '操作状态' DEFAULT 3 COMMENT '操作状态:1=同意,2=拒绝,3=待确认,4=超期取消',
`op_order` int NOT NULL COMMENT '联合时用户的操作顺序',
`op_time` datetime NOT NULL COMMENT '联合时用户的操作时间',
`op_time` datetime NULL COMMENT '联合时用户的操作时间',
`op_message` varchar(500) NOT NULL COMMENT '联合时用户输入的操作消息',
`op_set_date` datetime NOT NULL COMMENT '联合时用户选择的操作时间',
`op_set_time` tinyint NOT NULL COMMENT '执行时段:1=上午,2=下午,3=其他',
`from` tinyint NOT NULL COMMENT '来自' COMMENT '来自:系统匹配=1,手动匹配=0',
`res_from` tinyint NOT NULL COMMENT '来自' COMMENT '来自:系统匹配=1,手动匹配=0',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_dept` varchar(64) DEFAULT NULL COMMENT '创建人部门',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
@ -115,7 +117,7 @@ CREATE TABLE `efcode_cp_notice`
`enterprise_number` varchar(32) DEFAULT NULL COMMENT '企业统一社会信用代码',
`contact_person` varchar(100) NOT NULL COMMENT '企业联系人',
`contact_phone` varchar(200) NOT NULL COMMENT '企业联系电话',
`contact_phone` varchar(200) NULL COMMENT '企业联系电话',
`enforce_content` varchar(1000) NOT NULL COMMENT '执法事项',
`enforce_requirement` varchar(1000) NOT NULL COMMENT '执法要求',
@ -137,9 +139,10 @@ CREATE TABLE `efcode_cp_notice`
CREATE TABLE `efcode_cp_notice_users`
(
`id` varchar(50) NOT NULL COMMENT '主键ID' primary key,
`notice_id` varchar(50) NOT NULL COMMENT '计划ID',
`notice_id` varchar(50) NOT NULL COMMENT '通知ID',
`user_id` varchar(50) NOT NULL COMMENT '用户ID',
`user_name` varchar(100) NOT NULL COMMENT '用户名称',
`user_tel` varchar(50) NULL COMMENT '执法人员电话号码',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_dept` varchar(64) DEFAULT NULL COMMENT '创建人部门',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
@ -153,7 +156,7 @@ CREATE TABLE `efcode_cp_notice_message`
`notice_id` varchar(50) NOT NULL COMMENT '预告ID',
`user_id` varchar(50) NOT NULL COMMENT '用户ID',
`user_name` varchar(100) NOT NULL COMMENT '用户名称',
`from` tinyint NOT NULL COMMENT '来自' COMMENT '来自:企业=1,执法单位=0',
`msg_from` tinyint NOT NULL COMMENT '来自:企业=1,执法单位=0',
`message` varchar(1000) NOT NULL COMMENT '消息内容',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_dept` varchar(64) DEFAULT NULL COMMENT '创建人部门',

36
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfCpPlanController.java

@ -4,6 +4,8 @@ import com.zdxt.enforcementcode.controller.web.supervision.EfcodeCpPlanControlle
import com.zdxt.enforcementcode.domain.bo.EfcodeCpPlanBo;
import com.zdxt.enforcementcode.domain.vo.EfcodeCpPlanVo;
import com.zdxt.enforcementcode.service.IEfcodeCpPlanService;
import com.zdxt.enforcementcode.service.IEfcodeCpReserveService;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
@ -30,11 +32,27 @@ public class AppEnfCpPlanController extends EfcodeCpPlanController {
@Autowired
private IEfcodeCpPlanService cpPlanService;
@Autowired
private IEfcodeCpReserveService cpReserveService;
public AppEnfCpPlanController(IEfcodeCpPlanService efcodeCpPlanService) {
super(efcodeCpPlanService);
this.cpPlanService = efcodeCpPlanService;
}
/**
* 查询我的计划列表仅查询当前登录用户创建的计划
*/
@Override
@GetMapping("/list")
public TableDataInfo<EfcodeCpPlanVo> list(EfcodeCpPlanBo bo, PageQuery pageQuery) {
bo.setCreateBy(LoginHelper.getUserId());
if (bo.getIsDelete() == null) {
bo.setIsDelete(0L);
}
return cpPlanService.queryPageList(bo, pageQuery);
}
/**
* 查询其他计划列表本单位全部 + 其他单位公开仅待预约状态
*/
@ -56,4 +74,22 @@ public class AppEnfCpPlanController extends EfcodeCpPlanController {
SysDeptVo bureauDept = sysDeptService.iterationDeptParentToBureau(deptId);
return bureauDept != null ? bureauDept.getDeptId() : null;
}
/**
* 预约前置检查
*/
@GetMapping("/reserve/check/{targetPlanId}")
public R<Void> checkCanReserve(@PathVariable String targetPlanId) {
return cpReserveService.checkCanReserve(targetPlanId);
}
/**
* 执行预约
*/
@PostMapping("/reserve/do")
public R<Void> doReserve(@RequestBody java.util.Map<String, String> params) {
String targetPlanId = params.get("targetPlanId");
String opMessage = params.get("opMessage");
return cpReserveService.doReserve(targetPlanId, opMessage);
}
}

3
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/EfcodeCpNoticeMessage.java

@ -45,7 +45,8 @@ public class EfcodeCpNoticeMessage extends BaseEntity {
/**
* 来自:企业=1,执法单位=0
*/
private Long from;
@TableField(value = "msg_from")
private Long msgFrom;
/**
* 消息内容

5
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/EfcodeCpNoticeUsers.java

@ -42,5 +42,10 @@ public class EfcodeCpNoticeUsers extends BaseEntity {
*/
private String userName;
/**
* 执法人员电话号码
*/
private String userTel;
}

5
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/EfcodeCpPlan.java

@ -89,6 +89,11 @@ public class EfcodeCpPlan extends BaseEntity {
*/
private String enforceUserCodes;
/**
* 执法人员电话号码多个逗号分隔
*/
private String enforceUserTels;
/**
* 是否公开:1=,0=
*/

5
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/EfcodeCpPlanUsers.java

@ -42,5 +42,10 @@ public class EfcodeCpPlanUsers extends BaseEntity {
*/
private String userName;
/**
* 执法人员电话号码
*/
private String userTel;
}

3
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/EfcodeCpReserve.java

@ -77,7 +77,8 @@ public class EfcodeCpReserve extends BaseEntity {
/**
* 来自:系统匹配=1,手动匹配=0
*/
private Long from;
@TableField(value = "res_from")
private Long resFrom;
}

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

@ -48,7 +48,7 @@ public class EfcodeCpNoticeMessageBo extends BaseEntity {
* 来自:企业=1,执法单位=0
*/
@NotNull(message = "来自:企业=1,执法单位=0不能为空", groups = { AddGroup.class, EditGroup.class })
private Long from;
private Long msgFrom;
/**
* 消息内容

5
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeCpNoticeUsersBo.java

@ -44,5 +44,10 @@ public class EfcodeCpNoticeUsersBo extends BaseEntity {
@NotBlank(message = "用户名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String userName;
/**
* 执法人员电话号码
*/
private String userTel;
}

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

@ -100,6 +100,11 @@ public class EfcodeCpPlanBo extends BaseEntity {
@NotBlank(message = "执法人员证件编号(多个逗号分隔)不能为空", groups = { AddGroup.class, EditGroup.class })
private String enforceUserCodes;
/**
* 执法人员电话号码多个逗号分隔
*/
private String enforceUserTels;
/**
* 是否公开:1=,0=
*/

5
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/EfcodeCpPlanUsersBo.java

@ -44,5 +44,10 @@ public class EfcodeCpPlanUsersBo extends BaseEntity {
@NotBlank(message = "用户名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String userName;
/**
* 执法人员电话号码
*/
private String userTel;
}

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

@ -86,7 +86,7 @@ public class EfcodeCpReserveBo extends BaseEntity {
* 来自:系统匹配=1,手动匹配=0
*/
@NotNull(message = "来自:系统匹配=1,手动匹配=0不能为空", groups = { AddGroup.class, EditGroup.class })
private Long from;
private Long resFrom;
}

2
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpNoticeMessageVo.java

@ -56,7 +56,7 @@ public class EfcodeCpNoticeMessageVo implements Serializable {
* 来自:企业=1,执法单位=0
*/
@ExcelProperty(value = "来自:企业=1,执法单位=0")
private Long from;
private Long msgFrom;
/**
* 消息内容

6
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpNoticeUsersVo.java

@ -52,5 +52,11 @@ public class EfcodeCpNoticeUsersVo implements Serializable {
@ExcelProperty(value = "用户名称")
private String userName;
/**
* 执法人员电话号码
*/
@ExcelProperty(value = "执法人员电话号码")
private String userTel;
}

6
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpPlanUsersVo.java

@ -52,5 +52,11 @@ public class EfcodeCpPlanUsersVo implements Serializable {
@ExcelProperty(value = "用户名称")
private String userName;
/**
* 执法人员电话号码
*/
@ExcelProperty(value = "执法人员电话号码")
private String userTel;
}

6
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpPlanVo.java

@ -114,6 +114,12 @@ public class EfcodeCpPlanVo implements Serializable {
@ExcelDictFormat(readConverterExp = "多=个逗号分隔")
private String enforceUserCodes;
/**
* 执法人员电话号码多个逗号分隔
*/
@ExcelProperty(value = "执法人员电话号码")
private String enforceUserTels;
/**
* 是否公开:1=,0=
*/

2
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpReserveVo.java

@ -94,7 +94,7 @@ public class EfcodeCpReserveVo implements Serializable {
* 来自:系统匹配=1,手动匹配=0
*/
@ExcelProperty(value = "来自:系统匹配=1,手动匹配=0")
private Long from;
private Long resFrom;
}

13
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/EfcodeCpPlanMapper.java

@ -1,7 +1,10 @@
package com.zdxt.enforcementcode.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zdxt.enforcementcode.domain.EfcodeCpPlan;
import com.zdxt.enforcementcode.domain.bo.EfcodeCpPlanBo;
import com.zdxt.enforcementcode.domain.vo.EfcodeCpPlanVo;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
@ -12,4 +15,14 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
*/
public interface EfcodeCpPlanMapper extends BaseMapperPlus<EfcodeCpPlan, EfcodeCpPlanVo> {
/**
* 分页查询其他计划列表本单位全部 + 其他单位公开仅待预约状态排除当前用户
*/
Page<EfcodeCpPlanVo> selectOtherPageList(
@Param("page") Page<EfcodeCpPlanVo> page,
@Param("bo") EfcodeCpPlanBo bo,
@Param("currentUserId") Long currentUserId,
@Param("bureauDeptId") String bureauDeptId
);
}

19
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpReserveService.java

@ -2,6 +2,7 @@ package com.zdxt.enforcementcode.service;
import com.zdxt.enforcementcode.domain.vo.EfcodeCpReserveVo;
import com.zdxt.enforcementcode.domain.bo.EfcodeCpReserveBo;
import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
@ -65,4 +66,22 @@ public interface IEfcodeCpReserveService {
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid);
/**
* 预约前置检查判断当前用户是否可以预约目标计划
* 条件当前用户需存在同一时间+同一时段+同一企业的计划
*
* @param targetPlanId 目标计划ID
* @return 检查通过返回 R.ok()不通过返回 R.fail(msg)
*/
R<Void> checkCanReserve(String targetPlanId);
/**
* 执行预约操作
*
* @param targetPlanId 目标计划ID
* @param opMessage 预约留言
* @return 操作结果
*/
R<Void> doReserve(String targetPlanId, String opMessage);
}

2
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpNoticeMessageServiceImpl.java

@ -77,7 +77,7 @@ public class EfcodeCpNoticeMessageServiceImpl implements IEfcodeCpNoticeMessageS
lqw.eq(StringUtils.isNotBlank(bo.getNoticeId()), EfcodeCpNoticeMessage::getNoticeId, bo.getNoticeId());
lqw.eq(StringUtils.isNotBlank(bo.getUserId()), EfcodeCpNoticeMessage::getUserId, bo.getUserId());
lqw.like(StringUtils.isNotBlank(bo.getUserName()), EfcodeCpNoticeMessage::getUserName, bo.getUserName());
lqw.eq(bo.getFrom() != null, EfcodeCpNoticeMessage::getFrom, bo.getFrom());
lqw.eq(bo.getMsgFrom() != null, EfcodeCpNoticeMessage::getMsgFrom, bo.getMsgFrom());
lqw.eq(StringUtils.isNotBlank(bo.getMessage()), EfcodeCpNoticeMessage::getMessage, bo.getMessage());
lqw.eq(bo.getIsDelete() != null, EfcodeCpNoticeMessage::getIsDelete, bo.getIsDelete());
return lqw;

44
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpPlanServiceImpl.java

@ -92,35 +92,8 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService {
public TableDataInfo<EfcodeCpPlanVo> queryOtherPageList(EfcodeCpPlanBo bo, PageQuery pageQuery, String bureauDeptId) {
Long currentUserId = LoginHelper.getUserId();
LambdaQueryWrapper<EfcodeCpPlan> lqw = Wrappers.lambdaQuery();
lqw.orderByDesc(EfcodeCpPlan::getPlanDate);
// 基础条件:待预约 + 未删除
lqw.eq(EfcodeCpPlan::getReserveStatus, 1L);
lqw.eq(EfcodeCpPlan::getIsDelete, 0L);
// 排除当前用户自己的计划
if (currentUserId != null) {
lqw.ne(EfcodeCpPlan::getCreateBy, currentUserId);
}
// 可见性:(本单位全部)OR(其他单位公开)
if (StringUtils.isNotBlank(bureauDeptId)) {
lqw.and(w -> w
.eq(EfcodeCpPlan::getBureauDeptId, bureauDeptId)
.or()
.nested(inner -> inner
.ne(EfcodeCpPlan::getBureauDeptId, bureauDeptId)
.eq(EfcodeCpPlan::getIsPublic, 1L)
)
);
} else {
// 无法确定单位时,只显示公开计划
lqw.eq(EfcodeCpPlan::getIsPublic, 1L);
}
// 搜索条件
lqw.eq(bo.getPlanDate() != null, EfcodeCpPlan::getPlanDate, bo.getPlanDate());
lqw.like(StringUtils.isNotBlank(bo.getEnterpriseName()), EfcodeCpPlan::getEnterpriseName, bo.getEnterpriseName());
lqw.like(StringUtils.isNotBlank(bo.getEnforceContent()), EfcodeCpPlan::getEnforceContent, bo.getEnforceContent());
Page<EfcodeCpPlanVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
Page<EfcodeCpPlanVo> page = pageQuery.build();
Page<EfcodeCpPlanVo> result = baseMapper.selectOtherPageList(page, bo, currentUserId, bureauDeptId);
// 后置处理:控制记录是否可预约
afterQueryOtherList(result.getRecords(), bureauDeptId, currentUserId);
return TableDataInfo.build(result);
@ -164,7 +137,8 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService {
private LambdaQueryWrapper<EfcodeCpPlan> buildQueryWrapper(EfcodeCpPlanBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<EfcodeCpPlan> lqw = Wrappers.lambdaQuery();
lqw.orderByAsc(EfcodeCpPlan::getId);
lqw.orderByDesc(EfcodeCpPlan::getCreateTime);
lqw.eq(bo.getCreateBy() != null, EfcodeCpPlan::getCreateBy, bo.getCreateBy());
lqw.eq(bo.getPlanType() != null, EfcodeCpPlan::getPlanType, bo.getPlanType());
lqw.eq(bo.getPlanDate() != null, EfcodeCpPlan::getPlanDate, bo.getPlanDate());
lqw.eq(bo.getPlanTime() != null, EfcodeCpPlan::getPlanTime, bo.getPlanTime());
@ -211,7 +185,7 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService {
if (flag) {
bo.setId(add.getId());
// 同步写入计划参与人员表
syncPlanUsers(add.getId(), bo.getEnforceUserIds(), bo.getEnforceUserNames());
syncPlanUsers(add.getId(), bo.getEnforceUserIds(), bo.getEnforceUserNames(), bo.getEnforceUserTels());
}
// 新增后置处理
afterInsert(bo, add);
@ -234,7 +208,7 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService {
boolean flag = baseMapper.updateById(update) > 0;
if (flag) {
// 重建计划参与人员关联(先删后插,保证与表头字段一致)
syncPlanUsers(bo.getId(), bo.getEnforceUserIds(), bo.getEnforceUserNames());
syncPlanUsers(bo.getId(), bo.getEnforceUserIds(), bo.getEnforceUserNames(), bo.getEnforceUserTels());
}
// 修改后置处理
afterUpdate(bo, update);
@ -263,9 +237,9 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService {
/**
* 同步计划参与人员表 efcode_cp_plan_users
* <p>策略先根据 plan_id 清除原有关联再按 enforceUserIds / enforceUserNames 的逗号分隔顺序逐条写入</p>
* <p>策略先根据 plan_id 清除原有关联再按 enforceUserIds / enforceUserNames / enforceUserTels 的逗号分隔顺序逐条写入</p>
*/
private void syncPlanUsers(String planId, String userIdsCsv, String userNamesCsv) {
private void syncPlanUsers(String planId, String userIdsCsv, String userNamesCsv, String userTelsCsv) {
if (StringUtils.isBlank(planId)) {
return;
}
@ -278,6 +252,7 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService {
}
String[] ids = userIdsCsv.split(",");
String[] names = StringUtils.isNotBlank(userNamesCsv) ? userNamesCsv.split(",") : new String[0];
String[] tels = StringUtils.isNotBlank(userTelsCsv) ? userTelsCsv.split(",") : new String[0];
List<EfcodeCpPlanUsers> list = new ArrayList<>(ids.length);
for (int i = 0; i < ids.length; i++) {
String uid = ids[i] == null ? "" : ids[i].trim();
@ -288,6 +263,7 @@ public class EfcodeCpPlanServiceImpl implements IEfcodeCpPlanService {
u.setPlanId(planId);
u.setUserId(uid);
u.setUserName(i < names.length && names[i] != null ? names[i].trim() : "");
u.setUserTel(i < tels.length && tels[i] != null ? tels[i].trim() : "");
list.add(u);
}
for (EfcodeCpPlanUsers u : list) {

162
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpReserveServiceImpl.java

@ -1,24 +1,29 @@
package com.zdxt.enforcementcode.service.impl;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.satoken.utils.LoginHelper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.zdxt.enforcementcode.domain.bo.EfcodeCpReserveBo;
import com.zdxt.enforcementcode.domain.vo.EfcodeCpReserveVo;
import com.zdxt.enforcementcode.domain.EfcodeCpReserve;
import com.zdxt.enforcementcode.domain.EfcodeCpPlan;
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 java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.*;
import java.util.stream.Collectors;
/**
* 行政执法检查计划-预约Service业务层处理
@ -32,6 +37,8 @@ import java.util.Collection;
public class EfcodeCpReserveServiceImpl implements IEfcodeCpReserveService {
private final EfcodeCpReserveMapper baseMapper;
private final EfcodeCpPlanMapper cpPlanMapper;
private final IEfcodeCpSettingService cpSettingService;
/**
* 查询行政执法检查计划-预约
@ -82,7 +89,7 @@ public class EfcodeCpReserveServiceImpl implements IEfcodeCpReserveService {
lqw.eq(StringUtils.isNotBlank(bo.getOpMessage()), EfcodeCpReserve::getOpMessage, bo.getOpMessage());
lqw.eq(bo.getOpSetDate() != null, EfcodeCpReserve::getOpSetDate, bo.getOpSetDate());
lqw.eq(bo.getOpSetTime() != null, EfcodeCpReserve::getOpSetTime, bo.getOpSetTime());
lqw.eq(bo.getFrom() != null, EfcodeCpReserve::getFrom, bo.getFrom());
lqw.eq(bo.getResFrom() != null, EfcodeCpReserve::getResFrom, bo.getResFrom());
return lqw;
}
@ -137,4 +144,151 @@ public class EfcodeCpReserveServiceImpl implements IEfcodeCpReserveService {
}
return baseMapper.deleteByIds(ids) > 0;
}
/**
* 预约前置检查
*/
@Override
public R<Void> checkCanReserve(String targetPlanId) {
Long currentUserId = LoginHelper.getUserId();
// 1. 查询目标计划
EfcodeCpPlan targetPlan = cpPlanMapper.selectById(targetPlanId);
if (targetPlan == null) {
return R.fail("目标计划不存在");
}
// 2. 判断当前用户是否有同一时间+同一时段+同一企业的计划
EfcodeCpPlan myPlan = findMyMatchingPlan(targetPlan, currentUserId);
if (myPlan == null) {
return R.fail("请先添加我的计划再进行预约");
}
// 3. 判断 plan_group_id 人数是否已达上限
String planGroupId = findExistingPlanGroupId(targetPlanId);
if (planGroupId != null) {
int maxUnionUnit = cpSettingService.getMaxUnionUnit();
long activeCount = countActiveReserves(planGroupId);
if (activeCount >= maxUnionUnit) {
return R.fail("该计划的预约已经到达最大数量(" + maxUnionUnit + "),无法参与预约");
}
// 4. 判断当前用户是否已经预约过
boolean alreadyReserved = checkAlreadyReserved(myPlan.getId(), planGroupId);
if (alreadyReserved) {
return R.fail("您已经预约过该计划");
}
}
return R.ok();
}
/**
* 执行预约
*/
@Transactional(rollbackFor = Exception.class)
@Override
public R<Void> doReserve(String targetPlanId, String opMessage) {
Long currentUserId = LoginHelper.getUserId();
// 1. 查询目标计划
EfcodeCpPlan targetPlan = cpPlanMapper.selectById(targetPlanId);
if (targetPlan == null) {
return R.fail("目标计划不存在");
}
// 2. 查找当前用户匹配的计划
EfcodeCpPlan myPlan = findMyMatchingPlan(targetPlan, currentUserId);
if (myPlan == null) {
return R.fail("请先添加我的计划再进行预约");
}
// 3. 判断目标计划在reserve表中是否已存在
String planGroupId = findExistingPlanGroupId(targetPlanId);
int maxUnionUnit = cpSettingService.getMaxUnionUnit();
if (planGroupId == null) {
// 不存在:插入2条记录(目标计划 + 我的计划),plan_group_id = 目标计划ID
planGroupId = targetPlanId;
if (2 > maxUnionUnit) {
return R.fail("该计划的预约已经到达最大数量(" + maxUnionUnit + "),无法参与预约");
}
// 目标计划记录
insertReserveRecord(targetPlanId, planGroupId, "", targetPlan.getPlanDate(), targetPlan.getPlanTime(), 0L);
// 我的计划记录
insertReserveRecord(myPlan.getId(), planGroupId, opMessage, targetPlan.getPlanDate(), targetPlan.getPlanTime(), 0L);
} else {
// 已存在:检查人数上限
long activeCount = countActiveReserves(planGroupId);
if (activeCount >= maxUnionUnit) {
return R.fail("该计划的预约已经到达最大数量(" + maxUnionUnit + "),无法参与预约");
}
// 检查是否已经预约过
boolean alreadyReserved = checkAlreadyReserved(myPlan.getId(), planGroupId);
if (alreadyReserved) {
return R.fail("您已经预约过该计划");
}
// 插入1条记录
insertReserveRecord(myPlan.getId(), planGroupId, opMessage, targetPlan.getPlanDate(), targetPlan.getPlanTime(), 0L);
}
return R.ok();
}
/**
* 查找当前用户同一时间+同一时段+同一企业的计划
*/
private EfcodeCpPlan findMyMatchingPlan(EfcodeCpPlan targetPlan, Long currentUserId) {
LambdaQueryWrapper<EfcodeCpPlan> lqw = Wrappers.lambdaQuery();
lqw.eq(EfcodeCpPlan::getPlanDate, targetPlan.getPlanDate());
lqw.eq(EfcodeCpPlan::getPlanTime, targetPlan.getPlanTime());
lqw.eq(EfcodeCpPlan::getEnterpriseId, targetPlan.getEnterpriseId());
lqw.eq(EfcodeCpPlan::getCreateBy, currentUserId);
lqw.eq(EfcodeCpPlan::getIsDelete, 0L);
lqw.last("LIMIT 1");
return cpPlanMapper.selectOne(lqw);
}
/**
* 查找目标计划在reserve表中已存在的plan_group_id
*/
private String findExistingPlanGroupId(String targetPlanId) {
LambdaQueryWrapper<EfcodeCpReserve> lqw = Wrappers.lambdaQuery();
lqw.eq(EfcodeCpReserve::getPlanId, targetPlanId);
lqw.last("LIMIT 1");
EfcodeCpReserve existing = baseMapper.selectOne(lqw);
return existing != null ? existing.getPlanGroupId() : null;
}
/**
* 统计plan_group_id下状态为同意(1)或待确认(3)的记录数
*/
private long countActiveReserves(String planGroupId) {
return baseMapper.selectCount(
Wrappers.<EfcodeCpReserve>lambdaQuery()
.eq(EfcodeCpReserve::getPlanGroupId, planGroupId)
.in(EfcodeCpReserve::getOpStatus, Arrays.asList(1L, 3L))
);
}
/**
* 检查当前用户的计划是否已在该分组中预约过
*/
private boolean checkAlreadyReserved(String myPlanId, String planGroupId) {
long count = baseMapper.selectCount(
Wrappers.<EfcodeCpReserve>lambdaQuery()
.eq(EfcodeCpReserve::getPlanId, myPlanId)
.eq(EfcodeCpReserve::getPlanGroupId, planGroupId)
.in(EfcodeCpReserve::getOpStatus, Arrays.asList(1L, 3L))
);
return count > 0;
}
/**
* 插入一条预约记录
*/
private void insertReserveRecord(String planId, String planGroupId, String opMessage, Date opSetDate, Long opSetTime, Long resFrom) {
EfcodeCpReserve record = new EfcodeCpReserve();
record.setPlanId(planId);
record.setPlanGroupId(planGroupId);
record.setReserveTime(new Date());
record.setOpStatus(3L); // 待确认
record.setOpOrder(0L);
record.setOpMessage(opMessage);
record.setOpSetDate(opSetDate);
record.setOpSetTime(opSetTime);
record.setResFrom(resFrom);
baseMapper.insert(record);
}
}

47
zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpPlanMapper.xml

@ -3,4 +3,51 @@
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zdxt.enforcementcode.mapper.EfcodeCpPlanMapper">
<!-- 其他计划列表:本单位全部 + 其他单位公开,仅待预约状态,排除当前用户 -->
<select id="selectOtherPageList" resultType="com.zdxt.enforcementcode.domain.vo.EfcodeCpPlanVo">
SELECT
id, plan_type, plan_date, plan_time,
plan_actual_date, plan_actual_time,
enforce_content, enterprise_name, enterprise_number, enterprise_id,
enforce_user_names, enforce_user_ids, enforce_user_codes, enforce_user_tels,
is_public, is_union, union_bureau_dept_names,
reserve_status, system_reserved, manual_reserved,
bureau_dept_id, bureau_dept_name,
organ_id, organ_name, dept_id, dept_name,
is_delete, remark, my_remark,
create_by, create_dept, create_time, update_by, update_time
FROM efcode_cp_plan
<where>
reserve_status = 1
AND is_delete = 0
<if test="currentUserId != null">
AND create_by != #{currentUserId}
</if>
<!-- 可见性:本单位全部 OR 其他单位公开 -->
<choose>
<when test="bureauDeptId != null and bureauDeptId != ''">
AND (
bureau_dept_id = #{bureauDeptId}
OR (bureau_dept_id != #{bureauDeptId} AND is_public = 1)
)
</when>
<otherwise>
AND is_public = 1
</otherwise>
</choose>
<!-- 搜索条件 -->
<if test="bo.planDate != null">
AND plan_date = #{bo.planDate}
</if>
<if test="bo.enterpriseName != null and bo.enterpriseName != ''">
AND enterprise_name LIKE CONCAT('%', #{bo.enterpriseName}, '%')
</if>
<if test="bo.enforceContent != null and bo.enforceContent != ''">
AND enforce_content LIKE CONCAT('%', #{bo.enforceContent}, '%')
</if>
</where>
ORDER BY plan_date DESC
</select>
</mapper>

6
zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/plan.js

@ -22,6 +22,12 @@ export const editPlan = (params, success, error) => _put(planBaseUrl, params, su
// 删除计划
export const deletePlan = (ids, success, error) => _delete(planBaseUrl + "/" + ids, {}, success, error);
// 预约前置检查
export const checkCanReserve = (targetPlanId, success, error) => _get(planBaseUrl + "/reserve/check/" + targetPlanId, {}, success, error);
// 执行预约
export const doReservePlan = (params, success, error) => _post(planBaseUrl + "/reserve/do", params, success, error);
// endregion
// region 计划-设置接口

17
zdxt-web-client/zdxt-efcode-enforcement-app/src/assets/style/index.less

@ -49,4 +49,19 @@ html,body,#app{
.van-nav-bar .van-icon {
color: #333;
}
}
/* ===== Toast 样式增强:更醒目、层级更高 ===== */
.van-toast {
z-index: 99999 !important;
background: rgba(0, 0, 0, 0.82) !important;
padding: 14px 24px !important;
border-radius: 12px !important;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3) !important;
}
.van-toast__text {
color: #ffffff !important;
font-size: 15px !important;
font-weight: 500 !important;
line-height: 1.5 !important;
}

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

@ -228,7 +228,7 @@
<script setup name="cpPlanEdit">
import { useRouter, useRoute } from 'vue-router';
import { showToast } from 'vant';
import { showToast, showSuccessToast } from 'vant';
import { addPlan, editPlan, getPlanDetail, getSubmitDeadline, getMaxInnerUnitAcPersonNum, searchUnionByEnterpriseName, searchBureauUnitUsers } from '@/api/enforcement/plan';
const router = useRouter();
@ -290,6 +290,7 @@ const form = ref({
enterpriseId: '',
enforceUserNames: '',
enforceUserIds: '',
enforceUserTels: '',
enforceUserCodes: '',
isPublic: 1,
isUnion: 0,
@ -356,6 +357,9 @@ onMounted(() => {
loadMaxPersonNum();
if (isEdit.value) {
loadDetail(route.query.id);
} else {
//
applyPrefillParams();
}
});
@ -369,6 +373,33 @@ const bindCurrentUserAsDefaultPerson = () => {
syncPersonData();
};
//
const applyPrefillParams = () => {
const q = route.query;
if (q.prefillPlanDate) {
form.value.planDate = q.prefillPlanDate;
form.value.planActualDate = q.prefillPlanDate;
//
const parts = q.prefillPlanDate.split('-');
if (parts.length === 3) {
datePickerValue.value = [parts[0], parts[1], parts[2]];
}
}
if (q.prefillPlanTime) {
form.value.planTime = Number(q.prefillPlanTime) || 1;
form.value.planActualTime = form.value.planTime;
}
if (q.prefillEnterpriseName) {
form.value.enterpriseName = q.prefillEnterpriseName;
}
if (q.prefillEnterpriseId) {
form.value.enterpriseId = q.prefillEnterpriseId;
}
if (q.prefillEnterpriseNumber) {
form.value.enterpriseNumber = q.prefillEnterpriseNumber;
}
};
//
const loadMaxPersonNum = () => {
getMaxInnerUnitAcPersonNum((res) => {
@ -434,7 +465,14 @@ const loadDetail = (id) => {
//
if (data.enforceUserNames) {
const names = data.enforceUserNames.split(',');
personList.value = names.map(name => ({ name, phone: '' }));
const tels = data.enforceUserTels ? data.enforceUserTels.split(',') : [];
const ids = data.enforceUserIds ? data.enforceUserIds.split(',') : [];
personList.value = names.map((name, i) => ({
id: i < ids.length ? ids[i] : '',
name,
phone: i < tels.length ? tels[i] : '',
code: '',
}));
}
}
});
@ -574,6 +612,7 @@ const removePerson = (index) => {
const syncPersonData = () => {
form.value.enforceUserNames = personList.value.map(p => p.name).join(',');
form.value.enforceUserIds = personList.value.map(p => p.id || '').join(',');
form.value.enforceUserTels = personList.value.map(p => p.phone || '').join(',');
form.value.enforceUserCodes = personList.value.map(p => p.code || '').join(',');
};
@ -613,7 +652,11 @@ const onSubmit = () => {
// 1) /(/)
form.value.planActualDate = form.value.planActualDate || form.value.planDate;
form.value.planActualTime = form.value.planTime;
// 2) (,"-"@NotBlank)
// 2) ()
if (!form.value.enforceUserTels || !form.value.enforceUserTels.replace(/[,,\s]/g, '')) {
form.value.enforceUserTels = '-';
}
// 3) (,"-"@NotBlank)
if (!form.value.enforceUserCodes || !form.value.enforceUserCodes.replace(/[,,\s]/g, '')) {
form.value.enforceUserCodes = '-';
}
@ -641,8 +684,8 @@ const onSubmit = () => {
(res) => {
submitting.value = false;
if (res.code === 200) {
showToast(isEdit.value ? '修改成功' : '提交成功');
router.back();
showSuccessToast(isEdit.value ? '修改成功' : '提交成功');
setTimeout(() => router.back(), 800);
} else {
showToast(res.msg || '操作失败');
}

67
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_mine.vue

@ -7,6 +7,26 @@
<van-icon v-if="hasSearchCondition" name="clear" size="14" color="#999" @click.stop="onResetSearch" />
</div>
<!-- 排序栏 -->
<div class="sort-bar">
<div
class="sort-item"
:class="{ active: sortField === 'createTime' }"
@click="onToggleSort('createTime')"
>
<span>创建时间</span>
<van-icon v-if="sortField === 'createTime'" :name="sortOrder === 'desc' ? 'arrow-down' : 'arrow-up'" size="12" />
</div>
<div
class="sort-item"
:class="{ active: sortField === 'planDate' }"
@click="onToggleSort('planDate')"
>
<span>执行日期</span>
<van-icon v-if="sortField === 'planDate'" :name="sortOrder === 'desc' ? 'arrow-down' : 'arrow-up'" size="12" />
</div>
</div>
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list
v-model:loading="loading"
@ -131,6 +151,22 @@ import { getPlanList, deletePlan } from '@/api/enforcement/plan';
const emit = defineEmits(['edit']);
//
const sortField = ref('createTime'); // createTime | planDate
const sortOrder = ref('desc'); // desc | asc
const onToggleSort = (field) => {
if (sortField.value === field) {
//
sortOrder.value = sortOrder.value === 'desc' ? 'asc' : 'desc';
} else {
//
sortField.value = field;
sortOrder.value = 'desc';
}
doSearch();
};
//
const searchForm = ref({
planDate: '',
@ -241,6 +277,9 @@ const fetchList = () => {
if (searchForm.value.planDate) params.planDate = searchForm.value.planDate;
if (searchForm.value.enterpriseName) params.enterpriseName = searchForm.value.enterpriseName;
if (searchForm.value.enforceContent) params.enforceContent = searchForm.value.enforceContent;
//
params.orderByColumn = sortField.value;
params.isAsc = sortOrder.value;
getPlanList(
params,
(res) => {
@ -310,7 +349,7 @@ const onDeletePlan = (item) => {
background: #fff;
border-radius: 20px;
padding: 10px 14px;
margin-bottom: 12px;
margin-bottom: 8px;
box-shadow: 0 2px 8px rgba(44, 116, 190, 0.06);
cursor: pointer;
@ -324,6 +363,32 @@ const onDeletePlan = (item) => {
}
}
.sort-bar {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 12px;
padding: 0 4px;
.sort-item {
display: flex;
align-items: center;
gap: 3px;
font-size: 13px;
color: #999;
cursor: pointer;
padding: 4px 10px;
border-radius: 14px;
transition: all 0.2s;
&.active {
color: #2382cf;
font-weight: 500;
background: rgba(35, 130, 207, 0.08);
}
}
}
.search-popup {
padding: 16px;

131
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_other.vue

@ -110,12 +110,34 @@
@cancel="showSearchDate = false"
/>
</van-popup>
<!-- 预约留言弹窗 -->
<van-popup v-model:show="showReservePopup" position="bottom" round :style="{ maxHeight: '50%' }">
<div class="reserve-popup">
<div class="reserve-popup-title">预约留言</div>
<van-field
v-model="reserveMessage"
type="textarea"
rows="3"
maxlength="200"
show-word-limit
placeholder="请输入预约留言(可选)"
/>
<div class="reserve-popup-actions">
<van-button plain type="default" size="small" @click="showReservePopup = false">取消</van-button>
<van-button type="primary" size="small" :loading="reserveSubmitting" @click="onConfirmReserve">确认预约</van-button>
</div>
</div>
</van-popup>
</div>
</template>
<script setup name="cpPlanOther">
import { showToast } from 'vant';
import { getOtherPlanList } from '@/api/enforcement/plan';
import { showSuccessToast, showDialog } from 'vant';
import { useRouter } from 'vue-router';
import { getOtherPlanList, checkCanReserve, doReservePlan } from '@/api/enforcement/plan';
const router = useRouter();
//
const searchForm = ref({
@ -251,9 +273,82 @@ const fetchList = () => {
};
//
const showReservePopup = ref(false);
const reserveMessage = ref('');
const reserveSubmitting = ref(false);
const currentReserveItem = ref(null);
const onReservePlan = (item) => {
// TODO:
showToast('预约功能开发中');
//
checkCanReserve(
item.id,
(res) => {
if (res.code === 200) {
//
currentReserveItem.value = item;
reserveMessage.value = '';
showReservePopup.value = true;
} else {
showCannotReserveDialog(item, res.code, res.msg);
}
},
(err) => {
showCannotReserveDialog(item, err?.code || 0, err?.msg || err?.message);
}
);
};
// 500""""
const showCannotReserveDialog = (item, code, msg) => {
const needAddPlanBtn = code === 500 && msg === '请先添加我的计划再进行预约';
if (needAddPlanBtn) {
showDialog({
title: '提示',
message: msg,
confirmButtonText: '添加计划',
showCancelButton: true,
cancelButtonText: '取消',
}).then(() => {
// ""
router.push({
path: '/enforcement/plan/edit',
query: {
prefillPlanDate: item.planDate || '',
prefillPlanTime: item.planTime || '',
prefillEnterpriseName: item.enterpriseName || '',
prefillEnterpriseId: item.enterpriseId || '',
prefillEnterpriseNumber: item.enterpriseNumber || '',
}
});
}).catch(() => {});
} else {
showDialog({ title: '提示', message: msg || '预约失败' });
}
};
const onConfirmReserve = () => {
if (!currentReserveItem.value) return;
reserveSubmitting.value = true;
doReservePlan(
{ targetPlanId: currentReserveItem.value.id, opMessage: reserveMessage.value },
(res) => {
reserveSubmitting.value = false;
showReservePopup.value = false;
currentReserveItem.value = null;
if (res.code === 200) {
nextTick(() => { showSuccessToast('预约成功'); });
//
onRefresh();
} else {
nextTick(() => { showDialog({ title: '提示', message: res.msg || '预约失败' }); });
}
},
(err) => {
reserveSubmitting.value = false;
showReservePopup.value = false;
nextTick(() => { showDialog({ title: '提示', message: err?.msg || err?.message || '网络错误,请稍后重试' }); });
}
);
};
</script>
@ -429,4 +524,32 @@ const onReservePlan = (item) => {
color: #07c160;
font-weight: 500;
}
/* 预约留言弹窗 */
.reserve-popup {
padding: 16px;
.reserve-popup-title {
font-size: 16px;
font-weight: 600;
text-align: center;
margin-bottom: 16px;
color: #333;
}
:deep(.van-field) {
padding: 10px 0;
}
.reserve-popup-actions {
display: flex;
gap: 12px;
margin-top: 20px;
padding: 0 10px;
.van-button {
flex: 1;
}
}
}
</style>

2
zdxt-web-server/zdxt-admin-web-server/src/test/java/com/zdxt/rest/test/cp/AppEnfCpPlanControllerTest.java

@ -120,6 +120,7 @@ public class AppEnfCpPlanControllerTest {
info.put("organName", data.get("organName").asText());
info.put("bureauUnitId", data.get("bureauUnitId").asText());
info.put("bureauUnitName", data.get("bureauUnitName").asText());
info.put("phonenumber", data.has("phonenumber") ? data.get("phonenumber").asText() : "");
System.out.println("[" + account + "] 登录成功: userId=" + info.get("userId"));
return info;
@ -252,6 +253,7 @@ public class AppEnfCpPlanControllerTest {
bo.put("enterpriseId", enterprise.getId());
bo.put("enforceUserNames", userName);
bo.put("enforceUserIds", userId);
bo.put("enforceUserTels", loginInfo.get("phonenumber"));
bo.put("enforceUserCodes", "-");
bo.put("isPublic", random.nextInt(2) == 0 ? 0L : 1L); // 随机公开/不公开
bo.put("isUnion", random.nextInt(2) == 0 ? 0L : 1L); // 随机联合/普通

Loading…
Cancel
Save