This commit is contained in:
PQZ 2024-10-25 17:53:31 +08:00
commit e3607bed22
29 changed files with 1199 additions and 179 deletions

View File

@ -29,10 +29,15 @@
<select id="pageNotice" resultMap="BaseResultMap">
<include refid="Base_SQL" />
and dbn.parent_server = #{map.parentServer}
<if test="map.parentServer != null and map.parentServer != ''">
and dbn.parent_server = #{map.parentServer}
</if>
<if test="map.server != null and map.server != ''">
and dbn.server = #{map.server}
</if>
<if test="map.type != null and map.type != ''">
and dbn.type = #{map.type}
</if>
<if test="map.status != null">
and dbn.status = #{map.status}
</if>

View File

@ -57,7 +57,7 @@
<choose>
<when test="map.selectType == 'working'">
-- 维修中的订单 --
and (drt.tickets_status = '04' OR drt.tickets_status = '05' )
and (drt.tickets_status = '04' OR drt.tickets_status = '05' OR drt.tickets_status = '05' OR drt.tickets_status ='01')
</when>
<when test="map.selectType == 'waitingPay'">
-- 待支付的订单 --

View File

@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 工单操作记录-工作类型枚举
* 工单操作记录-工作类型枚举(repair_records_type)
*
* @author vinjor-m
*/
@ -39,6 +39,10 @@ public enum RecordTypeEnum {
* 结束工单
*/
JSGD("jsgd","结束工单"),
/**
* 通知客户取车
*/
TZQC("tzqc","通知客户取车"),
/**
* 开始施工
*/

View File

@ -11,4 +11,9 @@ public class RepairCons {
public static final String TICKETS_WAITING = "waiting";
/**工单-所有*/
public static final String TICKETS_ALL = "all";
/**数据字典常量-repair_records_type-*/
public static final String DICT_REPAIR_RECORDS_TYPE = "repair_records_type";
/**数据字典常量-repair_type-*/
public static final String DICT_REPAIR_TYPE = "repair_type";
}

View File

@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 维修工单状态枚举
* 维修工单状态枚举(repair_tickets_status)
*
* @author vinjor-m
*/
@ -23,6 +23,10 @@ public enum TicketsStatusEnum {
* 未结账
*/
NO_PAY("01","未结账"),
/**
* 待通知客户取车
*/
WAITING_NOTICE("07","待通知客户取车"),
/**
* 挂单/记账
*/

View File

@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.base.entity.RepairRecordsItem;
import cn.iocoder.yudao.module.base.service.RepairRecordsItemService;
import cn.iocoder.yudao.module.base.service.RepairRecordsService;
import cn.iocoder.yudao.module.base.vo.RepairRecordsPageReqVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
@ -56,5 +57,16 @@ public class RepairRecordsController {
return CommonResult.success("");
}
/**
* 根据条件查询维修记录
*
* @author 小李
* @date 9:48 2024/10/25
* @param reqVO RepairRecordsPageReqVO实体
**/
@GetMapping("/list")
@Operation(summary = "根据条件查询维修记录")
public CommonResult<?> queryList(RepairRecordsPageReqVO reqVO) {
return CommonResult.success(repairRecordsService.queryList(reqVO));
}
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.base.controller.admin;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.base.service.RepairRecordsItemService;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("/dl/repair-records-item")
public class RepairRecordsItemController {
@Resource
private RepairRecordsItemService repairRecordsItemService;
/**
* 设置图片是否开放给用户
*
* @author 小李
* @date 9:53 2024/10/25
* @param ids 前端选中图片id多个用分隔
* @param isOpen 0否1是
**/
@GetMapping("/updateOpen")
@Operation(summary = "设置图片是否开放给用户")
public CommonResult<?> updateOpen(@RequestParam("ids") String ids, @RequestParam("isOpen") String isOpen) {
repairRecordsItemService.setRepairOpen(ids, isOpen);
return CommonResult.ok();
}
}

View File

@ -13,5 +13,4 @@ import lombok.ToString;
public class RepairRecordsPageReqVO extends RepairRecords {
/**是否开放给用户*/
private String isOpen;
}

View File

@ -320,5 +320,19 @@ public class DlRepairTicketsController {
dlRepairTicketsService.noticeCus(noticeCusVO);
return CommonResult.ok();
}
/**
* 新增工单子项
*
* @author 小李
* @date 19:59 2024/10/24
* @param respVO 主要有两个参数主表ID,itemList(这个需要前端处理成子表的对象能接收的数据)
**/
@PostMapping("/addItems")
@Operation(summary = "新增工单子项")
public CommonResult<?> addItems(@RequestBody DlRepairTicketsRespVO respVO) {
dlRepairTicketsService.addItems(respVO);
return CommonResult.ok();
}
}

View File

@ -69,5 +69,45 @@ public class DlRepairTitemController {
public CommonResult<?> updateRepairAndSale(@RequestBody DlRepairTitemReqVO dlRepairTitemReqVO){
return success(dlRepairTitemService.updateRepairAndSale(dlRepairTitemReqVO));
}
/**
* 查看单个维修子表的数据
*
* @author 小李
* @param id 子表ID
**/
@GetMapping("/getById")
@Operation(summary = "查看单个维修子表的数据")
public CommonResult<?> getItemById(@RequestParam("id") String id){
return success(dlRepairTitemService.getItemById(id));
}
/**
* 修改单个工单子项的内容
*
* @author 小李
* @date 15:41 2024/10/24
* @param dlRepairTitemReqVO 对象
**/
@PostMapping("/updateById")
@Operation(summary = "修改单个工单子项的内容")
public CommonResult<?> updateItemById(@RequestBody DlRepairTitemReqVO dlRepairTitemReqVO){
dlRepairTitemService.updateItemById(dlRepairTitemReqVO);
return CommonResult.ok();
}
/**
* 维修工单单个子项
*
* @author 小李
* @date 20:18 2024/10/24
* @param id 工单子项ID
**/
@DeleteMapping("/removeById")
@Operation(summary = "维修工单单个子项")
public CommonResult<?> removeItemById(@RequestParam("id") String id){
dlRepairTitemService.removeItemById(id);
return CommonResult.ok();
}
}

View File

@ -182,4 +182,22 @@ public interface DlRepairTicketsService extends IService<DlRepairTickets> {
* @param noticeCusVO 请求对象
**/
void noticeCus(NoticeCusVO noticeCusVO);
/**
* 重新计算工单的一些数值
*
* @author 小李
* @date 15:47 2024/10/24
* @param ticketId 工单ID
**/
boolean computeTicket(String ticketId);
/**
* 新增工单子项
*
* @author 小李
* @date 19:59 2024/10/24
* @param respVO 主要有两个参数主表ID,itemList(这个需要前端处理成子表的对象能接收的数据)
**/
void addItems(DlRepairTicketsRespVO respVO);
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.tickets.service;
import cn.iocoder.yudao.module.tickets.entity.DlRepairTitem;
import cn.iocoder.yudao.module.tickets.vo.DlRepairTitemReqVO;
import cn.iocoder.yudao.module.tickets.vo.DlRepairTitemRespVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -41,4 +42,29 @@ public interface DlRepairTitemService extends IService<DlRepairTitem> {
*/
DlRepairTitem updateRepairAndSale(DlRepairTitem dlRepairTitem);
/**
* 查看单个维修子表的数据
*
* @author 小李
* @param id 子表ID
**/
DlRepairTitem getItemById(String id);
/**
* 修改单个工单子项的内容
*
* @author 小李
* @date 15:41 2024/10/24
* @param dlRepairTitemReqVO 对象
**/
void updateItemById(DlRepairTitemReqVO dlRepairTitemReqVO);
/**
* 维修工单单个子项
*
* @author 小李
* @date 20:18 2024/10/24
* @param id 工单子项ID
**/
void removeItemById(String id);
}

View File

@ -19,6 +19,7 @@ import cn.iocoder.yudao.module.custom.service.CustomerCarService;
import cn.iocoder.yudao.module.custom.service.CustomerMainService;
import cn.iocoder.yudao.module.custom.vo.CarMainRespVO;
import cn.iocoder.yudao.module.custom.vo.CustomerMainRespVO;
import cn.iocoder.yudao.module.order.entity.RepairOrderInfo;
import cn.iocoder.yudao.module.order.service.RepairOrderInfoService;
import cn.iocoder.yudao.module.order.vo.RepairOrderInfoSaveReqVO;
import cn.iocoder.yudao.module.other.entity.DlRepairOther;
@ -39,11 +40,16 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.UserDTO;
import cn.iocoder.yudao.module.tickets.entity.DlRepairTickets;
import cn.iocoder.yudao.module.tickets.entity.DlRepairTitem;
import cn.iocoder.yudao.module.tickets.entity.DlTicketWares;
import cn.iocoder.yudao.module.tickets.entity.DlTwItem;
import cn.iocoder.yudao.module.tickets.mapper.DlRepairTicketsMapper;
import cn.iocoder.yudao.module.tickets.service.DlRepairTicketsService;
import cn.iocoder.yudao.module.tickets.service.DlRepairTitemService;
import cn.iocoder.yudao.module.tickets.service.DlTicketWaresService;
import cn.iocoder.yudao.module.tickets.service.DlTwItemService;
import cn.iocoder.yudao.module.tickets.tools.WordUtil;
import cn.iocoder.yudao.module.tickets.vo.*;
import cn.iocoder.yudao.util.SendSmsUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@ -52,8 +58,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.Na;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@ -62,11 +66,12 @@ import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.common.BaseConstants.ORDER_TENANT_NAME;
import static cn.iocoder.yudao.common.RepairCons.DICT_REPAIR_RECORDS_TYPE;
import static cn.iocoder.yudao.common.RepairCons.DICT_REPAIR_TYPE;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
@ -138,11 +143,16 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
private RepairWorkerService repairWorkerService;
@Resource
@Lazy
private RepairRecordsService recordsService;
private RepairRecordsService repairRecordsService;
@Resource
private RepairRecordsService repairRecordsService;
@Lazy
private DlTicketWaresService ticketWaresService;
@Resource
@Lazy
private DlTwItemService twItemService;
/**
@ -187,10 +197,10 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
// 新增子表
itemList.forEach(item -> {
item.setTicketId(ticketsRespVO.getId());
if("01".equals(item.getItemType())){
if ("01".equals(item.getItemType())) {
//维修项目,初始状态待派工
item.setItemStatus(TicketsItemStatusEnum.WAITING_WORK.getCode());
}else if("02".equals(item.getItemType())){
} else if ("02".equals(item.getItemType())) {
//维修配件初始状态待领料
item.setItemStatus(TicketsItemStatusEnum.WAITING_RECEIVE.getCode());
}
@ -306,7 +316,10 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
RepairRecordsPageReqVO entity = new RepairRecordsPageReqVO();
entity.setTicketId(id);
List<RepairRecordsRespVO> records = repairRecordsService.queryList(entity);
result.setRecords(records);
// 操作记录类型
List<DictDataRespDTO> recordTypeList = dictDataApi.getDictDataList(DICT_REPAIR_RECORDS_TYPE);
Map<String,String> typeMap = recordTypeList.stream().collect(Collectors.toMap(DictDataRespDTO::getValue,DictDataRespDTO::getLabel));
result.setRecords(records.stream().peek(item->item.setType(typeMap.get(item.getType()))).collect(Collectors.toList()));
return result;
}
@ -330,7 +343,18 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
* @date 8:50 2024/9/23
**/
@Override
@DSTransactional
public void setTicketsPaid(DlRepairTicketsRespVO repairTicketsRespVO) {
// 更新订单状态
RepairOrderInfo one = repairOrderInfoService.getOne(new LambdaQueryWrapper<RepairOrderInfo>().eq(RepairOrderInfo::getGoodsId, repairTicketsRespVO.getId()));
if (ObjectUtil.isEmpty(one)){
throw exception0(500, "系统异常");
}
RepairOrderInfo repairOrderInfo = new RepairOrderInfo();
repairOrderInfo.setId(one.getId());
repairOrderInfo.setPayType(repairTicketsRespVO.getPayType());
repairOrderInfoService.updateById(repairOrderInfo);
// 更新工单
baseMapper.updateById(repairTicketsRespVO);
}
@ -432,13 +456,13 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
String userRoleCode = getUserRole();
if (userRoleCode.equals(RepairRoleEnum.ADMIN.getCode())) {
//维修管理员看所有数据
} else if(userRoleCode.equals(RepairRoleEnum.INSPECTION.getCode())){
} else if (userRoleCode.equals(RepairRoleEnum.INSPECTION.getCode())) {
//总检
if (RepairCons.TICKETS_WAITING.equals(repairTicketsReqVO.getSelectType())) {
//查待处理的查需要自己处理的否则就是查所有
repairTicketsReqVO.setUserIds(Collections.singletonList(SecurityFrameworkUtils.getLoginUserId()));
}
}else if (userRoleCode.equals(RepairRoleEnum.ADVISOR.getCode())) {
} else if (userRoleCode.equals(RepairRoleEnum.ADVISOR.getCode())) {
//服务顾问
repairTicketsReqVO.setAdviserId(String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
} else if (userRoleCode.equals(RepairRoleEnum.REPAIR_STAFF.getCode())) {
@ -574,9 +598,9 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
@DSTransactional
public void updateStatus(DlRepairTicketsRespVO respVO) {
// 如果是开始施工但项目还在施工中就不能施工
if (RecordTypeEnum.KSSG.getCode().equals(respVO.getRecordType())){
if (RecordTypeEnum.KSSG.getCode().equals(respVO.getRecordType())) {
DlRepairTitem titem = titemService.getById(respVO.getItem().getId());
if (TicketsItemStatusEnum.WORKING.getCode().equals(titem.getItemStatus())){
if (TicketsItemStatusEnum.WORKING.getCode().equals(titem.getItemStatus())) {
throw exception0(500, "选择的项目在施工中,不能重新开始施工");
}
}
@ -600,7 +624,7 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
);
}
// 记录日志
recordsService.saveRepairRecord(respVO.getId(), respVO.getItem().getId(), respVO.getRecordType(), respVO.getRemark(), respVO.getImage());
repairRecordsService.saveRepairRecord(respVO.getId(), respVO.getItem().getId(), respVO.getRecordType(), respVO.getRemark(), respVO.getImage());
// 通知服务顾问和维修总检
DlRepairTickets tickets = baseMapper.selectById(respVO.getId());
@ -618,7 +642,7 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
String message = createMessage(tickets.getNowRepairName(), tickets.getTicketNo(), titem.getItemName(), respVO.getRecordType(), respVO.getFinishType(), respVO.getNextName());
// 通知服务顾问
// 如果员工完成了订单
if (RecordTypeEnum.SGWCZJ.getCode().equals(respVO.getRecordType())&& "03".equals(respVO.getFinishType())) {
if (RecordTypeEnum.SGWCZJ.getCode().equals(respVO.getRecordType()) && "03".equals(respVO.getFinishType())) {
repairWorkerService.sentMessage(Long.valueOf(tickets.getAdviserId()), "您有新的工单可以出厂检验");
// 需要把工单的当前操作人移交服务顾问
baseMapper.update(new LambdaUpdateWrapper<DlRepairTickets>()
@ -751,6 +775,52 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
.setSql("now_repair_name = adviser_name")
.eq(DlRepairTickets::getId, respVO.getId())
);
// 先查满足条件的申请表
ArrayList<String> status = new ArrayList<>();
status.add("01"); // 待审核
status.add("05"); // 已驳回
// 查工单所有已通过的配件申请单
List<DlTicketWares> list = ticketWaresService.list(new LambdaQueryWrapper<DlTicketWares>().and(item -> {
item.eq(DlTicketWares::getTicketId, respVO.getId())
.notIn(DlTicketWares::getStatus, status);
}));
// 查配件申请表的所有已领取数量小于申请数量的子表信息
List<String> ids = list.stream().map(DlTicketWares::getId).collect(Collectors.toList());
List<DlTwItem> twItems = twItemService.list(new LambdaQueryWrapper<DlTwItem>().and(item -> {
item.in(DlTwItem::getTwId, ids)
.apply("wares_already_count < wares_count");
}));
if (CollectionUtil.isNotEmpty(twItems)) {
// 更新工单子表主要是把已领料的字段同步给工单配件的数量字段
// 查询工单子表三个查询条件属于那个工单属于配件类型属于需要改变的即申请表的已领取数量小于申请数量的
Set<String> waresId = twItems.stream().map(DlTwItem::getWaresId).collect(Collectors.toSet());
List<DlRepairTitem> items = titemService.list(new LambdaQueryWrapper<DlRepairTitem>().and(item -> {
item.eq(DlRepairTitem::getTicketId, respVO.getId())
.eq(DlRepairTitem::getItemType, "02")
.in(DlRepairTitem::getPartId, waresId);
}));
// 同一个配件可能申请过多次属于是一个工单配件可能是对应多个申请表配件
List<DlRepairTitem> updateItems = items.stream().map(item -> {
DlRepairTitem titem = new DlRepairTitem();
titem.setId(item.getId());
List<DlTwItem> wares = twItems.stream().filter(i -> i.getWaresId().equals(item.getPartId())).collect(Collectors.toList());
int sum = wares.stream().mapToInt(DlTwItem::getWaresAlreadyCount).sum();
titem.setItemCount(sum);
BigDecimal discount = item.getItemDiscount() == null ? BigDecimal.ONE : item.getItemDiscount();
titem.setItemMoney(item.getItemPrice().multiply(BigDecimal.valueOf(sum)).multiply(discount));
return titem;
}).collect(Collectors.toList());
// 更新维修工单子表
titemService.updateBatchById(updateItems);
// 重新计算维修工单
boolean flag = computeTicket(respVO.getId());
if (!flag){
throw exception0(500, "系统异常");
}
}
// 通知服务顾问
DlRepairTickets tickets = baseMapper.selectById(respVO.getId());
repairWorkerService.sentMessage(Long.valueOf(tickets.getAdviserId()), "您有新的工单可以出厂检验");
@ -768,6 +838,7 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
// 更新工单状态
baseMapper.update(new LambdaUpdateWrapper<DlRepairTickets>()
.set(DlRepairTickets::getTicketsWorkStatus, TicketsWorkStatusEnum.END.getCode())
.set(DlRepairTickets::getTicketsStatus, TicketsStatusEnum.WAITING_NOTICE.getCode())
.eq(DlRepairTickets::getId, respVO.getId())
);
@ -814,38 +885,103 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
public void noticeCus(NoticeCusVO noticeCusVO) {
// 获取客户信息
DlRepairTickets tickets = baseMapper.selectById(noticeCusVO.getId());
// 更新工单状态为待结算待取车
baseMapper.update(new LambdaUpdateWrapper<DlRepairTickets>()
.set(DlRepairTickets::getTicketsStatus, TicketsStatusEnum.NO_PAY.getCode())
.eq(DlRepairTickets::getId, noticeCusVO.getId())
);
CustomerMain cus = customerService.getById(tickets.getUserId());
// 维修项目
List<DictDataRespDTO> repairType = dictDataApi.getDictDataList("repair_type");
List<DictDataRespDTO> repairType = dictDataApi.getDictDataList(DICT_REPAIR_TYPE);
// 默认是维修
String type = "维修";
DictDataRespDTO dictDataRespDTO = repairType.stream()
.filter(item -> item.getValue().equals(tickets.getRepairType()))
.findFirst()
.orElse(null);
if (dictDataRespDTO != null){
if (dictDataRespDTO != null) {
type = dictDataRespDTO.getLabel();
}
// 构建消息
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String start = format.format(noticeCusVO.getTime()[0]);
String end = format.format(noticeCusVO.getTime()[1]);
String message = String.format(
"尊敬的客户您好:您的爱车%s已%s完毕请您于%s至%s之内前来取车。若有问题可以联系%s联系电话%s"
, tickets.getCarNo(), type, start, end, noticeCusVO.getName(), noticeCusVO.getMobile()
"尊敬的客户您好:您的爱车%s已%s完毕请您前来取车。若有问题可以联系%s联系电话%s"
, tickets.getCarNo(), type, noticeCusVO.getName(), noticeCusVO.getMobile()
);
// todo 小程序通知客户
// todo 短信通知客户
if(null!=cus && StringUtils.isNotEmpty(cus.getPhoneNumber())){
// 短信通知客户
SendSmsUtil.sendMsgCommon(new String[]{message}, cus.getPhoneNumber(), "1400852709", "蓝安汽车小程序", "2143603");
}
// 记录日志
String recordStr = noticeCusVO.getName()
+ "通知客户:"
+ cus.getCusName()
+ ""
+ start
+ ""
+ end
+ "前来取车";
repairRecordsService.saveRepairRecord(noticeCusVO.getId(), null, RecordTypeEnum.JSGD.getCode(), recordStr, null);
+ "通知客户取车:"+message;
repairRecordsService.saveRepairRecord(noticeCusVO.getId(), null, RecordTypeEnum.TZQC.getCode(), recordStr, null);
}
/**
* 重新计算工单的一些数值
*
* @param ticketId 工单ID
* @author 小李
* @date 15:47 2024/10/24
**/
@Override
public boolean computeTicket(String ticketId) {
// 查子表
List<DlRepairTitem> list = titemService.list(new LambdaQueryWrapper<DlRepairTitem>().eq(DlRepairTitem::getTicketId, ticketId));
// 计算
DlRepairTickets tickets = new DlRepairTickets();
// 计算子项总数
int count = list.stream().mapToInt(DlRepairTitem::getItemCount).sum();
tickets.setId(ticketId);
tickets.setCount(count);
// 分类计算各自的总价和最终工单总价
Map<String, List<DlRepairTitem>> map = list.stream().collect(Collectors.groupingBy(DlRepairTitem::getItemType));
// 01项目02配件03其他
tickets.setTotalPrice(BigDecimal.ZERO);
map.forEach((k, v) -> {
BigDecimal reduce = v.stream().map(DlRepairTitem::getItemMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
tickets.setTotalPrice(tickets.getTotalPrice().add(reduce));
if (k.equals("01")) {
tickets.setProjectPrice(reduce);
} else if (k.equals("02")) {
tickets.setPartPrice(reduce);
} else if (k.equals("03")) {
tickets.setOtherPrice(reduce);
}
});
return baseMapper.updateById(tickets) > 0;
}
/**
* 新增工单子项
*
* @author 小李
* @date 19:59 2024/10/24
* @param respVO 主要有两个参数主表ID,itemList(这个需要前端处理成子表的对象能接收的数据)
**/
@Override
@DSTransactional
public void addItems(DlRepairTicketsRespVO respVO){
// 先判断是否施工人员和销售人员是否都设置了
respVO.getItemList().forEach(item -> {
if (ObjectUtil.isEmpty(item.getRepairIds())){
throw exception0(500, "施工人员尚未设置");
}
if (ObjectUtil.isEmpty(item.getSaleId())){
throw exception0(500, "销售人员尚未设置");
}
});
// 新增子表
List<DlRepairTitem> itemList = respVO.getItemList();
itemList.forEach(item -> item.setTicketId(respVO.getId()));
titemService.saveBatch(itemList);
// 更新主表
boolean flag = computeTicket(respVO.getId());
if (!flag){
throw exception0(500, "系统错误");
}
}
}

View File

@ -2,16 +2,23 @@ package cn.iocoder.yudao.module.tickets.service.impl;
import cn.iocoder.yudao.module.tickets.entity.DlRepairTitem;
import cn.iocoder.yudao.module.tickets.mapper.DlRepairTitemMapper;
import cn.iocoder.yudao.module.tickets.service.DlRepairTicketsService;
import cn.iocoder.yudao.module.tickets.service.DlRepairTitemService;
import cn.iocoder.yudao.module.tickets.vo.DlRepairTitemReqVO;
import cn.iocoder.yudao.module.tickets.vo.DlRepairTitemRespVO;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
/**
* 针对表dl_repair_titem(维修工单子表)的数据库操作Service实现
*
@ -22,6 +29,9 @@ import java.util.List;
public class DlRepairTitemServiceImpl extends ServiceImpl<DlRepairTitemMapper, DlRepairTitem>
implements DlRepairTitemService {
@Resource
private DlRepairTicketsService repairTicketsService;
/**
* 维修工单子表 分页
*
@ -60,6 +70,63 @@ public class DlRepairTitemServiceImpl extends ServiceImpl<DlRepairTitemMapper, D
baseMapper.updateRepairAndSale(dlRepairTitem);
return dlRepairTitem;
}
/**
* 查看单个维修子表的数据
*
* @author 小李
* @param id 子表ID
**/
@Override
public DlRepairTitem getItemById(String id){
return baseMapper.selectById(id);
}
/**
* 修改单个工单子项的内容
*
* @author 小李
* @date 15:41 2024/10/24
* @param dlRepairTitemReqVO 对象
**/
@Override
@DSTransactional
public void updateItemById(DlRepairTitemReqVO dlRepairTitemReqVO){
// 更新工单子表
DlRepairTitem titem = new DlRepairTitem();
titem.setId(dlRepairTitemReqVO.getId());
titem.setItemCount(dlRepairTitemReqVO.getItemCount());
titem.setItemPrice(dlRepairTitemReqVO.getItemPrice());
titem.setItemDiscount(dlRepairTitemReqVO.getItemDiscount());
// 计算总价
BigDecimal total = titem.getItemPrice().multiply(BigDecimal.valueOf(titem.getItemCount())).multiply(titem.getItemDiscount());
titem.setItemMoney(total);
baseMapper.updateById(titem);
// 重新计算工单的一些数值
boolean flag = repairTicketsService.computeTicket(dlRepairTitemReqVO.getTicketId());
if (!flag){
throw exception0(500, "系统异常");
}
}
/**
* 维修工单单个子项
*
* @author 小李
* @date 20:18 2024/10/24
* @param id 工单子项ID
**/
@Override
@DSTransactional
public void removeItemById(String id){
// 先查出来备用
DlRepairTitem titem = baseMapper.selectById(id);
// 删除数据
baseMapper.deleteById(id);
// 更新主表
repairTicketsService.computeTicket(titem.getTicketId());
}
}

View File

@ -150,11 +150,11 @@ public class DlTicketWaresServiceImpl extends ServiceImpl<DlTicketWaresMapper, D
String userRoleCode = repairTicketsService.getUserRole();
List<DlTicketWares> result = new ArrayList<>();
//维修业务管理员总检服务顾问均可以进行审批
if (userRoleCode.equals(RepairRoleEnum.ADMIN.getCode())|| userRoleCode.equals(RepairRoleEnum.INSPECTION.getCode())||userRoleCode.equals(RepairRoleEnum.ADVISOR.getCode())){
if (userRoleCode.equals(RepairRoleEnum.ADMIN.getCode()) || userRoleCode.equals(RepairRoleEnum.INSPECTION.getCode()) || userRoleCode.equals(RepairRoleEnum.ADVISOR.getCode())) {
LambdaQueryWrapper<DlTicketWares> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(DlTicketWares::getTicketId,reqVO.getTicketId());
if (null != reqVO.getStatus()){
lambdaQueryWrapper.eq(DlTicketWares::getStatus,reqVO.getStatus());
lambdaQueryWrapper.eq(DlTicketWares::getTicketId, reqVO.getTicketId());
if (null != reqVO.getStatus()) {
lambdaQueryWrapper.eq(DlTicketWares::getStatus, reqVO.getStatus());
}
result = list(lambdaQueryWrapper);
}
@ -194,7 +194,7 @@ public class DlTicketWaresServiceImpl extends ServiceImpl<DlTicketWaresMapper, D
// 通过角色信息查有这个角色的人
List<Long> ids = permissionApi.getUserIdByRoleId(roleInfo.getId());
// 发通知
if (CollectionUtil.isNotEmpty(ids)){
if (CollectionUtil.isNotEmpty(ids)) {
ids.forEach(id -> repairWorkerService.sentMessage(id, "您有新的配件申请单需要审核"));
}
}
@ -241,18 +241,18 @@ public class DlTicketWaresServiceImpl extends ServiceImpl<DlTicketWaresMapper, D
// 如果是通过并且是领料就还需要把配件信息加入到工单中
if (ObjectUtil.isNotEmpty(status) && status.equals("02") && type.equals("01")) {
// 更新维修工单
if(null== repairItemList || repairItemList.isEmpty()){
if (null == repairItemList || repairItemList.isEmpty()) {
repairItemList = new ArrayList<>();
//配件没传去库里面查需要的配件
LambdaQueryWrapper<DlTwItem> queryWrapper= new LambdaQueryWrapper<DlTwItem>()
.eq(DlTwItem::getTwId,mainId);
LambdaQueryWrapper<DlTwItem> queryWrapper = new LambdaQueryWrapper<DlTwItem>()
.eq(DlTwItem::getTwId, mainId);
List<DlTwItem> applyList = twItemService.list(queryWrapper);
if(!applyList.isEmpty()){
if (!applyList.isEmpty()) {
//查配件库
List<RepairWares> waresList = repairWaresService.listByIds(applyList.stream().map(DlTwItem::getWaresId).collect(Collectors.toList()));
Map<String,RepairWares> waresMap =waresList.stream().collect(Collectors.toMap(RepairWares::getId, Function.identity()));
Map<String, RepairWares> waresMap = waresList.stream().collect(Collectors.toMap(RepairWares::getId, Function.identity()));
//组装工单子表数据
for (DlTwItem item:applyList){
for (DlTwItem item : applyList) {
DlRepairTitem repairTitem = new DlRepairTitem();
repairTitem.setTicketId(ticketMainId);
repairTitem.setItemCount(item.getWaresCount());
@ -270,25 +270,53 @@ public class DlTicketWaresServiceImpl extends ServiceImpl<DlTicketWaresMapper, D
}
}
}
// 计算配件的总价
BigDecimal reduce = repairItemList.stream().map(DlRepairTitem::getItemMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
repairTicketsService.update(new LambdaUpdateWrapper<DlRepairTickets>()
// 工单子项总数量增加上配件的数量
.setSql("count = count + " + repairItemList.size())
// 工单配件总价
.setSql("part_price = part_price + " + reduce)
// 工单总价
.setSql("total_price = total_price + " + reduce)
// 参考成本
.setSql("cost = cost + " + reduce)
// 参考毛利
.setSql("profit = profit + " + reduce)
// 领料状态
.set(DlRepairTickets::getPartStatus, "02")
.eq(DlRepairTickets::getId, ticketMainId)
);
// 更新维修工单子表
repairItemList.forEach(item -> {
// 这里是重新计算维修工单中的配件相关的信息写了一个公共的重新计算工单的方法替换掉
// // 计算配件的总价
// BigDecimal reduce = repairItemList.stream().map(DlRepairTitem::getItemMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
// repairTicketsService.update(new LambdaUpdateWrapper<DlRepairTickets>()
// // 工单子项总数量增加上配件的数量
// .setSql("count = count + " + repairItemList.size())
// // 工单配件总价
// .setSql("part_price = part_price + " + reduce)
// // 工单总价
// .setSql("total_price = total_price + " + reduce)
// // 参考成本
// .setSql("cost = cost + " + reduce)
// // 参考毛利
// .setSql("profit = profit + " + reduce)
// // 领料状态
// .set(DlRepairTickets::getPartStatus, "02")
// .eq(DlRepairTickets::getId, ticketMainId)
// );
// 更新维修工单子表----需要合并相同的配件故修改
// 先查维修工单的子表中的配件相关的信息
List<DlRepairTitem> oldTitem = repairTitemService.list(new LambdaQueryWrapper<DlRepairTitem>().and(i -> i.eq(DlRepairTitem::getTicketId, ticketMainId).eq(DlRepairTitem::getItemType, "02")));
// 过滤出新申请的配件里面有没有已经存在于工单子表的
List<String> waresIds = oldTitem.stream().map(DlRepairTitem::getPartId).collect(Collectors.toList());
List<DlRepairTitem> already = repairItemList.stream().filter(item -> waresIds.contains(item.getPartId())).collect(Collectors.toList());
// 更新已经存在的配件
if (CollectionUtil.isNotEmpty(already)) {
List<DlRepairTitem> updateItems = new ArrayList<>();
already.forEach(item -> {
DlRepairTitem titem = oldTitem.stream().filter(i -> i.getPartId().equals(item.getPartId())).findFirst().orElse(null);
if (titem != null) {
DlRepairTitem newItem = new DlRepairTitem();
newItem.setId(titem.getId());
newItem.setItemCount(titem.getItemCount() + item.getItemCount());
// 如果设置了折扣就用没有就是1
BigDecimal itemDiscount = titem.getItemDiscount() == null ? new BigDecimal(1) : titem.getItemDiscount();
// titem取价格newItem取数量
newItem.setItemMoney(titem.getItemPrice().multiply(BigDecimal.valueOf(newItem.getItemCount())).multiply(itemDiscount));
updateItems.add(newItem);
}
});
if (CollectionUtil.isNotEmpty(updateItems)) {
repairTitemService.updateBatchById(updateItems);
}
}
// 新增维修工单中没有的配件
List<DlRepairTitem> newItems = repairItemList.stream().filter(item -> !waresIds.contains(item.getPartId())).collect(Collectors.toList());
newItems.forEach(item -> {
// 主表id
item.setTicketId(ticketMainId);
// 类型为配件
@ -296,62 +324,76 @@ public class DlTicketWaresServiceImpl extends ServiceImpl<DlTicketWaresMapper, D
// 状态为未领料
item.setItemStatus(TicketsItemStatusEnum.WAITING_RECEIVE.getCode());
});
repairTitemService.saveBatch(repairItemList);
repairTitemService.saveBatch(newItems);
// 重新计算工单
boolean flag = repairTicketsService.computeTicket(ticketMainId);
if (!flag) {
throw exception0(500, "系统异常");
}
// 发送通过的消息给仓库
RoleReqDTO roleInfo = roleApi.getRoleInfo(RepairRoleEnum.WAREHOUSE.getCode());
List<Long> ids = permissionApi.getUserIdByRoleId(roleInfo.getId());
if (CollectionUtil.isNotEmpty(ids)){
if (CollectionUtil.isNotEmpty(ids)) {
ids.forEach(id -> repairWorkerService.sentMessage(id, "您有新的配件申请单需要处理"));
}
} else if (ObjectUtil.isNotEmpty(respVO.getStatus()) && respVO.getStatus().equals("02") && respVO.getType().equals("02")) {
// 如果通过退料也需要更新
// 更新维修工单
// 计算配件的总价
BigDecimal reduce = respVO.getWares().stream().map(DlRepairTitem::getItemMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
repairTicketsService.update(new LambdaUpdateWrapper<DlRepairTickets>()
// 工单子项总数量增加上配件的数量
.setSql("count = count - " + respVO.getWares().size())
// 工单配件总价
.setSql("part_price = part_price - " + reduce)
// 工单总价
.setSql("total_price = total_price - " + reduce)
// 参考成本
.setSql("cost = cost - " + reduce)
// 参考毛利
.setSql("profit = profit - " + reduce)
// 领料状态
.set(DlRepairTickets::getPartStatus, "02")
.eq(DlRepairTickets::getId, respVO.getTicketId())
);
// 维修工单子表对应的数据更新
// 先查数据出来
List<DlRepairTitem> list = repairTitemService.list(new LambdaQueryWrapper<DlRepairTitem>().and(i -> {
i.eq(DlRepairTitem::getTicketId, respVO.getTicketId())
.in(DlRepairTitem::getPartId, respVO.getWares().stream().map(DlRepairTitem::getPartId).collect(Collectors.toList()));
}));
list.forEach(item -> {
respVO.getWares().stream().filter(i -> i.getPartId().equals(item.getPartId())).findFirst().ifPresent(i -> {
// 如果只是退部分就减少数量
if (!i.getItemCount().equals(item.getItemCount())) {
repairTitemService.update(new LambdaUpdateWrapper<DlRepairTitem>()
.setSql("item_count = item_count - " + i.getItemCount())
.setSql("item_money = item_money - " + i.getItemMoney())
.and(x -> {
x.eq(DlRepairTitem::getTicketId, respVO.getTicketId()).eq(DlRepairTitem::getPartId, item.getPartId());
})
);
} else {
// 如果是全部退了就直接删掉数据
repairTitemService.removeById(item.getId());
}
});
});
}
// 如果是驳回通知维修工
if (status.equals("05")){
// 发送没有通过的消息给员工
DlTicketWares ticketWares = baseMapper.selectById(respVO.getId());
repairWorkerService.sentMessage(ticketWares.getRepairId(), "您的配件申请单被驳回了");
}
// 下面的代码为退料申请单通过的代码但没有退料申请单可以注掉但防止有问题所以先不删除
// } else if (ObjectUtil.isNotEmpty(respVO.getStatus()) && respVO.getStatus().equals("02") && respVO.getType().equals("02")) {
// // 如果通过退料也需要更新
// // 更新维修工单
// // 计算配件的总价
// BigDecimal reduce = respVO.getWares().stream().map(DlRepairTitem::getItemMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
// repairTicketsService.update(new LambdaUpdateWrapper<DlRepairTickets>()
// // 工单子项总数量增加上配件的数量
// .setSql("count = count - " + respVO.getWares().size())
// // 工单配件总价
// .setSql("part_price = part_price - " + reduce)
// // 工单总价
// .setSql("total_price = total_price - " + reduce)
// // 参考成本
// .setSql("cost = cost - " + reduce)
// // 参考毛利
// .setSql("profit = profit - " + reduce)
// // 领料状态
// .set(DlRepairTickets::getPartStatus, "02")
// .eq(DlRepairTickets::getId, respVO.getTicketId())
// );
// // 维修工单子表对应的数据更新
// // 先查数据出来
// List<DlRepairTitem> list = repairTitemService.list(new LambdaQueryWrapper<DlRepairTitem>().and(i -> {
// i.eq(DlRepairTitem::getTicketId, respVO.getTicketId())
// .in(DlRepairTitem::getPartId, respVO.getWares().stream().map(DlRepairTitem::getPartId).collect(Collectors.toList()));
// }));
// list.forEach(item -> {
// respVO.getWares().stream().filter(i -> i.getPartId().equals(item.getPartId())).findFirst().ifPresent(i -> {
// // 如果只是退部分就减少数量
// if (!i.getItemCount().equals(item.getItemCount())) {
// repairTitemService.update(new LambdaUpdateWrapper<DlRepairTitem>()
// .setSql("item_count = item_count - " + i.getItemCount())
// .setSql("item_money = item_money - " + i.getItemMoney())
// .and(x -> {
// x.eq(DlRepairTitem::getTicketId, respVO.getTicketId()).eq(DlRepairTitem::getPartId, item.getPartId());
// })
// );
// } else {
// // 如果是全部退了就直接删掉数据
// repairTitemService.removeById(item.getId());
// }
// });
// });
//
// // 发送没有通过的消息给员工
// DlTicketWares ticketWares = baseMapper.selectById(respVO.getId());
// repairWorkerService.sentMessage(ticketWares.getRepairId(), "您的配件申请单被驳回了");
// }
}
/**
@ -412,7 +454,7 @@ public class DlTicketWaresServiceImpl extends ServiceImpl<DlTicketWaresMapper, D
同理通知领料的数量可能与实际需要的数量不一致需要重新计算状态
*/
// 先查老数据领料才需要更新
if (type.equals("02")){
if (type.equals("02")) {
List<DlTwItem> oldData = twItemService.list(new LambdaQueryWrapper<DlTwItem>().in(DlTwItem::getId, respVO.getItems().stream().map(DlTwItem::getId).collect(Collectors.toList())));
// 构造新数据
List<DlTwItem> newData = oldData.stream().map(item -> {
@ -492,7 +534,7 @@ public class DlTicketWaresServiceImpl extends ServiceImpl<DlTicketWaresMapper, D
respVO.setAdviserId(Long.valueOf(tickets.getAdviserId()));
respVO.setAdviserName(tickets.getAdviserName());
this.save(respVO);
if(!respVO.getItems().isEmpty()){
if (!respVO.getItems().isEmpty()) {
List<DlTwItem> list = respVO.getItems().stream().map(dlTwItem -> dlTwItem.setTwId(respVO.getId())).collect(Collectors.toList());
twItemService.saveBatch(list);
}
@ -509,8 +551,8 @@ public class DlTicketWaresServiceImpl extends ServiceImpl<DlTicketWaresMapper, D
public Map<String, Integer> getWorkerTodo() {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
LambdaQueryWrapper<DlTicketWares> queryWrapper = new LambdaQueryWrapper<DlTicketWares>()
.eq(DlTicketWares::getRepairId,loginUser.getId())
.eq(DlTicketWares::getType,"01");
.eq(DlTicketWares::getRepairId, loginUser.getId())
.eq(DlTicketWares::getType, "01");
List<DlTicketWares> list = this.list(queryWrapper);
Map<String, Integer> rtnMap = new HashMap<>();
//所有提交的
@ -520,23 +562,23 @@ public class DlTicketWaresServiceImpl extends ServiceImpl<DlTicketWaresMapper, D
//未通过的
Integer noAllowNum = 0;
//待确认领料单
Integer waitingReceiveNum = dlRepairSoMapper.selectCountNum("02",loginUser.getId(), SoStatusEnum.TO_BE_PICKED.getCode());
Integer waitingReceiveNum = dlRepairSoMapper.selectCountNum("02", loginUser.getId(), SoStatusEnum.TO_BE_PICKED.getCode());
//待确认退料单
Integer waitingBackNum = dlRepairSoMapper.selectCountNum("04",loginUser.getId(), SoStatusEnum.TO_BE_RETURNED.getCode());
for (DlTicketWares wares:list){
if("02".equals(wares.getStatus())){
Integer waitingBackNum = dlRepairSoMapper.selectCountNum("04", loginUser.getId(), SoStatusEnum.TO_BE_RETURNED.getCode());
for (DlTicketWares wares : list) {
if ("02".equals(wares.getStatus())) {
//已通过
allowNum++;
}else if("05".equals(wares.getStatus())){
} else if ("05".equals(wares.getStatus())) {
//被驳回
noAllowNum++;
}
}
rtnMap.put("submitNum",submitNum);
rtnMap.put("allowNum",allowNum);
rtnMap.put("noAllowNum",noAllowNum);
rtnMap.put("waitingReceiveNum",waitingReceiveNum);
rtnMap.put("waitingBackNum",waitingBackNum);
rtnMap.put("submitNum", submitNum);
rtnMap.put("allowNum", allowNum);
rtnMap.put("noAllowNum", noAllowNum);
rtnMap.put("waitingReceiveNum", waitingReceiveNum);
rtnMap.put("waitingBackNum", waitingBackNum);
return rtnMap;
}

View File

@ -185,7 +185,7 @@
-- 查待处理数据 --
select drt.*
from dl_repair_tickets drt
where (drt.deleted = '0') AND drt.tickets_status IN ('04','05','01')
where (drt.deleted = '0') AND drt.tickets_status IN ('04','05','01','07')
<if test="map.ticketNo != null and map.ticketNo != ''">
and (
drt.ticket_no like concat('%', #{map.ticketNo}, '%')

View File

@ -1,26 +1,112 @@
package cn.iocoder.yudao.module.rescue.controller.admin;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.rescue.service.IRescueCarInfoService;
import cn.iocoder.yudao.module.rescue.service.IRescueInfoService;
import cn.iocoder.yudao.module.rescue.service.IRescueOrderInfoService;
import cn.iocoder.yudao.module.rescue.service.IRescueRefuelRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 大屏数据统计
*/
@RestController
@RequestMapping("/rescue/bigScree")
public class RescueBigScreeController {
@Autowired
private IRescueOrderInfoService rescueOrderInfoService;
@Autowired
private IRescueRefuelRecordService rescueRefuelRecordService;
@Autowired
private IRescueInfoService rescueInfoService;
@Autowired
private IRescueCarInfoService rescueCarInfoService;
/**
* 救援大屏救援订单接口
*
* @param type count 数量 money 金额
* @param type count 数量 money 金额
* @param timeType day month year
* @return
*/
@GetMapping("/getRescueOrderCount")
public CommonResult getRescueOrderCount(String type, String timeType){
return CommonResult.success(rescueOrderInfoService.getRescueOrderCount(type,timeType));
public CommonResult getRescueOrderCount(String type, String timeType) {
return CommonResult.success(rescueOrderInfoService.getRescueOrderCount(type, timeType));
}
/**
* 救援大屏日常费用统计接口
* @param timeType day week month
* @return
*/
@GetMapping("/getRescueExpenseCount")
public CommonResult getRescueExpenseCount(String timeType) {
return CommonResult.success(rescueRefuelRecordService.getRescueExpenseCount(timeType));
}
/**
* 救援大屏获取经营分析接口
* @return
*/
@GetMapping("/getManageAnalyze")
public CommonResult getManageAnalyze(String timeType) {
if (ObjectUtil.isEmpty(timeType)){
timeType = "month";
}
return CommonResult.success(rescueInfoService.getManageAnalyze(timeType));
}
/**
* 救援大屏获取出车次数统计接口
* @param timeType day month year
* @return
*/
@GetMapping("/getDrawOutAVehicleCount")
public CommonResult getDrawOutAVehicleCount(String timeType) {
return CommonResult.success(rescueInfoService.getDrawOutAVehicleCount(timeType));
}
/**
* 救援大屏获取司机排名接口
* @param timeType recentMonth 近一月 recentYear 近一年 recentQuarter 近季度
* @return
*/
@GetMapping("/getDriverSort")
public CommonResult getDriverSort(String timeType){
return CommonResult.success(rescueInfoService.getDriverSort(timeType));
}
/**
* 救援大屏获取车辆预警接口
* @param type keep 保养 insurance 保险 check 年审
* @return
*/
@GetMapping("/getRescueCarEarlyWarning")
public CommonResult getRescueCarEarlyWarning(String type){
return CommonResult.success(rescueCarInfoService.getRescueCarEarlyWarning(type));
}
/**
* 救援大屏获取救援订单占比接口
* @return
*/
@GetMapping("/getRescueOrderByRoad")
public CommonResult getRescueOrderByRoad(){
return CommonResult.success(rescueInfoService.getRescueOrderByRoad());
}
/**
* 救援大屏获取救援详细数据接口
* @param startTime 开始时间
* @param endTime 结束时间
* @return
*/
@GetMapping("/getRescueStatistics")
public CommonResult getRescueMessage(String startTime, String endTime){
return CommonResult.success(rescueInfoService.getRescueMessage(startTime,endTime));
}
}

View File

@ -9,6 +9,7 @@ import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* 救援车辆信息Mapper接口
@ -69,4 +70,11 @@ public interface RescueCarInfoMapper extends BaseMapper<RescueCarInfo>
List<RescueCarInfo> warnListBy( @Param("warnTime")String warnTime);
List<RescueCarInfo> warnListBx(@Param("warnTime")String warnTime);
List<RescueCarInfo> warnListNj(@Param("warnTime")String warnTime);
/**
* 救援大屏获取车辆预警接口
* @param type keep 保养 insurance 保险 check 年审
* @return
*/
List<Map<String, Object>> selectRescueCarEarlyWarning(String type);
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.rescue.mapper;
import cn.hutool.core.date.DateTime;
import cn.iocoder.yudao.module.rescue.domain.DriverInfo;
import cn.iocoder.yudao.module.rescue.domain.RescueInfo;
import cn.iocoder.yudao.module.rescue.dto.DriverInfo2Dto;
@ -69,4 +70,21 @@ public interface RescueInfoMapper extends BaseMapper<RescueInfo>
* @date 10:46 2024/9/5
**/
List<BuckleVO> listBuckle();
List<Map<String, Object>> selectManageAnalyze(@Param("startTime") DateTime startTime,@Param("endTime") DateTime endTime,@Param("tenantId") Long tenantId);
/**
* 获取司机排序
* @param startTime
* @param endTime
* @return
*/
List<Map<String, Object>> selectDriverSort(@Param("startTime") DateTime startTime,@Param("endTime") DateTime endTime);
/**
* 救援大屏获取救援订单占比接口
* @param dictType
* @return
*/
List<Map<String, Object>> selectRescueOrderByRoad(String dictType);
}

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
/**
* 救援车辆信息Service接口
@ -70,4 +71,11 @@ public interface IRescueCarInfoService extends IService<RescueCarInfo>
*/
public int deleteRescueCarInfoById(Long id);
List<String> warnList(RescueCarInfo rescueCarInfo);
/**
* 救援大屏获取车辆预警接口
* @param type keep 保养 insurance 保险 check 年审
* @return
*/
List<Map<String, Object>> getRescueCarEarlyWarning(String type);
}

View File

@ -134,4 +134,39 @@ public interface IRescueInfoService extends IService<RescueInfo>
* @param returnCarVO 订单信息
**/
void inBase(ReturnCarVO returnCarVO);
/**
* 获取经营分析
* @param timeType
* @return
*/
List<Map<String, Object>> getManageAnalyze(String timeType);
/**
* 救援大屏获取出车次数统计
* @param timeType
* @return
*/
Map<String, Object> getDrawOutAVehicleCount(String timeType);
/**
* 救援大屏获取司机排名
* @param timeType
* @return
*/
List<Map<String, Object>> getDriverSort(String timeType);
/**
* 救援大屏获取救援订单占比接口
* @return
*/
List<Map<String, Object>> getRescueOrderByRoad();
/**
* 救援大屏获取救援详细数据
* @param startTime
* @param endTime
* @return
*/
Map<String, Object> getRescueMessage(String startTime, String endTime);
}

View File

@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
/**
* 加油记录Service接口
@ -67,4 +68,11 @@ public interface IRescueRefuelRecordService extends IService<RescueRefuelRecord
public int deleteRescueRefuelRecordById(Long id);
public JSONObject getMonthRescueRefuelRecord(Long driverId, String time, Long carId);
JSONObject listData(RescueInfo rescueInfo);
/**
* 救援大屏日常费用统计
* @param timeType day week month
* @return
*/
Map<String, Object> getRescueExpenseCount(String timeType);
}

View File

@ -2,6 +2,7 @@ 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.rescue.domain.RescueCarInfo;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.module.rescue.mapper.RescueCarInfoMapper;
@ -18,6 +19,7 @@ import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;
@ -161,4 +163,18 @@ public class RescueCarInfoServiceImpl extends ServiceImpl<RescueCarInfoMapper, R
}
return res;
}
/**
* 救援大屏获取车辆预警接口
*
* @param type keep 保养 insurance 保险 check 年审
* @return
*/
@Override
public List<Map<String, Object>> getRescueCarEarlyWarning(String type) {
if (ObjectUtil.isEmpty(type)){
return null;
}
return baseMapper.selectRescueCarEarlyWarning(type);
}
}

View File

@ -1,11 +1,13 @@
package cn.iocoder.yudao.module.rescue.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.appBase.domain.SysAnnouncement;
import cn.iocoder.yudao.module.appBase.service.ISysAnnouncementService;
@ -16,6 +18,7 @@ import cn.iocoder.yudao.module.rescue.dto.DriverInfoDto;
import cn.iocoder.yudao.module.rescue.dto.TaskDto;
import cn.iocoder.yudao.module.rescue.mapper.RescueInfoMapper;
import cn.iocoder.yudao.module.rescue.service.*;
import cn.iocoder.yudao.module.rescue.utils.DateUtils;
import cn.iocoder.yudao.module.rescue.utils.RedisUtil;
import cn.iocoder.yudao.module.rescue.utils.RedissonDelayQueue;
import cn.iocoder.yudao.module.rescue.utils.StringUtils;
@ -49,6 +52,7 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -1235,4 +1239,183 @@ public class RescueInfoServiceImpl extends ServiceImpl<RescueInfoMapper, RescueI
rescueInfo.setRescueStatus("9");
baseMapper.updateById(rescueInfo);
}
/**
* 获取经营分析
*
* @param timeType
* @return
*/
@TenantIgnore
@Override
public List<Map<String, Object>> getManageAnalyze(String timeType) {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
Map<String, Object> map = DateUtils.getDateTimeList(timeType);
DateTime startTime = (DateTime) map.get("startTime");
DateTime endTime = (DateTime) map.get("endTime");
List<Map<String, Object>> list = baseMapper.selectManageAnalyze(startTime, endTime,loginUser.getTenantId());
return list;
}
/**
* 救援大屏获取出车次数统计
*
* @param timeType
* @return
*/
@Override
public Map<String, Object> getDrawOutAVehicleCount(String timeType) {
//获取日期范围startTimeendTime
Map<String, Object> dateMap = DateUtils.getDateTimeList(timeType);
List<DateTime> dateList = (List<DateTime>) dateMap.get("dateList");
DateTime startTime = (DateTime) dateMap.get("startTime");
DateTime endTime = (DateTime) dateMap.get("endTime");
//根据日期范围查询救援订单
List<RescueInfo> rescueOrderInfos = this.list(new LambdaQueryWrapper<RescueInfo>()
.between(RescueInfo::getRescueTime, startTime, endTime));
List<String> xList = new ArrayList<>();
List<Long> yList = new ArrayList<>();
// 遍历日期列表获取每个日期对应的订单数量
for (DateTime dateTime : dateList) {
//echarts x轴
String dateName = DateUtils.getDateName(timeType, dateTime);
xList.add(dateName);
List<RescueInfo> infos = filterRescueInfoByDate(rescueOrderInfos, dateTime, DateUtils.getEndTime(timeType, dateTime));
//echarts y轴
long count = infos.stream().count();
yList.add(count);
}
Map<String, Object> map = new HashMap<>();
map.put("xList", xList);
map.put("yList", yList);
return map;
}
/**
* 救援大屏获取司机排名
*
* @param timeType
* @return
*/
@Override
public List<Map<String, Object>> getDriverSort(String timeType) {
Map<String, Object> map = DateUtils.getDateTimeList(timeType);
DateTime startTime = (DateTime) map.get("startTime");
DateTime endTime = (DateTime) map.get("endTime");
return baseMapper.selectDriverSort(startTime, endTime);
}
/**
* 救援大屏获取救援订单占比接口
*
* @return
*/
@Override
public List<Map<String, Object>> getRescueOrderByRoad() {
LoginUser user = SecurityFrameworkUtils.getLoginUser();
return baseMapper.selectRescueOrderByRoad("kcRescueRoad-" + user.getTenantId());
}
/**
* 救援大屏获取救援详细数据
*
* @param startTime
* @param endTime
* @return
*/
@Override
public Map<String, Object> getRescueMessage(String startTime, String endTime) {
Map<String, Object> resp = new HashMap<>();
// .查询救援订单
List<RescueOrderInfo> rescueOrders = rescueOrderInfoService.list(new LambdaQueryWrapper<RescueOrderInfo>()
.between(RescueOrderInfo::getCreateTime, startTime, endTime));
// 1.计算救援金额
long totalRescueMoney = rescueOrders.stream().mapToLong(order -> order.getPayMoney() != null ? order.getPayMoney() : 0L).sum();
resp.put("totalRescueMoney", totalRescueMoney);
// 2.计算出车次数
long totalOutCarCount = rescueOrders.size();
resp.put("totalOutCarCount", totalOutCarCount);
// 3.计算待支付订单数量
long totalPayOrderCount = rescueOrders.stream().filter(info -> info.getOrderStatus().equals("1")).count();
resp.put("totalPayOrderCount", totalPayOrderCount);
// .查询加油记录表
List<RescueRefuelRecord> rescueRefuelRecords = refuelRecordService.list(new LambdaQueryWrapper<RescueRefuelRecord>()
.between(RescueRefuelRecord::getRecordTime, startTime, endTime));
// 1.计算加油金额
Double totalRefuelMoney = rescueRefuelRecords.stream().mapToDouble(RescueRefuelRecord::getRefuelMoney).sum();
resp.put("totalRefuelMoney", totalRefuelMoney);
// .查询救援信息表
List<RescueInfo> rescueInfos = baseMapper.selectList(new LambdaQueryWrapper<RescueInfo>()
.between(RescueInfo::getRescueTime, startTime, endTime));
// 1.计算待取车数量
long totalWaitCarCount = rescueInfos.stream().filter(info -> info.getRescueStatus().equals("6")).count();
resp.put("totalWaitCarCount", totalWaitCarCount);
// 2.计算救援中数量
long totalRescueingCarCount = rescueInfos.stream().filter(info -> info.getRescueStatus().equals("3")).count();
resp.put("totalRescueingCarCount", totalRescueingCarCount);
// 3.计算已完成数量
long totalCompletedCarCount = rescueInfos.stream().filter(info -> info.getRescueStatus().equals("5")).count();
resp.put("totalCompletedCarCount", totalCompletedCarCount);
// 4.计算扣车中
long totalDeductedCarCount = rescueInfos.stream().filter(info -> info.getRescueStatus().equals("9")).count();
resp.put("totalDeductedCarCount", totalDeductedCarCount);
// 5.计算以还车
long totalReturnCarCount = rescueInfos.stream().filter(info -> info.getRescueStatus().equals("8")).count();
resp.put("totalReturnCarCount", totalReturnCarCount);
// .查询司机提成表
Double rescueTcBig = 0d;
Double rescueTcMid = 0d;
Double rescueTcSmall = 0d;
RescueConfig rescueConfig = rescueConfigService.selectRescueConfigByDeptId();
if (ObjectUtils.isNotEmpty(rescueConfig)) {
rescueTcBig = Optional.ofNullable(rescueConfig.getRescueTcBig()).orElse(0d);
rescueTcMid = Optional.ofNullable(rescueConfig.getRescueTcMid()).orElse(0d);
rescueTcSmall = Optional.ofNullable(rescueConfig.getRescueTcSmall()).orElse(0d);
}
Double totalRoyaltyMoney = 0d;
// 1.将救援信息转为map
Map<Long, RescueInfo> rescueInfoMap = rescueInfos.stream().collect(Collectors.toMap(RescueInfo::getId, Function.identity()));
// 2.循环救援订单 计算提成
for (RescueOrderInfo info : rescueOrders) {
RescueInfo rescueInfo = rescueInfoMap.get(info.getRescueInfoId());
if (ObjectUtil.isNotNull(rescueInfo) && ObjectUtil.isNotEmpty(rescueInfo.getCarType())) {
String carType = rescueInfo.getCarType();
Double tempSetMoney = ObjectUtils.isNotEmpty(info.getSetMoney()) ? Double.valueOf(info.getSetMoney()) / 100d : 0d;
switch (carType) {
case "1":
// 大车
totalRoyaltyMoney += tempSetMoney * rescueTcBig;
break;
case "2":
// 中车
totalRoyaltyMoney += tempSetMoney * rescueTcMid;
break;
case "3":
// 小车
totalRoyaltyMoney += tempSetMoney * rescueTcSmall;
break;
}
}
}
resp.put("totalRoyaltyMoney", totalRoyaltyMoney);
return resp;
}
public List<RescueInfo> filterRescueInfoByDate(List<RescueInfo> rescueInfos, Date startTime, Date endTime) {
return rescueInfos.stream()
.filter(info -> info.getRescueTime() != null &&
!info.getRescueTime().before(startTime) &&
!info.getRescueTime().after(endTime))
.collect(Collectors.toList());
}
}

View File

@ -7,6 +7,7 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.module.rescue.domain.*;
import cn.iocoder.yudao.module.rescue.utils.DateUtils;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.rescue.service.*;
import cn.iocoder.yudao.module.rescue.utils.pay.AesUtil;
@ -326,45 +327,18 @@ public class RescueOrderInfoServiceImpl extends ServiceImpl<RescueOrderInfoMappe
@Override
public List<Map<String, Object>> getRescueOrderCount(String type, String timeType) {
List<Map<String, Object>> res = new ArrayList<>();
DateTime startTime = DateUtil.date();
DateTime endTime = new DateTime();
List<DateTime> dateList = new ArrayList<>();
switch (timeType) {
case "day":
startTime = DateUtil.beginOfDay(startTime);
endTime = DateUtil.endOfDay(endTime);
dateList = DateUtil.rangeToList(startTime, endTime, DateField.HOUR_OF_DAY);
break;
case "month":
startTime = DateUtil.beginOfMonth(startTime);
endTime = DateUtil.endOfMonth(endTime);
dateList = DateUtil.rangeToList(startTime, endTime, DateField.DAY_OF_MONTH);
break;
case "year":
startTime = DateUtil.beginOfYear(startTime);
endTime = DateUtil.endOfYear(endTime);
dateList = DateUtil.rangeToList(startTime, endTime, DateField.MONTH);
break;
}
Map<String, Object> resp = DateUtils.getDateTimeList(timeType);
List<DateTime> dateList = (List<DateTime>) resp.get("dateList");
DateTime startTime = (DateTime) resp.get("startTime");
DateTime endTime = (DateTime) resp.get("endTime");
LambdaQueryWrapper<RescueOrderInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.between(RescueOrderInfo::getCreateTime, startTime, endTime);
queryWrapper.eq(RescueOrderInfo::getOrderStatus, "3");
List<RescueOrderInfo> list = this.list(queryWrapper);
for (DateTime dateTime : dateList) {
String name = "";
switch (timeType) {
case "day":
name = dateTime.toString("HH:mm");
break;
case "month":
name = dateTime.toString("MM-dd");
break;
case "year":
name = dateTime.toString("YYYY-MM");
break;
}
String name = DateUtils.getDateName(timeType, dateTime);
Map<String, Object> map = new HashMap<>();
DateTime endTime1 = getEndTime(timeType, dateTime);
DateTime endTime1 = DateUtils.getEndTime(timeType, dateTime);
List<RescueOrderInfo> rescueOrderInfos = filterOrdersByDate(list, dateTime, endTime1);
map.put("name", name);
if ("count".equals(type)) {
@ -385,18 +359,13 @@ public class RescueOrderInfoServiceImpl extends ServiceImpl<RescueOrderInfoMappe
return res;
}
public DateTime getEndTime(String timeType, DateTime startTime){
switch (timeType) {
case "day":
return DateUtil.endOfHour(startTime);
case "month":
return DateUtil.endOfDay(startTime);
case "year":
return DateUtil.endOfMonth(startTime);
}
return null;
}
/**
* 根据日期范围过滤订单
* @param orders
* @param startDate
* @param endDate
* @return
*/
public List<RescueOrderInfo> filterOrdersByDate(List<RescueOrderInfo> orders, Date startDate, Date endDate) {
return orders.stream()
.filter(order -> order.getOrderTime() != null &&

View File

@ -1,17 +1,26 @@
package cn.iocoder.yudao.module.rescue.service.impl;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.module.rescue.domain.RescueCarSpend;
import cn.iocoder.yudao.module.rescue.domain.RescueInfo;
import cn.iocoder.yudao.module.rescue.domain.RescueOrderInfo;
import cn.iocoder.yudao.module.rescue.domain.RescueRefuelRecord;
import cn.iocoder.yudao.module.rescue.mapper.RescueCarSpendMapper;
import cn.iocoder.yudao.module.rescue.service.IRescueRefuelRecordService;
import cn.iocoder.yudao.module.rescue.utils.DateUtils;
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 com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.iocoder.yudao.module.rescue.mapper.RescueRefuelRecordMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
* 加油记录Service业务层处理
@ -22,6 +31,8 @@ import java.util.List;
@Service
public class RescueRefuelRecordServiceImpl extends ServiceImpl<RescueRefuelRecordMapper, RescueRefuelRecord> implements IRescueRefuelRecordService {
@Autowired
private RescueCarSpendMapper rescueCarSpendMapper;
/**
* 查询加油记录
*
@ -100,4 +111,91 @@ public class RescueRefuelRecordServiceImpl extends ServiceImpl<RescueRefuelRecor
public JSONObject listData(RescueInfo rescueInfo) {
return baseMapper.listData(rescueInfo);
}
/**
* 救援大屏日常费用统计
*
* @param timeType day week month
* @return
*/
@Override
public Map<String, Object> getRescueExpenseCount(String timeType) {
Map<String, Object> map = new HashMap<>();
Map<String, Object> resp = DateUtils.getDateTimeList(timeType);
List<DateTime> dateList = (List<DateTime>) resp.get("dateList");
DateTime startTime = (DateTime) resp.get("startTime");
DateTime endTime = (DateTime) resp.get("endTime");
//根据开始时间与结束时间查询救援车加油记录表
List<RescueRefuelRecord> rescueRefuelRecords = baseMapper.selectList(new LambdaQueryWrapper<RescueRefuelRecord>()
.between(RescueRefuelRecord::getRecordTime, startTime, endTime));
//根据开始时间与结束时间查询救援测保养费用
List<RescueCarSpend> rescueCarSpends = rescueCarSpendMapper.selectList(new LambdaQueryWrapper<RescueCarSpend>()
.between(RescueCarSpend::getMaintenanceTime, startTime, endTime));
//燃油费统计
double reefuleSum = rescueRefuelRecords.stream()
.filter(Objects::nonNull) // 过滤掉 null 对象
.filter(refule -> Objects.nonNull(refule.getRefuelMoney())) // 过滤掉 payMoney null 的对象
.mapToDouble(RescueRefuelRecord::getRefuelMoney) // 获取支付金额
.sum();// 计算总和
map.put("totalRefuelMoney", reefuleSum);
//保养费统计
double maintenanceSum = rescueCarSpends.stream()
.filter(Objects::nonNull) // 过滤掉 null 对象
.filter(maintenance -> Objects.nonNull(maintenance.getMaintenanceMoney())) // 过滤掉 payMoney null 的对象
.mapToDouble(RescueCarSpend::getMaintenanceMoney) // 获取支付金额
.sum();// 计算总和
map.put("totalMaintenanceMoney", maintenanceSum);
//echarts 数据
List<List<Object>> dataList = new ArrayList<>();
List<Object> titleList = new ArrayList<>();
titleList.add("product");
titleList.add("油费");
titleList.add("保养");
dataList.add(titleList);
for (DateTime dateTime : dateList) {
List<Object> list = new ArrayList<>();
String dateName = DateUtils.getDateName(timeType, dateTime);
list.add(dateName);
endTime = DateUtils.getEndTime(timeType, dateTime);
Map<String, Double> maps = getTotalRefuelAndMaintenanceData(rescueRefuelRecords, rescueCarSpends, dateTime, endTime);
list.add(maps.get("totalRefuelMoney"));
list.add(maps.get("totalMaintenanceMoney"));
dataList.add(list);
}
map.put("source", dataList);
return map;
}
/**
* 根据救援加油记录与救援保养记录计算总加油费用与总保养费用通过时间筛选
* @param refuelRecords
* @param carSpends
* @param startTime 开始时间
* @param endTime 结束时间
* @return
*/
public Map<String, Double> getTotalRefuelAndMaintenanceData(
List<RescueRefuelRecord> refuelRecords,
List<RescueCarSpend> carSpends,
Date startTime,
Date endTime) {
double totalRefuelMoney = refuelRecords.stream()
.filter(record -> record.getRecordTime().after(startTime) && record.getRecordTime().before(endTime))
.mapToDouble(RescueRefuelRecord::getRefuelMoney)
.sum();
double totalMaintenanceMoney = carSpends.stream()
.filter(spend -> spend.getMaintenanceTime().after(startTime) && spend.getMaintenanceTime().before(endTime))
.mapToDouble(RescueCarSpend::getMaintenanceMoney)
.sum();
Map<String, Double> result = new HashMap<>();
result.put("totalRefuelMoney", totalRefuelMoney);
result.put("totalMaintenanceMoney", totalMaintenanceMoney);
return result;
}
}

View File

@ -1,12 +1,15 @@
package cn.iocoder.yudao.module.rescue.utils;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import org.apache.commons.lang3.time.DateFormatUtils;
import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Date;
import java.util.*;
/**
* 时间工具类
@ -185,4 +188,115 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
return Date.from(zdt.toInstant());
}
/**
* 通过时间类型开始时间计算结束时间
* @param timeType
* @param startTime
* @return
*/
public static DateTime getEndTime(String timeType, DateTime startTime) {
switch (timeType) {
case "day":
return DateUtil.endOfDay(startTime);
case "week":
return DateUtil.endOfWeek(startTime);
case "month":
return DateUtil.endOfMonth(startTime);
case "year":
return DateUtil.endOfYear(startTime);
case "recentYear":
return DateUtil.endOfYear(startTime);
case "recentMonth":
return DateUtil.endOfMonth(startTime);
case "recentQuarter":
DateTime endOfQuarter = DateUtil.offsetMonth(startTime, 3);
return DateUtil.endOfDay(DateUtil.offsetDay(endOfQuarter, -1));
default:
return null;
}
}
/**
* 获取时间名称根据时间类型
* @param timeType
* @param dateTime
* @return
*/
public static String getDateName(String timeType, DateTime dateTime) {
String name = "";
switch (timeType) {
case "day":
name = dateTime.toString("HH:mm");
break;
case "month":
case "week":
case "recentMonth":
name = dateTime.toString("MM-dd");
break;
case "year":
case "recentYear":
case "recentQuarter":
name = dateTime.toString("YYYY-MM");
break;
}
return name;
}
/**
* 获取时间列表根据时间类型
* @param timeType
* @return
*/
public static Map<String, Object> getDateTimeList(String timeType) {
Map<String, Object> result = new HashMap<>();
DateTime now = DateUtil.date();
DateTime startTime = now;
DateTime endTime = now;
List<DateTime> dateList = new ArrayList<>();
switch (timeType) {
case "day":
startTime = DateUtil.beginOfDay(startTime);
endTime = DateUtil.endOfDay(endTime);
dateList = DateUtil.rangeToList(startTime, endTime, DateField.HOUR_OF_DAY);
break;
case "week":
startTime = DateUtil.beginOfWeek(startTime);
endTime = DateUtil.endOfWeek(endTime);
dateList = DateUtil.rangeToList(startTime, endTime, DateField.DAY_OF_WEEK);
break;
case "month":
startTime = DateUtil.beginOfMonth(startTime);
endTime = DateUtil.endOfMonth(endTime);
dateList = DateUtil.rangeToList(startTime, endTime, DateField.DAY_OF_MONTH);
break;
case "year":
startTime = DateUtil.beginOfYear(startTime);
endTime = DateUtil.endOfYear(endTime);
dateList = DateUtil.rangeToList(startTime, endTime, DateField.MONTH);
break;
case "recentYear":
startTime = DateUtil.offsetYear(now, -1);
endTime = now;
dateList = DateUtil.rangeToList(startTime, endTime, DateField.MONTH);
break;
case "recentMonth":
startTime = DateUtil.offsetMonth(now, -1);
endTime = now;
dateList = DateUtil.rangeToList(startTime, endTime, DateField.DAY_OF_MONTH);
break;
case "recentQuarter":
startTime = DateUtil.offsetMonth(now, -3);
endTime = now;
dateList = DateUtil.rangeToList(startTime, endTime, DateField.MONTH);
break;
}
result.put("dateList", dateList);
result.put("startTime", startTime);
result.put("endTime", endTime);
return result;
}
}

View File

@ -163,4 +163,22 @@
FROM `rescue_car_info`
where car_check_time <![CDATA[<]]> #{warnTime}
</select>
<select id="selectRescueCarEarlyWarning" resultType="java.util.Map">
SELECT
rescue_car_num AS carNum,
rescue_car_brand AS carBrand,
<if test="type == 'keep'">
DATEDIFF(CURRENT_DATE, car_keep_time) AS day
</if>
<if test="type == 'insurance'">
DATEDIFF(CURRENT_DATE, car_insurance_time) AS day
</if>
<if test="type == 'check'">
DATEDIFF(CURRENT_DATE, car_check_time) AS day
</if>
FROM
rescue_car_info
ORDER BY
day DESC
</select>
</mapper>

View File

@ -439,4 +439,57 @@
LEFT JOIN system_dept sd ON t1.dept_id = sd.id
ORDER BY sd.id desc
</select>
<select id="selectManageAnalyze" resultType="java.util.Map">
WITH rescue_types AS (
SELECT '1' AS rescue_type, '拖车' AS rescue_type_desc
UNION ALL SELECT '2', '送油'
UNION ALL SELECT '3', '搭电'
UNION ALL SELECT '4', '换台'
UNION ALL SELECT '5', '扣车'
)
SELECT
rt.rescue_type_desc AS rescueType,
COUNT(ri.rescue_type) AS typeCount,
ROUND((COUNT(ri.rescue_type) * 100.0 / NULLIF((SELECT COUNT(*) FROM rescue_info WHERE deleted = b'0' AND rescue_time BETWEEN #{startTime} AND #{endTime} AND tenant_id = #{tenantId}), 0)), 2) AS percentage
FROM
rescue_types rt
LEFT JOIN
rescue_info ri ON rt.rescue_type = ri.rescue_type
AND ri.rescue_time BETWEEN #{startTime} AND #{endTime}
AND ri.tenant_id = #{tenantId}
GROUP BY
rt.rescue_type_desc
ORDER BY
rt.rescue_type;
</select>
<select id="selectDriverSort" resultType="java.util.Map">
SELECT
ROW_NUMBER() OVER (ORDER BY COALESCE(SUM(roi.pay_money), 0) DESC) AS sort,
su.nickname,
COALESCE(SUM(roi.set_money), 0) AS money,
COALESCE(COUNT(roi.id), 0) AS count
FROM
driver_info di
LEFT JOIN
system_users su ON di.user_id = su.id
LEFT JOIN
rescue_info ri ON di.id = ri.driver_id
LEFT JOIN
rescue_order_info roi ON ri.id = roi.rescue_info_id
WHERE roi.pay_time BETWEEN #{startTime} AND #{endTime}
GROUP BY
su.nickname,
di.id
ORDER BY
COALESCE(SUM(roi.set_money), 0) DESC;
</select>
<select id="selectRescueOrderByRoad" resultType="java.util.Map">
select
COALESCE((select value from system_dict_data where dict_type = #{dictType} and id = ri.section_road),'其他') name,
count(1) as count
from rescue_info ri
group by name;
</select>
</mapper>