From 889b9b6b2cec6ef1f1882bdf369114b998580486 Mon Sep 17 00:00:00 2001 From: xiao-fajia <1665375861@qq.com> Date: Mon, 26 Aug 2024 16:08:24 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=95=91=E6=8F=B4=E6=96=B0=E5=8A=9F?= =?UTF-8?q?=E8=83=BD1/2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/module/constant/UserConstants.java | 5 + .../controller/admin/RescueInfoSystem.java | 109 ++++++++++++++++-- .../module/rescue/domain/RescueDictStaff.java | 41 +++++++ .../rescue/mapper/RescueDictStaffMapper.java | 9 ++ .../service/IRescueDictStaffService.java | 12 ++ .../impl/RescueDictStaffServiceImpl.java | 16 +++ .../mapper/rescue/RescueDictStaffMapper.xml | 6 + .../system/api/permission/PermissionApi.java | 8 ++ .../api/permission/PermissionApiImpl.java | 11 ++ .../service/permission/PermissionService.java | 9 ++ .../permission/PermissionServiceImpl.java | 13 +++ 11 files changed, 227 insertions(+), 12 deletions(-) create mode 100644 dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/domain/RescueDictStaff.java create mode 100644 dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/mapper/RescueDictStaffMapper.java create mode 100644 dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/IRescueDictStaffService.java create mode 100644 dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/impl/RescueDictStaffServiceImpl.java create mode 100644 dl-module-rescue/src/main/resources/mapper/rescue/RescueDictStaffMapper.xml diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/constant/UserConstants.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/constant/UserConstants.java index 4adefaa3..d9f9bba7 100644 --- a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/constant/UserConstants.java +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/constant/UserConstants.java @@ -75,4 +75,9 @@ public class UserConstants */ public static final int PASSWORD_MIN_LENGTH = 5; public static final int PASSWORD_MAX_LENGTH = 20; + /** 救援业务管理员 */ + public static final String RESCUE_MANAGE = "jiuyuan"; + + /** 救援司机 */ + public static final String RESCUE_DRIVER = "jysj"; } diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/controller/admin/RescueInfoSystem.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/controller/admin/RescueInfoSystem.java index bf27d801..f93d7240 100644 --- a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/controller/admin/RescueInfoSystem.java +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/controller/admin/RescueInfoSystem.java @@ -1,34 +1,38 @@ package cn.iocoder.yudao.module.rescue.controller.admin; import cn.hutool.core.collection.CollectionUtil; - import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.module.constant.UserConstants; import cn.iocoder.yudao.module.rescue.core.controller.BaseController; import cn.iocoder.yudao.module.rescue.core.page.TableDataInfo; -import cn.iocoder.yudao.module.rescue.domain.DriverInfo; -import cn.iocoder.yudao.module.rescue.domain.RescueInfo; -import cn.iocoder.yudao.module.rescue.domain.RescueInfoDetail; -import cn.iocoder.yudao.module.rescue.domain.RescueOrderInfo; +import cn.iocoder.yudao.module.rescue.domain.*; import cn.iocoder.yudao.module.rescue.dto.DriverInfoDto; import cn.iocoder.yudao.module.rescue.dto.SysDictData; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.security.core.LoginUser; -import cn.iocoder.yudao.module.staff.entity.CompanyStaff; -import cn.iocoder.yudao.module.system.api.dict.DictDataApi; -import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO; +import cn.iocoder.yudao.module.rescue.service.IRescueDictStaffService; import cn.iocoder.yudao.module.rescue.service.IRescueInfoDetailService; import cn.iocoder.yudao.module.rescue.service.IRescueInfoService; import cn.iocoder.yudao.module.rescue.service.IRescueOrderInfoService; import cn.iocoder.yudao.module.rescue.utils.ExcelUtil; import cn.iocoder.yudao.module.rescue.utils.StringUtils; import cn.iocoder.yudao.module.rescue.vo.MoneyManagement; +import cn.iocoder.yudao.module.staff.entity.CompanyStaff; +import cn.iocoder.yudao.module.staff.service.CompanyStaffService; +import cn.iocoder.yudao.module.system.api.dict.DictDataApi; +import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO; +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; +import cn.iocoder.yudao.module.system.api.permission.RoleApi; +import cn.iocoder.yudao.module.system.api.permission.dto.RoleReqDTO; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.context.annotation.Lazy; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -53,6 +57,22 @@ public class RescueInfoSystem extends BaseController { @Resource private IRescueInfoDetailService rescueInfoDetailService; + @Resource + private IRescueDictStaffService rescueDictStaffService; + + @Resource + @Lazy + private AdminUserApi adminUserApi; + + @Resource + private CompanyStaffService staffService; + + @Resource + private RoleApi roleApi; + + @Resource + private PermissionApi permissionApi; + /** * 新增【道路救援发起】 */ @@ -310,6 +330,10 @@ public class RescueInfoSystem extends BaseController { @PostMapping("/delRescueRoad") public CommonResult delRescueRoad(Long dictId) { dictDataApi.deleteDictDataByIds(new Long[]{dictId}); + RescueDictStaff flag = rescueDictStaffService.getOne(new LambdaQueryWrapper().eq(RescueDictStaff::getDictId, dictId)); + if (ObjectUtil.isNotEmpty(flag)){ + rescueDictStaffService.remove(new LambdaQueryWrapper().eq(RescueDictStaff::getDictId, dictId)); + } return CommonResult.ok(); } @@ -349,4 +373,65 @@ public class RescueInfoSystem extends BaseController { String title = "施救总金额:" + jsonObject.getString("allMoney") + "元 出车次数:" + jsonObject.getString("allNum") + "次 提成总金额:" + jsonObject.getString("tcAll") + " 元 燃油费小计:" + jsonObject.getString("refuelMoney") + "元"; util.exportExcel(response, list, "救援财务报表", title); } + + /** + * 查询救援路段的司机和管理人员信息 + * @author 小李 + * @date 9:17 2024/8/26 + * @param ids 路段IDs 一个或多个 + **/ + @GetMapping("/getDictStaff/{ids}") + public CommonResult getDictStaff(@PathVariable("ids") Long[] ids){ + List dictIds = Arrays.asList(ids); + List rescueDictStaffs = dictIds.stream().map(item -> { + RescueDictStaff rescueDictStaff = rescueDictStaffService.getOne(new LambdaQueryWrapper().eq(RescueDictStaff::getDictId, item)); + if (ObjectUtil.isNotEmpty(rescueDictStaff)) { + // 拿路段管理员的名字 + AdminUserRespDTO user = adminUserApi.getUser(rescueDictStaff.getManageId()); + rescueDictStaff.setManageName(user.getNickname()); + // 拿路段司机的名字 + List driverIds = Arrays.asList(rescueDictStaff.getDriverIds().split(",")).stream().map(Long::parseLong).collect(Collectors.toList()); + List drivers = adminUserApi.getUserList(driverIds); + StringJoiner tempStr = new StringJoiner("|"); + for (AdminUserRespDTO driver : drivers) { + tempStr.add(driver.getNickname()); + } + rescueDictStaff.setDriverNames(tempStr.toString()); + } + return rescueDictStaff; + }).collect(Collectors.toList()); + return success(rescueDictStaffs); + } + + /** + * 获得所有救援业务管理员 + * @author 小李 + * @date 10:10 2024/8/26 + **/ + @GetMapping("/getManages") + public CommonResult getManages(){ + RoleReqDTO roleInfo = roleApi.getRoleInfo(UserConstants.RESCUE_MANAGE); + List userIds = permissionApi.getUserIdByRoleId(roleInfo.getId()); + List staffs = staffService.list(new LambdaQueryWrapper().in(CompanyStaff::getUserId, userIds)); + return success(staffs); + } + + /** + * 获得所有司机 + * @author 小李 + * @date 10:10 2024/8/26 + **/ + @GetMapping("/getDrivers") + public CommonResult getDrivers(){ + RoleReqDTO roleInfo = roleApi.getRoleInfo(UserConstants.RESCUE_DRIVER); + List userIds = permissionApi.getUserIdByRoleId(roleInfo.getId()); + List staffs = staffService.list(new LambdaQueryWrapper().in(CompanyStaff::getUserId, userIds)); + return success(staffs); + } + + @PostMapping("/bindDictStaff") + public CommonResult bindDictStaff(@RequestBody RescueDictStaff rescueDictStaff){ + rescueDictStaffService.saveOrUpdate(rescueDictStaff); + return CommonResult.ok(); + } } diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/domain/RescueDictStaff.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/domain/RescueDictStaff.java new file mode 100644 index 00000000..35455772 --- /dev/null +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/domain/RescueDictStaff.java @@ -0,0 +1,41 @@ +package cn.iocoder.yudao.module.rescue.domain; + +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 路段和人员绑定表 + * @author 小李 + * @date 9:12 2024/8/26 +**/ +@Data +@TableName("rescue_dict_staff") +@EqualsAndHashCode(callSuper = true) +public class RescueDictStaff extends TenantBaseDO { + + /** 主键标识 */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** 字典数据ID */ + private Long dictId; + + /** 管理人员ID */ + private Long manageId; + + /** 管理人员名字 */ + @TableField(exist = false) + private String manageName; + + /** 司机们的ID 逗号分隔 */ + private String driverIds; + + /** 司机们的名字 */ + @TableField(exist = false) + private String driverNames; +} diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/mapper/RescueDictStaffMapper.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/mapper/RescueDictStaffMapper.java new file mode 100644 index 00000000..500f72a9 --- /dev/null +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/mapper/RescueDictStaffMapper.java @@ -0,0 +1,9 @@ +package cn.iocoder.yudao.module.rescue.mapper; + +import cn.iocoder.yudao.module.rescue.domain.RescueDictStaff; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface RescueDictStaffMapper extends BaseMapper { +} diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/IRescueDictStaffService.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/IRescueDictStaffService.java new file mode 100644 index 00000000..fba8d816 --- /dev/null +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/IRescueDictStaffService.java @@ -0,0 +1,12 @@ +package cn.iocoder.yudao.module.rescue.service; + +import cn.iocoder.yudao.module.rescue.domain.RescueDictStaff; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * 路段和人员绑定表 接口 + * @author 小李 + * @date 9:13 2024/8/26 +**/ +public interface IRescueDictStaffService extends IService { +} diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/impl/RescueDictStaffServiceImpl.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/impl/RescueDictStaffServiceImpl.java new file mode 100644 index 00000000..8cbdc81d --- /dev/null +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/impl/RescueDictStaffServiceImpl.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.module.rescue.service.impl; + +import cn.iocoder.yudao.module.rescue.domain.RescueDictStaff; +import cn.iocoder.yudao.module.rescue.mapper.RescueDictStaffMapper; +import cn.iocoder.yudao.module.rescue.service.IRescueDictStaffService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * 路段和人员绑定表 接口实现类 + * @author 小李 + * @date 9:13 2024/8/26 +**/ +@Service +public class RescueDictStaffServiceImpl extends ServiceImpl implements IRescueDictStaffService { +} diff --git a/dl-module-rescue/src/main/resources/mapper/rescue/RescueDictStaffMapper.xml b/dl-module-rescue/src/main/resources/mapper/rescue/RescueDictStaffMapper.xml new file mode 100644 index 00000000..9c3cd373 --- /dev/null +++ b/dl-module-rescue/src/main/resources/mapper/rescue/RescueDictStaffMapper.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApi.java index 4487a93e..914e1005 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApi.java @@ -72,4 +72,12 @@ public interface PermissionApi { * @param userId 用户ID **/ List getRoleIdsByUserId(Long userId); + + /** + * 根据权限ID拿拥有该权限的所有人 + * @author 小李 + * @date 10:25 2024/8/26 + * @param roleId 权限ID + **/ + List getUserIdByRoleId(Long roleId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApiImpl.java index 741a84c9..01154e35 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/permission/PermissionApiImpl.java @@ -77,4 +77,15 @@ public class PermissionApiImpl implements PermissionApi { return roleIds.stream().collect(Collectors.toList()); } + /** + * 根据权限ID拿拥有该权限的所有人 + * @author 小李 + * @date 10:25 2024/8/26 + * @param roleId 权限ID + **/ + @Override + public List getUserIdByRoleId(Long roleId){ + return permissionService.getUserIdByRoleId(roleId); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionService.java index 47f2bda6..f0d6dfa6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionService.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.service.permission; import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO; import java.util.Collection; +import java.util.List; import java.util.Set; import static java.util.Collections.singleton; @@ -161,4 +162,12 @@ public interface PermissionService { */ DeptDataPermissionRespDTO getDeptDataPermission(Long userId); + /** + * 根据权限ID拿拥有该权限的所有人 + * @author 小李 + * @date 10:25 2024/8/26 + * @param roleId 权限ID + **/ + List getUserIdByRoleId(Long roleId); + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java index 2dd4e91e..2dd0e6e0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java @@ -7,6 +7,7 @@ import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore; import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO; import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; @@ -33,6 +34,7 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.*; import java.util.function.Supplier; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; @@ -359,4 +361,15 @@ public class PermissionServiceImpl implements PermissionService { return SpringUtil.getBean(getClass()); } + /** + * 根据权限ID拿拥有该权限的所有人 + * @author 小李 + * @date 10:25 2024/8/26 + * @param roleId 权限ID + **/ + public List getUserIdByRoleId(Long roleId){ + List userRoleDOS = userRoleMapper.selectList(new LambdaQueryWrapperX().eq(UserRoleDO::getRoleId, roleId)); + List userIds = userRoleDOS.stream().map(item -> item.getUserId()).collect(Collectors.toList()); + return userIds; + } } From 4057dd5e59f5587fc78acdb2776c5e3a971ac6f6 Mon Sep 17 00:00:00 2001 From: xiao-fajia <1665375861@qq.com> Date: Mon, 26 Aug 2024 21:19:46 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=95=91=E6=8F=B4=E6=96=B0=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/module/constant/UserConstants.java | 3 + .../module/rescue/domain/RescueInfo.java | 3 + .../yudao/module/rescue/dto/TaskDto.java | 18 ++ .../service/impl/DriverInfoServiceImpl.java | 69 ++++--- .../impl/RescueDriverInfoServiceImpl.java | 14 +- .../service/impl/RescueInfoServiceImpl.java | 46 ++++- .../rescue/utils/RedissonDelayQueue.java | 178 ++++++++++++++++++ 7 files changed, 293 insertions(+), 38 deletions(-) create mode 100644 dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/dto/TaskDto.java create mode 100644 dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/utils/RedissonDelayQueue.java diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/constant/UserConstants.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/constant/UserConstants.java index d9f9bba7..2bc14568 100644 --- a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/constant/UserConstants.java +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/constant/UserConstants.java @@ -80,4 +80,7 @@ public class UserConstants /** 救援司机 */ public static final String RESCUE_DRIVER = "jysj"; + + /** 救援定时任务时间 */ + public static final Integer RESCUE_TIME = 3 * 60; } diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/domain/RescueInfo.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/domain/RescueInfo.java index 1d461329..be24eb45 100644 --- a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/domain/RescueInfo.java +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/domain/RescueInfo.java @@ -184,4 +184,7 @@ public class RescueInfo extends TenantBaseDO @TableField(exist = false) private String rescueStartMonth; + @TableField(exist = false) + private Long[] roadIds; + } diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/dto/TaskDto.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/dto/TaskDto.java new file mode 100644 index 00000000..e88c008b --- /dev/null +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/dto/TaskDto.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.rescue.dto; + +import lombok.Data; + +/** + * 用于创建定时任务 + * @author 小李 + * @date 18:41 2024/8/26 +**/ +@Data +public class TaskDto { + + // 谁发起的订单 + private Long manageId; + + // 发起的订单 + private Long rescueInfoId; +} diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/impl/DriverInfoServiceImpl.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/impl/DriverInfoServiceImpl.java index c4aed1eb..a389b931 100644 --- a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/impl/DriverInfoServiceImpl.java +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/impl/DriverInfoServiceImpl.java @@ -127,33 +127,46 @@ public class DriverInfoServiceImpl extends ServiceImpl driverInfos = baseMapper.selectList(new QueryWrapper<>()); - List companyStaffs = new ArrayList<>(); - driverInfos.stream().forEach(item -> { - AdminUserRespDTO user = adminUserApi.getUser(item.getUserId()); - if (ObjectUtil.isNotEmpty(user)){ - long count = staffService.count(new LambdaQueryWrapper().eq(CompanyStaff::getUserId, user.getId())); - if (count == 0){ - CompanyStaff staff = new CompanyStaff(); - staff.setUserId(user.getId()); - staff.setDeptId(user.getDeptId()); - DeptRespDTO dept = deptApi.getDept(user.getDeptId()); - staff.setCorpId(dept.getCorpId()); - String uniqueCode = uniqueCodeService.createUniqueCode(); - if (!ObjectUtil.isNotEmpty(uniqueCode)) { - throw exception(CommonErrorCodeConstants.UNIQUE_CODE_CREATE_REPEAT); - } - staff.setUniqueCode(uniqueCode); - - staff.setName(user.getNickname()); - staff.setTel(item.getPhonenumber()); - staff.setSex(String.valueOf(user.getSex())); - companyStaffs.add(staff); - } - } - }); - if (ObjectUtil.isNotEmpty(companyStaffs)){ - staffService.saveBatch(companyStaffs); +// List driverInfos = baseMapper.selectList(new QueryWrapper<>()); +// List companyStaffs = new ArrayList<>(); +// driverInfos.stream().forEach(item -> { +// AdminUserRespDTO user = adminUserApi.getUser(item.getUserId()); +// if (ObjectUtil.isNotEmpty(user)){ +// long count = staffService.count(new LambdaQueryWrapper().eq(CompanyStaff::getUserId, user.getId())); +// if (count == 0){ +// CompanyStaff staff = new CompanyStaff(); +// staff.setUserId(user.getId()); +// staff.setDeptId(user.getDeptId()); +// DeptRespDTO dept = deptApi.getDept(user.getDeptId()); +// staff.setCorpId(dept.getCorpId()); +// String uniqueCode = uniqueCodeService.createUniqueCode(); +// if (!ObjectUtil.isNotEmpty(uniqueCode)) { +// throw exception(CommonErrorCodeConstants.UNIQUE_CODE_CREATE_REPEAT); +// } +// staff.setUniqueCode(uniqueCode); +// +// staff.setName(user.getNickname()); +// staff.setTel(item.getPhonenumber()); +// staff.setSex(String.valueOf(user.getSex())); +// companyStaffs.add(staff); +// } +// } +// }); +// if (ObjectUtil.isNotEmpty(companyStaffs)){ +// staffService.saveBatch(companyStaffs); +// } + AdminUserRespDTO user = adminUserApi.getUser(708L); + CompanyStaff staff = new CompanyStaff(); + staff.setUserId(user.getId()); + staff.setDeptId(100L); + staff.setWorkNo("la0000"); + staff.setName(user.getNickname()); + staff.setTel(user.getMobile()); + staff.setSex(String.valueOf(user.getSex())); + String uniqueCode = uniqueCodeService.createUniqueCode(); + if (ObjectUtil.isNotEmpty(uniqueCode)){ + staff.setUniqueCode(uniqueCode); } - }; + staffService.save(staff); + } } diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/impl/RescueDriverInfoServiceImpl.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/impl/RescueDriverInfoServiceImpl.java index 12dcdde3..2dd5f836 100644 --- a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/impl/RescueDriverInfoServiceImpl.java +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/service/impl/RescueDriverInfoServiceImpl.java @@ -4,7 +4,9 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.CoordinateUtil; import cn.hutool.http.HttpUtil; import cn.iocoder.yudao.module.rescue.domain.*; +import cn.iocoder.yudao.module.rescue.dto.TaskDto; import cn.iocoder.yudao.module.rescue.mapper.RescueDriverInfoMapper; +import cn.iocoder.yudao.module.rescue.utils.RedissonDelayQueue; import cn.iocoder.yudao.module.system.api.dict.DictDataApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; @@ -31,7 +33,8 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import static cn.hutool.core.util.CoordinateUtil.wgs84ToGcj02; - +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0; /** @@ -68,6 +71,8 @@ public class RescueDriverInfoServiceImpl extends ServiceImpl { -// //自动派单 -// this.appointDriverByBusiness(deptId,rescueInfo.getId()); -// }); -// thread.start(); + + // 自动通知对应路段司机 + List list = rescueDictStaffService.list(new LambdaQueryWrapper().in(RescueDictStaff::getDictId, rescueInfo.getRoadIds())); + if (CollectionUtil.isNotEmpty(list)){ + Set driverIds = list.stream() + .map(RescueDictStaff::getDriverIds) + .flatMap(item -> Arrays.stream(item.split(","))) + .map(Long::parseLong) + .collect(Collectors.toSet()); + driverIds.forEach(item -> { + SysAnnouncement sysAnnouncement = new SysAnnouncement(); + sysAnnouncement.setType("救援信息"); + sysAnnouncement.setToUserIds(Collections.singletonList(item)); + sysAnnouncement.setTitle("有新的救援订单请立即处理"); + sysAnnouncement.setContent("有新的救援订单请立即处理"); + announcementService.insertSysAnnouncements(sysAnnouncement); + }); + } + // 新增延迟消息,用于三分钟后没人接单通知 + TaskDto taskDto = new TaskDto(); + taskDto.setManageId(loginUser.getId()); + taskDto.setRescueInfoId(rescueInfo.getId()); + redissonDelayQueue.offerTask(JSON.toJSONString(taskDto), UserConstants.RESCUE_TIME); } } @@ -401,6 +429,10 @@ public class RescueInfoServiceImpl extends ServiceImpl 0) { rescueInfo.setRescueStatus(null); } + // 取消订单时删除定时任务 + if (rescueInfo.getRescueStatus().equals("0")){ + redissonDelayQueue.removeAllTasks(rescueInfo.getId()); + } return baseMapper.updateById(rescueInfo); } diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/utils/RedissonDelayQueue.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/utils/RedissonDelayQueue.java new file mode 100644 index 00000000..addc677f --- /dev/null +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/utils/RedissonDelayQueue.java @@ -0,0 +1,178 @@ +package cn.iocoder.yudao.module.rescue.utils; + +import cn.iocoder.yudao.module.appBase.domain.SysAnnouncement; +import cn.iocoder.yudao.module.appBase.service.ISysAnnouncementService; +import cn.iocoder.yudao.module.constant.UserConstants; +import cn.iocoder.yudao.module.rescue.dto.TaskDto; +import com.alibaba.fastjson.JSON; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.redisson.api.RBlockingQueue; +import org.redisson.api.RDelayedQueue; +import org.redisson.api.RMap; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.util.Collections; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * Redisson 延迟队列组件,用于处理带有延迟时间的任务。 + * + * @author 小李 + * @date 16:37 2024/8/26 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class RedissonDelayQueue { + + // 注入 Redisson 提供的延迟队列接口 + @Resource + private RDelayedQueue delayedQueue; + + // 注入 Redisson 提供的阻塞队列接口 + @Resource + private RBlockingQueue blockingQueue; + + @Resource + private ISysAnnouncementService announcementService; + + // 任务索引,用于快速查找任务 + @Resource + private RMap taskIndex; + + /** + * 初始化方法,在 Spring 容器加载后自动执行。 + * 创建一个固定大小的线程池来消费阻塞队列中的任务。 + */ + @PostConstruct + public void init() { + // 创建一个单线程的线程池 + ExecutorService executorService = Executors.newFixedThreadPool(1); + + // 提交一个无限循环的任务到线程池,用于持续消费队列中的任务 + executorService.submit(() -> { + while (true) { + try { + // 从阻塞队列中获取一个任务,如果队列为空,则此方法会一直阻塞直到有任务可用 + String task = blockingQueue.take(); + + // 记录接收到的任务信息 + log.info("定时任务:{}", task); + + // 通知发起者 + TaskDto taskDto = JSON.parseObject(task, TaskDto.class); + SysAnnouncement sysAnnouncement = new SysAnnouncement(); + sysAnnouncement.setType("救援超时信息"); + sysAnnouncement.setToUserIds(Collections.singletonList(taskDto.getManageId())); + sysAnnouncement.setTitle("有救援订单超时请立即处理"); + sysAnnouncement.setContent("有救援订单超时请立即处理"); + announcementService.insertSysAnnouncements(sysAnnouncement); + + // TODO 还要通知总调度 + + // 在新创建定时任务 + offerTask(task, UserConstants.RESCUE_TIME); + } catch (Exception e) { + // 记录并打印异常信息 + log.error("发生错误", e); + } + } + }); + } + + /** + * 向延迟队列中添加一个任务,并设置延迟时间。 + * + * @param task 要添加的任务 + * @param seconds 任务的延迟时间,单位为秒 + */ + public void offerTask(String task, long seconds) { + // 记录添加任务的日志信息 + log.info("添加定时任务:{},过期时间为:{}s", task, seconds); + + // 从任务中提取 rescueInfoId + TaskDto taskDto = JSON.parseObject(task, TaskDto.class); + Long rescueInfoId = taskDto.getRescueInfoId(); + + // 存储任务索引 + taskIndex.put(rescueInfoId, task); + + // 向延迟队列添加任务,并设置延迟时间 + delayedQueue.offer(task, seconds, TimeUnit.SECONDS); + } + + /** + * 从延迟队列中移除指定的任务。 + * + * @param rescueInfoId 要移除的任务 + * @return 移除是否成功 + */ + private boolean removeDelayedTask(Long rescueInfoId) { + try { + // 从任务索引中查找任务 + String task = taskIndex.get(rescueInfoId); + + // 如果找到了任务,则尝试从延迟队列中移除任务 + if (task != null) { + boolean removed = delayedQueue.remove(task); + if (removed) { + // 从任务索引中移除任务 + taskIndex.remove(rescueInfoId); + } + return removed; + } + } catch (Exception e) { + log.error("延迟队列删除失败", e); + } + return false; + } + + /** + * 从阻塞队列中移除指定的任务。 + * + * @param rescueInfoId 要移除的任务 + * @return 移除是否成功 + */ + private boolean removeBlockingTask(Long rescueInfoId) { + try { + // 从任务索引中查找任务 + String task = taskIndex.get(rescueInfoId); + + // 如果找到了任务,则尝试从阻塞队列中移除任务 + if (task != null) { + boolean removed = blockingQueue.remove(task); + if (removed) { + // 从任务索引中移除任务 + taskIndex.remove(rescueInfoId); + } + return removed; + } + } catch (Exception e) { + log.error("阻塞队列删除失败", e); + } + return false; + } + + /** + * 尝试同时从延迟队列和阻塞队列中移除指定的任务。 + * 如果任务在任何一个队列中存在,则尝试移除。 + * + * @param rescueInfoId 要移除的任务 + * @return 是否至少在一个队列中移除成功 + */ + public boolean removeAllTasks(Long rescueInfoId) { + // 尝试从延迟队列中移除任务 + boolean removedFromDelayed = removeDelayedTask(rescueInfoId); + + // 尝试从阻塞队列中移除任务 + boolean removedFromBlocking = removeBlockingTask(rescueInfoId); + + // 如果任何一个队列中移除成功,则返回 true + return removedFromDelayed || removedFromBlocking; + } +} \ No newline at end of file From 66cc4be5114df959c152231b91d33eaddea097c6 Mon Sep 17 00:00:00 2001 From: xiao-fajia <1665375861@qq.com> Date: Mon, 26 Aug 2024 21:25:59 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=A1=A5=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rescue/utils/RedissonDelayQueue.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/utils/RedissonDelayQueue.java b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/utils/RedissonDelayQueue.java index addc677f..0771ed55 100644 --- a/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/utils/RedissonDelayQueue.java +++ b/dl-module-rescue/src/main/java/cn/iocoder/yudao/module/rescue/utils/RedissonDelayQueue.java @@ -10,6 +10,7 @@ import lombok.extern.slf4j.Slf4j; import org.redisson.api.RBlockingQueue; import org.redisson.api.RDelayedQueue; import org.redisson.api.RMap; +import org.redisson.api.RedissonClient; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; @@ -30,27 +31,34 @@ import java.util.concurrent.TimeUnit; @RequiredArgsConstructor public class RedissonDelayQueue { - // 注入 Redisson 提供的延迟队列接口 @Resource + private RedissonClient redissonClient; + + // 注入 Redisson 提供的延迟队列接口 private RDelayedQueue delayedQueue; // 注入 Redisson 提供的阻塞队列接口 - @Resource private RBlockingQueue blockingQueue; + // 任务索引,用于快速查找任务 + private RMap taskIndex; + @Resource private ISysAnnouncementService announcementService; - // 任务索引,用于快速查找任务 - @Resource - private RMap taskIndex; - /** * 初始化方法,在 Spring 容器加载后自动执行。 * 创建一个固定大小的线程池来消费阻塞队列中的任务。 */ @PostConstruct public void init() { + + blockingQueue = redissonClient.getBlockingQueue("RESCUE_QUEUE"); + + delayedQueue = redissonClient.getDelayedQueue(blockingQueue); + + taskIndex = redissonClient.getMap("RESCUE_INDEX"); + // 创建一个单线程的线程池 ExecutorService executorService = Executors.newFixedThreadPool(1);