tams 代码初始化

This commit is contained in:
lizhengwei 2025-01-07 00:46:54 +08:00
parent 245cedc645
commit 2d4cc38cfa
103 changed files with 4332 additions and 0 deletions

View File

@ -1 +1,5 @@
所有站点
后续h5在线链接、在线抽奖系统。

View File

@ -13,6 +13,7 @@
<module>ruoyi-sso-server</module>
<module>ruoyi-h5</module>
<module>ruoyi-gateway</module>
<module>ruoyi-tams</module>
</modules>
<artifactId>ruoyi-site</artifactId>

View File

@ -0,0 +1,20 @@
FROM bellsoft/liberica-openjdk-debian:17.0.11-cds
LABEL maintainer="lizhw"
RUN mkdir -p /ruoyi/resource/logs \
/ruoyi/resource/temp \
/ruoyi/skywalking/agent
WORKDIR /ruoyi/resource
ENV SERVER_PORT=19201 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
EXPOSE ${SERVER_PORT}
ADD ./target/ruoyi-tams.jar ./app.jar
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \
-XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \
-jar app.jar

View File

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-site</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-tams</artifactId>
<description>
ruoyi-tams 教培系统后台
</description>
<dependencies>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-core</artifactId>
</dependency>
<!-- 租户模块 -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-tenant</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-doc</artifactId>
</dependency>
<!-- 远程调用模块 TODO rename -->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-api-system</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-log</artifactId>
</dependency>
<!-- Mysql驱动包 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-encrypt</artifactId>
</dependency>
<!-- SpringBoot Web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Apache Dubbo 配置 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-nacos-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,95 @@
create schema mall-tams-core;
set
character set utf8mb4;
create table t_classroom
(
id bigint auto_increment
primary key,
name varchar(30) default '' not null comment '名称',
enable_state int unsigned default 1 not null comment '停启用状态1启用 2停用'
) comment '教室';
create table t_color
(
id bigint auto_increment comment 'id'
primary key,
name varchar(30) default '' not null comment '名称',
value char(7) default '' not null comment ''
) comment '颜色';
create table t_course
(
id bigint auto_increment comment 'id'
primary key,
name varchar(30) default '' not null comment '名称',
enable_state int unsigned default 1 not null comment '停启用状态1启用 2停用',
duration int unsigned null comment '课程时长,单位分钟',
background_color char(7) default '' not null comment '背景颜色'
) comment '课程';
create table t_course_scheduling
(
id bigint auto_increment comment 'id'
primary key,
classroom_id bigint default 0 not null comment '教室id',
course_id bigint default 0 not null comment '课程id',
teacher_id bigint default 0 not null comment '教师id',
date date null comment '日期',
attend_time time null comment '上课时间',
finish_time time null comment '下课时间'
) comment '排课';
create table t_school
(
id bigint auto_increment comment 'id'
primary key,
varchar(50) default '' not null comment '名称'
) comment '学校';
create table t_teacher
(
id bigint auto_increment comment 'id'
primary key,
name varchar(10) default '' not null comment '姓名',
enable_state int unsigned default 1 not null comment '停启用状态1启用 2停用'
) comment '教师';
create table t_course
(
id bigint auto_increment comment 'id'
primary key,
name varchar(30) default '' not null comment '名称',
enable_state int unsigned default 1 not null comment '停启用状态1启用 2停用',
duration int unsigned null comment '课程时长,单位分钟',
lesson double unsigned null comment '课时',
background_color char(7) default '' not null comment '背景颜色'
) comment '课程';
create table t_registration
(
id bigint auto_increment comment 'id'
primary key,
student_id bigint not null comment '学员',
student_name varchar(50) null comment '学员名称',
student_phone varchar(20) null comment '学员电话',
course_id bigint not null comment '课程id',
course_name varchar(255) null comment '课程',
duration int null comment '课程时长,单位分钟',
lesson double null comment '课时',
class_time datetime null comment '上课时间',
create_time datetime null comment '创建时间',
enable_state int unsigned default 1 not null comment '停启用状态'
) comment '登记';
CREATE TABLE t_student
(
id bigint auto_increment comment '学号',
name varchar(50) not null comment '姓名',
phone varchar(20) not null comment '电话',
create_time datetime comment '创建时间',
enable_state int unsigned default 1 not null comment '停启用状态',
PRIMARY KEY (id)
) COMMENT ='学生信息表' CHARACTER SET utf8mb4
COLLATE utf8mb4_general_ci;

View File

@ -0,0 +1,12 @@
set character set utf8mb4;
INSERT INTO t_color (name, value) VALUES ('GREEN SEA', '#16a085');
INSERT INTO t_color (name, value) VALUES ('NEPHRITIS', '#27ae60');
INSERT INTO t_color (name, value) VALUES ('BELIZE HOLE', '#2980b9');
INSERT INTO t_color (name, value) VALUES ('MIDNIGHT', '#2c3e50');
INSERT INTO t_color (name, value) VALUES ('ASBESTOS', '#7f8c8d');
INSERT INTO t_color (name, value) VALUES ('WISTERIA', '#8e44ad');
INSERT INTO t_color (name, value) VALUES ('SILVER', '#bdc3c7');
INSERT INTO t_color (name, value) VALUES ('POMEGRANATE', '#c0392b');
INSERT INTO t_color (name, value) VALUES ('PUMPKIN', '#d35400');
INSERT INTO t_color (name, value) VALUES ('Dark Salmon', '#efa48b');
INSERT INTO t_color (name, value) VALUES ('ORANGE', '#f39c12');

View File

@ -0,0 +1,17 @@
package com.lhd.tams;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
//import org.springframework.cloud.openfeign.EnableFeignClients;
//@EnableFeignClients
//@EnableDiscoveryClient
@SpringBootApplication
public class MallTamsApplication {
public static void main(String[] args) {
SpringApplication.run(MallTamsApplication.class, args);
}
}

View File

@ -0,0 +1,24 @@
package com.lhd.tams.common.base;
import com.lhd.tams.common.model.ApiResult;
import com.lhd.tams.common.util.ResponseEntityUtils;
import org.springframework.http.ResponseEntity;
public class BaseController {
protected static ResponseEntity<ApiResult<?>> success() {
return ResponseEntityUtils.ok("");
}
protected static <T> ResponseEntity<ApiResult<T>> success(T data) {
return ResponseEntityUtils.ok(data);
}
protected static ResponseEntity<ApiResult<?>> error(String msg) {
return ResponseEntityUtils.badRequest(msg);
}
protected static ResponseEntity<ApiResult<?>> successOrFail(Boolean flag) {
return flag ? success() : ResponseEntityUtils.badRequest("操作失败,数据可能已被修改或删除");
}
}

View File

@ -0,0 +1,14 @@
package com.lhd.tams.common.consts;
/**
* 通用常量
*/
public class CommonConsts {
public static final Integer TRUE_VALUE_INT = 1;
public static final Integer FALSE_VALUE_INT = 0;
public static final String TIME_FORMATTER = "HH:mm:ss";
public static final String DATE_FORMATTER = "yyyy-MM-dd";
public static final String DATETIME_FORMATTER = "yyyy-MM-dd HH:mm:ss";
}

View File

@ -0,0 +1,34 @@
package com.lhd.tams.common.consts;
/**
* 停启用状态
*/
public enum EnableStateEnum {
DISABLED(2, "停用"),
ENABLED(1, "启用");
private Integer code;
private String msg;
EnableStateEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

View File

@ -0,0 +1,46 @@
package com.lhd.tams.common.consts;
/**
* 详细错误码
* 起始值1000每100个为一类
* 命名类别_具体描述
*/
public enum ErrorCodeEnum {
/**
* 业务异常
*/
BUSINESS_COURSE_SCHEDULING_DATE_CONFLICT(100001, "排课时间冲突"),
BUSINESS_ERROR(100000, "业务异常"),
/**
* 关系型数据库
*/
DB_DATA_TOO_LONG(1101, "字段超长"),
DB_DATA_INTEGRITY_VIOLATION(1100, "数据完整性异常"),
UNKNOWN_ERROR(1000, "未知异常");
private Integer code;
private String msg;
ErrorCodeEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

View File

@ -0,0 +1,34 @@
package com.lhd.tams.common.consts;
/**
* sheet命名方式
*/
public enum SheetNaingTypeEnum {
WEEK_NUM(2, "第几周"),
TIME_PERIOD(1, "时间段");
private Integer code;
private String msg;
SheetNaingTypeEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

View File

@ -0,0 +1,61 @@
package com.lhd.tams.common.exception;
import com.lhd.tams.common.consts.ErrorCodeEnum;
/**
* 业务异常
*/
public class BusinessException extends RuntimeException {
/**
* 错误编码
*/
private Integer code;
/**
* 错误数据
*/
private Object data;
public BusinessException(String msg) {
super(msg);
}
public BusinessException(String msg, Throwable t) {
super(msg, t);
}
public BusinessException(ErrorCodeEnum errorCodeEnum) {
this(errorCodeEnum.getCode(), errorCodeEnum.getMsg(), null);
}
public BusinessException(ErrorCodeEnum errorApiStatusEnum, Throwable t) {
this(errorApiStatusEnum.getCode(), errorApiStatusEnum.getMsg(), t);
}
public BusinessException(Integer code, String msg, Throwable t) {
this(code, null, msg, t);
}
public BusinessException(Integer code, Object data, String msg, Throwable t) {
super(msg, t);
this.code = code;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}

View File

@ -0,0 +1,118 @@
package com.lhd.tams.common.exception;
import com.lhd.tams.common.consts.ErrorCodeEnum;
import com.lhd.tams.common.model.ApiResult;
import com.lhd.tams.common.util.ResponseEntityUtils;
import com.mysql.cj.jdbc.exceptions.MysqlDataTruncation;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.nio.file.AccessDeniedException;
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 参数校验异常
* @param e
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ApiResult<?>> handle(MethodArgumentNotValidException e) {
String msgStr = "";
StringBuilder msgBuilder = new StringBuilder();
for (FieldError error : e.getBindingResult().getFieldErrors()) {
msgBuilder.append("");
msgBuilder.append(error.getField());
msgBuilder.append("");
msgBuilder.append(error.getDefaultMessage());
msgBuilder.append(";");
}
if (msgBuilder.length() > 0) {
msgStr = msgBuilder.substring(0, msgBuilder.length() - 1);
}
return ResponseEntityUtils.badRequest(msgStr);
}
/**
* 参数缺失异常
* @param e
* @return
*/
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<ApiResult<?>> handle(HttpMessageNotReadableException e) {
return ResponseEntityUtils.badRequest("请求参数转换异常");
}
/**
* 媒体类型异常
* @param e
* @return
*/
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
public ResponseEntity<ApiResult<?>> handle(HttpMediaTypeNotSupportedException e) {
return ResponseEntityUtils.badRequest("不支持的媒体类型");
}
/**
* 访问异常
* @param e
* @return
*/
@ExceptionHandler(AccessDeniedException.class)
public ResponseEntity<ApiResult<?>> handle(AccessDeniedException e) {
return ResponseEntityUtils.forbidden(e.getMessage());
}
/**
* 数据库-数据完整性异常
* @param e
* @return
*/
@ExceptionHandler(DataIntegrityViolationException.class)
public ResponseEntity<ApiResult<?>> handle(DataIntegrityViolationException e) {
if (((MysqlDataTruncation) e.getCause()).getErrorCode() == 1406) {
return ResponseEntityUtils.internalServerError(ErrorCodeEnum.DB_DATA_TOO_LONG, e);
}
return ResponseEntityUtils.internalServerError(ErrorCodeEnum.DB_DATA_INTEGRITY_VIOLATION, e);
}
/**
* 业务异常
* @param e
* @return
*/
@ExceptionHandler(BusinessException.class)
public ResponseEntity<ApiResult<?>> handle(BusinessException e) {
if (e.getCode() == null || e.getCode() >= ErrorCodeEnum.BUSINESS_ERROR.getCode()) {
return ResponseEntityUtils.badRequest(e.getCode(), e.getMessage(), e.getData());
}
return ResponseEntityUtils.internalServerError(e.getCode(), e.getMessage(), e);
}
/**
* 未知异常
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<ApiResult<?>> handle(Exception e) {
return ResponseEntityUtils.internalServerError(ErrorCodeEnum.UNKNOWN_ERROR, e);
}
}

View File

@ -0,0 +1,63 @@
package com.lhd.tams.common.model;
/**
* 接口返回值结构
* @param <T>
*/
public class ApiResult<T> {
/**
* 错误编码
*/
private Integer code;
/**
* 响应信息
*/
private String msg;
/**
* 响应数据
*/
private T data;
public ApiResult(String msg) {
this(msg, null);
}
public ApiResult(T data) {
this("", data);
}
public ApiResult(String msg, T data) {
this(null, msg, data);
}
public ApiResult(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}

View File

@ -0,0 +1,34 @@
package com.lhd.tams.common.model;
public class BasePageQuery {
private final static int MAX_SIZE = 100;
private final static int DEFAULT_SIZE = 10;
private final static int FIRST_PAGE = 1;
/**
* 当前页码
*/
private Integer current = 1;
/**
* 每页大小
*/
private Integer size = 10;
public Integer getCurrent() {
return current == null || current <= 0 ? FIRST_PAGE : current;
}
public void setCurrent(Integer current) {
this.current = current;
}
public Integer getSize() {
return (size == null || size <= 0 || size > MAX_SIZE) ? DEFAULT_SIZE : size;
}
public void setSize(Integer size) {
this.size = size;
}
}

View File

@ -0,0 +1,32 @@
package com.lhd.tams.common.util;
import java.util.Collection;
import java.util.Map;
public class CollectionUtils {
public static boolean isEmpty(Collection<?> collection) {
return collection == null || collection.isEmpty();
}
public static boolean isAnyEmpty(Collection<?>... collections) {
for (Collection<?> collection : collections) {
if (isEmpty(collection)) {
return true;
}
}
return false;
}
public static boolean isNotEmpty(Collection<?> collection) {
return collection != null && !collection.isEmpty();
}
public static boolean isEmpty(Map<?, ?> map) {
return map == null || map.isEmpty();
}
public static boolean isNotEmpty(Map<?, ?> map) {
return map != null && !map.isEmpty();
}
}

View File

@ -0,0 +1,127 @@
package com.lhd.tams.common.util;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.lhd.tams.common.consts.CommonConsts;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* json 工具
*
* @author lhd
*/
public class JacksonUtils {
private static final Logger log = LoggerFactory.getLogger(JacksonUtils.class);
public final static Map<Class, JsonSerializer> SERIALIZER_MAP;
public final static Map<Class, JsonDeserializer> DESERIALIZER_MAP;
static {
SERIALIZER_MAP = new LinkedHashMap<>();
SERIALIZER_MAP.put(Long.class, ToStringSerializer.instance);
SERIALIZER_MAP.put(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(CommonConsts.TIME_FORMATTER)));
SERIALIZER_MAP.put(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(CommonConsts.DATE_FORMATTER)));
SERIALIZER_MAP.put(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(CommonConsts.DATETIME_FORMATTER)));
DESERIALIZER_MAP = new LinkedHashMap<>();
DESERIALIZER_MAP.put(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(CommonConsts.TIME_FORMATTER)));
DESERIALIZER_MAP.put(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(CommonConsts.DATE_FORMATTER)));
DESERIALIZER_MAP.put(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(CommonConsts.DATETIME_FORMATTER)));
}
private final static ObjectMapper OBJECT_MAPPER;
static {
OBJECT_MAPPER = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
SERIALIZER_MAP.forEach(simpleModule::addSerializer);
DESERIALIZER_MAP.forEach(simpleModule::addDeserializer);
OBJECT_MAPPER.registerModule(simpleModule);
}
/**
* 对象转换字符串
* @param obj
* @return
*/
public static String toStr(Object obj) {
if (obj == null) {
return null;
}
try {
return OBJECT_MAPPER.writeValueAsString(obj);
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug("转换为字符串出错", e);
}
}
return "";
}
/**
* 字符串转换对象
* @param str
* @return
*/
public static Object toObj(String str) {
return toObj(str, Object.class);
}
/**
* 字符串转换指定类型
* @param str
* @param clazz
* @param <T>
* @return
*/
public static <T> T toObj(String str, Class<T> clazz) {
if (StringUtils.isEmpty(str) || clazz == null) {
return null;
}
try {
return OBJECT_MAPPER.readValue(str, clazz);
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug("转换为指定类型出错str: {} class: {}", str, clazz, e);
}
}
return null;
}
public static <T> T toObj(String str, TypeReference<T> typeReference) {
if (StringUtils.isEmpty(str) || typeReference == null) {
return null;
}
try {
return OBJECT_MAPPER.readValue(str, typeReference);
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug("转换为指定范型出错str: {}", str, e);
}
}
return null;
}
}

View File

@ -0,0 +1,57 @@
package com.lhd.tams.common.util;
import com.lhd.tams.common.consts.ErrorCodeEnum;
import com.lhd.tams.common.model.ApiResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
/**
* HTTP响应结果构建器HTTP状态码+接口返回值结构
*/
public class ResponseEntityUtils {
private static final String SERVER_ERROR = "服务器异常,请联系管理员。";
private static final Logger log = LoggerFactory.getLogger(ResponseEntityUtils.class);
public static ResponseEntity<ApiResult<?>> ok(String msg) {
return ResponseEntity.ok(new ApiResult<>(msg));
}
public static <T> ResponseEntity<ApiResult<T>> ok(T data) {
return ResponseEntity.ok(new ApiResult<>(data));
}
public static ResponseEntity<ApiResult<?>> badRequest(String msg) {
return new ResponseEntity<>(new ApiResult<>(msg), HttpStatus.BAD_REQUEST);
}
public static <T> ResponseEntity<ApiResult<?>> badRequest(Integer code, String msg, T data) {
return new ResponseEntity<>(new ApiResult<>(code, msg, data), HttpStatus.BAD_REQUEST);
}
public static ResponseEntity<ApiResult<?>> unauthorized(String msg) {
return new ResponseEntity<>(new ApiResult<>(msg), HttpStatus.UNAUTHORIZED);
}
public static ResponseEntity<ApiResult<?>> forbidden(String msg) {
return new ResponseEntity<>(new ApiResult<>(msg), HttpStatus.FORBIDDEN);
}
public static ResponseEntity<ApiResult<?>> internalServerError(ErrorCodeEnum errorCodeEnum, Throwable throwable) {
log.error(errorCodeEnum.getMsg(), throwable);
return new ResponseEntity<>(new ApiResult<>(String.format("【%s】%s", errorCodeEnum.getCode(), SERVER_ERROR)), HttpStatus.INTERNAL_SERVER_ERROR);
}
public static ResponseEntity<ApiResult<?>> internalServerError(Integer code, String msg, Throwable throwable) {
log.error(msg, throwable);
return new ResponseEntity<>(new ApiResult<>(String.format("【%s】%s", code, SERVER_ERROR)), HttpStatus.INTERNAL_SERVER_ERROR);
}
}

View File

@ -0,0 +1,18 @@
package com.lhd.tams.config;
import com.lhd.tams.common.util.JacksonUtils;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JacksonConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return (builder) -> {
JacksonUtils.SERIALIZER_MAP.forEach(builder::serializerByType);
JacksonUtils.DESERIALIZER_MAP.forEach(builder::deserializerByType);
};
}
}

View File

@ -0,0 +1,61 @@
package com.lhd.tams.config;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.config.MybatisPlusConfig;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.tenant.properties.TenantProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
@ConditionalOnBean(MybatisPlusConfig.class)
@AutoConfiguration(after = {MybatisPlusConfig.class})
@Slf4j
public class MybatisPlusAutoConfigTenant {
@Bean
public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties tenantProperties) {
return new TenantLineInnerInterceptor(new TenantLineHandler() {
@Override
public Expression getTenantId() {
String tenantId = TenantHelper.getTenantId();
if (StringUtils.isBlank(tenantId)) {
log.error("无法获取有效的租户id -> Null");
return new NullValue();
}
// 返回固定租户
return new StringValue(tenantId);
}
@Override
public boolean ignoreTable(String tableName) {
String tenantId = TenantHelper.getTenantId();
// 判断是否有租户
if (StringUtils.isNotBlank(tenantId)) {
// 不需要过滤租户的表
List<String> excludes = tenantProperties.getExcludes();
// 非业务表
List<String> tables = ListUtil.toList(
"gen_table",
"gen_table_column"
);
tables.addAll(excludes);
return tables.contains(tableName);
}
return true;
}
});
}
}

View File

@ -0,0 +1,27 @@
package com.lhd.tams.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").
allowedMethods(CorsConfiguration.ALL). //允许任何方法postget等
allowedHeaders(CorsConfiguration.ALL). //允许任何请求头
allowCredentials(true).
allowedOriginPatterns(CorsConfiguration.ALL).//带上cookie信息
exposedHeaders(HttpHeaders.SET_COOKIE).maxAge(3600L); //maxAge(3600)表明在3600秒内不需要再发送预检验请求可以缓存该结果
}
};
}
}

View File

@ -0,0 +1,37 @@
package com.lhd.tams.module;
import com.lhd.tams.common.base.BaseController;
import com.lhd.tams.common.model.ApiResult;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 测试feign 用的后面删除
*/
@Tag(name = "报表")
@RequestMapping()
@RestController
public class Report2Controller extends BaseController {
@Autowired
private TenantRpc tenantRpc;
//todo 测试rpc然后在测试免权限rpc在测试传递租户信息用户信息链路追踪id
@GetMapping("/resource/sms/code")
public ResponseEntity<ApiResult<Object>> getReportTeacherCount() {
return success(tenantRpc.emailCode());
}
@GetMapping("/system/client/{id}")
public ResponseEntity<ApiResult<Object>> getReportTeacherCount2(@PathVariable Long id) {
return success(tenantRpc.getInfo(id));
}
}

View File

@ -0,0 +1,22 @@
package com.lhd.tams.module;
//import com.lhd.tams.config.FeignInterceptor;
//import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
//@FeignClient(
// name = "saas-tenant-admin", // 服务名称
// configuration = FeignInterceptor.class // 请求拦截器 关键代码
//// fallbackFactory = SpCfgInterfaceFallback.class // 服务降级处理
//)
public interface TenantRpc {
@GetMapping(value = "/auth/code")
Object emailCode();
@GetMapping(value = "/system/client/{id}")
Object getInfo(@PathVariable Long id);
}

View File

@ -0,0 +1,68 @@
package com.lhd.tams.module.classroom.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhd.tams.common.base.BaseController;
import com.lhd.tams.common.model.ApiResult;
import com.lhd.tams.module.classroom.model.dto.ClassroomPageQuery;
import com.lhd.tams.module.classroom.model.dto.ClassroomSaveDTO;
import com.lhd.tams.module.classroom.model.vo.ClassroomListVO;
import com.lhd.tams.module.classroom.service.ClassroomService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Tag(name = "教室")
@RequestMapping("classroom")
@RestController
public class ClassroomController extends BaseController {
@Autowired
private ClassroomService classroomService;
@Operation(summary = "分页列表")
@GetMapping
public ResponseEntity<ApiResult<IPage<ClassroomListVO>>> pageCourse(ClassroomPageQuery pageQuery) {
return success(classroomService.pageCourse(pageQuery));
}
@Operation(summary = "参照列表")
@GetMapping("list/ref")
public ResponseEntity<ApiResult<List<ClassroomListVO>>> refList() {
return success(classroomService.refList());
}
@Operation(summary = "详情")
@GetMapping("{id}")
public ResponseEntity<ApiResult<ClassroomListVO>> getCourseById(@PathVariable("id") Long id) {
return success(classroomService.getCourseById(id));
}
@Operation(summary = "新增")
@PostMapping
public ResponseEntity<ApiResult<?>> saveCourse(@Validated @RequestBody ClassroomSaveDTO saveDTO) {
return successOrFail(classroomService.saveCourse(saveDTO));
}
@Operation(summary = "修改")
@PutMapping("{id}")
public ResponseEntity<ApiResult<?>> updateCourseById(@PathVariable("id") Long id, @Validated @RequestBody ClassroomSaveDTO saveDTO) {
return successOrFail(classroomService.updateCourseById(id, saveDTO));
}
@Operation(summary = "停启用")
@PutMapping("{id}/enable-state/{enableState}")
public ResponseEntity<ApiResult<?>> updateCourseEnableStateById(@PathVariable("id") Long id, @PathVariable("enableState") Integer enableState) {
return successOrFail(classroomService.updateCourseEnableStateById(id, enableState));
}
}

View File

@ -0,0 +1,7 @@
package com.lhd.tams.module.classroom.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lhd.tams.module.classroom.model.data.ClassroomDO;
public interface ClassroomMapper extends BaseMapper<ClassroomDO> {
}

View File

@ -0,0 +1,26 @@
package com.lhd.tams.module.classroom.model.convert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lhd.tams.module.classroom.model.data.ClassroomDO;
import com.lhd.tams.module.classroom.model.dto.ClassroomSaveDTO;
import com.lhd.tams.module.classroom.model.vo.ClassroomListVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public abstract class AbstractClassroomConverter {
public static AbstractClassroomConverter INSTANCE = Mappers.getMapper(AbstractClassroomConverter.class);
public abstract Page<ClassroomListVO> doPage2ListVoPage(IPage<ClassroomDO> doPage);
public abstract List<ClassroomListVO> doList2ListVoList(List<ClassroomDO> doList);
public abstract ClassroomListVO do2ListVO(ClassroomDO dataObj);
public abstract ClassroomDO saveDto2DO(ClassroomSaveDTO saveDTO);
}

View File

@ -0,0 +1,24 @@
package com.lhd.tams.module.classroom.model.data;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("t_classroom")
public class ClassroomDO {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 名称
*/
private String name;
/**
* 停启用状态
*/
private Integer enableState;
}

View File

@ -0,0 +1,13 @@
package com.lhd.tams.module.classroom.model.dto;
import com.lhd.tams.common.model.BasePageQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "教室分页查询参数")
@Data
public class ClassroomPageQuery extends BasePageQuery {
@Schema(description = "停启用状态")
private Integer enableState;
}

View File

@ -0,0 +1,12 @@
package com.lhd.tams.module.classroom.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "教室新增参数")
@Data
public class ClassroomSaveDTO {
@Schema(description = "名称")
private String name;
}

View File

@ -0,0 +1,18 @@
package com.lhd.tams.module.classroom.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "教室列表返回结果")
@Data
public class ClassroomListVO {
@Schema(description = "id")
private Long id;
@Schema(description = "名称")
private String name;
@Schema(description = "停启用状态")
private Integer enableState;
}

View File

@ -0,0 +1,23 @@
package com.lhd.tams.module.classroom.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhd.tams.module.classroom.model.dto.ClassroomPageQuery;
import com.lhd.tams.module.classroom.model.dto.ClassroomSaveDTO;
import com.lhd.tams.module.classroom.model.vo.ClassroomListVO;
import java.util.List;
public interface ClassroomService {
IPage<ClassroomListVO> pageCourse(ClassroomPageQuery pageQuery);
List<ClassroomListVO> refList();
ClassroomListVO getCourseById(Long id);
boolean saveCourse(ClassroomSaveDTO saveDTO);
boolean updateCourseById(Long id, ClassroomSaveDTO saveDTO);
boolean updateCourseEnableStateById(Long id, Integer enableState);
}

View File

@ -0,0 +1,87 @@
package com.lhd.tams.module.classroom.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lhd.tams.common.consts.EnableStateEnum;
import com.lhd.tams.module.classroom.dao.ClassroomMapper;
import com.lhd.tams.module.classroom.model.convert.AbstractClassroomConverter;
import com.lhd.tams.module.classroom.model.data.ClassroomDO;
import com.lhd.tams.module.classroom.model.dto.ClassroomPageQuery;
import com.lhd.tams.module.classroom.model.dto.ClassroomSaveDTO;
import com.lhd.tams.module.classroom.model.vo.ClassroomListVO;
import com.lhd.tams.module.classroom.service.ClassroomService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ClassroomServiceImpl extends ServiceImpl<ClassroomMapper, ClassroomDO> implements ClassroomService {
@Override
public IPage<ClassroomListVO> pageCourse(ClassroomPageQuery pageQuery) {
LambdaQueryWrapper<ClassroomDO> queryWrapper = Wrappers.<ClassroomDO>lambdaQuery()
.eq(pageQuery.getEnableState() != null, ClassroomDO::getEnableState, pageQuery.getEnableState())
.orderByAsc(ClassroomDO::getName);
IPage<ClassroomDO> doPage = page(new Page<>(pageQuery.getCurrent(), pageQuery.getSize()), queryWrapper);
IPage<ClassroomListVO> voPage = AbstractClassroomConverter.INSTANCE.doPage2ListVoPage(doPage);
return voPage;
}
@Override
public List<ClassroomListVO> refList() {
LambdaQueryWrapper<ClassroomDO> queryWrapper = Wrappers.<ClassroomDO>lambdaQuery()
.eq(ClassroomDO::getEnableState, EnableStateEnum.ENABLED.getCode())
.orderByAsc(ClassroomDO::getName);
List<ClassroomDO> doList = list(queryWrapper);
List<ClassroomListVO> voList = AbstractClassroomConverter.INSTANCE.doList2ListVoList(doList);
return voList;
}
@Override
public ClassroomListVO getCourseById(Long id) {
ClassroomDO dataObj = getById(id);
ClassroomListVO vo = AbstractClassroomConverter.INSTANCE.do2ListVO(dataObj);
return vo;
}
@Override
public boolean saveCourse(ClassroomSaveDTO saveDTO) {
ClassroomDO dataObj = AbstractClassroomConverter.INSTANCE.saveDto2DO(saveDTO);
return save(dataObj);
}
@Override
public boolean updateCourseById(Long id, ClassroomSaveDTO saveDTO) {
ClassroomDO dataObj = AbstractClassroomConverter.INSTANCE.saveDto2DO(saveDTO);
dataObj.setId(id);
return updateById(dataObj);
}
@Override
public boolean updateCourseEnableStateById(Long id, Integer enableState) {
ClassroomDO dataObj = new ClassroomDO();
dataObj.setId(id);
dataObj.setEnableState(enableState);
return updateById(dataObj);
}
}

View File

@ -0,0 +1,30 @@
package com.lhd.tams.module.color.controller;
import com.lhd.tams.common.base.BaseController;
import com.lhd.tams.common.model.ApiResult;
import com.lhd.tams.module.color.service.ColorService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Tag(name = "颜色")
@RequestMapping("color")
@RestController
public class ColorController extends BaseController {
@Autowired
private ColorService colorService;
@Operation(summary = "有效颜色列表")
@GetMapping("list/effective")
public ResponseEntity<ApiResult<List<String>>> getEffectiveList() {
return success(colorService.getEffectiveList());
}
}

View File

@ -0,0 +1,7 @@
package com.lhd.tams.module.color.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lhd.tams.module.color.model.data.ColorDO;
public interface ColorMapper extends BaseMapper<ColorDO> {
}

View File

@ -0,0 +1,16 @@
package com.lhd.tams.module.color.model.convert;
import com.lhd.tams.module.color.model.data.ColorDO;
import com.lhd.tams.module.color.model.vo.ColorListVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public abstract class AbstractColorConverter {
public static AbstractColorConverter INSTANCE = Mappers.getMapper(AbstractColorConverter.class);
public abstract List<ColorListVO> doList2ListVoList(List<ColorDO> doList);
}

View File

@ -0,0 +1,24 @@
package com.lhd.tams.module.color.model.data;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("t_color")
public class ColorDO {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 名称
*/
private String name;
/**
*
*/
private String value;
}

View File

@ -0,0 +1,18 @@
package com.lhd.tams.module.color.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "颜色列表返回结果")
@Data
public class ColorListVO {
@Schema(description = "id")
private Long id;
@Schema(description = "名称")
private String name;
@Schema(description = "")
private String value;
}

View File

@ -0,0 +1,8 @@
package com.lhd.tams.module.color.service;
import java.util.List;
public interface ColorService {
List<String> getEffectiveList();
}

View File

@ -0,0 +1,26 @@
package com.lhd.tams.module.color.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lhd.tams.module.color.dao.ColorMapper;
import com.lhd.tams.module.color.model.data.ColorDO;
import com.lhd.tams.module.color.service.ColorService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ColorServiceImpl extends ServiceImpl<ColorMapper, ColorDO> implements ColorService {
@Override
public List<String> getEffectiveList() {
LambdaQueryWrapper<ColorDO> queryWrapper = Wrappers.<ColorDO>lambdaQuery()
.select(ColorDO::getValue)
.notExists("select 1 from t_course course where course.background_color = t_color.value")
.orderByAsc(ColorDO::getValue);
return listObjs(queryWrapper, Object::toString);
}
}

View File

@ -0,0 +1,68 @@
package com.lhd.tams.module.course.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhd.tams.common.base.BaseController;
import com.lhd.tams.common.model.ApiResult;
import com.lhd.tams.module.course.model.dto.CoursePageQuery;
import com.lhd.tams.module.course.model.dto.CourseSaveDTO;
import com.lhd.tams.module.course.model.vo.CourseListVO;
import com.lhd.tams.module.course.service.CourseService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Tag(name = "课程")
@RequestMapping("course")
@RestController
public class CourseController extends BaseController {
@Autowired
private CourseService courseService;
@Operation(summary = "分页列表")
@GetMapping
public ResponseEntity<ApiResult<IPage<CourseListVO>>> pageCourse(CoursePageQuery pageQuery) {
return success(courseService.pageCourse(pageQuery));
}
@Operation(summary = "参照列表")
@GetMapping("list/ref")
public ResponseEntity<ApiResult<List<CourseListVO>>> refList() {
return success(courseService.refList());
}
@Operation(summary = "详情")
@GetMapping("{id}")
public ResponseEntity<ApiResult<CourseListVO>> getCourseById(@PathVariable("id") Long id) {
return success(courseService.getCourseById(id));
}
@Operation(summary = "新增")
@PostMapping
public ResponseEntity<ApiResult<?>> saveCourse(@Validated @RequestBody CourseSaveDTO saveDTO) {
return successOrFail(courseService.saveCourse(saveDTO));
}
@Operation(summary = "修改")
@PutMapping("{id}")
public ResponseEntity<ApiResult<?>> updateCourseById(@PathVariable("id") Long id, @Validated @RequestBody CourseSaveDTO saveDTO) {
return successOrFail(courseService.updateCourseById(id, saveDTO));
}
@Operation(summary = "停启用")
@PutMapping("{id}/enable-state/{enableState}")
public ResponseEntity<ApiResult<?>> updateCourseEnableStateById(@PathVariable("id") Long id, @PathVariable("enableState") Integer enableState) {
return successOrFail(courseService.updateCourseEnableStateById(id, enableState));
}
}

View File

@ -0,0 +1,7 @@
package com.lhd.tams.module.course.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lhd.tams.module.course.model.data.CourseDO;
public interface CourseMapper extends BaseMapper<CourseDO> {
}

View File

@ -0,0 +1,26 @@
package com.lhd.tams.module.course.model.convert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lhd.tams.module.course.model.data.CourseDO;
import com.lhd.tams.module.course.model.dto.CourseSaveDTO;
import com.lhd.tams.module.course.model.vo.CourseListVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public abstract class AbstractCourseConverter {
public static AbstractCourseConverter INSTANCE = Mappers.getMapper(AbstractCourseConverter.class);
public abstract Page<CourseListVO> doPage2ListVoPage(IPage<CourseDO> doPage);
public abstract List<CourseListVO> doList2ListVoList(List<CourseDO> doList);
public abstract CourseListVO do2ListVO(CourseDO dataObj);
public abstract CourseDO saveDto2DO(CourseSaveDTO saveDTO);
}

View File

@ -0,0 +1,39 @@
package com.lhd.tams.module.course.model.data;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("t_course")
public class CourseDO {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 名称
*/
private String name;
/**
* 停启用状态
*/
private Integer enableState;
/**
* 课程时长单位分钟
*/
private Integer duration;
/**
* 课时
*/
private Double lesson;
/**
* 背景颜色
*/
private String backgroundColor;
}

View File

@ -0,0 +1,13 @@
package com.lhd.tams.module.course.model.dto;
import com.lhd.tams.common.model.BasePageQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "课程分页查询参数")
@Data
public class CoursePageQuery extends BasePageQuery {
@Schema(description = "停启用状态")
private Integer enableState;
}

View File

@ -0,0 +1,21 @@
package com.lhd.tams.module.course.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "课程新增参数")
@Data
public class CourseSaveDTO {
@Schema(description = "名称")
private String name;
@Schema(description = "课程时长,单位分钟")
private Integer duration;
@Schema(description = "课时")
private Double lesson;
@Schema(description = "背景颜色")
private String backgroundColor;
}

View File

@ -0,0 +1,27 @@
package com.lhd.tams.module.course.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "课程列表返回结果")
@Data
public class CourseListVO {
@Schema(description = "id")
private Long id;
@Schema(description = "名称")
private String name;
@Schema(description = "停启用状态")
private Integer enableState;
@Schema(description = "课程时长,单位分钟")
private Integer duration;
@Schema(description = "课时")
private Double lesson;
@Schema(description = "背景颜色")
private String backgroundColor;
}

View File

@ -0,0 +1,23 @@
package com.lhd.tams.module.course.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhd.tams.module.course.model.dto.CoursePageQuery;
import com.lhd.tams.module.course.model.dto.CourseSaveDTO;
import com.lhd.tams.module.course.model.vo.CourseListVO;
import java.util.List;
public interface CourseService {
IPage<CourseListVO> pageCourse(CoursePageQuery pageQuery);
List<CourseListVO> refList();
CourseListVO getCourseById(Long id);
boolean saveCourse(CourseSaveDTO saveDTO);
boolean updateCourseById(Long id, CourseSaveDTO saveDTO);
boolean updateCourseEnableStateById(Long id, Integer enableState);
}

View File

@ -0,0 +1,87 @@
package com.lhd.tams.module.course.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lhd.tams.common.consts.EnableStateEnum;
import com.lhd.tams.module.course.dao.CourseMapper;
import com.lhd.tams.module.course.model.convert.AbstractCourseConverter;
import com.lhd.tams.module.course.model.data.CourseDO;
import com.lhd.tams.module.course.model.dto.CoursePageQuery;
import com.lhd.tams.module.course.model.dto.CourseSaveDTO;
import com.lhd.tams.module.course.model.vo.CourseListVO;
import com.lhd.tams.module.course.service.CourseService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, CourseDO> implements CourseService {
@Override
public IPage<CourseListVO> pageCourse(CoursePageQuery pageQuery) {
LambdaQueryWrapper<CourseDO> queryWrapper = Wrappers.<CourseDO>lambdaQuery()
.eq(pageQuery.getEnableState() != null, CourseDO::getEnableState, pageQuery.getEnableState())
.orderByAsc(CourseDO::getName);
IPage<CourseDO> doPage = page(new Page<>(pageQuery.getCurrent(), pageQuery.getSize()), queryWrapper);
IPage<CourseListVO> voPage = AbstractCourseConverter.INSTANCE.doPage2ListVoPage(doPage);
return voPage;
}
@Override
public List<CourseListVO> refList() {
LambdaQueryWrapper<CourseDO> queryWrapper = Wrappers.<CourseDO>lambdaQuery()
.eq(CourseDO::getEnableState, EnableStateEnum.ENABLED.getCode())
.orderByAsc(CourseDO::getName);
List<CourseDO> doList = list(queryWrapper);
List<CourseListVO> voList = AbstractCourseConverter.INSTANCE.doList2ListVoList(doList);
return voList;
}
@Override
public CourseListVO getCourseById(Long id) {
CourseDO dataObj = getById(id);
CourseListVO vo = AbstractCourseConverter.INSTANCE.do2ListVO(dataObj);
return vo;
}
@Override
public boolean saveCourse(CourseSaveDTO saveDTO) {
CourseDO dataObj = AbstractCourseConverter.INSTANCE.saveDto2DO(saveDTO);
return save(dataObj);
}
@Override
public boolean updateCourseById(Long id, CourseSaveDTO saveDTO) {
CourseDO dataObj = AbstractCourseConverter.INSTANCE.saveDto2DO(saveDTO);
dataObj.setId(id);
return updateById(dataObj);
}
@Override
public boolean updateCourseEnableStateById(Long id, Integer enableState) {
CourseDO dataObj = new CourseDO();
dataObj.setId(id);
dataObj.setEnableState(enableState);
return updateById(dataObj);
}
}

View File

@ -0,0 +1,118 @@
package com.lhd.tams.module.coursescheduling.controller;
import com.lhd.tams.common.base.BaseController;
import com.lhd.tams.common.model.ApiResult;
import com.lhd.tams.module.coursescheduling.manager.CourseSchedulingExcelManager;
import com.lhd.tams.module.coursescheduling.model.dto.*;
import com.lhd.tams.module.coursescheduling.model.vo.CourseSchedulingListVO;
import com.lhd.tams.module.coursescheduling.service.CourseSchedulingService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
@Tag(name = "排课")
@RequestMapping("course-scheduling")
@RestController
public class CourseSchedulingController extends BaseController {
@Autowired
private CourseSchedulingService courseSchedulingService;
@Autowired
private CourseSchedulingExcelManager courseSchedulingExcelManager;
@Operation(summary = "列表")
@PostMapping("list")
public ResponseEntity<ApiResult<List<CourseSchedulingListVO>>> listCourseScheduling(@RequestBody CourseSchedulingQuery query) {
return success(courseSchedulingService.listCourseScheduling(query));
}
@Operation(summary = "详情")
@GetMapping("{id}")
public ResponseEntity<ApiResult<CourseSchedulingListVO>> getCourseSchedulingById(@PathVariable("id") Long id) {
return success(courseSchedulingService.getCourseSchedulingById(id));
}
@Operation(summary = "课程数量")
@PostMapping("course/count")
public ResponseEntity<ApiResult<Map<String, Integer>>> getCourseSchedulingCourseCount(@RequestBody CourseSchedulingQuery query) {
return success(courseSchedulingService.getCourseSchedulingCourseCount(query));
}
@Operation(summary = "新增")
@PostMapping
public ResponseEntity<ApiResult<?>> saveCourseScheduling(@Validated @RequestBody CourseSchedulingSaveDTO saveDTO) {
return successOrFail(courseSchedulingService.saveCourseScheduling(saveDTO));
}
@Operation(summary = "批量新增")
@PostMapping("batch")
public ResponseEntity<ApiResult<?>> saveCourseScheduling(@Validated @RequestBody CourseSchedulingBatchSaveDTO saveDTO) {
courseSchedulingService.batchSaveCourseScheduling(saveDTO);
return success();
}
@Operation(summary = "修改排课时间")
@PutMapping("{id}/time")
public ResponseEntity<ApiResult<?>> updateCourseSchedulingTimeById(@PathVariable("id") Long id, @Validated @RequestBody CourseSchedulingTimeUpdateDTO updateDTO) {
return successOrFail(courseSchedulingService.updateCourseSchedulingTimeById(id, updateDTO));
}
@Operation(summary = "修改")
@PutMapping("{id}")
public ResponseEntity<ApiResult<?>> updateCourseSchedulingById(@PathVariable("id") Long id, @Validated @RequestBody CourseSchedulingSaveDTO saveDTO) {
return successOrFail(courseSchedulingService.updateCourseSchedulingById(id, saveDTO));
}
@Operation(summary = "删除")
@DeleteMapping("{id}")
public ResponseEntity<ApiResult<?>> removeCourseSchedulingById(@PathVariable("id") Long id) {
return successOrFail(courseSchedulingService.removeCourseSchedulingById(id));
}
@Operation(summary = "批量删除")
@DeleteMapping("batch")
public ResponseEntity<ApiResult<?>> removeCourseSchedulingByIdList(@RequestBody List<Long> idList) {
courseSchedulingService.removeCourseSchedulingByIdList(idList);
return success();
}
@Operation(summary = "导出excel")
@GetMapping("export/excel")
public void exportExcel(HttpServletResponse response, @Validated CourseSchedulingExportDTO dto) throws IOException {
Workbook workbook = courseSchedulingExcelManager.createExcel(dto);
String filename = (StringUtils.isEmpty(dto.getFilename()) ? "课表" : dto.getFilename()) + ".xlsx";
response.reset();
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes(), StandardCharsets.ISO_8859_1));
workbook.write(response.getOutputStream());
response.flushBuffer();
workbook.close();
}
}

View File

@ -0,0 +1,31 @@
package com.lhd.tams.module.coursescheduling.dao;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.lhd.tams.module.coursescheduling.model.data.CourseSchedulingDO;
import com.lhd.tams.module.coursescheduling.model.vo.CourseSchedulingExportVO;
import com.lhd.tams.module.coursescheduling.model.vo.CourseSchedulingListVO;
import com.lhd.tams.module.coursescheduling.model.vo.CourseSchedulingReportVO;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
public interface CourseSchedulingMapper extends BaseMapper<CourseSchedulingDO> {
List<CourseSchedulingListVO> selectCourseSchedulingList(@Param(Constants.WRAPPER) Wrapper<?> queryWrapper);
CourseSchedulingListVO selectCourseSchedulingById(Long id);
List<Map<String, String>> selectCourseSchedulingCourseCount(@Param(Constants.WRAPPER) Wrapper<?> queryWrapper);
List<String> selectTimePeriodByDateRange(@Param("dateList") List<LocalDate> dateList, @Param("classroomId") Long classroomId);
List<CourseSchedulingExportVO> selectByDateRange(@Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate, @Param("classroomId") Long classroomId);
List<CourseSchedulingReportVO> selectReportTeacherCount(@Param("startDate") String startDate, @Param("endDate") String endDate);
List<CourseSchedulingReportVO> selectReportCourseCount(@Param("startDate") String startDate, @Param("endDate") String endDate);
}

View File

@ -0,0 +1,307 @@
package com.lhd.tams.module.coursescheduling.manager;
import com.lhd.tams.common.consts.SheetNaingTypeEnum;
import com.lhd.tams.common.exception.BusinessException;
import com.lhd.tams.common.util.CollectionUtils;
import com.lhd.tams.module.coursescheduling.dao.CourseSchedulingMapper;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingExportDTO;
import com.lhd.tams.module.coursescheduling.model.vo.CourseSchedulingExportVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellUtil;
import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Component
public class CourseSchedulingExcelManager {
private static final String FONT_NAME = "等线";
private static final Map<DayOfWeek, String> DAY_OF_WEEK_STRING_MAP;
static {
DAY_OF_WEEK_STRING_MAP = new HashMap<>();
DAY_OF_WEEK_STRING_MAP.put(DayOfWeek.MONDAY, "星期一");
DAY_OF_WEEK_STRING_MAP.put(DayOfWeek.TUESDAY, "星期二");
DAY_OF_WEEK_STRING_MAP.put(DayOfWeek.WEDNESDAY, "星期三");
DAY_OF_WEEK_STRING_MAP.put(DayOfWeek.THURSDAY, "星期四");
DAY_OF_WEEK_STRING_MAP.put(DayOfWeek.FRIDAY, "星期五");
DAY_OF_WEEK_STRING_MAP.put(DayOfWeek.SATURDAY, "星期六");
DAY_OF_WEEK_STRING_MAP.put(DayOfWeek.SUNDAY, "星期日");
}
@Autowired
private CourseSchedulingMapper courseSchedulingMapper;
public Workbook createExcel(CourseSchedulingExportDTO dto) {
LocalDate startDate = LocalDate.parse(dto.getStartDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDate endDate = LocalDate.parse(dto.getEndDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
// 日期map <第几周, dateList>
long days = ChronoUnit.DAYS.between(startDate, endDate) + 1;
int week = 0;
Map<Integer, List<LocalDate>> dateMap = new HashMap<>();
for (int i = 0; i < days; i++) {
LocalDate date = startDate.plusDays(i);
boolean isWeek = date.getDayOfWeek() == DayOfWeek.SATURDAY || date.getDayOfWeek() == DayOfWeek.SUNDAY;
if (!dto.getIsShowWeek() && isWeek) {
continue;
}
// 前6天中有非周一日期
if (week == 0 && date.getDayOfWeek().getValue() > 1 && i < 6) {
week ++;
}
if (date.getDayOfWeek() == DayOfWeek.MONDAY) {
// 计算有多少周
week ++;
}
List<LocalDate> dateList = dateMap.computeIfAbsent(week, k -> new ArrayList<>());
dateList.add(date);
}
// 时间map <第几周, timeList>
Map<Integer, List<String>> timeMap = new HashMap<>();
for (Map.Entry<Integer, List<LocalDate>> entry : dateMap.entrySet()) {
timeMap.put(entry.getKey(), courseSchedulingMapper.selectTimePeriodByDateRange(entry.getValue(), dto.getClassroomId()));
}
// 课程map <date+time, course>
List<CourseSchedulingExportVO> voList = courseSchedulingMapper.selectByDateRange(startDate, endDate, dto.getClassroomId());
Map<String, CourseSchedulingExportVO> dataMap = new HashMap<>();
for (CourseSchedulingExportVO vo : voList) {
dataMap.put(vo.getDate() + vo.getTime(), vo);
}
try {
// xssf
Workbook workbook = WorkbookFactory.create(true);
for (int i = 1; i <= dateMap.size(); i++) {
List<LocalDate> dateList = dateMap.get(i);
createSheet(workbook, dateList, timeMap.get(i), dataMap,
getSheetName(dto.getSheetNamingType(), i, dateList),
dto.getTitle(),
dto.getClassroomName());
}
return workbook;
}
catch (Exception e) {
log.error("生成Excel异常", e);
throw new BusinessException("生成Excel异常");
}
}
private static String getSheetName(Integer sheetNamingType, int num, List<LocalDate> dateList) {
if (SheetNaingTypeEnum.WEEK_NUM.getCode().equals(sheetNamingType)) {
return String.format("第%s周", num);
} else {
return dateList.size() == 1 ?
dateList.get(0).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) :
String.format("%s至%s",
dateList.get(0).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")),
dateList.get(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
}
}
private static void createSheet(Workbook workbook,
List<LocalDate> dateList, List<String> timeList, Map<String, CourseSchedulingExportVO> dataMap,
String sheetName, String title, String subtitleClassroomName) {
if (workbook == null || CollectionUtils.isAnyEmpty(dateList, timeList) || CollectionUtils.isEmpty(dataMap)) {
return;
}
Sheet sheet = workbook.createSheet(sheetName);
// 时间列
sheet.setColumnWidth(0, 15 * 256);
int dateRowIndex = 0;
int dataRowIndex = 0;
int classroomRowIndex = 0;
int dateColumnNum = dateList.size();
if (StringUtils.isNotEmpty(title)) {
createTitleRow(sheet, 0, dateColumnNum + 1, title);
dateRowIndex ++;
dataRowIndex ++;
classroomRowIndex ++;
}
if (StringUtils.isNotEmpty(subtitleClassroomName)) {
createClassroomRow(sheet, classroomRowIndex, dateColumnNum + 1, "教室:" + subtitleClassroomName);
dateRowIndex ++;
dataRowIndex ++;
}
// 星期行
Row dateRow = sheet.createRow(dateRowIndex);
dateRow.setHeight((short) 800);
CellStyle headerCellStyle = workbook.createCellStyle();
Font headerCellFont = workbook.createFont();
for (int i = 0; i < dateColumnNum; i++) {
LocalDate date = dateList.get(i);
sheet.setColumnWidth(i + 1, 20 * 256);
createHeaderCell(dateRow,
i + 1,
String.format("%s\n%s", date, DAY_OF_WEEK_STRING_MAP.get(date.getDayOfWeek())),
headerCellStyle, headerCellFont);
}
// 数据行
CellStyle timeCellStyle = workbook.createCellStyle();
Font timeCellFont = workbook.createFont();
for (int i = 0; i < timeList.size(); i++) {
dataRowIndex ++;
Row courseRow = sheet.createRow(dataRowIndex);
courseRow.setHeight((short) 1000);
// 时间列
String time = timeList.get(i);
createTimeCell(courseRow, 0, time, timeCellStyle, timeCellFont);
// 数据列
for (int j = 0; j < dateColumnNum; j++) {
CourseSchedulingExportVO vo = dataMap.get(dateList.get(j) + time);
if (vo != null) {
createDataCell(courseRow, j + 1, vo, StringUtils.isEmpty(subtitleClassroomName));
}
}
}
}
private static void createTitleRow(Sheet sheet, int index, int totalColumnNum, String value) {
CellRangeAddress region = new CellRangeAddress(index, index, 0, totalColumnNum - 1);
sheet.addMergedRegion(region);
Row row = sheet.createRow(index);
row.setHeight((short) 800);
Workbook workbook = sheet.getWorkbook();
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
Font font = workbook.createFont();
font.setFontName(FONT_NAME);
font.setFontHeightInPoints((short) 14);
cellStyle.setFont(font);
CellUtil.createCell(row, 0, value, cellStyle);
}
private static void createClassroomRow(Sheet sheet, int index, int totalColumnNum, String value) {
CellRangeAddress region = new CellRangeAddress(index, index, 0, totalColumnNum - 1);
sheet.addMergedRegion(region);
Row row = sheet.createRow(index);
row.setHeight((short) 800);
Workbook workbook = sheet.getWorkbook();
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
Font font = workbook.createFont();
font.setFontName(FONT_NAME);
font.setFontHeightInPoints((short) 12);
cellStyle.setFont(font);
CellUtil.createCell(row, 0, value, cellStyle);
}
private static void createHeaderCell(Row row, int index, String value, CellStyle cellStyle, Font font) {
font.setFontName(FONT_NAME);
font.setFontHeightInPoints((short) 12);
cellStyle.setFont(font);
cellStyle.setWrapText(true);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
CellUtil.createCell(row, index, value, cellStyle);
}
private static void createTimeCell(Row row, int index, String value, CellStyle cellStyle, Font font) {
font.setFontName(FONT_NAME);
font.setFontHeightInPoints((short) 12);
cellStyle.setFont(font);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
CellUtil.createCell(row, index, value, cellStyle);
}
private static void createDataCell(Row row, int index, CourseSchedulingExportVO vo, boolean isShowClassroom) {
if (vo != null) {
// 不同单元格可能需要不同的样式因此为每个单元格创建单独样式
Workbook workbook = row.getSheet().getWorkbook();
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setWrapText(true);
if (StringUtils.isNotEmpty(vo.getBackgroundColor())) {
XSSFColor xssfColor = new XSSFColor(java.awt.Color.decode(vo.getBackgroundColor()) , new DefaultIndexedColorMap());
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
((XSSFCellStyle) cellStyle).setFillForegroundColor(xssfColor);
}
setBorderStyle(cellStyle, BorderStyle.THIN, IndexedColors.GREY_25_PERCENT);
Font courseFont = workbook.createFont();
courseFont.setFontName(FONT_NAME);
courseFont.setFontHeightInPoints((short) 16);
courseFont.setColor(IndexedColors.WHITE.index);
Font otherFont = workbook.createFont();
otherFont.setFontName(FONT_NAME);
otherFont.setFontHeightInPoints((short) 12);
otherFont.setColor(IndexedColors.WHITE.index);
String course = vo.getCourseName();
String otherInfo = isShowClassroom ? String.format("%s %s", vo.getClassroomName(), vo.getTeacherName()) : vo.getTeacherName();
String value = String.format("%s\n%s", course, otherInfo);
RichTextString richTextString = new XSSFRichTextString(value);
richTextString.applyFont(0, course.length(), courseFont);
richTextString.applyFont(course.length(), value.length(), otherFont);
Cell cell = row.createCell(index);
cell.setCellStyle(cellStyle);
cell.setCellValue(richTextString);
}
}
private static void setBorderStyle(CellStyle style, BorderStyle borderStyle, IndexedColors borderColor) {
style.setBorderTop(borderStyle);
style.setTopBorderColor(borderColor.index);
style.setBorderBottom(borderStyle);
style.setBottomBorderColor(borderColor.index);
style.setBorderLeft(borderStyle);
style.setLeftBorderColor(borderColor.index);
style.setBorderRight(borderStyle);
style.setRightBorderColor(borderColor.index);
}
}

View File

@ -0,0 +1,30 @@
package com.lhd.tams.module.coursescheduling.model.convert;
import com.lhd.tams.module.coursescheduling.model.data.CourseSchedulingDO;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingBatchSaveDTO;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingSaveDTO;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingTimeUpdateDTO;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingUpdateDTO;
import com.lhd.tams.module.coursescheduling.model.vo.CourseSchedulingListVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public abstract class AbstractCourseSchedulingConverter {
public static AbstractCourseSchedulingConverter INSTANCE = Mappers.getMapper(AbstractCourseSchedulingConverter.class);
public abstract List<CourseSchedulingListVO> doList2ListVoList(List<CourseSchedulingDO> doList);
public abstract CourseSchedulingListVO do2ListVO(CourseSchedulingDO dataObj);
public abstract CourseSchedulingDO saveDto2DO(CourseSchedulingSaveDTO saveDTO);
public abstract CourseSchedulingDO batchSaveDto2DO(CourseSchedulingBatchSaveDTO saveDTO);
public abstract CourseSchedulingDO timeUpdateDto2DO(CourseSchedulingTimeUpdateDTO updateDTO);
public abstract CourseSchedulingDO updateDto2DO(CourseSchedulingUpdateDTO updateDTO);
}

View File

@ -0,0 +1,47 @@
package com.lhd.tams.module.coursescheduling.model.data;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalTime;
@Data
@TableName("t_course_scheduling")
public class CourseSchedulingDO {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 教室id
*/
private Long classroomId;
/**
* 课程id
*/
private Long courseId;
/**
* 老师id
*/
private Long teacherId;
/**
* 日期
*/
private LocalDate date;
/**
* 上课时间
*/
private LocalTime attendTime;
/**
* 下课时间
*/
private LocalTime finishTime;
}

View File

@ -0,0 +1,47 @@
package com.lhd.tams.module.coursescheduling.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
@Schema(description = "排课批量新增参数")
@Data
public class CourseSchedulingBatchSaveDTO {
@NotNull
@Schema(description = "教室id")
private Long classroomId;
@NotNull
@Schema(description = "课程id")
private Long courseId;
@NotNull
@Schema(description = "老师id")
private Long teacherId;
@NotNull
@Schema(description = "上课时间")
private LocalTime attendTime;
@NotNull
@Schema(description = "下课时间")
private LocalTime finishTime;
@NotNull
@Schema(description = "开课日期")
private LocalDate startDate;
@NotNull
@Schema(description = "结课日期")
private LocalDate endDate;
@NotEmpty
@Schema(description = "周几上课列表")
private List<Integer> weekList;
}

View File

@ -0,0 +1,36 @@
package com.lhd.tams.module.coursescheduling.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "排课导出参数")
@Data
public class CourseSchedulingExportDTO {
@NotNull
@Schema(description = "开课日期")
private String startDate;
@NotNull
@Schema(description = "结课日期")
private String endDate;
@Schema(description = "标题")
private String title;
@Schema(description = "文件名")
private String filename;
@Schema(description = "sheet命名方式")
private Integer sheetNamingType;
@Schema(description = "指定教室id")
private Long classroomId;
@Schema(description = "指定教室名称")
private String classroomName;
@Schema(description = "是否显示周末")
private Boolean isShowWeek;
}

View File

@ -0,0 +1,32 @@
package com.lhd.tams.module.coursescheduling.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "排课查询参数")
public class CourseSchedulingQuery {
@Schema(description = "教室id列表")
private List<Long> classroomIdList;
@Schema(description = "课程id列表")
private List<Long> courseIdList;
@Schema(description = "老师id列表")
private List<Long> teacherIdList;
@Schema(description = "开始日期")
private String startDate;
@Schema(description = "结束日期")
private String endDate;
@Schema(description = "上课时间")
private String attendTime;
@Schema(description = "下课时间")
private String finishTime;
}

View File

@ -0,0 +1,37 @@
package com.lhd.tams.module.coursescheduling.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalTime;
@Schema(description = "排课新增参数")
@Data
public class CourseSchedulingSaveDTO {
@NotNull
@Schema(description = "教室id")
private Long classroomId;
@NotNull
@Schema(description = "课程id")
private Long courseId;
@NotNull
@Schema(description = "老师id")
private Long teacherId;
@NotNull
@Schema(description = "日期")
private LocalDate date;
@NotNull
@Schema(description = "上课时间")
private LocalTime attendTime;
@NotNull
@Schema(description = "下课时间")
private LocalTime finishTime;
}

View File

@ -0,0 +1,25 @@
package com.lhd.tams.module.coursescheduling.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalTime;
@Schema(description = "排课时间修改参数")
@Data
public class CourseSchedulingTimeUpdateDTO {
@NotNull
@Schema(description = "日期")
private LocalDate date;
@NotNull
@Schema(description = "上课时间")
private LocalTime attendTime;
@NotNull
@Schema(description = "下课时间")
private LocalTime finishTime;
}

View File

@ -0,0 +1,22 @@
package com.lhd.tams.module.coursescheduling.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "排课修改参数")
@Data
public class CourseSchedulingUpdateDTO {
@NotNull
@Schema(description = "教室id")
private Long classroomId;
@NotNull
@Schema(description = "课程id")
private Long courseId;
@NotNull
@Schema(description = "老师id")
private Long teacherId;
}

View File

@ -0,0 +1,29 @@
package com.lhd.tams.module.coursescheduling.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDate;
@Schema(description = "排课导出返回结果")
@Data
public class CourseSchedulingExportVO {
@Schema(description = "教室名称")
private String classroomName;
@Schema(description = "课程名称")
private String courseName;
@Schema(description = "课程背景颜色")
private String backgroundColor;
@Schema(description = "老师姓名")
private String teacherName;
@Schema(description = "日期")
private LocalDate date;
@Schema(description = "时间")
private String time;
}

View File

@ -0,0 +1,48 @@
package com.lhd.tams.module.coursescheduling.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalTime;
@Schema(description = "排课列表返回结果")
@Data
public class CourseSchedulingListVO {
@Schema(description = "id")
private Long id;
@Schema(description = "教室id")
private Long classroomId;
@Schema(description = "教室名称")
private String classroomName;
@Schema(description = "课程id")
private Long courseId;
@Schema(description = "课程名称")
private String courseName;
@Schema(description = "课程时长,单位分钟")
private Integer duration;
@Schema(description = "课程背景颜色")
private String backgroundColor;
@Schema(description = "老师id")
private Long teacherId;
@Schema(description = "老师姓名")
private String teacherName;
@Schema(description = "日期")
private LocalDate date;
@Schema(description = "上课时间")
private LocalTime attendTime;
@Schema(description = "下课时间")
private LocalTime finishTime;
}

View File

@ -0,0 +1,21 @@
package com.lhd.tams.module.coursescheduling.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "排课报表返回结果")
@Data
public class CourseSchedulingReportVO {
@Schema(description = "id")
private Long id;
@Schema(description = "名称")
private String name;
@Schema(description = "颜色")
private String color;
@Schema(description = "数量")
private Integer count;
}

View File

@ -0,0 +1,36 @@
package com.lhd.tams.module.coursescheduling.service;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingBatchSaveDTO;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingQuery;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingSaveDTO;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingTimeUpdateDTO;
import com.lhd.tams.module.coursescheduling.model.vo.CourseSchedulingListVO;
import com.lhd.tams.module.coursescheduling.model.vo.CourseSchedulingReportVO;
import java.util.List;
import java.util.Map;
public interface CourseSchedulingService {
List<CourseSchedulingListVO> listCourseScheduling(CourseSchedulingQuery query);
CourseSchedulingListVO getCourseSchedulingById(Long id);
Map<String, Integer> getCourseSchedulingCourseCount(CourseSchedulingQuery query);
List<CourseSchedulingReportVO> getReportTeacherCount(String startDate, String endDate);
List<CourseSchedulingReportVO> getReportCourseCount(String startDate, String endDate);
boolean saveCourseScheduling(CourseSchedulingSaveDTO saveDTO);
void batchSaveCourseScheduling(CourseSchedulingBatchSaveDTO saveDTO);
boolean updateCourseSchedulingTimeById(Long id, CourseSchedulingTimeUpdateDTO updateDTO);
boolean updateCourseSchedulingById(Long id, CourseSchedulingSaveDTO saveDTO);
boolean removeCourseSchedulingById(Long id);
void removeCourseSchedulingByIdList(List<Long> idList);
}

View File

@ -0,0 +1,232 @@
package com.lhd.tams.module.coursescheduling.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lhd.tams.common.consts.ErrorCodeEnum;
import com.lhd.tams.common.exception.BusinessException;
import com.lhd.tams.module.coursescheduling.dao.CourseSchedulingMapper;
import com.lhd.tams.module.coursescheduling.model.convert.AbstractCourseSchedulingConverter;
import com.lhd.tams.module.coursescheduling.model.data.CourseSchedulingDO;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingBatchSaveDTO;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingQuery;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingSaveDTO;
import com.lhd.tams.module.coursescheduling.model.dto.CourseSchedulingTimeUpdateDTO;
import com.lhd.tams.module.coursescheduling.model.vo.CourseSchedulingListVO;
import com.lhd.tams.module.coursescheduling.model.vo.CourseSchedulingReportVO;
import com.lhd.tams.module.coursescheduling.service.CourseSchedulingService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
@Slf4j
@Service
public class CourseSchedulingServiceImpl extends ServiceImpl<CourseSchedulingMapper, CourseSchedulingDO> implements CourseSchedulingService {
@Override
public List<CourseSchedulingListVO> listCourseScheduling(CourseSchedulingQuery query) {
QueryWrapper<CourseSchedulingDO> queryWrapper = Wrappers.<CourseSchedulingDO>query()
.in(query.getClassroomIdList() != null && query.getClassroomIdList().size() > 0, "cs.classroom_id", query.getClassroomIdList())
.in(query.getCourseIdList() != null && query.getCourseIdList().size() > 0, "cs.course_id", query.getCourseIdList())
.in(query.getTeacherIdList() != null && query.getTeacherIdList().size() > 0, "cs.teacher_id", query.getTeacherIdList())
.ge(StringUtils.isNotEmpty(query.getStartDate()), "cs.date", query.getStartDate())
.le(StringUtils.isNotEmpty(query.getEndDate()), "cs.date", query.getEndDate())
.eq(StringUtils.isNotEmpty(query.getAttendTime()), "cs.attend_time", query.getAttendTime())
.eq(StringUtils.isNotEmpty(query.getFinishTime()), "cs.finish_time", query.getFinishTime());
return baseMapper.selectCourseSchedulingList(queryWrapper);
}
@Override
public CourseSchedulingListVO getCourseSchedulingById(Long id) {
return baseMapper.selectCourseSchedulingById(id);
}
@Override
public Map<String, Integer> getCourseSchedulingCourseCount(CourseSchedulingQuery query) {
Map<String, Integer> map = new HashMap<>();
QueryWrapper<CourseSchedulingDO> queryWrapper = Wrappers.<CourseSchedulingDO>query()
.in(query.getClassroomIdList() != null && query.getClassroomIdList().size() > 0, "classroom_id", query.getClassroomIdList())
.in(query.getCourseIdList() != null && query.getCourseIdList().size() > 0, "course_id", query.getCourseIdList())
.in(query.getTeacherIdList() != null && query.getTeacherIdList().size() > 0, "teacher_id", query.getTeacherIdList())
.ge(StringUtils.isNotEmpty(query.getStartDate()), "date", query.getStartDate())
.le(StringUtils.isNotEmpty(query.getEndDate()), "date", query.getEndDate())
.groupBy("date")
.orderByAsc("date");;
List<Map<String, String>> list = baseMapper.selectCourseSchedulingCourseCount(queryWrapper);
if (list != null && list.size() > 0) {
list.forEach(item -> map.put(String.valueOf(item.get("date")), item.get("count") != null ? Integer.parseInt(String.valueOf(item.get("count"))) : 0));
}
return map;
}
@Override
public List<CourseSchedulingReportVO> getReportTeacherCount(String startDate, String endDate) {
return baseMapper.selectReportTeacherCount(startDate, endDate);
}
@Override
public List<CourseSchedulingReportVO> getReportCourseCount(String startDate, String endDate) {
return baseMapper.selectReportCourseCount(startDate, endDate);
}
@Override
public boolean saveCourseScheduling(CourseSchedulingSaveDTO saveDTO) {
check(null, saveDTO.getClassroomId(), saveDTO.getTeacherId(), saveDTO.getDate(), saveDTO.getAttendTime(), saveDTO.getFinishTime());
CourseSchedulingDO dataObj = AbstractCourseSchedulingConverter.INSTANCE.saveDto2DO(saveDTO);
return save(dataObj);
}
@Override
public void batchSaveCourseScheduling(CourseSchedulingBatchSaveDTO saveDTO) {
List<Integer> weekList = saveDTO.getWeekList();
LocalDate startDate = saveDTO.getStartDate();
LocalDate endDate = saveDTO.getEndDate();
List<LocalDate> dateList = new ArrayList<>();
while (startDate.compareTo(endDate) <= 0) {
if (weekList.contains(startDate.getDayOfWeek().getValue())) {
dateList.add(startDate);
}
startDate = startDate.plusDays(1);
}
List<CourseSchedulingListVO> voList = baseMapper.selectCourseSchedulingList(Wrappers.<CourseSchedulingDO>query()
.eq("cs.classroom_id",saveDTO.getClassroomId())
.in("cs.date", dateList)
.orderByAsc("cs.date, cs.attend_time"));
Set<String> errorSet = new HashSet<>();
for (CourseSchedulingListVO vo : voList) {
if (isTimeConflict(saveDTO.getAttendTime(), saveDTO.getFinishTime(), vo.getAttendTime(), vo.getFinishTime())) {
errorSet.add(String.format("%s %s-%s %s %s %s", vo.getDate(), vo.getAttendTime(), vo.getFinishTime(), vo.getClassroomName(), vo.getCourseName(), vo.getTeacherName()));
}
}
List<CourseSchedulingListVO> teacherVoList = baseMapper.selectCourseSchedulingList(Wrappers.<CourseSchedulingDO>query()
.eq("cs.teacher_id", saveDTO.getTeacherId())
.in("cs.date", dateList)
.orderByAsc("cs.date, cs.attend_time"));
for (CourseSchedulingListVO vo : teacherVoList) {
if (isTimeConflict(saveDTO.getAttendTime(), saveDTO.getFinishTime(), vo.getAttendTime(), vo.getFinishTime())) {
errorSet.add(String.format("%s %s-%s %s %s %s", vo.getDate(), vo.getAttendTime(), vo.getFinishTime(), vo.getClassroomName(), vo.getCourseName(), vo.getTeacherName()));
}
}
if (errorSet.size() > 0) {
throw new BusinessException(ErrorCodeEnum.BUSINESS_COURSE_SCHEDULING_DATE_CONFLICT.getCode(), errorSet, "检测到排课时间冲突", null);
}
List<CourseSchedulingDO> doList = new ArrayList<>();
for (LocalDate date : dateList) {
CourseSchedulingDO dataObj = AbstractCourseSchedulingConverter.INSTANCE.batchSaveDto2DO(saveDTO);
dataObj.setDate(date);
doList.add(dataObj);
}
saveBatch(doList);
}
@Override
public boolean updateCourseSchedulingTimeById(Long id, CourseSchedulingTimeUpdateDTO updateDTO) {
CourseSchedulingDO detailDO = getById(id);
check(id, detailDO.getClassroomId(), detailDO.getTeacherId(), updateDTO.getDate(), updateDTO.getAttendTime(), updateDTO.getFinishTime());
CourseSchedulingDO dataObj = AbstractCourseSchedulingConverter.INSTANCE.timeUpdateDto2DO(updateDTO);
dataObj.setId(id);
return updateById(dataObj);
}
@Override
public boolean updateCourseSchedulingById(Long id, CourseSchedulingSaveDTO saveDTO) {
check(id, saveDTO.getClassroomId(), saveDTO.getTeacherId(), saveDTO.getDate(), saveDTO.getAttendTime(), saveDTO.getFinishTime());
CourseSchedulingDO dataObj = AbstractCourseSchedulingConverter.INSTANCE.saveDto2DO(saveDTO);
dataObj.setId(id);
return updateById(dataObj);
}
@Override
public boolean removeCourseSchedulingById(Long id) {
return removeById(id);
}
@Override
public void removeCourseSchedulingByIdList(List<Long> idList) {
remove(Wrappers.<CourseSchedulingDO>lambdaUpdate()
.in(CourseSchedulingDO::getId, idList));
}
private void check(Long id, Long classroomId, Long teacherId, LocalDate date, LocalTime attendTime, LocalTime finishTime) {
List<CourseSchedulingListVO> classroomVoList = baseMapper.selectCourseSchedulingList(Wrappers.<CourseSchedulingDO>query()
.ne(id != null, "cs.id", id)
.eq("cs.classroom_id", classroomId)
.eq("cs.date", date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.orderByAsc("cs.attend_time"));
for (CourseSchedulingListVO vo : classroomVoList) {
/**
* 同一教室不能同时上多节课
*/
if (isTimeConflict(attendTime, finishTime, vo.getAttendTime(), vo.getFinishTime())) {
throw new BusinessException(String.format("教室时间冲突,冲突信息【%s %s-%s %s %s %s】",
vo.getDate(), vo.getAttendTime(), vo.getFinishTime(), vo.getClassroomName(), vo.getCourseName(), vo.getTeacherName()));
}
}
List<CourseSchedulingListVO> teacherVoList = baseMapper.selectCourseSchedulingList(Wrappers.<CourseSchedulingDO>query()
.ne(id != null, "cs.id", id)
.eq("cs.teacher_id", teacherId)
.eq("cs.date", date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.orderByAsc("cs.attend_time"));
for (CourseSchedulingListVO vo : teacherVoList) {
/**
* 同一老师不能同时上多节课
*/
if (isTimeConflict(attendTime, finishTime, vo.getAttendTime(), vo.getFinishTime())) {
throw new BusinessException(String.format("老师时间冲突,冲突信息【%s %s-%s %s %s %s】",
vo.getDate(), vo.getAttendTime(), vo.getFinishTime(), vo.getClassroomName(), vo.getCourseName(), vo.getTeacherName()));
}
}
}
private Integer calcMinute(LocalTime time) {
return time.getHour() * 60 + time.getMinute();
}
private boolean isBetween(LocalTime time, LocalTime destTime1, LocalTime destTime2) {
Integer minute = calcMinute(time);
return calcMinute(destTime1) < minute && minute < calcMinute(destTime2);
}
/**
* 新增时间范围跨度较小在现有时间范围内
* 新增时间是否在已有课程的时间段在则冲突
* 新增时间范围跨度较大大包含现有时间段
* 现有时间是否在新增时间范围内在则冲突
* 时间完全相等
*/
private boolean isTimeConflict(LocalTime attendTime1, LocalTime finishTime1, LocalTime attendTime2, LocalTime finishTime2) {
return isBetween(attendTime1, attendTime2, finishTime2)
|| isBetween(finishTime1, attendTime2, finishTime2)
|| isBetween(attendTime2, attendTime1, finishTime1)
|| isBetween(finishTime2, attendTime1, finishTime1)
|| (attendTime1.equals(attendTime2) && finishTime1.equals(finishTime2));
}
}

View File

@ -0,0 +1,98 @@
package com.lhd.tams.module.registration.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhd.tams.common.base.BaseController;
import com.lhd.tams.common.model.ApiResult;
import com.lhd.tams.module.registration.model.dto.RegistrationPageQuery;
import com.lhd.tams.module.registration.model.dto.RegistrationSaveDTO;
import com.lhd.tams.module.registration.model.vo.RegistrationListVO;
import com.lhd.tams.module.registration.service.RegistrationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.List;
@Tag(name = "上课统计")
@RequestMapping("registration")
@RestController
public class RegistrationController extends BaseController {
@Autowired
private RegistrationService registrationService;
@Operation(summary = "求和列表")
@PostMapping("sum")
public ResponseEntity<ApiResult<List<RegistrationListVO>>> listRegistration(@RequestBody RegistrationPageQuery query) {
if (StringUtils.hasLength(query.getStartClassTime())) {
query.setStartClassTime(query.getStartClassTime() + " 00:00:00");
}
if (StringUtils.hasLength(query.getEndClassTime())) {
query.setEndClassTime(query.getEndClassTime() + " 23:59:59");
}
return success(registrationService.listRegistration(query));
}
@Operation(summary = "导出excel")
@PostMapping("sum/excel")
public void listRegistrationExcel(HttpServletResponse response, @RequestBody RegistrationPageQuery query) throws IOException {
//
//
// String filename = (StringUtils.isEmpty(dto.getFilename()) ? "课表" : dto.getFilename()) + ".xlsx";
// response.reset();
// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
// response.setHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes(), StandardCharsets.ISO_8859_1));
//
// workbook.write(response.getOutputStream());
// response.flushBuffer();
//
// workbook.close();
}
@Operation(summary = "分页列表")
@PostMapping("page")
public ResponseEntity<ApiResult<IPage<RegistrationListVO>>> pageRegistration(@RequestBody RegistrationPageQuery pageQuery) {
return success(registrationService.pageRegistration(pageQuery));
}
@Operation(summary = "参照列表")
@GetMapping("list/ref")
public ResponseEntity<ApiResult<List<RegistrationListVO>>> refList() {
return success(registrationService.refList());
}
@Operation(summary = "详情")
@GetMapping("{id}")
public ResponseEntity<ApiResult<RegistrationListVO>> getRegistrationById(@PathVariable("id") Long id) {
return success(registrationService.getRegistrationById(id));
}
@Operation(summary = "新增")
@PostMapping
public ResponseEntity<ApiResult<?>> saveRegistration(@Validated @RequestBody RegistrationSaveDTO saveDTO) {
return successOrFail(registrationService.saveRegistration(saveDTO));
}
@Operation(summary = "修改")
@PutMapping("{id}")
public ResponseEntity<ApiResult<?>> updateRegistrationById(@PathVariable("id") Long id, @Validated @RequestBody RegistrationSaveDTO saveDTO) {
return successOrFail(registrationService.updateRegistrationById(id, saveDTO));
}
@Operation(summary = "停启用")
@PutMapping("{id}/enable-state/{enableState}")
public ResponseEntity<ApiResult<?>> updateRegistrationEnableStateById(@PathVariable("id") Long id, @PathVariable("enableState") Integer enableState) {
return successOrFail(registrationService.updateRegistrationEnableStateById(id, enableState));
}
}

View File

@ -0,0 +1,13 @@
package com.lhd.tams.module.registration.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lhd.tams.module.registration.model.data.RegistrationDO;
import com.lhd.tams.module.registration.model.dto.RegistrationPageQuery;
import com.lhd.tams.module.registration.model.vo.RegistrationListVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface RegistrationMapper extends BaseMapper<RegistrationDO> {
List<RegistrationListVO> selectRegistrationMapperSum(@Param("params") RegistrationPageQuery params);
}

View File

@ -0,0 +1,26 @@
package com.lhd.tams.module.registration.model.convert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lhd.tams.module.registration.model.data.RegistrationDO;
import com.lhd.tams.module.registration.model.dto.RegistrationSaveDTO;
import com.lhd.tams.module.registration.model.vo.RegistrationListVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public abstract class AbstractRegistrationConverter {
public static AbstractRegistrationConverter INSTANCE = Mappers.getMapper(AbstractRegistrationConverter.class);
public abstract Page<RegistrationListVO> doPage2ListVoPage(IPage<RegistrationDO> doPage);
public abstract List<RegistrationListVO> doList2ListVoList(List<RegistrationDO> doList);
public abstract RegistrationListVO do2ListVO(RegistrationDO dataObj);
public abstract RegistrationDO saveDto2DO(RegistrationSaveDTO saveDTO);
}

View File

@ -0,0 +1,51 @@
package com.lhd.tams.module.registration.model.data;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("t_registration")
public class RegistrationDO {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 学员
*/
private Long studentId;
private String studentName;
private String studentPhone;
/**
* 课程
*/
private Long courseId;
private String courseName;
/**
* 课程时长单位分钟
*/
private Integer duration;
/**
* 课时
*/
private Double lesson;
/**
* 上课时间
*/
private LocalDateTime classTime;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 停启用状态
*/
private Integer enableState;
}

View File

@ -0,0 +1,28 @@
package com.lhd.tams.module.registration.model.dto;
import com.lhd.tams.common.model.BasePageQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Schema(description = "上课统计分页查询参数")
@Data
public class RegistrationPageQuery extends BasePageQuery {
@Schema(description = "停启用状态")
private Integer enableState;
@Schema(description = "课程id列表")
private List<Long> courseIdList;
@Schema(description = "学员id列表")
private List<Long> studentIdList;
@Schema(description = "开始上课日期")
private String startClassTime;
@Schema(description = "结束上课日期")
private String endClassTime;
}

View File

@ -0,0 +1,27 @@
package com.lhd.tams.module.registration.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "上课统计分页查询参数")
@Data
public class RegistrationSaveDTO {
@Schema(description = "学员id")
private List<Long> studentIds;
@Schema(description = "课程id")
private Long courseId;
@Schema(description = "真实课程时长,单位分钟")
private Integer duration;
@Schema(description = "真实课时")
private Double lesson;
@Schema(description = "上课时间")
private LocalDateTime classTime;
}

View File

@ -0,0 +1,38 @@
package com.lhd.tams.module.registration.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "上课统计列表返回结果")
@Data
public class RegistrationListVO {
@Schema(description = "id")
private Long id;
@Schema(description = "学员姓名")
private String studentName;
@Schema(description = "电话")
private String studentPhone;
@Schema(description = "课程名称")
private String courseName;
@Schema(description = "真实课程时长,单位分钟")
private Integer duration;
@Schema(description = "真实课时")
private Double lesson;
@Schema(description = "上课时间")
private LocalDateTime classTime;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "停启用状态")
private Integer enableState;
}

View File

@ -0,0 +1,27 @@
package com.lhd.tams.module.registration.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhd.tams.module.registration.model.dto.RegistrationPageQuery;
import com.lhd.tams.module.registration.model.dto.RegistrationSaveDTO;
import com.lhd.tams.module.registration.model.vo.RegistrationListVO;
import java.util.List;
public interface RegistrationService {
IPage<RegistrationListVO> pageRegistration(RegistrationPageQuery pageQuery);
List<RegistrationListVO> refList();
RegistrationListVO getRegistrationById(Long id);
boolean saveRegistration(RegistrationSaveDTO saveDTO);
boolean updateRegistrationById(Long id, RegistrationSaveDTO saveDTO);
boolean updateRegistrationEnableStateById(Long id, Integer enableState);
IPage<RegistrationListVO> pageRegistrationList(RegistrationPageQuery pageQuery);
List<RegistrationListVO> listRegistration(RegistrationPageQuery pageQuery);
}

View File

@ -0,0 +1,147 @@
package com.lhd.tams.module.registration.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lhd.tams.common.consts.EnableStateEnum;
import com.lhd.tams.module.course.model.vo.CourseListVO;
import com.lhd.tams.module.course.service.CourseService;
import com.lhd.tams.module.registration.dao.RegistrationMapper;
import com.lhd.tams.module.registration.model.convert.AbstractRegistrationConverter;
import com.lhd.tams.module.registration.model.data.RegistrationDO;
import com.lhd.tams.module.registration.model.dto.RegistrationPageQuery;
import com.lhd.tams.module.registration.model.dto.RegistrationSaveDTO;
import com.lhd.tams.module.registration.model.vo.RegistrationListVO;
import com.lhd.tams.module.registration.service.RegistrationService;
import com.lhd.tams.module.student.model.vo.StudentListVO;
import com.lhd.tams.module.student.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class RegistrationServiceImpl extends ServiceImpl<RegistrationMapper, RegistrationDO> implements RegistrationService {
@Autowired
private StudentService studentService;
@Autowired
private CourseService courseService;
@Override
public List<RegistrationListVO> listRegistration(RegistrationPageQuery query) {
return baseMapper.selectRegistrationMapperSum(query);
}
@Override
public IPage<RegistrationListVO> pageRegistration(RegistrationPageQuery query) {
LambdaQueryWrapper<RegistrationDO> queryWrapper = Wrappers.<RegistrationDO>lambdaQuery()
.eq(query.getEnableState() != null, RegistrationDO::getEnableState, query.getEnableState());
if (!CollectionUtils.isEmpty(query.getStudentIdList())) {
queryWrapper.in(RegistrationDO::getStudentId, query.getStudentIdList());
}
if (!CollectionUtils.isEmpty(query.getCourseIdList())) {
queryWrapper.in(RegistrationDO::getCourseId, query.getCourseIdList());
}
if (StringUtils.hasLength(query.getStartClassTime())) {
queryWrapper.ge(RegistrationDO::getClassTime, query.getStartClassTime());
}
if (StringUtils.hasLength(query.getEndClassTime())) {
queryWrapper.le(RegistrationDO::getClassTime, query.getEndClassTime());
}
queryWrapper.orderByDesc(RegistrationDO::getCreateTime);
IPage<RegistrationDO> doPage = page(new Page<>(query.getCurrent(), query.getSize()), queryWrapper);
IPage<RegistrationListVO> voPage = AbstractRegistrationConverter.INSTANCE.doPage2ListVoPage(doPage);
return voPage;
}
@Override
public IPage<RegistrationListVO> pageRegistrationList(RegistrationPageQuery pageQuery) {
LambdaQueryWrapper<RegistrationDO> queryWrapper = Wrappers.<RegistrationDO>lambdaQuery()
.eq(pageQuery.getEnableState() != null, RegistrationDO::getEnableState, pageQuery.getEnableState())
.orderByDesc(RegistrationDO::getCreateTime);
IPage<RegistrationDO> doPage = page(new Page<>(pageQuery.getCurrent(), pageQuery.getSize()), queryWrapper);
IPage<RegistrationListVO> voPage = AbstractRegistrationConverter.INSTANCE.doPage2ListVoPage(doPage);
return voPage;
}
@Override
public List<RegistrationListVO> refList() {
LambdaQueryWrapper<RegistrationDO> queryWrapper = Wrappers.<RegistrationDO>lambdaQuery()
.eq(RegistrationDO::getEnableState, EnableStateEnum.ENABLED.getCode())
.orderByAsc(RegistrationDO::getStudentName);
List<RegistrationDO> doList = list(queryWrapper);
List<RegistrationListVO> voList = AbstractRegistrationConverter.INSTANCE.doList2ListVoList(doList);
return voList;
}
@Override
public RegistrationListVO getRegistrationById(Long id) {
RegistrationDO dataObj = getById(id);
RegistrationListVO vo = AbstractRegistrationConverter.INSTANCE.do2ListVO(dataObj);
return vo;
}
@Override
public boolean saveRegistration(RegistrationSaveDTO saveDTO) {
Long courseId = saveDTO.getCourseId();
CourseListVO course = courseService.getCourseById(courseId);
if(saveDTO.getDuration() == null){
saveDTO.setDuration(course.getDuration());
}
if(saveDTO.getLesson() == null){
saveDTO.setLesson(course.getLesson());
}
List<Long> studentIds = saveDTO.getStudentIds();
for (Long studentId : studentIds) {
StudentListVO student = studentService.getStudentById(studentId);
RegistrationDO dataObj = AbstractRegistrationConverter.INSTANCE.saveDto2DO(saveDTO);
dataObj.setStudentId(studentId);
dataObj.setCourseName(course.getName());
dataObj.setStudentName(student.getName());
dataObj.setStudentPhone(student.getPhone());
dataObj.setCreateTime(LocalDateTime.now());
save(dataObj);
}
return true;
}
@Override
public boolean updateRegistrationById(Long id, RegistrationSaveDTO saveDTO) {
RegistrationDO dataObj = AbstractRegistrationConverter.INSTANCE.saveDto2DO(saveDTO);
dataObj.setId(id);
return updateById(dataObj);
}
@Override
public boolean updateRegistrationEnableStateById(Long id, Integer enableState) {
RegistrationDO dataObj = new RegistrationDO();
dataObj.setId(id);
dataObj.setEnableState(enableState);
return updateById(dataObj);
}
}

View File

@ -0,0 +1,41 @@
package com.lhd.tams.module.report.controller;
import com.lhd.tams.common.base.BaseController;
import com.lhd.tams.common.model.ApiResult;
import com.lhd.tams.module.coursescheduling.model.vo.CourseSchedulingReportVO;
import com.lhd.tams.module.coursescheduling.service.CourseSchedulingService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Tag(name = "报表")
@RequestMapping("report")
@RestController
public class ReportController extends BaseController {
@Autowired
private CourseSchedulingService courseSchedulingService;
@Operation(summary = "老师上课数量")
@GetMapping("teacher/count")
public ResponseEntity<ApiResult<List<CourseSchedulingReportVO>>> getReportTeacherCount(@RequestParam("startDate") String startDate,
@RequestParam("endDate") String endDate) {
return success(courseSchedulingService.getReportTeacherCount(startDate, endDate));
}
@Operation(summary = "课程数量")
@GetMapping("course/count")
public ResponseEntity<ApiResult<List<CourseSchedulingReportVO>>> getReportCourseCount(@RequestParam("startDate") String startDate,
@RequestParam("endDate") String endDate) {
return success(courseSchedulingService.getReportCourseCount(startDate, endDate));
}
}

View File

@ -0,0 +1,66 @@
package com.lhd.tams.module.student.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhd.tams.common.base.BaseController;
import com.lhd.tams.common.model.ApiResult;
import com.lhd.tams.module.student.model.dto.StudentPageQuery;
import com.lhd.tams.module.student.model.dto.StudentSaveDTO;
import com.lhd.tams.module.student.model.vo.StudentListVO;
import com.lhd.tams.module.student.service.StudentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Tag(name = "学员")
@RequestMapping("student")
@RestController
public class StudentController extends BaseController {
@Autowired
private StudentService studentService;
@Operation(summary = "分页列表")
@GetMapping
public ResponseEntity<ApiResult<IPage<StudentListVO>>> pageStudent(StudentPageQuery pageQuery) {
return success(studentService.pageStudent(pageQuery));
}
@Operation(summary = "参照列表")
@GetMapping("list/ref")
public ResponseEntity<ApiResult<List<StudentListVO>>> refList() {
return success(studentService.refList());
}
@Operation(summary = "详情")
@GetMapping("{id}")
public ResponseEntity<ApiResult<StudentListVO>> getStudentById(@PathVariable("id") Long id) {
return success(studentService.getStudentById(id));
}
@Operation(summary = "新增")
@PostMapping
public ResponseEntity<ApiResult<?>> saveStudent(@Validated @RequestBody StudentSaveDTO saveDTO) {
return successOrFail(studentService.saveStudent(saveDTO));
}
@Operation(summary = "修改")
@PutMapping("{id}")
public ResponseEntity<ApiResult<?>> updateStudentById(@PathVariable("id") Long id, @Validated @RequestBody StudentSaveDTO saveDTO) {
return successOrFail(studentService.updateStudentById(id, saveDTO));
}
@Operation(summary = "停启用")
@PutMapping("{id}/enable-state/{enableState}")
public ResponseEntity<ApiResult<?>> updateStudentEnableStateById(@PathVariable("id") Long id, @PathVariable("enableState") Integer enableState) {
return successOrFail(studentService.updateStudentEnableStateById(id, enableState));
}
}

View File

@ -0,0 +1,7 @@
package com.lhd.tams.module.student.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lhd.tams.module.student.model.data.StudentDO;
public interface StudentMapper extends BaseMapper<StudentDO> {
}

View File

@ -0,0 +1,26 @@
package com.lhd.tams.module.student.model.convert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lhd.tams.module.student.model.data.StudentDO;
import com.lhd.tams.module.student.model.dto.StudentSaveDTO;
import com.lhd.tams.module.student.model.vo.StudentListVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public abstract class AbstractStudentConverter {
public static AbstractStudentConverter INSTANCE = Mappers.getMapper(AbstractStudentConverter.class);
public abstract Page<StudentListVO> doPage2ListVoPage(IPage<StudentDO> doPage);
public abstract List<StudentListVO> doList2ListVoList(List<StudentDO> doList);
public abstract StudentListVO do2ListVO(StudentDO dataObj);
public abstract StudentDO saveDto2DO(StudentSaveDTO saveDTO);
}

View File

@ -0,0 +1,38 @@
package com.lhd.tams.module.student.model.data;
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 lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("t_student")
public class StudentDO {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 姓名
*/
private String name;
/**
* 电话
*/
private String phone;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 停启用状态
*/
private Integer enableState;
}

View File

@ -0,0 +1,13 @@
package com.lhd.tams.module.student.model.dto;
import com.lhd.tams.common.model.BasePageQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "学员分页查询参数")
@Data
public class StudentPageQuery extends BasePageQuery {
@Schema(description = "停启用状态")
private Integer enableState;
}

View File

@ -0,0 +1,15 @@
package com.lhd.tams.module.student.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "学员分页查询参数")
@Data
public class StudentSaveDTO {
@Schema(description = "姓名")
private String name;
@Schema(description = "电话")
private String phone;
}

View File

@ -0,0 +1,26 @@
package com.lhd.tams.module.student.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "学员列表返回结果")
@Data
public class StudentListVO {
@Schema(description = "id")
private Long id;
@Schema(description = "姓名")
private String name;
@Schema(description = "电话")
private String phone;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "停启用状态")
private Integer enableState;
}

View File

@ -0,0 +1,23 @@
package com.lhd.tams.module.student.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhd.tams.module.student.model.dto.StudentPageQuery;
import com.lhd.tams.module.student.model.dto.StudentSaveDTO;
import com.lhd.tams.module.student.model.vo.StudentListVO;
import java.util.List;
public interface StudentService {
IPage<StudentListVO> pageStudent(StudentPageQuery pageQuery);
List<StudentListVO> refList();
StudentListVO getStudentById(Long id);
boolean saveStudent(StudentSaveDTO saveDTO);
boolean updateStudentById(Long id, StudentSaveDTO saveDTO);
boolean updateStudentEnableStateById(Long id, Integer enableState);
}

View File

@ -0,0 +1,88 @@
package com.lhd.tams.module.student.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lhd.tams.common.consts.EnableStateEnum;
import com.lhd.tams.module.student.dao.StudentMapper;
import com.lhd.tams.module.student.model.convert.AbstractStudentConverter;
import com.lhd.tams.module.student.model.data.StudentDO;
import com.lhd.tams.module.student.model.dto.StudentPageQuery;
import com.lhd.tams.module.student.model.dto.StudentSaveDTO;
import com.lhd.tams.module.student.model.vo.StudentListVO;
import com.lhd.tams.module.student.service.StudentService;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, StudentDO> implements StudentService {
@Override
public IPage<StudentListVO> pageStudent(StudentPageQuery pageQuery) {
LambdaQueryWrapper<StudentDO> queryWrapper = Wrappers.<StudentDO>lambdaQuery()
.eq(pageQuery.getEnableState() != null, StudentDO::getEnableState, pageQuery.getEnableState())
.orderByAsc(StudentDO::getName);
IPage<StudentDO> doPage = page(new Page<>(pageQuery.getCurrent(), pageQuery.getSize()), queryWrapper);
IPage<StudentListVO> voPage = AbstractStudentConverter.INSTANCE.doPage2ListVoPage(doPage);
return voPage;
}
@Override
public List<StudentListVO> refList() {
LambdaQueryWrapper<StudentDO> queryWrapper = Wrappers.<StudentDO>lambdaQuery()
.eq(StudentDO::getEnableState, EnableStateEnum.ENABLED.getCode())
.orderByAsc(StudentDO::getName);
List<StudentDO> doList = list(queryWrapper);
List<StudentListVO> voList = AbstractStudentConverter.INSTANCE.doList2ListVoList(doList);
return voList;
}
@Override
public StudentListVO getStudentById(Long id) {
StudentDO dataObj = getById(id);
StudentListVO vo = AbstractStudentConverter.INSTANCE.do2ListVO(dataObj);
return vo;
}
@Override
public boolean saveStudent(StudentSaveDTO saveDTO) {
StudentDO dataObj = AbstractStudentConverter.INSTANCE.saveDto2DO(saveDTO);
dataObj.setCreateTime(LocalDateTime.now());
return save(dataObj);
}
@Override
public boolean updateStudentById(Long id, StudentSaveDTO saveDTO) {
StudentDO dataObj = AbstractStudentConverter.INSTANCE.saveDto2DO(saveDTO);
dataObj.setId(id);
return updateById(dataObj);
}
@Override
public boolean updateStudentEnableStateById(Long id, Integer enableState) {
StudentDO dataObj = new StudentDO();
dataObj.setId(id);
dataObj.setEnableState(enableState);
return updateById(dataObj);
}
}

View File

@ -0,0 +1,68 @@
package com.lhd.tams.module.teacher.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhd.tams.common.base.BaseController;
import com.lhd.tams.common.model.ApiResult;
import com.lhd.tams.module.teacher.model.dto.TeacherPageQuery;
import com.lhd.tams.module.teacher.model.dto.TeacherSaveDTO;
import com.lhd.tams.module.teacher.model.vo.TeacherListVO;
import com.lhd.tams.module.teacher.service.TeacherService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Tag(name = "教师")
@RequestMapping("teacher")
@RestController
public class TeacherController extends BaseController {
@Autowired
private TeacherService teacherService;
@Operation(summary = "分页列表")
@GetMapping
public ResponseEntity<ApiResult<IPage<TeacherListVO>>> pageTeacher(TeacherPageQuery pageQuery) {
return success(teacherService.pageTeacher(pageQuery));
}
@Operation(summary = "参照列表")
@GetMapping("list/ref")
public ResponseEntity<ApiResult<List<TeacherListVO>>> refList() {
return success(teacherService.refList());
}
@Operation(summary = "详情")
@GetMapping("{id}")
public ResponseEntity<ApiResult<TeacherListVO>> getTeacherById(@PathVariable("id") Long id) {
return success(teacherService.getTeacherById(id));
}
@Operation(summary = "新增")
@PostMapping
public ResponseEntity<ApiResult<?>> saveTeacher(@Validated @RequestBody TeacherSaveDTO saveDTO) {
return successOrFail(teacherService.saveTeacher(saveDTO));
}
@Operation(summary = "修改")
@PutMapping("{id}")
public ResponseEntity<ApiResult<?>> updateTeacherById(@PathVariable("id") Long id, @Validated @RequestBody TeacherSaveDTO saveDTO) {
return successOrFail(teacherService.updateTeacherById(id, saveDTO));
}
@Operation(summary = "停启用")
@PutMapping("{id}/enable-state/{enableState}")
public ResponseEntity<ApiResult<?>> updateTeacherEnableStateById(@PathVariable("id") Long id, @PathVariable("enableState") Integer enableState) {
return successOrFail(teacherService.updateTeacherEnableStateById(id, enableState));
}
}

View File

@ -0,0 +1,7 @@
package com.lhd.tams.module.teacher.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lhd.tams.module.teacher.model.data.TeacherDO;
public interface TeacherMapper extends BaseMapper<TeacherDO> {
}

View File

@ -0,0 +1,26 @@
package com.lhd.tams.module.teacher.model.convert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lhd.tams.module.teacher.model.data.TeacherDO;
import com.lhd.tams.module.teacher.model.dto.TeacherSaveDTO;
import com.lhd.tams.module.teacher.model.vo.TeacherListVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public abstract class AbstractTeacherConverter {
public static AbstractTeacherConverter INSTANCE = Mappers.getMapper(AbstractTeacherConverter.class);
public abstract Page<TeacherListVO> doPage2ListVoPage(IPage<TeacherDO> doPage);
public abstract List<TeacherListVO> doList2ListVoList(List<TeacherDO> doList);
public abstract TeacherListVO do2ListVO(TeacherDO dataObj);
public abstract TeacherDO saveDto2DO(TeacherSaveDTO saveDTO);
}

View File

@ -0,0 +1,24 @@
package com.lhd.tams.module.teacher.model.data;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("t_teacher")
public class TeacherDO {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 姓名
*/
private String name;
/**
* 停启用状态
*/
private Integer enableState;
}

View File

@ -0,0 +1,13 @@
package com.lhd.tams.module.teacher.model.dto;
import com.lhd.tams.common.model.BasePageQuery;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "教师分页查询参数")
@Data
public class TeacherPageQuery extends BasePageQuery {
@Schema(description = "停启用状态")
private Integer enableState;
}

View File

@ -0,0 +1,12 @@
package com.lhd.tams.module.teacher.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "教师分页查询参数")
@Data
public class TeacherSaveDTO {
@Schema(description = "姓名")
private String name;
}

View File

@ -0,0 +1,18 @@
package com.lhd.tams.module.teacher.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "教师列表返回结果")
@Data
public class TeacherListVO {
@Schema(description = "id")
private Long id;
@Schema(description = "姓名")
private String name;
@Schema(description = "停启用状态")
private Integer enableState;
}

View File

@ -0,0 +1,23 @@
package com.lhd.tams.module.teacher.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhd.tams.module.teacher.model.dto.TeacherPageQuery;
import com.lhd.tams.module.teacher.model.dto.TeacherSaveDTO;
import com.lhd.tams.module.teacher.model.vo.TeacherListVO;
import java.util.List;
public interface TeacherService {
IPage<TeacherListVO> pageTeacher(TeacherPageQuery pageQuery);
List<TeacherListVO> refList();
TeacherListVO getTeacherById(Long id);
boolean saveTeacher(TeacherSaveDTO saveDTO);
boolean updateTeacherById(Long id, TeacherSaveDTO saveDTO);
boolean updateTeacherEnableStateById(Long id, Integer enableState);
}

View File

@ -0,0 +1,87 @@
package com.lhd.tams.module.teacher.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lhd.tams.common.consts.EnableStateEnum;
import com.lhd.tams.module.teacher.dao.TeacherMapper;
import com.lhd.tams.module.teacher.model.convert.AbstractTeacherConverter;
import com.lhd.tams.module.teacher.model.data.TeacherDO;
import com.lhd.tams.module.teacher.model.dto.TeacherPageQuery;
import com.lhd.tams.module.teacher.model.dto.TeacherSaveDTO;
import com.lhd.tams.module.teacher.model.vo.TeacherListVO;
import com.lhd.tams.module.teacher.service.TeacherService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, TeacherDO> implements TeacherService {
@Override
public IPage<TeacherListVO> pageTeacher(TeacherPageQuery pageQuery) {
LambdaQueryWrapper<TeacherDO> queryWrapper = Wrappers.<TeacherDO>lambdaQuery()
.eq(pageQuery.getEnableState() != null, TeacherDO::getEnableState, pageQuery.getEnableState())
.orderByAsc(TeacherDO::getName);
IPage<TeacherDO> doPage = page(new Page<>(pageQuery.getCurrent(), pageQuery.getSize()), queryWrapper);
IPage<TeacherListVO> voPage = AbstractTeacherConverter.INSTANCE.doPage2ListVoPage(doPage);
return voPage;
}
@Override
public List<TeacherListVO> refList() {
LambdaQueryWrapper<TeacherDO> queryWrapper = Wrappers.<TeacherDO>lambdaQuery()
.eq(TeacherDO::getEnableState, EnableStateEnum.ENABLED.getCode())
.orderByAsc(TeacherDO::getName);
List<TeacherDO> doList = list(queryWrapper);
List<TeacherListVO> voList = AbstractTeacherConverter.INSTANCE.doList2ListVoList(doList);
return voList;
}
@Override
public TeacherListVO getTeacherById(Long id) {
TeacherDO dataObj = getById(id);
TeacherListVO vo = AbstractTeacherConverter.INSTANCE.do2ListVO(dataObj);
return vo;
}
@Override
public boolean saveTeacher(TeacherSaveDTO saveDTO) {
TeacherDO dataObj = AbstractTeacherConverter.INSTANCE.saveDto2DO(saveDTO);
return save(dataObj);
}
@Override
public boolean updateTeacherById(Long id, TeacherSaveDTO saveDTO) {
TeacherDO dataObj = AbstractTeacherConverter.INSTANCE.saveDto2DO(saveDTO);
dataObj.setId(id);
return updateById(dataObj);
}
@Override
public boolean updateTeacherEnableStateById(Long id, Integer enableState) {
TeacherDO dataObj = new TeacherDO();
dataObj.setId(id);
dataObj.setEnableState(enableState);
return updateById(dataObj);
}
}

View File

@ -0,0 +1,103 @@
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mall-tams-core?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: root
druid:
initial-size: 5 #连接池初始化大小
min-idle: 10 #最小空闲连接数
max-active: 20 #最大连接数
web-stat-filter:
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #不统计这些请求数据
stat-view-servlet: #访问监控网页的登录用户名和密码
login-username: druid
login-password: druid
redis:
host: localhost # Redis服务器地址
database: 0 # Redis数据库索引默认为0
port: 6379 # Redis服务器连接端口
password: Lzw8800580/ # Redis服务器连接密码默认为空
timeout: 3000ms # 连接超时时间(毫秒)
jackson:
time-zone: GMT+8
mvc:
pathmatch:
matching-strategy: ant_path_matcher
management: #开启SpringBoot Admin的监控
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
springdoc:
api-docs:
# 是否开启接口文档
enabled: true
# swagger-ui:
# # 持久化认证数据
# persistAuthorization: true
info:
# 标题
title: '标题:${spring.application.name}多租户管理系统_接口文档'
# 描述
description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
# 版本
version: '版本号: 1.0.0'
# 作者信息
contact:
name: Lion Li
email: crazylionli@163.com
url: https://gitee.com/dromara/RuoYi-Vue-Plus
components:
# 鉴权方式配置
security-schemes:
apiKey:
type: APIKEY
in: HEADER
name: Authorization
#这里定义了两个分组,可定义多个,也可以不定义
group-configs:
- group: 1.演示模块
packages-to-scan: org.dromara.demo
- group: 2.通用模块
packages-to-scan: org.dromara.web
- group: 3.系统模块
packages-to-scan: org.dromara.system
- group: 4.代码生成模块
packages-to-scan: org.dromara.generator
# 多租户配置
tenant:
# 是否开启
enable: true
# 排除表
excludes:
- sys_menu
- sys_tenant
- sys_tenant_package
- sys_saas_user_role
# MyBatisPlus配置
# https://baomidou.com/config/
mybatis-plus:
# 多包名使用 例如 org.dromara.**.mapper,org.xxx.**.mapper
mapperPackage: com.luban.api.dao
# # 实体扫描多个package用逗号或者分号分隔
# typeAliasesPackage: com.luban.api.entity
global-config:
dbConfig:
# 主键类型
# AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
# 如需改为自增 需要将数据库表全部设置为自增
idType: ASSIGN_ID

View File

@ -0,0 +1,101 @@
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mall-tams-core?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: root
druid:
initial-size: 5 #连接池初始化大小
min-idle: 10 #最小空闲连接数
max-active: 20 #最大连接数
web-stat-filter:
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #不统计这些请求数据
stat-view-servlet: #访问监控网页的登录用户名和密码
login-username: druid
login-password: druid
redis:
host: localhost # Redis服务器地址
database: 0 # Redis数据库索引默认为0
port: 6379 # Redis服务器连接端口
password: Lzw8800580/ # Redis服务器连接密码默认为空
timeout: 3000ms # 连接超时时间(毫秒)
jackson:
time-zone: GMT+8
mvc:
pathmatch:
matching-strategy: ant_path_matcher
management: #开启SpringBoot Admin的监控
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
springdoc:
api-docs:
# 是否开启接口文档
enabled: true
# swagger-ui:
# # 持久化认证数据
# persistAuthorization: true
info:
# 标题
title: '标题:${spring.application.name}多租户管理系统_接口文档'
# 描述
description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
# 版本
version: '版本号: 1.0.0'
# 作者信息
contact:
name: Lion Li
email: crazylionli@163.com
url: https://gitee.com/dromara/RuoYi-Vue-Plus
components:
# 鉴权方式配置
security-schemes:
apiKey:
type: APIKEY
in: HEADER
name: Authorization
#这里定义了两个分组,可定义多个,也可以不定义
group-configs:
- group: 1.演示模块
packages-to-scan: org.dromara.demo
- group: 2.通用模块
packages-to-scan: org.dromara.web
- group: 3.系统模块
packages-to-scan: org.dromara.system
- group: 4.代码生成模块
packages-to-scan: org.dromara.generator
# 多租户配置
tenant:
# 是否开启
enable: true
# 排除表
excludes:
- sys_menu
- sys_tenant
- sys_tenant_package
- sys_saas_user_role
# MyBatisPlus配置
# https://baomidou.com/config/
mybatis-plus:
# 多包名使用 例如 org.dromara.**.mapper,org.xxx.**.mapper
mapperPackage: com.lhd.tams.module.**.dao
# # 实体扫描多个package用逗号或者分号分隔
# typeAliasesPackage: com.luban.api.entity
global-config:
dbConfig:
# 主键类型
# AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
# 如需改为自增 需要将数据库表全部设置为自增
idType: ASSIGN_ID

View File

@ -0,0 +1,11 @@
spring:
profiles:
active: ${profiles.active}
application:
name: ruoyi-tams
# 开发环境配置
server:
# 服务器的HTTP端口默认为19100
port: 19201

View File

@ -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.lhd.tams.module.classroom.dao.ClassroomMapper">
</mapper>

View File

@ -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.lhd.tams.module.color.dao.ColorMapper">
</mapper>

View File

@ -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.lhd.tams.module.course.dao.CourseMapper">
</mapper>

View File

@ -0,0 +1,93 @@
<?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.lhd.tams.module.coursescheduling.dao.CourseSchedulingMapper">
<sql id="column">
cs.id, cs.classroom_id classroomId, classroom.name classroomName,
cs.course_id courseId, course.name courseName, course.duration, course.background_color backgroundColor,
cs.teacher_id teacherId, teacher.name teacherName,
cs.date, cs.attend_time attendTime, cs.finish_time finishTime
</sql>
<select id="selectCourseSchedulingList" resultType="CourseSchedulingListVO">
select
<include refid="column"></include>
from t_course_scheduling cs
left join t_classroom classroom on cs.classroom_id = classroom.id
left join t_course course on cs.course_id = course.id
left join t_teacher teacher on cs.teacher_id = teacher.id
where 1=1
<if test="ew.sqlSegment != ''">
and ${ew.sqlSegment}
</if>
</select>
<select id="selectCourseSchedulingById" resultType="CourseSchedulingListVO">
select
<include refid="column"></include>
from t_course_scheduling cs
left join t_classroom classroom on cs.classroom_id = classroom.id
left join t_course course on cs.course_id = course.id
left join t_teacher teacher on cs.teacher_id = teacher.id
where cs.id = #{id}
</select>
<select id="selectCourseSchedulingCourseCount" resultType="map">
select date, count(id) count
from t_course_scheduling
where 1=1
<if test="ew.sqlSegment != ''">
and ${ew.sqlSegment}
</if>
</select>
<select id="selectTimePeriodByDateRange" resultType="string">
select concat(date_format(attend_time, '%H:%i'), '-', date_format(finish_time, '%H:%i')) time
from t_course_scheduling
where date in
<foreach item="item" collection="dateList" separator="," open="(" close=")">
#{item}
</foreach>
<if test="classroomId != null">
and classroom_id = #{classroomId}
</if>
group by time
order by time
</select>
<select id="selectByDateRange" resultType="CourseSchedulingExportVO">
select date,
concat(date_format(cs.attend_time, '%H:%i'), '-', date_format(cs.finish_time, '%H:%i')) time,
classroom.name classroomName,
course.name courseName, course.background_color backgroundColor,
teacher.name teacherName
from t_course_scheduling cs
left join t_classroom classroom on cs.classroom_id = classroom.id
left join t_course course on cs.course_id = course.id
left join t_teacher teacher on cs.teacher_id = teacher.id
where date between #{startDate} and #{endDate}
<if test="classroomId != null">
and cs.classroom_id = #{classroomId}
</if>
order by date, time
</select>
<select id="selectReportTeacherCount" resultType="CourseSchedulingReportVO">
select teacher.id, teacher.name, count(cs.id) count
from t_teacher teacher
left join t_course_scheduling cs on teacher.id = cs.teacher_id
and cs.date between #{startDate} and #{endDate}
group by teacher.id, teacher.name
order by count desc;
</select>
<select id="selectReportCourseCount" resultType="CourseSchedulingReportVO">
select course.id, course.name, course.background_color color, count(cs.id) count
from t_course course
left join t_course_scheduling cs on course.id = cs.course_id
and cs.date between #{startDate} and #{endDate}
group by course.id, course.name
order by count desc;
</select>
</mapper>

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