首次提交
parent
d2d52257a8
commit
300a50843c
@ -0,0 +1,58 @@
|
|||||||
|
# ============================
|
||||||
|
# Java / Maven
|
||||||
|
# ============================
|
||||||
|
target/
|
||||||
|
*.class
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.log
|
||||||
|
*.logs
|
||||||
|
|
||||||
|
# ============================
|
||||||
|
# IDE
|
||||||
|
# ============================
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
.vscode/
|
||||||
|
.settings/
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# ============================
|
||||||
|
# OS
|
||||||
|
# ============================
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# ============================
|
||||||
|
# Logs
|
||||||
|
# ============================
|
||||||
|
logs/
|
||||||
|
*.log
|
||||||
|
*.log.*
|
||||||
|
|
||||||
|
# ============================
|
||||||
|
# Temp / Cache
|
||||||
|
# ============================
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.cache
|
||||||
|
|
||||||
|
# ============================
|
||||||
|
# Environment / Sensitive
|
||||||
|
# ============================
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
application-local.yml
|
||||||
|
application-dev.yml
|
||||||
|
|
||||||
|
# ============================
|
||||||
|
# Upload / Data
|
||||||
|
# ============================
|
||||||
|
upload/
|
||||||
|
data/
|
||||||
@ -0,0 +1,126 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||||
|
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.7.18</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.attendance</groupId>
|
||||||
|
<artifactId>attendance-system-server</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>attendance-system-server</name>
|
||||||
|
<description>教室智能人脸考勤系统后端服务</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<mybatis-plus.version>3.5.5</mybatis-plus.version>
|
||||||
|
<knife4j.version>4.4.0</knife4j.version>
|
||||||
|
<jwt.version>4.4.0</jwt.version>
|
||||||
|
<fastjson2.version>2.0.49</fastjson2.version>
|
||||||
|
<minio.version>8.5.7</minio.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!-- Hutool工具类 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>5.8.16</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Boot Starter -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- MySQL & MyBatis-Plus -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>8.0.33</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
|
<version>${mybatis-plus.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Knife4j (Swagger) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.xiaoymin</groupId>
|
||||||
|
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
|
||||||
|
<version>${knife4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JWT -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.auth0</groupId>
|
||||||
|
<artifactId>java-jwt</artifactId>
|
||||||
|
<version>${jwt.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JSON -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2</artifactId>
|
||||||
|
<version>${fastjson2.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- MinIO -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.minio</groupId>
|
||||||
|
<artifactId>minio</artifactId>
|
||||||
|
<version>${minio.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Test -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.attendance;
|
||||||
|
|
||||||
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableAsync
|
||||||
|
@MapperScan("com.attendance.mapper")
|
||||||
|
public class AttendanceApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(AttendanceApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
package com.attendance.aspect;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.attendance.annotation.OperationLog;
|
||||||
|
import com.attendance.common.UserContext;
|
||||||
|
import com.attendance.entity.SysOperationLog;
|
||||||
|
import com.attendance.service.SysOperationLogService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class OperationLogAspect {
|
||||||
|
|
||||||
|
private final SysOperationLogService sysOperationLogService;
|
||||||
|
|
||||||
|
@Around("@annotation(operationLog)")
|
||||||
|
public Object around(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
SysOperationLog logEntity = new SysOperationLog();
|
||||||
|
logEntity.setUserId(UserContext.getUserId());
|
||||||
|
logEntity.setUsername(UserContext.getUsername());
|
||||||
|
logEntity.setModule(operationLog.module());
|
||||||
|
logEntity.setAction(operationLog.action());
|
||||||
|
|
||||||
|
// 填充请求相关字段
|
||||||
|
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
|
if (attributes != null) {
|
||||||
|
HttpServletRequest request = attributes.getRequest();
|
||||||
|
logEntity.setMethod(request.getMethod());
|
||||||
|
logEntity.setRequestUrl(request.getRequestURI());
|
||||||
|
logEntity.setIpAddress(getClientIp(request));
|
||||||
|
logEntity.setUserAgent(request.getHeader("User-Agent"));
|
||||||
|
|
||||||
|
// 记录请求参数(排除文件上传等二进制参数)
|
||||||
|
Object[] args = joinPoint.getArgs();
|
||||||
|
try {
|
||||||
|
logEntity.setRequestParams(JSON.toJSONString(args));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logEntity.setRequestParams("[无法序列化的参数]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Object result;
|
||||||
|
try {
|
||||||
|
result = joinPoint.proceed();
|
||||||
|
logEntity.setStatus(1);
|
||||||
|
try {
|
||||||
|
logEntity.setResponseData(JSON.toJSONString(result));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logEntity.setResponseData("[无法序列化的响应]");
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
logEntity.setStatus(0);
|
||||||
|
logEntity.setErrorMsg(e.getMessage());
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
logEntity.setDuration((int) (System.currentTimeMillis() - startTime));
|
||||||
|
try {
|
||||||
|
sysOperationLogService.asyncSave(logEntity);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("保存操作日志失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取客户端真实IP */
|
||||||
|
private String getClientIp(HttpServletRequest request) {
|
||||||
|
String ip = request.getHeader("X-Forwarded-For");
|
||||||
|
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||||
|
ip = request.getHeader("X-Real-IP");
|
||||||
|
}
|
||||||
|
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||||
|
ip = request.getHeader("Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||||
|
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||||
|
ip = request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
// 多级代理取第一个IP
|
||||||
|
if (ip != null && ip.contains(",")) {
|
||||||
|
ip = ip.split(",")[0].trim();
|
||||||
|
}
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.attendance.common;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class BusinessException extends RuntimeException {
|
||||||
|
|
||||||
|
private final Integer code;
|
||||||
|
|
||||||
|
public BusinessException(String message) {
|
||||||
|
super(message);
|
||||||
|
this.code = ResultCode.ERROR.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessException(ResultCode resultCode) {
|
||||||
|
super(resultCode.getMessage());
|
||||||
|
this.code = resultCode.getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BusinessException(Integer code, String message) {
|
||||||
|
super(message);
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.attendance.common;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.validation.BindException;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
@ExceptionHandler(BusinessException.class)
|
||||||
|
public Result<Void> handleBusinessException(BusinessException e) {
|
||||||
|
log.warn("业务异常: {}", e.getMessage());
|
||||||
|
return Result.error(e.getCode(), e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(BindException.class)
|
||||||
|
public Result<Void> handleBindException(BindException e) {
|
||||||
|
String message = e.getAllErrors().get(0).getDefaultMessage();
|
||||||
|
log.warn("参数校验失败: {}", message);
|
||||||
|
return Result.error(ResultCode.PARAM_VALIDATE_FAILED.getCode(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(IllegalArgumentException.class)
|
||||||
|
public Result<Void> handleIllegalArgumentException(IllegalArgumentException e) {
|
||||||
|
log.warn("参数异常: {}", e.getMessage());
|
||||||
|
return Result.error(ResultCode.PARAM_ERROR.getCode(), e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(Exception.class)
|
||||||
|
public Result<Void> handleException(Exception e) {
|
||||||
|
log.error("系统异常", e);
|
||||||
|
return Result.error("服务器异常,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
package com.attendance.common;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "统一响应结果")
|
||||||
|
public class Result<T> {
|
||||||
|
|
||||||
|
@Schema(description = "状态码", example = "200")
|
||||||
|
private Integer code;
|
||||||
|
|
||||||
|
@Schema(description = "提示消息", example = "操作成功")
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
@Schema(description = "响应数据")
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
@Schema(description = "时间戳")
|
||||||
|
private Long timestamp;
|
||||||
|
|
||||||
|
public Result() {
|
||||||
|
this.timestamp = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> success() {
|
||||||
|
return success(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> success(T data) {
|
||||||
|
Result<T> result = new Result<>();
|
||||||
|
result.setCode(ResultCode.SUCCESS.getCode());
|
||||||
|
result.setMessage(ResultCode.SUCCESS.getMessage());
|
||||||
|
result.setData(data);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> success(String message, T data) {
|
||||||
|
Result<T> result = new Result<>();
|
||||||
|
result.setCode(ResultCode.SUCCESS.getCode());
|
||||||
|
result.setMessage(message);
|
||||||
|
result.setData(data);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result<Void> ok(String message) {
|
||||||
|
Result<Void> result = new Result<>();
|
||||||
|
result.setCode(ResultCode.SUCCESS.getCode());
|
||||||
|
result.setMessage(message);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> error(String message) {
|
||||||
|
return error(ResultCode.ERROR.getCode(), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> error(ResultCode resultCode) {
|
||||||
|
return error(resultCode.getCode(), resultCode.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result<T> error(Integer code, String message) {
|
||||||
|
Result<T> result = new Result<>();
|
||||||
|
result.setCode(code);
|
||||||
|
result.setMessage(message);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.attendance.common;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum ResultCode {
|
||||||
|
|
||||||
|
SUCCESS(200, "操作成功"),
|
||||||
|
ERROR(500, "操作失败"),
|
||||||
|
PARAM_ERROR(400, "参数错误"),
|
||||||
|
UNAUTHORIZED(401, "未登录或登录已过期"),
|
||||||
|
FORBIDDEN(403, "没有访问权限"),
|
||||||
|
NOT_FOUND(404, "资源不存在"),
|
||||||
|
METHOD_NOT_ALLOWED(405, "请求方式不允许"),
|
||||||
|
PARAM_VALIDATE_FAILED(422, "参数校验失败"),
|
||||||
|
|
||||||
|
USER_NOT_FOUND(1001, "用户不存在"),
|
||||||
|
USER_PASSWORD_ERROR(1002, "密码错误"),
|
||||||
|
USER_DISABLED(1003, "账号已被禁用"),
|
||||||
|
USERNAME_EXISTS(1004, "用户名已存在"),
|
||||||
|
|
||||||
|
TOKEN_INVALID(2001, "Token无效"),
|
||||||
|
TOKEN_EXPIRED(2002, "Token已过期");
|
||||||
|
|
||||||
|
private final Integer code;
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
ResultCode(Integer code, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.attendance.config;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.info.Contact;
|
||||||
|
import io.swagger.v3.oas.models.info.Info;
|
||||||
|
import io.swagger.v3.oas.models.info.License;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class Knife4jConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public OpenAPI customOpenAPI() {
|
||||||
|
return new OpenAPI()
|
||||||
|
.info(new Info()
|
||||||
|
.title("教室智能人脸考勤系统 API")
|
||||||
|
.description("教室智能人脸考勤系统后端接口文档")
|
||||||
|
.version("v1.0.0")
|
||||||
|
.contact(new Contact()
|
||||||
|
.name("SmartCampus")
|
||||||
|
.email("admin@school.edu"))
|
||||||
|
.license(new License()
|
||||||
|
.name("Apache 2.0")
|
||||||
|
.url("https://www.apache.org/licenses/LICENSE-2.0")));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package com.attendance.config;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.DbType;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class MyBatisPlusConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||||
|
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||||
|
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||||
|
return interceptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.attendance.config;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.ibatis.reflection.MetaObject;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class MyMetaObjectHandler implements MetaObjectHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insertFill(MetaObject metaObject) {
|
||||||
|
this.strictInsertFill(metaObject, "createdAt", LocalDateTime.class, LocalDateTime.now());
|
||||||
|
this.strictInsertFill(metaObject, "updatedAt", LocalDateTime.class, LocalDateTime.now());
|
||||||
|
this.strictInsertFill(metaObject, "deleted", Integer.class, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateFill(MetaObject metaObject) {
|
||||||
|
this.strictUpdateFill(metaObject, "updatedAt", LocalDateTime.class, LocalDateTime.now());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
package com.attendance.config;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class WebMvcConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
private final JwtInterceptor jwtInterceptor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCorsMappings(CorsRegistry registry) {
|
||||||
|
registry.addMapping("/**")
|
||||||
|
.allowedOriginPatterns("*")
|
||||||
|
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
|
||||||
|
.allowedHeaders("*")
|
||||||
|
.allowCredentials(true)
|
||||||
|
.maxAge(3600);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
|
registry.addInterceptor(jwtInterceptor)
|
||||||
|
.addPathPatterns("/**")
|
||||||
|
.excludePathPatterns(
|
||||||
|
"/auth/login",
|
||||||
|
"/auth/register",
|
||||||
|
"/v3/api-docs/**",
|
||||||
|
"/swagger-ui/**",
|
||||||
|
"/swagger-ui.html",
|
||||||
|
"/doc.html",
|
||||||
|
"/webjars/**",
|
||||||
|
"/favicon.ico"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.annotation.OperationLog;
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.entity.AttRule;
|
||||||
|
import com.attendance.service.AttRuleService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name = "考勤规则", description = "考勤规则设置接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/att-rule")
|
||||||
|
public class AttRuleController {
|
||||||
|
|
||||||
|
private final AttRuleService attRuleService;
|
||||||
|
|
||||||
|
public AttRuleController(AttRuleService attRuleService) {
|
||||||
|
this.attRuleService = attRuleService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询考勤规则")
|
||||||
|
@GetMapping("/page")
|
||||||
|
public Result<Page<AttRule>> page(
|
||||||
|
@RequestParam(defaultValue = "1") Long current,
|
||||||
|
@RequestParam(defaultValue = "10") Long size) {
|
||||||
|
LambdaQueryWrapper<AttRule> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.orderByDesc(AttRule::getCreatedAt);
|
||||||
|
return Result.success(attRuleService.page(new Page<>(current, size), wrapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取规则详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<AttRule> getById(@PathVariable Long id) {
|
||||||
|
return Result.success(attRuleService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "考勤规则", action = "新增考勤规则")
|
||||||
|
@Operation(summary = "新增考勤规则")
|
||||||
|
@PostMapping
|
||||||
|
public Result<Void> save(@RequestBody AttRule rule) {
|
||||||
|
attRuleService.save(rule);
|
||||||
|
return Result.ok("新增成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "考勤规则", action = "修改考勤规则")
|
||||||
|
@Operation(summary = "修改考勤规则")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@PathVariable Long id, @RequestBody AttRule rule) {
|
||||||
|
rule.setId(id);
|
||||||
|
attRuleService.updateById(rule);
|
||||||
|
return Result.ok("修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "考勤规则", action = "删除考勤规则")
|
||||||
|
@Operation(summary = "删除考勤规则")
|
||||||
|
@DeleteMapping
|
||||||
|
public Result<Void> remove(@Parameter(description = "规则ID列表") @RequestBody List<Long> ids) {
|
||||||
|
attRuleService.removeByIds(ids);
|
||||||
|
return Result.ok("删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取全部规则")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<AttRule>> list() {
|
||||||
|
return Result.success(attRuleService.list());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.dto.LoginDTO;
|
||||||
|
import com.attendance.dto.LoginResultDTO;
|
||||||
|
import com.attendance.service.SysUserService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
@Tag(name = "认证管理", description = "用户登录相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/auth")
|
||||||
|
public class AuthController {
|
||||||
|
|
||||||
|
private final SysUserService sysUserService;
|
||||||
|
|
||||||
|
public AuthController(SysUserService sysUserService) {
|
||||||
|
this.sysUserService = sysUserService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "用户登录")
|
||||||
|
@PostMapping("/login")
|
||||||
|
public Result<LoginResultDTO> login(@Valid @RequestBody LoginDTO loginDTO) {
|
||||||
|
return Result.success(sysUserService.login(loginDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "用户登出")
|
||||||
|
@PostMapping("/logout")
|
||||||
|
public Result<Void> logout() {
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,100 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.entity.AttTask;
|
||||||
|
import com.attendance.entity.Classroom;
|
||||||
|
import com.attendance.entity.Device;
|
||||||
|
import com.attendance.service.AttTaskService;
|
||||||
|
import com.attendance.service.ClassroomService;
|
||||||
|
import com.attendance.service.DeviceService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Tag(name = "数据展示大屏", description = "大屏数据展示接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/bigscreen")
|
||||||
|
public class BigScreenController {
|
||||||
|
|
||||||
|
private final AttTaskService attTaskService;
|
||||||
|
private final ClassroomService classroomService;
|
||||||
|
private final DeviceService deviceService;
|
||||||
|
|
||||||
|
public BigScreenController(AttTaskService attTaskService, ClassroomService classroomService, DeviceService deviceService) {
|
||||||
|
this.attTaskService = attTaskService;
|
||||||
|
this.classroomService = classroomService;
|
||||||
|
this.deviceService = deviceService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取大屏核心统计数据")
|
||||||
|
@GetMapping("/stats")
|
||||||
|
public Result<Map<String, Object>> getStats() {
|
||||||
|
List<AttTask> todayTasks = attTaskService.getTasksByDate(LocalDate.now());
|
||||||
|
int totalShould = todayTasks.stream().mapToInt(AttTask::getTotalCount).sum();
|
||||||
|
int totalActual = todayTasks.stream().mapToInt(AttTask::getActualCount).sum();
|
||||||
|
BigDecimal attendanceRate = totalShould > 0
|
||||||
|
? BigDecimal.valueOf(totalActual * 100.0 / totalShould).setScale(1, RoundingMode.HALF_UP)
|
||||||
|
: BigDecimal.ZERO;
|
||||||
|
|
||||||
|
Map<String, Object> stats = new HashMap<>();
|
||||||
|
stats.put("attendanceRate", attendanceRate);
|
||||||
|
stats.put("focusRate", 85.2);
|
||||||
|
stats.put("trend", 2.5);
|
||||||
|
stats.put("focusTrend", 0.8);
|
||||||
|
return Result.success(stats);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "出勤趋势数据")
|
||||||
|
@GetMapping("/trend")
|
||||||
|
public Result<Map<String, Object>> getTrend() {
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("dates", Arrays.asList("5/26", "5/27", "5/28", "5/29", "5/30", "5/31", "6/01"));
|
||||||
|
data.put("rates", Arrays.asList(93, 95, 94.5, 96, 95.8, 97, 96.8));
|
||||||
|
return Result.success(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "行为分布数据")
|
||||||
|
@GetMapping("/behavior-distribution")
|
||||||
|
public Result<List<Map<String, Object>>> getBehaviorDistribution() {
|
||||||
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
|
list.add(createMap("name", "专注听讲", "value", 65, "color", "#52c41a"));
|
||||||
|
list.add(createMap("name", "举手互动", "value", 15, "color", "#1890ff"));
|
||||||
|
list.add(createMap("name", "低头书写", "value", 12, "color", "#722ed1"));
|
||||||
|
list.add(createMap("name", "交谈讨论", "value", 5, "color", "#faad14"));
|
||||||
|
list.add(createMap("name", "其他", "value", 3, "color", "#bfbfbf"));
|
||||||
|
return Result.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> createMap(Object... kv) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
for (int i = 0; i < kv.length; i += 2) {
|
||||||
|
map.put((String) kv[i], kv[i + 1]);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取教室监控列表")
|
||||||
|
@GetMapping("/cameras")
|
||||||
|
public Result<List<Classroom>> getCameras() {
|
||||||
|
return Result.success(classroomService.list(new LambdaQueryWrapper<Classroom>().eq(Classroom::getStatus, 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取设备在线状态")
|
||||||
|
@GetMapping("/device-status")
|
||||||
|
public Result<Map<String, Long>> getDeviceStatus() {
|
||||||
|
long online = deviceService.count(new LambdaQueryWrapper<Device>().eq(Device::getOnlineStatus, 1));
|
||||||
|
long offline = deviceService.count(new LambdaQueryWrapper<Device>().eq(Device::getOnlineStatus, 0));
|
||||||
|
Map<String, Long> map = new HashMap<>();
|
||||||
|
map.put("online", online);
|
||||||
|
map.put("offline", offline);
|
||||||
|
return Result.success(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.annotation.OperationLog;
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.entity.Building;
|
||||||
|
import com.attendance.service.BuildingService;
|
||||||
|
import com.attendance.vo.BuildingVO;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name = "教学楼管理", description = "教学管理-教学楼相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/building")
|
||||||
|
public class BuildingController {
|
||||||
|
|
||||||
|
private final BuildingService buildingService;
|
||||||
|
|
||||||
|
public BuildingController(BuildingService buildingService) {
|
||||||
|
this.buildingService = buildingService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询教学楼列表")
|
||||||
|
@GetMapping("/page")
|
||||||
|
public Result<IPage<BuildingVO>> page(
|
||||||
|
@Parameter(description = "页码") @RequestParam(defaultValue = "1") Long current,
|
||||||
|
@Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Long size,
|
||||||
|
@Parameter(description = "关键词(教学楼名称/编码)") @RequestParam(required = false) String keyword) {
|
||||||
|
Page<BuildingVO> page = new Page<>(current, size);
|
||||||
|
return Result.success(buildingService.getBuildingPage(page, keyword));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取教学楼详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<Building> getById(@PathVariable Long id) {
|
||||||
|
return Result.success(buildingService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "教学楼管理", action = "新增教学楼")
|
||||||
|
@Operation(summary = "新增教学楼")
|
||||||
|
@PostMapping
|
||||||
|
public Result<Void> save(@RequestBody Building building) {
|
||||||
|
buildingService.save(building);
|
||||||
|
return Result.ok("新增成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "教学楼管理", action = "修改教学楼")
|
||||||
|
@Operation(summary = "修改教学楼")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@PathVariable Long id, @RequestBody Building building) {
|
||||||
|
building.setId(id);
|
||||||
|
buildingService.updateById(building);
|
||||||
|
return Result.ok("修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "教学楼管理", action = "删除教学楼")
|
||||||
|
@Operation(summary = "删除教学楼")
|
||||||
|
@DeleteMapping
|
||||||
|
public Result<Void> remove(@Parameter(description = "教学楼ID列表") @RequestBody List<Long> ids) {
|
||||||
|
buildingService.removeByIds(ids);
|
||||||
|
return Result.ok("删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取全部教学楼")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<Building>> list() {
|
||||||
|
return Result.success(buildingService.list(new LambdaQueryWrapper<Building>().eq(Building::getStatus, 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.annotation.OperationLog;
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.entity.Course;
|
||||||
|
import com.attendance.service.CourseService;
|
||||||
|
import com.attendance.vo.CourseVO;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name = "课程管理", description = "课程信息相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/course")
|
||||||
|
public class CourseController {
|
||||||
|
|
||||||
|
private final CourseService courseService;
|
||||||
|
|
||||||
|
public CourseController(CourseService courseService) {
|
||||||
|
this.courseService = courseService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询课程列表")
|
||||||
|
@GetMapping("/page")
|
||||||
|
public Result<IPage<CourseVO>> page(
|
||||||
|
@Parameter(description = "页码") @RequestParam(defaultValue = "1") Long current,
|
||||||
|
@Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Long size,
|
||||||
|
@Parameter(description = "课程名称") @RequestParam(required = false) String courseName,
|
||||||
|
@Parameter(description = "教师名称") @RequestParam(required = false) String teacherName,
|
||||||
|
@Parameter(description = "课程类型") @RequestParam(required = false) String courseType) {
|
||||||
|
Page<CourseVO> page = new Page<>(current, size);
|
||||||
|
return Result.success(courseService.getCoursePage(page, courseName, teacherName, courseType));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取课程详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<Course> getById(@PathVariable Long id) {
|
||||||
|
return Result.success(courseService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "课程管理", action = "新增课程")
|
||||||
|
@Operation(summary = "新增课程")
|
||||||
|
@PostMapping
|
||||||
|
public Result<Void> save(@RequestBody Course course) {
|
||||||
|
courseService.save(course);
|
||||||
|
return Result.ok("新增成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "课程管理", action = "修改课程")
|
||||||
|
@Operation(summary = "修改课程")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@PathVariable Long id, @RequestBody Course course) {
|
||||||
|
course.setId(id);
|
||||||
|
courseService.updateById(course);
|
||||||
|
return Result.ok("修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "课程管理", action = "删除课程")
|
||||||
|
@Operation(summary = "删除课程")
|
||||||
|
@DeleteMapping
|
||||||
|
public Result<Void> remove(@Parameter(description = "课程ID列表") @RequestBody List<Long> ids) {
|
||||||
|
courseService.removeByIds(ids);
|
||||||
|
return Result.ok("删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取全部课程")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<Course>> list() {
|
||||||
|
return Result.success(courseService.list(new LambdaQueryWrapper<Course>().eq(Course::getStatus, 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.annotation.OperationLog;
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.entity.CourseSchedule;
|
||||||
|
import com.attendance.service.CourseScheduleService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name = "课程安排", description = "课表/课程安排相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/schedule")
|
||||||
|
public class CourseScheduleController {
|
||||||
|
|
||||||
|
private final CourseScheduleService courseScheduleService;
|
||||||
|
|
||||||
|
public CourseScheduleController(CourseScheduleService courseScheduleService) {
|
||||||
|
this.courseScheduleService = courseScheduleService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询课程安排")
|
||||||
|
@GetMapping("/page")
|
||||||
|
public Result<Page<CourseSchedule>> page(
|
||||||
|
@Parameter(description = "页码") @RequestParam(defaultValue = "1") Long current,
|
||||||
|
@Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Long size,
|
||||||
|
@Parameter(description = "学期") @RequestParam(required = false) String semester,
|
||||||
|
@Parameter(description = "班级ID") @RequestParam(required = false) Long classId,
|
||||||
|
@Parameter(description = "教师ID") @RequestParam(required = false) Long teacherId) {
|
||||||
|
LambdaQueryWrapper<CourseSchedule> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
if (semester != null && !semester.isEmpty()) {
|
||||||
|
wrapper.eq(CourseSchedule::getSemester, semester);
|
||||||
|
}
|
||||||
|
if (teacherId != null) {
|
||||||
|
wrapper.eq(CourseSchedule::getTeacherId, teacherId);
|
||||||
|
}
|
||||||
|
if (classId != null) {
|
||||||
|
wrapper.eq(CourseSchedule::getClassId, classId);
|
||||||
|
}
|
||||||
|
wrapper.orderByAsc(CourseSchedule::getWeekDay).orderByAsc(CourseSchedule::getStartSection);
|
||||||
|
return Result.success(courseScheduleService.page(new Page<>(current, size), wrapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取课程安排详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<CourseSchedule> getById(@PathVariable Long id) {
|
||||||
|
return Result.success(courseScheduleService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "课程安排", action = "新增课程安排")
|
||||||
|
@Operation(summary = "新增课程安排")
|
||||||
|
@PostMapping
|
||||||
|
public Result<Void> save(@RequestBody CourseSchedule schedule) {
|
||||||
|
courseScheduleService.saveWithTasks(schedule);
|
||||||
|
return Result.ok("新增成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "课程安排", action = "修改课程安排")
|
||||||
|
@Operation(summary = "修改课程安排")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@PathVariable Long id, @RequestBody CourseSchedule schedule) {
|
||||||
|
schedule.setId(id);
|
||||||
|
courseScheduleService.updateWithTasks(schedule);
|
||||||
|
return Result.ok("修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "课程安排", action = "删除课程安排")
|
||||||
|
@Operation(summary = "删除课程安排")
|
||||||
|
@DeleteMapping
|
||||||
|
public Result<Void> remove(@Parameter(description = "课程安排ID列表") @RequestBody List<Long> ids) {
|
||||||
|
courseScheduleService.removeWithTasks(ids);
|
||||||
|
return Result.ok("删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取全部课程安排")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<CourseSchedule>> list(@RequestParam(required = false) String semester) {
|
||||||
|
LambdaQueryWrapper<CourseSchedule> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
if (semester != null && !semester.isEmpty()) {
|
||||||
|
wrapper.eq(CourseSchedule::getSemester, semester);
|
||||||
|
}
|
||||||
|
return Result.success(courseScheduleService.list(wrapper));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.entity.AttTask;
|
||||||
|
import com.attendance.service.AttTaskService;
|
||||||
|
import com.attendance.vo.AttTrendVO;
|
||||||
|
import com.attendance.vo.ClassRankVO;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Tag(name = "首页仪表盘", description = "Dashboard 统计数据接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/dashboard")
|
||||||
|
public class DashboardController {
|
||||||
|
|
||||||
|
private final AttTaskService attTaskService;
|
||||||
|
|
||||||
|
public DashboardController(AttTaskService attTaskService) {
|
||||||
|
this.attTaskService = attTaskService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取今日核心统计数据")
|
||||||
|
@GetMapping("/stats")
|
||||||
|
public Result<Map<String, Object>> getStats() {
|
||||||
|
List<AttTask> todayTasks = attTaskService.getTasksByDate(LocalDate.now());
|
||||||
|
|
||||||
|
int totalShould = todayTasks.stream().mapToInt(AttTask::getTotalCount).sum();
|
||||||
|
int totalActual = todayTasks.stream().mapToInt(AttTask::getActualCount).sum();
|
||||||
|
BigDecimal attendanceRate = totalShould > 0
|
||||||
|
? BigDecimal.valueOf(totalActual * 100.0 / totalShould).setScale(1, RoundingMode.HALF_UP)
|
||||||
|
: BigDecimal.ZERO;
|
||||||
|
|
||||||
|
Map<String, Object> stats = new HashMap<>();
|
||||||
|
stats.put("attendanceRate", attendanceRate);
|
||||||
|
stats.put("classroomUsage", 78.5);
|
||||||
|
stats.put("warningCount", 3);
|
||||||
|
stats.put("taskCount", todayTasks.size());
|
||||||
|
return Result.success(stats);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取今日考勤任务列表")
|
||||||
|
@GetMapping("/tasks")
|
||||||
|
public Result<List<AttTask>> getTodayTasks() {
|
||||||
|
return Result.success(attTaskService.getTasksByDate(LocalDate.now()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "出勤趋势")
|
||||||
|
@GetMapping("/trend")
|
||||||
|
public Result<List<AttTrendVO>> getTrend(
|
||||||
|
@Parameter(description = "统计天数") @RequestParam(defaultValue = "7") Integer days) {
|
||||||
|
return Result.success(attTaskService.getAttTrend(days));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "班级出勤排名")
|
||||||
|
@GetMapping("/ranking")
|
||||||
|
public Result<IPage<ClassRankVO>> getClassRanking(
|
||||||
|
@Parameter(description = "页码") @RequestParam(defaultValue = "1") Long current,
|
||||||
|
@Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Long size) {
|
||||||
|
Page<ClassRankVO> page = new Page<>(current, size);
|
||||||
|
return Result.success(attTaskService.getClassRankPage(page));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,102 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.annotation.OperationLog;
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.entity.Device;
|
||||||
|
import com.attendance.service.DeviceService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name = "设备管理", description = "考勤设备管理接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/device")
|
||||||
|
public class DeviceController {
|
||||||
|
|
||||||
|
private final DeviceService deviceService;
|
||||||
|
|
||||||
|
public DeviceController(DeviceService deviceService) {
|
||||||
|
this.deviceService = deviceService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询设备列表")
|
||||||
|
@GetMapping("/page")
|
||||||
|
public Result<Page<Device>> page(
|
||||||
|
@Parameter(description = "页码") @RequestParam(defaultValue = "1") Long current,
|
||||||
|
@Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Long size,
|
||||||
|
@Parameter(description = "设备类型") @RequestParam(required = false) String deviceType,
|
||||||
|
@Parameter(description = "设备名称") @RequestParam(required = false) String deviceName,
|
||||||
|
@Parameter(description = "安装教室ID") @RequestParam(required = false) Long classroomId,
|
||||||
|
@Parameter(description = "在线状态") @RequestParam(required = false) Integer onlineStatus) {
|
||||||
|
LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
if (deviceType != null && !deviceType.isEmpty()) {
|
||||||
|
wrapper.eq(Device::getDeviceType, deviceType);
|
||||||
|
}
|
||||||
|
if (onlineStatus != null) {
|
||||||
|
wrapper.eq(Device::getOnlineStatus, onlineStatus);
|
||||||
|
}
|
||||||
|
if (classroomId != null) {
|
||||||
|
wrapper.eq(Device::getClassroomId, classroomId);
|
||||||
|
}
|
||||||
|
if (deviceName != null) {
|
||||||
|
wrapper.like(Device::getDeviceName, deviceName);
|
||||||
|
}
|
||||||
|
wrapper.orderByDesc(Device::getCreatedAt);
|
||||||
|
return Result.success(deviceService.page(new Page<>(current, size), wrapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取设备详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<Device> getById(@PathVariable Long id) {
|
||||||
|
return Result.success(deviceService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "设备管理", action = "新增设备")
|
||||||
|
@Operation(summary = "新增设备")
|
||||||
|
@PostMapping
|
||||||
|
public Result<Void> save(@RequestBody Device device) {
|
||||||
|
deviceService.save(device);
|
||||||
|
return Result.ok("新增成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "设备管理", action = "修改设备")
|
||||||
|
@Operation(summary = "修改设备")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@PathVariable Long id, @RequestBody Device device) {
|
||||||
|
device.setId(id);
|
||||||
|
deviceService.updateById(device);
|
||||||
|
return Result.ok("修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "设备管理", action = "删除设备")
|
||||||
|
@Operation(summary = "删除设备")
|
||||||
|
@DeleteMapping
|
||||||
|
public Result<Void> remove(@Parameter(description = "设备ID列表") @RequestBody List<Long> ids) {
|
||||||
|
deviceService.removeByIds(ids);
|
||||||
|
return Result.ok("删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "设备管理", action = "设备心跳上报")
|
||||||
|
@Operation(summary = "设备心跳上报")
|
||||||
|
@PostMapping("/{id}/heartbeat")
|
||||||
|
public Result<Void> heartbeat(@PathVariable Long id) {
|
||||||
|
Device device = new Device();
|
||||||
|
device.setId(id);
|
||||||
|
device.setLastHeartbeat(LocalDateTime.now());
|
||||||
|
device.setOnlineStatus(1);
|
||||||
|
deviceService.updateById(device);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取全部设备")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<Device>> list() {
|
||||||
|
return Result.success(deviceService.list());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.annotation.OperationLog;
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.entity.EduClass;
|
||||||
|
import com.attendance.service.EduClassService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name = "班级管理", description = "教学管理-班级相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/class")
|
||||||
|
public class EduClassController {
|
||||||
|
|
||||||
|
private final EduClassService eduClassService;
|
||||||
|
|
||||||
|
public EduClassController(EduClassService eduClassService) {
|
||||||
|
this.eduClassService = eduClassService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询班级列表")
|
||||||
|
@GetMapping("/page")
|
||||||
|
public Result<Page<EduClass>> page(
|
||||||
|
@Parameter(description = "页码") @RequestParam(defaultValue = "1") Long current,
|
||||||
|
@Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Long size,
|
||||||
|
@Parameter(description = "关键词(班级名称/班级编码/专业)") @RequestParam(required = false) String keyword,
|
||||||
|
@Parameter(description = "年级") @RequestParam(required = false) String grade) {
|
||||||
|
LambdaQueryWrapper<EduClass> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(EduClass::getDeleted, 0);
|
||||||
|
if (keyword != null && !keyword.isEmpty()) {
|
||||||
|
wrapper.and(w -> w.like(EduClass::getClassName, keyword)
|
||||||
|
.or().like(EduClass::getClassCode, keyword)
|
||||||
|
.or().like(EduClass::getMajor, keyword));
|
||||||
|
}
|
||||||
|
if (grade != null && !grade.isEmpty()) {
|
||||||
|
wrapper.eq(EduClass::getGrade, grade);
|
||||||
|
}
|
||||||
|
wrapper.orderByDesc(EduClass::getCreatedAt);
|
||||||
|
return Result.success(eduClassService.page(new Page<>(current, size), wrapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取班级详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<EduClass> getById(@PathVariable Long id) {
|
||||||
|
return Result.success(eduClassService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "班级管理", action = "新增班级")
|
||||||
|
@Operation(summary = "新增班级")
|
||||||
|
@PostMapping
|
||||||
|
public Result<Void> save(@RequestBody EduClass eduClass) {
|
||||||
|
eduClassService.save(eduClass);
|
||||||
|
return Result.ok("新增成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "班级管理", action = "修改班级")
|
||||||
|
@Operation(summary = "修改班级")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@PathVariable Long id, @RequestBody EduClass eduClass) {
|
||||||
|
eduClass.setId(id);
|
||||||
|
eduClassService.updateById(eduClass);
|
||||||
|
return Result.ok("修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "班级管理", action = "删除班级")
|
||||||
|
@Operation(summary = "删除班级")
|
||||||
|
@DeleteMapping
|
||||||
|
public Result<Void> remove(@Parameter(description = "班级ID列表") @RequestBody List<Long> ids) {
|
||||||
|
eduClassService.removeByIds(ids);
|
||||||
|
return Result.ok("删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取全部班级")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<EduClass>> list() {
|
||||||
|
return Result.success(eduClassService.list(new LambdaQueryWrapper<EduClass>().eq(EduClass::getStatus, 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.annotation.OperationLog;
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.entity.SysPermission;
|
||||||
|
import com.attendance.service.SysPermissionService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name = "权限管理", description = "权限管理-菜单/权限相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/permission")
|
||||||
|
public class PermissionController {
|
||||||
|
|
||||||
|
private final SysPermissionService sysPermissionService;
|
||||||
|
|
||||||
|
public PermissionController(SysPermissionService sysPermissionService) {
|
||||||
|
this.sysPermissionService = sysPermissionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "查询全部权限列表")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<SysPermission>> list() {
|
||||||
|
LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(SysPermission::getStatus, 1);
|
||||||
|
wrapper.orderByAsc(SysPermission::getSortOrder);
|
||||||
|
return Result.success(sysPermissionService.list(wrapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取权限树")
|
||||||
|
@GetMapping("/tree")
|
||||||
|
public Result<List<SysPermission>> tree() {
|
||||||
|
LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(SysPermission::getStatus, 1);
|
||||||
|
wrapper.orderByAsc(SysPermission::getSortOrder);
|
||||||
|
return Result.success(sysPermissionService.list(wrapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取权限详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<SysPermission> getById(@PathVariable Long id) {
|
||||||
|
return Result.success(sysPermissionService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "权限管理", action = "新增权限")
|
||||||
|
@Operation(summary = "新增权限")
|
||||||
|
@PostMapping
|
||||||
|
public Result<Void> save(@RequestBody SysPermission permission) {
|
||||||
|
sysPermissionService.save(permission);
|
||||||
|
return Result.ok("新增成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "权限管理", action = "修改权限")
|
||||||
|
@Operation(summary = "修改权限")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@PathVariable Long id, @RequestBody SysPermission permission) {
|
||||||
|
permission.setId(id);
|
||||||
|
sysPermissionService.updateById(permission);
|
||||||
|
return Result.ok("修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "权限管理", action = "删除权限")
|
||||||
|
@Operation(summary = "删除权限")
|
||||||
|
@DeleteMapping
|
||||||
|
public Result<Void> remove(@Parameter(description = "权限ID列表") @RequestBody List<Long> ids) {
|
||||||
|
sysPermissionService.removeByIds(ids);
|
||||||
|
return Result.ok("删除成功");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.annotation.OperationLog;
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.entity.SysRole;
|
||||||
|
import com.attendance.service.SysPermissionService;
|
||||||
|
import com.attendance.service.SysRoleService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name = "角色管理", description = "权限管理-角色相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/role")
|
||||||
|
public class RoleController {
|
||||||
|
|
||||||
|
private final SysRoleService sysRoleService;
|
||||||
|
private final SysPermissionService sysPermissionService;
|
||||||
|
|
||||||
|
public RoleController(SysRoleService sysRoleService, SysPermissionService sysPermissionService) {
|
||||||
|
this.sysRoleService = sysRoleService;
|
||||||
|
this.sysPermissionService = sysPermissionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询角色列表")
|
||||||
|
@GetMapping("/page")
|
||||||
|
public Result<Page<SysRole>> page(
|
||||||
|
@RequestParam(defaultValue = "1") Long current,
|
||||||
|
@RequestParam(defaultValue = "10") Long size) {
|
||||||
|
LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.orderByAsc(SysRole::getSortOrder);
|
||||||
|
return Result.success(sysRoleService.page(new Page<>(current, size), wrapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取角色详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<SysRole> getById(@PathVariable Long id) {
|
||||||
|
return Result.success(sysRoleService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "角色管理", action = "新增角色")
|
||||||
|
@Operation(summary = "新增角色")
|
||||||
|
@PostMapping
|
||||||
|
public Result<Void> save(@RequestBody SysRole role) {
|
||||||
|
sysRoleService.save(role);
|
||||||
|
return Result.ok("新增成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "角色管理", action = "修改角色")
|
||||||
|
@Operation(summary = "修改角色")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@PathVariable Long id, @RequestBody SysRole role) {
|
||||||
|
role.setId(id);
|
||||||
|
sysRoleService.updateById(role);
|
||||||
|
return Result.ok("修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "角色管理", action = "删除角色")
|
||||||
|
@Operation(summary = "删除角色")
|
||||||
|
@DeleteMapping
|
||||||
|
public Result<Void> remove(@Parameter(description = "角色ID列表") @RequestBody List<Long> ids) {
|
||||||
|
sysRoleService.removeByIds(ids);
|
||||||
|
return Result.ok("删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取角色权限列表")
|
||||||
|
@GetMapping("/{roleId}/permissions")
|
||||||
|
public Result<List<com.attendance.entity.SysPermission>> getRolePermissions(@PathVariable Long roleId) {
|
||||||
|
return Result.success(sysPermissionService.getPermissionsByRoleId(roleId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "角色管理", action = "分配角色权限")
|
||||||
|
@Operation(summary = "分配角色权限")
|
||||||
|
@PostMapping("/{roleId}/permissions")
|
||||||
|
public Result<Void> assignPermissions(@PathVariable Long roleId, @RequestBody List<Long> permissionIds) {
|
||||||
|
return Result.ok("分配成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取全部角色")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<SysRole>> list() {
|
||||||
|
return Result.success(sysRoleService.list());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import com.attendance.annotation.OperationLog;
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.dto.StudentDTO;
|
||||||
|
import com.attendance.entity.Student;
|
||||||
|
import com.attendance.service.StudentService;
|
||||||
|
import com.attendance.vo.StudentVO;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name = "学生管理", description = "人员管理-学生相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/student")
|
||||||
|
@Slf4j
|
||||||
|
public class StudentController {
|
||||||
|
|
||||||
|
@Value("${stream.import-face-url}")
|
||||||
|
private String importFaceUrl;
|
||||||
|
|
||||||
|
private final StudentService studentService;
|
||||||
|
|
||||||
|
public StudentController(StudentService studentService) {
|
||||||
|
this.studentService = studentService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询学生列表")
|
||||||
|
@GetMapping("/page")
|
||||||
|
public Result<IPage<StudentVO>> page(
|
||||||
|
@Parameter(description = "页码") @RequestParam(defaultValue = "1") Long current,
|
||||||
|
@Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Long size,
|
||||||
|
@Parameter(description = "所属班级ID") @RequestParam(required = false) Long classId,
|
||||||
|
@Parameter(description = "关键词(学号/姓名)") @RequestParam(required = false) String keyword) {
|
||||||
|
Page<StudentVO> page = new Page<>(current, size);
|
||||||
|
return Result.success(studentService.getStudentPage(page, classId, keyword));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取学生详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<Student> getById(@PathVariable Long id) {
|
||||||
|
return Result.success(studentService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "学生管理", action = "新增学生")
|
||||||
|
@Operation(summary = "新增学生")
|
||||||
|
@PostMapping(consumes = "multipart/form-data")
|
||||||
|
public Result<Void> save(StudentDTO dto) throws Exception {
|
||||||
|
studentService.addStudentWithFaceSamples(dto);
|
||||||
|
// 成功后调用外部接口导入人脸样本
|
||||||
|
try {
|
||||||
|
String importResult = HttpUtil.post(importFaceUrl, "");
|
||||||
|
log.info("import-face-samples response: {}", importResult);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.warn("调用import-face-samples接口失败: {}", ex.getMessage());
|
||||||
|
}
|
||||||
|
return Result.ok("新增成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "学生管理", action = "修改学生")
|
||||||
|
@Operation(summary = "修改学生")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@PathVariable Long id, @RequestBody Student student) {
|
||||||
|
student.setId(id);
|
||||||
|
studentService.updateById(student);
|
||||||
|
return Result.ok("修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "学生管理", action = "删除学生")
|
||||||
|
@Operation(summary = "删除学生")
|
||||||
|
@DeleteMapping
|
||||||
|
public Result<Void> remove(@Parameter(description = "学生ID列表") @RequestBody List<Long> ids) {
|
||||||
|
studentService.removeStudentsWithFaceData(ids);
|
||||||
|
return Result.ok("删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取全部学生")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<Student>> list() {
|
||||||
|
return Result.success(studentService.list(new LambdaQueryWrapper<Student>().eq(Student::getStatus, 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.annotation.OperationLog;
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.dto.PasswordDTO;
|
||||||
|
import com.attendance.entity.SysUser;
|
||||||
|
import com.attendance.service.SysUserService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.util.DigestUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name = "用户管理", description = "系统用户管理接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/user")
|
||||||
|
public class SysUserController {
|
||||||
|
|
||||||
|
private final SysUserService sysUserService;
|
||||||
|
|
||||||
|
public SysUserController(SysUserService sysUserService) {
|
||||||
|
this.sysUserService = sysUserService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询用户列表")
|
||||||
|
@GetMapping("/page")
|
||||||
|
public Result<Page<SysUser>> page(
|
||||||
|
@Parameter(description = "页码") @RequestParam(defaultValue = "1") Long current,
|
||||||
|
@Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Long size,
|
||||||
|
@Parameter(description = "关键词(用户名/真实姓名)") @RequestParam(required = false) String keyword) {
|
||||||
|
LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
if (keyword != null && !keyword.isEmpty()) {
|
||||||
|
wrapper.and(w -> w.like(SysUser::getUsername, keyword).or().like(SysUser::getRealName, keyword));
|
||||||
|
}
|
||||||
|
wrapper.orderByDesc(SysUser::getCreatedAt);
|
||||||
|
return Result.success(sysUserService.page(new Page<>(current, size), wrapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取用户详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<SysUser> getById(@PathVariable Long id) {
|
||||||
|
return Result.success(sysUserService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "用户管理", action = "新增用户")
|
||||||
|
@Operation(summary = "新增用户")
|
||||||
|
@PostMapping
|
||||||
|
public Result<Void> save(@RequestBody SysUser user) {
|
||||||
|
if (user.getPassword() != null && !user.getPassword().isEmpty()) {
|
||||||
|
user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes(StandardCharsets.UTF_8)));
|
||||||
|
}
|
||||||
|
sysUserService.save(user);
|
||||||
|
return Result.ok("新增成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "用户管理", action = "修改用户")
|
||||||
|
@Operation(summary = "修改用户")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@PathVariable Long id, @RequestBody SysUser user) {
|
||||||
|
user.setId(id);
|
||||||
|
user.setPassword(null);
|
||||||
|
sysUserService.updateById(user);
|
||||||
|
return Result.ok("修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "用户管理", action = "删除用户")
|
||||||
|
@Operation(summary = "删除用户")
|
||||||
|
@DeleteMapping
|
||||||
|
public Result<Void> remove(@Parameter(description = "用户ID列表") @RequestBody List<Long> ids) {
|
||||||
|
sysUserService.removeByIds(ids);
|
||||||
|
return Result.ok("删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "用户管理", action = "修改密码")
|
||||||
|
@Operation(summary = "修改密码")
|
||||||
|
@PutMapping("/{id}/password")
|
||||||
|
public Result<Void> updatePassword(@PathVariable Long id, @RequestBody PasswordDTO passwordDTO) {
|
||||||
|
sysUserService.updatePassword(id, passwordDTO);
|
||||||
|
return Result.ok("密码修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取全部用户")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<SysUser>> list() {
|
||||||
|
return Result.success(sysUserService.list());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
package com.attendance.controller;
|
||||||
|
|
||||||
|
import com.attendance.annotation.OperationLog;
|
||||||
|
import com.attendance.common.Result;
|
||||||
|
import com.attendance.entity.Teacher;
|
||||||
|
import com.attendance.service.TeacherService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Tag(name = "教师管理", description = "人员管理-教师相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/teacher")
|
||||||
|
public class TeacherController {
|
||||||
|
|
||||||
|
private final TeacherService teacherService;
|
||||||
|
|
||||||
|
public TeacherController(TeacherService teacherService) {
|
||||||
|
this.teacherService = teacherService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询教师列表")
|
||||||
|
@GetMapping("/page")
|
||||||
|
public Result<Page<Teacher>> page(
|
||||||
|
@Parameter(description = "页码") @RequestParam(defaultValue = "1") Long current,
|
||||||
|
@Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Long size,
|
||||||
|
@Parameter(description = "关键词(工号/姓名/院系)") @RequestParam(required = false) String keyword,
|
||||||
|
@Parameter(description = "职称") @RequestParam(required = false) String title) {
|
||||||
|
LambdaQueryWrapper<Teacher> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(Teacher::getDeleted, 0);
|
||||||
|
if (keyword != null && !keyword.isEmpty()) {
|
||||||
|
wrapper.and(w -> w.like(Teacher::getTeacherNo, keyword)
|
||||||
|
.or().like(Teacher::getName, keyword)
|
||||||
|
.or().like(Teacher::getDepartment, keyword));
|
||||||
|
}
|
||||||
|
if (title != null && !title.isEmpty()) {
|
||||||
|
wrapper.eq(Teacher::getTitle, title);
|
||||||
|
}
|
||||||
|
wrapper.orderByDesc(Teacher::getCreatedAt);
|
||||||
|
return Result.success(teacherService.page(new Page<>(current, size), wrapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取教师详情")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public Result<Teacher> getById(@PathVariable Long id) {
|
||||||
|
return Result.success(teacherService.getById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "教师管理", action = "新增教师")
|
||||||
|
@Operation(summary = "新增教师")
|
||||||
|
@PostMapping
|
||||||
|
public Result<Void> save(@RequestBody Teacher teacher) {
|
||||||
|
teacherService.save(teacher);
|
||||||
|
return Result.ok("新增成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "教师管理", action = "修改教师")
|
||||||
|
@Operation(summary = "修改教师")
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@PathVariable Long id, @RequestBody Teacher teacher) {
|
||||||
|
teacher.setId(id);
|
||||||
|
teacherService.updateById(teacher);
|
||||||
|
return Result.ok("修改成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperationLog(module = "教师管理", action = "删除教师")
|
||||||
|
@Operation(summary = "删除教师")
|
||||||
|
@DeleteMapping
|
||||||
|
public Result<Void> remove(@Parameter(description = "教师ID列表") @RequestBody List<Long> ids) {
|
||||||
|
teacherService.removeByIds(ids);
|
||||||
|
return Result.ok("删除成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取全部教师")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public Result<List<Teacher>> list() {
|
||||||
|
return Result.success(teacherService.list(new LambdaQueryWrapper<Teacher>().eq(Teacher::getStatus, 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.attendance.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "登录请求参数")
|
||||||
|
public class LoginDTO {
|
||||||
|
|
||||||
|
@NotBlank(message = "请输入工号/学号")
|
||||||
|
@Schema(description = "登录账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "admin")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@NotBlank(message = "请输入密码")
|
||||||
|
@Schema(description = "登录密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||||
|
private String password;
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.attendance.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "登录响应结果")
|
||||||
|
public class LoginResultDTO {
|
||||||
|
|
||||||
|
@Schema(description = "访问令牌")
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
@Schema(description = "token类型")
|
||||||
|
private String tokenType;
|
||||||
|
|
||||||
|
@Schema(description = "用户ID")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Schema(description = "用户名")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Schema(description = "真实姓名")
|
||||||
|
private String realName;
|
||||||
|
|
||||||
|
@Schema(description = "头像")
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@Schema(description = "角色编码")
|
||||||
|
private String role;
|
||||||
|
|
||||||
|
@Schema(description = "角色名称")
|
||||||
|
private String roleName;
|
||||||
|
|
||||||
|
@Schema(description = "所属学校")
|
||||||
|
private String schoolName;
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.attendance.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "分页查询参数")
|
||||||
|
public class PageDTO {
|
||||||
|
|
||||||
|
@Schema(description = "当前页码", example = "1")
|
||||||
|
private Long current = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "每页条数", example = "10")
|
||||||
|
private Long size = 10L;
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.attendance.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "修改密码参数")
|
||||||
|
public class PasswordDTO {
|
||||||
|
|
||||||
|
@NotBlank(message = "请输入原密码")
|
||||||
|
@Schema(description = "原密码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String oldPassword;
|
||||||
|
|
||||||
|
@NotBlank(message = "请输入新密码")
|
||||||
|
@Schema(description = "新密码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private String newPassword;
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
package com.attendance.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("att_record")
|
||||||
|
@Schema(description = "考勤记录汇总实体")
|
||||||
|
public class AttRecord extends BaseEntity {
|
||||||
|
|
||||||
|
@Schema(description = "考勤任务ID")
|
||||||
|
private Long taskId;
|
||||||
|
|
||||||
|
@Schema(description = "课程安排ID")
|
||||||
|
private Long scheduleId;
|
||||||
|
|
||||||
|
@Schema(description = "课程ID")
|
||||||
|
private Long courseId;
|
||||||
|
|
||||||
|
@Schema(description = "教室ID")
|
||||||
|
private Long classroomId;
|
||||||
|
|
||||||
|
@Schema(description = "班级ID")
|
||||||
|
private Long classId;
|
||||||
|
|
||||||
|
@Schema(description = "教师ID")
|
||||||
|
private Long teacherId;
|
||||||
|
|
||||||
|
@Schema(description = "考勤日期")
|
||||||
|
private LocalDate attDate;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "开始时间")
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "结束时间")
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
|
||||||
|
@Schema(description = "应到人数")
|
||||||
|
private Integer totalCount;
|
||||||
|
|
||||||
|
@Schema(description = "实到人数")
|
||||||
|
private Integer actualCount;
|
||||||
|
|
||||||
|
@Schema(description = "缺勤人数")
|
||||||
|
private Integer absentCount;
|
||||||
|
|
||||||
|
@Schema(description = "迟到人数")
|
||||||
|
private Integer lateCount;
|
||||||
|
|
||||||
|
@Schema(description = "早退人数")
|
||||||
|
private Integer leaveEarlyCount;
|
||||||
|
|
||||||
|
@Schema(description = "出勤率%")
|
||||||
|
private BigDecimal attendanceRate;
|
||||||
|
|
||||||
|
@Schema(description = "缺勤率%")
|
||||||
|
private BigDecimal absentRate;
|
||||||
|
|
||||||
|
@Schema(description = "记录状态")
|
||||||
|
private Integer recordStatus;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
@Schema(description = "所属学校ID")
|
||||||
|
private Long schoolId;
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
package com.attendance.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("att_rule")
|
||||||
|
@Schema(description = "考勤规则实体")
|
||||||
|
public class AttRule extends BaseEntity {
|
||||||
|
|
||||||
|
@Schema(description = "规则名称")
|
||||||
|
private String ruleName;
|
||||||
|
|
||||||
|
@Schema(description = "规则类型")
|
||||||
|
private String ruleType;
|
||||||
|
|
||||||
|
@Schema(description = "关联目标ID")
|
||||||
|
private Long targetId;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "HH:mm:ss")
|
||||||
|
@Schema(description = "签到开始时间")
|
||||||
|
private LocalTime checkInStart;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "HH:mm:ss")
|
||||||
|
@Schema(description = "签到截止时间")
|
||||||
|
private LocalTime checkInEnd;
|
||||||
|
|
||||||
|
@Schema(description = "迟到阈值(分钟)")
|
||||||
|
private Integer lateThreshold;
|
||||||
|
|
||||||
|
@Schema(description = "缺勤阈值(分钟)")
|
||||||
|
private Integer absentThreshold;
|
||||||
|
|
||||||
|
@Schema(description = "早退阈值(分钟)")
|
||||||
|
private Integer earlyLeaveThreshold;
|
||||||
|
|
||||||
|
@Schema(description = "是否允许补签")
|
||||||
|
private Integer allowMakeUp;
|
||||||
|
|
||||||
|
@Schema(description = "补签时限(小时)")
|
||||||
|
private Integer makeUpLimit;
|
||||||
|
|
||||||
|
@Schema(description = "所属学校ID")
|
||||||
|
private Long schoolId;
|
||||||
|
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
package com.attendance.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("att_task")
|
||||||
|
@Schema(description = "考勤任务实体")
|
||||||
|
public class AttTask extends BaseEntity {
|
||||||
|
|
||||||
|
@Schema(description = "任务编号")
|
||||||
|
private String taskNo;
|
||||||
|
|
||||||
|
@Schema(description = "课程安排ID")
|
||||||
|
private Long scheduleId;
|
||||||
|
|
||||||
|
@Schema(description = "课程ID")
|
||||||
|
private Long courseId;
|
||||||
|
|
||||||
|
@Schema(description = "课程名称")
|
||||||
|
private String courseName;
|
||||||
|
|
||||||
|
@Schema(description = "教室ID")
|
||||||
|
private Long classroomId;
|
||||||
|
|
||||||
|
@Schema(description = "教室名称")
|
||||||
|
private String classroomName;
|
||||||
|
|
||||||
|
@Schema(description = "教师ID")
|
||||||
|
private Long teacherId;
|
||||||
|
|
||||||
|
@Schema(description = "教师姓名")
|
||||||
|
private String teacherName;
|
||||||
|
|
||||||
|
@Schema(description = "班级ID")
|
||||||
|
private Long classId;
|
||||||
|
|
||||||
|
@Schema(description = "考勤日期")
|
||||||
|
private LocalDate attDate;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "上课开始时间")
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "上课结束时间")
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
|
||||||
|
@Schema(description = "应到人数")
|
||||||
|
private Integer totalCount;
|
||||||
|
|
||||||
|
@Schema(description = "实到人数")
|
||||||
|
private Integer actualCount;
|
||||||
|
|
||||||
|
@Schema(description = "缺勤人数")
|
||||||
|
private Integer absentCount;
|
||||||
|
|
||||||
|
@Schema(description = "迟到人数")
|
||||||
|
private Integer lateCount;
|
||||||
|
|
||||||
|
@Schema(description = "早退人数")
|
||||||
|
private Integer leaveEarlyCount;
|
||||||
|
|
||||||
|
@Schema(description = "出勤率%")
|
||||||
|
private BigDecimal attendanceRate;
|
||||||
|
|
||||||
|
@Schema(description = "任务状态")
|
||||||
|
private Integer taskStatus;
|
||||||
|
|
||||||
|
@Schema(description = "所属学校ID")
|
||||||
|
private Long schoolId;
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
package com.attendance.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("behavior_record")
|
||||||
|
@Schema(description = "课堂行为记录实体")
|
||||||
|
public class BehaviorRecord extends BaseEntity {
|
||||||
|
|
||||||
|
@Schema(description = "考勤任务ID")
|
||||||
|
private Long taskId;
|
||||||
|
|
||||||
|
@Schema(description = "课程ID")
|
||||||
|
private Long courseId;
|
||||||
|
|
||||||
|
@Schema(description = "教室ID")
|
||||||
|
private Long classroomId;
|
||||||
|
|
||||||
|
@Schema(description = "学生ID")
|
||||||
|
private Long studentId;
|
||||||
|
|
||||||
|
@Schema(description = "行为类型ID")
|
||||||
|
private Long behaviorTypeId;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "行为发生时间")
|
||||||
|
private LocalDateTime behaviorTime;
|
||||||
|
|
||||||
|
@Schema(description = "持续时间(秒)")
|
||||||
|
private Integer duration;
|
||||||
|
|
||||||
|
@Schema(description = "AI识别置信度")
|
||||||
|
private BigDecimal confidence;
|
||||||
|
|
||||||
|
@Schema(description = "行为抓拍图片")
|
||||||
|
private String snapshotUrl;
|
||||||
|
|
||||||
|
@Schema(description = "是否预警")
|
||||||
|
private Integer isWarning;
|
||||||
|
|
||||||
|
@Schema(description = "预警级别")
|
||||||
|
private Integer warningLevel;
|
||||||
|
|
||||||
|
@Schema(description = "是否已处理")
|
||||||
|
private Integer handled;
|
||||||
|
|
||||||
|
@Schema(description = "处理人ID")
|
||||||
|
private Long handlerId;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "处理时间")
|
||||||
|
private LocalDateTime handleTime;
|
||||||
|
|
||||||
|
@Schema(description = "处理备注")
|
||||||
|
private String handleRemark;
|
||||||
|
|
||||||
|
@Schema(description = "所属学校ID")
|
||||||
|
private Long schoolId;
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
package com.attendance.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("behavior_type")
|
||||||
|
@Schema(description = "行为类型实体")
|
||||||
|
public class BehaviorType extends BaseEntity {
|
||||||
|
|
||||||
|
@Schema(description = "类型编码")
|
||||||
|
private String typeCode;
|
||||||
|
|
||||||
|
@Schema(description = "类型名称")
|
||||||
|
private String typeName;
|
||||||
|
|
||||||
|
@Schema(description = "分类")
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
@Schema(description = "图表颜色")
|
||||||
|
private String color;
|
||||||
|
|
||||||
|
@Schema(description = "排序")
|
||||||
|
private Integer sortOrder;
|
||||||
|
|
||||||
|
@Schema(description = "描述")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
@Schema(description = "该类型的统计次数")
|
||||||
|
private Integer count;
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
package com.attendance.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("edu_course")
|
||||||
|
@Schema(description = "课程实体")
|
||||||
|
public class Course extends BaseEntity {
|
||||||
|
|
||||||
|
@Schema(description = "课程编码")
|
||||||
|
private String courseCode;
|
||||||
|
|
||||||
|
@Schema(description = "课程名称")
|
||||||
|
private String courseName;
|
||||||
|
|
||||||
|
@Schema(description = "课程类型")
|
||||||
|
private String courseType;
|
||||||
|
|
||||||
|
@Schema(description = "学分")
|
||||||
|
private BigDecimal credit;
|
||||||
|
|
||||||
|
@Schema(description = "授课教师ID")
|
||||||
|
private Long teacherId;
|
||||||
|
|
||||||
|
@Schema(description = "所属学校ID")
|
||||||
|
private Long schoolId;
|
||||||
|
|
||||||
|
@Schema(description = "课程描述")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
package com.attendance.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("device")
|
||||||
|
@Schema(description = "设备实体")
|
||||||
|
public class Device extends BaseEntity {
|
||||||
|
|
||||||
|
@Schema(description = "设备编号")
|
||||||
|
private String deviceNo;
|
||||||
|
|
||||||
|
@Schema(description = "设备名称")
|
||||||
|
private String deviceName;
|
||||||
|
|
||||||
|
@Schema(description = "设备类型")
|
||||||
|
private String deviceType;
|
||||||
|
|
||||||
|
@Schema(description = "品牌")
|
||||||
|
private String brand;
|
||||||
|
|
||||||
|
@Schema(description = "型号")
|
||||||
|
private String model;
|
||||||
|
|
||||||
|
@Schema(description = "序列号")
|
||||||
|
private String serialNo;
|
||||||
|
|
||||||
|
@Schema(description = "IP地址")
|
||||||
|
private String ipAddress;
|
||||||
|
|
||||||
|
@Schema(description = "端口")
|
||||||
|
private Integer port;
|
||||||
|
|
||||||
|
@Schema(description = "MAC地址")
|
||||||
|
private String macAddress;
|
||||||
|
|
||||||
|
@Schema(description = "安装教室ID")
|
||||||
|
private Long classroomId;
|
||||||
|
|
||||||
|
@Schema(description = "安装位置描述")
|
||||||
|
private String location;
|
||||||
|
|
||||||
|
@Schema(description = "固件版本")
|
||||||
|
private String firmwareVersion;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "最后心跳时间")
|
||||||
|
private LocalDateTime lastHeartbeat;
|
||||||
|
|
||||||
|
@Schema(description = "在线状态")
|
||||||
|
private Integer onlineStatus;
|
||||||
|
|
||||||
|
@Schema(description = "使用状态")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@Schema(description = "所属学校ID")
|
||||||
|
private Long schoolId;
|
||||||
|
|
||||||
|
@Schema(description = "流类型")
|
||||||
|
private String streamType;
|
||||||
|
|
||||||
|
@Schema(description = "流地址")
|
||||||
|
private String streamUrl;
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
package com.attendance.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("edu_class")
|
||||||
|
@Schema(description = "班级实体")
|
||||||
|
public class EduClass extends BaseEntity {
|
||||||
|
|
||||||
|
@Schema(description = "班级名称")
|
||||||
|
private String className;
|
||||||
|
|
||||||
|
@Schema(description = "班级编码")
|
||||||
|
private String classCode;
|
||||||
|
|
||||||
|
@Schema(description = "年级")
|
||||||
|
private String grade;
|
||||||
|
|
||||||
|
@Schema(description = "专业")
|
||||||
|
private String major;
|
||||||
|
|
||||||
|
@Schema(description = "所属学校ID")
|
||||||
|
private Long schoolId;
|
||||||
|
|
||||||
|
@Schema(description = "学生人数")
|
||||||
|
private Integer studentCount;
|
||||||
|
|
||||||
|
@Schema(description = "班主任ID")
|
||||||
|
private Long headteacherId;
|
||||||
|
|
||||||
|
@Schema(description = "状态")
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
package com.attendance.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@TableName("monitor_record")
|
||||||
|
@Schema(description = "教室监控记录实体")
|
||||||
|
public class MonitorRecord extends BaseEntity {
|
||||||
|
|
||||||
|
@Schema(description = "教室ID")
|
||||||
|
private Long classroomId;
|
||||||
|
|
||||||
|
@Schema(description = "监控设备ID")
|
||||||
|
private Long deviceId;
|
||||||
|
|
||||||
|
@Schema(description = "记录日期")
|
||||||
|
private LocalDate recordDate;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "开始时间")
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Schema(description = "结束时间")
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
|
||||||
|
@Schema(description = "直播流地址")
|
||||||
|
private String streamUrl;
|
||||||
|
|
||||||
|
@Schema(description = "录像地址")
|
||||||
|
private String recordUrl;
|
||||||
|
|
||||||
|
@Schema(description = "录像文件大小(字节)")
|
||||||
|
private Long fileSize;
|
||||||
|
|
||||||
|
@Schema(description = "记录状态")
|
||||||
|
private Integer recordStatus;
|
||||||
|
|
||||||
|
@Schema(description = "所属学校ID")
|
||||||
|
private Long schoolId;
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.AttDetail;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface AttDetailMapper extends BaseMapper<AttDetail> {
|
||||||
|
|
||||||
|
@Select("SELECT * FROM att_detail WHERE task_id = #{taskId} AND deleted = 0 ORDER BY id")
|
||||||
|
List<AttDetail> selectByTaskId(@Param("taskId") Long taskId);
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.AttRecord;
|
||||||
|
import com.attendance.vo.AttRecordVO;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface AttRecordMapper extends BaseMapper<AttRecord> {
|
||||||
|
|
||||||
|
IPage<AttRecordVO> selectHistoryPage(Page<AttRecordVO> page,
|
||||||
|
@Param("courseName") String courseName,
|
||||||
|
@Param("attDate") String attDate);
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.AttRule;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface AttRuleMapper extends BaseMapper<AttRule> {
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.AttTask;
|
||||||
|
import com.attendance.vo.AttTaskVO;
|
||||||
|
import com.attendance.vo.AttTrendVO;
|
||||||
|
import com.attendance.vo.ClassRankVO;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface AttTaskMapper extends BaseMapper<AttTask> {
|
||||||
|
|
||||||
|
@Select("SELECT * FROM att_task WHERE att_date = #{date} AND deleted = 0 ORDER BY start_time DESC")
|
||||||
|
List<AttTask> selectByDate(@Param("date") LocalDate date);
|
||||||
|
|
||||||
|
IPage<AttTaskVO> selectTaskPage(Page<AttTaskVO> page,
|
||||||
|
@Param("attDate") LocalDate attDate,
|
||||||
|
@Param("keyword") String keyword,
|
||||||
|
@Param("taskStatus") Integer taskStatus);
|
||||||
|
|
||||||
|
IPage<ClassRankVO> selectClassRankPage(Page<ClassRankVO> page);
|
||||||
|
|
||||||
|
List<AttTrendVO> selectAttTrend(@Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate);
|
||||||
|
}
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.vo.BehaviorRecordVO;
|
||||||
|
import com.attendance.entity.BehaviorRecord;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface BehaviorRecordMapper extends BaseMapper<BehaviorRecord> {
|
||||||
|
|
||||||
|
@Select("SELECT bt.type_name as name, COUNT(*) as value " +
|
||||||
|
"FROM behavior_record br " +
|
||||||
|
"INNER JOIN behavior_type bt ON br.behavior_type_id = bt.id " +
|
||||||
|
"WHERE br.task_id = #{taskId} AND br.deleted = 0 " +
|
||||||
|
"GROUP BY br.behavior_type_id, bt.type_name")
|
||||||
|
List<Map<String, Object>> selectBehaviorStatsByTaskId(@Param("taskId") Long taskId);
|
||||||
|
|
||||||
|
@Select("<script>" +
|
||||||
|
"SELECT bt.type_name as name, COUNT(*) as value " +
|
||||||
|
"FROM behavior_record br " +
|
||||||
|
"INNER JOIN behavior_type bt ON br.behavior_type_id = bt.id " +
|
||||||
|
"INNER JOIN att_task at2 ON br.task_id = at2.id " +
|
||||||
|
"WHERE br.deleted = 0 " +
|
||||||
|
"<if test='courseId != null'> AND at2.course_id = #{courseId} </if>" +
|
||||||
|
"<if test='teacherId != null'> AND at2.teacher_id = #{teacherId} </if>" +
|
||||||
|
"<if test='attDate != null'> AND at2.att_date = #{attDate} </if>" +
|
||||||
|
"GROUP BY br.behavior_type_id, bt.type_name" +
|
||||||
|
"</script>")
|
||||||
|
List<Map<String, Object>> selectBehaviorStatsWithFilters(
|
||||||
|
@Param("courseId") Long courseId,
|
||||||
|
@Param("teacherId") Long teacherId,
|
||||||
|
@Param("attDate") LocalDate attDate);
|
||||||
|
|
||||||
|
@Select("<script>" +
|
||||||
|
"SELECT CONCAT(LPAD(t.slot * 2, 2, '0'), ':00-', LPAD(t.slot * 2 + 2, 2, '0'), ':00') as timeSlot, " +
|
||||||
|
"t.typeName, t.color, COUNT(*) as value " +
|
||||||
|
"FROM (" +
|
||||||
|
"SELECT FLOOR(HOUR(br.behavior_time) / 2) as slot, bt.type_name as typeName, bt.color " +
|
||||||
|
"FROM behavior_record br " +
|
||||||
|
"INNER JOIN behavior_type bt ON br.behavior_type_id = bt.id " +
|
||||||
|
"INNER JOIN att_task at2 ON br.task_id = at2.id " +
|
||||||
|
"WHERE br.deleted = 0 AND HOUR(br.behavior_time) >= 8 AND HOUR(br.behavior_time) < 22 " +
|
||||||
|
"<if test='courseId != null'> AND at2.course_id = #{courseId} </if>" +
|
||||||
|
"<if test='teacherId != null'> AND at2.teacher_id = #{teacherId} </if>" +
|
||||||
|
"<if test='attDate != null'> AND at2.att_date = #{attDate} </if>" +
|
||||||
|
") t " +
|
||||||
|
"GROUP BY t.slot, t.typeName, t.color " +
|
||||||
|
"ORDER BY t.slot, t.typeName" +
|
||||||
|
"</script>")
|
||||||
|
List<Map<String, Object>> selectTimePeriodStats(
|
||||||
|
@Param("courseId") Long courseId,
|
||||||
|
@Param("teacherId") Long teacherId,
|
||||||
|
@Param("attDate") LocalDate attDate);
|
||||||
|
|
||||||
|
@Select("<script>" +
|
||||||
|
"SELECT br.*, at2.course_name, at2.teacher_name, bt.type_name as behaviorTypeName, es.name as studentName " +
|
||||||
|
"FROM behavior_record br " +
|
||||||
|
"INNER JOIN att_task at2 ON br.task_id = at2.id " +
|
||||||
|
"INNER JOIN behavior_type bt ON br.behavior_type_id = bt.id " +
|
||||||
|
"LEFT JOIN edu_student es ON br.student_id = es.id " +
|
||||||
|
"WHERE br.deleted = 0 " +
|
||||||
|
"<if test='courseId != null'> AND at2.course_id = #{courseId} </if>" +
|
||||||
|
"<if test='teacherId != null'> AND at2.teacher_id = #{teacherId} </if>" +
|
||||||
|
"<if test='attDate != null'> AND at2.att_date = #{attDate} </if>" +
|
||||||
|
"<if test='behaviorTypeId != null'> AND br.behavior_type_id = #{behaviorTypeId} </if>" +
|
||||||
|
"ORDER BY br.behavior_time DESC" +
|
||||||
|
"</script>")
|
||||||
|
IPage<BehaviorRecordVO> selectBehaviorRecordPage(
|
||||||
|
IPage<?> page,
|
||||||
|
@Param("courseId") Long courseId,
|
||||||
|
@Param("teacherId") Long teacherId,
|
||||||
|
@Param("attDate") LocalDate attDate,
|
||||||
|
@Param("behaviorTypeId") Long behaviorTypeId);
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.BehaviorType;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface BehaviorTypeMapper extends BaseMapper<BehaviorType> {
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.Building;
|
||||||
|
import com.attendance.vo.BuildingVO;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface BuildingMapper extends BaseMapper<Building> {
|
||||||
|
|
||||||
|
IPage<BuildingVO> selectBuildingPage(Page<BuildingVO> page,
|
||||||
|
@Param("keyword") String keyword);
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.Classroom;
|
||||||
|
import com.attendance.vo.ClassroomVO;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface ClassroomMapper extends BaseMapper<Classroom> {
|
||||||
|
|
||||||
|
IPage<ClassroomVO> selectClassroomPage(Page<ClassroomVO> page,
|
||||||
|
@Param("buildingId") Long buildingId);
|
||||||
|
|
||||||
|
List<ClassroomVO> selectClassroomList(@Param("buildingId") Long buildingId);
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.Course;
|
||||||
|
import com.attendance.vo.CourseVO;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface CourseMapper extends BaseMapper<Course> {
|
||||||
|
|
||||||
|
IPage<CourseVO> selectCoursePage(Page<CourseVO> page,
|
||||||
|
@Param("courseName") String courseName,
|
||||||
|
@Param("teacherName") String teacherName,
|
||||||
|
@Param("courseType") String courseType);
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.CourseSchedule;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface CourseScheduleMapper extends BaseMapper<CourseSchedule> {
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.Device;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface DeviceMapper extends BaseMapper<Device> {
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.EduClass;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface EduClassMapper extends BaseMapper<EduClass> {
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.FaceIdentity;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface FaceIdentityMapper extends BaseMapper<FaceIdentity> {
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.FaceSample;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface FaceSampleMapper extends BaseMapper<FaceSample> {
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.MonitorRecord;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface MonitorRecordMapper extends BaseMapper<MonitorRecord> {
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.Student;
|
||||||
|
import com.attendance.vo.StudentVO;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface StudentMapper extends BaseMapper<Student> {
|
||||||
|
|
||||||
|
IPage<StudentVO> selectStudentPage(Page<StudentVO> page,
|
||||||
|
@Param("classId") Long classId,
|
||||||
|
@Param("keyword") String keyword);
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.SysOperationLog;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysOperationLogMapper extends BaseMapper<SysOperationLog> {
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.SysPermission;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysPermissionMapper extends BaseMapper<SysPermission> {
|
||||||
|
|
||||||
|
@Select("SELECT p.* FROM sys_permission p " +
|
||||||
|
"INNER JOIN sys_role_permission rp ON p.id = rp.permission_id " +
|
||||||
|
"WHERE rp.role_id = #{roleId} AND p.status = 1 ORDER BY p.sort_order")
|
||||||
|
List<SysPermission> selectByRoleId(@Param("roleId") Long roleId);
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.SysRole;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysRoleMapper extends BaseMapper<SysRole> {
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.SysRolePermission;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysRolePermissionMapper extends BaseMapper<SysRolePermission> {
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.SysSchool;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysSchoolMapper extends BaseMapper<SysSchool> {
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.SysUser;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SysUserMapper extends BaseMapper<SysUser> {
|
||||||
|
|
||||||
|
@Select("SELECT * FROM sys_user WHERE username = #{username} AND deleted = 0 LIMIT 1")
|
||||||
|
SysUser selectByUsername(String username);
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.mapper;
|
||||||
|
|
||||||
|
import com.attendance.entity.Teacher;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface TeacherMapper extends BaseMapper<Teacher> {
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.AttDetail;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface AttDetailService extends IService<AttDetail> {
|
||||||
|
|
||||||
|
List<AttDetail> getDetailsByTaskId(Long taskId);
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.AttRecord;
|
||||||
|
import com.attendance.entity.Student;
|
||||||
|
import com.attendance.vo.AttRecordVO;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface AttRecordService extends IService<AttRecord> {
|
||||||
|
|
||||||
|
IPage<AttRecordVO> getHistoryPage(IPage<AttRecordVO> page, String courseName, String attDate);
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.AttRule;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
public interface AttRuleService extends IService<AttRule> {
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.AttTask;
|
||||||
|
import com.attendance.vo.AttTaskVO;
|
||||||
|
import com.attendance.vo.AttTrendVO;
|
||||||
|
import com.attendance.vo.ClassRankVO;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface AttTaskService extends IService<AttTask> {
|
||||||
|
|
||||||
|
List<AttTask> getTasksByDate(LocalDate date);
|
||||||
|
|
||||||
|
IPage<AttTaskVO> getTaskPage(Page<AttTaskVO> page, LocalDate attDate, String keyword, Integer taskStatus);
|
||||||
|
|
||||||
|
IPage<ClassRankVO> getClassRankPage(Page<ClassRankVO> page);
|
||||||
|
|
||||||
|
List<AttTrendVO> getAttTrend(Integer days);
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.vo.BehaviorRecordVO;
|
||||||
|
import com.attendance.entity.BehaviorRecord;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface BehaviorRecordService extends IService<BehaviorRecord> {
|
||||||
|
|
||||||
|
List<Map<String, Object>> getBehaviorStatsByTaskId(Long taskId);
|
||||||
|
|
||||||
|
List<Map<String, Object>> getBehaviorStatsWithFilters(Long courseId, Long teacherId, LocalDate attDate);
|
||||||
|
|
||||||
|
List<Map<String, Object>> getTimePeriodStats(Long courseId, Long teacherId, LocalDate attDate);
|
||||||
|
|
||||||
|
IPage<BehaviorRecordVO> getBehaviorRecordPage(IPage<?> page, Long courseId, Long teacherId, LocalDate attDate, Long behaviorTypeId);
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.BehaviorType;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
public interface BehaviorTypeService extends IService<BehaviorType> {
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.Building;
|
||||||
|
import com.attendance.vo.BuildingVO;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface BuildingService extends IService<Building> {
|
||||||
|
|
||||||
|
IPage<BuildingVO> getBuildingPage(IPage<BuildingVO> page, String keyword);
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
boolean removeByIds(List<Long> ids);
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.Classroom;
|
||||||
|
import com.attendance.vo.ClassroomAttendanceVO;
|
||||||
|
import com.attendance.vo.ClassroomVO;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ClassroomService extends IService<Classroom> {
|
||||||
|
|
||||||
|
IPage<ClassroomVO> getClassroomPage(IPage<ClassroomVO> page, Long buildingId);
|
||||||
|
|
||||||
|
List<ClassroomVO> getClassroomList(Long buildingId);
|
||||||
|
|
||||||
|
ClassroomAttendanceVO getCurrentAttendance(Long classroomId, LocalDateTime currentTime);
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
boolean removeByIds(List<Long> ids);
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.CourseSchedule;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface CourseScheduleService extends IService<CourseSchedule> {
|
||||||
|
|
||||||
|
void saveWithTasks(CourseSchedule schedule);
|
||||||
|
|
||||||
|
void updateWithTasks(CourseSchedule schedule);
|
||||||
|
|
||||||
|
void removeWithTasks(List<Long> ids);
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.Course;
|
||||||
|
import com.attendance.vo.CourseVO;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
public interface CourseService extends IService<Course> {
|
||||||
|
|
||||||
|
IPage<CourseVO> getCoursePage(IPage<CourseVO> page, String courseName, String teacherName, String courseType);
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.Device;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
public interface DeviceService extends IService<Device> {
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.EduClass;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
public interface EduClassService extends IService<EduClass> {
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.FaceIdentity;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
public interface FaceIdentityService extends IService<FaceIdentity> {
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.FaceSample;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
public interface FaceSampleService extends IService<FaceSample> {
|
||||||
|
|
||||||
|
void addFaceSample(FaceSample faceSample);
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package com.attendance.service;
|
||||||
|
|
||||||
|
import com.attendance.entity.MonitorRecord;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
public interface MonitorRecordService extends IService<MonitorRecord> {
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue