caozixuan 1 жил өмнө
parent
commit
ab54162a37

+ 66 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/CourseDimensionDto.java

@@ -0,0 +1,66 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+import com.qmth.teachcloud.common.annotation.ExcelNote;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Description: 课程知识点数据导入dto
+ * @Author: CaoZixuan
+ * @Date: 2024-02-27
+ */
+public class CourseDimensionDto {
+
+    @ApiModelProperty("课程代码")
+    @ExcelNote(value = "课程代码")
+    @NotNull
+    private String courseCode;
+
+    @ApiModelProperty("课程名称")
+    @ExcelNote(value = "课程名称")
+    @NotNull
+    private String courseName;
+
+    @ApiModelProperty("一级属性内容")
+    @ExcelNote(value = "一级属性内容")
+    @NotNull
+    private String firstDimensionName;
+
+    @ApiModelProperty("二级属性内容")
+    @ExcelNote(value = "二级属性内容")
+    @NotNull
+    private String secondDimensionName;
+
+    public String getCourseCode() {
+        return courseCode;
+    }
+
+    public void setCourseCode(String courseCode) {
+        this.courseCode = courseCode;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public String getFirstDimensionName() {
+        return firstDimensionName;
+    }
+
+    public void setFirstDimensionName(String firstDimensionName) {
+        this.firstDimensionName = firstDimensionName;
+    }
+
+    public String getSecondDimensionName() {
+        return secondDimensionName;
+    }
+
+    public void setSecondDimensionName(String secondDimensionName) {
+        this.secondDimensionName = secondDimensionName;
+    }
+}

+ 20 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/controller/CourseDimensionController.java

@@ -0,0 +1,20 @@
+package com.qmth.distributed.print.business.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 课程知识点表 前端控制器
+ * </p>
+ *
+ * @author CaoZixuan
+ * @since 2024-02-27
+ */
+@RestController
+@RequestMapping("/course-dimension")
+public class CourseDimensionController {
+
+}

+ 113 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/CourseDimension.java

@@ -0,0 +1,113 @@
+package com.qmth.distributed.print.business.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.teachcloud.common.base.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * <p>
+ * 课程知识点表
+ * </p>
+ *
+ * @author CaoZixuan
+ * @since 2024-02-27
+ */
+@ApiModel(value="CourseDimension对象", description="课程知识点表")
+public class CourseDimension extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "学校id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long schoolId;
+
+    @ApiModelProperty(value = "学期id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long semesterId;
+
+    @ApiModelProperty(value = "考试id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examId;
+
+    @ApiModelProperty(value = "课程编号")
+    private String courseCode;
+
+    @ApiModelProperty(value = "知识点编号")
+    private String code;
+
+    @ApiModelProperty(value = "知识点名称")
+    private String name;
+
+    @ApiModelProperty(value = "排序")
+    private Integer number;
+
+    @ApiModelProperty(value = "父id(顶级知识点父id为0)")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long parentId;
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getSemesterId() {
+        return semesterId;
+    }
+
+    public void setSemesterId(Long semesterId) {
+        this.semesterId = semesterId;
+    }
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public String getCourseCode() {
+        return courseCode;
+    }
+
+    public void setCourseCode(String courseCode) {
+        this.courseCode = courseCode;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public Long getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+}

+ 103 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/CourseDimensionCodeEnum.java

@@ -0,0 +1,103 @@
+package com.qmth.distributed.print.business.enums;
+
+import com.qmth.boot.core.exception.StatusException;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 课程知识点编号枚举
+ * @Author: CaoZixuan
+ * @Date: 2022-10-18
+ */
+public enum CourseDimensionCodeEnum {
+    A("A", 1),
+    B("B", 2),
+    C("C", 3),
+    D("D", 4),
+    E("E", 5),
+    F("F", 6),
+    G("G", 7),
+    H("H", 8),
+    I("I", 9),
+    J("J", 10),
+    K("K", 11),
+    L("L", 12),
+    M("M", 13),
+    N("N", 14),
+    O("O", 15),
+    P("P", 16),
+    Q("Q", 17),
+    R("R", 18),
+    S("S", 19),
+    T("T", 20),
+    U("U", 21),
+    V("V", 22),
+    W("W", 23),
+    X("X", 24),
+    Y("Y", 25),
+    Z("Z", 26),
+    a("a", 27),
+    b("b", 28),
+    c("c", 29),
+    d("d", 30),
+    e("e", 31),
+    f("f", 32),
+    g("g", 33),
+    h("h", 34),
+    i("i", 35),
+    j("j", 36),
+    k("k", 37),
+    l("l", 38),
+    m("m", 39),
+    n("n", 40),
+    o("o", 41),
+    p("p", 42),
+    q("q", 43),
+    r("r", 44),
+    s("s", 45),
+    t("t", 46),
+    u("u", 47),
+    v("v", 48),
+    w("w", 49),
+    x("x", 50),
+    y("y", 51),
+    z("z", 52);
+
+    private final String code;
+    private final int index;
+
+    CourseDimensionCodeEnum(String code, int index) {
+        this.code = code;
+        this.index = index;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public int getIndex() {
+        return index;
+    }
+
+    /**
+     * 根据索引查找编号
+     *
+     * @param index 索引
+     * @return 编号
+     */
+    public static String getCodeByIndex(int index) {
+        String result = "";
+        List<CourseDimensionCodeEnum> courseDimensionCodeEnumList = Arrays.stream(CourseDimensionCodeEnum.values())
+                .filter(e -> index == e.getIndex())
+                .collect(Collectors.toList());
+        int size = courseDimensionCodeEnumList.size();
+        if (size > 1) {
+            throw new StatusException("index:" + index + "的编号枚举异常");
+        } else if (size == 1) {
+            result = courseDimensionCodeEnumList.get(0).getCode();
+        }
+        return result;
+    }
+}

+ 16 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/CourseDimensionMapper.java

@@ -0,0 +1,16 @@
+package com.qmth.distributed.print.business.mapper;
+
+import com.qmth.distributed.print.business.entity.CourseDimension;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 课程知识点表 Mapper 接口
+ * </p>
+ *
+ * @author CaoZixuan
+ * @since 2024-02-27
+ */
+public interface CourseDimensionMapper extends BaseMapper<CourseDimension> {
+
+}

+ 43 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/CourseDimensionService.java

@@ -0,0 +1,43 @@
+package com.qmth.distributed.print.business.service;
+
+import com.qmth.distributed.print.business.entity.CourseDimension;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.teachcloud.common.entity.SysUser;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+
+/**
+ * <p>
+ * 课程知识点表 服务类
+ * </p>
+ *
+ * @author CaoZixuan
+ * @since 2024-02-27
+ */
+public interface CourseDimensionService extends IService<CourseDimension> {
+
+    /**
+     * 导入课程知识点
+     *
+     * @param requestUser 请求人
+     * @param file        知识点excel
+     * @param examId      考试id
+     * @param courseCode  课程编号
+     */
+    void importCourseDimension(SysUser requestUser, MultipartFile file, Long examId, String courseCode)
+            throws IOException, NoSuchFieldException;
+
+    /**
+     * 自动生成课程一二级属性编号
+     * <p>
+     * 一级属性编号从A-Z,二级属性编号为A1,A2。。。B1,B2。。。Z1,Z2。。。
+     * </P>
+     *
+     * @param examId     考试id
+     * @param courseCode 课程编号
+     * @param parentId   父属性id(根节点id为0)
+     * @return 生成的编号
+     */
+    String autoCreateDimensionCode(Long examId, String courseCode, Long parentId);
+}

+ 135 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/CourseDimensionServiceImpl.java

@@ -0,0 +1,135 @@
+package com.qmth.distributed.print.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
+import com.qmth.boot.core.exception.StatusException;
+import com.qmth.distributed.print.business.bean.dto.CourseDimensionDto;
+import com.qmth.distributed.print.business.entity.CourseDimension;
+import com.qmth.distributed.print.business.enums.CourseDimensionCodeEnum;
+import com.qmth.distributed.print.business.mapper.CourseDimensionMapper;
+import com.qmth.distributed.print.business.service.CourseDimensionService;
+import com.qmth.teachcloud.common.entity.SysUser;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.util.ExcelUtil;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 课程知识点表 服务实现类
+ * </p>
+ *
+ * @author CaoZixuan
+ * @since 2024-02-27
+ */
+@Service
+public class CourseDimensionServiceImpl extends ServiceImpl<CourseDimensionMapper, CourseDimension> implements CourseDimensionService {
+
+    @Transactional
+    @Override
+    public void importCourseDimension(SysUser requestUser, MultipartFile file, Long examId, String courseCode)
+            throws IOException, NoSuchFieldException {
+        List<String> errorMsgList = new ArrayList<>();
+        List<CourseDimensionDto> list = new ArrayList<>();
+        ExcelUtil.excelReader(file.getInputStream(), Lists.newArrayList(CourseDimensionDto.class), (finalExcelList, finalColumnNameList, finalExcelErrorList) -> {
+            for (int i = 0; i < finalExcelList.size(); i++) {
+                LinkedMultiValueMap<Integer, Object> excelMap = finalExcelList.get(i);
+                List<Object> courseDimensionDtoList = excelMap.get(i);
+                // 无数据,跳过
+                if (CollectionUtils.isEmpty(courseDimensionDtoList)) {
+                    continue;
+                }
+                for (int y = 0; y < courseDimensionDtoList.size(); y++) {
+
+                    // 行索引
+                    Integer rowIndex = y + 1;
+                    CourseDimensionDto courseDimensionDto = (CourseDimensionDto) courseDimensionDtoList.get(y);
+                    String excelCourseCode = StringUtils.trimToNull(courseDimensionDto.getCourseCode());
+                    String excelCourseName = StringUtils.trimToNull(courseDimensionDto.getCourseName());
+                    String firstDimensionName = StringUtils.trimToNull(courseDimensionDto.getFirstDimensionName());
+                    String secondDimensionName = StringUtils.trimToNull(courseDimensionDto.getSecondDimensionName());
+
+                    // 本行全部列为空,跳过
+                    if (StringUtils.isAllBlank(excelCourseCode, excelCourseName, firstDimensionName, secondDimensionName)) {
+                        continue;
+                    }
+                    if (courseCode.equals(excelCourseCode)) {
+                        errorMsgList.add(String.format("第[%s]行,课程代码异常", rowIndex));
+                    }
+                    list.add(courseDimensionDto);
+                }
+            }
+            return finalExcelList;
+        }, 2);
+        if (CollectionUtils.isNotEmpty(errorMsgList)) {
+            throw ExceptionResultEnum.ERROR.exception(String.join(";", errorMsgList));
+        } else {
+            // 处理要新增的考察点
+            // TODO: 2024/2/27  
+        }
+    }
+
+    @Override
+    public String autoCreateDimensionCode(Long examId, String courseCode, Long parentId) {
+        // 一级属性
+        boolean isPrimaryProperty = parentId == null || parentId == 0;
+        int primaryPropertyNumber;
+        int secondaryPropertyNumber;
+        String code;
+        List<CourseDimension> sameLevelPropertyList = this.list(
+                new QueryWrapper<CourseDimension>().lambda().eq(CourseDimension::getExamId, examId).eq(CourseDimension::getCourseCode, courseCode).eq(CourseDimension::getParentId, parentId)
+                        .orderByDesc(CourseDimension::getNumber));
+        if (sameLevelPropertyList.size() > 0) {
+            // 当前级别属性已经有值
+            if (isPrimaryProperty) {
+                // 一级属性
+                primaryPropertyNumber = sameLevelPropertyList.get(0).getNumber() + 1;
+                code = CourseDimensionCodeEnum.getCodeByIndex(primaryPropertyNumber);
+                if (code == null || code.length() == 0) {
+                    CourseDimensionCodeEnum[] questionPropertyCodeEnums = CourseDimensionCodeEnum.values();
+                    Set<String> alreadyUsedCodeSet = sameLevelPropertyList.stream().map(CourseDimension::getCode).collect(Collectors.toSet());
+                    // 最大编号已经超过属性编号枚举,则查询是否有,没有使用过的编号
+                    Set<String> canUseCodeSet = Arrays.stream(questionPropertyCodeEnums)
+                            .filter(e -> !alreadyUsedCodeSet.contains(e.getCode()))
+                            .sorted(Comparator.comparing(CourseDimensionCodeEnum::getIndex))
+                            .map(CourseDimensionCodeEnum::getCode).collect(Collectors.toSet());
+                    if (canUseCodeSet.size() == 0) {
+                        throw new StatusException("课程属性一级结构编号已经用完");
+                    }
+                    code = canUseCodeSet.iterator().next();
+                }
+            } else {
+                // 二级属性
+                CourseDimension primaryProperty = this.getById(parentId);
+                if (Objects.isNull(primaryProperty)) {
+                    throw new StatusException("未找到对应的一级属性");
+                }
+                secondaryPropertyNumber = sameLevelPropertyList.get(0).getNumber() + 1;
+                code = primaryProperty.getCode() + secondaryPropertyNumber;
+            }
+        } else {
+            // 当前级别还未建立属性
+            if (isPrimaryProperty) {
+                // 一级属性
+                code = CourseDimensionCodeEnum.A.getCode();
+            } else {
+                // 二级属性
+                CourseDimension primaryProperty = this.getById(parentId);
+                if (Objects.isNull(primaryProperty)) {
+                    throw new StatusException("未找到对应的一级属性");
+                }
+                code = primaryProperty.getCode() + 1;
+            }
+        }
+        return code;
+    }
+}

+ 1 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/TaskLogicService.java

@@ -119,6 +119,7 @@ public interface TaskLogicService {
 
     /**
      * 处理考生字典导入
+     *
      * @param map 数据源
      * @return 结果
      * @throws Exception 异常

+ 20 - 0
distributed-print-business/src/main/resources/db/log/脚本-caozx.sql

@@ -0,0 +1,20 @@
+CREATE TABLE `course_dimension` (
+    `id` BIGINT(20) NOT NULL COMMENT 'id',
+    `school_id` BIGINT(20) NOT NULL COMMENT '学校id',
+    `semester_id` BIGINT(20) NOT NULL COMMENT '学期id',
+    `exam_id` BIGINT(20) NOT NULL COMMENT '考试id',
+    `course_code` VARCHAR(20) NOT NULL COMMENT '课程编号',
+    `code` VARCHAR(32) NOT NULL COMMENT '知识点编号',
+    `name` VARCHAR(255) NOT NULL COMMENT '知识点名称',
+    `number` INT NOT NULL COMMENT '排序',
+    `parent_id` BIGINT(20) NOT NULL COMMENT '父id(顶级知识点父id为0)',
+    `create_id` BIGINT(20) NULL COMMENT '创建人',
+    `create_time` BIGINT(20) NULL COMMENT '创建时间',
+    `update_id` BIGINT(20) NULL COMMENT '更新人',
+    `update_time` BIGINT(20) NULL COMMENT '更新时间',
+    PRIMARY KEY (`id`)
+)  ENGINE=INNODB DEFAULT CHARACTER SET=UTF8MB4 COMMENT='课程知识点表';
+
+ALTER TABLE `course_dimension` 
+ADD UNIQUE INDEX `course_dimension_unique` (`exam_id` ASC, `course_code` ASC, `code` ASC) VISIBLE;
+;

+ 5 - 0
distributed-print-business/src/main/resources/mapper/CourseDimensionMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qmth.distributed.print.business.mapper.CourseDimensionMapper">
+
+</mapper>

+ 24 - 3
distributed-print/src/main/java/com/qmth/distributed/print/api/CourseTargetController.java

@@ -1,9 +1,19 @@
 package com.qmth.distributed.print.api;
 
-
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.distributed.print.business.service.PrintCommonService;
+import com.qmth.teachcloud.common.annotation.OperationLogDetail;
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.enums.log.CustomizedOperationTypeEnum;
+import com.qmth.teachcloud.common.util.Result;
+import io.swagger.annotations.*;
 import org.springframework.web.bind.annotation.RequestMapping;
-
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
 
 /**
  * <p>
@@ -13,8 +23,19 @@ import org.springframework.web.bind.annotation.RestController;
  * @author CaoZixuan
  * @since 2024-02-22
  */
+@Api(tags = "课程目标管理controller")
 @RestController
-@RequestMapping("/course-target")
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_TEACH + "/course-target")
 public class CourseTargetController {
+    @Resource
+    private PrintCommonService printCommonService;
+
+    @ApiOperation(value = "课程目标管理-导入课程知识点")
+    @RequestMapping(value = "/dimension_import", method = RequestMethod.POST)
+    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = Result.class) })
+    @OperationLogDetail(customizedOperationType = CustomizedOperationTypeEnum.IMPORT)
+    public Result courseDimensionImportSync(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file) {
 
+        return null;
+    }
 }

+ 2 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/TaskTypeEnum.java

@@ -16,6 +16,8 @@ public enum TaskTypeEnum {
 
     STUDENT_IMPORT("学生导入"),
 
+    COURSE_DIMENSION_IMPORT("课程知识点导入"),
+
     CLAZZ_IMPORT("班级导入"),
 
     QUESTION_MISSION_BATCH_CREATE("批量新建命题任务"),