fix: [临时提交]

This commit is contained in:
ovo 2025-04-15 23:47:50 +08:00
parent 8a81b6bae3
commit e01fe45e8b
111 changed files with 139 additions and 6970 deletions

View File

@ -12,6 +12,8 @@ public class SecurityConstants {
* 这些路径可以直接访问不需要认证
*/
public static final List<String> WHITE_LIST = List.of(
"/exam/api/paper/**",
"/bs/**",
"/api/common/**", //公共接口
"/demo/**", // 测试接口

View File

@ -1,6 +1,7 @@
/**
* Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
*/
*//*
package com.guwan.backend.core.utils.excel;
import com.google.common.collect.Lists;
@ -24,56 +25,72 @@ import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.*;
*/
/**
* 导出Excel文件导出XLSX格式支持大数据量导出 @see org.apache.poi.ss.SpreadsheetVersion
* @author jeeplus
* @version 2016-04-21
*/
*//*
public class ExportExcel {
private static Logger log = LoggerFactory.getLogger(ExportExcel.class);
*/
/**
* 工作薄对象
*/
*//*
private SXSSFWorkbook wb;
*/
/**
* 工作表对象
*/
*//*
private Sheet sheet;
*/
/**
* 样式列表
*/
*//*
private Map<String, CellStyle> styles;
*/
/**
* 当前行号
*/
*//*
private int rownum;
*/
/**
* 注解列表Object[]{ ExcelField, Field/Method }
*/
*//*
List<Object[]> annotationList = Lists.newArrayList();
*/
/**
* 构造函数
* @param title 表格标题空值表示无标题
* @param cls 实体对象通过annotation.ExportField获取标题
*/
*//*
public ExportExcel(String title, Class<?> cls){
this(title, cls, 1);
}
*/
/**
* 构造函数
* @param title 表格标题空值表示无标题
* @param cls 实体对象通过annotation.ExportField获取标题
* @param type 导出类型1:导出数据2导出模板
* @param groups 导入分组
*/
*//*
public ExportExcel(String title, Class<?> cls, int type, int... groups){
// Get annotation field
Field[] fs = cls.getDeclaredFields();
@ -127,8 +144,10 @@ public class ExportExcel {
Collections.sort(annotationList, new Comparator<Object[]>() {
@Override
public int compare(Object[] o1, Object[] o2) {
*/
/*return new Integer(((ExcelField)o1[0]).sort()).compareTo(
new Integer(((ExcelField)o2[0]).sort()));*/
new Integer(((ExcelField)o2[0]).sort()));*//*
return Integer.compare(((ExcelField) o1[0]).sort(), ((ExcelField) o2[0]).sort());
}
});
@ -147,11 +166,13 @@ public class ExportExcel {
}
initialize(title, headerList);
}
*/
/**
* 初始化函数
* @param title 表格标题空值表示无标题
* @param headerList 表头列表
*/
*//*
private void initialize(String title, List<String> headerList) {
this.wb = new SXSSFWorkbook(500);
this.sheet = wb.createSheet("Export");
@ -194,11 +215,13 @@ public class ExportExcel {
log.debug("Initialize success.");
}
*/
/**
* 创建表格样式
* @param wb 工作薄对象
* @return 样式列表
*/
*//*
private Map<String, CellStyle> createStyles(Workbook wb) {
Map<String, CellStyle> styles = new HashMap<>(16);
@ -260,26 +283,31 @@ public class ExportExcel {
return styles;
}
*/
/**
* 添加一行
* @return 行对象
*/
*//*
public Row addRow(){
return sheet.createRow(rownum++);
}
*/
/**
* 添加一个单元格
* @param row 添加的行
* @param column 添加列号
* @param val 添加值
* @return 单元格对象
*/
*//*
public Cell addCell(Row row, int column, Object val){
return this.addCell(row, column, val, 0, Class.class);
}
*/
/**
* 添加一个单元格
* @param row 添加的行
@ -287,7 +315,8 @@ public class ExportExcel {
* @param val 添加值
* @param align 对齐方式1靠左2居中3靠右
* @return 单元格对象
*/
*//*
public Cell addCell(Row row, int column, Object val, int align, Class<?> fieldType){
Cell cell = row.createCell(column);
CellStyle style = styles.get("data"+(align>=1&&align<=3?align:""));
@ -324,10 +353,12 @@ public class ExportExcel {
return cell;
}
*/
/**
* 添加数据通过annotation.ExportField添加数据
* @return list 数据列表
*/
*//*
public <E> ExportExcel setDataList(List<E> list){
for (E e : list){
int colunm = 0;
@ -358,19 +389,23 @@ public class ExportExcel {
return this;
}
*/
/**
* 输出数据流
* @param os 输出数据流
*/
*//*
public ExportExcel write(OutputStream os) throws IOException{
wb.write(os);
return this;
}
*/
/**
* 输出到客户端
* @param fileName 输出文件名
*/
*//*
public ExportExcel write(HttpServletResponse response, String fileName) throws IOException{
response.reset();
response.setHeader("Access-Control-Allow-Origin", "*");
@ -380,12 +415,15 @@ public class ExportExcel {
return this;
}
*/
/**
* 清理临时文件
*/
*//*
public ExportExcel dispose(){
wb.dispose();
return this;
}
}
*/

View File

@ -1,10 +1,10 @@
/**
* Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
*/
*//*
package com.guwan.backend.core.utils.excel;
import com.google.common.collect.Lists;
import com.guwan.backend.core.utils.Reflections;
import com.guwan.backend.core.utils.excel.annotation.ExcelField;
import org.apache.commons.lang3.StringUtils;
@ -31,32 +31,41 @@ import java.util.Comparator;
import java.util.Date;
import java.util.List;
*/
/**
* 导入Excel文件支持XLSXLSX格式
* @author jeeplus
* @version 2016-03-10
*/
*//*
public class ImportExcel {
private static Logger log = LoggerFactory.getLogger(ImportExcel.class);
*/
/**
* 工作薄对象
*/
*//*
private Workbook wb;
*/
/**
* 工作表对象
*/
*//*
private Sheet sheet;
*/
/**
* 标题行号
*/
*//*
private int headerNum;
*/
/**
* 构造函数
* @param multipartFile 导入文件对象
@ -64,12 +73,14 @@ public class ImportExcel {
* @param sheetIndex 工作表编号
* @throws InvalidFormatException
* @throws IOException
*/
*//*
public ImportExcel(MultipartFile multipartFile, int headerNum, int sheetIndex)
throws InvalidFormatException, IOException {
this(multipartFile.getOriginalFilename(), multipartFile.getInputStream(), headerNum, sheetIndex);
}
*/
/**
* 构造函数
* @param is 导入文件对象
@ -77,7 +88,8 @@ public class ImportExcel {
* @param sheetIndex 工作表编号
* @throws InvalidFormatException
* @throws IOException
*/
*//*
public ImportExcel(String fileName, InputStream is, int headerNum, int sheetIndex)
throws IOException {
if (StringUtils.isBlank(fileName)){
@ -97,38 +109,46 @@ public class ImportExcel {
log.debug("Initialize success.");
}
*/
/**
* 获取行对象
* @param rownum
* @return
*/
*//*
public Row getRow(int rownum){
return this.sheet.getRow(rownum);
}
*/
/**
* 获取数据行号
* @return
*/
*//*
public int getDataRowNum(){
return headerNum+1;
}
*/
/**
* 获取最后一个数据行号
* @return
*/
*//*
public int getLastDataRowNum(){
return this.sheet.getLastRowNum()+headerNum;
}
*/
/**
* 获取单元格值
* @param row 获取的行
* @param column 获取单元格列号
* @return 单元格值
*/
*//*
public Object getCellValue(Row row, int column) {
Object val = "";
try {
@ -163,11 +183,13 @@ public class ImportExcel {
return val;
}
*/
/**
* 获取导入数据列表
* @param cls 导入对象类型
* @param groups 导入分组
*/
*//*
public <E> List<E> getDataList(Class<E> cls, int... groups) throws InstantiationException, IllegalAccessException{
List<Object[]> annotationList = Lists.newArrayList();
// Get annotation field
@ -303,3 +325,4 @@ public class ImportExcel {
}
}
*/

View File

@ -20,10 +20,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
//import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
@ -37,11 +34,11 @@ import java.util.Date;
*/
@Api(tags={"考试"})
@RestController
@RequestMapping("/api/common/exam/api/exam/exam")
@RequestMapping("/api/common/exam")
public class ExamController extends BaseController {
@Autowired
private ExamService baseService;
private ExamService examService;
/**
@ -50,11 +47,11 @@ public class ExamController extends BaseController {
* @return
*/
@ApiOperation(value = "考试视角")
@RequestMapping(value = "/online-paging", method = { RequestMethod.POST})
@PostMapping(value = "/online-paging")
public ApiRest<IPage<ExamOnlineRespDTO>> myPaging(@RequestBody PagingReqDTO<ExamDTO> reqDTO) {
//分页查询并转换
IPage<ExamOnlineRespDTO> page = baseService.onlinePaging(reqDTO);
IPage<ExamOnlineRespDTO> page = examService.onlinePaging(reqDTO);
return super.success(page);
}
@ -62,7 +59,7 @@ public class ExamController extends BaseController {
@ApiOperation(value = "查找详情")
@RequestMapping(value = "/detail", method = { RequestMethod.POST})
public ApiRest<ExamSaveReqDTO> find(@RequestBody BaseIdReqDTO reqDTO) {
ExamSaveReqDTO dto = baseService.findDetail(reqDTO.getId());
ExamSaveReqDTO dto = examService.findDetail(reqDTO.getId());
return super.success(dto);
}

View File

@ -31,4 +31,6 @@ public interface ExamService extends IService<Exam> {
ExamSaveReqDTO findDetail(String id);
ExamDTO findById(String id);
}

View File

@ -73,5 +73,13 @@ public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements Ex
return respDTO;
}
@Override
public ExamDTO findById(String id) {
ExamDTO respDTO = new ExamDTO();
Exam exam = this.getById(id);
BeanMapper.copy(exam, respDTO);
return respDTO;
}
}

View File

@ -1,171 +0,0 @@
package com.guwan.backend.model.paper.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.guwan.backend.core.api.ApiRest;
import com.guwan.backend.core.api.controller.BaseController;
import com.guwan.backend.core.api.dto.BaseIdReqDTO;
import com.guwan.backend.core.api.dto.BaseIdRespDTO;
import com.guwan.backend.core.api.dto.PagingReqDTO;
import com.guwan.backend.model.paper.dto.PaperDTO;
import com.guwan.backend.model.paper.dto.ext.PaperQuDetailDTO;
import com.guwan.backend.model.paper.dto.request.PaperAnswerDTO;
import com.guwan.backend.model.paper.dto.request.PaperCreateReqDTO;
import com.guwan.backend.model.paper.dto.request.PaperListReqDTO;
import com.guwan.backend.model.paper.dto.request.PaperQuQueryDTO;
import com.guwan.backend.model.paper.dto.response.ExamDetailRespDTO;
import com.guwan.backend.model.paper.dto.response.ExamResultRespDTO;
import com.guwan.backend.model.paper.dto.response.PaperListRespDTO;
import com.guwan.backend.model.paper.service.PaperService;
import com.guwan.backend.model.user.UserUtils;
import com.guwan.backend.security.CustomUserDetails;
import com.guwan.backend.util.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 试卷控制器
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 16:33
*/
@Api(tags={"试卷"})
@RestController
@RequestMapping("/exam/api/paper/paper")
public class PaperController extends BaseController {
@Autowired
private PaperService baseService;
@Autowired
private JwtUtil jwtUtil;
/**
* 分页查找
* @param reqDTO
* @return
*/
@ApiOperation(value = "分页查找")
@RequestMapping(value = "/paging", method = { RequestMethod.POST})
public ApiRest<IPage<PaperListRespDTO>> paging(@RequestBody PagingReqDTO<PaperListReqDTO> reqDTO) {
//分页查询并转换
IPage<PaperListRespDTO> page = baseService.paging(reqDTO);
return super.success(page);
}
/**
* 创建试卷
* @param reqDTO
* @return
*/
@ApiOperation(value = "创建试卷")
@RequestMapping(value = "/create-paper", method = { RequestMethod.POST})
public ApiRest<BaseIdRespDTO> save(@RequestBody PaperCreateReqDTO reqDTO) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.getPrincipal() instanceof CustomUserDetails userDetails) {
// sysLog.setUserId(userDetails.getUserId());
// sysLog.setUsername(userDetails.getUsername());
}
//复制参数
// String paperId = baseService.createPaper(UserUtils.getUserId(), reqDTO.getExamId());
String paperId = baseService.createPaper(jwtUtil.getUserIdFromToken("111") + "",
reqDTO.getExamId());
return super.success(new BaseIdRespDTO(paperId));
}
/**
* 批量删除
* @param reqDTO
* @return
*/
@ApiOperation(value = "试卷详情")
@RequestMapping(value = "/paper-detail", method = { RequestMethod.POST})
public ApiRest<ExamDetailRespDTO> paperDetail(@RequestBody BaseIdReqDTO reqDTO) {
//根据ID删除
ExamDetailRespDTO respDTO = baseService.paperDetail(reqDTO.getId());
return super.success(respDTO);
}
/**
* 批量删除
* @param reqDTO
* @return
*/
@ApiOperation(value = "试题详情")
@RequestMapping(value = "/qu-detail", method = { RequestMethod.POST})
public ApiRest<PaperQuDetailDTO> quDetail(@RequestBody PaperQuQueryDTO reqDTO) {
//根据ID删除
PaperQuDetailDTO respDTO = baseService.findQuDetail(reqDTO.getPaperId(), reqDTO.getQuId());
return super.success(respDTO);
}
/**
* 填充答案
* @param reqDTO
* @return
*/
@ApiOperation(value = "填充答案")
@RequestMapping(value = "/fill-answer", method = { RequestMethod.POST})
public ApiRest<PaperQuDetailDTO> fillAnswer(@RequestBody PaperAnswerDTO reqDTO) {
//根据ID删除
baseService.fillAnswer(reqDTO);
return super.success();
}
/**
* 交卷操作
* @param reqDTO
* @return
*/
@ApiOperation(value = "交卷操作")
@RequestMapping(value = "/hand-exam", method = { RequestMethod.POST})
public ApiRest<PaperQuDetailDTO> handleExam(@RequestBody BaseIdReqDTO reqDTO) {
//根据ID删除
baseService.handExam(reqDTO.getId());
return super.success();
}
/**
* 批量删除
* @param reqDTO
* @return
*/
@ApiOperation(value = "试卷详情")
@RequestMapping(value = "/paper-result", method = { RequestMethod.POST})
public ApiRest<ExamResultRespDTO> paperResult(@RequestBody BaseIdReqDTO reqDTO) {
//根据ID删除
ExamResultRespDTO respDTO = baseService.paperResult(reqDTO.getId());
return super.success(respDTO);
}
/**
* 检测用户有没有中断的考试
* @return
*/
@ApiOperation(value = "检测进行中的考试")
@RequestMapping(value = "/check-process", method = { RequestMethod.POST})
public ApiRest<PaperDTO> checkProcess() {
//复制参数
PaperDTO dto = baseService.checkProcess(UserUtils.getUserId());
return super.success(dto);
}
}

View File

@ -1,80 +0,0 @@
package com.guwan.backend.model.paper.dto;
import com.guwan.backend.core.annon.Dict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 试卷请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 17:31
*/
@Data
@ApiModel(value="试卷", description="试卷")
public class PaperDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "试卷ID", required=true)
private String id;
@Dict(dictTable = "sys_user", dicText = "real_name", dicCode = "id")
@ApiModelProperty(value = "用户ID", required=true)
private String userId;
@Dict(dictTable = "sys_depart", dicText = "dept_name", dicCode = "id")
@ApiModelProperty(value = "部门ID", required=true)
private String departId;
@ApiModelProperty(value = "规则ID", required=true)
private String examId;
@ApiModelProperty(value = "考试标题", required=true)
private String title;
@ApiModelProperty(value = "考试时长", required=true)
private Integer totalTime;
@ApiModelProperty(value = "用户时长", required=true)
private Integer userTime;
@ApiModelProperty(value = "试卷总分", required=true)
private Integer totalScore;
@ApiModelProperty(value = "及格分", required=true)
private Integer qualifyScore;
@ApiModelProperty(value = "客观分", required=true)
private Integer objScore;
@ApiModelProperty(value = "主观分", required=true)
private Integer subjScore;
@ApiModelProperty(value = "用户得分", required=true)
private Integer userScore;
@ApiModelProperty(value = "是否包含简答题", required=true)
private Boolean hasSaq;
@ApiModelProperty(value = "试卷状态", required=true)
private Integer state;
@ApiModelProperty(value = "创建时间", required=true)
private Date createTime;
@ApiModelProperty(value = "更新时间", required=true)
private Date updateTime;
@ApiModelProperty(value = "截止时间")
private Date limitTime;
}

View File

@ -1,48 +0,0 @@
package com.guwan.backend.model.paper.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 试卷考题备选答案请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 17:31
*/
@Data
@ApiModel(value="试卷考题备选答案", description="试卷考题备选答案")
public class PaperQuAnswerDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "自增ID", required=true)
private String id;
@ApiModelProperty(value = "试卷ID", required=true)
private String paperId;
@ApiModelProperty(value = "回答项ID", required=true)
private String answerId;
@ApiModelProperty(value = "题目ID", required=true)
private String quId;
@ApiModelProperty(value = "是否正确项", required=true)
private Boolean isRight;
@ApiModelProperty(value = "是否选中", required=true)
private Boolean checked;
@ApiModelProperty(value = "排序", required=true)
private Integer sort;
@ApiModelProperty(value = "选项标签", required=true)
private String abc;
}

View File

@ -1,54 +0,0 @@
package com.guwan.backend.model.paper.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 试卷考题请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 17:31
*/
@Data
@ApiModel(value="试卷考题", description="试卷考题")
public class PaperQuDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID", required=true)
private String id;
@ApiModelProperty(value = "试卷ID", required=true)
private String paperId;
@ApiModelProperty(value = "题目ID", required=true)
private String quId;
@ApiModelProperty(value = "题目类型", required=true)
private Integer quType;
@ApiModelProperty(value = "是否已答", required=true)
private Boolean answered;
@ApiModelProperty(value = "主观答案", required=true)
private String answer;
@ApiModelProperty(value = "问题排序", required=true)
private Integer sort;
@ApiModelProperty(value = "单题分分值", required=true)
private Integer score;
@ApiModelProperty(value = "实际得分(主观题)", required=true)
private Integer actualScore;
@ApiModelProperty(value = "是否答对", required=true)
private Boolean isRight;
}

View File

@ -1,29 +0,0 @@
package com.guwan.backend.model.paper.dto.ext;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* <p>
* 试卷考题备选答案请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 17:31
*/
@Data
@ApiModel(value="试卷考题备选答案", description="试卷考题备选答案")
public class PaperQuAnswerExtDTO extends PaperQuAnswerDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "试题图片", required=true)
private String image;
@ApiModelProperty(value = "答案内容", required=true)
private String content;
}

View File

@ -1,33 +0,0 @@
package com.guwan.backend.model.paper.dto.ext;
import com.guwan.backend.model.paper.dto.PaperQuDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* <p>
* 试卷考题请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 17:31
*/
@Data
@ApiModel(value="试卷题目详情类", description="试卷题目详情类")
public class PaperQuDetailDTO extends PaperQuDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "图片", required=true)
private String image;
@ApiModelProperty(value = "题目内容", required=true)
private String content;
@ApiModelProperty(value = "答案内容", required=true)
List<PaperQuAnswerExtDTO> answerList;
}

View File

@ -1,22 +0,0 @@
package com.guwan.backend.model.paper.dto.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* @author bool
*/
@Data
@ApiModel(value="查找试卷题目详情请求类", description="查找试卷题目详情请求类")
public class PaperAnswerDTO extends PaperQuQueryDTO {
@ApiModelProperty(value = "回答列表", required=true)
private List<String> answers;
@ApiModelProperty(value = "主观答案", required=true)
private String answer;
}

View File

@ -1,22 +0,0 @@
package com.guwan.backend.model.paper.dto.request;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.yf.exam.core.api.dto.BaseDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author bool
*/
@Data
@ApiModel(value="试卷创建请求类", description="试卷创建请求类")
public class PaperCreateReqDTO extends BaseDTO {
@JsonIgnore
private String userId;
@ApiModelProperty(value = "考试ID", required=true)
private String examId;
}

View File

@ -1,39 +0,0 @@
package com.guwan.backend.model.paper.dto.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 试卷请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 17:31
*/
@Data
@ApiModel(value="试卷", description="试卷")
public class PaperListReqDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户ID", required=true)
private String userId;
@ApiModelProperty(value = "部门ID", required=true)
private String departId;
@ApiModelProperty(value = "规则ID", required=true)
private String examId;
@ApiModelProperty(value = "用户昵称", required=true)
private String realName;
@ApiModelProperty(value = "试卷状态", required=true)
private Integer state;
}

View File

@ -1,21 +0,0 @@
package com.guwan.backend.model.paper.dto.request;
import com.yf.exam.core.api.dto.BaseDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author bool
*/
@Data
@ApiModel(value="查找试卷题目详情请求类", description="查找试卷题目详情请求类")
public class PaperQuQueryDTO extends BaseDTO {
@ApiModelProperty(value = "试卷ID", required=true)
private String paperId;
@ApiModelProperty(value = "题目ID", required=true)
private String quId;
}

View File

@ -1,39 +0,0 @@
package com.guwan.backend.model.paper.dto.response;
import com.guwan.backend.model.paper.dto.PaperDTO;
import com.guwan.backend.model.paper.dto.PaperQuDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Calendar;
import java.util.List;
@Data
@ApiModel(value="考试详情", description="考试详情")
public class ExamDetailRespDTO extends PaperDTO {
@ApiModelProperty(value = "单选题列表", required=true)
private List<PaperQuDTO> radioList;
@ApiModelProperty(value = "多选题列表", required=true)
private List<PaperQuDTO> multiList;
@ApiModelProperty(value = "判断题", required=true)
private List<PaperQuDTO> judgeList;
@ApiModelProperty(value = "剩余结束秒数", required=true)
public Long getLeftSeconds(){
// 结束时间
Calendar cl = Calendar.getInstance();
cl.setTime(this.getCreateTime());
cl.add(Calendar.MINUTE, getTotalTime());
return (cl.getTimeInMillis() - System.currentTimeMillis()) / 1000;
}
}

View File

@ -1,19 +0,0 @@
package com.guwan.backend.model.paper.dto.response;
import com.guwan.backend.model.paper.dto.PaperDTO;
import com.guwan.backend.model.paper.dto.ext.PaperQuDetailDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(value="考试结果展示响应类", description="考试结果展示响应类")
public class ExamResultRespDTO extends PaperDTO {
@ApiModelProperty(value = "问题列表", required=true)
private List<PaperQuDetailDTO> quList;
}

View File

@ -1,27 +0,0 @@
package com.guwan.backend.model.paper.dto.response;
import com.guwan.backend.model.paper.dto.PaperDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* <p>
* 试卷请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 17:31
*/
@Data
@ApiModel(value="试卷列表响应类", description="试卷列表响应类")
public class PaperListRespDTO extends PaperDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "人员", required=true)
private String realName;
}

View File

@ -1,125 +0,0 @@
package com.guwan.backend.model.paper.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import java.util.Date;
/**
* <p>
* 试卷实体类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 17:31
*/
@Data
@TableName("el_paper")
public class Paper extends Model<Paper> {
private static final long serialVersionUID = 1L;
/**
* 试卷ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 用户ID
*/
@TableField("user_id")
private String userId;
/**
* 部门ID
*/
@TableField("depart_id")
private String departId;
/**
* 规则ID
*/
@TableField("exam_id")
private String examId;
/**
* 考试标题
*/
private String title;
/**
* 考试时长
*/
@TableField("total_time")
private Integer totalTime;
/**
* 用户时长
*/
@TableField("user_time")
private Integer userTime;
/**
* 试卷总分
*/
@TableField("total_score")
private Integer totalScore;
/**
* 及格分
*/
@TableField("qualify_score")
private Integer qualifyScore;
/**
* 客观分
*/
@TableField("obj_score")
private Integer objScore;
/**
* 主观分
*/
@TableField("subj_score")
private Integer subjScore;
/**
* 用户得分
*/
@TableField("user_score")
private Integer userScore;
/**
* 是否包含简答题
*/
@TableField("has_saq")
private Boolean hasSaq;
/**
* 试卷状态
*/
private Integer state;
/**
* 创建时间
*/
@TableField("create_time")
private Date createTime;
/**
* 更新时间
*/
@TableField("update_time")
private Date updateTime;
/**
* 截止时间
*/
@TableField("limit_time")
private Date limitTime;
}

View File

@ -1,80 +0,0 @@
package com.guwan.backend.model.paper.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
/**
* <p>
* 试卷考题实体类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 17:31
*/
@Data
@TableName("el_paper_qu")
public class PaperQu extends Model<PaperQu> {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 试卷ID
*/
@TableField("paper_id")
private String paperId;
/**
* 题目ID
*/
@TableField("qu_id")
private String quId;
/**
* 题目类型
*/
@TableField("qu_type")
private Integer quType;
/**
* 是否已答
*/
private Boolean answered;
/**
* 主观答案
*/
private String answer;
/**
* 问题排序
*/
private Integer sort;
/**
* 单题分分值
*/
private Integer score;
/**
* 实际得分(主观题)
*/
@TableField("actual_score")
private Integer actualScore;
/**
* 是否答对
*/
@TableField("is_right")
private Boolean isRight;
}

View File

@ -1,68 +0,0 @@
package com.guwan.backend.model.paper.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
/**
* <p>
* 试卷考题备选答案实体类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 17:31
*/
@Data
@TableName("el_paper_qu_answer")
public class PaperQuAnswer extends Model<PaperQuAnswer> {
/**
* 自增ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 试卷ID
*/
@TableField("paper_id")
private String paperId;
/**
* 回答项ID
*/
@TableField("answer_id")
private String answerId;
/**
* 题目ID
*/
@TableField("qu_id")
private String quId;
/**
* 是否正确项
*/
@TableField("is_right")
private Boolean isRight;
/**
* 是否选中
*/
private Boolean checked;
/**
* 排序
*/
private Integer sort;
/**
* 选项标签
*/
private String abc;
}

View File

@ -1,33 +0,0 @@
package com.guwan.backend.model.paper.enums;
/**
* 考试状态
* @author bool
* @date 2019-10-30 13:11
*/
public interface ExamState {
/**
* 考试中
*/
Integer ENABLE = 0;
/**
* 待阅卷
*/
Integer DISABLED = 1;
/**
* 已完成
*/
Integer READY_START = 2;
/**
* 已结束
*/
Integer OVERDUE = 3;
}

View File

@ -1,33 +0,0 @@
package com.guwan.backend.model.paper.enums;
/**
* 试卷状态
* @author bool
* @date 2019-10-30 13:11
*/
public interface PaperState {
/**
* 考试中
*/
Integer ING = 0;
/**
* 待阅卷
*/
Integer WAIT_OPT = 1;
/**
* 已完成
*/
Integer FINISHED = 2;
/**
* 弃考
*/
Integer BREAK = 3;
}

View File

@ -1,45 +0,0 @@
package com.guwan.backend.model.paper.job;
import com.yf.exam.ability.job.service.JobService;
import com.yf.exam.modules.paper.service.PaperService;
import lombok.extern.log4j.Log4j2;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 超时自动交卷任务
* @author bool
*/
@Log4j2
@Component
public class BreakExamJob implements Job {
@Autowired
private PaperService paperService;
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobDetail detail = jobExecutionContext.getJobDetail();
String name = detail.getKey().getName();
String group = detail.getKey().getGroup();
String data = String.valueOf(detail.getJobDataMap().get(JobService.TASK_DATA));
log.info("++++++++++定时任务:处理到期的交卷");
log.info("++++++++++jobName:{}", name);
log.info("++++++++++jobGroup:{}", group);
log.info("++++++++++taskData:{}", data);
// 强制交卷
paperService.handExam(data);
}
}

View File

@ -1,40 +0,0 @@
package com.guwan.backend.model.paper.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guwan.backend.model.paper.dto.PaperDTO;
import com.guwan.backend.model.paper.dto.request.PaperListReqDTO;
import com.guwan.backend.model.paper.dto.response.PaperListRespDTO;
import com.guwan.backend.model.paper.entity.Paper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 试卷Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 16:33
*/
public interface PaperMapper extends BaseMapper<Paper> {
/**
* 查找试卷分页
* @param page
* @param query
* @return
*/
IPage<PaperListRespDTO> paging(Page page, @Param("query") PaperListReqDTO query);
/**
* 试卷列表响应类
* @param query
* @return
*/
List<PaperListRespDTO> list(@Param("query") PaperDTO query);
}

View File

@ -1,27 +0,0 @@
package com.guwan.backend.model.paper.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.guwan.backend.model.paper.dto.ext.PaperQuAnswerExtDTO;
import com.guwan.backend.model.paper.entity.PaperQuAnswer;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 试卷考题备选答案Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 16:33
*/
public interface PaperQuAnswerMapper extends BaseMapper<PaperQuAnswer> {
/**
* 查找试卷试题答案列表
* @param paperId
* @param quId
* @return
*/
List<PaperQuAnswerExtDTO> list(@Param("paperId") String paperId, @Param("quId") String quId);
}

View File

@ -1,42 +0,0 @@
package com.guwan.backend.model.paper.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.guwan.backend.model.paper.dto.ext.PaperQuDetailDTO;
import com.guwan.backend.model.paper.entity.PaperQu;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 试卷考题Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 16:33
*/
public interface PaperQuMapper extends BaseMapper<PaperQu> {
/**
* 统计客观分
* @param paperId
* @return
*/
int sumObjective(@Param("paperId") String paperId);
/**
* 统计主观分
* @param paperId
* @return
*/
int sumSubjective(@Param("paperId") String paperId);
/**
* 找出全部试题列表
* @param paperId
* @return
*/
List<PaperQuDetailDTO> listByPaper(@Param("paperId") String paperId);
}

View File

@ -1,45 +0,0 @@
package com.guwan.backend.model.paper.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.guwan.backend.core.api.dto.PagingReqDTO;
import com.guwan.backend.model.paper.dto.PaperQuAnswerDTO;
import com.guwan.backend.model.paper.dto.ext.PaperQuAnswerExtDTO;
import com.guwan.backend.model.paper.entity.PaperQuAnswer;
import java.util.List;
/**
* <p>
* 试卷考题备选答案业务类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 16:33
*/
public interface PaperQuAnswerService extends IService<PaperQuAnswer> {
/**
* 分页查询数据
* @param reqDTO
* @return
*/
IPage<PaperQuAnswerDTO> paging(PagingReqDTO<PaperQuAnswerDTO> reqDTO);
/**
* 查找试卷试题答案列表
* @param paperId
* @param quId
* @return
*/
List<PaperQuAnswerExtDTO> listForExam(String paperId, String quId);
/**
* 查找答案列表用来填充
* @param paperId
* @param quId
* @return
*/
List<PaperQuAnswer> listForFill(String paperId, String quId);
}

View File

@ -1,71 +0,0 @@
package com.guwan.backend.model.paper.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.guwan.backend.core.api.dto.PagingReqDTO;
import com.guwan.backend.model.paper.dto.PaperQuDTO;
import com.guwan.backend.model.paper.dto.ext.PaperQuDetailDTO;
import com.guwan.backend.model.paper.entity.PaperQu;
import java.util.List;
/**
* <p>
* 试卷考题业务类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 16:33
*/
public interface PaperQuService extends IService<PaperQu> {
/**
* 分页查询数据
* @param reqDTO
* @return
*/
IPage<PaperQuDTO> paging(PagingReqDTO<PaperQuDTO> reqDTO);
/**
* 根据试卷找出题目列表
* @param paperId
* @return
*/
List<PaperQuDTO> listByPaper(String paperId);
/**
* 查找详情
* @param paperId
* @param quId
* @return
*/
PaperQu findByKey(String paperId, String quId);
/**
* 根据组合索引更新
* @param qu
*/
void updateByKey(PaperQu qu);
/**
* 统计客观分
* @param paperId
* @return
*/
int sumObjective(String paperId);
/**
* 统计主观分
* @param paperId
* @return
*/
int sumSubjective(String paperId);
/**
* 找出全部试题列表
* @param paperId
* @return
*/
List<PaperQuDetailDTO> listForPaperResult(String paperId);
}

View File

@ -1,84 +0,0 @@
package com.guwan.backend.model.paper.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.guwan.backend.core.api.dto.PagingReqDTO;
import com.guwan.backend.model.paper.dto.PaperDTO;
import com.guwan.backend.model.paper.dto.ext.PaperQuDetailDTO;
import com.guwan.backend.model.paper.dto.request.PaperAnswerDTO;
import com.guwan.backend.model.paper.dto.request.PaperListReqDTO;
import com.guwan.backend.model.paper.dto.response.ExamDetailRespDTO;
import com.guwan.backend.model.paper.dto.response.ExamResultRespDTO;
import com.guwan.backend.model.paper.dto.response.PaperListRespDTO;
import com.guwan.backend.model.paper.entity.Paper;
/**
* <p>
* 试卷业务类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 16:33
*/
public interface PaperService extends IService<Paper> {
/**
* 创建试卷
* @param userId
* @param examId
* @return
*/
String createPaper(String userId, String examId);
/**
* 查找详情
* @param paperId
* @return
*/
ExamDetailRespDTO paperDetail(String paperId);
/**
* 考试结果
* @param paperId
* @return
*/
ExamResultRespDTO paperResult(String paperId);
/**
* 查找题目详情
* @param paperId
* @param quId
* @return
*/
PaperQuDetailDTO findQuDetail(String paperId, String quId);
/**
* 填充答案
* @param reqDTO
*/
void fillAnswer(PaperAnswerDTO reqDTO);
/**
* 交卷操作
* @param paperId
* @return
*/
void handExam(String paperId);
/**
* 试卷列表响应类
* @param reqDTO
* @return
*/
IPage<PaperListRespDTO> paging(PagingReqDTO<PaperListReqDTO> reqDTO);
/**
* 检测是否有进行中的考试
* @param userId
* @return
*/
PaperDTO checkProcess(String userId);
}

View File

@ -1,62 +0,0 @@
package com.guwan.backend.model.paper.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guwan.backend.core.api.dto.PagingReqDTO;
import com.guwan.backend.model.paper.dto.PaperQuAnswerDTO;
import com.guwan.backend.model.paper.dto.ext.PaperQuAnswerExtDTO;
import com.guwan.backend.model.paper.entity.PaperQuAnswer;
import com.guwan.backend.model.paper.mapper.PaperQuAnswerMapper;
import com.guwan.backend.model.paper.service.PaperQuAnswerService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
* 语言设置 服务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 16:33
*/
@Service
public class PaperQuAnswerServiceImpl extends ServiceImpl<PaperQuAnswerMapper, PaperQuAnswer> implements PaperQuAnswerService {
@Override
public IPage<PaperQuAnswerDTO> paging(PagingReqDTO<PaperQuAnswerDTO> reqDTO) {
//创建分页对象
IPage<PaperQuAnswer> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
//查询条件
QueryWrapper<PaperQuAnswer> wrapper = new QueryWrapper<>();
//获得数据
IPage<PaperQuAnswer> page = this.page(query, wrapper);
//转换结果
IPage<PaperQuAnswerDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<PaperQuAnswerDTO>>(){});
return pageData;
}
@Override
public List<PaperQuAnswerExtDTO> listForExam(String paperId, String quId) {
return baseMapper.list(paperId, quId);
}
@Override
public List<PaperQuAnswer> listForFill(String paperId, String quId) {
//查询条件
QueryWrapper<PaperQuAnswer> wrapper = new QueryWrapper<>();
wrapper.lambda()
.eq(PaperQuAnswer::getPaperId, paperId)
.eq(PaperQuAnswer::getQuId, quId);
return this.list(wrapper);
}
}

View File

@ -1,95 +0,0 @@
package com.guwan.backend.model.paper.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guwan.backend.core.api.dto.PagingReqDTO;
import com.guwan.backend.core.BeanMapper;
import com.guwan.backend.model.paper.dto.PaperQuDTO;
import com.guwan.backend.model.paper.dto.ext.PaperQuDetailDTO;
import com.guwan.backend.model.paper.entity.PaperQu;
import com.guwan.backend.model.paper.mapper.PaperQuMapper;
import com.guwan.backend.model.paper.service.PaperQuService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
* 语言设置 服务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 16:33
*/
@Service
public class PaperQuServiceImpl extends ServiceImpl<PaperQuMapper, PaperQu> implements PaperQuService {
@Override
public IPage<PaperQuDTO> paging(PagingReqDTO<PaperQuDTO> reqDTO) {
//创建分页对象
IPage<PaperQu> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
//查询条件
QueryWrapper<PaperQu> wrapper = new QueryWrapper<>();
//获得数据
IPage<PaperQu> page = this.page(query, wrapper);
//转换结果
IPage<PaperQuDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<PaperQuDTO>>(){});
return pageData;
}
@Override
public List<PaperQuDTO> listByPaper(String paperId) {
//查询条件
QueryWrapper<PaperQu> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(PaperQu::getPaperId, paperId)
.orderByAsc(PaperQu::getSort);
List<PaperQu> list = this.list(wrapper);
return BeanMapper.mapList(list, PaperQuDTO.class);
}
@Override
public PaperQu findByKey(String paperId, String quId) {
//查询条件
QueryWrapper<PaperQu> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(PaperQu::getPaperId, paperId)
.eq(PaperQu::getQuId, quId);
return this.getOne(wrapper, false);
}
@Override
public void updateByKey(PaperQu qu) {
//查询条件
QueryWrapper<PaperQu> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(PaperQu::getPaperId, qu.getPaperId())
.eq(PaperQu::getQuId, qu.getQuId());
this.update(qu, wrapper);
}
@Override
public int sumObjective(String paperId) {
return baseMapper.sumObjective(paperId);
}
@Override
public int sumSubjective(String paperId) {
return baseMapper.sumSubjective(paperId);
}
@Override
public List<PaperQuDetailDTO> listForPaperResult(String paperId) {
return baseMapper.listByPaper(paperId);
}
}

View File

@ -1,537 +0,0 @@
package com.guwan.backend.model.paper.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.guwan.backend.core.api.ApiError;
import com.guwan.backend.core.api.dto.PagingReqDTO;
import com.guwan.backend.core.exception.ServiceException;
import com.guwan.backend.core.BeanMapper;
import com.guwan.backend.core.utils.CronUtils;
import com.guwan.backend.model.exam.dto.ExamDTO;
import com.guwan.backend.model.exam.dto.ExamRepoDTO;
import com.guwan.backend.model.exam.dto.ext.ExamRepoExtDTO;
import com.guwan.backend.model.exam.service.ExamService;
import com.guwan.backend.model.paper.dto.PaperDTO;
import com.guwan.backend.model.paper.dto.PaperQuDTO;
import com.guwan.backend.model.paper.dto.ext.PaperQuAnswerExtDTO;
import com.guwan.backend.model.paper.dto.ext.PaperQuDetailDTO;
import com.guwan.backend.model.paper.dto.request.PaperAnswerDTO;
import com.guwan.backend.model.paper.dto.request.PaperListReqDTO;
import com.guwan.backend.model.paper.dto.response.ExamDetailRespDTO;
import com.guwan.backend.model.paper.dto.response.ExamResultRespDTO;
import com.guwan.backend.model.paper.dto.response.PaperListRespDTO;
import com.guwan.backend.model.paper.entity.Paper;
import com.guwan.backend.model.paper.entity.PaperQu;
import com.guwan.backend.model.paper.entity.PaperQuAnswer;
import com.guwan.backend.model.paper.enums.ExamState;
import com.guwan.backend.model.paper.enums.PaperState;
import com.guwan.backend.model.paper.job.BreakExamJob;
import com.guwan.backend.model.paper.mapper.PaperMapper;
import com.guwan.backend.model.paper.service.PaperQuAnswerService;
import com.guwan.backend.model.paper.service.PaperQuService;
import com.guwan.backend.model.paper.service.PaperService;
import com.guwan.backend.model.qu.entity.Qu;
import com.guwan.backend.model.qu.entity.QuAnswer;
import com.guwan.backend.model.qu.enums.QuType;
import com.guwan.backend.model.qu.service.QuAnswerService;
import com.guwan.backend.model.qu.service.QuService;
import com.guwan.backend.model.user.book.service.UserBookService;
import com.guwan.backend.model.user.exam.service.UserExamService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.*;
/**
* <p>
* 语言设置 服务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 16:33
*/
@Service
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements PaperService {
@Autowired
private SysUserService sysUserService;
@Autowired
private ExamService examService;
@Autowired
private QuService quService;
@Autowired
private QuAnswerService quAnswerService;
@Autowired
private PaperService paperService;
@Autowired
private PaperQuService paperQuService;
@Autowired
private PaperQuAnswerService paperQuAnswerService;
@Autowired
private UserBookService userBookService;
@Autowired
private ExamRepoService examRepoService;
@Autowired
private UserExamService userExamService;
@Autowired
private JobService jobService;
/**
* 展示的选项ABC这样
*/
private static List<String> ABC = Arrays.asList(new String[]{
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K","L","M","N","O","P","Q","R","S","T","U","V","W","X"
,"Y","Z"
});
@Transactional(rollbackFor = Exception.class)
@Override
public String createPaper(String userId, String examId) {
// 校验是否有正在考试的试卷
QueryWrapper<Paper> wrapper = new QueryWrapper<>();
wrapper.lambda()
.eq(Paper::getUserId, userId)
.eq(Paper::getState, PaperState.ING);
int exists = this.count(wrapper);
if (exists > 0) {
throw new ServiceException(ApiError.ERROR_20010002);
}
// 查找考试
ExamDTO exam = examService.findById(examId);
if(exam == null){
throw new ServiceException(1, "考试不存在!");
}
if(!ExamState.ENABLE.equals(exam.getState())){
throw new ServiceException(1, "考试状态不正确!");
}
// 考试题目列表
List<PaperQu> quList = this.generateByRepo(examId);
if(CollectionUtils.isEmpty(quList)){
throw new ServiceException(1, "规则不正确,无对应的考题!");
}
//保存试卷内容
Paper paper = this.savePaper(userId, exam, quList);
// 强制交卷任务
String jobName = JobPrefix.BREAK_EXAM + paper.getId();
jobService.addCronJob(BreakExamJob.class, jobName, CronUtils.dateToCron(paper.getLimitTime()), paper.getId());
return paper.getId();
}
@Override
public ExamDetailRespDTO paperDetail(String paperId) {
ExamDetailRespDTO respDTO = new ExamDetailRespDTO();
// 试题基本信息
Paper paper = paperService.getById(paperId);
BeanMapper.copy(paper, respDTO);
// 查找题目列表
List<PaperQuDTO> list = paperQuService.listByPaper(paperId);
List<PaperQuDTO> radioList = new ArrayList<>();
List<PaperQuDTO> multiList = new ArrayList<>();
List<PaperQuDTO> judgeList = new ArrayList<>();
for(PaperQuDTO item: list){
if(QuType.RADIO.equals(item.getQuType())){
radioList.add(item);
}
if(QuType.MULTI.equals(item.getQuType())){
multiList.add(item);
}
if(QuType.JUDGE.equals(item.getQuType())){
judgeList.add(item);
}
}
respDTO.setRadioList(radioList);
respDTO.setMultiList(multiList);
respDTO.setJudgeList(judgeList);
return respDTO;
}
@Override
public ExamResultRespDTO paperResult(String paperId) {
ExamResultRespDTO respDTO = new ExamResultRespDTO();
// 试题基本信息
Paper paper = paperService.getById(paperId);
BeanMapper.copy(paper, respDTO);
List<PaperQuDetailDTO> quList = paperQuService.listForPaperResult(paperId);
respDTO.setQuList(quList);
return respDTO;
}
@Override
public PaperQuDetailDTO findQuDetail(String paperId, String quId) {
PaperQuDetailDTO respDTO = new PaperQuDetailDTO();
// 问题
Qu qu = quService.getById(quId);
// 基本信息
PaperQu paperQu = paperQuService.findByKey(paperId, quId);
BeanMapper.copy(paperQu, respDTO);
respDTO.setContent(qu.getContent());
respDTO.setImage(qu.getImage());
// 答案列表
List<PaperQuAnswerExtDTO> list = paperQuAnswerService.listForExam(paperId, quId);
respDTO.setAnswerList(list);
return respDTO;
}
/**
* 题库组题方式产生题目列表
* @param examId
* @return
*/
private List<PaperQu> generateByRepo(String examId){
// 查找规则指定的题库
List<ExamRepoExtDTO> list = examRepoService.listByExam(examId);
//最终的题目列表
List<PaperQu> quList = new ArrayList<>();
//排除ID避免题目重复
List<String> excludes = new ArrayList<>();
excludes.add("none");
if (!CollectionUtils.isEmpty(list)) {
for (ExamRepoExtDTO item : list) {
// 单选题
if(item.getRadioCount() > 0){
List<Qu> radioList = quService.listByRandom(item.getRepoId(), QuType.RADIO, excludes, item.getRadioCount());
for (Qu qu : radioList) {
PaperQu paperQu = this.processPaperQu(item, qu);
quList.add(paperQu);
excludes.add(qu.getId());
}
}
//多选题
if(item.getMultiCount() > 0) {
List<Qu> multiList = quService.listByRandom(item.getRepoId(), QuType.MULTI, excludes,
item.getMultiCount());
for (Qu qu : multiList) {
PaperQu paperQu = this.processPaperQu(item, qu);
quList.add(paperQu);
excludes.add(qu.getId());
}
}
// 判断题
if(item.getJudgeCount() > 0) {
List<Qu> judgeList = quService.listByRandom(item.getRepoId(), QuType.JUDGE, excludes,
item.getJudgeCount());
for (Qu qu : judgeList) {
PaperQu paperQu = this.processPaperQu(item, qu);
quList.add(paperQu);
excludes.add(qu.getId());
}
}
}
}
return quList;
}
/**
* 填充试题题目信息
* @param repo
* @param qu
* @return
*/
private PaperQu processPaperQu(ExamRepoDTO repo, Qu qu) {
//保存试题信息
PaperQu paperQu = new PaperQu();
paperQu.setQuId(qu.getId());
paperQu.setAnswered(false);
paperQu.setIsRight(false);
paperQu.setQuType(qu.getQuType());
if (QuType.RADIO.equals(qu.getQuType())) {
paperQu.setScore(repo.getRadioScore());
paperQu.setActualScore(repo.getRadioScore());
}
if (QuType.MULTI.equals(qu.getQuType())) {
paperQu.setScore(repo.getMultiScore());
paperQu.setActualScore(repo.getMultiScore());
}
if (QuType.JUDGE.equals(qu.getQuType())) {
paperQu.setScore(repo.getJudgeScore());
paperQu.setActualScore(repo.getJudgeScore());
}
return paperQu;
}
/**
* 保存试卷
* @param userId
* @param exam
* @param quList
* @return
*/
private Paper savePaper(String userId, ExamDTO exam, List<PaperQu> quList) {
// 查找用户
SysUser user = sysUserService.getById(userId);
//保存试卷基本信息
Paper paper = new Paper();
paper.setDepartId(user.getDepartId());
paper.setExamId(exam.getId());
paper.setTitle(exam.getTitle());
paper.setTotalScore(exam.getTotalScore());
paper.setTotalTime(exam.getTotalTime());
paper.setUserScore(0);
paper.setUserId(userId);
paper.setCreateTime(new Date());
paper.setUpdateTime(new Date());
paper.setQualifyScore(exam.getQualifyScore());
paper.setState(PaperState.ING);
paper.setHasSaq(false);
// 截止时间
Calendar cl = Calendar.getInstance();
cl.setTimeInMillis(System.currentTimeMillis());
cl.add(Calendar.MINUTE, exam.getTotalTime());
paper.setLimitTime(cl.getTime());
paperService.save(paper);
if (!CollectionUtils.isEmpty(quList)) {
this.savePaperQu(paper.getId(), quList);
}
return paper;
}
/**
* 保存试卷试题列表
* @param paperId
* @param quList
*/
private void savePaperQu(String paperId, List<PaperQu> quList){
List<PaperQu> batchQuList = new ArrayList<>();
List<PaperQuAnswer> batchAnswerList = new ArrayList<>();
int sort = 0;
for (PaperQu item : quList) {
item.setPaperId(paperId);
item.setSort(sort);
item.setId(IdWorker.getIdStr());
//回答列表
List<QuAnswer> answerList = quAnswerService.listAnswerByRandom(item.getQuId());
if (!CollectionUtils.isEmpty(answerList)) {
int ii = 0;
for (QuAnswer answer : answerList) {
PaperQuAnswer paperQuAnswer = new PaperQuAnswer();
paperQuAnswer.setId(UUID.randomUUID().toString());
paperQuAnswer.setPaperId(paperId);
paperQuAnswer.setQuId(answer.getQuId());
paperQuAnswer.setAnswerId(answer.getId());
paperQuAnswer.setChecked(false);
paperQuAnswer.setSort(ii);
paperQuAnswer.setAbc(ABC.get(ii));
paperQuAnswer.setIsRight(answer.getIsRight());
ii++;
batchAnswerList.add(paperQuAnswer);
}
}
batchQuList.add(item);
sort++;
}
//添加问题
paperQuService.saveBatch(batchQuList);
//批量添加问题答案
paperQuAnswerService.saveBatch(batchAnswerList);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void fillAnswer(PaperAnswerDTO reqDTO) {
// 未作答
if(CollectionUtils.isEmpty(reqDTO.getAnswers())
&& StringUtils.isBlank(reqDTO.getAnswer())){
return;
}
//查找答案列表
List<PaperQuAnswer> list = paperQuAnswerService.listForFill(reqDTO.getPaperId(), reqDTO.getQuId());
//是否正确
boolean right = true;
//更新正确答案
for (PaperQuAnswer item : list) {
if (reqDTO.getAnswers().contains(item.getId())) {
item.setChecked(true);
} else {
item.setChecked(false);
}
//有一个对不上就是错的
if (item.getIsRight()!=null && !item.getIsRight().equals(item.getChecked())) {
right = false;
}
paperQuAnswerService.updateById(item);
}
//修改为已回答
PaperQu qu = new PaperQu();
qu.setQuId(reqDTO.getQuId());
qu.setPaperId(reqDTO.getPaperId());
qu.setIsRight(right);
qu.setAnswer(reqDTO.getAnswer());
qu.setAnswered(true);
paperQuService.updateByKey(qu);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void handExam(String paperId) {
//获取试卷信息
Paper paper = paperService.getById(paperId);
//如果不是正常的抛出异常
if(!PaperState.ING.equals(paper.getState())){
throw new ServiceException(1, "试卷状态不正确!");
}
// 客观分
int objScore = paperQuService.sumObjective(paperId);
paper.setObjScore(objScore);
paper.setUserScore(objScore);
// 主观分因为要阅卷所以给0
paper.setSubjScore(0);
// 待阅卷
if(paper.getHasSaq()) {
paper.setState(PaperState.WAIT_OPT);
}else {
// 同步保存考试成绩
userExamService.joinResult(paper.getUserId(), paper.getExamId(), objScore, objScore>=paper.getQualifyScore());
paper.setState(PaperState.FINISHED);
}
paper.setUpdateTime(new Date());
//计算考试时长
Calendar cl = Calendar.getInstance();
cl.setTimeInMillis(System.currentTimeMillis());
int userTime = (int)((System.currentTimeMillis() - paper.getCreateTime().getTime()) / 1000 / 60);
if(userTime == 0){
userTime = 1;
}
paper.setUserTime(userTime);
//更新试卷
paperService.updateById(paper);
// 终止定时任务
String name = JobPrefix.BREAK_EXAM + paperId;
jobService.deleteJob(name, JobGroup.SYSTEM);
//把打错的问题加入错题本
List<PaperQuDTO> list = paperQuService.listByPaper(paperId);
for(PaperQuDTO qu: list){
// 主观题和对的都不加入错题库
if(qu.getIsRight()){
continue;
}
//加入错题本
new Thread(() -> userBookService.addBook(paper.getExamId(), qu.getQuId())).run();
}
}
@Override
public IPage<PaperListRespDTO> paging(PagingReqDTO<PaperListReqDTO> reqDTO) {
return baseMapper.paging(reqDTO.toPage(), reqDTO.getParams());
}
@Override
public PaperDTO checkProcess(String userId) {
QueryWrapper<Paper> wrapper = new QueryWrapper<>();
wrapper.lambda()
.eq(Paper::getUserId, userId)
.eq(Paper::getState, PaperState.ING);
Paper paper = this.getOne(wrapper, false);
if (paper != null) {
return BeanMapper.map(paper, PaperDTO.class);
}
return null;
}
}

View File

@ -1,316 +0,0 @@
package com.guwan.backend.model.qu.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.yf.exam.core.api.ApiRest;
import com.yf.exam.core.api.controller.BaseController;
import com.yf.exam.core.api.dto.BaseIdReqDTO;
import com.yf.exam.core.api.dto.BaseIdRespDTO;
import com.yf.exam.core.api.dto.BaseIdsReqDTO;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.core.exception.ServiceException;
import com.yf.exam.core.utils.excel.ExportExcel;
import com.yf.exam.core.utils.excel.ImportExcel;
import com.yf.exam.modules.qu.dto.QuDTO;
import com.yf.exam.modules.qu.dto.export.QuExportDTO;
import com.yf.exam.modules.qu.dto.ext.QuDetailDTO;
import com.yf.exam.modules.qu.dto.request.QuQueryReqDTO;
import com.yf.exam.modules.qu.service.QuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
/**
* <p>
* 问题题目控制器
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:25
*/
@Api(tags={"问题题目"})
@RestController
@RequestMapping("/exam/api/qu/qu")
public class QuController extends BaseController {
@Autowired
private QuService baseService;
/**
* 添加或修改
*
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "添加或修改")
@RequestMapping(value = "/save", method = {RequestMethod.POST})
public ApiRest<BaseIdRespDTO> save(@RequestBody QuDetailDTO reqDTO) {
baseService.save(reqDTO);
return super.success();
}
/**
* 批量删除
*
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "批量删除")
@RequestMapping(value = "/delete", method = {RequestMethod.POST})
public ApiRest edit(@RequestBody BaseIdsReqDTO reqDTO) {
//根据ID删除
baseService.delete(reqDTO.getIds());
return super.success();
}
/**
* 查找详情
*
* @param reqDTO
* @return
*/
@ApiOperation(value = "查找详情")
@RequestMapping(value = "/detail", method = {RequestMethod.POST})
public ApiRest<QuDetailDTO> detail(@RequestBody BaseIdReqDTO reqDTO) {
QuDetailDTO dto = baseService.detail(reqDTO.getId());
return super.success(dto);
}
/**
* 分页查找
*
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "分页查找")
@RequestMapping(value = "/paging", method = {RequestMethod.POST})
public ApiRest<IPage<QuDTO>> paging(@RequestBody PagingReqDTO<QuQueryReqDTO> reqDTO) {
//分页查询并转换
IPage<QuDTO> page = baseService.paging(reqDTO);
return super.success(page);
}
/**
* 导出excel文件
*/
@RequiresRoles("sa")
@ResponseBody
@RequestMapping(value = "/export")
public ApiRest exportFile(HttpServletResponse response, @RequestBody QuQueryReqDTO reqDTO) {
// 导出文件名
String fileName = "导出的试题-" + System.currentTimeMillis() + ".xlsx";
try {
int no = 0;
String quId = "";
List<QuExportDTO> list = baseService.listForExport(reqDTO);
for (QuExportDTO item : list) {
if (!quId.equals(item.getQId())) {
quId = item.getQId();
no += 1;
} else {
item.setQuType("0");
item.setQContent("");
item.setQAnalysis("");
item.setRepoList(null);
item.setQImage("");
item.setQVideo("");
}
item.setNo(String.valueOf(no));
}
new ExportExcel("试题", QuExportDTO.class).setDataList(list).write(response, fileName).dispose();
return super.success();
} catch (Exception e) {
return failure(e.getMessage());
}
}
/**
* 导入Excel
*
* @param file
* @return
*/
@RequiresRoles("sa")
@ResponseBody
@RequestMapping(value = "/import")
public ApiRest importFile(@RequestParam("file") MultipartFile file) {
try {
ImportExcel ei = new ImportExcel(file, 1, 0);
List<QuExportDTO> list = ei.getDataList(QuExportDTO.class);
// 校验数据
this.checkExcel(list);
// 导入数据条数
baseService.importExcel(list);
// 导入成功
return super.success();
} catch (IOException e) {
} catch (InvalidFormatException e) {
} catch (IllegalAccessException e) {
} catch (InstantiationException e) {
}
return super.failure();
}
/**
* 校验Excel
*
* @param list
* @throws Exception
*/
private void checkExcel(List<QuExportDTO> list) throws ServiceException {
// 约定第三行开始导入
int line = 3;
StringBuffer sb = new StringBuffer();
if (CollectionUtils.isEmpty(list)) {
throw new ServiceException(1, "您导入的数据似乎是一个空表格!");
}
Integer quNo = null;
for (QuExportDTO item : list) {
System.out.println(item.getNo());
if (StringUtils.isBlank(item.getNo())) {
line++;
continue;
}
System.out.println(item.getQContent());
Integer no;
try {
no = Integer.parseInt(item.getNo());
} catch (Exception e) {
line++;
continue;
}
if (no == null) {
sb.append("" + line + "行,题目序号不能为空!<br>");
}
if (quNo == null || !quNo.equals(no)) {
if (item.getQuType() == null) {
sb.append("" + line + "行,题目类型不能为空<br>");
}
if (StringUtils.isBlank(item.getQContent())) {
sb.append("" + line + "行,题目内容不能为空<br>");
}
if (CollectionUtils.isEmpty(item.getRepoList())) {
sb.append("" + line + "行,题目必须包含一个题库<br>");
}
}
if (StringUtils.isBlank(item.getAIsRight())) {
sb.append("" + line + "行,选项是否正确不能为空<br>");
}
if (StringUtils.isBlank(item.getAContent()) && StringUtils.isBlank(item.getAImage())) {
sb.append("" + line + "行,选项内容和选项图片必须有一个不为空<br>");
}
quNo = no;
line++;
}
// 存在错误
if (!"".equals(sb.toString())) {
throw new ServiceException(1, sb.toString());
}
}
/**
* 下载导入试题数据模板
*/
@ResponseBody
@RequestMapping(value = "import/template")
public ApiRest importFileTemplate(HttpServletResponse response) {
try {
String fileName = "试题导入模板.xlsx";
List<QuExportDTO> list = Lists.newArrayList();
QuExportDTO l1 = new QuExportDTO();
l1.setNo("正式导入,请删除此说明行:数字,相同的数字表示同一题的序列");
l1.setQContent("问题内容");
l1.setQAnalysis("整个问题的解析");
l1.setQuType("只能填写1、2、3、41表示单选题2表示多选题3表示判断题4表示主观题");
l1.setQImage("题目图片完整URL多个用逗号隔开限制10个");
l1.setQVideo("题目视频完整URL只限一个");
l1.setAImage("答案图片完整URL只限一个");
l1.setRepoList(Arrays.asList(new String[]{"已存在题库的ID多个用逗号隔开题库ID错误无法导入"}));
l1.setAContent("候选答案1");
l1.setAIsRight("只能填写0或10表示否1表示是");
l1.setAAnalysis("这个项是正确的");
QuExportDTO l2 = new QuExportDTO();
l2.setQContent("找出以下可以被2整除的数多选");
l2.setQAnalysis("最基本的数学题,不做过多解析");
l2.setQuType("2");
l2.setNo("1");
l2.setAIsRight("1");
l2.setAContent("数字2");
l2.setAAnalysis("2除以2=1对的");
QuExportDTO l3 = new QuExportDTO();
l3.setNo("1");
l3.setAIsRight("0");
l3.setAContent("数字3");
l3.setAAnalysis("3除以2=1.5,不能被整除");
QuExportDTO l4 = new QuExportDTO();
l4.setNo("1");
l4.setAIsRight("1");
l4.setAContent("数字6");
l4.setAAnalysis("6除以2=3对的");
list.add(l1);
list.add(l2);
list.add(l3);
list.add(l4);
new ExportExcel("试题数据", QuExportDTO.class, 1).setDataList(list).write(response, fileName).dispose();
return super.success();
} catch (Exception e) {
return super.failure("导入模板下载失败!失败信息:"+e.getMessage());
}
}
}

View File

@ -1,42 +0,0 @@
package com.guwan.backend.model.qu.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 候选答案请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
@Data
@ApiModel(value="候选答案", description="候选答案")
public class QuAnswerDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "答案ID", required=true)
private String id;
@ApiModelProperty(value = "问题ID", required=true)
private String quId;
@ApiModelProperty(value = "是否正确", required=true)
private Boolean isRight;
@ApiModelProperty(value = "选项图片", required=true)
private String image;
@ApiModelProperty(value = "答案内容", required=true)
private String content;
@ApiModelProperty(value = "答案分析", required=true)
private String analysis;
}

View File

@ -1,53 +0,0 @@
package com.guwan.backend.model.qu.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 问题题目请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
@Data
@ApiModel(value="问题题目", description="问题题目")
public class QuDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "题目ID", required=true)
private String id;
@ApiModelProperty(value = "题目类型", required=true)
private Integer quType;
@ApiModelProperty(value = "1普通,2较难", required=true)
private Integer level;
@ApiModelProperty(value = "题目图片", required=true)
private String image;
@ApiModelProperty(value = "题目内容", required=true)
private String content;
@ApiModelProperty(value = "创建时间", required=true)
private Date createTime;
@ApiModelProperty(value = "更新时间", required=true)
private Date updateTime;
@ApiModelProperty(value = "题目备注", required=true)
private String remark;
@ApiModelProperty(value = "整题解析", required=true)
private String analysis;
}

View File

@ -1,38 +0,0 @@
package com.guwan.backend.model.qu.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 试题题库请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
@Data
@ApiModel(value="试题题库", description="试题题库")
public class QuRepoDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
@ApiModelProperty(value = "试题", required=true)
private String quId;
@ApiModelProperty(value = "归属题库", required=true)
private String repoId;
@ApiModelProperty(value = "题目类型", required=true)
private Integer quType;
@ApiModelProperty(value = "排序", required=true)
private Integer sort;
}

View File

@ -1,45 +0,0 @@
package com.guwan.backend.model.qu.dto.export;
import com.yf.exam.core.utils.excel.annotation.ExcelField;
import com.yf.exam.core.utils.excel.fieldtype.ListType;
import lombok.Data;
import java.util.List;
/**
* 用于导出的数据结构
* @author bool
*/
@Data
public class QuExportDTO {
private static final long serialVersionUID = 1L;
/**
*
*/
private String qId;
@ExcelField(title="题目序号", align=2, sort=1)
private String no;
@ExcelField(title="题目类型", align=2, sort=2)
private String quType;
@ExcelField(title="题目内容", align=2, sort=3)
private String qContent;
@ExcelField(title="整体解析", align=2, sort=4)
private String qAnalysis;
@ExcelField(title="题目图片", align=2, sort=5)
private String qImage;
@ExcelField(title="题目视频", align=2, sort=6)
private String qVideo;
@ExcelField(title="所属题库", align=2, sort=7, fieldType = ListType.class)
private List<String> repoList;
@ExcelField(title="是否正确项", align=2, sort=8)
private String aIsRight;
@ExcelField(title="选项内容", align=2, sort=9)
private String aContent;
@ExcelField(title="选项解析", align=2, sort=10)
private String aAnalysis;
@ExcelField(title="选项图片", align=2, sort=11)
private String aImage;
}

View File

@ -1,23 +0,0 @@
package com.guwan.backend.model.qu.dto.export;
import com.yf.exam.modules.qu.dto.QuAnswerDTO;
import lombok.Data;
import java.util.List;
/**
* 用于导出的数据结构
* @author bool
*/
@Data
public class QuImportDTO {
private static final long serialVersionUID = 1L;
private String quType;
private String qContent;
private String qAnalysis;
private String qImage;
private String repoName;
private List<QuAnswerDTO> answerList;
}

View File

@ -1,33 +0,0 @@
package com.guwan.backend.model.qu.dto.ext;
import com.yf.exam.modules.qu.dto.QuAnswerDTO;
import com.yf.exam.modules.qu.dto.QuDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* <p>
* 问题题目请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
@Data
@ApiModel(value="问题题目详情", description="问题题目详情")
public class QuDetailDTO extends QuDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "备选项列表", required=true)
private List<QuAnswerDTO> answerList;
@ApiModelProperty(value = "题库列表", required=true)
private List<String> repoIds;
}

View File

@ -1,38 +0,0 @@
package com.guwan.backend.model.qu.dto.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* <p>
* 问题题目请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
@Data
@ApiModel(value="题目查询请求类", description="题目查询请求类")
public class QuQueryReqDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "题目类型")
private Integer quType;
@ApiModelProperty(value = "归属题库")
private List<String> repoIds;
@ApiModelProperty(value = "题目内容")
private String content;
@ApiModelProperty(value = "排除ID列表")
private List<String> excludes;
}

View File

@ -1,34 +0,0 @@
package com.guwan.backend.model.qu.dto.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* <p>
* 问题题目请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
@Data
@ApiModel(value="试题题库批量操作类", description="试题题库批量操作类")
public class QuRepoBatchReqDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "题目ID", required=true)
private List<String> quIds;
@ApiModelProperty(value = "题目类型", required=true)
private List<String> repoIds;
@ApiModelProperty(value = "是否移除,否就新增;是就移除", required=true)
private Boolean remove;
}

View File

@ -1,75 +0,0 @@
package com.guwan.backend.model.qu.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import java.util.Date;
/**
* <p>
* 问题题目实体类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
@Data
@TableName("el_qu")
public class Qu extends Model<Qu> {
private static final long serialVersionUID = 1L;
/**
* 题目ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 题目类型
*/
@TableField("qu_type")
private Integer quType;
/**
* 1普通,2较难
*/
private Integer level;
/**
* 题目图片
*/
private String image;
/**
* 题目内容
*/
private String content;
/**
* 创建时间
*/
@TableField("create_time")
private Date createTime;
/**
* 更新时间
*/
@TableField("update_time")
private Date updateTime;
/**
* 题目备注
*/
private String remark;
/**
* 整题解析
*/
private String analysis;
}

View File

@ -1,58 +0,0 @@
package com.guwan.backend.model.qu.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
/**
* <p>
* 候选答案实体类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
@Data
@TableName("el_qu_answer")
public class QuAnswer extends Model<QuAnswer> {
private static final long serialVersionUID = 1L;
/**
* 答案ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 问题ID
*/
@TableField("qu_id")
private String quId;
/**
* 是否正确
*/
@TableField("is_right")
private Boolean isRight;
/**
* 选项图片
*/
private String image;
/**
* 答案内容
*/
private String content;
/**
* 答案分析
*/
private String analysis;
}

View File

@ -1,50 +0,0 @@
package com.guwan.backend.model.qu.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
/**
* <p>
* 试题题库实体类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
@Data
@TableName("el_qu_repo")
public class QuRepo extends Model<QuRepo> {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 试题
*/
@TableField("qu_id")
private String quId;
/**
* 归属题库
*/
@TableField("repo_id")
private String repoId;
/**
* 题目类型
*/
@TableField("qu_type")
private Integer quType;
/**
* 排序
*/
private Integer sort;
}

View File

@ -1,26 +0,0 @@
package com.guwan.backend.model.qu.enums;
/**
* 题目类型
* @author bool
* @date 2019-10-30 13:11
*/
public interface QuType {
/**
* 单选题
*/
Integer RADIO = 1;
/**
* 多选题
*/
Integer MULTI = 2;
/**
* 判断题
*/
Integer JUDGE = 3;
}

View File

@ -1,16 +0,0 @@
package com.guwan.backend.model.qu.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yf.exam.modules.qu.entity.QuAnswer;
/**
* <p>
* 候选答案Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
public interface QuAnswerMapper extends BaseMapper<QuAnswer> {
}

View File

@ -1,56 +0,0 @@
package com.guwan.backend.model.qu.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yf.exam.modules.qu.dto.QuDTO;
import com.yf.exam.modules.qu.dto.export.QuExportDTO;
import com.yf.exam.modules.qu.dto.request.QuQueryReqDTO;
import com.yf.exam.modules.qu.entity.Qu;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 问题题目Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
public interface QuMapper extends BaseMapper<Qu> {
/**
* 随机抽取题库的数据
* @param repoId
* @param quType
* @param level
* @param excludes 要排除的ID列表
* @param size
* @return
*/
List<Qu> listByRandom(@Param("repoId") String repoId,
@Param("quType") Integer quType,
@Param("excludes") List<String> excludes,
@Param("size") Integer size);
/**
* 查找导出列表
* @param query
* @return
*/
List<QuExportDTO> listForExport(@Param("query") QuQueryReqDTO query);
/**
* 分页查找
* @param page
* @param query
* @return
*/
IPage<QuDTO> paging(Page page, @Param("query") QuQueryReqDTO query);
}

View File

@ -1,16 +0,0 @@
package com.guwan.backend.model.qu.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yf.exam.modules.qu.entity.QuRepo;
/**
* <p>
* 试题题库Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
public interface QuRepoMapper extends BaseMapper<QuRepo> {
}

View File

@ -1,48 +0,0 @@
package com.guwan.backend.model.qu.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.qu.dto.QuAnswerDTO;
import com.yf.exam.modules.qu.entity.QuAnswer;
import java.util.List;
/**
* <p>
* 候选答案业务类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
public interface QuAnswerService extends IService<QuAnswer> {
/**
* 分页查询数据
* @param reqDTO
* @return
*/
IPage<QuAnswerDTO> paging(PagingReqDTO<QuAnswerDTO> reqDTO);
/**
* 根据题目ID查询答案并随机
* @param quId
* @return
*/
List<QuAnswer> listAnswerByRandom(String quId);
/**
* 根据问题查找答案
* @param quId
* @return
*/
List<QuAnswerDTO> listByQu(String quId);
/**
* 保存试题
* @param quId
* @param list
*/
void saveAll(String quId, List<QuAnswerDTO> list);
}

View File

@ -1,59 +0,0 @@
package com.guwan.backend.model.qu.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.qu.dto.QuRepoDTO;
import com.yf.exam.modules.qu.dto.request.QuRepoBatchReqDTO;
import com.yf.exam.modules.qu.entity.QuRepo;
import java.util.List;
/**
* <p>
* 试题题库业务类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
public interface QuRepoService extends IService<QuRepo> {
/**
* 分页查询数据
* @param reqDTO
* @return
*/
IPage<QuRepoDTO> paging(PagingReqDTO<QuRepoDTO> reqDTO);
/**
* 保存全部列表
* @param quId
* @param quType
* @param ids
*/
void saveAll(String quId, Integer quType, List<String> ids);
/**
* 根据问题查找题库
* @param quId
* @return
*/
List<String> listByQu(String quId);
/**
* 根据题库查找题目ID列表
* @param repoId
* @param quType
* @param rand
* @return
*/
List<String> listByRepo(String repoId, Integer quType, boolean rand);
/**
* 批量操作
* @param reqDTO
*/
void batchAction(QuRepoBatchReqDTO reqDTO);
}

View File

@ -1,76 +0,0 @@
package com.guwan.backend.model.qu.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.qu.dto.QuDTO;
import com.yf.exam.modules.qu.dto.export.QuExportDTO;
import com.yf.exam.modules.qu.dto.ext.QuDetailDTO;
import com.yf.exam.modules.qu.dto.request.QuQueryReqDTO;
import com.yf.exam.modules.qu.entity.Qu;
import java.util.List;
/**
* <p>
* 问题题目业务类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
public interface QuService extends IService<Qu> {
/**
* 分页查询数据
* @param reqDTO
* @return
*/
IPage<QuDTO> paging(PagingReqDTO<QuQueryReqDTO> reqDTO);
/**
* 删除试题
* @param ids
*/
void delete(List<String> ids);
/**
* 随机抽取题库的数据
* @param repoId
* @param quType
* @param excludes 要排除的ID列表
* @param size
* @return
*/
List<Qu> listByRandom(String repoId,
Integer quType,
List<String> excludes,
Integer size);
/**
* 问题详情
* @param id
* @return
*/
QuDetailDTO detail(String id);
/**
* 保存试题
* @param reqDTO
*/
void save(QuDetailDTO reqDTO);
/**
* 查找导出列表
* @param query
* @return
*/
List<QuExportDTO> listForExport(QuQueryReqDTO query);
/**
* 导入Excel
* @param dtoList
* @return
*/
int importExcel(List<QuExportDTO> dtoList);
}

View File

@ -1,144 +0,0 @@
package com.guwan.backend.model.qu.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.core.utils.BeanMapper;
import com.yf.exam.modules.qu.dto.QuAnswerDTO;
import com.yf.exam.modules.qu.entity.QuAnswer;
import com.yf.exam.modules.qu.mapper.QuAnswerMapper;
import com.yf.exam.modules.qu.service.QuAnswerService;
import com.yf.exam.modules.qu.utils.ImageCheckUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 语言设置 服务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
@Service
public class QuAnswerServiceImpl extends ServiceImpl<QuAnswerMapper, QuAnswer> implements QuAnswerService {
@Autowired
private ImageCheckUtils imageCheckUtils;
@Override
public IPage<QuAnswerDTO> paging(PagingReqDTO<QuAnswerDTO> reqDTO) {
//创建分页对象
IPage<QuAnswer> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
//查询条件
QueryWrapper<QuAnswer> wrapper = new QueryWrapper<>();
//获得数据
IPage<QuAnswer> page = this.page(query, wrapper);
//转换结果
IPage<QuAnswerDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<QuAnswerDTO>>(){});
return pageData;
}
@Override
public List<QuAnswer> listAnswerByRandom(String quId) {
QueryWrapper<QuAnswer> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(QuAnswer::getQuId, quId);
wrapper.last(" ORDER BY RAND() ");
return this.list(wrapper);
}
@Override
public List<QuAnswerDTO> listByQu(String quId) {
QueryWrapper<QuAnswer> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(QuAnswer::getQuId, quId);
List<QuAnswer> list = this.list(wrapper);
if(!CollectionUtils.isEmpty(list)){
return BeanMapper.mapList(list, QuAnswerDTO.class);
}
return null;
}
/**
* 查找已存在的列表
* @param quId
* @return
*/
public List<String> findExistsList(String quId) {
//返回结果
List<String> ids = new ArrayList<>();
QueryWrapper<QuAnswer> wrapper = new QueryWrapper();
wrapper.lambda().eq(QuAnswer::getQuId, quId);
List<QuAnswer> list = this.list(wrapper);
if (!CollectionUtils.isEmpty(list)) {
for (QuAnswer item : list) {
ids.add(item.getId());
}
}
return ids;
}
@Override
public void saveAll(String quId, List<QuAnswerDTO> list) {
//最终要保存的列表
List<QuAnswer> saveList = new ArrayList<>();
//已存在的标签列表
List<String> ids = this.findExistsList(quId);
if(!CollectionUtils.isEmpty(list)){
for(QuAnswerDTO item: list){
// 校验图片地址
imageCheckUtils.checkImage(item.getImage(), "选项图片地址错误!");
//标签ID
String id = item.getId();
QuAnswer answer = new QuAnswer();
BeanMapper.copy(item, answer);
answer.setQuId(quId);
//补全ID避免新增
if(ids.contains(id)){
ids.remove(id);
}
saveList.add(answer);
}
//保存标签列表
if(!CollectionUtils.isEmpty(saveList)) {
this.saveOrUpdateBatch(saveList);
}
//删除已移除
if(!ids.isEmpty()){
this.removeByIds(ids);
}
}else{
QueryWrapper<QuAnswer> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(QuAnswer::getQuId, quId);
this.remove(wrapper);
}
}
}

View File

@ -1,175 +0,0 @@
package com.guwan.backend.model.qu.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.qu.dto.QuRepoDTO;
import com.yf.exam.modules.qu.dto.request.QuRepoBatchReqDTO;
import com.yf.exam.modules.qu.entity.Qu;
import com.yf.exam.modules.qu.entity.QuRepo;
import com.yf.exam.modules.qu.mapper.QuMapper;
import com.yf.exam.modules.qu.mapper.QuRepoMapper;
import com.yf.exam.modules.qu.service.QuRepoService;
import com.yf.exam.modules.repo.service.RepoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 语言设置 服务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 13:23
*/
@Service
public class QuRepoServiceImpl extends ServiceImpl<QuRepoMapper, QuRepo> implements QuRepoService {
@Autowired
private QuMapper quMapper;
@Autowired
private RepoService repoService;
@Override
public IPage<QuRepoDTO> paging(PagingReqDTO<QuRepoDTO> reqDTO) {
//创建分页对象
IPage<QuRepo> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
//查询条件
QueryWrapper<QuRepo> wrapper = new QueryWrapper<>();
//获得数据
IPage<QuRepo> page = this.page(query, wrapper);
//转换结果
IPage<QuRepoDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<QuRepoDTO>>(){});
return pageData;
}
@Override
public void saveAll(String quId, Integer quType, List<String> ids) {
// 先删除
QueryWrapper<QuRepo> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(QuRepo::getQuId, quId);
this.remove(wrapper);
// 保存全部
if(!CollectionUtils.isEmpty(ids)){
List<QuRepo> list = new ArrayList<>();
for(String id: ids){
QuRepo ref = new QuRepo();
ref.setQuId(quId);
ref.setRepoId(id);
ref.setQuType(quType);
list.add(ref);
}
this.saveBatch(list);
for(String id: ids){
this.sortRepo(id);
}
}
}
@Override
public List<String> listByQu(String quId) {
// 先删除
QueryWrapper<QuRepo> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(QuRepo::getQuId, quId);
List<QuRepo> list = this.list(wrapper);
List<String> ids = new ArrayList<>();
if(!CollectionUtils.isEmpty(list)){
for(QuRepo item: list){
ids.add(item.getRepoId());
}
}
return ids;
}
@Override
public List<String> listByRepo(String repoId, Integer quType, boolean rand) {
QueryWrapper<QuRepo> wrapper = new QueryWrapper<>();
wrapper.lambda()
.eq(QuRepo::getRepoId, repoId);
if(quType!=null){
wrapper.lambda().eq(QuRepo::getQuType, quType);
}
if(rand){
wrapper.orderByAsc(" RAND() ");
}else{
wrapper.lambda().orderByAsc(QuRepo::getSort);
}
List<QuRepo> list = this.list(wrapper);
List<String> ids = new ArrayList<>();
if(!CollectionUtils.isEmpty(list)){
for(QuRepo item: list){
ids.add(item.getQuId());
}
}
return ids;
}
@Override
public void batchAction(QuRepoBatchReqDTO reqDTO) {
// 移除的
if(reqDTO.getRemove()!=null && reqDTO.getRemove()){
QueryWrapper<QuRepo> wrapper = new QueryWrapper<>();
wrapper.lambda()
.in(QuRepo::getRepoId, reqDTO.getRepoIds())
.in(QuRepo::getQuId, reqDTO.getQuIds());
this.remove(wrapper);
}else{
// 新增的
for(String quId : reqDTO.getQuIds()){
Qu q = quMapper.selectById(quId);
this.saveAll(quId, q.getQuType(), reqDTO.getRepoIds());
}
}
for(String id: reqDTO.getRepoIds()){
this.sortRepo(id);
}
}
/**
* 单个题库进行排序
* @param repoId
*/
private void sortRepo(String repoId){
QueryWrapper<QuRepo> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(QuRepo::getRepoId, repoId);
List<QuRepo> list = this.list(wrapper);
if(CollectionUtils.isEmpty(list)){
return;
}
int sort = 1;
for(QuRepo item: list){
item.setSort(sort);
sort++;
}
this.updateBatchById(list);
}
}

View File

@ -1,277 +0,0 @@
package com.guwan.backend.model.qu.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.core.exception.ServiceException;
import com.yf.exam.core.utils.BeanMapper;
import com.yf.exam.modules.qu.dto.QuAnswerDTO;
import com.yf.exam.modules.qu.dto.QuDTO;
import com.yf.exam.modules.qu.dto.export.QuExportDTO;
import com.yf.exam.modules.qu.dto.ext.QuDetailDTO;
import com.yf.exam.modules.qu.dto.request.QuQueryReqDTO;
import com.yf.exam.modules.qu.entity.Qu;
import com.yf.exam.modules.qu.entity.QuAnswer;
import com.yf.exam.modules.qu.entity.QuRepo;
import com.yf.exam.modules.qu.enums.QuType;
import com.yf.exam.modules.qu.mapper.QuMapper;
import com.yf.exam.modules.qu.service.QuAnswerService;
import com.yf.exam.modules.qu.service.QuRepoService;
import com.yf.exam.modules.qu.service.QuService;
import com.yf.exam.modules.qu.utils.ImageCheckUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.*;
/**
* <p>
* 语言设置 服务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-25 10:17
*/
@Service
public class QuServiceImpl extends ServiceImpl<QuMapper, Qu> implements QuService {
@Autowired
private QuAnswerService quAnswerService;
@Autowired
private QuRepoService quRepoService;
@Autowired
private ImageCheckUtils imageCheckUtils;
@Override
public IPage<QuDTO> paging(PagingReqDTO<QuQueryReqDTO> reqDTO) {
//创建分页对象
Page page = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
//转换结果
IPage<QuDTO> pageData = baseMapper.paging(page, reqDTO.getParams());
return pageData;
}
@Transactional(rollbackFor = Exception.class)
@Override
public void delete(List<String> ids) {
// 移除题目
this.removeByIds(ids);
// 移除选项
QueryWrapper<QuAnswer> wrapper = new QueryWrapper<>();
wrapper.lambda().in(QuAnswer::getQuId, ids);
quAnswerService.remove(wrapper);
// 移除题库绑定
QueryWrapper<QuRepo> wrapper1 = new QueryWrapper<>();
wrapper1.lambda().in(QuRepo::getQuId, ids);
quRepoService.remove(wrapper1);
}
@Override
public List<Qu> listByRandom(String repoId, Integer quType, List<String> excludes, Integer size) {
return baseMapper.listByRandom(repoId, quType, excludes, size);
}
@Override
public QuDetailDTO detail(String id) {
QuDetailDTO respDTO = new QuDetailDTO();
Qu qu = this.getById(id);
BeanMapper.copy(qu, respDTO);
List<QuAnswerDTO> answerList = quAnswerService.listByQu(id);
respDTO.setAnswerList(answerList);
List<String> repoIds = quRepoService.listByQu(id);
respDTO.setRepoIds(repoIds);
return respDTO;
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(QuDetailDTO reqDTO) {
// 校验数据
this.checkData(reqDTO, "");
Qu qu = new Qu();
BeanMapper.copy(reqDTO, qu);
// 校验图片地址
imageCheckUtils.checkImage(qu.getImage(), "题干图片地址错误!");
// 更新
this.saveOrUpdate(qu);
// 保存全部问题
quAnswerService.saveAll(qu.getId(), reqDTO.getAnswerList());
// 保存到题库
quRepoService.saveAll(qu.getId(), qu.getQuType(), reqDTO.getRepoIds());
}
@Override
public List<QuExportDTO> listForExport(QuQueryReqDTO query) {
return baseMapper.listForExport(query);
}
@Override
public int importExcel(List<QuExportDTO> dtoList) {
//根据题目名称分组
Map<Integer, List<QuExportDTO>> anMap = new HashMap<>(16);
//题目本体信息
Map<Integer, QuExportDTO> quMap = new HashMap<>(16);
//数据分组
for (QuExportDTO item : dtoList) {
// 空白的ID
if (StringUtils.isEmpty(item.getNo())) {
continue;
}
Integer key;
//序号
try {
key = Integer.parseInt(item.getNo());
} catch (Exception e) {
continue;
}
//如果已经有题目了直接处理选项
if (anMap.containsKey(key)) {
anMap.get(key).add(item);
} else {
//如果没有将题目内容和选项一起
List<QuExportDTO> subList = new ArrayList<>();
subList.add(item);
anMap.put(key, subList);
quMap.put(key, item);
}
}
int count = 0;
try {
//循环题目插入
for (Integer key : quMap.keySet()) {
QuExportDTO im = quMap.get(key);
//题目基本信息
QuDetailDTO qu = new QuDetailDTO();
qu.setContent(im.getQContent());
qu.setAnalysis(im.getQAnalysis());
qu.setQuType(Integer.parseInt(im.getQuType()));
qu.setCreateTime(new Date());
//设置回答列表
List<QuAnswerDTO> answerList = this.processAnswerList(anMap.get(key));
//设置题目
qu.setAnswerList(answerList);
//设置引用题库
qu.setRepoIds(im.getRepoList());
// 保存答案
this.save(qu);
count++;
}
} catch (ServiceException e) {
e.printStackTrace();
throw new ServiceException(1, "导入出现问题,行:" + count + "" + e.getMessage());
}
return count;
}
/**
* 处理回答列表
*
* @param importList
* @return
*/
private List<QuAnswerDTO> processAnswerList(List<QuExportDTO> importList) {
List<QuAnswerDTO> list = new ArrayList<>(16);
for (QuExportDTO item : importList) {
QuAnswerDTO a = new QuAnswerDTO();
a.setIsRight("1".equals(item.getAIsRight()));
a.setContent(item.getAContent());
a.setAnalysis(item.getAAnalysis());
a.setId("");
list.add(a);
}
return list;
}
/**
* 校验题目信息
*
* @param qu
* @param no
* @throws Exception
*/
public void checkData(QuDetailDTO qu, String no) {
if (StringUtils.isEmpty(qu.getContent())) {
throw new ServiceException(1, no + "题目内容不能为空!");
}
if (CollectionUtils.isEmpty(qu.getRepoIds())) {
throw new ServiceException(1, no + "至少要选择一个题库!");
}
List<QuAnswerDTO> answers = qu.getAnswerList();
if (CollectionUtils.isEmpty(answers)) {
throw new ServiceException(1, no + "客观题至少要包含一个备选答案!");
}
int trueCount = 0;
for (QuAnswerDTO a : answers) {
if (a.getIsRight() == null) {
throw new ServiceException(1, no + "必须定义选项是否正确项!");
}
if (StringUtils.isEmpty(a.getContent())) {
throw new ServiceException(1, no + "选项内容不为空!");
}
if (a.getIsRight()) {
trueCount += 1;
}
}
if (trueCount == 0) {
throw new ServiceException(1, no + "至少要包含一个正确项!");
}
//单选题
if (qu.getQuType().equals(QuType.RADIO) && trueCount > 1) {
throw new ServiceException(1, no + "单选题不能包含多个正确项!");
}
}
}

View File

@ -1,31 +0,0 @@
package com.guwan.backend.model.qu.utils;
import com.yf.exam.ability.upload.config.UploadConfig;
import com.yf.exam.core.exception.ServiceException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ImageCheckUtils {
@Autowired
private UploadConfig conf;
/**
* 进行图片校验
* @param image
* @param throwMsg
*/
public void checkImage(String image, String throwMsg) {
if(StringUtils.isBlank(image)){
return;
}
// 校验图片地址
if(!image.startsWith(conf.getUrl())){
throw new ServiceException(throwMsg);
}
}
}

View File

@ -1,70 +0,0 @@
package com.guwan.backend.model.sys.config.controller;
import com.yf.exam.core.api.ApiRest;
import com.yf.exam.core.api.controller.BaseController;
import com.yf.exam.core.api.dto.BaseIdRespDTO;
import com.yf.exam.core.utils.BeanMapper;
import com.yf.exam.modules.qu.utils.ImageCheckUtils;
import com.yf.exam.modules.sys.config.dto.SysConfigDTO;
import com.yf.exam.modules.sys.config.entity.SysConfig;
import com.yf.exam.modules.sys.config.service.SysConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 通用配置控制器
* </p>
*
* @author 聪明笨狗
* @since 2020-04-17 09:12
*/
@Api(tags={"通用配置"})
@RestController
@RequestMapping("/exam/api/sys/config")
public class SysConfigController extends BaseController {
@Autowired
private SysConfigService baseService;
@Autowired
private ImageCheckUtils imageCheckUtils;
/**
* 添加或修改
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "添加或修改")
@RequestMapping(value = "/save", method = { RequestMethod.POST})
public ApiRest<BaseIdRespDTO> save(@RequestBody SysConfigDTO reqDTO) {
//复制参数
SysConfig entity = new SysConfig();
BeanMapper.copy(reqDTO, entity);
// 校验图片地址
imageCheckUtils.checkImage(entity.getBackLogo(), "系统LOGO地址错误");
baseService.saveOrUpdate(entity);
return super.success(new BaseIdRespDTO(entity.getId()));
}
/**
* 查找详情
* @return
*/
@ApiOperation(value = "查找详情")
@RequestMapping(value = "/detail", method = { RequestMethod.POST})
public ApiRest<SysConfigDTO> find() {
SysConfigDTO dto = baseService.find();
return super.success(dto);
}
}

View File

@ -1,39 +0,0 @@
package com.guwan.backend.model.sys.config.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 通用配置请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-17 09:12
*/
@Data
@ApiModel(value="通用配置", description="通用配置")
public class SysConfigDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID", required=true)
private String id;
@ApiModelProperty(value = "系统名称")
private String siteName;
@ApiModelProperty(value = "前端LOGO")
private String frontLogo;
@ApiModelProperty(value = "后台LOGO")
private String backLogo;
@ApiModelProperty(value = "版权信息")
private String copyRight;
}

View File

@ -1,53 +0,0 @@
package com.guwan.backend.model.sys.config.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
/**
* <p>
* 通用配置实体类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-17 09:12
*/
@Data
@TableName("sys_config")
public class SysConfig extends Model<SysConfig> {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 系统名称
*/
@TableField("site_name")
private String siteName;
/**
* 前端LOGO
*/
@TableField("front_logo")
private String frontLogo;
/**
* 后台LOGO
*/
@TableField("back_logo")
private String backLogo;
/**
* 版权信息
*/
@TableField("copy_right")
private String copyRight;
}

View File

@ -1,16 +0,0 @@
package com.guwan.backend.model.sys.config.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yf.exam.modules.sys.config.entity.SysConfig;
/**
* <p>
* 通用配置Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-04-17 09:12
*/
public interface SysConfigMapper extends BaseMapper<SysConfig> {
}

View File

@ -1,22 +0,0 @@
package com.guwan.backend.model.sys.config.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yf.exam.modules.sys.config.dto.SysConfigDTO;
import com.yf.exam.modules.sys.config.entity.SysConfig;
/**
* <p>
* 通用配置业务类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-17 09:12
*/
public interface SysConfigService extends IService<SysConfig> {
/**
* 查找配置信息
* @return
*/
SysConfigDTO find();
}

View File

@ -1,34 +0,0 @@
package com.guwan.backend.model.sys.config.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yf.exam.core.utils.BeanMapper;
import com.yf.exam.modules.sys.config.dto.SysConfigDTO;
import com.yf.exam.modules.sys.config.entity.SysConfig;
import com.yf.exam.modules.sys.config.mapper.SysConfigMapper;
import com.yf.exam.modules.sys.config.service.SysConfigService;
import org.springframework.stereotype.Service;
/**
* <p>
* 语言设置 服务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-17 09:12
*/
@Service
public class SysConfigServiceImpl extends ServiceImpl<SysConfigMapper, SysConfig> implements SysConfigService {
@Override
public SysConfigDTO find() {
QueryWrapper<SysConfig> wrapper = new QueryWrapper<>();
wrapper.last(" LIMIT 1");
SysConfig entity = this.getOne(wrapper, false);
SysConfigDTO dto = new SysConfigDTO();
BeanMapper.copy(entity, dto);
return dto;
}
}

View File

@ -1,150 +0,0 @@
package com.guwan.backend.model.sys.depart.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yf.exam.core.api.ApiRest;
import com.yf.exam.core.api.controller.BaseController;
import com.yf.exam.core.api.dto.BaseIdReqDTO;
import com.yf.exam.core.api.dto.BaseIdsReqDTO;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.core.utils.BeanMapper;
import com.yf.exam.modules.sys.depart.dto.SysDepartDTO;
import com.yf.exam.modules.sys.depart.dto.request.DepartSortReqDTO;
import com.yf.exam.modules.sys.depart.dto.response.SysDepartTreeDTO;
import com.yf.exam.modules.sys.depart.entity.SysDepart;
import com.yf.exam.modules.sys.depart.service.SysDepartService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* 部门信息控制器
* </p>
*
* @author 聪明笨狗
* @since 2020-09-02 17:25
*/
@Api(tags={"部门信息"})
@RestController
@RequestMapping("/exam/api/sys/depart")
public class SysDepartController extends BaseController {
@Autowired
private SysDepartService baseService;
/**
* 添加或修改
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "添加或修改")
@RequestMapping(value = "/save", method = { RequestMethod.POST})
public ApiRest save(@RequestBody SysDepartDTO reqDTO) {
baseService.save(reqDTO);
return super.success();
}
/**
* 批量删除
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "批量删除")
@RequestMapping(value = "/delete", method = { RequestMethod.POST})
public ApiRest edit(@RequestBody BaseIdsReqDTO reqDTO) {
//根据ID删除
baseService.removeByIds(reqDTO.getIds());
return super.success();
}
/**
* 查找详情
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "查找详情")
@RequestMapping(value = "/detail", method = { RequestMethod.POST})
public ApiRest<SysDepartDTO> find(@RequestBody BaseIdReqDTO reqDTO) {
SysDepart entity = baseService.getById(reqDTO.getId());
SysDepartDTO dto = new SysDepartDTO();
BeanUtils.copyProperties(entity, dto);
return super.success(dto);
}
/**
* 分页查找
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "分页查找")
@RequestMapping(value = "/paging", method = { RequestMethod.POST})
public ApiRest<IPage<SysDepartTreeDTO>> paging(@RequestBody PagingReqDTO<SysDepartDTO> reqDTO) {
//分页查询并转换
IPage<SysDepartTreeDTO> page = baseService.paging(reqDTO);
return super.success(page);
}
/**
* 查找列表每次最多返回200条数据
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "查找列表")
@RequestMapping(value = "/list", method = { RequestMethod.POST})
public ApiRest<List<SysDepartDTO>> list(@RequestBody SysDepartDTO reqDTO) {
//分页查询并转换
QueryWrapper<SysDepart> wrapper = new QueryWrapper<>();
//转换并返回
List<SysDepart> list = baseService.list(wrapper);
//转换数据
List<SysDepartDTO> dtoList = BeanMapper.mapList(list, SysDepartDTO.class);
return super.success(dtoList);
}
/**
* 树列表
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "树列表")
@RequestMapping(value = "/tree", method = { RequestMethod.POST})
public ApiRest<List<SysDepartTreeDTO>> tree() {
List<SysDepartTreeDTO> dtoList = baseService.findTree();
return super.success(dtoList);
}
/**
* 分类排序
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "分类排序")
@RequestMapping(value = "/sort", method = { RequestMethod.POST})
public ApiRest sort(@RequestBody DepartSortReqDTO reqDTO) {
baseService.sort(reqDTO.getId(), reqDTO.getSort());
return super.success();
}
}

View File

@ -1,42 +0,0 @@
package com.guwan.backend.model.sys.depart.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 部门信息数据传输类
* </p>
*
* @author 聪明笨狗
* @since 2020-09-02 17:25
*/
@Data
@ApiModel(value="部门信息", description="部门信息")
public class SysDepartDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID", required=true)
private String id;
@ApiModelProperty(value = "1公司2部门", required=true)
private Integer deptType;
@ApiModelProperty(value = "所属上级", required=true)
private String parentId;
@ApiModelProperty(value = "部门名称", required=true)
private String deptName;
@ApiModelProperty(value = "部门编码", required=true)
private String deptCode;
@ApiModelProperty(value = "排序", required=true)
private Integer sort;
}

View File

@ -1,28 +0,0 @@
package com.guwan.backend.model.sys.depart.dto.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 部门排序请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-03-14 10:37
*/
@Data
@ApiModel(value="部门排序请求类", description="部门排序请求类")
public class DepartSortReqDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "分类ID")
private String id;
@ApiModelProperty(value = "排序0下降1上升")
private Integer sort;
}

View File

@ -1,28 +0,0 @@
package com.guwan.backend.model.sys.depart.dto.response;
import com.yf.exam.modules.sys.depart.dto.SysDepartDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* <p>
* 部门树结构响应类
* </p>
*
* @author 聪明笨狗
* @since 2020-09-02 17:25
*/
@Data
@ApiModel(value="部门树结构响应类", description="部门树结构响应类")
public class SysDepartTreeDTO extends SysDepartDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "子列表", required=true)
private List<SysDepartTreeDTO> children;
}

View File

@ -1,59 +0,0 @@
package com.guwan.backend.model.sys.depart.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
/**
* <p>
* 部门信息实体类
* </p>
*
* @author 聪明笨狗
* @since 2020-09-02 17:25
*/
@Data
@TableName("sys_depart")
public class SysDepart extends Model<SysDepart> {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 1公司2部门
*/
@TableField("dept_type")
private Integer deptType;
/**
* 所属上级
*/
@TableField("parent_id")
private String parentId;
/**
* 部门名称
*/
@TableField("dept_name")
private String deptName;
/**
* 部门编码
*/
@TableField("dept_code")
private String deptCode;
/**
* 排序
*/
private Integer sort;
}

View File

@ -1,28 +0,0 @@
package com.guwan.backend.model.sys.depart.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yf.exam.modules.sys.depart.dto.SysDepartDTO;
import com.yf.exam.modules.sys.depart.dto.response.SysDepartTreeDTO;
import com.yf.exam.modules.sys.depart.entity.SysDepart;
import org.apache.ibatis.annotations.Param;
/**
* <p>
* 部门信息Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-09-02 17:25
*/
public interface SysDepartMapper extends BaseMapper<SysDepart> {
/**
* 部门树分页
* @param page
* @param query
* @return
*/
IPage<SysDepartTreeDTO> paging(Page page, @Param("query") SysDepartDTO query);
}

View File

@ -1,62 +0,0 @@
package com.guwan.backend.model.sys.depart.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.sys.depart.dto.SysDepartDTO;
import com.yf.exam.modules.sys.depart.dto.response.SysDepartTreeDTO;
import com.yf.exam.modules.sys.depart.entity.SysDepart;
import java.util.List;
/**
* <p>
* 部门信息业务类
* </p>
*
* @author 聪明笨狗
* @since 2020-09-02 17:25
*/
public interface SysDepartService extends IService<SysDepart> {
/**
* 保存
* @param reqDTO
*/
void save(SysDepartDTO reqDTO);
/**
* 分页查询数据
* @param reqDTO
* @return
*/
IPage<SysDepartTreeDTO> paging(PagingReqDTO<SysDepartDTO> reqDTO);
/**
* 查找部门树结构
* @return
*/
List<SysDepartTreeDTO> findTree();
/**
* 查找部门树
* @param ids
* @return
*/
List<SysDepartTreeDTO> findTree(List<String> ids);
/**
* 排序
* @param id
* @param sort
*/
void sort(String id, Integer sort);
/**
* 获取某个部门ID下的所有子部门ID
* @param id
* @return
*/
List<String> listAllSubIds( String id);
}

View File

@ -1,288 +0,0 @@
package com.guwan.backend.model.sys.depart.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.core.utils.BeanMapper;
import com.yf.exam.modules.sys.depart.dto.SysDepartDTO;
import com.yf.exam.modules.sys.depart.dto.response.SysDepartTreeDTO;
import com.yf.exam.modules.sys.depart.entity.SysDepart;
import com.yf.exam.modules.sys.depart.mapper.SysDepartMapper;
import com.yf.exam.modules.sys.depart.service.SysDepartService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
* 部门信息业务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-09-02 17:25
*/
@Service
public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart> implements SysDepartService {
/**
* 0标识为顶级分类
*/
private static final String ROOT_TAG = "0";
@Override
public void save(SysDepartDTO reqDTO) {
if(StringUtils.isBlank(reqDTO.getId())) {
this.fillCode(reqDTO);
}else{
reqDTO.setSort(null);
reqDTO.setDeptCode(null);
}
SysDepart entity = new SysDepart();
BeanMapper.copy(reqDTO, entity);
this.saveOrUpdate(entity);
}
@Override
public IPage<SysDepartTreeDTO> paging(PagingReqDTO<SysDepartDTO> reqDTO) {
// 创建分页对象
Page query = new Page(reqDTO.getCurrent(), reqDTO.getSize());
// 请求参数
SysDepartDTO params = reqDTO.getParams();
//转换结果
IPage<SysDepartTreeDTO> pageData = baseMapper.paging(query, params);
return pageData;
}
@Override
public List<SysDepartTreeDTO> findTree() {
return this.findTree(null);
}
@Override
public List<SysDepartTreeDTO> findTree(List<String> ids) {
QueryWrapper<SysDepart> wrapper = new QueryWrapper();
wrapper.lambda().orderByAsc(SysDepart::getSort);
if(!CollectionUtils.isEmpty(ids)){
List<String> fullIds = new ArrayList<>();
for(String id: ids){
this.cycleAllParent(fullIds, id);
}
if(!CollectionUtils.isEmpty(fullIds)){
wrapper.lambda().in(SysDepart::getId, fullIds);
}
}
//全部列表
List<SysDepart> list = this.list(wrapper);
List<SysDepartTreeDTO> dtoList = BeanMapper.mapList(list, SysDepartTreeDTO.class);
//子结构的列表
Map<String,List<SysDepartTreeDTO>> map = new HashMap<>(16);
for(SysDepartTreeDTO item: dtoList){
//如果存在
if(map.containsKey(item.getParentId())){
map.get(item.getParentId()).add(item);
continue;
}
//增加新的结构
List<SysDepartTreeDTO> a = new ArrayList<>();
a.add(item);
map.put(item.getParentId(), a);
}
//注意第0级为顶级的
List<SysDepartTreeDTO> topList = map.get(ROOT_TAG);
if(!CollectionUtils.isEmpty(topList)){
for(SysDepartTreeDTO item: topList){
this.fillChildren(map, item);
}
}
return topList;
}
@Override
public void sort(String id, Integer sort) {
SysDepart depart = this.getById(id);
SysDepart exchange = null;
QueryWrapper<SysDepart> wrapper = new QueryWrapper<>();
// 同级排序
wrapper.lambda()
.eq(SysDepart::getParentId, depart.getParentId());
wrapper.last("LIMIT 1");
// 上升
if(sort == 0){
// 同级排序
wrapper.lambda()
.lt(SysDepart::getSort, depart.getSort())
.orderByDesc(SysDepart::getSort);
exchange = this.getOne(wrapper, false);
}
// 下降
if(sort == 1){
// 同级排序
wrapper.lambda()
.gt(SysDepart::getSort, depart.getSort())
.orderByAsc(SysDepart::getSort);
exchange = this.getOne(wrapper, false);
}
if(exchange!=null) {
SysDepart a = new SysDepart();
a.setId(id);
a.setSort(exchange.getSort());
SysDepart b = new SysDepart();
b.setId(exchange.getId());
b.setSort(depart.getSort());
this.updateById(a);
this.updateById(b);
}
}
/**
* 获取部门编号
* @param reqDTO
* @return
*/
private void fillCode(SysDepartDTO reqDTO){
// 前缀
String code = "";
if(StringUtils.isNotBlank(reqDTO.getParentId())
&& !ROOT_TAG.equals(reqDTO.getParentId())){
SysDepart parent = this.getById(reqDTO.getParentId());
code = parent.getDeptCode();
}
QueryWrapper<SysDepart> wrapper = new QueryWrapper<>();
// 同级排序
wrapper.lambda()
.eq(SysDepart::getParentId, reqDTO.getParentId())
.orderByDesc(SysDepart::getSort);
wrapper.last("LIMIT 1");
SysDepart depart = this.getOne(wrapper, false);
if(depart !=null){
code += this.formatCode(depart.getSort()+1);
reqDTO.setSort(depart.getSort()+1);
}else{
code += this.formatCode(1);
reqDTO.setSort(1);
}
reqDTO.setDeptCode(code);
}
/**
* 根式化加0
* @param sort
* @return
*/
private String formatCode(Integer sort){
if(sort < 10){
return "A0"+sort;
}
return "A"+sort;
}
/**
* 递归去做填充数据
* @param map
* @param item
*/
private void fillChildren(Map<String,List<SysDepartTreeDTO>> map, SysDepartTreeDTO item){
//设置子类
if(map.containsKey(item.getId())){
List<SysDepartTreeDTO> children = map.get(item.getId());
if(!CollectionUtils.isEmpty(children)){
for(SysDepartTreeDTO sub: children){
this.fillChildren(map, sub);
}
}
item.setChildren(children);
}
}
@Override
public List<String> listAllSubIds( String id){
List<String> ids = new ArrayList<>();
this.cycleAllSubs(ids, id);
return ids;
}
/**
* 递归所有子级别ID
* @param list
* @param id
*/
private void cycleAllSubs(List<String> list, String id){
// 添加ID
list.add(id);
QueryWrapper<SysDepart> wrapper = new QueryWrapper<>();
wrapper.lambda()
.eq(SysDepart::getParentId, id)
.orderByDesc(SysDepart::getSort);
List<SysDepart> subList = this.list(wrapper);
if(!CollectionUtils.isEmpty(subList)){
for(SysDepart item: subList){
this.cycleAllSubs(list, item.getId());
}
}
}
/**
* 递归所有子级别ID
* @param list
* @param id
*/
private void cycleAllParent(List<String> list, String id){
// 往上递归获得父类
list.add(id);
SysDepart depart = this.getById(id);
if(StringUtils.isNotBlank(depart.getParentId())
&& !ROOT_TAG.equals(depart.getParentId())){
this.cycleAllParent(list, depart.getParentId());
}
}
}

View File

@ -1,29 +0,0 @@
package com.guwan.backend.model.sys.system.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* <p>
* 机主信息Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-08-22 13:46
*/
@Mapper
public interface SysDictMapper {
/**
* 查找数据字典
* @param table
* @param text
* @param key
* @param value
* @return
*/
String findDict(@Param("table") String table,
@Param("text") String text,
@Param("key") String key,
@Param("value") String value);
}

View File

@ -1,21 +0,0 @@
package com.guwan.backend.model.sys.system.service;
/**
* 数据字典工具类
* @author bool
*/
public interface SysDictService {
/**
* 查找数据字典
* @param table
* @param text
* @param key
* @param value
* @return
*/
String findDict(String table,
String text,
String key,
String value);
}

View File

@ -1,21 +0,0 @@
package com.guwan.backend.model.sys.system.service.impl;
import com.yf.exam.modules.sys.system.mapper.SysDictMapper;
import com.yf.exam.modules.sys.system.service.SysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author bool
*/
@Service
public class SysDictServiceImpl implements SysDictService {
@Autowired
private SysDictMapper sysDictMapper;
@Override
public String findDict(String table, String text, String key, String value) {
return sysDictMapper.findDict(table, text, key, value);
}
}

View File

@ -1,77 +0,0 @@
package com.guwan.backend.model.sys.user.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yf.exam.core.api.ApiRest;
import com.yf.exam.core.api.controller.BaseController;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.core.utils.BeanMapper;
import com.yf.exam.modules.sys.user.dto.SysRoleDTO;
import com.yf.exam.modules.sys.user.entity.SysRole;
import com.yf.exam.modules.sys.user.service.SysRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* 管理用户控制器
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Api(tags = {"管理用户"})
@RestController
@RequestMapping("/exam/api/sys/role")
public class SysRoleController extends BaseController {
@Autowired
private SysRoleService baseService;
/**
* 分页查找
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "分页查找")
@RequestMapping(value = "/paging", method = { RequestMethod.POST})
public ApiRest<IPage<SysRoleDTO>> paging(@RequestBody PagingReqDTO<SysRoleDTO> reqDTO) {
//分页查询并转换
IPage<SysRoleDTO> page = baseService.paging(reqDTO);
return super.success(page);
}
/**
* 查找列表每次最多返回200条数据
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "查找列表")
@RequestMapping(value = "/list", method = { RequestMethod.POST})
public ApiRest<List<SysRoleDTO>> list() {
//分页查询并转换
QueryWrapper<SysRole> wrapper = new QueryWrapper<>();
//转换并返回
List<SysRole> list = baseService.list(wrapper);
//转换数据
List<SysRoleDTO> dtoList = BeanMapper.mapList(list, SysRoleDTO.class);
return super.success(dtoList);
}
}

View File

@ -1,177 +0,0 @@
package com.guwan.backend.model.sys.user.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yf.exam.core.api.ApiRest;
import com.yf.exam.core.api.controller.BaseController;
import com.yf.exam.core.api.dto.BaseIdsReqDTO;
import com.yf.exam.core.api.dto.BaseStateReqDTO;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.sys.user.dto.SysUserDTO;
import com.yf.exam.modules.sys.user.dto.request.SysUserLoginReqDTO;
import com.yf.exam.modules.sys.user.dto.request.SysUserSaveReqDTO;
import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO;
import com.yf.exam.modules.sys.user.entity.SysUser;
import com.yf.exam.modules.sys.user.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
/**
* <p>
* 管理用户控制器
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Api(tags = {"管理用户"})
@RestController
@RequestMapping("/exam/api/sys/user")
public class SysUserController extends BaseController {
@Autowired
private SysUserService baseService;
/**
* 用户登录
* @return
*/
@CrossOrigin
@ApiOperation(value = "用户登录")
@RequestMapping(value = "/login", method = {RequestMethod.POST})
public ApiRest<SysUserLoginDTO> login(@RequestBody SysUserLoginReqDTO reqDTO) {
SysUserLoginDTO respDTO = baseService.login(reqDTO.getUsername(), reqDTO.getPassword());
return super.success(respDTO);
}
/**
* 用户登录
* @return
*/
@CrossOrigin
@ApiOperation(value = "用户登录")
@RequestMapping(value = "/logout", method = {RequestMethod.POST})
public ApiRest logout(HttpServletRequest request) {
String token = request.getHeader("token");
System.out.println("+++++当前会话为:"+token);
baseService.logout(token);
return super.success();
}
/**
* 获取会话
* @return
*/
@ApiOperation(value = "获取会话")
@RequestMapping(value = "/info", method = {RequestMethod.POST})
public ApiRest info(@RequestParam("token") String token) {
SysUserLoginDTO respDTO = baseService.token(token);
return success(respDTO);
}
/**
* 修改用户资料
* @return
*/
@ApiOperation(value = "修改用户资料")
@RequestMapping(value = "/update", method = {RequestMethod.POST})
public ApiRest update(@RequestBody SysUserDTO reqDTO) {
baseService.update(reqDTO);
return success();
}
/**
* 保存或修改系统用户
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "保存或修改")
@RequestMapping(value = "/save", method = {RequestMethod.POST})
public ApiRest save(@RequestBody SysUserSaveReqDTO reqDTO) {
baseService.save(reqDTO);
return success();
}
/**
* 批量删除
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "批量删除")
@RequestMapping(value = "/delete", method = { RequestMethod.POST})
public ApiRest edit(@RequestBody BaseIdsReqDTO reqDTO) {
//根据ID删除
baseService.removeByIds(reqDTO.getIds());
return super.success();
}
/**
* 分页查找
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "分页查找")
@RequestMapping(value = "/paging", method = { RequestMethod.POST})
public ApiRest<IPage<SysUserDTO>> paging(@RequestBody PagingReqDTO<SysUserDTO> reqDTO) {
//分页查询并转换
IPage<SysUserDTO> page = baseService.paging(reqDTO);
return super.success(page);
}
/**
* 修改状态
* @param reqDTO
* @return
*/
@RequiresRoles("sa")
@ApiOperation(value = "修改状态")
@RequestMapping(value = "/state", method = { RequestMethod.POST})
public ApiRest state(@RequestBody BaseStateReqDTO reqDTO) {
// 条件
QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
wrapper.lambda()
.in(SysUser::getId, reqDTO.getIds())
.ne(SysUser::getUserName, "admin");
SysUser record = new SysUser();
record.setState(reqDTO.getState());
baseService.update(record, wrapper);
return super.success();
}
/**
* 保存或修改系统用户
* @return
*/
@ApiOperation(value = "学员注册")
@RequestMapping(value = "/reg", method = {RequestMethod.POST})
public ApiRest<SysUserLoginDTO> reg(@RequestBody SysUserDTO reqDTO) {
SysUserLoginDTO respDTO = baseService.reg(reqDTO);
return success(respDTO);
}
/**
* 快速注册如果手机号存在则登录不存在就注册
* @return
*/
@ApiOperation(value = "快速注册")
@RequestMapping(value = "/quick-reg", method = {RequestMethod.POST})
public ApiRest<SysUserLoginDTO> quick(@RequestBody SysUserDTO reqDTO) {
SysUserLoginDTO respDTO = baseService.quickReg(reqDTO);
return success(respDTO);
}
}

View File

@ -1,30 +0,0 @@
package com.guwan.backend.model.sys.user.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 角色请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Data
@ApiModel(value="角色", description="角色")
public class SysRoleDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "角色ID", required=true)
private String id;
@ApiModelProperty(value = "角色名称", required=true)
private String roleName;
}

View File

@ -1,55 +0,0 @@
package com.guwan.backend.model.sys.user.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 管理用户请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Data
@ApiModel(value="管理用户", description="管理用户")
public class SysUserDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID", required=true)
private String id;
@ApiModelProperty(value = "用户名", required=true)
private String userName;
@ApiModelProperty(value = "真实姓名", required=true)
private String realName;
@ApiModelProperty(value = "密码", required=true)
private String password;
@ApiModelProperty(value = "密码盐", required=true)
private String salt;
@ApiModelProperty(value = "角色列表", required=true)
private String roleIds;
@ApiModelProperty(value = "部门ID", required=true)
private String departId;
@ApiModelProperty(value = "创建时间", required=true)
private Date createTime;
@ApiModelProperty(value = "更新时间", required=true)
private Date updateTime;
@ApiModelProperty(value = "状态", required=true)
private Integer state;
}

View File

@ -1,33 +0,0 @@
package com.guwan.backend.model.sys.user.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 用户角色请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Data
@ApiModel(value="用户角色", description="用户角色")
public class SysUserRoleDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID", required=true)
private String id;
@ApiModelProperty(value = "用户ID", required=true)
private String userId;
@ApiModelProperty(value = "角色ID", required=true)
private String roleId;
}

View File

@ -1,29 +0,0 @@
package com.guwan.backend.model.sys.user.dto.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 管理员登录请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Data
@ApiModel(value="管理员登录请求类", description="管理员登录请求类")
public class SysUserLoginReqDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户名", required=true)
private String username;
@ApiModelProperty(value = "密码", required=true)
private String password;
}

View File

@ -1,43 +0,0 @@
package com.guwan.backend.model.sys.user.dto.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* <p>
* 管理员登录请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Data
@ApiModel(value="管理员保存请求类", description="管理员保存请求类")
public class SysUserSaveReqDTO implements Serializable {
@ApiModelProperty(value = "ID", required=true)
private String id;
@ApiModelProperty(value = "用户名", required=true)
private String userName;
@ApiModelProperty(value = "头像", required=true)
private String avatar;
@ApiModelProperty(value = "真实姓名", required=true)
private String realName;
@ApiModelProperty(value = "密码", required=true)
private String password;
@ApiModelProperty(value = "部门", required=true)
private String departId;
@ApiModelProperty(value = "角色列表", required=true)
private List<String> roles;
}

View File

@ -1,26 +0,0 @@
package com.guwan.backend.model.sys.user.dto.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* 会话检查请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Data
@ApiModel(value="会话检查请求类", description="会话检查请求类")
public class SysUserTokenReqDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "用户名", required=true)
private String token;
}

View File

@ -1,55 +0,0 @@
package com.guwan.backend.model.sys.user.dto.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* <p>
* 管理用户请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Data
@ApiModel(value="管理用户登录响应类", description="管理用户登录响应类")
public class SysUserLoginDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID", required=true)
private String id;
@ApiModelProperty(value = "用户名", required=true)
private String userName;
@ApiModelProperty(value = "真实姓名", required=true)
private String realName;
@ApiModelProperty(value = "角色列表", required=true)
private String roleIds;
@ApiModelProperty(value = "部门ID", required=true)
private String departId;
@ApiModelProperty(value = "创建时间", required=true)
private Date createTime;
@ApiModelProperty(value = "更新时间", required=true)
private Date updateTime;
@ApiModelProperty(value = "状态", required=true)
private Integer state;
@ApiModelProperty(value = "角色列表", required=true)
private List<String> roles;
@ApiModelProperty(value = "登录令牌", required=true)
private String token;
}

View File

@ -1,36 +0,0 @@
package com.guwan.backend.model.sys.user.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
/**
* <p>
* 角色实体类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Data
@TableName("sys_role")
public class SysRole extends Model<SysRole> {
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 角色名称
*/
@TableField("role_name")
private String roleName;
}

View File

@ -1,83 +0,0 @@
package com.guwan.backend.model.sys.user.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import java.util.Date;
/**
* <p>
* 管理用户实体类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Data
@TableName("sys_user")
public class SysUser extends Model<SysUser> {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 用户名
*/
@TableField("user_name")
private String userName;
/**
* 真实姓名
*/
@TableField("real_name")
private String realName;
/**
* 密码
*/
private String password;
/**
* 密码盐
*/
private String salt;
/**
* 角色列表
*/
@TableField("role_ids")
private String roleIds;
/**
* 部门ID
*/
@TableField("depart_id")
private String departId;
/**
* 创建时间
*/
@TableField("create_time")
private Date createTime;
/**
* 更新时间
*/
@TableField("update_time")
private Date updateTime;
/**
* 状态
*/
private Integer state;
}

View File

@ -1,42 +0,0 @@
package com.guwan.backend.model.sys.user.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
/**
* <p>
* 用户角色实体类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Data
@TableName("sys_user_role")
public class SysUserRole extends Model<SysUserRole> {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 用户ID
*/
@TableField("user_id")
private String userId;
/**
* 角色ID
*/
@TableField("role_id")
private String roleId;
}

View File

@ -1,15 +0,0 @@
package com.guwan.backend.model.sys.user.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yf.exam.modules.sys.user.entity.SysRole;
/**
* <p>
* 角色Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
public interface SysRoleMapper extends BaseMapper<SysRole> {
}

View File

@ -1,16 +0,0 @@
package com.guwan.backend.model.sys.user.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yf.exam.modules.sys.user.entity.SysUser;
/**
* <p>
* 管理用户Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
public interface SysUserMapper extends BaseMapper<SysUser> {
}

View File

@ -1,16 +0,0 @@
package com.guwan.backend.model.sys.user.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yf.exam.modules.sys.user.entity.SysUserRole;
/**
* <p>
* 用户角色Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {
}

View File

@ -1,25 +0,0 @@
package com.guwan.backend.model.sys.user.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.sys.user.dto.SysRoleDTO;
import com.yf.exam.modules.sys.user.entity.SysRole;
/**
* <p>
* 角色业务类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
public interface SysRoleService extends IService<SysRole> {
/**
* 分页查询数据
* @param reqDTO
* @return
*/
IPage<SysRoleDTO> paging(PagingReqDTO<SysRoleDTO> reqDTO);
}

View File

@ -1,61 +0,0 @@
package com.guwan.backend.model.sys.user.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.sys.user.dto.SysUserRoleDTO;
import com.yf.exam.modules.sys.user.entity.SysUserRole;
import java.util.List;
/**
* <p>
* 用户角色业务类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
public interface SysUserRoleService extends IService<SysUserRole> {
/**
* 分页查询数据
* @param reqDTO
* @return
*/
IPage<SysUserRoleDTO> paging(PagingReqDTO<SysUserRoleDTO> reqDTO);
/**
* 查找用户角色列表
* @param userId
* @return
*/
List<String> listRoles(String userId);
/**
* 保存全部角色
* @param userId
* @param ids
* @return
*/
String saveRoles(String userId, List<String> ids);
/**
* 是否学生
* @param userId
* @return
*/
boolean isStudent(String userId);
/**
* 是否老师
*/
boolean isTeacher(String userId);
/**
* 是否管理
* @param userId
* @return
*/
boolean isAdmin(String userId);
}

View File

@ -1,72 +0,0 @@
package com.guwan.backend.model.sys.user.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.sys.user.dto.SysUserDTO;
import com.yf.exam.modules.sys.user.dto.request.SysUserSaveReqDTO;
import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO;
import com.yf.exam.modules.sys.user.entity.SysUser;
/**
* <p>
* 管理用户业务类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
public interface SysUserService extends IService<SysUser> {
/**
* 分页查询数据
* @param reqDTO
* @return
*/
IPage<SysUserDTO> paging(PagingReqDTO<SysUserDTO> reqDTO);
/**
* 登录
* @param userName
* @param password
* @return
*/
SysUserLoginDTO login(String userName, String password);
/**
* 获取管理会话
* @param token
* @return
*/
SysUserLoginDTO token(String token);
/**
* 退出登录
* @param token
*/
void logout(String token);
/**
* 修改用户资料
* @param reqDTO
*/
void update(SysUserDTO reqDTO);
/**
* 保存添加系统用户
* @param reqDTO
*/
void save(SysUserSaveReqDTO reqDTO);
/**
* 用户注册
* @param reqDTO
*/
SysUserLoginDTO reg(SysUserDTO reqDTO);
/**
* 快速注册
* @param reqDTO
*/
SysUserLoginDTO quickReg(SysUserDTO reqDTO);
}

View File

@ -1,42 +0,0 @@
package com.guwan.backend.model.sys.user.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.sys.user.dto.SysRoleDTO;
import com.yf.exam.modules.sys.user.entity.SysRole;
import com.yf.exam.modules.sys.user.mapper.SysRoleMapper;
import com.yf.exam.modules.sys.user.service.SysRoleService;
import org.springframework.stereotype.Service;
/**
* <p>
* 语言设置 服务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
@Override
public IPage<SysRoleDTO> paging(PagingReqDTO<SysRoleDTO> reqDTO) {
//创建分页对象
IPage<SysRole> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
//查询条件
QueryWrapper<SysRole> wrapper = new QueryWrapper<>();
//获得数据
IPage<SysRole> page = this.page(query, wrapper);
//转换结果
IPage<SysRoleDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<SysRoleDTO>>(){});
return pageData;
}
}

View File

@ -1,128 +0,0 @@
package com.guwan.backend.model.sys.user.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.sys.user.dto.SysUserRoleDTO;
import com.yf.exam.modules.sys.user.entity.SysUserRole;
import com.yf.exam.modules.sys.user.mapper.SysUserRoleMapper;
import com.yf.exam.modules.sys.user.service.SysUserRoleService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 语言设置 服务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Service
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRole> implements SysUserRoleService {
@Override
public IPage<SysUserRoleDTO> paging(PagingReqDTO<SysUserRoleDTO> reqDTO) {
//创建分页对象
IPage<SysUserRole> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
//查询条件
QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
//获得数据
IPage<SysUserRole> page = this.page(query, wrapper);
//转换结果
IPage<SysUserRoleDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<SysUserRoleDTO>>(){});
return pageData;
}
@Override
public List<String> listRoles(String userId) {
QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUserRole::getUserId, userId);
List<SysUserRole> list = this.list(wrapper);
List<String> roles = new ArrayList<>();
if(!CollectionUtils.isEmpty(list)){
for(SysUserRole item: list){
roles.add(item.getRoleId());
}
}
return roles;
}
@Override
public String saveRoles(String userId, List<String> ids) {
// 删除全部角色
QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUserRole::getUserId, userId);
this.remove(wrapper);
if(!CollectionUtils.isEmpty(ids)){
List<SysUserRole> list = new ArrayList<>();
String roleIds = null;
for(String item: ids){
SysUserRole role = new SysUserRole();
role.setRoleId(item);
role.setUserId(userId);
list.add(role);
if(StringUtils.isEmpty(roleIds)){
roleIds = item;
}else{
roleIds+=","+item;
}
}
this.saveBatch(list);
return roleIds;
}
return "";
}
@Override
public boolean isStudent(String userId) {
// 学生角色
QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUserRole::getUserId, userId)
.eq(SysUserRole::getRoleId, "student");
return this.count(wrapper) > 0;
}
@Override
public boolean isTeacher(String userId) {
// 学生角色
QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUserRole::getUserId, userId)
.eq(SysUserRole::getRoleId, "teacher");
return this.count(wrapper) > 0;
}
@Override
public boolean isAdmin(String userId) {
// 学生角色
QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUserRole::getUserId, userId)
.eq(SysUserRole::getRoleId, "sa");
return this.count(wrapper) > 0;
}
}

View File

@ -1,253 +0,0 @@
package com.guwan.backend.model.sys.user.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yf.exam.ability.shiro.jwt.JwtUtils;
import com.yf.exam.core.api.ApiError;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.core.enums.CommonState;
import com.yf.exam.core.exception.ServiceException;
import com.yf.exam.core.utils.BeanMapper;
import com.yf.exam.core.utils.passwd.PassHandler;
import com.yf.exam.core.utils.passwd.PassInfo;
import com.yf.exam.modules.sys.user.dto.SysUserDTO;
import com.yf.exam.modules.sys.user.dto.request.SysUserSaveReqDTO;
import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO;
import com.yf.exam.modules.sys.user.entity.SysUser;
import com.yf.exam.modules.sys.user.mapper.SysUserMapper;
import com.yf.exam.modules.sys.user.service.SysUserRoleService;
import com.yf.exam.modules.sys.user.service.SysUserService;
import com.yf.exam.modules.user.UserUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 语言设置 服务实现类
* </p>
*
* @author 聪明笨狗
* @since 2020-04-13 16:57
*/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
@Autowired
private SysUserRoleService sysUserRoleService;
@Override
public IPage<SysUserDTO> paging(PagingReqDTO<SysUserDTO> reqDTO) {
//创建分页对象
IPage<SysUser> query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
//查询条件
QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
SysUserDTO params = reqDTO.getParams();
if(params!=null){
if(!StringUtils.isBlank(params.getUserName())){
wrapper.lambda().like(SysUser::getUserName, params.getUserName());
}
if(!StringUtils.isBlank(params.getRealName())){
wrapper.lambda().like(SysUser::getRealName, params.getRealName());
}
}
//获得数据
IPage<SysUser> page = this.page(query, wrapper);
//转换结果
IPage<SysUserDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<SysUserDTO>>(){});
return pageData;
}
@Override
public SysUserLoginDTO login(String userName, String password) {
QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUser::getUserName, userName);
SysUser user = this.getOne(wrapper, false);
if(user == null){
throw new ServiceException(ApiError.ERROR_90010002);
}
// 被禁用
if(user.getState().equals(CommonState.ABNORMAL)){
throw new ServiceException(ApiError.ERROR_90010005);
}
boolean check = PassHandler.checkPass(password,user.getSalt(), user.getPassword());
if(!check){
throw new ServiceException(ApiError.ERROR_90010002);
}
return this.setToken(user);
}
@Override
public SysUserLoginDTO token(String token) {
// 获得会话
String username = JwtUtils.getUsername(token);
// 校验结果
boolean check = JwtUtils.verify(token, username);
if(!check){
throw new ServiceException(ApiError.ERROR_90010002);
}
QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUser::getUserName, username);
SysUser user = this.getOne(wrapper, false);
if(user == null){
throw new ServiceException(ApiError.ERROR_10010002);
}
// 被禁用
if(user.getState().equals(CommonState.ABNORMAL)){
throw new ServiceException(ApiError.ERROR_90010005);
}
return this.setToken(user);
}
@Override
public void logout(String token) {
// 仅退出当前会话
SecurityUtils.getSubject().logout();
}
@Override
public void update(SysUserDTO reqDTO) {
String pass = reqDTO.getPassword();
if(!StringUtils.isBlank(pass)){
PassInfo passInfo = PassHandler.buildPassword(pass);
SysUser user = this.getById(UserUtils.getUserId());
user.setPassword(passInfo.getPassword());
user.setSalt(passInfo.getSalt());
this.updateById(user);
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(SysUserSaveReqDTO reqDTO) {
List<String> roles = reqDTO.getRoles();
if(CollectionUtils.isEmpty(roles)){
throw new ServiceException(ApiError.ERROR_90010003);
}
// 保存基本信息
SysUser user = new SysUser();
BeanMapper.copy(reqDTO, user);
// 添加模式
if(StringUtils.isBlank(user.getId())){
user.setId(IdWorker.getIdStr());
}
// 修改密码
if(!StringUtils.isBlank(reqDTO.getPassword())){
PassInfo pass = PassHandler.buildPassword(reqDTO.getPassword());
user.setPassword(pass.getPassword());
user.setSalt(pass.getSalt());
}
// 保存角色信息
String roleIds = sysUserRoleService.saveRoles(user.getId(), roles);
user.setRoleIds(roleIds);
this.saveOrUpdate(user);
}
@Transactional(rollbackFor = Exception.class)
@Override
public SysUserLoginDTO reg(SysUserDTO reqDTO) {
QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUser::getUserName, reqDTO.getUserName());
int count = this.count(wrapper);
if(count > 0){
throw new ServiceException(1, "用户名已存在,换一个吧!");
}
// 保存用户
SysUser user = new SysUser();
user.setId(IdWorker.getIdStr());
user.setUserName(reqDTO.getUserName());
user.setRealName(reqDTO.getRealName());
PassInfo passInfo = PassHandler.buildPassword(reqDTO.getPassword());
user.setPassword(passInfo.getPassword());
user.setSalt(passInfo.getSalt());
// 保存角色
List<String> roles = new ArrayList<>();
roles.add("student");
String roleIds = sysUserRoleService.saveRoles(user.getId(), roles);
user.setRoleIds(roleIds);
this.save(user);
return this.setToken(user);
}
@Override
public SysUserLoginDTO quickReg(SysUserDTO reqDTO) {
QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(SysUser::getUserName, reqDTO.getUserName());
wrapper.last(" LIMIT 1 ");
SysUser user = this.getOne(wrapper);
if(user!=null){
return this.setToken(user);
}
return this.reg(reqDTO);
}
/**
* 保存会话信息
* @param user
* @return
*/
private SysUserLoginDTO setToken(SysUser user){
SysUserLoginDTO respDTO = new SysUserLoginDTO();
BeanMapper.copy(user, respDTO);
// 生成Token
String token = JwtUtils.sign(user.getUserName());
respDTO.setToken(token);
// 填充角色
List<String> roles = sysUserRoleService.listRoles(user.getId());
respDTO.setRoles(roles);
return respDTO;
}
}

View File

@ -1,56 +0,0 @@
package com.guwan.backend.model.user;
import com.yf.exam.core.api.ApiError;
import com.yf.exam.core.exception.ServiceException;
import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO;
import org.apache.shiro.SecurityUtils;
/**
* 用户静态工具类
* @author bool
*/
public class UserUtils {
/**
* 获取当前登录用户的ID
* @param throwable
* @return
*/
public static String getUserId(boolean throwable){
try {
return ((SysUserLoginDTO) SecurityUtils.getSubject().getPrincipal()).getId();
}catch (Exception e){
if(throwable){
throw new ServiceException(ApiError.ERROR_10010002);
}
return null;
}
}
/**
* 获取当前登录用户的ID
* @param throwable
* @return
*/
public static boolean isAdmin(boolean throwable){
try {
SysUserLoginDTO dto = ((SysUserLoginDTO) SecurityUtils.getSubject().getPrincipal());
return dto.getRoles().contains("sa");
}catch (Exception e){
if(throwable){
throw new ServiceException(ApiError.ERROR_10010002);
}
}
return false;
}
/**
* 获取当前登录用户的ID默认是会抛异常的
* @return
*/
public static String getUserId(){
return getUserId(true);
}
}

View File

@ -1,76 +0,0 @@
package com.guwan.backend.model.user.book.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yf.exam.core.api.ApiRest;
import com.yf.exam.core.api.controller.BaseController;
import com.yf.exam.core.api.dto.BaseIdRespDTO;
import com.yf.exam.core.api.dto.BaseIdsReqDTO;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.user.book.dto.UserBookDTO;
import com.yf.exam.modules.user.book.service.UserBookService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 错题本控制器
* </p>
*
* @author 聪明笨狗
* @since 2020-05-27 17:56
*/
@Api(tags={"错题本"})
@RestController
@RequestMapping("/exam/api/user/wrong-book")
public class UserBookController extends BaseController {
@Autowired
private UserBookService baseService;
/**
* 批量删除
* @param reqDTO
* @return
*/
@ApiOperation(value = "批量删除")
@RequestMapping(value = "/delete", method = { RequestMethod.POST})
public ApiRest delete(@RequestBody BaseIdsReqDTO reqDTO) {
//根据ID删除
baseService.removeByIds(reqDTO.getIds());
return super.success();
}
/**
* 分页查找
* @param reqDTO
* @return
*/
@ApiOperation(value = "分页查找")
@RequestMapping(value = "/paging", method = { RequestMethod.POST})
public ApiRest<IPage<UserBookDTO>> paging(@RequestBody PagingReqDTO<UserBookDTO> reqDTO) {
//分页查询并转换
IPage<UserBookDTO> page = baseService.paging(reqDTO);
return super.success(page);
}
/**
* 查找列表每次最多返回200条数据
* @param reqDTO
* @return
*/
@ApiOperation(value = "查找列表")
@RequestMapping(value = "/next", method = { RequestMethod.POST})
public ApiRest<BaseIdRespDTO> nextQu(@RequestBody UserBookDTO reqDTO) {
//转换并返回
String quId = baseService.findNext(reqDTO.getExamId(), reqDTO.getQuId());
return super.success(new BaseIdRespDTO(quId));
}
}

View File

@ -1,52 +0,0 @@
package com.guwan.backend.model.user.book.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 错题本请求类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-27 17:56
*/
@Data
@ApiModel(value="错题本", description="错题本")
public class UserBookDTO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "ID", required=true)
private String id;
@ApiModelProperty(value = "考试ID", required=true)
private String examId;
@ApiModelProperty(value = "用户ID", required=true)
private String userId;
@ApiModelProperty(value = "题目ID", required=true)
private String quId;
@ApiModelProperty(value = "加入时间", required=true)
private Date createTime;
@ApiModelProperty(value = "最近错误时间", required=true)
private Date updateTime;
@ApiModelProperty(value = "错误时间", required=true)
private Integer wrongCount;
@ApiModelProperty(value = "题目标题", required=true)
private String title;
@ApiModelProperty(value = "错题序号", required=true)
private Integer sort;
}

View File

@ -1,78 +0,0 @@
package com.guwan.backend.model.user.book.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import java.util.Date;
/**
* <p>
* 错题本实体类
* </p>
*
* @author 聪明笨狗
* @since 2020-05-27 17:56
*/
@Data
@TableName("el_user_book")
public class UserBook extends Model<UserBook> {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 考试ID
*/
@TableField("exam_id")
private String examId;
/**
* 用户ID
*/
@TableField("user_id")
private String userId;
/**
* 题目ID
*/
@TableField("qu_id")
private String quId;
/**
* 加入时间
*/
@TableField("create_time")
private Date createTime;
/**
* 最近错误时间
*/
@TableField("update_time")
private Date updateTime;
/**
* 错误时间
*/
@TableField("wrong_count")
private Integer wrongCount;
/**
* 题目标题
*/
private String title;
/**
* 错题序号
*/
private Integer sort;
}

View File

@ -1,16 +0,0 @@
package com.guwan.backend.model.user.book.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yf.exam.modules.user.book.entity.UserBook;
/**
* <p>
* 错题本Mapper
* </p>
*
* @author 聪明笨狗
* @since 2020-05-27 17:56
*/
public interface UserBookMapper extends BaseMapper<UserBook> {
}

Some files were not shown because too many files have changed in this diff Show More