Compare commits
No commits in common. 'master' and 'frontend/dev' have entirely different histories.
master
...
frontend/d
@ -1 +0,0 @@
|
||||
.idea
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package cc.aspark.config;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DatabaseConnectionWarmer implements ApplicationRunner {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
log.info("开始预热数据库连接池...");
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
stmt.execute("SELECT 1");
|
||||
}
|
||||
log.info("数据库连接预热完成,耗时:{}ms", System.currentTimeMillis() - startTime);
|
||||
} catch (SQLException e) {
|
||||
log.error("数据库连接预热失败", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package cc.aspark.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 MybatisPlusConfiguration {
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package cc.aspark.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 SwaggerConfiguration {
|
||||
|
||||
// 设置 openapi 基础参数
|
||||
@Bean
|
||||
public OpenAPI customOpenAPI() {
|
||||
return new OpenAPI()
|
||||
.info(new Info()
|
||||
.title("SpringBoot API 管理")
|
||||
.contact(new Contact().name("spark"))
|
||||
.version("1.0")
|
||||
.description("SpringBoot 集成 Knife4j 示例")
|
||||
.license(new License().name("Apache 2.0")));
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package cc.aspark.constant;
|
||||
|
||||
public class MessageConstant {
|
||||
|
||||
public static final String PASSWORD_ERROR = "密码错误";
|
||||
public static final String ACCOUNT_NOT_FOUND = "账号不存在";
|
||||
public static final String UNKNOWN_ERROR = "未知错误";
|
||||
public static final String USER_NOT_LOGIN = "用户未登录";
|
||||
public static final String LOGIN_FAILED = "登录失败";
|
||||
public static final String DELETE_FAILED = "删除失败";
|
||||
public static final String INVALID_INPUT = "输入无效";
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package cc.aspark.context;
|
||||
|
||||
public class BaseContext {
|
||||
|
||||
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
|
||||
|
||||
public static void setCurrentId(Long id) {
|
||||
threadLocal.set(id);
|
||||
}
|
||||
|
||||
public static Long getCurrentId() {
|
||||
return threadLocal.get();
|
||||
}
|
||||
|
||||
public static void removeCurrentId() {
|
||||
threadLocal.remove();
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package cc.aspark.controller;
|
||||
|
||||
|
||||
import cc.aspark.domain.dto.UserLoginDTO;
|
||||
import cc.aspark.domain.dto.UserRegisterDTO;
|
||||
import cc.aspark.domain.vo.UserLoginVO;
|
||||
import cc.aspark.result.Result;
|
||||
import cc.aspark.service.AdminService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/admin")
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "管理员表相关操作")
|
||||
public class AdminController {
|
||||
|
||||
private final AdminService adminService;
|
||||
|
||||
@PostMapping("/login")
|
||||
@Operation(summary = "用户登录")
|
||||
public Result<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO) {
|
||||
log.info("用户登录:{}", userLoginDTO);
|
||||
UserLoginVO userLoginVO = adminService.login(userLoginDTO);
|
||||
return Result.success(userLoginVO);
|
||||
}
|
||||
|
||||
@PostMapping("/register")
|
||||
@Operation(summary = "用户注册")
|
||||
public Result register(@RequestBody UserRegisterDTO userRegisterDTO) {
|
||||
log.info("用户注册:{}", userRegisterDTO);
|
||||
adminService.register(userRegisterDTO);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
package cc.aspark.controller;
|
||||
|
||||
|
||||
import cc.aspark.domain.dto.PageQueryDTO;
|
||||
import cc.aspark.domain.dto.StudentDTO;
|
||||
import cc.aspark.domain.entity.Student;
|
||||
import cc.aspark.result.PageResult;
|
||||
import cc.aspark.result.Result;
|
||||
import cc.aspark.service.StudentService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.Builder;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/student")
|
||||
@RequiredArgsConstructor
|
||||
@Builder
|
||||
@Tag(name = "学生表相关操作")
|
||||
public class StudentController {
|
||||
|
||||
private final StudentService studentService;
|
||||
|
||||
@Operation(summary = "查询全部学生信息")
|
||||
@GetMapping
|
||||
public Result<List<Student>> list() {
|
||||
List<Student> studentList = studentService.list();
|
||||
return Result.success(studentList);
|
||||
}
|
||||
|
||||
@Operation(summary = "根据 id 查询学生信息")
|
||||
@GetMapping("/{id}")
|
||||
public Result<Student> getStuInfoById(@PathVariable Integer id) {
|
||||
Student stuInfo = studentService.getById(id);
|
||||
return Result.success(stuInfo);
|
||||
}
|
||||
|
||||
@Operation(summary = "学生信息分页查询")
|
||||
@GetMapping("/page")
|
||||
public Result<PageResult<Student>> pageStuInfo(PageQueryDTO pageQueryDTO) {
|
||||
log.info("学生信息分页查询: {}", pageQueryDTO);
|
||||
PageResult<Student> pageResult = studentService.page(pageQueryDTO);
|
||||
return Result.success(pageResult);
|
||||
}
|
||||
|
||||
@Operation(summary = "新增学生信息")
|
||||
@PostMapping
|
||||
public Result save(@RequestBody StudentDTO studentDTO) {
|
||||
studentService.save(studentDTO);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "通过文件导入学生信息")
|
||||
@PostMapping("/import")
|
||||
public Result saveBatch(MultipartFile file) {
|
||||
studentService.importStudentsByExcel(file);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "导出学生信息")
|
||||
@GetMapping("/export")
|
||||
public void exportStudents(HttpServletResponse response) {
|
||||
studentService.exportStudentsToExcel(response);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新学生信息")
|
||||
@PutMapping
|
||||
public Result updateStu(@RequestBody StudentDTO studentDTO) {
|
||||
studentService.updateStu(studentDTO);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "删除学生信息")
|
||||
@DeleteMapping("/{ids}")
|
||||
public Result deleteStus(@PathVariable List<Integer> ids) {
|
||||
studentService.removeByIds(ids);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "随机抽取一名学生")
|
||||
@GetMapping("/rollcall")
|
||||
public Result<Student> rollCall() {
|
||||
Student stu = studentService.rollCall();
|
||||
return Result.success(stu);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新积分")
|
||||
@PutMapping("/points/{id}/{points}")
|
||||
public Result updatePoints(@PathVariable Integer id, @PathVariable Double points) {
|
||||
studentService.updatePoints(id, points);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package cc.aspark.domain.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@Tag(name = "PageQueryDTO")
|
||||
public class PageQueryDTO implements Serializable {
|
||||
@Schema(name = "no", description = "学号")
|
||||
@Max(20)
|
||||
private String no;
|
||||
|
||||
@Schema(name = "name", description = "姓名")
|
||||
@Max(20)
|
||||
private String name;
|
||||
|
||||
@Schema(name = "gender", description = "性别")
|
||||
private Short gender;
|
||||
|
||||
@Schema(name = "className", description = "班级")
|
||||
@Max(20)
|
||||
private String className;
|
||||
|
||||
@Schema(name = "page", description = "分页页码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer page;
|
||||
|
||||
@Schema(name = "pageSize", description = "分页大小", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer pageSize;
|
||||
|
||||
@Schema(name = "exactQuery", description = "是否使用精确查询")
|
||||
private Boolean exactQuery;
|
||||
|
||||
@Schema(name = "createTimeStart")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTimeStart;
|
||||
|
||||
@Schema(name = "createTimeEnd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTimeEnd;
|
||||
|
||||
@Schema(name = "updateTimeStart")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime updateTimeStart;
|
||||
|
||||
@Schema(name = "updateTimeEnd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime updateTimeEnd;
|
||||
|
||||
@Schema(name = "orderBy")
|
||||
private String orderBy;
|
||||
|
||||
@Schema(name = "orderRule")
|
||||
private String orderRule;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package cc.aspark.domain.dto;
|
||||
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserLoginDTO {
|
||||
|
||||
@Min(3)
|
||||
@Max(20)
|
||||
private String username;
|
||||
|
||||
@Min(8)
|
||||
@Max(32)
|
||||
private String password;
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package cc.aspark.domain.dto;
|
||||
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserRegisterDTO {
|
||||
@Min(3)
|
||||
@Max(20)
|
||||
private String username;
|
||||
|
||||
@Min(8)
|
||||
@Max(32)
|
||||
private String password;
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package cc.aspark.domain.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 管理员信息表
|
||||
* @TableName tb_admin
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Tag(name = "管理员实体类")
|
||||
public class Admin implements Serializable {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@Schema(name = "id")
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
@Schema(name = "username", description = "用户名")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@Schema(name = "password", description = "密码")
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Schema(name = "createTime", description = "创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 最后修改时间
|
||||
*/
|
||||
@Schema(name = "updateTime", description = "最后修改时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime updateTime;
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package cc.aspark.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserLoginVO {
|
||||
|
||||
private Integer id;
|
||||
private String username;
|
||||
private String token;
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package cc.aspark.exception;
|
||||
|
||||
/**
|
||||
* 账号不存在异常
|
||||
*/
|
||||
public class AccountNotFoundException extends BaseException {
|
||||
|
||||
public AccountNotFoundException() {
|
||||
}
|
||||
|
||||
public AccountNotFoundException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package cc.aspark.exception;
|
||||
|
||||
/**
|
||||
* 业务异常
|
||||
*/
|
||||
public class BaseException extends RuntimeException {
|
||||
|
||||
public BaseException() {
|
||||
}
|
||||
|
||||
public BaseException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package cc.aspark.exception;
|
||||
|
||||
/**
|
||||
* 登录失败
|
||||
*/
|
||||
public class LoginFailedException extends BaseException{
|
||||
public LoginFailedException(String msg){
|
||||
super(msg);
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package cc.aspark.exception;
|
||||
|
||||
/**
|
||||
* 密码错误异常
|
||||
*/
|
||||
public class PasswordErrorException extends BaseException {
|
||||
|
||||
public PasswordErrorException() {
|
||||
}
|
||||
|
||||
public PasswordErrorException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package cc.aspark.exception;
|
||||
|
||||
public class UserNotLoginException extends BaseException {
|
||||
|
||||
public UserNotLoginException() {
|
||||
}
|
||||
|
||||
public UserNotLoginException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package cc.aspark.mapper;
|
||||
|
||||
import cc.aspark.domain.entity.Admin;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author night
|
||||
* @description 针对表【admin(管理员信息表)】的数据库操作Mapper
|
||||
* @createDate 2024-10-02 16:31:44
|
||||
* @Entity generator.domain.TbAdmin
|
||||
*/
|
||||
public interface AdminMapper extends BaseMapper<Admin> {
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package cc.aspark.mapper;
|
||||
|
||||
import cc.aspark.domain.entity.Student;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author night
|
||||
* @description 针对表【tb_stu(学生信息表)】的数据库操作Mapper
|
||||
* @createDate 2024-10-02 16:31:44
|
||||
* @Entity generator.domain.TbStu
|
||||
*/
|
||||
public interface StudentMapper extends BaseMapper<Student> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
package cc.aspark.properties;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "jwt")
|
||||
@Data
|
||||
public class JwtProperties {
|
||||
|
||||
/**
|
||||
* 管理端员工生成jwt令牌相关配置
|
||||
*/
|
||||
private String secretKey;
|
||||
private long ttl;
|
||||
private String tokenName;
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package cc.aspark.result;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 封装分页查询结果
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class PageResult<T> implements Serializable {
|
||||
|
||||
private long total; //总记录数
|
||||
|
||||
private List<T> records; //当前页数据集合
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package cc.aspark.service;
|
||||
|
||||
import cc.aspark.domain.dto.UserLoginDTO;
|
||||
import cc.aspark.domain.dto.UserRegisterDTO;
|
||||
import cc.aspark.domain.entity.Admin;
|
||||
import cc.aspark.domain.vo.UserLoginVO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @author night
|
||||
* @description 针对表【tb_admin(管理员信息表)】的数据库操作Service
|
||||
* @createDate 2024-10-02 16:31:44
|
||||
*/
|
||||
public interface AdminService extends IService<Admin> {
|
||||
|
||||
UserLoginVO login(UserLoginDTO userLoginDTO);
|
||||
|
||||
void register(UserRegisterDTO userRegisterDTO);
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package cc.aspark.service;
|
||||
|
||||
import cc.aspark.domain.dto.PageQueryDTO;
|
||||
import cc.aspark.domain.dto.StudentDTO;
|
||||
import cc.aspark.domain.entity.Student;
|
||||
import cc.aspark.result.PageResult;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* @author night
|
||||
* @description 针对表【tb_stu(学生信息表)】的数据库操作Service
|
||||
* @createDate 2024-10-02 16:31:44
|
||||
*/
|
||||
public interface StudentService extends IService<Student> {
|
||||
|
||||
void updateStu(StudentDTO studentDTO);
|
||||
|
||||
PageResult<Student> page(PageQueryDTO pageQueryDTO);
|
||||
|
||||
void save(StudentDTO studentDTO);
|
||||
|
||||
Student rollCall();
|
||||
|
||||
void importStudentsByExcel(MultipartFile file);
|
||||
|
||||
void exportStudentsToExcel(HttpServletResponse response);
|
||||
|
||||
void updatePoints(Integer id, Double points);
|
||||
}
|
@ -1,278 +0,0 @@
|
||||
package cc.aspark.service.impl;
|
||||
|
||||
import cc.aspark.constant.MessageConstant;
|
||||
import cc.aspark.context.BaseContext;
|
||||
import cc.aspark.domain.dto.PageQueryDTO;
|
||||
import cc.aspark.domain.dto.StudentDTO;
|
||||
import cc.aspark.domain.entity.Student;
|
||||
import cc.aspark.exception.BaseException;
|
||||
import cc.aspark.mapper.StudentMapper;
|
||||
import cc.aspark.result.PageResult;
|
||||
import cc.aspark.service.StudentService;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.poi.excel.ExcelReader;
|
||||
import cn.hutool.poi.excel.ExcelUtil;
|
||||
import cn.hutool.poi.excel.ExcelWriter;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import jakarta.servlet.ServletOutputStream;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author night
|
||||
* @description 针对表【student(学生信息表)】的数据库操作Service实现
|
||||
* @createDate 2024-10-02 16:31:44
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student>
|
||||
implements StudentService {
|
||||
|
||||
@Override
|
||||
public void updateStu(StudentDTO studentDTO) {
|
||||
Student student = BeanUtil.copyProperties(studentDTO, Student.class);
|
||||
student.setUpdateTime(LocalDateTime.now());
|
||||
baseMapper.updateById(student);
|
||||
}
|
||||
|
||||
private void handleSort(LambdaQueryWrapper<Student> wrapper, String orderBy, String orderRule) {
|
||||
if (orderBy == null || orderRule == null) {
|
||||
wrapper.orderByAsc(Student::getNo);
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用Map存储字段与对应的getter方法
|
||||
Map<String, SFunction<Student, ?>> sortFieldMap = new HashMap<>();
|
||||
sortFieldMap.put("no", Student::getNo);
|
||||
sortFieldMap.put("name", Student::getName);
|
||||
sortFieldMap.put("gender", Student::getGender);
|
||||
sortFieldMap.put("className", Student::getClassName);
|
||||
sortFieldMap.put("points", Student::getPoints);
|
||||
sortFieldMap.put("createTime", Student::getCreateTime);
|
||||
sortFieldMap.put("updateTime", Student::getUpdateTime);
|
||||
|
||||
SFunction<Student, ?> sortField = sortFieldMap.get(orderBy);
|
||||
if (sortField == null) {
|
||||
throw new BaseException(MessageConstant.INVALID_INPUT);
|
||||
}
|
||||
|
||||
switch (orderRule.toUpperCase()) {
|
||||
case "ASC" -> wrapper.orderByAsc(sortField);
|
||||
case "DESC" -> wrapper.orderByDesc(sortField);
|
||||
default -> throw new BaseException(MessageConstant.INVALID_INPUT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<Student> page(PageQueryDTO pageQueryDTO) {
|
||||
int page = Math.max(1, pageQueryDTO.getPage());
|
||||
int pageSize = Math.min(Math.max(1, pageQueryDTO.getPageSize()), 20);
|
||||
|
||||
Page<Student> pageStu = new Page<>(page, pageSize);
|
||||
|
||||
LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
Boolean isExactQuery = pageQueryDTO.getExactQuery();
|
||||
if (isExactQuery == null || !isExactQuery) {
|
||||
wrapper .eq(Student::getCreator, BaseContext.getCurrentId())
|
||||
.like(pageQueryDTO.getNo() != null, Student::getNo, pageQueryDTO.getNo())
|
||||
.like(pageQueryDTO.getName() != null, Student::getName, pageQueryDTO.getName())
|
||||
.eq(pageQueryDTO.getGender() != null, Student::getGender, pageQueryDTO.getGender())
|
||||
.like(pageQueryDTO.getClassName() != null, Student::getClassName, pageQueryDTO.getClassName())
|
||||
.between(pageQueryDTO.getCreateTimeStart() != null && pageQueryDTO.getCreateTimeEnd() != null,
|
||||
Student::getCreateTime, pageQueryDTO.getCreateTimeStart(), pageQueryDTO.getCreateTimeEnd())
|
||||
.between(pageQueryDTO.getUpdateTimeStart() != null && pageQueryDTO.getUpdateTimeEnd() != null,
|
||||
Student::getUpdateTime, pageQueryDTO.getUpdateTimeStart(), pageQueryDTO.getUpdateTimeEnd());
|
||||
} else {
|
||||
wrapper .eq(Student::getCreator, BaseContext.getCurrentId())
|
||||
.eq(pageQueryDTO.getNo() != null, Student::getNo, pageQueryDTO.getNo())
|
||||
.eq(pageQueryDTO.getName() != null, Student::getName, pageQueryDTO.getName())
|
||||
.eq(pageQueryDTO.getGender() != null, Student::getGender, pageQueryDTO.getGender())
|
||||
.eq(pageQueryDTO.getClassName() != null, Student::getClassName, pageQueryDTO.getClassName())
|
||||
.between(pageQueryDTO.getCreateTimeStart() != null && pageQueryDTO.getCreateTimeEnd() != null,
|
||||
Student::getCreateTime, pageQueryDTO.getCreateTimeStart(), pageQueryDTO.getCreateTimeEnd())
|
||||
.between(pageQueryDTO.getUpdateTimeStart() != null && pageQueryDTO.getUpdateTimeEnd() != null,
|
||||
Student::getUpdateTime, pageQueryDTO.getUpdateTimeStart(), pageQueryDTO.getUpdateTimeEnd());
|
||||
}
|
||||
|
||||
handleSort(wrapper, pageQueryDTO.getOrderBy(), pageQueryDTO.getOrderRule());
|
||||
|
||||
pageStu = baseMapper.selectPage(pageStu, wrapper);
|
||||
|
||||
return new PageResult<>(pageStu.getTotal(), pageStu.getRecords());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(StudentDTO studentDTO) {
|
||||
Student student = BeanUtil.copyProperties(studentDTO, Student.class);
|
||||
student.setUpdateTime(LocalDateTime.now());
|
||||
student.setCreateTime(LocalDateTime.now());
|
||||
student.setCreator(Integer.valueOf(BaseContext.getCurrentId().toString()));
|
||||
log.info("{}", student);
|
||||
baseMapper.insert(student);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Student rollCall() {
|
||||
List<Student> studentList = this.list();
|
||||
|
||||
if (studentList.isEmpty()) {
|
||||
throw new RuntimeException("学生列表为空");
|
||||
}
|
||||
|
||||
// 找出最高积分,用于计算反向权重
|
||||
final double maxPoints = studentList.stream()
|
||||
.mapToDouble(Student::getPoints)
|
||||
.max()
|
||||
.orElse(0.0) + 1.0;
|
||||
|
||||
// 计算总的反向权重
|
||||
double totalInverseWeights = studentList.stream()
|
||||
.mapToDouble(student -> maxPoints - student.getPoints())
|
||||
.sum();
|
||||
|
||||
// 生成一个0到总反向权重之间的随机数
|
||||
Random random = new Random();
|
||||
double randomValue = random.nextDouble() * totalInverseWeights;
|
||||
|
||||
// 使用累加器方法选择学生
|
||||
double accumulatedWeight = 0;
|
||||
for (Student student : studentList) {
|
||||
// 计算该学生的反向权重
|
||||
double inverseWeight = maxPoints - student.getPoints();
|
||||
accumulatedWeight += inverseWeight;
|
||||
if (accumulatedWeight >= randomValue) {
|
||||
return student;
|
||||
}
|
||||
}
|
||||
|
||||
// 以防万一,返回最后一个学生
|
||||
return studentList.get(studentList.size() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void importStudentsByExcel(MultipartFile file) {
|
||||
try {
|
||||
ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
|
||||
reader .addHeaderAlias("学号", "no")
|
||||
.addHeaderAlias("姓名", "name")
|
||||
.addHeaderAlias("性别", "gender")
|
||||
.addHeaderAlias("班级", "className")
|
||||
.addHeaderAlias("积分", "credits")
|
||||
.addHeaderAlias("创建时间", "createTime")
|
||||
.addHeaderAlias("最后操作时间", "updateTime");
|
||||
List<Map<String, Object>> rows = reader.readAll();
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
List<Student> studentList = rows.stream().map(row -> {
|
||||
Student student = new Student();
|
||||
student.setNo(row.get("no").toString());
|
||||
student.setName(row.get("name").toString());
|
||||
student.setGender("男".equals(row.get("gender")) ? (short) 0 : (short) 1);
|
||||
student.setClassName(row.get("className").toString());
|
||||
student.setCreator(Integer.valueOf(BaseContext.getCurrentId().toString()));
|
||||
if (row.get("credits") == null) {
|
||||
student.setPoints(0.00);
|
||||
} else {
|
||||
student.setPoints(Double.valueOf(row.get("credits").toString()));
|
||||
}
|
||||
|
||||
if (row.get("createTime") == null) {
|
||||
student.setCreateTime(now);
|
||||
} else {
|
||||
String createTimeStr = row.get("createTime").toString();
|
||||
student.setCreateTime(LocalDateTime.parse(createTimeStr, formatter));
|
||||
}
|
||||
|
||||
if (row.get("updateTime") == null) {
|
||||
student.setUpdateTime(now);
|
||||
} else {
|
||||
String updateTimeStr = row.get("updateTime").toString();
|
||||
student.setUpdateTime(LocalDateTime.parse(updateTimeStr, formatter));
|
||||
}
|
||||
return student;
|
||||
}).toList();
|
||||
try {
|
||||
baseMapper.insertOrUpdate(studentList);
|
||||
} catch (Exception e) {
|
||||
log.info(e.getMessage());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportStudentsToExcel(HttpServletResponse response) {
|
||||
try {
|
||||
LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(Student::getCreator, BaseContext.getCurrentId());
|
||||
List<Student> studentList = baseMapper.selectList(wrapper);
|
||||
|
||||
// 创建一个Excel写入器
|
||||
ExcelWriter writer = ExcelUtil.getWriter(true);
|
||||
|
||||
// 设置表头别名
|
||||
writer.addHeaderAlias("no", "学号");
|
||||
writer.addHeaderAlias("name", "姓名");
|
||||
writer.addHeaderAlias("gender", "性别");
|
||||
writer.addHeaderAlias("className", "班级");
|
||||
writer.addHeaderAlias("points", "积分");
|
||||
writer.addHeaderAlias("createTime", "创建时间");
|
||||
writer.addHeaderAlias("updateTime", "最后操作时间");
|
||||
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
// 将性别的数字转换为文字
|
||||
List<Map<String, Object>> rows = studentList.stream().map(student -> {
|
||||
Map<String, Object> row = new HashMap<>();
|
||||
row.put("no", student.getNo());
|
||||
row.put("name", student.getName());
|
||||
row.put("gender", student.getGender() == 0 ? "男" : "女");
|
||||
row.put("className", student.getClassName());
|
||||
row.put("points", student.getPoints());
|
||||
row.put("createTime", student.getCreateTime().format(formatter));
|
||||
row.put("updateTime", student.getUpdateTime().format(formatter));
|
||||
return row;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
// 写入数据
|
||||
writer.write(rows, true);
|
||||
|
||||
// 设置响应头
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
|
||||
response.setHeader("Content-Disposition", "attachment;filename=students.xlsx");
|
||||
|
||||
// 输出Excel文件
|
||||
ServletOutputStream out = response.getOutputStream();
|
||||
writer.flush(out, true);
|
||||
writer.close();
|
||||
IoUtil.close(out);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("导出Excel失败", e);
|
||||
throw new BaseException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePoints(Integer id, Double points) {
|
||||
Student student = baseMapper.selectById(id);
|
||||
student.setPoints(student.getPoints() + points);
|
||||
baseMapper.updateById(student);
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cc.aspark.mapper.AdminMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="cc.aspark.domain.entity.Admin">
|
||||
<id property="id" column="id" jdbcType="INTEGER"/>
|
||||
<result property="username" column="username" jdbcType="VARCHAR"/>
|
||||
<result property="password" column="password" jdbcType="VARCHAR"/>
|
||||
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id,username,password,
|
||||
create_time,update_time
|
||||
</sql>
|
||||
</mapper>
|
@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cc.aspark.mapper.StudentMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="cc.aspark.domain.entity.Student">
|
||||
<id property="id" column="id" jdbcType="INTEGER"/>
|
||||
<result property="name" column="name" jdbcType="VARCHAR"/>
|
||||
<result property="gender" column="gender" jdbcType="TINYINT"/>
|
||||
<result property="major" column="major" jdbcType="VARCHAR"/>
|
||||
<result property="class" column="class" jdbcType="INTEGER"/>
|
||||
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id,name,gender,
|
||||
major,class,create_time,
|
||||
update_time
|
||||
</sql>
|
||||
</mapper>
|
@ -0,0 +1,13 @@
|
||||
package cc.aspark;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class TestApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue