Compare commits

...

9 Commits

Author SHA1 Message Date
xyc
6f9a2986f9 Merge branch 'insp' 2025-06-13 17:07:45 +08:00
xyc
c22edb5c6d 更新 2025-06-13 17:06:48 +08:00
Lx
3f0d8297d1 0613 2025-06-13 16:57:34 +08:00
xyc
e65d3e4972 更新 2025-06-10 17:45:21 +08:00
xyc
4d8dee555f 更新 2025-06-06 15:56:02 +08:00
xyc
735f26ed3c 更新 2025-06-06 10:47:57 +08:00
xyc
e4346ad141 更新 2025-06-03 15:58:45 +08:00
xyc
b2ce977796 更新 2025-05-30 16:23:02 +08:00
xyc
b02a3b863a 更新 2025-05-29 17:40:23 +08:00
80 changed files with 1779 additions and 138 deletions

View File

@ -95,4 +95,9 @@ public class InspectionConstants {
*/
public static final String INSPECTION_NOTICE_TEMPLATE_ASSIGN_STAFF_MEET_CAR_NO_CAR_NO = "您有的新的接车订单需要处理 接车时间:%s 详细信息请前往接车列表";
/**
* 检测站内信模板-提示业务经理 接车订单已被创建
*/
public static final String INSPECTION_NOTICE_TEMPLATE_BUSINESS_MANAGER_MEET_CAR_ORDER_CREATE = "%s的工单已创建详细信息请前往列表查看";
}

View File

@ -125,6 +125,19 @@ public class InspectionInfoController extends BaseController {
return success(inspectionInfoService.geStelectInspection(page, inspectionInfo));
}
/**
* 根据当前登陆人获取可以选择的工单业务经理查询
*
* @return
*/
@GetMapping("geStelectInspectionByBusiness")
public CommonResult geStelectInspectionByBusiness(InspectionInfo inspectionInfo,
@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
@RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
Page<InspectionInfo> page = new Page<>(pageNum, pageSize);
return success(inspectionInfoService.geStelectInspectionByBusiness(page, inspectionInfo));
}
/**
* 获取工单详情
*
@ -376,6 +389,17 @@ public class InspectionInfoController extends BaseController {
return success(inspectionInfoService.getCountByType(partnerId));
}
/**
* 获得不同状态的数据的数量
*
* @author 小李
* @date 16:22 2024/12/18
**/
@GetMapping("/getBusinessCountByType")
public CommonResult<?> getBusinessCountByType(@RequestParam("partnerId") Integer partnerId) {
return success(inspectionInfoService.getBusinessCountByType(partnerId));
}
/**
* 接车拍照
*
@ -387,6 +411,17 @@ public class InspectionInfoController extends BaseController {
return success(inspectionInfoService.meetCarPhoto(inspectionWorkNode));
}
/**
* 还车拍照
*
* @param inspectionWorkNode
* @return
*/
@PostMapping("/returnCarPhoto")
public CommonResult<?> returnCarPhoto(@RequestBody InspectionWorkNode inspectionWorkNode) {
return success(inspectionInfoService.returnCarPhoto(inspectionWorkNode));
}
/**
* 修改异常工单
*

View File

@ -12,6 +12,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.core.controller.BaseController;
import cn.iocoder.yudao.module.inspection.enums.DriverLicenseType;
import cn.iocoder.yudao.module.inspection.query.InspectionListQuery;
import cn.iocoder.yudao.module.inspection.query.InspectionStaffQuery;
import cn.iocoder.yudao.module.inspection.service.InspectionStaffService;
import cn.iocoder.yudao.module.inspection.vo.InspectionStaffExportVo;
@ -181,15 +182,15 @@ public class InspectionStaffController extends BaseController {
/**
* 获取已完成项目
* @param userId 用户id
* @param query 请求参数
* @return
*/
@GetMapping("/getFinishProjectByUserId")
public CommonResult<?> getFinishProjectByUserId(@RequestParam("userId") Long userId,
public CommonResult<?> getFinishProjectByUserId(InspectionListQuery query,
@RequestParam(value = "pageNo", required = false, defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
Page<Map<String, Object>> page = new Page<>(pageNo, pageSize);
return success(inspectionStaffService.getFinishProjectByUserId(page, userId));
return success(inspectionStaffService.getFinishProjectByUserId(page, query));
}
/**

View File

@ -7,6 +7,7 @@ import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.inspection.query.FileByTypeQuery;
import cn.iocoder.yudao.module.inspection.query.OrderTableQuery;
import cn.iocoder.yudao.module.inspection.vo.*;
import cn.iocoder.yudao.module.label.vo.LabelRespVO;
@ -922,4 +923,14 @@ public class PartnerOwnController extends BaseController {
@RequestParam(value = "endTime", required = false) String endTime){
return success(partnerList.fileStatistics(servicePackageId,startTime, endTime));
}
/**
* 文件统计
* @param fileByTypeQuery
* @return
*/
@GetMapping("/getFileByType")
public CommonResult<?> getFileByType(FileByTypeQuery fileByTypeQuery){
return success(partnerList.fileStatisticsList(fileByTypeQuery.getServicePackageId(),fileByTypeQuery.getStartTime(),fileByTypeQuery.getEndTime()));
}
}

View File

@ -8,7 +8,9 @@ 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("/channel")
@ -23,6 +25,7 @@ public class InspectionBusinessChannelController {
@GetMapping("/tree")
public CommonResult<List<InspectionBusinessChannel>> getChannelTree(InspectionBusinessChannel channel) {
return CommonResult.success(inspectionBusinessChannelService.list(Wrappers.<InspectionBusinessChannel>lambdaQuery()
.eq(ObjectUtil.isNotEmpty(channel.getType()), InspectionBusinessChannel::getType, channel.getType())
.like(ObjectUtil.isNotEmpty(channel.getName()), InspectionBusinessChannel::getName, channel.getName())));
}
@ -39,7 +42,18 @@ public class InspectionBusinessChannelController {
*/
@GetMapping("/{id}")
public CommonResult<InspectionBusinessChannel> getChannelById(@PathVariable("id") Long id) {
return CommonResult.success(inspectionBusinessChannelService.getById(id));
InspectionBusinessChannel info = inspectionBusinessChannelService.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);
}
/**
@ -47,6 +61,13 @@ public class InspectionBusinessChannelController {
*/
@PutMapping("/update")
public CommonResult<?> updateChannel(@RequestBody InspectionBusinessChannel channel) {
if (ObjectUtil.isNotEmpty(channel.getUserIdList())) {
String userIds = channel.getUserIdList().stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
channel.setUserIds(userIds);
}
return CommonResult.success(inspectionBusinessChannelService.updateById(channel));
}
@ -60,10 +81,11 @@ public class InspectionBusinessChannelController {
/**
* 获取业务渠道或客户来源列表(app)
*
* @return
*/
@GetMapping("/list")
public CommonResult<?> list(){
public CommonResult<?> list() {
return CommonResult.success(inspectionBusinessChannelService.getChannelTree());
}
}

View File

@ -48,4 +48,7 @@ public class DlInspectionProject extends TenantBaseDO {
@TableField(exist = false)
private List<ProjectRoyalty> projectRoyaltyList;
}
@TableField(exist = false)
private List<String> datetimeRange;
}

View File

@ -17,7 +17,12 @@ public class InspectionBusinessChannel extends TenantBaseDO {
private Integer type; // 0-业务渠道 1-客户来源
private String userIds; // 绑定的用户ID
// 子节点
@TableField(exist = false)
private List<InspectionBusinessChannel> children;
@TableField(exist = false)
private List<Long> userIdList;
}

View File

@ -163,6 +163,10 @@ public class InspectionInfo extends TenantBaseDO
private String isPickCar;
/** 当前流程节点 */
private Integer nowOrderNum;
/** 还车人id */
private Long returnCarUserId;
/** 是否还车 */
private Integer isReturnCar;
/** 开始检测时需要 传入 选择项目的id、角色id、排序 */
@TableField(exist = false)

View File

@ -99,4 +99,10 @@ public class InspectionStaff extends TenantBaseDO {
*/
@TableField("folder_id")
private Long folderId;
/**
* 唯一码
*/
@TableField("unique_code")
private String uniqueCode;
}

View File

@ -23,4 +23,6 @@ public interface InspectionFileRecordMapper extends BaseMapper<InspectionFileRec
List<InspectionFileRecord> getRecordList(Long id);
long queryCount(@Param("servicePackageId") String servicePackageId,@Param("startTime") String startTime, @Param("endTime") String endTime);
List<InspectionFileRecord> query(@Param("servicePackageId") String servicePackageId, @Param("startTime") String startTime, @Param("endTime") String endTime);
}

View File

@ -94,4 +94,7 @@ public interface InspectionInfoMapper extends BaseMapper<InspectionInfo>
*/
IPage<InspectionInfo> selectByUser(@Param("page") IPage page, @Param("roleIds") List<Long> roleIds,@Param("inspectionInfo") InspectionInfo inspectionInfo);
Long countByUser(@Param("roleIds") List<Long> roleIds,@Param("inspectionInfo") InspectionInfo inspectionInfo);
IPage<InspectionInfo> geStelectInspectionByBusiness(@Param("page") Page<InspectionInfo> page,@Param("info") InspectionInfo inspectionInfo);
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.inspection.mapper;
import cn.iocoder.yudao.module.inspection.entity.DlInspectionProject;
import cn.iocoder.yudao.module.inspection.entity.InspectionWorkNode;
import cn.iocoder.yudao.module.inspection.query.InspectionListQuery;
import cn.iocoder.yudao.module.inspection.vo.StaffProjectCountVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -50,5 +51,5 @@ public interface InspectionWorkNodeMapper extends BaseMapper<InspectionWorkNode>
*/
List<Map<String, Object>> selectExceptionNodesByInspectionIds(@Param("ids") List<Long> idList);
IPage<Map<String, Object>> selectStaffProjectByUserId(@Param("page")Page<Map<String, Object>> page, @Param("userId") Long userId);
IPage<Map<String, Object>> selectStaffProjectByUserId(@Param("page")Page<Map<String, Object>> page, @Param("query") InspectionListQuery query);
}

View File

@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.inspection.query;
import lombok.Data;
@Data
public class FileByTypeQuery {
/**
* 服务包id
*/
private String servicePackageId;
/**
* 查询类型 add-新增 update-修改
*/
private String type;
/**
* 开始时间
*/
private String startTime;
/**
* 结束时间
*/
private String endTime;
}

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.inspection.query;
import lombok.Data;
import java.util.List;
@Data
public class InspectionListQuery {
/**
* 用户id
*/
private Long userId;
/**
* 客户来源
*/
private String customerSource;
/**
* 时间范围
*/
private List<String> datetimeRange;
/**
* 客户来源
*/
private String customSource;
/**
* 业务
*/
private String bussiness;
/**
* 项目id
*/
private String projectId;
}

View File

@ -43,4 +43,7 @@ public class OrderTableQuery {
/** 检测时长 */
private String[] inspectionTime;
/** 时间范围 */
private String[] datetimeRange;
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.inspection.service;
import cn.iocoder.yudao.module.inspection.query.FileByTypeQuery;
import cn.iocoder.yudao.module.inspection.query.OrderTableQuery;
import cn.iocoder.yudao.module.label.vo.LabelPageReqVO;
import cn.iocoder.yudao.module.label.vo.LabelRespVO;
@ -262,4 +263,13 @@ public interface AppInspectionPartnerService extends IService<ShopMallPartners>
* @return
*/
List<Map<String, Object>> customerSourceCount(String startTime, String endTime, Long businessId);
/**
* 文件统计列表
*
* @param startTime 开始时间
* @param endTime 结束时间
* @return 结果
*/
Map<String, Object> fileStatisticsList(String servicePackageId, String startTime, String endTime);
}

View File

@ -154,9 +154,25 @@ public interface IInspectionInfoService extends IService<InspectionInfo>
*/
Boolean meetCarPhoto(InspectionWorkNode inspectionWorkNode);
/**
* 还车拍照
* @param inspectionWorkNode
*/
Boolean returnCarPhoto(InspectionWorkNode inspectionWorkNode);
/**
* 引车
* @param inspectionInfo
*/
void leadCar(InspectionInfo inspectionInfo);
/**
* 获取业务方工单
* @param page
* @param inspectionInfo
* @return
*/
IPage<InspectionInfo> geStelectInspectionByBusiness(Page<InspectionInfo> page, InspectionInfo inspectionInfo);
Map<String, Long> getBusinessCountByType(Integer partnerId);
}

View File

@ -21,4 +21,6 @@ public interface InspectionFileRecordService extends IService<InspectionFileReco
List<InspectionFileRecord> getRecordList(Long id);
long queryCount(String servicePackageId, String startTime, String endTime);
List<InspectionFileRecord> query(String servicePackageId, String startTime, String endTime);
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.inspection.service;
import cn.iocoder.yudao.module.inspection.entity.*;
import cn.iocoder.yudao.module.inspection.query.GoodsQuery;
import cn.iocoder.yudao.module.inspection.query.InspectionListQuery;
import cn.iocoder.yudao.module.inspection.query.InspectionStaffQuery;
import cn.iocoder.yudao.module.inspection.vo.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -81,6 +82,6 @@ public interface InspectionStaffService extends IService<InspectionStaff> {
* @param userId
* @return
*/
IPage<Map<String, Object>> getFinishProjectByUserId(Page<Map<String, Object>> page, Long userId);
IPage<Map<String, Object>> getFinishProjectByUserId(Page<Map<String, Object>> page, InspectionListQuery query);
}

View File

@ -1549,11 +1549,12 @@ public class AppInspectionPartnerServiceImpl extends ServiceImpl<AppInspectionPa
Set<Long> userIds = new HashSet<>();
userIds.add(info.getUserId());
userIds.add(info.getWorkId());
userIds.add(info.getReturnCarUserId());
if (info.getLeadManId() != null) userIds.add(info.getLeadManId());
if (info.getMeetManId() != null) userIds.add(info.getMeetManId());
List<AdminUserDO> userList = userService.list(Wrappers.<AdminUserDO>lambdaQuery()
.in(AdminUserDO::getId,userIds)); // 你需新增 getUsers(Collection<Long> ids)
.in(AdminUserDO::getId, userIds)); // 你需新增 getUsers(Collection<Long> ids)
//转为map
Map<Long, AdminUserDO> userMap = userList.stream().collect(Collectors.toMap(AdminUserDO::getId, Function.identity()));
@ -1564,11 +1565,13 @@ public class AppInspectionPartnerServiceImpl extends ServiceImpl<AppInspectionPa
AdminUserDO meetMan = userMap.get(info.getMeetManId());
InspectionInfoVo res = new InspectionInfoVo();
BeanUtils.copyProperties(order, res); // 建议手动复制必要字段
BeanUtils.copyProperties(order, res); // 建议手动复制必要字段
res.setInspectionId(info.getId());
res.setBuyUserName(buyUser != null ? buyUser.getNickname() : "");
res.setBuyUserPhone(buyUser != null ? buyUser.getMobile() : "");
res.setReturnCarUserId(info.getReturnCarUserId());
res.setReturnCarUserName(userMap.get(info.getReturnCarUserId()) != null ? userMap.get(info.getReturnCarUserId()).getNickname() : "");
if (worker != null) {
res.setWorkerAvatar(worker.getAvatar());
@ -1597,7 +1600,6 @@ public class AppInspectionPartnerServiceImpl extends ServiceImpl<AppInspectionPa
}
if (leadMan != null) {
res.setLeadManName(leadMan.getNickname());
res.setLeadManId(leadMan.getId());
@ -1673,7 +1675,6 @@ public class AppInspectionPartnerServiceImpl extends ServiceImpl<AppInspectionPa
}
@Override
public List<InspectionInfo> workerInspectionList(Long workerId, String status, String searchValue) {
return baseMapper.workerInspectionList(workerId, status, searchValue);
@ -2027,7 +2028,7 @@ public class AppInspectionPartnerServiceImpl extends ServiceImpl<AppInspectionPa
startTime = startTime + " 00:00:00";
endTime = endTime + " 23:59:59";
// List<Map<String, Object>> res = baseMapper.staticsTable3(partnerId, startTime, endTime);
List<Map<String, Object>> res = baseMapper.selectBusinessStatistics( startTime, endTime);
List<Map<String, Object>> res = baseMapper.selectBusinessStatistics(startTime, endTime);
return res;
}
@ -2307,16 +2308,46 @@ public class AppInspectionPartnerServiceImpl extends ServiceImpl<AppInspectionPa
Map<Long, Long> meetManIdCountMap = list.stream()
.filter(info -> info.getMeetManId() != null) // 过滤 null
.collect(Collectors.groupingBy(InspectionInfo::getMeetManId, Collectors.counting()));
// 根据userId查询还车人
List<InspectionInfo> returnCarList = inspectionInfoService.list(Wrappers.<InspectionInfo>lambdaQuery()
.eq(InspectionInfo::getIsReturnCar, 1));
// 统计每个 returnCarUserId 的数量避免 null key 异常
Map<Long, Long> returnCarUserIdCountMap = returnCarList.stream()
.filter(info -> info.getReturnCarUserId() != null) // 过滤 null
.collect(Collectors.groupingBy(InspectionInfo::getReturnCarUserId, Collectors.counting()));
for (Map<String, Object> stringObjectMap : staffCount) {
Long userId = (Long) stringObjectMap.get("userId");
List<Map<String, Object>> children = (List<Map<String, Object>>) stringObjectMap.get("children");
stringObjectMap.put("meetCarCount", meetManIdCountMap.get(userId));
// stringObjectMap.put("meetCarCount", meetManIdCountMap.get(userId));
stringObjectMap.put("totalCount", (Long) stringObjectMap.get("totalCount") == null ? 0 : (Long) stringObjectMap.get("totalCount") + (meetManIdCountMap.get(userId) == null ? 0 : meetManIdCountMap.get(userId)));
HashMap<String, Object> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("count", meetManIdCountMap.get(userId) == null ? 0 : meetManIdCountMap.get(userId));
objectObjectHashMap.put("projectName", "接车");
children.add(objectObjectHashMap);
//还车
//设置totalCount
stringObjectMap.put("totalCount", (Long) stringObjectMap.get("totalCount") == null ? 0 : (Long) stringObjectMap.get("totalCount") + (returnCarUserIdCountMap.get(userId) == null ? 0 : returnCarUserIdCountMap.get(userId)));
Map<String, Object> objectObjectHashMap1 = new HashMap<>();
objectObjectHashMap1.put("count", returnCarUserIdCountMap.get(userId) == null ? 0 : returnCarUserIdCountMap.get(userId));
objectObjectHashMap1.put("projectName", "还车");
children.add(objectObjectHashMap1);
}
// meetCarCount 降序排序员工
staffCount.sort(Comparator.comparingLong(
(Map<String, Object> staff) -> (Long) staff.getOrDefault("totalCount", 0L)
).reversed());
// 对每个员工的 children count 降序排序
staffCount.forEach(staff -> {
List<Map<String, Object>> children = (List<Map<String, Object>>) staff.get("children");
if (children != null) {
children.sort(Comparator.comparingLong(
(Map<String, Object> child) -> (Long) child.getOrDefault("count", 0L)
).reversed());
}
});
return staffCount;
}
@ -2328,7 +2359,7 @@ public class AppInspectionPartnerServiceImpl extends ServiceImpl<AppInspectionPa
* @return 结果
*/
@Override
public Map<String, Object> fileStatistics(String servicePackageId,String startTime, String endTime) {
public Map<String, Object> fileStatistics(String servicePackageId, String startTime, String endTime) {
// 判断开始时间与结束时间如果为空 默认查询本月
if (StringUtils.isEmpty(startTime)) {
startTime = DateUtil.format(DateUtil.beginOfMonth(new Date()), "yyyy-MM-dd");
@ -2337,7 +2368,7 @@ public class AppInspectionPartnerServiceImpl extends ServiceImpl<AppInspectionPa
endTime = DateUtil.format(DateUtil.endOfMonth(new Date()), "yyyy-MM-dd");
}
long addCount = inspectionFileService.count(Wrappers.<InspectionFile>lambdaQuery()
.eq(InspectionFile::getServicePackageId, servicePackageId)
.eq(InspectionFile::getServicePackageId, servicePackageId)
.between(InspectionFile::getCreateTime, startTime, endTime));
// 查询文件记录表
@ -2370,4 +2401,35 @@ public class AppInspectionPartnerServiceImpl extends ServiceImpl<AppInspectionPa
maps.sort(Comparator.comparingInt(map -> -Integer.parseInt(map.get("theNum").toString())));
return maps;
}
/**
* 文件统计列表
*
* @param servicePackageId
* @param startTime 开始时间
* @param endTime 结束时间
* @return 结果
*/
@Override
public Map<String, Object> fileStatisticsList(String servicePackageId, String startTime, String endTime) {
Map<String, Object> result = new HashMap<>();
// 根据开始时间与结束时间查询新增文件
if (StringUtils.isEmpty(startTime)) {
startTime = DateUtil.format(DateUtil.beginOfMonth(new Date()), "yyyy-MM-dd");
}
if (StringUtils.isEmpty(endTime)) {
endTime = DateUtil.format(DateUtil.endOfMonth(new Date()), "yyyy-MM-dd");
}
List<InspectionFile> insertFile = inspectionFileService.list(Wrappers.<InspectionFile>lambdaQuery()
.eq(InspectionFile::getServicePackageId, servicePackageId)
.between(InspectionFile::getCreateTime, startTime, endTime));
result.put("insertFile", insertFile);
// 根据开始时间与结束时间查询修改文件
List<InspectionFileRecord> query = inspectionFileRecordService.query(servicePackageId, startTime, endTime);
result.put("updateFile", query);
return result;
}
}

View File

@ -39,4 +39,15 @@ public class InspectionFileRecordServiceImpl extends ServiceImpl<InspectionFileR
public long queryCount(String servicePackageId, String startTime, String endTime) {
return baseMapper.queryCount(servicePackageId, startTime, endTime);
}
/**
* @param servicePackageId
* @param startTime
* @param endTime
* @return
*/
@Override
public List<InspectionFileRecord> query(String servicePackageId, String startTime, String endTime) {
return baseMapper.query(servicePackageId, startTime, endTime);
}
}

View File

@ -419,6 +419,15 @@ public class InspectionInfoServiceImpl extends ServiceImpl<InspectionInfoMapper,
update(Wrappers.<InspectionInfo>lambdaUpdate()
.eq(InspectionInfo::getId, inspectionInfo.getId())
.set(InspectionInfo::getIsMeetCar, 1));
// 查询接车标
InspectionMeetCarOrder inspectionMeetCarOrder = inspectionMeetCarOrderService.getById(inspectionInfo.getMeetCarId());
// 判断接车类型是否是业务接车
if (inspectionMeetCarOrder.getMeetType() == 2) {
// 给对应的业务经理发送消息
String message = String.format(InspectionConstants.INSPECTION_NOTICE_TEMPLATE_BUSINESS_MANAGER_MEET_CAR_ORDER_CREATE, inspectionInfo.getBuyName() == null ? inspectionInfo.getBuyPhone() : inspectionInfo.getBuyName());
noticeService.sentMessage(inspectionMeetCarOrder.getMeetManId(), message);
}
}
workNodeService.saveBatch(inspectionWorkNodes);
@ -830,7 +839,7 @@ public class InspectionInfoServiceImpl extends ServiceImpl<InspectionInfoMapper,
@Override
public Map<String, Long> getCountByType(Integer partnerId) {
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(6);
ExecutorService executor = Executors.newFixedThreadPool(10);
try {
InspectionInfo inspectionInfo = new InspectionInfo();
@ -850,9 +859,9 @@ public class InspectionInfoServiceImpl extends ServiceImpl<InspectionInfoMapper,
Map<String, Long> result = new ConcurrentHashMap<>(); // 线程安全
// 这里 `5` 而不是 `6`因为 i `0` 开始
CompletableFuture<Void>[] futures = new CompletableFuture[9];
CompletableFuture<Void>[] futures = new CompletableFuture[10];
for (int i = 0; i < 9; i++) { // 改为 `0~4`
for (int i = 0; i < 10; i++) { // 改为 `0~4`
final String status = String.valueOf(i + 1);
// 深拷贝对象防止多线程修改冲突
@ -927,6 +936,38 @@ public class InspectionInfoServiceImpl extends ServiceImpl<InspectionInfoMapper,
return true;
}
/**
* 还车拍照
*
* @param inspectionWorkNode
*/
@Override
public Boolean returnCarPhoto(InspectionWorkNode inspectionWorkNode) {
//图片和描述
String remark = StrUtil.isNotEmpty(inspectionWorkNode.getRemark()) ? inspectionWorkNode.getRemark() : "";
String dealImages = StrUtil.isNotEmpty(inspectionWorkNode.getDealImages()) ? inspectionWorkNode.getDealImages() : "";
//存入步骤表
InspectionStepInfo stepInfo = new InspectionStepInfo();
stepInfo.setInspectionInfoId(inspectionWorkNode.getInspectionInfoId());
stepInfo.setTitle("还车拍照");
stepInfo.setContent(remark);
stepInfo.setImages(dealImages);
stepInfo.setCreator(Math.toIntExact(SecurityFrameworkUtils.getLoginUserId()));
stepInfo.setUpdater(Math.toIntExact(SecurityFrameworkUtils.getLoginUserId()));
stepInfo.setCreateTime(new Date());
stepInfo.setUpdateTime(new Date());
inspectionStepInfoService.save(stepInfo);
// 修改主表为已还车
int update = baseMapper.update(Wrappers.<InspectionInfo>lambdaUpdate()
.eq(InspectionInfo::getId, inspectionWorkNode.getInspectionInfoId())
.set(InspectionInfo::getIsReturnCar, InspectionConstants.INSPECTION_MEET_CAR_ORDER_IS_MEET_CAR_YES)
.set(InspectionInfo::getReturnCarUserId, SecurityFrameworkUtils.getLoginUserId()));
return true;
}
/**
* 引车
*
@ -942,6 +983,83 @@ public class InspectionInfoServiceImpl extends ServiceImpl<InspectionInfoMapper,
saveLeadRecord(inspectionInfo.getId(), loginUser.getId());
}
/**
* 获取业务方工单
*
* @param page
* @param inspectionInfo
* @return
*/
@Override
public IPage<InspectionInfo> geStelectInspectionByBusiness(Page<InspectionInfo> page, InspectionInfo inspectionInfo) {
return baseMapper.geStelectInspectionByBusiness(page, inspectionInfo);
}
/**
* @param partnerId
* @return
*/
@Override
public Map<String, Long> getBusinessCountByType(Integer partnerId) {
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(10);
try {
InspectionInfo inspectionInfo = new InspectionInfo();
inspectionInfo.setPartnerId(partnerId.longValue());
// 获取当前登录人
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
// 获取当前登陆人的角色
// List<UserRoleDO> byUserId = roleService.getByUserId(loginUser.getId());
// inspectionInfo.setLeadManId(loginUser.getId());
// List<Long> roleIds = byUserId.stream().map(UserRoleDO::getRoleId).collect(Collectors.toList());
inspectionInfo.setUserId(loginUser.getId());
if (!"1".equals(inspectionInfo.getStatus())) {
inspectionInfo.setDealUserId(loginUser.getId());
}
Map<String, Long> result = new ConcurrentHashMap<>(); // 线程安全
// 这里 `5` 而不是 `6`因为 i `0` 开始
CompletableFuture<Void>[] futures = new CompletableFuture[3];
for (int i = 0; i < 3; i++) { // 改为 `0~4`
final String status = String.valueOf(i + 1);
// 深拷贝对象防止多线程修改冲突
InspectionInfo infoCopy = JSON.parseObject(JSON.toJSONString(inspectionInfo), InspectionInfo.class);
infoCopy.setStatus(status);
Page<InspectionInfo> page = new Page<>(1, 1);
futures[i] = CompletableFuture.runAsync(() -> {
IPage<InspectionInfo> inspectionInfoIPage = baseMapper.geStelectInspectionByBusiness(page, infoCopy);
Long count = inspectionInfoIPage.getTotal();
result.put(status, count);
}, executor);
}
// 等待所有任务完成
CompletableFuture.allOf(futures).join();
return result;
} catch (Exception e) {
throw new RuntimeException("Failed to execute tasks in parallel", e);
} finally {
executor.shutdown();
try {
if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
}
}
}
/**
* 保存引车员记录
*

View File

@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.inspection.entity.InspectionPickCar;
import cn.iocoder.yudao.module.inspection.entity.InspectionStaff;
import cn.iocoder.yudao.module.inspection.mapper.InspectionStaffMapper;
import cn.iocoder.yudao.module.inspection.mapper.InspectionWorkNodeMapper;
import cn.iocoder.yudao.module.inspection.query.InspectionListQuery;
import cn.iocoder.yudao.module.inspection.query.InspectionStaffQuery;
import cn.iocoder.yudao.module.inspection.service.IInspectionFileService;
import cn.iocoder.yudao.module.inspection.service.InspectionStaffService;
@ -20,6 +21,7 @@ import cn.iocoder.yudao.module.inspection.vo.ImportStaffVo;
import cn.iocoder.yudao.module.inspection.vo.InspectionStaffExportVo;
import cn.iocoder.yudao.module.inspection.vo.InspectionStaffSaveVo;
import cn.iocoder.yudao.module.inspection.vo.StaffImportExcelVO;
import cn.iocoder.yudao.module.staff.service.UniqueCodeService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.UserDTO;
import cn.iocoder.yudao.module.system.api.user.dto.UserRoleDTO;
@ -38,6 +40,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
@ -68,6 +71,9 @@ public class InspectionStaffServiceImpl extends ServiceImpl<InspectionStaffMappe
@Autowired
private InspectionWorkNodeMapper inspectionWorkNodeMapper;
@Resource
private UniqueCodeService uniqueCodeService;
/**
* 获取检测员工分页
*
@ -137,6 +143,9 @@ public class InspectionStaffServiceImpl extends ServiceImpl<InspectionStaffMappe
@Override
public InspectionStaffSaveVo get(Long id) {
InspectionStaffSaveVo inspectionStaffSaveVo = baseMapper.get(id);
if (inspectionStaffSaveVo == null) {
return null;
}
// 查询用户角色集合
List<UserRoleDTO> userRoleDTOS = permissionService.userRoleDTOList(Collections.singletonList(id));
inspectionStaffSaveVo.setRoleIds(userRoleDTOS.stream()
@ -145,6 +154,8 @@ public class InspectionStaffServiceImpl extends ServiceImpl<InspectionStaffMappe
.map(UserRoleDTO::getRoleId)
.collect(Collectors.toList()));
inspectionStaffSaveVo.setUserRoles(userRoleDTOS);
//将驾驶证类型转为数组
if (ObjectUtil.isNotEmpty(inspectionStaffSaveVo.getDriverLicenseType())) {
inspectionStaffSaveVo.setDriverLicenseTypeArr(Arrays.asList(inspectionStaffSaveVo.getDriverLicenseType().split(",")));
@ -156,6 +167,12 @@ public class InspectionStaffServiceImpl extends ServiceImpl<InspectionStaffMappe
inspectionStaffSaveVo.setFolderId(null);
}
}
// 生成唯一推广码
if (inspectionStaffSaveVo.getUniqueCode() == null) {
inspectionStaffSaveVo.setUniqueCode(uniqueCodeService.createUniqueCode());
baseMapper.update(Wrappers.<InspectionStaff>lambdaUpdate().eq(InspectionStaff::getUserId, inspectionStaffSaveVo.getId()).set(InspectionStaff::getUniqueCode, inspectionStaffSaveVo.getUniqueCode()));
}
return inspectionStaffSaveVo;
}
@ -259,8 +276,8 @@ public class InspectionStaffServiceImpl extends ServiceImpl<InspectionStaffMappe
* @return
*/
@Override
public IPage<Map<String, Object>> getFinishProjectByUserId(Page<Map<String, Object>> page, Long userId) {
return inspectionWorkNodeMapper.selectStaffProjectByUserId(page,userId);
public IPage<Map<String, Object>> getFinishProjectByUserId(Page<Map<String, Object>> page, InspectionListQuery query) {
return inspectionWorkNodeMapper.selectStaffProjectByUserId(page,query);
}
/**

View File

@ -112,4 +112,9 @@ public class InspectionInfoVo {
private String isMeetCar;
private String otherName;
private String otherPhone;
/** 还车人id */
private Long returnCarUserId;
private String returnCarUserName;
/** 是否还车 */
private Integer isReturnCar;
}

View File

@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.inspection.vo;
import cn.iocoder.yudao.annotation.Excel;
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import cn.iocoder.yudao.module.inspection.entity.InspectionStaff;
import cn.iocoder.yudao.module.system.api.user.dto.UserRoleDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@ -106,7 +108,12 @@ public class InspectionStaffSaveVo extends InspectionStaff {
private List<FileDO> fileList;
/**
* 角色集合
* 角色ID集合
*/
private List<Long> roleIds;
/**
* 角色集合
*/
private List<UserRoleDTO> userRoles;
}

View File

@ -241,23 +241,27 @@
<!-- </select>-->
<select id="getStaffCount" resultType="cn.iocoder.yudao.module.inspection.vo.StaffProjectCountVO"
parameterType="cn.iocoder.yudao.module.inspection.entity.DlInspectionProject">
SELECT
ip.id,ip.project_name, count(iwn.id) as count,is2.user_id,su.nickname
FROM inspection_staff is2
LEFT JOIN inspection_work_node iwn ON is2.user_id = iwn.deal_user_id
LEFT JOIN inspection_project ip ON iwn.project_id = ip.id
LEFT JOIN system_users su on su.id = is2.user_id
WHERE
ip.id in (
SELECT
ip2.id
FROM
inspection_project ip2
WHERE
ip2.deleted = 0
)
group by is2.user_id,ip.project_name
SELECT
ip.id AS project_id,
ip.project_name,
is2.user_id,
su.nickname,
COUNT(iwn.id) AS count
FROM inspection_staff is2
CROSS JOIN inspection_project ip
LEFT JOIN system_users su ON su.id = is2.user_id
LEFT JOIN inspection_work_node iwn ON
iwn.deal_user_id = is2.user_id
AND iwn.project_id = ip.id
<if test="datetimeRange != null">
AND iwn.create_time BETWEEN #{datetimeRange[0]} AND #{datetimeRange[1]}
</if>
WHERE
is2.deleted = 0
AND ip.deleted = 0
GROUP BY is2.user_id, ip.id
</select>
<select id="selectExceptionNodesByInspectionIds" resultType="java.util.Map">
SELECT
w.inspection_info_id AS inspectionInfoId,
@ -285,36 +289,54 @@
</select>
<select id="selectStaffProjectByUserId" resultType="java.util.Map">
SELECT
ii.id AS inspectionInfoId,
ii.user_id AS userId,
ii.user_name AS userName,
ii.buy_name AS buyName,
ii.buy_phone AS buyPhone,
ii.car_num AS carNum,
ii.car_model AS carModel,
ii.car_status AS carStatus,
ii.start_time AS startTime,
ii.end_time AS endTime,
ii.unit_name AS unitName,
ii.partner_id,
ii.work_id AS workId,
ii.worker_name AS workerName,
ii.worker_phone AS workerPhone,
ii.worker_avatar AS workerAvatar,
CASE
WHEN ii.is_pass = '0' THEN '不通过'
WHEN ii.is_pass = '1' THEN '通过'
WHEN ii.is_pass IS NULL THEN '进行中'
ELSE '未知'
END AS status,
GROUP_CONCAT(ip.project_name ORDER BY iwn.order_num SEPARATOR ',') AS projectName
ii.id AS inspectionInfoId,
ii.user_id AS userId,
ii.user_name AS userName,
ii.buy_name AS buyName,
ii.buy_phone AS buyPhone,
ii.car_num AS carNum,
ii.car_model AS carModel,
ii.car_status AS carStatus,
ii.start_time AS startTime,
ii.end_time AS endTime,
ii.unit_name AS unitName,
ii.partner_id,
ii.work_id AS workId,
ii.worker_name AS workerName,
ii.worker_phone AS workerPhone,
ii.worker_avatar AS workerAvatar,
CASE
WHEN ii.is_pass = '0' THEN '不通过'
WHEN ii.is_pass = '1' THEN '通过'
WHEN ii.is_pass IS NULL THEN '进行中'
ELSE '未知'
END AS status,
GROUP_CONCAT(ip.project_name ORDER BY iwn.order_num SEPARATOR ',') AS projectName
FROM inspection_work_node iwn
LEFT JOIN inspection_info ii ON iwn.inspection_info_id = ii.id
LEFT JOIN inspection_project ip ON ip.id = iwn.project_id
WHERE
iwn.deal_user_id = #{userId}
AND iwn.status = '2'
AND iwn.deleted = b'0'
LEFT JOIN inspection_info ii ON iwn.inspection_info_id = ii.id
LEFT JOIN inspection_project ip ON ip.id = iwn.project_id
<where>
<if test="query.userId != null">
AND iwn.deal_user_id = #{query.userId}
</if>
<if test="query.customerSource != null">
AND ii.customer_source = #{query.customerSource}
</if>
<if test="query.datetimeRange != null">
AND ii.create_time BETWEEN #{query.datetimeRange[0]} AND #{query.datetimeRange[1]}
</if>
<if test="query.customSource != null">
AND ii.customer_source = #{query.customSource}
</if>
<if test="query.bussiness != null">
AND ii.business_channel = #{query.bussiness}
</if>
<if test="query.projectId != null">
AND ip.id = #{query.projectId}
</if>
AND iwn.status = '2'
AND iwn.deleted = b'0'
</where>
GROUP BY ii.id
ORDER BY ii.start_time DESC;
</select>

View File

@ -265,7 +265,7 @@ where sig.partner_id =#{partnerId}
<!-- 待复检 -->
<if test="status == 4">
AND iwn.status = '3'
AND iwn.type = '0'
AND info.status != '1'
</if>
@ -476,6 +476,7 @@ FROM
count(1) allNum,
IFNULL(SUM(ii.status='0'),0) jxzNum,
IFNULL(SUM(ii.status='1'),0) ywcNum,
IFNULL(SUM(ii.status='1' and ii.is_pass='0'),0) tblNum,
IFNULL(SUM(oi.sku_name LIKE '%年审%'),0) nsNum,
IFNULL(SUM(oi.sku_name LIKE '%上户%'),0) shNum,
IFNULL(SUM(oi.sku_name LIKE '%非定检%'),0) fdjNum,
@ -710,7 +711,16 @@ FROM
AND TIMESTAMPDIFF(MINUTE, ii.start_time, ii.end_time)
BETWEEN #{query.inspectionTime[0]} AND #{query.inspectionTime[1]}
</if>
<if test="query.chooseStatus == '5'.toString()">
AND ii.reinspect_count != 0 AND ii.reinspect_count IS NOT NULL
</if>
<if test="query.chooseStatus == '6'.toString()">
AND ii.recheck_count != 0 AND ii.recheck_count IS NOT NULL
</if>
<if test="query.datetimeRange != null">
AND ii.create_time
BETWEEN CONCAT(#{query.datetimeRange[0]},' 00:00:00') AND CONCAT(#{query.datetimeRange[1]},' 23:59:59')
</if>
<if test="query.inspectionTime[0] !=null and query.inspectionTime.length == 1">
AND ii.start_time IS NOT NULL AND ii.end_time IS NOT NULL
AND TIMESTAMPDIFF(MINUTE, ii.start_time, ii.end_time) >= #{query.inspectionTime[0]}

View File

@ -20,4 +20,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
AND record.create_time between #{startTime} and #{endTime}
</if>
</select>
<select id="query" resultType="cn.iocoder.yudao.module.inspection.entity.InspectionFileRecord">
select record.*
from inspection_file_record record
INNER JOIN inspection_file file on record.file_id = file.id
where record.deleted = 0
AND file.service_package_id = #{servicePackageId}
<if test="startTime != null">
AND record.create_time between #{startTime} and #{endTime}
</if>
order by record.create_time desc
</select>
</mapper>

View File

@ -375,6 +375,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
AND ii.status = '0'
ORDER BY ii.update_time DESC
</if>
<!-- 还车 -->
<if test="inspectionInfo.status == 10">
AND ii.is_return_car != 1
AND ii.status = '1'
ORDER BY ii.update_time DESC
</if>
</where>
) AS subquery
WHERE rn = 1;
@ -566,6 +572,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
AND ii.lead_man_id IS NULL
AND ii.status = '0'
</if>
<!-- 还车 -->
<if test="inspectionInfo.status == 10">
AND ii.is_return_car != 1
AND ii.status = '1'
ORDER BY ii.update_time DESC
</if>
</where>
</if>
<if test="inspectionInfo.status == 6">
@ -605,4 +617,38 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</if>
</if>
</select>
<select id="geStelectInspectionByBusiness"
resultType="cn.iocoder.yudao.module.inspection.entity.InspectionInfo">
SELECT imco.meet_man_id,imco.buy_name,imco.buy_phone, imco.car_num,imco.other_phone
<if test="info.status != 1">
,ii.id AS id,imco.id AS meetCarId,oi.sku_name AS skuName,oi.goods_title,ii.*
</if>
<if test="info.status == 1">
,imco.id AS id
</if>
FROM inspection_meet_car_order imco
JOIN inspection_business_channel ibc
ON imco.customer_source_id = ibc.id
<if test="info.status != 1">
INNER JOIN inspection_info ii ON imco.inspection_info_id = ii.id AND ii.deleted = 0
LEFT JOIN order_info oi ON ii.inspection_order_id = oi.id AND oi.deleted = 0
</if>
<where>
ibc.deleted = 0
AND imco.deleted = 0
<if test="info.userId != null and info.userId != ''">
AND FIND_IN_SET(#{info.userId}, ibc.user_ids)
AND imco.creator = #{info.userId}
</if>
<if test="info.carNum != null and info.carNum != ''">
AND imco.car_num LIKE CONCAT('%', #{info.carNum}, '%')
</if>
<if test="info.status == 2">
AND ii.status = '0'
</if>
<if test="info.status == 3">
AND ii.status = '1'
</if>
</where>
</select>
</mapper>

View File

@ -68,7 +68,8 @@
iss.emergency_contact_name,
iss.emergency_contact_phone,
iss.driver_license_type,
iss.folder_id
iss.folder_id,
iss.unique_code
FROM system_users su
left join system_user_role sur on su.id = sur.user_id
left join system_role sr on sur.role_id = sr.id

View File

@ -78,6 +78,17 @@ public class DataViewController {
return success(dataViewService.selectIndexInfoByBusiness(type,timeType,coachId,startTime,endTime, isSign));
}
@GetMapping("/indexDataByWorking")
@Operation(summary = "首页数据统计查询接口")
public CommonResult<?> selectIndexInfoByWorking(@RequestParam(value = "type") String type,
@RequestParam(value = "timeType") String timeType,
@RequestParam(value = "coachId",required = false) Long coachId,
@RequestParam(value = "startTime",required = false) String startTime,
@RequestParam(value = "endTime",required = false) String endTime,
@RequestParam(value = "isSign",required = false) Integer isSign) {
return success(dataViewService.selectIndexInfoByWorking(type,timeType,coachId,startTime,endTime, isSign));
}
/**
* 查询学生总数
* @author vinjor-M

View File

@ -299,4 +299,5 @@ public class DlDriveSchoolCoachController {
Page<BusinessRecordVO> page = new Page<>(pageNo, pageSize);
return success(dlDriveSchoolCoachService.getBusinessManager(businessRecordVO, page));
}
}

View File

@ -38,4 +38,15 @@ public class DlDriveSchoolCoachCourseController {
public CommonResult<?> getCoachByCourseId(@RequestParam("courseId") String courseId) {
return success(coachCourseService.queryByCourseId(courseId));
}
/**
* 根据课程id获取教练信息
* @param courseId 课程id
* @return 教练信息
*/
@GetMapping("/getCoachByCourseIdAndSubject")
@Operation(summary = "根据课程id和科目获取教练信息")
public CommonResult<?> getCoachByCourseIdAndSubject(@RequestParam("courseId") String courseId, @RequestParam("subject") String subject) {
return success(coachCourseService.getCoachByCourseIdAndSubject(courseId, subject));
}
}

View File

@ -2,7 +2,9 @@ package cn.iocoder.yudao.module.base.controller.admin;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCourseService;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseNewVO;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseVO;
import cn.iocoder.yudao.module.course.entity.SchoolCourseScheme;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
@ -71,7 +73,7 @@ public class DlDriveSchoolCourseController {
**/
@PostMapping("/save")
@Operation(summary = "保存课程信息")
public CommonResult<Boolean> saveSchoolCoach(@Valid @RequestBody DlDriveSchoolCourseVO saveVO) {
public CommonResult<Boolean> saveSchoolCoach(@Valid @RequestBody DlDriveSchoolCourseNewVO saveVO) {
courseService.saveDriveSchoolCourse(saveVO);
return success(true);
}
@ -109,5 +111,12 @@ public class DlDriveSchoolCourseController {
return success(courseService.queryDetailById(id));
}
/**
* 根据课程id查询提成方案列表
*/
@GetMapping("/getSchemeList")
public CommonResult<List<SchoolCourseScheme>> getSchemeList(@RequestParam("id") String id) {
return success(courseService.getSchemeList(id));
}
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.base.controller.app;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
@ -20,6 +21,10 @@ import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "小程序 - 驾照报名订单")
@ -87,6 +92,16 @@ public class SchoolCourseOrderSmallProgramController {
return success(schoolCourseOrderService.getCourseByLoginUser(SecurityFrameworkUtils.getLoginUserId()));
}
/**
* 查询学员代报名且没有确认的订单
*/
@TenantIgnore
@GetMapping("/getCourseIfProxyOrders")
public CommonResult<?> getCourseIfProxyOrders() {
//获取当前登陆人
return success(schoolCourseOrderService.getCourseIfProxyOrders(SecurityFrameworkUtils.getLoginUserId()));
}
/**
* 报名之后发送对应消息
*/
@ -95,4 +110,19 @@ public class SchoolCourseOrderSmallProgramController {
public CommonResult<?> sendMessage(String studentName, String courseName,Long coachId) {
return success(schoolCourseOrderService.sendOrderMessage(studentName, courseName, coachId));
}
/**
* 代报名用户确认订单之后更新订单状态
*/
@PutMapping("/updateOrderIfAgree")
@TenantIgnore
public CommonResult<?> updateOrderIfAgree(String orderIds) {
if (StrUtil.isBlank(orderIds)) {
return CommonResult.success("请选择订单");
}
List<String> orderIdList = Arrays.stream(orderIds.split(";"))
.collect(Collectors.toList());
return CommonResult.success(schoolCourseOrderService.updateOrderifAgree(orderIdList));
}
}

View File

@ -25,7 +25,10 @@ public class DriveSchoolCourseDeduct extends TenantBaseDO
@Excel(name = "提成比例")
private BigDecimal deduct;
/** 科目id */
/** 提成方案id */
private String schemeId;
/** 课程id */
private String courseId;
/** 科目 */

View File

@ -27,4 +27,9 @@ public interface DlDriveSchoolCourseMapper extends BaseMapper<DlDriveSchoolCours
**/
IPage<DlDriveSchoolCourseVO> queryListPage(@Param("entity") DlDriveSchoolCourseVO entity, Page<DlDriveSchoolCourseVO> page);
}
/**
* 删除课程时判断订单中是否存在已报名该课程的订单
*/
Integer orderCountByCourseId(@Param("courseId") String courseId);
}

View File

@ -101,6 +101,7 @@ public interface DlDriveSchoolStudentMapper extends BaseMapper<DlDriveSchoolStud
List<DlDriveSchoolStudentVO> selectStudentListCoach(@Param("coachId") Long coachId, @Param("startTime") String startTime, @Param("endTime") String endTime);
List<DlDriveSchoolStudentVO> selectStudentListBusiness(@Param("coachId") Long coachId, @Param("startTime") String startTime, @Param("endTime") String endTime);
List<DlDriveSchoolStudentByBusinessVO> selectStudentListByBusiness(@Param("coachId") Long coachId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("isSign") Integer isSign);
List<DlDriveSchoolStudentByBusinessVO> selectIndexInfoByWorking(@Param("coachId") Long coachId, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("isSign") Integer isSign);
/**
* app首页查询训练学员---指定条件下

View File

@ -6,8 +6,10 @@ import cn.iocoder.yudao.module.jx.domain.DriveSchoolDeduct;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.pagehelper.Page;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@ -21,4 +23,12 @@ import java.util.List;
public interface DriveSchoolCourseDeductMapper extends BaseMapper<DriveSchoolCourseDeduct>
{
IPage<DriveSchoolCourseDeductVO> queryPage(@Param("page") Page<DriveSchoolCourseDeductVO> page, @Param("request") DriveSchoolCourseDeductVO request);
void deleteBySchemeId(@Param("schemeId") String schemeId);
void insertBatch(List<DriveSchoolCourseDeduct> list);
@Select("SELECT * FROM drive_school_course_deduct WHERE scheme_id = #{schemeId}")
List<DriveSchoolCourseDeduct> selectBySchemeId(@Param("schemeId") String schemeId);
}

View File

@ -31,6 +31,7 @@ public interface DataViewService {
**/
IndexDataVO selectIndexInfo(String type, String timeType, Long coachId, String startTime, String endTime);
IndexDataVO selectIndexInfoByBusiness(String type, String timeType, Long coachId, String startTime, String endTime, Integer isSign);
IndexDataVO selectIndexInfoByWorking(String type, String timeType, Long coachId, String startTime, String endTime, Integer isSign);
/**
* 查询学生总数

View File

@ -1,9 +1,11 @@
package cn.iocoder.yudao.module.base.service;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolCoach;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolCoachCourse;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCoachVO;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@ -44,4 +46,6 @@ public interface DlDriveSchoolCoachCourseService extends IService<DlDriveSchoolC
* @date 14:17 2025/2/8
**/
List<DlDriveSchoolCoachCourse> queryByCourseId(String courseId);
}
List<DlDriveSchoolCoachCourse> getCoachByCourseIdAndSubject(String courseId, String subject);
}

View File

@ -43,4 +43,6 @@ public interface DlDriveSchoolCourseDeductService extends IService<DriveSchoolCo
/** 根据课程id和科目查询提成配置 */
DriveSchoolCourseDeduct getDeductByCourseIdAndSubject(String courseId, Integer subject);
void deleteBySchemeId(String schemeId);
}

View File

@ -1,7 +1,9 @@
package cn.iocoder.yudao.module.base.service;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolCourse;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseNewVO;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseVO;
import cn.iocoder.yudao.module.course.entity.SchoolCourseScheme;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
@ -43,7 +45,7 @@ public interface DlDriveSchoolCourseService extends IService<DlDriveSchoolCourse
* @author PQZ
* @date 22:12 2025/1/16
**/
void saveDriveSchoolCourse(DlDriveSchoolCourseVO courseVO);
void saveDriveSchoolCourse(DlDriveSchoolCourseNewVO courseVO);
/**
* 删除课程信息
@ -64,4 +66,11 @@ public interface DlDriveSchoolCourseService extends IService<DlDriveSchoolCourse
**/
DlDriveSchoolCourseVO queryDetailById(String id);
}
/**
* 根据课程id查询提成方案列表
*/
public List<SchoolCourseScheme> getSchemeList(String id);
}

View File

@ -227,7 +227,7 @@ public class DataViewServiceImpl implements DataViewService {
schoolAmount = schoolAmount + item.getPriceAmount();
}
}
int allNum = coachNum + schoolNum;
int allNum = coachNum + schoolNum + businessNum;
double coachRate = 0;
double schoolRate = 0;
double businessRate = 0;
@ -445,6 +445,47 @@ public class DataViewServiceImpl implements DataViewService {
return rtnObj;
}
@Override
public IndexDataVO selectIndexInfoByWorking(String type, String timeType, Long coachId, String startTime, String endTime, Integer isSign) {
IndexDataVO rtnObj = new IndexDataVO();
DecimalFormat df = new DecimalFormat("#.00");
//默认查全部数据
String startTimeStr = "";
String endTimeStr = "";
if ("more".equals(timeType)) {
if (StringUtils.isNotEmpty(startTime)) {
startTimeStr = startTime + " 00:00:01";
}
if (StringUtils.isNotEmpty(endTime)) {
endTimeStr = endTime + " 23:59:59";
}
} else if ("month".equals(timeType)) {
//当月
startTimeStr = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd") + " 00:00:01";
endTimeStr = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd") + " 23:59:59";
} else if ("day".equals(timeType)) {
//当天
startTimeStr = DateUtil.formatDate(DateUtil.date()) + " 00:00:01";
endTimeStr = DateUtil.formatDate(DateUtil.date()) + " 23:59:59";
}
//业务经理查询
/*1.招生情况*/
List<DlDriveSchoolStudentByBusinessVO> studentVOList = studentMapper.selectIndexInfoByWorking(coachId, startTimeStr, endTimeStr,isSign);
int overNum = (int) studentVOList.stream().filter(item -> null != item.getOrderGradTime()).count();
int noOverNum = studentVOList.size() - overNum;
// courseTypeC1/C2统计
long c1Total = studentVOList.stream().filter(item -> "C1".equals(item.getCourseType())).count();
long c2Total = studentVOList.stream().filter(item -> "C2".equals(item.getCourseType())).count();
Map<String, Object> studentInfoMap = new HashMap<>();
studentInfoMap.put("allNum", studentVOList.size());
studentInfoMap.put("overNum", overNum);
studentInfoMap.put("noOverNum", noOverNum);
studentInfoMap.put("c1Total", c1Total);
studentInfoMap.put("c2Total", c2Total);
rtnObj.setStudentInfo(studentInfoMap);
return rtnObj;
}
/**
* 查询学生总数
*

View File

@ -87,4 +87,11 @@ public class DlDriveSchoolCoachCourseServiceImpl extends ServiceImpl<DlDriveScho
lambdaQueryWrapper.eq(DlDriveSchoolCoachCourse::getCourseId,courseId).eq(BaseDO::getDeleted,0).orderByDesc(BaseDO::getCreateTime);
return list(lambdaQueryWrapper);
}
}
@Override
public List<DlDriveSchoolCoachCourse> getCoachByCourseIdAndSubject(String courseId, String subject){
LambdaQueryWrapper<DlDriveSchoolCoachCourse> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(DlDriveSchoolCoachCourse::getCourseId,courseId).eq(DlDriveSchoolCoachCourse::getSubject,subject).eq(BaseDO::getDeleted,0).orderByDesc(BaseDO::getCreateTime);
return list(lambdaQueryWrapper);
}
}

View File

@ -82,4 +82,11 @@ public class DlDriveSchoolCourseDeductServiceImpl extends ServiceImpl<DriveSchoo
.eq(DriveSchoolCourseDeduct::getCourseSubject, subject)
.one();
}
@Override
public void deleteBySchemeId(String schemeId) {
LambdaQueryWrapper<DriveSchoolCourseDeduct> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(DriveSchoolCourseDeduct::getSchemeId, schemeId);
this.remove(wrapper);
}
}

View File

@ -1,31 +1,43 @@
package cn.iocoder.yudao.module.base.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.UUID;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolCoachCourse;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolCourse;
import cn.iocoder.yudao.module.base.entity.DriveSchoolCourseDeduct;
import cn.iocoder.yudao.module.base.mapper.DlDriveSchoolCourseMapper;
import cn.iocoder.yudao.module.base.mapper.DriveSchoolCourseDeductMapper;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCoachCourseService;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCourseDeductService;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCourseService;
import cn.iocoder.yudao.module.base.vo.CourseSchemeVO;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCoachVO;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseNewVO;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseVO;
import cn.iocoder.yudao.module.course.entity.SchoolCourseScheme;
import cn.iocoder.yudao.module.course.mapper.SchoolCourseSchemeMapper;
import cn.iocoder.yudao.module.course.service.SchoolCourseSchemeService;
import cn.iocoder.yudao.module.course.vo.SchoolCourseSchemeVO;
import cn.iocoder.yudao.module.jx.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
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.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@ -45,6 +57,12 @@ public class DlDriveSchoolCourseServiceImpl extends ServiceImpl<DlDriveSchoolCou
private DlDriveSchoolCoachCourseService coachCourseService;
@Resource
private DlDriveSchoolCourseDeductService driveSchoolCourseDeductService;
@Autowired
private SchoolCourseSchemeService schoolCourseSchemeService;
@Autowired
private SchoolCourseSchemeMapper schoolCourseSchemeMapper;
@Autowired
private DriveSchoolCourseDeductMapper schoolCourseDeductMapper;
/**
* 分页查询驾校课程
@ -91,7 +109,53 @@ public class DlDriveSchoolCourseServiceImpl extends ServiceImpl<DlDriveSchoolCou
**/
@Override
@Transactional(rollbackFor = Exception.class)
public void saveDriveSchoolCourse(DlDriveSchoolCourseVO courseVO) {
public void saveDriveSchoolCourse(DlDriveSchoolCourseNewVO courseVO) {
boolean isNew = (courseVO.getId() == null);
DlDriveSchoolCourse course = BeanUtils.toBean(courseVO, DlDriveSchoolCourse.class);
if (isNew) {
// 先保存课程生成 courseId
save(course);
List<CourseSchemeVO> schemeList = courseVO.getSchemeList();
if (schemeList == null || schemeList.isEmpty()) {
throw new RuntimeException("新增课程时必须至少包含一个提成方案");
}
for (CourseSchemeVO schemeVO : schemeList) {
// 构建方案对象主键为 UUID
String schemeId = UUID.randomUUID().toString().replace("-", "");
SchoolCourseScheme scheme = SchoolCourseScheme.builder()
.id(schemeId)
.name(schemeVO.getSchemeName())
.courseId(course.getId())
.isDefault(Boolean.TRUE.equals(schemeVO.getIsDefault()))
.build();
schoolCourseSchemeService.save(scheme);
// 保存方案对应的提成明细
List<DriveSchoolCourseDeduct> deductList = schemeVO.getDeductList();
if (deductList != null && !deductList.isEmpty()) {
for (DriveSchoolCourseDeduct deduct : deductList) {
deduct.setCourseId(course.getId());
deduct.setSchemeId(schemeId);
deduct.setId(null);
}
driveSchoolCourseDeductService.saveBatch(deductList);
}
}
} else {
// 修改课程保留提成方案及提成明细不变
updateById(course);
}
// 保存教练课程关系
coachCourseService.saveCoachCourse(course.getId(), courseVO.getName(), courseVO.getType(), courseVO.getCoachList());
}
/*public void saveDriveSchoolCourse(DlDriveSchoolCourseVO courseVO) {
DlDriveSchoolCourse course = BeanUtils.toBean(courseVO, DlDriveSchoolCourse.class);
saveOrUpdate(course);
coachCourseService.saveCoachCourse(course.getId(), courseVO.getName(), courseVO.getType(), courseVO.getCoachList());
@ -106,7 +170,8 @@ public class DlDriveSchoolCourseServiceImpl extends ServiceImpl<DlDriveSchoolCou
// 保存提成信息
driveSchoolCourseDeductService.saveBatch(courseVO.getDeductList());
}
}*/
/**
* 删除课程信息
@ -117,7 +182,14 @@ public class DlDriveSchoolCourseServiceImpl extends ServiceImpl<DlDriveSchoolCou
**/
@Override
public void deleteCourse(String id) {
removeById(id);
// 删除前判断是否有已报名课程的订单
Integer count = courseMapper.orderCountByCourseId(id);
if(count > 0){
throw new RuntimeException("该课程有已报名订单,无法删除");
}else{
removeById(id);
}
}
/**
@ -188,5 +260,66 @@ public class DlDriveSchoolCourseServiceImpl extends ServiceImpl<DlDriveSchoolCou
return transList;
}
/**
* 根据课程id查询提成方案列表
*/
@Override
public List<SchoolCourseScheme> getSchemeList(String courseId) {
List<SchoolCourseScheme> schemes = schoolCourseSchemeMapper.selectList(
new LambdaQueryWrapper<SchoolCourseScheme>()
.eq(SchoolCourseScheme::getCourseId, courseId)
.eq(SchoolCourseScheme::getDeleted, false)
);
if (CollectionUtils.isEmpty(schemes)) {
return Collections.emptyList();
}
// 批量查询这些方案的提成明细一次性查询避免循环查库
List<String> schemeIds = schemes.stream()
.map(SchoolCourseScheme::getId)
.collect(Collectors.toList());
List<DriveSchoolCourseDeduct> allDeducts = schoolCourseDeductMapper.selectList(
new LambdaQueryWrapper<DriveSchoolCourseDeduct>()
.in(DriveSchoolCourseDeduct::getSchemeId, schemeIds)
.eq(DriveSchoolCourseDeduct::getDeleted, false)
);
// 将提成明细按 schemeId 分组
Map<String, List<DriveSchoolCourseDeduct>> deductsByScheme = allDeducts.stream()
.collect(Collectors.groupingBy(DriveSchoolCourseDeduct::getSchemeId));
// 组装前端需要的结构
return schemes.stream().map(scheme -> {
// 提取当前方案的所有提成记录
List<DriveSchoolCourseDeduct> deducts = deductsByScheme.getOrDefault(scheme.getId(), Collections.emptyList());
// 转换为前端需要的字段格式科目0-4分别映射
Map<String, BigDecimal> deductMap = deducts.stream()
.collect(Collectors.toMap(
DriveSchoolCourseDeduct::getCourseSubject,
DriveSchoolCourseDeduct::getDeduct,
(v1, v2) -> v1
));
// 设置到 scheme 对象中
SchoolCourseSchemeVO result = BeanUtils.toBean(scheme, SchoolCourseSchemeVO.class);
/*result.setId(scheme.getId());
result.setCourseId(scheme.getCourseId());
result.setIsDefault(scheme.getIsDefault());
result.setCourseId(scheme.getCourseId());*/
result.setName(scheme.getName());
result.setSubject0Deduct(deductMap.getOrDefault("0", BigDecimal.ZERO));
result.setSubject1Deduct(deductMap.getOrDefault("1", BigDecimal.ZERO));
result.setSubject2Deduct(deductMap.getOrDefault("2", BigDecimal.ZERO));
result.setSubject3Deduct(deductMap.getOrDefault("3", BigDecimal.ZERO));
result.setSubject4Deduct(deductMap.getOrDefault("4", BigDecimal.ZERO));
return result;
}).collect(Collectors.toList());
}
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.base.vo;
import cn.iocoder.yudao.module.base.entity.DriveSchoolCourseDeduct;
import lombok.Data;
import java.util.List;
@Data
public class CourseSchemeVO {
/** 方案id */
private String schemeId;
/** 方案名称 */
private String schemeName;
/** 是否默认 */
private Boolean isDefault;
/** 提成明细 */
private List<DriveSchoolCourseDeduct> deductList;
}

View File

@ -0,0 +1,16 @@
package cn.iocoder.yudao.module.base.vo;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolCourse;
import cn.iocoder.yudao.module.base.entity.DriveSchoolCourseDeduct;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Schema(description = "驾校课程管理VO")
@Data
public class DlDriveSchoolCourseNewVO extends DlDriveSchoolCourse {
private List<DlDriveSchoolCoachVO> coachList;
private String coachListText;
private List<CourseSchemeVO> schemeList;
}

View File

@ -68,4 +68,7 @@ public class DlDriveSchoolStaffVO {
private Date gradTime;
/**拿证时间*/
private Date passTime;
/**总招生数*/
private Integer studentTotalNum;
}

View File

@ -45,4 +45,6 @@ public class DlDriveSchoolStudentVO extends DlDriveSchoolStudent {
private String sort;
/**是否面签*/
private Integer isSign;
/**查询人员类型*/
private String pType;
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.base.vo;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class SchemeFormDTO {
private String id;
private String name;
private String courseId;
private Boolean isDefault;
private BigDecimal subject0Deduct;
private BigDecimal subject1Deduct;
private BigDecimal subject2Deduct;
private BigDecimal subject3Deduct;
private BigDecimal subject4Deduct;
}

View File

@ -3,9 +3,11 @@ package cn.iocoder.yudao.module.course.controller.admin;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolStudent;
import cn.iocoder.yudao.module.base.entity.DriveSchoolCourseDeduct;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCourseDeductService;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCourseService;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolStudentService;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseVO;
import cn.iocoder.yudao.module.course.entity.Process;
import cn.iocoder.yudao.module.course.service.ProcessService;
@ -41,15 +43,18 @@ public class ProcessController {
@Resource
private ProcessService processService;
@Autowired
@Resource
private DlDriveSchoolCourseDeductService driveSchoolCourseDeductService;
@Autowired
@Resource
private IDriveSchoolDeductService driveSchoolDeductService;
@Resource
private SchoolCourseOrderService schoolCourseOrderService;
@Resource
private DlDriveSchoolStudentService schoolStudentService;
@ -122,38 +127,8 @@ public class ProcessController {
@Operation(summary = "通过id 查询学员进度课程")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<ProcessVO> getDlDriveSchoolCoach(@RequestParam("id") String id) {
ProcessVO processVO = BeanUtils.toBean(processService.getById(id), ProcessVO.class);
Long coachId = processVO.getCoachId();
Integer subject = processVO.getSubject();
Long userId = processVO.getUserId();
String courseId = processVO.getCourseId();
BigDecimal deduct = BigDecimal.ZERO;
DriveSchoolCourseDeduct courseDeduct = driveSchoolCourseDeductService.getDeductByCourseIdAndSubject(courseId, subject);
if (courseDeduct != null) {
if (courseDeduct.getDeduct() != null) {
deduct = courseDeduct.getDeduct();
}
else if (courseDeduct.getCourseSubject() != null) {
DriveSchoolDeduct schoolDeduct = driveSchoolDeductService.queryBySubject(courseDeduct.getCourseSubject());
if (schoolDeduct != null && schoolDeduct.getDeduct() != null) {
deduct = schoolDeduct.getDeduct();
}
}
}
List<SchoolCourseOrderVO> courseByInfo = schoolCourseOrderService.getCourseByInfo(userId, courseId);
BigDecimal studentPay = BigDecimal.ZERO;
BigDecimal studentRemainingPay = BigDecimal.ZERO;
if (!courseByInfo.isEmpty()) {
studentPay = courseByInfo.get(0).getReserveMoney() != null ?
courseByInfo.get(0).getReserveMoney() : BigDecimal.ZERO;
studentRemainingPay = courseByInfo.get(0).getRestMoney() != null ?
courseByInfo.get(0).getRestMoney() : BigDecimal.ZERO;
}
processVO.setCoachCommission(deduct);
processVO.setStudentPay(studentPay);
processVO.setStudentRemainingPay(studentRemainingPay);
return success(processVO);
ProcessVO dlDriveSchoolCoach = processService.getDlDriveSchoolCoach(id);
return success(dlDriveSchoolCoach);
}
@GetMapping("/getProcessAndBatch")
@ -216,4 +191,11 @@ public class ProcessController {
return success(true);
}
/**
* 在录入成绩处修改教练
*/
@GetMapping("/updateCoach")
public CommonResult<Boolean> updateCoachForScoreInput(String id, Long coachId, String coachName){
return success(processService.updateCoachForScoreInput(id, coachId, coachName));
}
}

View File

@ -150,4 +150,15 @@ public class SchoolCourseOrderController {
// return success("");
return success(schoolCourseOrderService.businessManagerCreateSchoolCourseOrder(createReqVO));
}
/**
* 查询是否有订单使用该提成方案
*/
@GetMapping("getOrderCountBySchemeId")
public CommonResult<Integer> getOrderCountBySchemeId(String schemeId){
return success(schoolCourseOrderService.getOrderCountBySchemeId(schemeId));
}
}

View File

@ -0,0 +1,52 @@
package cn.iocoder.yudao.module.course.controller.admin;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.base.entity.DriveSchoolCourseDeduct;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCourseDeductService;
import cn.iocoder.yudao.module.base.vo.SchemeFormDTO;
import cn.iocoder.yudao.module.course.entity.SchoolCourseScheme;
import cn.iocoder.yudao.module.course.service.SchoolCourseSchemeService;
import cn.iocoder.yudao.module.course.vo.SchoolCourseSchemeVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Arrays;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 课程-方案关联")
@RestController
@RequestMapping("/courseScheme")
@Validated
public class SchoolCourseSchemeController {
@Autowired
private SchoolCourseSchemeService schoolCourseSchemeService;
@GetMapping("/get/{id}")
@Operation(summary = "获取提成方案详情")
public CommonResult<SchoolCourseSchemeVO> getScheme(@PathVariable String id) {
return CommonResult.success(schoolCourseSchemeService.getSchemeDetail(id));
}
@PostMapping("/save")
@Operation(summary = "新增/修改提成方案")
public CommonResult<Boolean> saveScheme(@Valid @RequestBody SchemeFormDTO reqVO) {
schoolCourseSchemeService.saveOrUpdateScheme(reqVO);
return CommonResult.success(true);
}
@DeleteMapping("/delete/{id}")
@Operation(summary = "删除提成方案")
public CommonResult<Boolean> deleteScheme(@PathVariable String id) {
schoolCourseSchemeService.deleteScheme(id);
return CommonResult.success(true);
}
}

View File

@ -127,10 +127,20 @@ public class SchoolCourseOrder extends TenantBaseDO {
*/
private String signType;
/**
* 是否同意代报名
*/
private String ifAgree;
/**
* 支付渠道微信1线下2
*/
private String payChannel;
/**
* 提成方案id
*/
private String schemeId;
}

View File

@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.course.entity;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 驾校-课程-方案关联表
*
* @author 若依
*/
@TableName("drive_school_course_scheme")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SchoolCourseScheme extends TenantBaseDO {
/**
* 方案id
*/
private String id;
/**
* 方案名称
*/
private String name;
/**
* 课程id
*/
private String courseId;
/**
* 是否默认
*/
private Boolean isDefault;
}

View File

@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCoachRespVO;
import cn.iocoder.yudao.module.course.entity.Process;
import cn.iocoder.yudao.module.course.vo.ProcessAndExamBatchVO;
import cn.iocoder.yudao.module.course.vo.ProcessVO;
import cn.iocoder.yudao.module.exam.entity.ExamBatch;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -87,4 +88,8 @@ public interface ProcessMapper extends BaseMapper<Process> {
@Param("subject") int subject,
@Param("fraction") double fraction,
@Param("userId") Long userId);
ExamBatch getBatchForProcess(@Param("entity") Process entity);
}

View File

@ -49,4 +49,14 @@ public interface SchoolCourseOrderMapper extends BaseMapper<SchoolCourseOrder> {
/**创建学员Users表信息*/
Long createStudentUsers(AdminUserDO adminUserDO);
/**
* 根据学员id获取订单提成方案
*/
String getSchemeByStudentId(@Param("studentId") Long studentId, @Param("courseId") String courseId, @Param("subject") Integer subject);
/**
* 查询是否有订单使用该提成方案
*/
Integer getOrderCountBySchemeId(@Param("schemeId") String schemeId);
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.course.mapper;
import cn.iocoder.yudao.module.course.entity.Process;
import cn.iocoder.yudao.module.course.entity.SchoolCourseScheme;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import java.math.BigDecimal;
@Mapper
public interface SchoolCourseSchemeMapper extends BaseMapper<SchoolCourseScheme> {
@Update("UPDATE drive_school_course_scheme SET is_default = false " +
"WHERE course_id = #{courseId} AND id != #{excludeId} AND is_default = true")
int cancelOtherDefault(@Param("courseId") String courseId,
@Param("excludeId") String excludeId);
BigDecimal getCourseDeduct(@Param("courseId") String courseId, @Param("subject") Integer subject);
BigDecimal getSchemeById(@Param("id") String id, @Param("subject") Integer subject);
/**
* 查询是否有订单使用该提成方案
*/
Integer getOrderCountBySchemeId(@Param("schemeId") String schemeId);
}

View File

@ -143,4 +143,14 @@ public interface ProcessService extends IService<Process> {
ProcessAndExamBatchVO getProcessAndBatch(String id);
/**
* 根据进度id查询进度详情
* @param id 进度id
*/
ProcessVO getDlDriveSchoolCoach(String id);
/**
* 在录入成绩出修改教练
*/
Boolean updateCoachForScoreInput(String id, Long coachId, String coachName);
}

View File

@ -86,6 +86,12 @@ public interface SchoolCourseOrderService extends IService<SchoolCourseOrder> {
* @return List<SchoolCourseOrderVO>
*/
List<SchoolCourseOrderVO> getCourseByLoginUser(Long loginUserId);
/**
* 查询学员代报名且没有确认的订单
* @param loginUserId
* @return
*/
List<SchoolCourseOrderVO> getCourseIfProxyOrders(Long loginUserId);
List<SchoolCourseOrderVO> getCourseByInfo(Long userId, String courseId);
/**
@ -104,5 +110,19 @@ public interface SchoolCourseOrderService extends IService<SchoolCourseOrder> {
void updateStudentPassTime(String studentId, String gradTime);
Long businessManagerCreateSchoolCourseOrder(SchoolCourseOrderBusinessVO createReqVO);
/**
* 代报名用户确认订单之后更新订单状态
*/
boolean updateOrderifAgree(List<String> orderIds);
/**
* 根据学员id获取订单提成方案
*/
String getSchemeByStudentId(Long studentId, String courseId, Integer subject);
/**
* 查询是否有订单使用该提成方案
*/
Integer getOrderCountBySchemeId(String schemeId);
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.course.service;
import cn.iocoder.yudao.module.base.vo.SchemeFormDTO;
import cn.iocoder.yudao.module.course.entity.SchoolCourseOrder;
import cn.iocoder.yudao.module.course.entity.SchoolCourseScheme;
import cn.iocoder.yudao.module.course.vo.SchoolCourseSchemeVO;
import com.baomidou.mybatisplus.extension.service.IService;
import java.math.BigDecimal;
import java.util.List;
public interface SchoolCourseSchemeService extends IService<SchoolCourseScheme> {
void saveOrUpdateScheme(SchemeFormDTO dto);
void deleteScheme(String id);
SchoolCourseSchemeVO getSchemeDetail(String id);
/**
* 根据课程id和科目获取默认提成金额
* @param courseId
* @param subject
* @return
*/
BigDecimal getCourseDeduct(String courseId, Integer subject);
/**
* 根据提成方案id和科目获取对应提成金额
*/
BigDecimal getSchemeById(String id, Integer subject);
}

View File

@ -7,6 +7,7 @@ import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.base.constant.SchoolBaseConstants;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolStudent;
import cn.iocoder.yudao.module.base.mapper.DlDriveSchoolCourseMapper;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCourseService;
import cn.iocoder.yudao.module.base.entity.DriveSchoolCourseDeduct;
@ -21,7 +22,12 @@ import cn.iocoder.yudao.module.course.mapper.ProcessMapper;
import cn.iocoder.yudao.module.course.service.ProcessService;
import cn.iocoder.yudao.module.course.service.SchoolCommissionService;
import cn.iocoder.yudao.module.course.service.SchoolCourseOrderService;
import cn.iocoder.yudao.module.course.service.SchoolCourseSchemeService;
import cn.iocoder.yudao.module.course.vo.*;
import cn.iocoder.yudao.module.exam.entity.ExamBatch;
import cn.iocoder.yudao.module.exam.entity.ExamBatchItem;
import cn.iocoder.yudao.module.exam.mapper.ExamBatchMapper;
import cn.iocoder.yudao.module.exam.vo.ExamBatchItemVO;
import cn.iocoder.yudao.module.exam.vo.ExamVO;
import cn.iocoder.yudao.module.exam.mapper.ExamBatchItemMapper;
import cn.iocoder.yudao.module.exam.vo.ExamBatchItemNewVO;
@ -42,6 +48,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
@ -72,6 +79,9 @@ public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> impl
@Autowired
private ExamBatchItemMapper examBatchItemMapper;
@Resource
private ExamBatchMapper examBatchMapper;
@Autowired
private SchoolNotifyMessageSendService schoolNotifyMessageSendService;
@ -81,6 +91,12 @@ public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> impl
@Autowired
private DlDriveSchoolCourseDeductService deductService;
@Resource
private IDriveSchoolDeductService driveSchoolDeductService;
@Resource
private SchoolCourseSchemeService schemeService;
/**
* 教练查自己带教的课程和科目
@ -725,4 +741,129 @@ public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> impl
return processAndExamBatchVO;
}
/**
* 根据进度id查询进度详情
*
*/
@Override
public ProcessVO getDlDriveSchoolCoach(String id) {
// ProcessVO processVO = BeanUtils.toBean(this.getById(id), ProcessVO.class);
ProcessVO processVO = new ProcessVO();
BeanUtil.copyProperties(this.getById(id), processVO);
Long coachId = processVO.getCoachId();
Integer subject = processVO.getSubject();
Long userId = processVO.getUserId();
String courseId = processVO.getCourseId();
BigDecimal deduct = BigDecimal.ZERO;
String schemeId = schoolCourseOrderService.getSchemeByStudentId(userId, courseId, subject);
if(schemeId == null){
deduct = schemeService.getCourseDeduct(courseId, subject);
if(deduct == null){
DriveSchoolDeduct schoolDeduct = driveSchoolDeductService.queryBySubject(subject.toString());
if (schoolDeduct != null && schoolDeduct.getDeduct() != null) {
deduct = schoolDeduct.getDeduct();
}
}
}else{
deduct = schemeService.getSchemeById(schemeId, subject);
if(deduct == null){
DriveSchoolDeduct schoolDeduct = driveSchoolDeductService.queryBySubject(subject.toString());
if (schoolDeduct != null && schoolDeduct.getDeduct() != null) {
deduct = schoolDeduct.getDeduct();
}
}
}
/*DriveSchoolCourseDeduct courseDeduct = deductService.getDeductByCourseIdAndSubject(courseId, subject);
if (courseDeduct != null) {
if (courseDeduct.getDeduct() != null) {
deduct = courseDeduct.getDeduct();
}
else if (courseDeduct.getCourseSubject() != null) {
DriveSchoolDeduct schoolDeduct = driveSchoolDeductService.queryBySubject(courseDeduct.getCourseSubject());
if (schoolDeduct != null && schoolDeduct.getDeduct() != null) {
deduct = schoolDeduct.getDeduct();
}
}
}*/
List<SchoolCourseOrderVO> courseByInfo = schoolCourseOrderService.getCourseByInfo(userId, courseId);
BigDecimal studentPay = BigDecimal.ZERO;
BigDecimal studentRemainingPay = BigDecimal.ZERO;
if (!courseByInfo.isEmpty()) {
studentPay = courseByInfo.get(0).getReserveMoney() != null ?
courseByInfo.get(0).getReserveMoney() : BigDecimal.ZERO;
studentRemainingPay = courseByInfo.get(0).getRestMoney() != null ?
courseByInfo.get(0).getRestMoney() : BigDecimal.ZERO;
}
processVO.setCoachCommission(deduct);
processVO.setStudentPay(studentPay);
processVO.setStudentRemainingPay(studentRemainingPay);
return processVO;
}
/**
* 在录入成绩出修改教练
*/
@Override
public Boolean updateCoachForScoreInput(String id, Long coachId, String coachName) {
Process process = processMapper.selectById(id);
if (process == null) {
return false;
}
process.setCoachId(coachId);
process.setCoachName(coachName);
int updateCount;
if(process.getSubject() == 1 || process.getSubject() == 4){
// 不生成批次信息
updateCount = processMapper.updateById(process);
}else{
// 科二和科三会生成批次信息如果有批次信息需要修改批次信息
updateCount = processMapper.updateById(process);
ExamBatch batchIdForProcess = processMapper.getBatchForProcess(process);
if(batchIdForProcess != null){
List<ExamBatchItemVO> batchItemVOList = examBatchItemMapper.getBatchItemCount(batchIdForProcess.getId());
if(batchItemVOList.size() == 1){
ExamBatch examBatch = examBatchMapper.selectById(batchIdForProcess);
examBatch.setCoachId(process.getCoachId());
examBatch.setCoachName(process.getCoachName());
examBatchMapper.updateById(examBatch);
// 如果数量大于1则需要新建批次和批次明细数据
}else if(batchItemVOList.size() > 1){
// 先通过batchId和userId 获取对应数据通过id进行删除
LambdaQueryWrapper<ExamBatchItem> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ExamBatchItem::getBatchId, batchIdForProcess)
.eq(ExamBatchItem::getUserId, process.getUserId())
.eq(ExamBatchItem::getDeleted, false);
List<ExamBatchItem> batchItems = examBatchItemMapper.selectList(wrapper);
// 将之前的数据拷贝并设置新的id和教练
ExamBatch newExamBatch = new ExamBatch();
BeanUtils.copyProperties(batchIdForProcess, newExamBatch, "id");
newExamBatch.setId(this.getUUID());
newExamBatch.setCoachId(process.getCoachId());
newExamBatch.setCoachName(process.getCoachName());
newExamBatch.setBatchName(newExamBatch.getBatchName() + "1");
examBatchMapper.insert(newExamBatch);
for (ExamBatchItem batchItem : batchItems) {
if(Objects.equals(batchIdForProcess.getId(), batchItem.getBatchId())){
batchItem.setBatchId(newExamBatch.getId());
examBatchItemMapper.updateById(batchItem);
}
}
}
}
}
if(updateCount > 0){
return true;
}else{
return false;
}
}
/**
* 生成32位uuid
*/
public String getUUID() {
UUID uuid = UUID.randomUUID();
return uuid.toString().replace("-", "");
}
}

View File

@ -24,7 +24,9 @@ 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.system.dal.dataobject.user.AdminUserDO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -95,7 +97,7 @@ public class SchoolCourseOrderServiceImpl extends ServiceImpl<SchoolCourseOrderM
SchoolCourseOrder schoolCourseOrder = schoolCourseOrderMapper.selectById(updateReqVO.getId());
DlDriveSchoolStudent studentByUserId = schoolStudentService.getStudentByUserId(Long.valueOf(updateReqVO.getUserId()));
if(studentByUserId != null){
if("04".equals(studentByUserId.getSource()) && studentByUserId.getSourceUserId() != null){
if(("01".equals(studentByUserId.getSource()) || "04".equals(studentByUserId.getSource())) && studentByUserId.getSourceUserId() != null){
if(schoolCourseOrder != null){
// 面签成功
if(schoolCourseOrder.getIsSign() == 0 && updateReqVO.getIsSign() == 1){
@ -257,6 +259,22 @@ public class SchoolCourseOrderServiceImpl extends ServiceImpl<SchoolCourseOrderM
return BeanUtil.copyToList(list, SchoolCourseOrderVO.class);
}
/**
* 查询学员代报名且没有确认的订单
* @param loginUserId
* @return
*/
public List<SchoolCourseOrderVO> getCourseIfProxyOrders(Long loginUserId) {
List<SchoolCourseOrder> list = list(Wrappers.lambdaQuery(SchoolCourseOrder.class)
.eq(SchoolCourseOrder::getUserId, loginUserId)
.eq(SchoolCourseOrder::getIfEnd, SchoolBaseConstants.COMMON_NO)
.isNotNull(SchoolCourseOrder::getSignType)
.isNotNull(SchoolCourseOrder::getIfAgree)
.eq(SchoolCourseOrder::getIfAgree, 0)
.eq(SchoolCourseOrder::getDeleted, SchoolBaseConstants.COMMON_NO));
return BeanUtil.copyToList(list, SchoolCourseOrderVO.class);
}
/**
* 根据获取订单信息
*
@ -369,7 +387,7 @@ public class SchoolCourseOrderServiceImpl extends ServiceImpl<SchoolCourseOrderM
}
public String generateOrderNum() {
return "DXD" + UUID.randomUUID().toString().replace("-", "").substring(0, 10);
return "DBM" + UUID.randomUUID().toString().replace("-", "").substring(0, 10);
}
@Transactional(rollbackFor = Exception.class)
@ -381,7 +399,7 @@ public class SchoolCourseOrderServiceImpl extends ServiceImpl<SchoolCourseOrderM
DlDriveSchoolStudentVO dlDriveSchoolStudentVO = new DlDriveSchoolStudentVO();
dlDriveSchoolStudentVO.setName(createReqVO.getUserName());
dlDriveSchoolStudentVO.setAge(createReqVO.getAge());
dlDriveSchoolStudentVO.setSource("04");
dlDriveSchoolStudentVO.setSource(createReqVO.getSource());
dlDriveSchoolStudentVO.setSourceUserId(SecurityFrameworkUtils.getLoginUserId());
dlDriveSchoolStudentVO.setSex(createReqVO.getUserSex());
dlDriveSchoolStudentVO.setPhone(createReqVO.getUserPhone());
@ -403,4 +421,32 @@ public class SchoolCourseOrderServiceImpl extends ServiceImpl<SchoolCourseOrderM
}
@Override
public boolean updateOrderifAgree(List<String> orderIds) {
if (CollectionUtils.isEmpty(orderIds)) {
return false;
}
LambdaUpdateWrapper<SchoolCourseOrder> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.in(SchoolCourseOrder::getId, orderIds)
.set(SchoolCourseOrder::getIfAgree, 1);
return this.update(updateWrapper);
}
/**
* 根据学员id获取订单提成方案
*/
@Override
public String getSchemeByStudentId(Long studentId, String courseId, Integer subject) {
return schoolCourseOrderMapper.getSchemeByStudentId(studentId, courseId, subject);
}
/**
* 查询是否有订单使用该提成方案
*/
@Override
public Integer getOrderCountBySchemeId(String schemeId){
return schoolCourseOrderMapper.getOrderCountBySchemeId(schemeId);
}
}

View File

@ -0,0 +1,210 @@
package cn.iocoder.yudao.module.course.service.impl;
import cn.hutool.core.lang.UUID;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.base.entity.DriveSchoolCourseDeduct;
import cn.iocoder.yudao.module.base.mapper.DriveSchoolCourseDeductMapper;
import cn.iocoder.yudao.module.base.vo.SchemeFormDTO;
import cn.iocoder.yudao.module.course.entity.SchoolCourseOrder;
import cn.iocoder.yudao.module.course.entity.SchoolCourseScheme;
import cn.iocoder.yudao.module.course.mapper.SchoolCourseOrderMapper;
import cn.iocoder.yudao.module.course.mapper.SchoolCourseSchemeMapper;
import cn.iocoder.yudao.module.course.service.SchoolCourseOrderService;
import cn.iocoder.yudao.module.course.service.SchoolCourseSchemeService;
import cn.iocoder.yudao.module.course.vo.SchoolCourseSchemeVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@Service
@Validated
public class SchoolCourseSchemeServiceImpl extends ServiceImpl<SchoolCourseSchemeMapper, SchoolCourseScheme> implements SchoolCourseSchemeService {
@Resource
private SchoolCourseSchemeMapper schemeMapper;
@Resource
private DriveSchoolCourseDeductMapper deductMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public void saveOrUpdateScheme(SchemeFormDTO dto) {
// 判断是否新增
boolean isUpdate = dto.getId() != null;
// 设置ID如果是新增则生成UUID
String schemeId = isUpdate ? dto.getId() : UUID.randomUUID().toString().replace("-", "");
// 保存/更新方案主表
SchoolCourseScheme scheme = new SchoolCourseScheme()
.setId(schemeId)
.setName(dto.getName())
.setCourseId(dto.getCourseId())
.setIsDefault(dto.getIsDefault());
if (isUpdate) {
schemeMapper.updateById(scheme);
// deductMapper.deleteBySchemeId(dto.getId());
} else {
schemeMapper.insert(scheme);
}
// 保存提成配置
saveDeductConfigs(scheme.getId(), dto);
// 处理默认方案
if (Boolean.TRUE.equals(dto.getIsDefault())) {
schemeMapper.cancelOtherDefault(scheme.getCourseId(), scheme.getId());
}
}
private void saveDeductConfigs(String schemeId, SchemeFormDTO dto) {
upsertDeduct(schemeId, dto.getCourseId(), "0", dto.getSubject0Deduct());
upsertDeduct(schemeId, dto.getCourseId(), "1", dto.getSubject1Deduct());
upsertDeduct(schemeId, dto.getCourseId(), "2", dto.getSubject2Deduct());
upsertDeduct(schemeId, dto.getCourseId(), "3", dto.getSubject3Deduct());
upsertDeduct(schemeId, dto.getCourseId(), "4", dto.getSubject4Deduct());
}
private void upsertDeduct(String schemeId, String courseId, String subject, BigDecimal amount) {
if (amount == null) {
return;
}
DriveSchoolCourseDeduct deduct = deductMapper.selectOne(
new LambdaQueryWrapper<DriveSchoolCourseDeduct>()
.eq(DriveSchoolCourseDeduct::getSchemeId, schemeId)
.eq(DriveSchoolCourseDeduct::getCourseSubject, subject)
.eq(DriveSchoolCourseDeduct::getDeleted, false)
);
if (deduct != null) {
// 更新已有记录
deduct.setDeduct(amount);
deductMapper.updateById(deduct);
} else {
// 插入新记录
DriveSchoolCourseDeduct newDeduct = new DriveSchoolCourseDeduct()
.setSchemeId(schemeId)
.setCourseId(courseId)
.setCourseSubject(subject)
.setDeduct(amount);
deductMapper.insert(newDeduct);
}
}
private void addDeductIfPositive(List<DriveSchoolCourseDeduct> list, String schemeId,
String courseId, String subject, BigDecimal amount) {
if (amount != null && amount.compareTo(BigDecimal.ZERO) > 0) {
list.add(new DriveSchoolCourseDeduct()
.setSchemeId(schemeId)
.setCourseId(courseId)
.setCourseSubject(subject)
.setDeduct(amount));
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteScheme(String id) {
// 校验存在
validateSchemeExists(id);
// 检查是否有订单在使用当前方案
Integer count = schemeMapper.getOrderCountBySchemeId(id);
if(count > 0){
throw new RuntimeException("有订单正在使用该方案,不能删除");
}else{
// 删除关联提成
// deductMapper.deleteBySchemeId(id);
deductMapper.delete(new LambdaQueryWrapper<DriveSchoolCourseDeduct>()
.eq(DriveSchoolCourseDeduct::getSchemeId, id));
// 删除方案
schemeMapper.deleteById(id);
}
}
private void validateSchemeExists(String id) {
if (schemeMapper.selectById(id) == null) {
throw new RuntimeException("方案不存在");
}
}
@Override
public SchoolCourseSchemeVO getSchemeDetail(String id) {
// 1. 查询方案基础信息
SchoolCourseScheme scheme = schemeMapper.selectById(id);
if (scheme == null) {
throw new RuntimeException("方案不存在");
}
// 2. 查询关联提成配置
List<DriveSchoolCourseDeduct> deducts = deductMapper.selectBySchemeId(id);
// 3. 转换为前端需要的结构
return convertToDetailVO(scheme, deducts);
}
/**
* 根据课程id和科目获取默认提成金额
*/
@Override
public BigDecimal getCourseDeduct(String courseId, Integer subject) {
return schemeMapper.getCourseDeduct(courseId, subject);
}
/**
* 根据提成方案id和科目获取对应提成金额
*/
@Override
public BigDecimal getSchemeById(String id, Integer subject) {
return schemeMapper.getSchemeById(id, subject);
}
private SchoolCourseSchemeVO convertToDetailVO(SchoolCourseScheme scheme, List<DriveSchoolCourseDeduct> deducts) {
SchoolCourseSchemeVO vo = new SchoolCourseSchemeVO();
vo.setId(scheme.getId());
vo.setName(scheme.getName());
vo.setCourseId(scheme.getCourseId());
vo.setIsDefault(scheme.getIsDefault());
// 初始化所有科目为0
vo.setSubject0Deduct(BigDecimal.ZERO);
vo.setSubject1Deduct(BigDecimal.ZERO);
vo.setSubject2Deduct(BigDecimal.ZERO);
vo.setSubject3Deduct(BigDecimal.ZERO);
vo.setSubject4Deduct(BigDecimal.ZERO);
// 填充实际存在的提成配置
deducts.forEach(deduct -> {
switch (deduct.getCourseSubject()) {
case "0":
vo.setSubject0Deduct(deduct.getDeduct());
break;
case "1":
vo.setSubject1Deduct(deduct.getDeduct());
break;
case "2":
vo.setSubject2Deduct(deduct.getDeduct());
break;
case "3":
vo.setSubject3Deduct(deduct.getDeduct());
break;
case "4":
vo.setSubject4Deduct(deduct.getDeduct());
break;
}
});
return vo;
}
}

View File

@ -26,5 +26,9 @@ public class SchoolCourseOrderBusinessVO extends SchoolCourseOrder {
* 户籍地址
*/
private String address;
/**
* 渠道
*/
private String source;
}

View File

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.course.vo;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.course.entity.SchoolCourseScheme;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.math.BigDecimal;
/**
* 驾校-课程-方案关联表VO
*
* @author 若依
*/
@Data
public class SchoolCourseSchemeVO extends SchoolCourseScheme {
private BigDecimal subject0Deduct;
private BigDecimal subject1Deduct;
private BigDecimal subject2Deduct;
private BigDecimal subject3Deduct;
private BigDecimal subject4Deduct;
}

View File

@ -33,4 +33,6 @@ public interface ExamBatchItemMapper extends BaseMapper<ExamBatchItem> {
List<ExamBatchItemVO> listJoinBatchByIds(@Param("examIds") List<String> examIds);
IPage<ExamBatchVO> batchItemListByCoach(@Param("entity") ExamBatchVO examBatchVO, Page<ExamBatchVO> page);
List<ExamBatchItemVO> getBatchItemCount(@Param("batchId") String batchId);
}

View File

@ -35,11 +35,13 @@
main.image AS avatar,
main.user_id AS userId,
dsc.car_register_date AS carRegisterDate,
GROUP_CONCAT(DISTINCT dscc.course_type SEPARATOR ',') AS courseTypes
GROUP_CONCAT(DISTINCT dscc.course_type SEPARATOR ',') AS courseTypes,
COUNT(dss.id) AS studentTotalNum
FROM
drive_school_coach main
LEFT JOIN drive_school_coach_course dscc ON main.id = dscc.coach_id AND dscc.deleted = 0
LEFT JOIN drive_school_car dsc ON main.user_id = dsc.user_id AND dsc.deleted = 0
LEFT JOIN drive_school_student dss on main.user_id = dss.source_user_id AND dss.deleted = 0
<where>
main.deleted = 0
<if test="entity.type != null and entity.type != ''">
@ -51,7 +53,7 @@
</where>
GROUP BY
main.id
order by main.create_time desc
order by studentTotalNum desc
</select>
<select id="getCoachByUniqueCode" parameterType="String" resultType="cn.iocoder.yudao.module.base.entity.DlDriveSchoolCoach">

View File

@ -21,4 +21,8 @@
</where>
order by main.create_time desc
</select>
<select id="orderCountByCourseId" resultType="java.lang.Integer">
SELECT COUNT(*) FROM drive_school_course_order WHERE course_id = #{courseId} AND deleted = 0
</select>
</mapper>

View File

@ -177,7 +177,14 @@
-- AND dsco.payment_status in ( '2', '3', '4', '5' )
-- AND dsco.is_sign = 1
AND dss.id IS NOT NULL
AND dss.source = '04'
<choose>
<when test="entity.pType == 'yg'">
AND dss.source = '01'
</when>
<when test="entity.pType == 'ywjl'">
AND dss.source = '04'
</when>
</choose>
AND dss.source_user_id = #{entity.coachId}
<if test="entity.name != null and entity.name!=''">
AND dss.`name` LIKE CONCAT('%',#{entity.name},'%')
@ -363,6 +370,55 @@
GROUP BY dss.user_id -- 按学生分组,确保每个学生只出现一次
</select>
<select id="selectIndexInfoByWorking" resultType="cn.iocoder.yudao.module.base.vo.DlDriveSchoolStudentByBusinessVO">
SELECT
dss.*,
-- 使用 MAX/MIN 取任意一个订单信息(不累加)
MAX(dsco.course_type) AS courseType,
MAX(dsco.course_name) AS course_name,
MAX(dsco.payment_status) AS payment_status,
MAX(dsco.is_sign) AS is_sign,
MAX(dsco.reserve_money) AS reserve_money, -- 不累加,只取一个订单的金额
MAX(dsco.rest_money) AS rest_money, -- 不累加,只取一个订单的金额
MAX(dsco.pay_type) AS pay_type
FROM
drive_school_student dss
LEFT JOIN drive_school_course_order dsco
ON dss.user_id = dsco.user_id
AND dsco.deleted = 0
AND dsco.if_end = 0
WHERE
dss.deleted = 0
AND dss.id IS NOT NULL
AND dss.source = '01'
<if test="coachId != null and coachId != ''">
AND dss.source_user_id = #{coachId}
</if>
<if test="startTime != null and startTime != ''">
AND dss.create_time &gt;= #{startTime}
</if>
<if test="endTime != null and endTime != ''">
AND dss.create_time &lt;= #{endTime}
</if>
<if test="isSign == 1">
-- 有至少一条订单已面签
AND dss.user_id IN (
SELECT user_id FROM drive_school_course_order
WHERE is_sign = 1 AND deleted = 0 AND if_end = 0
GROUP BY user_id
)
</if>
<if test="isSign == 0">
-- 没有任何一条订单是已面签的用户
AND dss.user_id NOT IN (
SELECT user_id FROM drive_school_course_order
WHERE is_sign = 1 AND deleted = 0 AND if_end = 0
GROUP BY user_id
)
</if>
GROUP BY dss.user_id -- 按学生分组,确保每个学生只出现一次
</select>
<select id="selectTrainStudent" resultType="cn.iocoder.yudao.module.base.vo.DlDriveSchoolStudentVO">
SELECT
dss.*,dsc.type AS courseType,dst.subject

View File

@ -9,4 +9,20 @@
FROM drive_school_course_deduct main
LEFT JOIN drive_school_course dsc ON main.course_id = dsc.id
</select>
<update id="deleteBySchemeId" parameterType="string">
UPDATE drive_school_course_deduct
SET deleted = 1
WHERE scheme_id = #{schemeId}
</update>
<insert id="insertBatch" parameterType="list">
INSERT INTO drive_school_course_deduct
(deduct, course_id, scheme_id, course_subject, tenant_id, creator, create_time)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.deduct}, #{item.courseId}, #{item.schemeId}, #{item.courseSubject},
#{item.tenantId}, #{item.creator}, #{item.createTime})
</foreach>
</insert>
</mapper>

View File

@ -55,7 +55,7 @@
dsp.deleted = 0
<if test="entity.coachName != null and entity.coachName != '' "> and dsp.coach_name like concat('%', #{entity.coachName}, '%')</if>
<if test="entity.userName != null and entity.userName != '' "> and dsp.user_name like concat('%', #{entity.userName}, '%')</if>
<if test="entity.courseName != null and entity.courseName != '' "> and dsp.name like concat('%', #{entity.courseName}, '%')</if>
<if test="entity.courseName != null and entity.courseName != '' "> and dsp.course_name like concat('%', #{entity.courseName}, '%')</if>
<if test="entity.userId != null "> and dsp.user_id = #{entity.userId}</if>
<if test="entity.courseId != null and entity.courseId != '' "> and dsp.course_id = #{entity.courseId}</if>
<if test="entity.subject != null "> and dsp.subject = #{entity.subject}</if>
@ -100,7 +100,7 @@
dsp.deleted = 0 AND dsp.subject in (2,3)
<if test="entity.coachName != null and entity.coachName != '' "> and dsp.coach_name like concat('%', #{entity.coachName}, '%')</if>
<if test="entity.userName != null and entity.userName != '' "> and dsp.user_name like concat('%', #{entity.userName}, '%')</if>
<if test="entity.courseName != null and entity.courseName != '' "> and dsp.name like concat('%', #{entity.courseName}, '%')</if>
<if test="entity.courseName != null and entity.courseName != '' "> and dsp.course_name like concat('%', #{entity.courseName}, '%')</if>
<if test="entity.userId != null "> and dsp.user_id = #{entity.userId}</if>
<if test="entity.courseId != null and entity.courseId != '' "> and dsp.course_id = #{entity.courseId}</if>
<if test="entity.examStatus != null ">and dsp.exam_status = #{entity.examStatus}</if>
@ -157,22 +157,47 @@
<select id="getProcessAndBatch" resultType="cn.iocoder.yudao.module.course.vo.ProcessAndExamBatchVO">
SELECT
dseb.start_time AS startTime,
dseb.end_time AS endTime,
dseb.addr_id AS addrId,
dseb.addr AS addr,
dseb.trans_way AS transWay,
dseb.creator AS creator,
dseb.id AS batchId,
dseb.updater AS updater,
dsebi.id AS batchItemId
dseb.start_time AS startTime,
dseb.end_time AS endTime,
dseb.addr_id AS addrId,
dseb.addr AS addr,
dseb.trans_way AS transWay,
dseb.creator AS creator,
dseb.id AS batchId,
dseb.updater AS updater,
dsebi.id AS batchItemId
from drive_school_exam_batch dseb
left join drive_school_exam_batch_item dsebi ON dseb.id = dsebi.batch_id
left join drive_school_exam_batch_item dsebi ON dseb.id = dsebi.batch_id
WHERE dseb.course_id = #{courseId}
AND dseb.coach_id = #{coachId}
AND dseb.subject = #{subject}
AND dsebi.fraction = #{fraction}
AND dsebi.user_id = #{userId}
AND dseb.coach_id = #{coachId}
AND dseb.subject = #{subject}
<if test="fraction != null">
AND dsebi.fraction = #{fraction}
</if>
<if test="fraction == null">
AND dsebi.fraction is NULL
</if>
AND dsebi.user_id = #{userId}
ORDER BY dseb.update_time DESC LIMIT 1
</select>
<select id="getBatchForProcess" resultType="cn.iocoder.yudao.module.exam.entity.ExamBatch" parameterType="cn.iocoder.yudao.module.course.entity.Process">
SELECT
dseb.*
from drive_school_exam_batch dseb
left join drive_school_exam_batch_item dsebi ON dseb.id = dsebi.batch_id
WHERE dseb.course_id = #{entity.courseId}
AND dseb.coach_id = #{entity.coachId}
AND dseb.subject = #{entity.subject}
<if test="entity.examScore != null">
AND dsebi.fraction = #{entity.examScore}
</if>
<if test="entity.examScore == null">
AND dsebi.fraction is NULL
</if>
AND dsebi.user_id = #{entity.userId}
ORDER BY dseb.update_time DESC LIMIT 1
</select>
</mapper>

View File

@ -118,4 +118,24 @@
#{deleted})
</insert>
<select id="getSchemeByStudentId" resultType="string">
select dsco.scheme_id FROM drive_school_process dsc
left join drive_school_course_order dsco on dsco.user_id = dsc.user_id
where
dsc.user_id=#{studentId}
AND dsc.subject=#{subject}
AND dsco.course_id = #{courseId}
AND dsco.payment_status=2
AND dsco.if_end=0
AND dsco.deleted=0
AND dsc.deleted=0
AND dsco.if_assignment_coach=1
</select>
<select id="getOrderCountBySchemeId" resultType="java.lang.Integer">
SELECT COUNT(*) FROM drive_school_course_order
WHERE scheme_id=#{schemeId}
AND deleted = 0
</select>
</mapper>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.course.mapper.SchoolCourseSchemeMapper">
<select id="getCourseDeduct" resultType="java.math.BigDecimal">
select dscd.deduct from drive_school_course_scheme dscs
LEFT JOIN drive_school_course_deduct dscd on dscs.id = dscd.scheme_id
where
dscs.course_id = #{courseId}
AND dscs.is_default = 1
AND dscs.deleted = 0
AND dscd.deleted = 0
AND dscd.course_subject = #{subject}
</select>
<select id="getSchemeById" resultType="java.math.BigDecimal" parameterType="cn.iocoder.yudao.module.course.vo.SchoolCourseSchemeVO">
select dscd.deduct, dscd.course_subject from drive_school_course_scheme dscs
LEFT JOIN drive_school_course_deduct dscd on dscs.id = dscd.scheme_id
WHERE dscs.id = #{id}
AND dscd.course_subject = #{subject}
AND dscs.deleted = 0
AND dscd.deleted = 0
</select>
<select id="getOrderCountBySchemeId" resultType="java.lang.Integer">
SELECT COUNT(*) FROM drive_school_course_order
WHERE scheme_id=#{schemeId}
</select>
</mapper>

View File

@ -225,4 +225,10 @@
ORDER BY
student_count DESC-->
</select>
<select id="getBatchItemCount" resultType="cn.iocoder.yudao.module.exam.vo.ExamBatchItemVO" parameterType="java.lang.String">
SELECT dsebi.* from drive_school_exam_batch dseb
left join drive_school_exam_batch_item dsebi ON dseb.id = dsebi.batch_id
where dseb.id = #{batchId}
</select>
</mapper>

View File

@ -589,6 +589,9 @@ public class SysLoginController {
Map<String, Object> map = new HashMap<>();
map.put("partnerId", user.getTenantId());
map.put("user", user);
// 查询用户表信息
AdminUserDO selectUser = userService.getUser(user.getId());
map.put("userInfo", selectUser);
return CommonResult.success(map);
}

View File

@ -44,4 +44,7 @@ public interface RoleMapper extends BaseMapperX<RoleDO> {
return selectList(new LambdaQueryWrapperX<RoleDO>().in(RoleDO::getCode, codes));
}
default List<RoleDO> selectListByPackageIds(@Nullable Collection<String> packageIds){
return selectList(new LambdaQueryWrapperX<RoleDO>().in(RoleDO::getServicePackageId, packageIds).eq(RoleDO::getTenantId, CommonStr.TENANT_ID));
}
}

View File

@ -259,7 +259,8 @@ public class RoleServiceImpl implements RoleService {
if (CollectionUtil.isEmpty(codes)) {
return Collections.emptyList();
}
return roleMapper.selectListByCodes(codes);
// return roleMapper.selectListByCodes(codes);
return roleMapper.selectListByPackageIds(codes);
}
/**