Compare commits

..

5 Commits

Author SHA1 Message Date
ac61fc83a4 Merge branch 'rescue' 2025-10-17 16:17:18 +08:00
8d790d497d Merge remote-tracking branch 'origin/rescue' into rescue 2025-10-17 16:07:51 +08:00
58765f9558 救援1-6功能 2025-10-17 16:07:20 +08:00
xyc
3655bd7fb2 更新1009 2025-10-09 09:12:29 +08:00
Lx
6e3f274688 0930 2025-09-30 10:10:33 +08:00
32 changed files with 1674 additions and 55 deletions

View File

@ -141,6 +141,10 @@ public class DlDriveSchoolCourseServiceImpl extends ServiceImpl<DlDriveSchoolCou
public void saveDriveSchoolCourse(DlDriveSchoolCourseNewVO courseVO) {
boolean isNew = (courseVO.getId() == null);
if (courseVO.getCoachList().isEmpty()) {
throw new RuntimeException("新增课程时必须至少包含一个教练");
}
DlDriveSchoolCourse course = BeanUtils.toBean(courseVO, DlDriveSchoolCourse.class);
if (isNew) {

View File

@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.constant;
public interface MessageConstants {
/**
* 保险到期提醒消息
*/
String INSURANCE_DEADLINE_REMINDER = "救援车辆:%s 的保险已到期!";
/**
* 车辆年检到期提醒
*/
String CAR_CHECK_DEADLINE_REMINDER = "救援车辆:%s 的年检已到期!";
}

View File

@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.rescue.domain.RescueInfo;
import cn.iocoder.yudao.module.rescue.dto.DriverInfo2Dto;
import cn.iocoder.yudao.module.rescue.dto.DriverInfoDto;
import cn.iocoder.yudao.module.rescue.service.IRescueInfoService;
import cn.iocoder.yudao.module.rescue.vo.RescueCarStatRespVO;
import cn.iocoder.yudao.module.rescue.vo.StatisticsStaffVO;
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
@ -19,6 +20,7 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -52,6 +54,42 @@ public class RescueInfoController extends BaseController {
@Resource
private RepairBookingService dlRepairBookingService;
/**
* 获取所有待救援订单
*/
@GetMapping("/getAllRescueOrder")
public CommonResult<List<RescueInfo>> getAllRescueOrder() {
List<RescueInfo> rescueOrder = rescueInfoService.getAllRescueOrder();
return success(rescueOrder);
}
/**
* 获取救援车辆列表 APP业务管理
*/
@GetMapping("/rescueCarList")
public CommonResult<List<RescueInfo>> rescueCarList(RescueInfo rescueInfo) {
List<List<RescueInfo>> rescueDriverList = rescueInfoService.rescueCarList(rescueInfo);
return success(rescueDriverList);
}
/**
* 计算救援车辆车龄和累计里程 APP业务管理
*/
@GetMapping("/getRescueCarAgeAndMileage")
public CommonResult<List<RescueCarStatRespVO>> getRescueCarAgeAndMileage() {
List<RescueCarStatRespVO> list = rescueInfoService.getRescueCarAgeAndMileage();
return success(list);
}
/**
* 通过车牌号获取救援车辆业绩表 APP业务管理
*/
@GetMapping("/getRescueCarKPI")
public CommonResult<List<RescueInfo>> getRescueCarKPI(String driverCarNum,String startTime,String endTime) {
List<RescueInfo> list = rescueInfoService.getRescueCarKPI(driverCarNum,startTime,endTime);
return success(list);
}
/**
* 获取救援订单
*/
@ -343,7 +381,7 @@ public class RescueInfoController extends BaseController {
* 获取扣车订单
*/
@GetMapping("/statisticsInfo")
public CommonResult statisticsInfo(String type) {
public CommonResult statisticsInfo(String type) {
return success(rescueInfoService.statisticsInfo(type));
}
@ -388,5 +426,78 @@ public class RescueInfoController extends BaseController {
return success(rescueInfoService.statisticsAll(statisticsStaffReqVO));
}
@GetMapping("/statisticsAllSecond")
public CommonResult statisticsAllSecond(StatisticsStaffVO statisticsStaffReqVO) {
return success(rescueInfoService.statisticsAllSecond(statisticsStaffReqVO));
}
/**
* App首页数据统计工单列表数据
*/
@GetMapping("/getRescueStatisticsInfoList")
public CommonResult getRescueStatisticsInfoList(RescueInfo rescueInfo,
@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
Page<RescueInfo> page = new Page<>(pageNum, pageSize);
//获取当前登录用户
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
AdminUserRespDTO user = userService.getUser(loginUser.getId());
List<Long> roleIds = permissionApi.getRoleIdsByUserId(user.getId());
List<RoleReqDTO> roleList = roleApi.getRoleList();
List<RoleReqDTO> roles = roleList.stream().filter(item -> roleIds.contains(item.getId())).collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(roles)) {
for (RoleReqDTO role : roles) {
//如果是调度中心
if (role.getCode().equals("admin") || role.getCode().equals("ddzx") || role.getCode().equals("qt") || role.getCode().equals("kj") || role.getCode().equals("cn") || role.getCode().equals("car_safekeeping")) {
IPage<RescueInfo> rescueInfos = rescueInfoService.selectRescueStatisticsInfoListByAdmin(rescueInfo, page);
return success(rescueInfos);
}
}
}
if (CollectionUtil.isNotEmpty(roles)) {
for (RoleReqDTO role : roles) {
//如果是二级调度
if (role.getCode().equals("second_dispatcher")) {
rescueInfo.setUserId(user.getId());
IPage<RescueInfo> rescueInfos = rescueInfoService.selectRescueStatisticsInfoListBySecondDispatcher(rescueInfo, page);
return success(rescueInfos);
}
}
}
IPage<RescueInfo> rescueInfos = rescueInfoService.selectRescueInfoList(rescueInfo, page);
return success(rescueInfos);
}
@GetMapping("/getRescueStatisticsInfoNum")
public CommonResult getRescueStatisticsInfoNum(RescueInfo rescueInfo) {
//获取当前登录用户
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
AdminUserRespDTO user = userService.getUser(loginUser.getId());
List<Long> roleIds = permissionApi.getRoleIdsByUserId(user.getId());
List<RoleReqDTO> roleList = roleApi.getRoleList();
List<RoleReqDTO> roles = roleList.stream().filter(item -> roleIds.contains(item.getId())).collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(roles)) {
for (RoleReqDTO role : roles) {
//如果是调度中心
if (role.getCode().equals("admin") || role.getCode().equals("ddzx") || role.getCode().equals("qt") || role.getCode().equals("kj") || role.getCode().equals("cn") || role.getCode().equals("car_safekeeping")) {
Map<String, Object> rescueInfoNum = rescueInfoService.getRescueStatisticsInfoNum(rescueInfo);
return success(rescueInfoNum);
}
}
}
if (CollectionUtil.isNotEmpty(roles)) {
for (RoleReqDTO role : roles) {
//如果是二级调度
if (role.getCode().equals("second_dispatcher")) {
rescueInfo.setUserId(user.getId());
Map<String, Object> rescueInfoNum = rescueInfoService.getRescueStatisticsInfoNumSecondDispatcher(rescueInfo);
return success(rescueInfoNum);
}
}
}
return success(null);
}
}

View File

@ -1,11 +1,57 @@
package cn.iocoder.yudao.module.rescue.controller.admin;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.rescue.core.controller.BaseController;
import cn.iocoder.yudao.module.rescue.domain.DriverInfo;
import cn.iocoder.yudao.module.rescue.domain.RescueCarInfo;
import cn.iocoder.yudao.module.rescue.service.IDriverInfoService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/system/DriverInfo")
public class DriverInfoController extends BaseController {
@Resource
private IDriverInfoService driverInfoService;
/**
* 获取司机完整列表
*/
@GetMapping("/listDriverInfo")
public CommonResult listDriverInfo() {
List<DriverInfo> driverInfoList = driverInfoService.listDriverInfo();
return success(driverInfoList);
}
/**
* 获取司机完整列表
*/
@GetMapping("/listCarInfo")
public CommonResult listCarInfo() {
List<RescueCarInfo> carInfoList = driverInfoService.listCarInfo();
return success(carInfoList);
}
/**
* 二级调度获取司机列表
*/
@GetMapping("/listDriverInfoSecond")
public CommonResult listDriverInfoSecond() {
List<DriverInfo> driverInfoList = driverInfoService.listDriverInfoSecond();
return success(driverInfoList);
}
/**
* 二级调度获取车辆列表
*/
@GetMapping("/listCarInfoSecond")
public CommonResult listCarInfoSecond() {
List<RescueCarInfo> carInfoList = driverInfoService.listCarInfoSecond();
return success(carInfoList);
}
}

View File

@ -1,21 +1,48 @@
package cn.iocoder.yudao.module.rescue.controller.admin;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.common.BaseConstants;
import cn.iocoder.yudao.common.SystemEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.custom.entity.CarMain;
import cn.iocoder.yudao.module.custom.service.CarMainService;
import cn.iocoder.yudao.module.custom.vo.CarMainReqVO;
import cn.iocoder.yudao.module.custom.vo.CarMainRespVO;
import cn.iocoder.yudao.module.rescue.core.controller.BaseController;
import cn.iocoder.yudao.module.rescue.domain.RescueCarInfo;
import cn.iocoder.yudao.module.rescue.service.IRescueCarInfoService;
import cn.iocoder.yudao.module.rescue.task.RescueDeadlineReminder;
import cn.iocoder.yudao.module.rescue.utils.ExcelUtil;
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.UserDTO;
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.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.constant.MessageConstants.INSURANCE_DEADLINE_REMINDER;
/**
* 救援车辆信息Controller
@ -30,6 +57,57 @@ public class RescueCarInfoController extends BaseController {
private IRescueCarInfoService rescueCarInfoService;
@Autowired
private AdminUserApi adminUserApi;
@Autowired
private RescueDeadlineReminder rescueDeadlineReminder;
@Autowired
private NotifyMessageSendApi sendApi;
@Resource
@Lazy
private RoleApi roleApi;
/**
* 定时任务提醒保险到期提醒教练未进行离场打卡学员信息
*/
@TenantIgnore
// @Scheduled(cron = "0 06 11 * * ?")
@GetMapping("/y")
public void noClockInRemind() {
// rescueCarInfoService.noClockInRemind();
//获取当前登录用户
// Long userId = SecurityFrameworkUtils.getLoginUserId();
// 1. 查询所有保险即将到期或已到期的车辆
LocalDateTime today = LocalDateTime.now();
List<RescueCarInfo> expiringCars = rescueCarInfoService.selectExpiringInsuranceCars(today);
for (RescueCarInfo expiringCar : expiringCars) {
Long tenantId = expiringCar.getTenantId();
String message = String.format(INSURANCE_DEADLINE_REMINDER,expiringCar.getRescueCarNum());
//获取接收消息的用户
List<UserDTO> officeStaffList = roleApi.selectUserListByRoleCode(tenantId, "jiuyuan");
if (officeStaffList != null && !officeStaffList.isEmpty()) {
for (UserDTO staff : officeStaffList) {
Long userId = staff.getId();
NotifySendSingleToUserReqDTO dto = new NotifySendSingleToUserReqDTO();
dto.setUserId(userId);
dto.setSystemCode(SystemEnum.RESCUE.getCode());
dto.setTemplateCode(BaseConstants.TICKET_EMPLOY);
// 准备发送参数
Map<String, Object> templateParams = new HashMap<>();
// 发送模版内容
templateParams.put("text", message);
dto.setTemplateParams(templateParams);
// 发送消息
sendApi.sendSingleMessageToAdmin(dto, tenantId);
}
}
}
}
/**
* 查询救援车辆信息列表
@ -47,6 +125,83 @@ public class RescueCarInfoController extends BaseController {
return success(rescueCarInfoService.selectRescueCarInfoList(rescueCarInfo, page));
}
/**
* 获取车辆统计数据
*/
@GetMapping("/getStats")
public CommonResult<Map<String, Object>> getStats() {
RescueCarInfo rescueCarInfo = new RescueCarInfo();
//获取当前登录用户
Long userId = SecurityFrameworkUtils.getLoginUserId();
//所在顶级机构
AdminUserRespDTO user = adminUserApi.getUser(userId);
rescueCarInfo.setDeptId(user.getDeptId());
Page<RescueCarInfo> page = new Page<>(1, 100);
IPage<RescueCarInfo> carInfoIPage = rescueCarInfoService.selectRescueCarInfoList(rescueCarInfo, page);
// 拿到分页数据
List<RescueCarInfo> records = carInfoIPage.getRecords();
// 1. 车辆总数
long totalCars = records.size();
// 2. 根据car_category分组统计
Map<String, Long> categoryCount = records.stream()
.filter(car -> car.getCarCategory() != null && !car.getCarCategory().trim().isEmpty())
.collect(Collectors.groupingBy(
RescueCarInfo::getCarCategory,
Collectors.counting()
));
// 3. 组装返回结果
Map<String, Object> result = new HashMap<>();
result.put("totalCars", totalCars);
result.put("categoryCount", categoryCount);
/**
* 返回给前端的数据格式示例
* {
* "code": 200,
* "data": {
* "totalCars": 100,
* "categoryCount": {
* "大拖车": 20,
* "小拖车": 10,
* "皮卡": 15,
* "清障车": 25,
* "吊车": 30
* }
* },
* "msg": "操作成功"
* }
*/
/* // 2. 车辆类型数去重统计
long typeCount = records.stream()
.map(RescueCarInfo::getRescueCarType)
.filter(Objects::nonNull)
.distinct()
.count();
// 3. 品牌型号数去重统计
long brandCount = records.stream()
.map(RescueCarInfo::getRescueCarBrand)
.filter(Objects::nonNull)
.distinct()
.count();
// 4. 车牌颜色数去重统计
long colorCount = records.stream()
.map(RescueCarInfo::getCarLicenseColor)
.filter(Objects::nonNull)
.distinct()
.count();
Map<String, Long> result = new HashMap<>();
result.put("totalCars", totalCars);
result.put("typeCount", typeCount);
result.put("brandCount", brandCount);
result.put("colorCount", colorCount);*/
return CommonResult.success(result);
}
/**
* 查询救援车辆信息列表
*/

View File

@ -64,6 +64,15 @@ public class RescueChannelSourceController extends BaseController {
return success(rescueChannelSourceService.channelList());
}
/**
* 获取所有来源
*/
@GetMapping("/sourceList")
public CommonResult<List<RescueChannelSource>> sourceList() {
return success(rescueChannelSourceService.sourceList());
}
@GetMapping("/getChannelListByDispatchId")
public CommonResult<List<RescueChannelSource>> getChannelListByDispatchId(@RequestParam(value = "dispatchId", required = false) Long dispatchId) {
return success(rescueChannelSourceService.getChannelListByDispatchId(dispatchId));

View File

@ -38,6 +38,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
@ -85,6 +86,14 @@ public class RescueInfoSystem extends BaseController {
@Resource
private RoleService roleService;
/**
* 新增发票信息(根据id进行修改)
*/
@PostMapping("/updateBilled")
public CommonResult updateBilled(@RequestBody RescueOrderInfo rescueOrderInfo) {
return CommonResult.success(infoService.updateById(rescueOrderInfo));
}
/**
* 新增道路救援发起
*/
@ -149,6 +158,15 @@ public class RescueInfoSystem extends BaseController {
return success(list);
}
/**
* 根据ID查询救援信息救援订单信息详情
*/
@GetMapping("/getById")
public CommonResult<RescueInfo> getById(Long id) {
RescueInfo rescueInfo = rescueInfoService.selectRescueInfoAndOrderById(id);
return success(rescueInfo);
}
@GetMapping("/listByRevoke")
public CommonResult<IPage<?>> listByRevoke(RescueInfo rescueInfo,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,

View File

@ -8,6 +8,7 @@ import cn.iocoder.yudao.annotation.Excel;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
@ -34,6 +35,12 @@ public class RescueCarInfo extends TenantBaseDO {
@TableField(exist = false)
private String rescueCarTypeStr;
/**
* 车辆归属
*/
@Excel(name = "车辆归属")
private String rescueCarOwn;
/**
* 车辆种类
*/
@ -96,6 +103,11 @@ public class RescueCarInfo extends TenantBaseDO {
*/
@Excel(name = "车架号")
private String frameNumber;
/**
* 车辆保养里程
*/
@Excel(name = "车辆保养里程")
private BigDecimal carMaintenanceMileage;
//车辆保养时间
@JsonFormat(pattern = "yyyy-MM-dd")
private Date carKeepTime;

View File

@ -428,6 +428,30 @@ public class RescueInfo extends TenantBaseDO
@TableField(exist = false)
private Date paymentTime;
/** 开发票相关字段 */
@TableField(exist = false)
private String ifBilled;
@TableField(exist = false)
private String billedUsername;
@TableField(exist = false)
private Long billedUserid;
@TableField(exist = false)
private String billedQrcode;
@TableField(exist = false)
private String billedRemark;
/** 救援车辆归属 */
@TableField(exist = false)
private String rescueCarOwn;
/** 救援车辆品牌型号 */
@TableField(exist = false)
private String rescueCarBrand;
/** 行驶里程 */
@TableField(exist = false)
private String mileage;
/** 车龄 */
@TableField(exist = false)
private String carAge;
/**
* 调度等级
*/

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.rescue.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import cn.iocoder.yudao.annotation.Excel;
@ -38,6 +39,17 @@ public class RescueOrderInfo extends TenantBaseDO
@Excel(name = "用户姓名")
private String realName;
/** 是否开票 */
private String ifBilled;
/** 开票人名字 */
private String billedUsername;
/** 开票人Id */
private Long billedUserid;
/** 开票二维码 */
private String billedQrcode;
/** 开票备注 */
private String billedRemark;
/** 用户手机号 */
@Excel(name = "用户手机号")
private String phonenumber;

View File

@ -8,6 +8,7 @@ import cn.iocoder.yudao.annotation.Excel;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
@ -57,4 +58,18 @@ public class RescueRefuelRecord extends TenantBaseDO
private String phonenumber;
@TableField(exist = false)
private String rescueCarNum;
/* ======= 新增派生字段 ======= */
/** 距上次加油行驶公里 */
@TableField(exist = false)
private Integer distancePrevKm;
/** 每公里油耗 (L/km),保留 3 位小数 */
@TableField(exist = false)
private BigDecimal fuelEfficiencyLpkm;
/** 每公里成本 (元/km),保留 2 位小数 */
@TableField(exist = false)
private BigDecimal costPerKm;
/** 金额兜底refuelNum × price用于校验 */
// @TableField(exist = false)
// private BigDecimal costAmountCalc;
}

View File

@ -3,8 +3,10 @@ package cn.iocoder.yudao.module.rescue.mapper;
import cn.iocoder.yudao.module.rescue.domain.DriverInfo;
import cn.iocoder.yudao.module.rescue.domain.RescueCarInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -12,7 +14,7 @@ import java.util.List;
/**
* 请填写功能名称Mapper接口
*
*
* @author ruoyi
* @date 2023-07-18
*/
@ -21,7 +23,7 @@ public interface DriverInfoMapper extends BaseMapper<DriverInfo>
{
/**
* 查询请填写功能名称
*
*
* @param id 请填写功能名称主键
* @return 请填写功能名称
*/
@ -29,7 +31,7 @@ public interface DriverInfoMapper extends BaseMapper<DriverInfo>
/**
* 查询请填写功能名称列表
*
*
* @param driverInfo 请填写功能名称
* @return 请填写功能名称集合
*/
@ -37,7 +39,7 @@ public interface DriverInfoMapper extends BaseMapper<DriverInfo>
/**
* 新增请填写功能名称
*
*
* @param driverInfo 请填写功能名称
* @return 结果
*/
@ -45,7 +47,7 @@ public interface DriverInfoMapper extends BaseMapper<DriverInfo>
/**
* 修改请填写功能名称
*
*
* @param driverInfo 请填写功能名称
* @return 结果
*/
@ -53,7 +55,7 @@ public interface DriverInfoMapper extends BaseMapper<DriverInfo>
/**
* 删除请填写功能名称
*
*
* @param id 请填写功能名称主键
* @return 结果
*/
@ -61,9 +63,33 @@ public interface DriverInfoMapper extends BaseMapper<DriverInfo>
/**
* 批量删除请填写功能名称
*
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteDriverInfoByIds(Long[] ids);
/**
* 获取司机列表
* @return
*/
List<DriverInfo> listDriverInfo();
/**
* 获取车辆列表
* @return
*/
List<RescueCarInfo> listCarInfo();
/**
* 二级调度获取司机
* @return
*/
List<DriverInfo> listDriverInfoSecond(@Param("userId") Long userId);
/**
* 二级调度获取车辆
* @return
*/
List<RescueCarInfo> listCarInfoSecond(@Param("userId") Long userId);
}

View File

@ -7,7 +7,9 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@ -20,6 +22,14 @@ import java.util.Map;
@Mapper
public interface RescueCarInfoMapper extends BaseMapper<RescueCarInfo>
{
@Select("SELECT * FROM rescue_car_info WHERE car_insurance_time >= #{expiryDate} and deleted=0")
List<RescueCarInfo> selectExpiringInsuranceCars(@Param("expiryDate") LocalDateTime expiryDate);
@Select("SELECT * FROM rescue_car_info WHERE car_check_time >= #{expiryDate} and deleted=0")
List<RescueCarInfo> selectExpiringCarsCheck(@Param("expiryDate") LocalDateTime expiryDate);
/**
* 查询救援车辆信息
*

View File

@ -6,10 +6,7 @@ import cn.iocoder.yudao.module.rescue.domain.DriverInfo;
import cn.iocoder.yudao.module.rescue.domain.RescueInfo;
import cn.iocoder.yudao.module.rescue.dto.DriverInfo2Dto;
import cn.iocoder.yudao.module.rescue.dto.DriverInfoDto;
import cn.iocoder.yudao.module.rescue.vo.BuckleVO;
import cn.iocoder.yudao.module.rescue.vo.DriverInfoExportVO;
import cn.iocoder.yudao.module.rescue.vo.DriverStaffSaveVO;
import cn.iocoder.yudao.module.rescue.vo.StatisticsStaffVO;
import cn.iocoder.yudao.module.rescue.vo.*;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@ -17,6 +14,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import java.util.Date;
import java.util.List;
@ -110,4 +108,36 @@ public interface RescueInfoMapper extends BaseMapper<RescueInfo>
List<StatisticsStaffVO> driverStatistics(@Param("vo") StatisticsStaffVO statisticsStaffReqVO);
List<StatisticsStaffVO> carStatistics(@Param("vo") StatisticsStaffVO statisticsStaffReqVO);
List<StatisticsStaffVO> dispatchStatistics(@Param("vo") StatisticsStaffVO statisticsStaffReqVO);
RescueInfo selectRescueInfoAndOrderById(Long id);
List<RescueInfo> getAllRescueOrder();
IPage<RescueInfo> selectRescueStatisticsInfoList(@Param("map") RescueInfo rescueInfo, Page<RescueInfo> page);
IPage<RescueInfo> selectRescueStatisticsInfoListSecondDispatcher(@Param("map") RescueInfo rescueInfo, Page<RescueInfo> page);
/**
* 数据统计中使用
* @param rescueInfo
* @return
*/
Map<String,Object> getRescueStatisticsInfoNum(@Param("map") RescueInfo rescueInfo);
Map<String,Object> getRescueStatisticsInfoNumSecondDispatcher(@Param("map") RescueInfo rescueInfo);
List<StatisticsStaffVO> driverStatisticsSecond(@Param("vo") StatisticsStaffVO statisticsStaffReqVO);
List<StatisticsStaffVO> carStatisticsSecond(@Param("vo") StatisticsStaffVO statisticsStaffReqVO);
void updateBilled(RescueInfo rescueInfo);
List<List<RescueInfo>> rescueCarList(@Param("map") RescueInfo rescueInfo);
List<RescueCarStatRespVO> selectCarAgeAndMileage();
List<RescueInfo> getRescueCarKPI(
@Param("driverCarNum") String driverCarNum,
@Param("startTime") String startTime,
@Param("endTime") String endTime
);
}

View File

@ -1,13 +1,14 @@
package cn.iocoder.yudao.module.rescue.service;
import cn.iocoder.yudao.module.rescue.domain.DriverInfo;
import cn.iocoder.yudao.module.rescue.domain.RescueCarInfo;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 请填写功能名称Service接口
*
*
* @author ruoyi
* @date 2023-07-18
*/
@ -15,7 +16,7 @@ public interface IDriverInfoService extends IService<DriverInfo>
{
/**
* 查询请填写功能名称
*
*
* @param id 请填写功能名称主键
* @return 请填写功能名称
*/
@ -23,7 +24,7 @@ public interface IDriverInfoService extends IService<DriverInfo>
/**
* 查询请填写功能名称列表
*
*
* @param driverInfo 请填写功能名称
* @return 请填写功能名称集合
*/
@ -31,7 +32,7 @@ public interface IDriverInfoService extends IService<DriverInfo>
/**
* 新增请填写功能名称
*
*
* @param driverInfo 请填写功能名称
* @return 结果
*/
@ -39,7 +40,7 @@ public interface IDriverInfoService extends IService<DriverInfo>
/**
* 修改请填写功能名称
*
*
* @param driverInfo 请填写功能名称
* @return 结果
*/
@ -47,7 +48,7 @@ public interface IDriverInfoService extends IService<DriverInfo>
/**
* 批量删除请填写功能名称
*
*
* @param ids 需要删除的请填写功能名称主键集合
* @return 结果
*/
@ -55,7 +56,7 @@ public interface IDriverInfoService extends IService<DriverInfo>
/**
* 删除请填写功能名称信息
*
*
* @param id 请填写功能名称主键
* @return 结果
*/
@ -69,4 +70,25 @@ public interface IDriverInfoService extends IService<DriverInfo>
**/
void syncData();
/**
* 获取司机完整列表
*/
List<DriverInfo> listDriverInfo();
/**
* 获取救援车辆完整列表
*/
List<RescueCarInfo> listCarInfo();
/**
* 二级调度获取司机列表
*/
List<DriverInfo> listDriverInfoSecond();
/**
* 二级调度获取车辆列表
*/
List<RescueCarInfo> listCarInfoSecond();
}

View File

@ -4,7 +4,10 @@ import cn.iocoder.yudao.module.rescue.domain.RescueCarInfo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.ibatis.annotations.Select;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@ -16,6 +19,21 @@ import java.util.Map;
*/
public interface IRescueCarInfoService extends IService<RescueCarInfo>
{
// 查询保险到期的所有车辆
List<RescueCarInfo> selectExpiringInsuranceCars(LocalDateTime expiryDate);
// 查询年检到期的所有车辆
List<RescueCarInfo> selectExpiringCarsCheck(LocalDateTime expiryDate);
/**
* 查询救援车辆信息
*

View File

@ -50,4 +50,6 @@ public interface IRescueChannelSourceService extends IService<RescueChannelSourc
* @return 来源列表
*/
List<RescueChannelSource> getSourcesByChannelId(Integer channelId);
List<RescueChannelSource> sourceList();
}

View File

@ -62,4 +62,5 @@ public interface IRescueDriverInfoService extends IService<RescueDriverInfo>
* 根据救援工单id获取指派司机列表
*/
List<DriverInfo> listDispatchDriverByRescueId(Long rescueId);
}

View File

@ -12,6 +12,7 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -197,4 +198,21 @@ public interface IRescueInfoService extends IService<RescueInfo>
Long safeStringToLong(String str, Long defaultValue);
List<StatisticsStaffVO> statisticsAll(StatisticsStaffVO statisticsStaffReqVO);
RescueInfo selectRescueInfoAndOrderById(Long id);
List<RescueInfo> getAllRescueOrder();
List<StatisticsStaffVO> statisticsAllSecond(StatisticsStaffVO statisticsStaffReqVO);
IPage<RescueInfo> selectRescueStatisticsInfoListByAdmin(RescueInfo rescueInfo, Page<RescueInfo> page);
IPage<RescueInfo> selectRescueStatisticsInfoListBySecondDispatcher(RescueInfo rescueInfo, Page<RescueInfo> page);
Map<String, Object> getRescueStatisticsInfoNum(RescueInfo rescueInfo);
Map<String, Object> getRescueStatisticsInfoNumSecondDispatcher(RescueInfo rescueInfo);
List<List<RescueInfo>> rescueCarList(RescueInfo rescueInfo);
List<RescueCarStatRespVO> getRescueCarAgeAndMileage();
List<RescueInfo> getRescueCarKPI(String driverCarNum,String startTime,String endTime);
}

View File

@ -3,7 +3,9 @@ package cn.iocoder.yudao.module.rescue.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.common.CommonErrorCodeConstants;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.rescue.domain.DriverInfo;
import cn.iocoder.yudao.module.rescue.domain.RescueCarInfo;
import cn.iocoder.yudao.module.rescue.service.IDriverInfoService;
import cn.iocoder.yudao.module.staff.entity.CompanyStaff;
import cn.iocoder.yudao.module.staff.service.CompanyStaffService;
@ -23,6 +25,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@ -186,4 +189,41 @@ public class DriverInfoServiceImpl extends ServiceImpl<DriverInfoMapper, DriverI
}
staffService.save(staff);
}
/**
* 获取司机完整列表
*/
@Override
public List<DriverInfo> listDriverInfo() {
return baseMapper.listDriverInfo();
}
/**
* 获取车辆完整列表
*/
@Override
public List<RescueCarInfo> listCarInfo() {
return baseMapper.listCarInfo();
}
/**
* 二级调度获取司机
* @return
*/
@Override
public List<DriverInfo> listDriverInfoSecond() {
Long userId = SecurityFrameworkUtils.getLoginUserId();
return baseMapper.listDriverInfoSecond(userId);
}
/**
* 二级调度获取车辆
* @return
*/
@Override
public List<RescueCarInfo> listCarInfoSecond() {
Long userId = SecurityFrameworkUtils.getLoginUserId();
return baseMapper.listCarInfoSecond(userId);
}
}

View File

@ -3,12 +3,15 @@ package cn.iocoder.yudao.module.rescue.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.custom.entity.CarMain;
import cn.iocoder.yudao.module.custom.service.CarMainService;
import cn.iocoder.yudao.module.rescue.domain.RescueCarInfo;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.module.rescue.mapper.RescueCarInfoMapper;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
import cn.iocoder.yudao.module.rescue.service.IRescueCarInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -16,7 +19,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;
@ -31,6 +36,16 @@ public class RescueCarInfoServiceImpl extends ServiceImpl<RescueCarInfoMapper, R
@Autowired
private DictDataApi dictDataService;
@Override
public List<RescueCarInfo> selectExpiringInsuranceCars(LocalDateTime expiryDate) {
return baseMapper.selectExpiringInsuranceCars(expiryDate);
}
@Override
public List<RescueCarInfo> selectExpiringCarsCheck(LocalDateTime expiryDate) {
return baseMapper.selectExpiringCarsCheck(expiryDate);
}
/**
* 查询救援车辆信息
*

View File

@ -74,6 +74,15 @@ public class RescueChannelSourceServiceImpl extends ServiceImpl<RescueChannelSou
return this.list(queryWrapper);
}
@Override
public List<RescueChannelSource> sourceList() {
return lambdaQuery()
.eq(RescueChannelSource::getType, 1)
.eq(RescueChannelSource::getDeleted, false)
.orderByAsc(RescueChannelSource::getCreateTime)
.list();
}
@Override
public List<RescueChannelSource> channelList() {
LambdaQueryWrapper<RescueChannelSource> queryWrapper = new LambdaQueryWrapper<>();

View File

@ -1004,4 +1004,5 @@ public class RescueDriverInfoServiceImpl extends ServiceImpl<RescueDriverInfoMap
}
}

View File

@ -851,6 +851,10 @@ public class RescueInfoServiceImpl extends ServiceImpl<RescueInfoMapper, RescueI
public JSONObject rescueInfoDetailByDispatch(Long rescueId) {
JSONObject res = new JSONObject();
RescueInfo rescueInfo = this.getById(rescueId);
String rescueStatusStr = dictDataService.getDictDataLabel("jy_status", rescueInfo.getRescueStatus());
rescueInfo.setRescueStatusStr(rescueStatusStr);
LambdaQueryWrapper<RescueOrderInfo> queryWrapperOrder = new LambdaQueryWrapper<>();
queryWrapperOrder.eq(RescueOrderInfo::getRescueInfoId, rescueId).last("limit 1");
RescueOrderInfo rescueOrderInfo = rescueOrderInfoService.getOne(queryWrapperOrder);
@ -861,6 +865,10 @@ public class RescueInfoServiceImpl extends ServiceImpl<RescueInfoMapper, RescueI
} else {
rescueInfo.setOrderStatus("0");
}
String orderStatusStr = dictDataService.getDictDataLabel("jy_order_status", rescueInfo.getOrderStatus());
rescueInfo.setOrderStatusStr(orderStatusStr);
res.put("rescueInfo", rescueInfo);
//救援详细信息
LambdaQueryWrapper<RescueInfoDispatchDetail> queryWrapper3 = new LambdaQueryWrapper<>();
@ -2260,9 +2268,15 @@ public class RescueInfoServiceImpl extends ServiceImpl<RescueInfoMapper, RescueI
moneyManagement.setUpMoney(tempSetMoney - tempCheckpointMoney);
moneyManagement.setEmptyingDistance(info.getEmptyNum());
String carType = "3";
if (StringUtils.isNotEmpty(info.getDriverCarNum())) {
/*if (StringUtils.isNotEmpty(info.getDriverCarNum())) {
RescueCarInfo carInfo = carInfoService.selectRescueCarInfoByNum(info.getDriverCarNum());
carType = carInfo.getRescueCarType();
}*/
if (StringUtils.isNotEmpty(info.getDriverCarNum())) {
RescueCarInfo carInfo = carInfoService.selectRescueCarInfoByNum(info.getDriverCarNum());
if (carInfo != null && StringUtils.isNotEmpty(carInfo.getRescueCarType())) {
carType = carInfo.getRescueCarType();
}
}
if (carType.equals("1")) {
@ -2800,6 +2814,111 @@ public class RescueInfoServiceImpl extends ServiceImpl<RescueInfoMapper, RescueI
return statisticsStaffVOS;
}
@Override
public List<StatisticsStaffVO> statisticsAllSecond(StatisticsStaffVO statisticsStaffReqVO) {
List<StatisticsStaffVO> statisticsStaffVOS = new ArrayList<>();
if (statisticsStaffReqVO == null || statisticsStaffReqVO.getQueryType() == null) {
return statisticsStaffVOS;
}
Long userId = SecurityFrameworkUtils.getLoginUserId();
statisticsStaffReqVO.setSecondUserId(userId);
String queryType = statisticsStaffReqVO.getQueryType();
switch (queryType) {
case "driver":
statisticsStaffVOS.addAll(this.driverStatisticsSecond(statisticsStaffReqVO));
break;
case "car":
statisticsStaffVOS.addAll(this.carStatisticsSecond(statisticsStaffReqVO));
break;
default:
break;
}
return statisticsStaffVOS;
}
@Override
public IPage<RescueInfo> selectRescueStatisticsInfoListByAdmin(RescueInfo rescueInfo, Page<RescueInfo> page) {
LoginUser user = getLoginUser();
AdminUserRespDTO adminUser = userService.getUser(user.getId());
rescueInfo.setDeptList(buildDeptList(adminUser.getDeptId()));
String startTime = "";
String endTime = "";
if ("more".equals(rescueInfo.getTimeType())) {
if (org.apache.commons.lang3.StringUtils.isNotEmpty(rescueInfo.getStartTimeStr())) {
startTime = rescueInfo.getStartTimeStr() + " 00:00:01";
}
if (org.apache.commons.lang3.StringUtils.isNotEmpty(rescueInfo.getEndTimeStr())) {
endTime = rescueInfo.getEndTimeStr() + " 23:59:59";
}
} else if ("month".equals(rescueInfo.getTimeType())) {
//当月
startTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd") + " 00:00:01";
endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd") + " 23:59:59";
} else if ("day".equals(rescueInfo.getTimeType())) {
//当天
startTime = DateUtil.formatDate(DateUtil.date()) + " 00:00:01";
endTime = DateUtil.formatDate(DateUtil.date()) + " 23:59:59";
}
rescueInfo.setStartTimeStr(startTime);
rescueInfo.setEndTimeStr(endTime);
IPage<RescueInfo> rescueInfos = baseMapper.selectRescueStatisticsInfoList(rescueInfo, page);
processRescueInfoRecords(rescueInfos, user, false);
return rescueInfos;
}
@Override
public IPage<RescueInfo> selectRescueStatisticsInfoListBySecondDispatcher(RescueInfo rescueInfo, Page<RescueInfo> page) {
LoginUser user = getLoginUser();
AdminUserRespDTO adminUser = userService.getUser(user.getId());
rescueInfo.setUserId(adminUser.getId());
rescueInfo.setDeptList(buildDeptList(adminUser.getDeptId()));
String startTime = "";
String endTime = "";
if ("more".equals(rescueInfo.getTimeType())) {
if (org.apache.commons.lang3.StringUtils.isNotEmpty(rescueInfo.getStartTimeStr())) {
startTime = rescueInfo.getStartTimeStr() + " 00:00:01";
}
if (org.apache.commons.lang3.StringUtils.isNotEmpty(rescueInfo.getEndTimeStr())) {
endTime = rescueInfo.getEndTimeStr() + " 23:59:59";
}
} else if ("month".equals(rescueInfo.getTimeType())) {
//当月
startTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd") + " 00:00:01";
endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd") + " 23:59:59";
} else if ("day".equals(rescueInfo.getTimeType())) {
//当天
startTime = DateUtil.formatDate(DateUtil.date()) + " 00:00:01";
endTime = DateUtil.formatDate(DateUtil.date()) + " 23:59:59";
}
rescueInfo.setStartTimeStr(startTime);
rescueInfo.setEndTimeStr(endTime);
IPage<RescueInfo> rescueInfos = baseMapper.selectRescueStatisticsInfoListSecondDispatcher(rescueInfo, page);
processRescueInfoRecords(rescueInfos, user, false);
return rescueInfos;
}
@Override
public RescueInfo selectRescueInfoAndOrderById(Long id) {
return baseMapper.selectRescueInfoAndOrderById(id);
}
@Override
public List<RescueInfo> getAllRescueOrder() {
List<RescueInfo> allRescueOrder = baseMapper.getAllRescueOrder();
for (RescueInfo rescueInfo : allRescueOrder) {
String dljy_type = dictDataService.getDictDataLabel("dljy_type", rescueInfo.getRescueType());
rescueInfo.setRescueTypeStr(dljy_type);
}
return allRescueOrder;
}
public List<StatisticsStaffVO> driverStatistics(StatisticsStaffVO statisticsStaffReqVO) {
return baseMapper.driverStatistics(statisticsStaffReqVO);
}
@ -2819,4 +2938,94 @@ public class RescueInfoServiceImpl extends ServiceImpl<RescueInfoMapper, RescueI
!info.getRescueTime().after(endTime))
.collect(Collectors.toList());
}
@Override
public Map<String, Object> getRescueStatisticsInfoNum(RescueInfo rescueInfo) {
LoginUser user = getLoginUser();
AdminUserRespDTO adminUser = userService.getUser(user.getId());
List<DeptRespDTO> childDeptList = deptService.getChildDeptList(adminUser.getDeptId());
List<Long> deptList = childDeptList.stream().map(DeptRespDTO::getId).collect(Collectors.toList());
deptList.add(adminUser.getDeptId());
rescueInfo.setDeptList(deptList);
String startTime = "";
String endTime = "";
if ("more".equals(rescueInfo.getTimeType())) {
if (org.apache.commons.lang3.StringUtils.isNotEmpty(rescueInfo.getStartTimeStr())) {
startTime = rescueInfo.getStartTimeStr() + " 00:00:01";
}
if (org.apache.commons.lang3.StringUtils.isNotEmpty(rescueInfo.getEndTimeStr())) {
endTime = rescueInfo.getEndTimeStr() + " 23:59:59";
}
} else if ("month".equals(rescueInfo.getTimeType())) {
//当月
startTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd") + " 00:00:01";
endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd") + " 23:59:59";
} else if ("day".equals(rescueInfo.getTimeType())) {
//当天
startTime = DateUtil.formatDate(DateUtil.date()) + " 00:00:01";
endTime = DateUtil.formatDate(DateUtil.date()) + " 23:59:59";
}
rescueInfo.setStartTimeStr(startTime);
rescueInfo.setEndTimeStr(endTime);
Map<String, Object> res = baseMapper.getRescueStatisticsInfoNum(rescueInfo);
return res;
}
@Override
public Map<String, Object> getRescueStatisticsInfoNumSecondDispatcher(RescueInfo rescueInfo) {
LoginUser user = getLoginUser();
AdminUserRespDTO adminUser = userService.getUser(user.getId());
List<DeptRespDTO> childDeptList = deptService.getChildDeptList(adminUser.getDeptId());
List<Long> deptList = childDeptList.stream().map(DeptRespDTO::getId).collect(Collectors.toList());
deptList.add(adminUser.getDeptId());
rescueInfo.setDeptList(deptList);
rescueInfo.setUserId(adminUser.getId());
String startTime = "";
String endTime = "";
if ("more".equals(rescueInfo.getTimeType())) {
if (org.apache.commons.lang3.StringUtils.isNotEmpty(rescueInfo.getStartTimeStr())) {
startTime = rescueInfo.getStartTimeStr() + " 00:00:01";
}
if (org.apache.commons.lang3.StringUtils.isNotEmpty(rescueInfo.getEndTimeStr())) {
endTime = rescueInfo.getEndTimeStr() + " 23:59:59";
}
} else if ("month".equals(rescueInfo.getTimeType())) {
//当月
startTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd") + " 00:00:01";
endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd") + " 23:59:59";
} else if ("day".equals(rescueInfo.getTimeType())) {
//当天
startTime = DateUtil.formatDate(DateUtil.date()) + " 00:00:01";
endTime = DateUtil.formatDate(DateUtil.date()) + " 23:59:59";
}
rescueInfo.setStartTimeStr(startTime);
rescueInfo.setEndTimeStr(endTime);
Map<String, Object> res = baseMapper.getRescueStatisticsInfoNumSecondDispatcher(rescueInfo);
return res;
}
@Override
public List<List<RescueInfo>> rescueCarList(RescueInfo rescueInfo) {
return baseMapper.rescueCarList(rescueInfo);
}
@Override
public List<RescueCarStatRespVO> getRescueCarAgeAndMileage() {
return baseMapper.selectCarAgeAndMileage();
}
@Override
public List<RescueInfo> getRescueCarKPI(String driverCarNum,String startTime,String endTime) {
return baseMapper.getRescueCarKPI(driverCarNum,startTime,endTime);
}
public List<StatisticsStaffVO> driverStatisticsSecond(StatisticsStaffVO statisticsStaffReqVO) {
return baseMapper.driverStatisticsSecond(statisticsStaffReqVO);
}
public List<StatisticsStaffVO> carStatisticsSecond(StatisticsStaffVO statisticsStaffReqVO) {
return baseMapper.carStatisticsSecond(statisticsStaffReqVO);
}
}

View File

@ -0,0 +1,95 @@
package cn.iocoder.yudao.module.rescue.task;
import cn.iocoder.yudao.common.BaseConstants;
import cn.iocoder.yudao.common.SystemEnum;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.rescue.domain.RescueCarInfo;
import cn.iocoder.yudao.module.rescue.service.IRescueCarInfoService;
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.module.constant.MessageConstants.CAR_CHECK_DEADLINE_REMINDER;
import static cn.iocoder.yudao.module.constant.MessageConstants.INSURANCE_DEADLINE_REMINDER;
@Component
@Slf4j
public class RescueDeadlineReminder {
@Autowired
private NotifyMessageSendApi sendApi;
@Autowired
private AdminUserApi adminUserApi;
@Autowired
private IRescueCarInfoService rescueCarInfoService;
/**
* 保险到期提醒
*/
// @Scheduled(cron = "0 0 1 * * ?") //每天凌晨一点检测
@Scheduled(cron = "0 23 10 * * ?")
public void insuranceReminder() {
//获取当前登录用户
Long userId = SecurityFrameworkUtils.getLoginUserId();
// 1. 查询所有保险即将到期或已到期的车辆
LocalDateTime today = LocalDateTime.now();
List<RescueCarInfo> expiringCars = rescueCarInfoService.selectExpiringInsuranceCars(today);
for (RescueCarInfo expiringCar : expiringCars) {
Long tenantId = expiringCar.getTenantId();
String message = String.format(INSURANCE_DEADLINE_REMINDER,expiringCar.getRescueCarNum());
NotifySendSingleToUserReqDTO dto = new NotifySendSingleToUserReqDTO();
dto.setUserId(userId);
dto.setSystemCode(SystemEnum.RESCUE.getCode());
dto.setTemplateCode(BaseConstants.TICKET_EMPLOY);
// 准备发送参数
Map<String, Object> templateParams = new HashMap<>();
// 发送模版内容
templateParams.put("text", message);
dto.setTemplateParams(templateParams);
// 发送消息
sendApi.sendSingleMessageToAdmin(dto, tenantId);
}
}
/**
* 车辆年检到期提醒
*/
@Scheduled(cron = "0 0 1 * * ?") //每天凌晨一点检测
public void carCheckReminder() {
//获取当前登录用户
Long userId = SecurityFrameworkUtils.getLoginUserId();
// 1. 查询所有保险即将到期或已到期的车辆
LocalDateTime today = LocalDateTime.now();
List<RescueCarInfo> expiringCars = rescueCarInfoService.selectExpiringCarsCheck(today);
for (RescueCarInfo expiringCar : expiringCars) {
Long tenantId = expiringCar.getTenantId();
String message = CAR_CHECK_DEADLINE_REMINDER;
NotifySendSingleToUserReqDTO dto = new NotifySendSingleToUserReqDTO();
dto.setUserId(userId);
dto.setSystemCode(SystemEnum.RESCUE.getCode());
dto.setTemplateCode(BaseConstants.TICKET_EMPLOY);
// 准备发送参数
Map<String, Object> templateParams = new HashMap<>();
// 发送模版内容
templateParams.put("text", message);
dto.setTemplateParams(templateParams);
// 发送消息
sendApi.sendSingleMessageToAdmin(dto, tenantId);
}
}
}

View File

@ -0,0 +1,11 @@
package cn.iocoder.yudao.module.rescue.vo;
import lombok.Data;
@Data
public class RescueCarStatRespVO {
private String rescueCarNum; // 车牌号 / 编号
private Integer carAge; // 车龄整数年
private Integer mileage; // 累计里程整数 km
}

View File

@ -96,4 +96,44 @@
#{id}
</foreach>
</delete>
<select id="listDriverInfo" resultType="cn.iocoder.yudao.module.rescue.domain.DriverInfo">
SELECT su.id AS userId,
su.nickname AS nickName,
di.id
FROM driver_info di
INNER JOIN system_users su ON di.user_id = su.id
AND su.deleted = '0'
WHERE 1 = 1
AND di.deleted = '0'
AND di.staff_type = 'jysj'
order by di.create_time desc
</select>
<select id="listCarInfo" resultType="cn.iocoder.yudao.module.rescue.domain.RescueCarInfo">
SELECT id, rescue_car_num, car_category
FROM `rescue_car_info`
WHERE deleted = 0
order by create_time desc
</select>
<select id="listDriverInfoSecond" resultType="cn.iocoder.yudao.module.rescue.domain.DriverInfo">
SELECT su.id AS userId,
su.nickname AS nickName,
di.id
FROM driver_info di
INNER JOIN system_users su ON di.user_id = su.id AND su.deleted = 0
WHERE FIND_IN_SET(#{userId}, di.second_dispatcher_id) > 0
AND di.deleted = 0;
</select>
<select id="listCarInfoSecond" resultType="cn.iocoder.yudao.module.rescue.domain.RescueCarInfo">
SELECT DISTINCT
rci.*
FROM rescue_car_info rci
INNER JOIN rescue_driver_car_relation rdcr ON rci.id = rdcr.car_id AND rdcr.deleted = 0
INNER JOIN driver_info di ON rdcr.driver_id = di.id AND di.deleted = 0
WHERE FIND_IN_SET(#{userId}, di.second_dispatcher_id) > 0
AND rci.deleted = 0
</select>
</mapper>

View File

@ -26,6 +26,7 @@
<sql id="selectRescueCarInfoVo">
SELECT rci.id,
rci.rescue_car_type,
rci.rescue_car_own,
rci.rescue_car_num,
rci.rescue_car_brand,
rci.car_own,
@ -35,7 +36,7 @@
rci.car_license_color,
rci.car_use_nature,
rci.frame_number,
rci.car_keep_time,
rci.car_maintenance_mileage,
rci.car_insurance_time,
rci.car_check_time,
rci.possessor_id,
@ -50,6 +51,9 @@
<if test="map.rescueCarType != null and map.rescueCarType != ''">and rci.rescue_car_type =
#{map.rescueCarType}
</if>
<if test="map.rescueCarOwn != null and map.rescueCarOwn != ''">and rci.rescue_car_own =
#{map.rescueCarOwn}
</if>
<if test="map.rescueCarNum != null and map.rescueCarNum != ''">and rci.rescue_car_num = #{map.rescueCarNum}
</if>
<if test="map.rescueCarBrand != null and map.rescueCarBrand != ''">and rci.rescue_car_brand =
@ -120,6 +124,7 @@
update rescue_car_info
<trim prefix="SET" suffixOverrides=",">
<if test="rescueCarType != null">rescue_car_type = #{rescueCarType},</if>
<if test="rescueCarOwn != null">rescue_car_own = #{rescueCarOwn},</if>
<if test="rescueCarNum != null">rescue_car_num = #{rescueCarNum},</if>
<if test="rescueCarBrand != null">rescue_car_brand = #{rescueCarBrand},</if>
<if test="carOwn != null">car_own = #{carOwn},</if>
@ -129,7 +134,7 @@
<if test="carLicenseColor != null">car_license_color = #{carLicenseColor},</if>
<if test="carUseNature != null">car_use_nature = #{carUseNature},</if>
<if test="frameNumber != null">frame_number = #{frameNumber},</if>
<if test="carKeepTime != null">car_keep_time = #{carKeepTime},</if>
<if test="carMaintenanceMileage != null">car_maintenance_mileage = #{carMaintenanceMileage},</if>
<if test="carInsuranceTime != null">car_insurance_time = #{carInsuranceTime},</if>
<if test="carCheckTime != null">car_check_time = #{carCheckTime},</if>
<if test="possessorId != null">possessor_id = #{possessorId},</if>

View File

@ -232,7 +232,7 @@
order by ri.create_time desc
</select>
<select id="selectRescueListSystem2" resultType="cn.iocoder.yudao.module.rescue.domain.RescueInfo">
<select id="selectRescueInfoAndOrderById" resultType="cn.iocoder.yudao.module.rescue.domain.RescueInfo">
SELECT ri.*,
roi.order_status,
roi.set_money,
@ -249,10 +249,42 @@
roi.confirm_payment_person_remark
FROM rescue_info ri
left join rescue_order_info roi on roi.rescue_info_id = ri.id
where ri.deleted = '0' AND ri.is_revoke = '0' and ri.id = #{id}
order by ri.create_time desc
</select>
<select id="selectRescueListSystem2" resultType="cn.iocoder.yudao.module.rescue.domain.RescueInfo">
SELECT ri.*,
roi.order_status,
roi.set_money,
roi.id as rescueOrderId,
roi.pay_type,
roi.pay_money,
roi.pay_time,
roi.order_signing_person_name,
roi.order_signing_charge_name,
roi.order_signing_remark,
roi.if_confirm_pay,
roi.confirm_payment_person_name,
roi.confirm_payment_time,
roi.confirm_payment_person_remark,
roi.if_billed,
roi.billed_userid,
roi.billed_username ,
roi.billed_qrcode,
roi.billed_remark
FROM rescue_info ri
left join rescue_order_info roi on roi.rescue_info_id = ri.id
where ri.deleted = '0' AND ri.is_revoke = '0'
<if test="map.orderStatus != null and map.orderStatus != ''">
and roi.order_status = #{map.orderStatus}
</if>
<if test="map.channel != null and map.channel != ''">
and ri.channel = #{map.channel}
</if>
<if test="map.source != null and map.source != ''">
and ri.source = #{map.source}
</if>
<if test="map.rescueStatus != null and map.rescueStatus != ''">
and if(#{map.rescueStatus} = 0, ri.rescue_status not in(6,8,9), ri.rescue_status = #{map.rescueStatus})
</if>
@ -742,6 +774,8 @@
di.create_time DESC;
</select>
<select id="driverInMap2" resultType="java.util.Map">
SELECT IFNULL(sum(di.driver_status = '1'), 0) as kxNum,
IFNULL(sum(di.driver_status = '2'), 0) as ztNum,
@ -821,6 +855,7 @@
IFNULL(sum(ri.rescue_status <![CDATA[>=]]> '5'), 0) as ywcNum,
IFNULL(sum(ri.is_wei_xiu = '1'), 0) as zwxNum,
IFNULL(count(ri.id), 0) as yjdNum,
IFNULL(sum(roi.set_money), 0) as yingskNum,
IFNULL(sum(CASE WHEN roi.if_confirm_pay = '1' THEN roi.pay_money ELSE 0 END), 0) as yiskNum,
IFNULL(sum(CASE WHEN roi.if_confirm_pay = '0' THEN roi.set_money ELSE 0 END), 0) as dskNum
FROM rescue_info ri
@ -1034,6 +1069,16 @@
<update id="revokeRescueInfo">
update rescue_info set is_revoke = 1,revoke_user_id = #{userId},revoke_user_name = #{userName}, revoke_time = #{time} where id = #{id}
</update>
<update id="updateBilled">
update rescue_order_info
<if test="billed != null">
set billed_qrcode = #{billed_qrcode}
</if>
<if test="billed == null">
set billed_remark = #{billed_remark}
</if>
where rescue_info_id = #{id}
</update>
<select id="driverStatistics" parameterType="cn.iocoder.yudao.module.rescue.vo.StatisticsStaffVO"
@ -1042,41 +1087,56 @@
su.id AS userId,
su.avatar,
ri.driver_name,
ri.driver_id,
di.id AS driver_id,
COUNT(ri.id) AS rescueNum,
SUM(ri.end_scale - ri.start_scale) AS mileage,
SUM(roi.set_money) AS money
FROM rescue_info ri
INNER JOIN driver_info di ON ri.driver_id = di.id AND di.deleted = 0
COALESCE(SUM(
CASE
WHEN ri.end_scale IS NOT NULL
AND ri.start_scale IS NOT NULL
AND ri.end_scale > ri.start_scale
THEN ri.end_scale - ri.start_scale
ELSE 0
END
), 0) AS mileage,
COALESCE(SUM(roi.set_money), 0) AS money
FROM driver_info di
INNER JOIN system_users su ON di.user_id = su.id AND su.deleted = 0
INNER JOIN rescue_order_info roi ON roi.rescue_info_id = ri.id AND roi.deleted = 0
WHERE ri.deleted = 0
AND ri.driver_name IS NOT NULL
LEFT JOIN rescue_info ri ON di.id = ri.driver_id AND ri.deleted = 0
LEFT JOIN rescue_order_info roi ON roi.rescue_info_id = ri.id AND roi.deleted = 0
WHERE di.deleted = 0
AND ri.driver_id IS NOT NULL
AND ri.driver_name IS NOT NULL
GROUP BY
su.id,
su.avatar,
ri.driver_name,
ri.driver_id
di.id
ORDER BY rescueNum DESC
</select>
<select id="carStatistics" parameterType="cn.iocoder.yudao.module.rescue.vo.StatisticsStaffVO"
resultType="cn.iocoder.yudao.module.rescue.vo.StatisticsStaffVO">
SELECT
ri.driver_car_num,
COUNT( ri.id ) AS rescueNum,
SUM( ri.end_scale - ri.start_scale ) AS mileage,
SUM( roi.set_money ) AS money
rci.rescue_car_num AS driver_car_num,
COUNT(ri.id) AS rescueNum,
COALESCE(SUM(
CASE
WHEN ri.end_scale IS NOT NULL
AND ri.start_scale IS NOT NULL
AND ri.end_scale > ri.start_scale
THEN ri.end_scale - ri.start_scale
ELSE 0
END
), 0) AS mileage,
COALESCE(SUM(roi.set_money), 0) AS money
FROM
rescue_info ri
INNER JOIN rescue_car_info rci ON rci.rescue_car_num = ri.driver_car_num
AND rci.deleted = 0
INNER JOIN rescue_order_info roi ON roi.rescue_info_id = ri.id
AND roi.deleted = 0
rescue_car_info rci
LEFT JOIN rescue_info ri ON rci.rescue_car_num = ri.driver_car_num AND ri.deleted = 0
LEFT JOIN rescue_order_info roi ON roi.rescue_info_id = ri.id AND roi.deleted = 0
WHERE
ri.deleted = 0
rci.deleted = 0
GROUP BY
ri.driver_car_num
rci.rescue_car_num
ORDER BY
rescueNum DESC
</select>
@ -1102,5 +1162,533 @@
ORDER BY
createRescueNum DESC;
</select>
<select id="getAllRescueOrder" resultType="cn.iocoder.yudao.module.rescue.domain.RescueInfo">
SELECT ri.*,
roi.order_status,
roi.set_money,
roi.id AS orderId,
roi.order_signing_person_id AS orderSigningPersonId,
roi.order_signing_person_name AS orderSigningPersonName,
roi.order_signing_charge_id AS orderSigningChargeId,
roi.order_signing_charge_name AS orderSigningChargeName,
roi.validation_real_name AS orderSigningRealName,
roi.payment_name AS paymentName,
roi.payment_time AS paymentTime,
roi.order_signing_remark AS orderSigningRemark
FROM rescue_info ri
left join rescue_order_info roi on roi.rescue_info_id = ri.id and roi.deleted = '0'
where ri.deleted = '0' AND ri.is_revoke = '0' and ri.rescue_status = 2
ORDER BY
rescue_time DESC;
</select>
<select id="selectRescueStatisticsInfoList" parameterType="cn.iocoder.yudao.module.rescue.domain.RescueInfo"
resultType="cn.iocoder.yudao.module.rescue.domain.RescueInfo">
SELECT ri.*,
roi.order_status,
roi.set_money,
roi.id AS orderId,
roi.order_signing_person_id AS orderSigningPersonId,
roi.order_signing_person_name AS orderSigningPersonName,
roi.order_signing_charge_id AS orderSigningChargeId,
roi.order_signing_charge_name AS orderSigningChargeName,
roi.validation_real_name AS orderSigningRealName,
roi.payment_name AS paymentName,
roi.payment_time AS paymentTime,
roi.order_signing_remark AS orderSigningRemark
FROM rescue_info ri
left join rescue_order_info roi on roi.rescue_info_id = ri.id and roi.deleted = '0'
<where>
1 = 1
and ri.deleted = '0' AND ri.is_revoke = '0'
<if test="map.connectionName!=null and map.connectionName!='' ">
and (ri.connection_name like concat('%', #{map.connectionName}, '%')
or ri.car_owner like concat('%', #{map.connectionName}, '%'))
</if>
<if test="map.connectionPhone!=null and map.connectionPhone!='' ">
and (ri.connection_phone like concat('%', #{map.connectionPhone}, '%')
or ri.car_owner_phone like concat('%', #{map.connectionPhone}, '%'))
</if>
<if test="map.driverCarNum != null and map.driverCarNum != '' ">
and ri.driver_car_num = #{map.driverCarNum}
</if>
<if test="map.faultType != null and map.faultType != '' ">
and ri.fault_type = #{map.faultType}
</if>
<if test="map.licenseNum != null and map.licenseNum != '' ">
and ri.license_num = #{map.licenseNum}
</if>
<if test="map.phenomenon != null and map.phenomenon != '' ">
and ri.phenomenon = #{map.phenomenon}
</if>
<if test="map.rescueStatus != null and map.rescueStatus != '' ">
and ri.rescue_status = #{map.rescueStatus}
</if>
<if test="map.rescueType != null and map.rescueType != '' ">
and ri.rescue_type = #{map.rescueType}
</if>
<if test="map.rescuePosition!=null and map.rescuePosition!='' ">
and ri.rescue_position like concat('%', #{map.rescuePosition}, '%')
</if>
<if test="map.driverId != null">
and ri.driver_id = #{map.driverId}
</if>
<if test="map.secondDispatchId != null">
and ri.second_dispatch_id = #{map.secondDispatchId}
</if>
<if test="map.startTimeStr!=null and map.startTimeStr!='' ">
AND ri.rescue_time &gt;= #{map.startTimeStr}
</if>
<if test="map.endTimeStr!=null and map.endTimeStr!='' ">
AND ri.rescue_time &lt;= #{map.endTimeStr}
</if>
</where>
order by ri.create_time desc
</select>
<select id="selectRescueStatisticsInfoListSecondDispatcher" parameterType="cn.iocoder.yudao.module.rescue.domain.RescueInfo"
resultType="cn.iocoder.yudao.module.rescue.domain.RescueInfo">
SELECT ri.*,
roi.order_status,
roi.set_money,
roi.id AS orderId,
roi.order_signing_person_id AS orderSigningPersonId,
roi.order_signing_person_name AS orderSigningPersonName,
roi.order_signing_charge_id AS orderSigningChargeId,
roi.order_signing_charge_name AS orderSigningChargeName,
roi.validation_real_name AS orderSigningRealName,
roi.payment_name AS paymentName,
roi.payment_time AS paymentTime,
roi.order_signing_remark AS orderSigningRemark
FROM rescue_info ri
left join rescue_order_info roi on roi.rescue_info_id = ri.id and roi.deleted = '0'
<where>
1 = 1
and ri.deleted = '0' AND ri.is_revoke = '0'
and ri.second_dispatch_id = #{map.userId}
<if test="map.connectionName!=null and map.connectionName!='' ">
and (ri.connection_name like concat('%', #{map.connectionName}, '%')
or ri.car_owner like concat('%', #{map.connectionName}, '%'))
</if>
<if test="map.connectionPhone!=null and map.connectionPhone!='' ">
and (ri.connection_phone like concat('%', #{map.connectionPhone}, '%')
or ri.car_owner_phone like concat('%', #{map.connectionPhone}, '%'))
</if>
<if test="map.driverCarNum != null and map.driverCarNum != '' ">
and ri.driver_car_num = #{map.driverCarNum}
</if>
<if test="map.faultType != null and map.faultType != '' ">
and ri.fault_type = #{map.faultType}
</if>
<if test="map.licenseNum != null and map.licenseNum != '' ">
and ri.license_num = #{map.licenseNum}
</if>
<if test="map.phenomenon != null and map.phenomenon != '' ">
and ri.phenomenon = #{map.phenomenon}
</if>
<if test="map.rescueStatus != null and map.rescueStatus != '' ">
and ri.rescue_status = #{map.rescueStatus}
</if>
<if test="map.rescueType != null and map.rescueType != '' ">
and ri.rescue_type = #{map.rescueType}
</if>
<if test="map.rescuePosition!=null and map.rescuePosition!='' ">
and ri.rescue_position like concat('%', #{map.rescuePosition}, '%')
</if>
<if test="map.driverId != null">
and ri.driver_id = #{map.driverId}
</if>
<if test="map.secondDispatchId != null">
and ri.second_dispatch_id = #{map.secondDispatchId}
</if>
<if test="map.startTimeStr!=null and map.startTimeStr!='' ">
AND ri.rescue_time &gt;= #{map.startTimeStr}
</if>
<if test="map.endTimeStr!=null and map.endTimeStr!='' ">
AND ri.rescue_time &lt;= #{map.endTimeStr}
</if>
</where>
order by ri.create_time desc
</select>
<select id="getRescueStatisticsInfoNum" resultType="java.util.Map" parameterType="cn.iocoder.yudao.module.rescue.domain.RescueInfo">
SELECT
IFNULL(sum(ri.rescue_status = '3' or ri.rescue_status = '4'), 0) as jyzNum,
IFNULL(sum(roi.order_status = '1'), 0) as dzfNum,
IFNULL(sum(ri.rescue_status = '6'), 0) as dqcNum,
IFNULL(sum(ri.rescue_status <![CDATA[>=]]> '5'), 0) as ywcNum,
IFNULL(sum(ri.is_wei_xiu = '1'), 0) as zwxNum,
IFNULL(count(ri.id), 0) as yjdNum,
IFNULL(sum(roi.set_money), 0) as yingskNum,
IFNULL(sum(CASE WHEN roi.if_confirm_pay = '1' THEN roi.pay_money ELSE 0 END), 0) as yiskNum,
IFNULL(sum(CASE WHEN roi.if_confirm_pay = '0' THEN roi.set_money ELSE 0 END), 0) as dskNum
FROM rescue_info ri
left join rescue_order_info roi on roi.rescue_info_id = ri.id and roi.deleted = '0'
<where>
1 = 1
and ri.deleted = '0' AND ri.is_revoke = '0'
<if test="map.connectionName!=null and map.connectionName!='' ">
and (ri.connection_name like concat('%', #{map.connectionName}, '%')
or ri.car_owner like concat('%', #{map.connectionName}, '%'))
</if>
<if test="map.connectionPhone!=null and map.connectionPhone!='' ">
and (ri.connection_phone like concat('%', #{map.connectionPhone}, '%')
or ri.car_owner_phone like concat('%', #{map.connectionPhone}, '%'))
</if>
<if test="map.driverCarNum != null and map.driverCarNum != '' ">
and ri.driver_car_num = #{map.driverCarNum}
</if>
<if test="map.channel != null and map.channel != '' ">
and ri.channel = #{map.channel}
</if>
<if test="map.source != null and map.source != '' ">
and ri.source = #{map.source}
</if>
<if test="map.feeType != null and map.feeType != '' ">
and ri.fee_type = #{map.feeType}
</if>
<if test="map.orderStatus != null and map.orderStatus != '' ">
and roi.order_status = #{map.orderStatus}
</if>
<if test="map.faultType != null and map.faultType != '' ">
and ri.fault_type = #{map.faultType}
</if>
<if test="map.licenseNum != null and map.licenseNum != '' ">
and ri.license_num = #{map.licenseNum}
</if>
<if test="map.phenomenon != null and map.phenomenon != '' ">
and ri.phenomenon = #{map.phenomenon}
</if>
<if test="map.rescueStatus != null and map.rescueStatus != '' ">
and ri.rescue_status = #{map.rescueStatus}
</if>
<if test="map.rescueType != null and map.rescueType != '' ">
and ri.rescue_type = #{map.rescueType}
</if>
<if test="map.rescuePosition!=null and map.rescuePosition!='' ">
and ri.rescue_position like concat('%', #{map.rescuePosition}, '%')
</if>
<if test="map.driverId != null">
and ri.driver_id = #{map.driverId}
</if>
<if test="map.secondDispatchId != null">
and ri.second_dispatch_id = #{map.secondDispatchId}
</if>
<if test="map.startTimeStr!=null and map.startTimeStr!='' ">
AND ri.rescue_time &gt;= #{map.startTimeStr}
</if>
<if test="map.endTimeStr!=null and map.endTimeStr!='' ">
AND ri.rescue_time &lt;= #{map.endTimeStr}
</if>
<if test="map.rescueStart!=null and map.rescueStart!='' ">
AND ri.rescue_time &gt;= #{map.rescueStart}
</if>
<if test="map.rescueEnd!=null and map.rescueEnd!='' ">
AND ri.rescue_time &lt;= #{map.rescueEnd}
</if>
</where>
</select>
<select id="getRescueStatisticsInfoNumSecondDispatcher" resultType="java.util.Map" parameterType="cn.iocoder.yudao.module.rescue.domain.RescueInfo">
SELECT
IFNULL(sum(ri.rescue_status = '3' or ri.rescue_status = '4'), 0) as jyzNum,
IFNULL(sum(roi.order_status = '1'), 0) as dzfNum,
IFNULL(sum(ri.rescue_status = '6'), 0) as dqcNum,
IFNULL(sum(ri.rescue_status <![CDATA[>=]]> '5'), 0) as ywcNum,
IFNULL(sum(ri.is_wei_xiu = '1'), 0) as zwxNum,
IFNULL(count(ri.id), 0) as yjdNum,
IFNULL(sum(roi.set_money), 0) as yingskNum,
IFNULL(sum(CASE WHEN roi.if_confirm_pay = '1' THEN roi.pay_money ELSE 0 END), 0) as yiskNum,
IFNULL(sum(CASE WHEN roi.if_confirm_pay = '0' THEN roi.set_money ELSE 0 END), 0) as dskNum
FROM rescue_info ri
left join rescue_order_info roi on roi.rescue_info_id = ri.id and roi.deleted = '0'
<where>
1 = 1
and ri.deleted = '0' AND ri.is_revoke = '0'
and ri.second_dispatch_id = #{map.userId}
<if test="map.connectionName!=null and map.connectionName!='' ">
and (ri.connection_name like concat('%', #{map.connectionName}, '%')
or ri.car_owner like concat('%', #{map.connectionName}, '%'))
</if>
<if test="map.connectionPhone!=null and map.connectionPhone!='' ">
and (ri.connection_phone like concat('%', #{map.connectionPhone}, '%')
or ri.car_owner_phone like concat('%', #{map.connectionPhone}, '%'))
</if>
<if test="map.driverCarNum != null and map.driverCarNum != '' ">
and ri.driver_car_num = #{map.driverCarNum}
</if>
<if test="map.channel != null and map.channel != '' ">
and ri.channel = #{map.channel}
</if>
<if test="map.source != null and map.source != '' ">
and ri.source = #{map.source}
</if>
<if test="map.feeType != null and map.feeType != '' ">
and ri.fee_type = #{map.feeType}
</if>
<if test="map.orderStatus != null and map.orderStatus != '' ">
and roi.order_status = #{map.orderStatus}
</if>
<if test="map.faultType != null and map.faultType != '' ">
and ri.fault_type = #{map.faultType}
</if>
<if test="map.licenseNum != null and map.licenseNum != '' ">
and ri.license_num = #{map.licenseNum}
</if>
<if test="map.phenomenon != null and map.phenomenon != '' ">
and ri.phenomenon = #{map.phenomenon}
</if>
<if test="map.rescueStatus != null and map.rescueStatus != '' ">
and ri.rescue_status = #{map.rescueStatus}
</if>
<if test="map.rescueType != null and map.rescueType != '' ">
and ri.rescue_type = #{map.rescueType}
</if>
<if test="map.rescuePosition!=null and map.rescuePosition!='' ">
and ri.rescue_position like concat('%', #{map.rescuePosition}, '%')
</if>
<if test="map.driverId != null">
and ri.driver_id = #{map.driverId}
</if>
<if test="map.secondDispatchId != null">
and ri.second_dispatch_id = #{map.secondDispatchId}
</if>
<if test="map.startTimeStr!=null and map.startTimeStr!='' ">
AND ri.rescue_time &gt;= #{map.startTimeStr}
</if>
<if test="map.endTimeStr!=null and map.endTimeStr!='' ">
AND ri.rescue_time &lt;= #{map.endTimeStr}
</if>
<if test="map.rescueStart!=null and map.rescueStart!='' ">
AND ri.rescue_time &gt;= #{map.rescueStart}
</if>
<if test="map.rescueEnd!=null and map.rescueEnd!='' ">
AND ri.rescue_time &lt;= #{map.rescueEnd}
</if>
</where>
</select>
<select id="driverStatisticsSecond" parameterType="cn.iocoder.yudao.module.rescue.vo.StatisticsStaffVO"
resultType="cn.iocoder.yudao.module.rescue.vo.StatisticsStaffVO">
SELECT
su.id AS userId,
su.avatar,
di.id AS driver_id,
su.nickname AS driver_name,
COALESCE(COUNT(ri.id), 0) AS rescueNum,
COALESCE(SUM(
CASE
WHEN ri.end_scale IS NOT NULL
AND ri.start_scale IS NOT NULL
AND ri.end_scale > ri.start_scale
THEN ri.end_scale - ri.start_scale
ELSE 0
END
), 0) AS mileage,
COALESCE(SUM(roi.set_money), 0) AS money
FROM driver_info di
INNER JOIN system_users su ON di.user_id = su.id AND su.deleted = 0
LEFT JOIN rescue_info ri ON ri.driver_id = di.id
AND ri.deleted = 0
AND ri.driver_name IS NOT NULL
AND ri.driver_id IS NOT NULL
AND ri.second_dispatch_id = #{vo.secondUserId}
LEFT JOIN rescue_order_info roi ON roi.rescue_info_id = ri.id AND roi.deleted = 0
WHERE di.deleted = 0
AND FIND_IN_SET(#{vo.secondUserId}, di.second_dispatcher_id) > 0
GROUP BY
su.id,
di.id,
su.nickname
ORDER BY rescueNum DESC
</select>
<select id="carStatisticsSecond" parameterType="cn.iocoder.yudao.module.rescue.vo.StatisticsStaffVO"
resultType="cn.iocoder.yudao.module.rescue.vo.StatisticsStaffVO">
SELECT
rci.rescue_car_num AS driverCarNum,
COALESCE(COUNT(ri.id), 0) AS rescueNum,
COALESCE(SUM(
CASE
WHEN ri.end_scale IS NOT NULL
AND ri.start_scale IS NOT NULL
AND ri.end_scale > ri.start_scale
THEN ri.end_scale - ri.start_scale
ELSE 0
END
), 0) AS mileage,
COALESCE(SUM(roi.set_money), 0) AS money
FROM rescue_car_info rci
INNER JOIN rescue_driver_car_relation rdcr ON rci.id = rdcr.car_id AND rdcr.deleted = 0
INNER JOIN driver_info di ON rdcr.driver_id = di.id AND di.deleted = 0
LEFT JOIN rescue_info ri ON ri.driver_car_num = rci.rescue_car_num
AND ri.deleted = 0
AND ri.second_dispatch_id = #{vo.secondUserId}
LEFT JOIN rescue_order_info roi ON roi.rescue_info_id = ri.id AND roi.deleted = 0
WHERE rci.deleted = 0
AND FIND_IN_SET(#{vo.secondUserId}, di.second_dispatcher_id) > 0
GROUP BY
rci.rescue_car_num
ORDER BY rescueNum DESC
</select>
<select id="rescueCarList" resultType="cn.iocoder.yudao.module.rescue.domain.RescueInfo">
SELECT
ri.*,
rci.rescue_car_own AS rescueCarOwn,
rci.rescue_car_brand AS rescueCarBrand,
roi.order_status,
roi.set_money,
roi.id AS orderId,
IFNULL(TIMESTAMPDIFF(YEAR, rci.car_buy_time, CURDATE()), 0) AS carAge,
COALESCE(SUM(
CASE
WHEN ri.end_scale IS NOT NULL
AND ri.start_scale IS NOT NULL
AND ri.end_scale > ri.start_scale
THEN ri.end_scale - ri.start_scale
ELSE 0
END
), 0) AS mileage
FROM rescue_car_info rci
LEFT JOIN rescue_info ri ON rci.rescue_car_num = ri.driver_car_num AND ri.deleted = 0
LEFT JOIN rescue_order_info roi ON roi.rescue_info_id = ri.id AND roi.deleted = 0
WHERE
rci.deleted = 0
<if test="map.rescueCarOwn != null and map.rescueCarOwn != ''">
and rci.rescue_car_own = #{map.rescueCarOwn}
</if>
<if test="map.orderStatus != null and map.orderStatus != ''">
and roi.order_status = #{map.orderStatus}
</if>
<if test="map.channel != null and map.channel != ''">
and ri.channel = #{map.channel}
</if>
<if test="map.secondDispatchName != null and map.secondDispatchName != ''">
and ri.second_dispatch_name = #{map.secondDispatchName}
</if>
<if test="map.rescueTime != null">
and ri.rescue_time between
concat(#{map.rescueTime}, ' 00:00:00') and concat(#{map.rescueTime}, ' 23:59:59')
</if>
<if test="map.licenseNum != null">
and ri.license_num like concat('%', #{map.licenseNum}, '%')
</if>
<if test="map.driverName != null">
and ri.driver_name like concat('%', #{map.driverName}, '%')
</if>
<if test="map.driverCarNum != null">
and ri.driver_car_num like concat('%', #{map.driverCarNum}, '%')
</if>
<if test="map.rescueStart != null and map.rescueEnd != null">
and rescue_time between
concat(#{map.rescueStart}, ' 00:00:00') and concat(#{map.rescueEnd}, ' 23:59:59')
</if>
GROUP BY
rci.rescue_car_num
ORDER BY
ri.create_time DESC
</select>
<select id="selectCarAgeAndMileage" resultType="cn.iocoder.yudao.module.rescue.vo.RescueCarStatRespVO">
SELECT
rci.rescue_car_num AS rescueCarNum,
IFNULL(TIMESTAMPDIFF(YEAR, rci.car_buy_time, CURDATE()), 0) AS carAge,
COALESCE(SUM(
CASE
WHEN ri.end_scale IS NOT NULL
AND ri.start_scale IS NOT NULL
AND ri.end_scale > ri.start_scale
THEN ri.end_scale - ri.start_scale
ELSE 0
END
), 0) AS mileage
FROM rescue_car_info rci
LEFT JOIN rescue_info ri
ON rci.rescue_car_num = ri.driver_car_num AND ri.deleted = 0
WHERE rci.deleted = 0
GROUP BY
rci.rescue_car_num,
rci.car_buy_time
ORDER BY rci.rescue_car_num
</select>
<select id="getRescueCarKPI" resultType="cn.iocoder.yudao.module.rescue.domain.RescueInfo">
SELECT
ri.driver_car_num AS driverCarNum,
DATE(ri.rescue_time) AS rescueTime,
ri.channel AS channel,
CASE
WHEN ri.end_scale IS NOT NULL
AND ri.start_scale IS NOT NULL
AND ri.end_scale > ri.start_scale
THEN (ri.end_scale - ri.start_scale)
ELSE 0
END AS mileage,
roi.order_status AS orderStatus,
roi.set_money AS setMoney
FROM rescue_info ri
LEFT JOIN rescue_order_info roi
ON roi.rescue_info_id = ri.id AND roi.deleted = '0'
<where>
ri.deleted = '0'
<!-- 按车牌过滤 -->
<if test="driverCarNum != null and driverCarNum != ''">
AND ri.driver_car_num = #{driverCarNum}
</if>
<if test="startTime!=null and startTime!='' and endTime!=null and endTime!=''">
and rescue_time between
concat(#{startTime}, ' 00:00:00') and concat(#{endTime}, ' 23:59:59')
</if>
</where>
ORDER BY ri.rescue_time DESC
</select>
</mapper>

View File

@ -18,21 +18,76 @@
<result property="updateTime" column="update_time"/>
</resultMap>
<select id="selectRescueRefuelRecordList" parameterType="cn.iocoder.yudao.module.rescue.domain.RescueRefuelRecord"
<!-- <select id="selectRescueRefuelRecordList" parameterType="cn.iocoder.yudao.module.rescue.domain.RescueRefuelRecord"-->
<!-- resultType="cn.iocoder.yudao.module.rescue.domain.RescueRefuelRecord">-->
<!-- SELECT-->
<!-- rrc.*,su.nickname as real_name,su.mobile as phonenumber,rci.rescue_car_num-->
<!-- FROM-->
<!-- rescue_refuel_record rrc-->
<!-- inner join driver_info di ON rrc.driver_id = di.id-->
<!-- INNER JOIN system_users su ON su.id = di.user_id-->
<!-- left join rescue_car_info rci on di.id = rci.possessor_id-->
<!-- where rrc.deleted = '0'-->
<!-- <if test="map.realName != null ">and su.nickname like concat('%',#{map.realName},'%')</if>-->
<!-- <if test="map.rescueCarNum != null ">and rci.rescue_car_num like concat('%',#{map.rescueCarNum},'%')</if>-->
<!-- order by rrc.record_time desc-->
<!-- </select>-->
<select id="selectRescueRefuelRecordList"
parameterType="cn.iocoder.yudao.module.rescue.domain.RescueRefuelRecord"
resultType="cn.iocoder.yudao.module.rescue.domain.RescueRefuelRecord">
SELECT
rrc.*,su.nickname as real_name,su.mobile as phonenumber,rci.rescue_car_num
FROM
rescue_refuel_record rrc
inner join driver_info di ON rrc.driver_id = di.id
INNER JOIN system_users su ON su.id = di.user_id
left join rescue_car_info rci on di.id = rci.possessor_id
where rrc.deleted = '0'
<if test="map.realName != null ">and su.nickname like concat('%',#{map.realName},'%')</if>
<if test="map.rescueCarNum != null ">and rci.rescue_car_num like concat('%',#{map.rescueCarNum},'%')</if>
order by rrc.record_time desc
rrc.*,
su.nickname AS real_name,
su.mobile AS phonenumber,
rci.rescue_car_num,
/* ① 距上次加油公里数 */
(rrc.refuel_distance
- LAG(rrc.refuel_distance) OVER (PARTITION BY rrc.car_id ORDER BY rrc.record_time)
) AS distance_prev_km,
/* ② 每公里油耗 L/km有上一条且距离>0 才计算) */
CASE
WHEN LAG(rrc.refuel_distance) OVER (PARTITION BY rrc.car_id ORDER BY rrc.record_time) IS NOT NULL
AND (rrc.refuel_distance
- LAG(rrc.refuel_distance) OVER (PARTITION BY rrc.car_id ORDER BY rrc.record_time)) > 0
THEN ROUND(
rrc.refuel_num /
(rrc.refuel_distance
- LAG(rrc.refuel_distance) OVER (PARTITION BY rrc.car_id ORDER BY rrc.record_time)
), 3)
END AS fuel_efficiency_lpkm,
/* ③ 每公里成本 元/km */
CASE
WHEN LAG(rrc.refuel_distance) OVER (PARTITION BY rrc.car_id ORDER BY rrc.record_time) IS NOT NULL
AND (rrc.refuel_distance
- LAG(rrc.refuel_distance) OVER (PARTITION BY rrc.car_id ORDER BY rrc.record_time)) > 0
THEN ROUND(
rrc.refuel_money /
(rrc.refuel_distance
- LAG(rrc.refuel_distance) OVER (PARTITION BY rrc.car_id ORDER BY rrc.record_time)
), 2)
END AS cost_per_km
/* 金额兜底(如果表里已有 refuel_money 可不用返回)
ROUND(rrc.refuel_num * (rrc.refuel_money / NULLIF(rrc.refuel_num, 0)), 2)
AS cost_amount_calc */
FROM rescue_refuel_record rrc
INNER JOIN driver_info di ON rrc.driver_id = di.id
INNER JOIN system_users su ON su.id = di.user_id
LEFT JOIN rescue_car_info rci ON rrc.car_id = rci.id
WHERE rrc.deleted = 0
<if test="map.realName != null">
AND su.nickname LIKE CONCAT('%', #{map.realName}, '%')
</if>
<if test="map.rescueCarNum != null">
AND rci.rescue_car_num LIKE CONCAT('%', #{map.rescueCarNum}, '%')
</if>
ORDER BY rrc.record_time DESC
</select>
<select id="selectRescueRefuelRecordById" parameterType="java.lang.Long"
resultType="cn.iocoder.yudao.module.rescue.domain.RescueRefuelRecord">
select *

View File

@ -17,7 +17,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
system_user_role sur
WHERE
sur.tenant_id = #{tenantId}
AND sur.role_id = ( SELECT id FROM system_role WHERE `code` = #{roleCode} ))
AND sur.role_id = ( SELECT id FROM system_role WHERE `code` = #{roleCode} and tenant_id = #{tenantId}))
</select>
<select id="selectListByRoleId" resultType="cn.iocoder.yudao.module.system.api.user.dto.UserDTO"
parameterType="cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RolePageReqVO">

View File

@ -47,6 +47,7 @@ spring:
datasource:
master:
url: jdbc:mysql://122.51.230.86:3306/lanan_platform_dev?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
# url: jdbc:mysql://localhost:3306/lanan_new?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
# url: jdbc:mysql://122.51.230.86:3306/lanan_platform?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai # MySQL Connector/J 5.X 连接的示例
# url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例
@ -57,6 +58,8 @@ spring:
# url: jdbc:postgresql://127.0.0.1:5432/postgres # OpenGauss 连接的示例
username: lanan_dev
password: lighting@2024
# username: root
# password: 12345678
# username: lanan
# password: 123456
# username: sa # SQL Server 连接的示例