This commit is contained in:
Lx 2025-07-08 17:48:51 +08:00
parent 0062df3660
commit 7a5532b658
8 changed files with 214 additions and 38 deletions

View File

@ -21,6 +21,7 @@ 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.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -249,6 +250,11 @@ public class ProcessController {
Page<ProcessExportVO> page = new Page<>(pageNo, pageSize);
return success(processService.getProcessExportData(exportVO, page));
}
@GetMapping("/getSubjectPassCount")
public CommonResult<ProcessExportVO> getSubjectPassCount(ProcessExportVO exportVO) {
return success(processService.getSubjectPassCount(exportVO));
}
/**
* 导出

View File

@ -109,6 +109,7 @@ public interface ProcessMapper extends BaseMapper<Process> {
* 需要导出的数据
*/
IPage<ProcessExportVO> getProcessExportData (@Param("entity") ProcessExportVO entity, Page<ProcessExportVO> page);
ProcessExportVO getSubjectPassCount (@Param("entity") ProcessExportVO entity);
/**
* 学员考试合格率计算

View File

@ -176,6 +176,7 @@ public interface ProcessService extends IService<Process> {
* @return
*/
IPage<ProcessExportVO> getProcessExportData(ProcessExportVO exportVO, Page<ProcessExportVO> page);
ProcessExportVO getSubjectPassCount(ProcessExportVO exportVO);
/**
* 导出数据的三种形式

View File

@ -1042,6 +1042,11 @@ public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> impl
return processMapper.getProcessExportData(exportVO, page);
}
@Override
public ProcessExportVO getSubjectPassCount(ProcessExportVO exportVO) {
return processMapper.getSubjectPassCount(exportVO);
}
/**
* 导出数据的三种形式
@ -1084,6 +1089,8 @@ public class ProcessServiceImpl extends ServiceImpl<ProcessMapper, Process> impl
/**
* 学员考试合格率计算
*/

View File

@ -109,7 +109,7 @@ public class CourseOrderExportVO {
@ExcelProperty(value = "收款账号", index = 17)
private String paymentAccount;
@ExcelIgnore
private Integer cashierConfirm;
private String cashierConfirm;
/*@ExcelProperty(value = "出纳确认时间", index = 17)*/
@ExcelIgnore
@ -184,9 +184,9 @@ public class CourseOrderExportVO {
return "待确认";
}
switch (cashierConfirm) {
case 0:
case "0":
return "未到账";
case 1:
case "1":
return "已到账";
default:
return "未知状态";

View File

@ -48,6 +48,15 @@ public class ProcessExportVO {
@ExcelIgnore
private String payFeesEndTimeStr;
@ExcelIgnore
private Integer subjectOver;
@ExcelIgnore
private String subject2PassCount;
@ExcelIgnore
private String subject3PassCount;
// 分页参数
@ExcelIgnore

View File

@ -301,6 +301,7 @@
<select id="getProcessExportData" resultType="cn.iocoder.yudao.module.course.vo.ProcessExportVO">
SELECT
MAX(dsp.user_name) AS studentName,
MAX(dss.id_card) AS studentIdCard,
MAX(dsp.user_mobile) AS studentPhone,
@ -392,6 +393,30 @@
LEFT JOIN drive_school_process sub3 ON sub3.user_id = dsp.user_id AND sub3.subject = 3 AND sub3.deleted = 0
LEFT JOIN drive_school_process sub4 ON sub4.user_id = dsp.user_id AND sub4.subject = 4 AND sub4.deleted = 0
WHERE dsp.deleted = 0
<if test="entity.subjectOver != null">
<choose>
<when test="entity.subjectOver == 2">
AND EXISTS (
SELECT 1 FROM drive_school_process p
WHERE p.user_id = dsp.user_id
AND p.subject = 2
AND p.exam_time IS NOT NULL
AND p.exam_status = 1
AND p.deleted = 0
)
</when>
<when test="entity.subjectOver == 3">
AND EXISTS (
SELECT 1 FROM drive_school_process p
WHERE p.user_id = dsp.user_id
AND p.subject = 3
AND p.exam_time IS NOT NULL
AND p.exam_status = 1
AND p.deleted = 0
)
</when>
</choose>
</if>
<if test="entity.studentName != null and entity.studentName != ''">
AND dsp.user_name LIKE CONCAT('%', #{entity.studentName}, '%')
</if>
@ -424,6 +449,94 @@
ORDER BY MAX(dsp.create_time) DESC
</select>
<select id="getSubjectPassCount" resultType="cn.iocoder.yudao.module.course.vo.ProcessExportVO">
SELECT
COUNT(DISTINCT CASE
WHEN sub2.exam_status = 1 AND sub2.exam_time IS NOT NULL THEN dsp.user_id
END) AS subject2PassCount,
COUNT(DISTINCT CASE
WHEN sub3.exam_status = 1 AND sub3.exam_time IS NOT NULL THEN dsp.user_id
END) AS subject3PassCount
FROM drive_school_process dsp
LEFT JOIN drive_school_student dss
ON dss.user_id = dsp.user_id AND dss.deleted = 0
LEFT JOIN (
SELECT * FROM drive_school_course_order
WHERE if_end = 0 AND is_sign = 1 AND payment_status IN ('2','3','4','5')
<if test="entity.payFeesStartTimeStr!=null and entity.payFeesStartTimeStr!=''">
AND pay_fees_time &gt;= #{entity.payFeesStartTimeStr}
</if>
<if test="entity.payFeesEndTimeStr!=null and entity.payFeesEndTimeStr!=''">
AND pay_fees_time &lt;= #{entity.payFeesEndTimeStr}
</if>
AND (user_id, create_time) IN (
SELECT user_id, MAX(create_time)
FROM drive_school_course_order
WHERE if_end = 0 AND is_sign = 1 AND payment_status IN ('2','3','4','5')
GROUP BY user_id
)
) dsco ON dsco.user_id = dsp.user_id
LEFT JOIN drive_school_process sub2
ON sub2.user_id = dsp.user_id AND sub2.subject = 2 AND sub2.deleted = 0
LEFT JOIN drive_school_process sub3
ON sub3.user_id = dsp.user_id AND sub3.subject = 3 AND sub3.deleted = 0
WHERE dsp.deleted = 0
<if test="entity.subjectOver != null">
<choose>
<when test="entity.subjectOver == 2">
AND EXISTS (
SELECT 1 FROM drive_school_process p
WHERE p.user_id = dsp.user_id
AND p.subject = 2
AND p.exam_time IS NOT NULL
AND p.exam_status = 1
AND p.deleted = 0
)
</when>
<when test="entity.subjectOver == 3">
AND EXISTS (
SELECT 1 FROM drive_school_process p
WHERE p.user_id = dsp.user_id
AND p.subject = 3
AND p.exam_time IS NOT NULL
AND p.exam_status = 1
AND p.deleted = 0
)
</when>
</choose>
</if>
<if test="entity.studentName != null and entity.studentName != ''">
AND dsp.user_name LIKE CONCAT('%', #{entity.studentName}, '%')
</if>
<if test="entity.studentIdCard != null and entity.studentIdCard != ''">
<choose>
<when test="entity.studentIdCard.length() == 18">
AND dss.id_card = #{entity.studentIdCard}
</when>
<when test="entity.studentIdCard.length() == 4">
AND RIGHT(dss.id_card, 4) = #{entity.studentIdCard}
</when>
<otherwise>
AND dss.id_card LIKE CONCAT('%', #{entity.studentIdCard}, '%')
</otherwise>
</choose>
</if>
<if test="entity.studentPhone != null and entity.studentPhone != ''">
AND dsp.user_mobile LIKE CONCAT('%', #{entity.studentPhone}, '%')
</if>
<if test="entity.courseId != null and entity.courseId != ''">
AND dsp.course_id = #{entity.courseId}
</if>
<if test="entity.courseType != null and entity.courseType != ''">
AND dsp.course_type = #{entity.courseType}
</if>
<if test="entity.coachId != null">
AND dsp.coach_id = #{entity.coachId}
</if>
</select>
<select id="getOverallPassingRate" resultType="cn.iocoder.yudao.module.course.vo.ExamPassRateVO">
SELECT

View File

@ -328,6 +328,9 @@
<if test="entity.studentPhone != null and entity.studentPhone != '' ">
AND dsco.user_phone like concat('%', #{entity.studentPhone}, '%')
</if>
<if test="entity.studentName != null and entity.studentName != '' ">
AND dsco.user_name like concat('%', #{entity.studentName}, '%')
</if>
<if test="entity.coachId != null and entity.coachId != '' ">
AND dsp.coach_id = #{entity.coachId}
</if>
@ -365,11 +368,18 @@
AND dsco.is_sign = #{entity.isSign}
</if>
<if test="entity.cashierConfirm != null">
AND dsco.cashier_Confirm = #{entity.cashierConfirm}
</if>
<if test="entity.cashierConfirm == null">
AND dsco.cashier_Confirm IS NULL
<if test="entity.cashierConfirm != null and entity.cashierConfirm != '' ">
<choose>
<when test="entity.cashierConfirm == '1'">
AND dsco.cashier_confirm = 1
</when>
<when test="entity.cashierConfirm == '0'">
AND dsco.cashier_confirm = 0
</when>
<otherwise>
AND dsco.cashier_confirm IS NULL
</otherwise>
</choose>
</if>
<if test="entity.source != null and entity.source != '' ">
AND dss.source = #{entity.source}
@ -405,50 +415,76 @@
dsco.cashier_confirm_remark
</select>
<select id="getOrderStatistics" resultType="cn.iocoder.yudao.module.course.vo.CourseOrderStatisticsVO">
SELECT
COUNT(DISTINCT dsco.user_id) AS studentCount,
SUM(dsco.reserve_money) AS totalAmount,
SUM(CASE WHEN dscd.course_subject = 2 THEN COALESCE(dscd.deduct, 0) ELSE 0 END) AS subject2DeductTotal,
SUM(CASE WHEN dscd.course_subject = 3 THEN COALESCE(dscd.deduct, 0) ELSE 0 END) AS subject3DeductTotal
FROM
drive_school_course_order dsco
LEFT JOIN drive_school_process dsp ON dsp.course_id = dsco.course_id AND dsp.user_id = dsco.user_id AND dsp.subject IN (2, 3) AND dsp.deleted = 0
LEFT JOIN drive_school_course_deduct dscd ON dsco.scheme_id = dscd.scheme_id AND dsco.course_id = dscd.course_id AND dscd.course_subject IN (2, 3) AND dscd.deleted = 0
LEFT JOIN drive_school_student dss ON dsco.user_id = dss.user_id AND dss.deleted = 0
SUM(IFNULL(sub.subject2Deduct, 0)) AS subject2DeductTotal,
SUM(IFNULL(sub.subject3Deduct, 0)) AS subject3DeductTotal
FROM drive_school_course_order dsco
LEFT JOIN drive_school_student dss
ON dsco.user_id = dss.user_id AND dss.deleted = 0
-- 子查询先聚合提成,防止 JOIN 多条数据导致金额翻倍
LEFT JOIN (
SELECT
dscd.course_id,
dscd.scheme_id,
SUM(CASE WHEN dscd.course_subject = '2' THEN COALESCE(dscd.deduct, 0) ELSE 0 END) AS subject2Deduct,
SUM(CASE WHEN dscd.course_subject = '3' THEN COALESCE(dscd.deduct, 0) ELSE 0 END) AS subject3Deduct
FROM drive_school_course_deduct dscd
WHERE dscd.deleted = 0
GROUP BY dscd.course_id, dscd.scheme_id
) sub ON (
(dsco.scheme_id IS NOT NULL AND dsco.scheme_id = sub.scheme_id AND dsco.course_id = sub.course_id)
OR
(
dsco.scheme_id IS NULL AND EXISTS (
SELECT 1 FROM drive_school_course_scheme s
WHERE s.course_id = dsco.course_id AND s.is_default = 1 AND s.id = sub.scheme_id AND s.deleted = 0
)
)
)
WHERE dsco.deleted = 0
AND dsco.if_end = 0
<!-- 筛选条件部分 -->
<if test="entity.courseId != null and entity.courseId != '' ">
AND dsco.course_id = #{entity.courseId}
</if>
<if test="entity.studentPhone != null and entity.studentPhone != '' ">
AND dsco.user_phone like concat('%', #{entity.studentPhone}, '%')
AND dsco.user_phone LIKE CONCAT('%', #{entity.studentPhone}, '%')
</if>
<if test="entity.studentName != null and entity.studentName != '' ">
AND dsco.user_name LIKE CONCAT('%', #{entity.studentName}, '%')
</if>
<if test="entity.coachId != null and entity.coachId != '' ">
AND dsp.coach_id = #{entity.coachId}
AND dsco.coach_user_id = #{entity.coachId}
</if>
<if test="entity.courseType != null and entity.courseType != '' ">
AND dsco.course_type = #{entity.courseType}
</if>
<if test="entity.signUpStartTimeStr!=null and entity.signUpStartTimeStr!='' ">
<if test="entity.signUpStartTimeStr != null and entity.signUpStartTimeStr != '' ">
AND dsco.create_time &gt;= #{entity.signUpStartTimeStr}
</if>
<if test="entity.signUpEndTimeStr!=null and entity.signUpEndTimeStr!='' ">
<if test="entity.signUpEndTimeStr != null and entity.signUpEndTimeStr != '' ">
AND dsco.create_time &lt;= #{entity.signUpEndTimeStr}
</if>
<if test="entity.payFeesStartTimeStr!=null and entity.payFeesStartTimeStr!='' ">
<if test="entity.payFeesStartTimeStr != null and entity.payFeesStartTimeStr != '' ">
AND dsco.pay_fees_time &gt;= #{entity.payFeesStartTimeStr}
</if>
<if test="entity.payFeesEndTimeStr!=null and entity.payFeesEndTimeStr!='' ">
<if test="entity.payFeesEndTimeStr != null and entity.payFeesEndTimeStr != '' ">
AND dsco.pay_fees_time &lt;= #{entity.payFeesEndTimeStr}
</if>
<if test="entity.cashierConfirmStartTimeStr!=null and entity.cashierConfirmStartTimeStr!='' ">
<if test="entity.cashierConfirmStartTimeStr != null and entity.cashierConfirmStartTimeStr != '' ">
AND dsco.cashier_confirm_time &gt;= #{entity.cashierConfirmStartTimeStr}
</if>
<if test="entity.cashierConfirmEndTimeStr!=null and entity.cashierConfirmEndTimeStr!='' ">
<if test="entity.cashierConfirmEndTimeStr != null and entity.cashierConfirmEndTimeStr != '' ">
AND dsco.cashier_confirm_time &lt;= #{entity.cashierConfirmEndTimeStr}
</if>
<if test="entity.paymentStatus != null and entity.paymentStatus != '' ">
@ -457,29 +493,32 @@
<if test="entity.isSign != null">
AND dsco.is_sign = #{entity.isSign}
</if>
<if test="entity.cashierConfirm != null">
AND dsco.cashier_Confirm = #{entity.cashierConfirm}
</if>
<if test="entity.cashierConfirm == null">
AND dsco.cashier_Confirm IS NULL
<if test="entity.cashierConfirm != null and entity.cashierConfirm != '' ">
<choose>
<when test="entity.cashierConfirm == '1'">
AND dsco.cashier_confirm = 1
</when>
<when test="entity.cashierConfirm == '0'">
AND dsco.cashier_confirm = 0
</when>
<otherwise>
AND dsco.cashier_confirm IS NULL
</otherwise>
</choose>
</if>
<if test="entity.source != null and entity.source != '' ">
AND dss.source = #{entity.source}
</if>
<if test="entity.studentIdCard != null and entity.studentIdCard != '' ">
<choose>
<!-- 精确匹配当输入18位时 -->
<when test="entity.studentIdCard.length() == 18">
AND dsco.id_card = #{entity.studentIdCard}
AND dsco.user_no = #{entity.studentIdCard}
</when>
<!-- 后4位匹配当输入正好4位时 -->
<when test="entity.studentIdCard.length() == 4">
AND RIGHT(dsco.id_card, 4) = #{entity.studentIdCard}
AND RIGHT(dsco.user_no, 4) = #{entity.studentIdCard}
</when>
<!-- 模糊搜索当输入大于4位但不足18位时 -->
<otherwise>
AND dsco.id_card LIKE concat('%', #{entity.studentIdCard}, '%')
AND dsco.user_no LIKE CONCAT('%', #{entity.studentIdCard}, '%')
</otherwise>
</choose>
</if>