Compare commits

..

No commits in common. 'master' and 'frontend/dev' have entirely different histories.

1
.gitignore vendored

@ -1 +0,0 @@
.idea

@ -7,7 +7,6 @@ import {listStudent, rollCall, updatePoints} from "@/api/student.js";
const loading = ref(false)
const cards = ref([])
const canSelect = ref(true)
const disableClick = ref(false)
const isResetting = ref(false)
const dialogVisible = ref(false)
const dialogVisible2 = ref(false)
@ -17,7 +16,6 @@ const avatarUrl = ref('https://api.aspark.cc')
const avatarKey = ref(0)
const pointChange = ref(0)
const pointChange2 = ref(0)
const nothingToDo = ref(false)
const randomEvents = ref([
{
title: "放他一马",
@ -26,10 +24,6 @@ const randomEvents = ref([
{
title: "天选之子",
content: "成为天选之子,看似幸运加身,实则背负孤独。所有人羡慕你的光环,却无人懂得你走过的黑暗。被命运选中,不是因为强大,而是因为只能独自面对那些无人能解的重担。(同学化身天选之子,本次点名积分 +10 )"
},
{
title: "无事发生",
content: "有时候,无事发生比风浪更让人心酸。日子在静默中悄然滑过,没有意外,也没有惊喜,连时间都像失去了温度。原以为平静是安全的,却不知这无声的流逝中,埋藏着无数未曾到来的期望和悄然消散的热情。"
}
])
@ -110,7 +104,8 @@ const handleRestart = () => {
dialogVisible2.value = false
if (isResetting.value) return
isResetting.value = true
disableClick.value = false
canSelect.value = false
cards.value.forEach(card => {
card.isFlipped = false
})
@ -212,7 +207,7 @@ const handlePointsChange = async () => {
return
}
let response;
// console.log(pointChange.value + ' ' + pointChange2.value)
console.log(pointChange.value + ' ' + pointChange2.value)
if(pointChange2.value !== 0){
response = await updatePoints(cardResult.value.id, pointChange2.value)
pointChange2.value = 0
@ -226,33 +221,17 @@ const handlePointsChange = async () => {
dialogVisible.value = false
}
const luckThing = () => {
disableClick.value = true
const lens = 3
let randomIndex = Math.floor((Date.now() * Math.random()) % lens);
console.log(randomIndex)
if (randomIndex === 1) {
const lens = randomEvents.value.length
const randomIndex = Math.floor(Math.random() * lens);
currentRandomEvent.value = randomEvents.value[randomIndex]
if (randomIndex === 1) {
pointChange2.value = 10
} else if (randomIndex >= 2) {
nothingToDo.value = true
randomIndex = 2
}
currentRandomEvent.value = randomEvents.value[randomIndex]
dialogVisible2.value = true;
};
const handleRandomEvents = () => {
console.log(disableClick.value)
console.log()
if (!nothingToDo.value) {
handleRestart()
handlePointsChange()
} else {
dialogVisible2.value = false
nothingToDo.value = false
}
}
</script>
<template>
@ -340,7 +319,7 @@ const handleRandomEvents = () => {
type="primary"
@click="luckThing"
class="round-button"
:disabled="disableClick"
>
<i class="iconfont yaya-touzi" style="font-size: 24px;;" />
</el-button>
@ -361,7 +340,7 @@ const handleRandomEvents = () => {
height="700px"
:align-center="true"
class="profile-dialog"
@close="handleRandomEvents"
@close="handleRestart"
>
<div class="profile-content">
<!-- 显示随机事件的标题原本头像位置替换为标题 -->
@ -373,7 +352,7 @@ const handleRandomEvents = () => {
<div class="button-container">
<el-button
type="success"
@click="dialogVisible2 = false"
@click="handlePointsChange"
class="round-button"
>
<i class="iconfont yaya-duigou" style="font-size: 24px;" />

@ -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,36 +0,0 @@
package cc.aspark.config;
import cc.aspark.interceptor.LoginCheckInterceptor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* web
*/
@Configuration
@Slf4j
@EnableWebMvc
@RequiredArgsConstructor
public class WebMvcConfiguration implements WebMvcConfigurer {
private final LoginCheckInterceptor loginCheckInterceptor;
/**
*
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
log.info("开始注册自定义拦截器...");
registry.addInterceptor(loginCheckInterceptor)
.excludePathPatterns("/admin/login")
.excludePathPatterns("/admin/register");
}
}

@ -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,48 +0,0 @@
package cc.aspark.domain.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import java.io.Serializable;
@Data
@Tag(name = "StudentDTO")
public class StudentDTO implements Serializable {
/**
* id
*/
@Schema(name = "id", description = "id", requiredMode = Schema.RequiredMode.REQUIRED)
private Integer id;
/**
* no
*/
@Schema(name = "no", description = "学号", requiredMode = Schema.RequiredMode.REQUIRED)
private String no;
/**
*
*/
@Schema(name = "name", description = "姓名", requiredMode = Schema.RequiredMode.REQUIRED)
private String name;
/**
* 0 1
*/
@Schema(name = "gender", description = "性别", requiredMode = Schema.RequiredMode.REQUIRED)
private Short gender;
/**
*
*/
@Schema(name = "className", description = "班级", requiredMode = Schema.RequiredMode.REQUIRED)
private String className;
/**
*
*/
@Schema(name = "points", description = "积分")
private Double points;
}

@ -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,77 +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_stu
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Tag(name = "学生实体类")
public class Student implements Serializable {
/**
* id
*/
@Schema(name = "id", description = "id")
private Integer id;
/**
*
*/
@Schema(name = "no", description = "学号")
private String no;
/**
*
*/
@Schema(name = "name", description = "姓名")
private String name;
/**
* 0 1
*/
@Schema(name = "gender", description = "性别")
private Short gender;
/**
*
*/
@Schema(name = "className", description = "班级")
private String className;
/**
*
*/
@Schema(name = "points", description = "积分")
private Double points;
/**
* id
*/
@Schema(name = "creator", description = "创建者id")
private Integer creator;
/**
*
*/
@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,46 +0,0 @@
package cc.aspark.handler;
import cc.aspark.constant.MessageConstant;
import cc.aspark.exception.BaseException;
import cc.aspark.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.sql.SQLIntegrityConstraintViolationException;
/**
*
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
/**
*
*/
@ExceptionHandler
public Result exceptionHandler(BaseException ex){
log.error("异常信息:{}", ex.getMessage());
return Result.error(ex.getMessage());
}
@ExceptionHandler
public Result exceptionHandler(SQLIntegrityConstraintViolationException ex) {
String msg = ex.getMessage();
if (msg.contains("Duplicate entry")) {
return Result.error("已存在,请勿重复添加");
}
return Result.error(MessageConstant.UNKNOWN_ERROR);
}
// @ExceptionHandler
// public Result exceptionHander(SQLException ex) {
// String msg = ex.getMessage();
// if (msg.contains("doesn't have a default value")) {
// return Result.error(MessageConstant.INVALID_INPUT);
// }
// return Result.error(MessageConstant.UNKNOWN_ERROR);
// }
}

@ -1,53 +0,0 @@
package cc.aspark.interceptor;
import cc.aspark.constant.MessageConstant;
import cc.aspark.context.BaseContext;
import cc.aspark.exception.UserNotLoginException;
import cc.aspark.properties.JwtProperties;
import cc.aspark.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
/**
* jwt
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class LoginCheckInterceptor implements HandlerInterceptor {
private final JwtProperties jwtProperties;
/**
* jwt
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws UserNotLoginException {
//判断当前拦截到的是Controller的方法还是其他资源
if (!(handler instanceof HandlerMethod)) {
//当前拦截到的不是动态方法,直接放行
return true;
}
//1、从请求头中获取令牌
String token = request.getHeader(jwtProperties.getTokenName());
//2、校验令牌
try {
log.info("jwt校验: {}", token);
Claims claims = JwtUtil.parseJWT(jwtProperties.getSecretKey(), token);
BaseContext.setCurrentId(Long.valueOf(claims.get("id").toString()));
//3、通过放行
return true;
} catch (Exception ex) {
throw new UserNotLoginException(MessageConstant.USER_NOT_LOGIN);
}
}
}

@ -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,34 +0,0 @@
package cc.aspark.result;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
*
* @param <T>
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> implements Serializable {
private Integer code; //编码1成功0和其它数字为失败
private String msg; //错误信息
private T data; //数据
public static <T> Result<T> success() {
return new Result<>(1, "success",null);
}
public static <T> Result<T> success(T object) {
return new Result<>(1, "success", object);
}
public static <T> Result<T> error(String msg) {
return new Result(0, msg, null);
}
}

@ -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,87 +0,0 @@
package cc.aspark.service.impl;
import cc.aspark.constant.MessageConstant;
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 cc.aspark.exception.AccountNotFoundException;
import cc.aspark.exception.LoginFailedException;
import cc.aspark.exception.PasswordErrorException;
import cc.aspark.mapper.AdminMapper;
import cc.aspark.properties.JwtProperties;
import cc.aspark.service.AdminService;
import cc.aspark.utils.JwtUtil;
import ch.qos.logback.core.util.StringUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
/**
* @author night
* @description admin()Service
* @createDate 2024-10-02 16:31:44
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin>
implements AdminService {
private final JwtProperties jwtProperties;
@Override
public UserLoginVO login(UserLoginDTO userLoginDTO) {
if (userLoginDTO == null || StringUtil.isNullOrEmpty(userLoginDTO.getUsername()) || StringUtil.isNullOrEmpty(userLoginDTO.getPassword())) {
throw new LoginFailedException(MessageConstant.INVALID_INPUT);
}
userLoginDTO.setPassword(SecureUtil.md5(userLoginDTO.getPassword()));
log.info(userLoginDTO.getPassword());
LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Admin::getUsername, userLoginDTO.getUsername());
Admin admin = baseMapper.selectOne(wrapper);
if (admin == null) {
throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
}
if (!admin.getPassword().equals(userLoginDTO.getPassword())) {
throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
}
//登录成功后生成jwt令牌
Map<String, Object> claims = new HashMap<>();
claims.put("id", admin.getId());
claims.put("username", admin.getUsername());
String token = JwtUtil.createJWT(
jwtProperties.getSecretKey(),
jwtProperties.getTtl(),
claims);
UserLoginVO userLoginVO = BeanUtil.copyProperties(admin, UserLoginVO.class);
userLoginVO.setToken(token);
return userLoginVO;
}
@Override
public void register(UserRegisterDTO userRegisterDTO) {
Admin admin = BeanUtil.copyProperties(userRegisterDTO, Admin.class);
admin.setPassword(SecureUtil.md5(admin.getPassword()));
admin.setUpdateTime(LocalDateTime.now());
admin.setCreateTime(LocalDateTime.now());
baseMapper.insert(admin);
}
}

@ -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,54 +0,0 @@
package cc.aspark.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;
public class JwtUtil {
/**
* jwt
* 使Hs256, 使
*
* @param secretKey jwt
* @param ttlMillis jwt()
* @param claims
* @return
*/
public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {
// 指定签名的时候使用的签名算法也就是header那部分
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
// 生成JWT的时间
long expMillis = System.currentTimeMillis() + ttlMillis;
Date exp = new Date(expMillis);
// 设置jwt的body
JwtBuilder builder = Jwts.builder()
.setClaims(claims)
.signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))
.setExpiration(exp);
return builder.compact();
}
/**
* Token
*
* @param secretKey jwt , , sign,
* @param token token
* @return
*/
public static Claims parseJWT(String secretKey, String token) {
// 得到DefaultJwtParser
return Jwts.parser()
.setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
.parseClaimsJws(token).getBody();
}
}

@ -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…
Cancel
Save