新增一人一档下载功能并优化考试记录查询

dev
zhangyue 2026-02-03 14:17:32 +08:00
parent aa06fcb829
commit 387b746f56
18 changed files with 348 additions and 46 deletions

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<License>
<Data>
<Products>
<Product>Aspose.Total for Java</Product>
<Product>Aspose.Words for Java</Product>
</Products>
<EditionType>Enterprise</EditionType>
<SubscriptionExpiry>20991231</SubscriptionExpiry>
<LicenseExpiry>20991231</LicenseExpiry>
<SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
</Data>
<Signature>
sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=
</Signature>
</License>

View File

@ -0,0 +1,35 @@
自评得分汇总表
{{category_list}}考评类目
标准分
实得分
扣分
空项分
[category]
[total_score]
[score]
[deduction_score]
[is_ignore_score]
合 计
{{total_score}}
{{score}}
{{deduction_score}}
{{is_ignore_score}}
评审分小计
总分
{{total_score}}
空项分
{{is_ignore_score}}
应得分
{{should_score}}
实得分
{{score}}
按百分制换算后得分
{{hundred_mark_score}}
等级
三级
自评组成员签字:
{{qry}}
年 月 日

View File

@ -4,8 +4,10 @@ import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.SingleResponse;
import com.jjb.saas.framework.auth.model.SSOUser;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.zcloud.edu.api.archives.ArchivesServiceI;
import com.zcloud.edu.api.study.ClassServiceI;
import com.zcloud.edu.api.study.StudentServiceI;
import com.zcloud.edu.dto.archives.ArchivesQry;
import com.zcloud.edu.dto.archives.ClassArchivesQry;
import com.zcloud.edu.dto.clientobject.study.ClassCO;
import com.zcloud.edu.dto.clientobject.study.StudentCO;
@ -31,6 +33,7 @@ import org.springframework.web.bind.annotation.RestController;
public class ArchivesController {
private final ClassServiceI classService;
private final StudentServiceI studentService;
private final ArchivesServiceI archivesService;
@ApiOperation("分页")
@PostMapping("/list")
@ -67,5 +70,12 @@ public class ArchivesController {
public SingleResponse<ClassArchivesDTO> getClassExamResult(@RequestBody ClassArchivesQry qry) {
return studentService.getClassExamResult(qry);
}
@ApiOperation("下载一人一档")
@PostMapping("/downloadPersonArchives")
public SingleResponse<ClassArchivesDTO> downloadPersonArchives(@RequestBody ArchivesQry qry) {
archivesService.downloadPersonArchives(qry);
return null;
}
}

View File

@ -13,6 +13,7 @@ import com.zcloud.edu.dto.archives.ArchivesReviewRecordAddCmd;
import com.zcloud.edu.dto.archives.ArchivesReviewRecordPageQry;
import com.zcloud.edu.dto.archives.ArchivesReviewRecordUpdateCmd;
import com.zcloud.edu.dto.clientobject.archives.ArchivesReviewRecordCO;
import com.zcloud.gbscommon.utils.Tools;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;

View File

@ -0,0 +1,57 @@
package com.zcloud.edu.command.query.archives;
import com.alibaba.cola.dto.PageResponse;
import com.zcloud.edu.command.convertor.archives.ArchivesPdfFileCoConvertor;
import com.zcloud.edu.dto.archives.ArchivesPdfFilePageQry;
import com.zcloud.edu.dto.clientobject.archives.ArchivesPdfFileCO;
import com.zcloud.edu.persistence.dataobject.archives.ArchivesPdfFileDO;
import com.zcloud.edu.persistence.repository.archives.ArchivesPdfFileRepository;
import com.zcloud.gbscommon.utils.PageQueryHelper;
import lombok.AllArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* web-app
*
* @Author zhangyue
* @Date 2026-02-02 10:32:42
*/
@Component
@AllArgsConstructor
public class ArchivesQueryExe {
private final ArchivesPdfFileRepository archivesPdfFileRepository;
private final ArchivesPdfFileCoConvertor archivesPdfFileCoConvertor;
/**
*
*
* @param archivesPdfFilePageQry
* @return
*/
public PageResponse<ArchivesPdfFileCO> execute(ArchivesPdfFilePageQry archivesPdfFilePageQry) {
Map<String, Object> params = PageQueryHelper.toHashMap(archivesPdfFilePageQry);
PageResponse<ArchivesPdfFileDO> pageResponse = archivesPdfFileRepository.listPage(params);
List<ArchivesPdfFileCO> examCenterCOS = archivesPdfFileCoConvertor.converDOsToCOs(pageResponse.getData());
return PageResponse.of(examCenterCOS, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
}
public void execte1(){
System.out.println(1);
}
@Async("archivesAsyncExecutor")
public void execte2(){
// 5s后执行
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(2);
}
}

View File

@ -0,0 +1,66 @@
package com.zcloud.edu.service.archives;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.SingleResponse;
import com.zcloud.edu.api.archives.ArchivesReviewServiceI;
import com.zcloud.edu.api.archives.ArchivesServiceI;
import com.zcloud.edu.command.archives.ArchivesReviewAddExe;
import com.zcloud.edu.command.archives.ArchivesReviewRemoveExe;
import com.zcloud.edu.command.archives.ArchivesReviewUpdateExe;
import com.zcloud.edu.command.query.archives.ArchivesPdfFileQueryExe;
import com.zcloud.edu.command.query.archives.ArchivesQueryExe;
import com.zcloud.edu.command.query.archives.ArchivesReviewQueryExe;
import com.zcloud.edu.dto.archives.ArchivesQry;
import com.zcloud.edu.dto.archives.ArchivesReviewAddCmd;
import com.zcloud.edu.dto.archives.ArchivesReviewPageQry;
import com.zcloud.edu.dto.archives.ArchivesReviewUpdateCmd;
import com.zcloud.edu.dto.clientobject.archives.ArchivesReviewCO;
import com.zcloud.gbscommon.utils.Tools;
import com.zcloud.gbscommon.utils.WordToPdfUtil;
import com.zcloud.gbscommon.zcloudimgfiles.facade.ZcloudImgFilesFacade;
import lombok.AllArgsConstructor;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.HashMap;
/**
* web-app
*
* @Author zhangyue
* @Date 2026-01-26 10:59:35
*/
@Service
@AllArgsConstructor
public class ArchivesServiceImpl implements ArchivesServiceI {
@DubboReference
private ZcloudImgFilesFacade zcloudImgFilesFacade;
private final ArchivesQueryExe archivesQueryExe;
@Override
public void downloadPersonArchives(ArchivesQry qry) {
// HashMap<String, Object> workItem = new HashMap<>();
// workItem.put("qry", "555");
// String templatePath = "templates/template/category_score_list.docx";
// try {
// ByteArrayOutputStream outputStream = Tools.renderTemplate(templatePath, workItem);
// byte[] pdfBytes = WordToPdfUtil.convertWordBytesToPdfBytes(outputStream.toByteArray());
// String s = zcloudImgFilesFacade.saveFile(pdfBytes, "clockSign.pdf","clockSign");
// System.out.println(s);
// archivesQueryExe.downloadPersonArchives();
archivesQueryExe.execte2();
System.out.println("下载成功");
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
}
}

View File

@ -0,0 +1,20 @@
package com.zcloud.edu.api.archives;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.SingleResponse;
import com.zcloud.edu.dto.archives.ArchivesQry;
import com.zcloud.edu.dto.archives.ArchivesReviewAddCmd;
import com.zcloud.edu.dto.archives.ArchivesReviewPageQry;
import com.zcloud.edu.dto.archives.ArchivesReviewUpdateCmd;
import com.zcloud.edu.dto.clientobject.archives.ArchivesReviewCO;
/**
* web-client
*
* @Author zhangyue
* @Date 2026-01-26 10:59:35
*/
public interface ArchivesServiceI {
void downloadPersonArchives(ArchivesQry qry);
}

View File

@ -0,0 +1,30 @@
package com.zcloud.edu.dto.archives;
import lombok.Data;
import java.util.List;
/**
* web-client
*
* @Author zhangyue
* @Date 2026-01-13 14:18:12
*/
@Data
public class ArchivesQry {
/**
* ,
* - `like`: SQLLIKE
* - `eq`: SQL=
* - `gt`:
* - `lt`:
* - `ge`:
* - `le`:
* - `ne`: SQL!=
*/
private List<Integer> typeList;
}

View File

@ -1,6 +1,7 @@
package com.zcloud.edu.dto.clientobject.study;
import com.alibaba.cola.dto.ClientObject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -71,6 +72,24 @@ public class StudentExamRecordCO extends ClientObject {
@ApiModelProperty(value = "剩余考试次数")
private Integer surplusExamNum;
//试卷名称
@ApiModelProperty(value = "试卷名称")
@TableField(exist = false)
private String examName;
//试卷总分数
@ApiModelProperty(value = "试卷总分数")
@TableField(exist = false)
private BigDecimal paperExamScore;
//合格分数
@ApiModelProperty(value = "合格分数")
@TableField(exist = false)
private BigDecimal passScore;
//考试时长(分钟)
@ApiModelProperty(value = "考试时长(分钟)")
@TableField(exist = false)
private Integer examTime;
//环境
@ApiModelProperty(value = "环境")
private String env;

View File

@ -1,6 +1,7 @@
package com.zcloud.edu.dto.clientobject.study;
import com.alibaba.cola.dto.ClientObject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -40,8 +41,12 @@ public class StudentSignCO extends ClientObject {
@ApiModelProperty(value = "打卡签字路径")
private String signUrl;
//签到类型 1-打卡签到 2-人脸签到
@ApiModelProperty(value = "签到类型 1-打卡签到 2-人脸签到")
@ApiModelProperty(value = "培训地点")
@TableField(exist = false)
private String trainingLocation;
//签到类型 1-打卡签到 2-考试签到
@ApiModelProperty(value = "签到类型 1-打卡签到 2-考试签到")
private Integer type;
//环境
@ApiModelProperty(value = "环境")

View File

@ -32,8 +32,8 @@ public class StudentSignAddCmd extends Command {
@ApiModelProperty(value = "签到类型 1-打卡签到 2-人脸签到", name = "type", required = true)
@NotNull(message = "签到类型 1-打卡签到 2-人脸签到不能为空")
@ApiModelProperty(value = "签到类型 1-打卡签到 2-考试签到", name = "type", required = true)
@NotNull(message = "签到类型 1-打卡签到 2-考试签到不能为空")
private Integer type;
@ApiModelProperty(value = "手机号", name = "phone", required = true)

View File

@ -38,7 +38,7 @@ public class StudentSignUpdateCmd extends Command {
private String faceUrl;
@ApiModelProperty(value = "签字路径", name = "signUrl", required = true)
private String signUrl;
@ApiModelProperty(value = "签到类型 1-打卡签到 2-人脸签到", name = "type", required = true)
@ApiModelProperty(value = "签到类型 1-打卡签到 2-考试签到", name = "type", required = true)
private Integer type;
}

View File

@ -42,7 +42,7 @@ public class StudentSignE extends BaseE {
private String faceUrl;
//打卡签字路径
private String signUrl;
//签到类型 1-打卡签到 2-人脸签到
//签到类型 1-打卡签到 2-考试签到
private Integer type;
private String phone;

View File

@ -0,0 +1,75 @@
package com.zcloud.edu.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author zhangyue
* @date 2026/2/2 17:24
*/
@Configuration
public class ArchivesAsyncConfig {
public static Integer maxPoolSize;
public static Integer corePoolSize;
public static Integer queueCapacity;
public static String namePrefix;
public static Integer keepAliveSeconds;
@Value("${archives.async.pool.maxPoolSize}")
public void setMaxPoolSize(Integer maxPoolSizeProperties) {
maxPoolSize = maxPoolSizeProperties;
}
@Value("${archives.async.pool.corePoolSize}")
public void setCorePoolSize(Integer corePoolSizeProperties) {
corePoolSize = corePoolSizeProperties;
}
@Value("${archives.async.pool.queueCapacity}")
public void setQueueCapacity(Integer queueCapacityProperties) {
queueCapacity = queueCapacityProperties;
}
@Value("${archives.async.pool.namePrefix}")
public void setNamePrefix(String namePrefixProperties) {
namePrefix = namePrefixProperties;
}
@Value("${archives.async.pool.keepAliveSeconds}")
public void setKeepAliveSeconds(Integer keepAliveSecondsProperties) {
keepAliveSeconds = keepAliveSecondsProperties;
}
@Bean()
public Executor archivesAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//最大线程数
executor.setMaxPoolSize(maxPoolSize);
//核心线程数
executor.setCorePoolSize(corePoolSize);
//任务队列的大小
executor.setQueueCapacity(queueCapacity);
//线程前缀名
executor.setThreadNamePrefix(namePrefix);
//线程存活时间
executor.setKeepAliveSeconds(keepAliveSeconds);
/**
*
* CallerRunsPolicy()线 main 线
* AbortPolicy()
* DiscardPolicy()
* DiscardOldestPolicy()
*/
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
// 初始化
executor.initialize();
return executor;
}
}

View File

@ -50,8 +50,8 @@ public class StudentSignDO extends BaseDO {
@ApiModelProperty(value = "打卡签字路径")
private String signUrl;
//签到类型 1-打卡签到 2-人脸签到
@ApiModelProperty(value = "签到类型 1-打卡签到 2-人脸签到")
//签到类型 1-打卡签到 2-考试签到
@ApiModelProperty(value = "签到类型 1-打卡签到 2-考试签到")
private Integer type;
@ApiModelProperty(value = "签到时间")

View File

@ -32,9 +32,9 @@ public class StudentExamRecordRepositoryImpl extends BaseRepositoryImpl<StudentE
public PageResponse<StudentExamRecordDO> listPage(Map<String, Object> params) {
IPage<StudentExamRecordDO> iPage = new Query<StudentExamRecordDO>().getPage(params);
QueryWrapper<StudentExamRecordDO> queryWrapper = new QueryWrapper<>();
queryWrapper = PageQueryHelper.createPageQueryWrapper(queryWrapper, params);
queryWrapper.orderByDesc("create_time");
IPage<StudentExamRecordDO> result = studentExamRecordMapper.selectPage(iPage, queryWrapper);
queryWrapper = PageQueryHelper.createPageQueryWrapper(queryWrapper, params, "er.");
queryWrapper.orderByDesc("er.create_time");
IPage<StudentExamRecordDO> result = studentExamRecordMapper.listPage(iPage, queryWrapper,null);
return PageHelper.pageToResponse(result, result.getRecords());
}

View File

@ -52,10 +52,15 @@
er.exam_question_wrong,
er.exam_score,
er.result,
ss.sign_url
ss.sign_url,
ep.exam_name,
ep.exam_score paper_exam_score,
ep.pass_score,
ep.exam_time
FROM
student_exam_record er
left join student_sign ss on ss.student_sign_id = er.student_sign_id
left join class_exam_paper ep on er.class_exam_paper_id = ep.class_exam_paper_id
<where>
er.delete_enum = 'FALSE'
and er.id = #{id}
@ -77,7 +82,7 @@
SELECT
er.*,
ep.exam_name,
ep.paper_exam_score,
ep.exam_score paper_exam_score,
ep.pass_score,
ep.exam_time

View File

@ -124,24 +124,22 @@
<select id="countStudentByCorpId" resultType="com.zcloud.edu.persistence.dataobject.study.StudentDO">
select
count(DISTINCT s.phone) student_count,
s.class_corpinfo_id
u.corpinfo_id,
count(DISTINCT u.username) student_count
from
student s
left join class c on c.class_id = s.class_id
<where>
s.delete_enum = 'FALSE'
and c.delete_enum = 'FALSE'
and c.state != 1
<if test="params.corpinfoIds != null and params.corpinfoIds.size > 0">
s.class_corpinfo_id in
<foreach item="item" collection="params.corpinfoIds" separator="," open="(" close=")">
#{item}
user u
left join training_user tu on tu.phone = u.username
where u.delete_enum = 'FALSE'
AND u.employment_flag = '1'
and tu.start_time &lt;= now()
and tu.end_time &gt;= now()
<if test="params.corpinfoIds != null and params.corpinfoIds.size() > 0">
AND u.corpinfo_id in
<foreach collection="params.corpinfoIds" item="corpinfoId" separator="," open="(" close=")">
#{corpinfoId}
</foreach>
</if>
</where>
group by
s.class_corpinfo_id
GROUP BY u.corpinfo_id
</select>