Compare commits

...

7 Commits

Author SHA1 Message Date
xyc
b5771bd801 Merge branch 'repair' 2025-09-26 15:09:34 +08:00
xyc
865f80ff91 更新0926 2025-09-26 15:05:32 +08:00
xyc
2afe93bf6e 更新0926 2025-09-26 14:32:41 +08:00
xyc
9dc4e188f0 更新0919 2025-09-19 10:20:42 +08:00
xyc
4c78b8b9a2 Merge branch 'master' into repair 2025-09-11 13:47:14 +08:00
xyc
b16dca836e 更新0911 2025-09-11 10:14:08 +08:00
xyc
79c5ac04d4 增加基础模块-业务渠道和来源 2025-09-08 13:57:14 +08:00
21 changed files with 534 additions and 117 deletions

View File

@ -95,6 +95,7 @@ public class CarMain extends TenantBaseDO {
* 下次年检日期
*/
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
@JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY, timezone = "GMT+8")
private LocalDateTime nextInspectionDate;
/**
* 保险到期日期
@ -157,4 +158,4 @@ public class CarMain extends TenantBaseDO {
private BigDecimal shangye;
/** 车龄 */
private Double carYear;
}
}

View File

@ -22,6 +22,7 @@ import cn.iocoder.yudao.module.label.entity.BusiLabel;
import cn.iocoder.yudao.module.label.service.BusiLabelService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
@ -126,15 +127,17 @@ public class CarMainServiceImpl extends ServiceImpl<CarMainMapper, CarMain> impl
}
//车俩品牌型号级联选择器返回值第一位是品牌第二位是型号
List<String> brandAndModel = updateReqVO.getBrandAndModel();
// 插入
CarMain carMain = BeanUtils.toBean(updateReqVO, CarMain.class);
carMain.setCarBrand(brandAndModel.get(0));
//判断是否仅填入了品牌
if (brandAndModel.size() > 1) {
//填入了型号
carMain.setCarModel(brandAndModel.get(1));
} else {
carMain.setCarModel("");
if (CollectionUtils.isNotEmpty(brandAndModel)) {
// 插入
carMain.setCarBrand(brandAndModel.get(0));
//判断是否仅填入了品牌
if (brandAndModel.size() > 1) {
//填入了型号
carMain.setCarModel(brandAndModel.get(1));
} else {
carMain.setCarModel("");
}
}
//todo 计算下次保养时间下次保养里程下次年检时间保险到期时间
baseMapper.updateById(carMain);
@ -525,4 +528,4 @@ public class CarMainServiceImpl extends ServiceImpl<CarMainMapper, CarMain> impl
}
}
}

View File

@ -149,4 +149,4 @@
</if>
</select>
</mapper>
</mapper>

View File

@ -0,0 +1,111 @@
package cn.iocoder.yudao.module.business.controller.admin;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.business.entity.DlBusinessChannel;
import cn.iocoder.yudao.module.business.service.BusinessChannelService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/business")
@RequiredArgsConstructor
public class BusinessChannelController {
private final BusinessChannelService businessChannelService;
/**
* @Author
* @Description 获取客户来源和业务渠道
* @Date 13:54 2025/9/8
* @Param [channel]
* @return cn.iocoder.yudao.framework.common.pojo.CommonResult<java.util.List < cn.iocoder.yudao.module.business.entity.DlBusinessChannel>>
**/
@GetMapping("/list")
public CommonResult<List<DlBusinessChannel>> list(DlBusinessChannel channel) {
return CommonResult.success(businessChannelService.list(Wrappers.<DlBusinessChannel>lambdaQuery()
.eq(ObjectUtil.isNotEmpty(channel.getType()), DlBusinessChannel::getType, channel.getType())
.like(ObjectUtil.isNotEmpty(channel.getName()), DlBusinessChannel::getName, channel.getName())
.eq(StrUtil.isNotEmpty(channel.getSystemCode()), DlBusinessChannel::getSystemCode, channel.getSystemCode())
.orderByAsc(DlBusinessChannel::getSort)));
}
/**
* @Author
* @Description 新增业务渠道来源
* @Date 13:44 2025/9/9
* @Param [channel]
* @return boolean
**/
@PostMapping("/add")
public boolean addChannel(@RequestBody DlBusinessChannel channel) {
if (ObjectUtil.isNotEmpty(channel.getUserIdList())) {
String userIds = channel.getUserIdList().stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
channel.setUserIds(userIds);
}
return businessChannelService.save(channel);
}
/**
* @Author
* @Description 获取业务来源和渠道
* @Date 13:45 2025/9/9
* @Param [id]
* @return cn.iocoder.yudao.framework.common.pojo.CommonResult<cn.iocoder.yudao.module.business.entity.DlBusinessChannel>
**/
@GetMapping("/{id}")
public CommonResult<DlBusinessChannel> getChannelById(@PathVariable("id") Long id) {
DlBusinessChannel info = businessChannelService.getById(id);
//将字符串转为集合
if (ObjectUtil.isNotEmpty(info.getUserIds())) {
List<Long> userIdList = Arrays.stream(info.getUserIds().split(","))
.filter(s -> s != null && !s.isEmpty()) // 可选避免空字符串
.map(Long::valueOf)
.collect(Collectors.toList());
info.setUserIdList(userIdList);
}
return CommonResult.success(info);
}
/**
* @Author
* @Description 修改
* @Date 13:45 2025/9/9
* @Param [channel]
* @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
**/
@PutMapping("/update")
public CommonResult<?> updateChannel(@RequestBody DlBusinessChannel channel) {
if (ObjectUtil.isNotEmpty(channel.getUserIdList())) {
String userIds = channel.getUserIdList().stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
channel.setUserIds(userIds);
} else if (ObjectUtil.isEmpty(channel.getUserIds())) {
channel.setUserIds("");
}
return CommonResult.success(businessChannelService.updateById(channel));
}
/**
* @Author
* @Description 删除
* @Date 13:45 2025/9/9
* @Param [id]
* @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
**/
@DeleteMapping("/delete/{id}")
public CommonResult<?> deleteChannel(@PathVariable("id") Long id) {
return CommonResult.success(businessChannelService.removeById(id));
}
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.business.entity;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.List;
@Data
@TableName("inspection_business_channel")
public class DlBusinessChannel extends TenantBaseDO {
private Integer id; // 主键ID
private Integer pid; // 父ID
private String name; // 名称
private Integer type; // 0-业务渠道 1-客户来源
private String userIds; // 绑定的用户ID
private Integer sort; // 排序
private String systemCode; // 系统标识
// 子节点
@TableField(exist = false)
private List<DlBusinessChannel> children;
@TableField(exist = false)
private List<Long> userIdList;
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.business.mapper;
import cn.iocoder.yudao.module.business.entity.DlBusinessChannel;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BusinessChannelMapper extends BaseMapper<DlBusinessChannel> {
/**
* 获取业务渠道 客户来源
* @param userId
* @return
*/
DlBusinessChannel getBusinessChannelByUserId(Long userId);
}

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.business.service;
import cn.iocoder.yudao.module.business.entity.DlBusinessChannel;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
public interface BusinessChannelService extends IService<DlBusinessChannel> {
/**
* 获取业务渠道和客户来源
*
* @param userId 用户id
* @return
*/
Map<String, Object> getBusinessChannelByUserId(Long userId);
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.business.service.impl;
import cn.iocoder.yudao.module.business.entity.DlBusinessChannel;
import cn.iocoder.yudao.module.business.mapper.BusinessChannelMapper;
import cn.iocoder.yudao.module.business.service.BusinessChannelService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class BusinessChannelServiceImpl extends ServiceImpl<BusinessChannelMapper, DlBusinessChannel> implements BusinessChannelService {
/**
* 获取业务渠道和客户来源
*
* @param userId 用户id
* @return
*/
@Override
public Map<String, Object> getBusinessChannelByUserId(Long userId) {
Map<String, Object> map = new HashMap<>();
// 客户来源
DlBusinessChannel channel = baseMapper.getBusinessChannelByUserId(userId);
if (channel == null) {
return null;
}
map.put("channel", channel);
// 根据客户来源的父id查询业务渠道
DlBusinessChannel business = getOne(Wrappers.<DlBusinessChannel>lambdaQuery()
.eq(DlBusinessChannel::getId, channel.getPid()));
if (business != null) {
map.put("business", business);
}
return map;
}
}

View File

@ -21,6 +21,8 @@ public class InspectionBusinessChannel extends TenantBaseDO {
private Integer sort; // 排序
private String systemCode; // 系统编码
// 子节点
@TableField(exist = false)
private List<InspectionBusinessChannel> children;

View File

@ -93,7 +93,8 @@ public enum RecordTypeEnum {
SK("sk", "收款"),
PICKCAR("pickcar", "接车"),
JSSQ("jssq", "结算申请"),
JSSP("jssp", "结算审批");
JSSP("jssp", "结算审批"),
QRSK("qrsk", "确认收款");
/**
* code

View File

@ -65,4 +65,9 @@ public class QueryBusinessResp {
* 经办人
*/
private String handleName;
/**
* 累计消费次数
*/
private Integer consumeCount;
}

View File

@ -762,6 +762,19 @@ public class DlRepairTicketsController {
return CommonResult.ok();
}
/**
* @Author
* @Description 确认收款
* @Date 11:12 2025/9/18
* @Param [repairTicketsRespVO]
* @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
**/
@PostMapping("/payConfirm")
public CommonResult<?> payConfirm(@RequestBody DlRepairTicketsRespVO repairTicketsRespVO) {
dlRepairTicketsService.payConfirm(repairTicketsRespVO);
return CommonResult.ok();
}
/**
* 格式化为百分比字符串
* @param value

View File

@ -124,6 +124,9 @@ public class DlTicketWaresController {
@PostMapping("/audit")
@Operation(summary = "审核")
public CommonResult<?> auditTicketWares(@RequestBody DlTicketWaresRespVO respVO){
if (CollUtil.isEmpty(respVO.getItems())) {
throw exception0(500,"请添加配件");
}
dlTicketWaresService.auditTicketWares(respVO);
return CommonResult.ok();
}

View File

@ -249,9 +249,12 @@ public class DlRepairTickets extends TenantBaseDO {
private BigDecimal jiaoqiang;
/** 商业险保费 */
private BigDecimal shangye;
/** 支付状态 字典repair_pat_status */
private String payStatus;
/** 支付确认 0:未确认 1:已确认*/
private String payConfirm;
/** 支付确认备注 */
private String payConfirmRemark;
/** 更新时上传的图片 */
@TableField(exist = false)

View File

@ -337,4 +337,12 @@ public interface DlRepairTicketsService extends IService<DlRepairTickets> {
* @return java.util.List<java.util.Map>
**/
Map<String, Object> getBossNumStatistics(String startDate, String endDate);
/**
* @Author
* @Description 确认收款
* @Date 11:12 2025/9/18
* @Param [repairTicketsRespVO]
**/
void payConfirm(DlRepairTicketsRespVO repairTicketsRespVO);
}

View File

@ -84,6 +84,7 @@ import com.deepoove.poi.plugin.table.HackLoopTableRenderPolicy;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
@ -593,6 +594,7 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
BigDecimal waresProfit = BigDecimal.ZERO;
List<JobTypeProfitDTO> resultList = new ArrayList<>();
if (CollectionUtil.isNotEmpty(items)) {
for (DlRepairTitemReqVO item : items) {
BigDecimal itemProfit = item.getItemProfit() != null ? item.getItemProfit() : BigDecimal.ZERO;
@ -610,6 +612,8 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
if (repairWorker != null) {
String jobType = repairWorker.getWorkType();
if (jobType == null) {
// 如果工种为空跳过处理
continue;
}
JobTypeProfitDTO dto = resultList.stream()
@ -742,6 +746,16 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
if (ObjectUtil.isEmpty(one)) {
throw exception0(500, "未找到该笔订单");
}
if ("0".equals(repairTicketsRespVO.getIsPaid())) {
// 未支付
one.setPayRemark(repairTicketsRespVO.getRemark());
//更新
repairOrderInfoService.updateById(one);
// 记录日志
repairRecordsService.saveRepairRecord(one.getGoodsId(), null, RecordTypeEnum.SK.getCode(), "未收款-"+repairTicketsRespVO.getRemark(), null);
return;
}
RepairOrderInfo repairOrderInfo = new RepairOrderInfo();
repairOrderInfo.setId(one.getId());
repairOrderInfo.setPayType(repairTicketsRespVO.getPayType());
@ -809,7 +823,17 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
* @Date 10:13 2025/8/20
* @Param [repairTicketsRespVO]
**/
@Transactional
public void setTicketsSettlement(TicketsSettlementVO vo) {
/*通过工单id查询工单配件申请表*/
List<DlTicketWares> list = ticketWaresService.list(Wrappers.<DlTicketWares>lambdaQuery()
.eq(DlTicketWares::getTicketId, vo.getTicketId()));
// 判断是否有未申领完成的
if (list.stream().anyMatch(item -> item.getStatus().equals("0"))) {
throw exception0(500, "请先完成配件申领");
}
/*添加结算数据*/
// 将vo转为json
String json = JSON.toJSONString(vo);
@ -895,7 +919,7 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
* @Param [startDate, endDate]
*/
@Override
public Map<String, Object> getBossNumStatistics(String startDate, String endDate) {
public Map<String, Object> getBossNumStatistics(String startDate, String endDate) {
Map<String, Object> resultMap = new HashMap<>();
List<Map<String, Object>> statsList = new ArrayList<>();
@ -912,38 +936,40 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
// 根据条件查询工单
List<DlRepairTickets> ticketsInRange = this.list(queryWrapper);
// 进厂数所有在范围内创建的
Map<String, Long> newOrderStats = ticketsInRange.stream()
.collect(Collectors.groupingBy(DlRepairTickets::getRepairType, Collectors.counting()));
statsList.add(createStatsNode("newOrderNum", "订单(进厂数)", newOrderStats, "jinchang"));
// 维修中 repairType 分组
Map<String, Long> workingStats = ticketsInRange.stream()
.filter(item -> TicketsStatusEnum.WORKING.getCode().equals(item.getTicketsStatus()))
.collect(Collectors.groupingBy(DlRepairTickets::getRepairType, Collectors.counting()));
statsList.add(createStatsNode("workingNum", "维修中", workingStats));
statsList.add(createStatsNode("workingNum", "维修中", workingStats, "weixiuzhong"));
// 已竣工通过 mapper 查询并按 repairType 分组
Map<String, Long> overStats = getOverStatsByRepairType(startDate, endDate);
statsList.add(createStatsNode("overNum", "已竣工", overStats, "yijungong"));
// 竣工已结算
// 竣工未结算
List<String> noPayCodeList = Arrays.asList("04", "05", "07", "01");
Map<String, Long> noPayStats = ticketsInRange.stream()
.filter(item -> noPayCodeList.contains(item.getTicketsStatus()))
.collect(Collectors.groupingBy(DlRepairTickets::getRepairType, Collectors.counting()));
statsList.add(createStatsNode("noPayNum", "未结算", noPayStats, "weijiesuan"));
// 已交车通过 mapper 查询并按 repairType 分组
Map<String, Long> giveCusStats = getGiveCusStatsByRepairType(startDate, endDate);
statsList.add(createStatsNode("giveCusNum", "已交车", giveCusStats, "yijiaoche"));
// 在厂未交车且不是已完成状态 03
Map<String, Long> inCompanyStats = ticketsInRange.stream()
.filter(item -> "0".equals(item.getIsHandover()))
.filter(item -> !"03".equals(item.getTicketsStatus()))
.collect(Collectors.groupingBy(DlRepairTickets::getRepairType, Collectors.counting()));
statsList.add(createStatsNode("inCompanyNum", "在厂", inCompanyStats));
// 未结算
List<String> noPayCodeList = Arrays.asList("04", "05", "07", "01");
Map<String, Long> noPayStats = ticketsInRange.stream()
.filter(item -> noPayCodeList.contains(item.getTicketsStatus()))
.collect(Collectors.groupingBy(DlRepairTickets::getRepairType, Collectors.counting()));
statsList.add(createStatsNode("noPayNum", "未结算", noPayStats));
// 进厂数所有在范围内创建的
Map<String, Long> newOrderStats = ticketsInRange.stream()
.collect(Collectors.groupingBy(DlRepairTickets::getRepairType, Collectors.counting()));
statsList.add(createStatsNode("newOrderNum", "进厂数", newOrderStats));
// 已完成通过 mapper 查询并按 repairType 分组
Map<String, Long> overStats = getOverStatsByRepairType(startDate, endDate);
statsList.add(createStatsNode("overNum", "已完成", overStats));
// 已交车通过 mapper 查询并按 repairType 分组
Map<String, Long> giveCusStats = getGiveCusStatsByRepairType(startDate, endDate);
statsList.add(createStatsNode("giveCusNum", "已交车", giveCusStats));
statsList.add(createStatsNode("inCompanyNum", "在厂", inCompanyStats, "zaichang"));
// 添加到结果map
resultMap.put("stats", statsList);
@ -955,6 +981,24 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
return resultMap;
}
/**
* @Author
* @Description 确认收款
* @Date 11:12 2025/9/18
* @Param [repairTicketsRespVO]
*/
@Override
public void payConfirm(DlRepairTicketsRespVO repairTicketsRespVO) {
// 修改主表 确认收款状态
update(Wrappers.<DlRepairTickets>lambdaUpdate()
.eq(DlRepairTickets::getId, repairTicketsRespVO.getId())
.set(DlRepairTickets::getPayConfirm, repairTicketsRespVO.getPayConfirm())
.set(StringUtils.isNotEmpty(repairTicketsRespVO.getPayConfirmRemark()),DlRepairTickets::getPayConfirmRemark, repairTicketsRespVO.getPayConfirmRemark()));
//添加记录
repairRecordsService.saveRepairRecord(repairTicketsRespVO.getId(), null, RecordTypeEnum.QRSK.getCode(), RecordTypeEnum.QRSK.getName(), null, null);
}
// 获取已完成工单按维修类型分组的统计优化版本
private Map<String, Long> getOverStatsByRepairType(String startDate, String endDate) {
// 直接使用 mapper 查询已完成工单并按 repairType 分组
@ -968,13 +1012,6 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
}
queryWrapper.eq("drr.type", RecordTypeEnum.ZJ.getCode());
// // 使用 group by 直接在数据库层面分组统计
// List<Map<String, Object>> result = repairTicketsMapper.selectMaps(
// queryWrapper.select("repair_type", "count(*) as count")
// .groupBy("repair_type")
// queryWrapper.getSqlSelect()
// );
// 使用 group by 直接在数据库层面分组统计
List<Map<String, Object>> result = repairTicketsMapper.selectTicketIdByParamsNew(
queryWrapper.select("repair_type", "count(*) as count")
@ -1020,11 +1057,18 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
return stats;
}
// 创建统计节点的辅助方法
private Map<String, Object> createStatsNode(String code, String name, Map<String, Long> stats) {
/**
* @Author
* @Description 创建统计节点
* @Date 11:13 2025/9/12
* @Param [code, name, stats, selectType] 统计项代码名称统计数据选择类型
* @return java.util.Map<java.lang.String, java.lang.Object>
**/
private Map<String, Object> createStatsNode(String code, String name, Map<String, Long> stats, String selectType) {
Map<String, Object> node = new HashMap<>();
node.put("code", code);
node.put("name", name);
node.put("selectType", selectType);
List<Map<String, Object>> children = stats.entrySet().stream()
.map(entry -> {
@ -1066,6 +1110,9 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
for (Map<String, Object> receivable : receivables) {
// 转换为TicketsSettlementVO
Object otherData = receivable.get("otherData");
if (ObjectUtil.isNull(otherData)) {
continue;
}
TicketsSettlementVO settlement = JSONObject.parseObject(
otherData.toString(), TicketsSettlementVO.class
);
@ -2732,6 +2779,59 @@ public class DlRepairTicketsServiceImpl extends ServiceImpl<DlRepairTicketsMappe
*/
@Override
public Map<String, Object> getStatistics(DlRepairTicketsReqVO repairTicketsReqVO) {
if (!RepairCons.TICKETS_WAITING.equals(repairTicketsReqVO.getSelectType())) {
if (("jinchang".equals(repairTicketsReqVO.getTicketsStatus()) ||
"yijungong".equals(repairTicketsReqVO.getTicketsStatus()) ||
"yijiaoche".equals(repairTicketsReqVO.getTicketsStatus())) && StringUtils.isNotEmpty(repairTicketsReqVO.getStartDate())) {
//如果是查询进场已竣工已交车三个状态同时选了时间范围的需要单独处理
String startDate = repairTicketsReqVO.getStartDate() + " 00:00:00";
String endDate = repairTicketsReqVO.getEndDate() + " 23:59:59";
List<String> idList = new ArrayList<>();
if ("yijungong".equals(repairTicketsReqVO.getTicketsStatus())) {
//已竣工
idList = repairTicketsMapper.selectTicketIdByParams(null, RecordTypeEnum.ZJ.getCode(), startDate, endDate);
} else if ("yijiaoche".equals(repairTicketsReqVO.getTicketsStatus())) {
//已交车
idList = repairTicketsMapper.selectTicketIdByParams(null, RecordTypeEnum.JC.getCode(), startDate, endDate);
} else {
//进厂
repairTicketsReqVO.setStartDate(startDate);
repairTicketsReqVO.setEndDate(endDate);
}
if (null != idList && !idList.isEmpty()) {
repairTicketsReqVO.setIdList(idList);
//时间查询条件置空
repairTicketsReqVO.setStartDate(null);
repairTicketsReqVO.setEndDate(null);
}
} else {
//否则查询时间不生效按维修状态查
List<String> statusList = new ArrayList<>();
if ("weixiuzhong".equals(repairTicketsReqVO.getTicketsStatus())) {
//维修中
statusList.add(TicketsStatusEnum.WORKING.getCode());
} else if ("weijiesuan".equals(repairTicketsReqVO.getTicketsStatus())) {
//未结算
statusList = Arrays.asList("04", "05", "07", "01");
} else if ("zaichang".equals(repairTicketsReqVO.getTicketsStatus())) {
//在厂就是没交车的,且不能是已作废和已完成的
repairTicketsReqVO.setIsHandover("0");
statusList = Arrays.asList("04", "05", "07", "01", "06", "02");
} else if ("jinchang".equals(repairTicketsReqVO.getTicketsStatus())) {
//进厂
statusList.add(TicketsStatusEnum.NO_WORK.getCode());
} else if ("yijungong".equals(repairTicketsReqVO.getTicketsStatus())) {
//已竣工
statusList = Arrays.asList("07", "01", "06", "02", "08");
} else if ("yijiaoche".equals(repairTicketsReqVO.getTicketsStatus())) {
//已交车
repairTicketsReqVO.setIsHandover("1");
}
if (!statusList.isEmpty()) {
repairTicketsReqVO.setStatusList(statusList);
}
}
}
return baseMapper.getStatistics(repairTicketsReqVO);
}
}

View File

@ -58,4 +58,13 @@ public class DlRepairTicketsReqVO extends DlRepairTickets {
/** 工种 */
private String workType;
/** 时间类型 */
private String timeType = "create";
/** 业务渠道 */
private String busiFrom;
/** 支付状态 receivable应收款 receivedAmount已收款 pendingAmount代收款 */
private String payStatus;
}

View File

@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.tickets.entity.DlRepairTitem;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@ -86,4 +87,11 @@ public class DlRepairTicketsRespVO extends DlRepairTickets {
private BigDecimal profitRateNo;
private List<JobTypeProfitDTO> groupByJobType;
/** 结算时间 */
private LocalDateTime settlementTime;
private String payTime;
/** 是否支付 */
private String isPaid;
}

View File

@ -123,7 +123,8 @@
GROUP BY drw.user_id,drr.ticket_id
ORDER BY value DESC
</select>
<select id="listBusinessByCustomer" resultType="cn.iocoder.yudao.module.base.vo.QueryBusinessResp"
<select id="listBusinessByCustomer"
resultType="cn.iocoder.yudao.module.base.vo.QueryBusinessResp"
parameterType="cn.iocoder.yudao.module.base.vo.QueryBusinessReqVO">
SELECT t.*
FROM (
@ -138,105 +139,72 @@
r.handle_name AS handleName,
'repair' AS source,
'维修' AS sourceStr,
ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY r.in_time DESC) AS rn
ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY r.in_time DESC) AS rn,
COUNT(*) OVER (PARTITION BY c.id) AS consumeCount -- 新增字段:消费次数
FROM base_customer_main c
JOIN dl_repair_tickets r ON c.id = r.user_id
LEFT JOIN dl_repair_titem t ON r.id = t.ticket_id
WHERE
1 = 1 and c.deleted = 0
1 = 1
AND c.deleted = 0
<if test="reqVO.dateRange != null">
AND r.in_time BETWEEN CONCAT(#{reqVO.dateRange[0]}, ' 00:00:00') AND CONCAT(#{reqVO.dateRange[1]}, ' 23:59:59')
AND r.in_time BETWEEN CONCAT(#{reqVO.dateRange[0]}, ' 00:00:00')
AND CONCAT(#{reqVO.dateRange[1]}, ' 23:59:59')
</if>
<if test="reqVO.search != null and reqVO.search != ''">
AND (c.cus_name LIKE CONCAT('%', #{reqVO.search}, '%')
AND (
c.cus_name LIKE CONCAT('%', #{reqVO.search}, '%')
OR c.phone_number LIKE CONCAT('%', #{reqVO.search}, '%')
OR r.ticket_no LIKE CONCAT('%', #{reqVO.search}, '%')
OR t.item_name LIKE CONCAT('%', #{reqVO.search}, '%')
)
</if>
ORDER BY r.in_time DESC
<!--
UNION ALL
SELECT
c.id AS customerId,
c.cus_name AS customerName,
c.phone_number AS customerPhone,
ri.id AS bizId,
NULL AS bizNo,
ri.rescue_type AS bizType,
ri.rescue_time AS bizTime,
'rescue' AS source,
ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY ri.rescue_time DESC) AS rn
FROM base_customer_main c
JOIN rescue_info ri ON c.user_id = ri.user_id
WHERE
1 = 1 and c.deleted = 0
<if test="reqVO.dateRange != null">
AND ri.rescue_time BETWEEN #{reqVO.dateRange[0]} AND #{reqVO.dateRange[1]}
</if>
<if test="reqVO.search != null and reqVO.search != ''">
AND (c.cus_name LIKE CONCAT('%', #{reqVO.search}, '%')
OR c.phone_number LIKE CONCAT('%', #{reqVO.search}, '%')
)
</if>-->
) t
WHERE t.rn = 1;
</select>
<select id="listBusinessByCar" resultType="cn.iocoder.yudao.module.base.vo.QueryBusinessResp"
<select id="listBusinessByCar"
resultType="cn.iocoder.yudao.module.base.vo.QueryBusinessResp"
parameterType="cn.iocoder.yudao.module.base.vo.QueryBusinessReqVO">
SELECT t.*
FROM (
-- 维修工单
SELECT
car.id AS carId,
car.license_number carNum,
c.id AS customerId,
c.cus_name AS customerName,
c.phone_number AS customerPhone,
car.license_number AS carNum,
c.id AS customerId,
c.cus_name AS customerName,
c.phone_number AS customerPhone,
r.id AS bizId,
r.ticket_no AS bizNo,
r.repair_type AS bizType,
r.create_time AS bizTime,
'repair' AS source,
'维修' AS sourceStr,
ROW_NUMBER() OVER (PARTITION BY car.id ORDER BY r.in_time DESC) AS rn
ROW_NUMBER() OVER (PARTITION BY car.id ORDER BY r.in_time DESC) AS rn,
COUNT(*) OVER (PARTITION BY car.id) AS consumeCount -- 新增字段:该车辆来过的次数
FROM base_car_main car
JOIN base_customer_car cc ON car.id = cc.car_id
JOIN base_customer_main c ON cc.cus_id = c.id
JOIN dl_repair_tickets r ON c.id = r.user_id
-- UNION ALL
--
-- -- 救援单
-- SELECT
-- car.id AS car_id,
-- car.license_number,
-- c.id AS customer_id,
-- c.cus_name,
-- c.phone_number,
-- ri.id AS biz_id,
-- NULL AS biz_no,
-- ri.rescue_type AS biz_type,
-- ri.rescue_time AS biz_time,
-- 'rescue' AS source,
-- ROW_NUMBER() OVER (PARTITION BY car.id ORDER BY ri.rescue_time DESC) AS rn
-- FROM base_car_main car
-- JOIN base_customer_car cc ON car.id = cc.car_id
-- JOIN base_customer_main c ON cc.cus_id = c.id
-- JOIN rescue_info ri ON c.id = ri.user_id
-- WHERE ri.rescue_time BETWEEN '2025-01-01 00:00:00' AND '2025-01-31 23:59:59'
INNER JOIN base_customer_car cc ON car.id = cc.car_id
LEFT JOIN base_customer_main c ON cc.cus_id = c.id
INNER JOIN dl_repair_tickets r ON car.license_number = r.car_no
) t
WHERE t.rn = 1
<if test="reqVO.dateRange != null">
AND t.bizTime BETWEEN CONCAT(#{reqVO.dateRange[0]}, ' 00:00:00') AND CONCAT( #{reqVO.dateRange[1]}, ' 23:59:59')
AND t.bizTime BETWEEN CONCAT(#{reqVO.dateRange[0]}, ' 00:00:00')
AND CONCAT(#{reqVO.dateRange[1]}, ' 23:59:59')
</if>
<if test="reqVO.search != null and reqVO.search != ''">
AND (t.customerName LIKE CONCAT('%', #{reqVO.search}, '%')
AND (
t.customerName LIKE CONCAT('%', #{reqVO.search}, '%')
OR t.customerPhone LIKE CONCAT('%', #{reqVO.search}, '%')
OR t.carNum LIKE CONCAT('%', #{reqVO.search}, '%')
)
</if>
GROUP BY t.carNum
ORDER BY t.bizTime DESC
</select>
<select id="pageByCustomerOrCar" resultType="cn.iocoder.yudao.module.base.vo.QueryTableResp">
SELECT drt.*, '维修' AS sourceStr
FROM dl_repair_tickets drt

View File

@ -61,7 +61,10 @@
<result property="jiaoqiang" column="jiaoqiang" />
<result property="shangye" column="shangye" />
<result property="payStatus" column="pay_status" />
<result property="payConfirm" column="pay_confirm" />
<result property="payConfirmRemark" column="pay_confirm_remark" />
<result property="settlementStr" column="settlementStr"/>
<result property="payTime" column="pay_time"/>
</resultMap>
<resultMap id="APPBaseResultMap" type="cn.iocoder.yudao.module.tickets.vo.DlRepairTicketsRespVO">
@ -124,6 +127,7 @@
<result property="canOperate" column="can_operate" />
<result property="handleName" column="handle_name" />
<result property="handleMobile" column="handle_mobile" />
<result property="settlementTime" column="settlementTime" />
<association property="booking" javaType="cn.iocoder.yudao.module.booking.entity.DlRepairBooking" select="selectBookingById" column="id"/>
<collection property="itemList" column="id" ofType="cn.iocoder.yudao.module.tickets.entity.DlRepairTitem" select="selectItemList" />
</resultMap>
@ -193,11 +197,12 @@
SELECT * FROM dl_repair_booking WHERE tickets_id = #{id}
</select>
<select id="getTicketsPage" resultMap="BaseResultMap">
SELECT drt.*
SELECT drt.*,rorder.pay_time AS pay_time
<if test="map.payStatus != null and map.payStatus != '' and map.payStatus == '01'">
,drr.other_data AS settlementStr
</if>
FROM dl_repair_tickets drt
LEFT JOIN repair_order_info rorder ON rorder.goods_id = drt.id
<if test="map.payStatus != null and map.payStatus != '' and map.payStatus == '01'">
LEFT JOIN dl_repair_records drr ON drt.id = drr.ticket_id AND drr.type = 'jssq'
</if>
@ -411,7 +416,7 @@
</select>
<select id="getPageTypeAll" resultMap="APPBaseResultMap">
SELECT drt.*
SELECT drt.*,drr.create_time AS settlementTime
FROM dl_repair_tickets drt
<if test="map.cusFrom != null and map.cusFrom!=''">
-- 按客户来源查,需要关联客户表 --
@ -421,9 +426,24 @@
ON drt.id = drti.ticket_id AND drti.deleted = '0' AND drti.item_type='01'
LEFT JOIN dl_repair_worker drw
ON FIND_IN_SET(drw.user_id, drti.repair_ids) > 0 AND drw.deleted = '0'
LEFT JOIN repair_order_info roi
ON drt.ticket_no = roi.order_no AND roi.deleted = '0'
LEFT JOIN dl_repair_records drr
ON drr.ticket_id = drt.id AND drr.deleted = '0' AND drr.type = 'jssp'
WHERE drt.deleted = '0' AND tickets_status!='03'
<!-- 模糊搜索 -->
<if test="map.searchTimeArray != null and map.searchTimeArray.length > 0">
<if test="map.timeType == 'create'">
AND (drt.create_time BETWEEN CONCAT(#{map.searchTimeArray[0]}, ' 00:00:00') AND CONCAT(#{map.searchTimeArray[1]}, ' 23:59:59'))
</if>
<if test="map.timeType == 'settlement'">
AND (drr.create_time BETWEEN CONCAT(#{map.searchTimeArray[0]}, ' 00:00:00') AND CONCAT(#{map.searchTimeArray[1]}, ' 23:59:59'))
</if>
</if>
<!-- 时间区间 -->
<if test="map.ticketNo != null and map.ticketNo != ''">
AND (
drt.ticket_no LIKE CONCAT('%', #{map.ticketNo}, '%')
@ -436,11 +456,6 @@
OR drti.item_name LIKE CONCAT('%', #{map.ticketNo}, '%')
)
</if>
<!-- 时间区间 -->
<if test="map.searchTimeArray != null and map.searchTimeArray.length > 0">
AND (drt.create_time BETWEEN CONCAT(#{map.searchTimeArray[0]}, ' 00:00:00') AND CONCAT(#{map.searchTimeArray[1]}, ' 23:59:59'))
</if>
<if test="map.startDate != null and map.startDate != ''">
AND (drt.create_time &gt;= #{map.startDate} AND drt.create_time &lt;= #{map.endDate})
</if>
@ -466,9 +481,31 @@
</foreach>
</if>
<!-- 收款状态 -->
<if test="map.payStatus != null and map.payStatus != ''">
<!-- -->
<!-- 应收款 -->
<if test="map.payStatus == 'receivable'">
AND drt.pay_status != '01'
</if>
<!-- 已收款 -->
<if test="map.payStatus == 'receivedAmount'">
AND drt.pay_status != '01' AND roi.pay_money IS NOT NULL
</if>
<!-- 代收款 -->
<if test="map.payStatus == 'pendingAmount'">
AND drt.pay_status != '01' AND roi.pay_money IS NULL
</if>
</if>
<!-- 客户来源 -->
<if test="map.cusFrom != null and map.cusFrom!=''">
AND bcm.data_from = #{map.cusFrom}
AND (bcm.data_from = #{map.cusFrom} OR drt.busi_from = #{map.busiFrom})
</if>
<!-- 业务渠道 -->
<if test="map.cusFrom != null and map.busiFrom!=''">
AND drt.busi_from = #{map.busiFrom}
</if>
<!-- 服务顾问 -->
@ -569,6 +606,10 @@
</if>
LEFT JOIN dl_repair_worker drw
ON FIND_IN_SET(drw.user_id, drti.repair_ids) > 0 AND drw.deleted = '0'
LEFT JOIN dl_repair_records drr
ON drr.ticket_id = drt.id AND drr.deleted = '0' AND drr.type = 'jssp'
LEFT JOIN repair_order_info roi
ON drt.ticket_no = roi.order_no AND roi.deleted = '0'
WHERE drt.deleted = '0'
AND drt.tickets_status != '03'
@ -586,8 +627,41 @@
)
</if>
<!-- 业务渠道 -->
<if test="map.cusFrom != null and map.busiFrom!=''">
AND drt.busi_from = #{map.busiFrom}
</if>
<!-- 客户来源 -->
<if test="map.cusFrom != null and map.cusFrom!=''">
AND (bcm.data_from = #{map.cusFrom} OR drt.busi_from = #{map.busiFrom})
</if>
<!-- 收款状态 -->
<if test="map.payStatus != null and map.payStatus != ''">
<!-- -->
<!-- 应收款 -->
<if test="map.payStatus == 'receivable'">
AND drt.pay_status != '01'
</if>
<!-- 已收款 -->
<if test="map.payStatus == 'receivedAmount'">
AND drt.pay_status != '01' AND roi.pay_money IS NOT NULL
</if>
<!-- 代收款 -->
<if test="map.payStatus == 'pendingAmount'">
AND drt.pay_status != '01' AND roi.pay_money IS NULL
</if>
</if>
<if test="map.searchTimeArray != null and map.searchTimeArray.length > 0">
AND (drt.create_time BETWEEN CONCAT(#{map.searchTimeArray[0]}, ' 00:00:00') AND CONCAT(#{map.searchTimeArray[1]}, ' 23:59:59'))
<if test="map.timeType == 'create'">
AND (drt.create_time BETWEEN CONCAT(#{map.searchTimeArray[0]}, ' 00:00:00') AND CONCAT(#{map.searchTimeArray[1]}, ' 23:59:59'))
</if>
<if test="map.timeType == 'settlement'">
AND (drr.create_time BETWEEN CONCAT(#{map.searchTimeArray[0]}, ' 00:00:00') AND CONCAT(#{map.searchTimeArray[1]}, ' 23:59:59'))
</if>
</if>
<if test="map.startDate != null and map.startDate != ''">
AND (drt.create_time &gt;= #{map.startDate} AND drt.create_time &lt;= #{map.endDate})

View File

@ -93,7 +93,8 @@
select 1 from dl_tw_item dti where dti.tw_id = dtw.id and dti.deleted = '0'
<choose>
<when test="map.userRole == 5 and map.isBack == false">
and (dti.wares_count > dti.wares_already_count and dti.wares_status = '1')
-- and (dti.wares_count > dti.wares_already_count and dti.wares_status = '1')
and ( dti.wares_status = '1')
</when>
<when test="map.userRole == 5 and map.isBack == true">
and (dti.wares_already_count > 0 and dti.wares_status = '1')