Compare commits

...

6 Commits

Author SHA1 Message Date
xyc
5a8b8e92c3 Merge branch 'driver' 2025-06-06 17:38:57 +08:00
Lx
412897e5ac 0606 2025-06-06 17:32:16 +08:00
Lx
69044eabb4 Merge remote-tracking branch 'origin/driver' into driver 2025-06-05 14:31:49 +08:00
Lx
1177ff987a 0605 2025-06-05 14:30:56 +08:00
xyc
a749fea2f3 更新 2025-06-04 14:23:49 +08:00
Lx
bb1bfee430 0603 2025-06-03 16:22:52 +08:00
53 changed files with 1602 additions and 249 deletions

View File

@ -96,4 +96,9 @@ public class CompanySmallProgramAPI {
List<Company> list = this.companyService.list(queryWrapper);
return success(list.isEmpty()?null:list.get(0));
}
@GetMapping("/getCompanyByTenantIdAndSystemCode")
public CommonResult<?> getCompanyAndManager(String tenantId, String systemCode){
return success(companyService.getCompanyByTenantIdAndSystemCode(tenantId, systemCode));
}
}

View File

@ -134,4 +134,25 @@ public class Company extends TenantBaseDO {
* 纬度
*/
private BigDecimal lat;
/**
* 小程序app_id
*/
private String appId;
/**
* 微信商户号
*/
private String mchId;
/**
* 微信支付密钥
*/
private String privateKeyStr;
/**
* 回调地址
*/
private String notifyUrl;
}

View File

@ -77,4 +77,7 @@ public interface CompanyService extends IService<Company> {
* @param id 企业ID
**/
CompanyToServerVO getCompanyServerById(String id);
}
Company getCompanyByTenantIdAndSystemCode(String tenantId, String systemCode);
}

View File

@ -5,6 +5,9 @@ import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import cn.iocoder.yudao.module.app.company.vo.CompanyToServerVO;
import cn.iocoder.yudao.module.company.entity.Company;
import cn.iocoder.yudao.module.company.vo.CompanyRespVO;
@ -18,6 +21,7 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.UserDTO;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.iocoder.yudao.module.company.vo.CompanyReqVO;
import org.springframework.beans.factory.annotation.Autowired;
@ -205,4 +209,16 @@ public class CompanyServiceImpl extends ServiceImpl<CompanyMapper, Company> impl
Optional.ofNullable(servicePackageByIds).ifPresent(result::setServicePackages);
return result;
}
}
@Override
@TenantIgnore
public Company getCompanyByTenantIdAndSystemCode(String tenantId, String systemCode) {
LambdaQueryWrapper<Company> queryWrapper = new LambdaQueryWrapper<Company>()
.eq(TenantBaseDO::getTenantId, tenantId)
.like(Company::getServiceCodes, systemCode)
.orderByDesc(BaseDO::getCreateTime);
List<Company> list = this.list(queryWrapper);
return list.isEmpty() ? null : list.get(0);
}
}

View File

@ -130,4 +130,24 @@ public interface SchoolBaseConstants {
*/
public static final String SCHOOL_NOTIFY_MESSAGE_TEMPLATE_MEMBER_ENROLL_TO_OFFICE= "学员 %s 报名了 %s 课程,请留意!";
/**
* 学员面签成功之后发送消息给教练
*/
public static final String SCHOOL_NOTIFY_MESSAGE_TEMPLATE_MEMBER_SIGN_TO_COACH= "学员 %s 已面签成功!";
/**
* 学员取消面签之后发送消息给教练
*/
public static final String SCHOOL_NOTIFY_MESSAGE_TEMPLATE_MEMBER_CANCEL_SIGN_TO_COACH= "学员 %s 已取消面签!";
/**
* 学员课程终止之后发送消息
*/
public static final String SCHOOL_NOTIFY_MESSAGE_TEMPLATE_COURSE_END_TO_MEMBER= "学员 %s 订单已终止!终止原因:%s";
/**
* 学员支付后
*/
public static final String SCHOOL_NOTIFY_MESSAGE_TEMPLATE_MEMBER_PAY_TO_MEMBER = "学员 %s 订单已支付!";
}

View File

@ -56,6 +56,28 @@ public class DataViewController {
return success(dataViewService.selectIndexInfo(type,timeType,coachId,startTime,endTime));
}
/**
* 业务经理首页数据统计查询接口 --
* @author vinjor-M
* @date 14:12 2025/2/14
* @param type 查询类型coach-教练查询|admin-管理员查询
* @param timeType 时间查询类型all-全部|day-当日|month-当月|more-自定义
* @param coachId 教练id
* @param startTime 查询时间范围--开始
* @param endTime 查询时间范围--结束
* @return cn.iocoder.yudao.framework.common.pojo.CommonResult<?>
**/
@GetMapping("/indexDataByBusiness")
@Operation(summary = "首页数据统计查询接口")
public CommonResult<?> selectIndexInfoByBusiness(@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.selectIndexInfoByBusiness(type,timeType,coachId,startTime,endTime, isSign));
}
/**
* 查询学生总数
* @author vinjor-M
@ -66,4 +88,4 @@ public class DataViewController {
public CommonResult<?> getStudentCount() {
return success(dataViewService.getStudentCount());
}
}
}

View File

@ -157,6 +157,24 @@ public class DlDriveSchoolCoachController {
return success(dlDriveSchoolCoachService.getCoachById(id));
}
@GetMapping("/getCoachByIdAndTime")
@Operation(summary = "获得驾校教练")
public CommonResult<?> appGetCoachByIdAndTime(@RequestParam("id") String id,
@RequestParam(value = "timeType") String timeType,
@RequestParam(value = "startTime",required = false) String startTime,
@RequestParam(value = "endTime",required = false) String endTime) {
return success(dlDriveSchoolCoachService.getCoachByIdAndTime(id,timeType,startTime,endTime));
}
@GetMapping("/getBusinessByIdAndTime")
@Operation(summary = "获得驾校业务经理")
public CommonResult<?> getBusinessByIdAndTime(@RequestParam("id") String id,
@RequestParam(value = "timeType") String timeType,
@RequestParam(value = "startTime",required = false) String startTime,
@RequestParam(value = "endTime",required = false) String endTime) {
return success(dlDriveSchoolCoachService.getBusinessByIdAndTime(id,timeType,startTime,endTime));
}
/**
*
* @author vinjor-M

View File

@ -1,10 +1,7 @@
package cn.iocoder.yudao.module.base.mapper;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolStudent;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolStaffVO;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolStudentVO;
import cn.iocoder.yudao.module.base.vo.DriveSchoolStudentExportVo;
import cn.iocoder.yudao.module.base.vo.StudentCountVO;
import cn.iocoder.yudao.module.base.vo.*;
import cn.iocoder.yudao.module.inspection.query.InspectionStaffQuery;
import cn.iocoder.yudao.module.inspection.vo.InspectionStaffExportVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@ -103,6 +100,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);
/**
* app首页查询训练学员---指定条件下

View File

@ -30,6 +30,7 @@ public interface DataViewService {
* @param endTime 查询时间范围--结束
**/
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);
/**
* 查询学生总数
@ -38,4 +39,4 @@ public interface DataViewService {
* @return java.util.Map<java.lang.String,java.lang.Object>
**/
Map<String,Object> getStudentCount();
}
}

View File

@ -104,6 +104,8 @@ public interface DlDriveSchoolCoachService extends IService<DlDriveSchoolCoach>
* @return cn.iocoder.yudao.module.base.vo.CoachInfoVO
**/
CoachInfoVO getCoachById(String id);
CoachInfoVO getCoachByIdAndTime(String id, String timeType, String startTime, String endTime);
CoachInfoVO getBusinessByIdAndTime(String id, String timeType, String startTime, String endTime);
/**
* 根据邀请码查询教练信息

View File

@ -192,4 +192,6 @@ public interface DlDriveSchoolStudentService extends IService<DlDriveSchoolStude
* 修改学员来源
*/
public boolean updateChannel(DlDriveSchoolStudent student);
DlDriveSchoolStudent getStudentByIdNo(String idNo);
}

View File

@ -21,6 +21,7 @@ import cn.iocoder.yudao.module.train.entity.Train;
import cn.iocoder.yudao.module.train.mapper.TrainMapper;
import cn.iocoder.yudao.module.train.service.TrainService;
import cn.iocoder.yudao.module.train.vo.TrainVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -67,7 +68,7 @@ public class DataViewServiceImpl implements DataViewService {
* @date 14:37 2025/2/8
**/
@Override
public StudentInfoVO selectStudentInfo(Long id,Long coachId) {
public StudentInfoVO selectStudentInfo(Long id, Long coachId) {
StudentInfoVO studentInfoVO = new StudentInfoVO();
// 学员主信息
@ -185,132 +186,144 @@ public class DataViewServiceImpl implements DataViewService {
//默认查全部数据
String startTimeStr = "";
String endTimeStr = "";
if("more".equals(timeType)){
if(StringUtils.isNotEmpty(startTime)){
startTimeStr = startTime+" 00:00:01";
if ("more".equals(timeType)) {
if (StringUtils.isNotEmpty(startTime)) {
startTimeStr = startTime + " 00:00:01";
}
if(StringUtils.isNotEmpty(endTime)) {
if (StringUtils.isNotEmpty(endTime)) {
endTimeStr = endTime + " 23:59:59";
}
}else if("month".equals(timeType)){
} 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.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";
startTimeStr = DateUtil.formatDate(DateUtil.date()) + " 00:00:01";
endTimeStr = DateUtil.formatDate(DateUtil.date()) + " 23:59:59";
}
if("admin".equals(type)){
if ("admin".equals(type)) {
//管理员查询
/*1.招生情况*/
List<DlDriveSchoolStudentVO> studentList = studentMapper.selectStudentList(coachId, startTimeStr, endTimeStr);
Map<String,Object> studentInfoMap = new HashMap<>();
int coachNum=0;
double coachAmount=0;
int schoolNum=0;
double schoolAmount=0;
for (DlDriveSchoolStudentVO item:studentList){
if("02".equals(item.getSource())){
Map<String, Object> studentInfoMap = new HashMap<>();
int coachNum = 0;
double coachAmount = 0;
int schoolNum = 0;
double schoolAmount = 0;
int businessNum = 0;
double businessAmount = 0;
for (DlDriveSchoolStudentVO item : studentList) {
if ("02".equals(item.getSource())) {
//教练自招
coachNum++;
coachAmount = coachAmount+item.getPriceAmount();
}else{
coachAmount = coachAmount + item.getPriceAmount();
} else if ("04".equals(item.getSource())) {
businessNum++;
businessAmount = businessAmount + item.getPriceAmount();
} else {
//驾校统招
schoolNum++;
schoolAmount = schoolAmount+item.getPriceAmount();
schoolAmount = schoolAmount + item.getPriceAmount();
}
}
int allNum = coachNum+schoolNum;
double coachRate=0;
double schoolRate=0;
if(allNum>0){
if(coachNum>0){
coachRate = (double)coachNum / allNum;
int allNum = coachNum + schoolNum;
double coachRate = 0;
double schoolRate = 0;
double businessRate = 0;
if (allNum > 0) {
if (coachNum > 0) {
coachRate = (double) coachNum / allNum;
}
if(schoolNum>0){
schoolRate = (double)schoolNum / allNum;
if (schoolNum > 0) {
schoolRate = (double) schoolNum / allNum;
}
if (businessNum > 0) {
businessRate = (double) businessNum / allNum;
}
}
studentInfoMap.put("coachNum", new BigDecimal(coachNum).setScale(2, RoundingMode.HALF_UP));
studentInfoMap.put("coachAmount", new BigDecimal(coachAmount).setScale(2, RoundingMode.HALF_UP));
studentInfoMap.put("coachRate",0!=coachRate?(Double.parseDouble(df.format(coachRate))*100):0);
studentInfoMap.put("schoolNum",schoolNum);
studentInfoMap.put("schoolAmount",schoolAmount);
studentInfoMap.put("schoolRate",0!=schoolRate?(Double.parseDouble(df.format(schoolRate))*100):0);
studentInfoMap.put("coachRate", 0 != coachRate ? (Double.parseDouble(df.format(coachRate)) * 100) : 0);
studentInfoMap.put("schoolNum", schoolNum);
studentInfoMap.put("schoolAmount", schoolAmount);
studentInfoMap.put("schoolRate", 0 != schoolRate ? (Double.parseDouble(df.format(schoolRate)) * 100) : 0);
studentInfoMap.put("businessNum", businessNum);
studentInfoMap.put("businessAmount", businessAmount);
studentInfoMap.put("businessRate", 0 != businessRate ? (Double.parseDouble(df.format(businessRate)) * 100) : 0);
rtnObj.setStudentInfo(studentInfoMap);
/*4.财务情况--*/
//应收
Double showedReceive = courseOrderMapper.selectByCoachUserId(coachId,startTimeStr,endTimeStr);
Double showedReceive = courseOrderMapper.selectByCoachUserId(coachId, startTimeStr, endTimeStr);
//应付
List<SchoolCommission> schoolCommissionList = commissionMapper.selectByCoachId(coachId,startTimeStr,endTimeStr);
double showedPay =0.0;
for (SchoolCommission item:schoolCommissionList){
if(null!=item.getCommissionAmount()){
showedPay =showedPay+item.getCommissionAmount().doubleValue();
List<SchoolCommission> schoolCommissionList = commissionMapper.selectByCoachId(coachId, startTimeStr, endTimeStr);
double showedPay = 0.0;
for (SchoolCommission item : schoolCommissionList) {
if (null != item.getCommissionAmount()) {
showedPay = showedPay + item.getCommissionAmount().doubleValue();
}
}
Map<String,Object> moneyInfoMap = new HashMap<>();
moneyInfoMap.put("inAmount",null==showedReceive?0:showedReceive);
moneyInfoMap.put("outAmount",showedPay);
Map<String, Object> moneyInfoMap = new HashMap<>();
moneyInfoMap.put("inAmount", null == showedReceive ? 0 : showedReceive);
moneyInfoMap.put("outAmount", showedPay);
rtnObj.setMoneyInfo(moneyInfoMap);
}else if("coach".equals(type)){
} else if ("coach".equals(type)) {
//教练查询
/*1.学员情况*/
List<DlDriveSchoolStudentVO> studentVOList = studentMapper.selectStudentListCoach(coachId,startTimeStr,endTimeStr);
List<DlDriveSchoolStudentVO> studentVOList = studentMapper.selectStudentListCoach(coachId, startTimeStr, endTimeStr);
int overNum = (int) studentVOList.stream().filter(item -> null != item.getOrderGradTime()).count();
int noOverNum = studentVOList.size()-overNum;
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);
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);
/*4.财务情况-查教练自己应得的提成-*/
List<SchoolCommission> schoolCommissionList = commissionMapper.selectByCoachId(coachId,startTimeStr,endTimeStr);
double showedPay =0.0;
for (SchoolCommission item:schoolCommissionList){
if(null!=item.getCommissionAmount()){
showedPay =showedPay+item.getCommissionAmount().doubleValue();
List<SchoolCommission> schoolCommissionList = commissionMapper.selectByCoachId(coachId, startTimeStr, endTimeStr);
double showedPay = 0.0;
for (SchoolCommission item : schoolCommissionList) {
if (null != item.getCommissionAmount()) {
showedPay = showedPay + item.getCommissionAmount().doubleValue();
}
}
Map<String,Object> moneyInfoMap = new HashMap<>();
moneyInfoMap.put("money",showedPay);
Map<String, Object> moneyInfoMap = new HashMap<>();
moneyInfoMap.put("money", showedPay);
rtnObj.setMoneyInfo(moneyInfoMap);
}else if("business".equals(type)){
} else if ("business".equals(type)) {
//业务经理查询
/*1.招生情况*/
List<DlDriveSchoolStudentVO> studentVOList = studentMapper.selectStudentListBusiness(coachId,startTimeStr,endTimeStr);
List<DlDriveSchoolStudentVO> studentVOList = studentMapper.selectStudentListBusiness(coachId, startTimeStr, endTimeStr);
int overNum = (int) studentVOList.stream().filter(item -> null != item.getOrderGradTime()).count();
int noOverNum = studentVOList.size()-overNum;
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);
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);
/*4.财务情况-查教练自己应得的提成-*/
List<SchoolCommission> schoolCommissionList = commissionMapper.selectByCoachId(coachId,startTimeStr,endTimeStr);
double showedPay =0.0;
for (SchoolCommission item:schoolCommissionList){
if(null!=item.getCommissionAmount()){
showedPay =showedPay+item.getCommissionAmount().doubleValue();
List<SchoolCommission> schoolCommissionList = commissionMapper.selectByCoachId(coachId, startTimeStr, endTimeStr);
double showedPay = 0.0;
for (SchoolCommission item : schoolCommissionList) {
if (null != item.getCommissionAmount()) {
showedPay = showedPay + item.getCommissionAmount().doubleValue();
}
}
Map<String,Object> moneyInfoMap = new HashMap<>();
moneyInfoMap.put("money",showedPay);
Map<String, Object> moneyInfoMap = new HashMap<>();
moneyInfoMap.put("money", showedPay);
rtnObj.setMoneyInfo(moneyInfoMap);
}
/*2.训练情况*/
List<TrainVO> allTrainList = trainMapper.selectTrainByCondition(coachId,startTimeStr,endTimeStr);
List<TrainVO> allTrainList = trainMapper.selectTrainByCondition(coachId, startTimeStr, endTimeStr);
//所有车辆set目的是去重
Set<String> allCarSet = new HashSet<>();
Set<String> subject2CarSet = new HashSet<>();
@ -318,67 +331,120 @@ public class DataViewServiceImpl implements DataViewService {
Set<Long> allUserSet = new HashSet<>();
Set<Long> subject2UserSet = new HashSet<>();
Set<Long> subject3UserSet = new HashSet<>();
for (TrainVO trainVO:allTrainList){
if(2==trainVO.getSubject()){
for (TrainVO trainVO : allTrainList) {
if (2 == trainVO.getSubject()) {
subject2CarSet.add(trainVO.getCarNo());
allCarSet.add(trainVO.getCarNo());
subject2UserSet.add(trainVO.getUserId());
allUserSet.add(trainVO.getUserId());
}else if(3==trainVO.getSubject()){
} else if (3 == trainVO.getSubject()) {
subject3CarSet.add(trainVO.getCarNo());
allCarSet.add(trainVO.getCarNo());
subject3UserSet.add(trainVO.getUserId());
allUserSet.add(trainVO.getUserId());
}
}
Map<String,Object> trainInfoMap = new HashMap<>();
trainInfoMap.put("allCarNum",allCarSet.size());
trainInfoMap.put("subject2CarNum",subject2CarSet.size());
trainInfoMap.put("subject3CarNum",subject3CarSet.size());
trainInfoMap.put("allUserNum",allUserSet.size());
trainInfoMap.put("subject2UserNum",subject2UserSet.size());
trainInfoMap.put("subject3UserNum",subject3UserSet.size());
Map<String, Object> trainInfoMap = new HashMap<>();
trainInfoMap.put("allCarNum", allCarSet.size());
trainInfoMap.put("subject2CarNum", subject2CarSet.size());
trainInfoMap.put("subject3CarNum", subject3CarSet.size());
trainInfoMap.put("allUserNum", allUserSet.size());
trainInfoMap.put("subject2UserNum", subject2UserSet.size());
trainInfoMap.put("subject3UserNum", subject3UserSet.size());
rtnObj.setTrainInfo(trainInfoMap);
/*3.考试情况*/
List<ExamBatchItemVO> examBatchItemVOList = examBatchItemMapper.selectByCoachId(coachId,startTimeStr,endTimeStr);
List<ExamBatchItemVO> examBatchItemVOList = examBatchItemMapper.selectByCoachId(coachId, startTimeStr, endTimeStr);
Double subject2Num = 0.0;
Double subject3Num = 0.0;
Double subject2PassNum = 0.0;
Double subject3PassNum = 0.0;
for (ExamBatchItemVO exam:examBatchItemVOList){
if(2==exam.getSubject()){
for (ExamBatchItemVO exam : examBatchItemVOList) {
if (2 == exam.getSubject()) {
subject2Num++;
if(null!=exam.getIfPass() && exam.getIfPass()){
if (null != exam.getIfPass() && exam.getIfPass()) {
//考试通过
subject2PassNum++;
}
}else if(3==exam.getSubject()){
} else if (3 == exam.getSubject()) {
subject3Num++;
if(null!=exam.getIfPass() && exam.getIfPass()){
if (null != exam.getIfPass() && exam.getIfPass()) {
//考试通过
subject3PassNum++;
}
}
}
double subject2Rate=0;
double subject3Rate=0;
if(0!=subject2Num && 0!=subject2PassNum){
double subject2Rate = 0;
double subject3Rate = 0;
if (0 != subject2Num && 0 != subject2PassNum) {
subject2Rate = subject2PassNum / subject2Num;
}
if(0!=subject3Num && 0!=subject3PassNum){
if (0 != subject3Num && 0 != subject3PassNum) {
subject3Rate = subject3PassNum / subject3Num;
}
Map<String,Object> examInfoMap = new HashMap<>();
examInfoMap.put("subject2All",subject2Num);
examInfoMap.put("subject2Pass",subject2PassNum);
examInfoMap.put("subject2Rate",0!=subject2Rate?(Double.parseDouble(df.format(subject2Rate))*100):0);
examInfoMap.put("subject3All",subject3Num);
examInfoMap.put("subject3Pass",subject3PassNum);
examInfoMap.put("subject3Rate",0!=subject3Rate?(Double.parseDouble(df.format(subject3Rate))*100):0);
Map<String, Object> examInfoMap = new HashMap<>();
examInfoMap.put("subject2All", subject2Num);
examInfoMap.put("subject2Pass", subject2PassNum);
examInfoMap.put("subject2Rate", 0 != subject2Rate ? (Double.parseDouble(df.format(subject2Rate)) * 100) : 0);
examInfoMap.put("subject3All", subject3Num);
examInfoMap.put("subject3Pass", subject3PassNum);
examInfoMap.put("subject3Rate", 0 != subject3Rate ? (Double.parseDouble(df.format(subject3Rate)) * 100) : 0);
rtnObj.setExamInfo(examInfoMap);
return rtnObj;
}
@Override
public IndexDataVO selectIndexInfoByBusiness(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.selectStudentListByBusiness(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);
/*4.财务情况-查教练自己应得的提成-*/
/*List<SchoolCommission> schoolCommissionList = commissionMapper.selectByCoachId(coachId, startTimeStr, endTimeStr);
double showedPay = 0.0;
for (SchoolCommission item : schoolCommissionList) {
if (null != item.getCommissionAmount()) {
showedPay = showedPay + item.getCommissionAmount().doubleValue();
}
}
Map<String, Object> moneyInfoMap = new HashMap<>();
moneyInfoMap.put("money", showedPay);
rtnObj.setMoneyInfo(moneyInfoMap);*/
return rtnObj;
}
/**
* 查询学生总数
*
@ -388,17 +454,38 @@ public class DataViewServiceImpl implements DataViewService {
**/
@Override
public Map<String, Object> getStudentCount() {
List<DlDriveSchoolStaffVO> list= studentMapper.selectStudentListCount();
List<DlDriveSchoolStaffVO> list = studentMapper.selectStudentListCount();
Map<String, Object> rtnMap = new HashMap<>();
rtnMap.put("all",list.size());
rtnMap.put("all", list.size());
//按courseType分组
Map<String, List<DlDriveSchoolStaffVO>> map = list.stream()
.filter(item -> item.getCourseType() != null) // 过滤掉 courseType null 的元素
.collect(Collectors.groupingBy(DlDriveSchoolStaffVO::getCourseType));
for (String key:map.keySet()){
rtnMap.put(key,map.get(key).size());
for (String key : map.keySet()) {
rtnMap.put(key, map.get(key).size());
}
// 已毕业人数gradTime 不为 null
Long graduatedCount = courseOrderMapper.selectCount(
new LambdaQueryWrapper<SchoolCourseOrder>()
.eq(SchoolCourseOrder::getIfEnd, false)
.in(SchoolCourseOrder::getPaymentStatus, Arrays.asList(2, 3, 4, 5))
.eq(SchoolCourseOrder::getIsSign, 1)
.isNotNull(SchoolCourseOrder::getGradTime)
);
// 未毕业人数gradTime null
Long notGraduatedCount = courseOrderMapper.selectCount(
new LambdaQueryWrapper<SchoolCourseOrder>()
.eq(SchoolCourseOrder::getIfEnd, false)
.in(SchoolCourseOrder::getPaymentStatus, Arrays.asList(2, 3, 4, 5))
.eq(SchoolCourseOrder::getIsSign, 1)
.isNull(SchoolCourseOrder::getGradTime)
);
rtnMap.put("graduated", graduatedCount);
rtnMap.put("notGraduated", notGraduatedCount);
return rtnMap;
}
}

View File

@ -483,6 +483,218 @@ public class DlDriveSchoolCoachServiceImpl extends ServiceImpl<DlDriveSchoolCoac
return result;
}
@Override
public CoachInfoVO getCoachByIdAndTime(String id, String timeType, String startTime, String endTime) {
DecimalFormat df = new DecimalFormat("#.00");
CoachInfoVO result = new CoachInfoVO();
//默认查全部数据
String startTimeStr = "";
String endTimeStr = "";
if("more".equals(timeType)){
if(org.apache.commons.lang3.StringUtils.isNotEmpty(startTime)){
startTimeStr = startTime+" 00:00:01";
}
if(org.apache.commons.lang3.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.教练信息*/
DlDriveSchoolCoach coach = getById(id);
result.setCoachInfo(coach);
/*2.车辆信息*/
DriveSchoolCar schoolCar = null;
if (coach.getUserId() != null) {
schoolCar = schoolCarService.selectByCoachId(coach.getUserId());
if (schoolCar != null && schoolCar.getCarRegisterDate() != null) {
Long carOld = DateUtil.betweenYear(schoolCar.getCarRegisterDate(), new Date(), true);
schoolCar.setCarOld(carOld);
}
}
result.setCar(schoolCar);
/*3.统计教练的学生基本信息*/
//毕业情况
List<DlDriveSchoolStudentVO> studentVOList = studentMapper.selectStudentListCoach(coach.getUserId(),startTimeStr,endTimeStr);
int overNum = (int) studentVOList.stream().filter(item -> null != item.getGradTime()).count();
int noOverNum = studentVOList.size()-overNum;
Map<String,Object> studentInfoMap = new HashMap<>();
studentInfoMap.put("overNum",overNum);
studentInfoMap.put("noOverNum",noOverNum);
//考试情况
List<ExamBatchItemVO> examBatchItemVOList = examBatchItemMapper.selectByCoachId(coach.getUserId(),startTimeStr,endTimeStr);
Double subject2Num = 0.0;
Double subject3Num = 0.0;
Double subject2PassNum = 0.0;
Double subject3PassNum = 0.0;
for (ExamBatchItemVO exam:examBatchItemVOList){
if(2==exam.getSubject()){
subject2Num++;
if(null!=exam.getIfPass() && exam.getIfPass()){
//考试通过
subject2PassNum++;
}
}else if(3==exam.getSubject()){
subject3Num++;
if(null!=exam.getIfPass() && exam.getIfPass()){
//考试通过
subject3PassNum++;
}
}
}
double subject2Rate=0;
double subject3Rate=0;
if(0!=subject2Num && 0!=subject2PassNum){
subject2Rate = subject2PassNum / subject2Num;
}
if(0!=subject3Num && 0!=subject3PassNum){
subject3Rate = subject3PassNum / subject3Num;
}
studentInfoMap.put("subject2All",subject2Num);
studentInfoMap.put("subject2Pass",subject2PassNum);
studentInfoMap.put("subject2Rate",0!=subject2Rate?(Double.parseDouble(df.format(subject2Rate))*100):0);
studentInfoMap.put("subject3All",subject3Num);
studentInfoMap.put("subject3Pass",subject3PassNum);
studentInfoMap.put("subject3Rate",0!=subject3Rate?(Double.parseDouble(df.format(subject3Rate))*100):0);
//招生情况
List<DlDriveSchoolStudentVO> studentList = studentMapper.selectStudentList(coach.getUserId(), startTimeStr, endTimeStr);
int coachNum=0;
double coachAmount=0;
for (DlDriveSchoolStudentVO item:studentList){
if("02".equals(item.getSource())){
//教练自招
coachNum++;
coachAmount = coachAmount+item.getPriceAmount();
}
}
studentInfoMap.put("coachNum",coachNum);
studentInfoMap.put("coachAmount",coachAmount);
//训练情况
List<TrainVO> trainList = trainMapper.selectTrainByCondition(coach.getUserId(),startTimeStr,endTimeStr);
Set<Long> allUserSet = new HashSet<>();
Double trainTime = 0.0;
for (TrainVO item:trainList){
allUserSet.add(item.getUserId());
if(null!=item.getTrainTime()){
trainTime =trainTime+item.getTrainTime();
}
}
studentInfoMap.put("trainUserNum",allUserSet.size());
studentInfoMap.put("trainTime",trainTime);
result.setStudentInfoMap(studentInfoMap);
/*4.财务情况*/
List<SchoolCommission> commissionList = commissionMapper.selectByCoachId(coach.getUserId(),startTimeStr,endTimeStr);
//科目2当月应付
Double subject2MonthShowed = 0.0;
//科目2累计已付
Double subject2Payed = 0.0;
//科目2累计应付
Double subject2Showed = 0.0;
//科目3当月应付
Double subject3MonthShowed = 0.0;
//科目3累计已付
Double subject3Payed = 0.0;
//科目3累计应付
Double subject3Showed = 0.0;
//当月时间范围
// 获取当前月份的开始时间和结束时间
DateTime startOfMonth = DateUtil.beginOfMonth(DateUtil.date());
DateTime endOfMonth = DateUtil.endOfMonth(DateUtil.date());
for (SchoolCommission item:commissionList){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String localDateTimeNowStr = item.getCreateTime().format(formatter);
DateTime createTime = DateUtil.parse(localDateTimeNowStr);
if("2".equals(item.getSubject())){
//科目二
subject2Showed=subject2Showed+item.getCommissionAmount().doubleValue();
if(null!=item.getIfPay() && item.getIfPay()){
subject2Payed=subject2Payed+item.getCommissionAmount().doubleValue();
}
if(createTime.isAfterOrEquals(startOfMonth) && createTime.isBeforeOrEquals(endOfMonth)){
//在当月内
subject2MonthShowed = subject2MonthShowed+item.getCommissionAmount().doubleValue();
}
}else if("3".equals(item.getSubject())){
//科目三
subject3Showed=subject3Showed+item.getCommissionAmount().doubleValue();
if(null!=item.getIfPay() && item.getIfPay()){
subject3Payed=subject3Payed+item.getCommissionAmount().doubleValue();
}
if(createTime.isAfterOrEquals(startOfMonth) && createTime.isBeforeOrEquals(endOfMonth)){
//在当月内
subject3MonthShowed = subject3MonthShowed+item.getCommissionAmount().doubleValue();
}
}
}
Map<String,Object> financeMap = new HashMap<>();
financeMap.put("subject2MonthShowed",subject2MonthShowed);
financeMap.put("subject2Showed",subject2Showed);
financeMap.put("subject2Payed",subject2Payed);
financeMap.put("subject3MonthShowed",subject3MonthShowed);
financeMap.put("subject3Showed",subject3Showed);
financeMap.put("subject3Payed",subject3Payed);
result.setFinanceMap(financeMap);
return result;
}
@Override
public CoachInfoVO getBusinessByIdAndTime(String id, String timeType, String startTime, String endTime) {
DecimalFormat df = new DecimalFormat("#.00");
CoachInfoVO result = new CoachInfoVO();
//默认查全部数据
String startTimeStr = "";
String endTimeStr = "";
if("more".equals(timeType)){
if(org.apache.commons.lang3.StringUtils.isNotEmpty(startTime)){
startTimeStr = startTime+" 00:00:01";
}
if(org.apache.commons.lang3.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.教练信息*/
DlDriveSchoolCoach coach = getById(id);
result.setCoachInfo(coach);
/*3.统计教练的学生基本信息*/
//毕业情况
List<DlDriveSchoolStudentVO> studentVOList = studentMapper.selectStudentListBusiness(coach.getUserId(),startTimeStr,endTimeStr);
int overNum = (int) studentVOList.stream().filter(item -> null != item.getGradTime()).count();
int noOverNum = studentVOList.size()-overNum;
Map<String,Object> studentInfoMap = new HashMap<>();
studentInfoMap.put("overNum",overNum);
studentInfoMap.put("noOverNum",noOverNum);
//招生情况
List<DlDriveSchoolStudentVO> studentList = studentMapper.selectStudentList(coach.getUserId(), startTimeStr, endTimeStr);
int coachNum=0;
double coachAmount=0;
for (DlDriveSchoolStudentVO item:studentList){
if("04".equals(item.getSource())){
//教练自招
coachNum++;
coachAmount = coachAmount+item.getPriceAmount();
}
}
studentInfoMap.put("coachNum",coachNum);
studentInfoMap.put("coachAmount",coachAmount);
result.setStudentInfoMap(studentInfoMap);
return result;
}
/**
* 根据邀请码查询教练信息
*/

View File

@ -456,6 +456,9 @@ public class DlDriveSchoolStudentServiceImpl extends ServiceImpl<DlDriveSchoolSt
if ("03".equals(type)) {
//自来的学生
return dlDriveSchoolStudentMapper.indexCusStudentList(startTime, endTime);
} else if ("04".equals(type)) {
//自来的学生
return dlDriveSchoolStudentMapper.indexGetTrainList(type, coachId, startTime, endTime);
} else {
return dlDriveSchoolStudentMapper.indexGetTrainList(type, coachId, startTime, endTime);
}
@ -684,4 +687,14 @@ public class DlDriveSchoolStudentServiceImpl extends ServiceImpl<DlDriveSchoolSt
return rows > 0;
}
@Override
public DlDriveSchoolStudent getStudentByIdNo(String idNo) {
return lambdaQuery()
.eq(DlDriveSchoolStudent::getIdCard, idNo)
.orderByDesc(DlDriveSchoolStudent::getCreateTime)
.eq(DlDriveSchoolStudent::getDeleted, false)
.last("LIMIT 1")
.one();
}
}

View File

@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Schema(description = "驾校人员-手机APP查询专用接口")
@Data
@ -55,4 +56,12 @@ public class DlDriveSchoolStaffVO {
private String endTime;
/**是否合格*/
private String examStatus;
/**查询时间范围*/
private List<String> rangeTime;
/**地址*/
private String address;
/**年龄*/
private List<String> age;
/**拿证天数*/
private Integer passDays;
}

View File

@ -0,0 +1,60 @@
package cn.iocoder.yudao.module.base.vo;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolStudent;
import cn.iocoder.yudao.module.course.entity.Process;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 驾校学员 Response VO")
@Data
@ExcelIgnoreUnannotated
public class DlDriveSchoolStudentByBusinessVO extends DlDriveSchoolStudent {
/**教练ID*/
private Long coachId;
/**教练姓名*/
private String coachName;
/**教练ID*/
private String courseId;
/**学习进度*/
private Process process;
/**总金额*/
private Double priceAmount;
/**课程类型*/
private String courseType;
/**科目*/
private Integer subject;
/**是否支付*/
private String paymentStatus;
/**是否终止*/
private String ifEnd;
/**终止原因*/
private String endReason;
/**订单金额*/
private BigDecimal reserveMoney;
/**尾款金额*/
private BigDecimal restMoney;
/**支付类型*/
private String payType;
/**时间查询类型all-全部|day-当日|month-当月|more-自定义)*/
private String timeType;
/**查询时间范围--开始*/
private String startTime;
/**查询时间范围--结束*/
private String endTime;
/**是否毕业*/
private String isGrad;
/**订单表中的毕业时间*/
private String orderGradTime;
/**课程名称*/
private String courseName;
/**订单ID*/
private String orderId;
/**排序方式asc desc*/
private String sort;
/**是否面签*/
private Integer isSign;
}

View File

@ -6,6 +6,8 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 驾校学员 Response VO")
@Data
@ExcelIgnoreUnannotated
@ -41,4 +43,6 @@ public class DlDriveSchoolStudentVO extends DlDriveSchoolStudent {
private String orderId;
/**排序方式asc desc*/
private String sort;
/**是否面签*/
private Integer isSign;
}

View File

@ -72,6 +72,15 @@ public class ProcessController {
return success(processService.pageProcess(page, pageReqVO));
}
@GetMapping("/newPage")
@Operation(summary = "学员课程进度分页")
public CommonResult<IPage<?>> getDlDriveSchoolCoachPageNew(ProcessVO pageReqVO,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
Page<ProcessVO> page = new Page<>(pageNo, pageSize);
return success(processService.pageProcessNew(page, pageReqVO));
}
/**
* 教练查自己带教的课程和科目
*

View File

@ -2,12 +2,12 @@ package cn.iocoder.yudao.module.course.controller.admin;
import cn.hutool.core.bean.BeanUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.course.entity.SchoolCourseOrder;
import cn.iocoder.yudao.module.course.service.SchoolCourseOrderService;
import cn.iocoder.yudao.module.course.vo.SchoolCommissionVO;
import cn.iocoder.yudao.module.course.vo.SchoolCourseOrderBusinessVO;
import cn.iocoder.yudao.module.course.vo.SchoolCourseOrderExportVO;
import cn.iocoder.yudao.module.course.vo.SchoolCourseOrderVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -15,7 +15,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -24,7 +23,6 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@ -143,4 +141,13 @@ public class SchoolCourseOrderController {
schoolCourseOrderService.updateStudentPassTime(studentId, passTime);
return success(true);
}
/**
* 业务经理代学员报名
*/
@PostMapping("/businessManagerCreate")
public CommonResult<Long> businessManagerCreateSchoolCourseOrder(@Valid @RequestBody SchoolCourseOrderBusinessVO createReqVO) {
// return success("");
return success(schoolCourseOrderService.businessManagerCreateSchoolCourseOrder(createReqVO));
}
}

View File

@ -0,0 +1,61 @@
package cn.iocoder.yudao.module.course.controller.admin;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.course.entity.SchoolStudentCommissionRecord;
import cn.iocoder.yudao.module.course.service.SchoolStudentCommissionRecordService;
import cn.iocoder.yudao.module.course.vo.SchoolStudentCommissionRecordVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@RestController
@RequestMapping("/commissionRecord")
@Validated
public class SchoolStudentCommissionRecordController {
@Autowired
private SchoolStudentCommissionRecordService commissionRecordService;
@PostMapping("/create")
public CommonResult<?> createRecord(@RequestBody SchoolStudentCommissionRecord record) {
return success(commissionRecordService.createRecord(record));
}
@PutMapping("/update")
public CommonResult<Boolean> updateRecord(@RequestBody SchoolStudentCommissionRecord record) {
return success(commissionRecordService.updateRecord(record));
}
@DeleteMapping("/delete")
public CommonResult<Boolean> deleteRecord(@RequestParam("id") Long id) {
return success(commissionRecordService.deleteRecord(id));
}
@GetMapping("/get")
public CommonResult<?> getRecord(@RequestParam("id") Long id) {
SchoolStudentCommissionRecord record = commissionRecordService.getRecordById(id);
return success(record);
}
@GetMapping("/list-by-student")
public CommonResult<List<SchoolStudentCommissionRecord>> getRecordsByStudentId(@RequestParam("studentId") Long studentId) {
List<SchoolStudentCommissionRecord> list = commissionRecordService.getRecordsByStudentId(studentId);
return success(list);
}
@GetMapping("/list-by-coach")
public CommonResult<List<SchoolStudentCommissionRecord>> getRecordsByCoachId(@RequestParam("coachId") Long coachId) {
List<SchoolStudentCommissionRecord> list = commissionRecordService.getRecordsByCoachId(coachId);
return success(list);
}
@PutMapping("/update-grant-status")
public CommonResult<Boolean> updateGrantStatus(@RequestBody SchoolStudentCommissionRecord reqVO) {
return success(commissionRecordService.updateGrantStatus(reqVO.getId(), reqVO.getIsGrant()));
}
}

View File

@ -73,8 +73,8 @@ public class SchoolCommission extends TenantBaseDO {
*/
private Boolean ifPay;
/**
* 是否已付
* 支付时间
*/
private Date payTime;
}
}

View File

@ -122,5 +122,15 @@ public class SchoolCourseOrder extends TenantBaseDO {
*/
private Date gradTime;
/**
* 报名方式1为代报名
*/
private String signType;
}
/**
* 支付渠道微信1线下2
*/
private String payChannel;
}

View File

@ -0,0 +1,72 @@
package cn.iocoder.yudao.module.course.entity;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* 学员各科目提成记录表
*/
@TableName("drive_school_commission_record")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SchoolStudentCommissionRecord extends TenantBaseDO {
/**
* 主键id
*/
@TableId(type = IdType.ASSIGN_UUID)
private Long id;
/**
* 课程id
*/
private String courseId;
/**
* 课程名称
*/
private String courseName;
/**
* 科目
*/
private String courseSubject;
/**
* 学员id
*/
private Long studentId;
/**
* 学员姓名
*/
private String studentName;
/**
* 教练id
*/
private Long coachId;
/**
* 教练姓名
*/
private String coachName;
/**
* 科目提成金额
*/
private BigDecimal subjectCommission;
/**
* 是否发放
*/
private Integer isGrant;
}

View File

@ -70,6 +70,7 @@ public interface ProcessMapper extends BaseMapper<Process> {
* @return com.baomidou.mybatisplus.core.metadata.IPage<cn.iocoder.yudao.module.course.vo.ProcessVO>
**/
IPage<ProcessVO> pageProcess(@Param("entity") ProcessVO entity, Page<ProcessVO> page);
IPage<ProcessVO> pageProcessNew(@Param("entity") ProcessVO entity, Page<ProcessVO> page);
Double selectAllTrainTime(@Param("userId") Long userId,@Param("courseId") String courseId);

View File

@ -2,7 +2,9 @@ package cn.iocoder.yudao.module.course.mapper;
import cn.iocoder.yudao.module.course.entity.SchoolCourseOrder;
import cn.iocoder.yudao.module.course.vo.SchoolCommissionVO;
import cn.iocoder.yudao.module.course.vo.SchoolCourseOrderBusinessVO;
import cn.iocoder.yudao.module.course.vo.SchoolCourseOrderVO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -43,4 +45,8 @@ public interface SchoolCourseOrderMapper extends BaseMapper<SchoolCourseOrder> {
/** 学员订单信息 */
SchoolCourseOrderVO getOrderInfo(@Param("userId") Long userId);
/**创建学员Users表信息*/
Long createStudentUsers(AdminUserDO adminUserDO);
}

View File

@ -0,0 +1,10 @@
package cn.iocoder.yudao.module.course.mapper;
import cn.iocoder.yudao.module.course.entity.SchoolStudentCommissionRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface SchoolStudentCommissionRecordMapper extends BaseMapper<SchoolStudentCommissionRecord> {
}

View File

@ -93,6 +93,7 @@ public interface ProcessService extends IService<Process> {
* @date 15:34 2025/2/17
**/
IPage<ProcessVO> pageProcess(Page<ProcessVO> page, ProcessVO pageReqVO);
IPage<ProcessVO> pageProcessNew(Page<ProcessVO> page, ProcessVO pageReqVO);
/**
* 财务审核

View File

@ -30,4 +30,9 @@ public interface SchoolCommissionService extends IService<SchoolCommission> {
*/
boolean createSchoolCommission(SchoolCommissionVO entity);
/**
* 判断提成记录是否存在
*/
boolean exists(SchoolCommission entity);
}

View File

@ -1,24 +1,17 @@
package cn.iocoder.yudao.module.course.service;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.course.entity.SchoolCommission;
import cn.iocoder.yudao.module.course.entity.SchoolCourseOrder;
import cn.iocoder.yudao.module.course.vo.SchoolCommissionVO;
import cn.iocoder.yudao.module.course.vo.SchoolCourseOrderBusinessVO;
import cn.iocoder.yudao.module.course.vo.SchoolCourseOrderVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.bind.annotation.GetMapping;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
/**
* 驾照报名订单 Service 接口
*
@ -110,4 +103,6 @@ public interface SchoolCourseOrderService extends IService<SchoolCourseOrder> {
*/
void updateStudentPassTime(String studentId, String gradTime);
Long businessManagerCreateSchoolCourseOrder(SchoolCourseOrderBusinessVO createReqVO);
}

View File

@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.course.service;
import cn.iocoder.yudao.module.course.entity.SchoolStudentCommissionRecord;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
public interface SchoolStudentCommissionRecordService extends IService<SchoolStudentCommissionRecord> {
/**
* 创建学员提成记录
*/
boolean createRecord(SchoolStudentCommissionRecord record);
/**
* 更新学员提成记录
*/
boolean updateRecord(SchoolStudentCommissionRecord record);
/**
* 删除学员提成记录
*/
boolean deleteRecord(Long id);
/**
* 根据ID获取学员提成记录
*/
SchoolStudentCommissionRecord getRecordById(Long id);
/**
* 获取学员的所有提成记录
*/
List<SchoolStudentCommissionRecord> getRecordsByStudentId(Long studentId);
/**
* 获取教练的所有提成记录
*/
List<SchoolStudentCommissionRecord> getRecordsByCoachId(Long coachId);
/**
* 更新提成发放状态
*/
boolean updateGrantStatus(Long id, Integer isGrant);
}

View File

@ -253,6 +253,10 @@ public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> impl
public IPage<ProcessVO> pageProcess(Page<ProcessVO> page, ProcessVO pageReqVO) {
return processMapper.pageProcess(pageReqVO, page);
}
@Override
public IPage<ProcessVO> pageProcessNew(Page<ProcessVO> page, ProcessVO pageReqVO) {
return processMapper.pageProcessNew(pageReqVO, page);
}
/**
* 财务审核
@ -261,7 +265,7 @@ public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> impl
* @author PQZ
* @date 15:24 2025/2/18
**/
@Override
/*@Override
@Transactional(rollbackFor = Exception.class)
public void checkProcess(Process process) {
//查询数据
@ -298,13 +302,99 @@ public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> impl
schoolCommission.setCheckId(sysUser.getId());
//审核人姓名
schoolCommission.setCheckName(sysUser.getNickname());
schoolCommissionService.save(schoolCommission);
// 检查是否已存在记录
SchoolCommission existing = schoolCommissionService.getOne(
Wrappers.<SchoolCommission>lambdaQuery()
.eq(SchoolCommission::getCoachUserId, schoolCommission.getCoachUserId())
.eq(SchoolCommission::getStudentId, schoolCommission.getStudentId())
.eq(SchoolCommission::getCourseId, schoolCommission.getCourseId())
.eq(SchoolCommission::getSubject, schoolCommission.getSubject())
);
if(existing != null){
schoolCommission.setId(existing.getId());
schoolCommission.setDeleted(!process.getFinancePass());
schoolCommissionService.updateById(schoolCommission);
}else{
schoolCommissionService.save(schoolCommission);
}
}
}
}
updateById(process);
}*/
@Override
@Transactional(rollbackFor = Exception.class)
public void checkProcess(Process process) {
// 查询原始数据和当前用户信息
Process oldProcess = getById(process.getId());
Long userId = SecurityFrameworkUtils.getLoginUserId();
AdminUserRespDTO sysUser = userApi.getUser(userId);
// 科目为空时直接更新Process并返回
if (process.getSubject() == null) {
updateById(process);
return;
}
// 查询提成规则
DriveSchoolCourseDeduct deduct = deductService.getOne(
Wrappers.<DriveSchoolCourseDeduct>lambdaQuery()
.eq(DriveSchoolCourseDeduct::getCourseId, process.getCourseId())
.eq(DriveSchoolCourseDeduct::getCourseSubject, process.getSubject())
);
// 如果存在提成规则
if (deduct != null) {
// 构建提成记录对象
SchoolCommission schoolCommission = new SchoolCommission();
schoolCommission.setCoachUserId(oldProcess.getCoachId());
schoolCommission.setCoachName(oldProcess.getCoachName());
schoolCommission.setStudentId(oldProcess.getUserId());
schoolCommission.setStudentName(oldProcess.getUserName());
schoolCommission.setCommissionAmount(deduct.getDeduct());
schoolCommission.setCourseId(oldProcess.getCourseId());
schoolCommission.setSubject(String.valueOf(oldProcess.getSubject()));
schoolCommission.setCheckId(sysUser.getId());
schoolCommission.setCheckName(sysUser.getNickname());
// 检查是否已存在记录
SchoolCommission existing = schoolCommissionService.getOne(
Wrappers.<SchoolCommission>lambdaQuery()
.eq(SchoolCommission::getCoachUserId, schoolCommission.getCoachUserId())
.eq(SchoolCommission::getStudentId, schoolCommission.getStudentId())
.eq(SchoolCommission::getCourseId, schoolCommission.getCourseId())
.eq(SchoolCommission::getSubject, schoolCommission.getSubject())
);
// 根据是否存在记录和审核状态处理
if (existing != null) {
if(process.getFinancePass()){
// 更新记录设置ID和deleted状态
schoolCommission.setId(existing.getId());
schoolCommission.setDeleted(!process.getFinancePass());
schoolCommissionService.updateById(schoolCommission);
}else {
// 删除记录设置ID和deleted状态
schoolCommission.setId(existing.getId());
schoolCommission.setDeleted(!process.getFinancePass());
schoolCommissionService.removeById(existing.getId());
}
} else if (process.getFinancePass()) {
// 仅审核通过时新增记录
schoolCommission.setDeleted(false);
schoolCommissionService.save(schoolCommission);
}
}
// 更新Process记录
updateById(process);
}
/**
* 保存学员课程进度
*

View File

@ -71,4 +71,14 @@ public class SchoolCommissionServiceImpl extends ServiceImpl<SchoolCommissionMap
return true;
}
@Override
public boolean exists(SchoolCommission entity) {
return this.lambdaQuery()
.eq(SchoolCommission::getCoachUserId, entity.getCoachUserId())
.eq(SchoolCommission::getStudentId, entity.getStudentId())
.eq(SchoolCommission::getCourseId, entity.getCourseId())
.eq(SchoolCommission::getSubject, entity.getSubject())
.exists();
}
}

View File

@ -1,24 +1,28 @@
package cn.iocoder.yudao.module.course.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.base.constant.SchoolBaseConstants;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolStudent;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCourseService;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolStudentService;
import cn.iocoder.yudao.module.base.service.SchoolNotifyMessageSendService;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolStudentVO;
import cn.iocoder.yudao.module.course.entity.Process;
import cn.iocoder.yudao.module.course.entity.SchoolCourseOrder;
import cn.iocoder.yudao.module.course.mapper.SchoolCourseOrderMapper;
import cn.iocoder.yudao.module.course.service.ProcessService;
import cn.iocoder.yudao.module.course.service.SchoolCourseOrderService;
import cn.iocoder.yudao.module.course.vo.SchoolCommissionVO;
import cn.iocoder.yudao.module.course.vo.SchoolCourseOrderBusinessVO;
import cn.iocoder.yudao.module.course.vo.SchoolCourseOrderVO;
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.UserDTO;
import cn.iocoder.yudao.module.system.service.permission.RoleService;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@ -62,6 +66,11 @@ public class SchoolCourseOrderServiceImpl extends ServiceImpl<SchoolCourseOrderM
@Lazy
private RoleApi roleApi;
@Lazy
@Resource
private DlDriveSchoolStudentService schoolStudentService;
@Override
public String createSchoolCourseOrder(SchoolCourseOrderVO createReqVO) {
// 插入
@ -75,9 +84,39 @@ public class SchoolCourseOrderServiceImpl extends ServiceImpl<SchoolCourseOrderM
public void updateSchoolCourseOrder(SchoolCourseOrderVO updateReqVO) {
// 更新
SchoolCourseOrder updateObj = BeanUtils.toBean(updateReqVO, SchoolCourseOrder.class);
if(updateReqVO.getIsSign() != null){
this.sendMessage(updateReqVO);
}
schoolCourseOrderMapper.updateById(updateObj);
}
// 判断是否面签发送消息
public void sendMessage(SchoolCourseOrderVO updateReqVO) {
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(schoolCourseOrder != null){
// 面签成功
if(schoolCourseOrder.getIsSign() == 0 && updateReqVO.getIsSign() == 1){
String messageToCoach = String.format(SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TEMPLATE_MEMBER_SIGN_TO_COACH, studentByUserId.getName());
schoolNotifyMessageSendService.sendMessage(studentByUserId.getSourceUserId(), messageToCoach, SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TYPE_ADMIN,null);
} else if (schoolCourseOrder.getIsSign() == 1 && updateReqVO.getIsSign() == 0) {
// 取消面签
String messageToCoach = String.format(SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TEMPLATE_MEMBER_CANCEL_SIGN_TO_COACH, studentByUserId.getName());
schoolNotifyMessageSendService.sendMessage(studentByUserId.getSourceUserId(), messageToCoach, SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TYPE_ADMIN,null);
} else if ("0".equals(schoolCourseOrder.getPaymentStatus()) && "2".equals(updateReqVO.getPaymentStatus())) {
// 支付成功
String messageToCoach = String.format(SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TEMPLATE_MEMBER_PAY_TO_MEMBER, studentByUserId.getName());
schoolNotifyMessageSendService.sendMessage(studentByUserId.getSourceUserId(), messageToCoach, SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TYPE_ADMIN,null);
}
}
}
}
}
@Override
public void deleteSchoolCourseOrder(String id) {
// 删除
@ -104,10 +143,11 @@ public class SchoolCourseOrderServiceImpl extends ServiceImpl<SchoolCourseOrderM
public IPage<SchoolCourseOrderVO> queryPage(Page<SchoolCommissionVO> page, SchoolCourseOrderVO pageReqVO) {
return schoolCourseOrderMapper.queryPage(pageReqVO, page);
}
@Override
public IPage<SchoolCourseOrderVO> queryPageNew(Page<SchoolCommissionVO> page, SchoolCourseOrderVO pageReqVO) {
return schoolCourseOrderMapper.queryPageNew(pageReqVO,page);
}
public IPage<SchoolCourseOrderVO> queryPageNew(Page<SchoolCommissionVO> page, SchoolCourseOrderVO pageReqVO) {
return schoolCourseOrderMapper.queryPageNew(pageReqVO, page);
}
/**
* 终止订单
@ -139,6 +179,16 @@ public class SchoolCourseOrderServiceImpl extends ServiceImpl<SchoolCourseOrderM
.eq(Process::getStatus, SchoolBaseConstants.PROCESS_STATUS_IN_PROGRESS))
);
DlDriveSchoolStudent studentByUserId = schoolStudentService.getStudentByUserId(Long.valueOf(schoolCourseOrder.getUserId()));
if (studentByUserId != null) {
// 如果为业务经理招生发送消息给业务经理
if("04".equals(studentByUserId.getSource()) && studentByUserId.getSourceUserId() != null){
String messageToCoach = String.format(SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TEMPLATE_COURSE_END_TO_MEMBER, studentByUserId.getName(), endReason);
schoolNotifyMessageSendService.sendMessage(studentByUserId.getSourceUserId(), messageToCoach, SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TYPE_ADMIN,null);
}
}
// 准备消息内容
String message = String.format(SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TEMPLATE_COURSE_END, schoolCourseOrder.getCourseName());
@ -229,7 +279,7 @@ public class SchoolCourseOrderServiceImpl extends ServiceImpl<SchoolCourseOrderM
@Override
public Boolean sendOrderMessage(String studentName, String courseName, Long coachId) {
if(coachId != null){
if (coachId != null) {
// 准备消息内容
String message = String.format(SchoolBaseConstants.SCHOOL_NOTIFY_MESSAGE_TEMPLATE_MEMBER_ENROLL, studentName, courseName);
@ -318,4 +368,39 @@ public class SchoolCourseOrderServiceImpl extends ServiceImpl<SchoolCourseOrderM
return "ORDER" + UUID.randomUUID().toString().replace("-", "").substring(0, 10);
}
public String generateOrderNum() {
return "DXD" + UUID.randomUUID().toString().replace("-", "").substring(0, 10);
}
@Transactional(rollbackFor = Exception.class)
@Override
public Long businessManagerCreateSchoolCourseOrder(SchoolCourseOrderBusinessVO createReqVO) {
DlDriveSchoolStudent studentByIdNo = schoolStudentService.getStudentByIdNo(createReqVO.getIdCard());
Long userId = null;
if (studentByIdNo == null) {
DlDriveSchoolStudentVO dlDriveSchoolStudentVO = new DlDriveSchoolStudentVO();
dlDriveSchoolStudentVO.setName(createReqVO.getUserName());
dlDriveSchoolStudentVO.setAge(createReqVO.getAge());
dlDriveSchoolStudentVO.setSource("04");
dlDriveSchoolStudentVO.setSourceUserId(SecurityFrameworkUtils.getLoginUserId());
dlDriveSchoolStudentVO.setSex(createReqVO.getUserSex());
dlDriveSchoolStudentVO.setPhone(createReqVO.getUserPhone());
dlDriveSchoolStudentVO.setIdCard(createReqVO.getIdCard());
dlDriveSchoolStudentVO.setIdPhoto(createReqVO.getIdCardImage());
dlDriveSchoolStudentVO.setRegistAddress(createReqVO.getAddress());
String studentId = schoolStudentService.createDlDriveSchoolStudent(dlDriveSchoolStudentVO);
DlDriveSchoolStudent dlDriveSchoolStudent = schoolStudentService.getDlDriveSchoolStudent(studentId);
userId = dlDriveSchoolStudent.getUserId();
} else {
userId = studentByIdNo.getUserId();
}
createReqVO.setUserId(Math.toIntExact(userId));
createReqVO.setOrderNo(generateOrderNum());
schoolCourseOrderMapper.insert(createReqVO);
return userId;
}
}

View File

@ -0,0 +1,53 @@
package cn.iocoder.yudao.module.course.service.impl;
import cn.iocoder.yudao.module.course.entity.SchoolStudentCommissionRecord;
import cn.iocoder.yudao.module.course.mapper.SchoolStudentCommissionRecordMapper;
import cn.iocoder.yudao.module.course.service.SchoolStudentCommissionRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class SchoolStudentCommissionRecordServiceImpl extends ServiceImpl<SchoolStudentCommissionRecordMapper, SchoolStudentCommissionRecord> implements SchoolStudentCommissionRecordService {
@Override
public boolean createRecord(SchoolStudentCommissionRecord record) {
return save(record);
}
@Override
public boolean updateRecord(SchoolStudentCommissionRecord record) {
return updateById(record);
}
@Override
public boolean deleteRecord(Long id) {
return removeById(id);
}
@Override
public SchoolStudentCommissionRecord getRecordById(Long id) {
return getById(id);
}
@Override
public List<SchoolStudentCommissionRecord> getRecordsByStudentId(Long studentId) {
return lambdaQuery().eq(SchoolStudentCommissionRecord::getStudentId, studentId).list();
}
@Override
public List<SchoolStudentCommissionRecord> getRecordsByCoachId(Long coachId) {
return lambdaQuery().eq(SchoolStudentCommissionRecord::getCoachId, coachId).list();
}
@Override
public boolean updateGrantStatus(Long id, Integer isGrant) {
SchoolStudentCommissionRecord record = new SchoolStudentCommissionRecord();
record.setId(id);
record.setIsGrant(isGrant);
return updateById(record);
}
}

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.course.vo;
import cn.iocoder.yudao.module.course.entity.SchoolCourseOrder;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 驾照报名订单 Response VO")
@Data
@ExcelIgnoreUnannotated
public class SchoolCourseOrderBusinessVO extends SchoolCourseOrder {
/**
* 学员身份证号
*/
private String idCard;
/**
* 学员身份证图片
*/
private String idCardImage;
/**
* 学员年龄
*/
private Integer age;
/**
* 户籍地址
*/
private String address;
}

View File

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.course.vo;
import java.math.BigDecimal;
public class SchoolStudentCommissionRecordVO {
private String courseId;
private String courseName;
private String courseSubject;
private Long studentId;
private String studentName;
private Long coachId;
private String coachName;
private BigDecimal subjectCommission;
private Integer isGrant;
}

View File

@ -46,5 +46,4 @@ public class ExamBatchController {
return success(examBatchService.selectOneById(id));
}
}
}

View File

@ -48,4 +48,15 @@ public class ExamBatchItemController {
return success(true);
}
}
/**
* 所有教练所有考试信息
*/
@GetMapping("/batchItemListByCoach")
public CommonResult<IPage<?>> batchItemListByCoach(ExamBatchVO examBatchVO,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
Page<ExamBatchVO> page = new Page<>(pageNo,pageSize);
return success(examBatchItemService.batchItemListByCoach(examBatchVO, page));
}
}

View File

@ -64,4 +64,6 @@ public class AppExamBatchController {
examBatchItemService.updateObjNew(examBatchVO);
return success(true);
}
}

View File

@ -32,4 +32,5 @@ public interface ExamBatchItemMapper extends BaseMapper<ExamBatchItem> {
List<ExamVO> selectExamByUserIdAndCoachId(@Param("userId") Long userId, @Param("coachId") Long coachId);
List<ExamBatchItemVO> listJoinBatchByIds(@Param("examIds") List<String> examIds);
IPage<ExamBatchVO> batchItemListByCoach(@Param("entity") ExamBatchVO examBatchVO, Page<ExamBatchVO> page);
}

View File

@ -84,4 +84,6 @@ public interface ExamBatchItemService extends IService<ExamBatchItem> {
* @return
*/
List<ExamBatchItemVO> listJoinBatchByIds(List<String> examIds);
IPage<ExamBatchVO> batchItemListByCoach(ExamBatchVO examBatchVO, Page<ExamBatchVO> page);
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.exam.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.base.constant.SchoolBaseConstants;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolStudentService;
@ -365,4 +366,41 @@ public class ExamBatchItemServiceImpl extends ServiceImpl<ExamBatchItemMapper, E
if (CollUtil.isEmpty(examIds)) return null;
return baseMapper.listJoinBatchByIds(examIds);
}
/**
* 所有教练所有考试信息
*
* @param
* @return
*/
@Override
public IPage<ExamBatchVO> batchItemListByCoach(ExamBatchVO examBatchVO, Page<ExamBatchVO> page) {
if (examBatchVO == null) {
return null;
}
String startTimeStr = "";
String endTimeStr = "";
String startTime = examBatchVO.getStartTimeSearch();
String endTime = examBatchVO.getEndTimeSearch();
String timeType = examBatchVO.getTimeType();
if("more".equals(timeType)){
if(org.apache.commons.lang3.StringUtils.isNotEmpty(startTime)){
startTimeStr = startTime+" 00:00:01";
}
if(org.apache.commons.lang3.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";
}
examBatchVO.setStartTimeSearch(startTimeStr);
examBatchVO.setEndTimeSearch(endTimeStr);
return baseMapper.batchItemListByCoach(examBatchVO, page);
}
}

View File

@ -28,4 +28,14 @@ public class ExamBatchVO extends ExamBatch {
* 查询时间区间-结束
*/
private String endTimeSearch;
/**
* 通过人数
*/
private Integer passCount;
/**
* 学生人数
*/
private Integer studentCount;
}

View File

@ -1,9 +1,12 @@
package cn.iocoder.yudao.module.jx.controller.admin;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.jx.core.controller.BaseController;
import cn.iocoder.yudao.module.jx.domain.DriveContractTest;
import cn.iocoder.yudao.module.jx.domain.DriveSchoolContract;
import cn.iocoder.yudao.module.jx.service.IDriveContractTestService;
import cn.iocoder.yudao.module.jx.service.IDriveSchoolContractService;
import cn.iocoder.yudao.module.jx.utils.ExcelUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -26,6 +29,9 @@ public class DriveContractTestController extends BaseController
@Autowired
private IDriveContractTestService driveContractTestService;
@Autowired
private IDriveSchoolContractService driveSchoolContractService;
/**
* 查询合同模板列表
*/
@ -84,4 +90,18 @@ public class DriveContractTestController extends BaseController
{
return toAjax(driveContractTestService.deleteDriveContractTestByIds(ids));
}
@GetMapping(value = "/tenantId/{tenantId}")
@TenantIgnore
public CommonResult getInfoByTenantId(@PathVariable("tenantId") String tenantId)
{
return CommonResult.success(driveContractTestService.selectDriveContractTestByTenantId(tenantId));
}
@PostMapping("/add")
@TenantIgnore
public CommonResult add(@RequestBody DriveSchoolContract driveSchoolContract)
{
return CommonResult.success(driveSchoolContractService.insertDriveSchoolContractNew(driveSchoolContract));
}
}

View File

@ -4,6 +4,8 @@ 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;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.company.entity.Company;
import cn.iocoder.yudao.module.company.service.CompanyService;
import cn.iocoder.yudao.module.course.entity.SchoolCourseOrder;
import cn.iocoder.yudao.module.course.service.SchoolCourseOrderService;
import cn.iocoder.yudao.module.course.vo.SchoolCourseOrderVO;
@ -51,6 +53,8 @@ public class NewSmallProgramJxOrderController {
private AdminUserApi userApi;
@Resource
private SchoolCourseOrderService schoolCourseOrderService;
@Resource
private CompanyService companyService;
@PostMapping("/offLinePay")
@ -121,19 +125,29 @@ public class NewSmallProgramJxOrderController {
@GetMapping("/prepayment")
@TenantIgnore
public Map<String,Object> transactions(String type, String orderId, String orderNo, String payType) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException, IOException {
public Map<String,Object> transactions(String type, String orderId, String orderNo, String payType, String tenantId) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException, IOException {
Long userId = SecurityFrameworkUtils.getLoginUserId();
AdminUserRespDTO user = userApi.getUser(userId);
String systemCode = "jiaxiao";
// SchoolCourseOrder dbSchoolCourseOrder = schoolCourseOrderService.getSchoolCourseOrder(orderId);
SchoolCourseOrder dbSchoolCourseOrder = schoolCourseOrderService.getSchoolCourseOrder(orderId);
if (dbSchoolCourseOrder == null) {
throw new IllegalStateException("订单不存在");
}
Company companyInfo = companyService.getCompanyByTenantIdAndSystemCode(tenantId, systemCode);
if (companyInfo == null) {
throw new IllegalStateException("商户信息不存在");
}
// 统一参数封装
Map<String, Object> params = new HashMap<>(8);
params.put("appid", wechatPayConfigs.getJxAppId());
params.put("mchid", wechatPayConfigs.getMchId());
params.put("appid", companyInfo.getAppId());
params.put("mchid", companyInfo.getMchId());
params.put("description", dbSchoolCourseOrder.getCourseName());
params.put("out_trade_no", orderNo);
params.put("notify_url", wechatPayConfigs.getNotifyUrl());
params.put("notify_url", companyInfo.getNotifyUrl());
Map<String, Object> amountMap = new HashMap<>(4);
Double amount = 0.0;
@ -169,7 +183,7 @@ public class NewSmallProgramJxOrderController {
log.info("请求参数 ===> {}" + paramsStr);
String resStr = wechatPayRequests.wechatHttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi",paramsStr);
Map<String, Object> resMap = JSONObject.parseObject(resStr, new TypeReference<Map<String, Object>>(){});
Map<String, Object> signMap = paySignMsg(resMap.get("prepay_id").toString(), wechatPayConfigs.getJxAppId(),null);
Map<String, Object> signMap = paySignMsg(resMap.get("prepay_id").toString(), companyInfo.getAppId(), companyInfo.getPrivateKeyStr());
return signMap;
}

View File

@ -4,6 +4,9 @@ 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;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.company.entity.Company;
import cn.iocoder.yudao.module.company.service.CompanyService;
import cn.iocoder.yudao.module.company.vo.CompanyRespVO;
import cn.iocoder.yudao.module.course.entity.SchoolCourseOrder;
import cn.iocoder.yudao.module.course.service.SchoolCourseOrderService;
import cn.iocoder.yudao.module.course.vo.SchoolCourseOrderVO;
@ -27,10 +30,7 @@ import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import java.io.IOException;
import java.security.*;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.*;
@Slf4j
@RestController
@ -53,6 +53,9 @@ public class SmallProgramJxOrderController {
@Resource
private SchoolCourseOrderService schoolCourseOrderService;
@Resource
private CompanyService companyService;
@PostMapping("/offLinePay")
@TenantIgnore
@ -89,7 +92,7 @@ public class SmallProgramJxOrderController {
@PostMapping("/onLinePay")
@TenantIgnore
public Map<String,String> userPayOnLine(@RequestBody SchoolCourseOrder schoolCourseOrder) {
public Map<String, String> userPayOnLine(@RequestBody SchoolCourseOrder schoolCourseOrder) {
SchoolCourseOrderVO schoolCourseOrderVO = BeanUtils.toBean(schoolCourseOrder, SchoolCourseOrderVO.class);
schoolCourseOrderVO.setPaymentStatus("0");
@ -113,35 +116,46 @@ public class SmallProgramJxOrderController {
String orderId = schoolCourseOrderService.createSchoolCourseOrder(schoolCourseOrderVO);
SchoolCourseOrder dbSchoolCourseOrder = schoolCourseOrderService.getSchoolCourseOrder(orderId);
String orderNo = dbSchoolCourseOrder.getOrderNo();
Map<String,String> resMap = new HashMap<>();
resMap.put("orderNo",orderNo);
resMap.put("orderId",orderId);
Map<String, String> resMap = new HashMap<>();
resMap.put("orderNo", orderNo);
resMap.put("orderId", orderId);
return resMap;
}
@GetMapping("/prepayment")
@TenantIgnore
public Map<String,Object> transactions(String type, String orderId, String orderNo, String payType) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException, IOException {
public Map<String, Object> transactions(String type, String orderId, String orderNo, String payType, String tenantId) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException, IOException {
Long userId = SecurityFrameworkUtils.getLoginUserId();
AdminUserRespDTO user = userApi.getUser(userId);
String systemCode = "jiaxiao";
// SchoolCourseOrder dbSchoolCourseOrder = schoolCourseOrderService.getSchoolCourseOrder(orderId);
// Company companyInfo = companyService.getCompanyByTenantIdAndSystemCode(tenantId, systemCode);
SchoolCourseOrder dbSchoolCourseOrder = schoolCourseOrderService.getSchoolCourseOrder(orderId);
if (dbSchoolCourseOrder == null) {
throw new IllegalStateException("订单不存在");
}
Company companyInfo = companyService.getCompanyByTenantIdAndSystemCode(tenantId, systemCode);
if (companyInfo == null) {
throw new IllegalStateException("商户信息不存在");
}
// 统一参数封装
Map<String, Object> params = new HashMap<>(8);
params.put("appid", wechatPayConfigs.getJxAppId());
params.put("mchid", wechatPayConfigs.getMchId());
params.put("appid", companyInfo.getAppId());
params.put("mchid", companyInfo.getMchId());
params.put("description", dbSchoolCourseOrder.getCourseName());
params.put("out_trade_no", orderNo);
params.put("notify_url", wechatPayConfigs.getNotifyUrl());
params.put("notify_url", companyInfo.getNotifyUrl());
Map<String, Object> amountMap = new HashMap<>(4);
Double amount = 0.0;
// 金额单位为分
amount = dbSchoolCourseOrder.getReserveMoney().doubleValue()*100;
if (payType.equals("2")){
amount = dbSchoolCourseOrder.getReserveMoney().doubleValue()*100;
amount = dbSchoolCourseOrder.getReserveMoney().doubleValue() * 100;
if (payType.equals("2")) {
amount = dbSchoolCourseOrder.getReserveMoney().doubleValue() * 100;
}
amountMap.put("total", amount.intValue());
//人民币
@ -168,13 +182,14 @@ public class SmallProgramJxOrderController {
params.put("scene_info", sceneInfoMap);
String paramsStr = JSON.toJSONString(params);
log.info("请求参数 ===> {}" + paramsStr);
String resStr = wechatPayRequests.wechatHttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi",paramsStr);
Map<String, Object> resMap = JSONObject.parseObject(resStr, new TypeReference<Map<String, Object>>(){});
Map<String, Object> signMap = paySignMsg(resMap.get("prepay_id").toString(), wechatPayConfigs.getJxAppId(),null);
String resStr = wechatPayRequests.wechatHttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi", paramsStr);
Map<String, Object> resMap = JSONObject.parseObject(resStr, new TypeReference<Map<String, Object>>() {
});
Map<String, Object> signMap = paySignMsg(resMap.get("prepay_id").toString(), companyInfo.getAppId(), companyInfo.getPrivateKeyStr());
return signMap;
}
String buildMessage(String appId, String timestamp,String nonceStr,String prepay_id) {
String buildMessage(String appId, String timestamp, String nonceStr, String prepay_id) {
return appId + "\n"
+ timestamp + "\n"
@ -182,15 +197,15 @@ public class SmallProgramJxOrderController {
+ prepay_id + "\n";
}
String sign(byte[] message,String privateKeyStr) throws NoSuchAlgorithmException, SignatureException, IOException, InvalidKeyException {
String sign(byte[] message, String privateKeyStr) throws NoSuchAlgorithmException, SignatureException, IOException, InvalidKeyException {
//签名方式
Signature sign = Signature.getInstance("SHA256withRSA");
//私钥通过MyPrivateKey来获取这是个静态类可以接调用方法 需要的是_key.pem文件的绝对路径配上文件名
PrivateKey privateKey =null;
if (StringUtils.isNotEmpty(privateKeyStr)){
PrivateKey privateKey = null;
if (StringUtils.isNotEmpty(privateKeyStr)) {
privateKey = PemUtil.loadPrivateKey(privateKeyStr);
}else {
privateKey = wechatPayConfigs.getPrivateKey(wechatPayConfigs.getKeyPemPath());
} else {
privateKey = wechatPayConfigs.getPrivateKey(wechatPayConfigs.getKeyPemPath());
}
sign.initSign(privateKey);
@ -198,16 +213,16 @@ public class SmallProgramJxOrderController {
return Base64.getEncoder().encodeToString(sign.sign());
}
private Map<String, Object> paySignMsg(String prepayId,String appId,String privateKeyStr) throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
private Map<String, Object> paySignMsg(String prepayId, String appId, String privateKeyStr) throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
long timeMillis = System.currentTimeMillis();
String timeStamp = timeMillis/1000+"";
String nonceStr = timeMillis+"";
String packageStr = "prepay_id="+prepayId;
String timeStamp = timeMillis / 1000 + "";
String nonceStr = timeMillis + "";
String packageStr = "prepay_id=" + prepayId;
// 公共参数
Map<String, Object> resMap = new HashMap<>();
resMap.put("nonceStr",nonceStr);
resMap.put("timeStamp",timeStamp);
resMap.put("appId",appId);
resMap.put("nonceStr", nonceStr);
resMap.put("timeStamp", timeStamp);
resMap.put("appId", appId);
resMap.put("package", packageStr);
// 使用字段appIdtimeStampnonceStrpackage进行签名
//从下往上依次生成

View File

@ -160,6 +160,12 @@
AND (dss.phone LIKE CONCAT('%', #{entity.phone}, '%')
OR dsc.phone LIKE CONCAT('%', #{entity.phone}, '%'))
</if>
<if test="entity.isSign != null ">
AND dsco.is_sign = #{entity.isSign}
</if>
<if test="entity.paymentStatus != null and entity.paymentStatus != ''">
AND dsco.payment_status = #{entity.paymentStatus}
</if>
</where>
ORDER BY dsco.create_time DESC
</select>

View File

@ -49,68 +49,82 @@
ORDER BY
dss.create_time DESC
</select>
<select id="pageStaffStudent" resultType="cn.iocoder.yudao.module.base.vo.DlDriveSchoolStaffVO">
SELECT
main.id AS id,
main.NAME AS NAME,
main.type AS type,
main.avatar AS avatar,
main.phone AS phone,
main.user_id AS userId,
dsco.course_type,
dsp.`subject`
FROM
drive_school_student main
LEFT JOIN drive_school_course_order dsco ON main.user_id = dsco.user_id
AND dsco.deleted = 0
AND dsco.payment_status IN ( '2', '3', '4', '5' )
AND dsco.if_end = 0
<select id="pageStaffStudent" resultType="cn.iocoder.yudao.module.base.vo.DlDriveSchoolStaffVO">
SELECT
main.id AS id,
main.NAME AS NAME,
main.type AS type,
main.avatar AS avatar,
main.phone AS phone,
main.user_id AS userId,
dsco.course_type,
dsp.`subject`
FROM
drive_school_student main
LEFT JOIN drive_school_course_order dsco ON main.user_id = dsco.user_id
AND dsco.deleted = 0
AND dsco.payment_status IN ( '2', '3', '4', '5' )
AND dsco.if_end = 0
LEFT JOIN drive_school_process dsp ON main.user_id = dsp.user_id
AND dsco.course_id = dsp.course_id
AND dsp.`status` = '1'
WHERE
main.deleted = 0 AND dsco.is_sign = 1
<if test="entity.coachId != null and entity.coachId != ''">
AND dsp.coach_id = #{entity.coachId}
</if>
<if test="entity.sourceCoachId != null and entity.sourceCoachId != ''">
AND main.source_user_id = #{entity.sourceCoachId}
</if>
<if test="entity.name!=null and entity.name!=''">
AND main.name LIKE CONCAT('%',#{entity.name},'%')
</if>
<if test="entity.courseType != null and entity.courseType != ''">
AND dsco.course_type = #{entity.courseType}
</if>
<if test="entity.subject != null and entity.subject != ''">
AND dsp.subject = #{entity.subject}
</if>
<if test="entity.startTime!=null and entity.startTime!=''">
AND dsco.create_time &gt;= #{entity.startTime}
</if>
<if test="entity.endTime!=null and entity.endTime!=''">
AND dsco.create_time &lt;= #{entity.endTime}
</if>
<if test="entity.source!=null and entity.source!=''">
AND main.source = #{entity.source}
</if>
<if test="entity.examStatus!=null and entity.examStatus!=''">
AND dsp.exam_status = #{entity.examStatus}
</if>
GROUP BY
main.id
<choose>
<when test="entity.sort=='asc'">
ORDER BY
dsco.create_time ASC
</when>
<otherwise>
ORDER BY
dsco.create_time DESC
</otherwise>
</choose>
</select>
LEFT JOIN drive_school_process dsp ON main.user_id = dsp.user_id
AND dsco.course_id = dsp.course_id
AND dsp.`status` = '1'
WHERE
main.deleted = 0 AND dsco.is_sign = 1
<if test="entity.coachId != null and entity.coachId != ''">
AND dsp.coach_id = #{entity.coachId}
</if>
<if test="entity.sourceCoachId != null and entity.sourceCoachId != ''">
AND main.source_user_id = #{entity.sourceCoachId}
</if>
<if test="entity.name!=null and entity.name!=''">
AND main.name LIKE CONCAT('%',#{entity.name},'%')
</if>
<if test="entity.courseType != null and entity.courseType != ''">
AND dsco.course_type = #{entity.courseType}
</if>
<if test="entity.subject != null and entity.subject != ''">
AND dsp.subject = #{entity.subject}
</if>
<if test="entity.startTime!=null and entity.startTime!=''">
AND dsco.create_time &gt;= #{entity.startTime}
</if>
<if test="entity.endTime!=null and entity.endTime!=''">
AND dsco.create_time &lt;= #{entity.endTime}
</if>
<if test="entity.source!=null and entity.source!=''">
AND main.source = #{entity.source}
</if>
<if test="entity.examStatus!=null and entity.examStatus!=''">
AND dsp.exam_status = #{entity.examStatus}
</if>
<if test="entity.rangeTime!=null">
AND dsco.create_time BETWEEN #{entity.rangeTime[0]} AND #{entity.rangeTime[1]}
</if>
<if test="entity.address!=null and entity.address!=''">
AND main.address LIKE CONCAT('%',#{entity.address},'%')
</if>
<if test="entity.age!=null and entity.age!=''">
AND main.id_card IS NOT NULL
AND TIMESTAMPDIFF(YEAR, STR_TO_DATE(SUBSTRING(main.id_card, 7, 8), '%Y%m%d'), CURDATE()) BETWEEN #{entity.age[0]} AND #{entity.age[1]}
</if>
<if test="entity.passDays!=null and entity.passDays!=''">
AND dsco.pass_time IS NOT NULL
AND TIMESTAMPDIFF(DAY, dsco.create_time, dsco.pass_time) = #{entity.passDays}
</if>
GROUP BY
main.id
<choose>
<when test="entity.sort=='asc'">
ORDER BY
dsco.create_time ASC
</when>
<otherwise>
ORDER BY
dsco.create_time DESC
</otherwise>
</choose>
</select>
<select id="selectByCoachId" resultType="cn.iocoder.yudao.module.base.vo.DlDriveSchoolStudentVO">
SELECT
temp.*
@ -160,8 +174,8 @@
dss.deleted = 0
AND dsco.if_end = 0
AND dsco.deleted = 0
AND dsco.payment_status in ( '2', '3', '4', '5' )
AND dsco.is_sign = 1
-- AND dsco.payment_status in ( '2', '3', '4', '5' )
-- AND dsco.is_sign = 1
AND dss.id IS NOT NULL
AND dss.source = '04'
AND dss.source_user_id = #{entity.coachId}
@ -177,6 +191,9 @@
<if test="entity.courseType!=null and entity.courseType!=''">
AND dsco.course_type = #{entity.courseType}
</if>
<if test="entity.isSign!=null">
AND dsco.is_sign = #{entity.isSign}
</if>
GROUP BY
dss.user_id
<choose>
@ -296,6 +313,56 @@
GROUP BY
dsco.id
</select>
<select id="selectStudentListByBusiness" 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 = '04'
<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
@ -374,6 +441,9 @@
<when test="type=='02'">
AND c.type='jl'
</when>
<when test="type=='04'">
AND c.type='ywjl'
</when>
</choose>
</if>
GROUP BY

View File

@ -86,6 +86,60 @@
dsp.create_time DESC; -- 再按创建时间降序
</select>
<select id="pageProcessNew" resultType="cn.iocoder.yudao.module.course.vo.ProcessVO">
SELECT
dsp.*,
dss.id_card AS studentIdCard,
sysu.nickname AS updateName
FROM drive_school_process dsp
LEFT JOIN drive_school_student dss ON dss.user_id = dsp.user_id
LEFT JOIN system_users sysu on sysu.id = dsp.updater
<where>
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.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>
<choose>
<when test="entity.financePass == true">
AND dsp.finance_pass = 1
</when>
<when test="entity.financePass == false">
AND dsp.finance_pass = 0
</when>
<when test="entity.financePass == null">
AND dsp.finance_pass IS NULL
</when>
</choose>
<if test="entity.studentIdCard != null and entity.studentIdCard != '' ">
<choose>
<!-- 精确匹配当输入18位时 -->
<when test="entity.studentIdCard.length() == 18">
AND dss.id_card = #{entity.studentIdCard}
</when>
<!-- 后4位匹配当输入正好4位时 -->
<when test="entity.studentIdCard.length() == 4">
AND RIGHT(dss.id_card, 4) = #{entity.studentIdCard}
</when>
<!-- 模糊搜索当输入大于4位但不足18位时 -->
<otherwise>
AND dss.id_card LIKE concat('%', #{entity.studentIdCard}, '%')
</otherwise>
</choose>
</if>
</where>
ORDER BY
(CASE
WHEN dsp.exam_status = '1' AND dsp.finance_pass IS NULL THEN 1 -- 优先级最高
WHEN dsp.exam_status = '9' THEN 2
WHEN dsp.status = '1' THEN 2
ELSE 4
END),
dsp.update_time DESC; -- 再按创建时间降序
</select>
<select id="getProcessList" resultType="cn.iocoder.yudao.module.course.entity.Process">
SELECT
*

View File

@ -11,28 +11,36 @@
<select id="queryPage" resultType="cn.iocoder.yudao.module.course.vo.SchoolCommissionVO">
SELECT
main.*,
dsc.name AS courseName,
dsc.type AS courseType
main.*,
dsc.name AS courseName,
dsc.type AS courseType
FROM
drive_school_commission main
LEFT JOIN drive_school_course dsc ON main.course_id = dsc.id AND dsc.deleted = 0
drive_school_commission main
LEFT JOIN drive_school_course dsc ON main.course_id = dsc.id AND dsc.deleted = 0
<where>
main.deleted = 0
<if test="entity.coachName != null and entity.coachName != '' "> and main.coach_name like concat('%', #{entity.coachName}, '%')</if>
<if test="entity.studentName != null and entity.studentName != '' "> and main.student_name like concat('%', #{entity.studentName}, '%')</if>
<if test="entity.checkName != null and entity.checkName != '' "> and main.check_name like concat('%', #{entity.checkName}, '%')</if>
<if test="entity.courseName != null and entity.courseName != '' "> and dsc.name like concat('%', #{entity.courseName}, '%')</if>
<if test="entity.coachName != null and entity.coachName != '' ">and main.coach_name like concat('%',
#{entity.coachName}, '%')
</if>
<if test="entity.studentName != null and entity.studentName != '' ">and main.student_name like concat('%',
#{entity.studentName}, '%')
</if>
<if test="entity.checkName != null and entity.checkName != '' ">and main.check_name like concat('%',
#{entity.checkName}, '%')
</if>
<if test="entity.courseName != null and entity.courseName != '' ">and dsc.name like concat('%',
#{entity.courseName}, '%')
</if>
</where>
order by main.create_time desc
order by main.create_time desc
</select>
<select id="selectByCoachId" resultType="cn.iocoder.yudao.module.course.entity.SchoolCommission">
SELECT
dsc.*
dsc.*
FROM
drive_school_commission dsc
drive_school_commission dsc
WHERE
dsc.deleted = 0
dsc.deleted = 0
<if test="coachId != null and coachId != ''">
AND dsc.coach_user_id = #{coachId}
</if>
@ -44,4 +52,4 @@ order by main.create_time desc
</if>
ORDER BY dsc.create_time DESC
</select>
</mapper>
</mapper>

View File

@ -92,4 +92,30 @@
ORDER BY create_time DESC
LIMIT 1
</select>
<insert id="createStudentUsers" parameterType="cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO" useGeneratedKeys="true" keyProperty="id">
INSERT INTO system_users (username,
password,
status,
nickname,
user_age,
sex,
mobile,
id_card,
id_card_image,
create_time,
deleted)
VALUES (#{username},
#{password},
#{status},
#{nickname},
#{userAge},
#{sex},
#{mobile},
#{idCard},
#{idCardImage},
#{createTime},
#{deleted})
</insert>
</mapper>

View File

@ -0,0 +1,4 @@
<?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.SchoolStudentCommissionRecordMapper">
</mapper>

View File

@ -158,4 +158,71 @@
#{id}
</foreach>
</select>
<select id="batchItemListByCoach" resultType="cn.iocoder.yudao.module.exam.vo.ExamBatchVO">
SELECT
c.user_id AS coach_id,
c.name AS coach_name,
COUNT(i.id) AS student_count,
SUM(CASE WHEN i.if_pass = 1 THEN 1 ELSE 0 END) AS pass_count,
ROUND(
IFNULL(SUM(CASE WHEN i.if_pass = 1 THEN 1 ELSE 0 END) / NULLIF(COUNT(i.id), 0) * 100, 0),
2
) AS pass_rate
FROM
drive_school_coach c
LEFT JOIN drive_school_exam_batch b
ON b.coach_id = c.user_id AND b.deleted = 0
<if test="entity.subject != null and entity.subject != '' ">
AND b.subject = #{entity.subject}
</if>
LEFT JOIN drive_school_exam_batch_item i
ON i.batch_id = b.id AND i.deleted = 0
<if test="entity.startTimeSearch != null and entity.startTimeSearch != '' ">
AND i.create_time &gt;= #{entity.startTimeSearch}
</if>
<if test="entity.endTimeSearch != null and entity.endTimeSearch != '' ">
AND i.create_time &lt;= #{entity.endTimeSearch}
</if>
WHERE
c.deleted = 0
<if test="entity.coachId != null">
AND c.id = #{entity.coachId}
</if>
GROUP BY
c.id, c.name
ORDER BY
student_count DESC
<!--SELECT
b.coach_id,
b.coach_name,
COUNT(i.id) AS student_count,
SUM(CASE WHEN i.if_pass = 1 THEN 1 ELSE 0 END) AS pass_count,
ROUND(
SUM(CASE WHEN i.if_pass = 1 THEN 1 ELSE 0 END) / NULLIF(COUNT(i.id), 0) * 100,
2
) AS pass_rate
FROM
drive_school_exam_batch b
LEFT JOIN drive_school_exam_batch_item i
ON b.id = i.batch_id AND i.deleted = 0
WHERE
b.deleted = 0
<if test="entity.subject != null">
AND b.subject = #{entity.subject}
</if>
<if test="entity.startTimeSearch != null and entity.startTimeSearch != '' ">
AND i.create_time &gt;= #{entity.startTimeSearch}
</if>
<if test="entity.endTimeSearch != null and entity.endTimeSearch != '' ">
AND i.create_time &lt;= #{entity.endTimeSearch}
</if>
<if test="entity.coachId != null">
AND b.coach_id = #{entity.coachId}
</if>
GROUP BY
b.coach_id, b.coach_name
ORDER BY
student_count DESC-->
</select>
</mapper>