├── images ├── ER1.png ├── ER2.png ├── addbook.png ├── booklist.png ├── borrow.png ├── chart1.png ├── chart2.png ├── lendreturn.png ├── login.png ├── manager.png ├── mapper1.png ├── mapper2.png ├── readerctg.png ├── readerupdate.png └── return.png ├── library-behind ├── .gitignore ├── common │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── fun │ │ └── cyhgraph │ │ ├── constant │ │ ├── AutoFillConstant.java │ │ ├── JwtClaimsConstant.java │ │ ├── MessageConstant.java │ │ └── StatusConstant.java │ │ ├── context │ │ └── BaseContext.java │ │ ├── enumeration │ │ └── OperationType.java │ │ ├── exception │ │ ├── BaseException.java │ │ ├── BorrowMaxException.java │ │ ├── BorrowTooLongException.java │ │ ├── ManagerNotFoundException.java │ │ └── PasswordErrorException.java │ │ ├── json │ │ └── JacksonObjectMapper.java │ │ ├── properties │ │ └── JwtProperties.java │ │ ├── result │ │ ├── PageResult.java │ │ └── Result.java │ │ └── utils │ │ └── JwtUtil.java ├── pojo │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── fun │ │ └── cyhgraph │ │ ├── dto │ │ ├── BookCatePageDTO.java │ │ ├── BookCategoryDTO.java │ │ ├── BookDTO.java │ │ ├── BookPageDTO.java │ │ ├── LendReturnDTO.java │ │ ├── LendReturnPageDTO.java │ │ ├── ManagerDTO.java │ │ ├── ManagerLoginDTO.java │ │ ├── ReaderCatePageDTO.java │ │ ├── ReaderCategoryDTO.java │ │ ├── ReaderDTO.java │ │ └── ReaderPageDTO.java │ │ ├── entity │ │ ├── Book.java │ │ ├── BookCategory.java │ │ ├── LendReturn.java │ │ ├── Manager.java │ │ ├── Reader.java │ │ ├── ReaderCategory.java │ │ └── TopInfo.java │ │ └── vo │ │ ├── BookCategoryVO.java │ │ ├── LendReturnReportVO.java │ │ ├── ManagerLoginVO.java │ │ ├── ReaderCategoryVo.java │ │ └── TopVO.java ├── pom.xml └── server │ ├── .gitignore │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── fun │ │ │ └── cyhgraph │ │ │ ├── ServerApplication.java │ │ │ ├── annotation │ │ │ └── AutoFill.java │ │ │ ├── aspect │ │ │ └── AutoFillAspect.java │ │ │ ├── config │ │ │ └── WebMvcConfiguration.java │ │ │ ├── controller │ │ │ ├── BookCategoryController.java │ │ │ ├── BookController.java │ │ │ ├── BorrowController.java │ │ │ ├── ChartController.java │ │ │ ├── ManagerController.java │ │ │ ├── ReaderCategoryController.java │ │ │ └── ReaderController.java │ │ │ ├── handler │ │ │ └── GlobalExceptionHandler.java │ │ │ ├── interceptor │ │ │ └── JwtTokenInterceptor.java │ │ │ ├── mapper │ │ │ ├── BookCategoryMapper.java │ │ │ ├── BookMapper.java │ │ │ ├── BorrowMapper.java │ │ │ ├── ChartMapper.java │ │ │ ├── ManagerMapper.java │ │ │ ├── ReaderCategoryMapper.java │ │ │ └── ReaderMapper.java │ │ │ └── service │ │ │ ├── BookCategoryService.java │ │ │ ├── BookService.java │ │ │ ├── BorrowService.java │ │ │ ├── ChartService.java │ │ │ ├── ManagerService.java │ │ │ ├── ReaderCategoryService.java │ │ │ ├── ReaderService.java │ │ │ └── serviceImpl │ │ │ ├── BookCategoryServiceImpl.java │ │ │ ├── BookServiceImpl.java │ │ │ ├── BorrowServiceImpl.java │ │ │ ├── ChartServiceImpl.java │ │ │ ├── ManagerServiceImpl.java │ │ │ ├── ReaderCategoryServiceImpl.java │ │ │ └── ReaderServiceImpl.java │ └── resources │ │ ├── application.yml │ │ └── mapper │ │ ├── BookCategoryMapper.xml │ │ ├── BookMapper.xml │ │ ├── BorrowMapper.xml │ │ ├── ReaderCategoryMapper.xml │ │ └── ReaderMapper.xml │ └── test │ └── java │ └── fun │ └── cyhgraph │ └── server │ └── ServerApplicationTests.java ├── library-front ├── .eslintrc.cjs ├── .gitignore ├── .prettierrc.json ├── .vscode │ └── extensions.json ├── README.md ├── env.d.ts ├── index.html ├── package-lock.json ├── package.json ├── public │ └── favicon.ico ├── src │ ├── App.vue │ ├── api │ │ ├── book.ts │ │ ├── bookCategory.ts │ │ ├── data.ts │ │ ├── lendReturn.ts │ │ ├── manager.ts │ │ ├── reader.ts │ │ └── readerCategory.ts │ ├── assets │ │ ├── base.css │ │ ├── library.jpg │ │ ├── logo.svg │ │ └── main.css │ ├── main.ts │ ├── router │ │ └── index.ts │ ├── store │ │ └── index.ts │ ├── types │ │ └── manager.d.ts │ ├── utils │ │ └── request.ts │ └── views │ │ ├── book │ │ ├── index.vue │ │ └── update.vue │ │ ├── bookCategory │ │ ├── index.vue │ │ └── update.vue │ │ ├── home │ │ └── index.vue │ │ ├── layout │ │ └── index.vue │ │ ├── lendReturn │ │ ├── add.vue │ │ ├── index.vue │ │ └── update.vue │ │ ├── login │ │ └── index.vue │ │ ├── manager │ │ └── index.vue │ │ ├── reader │ │ ├── index.vue │ │ └── update.vue │ │ ├── readerCategory │ │ ├── index.vue │ │ └── update.vue │ │ ├── reg │ │ └── index.vue │ │ └── test │ │ └── index.vue ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── library.sql └── readme.md /images/ER1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/ER1.png -------------------------------------------------------------------------------- /images/ER2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/ER2.png -------------------------------------------------------------------------------- /images/addbook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/addbook.png -------------------------------------------------------------------------------- /images/booklist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/booklist.png -------------------------------------------------------------------------------- /images/borrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/borrow.png -------------------------------------------------------------------------------- /images/chart1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/chart1.png -------------------------------------------------------------------------------- /images/chart2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/chart2.png -------------------------------------------------------------------------------- /images/lendreturn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/lendreturn.png -------------------------------------------------------------------------------- /images/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/login.png -------------------------------------------------------------------------------- /images/manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/manager.png -------------------------------------------------------------------------------- /images/mapper1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/mapper1.png -------------------------------------------------------------------------------- /images/mapper2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/mapper2.png -------------------------------------------------------------------------------- /images/readerctg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/readerctg.png -------------------------------------------------------------------------------- /images/readerupdate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/readerupdate.png -------------------------------------------------------------------------------- /images/return.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/images/return.png -------------------------------------------------------------------------------- /library-behind/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /library-behind/common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | fun.cyhgraph 8 | library 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | org.example 13 | common 14 | 15 | 16 | 17 17 | 17 18 | UTF-8 19 | 20 | 21 | 22 | 23 | io.jsonwebtoken 24 | jjwt 25 | 0.9.1 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/constant/AutoFillConstant.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.constant; 2 | 3 | public class AutoFillConstant { 4 | 5 | /** 6 | * 实体类中的方法名称 7 | */ 8 | public static final String SET_CREATE_TIME = "setCreateTime"; 9 | } 10 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/constant/JwtClaimsConstant.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.constant; 2 | 3 | public class JwtClaimsConstant { 4 | 5 | public static final String MANAGER_ID = "managerId"; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/constant/MessageConstant.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.constant; 2 | 3 | public class MessageConstant { 4 | 5 | public static final String MANAGER_NOT_FOUND = "账号不存在"; 6 | public static final String PASSWORD_ERROR = "密码错误"; 7 | public static final String ALREADY_EXiST = "已存在"; 8 | public static final String UNKNOWN_ERROR = "未知错误"; 9 | public static final String BORROW_MAX = "可借书数量已达上限"; 10 | public static final String BORROW_TOO_LONG = "借书时间过长"; 11 | public static final String BORROW_OUT_OF_EFFECT_PERIOD = "借书日期超出有效期"; 12 | } 13 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/constant/StatusConstant.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.constant; 2 | 3 | public class StatusConstant { 4 | 5 | public static final Integer ENABLE = 1; 6 | public static final Integer UNABLE = 0; 7 | } 8 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/context/BaseContext.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.context; 2 | 3 | public class BaseContext { 4 | public static ThreadLocal threadLocal = new ThreadLocal<>(); 5 | 6 | public static void setCurrentId(Integer id) { 7 | threadLocal.set(id); 8 | } 9 | 10 | public static Integer getCurrentId() { 11 | return threadLocal.get(); 12 | } 13 | 14 | public static void removeCurrentId() { 15 | threadLocal.remove(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/enumeration/OperationType.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.enumeration; 2 | 3 | public enum OperationType { 4 | 5 | INSERT, // 插入操作 6 | } 7 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/exception/BaseException.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.exception; 2 | 3 | public class BaseException extends RuntimeException { 4 | public BaseException(){} 5 | 6 | public BaseException(String msg){ 7 | super(msg); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/exception/BorrowMaxException.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.exception; 2 | 3 | public class BorrowMaxException extends BaseException{ 4 | 5 | public BorrowMaxException(){}; 6 | public BorrowMaxException(String msg){ 7 | super(msg); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/exception/BorrowTooLongException.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.exception; 2 | 3 | public class BorrowTooLongException extends BaseException{ 4 | 5 | public BorrowTooLongException (){} 6 | 7 | public BorrowTooLongException (String msg){ 8 | super(msg); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/exception/ManagerNotFoundException.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.exception; 2 | 3 | public class ManagerNotFoundException extends BaseException{ 4 | 5 | public ManagerNotFoundException(){} 6 | 7 | public ManagerNotFoundException(String msg){ 8 | super(msg); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/exception/PasswordErrorException.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.exception; 2 | 3 | public class PasswordErrorException extends BaseException{ 4 | 5 | public PasswordErrorException(){} 6 | 7 | public PasswordErrorException(String msg){ 8 | super(msg); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/json/JacksonObjectMapper.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.json; 2 | 3 | import com.fasterxml.jackson.databind.DeserializationFeature; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.fasterxml.jackson.databind.module.SimpleModule; 6 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; 7 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 8 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; 9 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; 10 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; 11 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; 12 | 13 | import java.time.LocalDate; 14 | import java.time.LocalDateTime; 15 | import java.time.LocalTime; 16 | import java.time.format.DateTimeFormatter; 17 | 18 | import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; 19 | 20 | /** 21 | * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象 22 | * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象] 23 | * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON] 24 | */ 25 | public class JacksonObjectMapper extends ObjectMapper { 26 | 27 | public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; 28 | public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss"; 29 | public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; 30 | 31 | public JacksonObjectMapper() { 32 | super(); 33 | //收到未知属性时不报异常 34 | this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false); 35 | 36 | //反序列化时,属性不存在的兼容处理 37 | this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); 38 | 39 | SimpleModule simpleModule = new SimpleModule() 40 | .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) 41 | .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) 42 | .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))) 43 | .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) 44 | .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) 45 | .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))); 46 | 47 | //注册功能模块 例如,可以添加自定义序列化器和反序列化器 48 | this.registerModule(simpleModule); 49 | } 50 | } -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/properties/JwtProperties.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.properties; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | // 加Component注解,将对象交给IOC容器管理,成为bean对象 8 | @Component 9 | // 标志其为配置属性类,sky.jwt在yml里有标注,存储具体的key value 10 | @ConfigurationProperties(prefix = "login-reg.jwt") 11 | @Data 12 | public class JwtProperties { 13 | 14 | /** 15 | * 管理端员工生成jwt令牌相关配置 16 | */ 17 | private String managerSecretKey; 18 | private long managerTtl; 19 | private String managerTokenName; 20 | 21 | } -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/result/PageResult.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.result; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /** 11 | * 封装分页查询的结果 12 | * 自动生成toString()等方法、有参无参构造 13 | */ 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | public class PageResult implements Serializable { 18 | 19 | private Long total; // 总记录数 20 | private List records; // 当前页数据集合 21 | } 22 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/result/Result.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.result; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 后端统一返回结果 9 | * @param 10 | */ 11 | @Data 12 | public class Result implements Serializable { 13 | 14 | private Integer code; 15 | private String msg; 16 | private T data; 17 | 18 | /** 19 | * 注意:静态方法是属于类的而不是对象的,因此才可以Result.success()直接 “类” 调用方法!!! 20 | * 而且,由于声明了static,表示下面的方法不属于类Rusult,即相当于没声明 21 | * 因此static方法后还要再加一个表示该方法是一个泛型方法 22 | * @return 23 | * @param 24 | */ 25 | public static Result success(){ 26 | Result result = new Result<>(); 27 | result.code = 0; 28 | return result; 29 | } 30 | 31 | public static Result success(T data){ 32 | Result result = new Result<>(); 33 | result.code = 0; 34 | result.data = data; 35 | return result; 36 | } 37 | 38 | public static Result error(String msg){ 39 | Result result = new Result<>(); 40 | result.code = 1; 41 | result.msg = msg; 42 | return result; 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /library-behind/common/src/main/java/fun/cyhgraph/utils/JwtUtil.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.utils; 2 | 3 | import io.jsonwebtoken.Claims; 4 | import io.jsonwebtoken.JwtBuilder; 5 | import io.jsonwebtoken.Jwts; 6 | import io.jsonwebtoken.SignatureAlgorithm; 7 | import lombok.extern.slf4j.Slf4j; 8 | 9 | import java.nio.charset.StandardCharsets; 10 | import java.util.Date; 11 | import java.util.Map; 12 | 13 | @Slf4j 14 | public class JwtUtil { 15 | /** 16 | * 生成jwt 17 | * 使用Hs256算法, 私匙使用固定秘钥 18 | * 19 | * @param secretKey jwt秘钥 20 | * @param ttlMillis jwt过期时间(毫秒) 21 | * @param claims 设置的信息 22 | * @return 23 | */ 24 | public static String createJWT(String secretKey, long ttlMillis, Map claims) { 25 | // 1. header:指定签名的时候使用的签名算法,至于token名称-那不就是JWT嘛! 26 | SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; 27 | // 生成JWT的时间 28 | long expMillis = System.currentTimeMillis() + ttlMillis; 29 | Date exp = new Date(expMillis); 30 | // 设置jwt的 payload 和 signature 31 | JwtBuilder builder = Jwts.builder() 32 | // 2. payload: 如果有私有声明,一定要先设置这个自己创建的私有的声明 33 | // 这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的 34 | .setClaims(claims) 35 | // 3. signature: 设置签名使用的签名算法和签名使用的秘钥 36 | .signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8)) 37 | // 设置过期时间 38 | .setExpiration(exp); 39 | // 至于转成base64,这个Jwts.builder会自动帮我们做的 40 | // 信息整合构建好,生成JWT字符串并返回 41 | return builder.compact(); 42 | } 43 | 44 | /** 45 | * Token解密 46 | * 47 | * @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个 48 | * @param token 加密后的token 49 | * @return 50 | */ 51 | public static Claims parseJWT(String secretKey, String token) { 52 | // 得到DefaultJwtParser 53 | log.info("来到这里校验token是否一致"); 54 | System.out.println(token); 55 | Claims claims = Jwts.parser() 56 | // 设置签名的秘钥 57 | .setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8)) 58 | // 设置需要解析的jwt 59 | .parseClaimsJws(token).getBody(); 60 | System.out.println("claims " + claims); 61 | return claims; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /library-behind/pojo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | fun.cyhgraph 8 | library 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | org.example 13 | pojo 14 | 15 | 16 | 17 17 | 17 18 | UTF-8 19 | 20 | 21 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/dto/BookCatePageDTO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class BookCatePageDTO implements Serializable { 13 | 14 | int page; 15 | int pageSize; 16 | private String name; // 书籍分类名称 17 | private String keywords; // 书籍分类关键词 18 | 19 | } 20 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/dto/BookCategoryDTO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class BookCategoryDTO implements Serializable { 13 | 14 | private Integer id; 15 | private String name; 16 | private String keywords; 17 | private String notes; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/dto/BookDTO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | import java.math.BigDecimal; 9 | import java.time.LocalDate; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class BookDTO implements Serializable { 15 | 16 | private Integer id; 17 | private String name; 18 | private String author; 19 | private String press; 20 | private LocalDate publishDate; 21 | private BigDecimal price; 22 | private Integer pageNumber; 23 | private String keywords; 24 | private String notes; 25 | private Integer categoryId; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/dto/BookPageDTO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class BookPageDTO implements Serializable { 13 | 14 | int page; 15 | int pageSize; 16 | private String name; // 书籍名称 17 | private String status; // 书籍是否借出 18 | private Integer categoryId; // 书籍所属分类 19 | } 20 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/dto/LendReturnDTO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | import java.time.LocalDate; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class LendReturnDTO implements Serializable { 15 | 16 | private Integer id; 17 | // 一个字母 + 一个单词的写法会被转成全小写,无法实现驼峰命名,只能加注解解决 18 | @JsonProperty("rId") 19 | private Integer rId; 20 | @JsonProperty("bId") 21 | private Integer bId; 22 | private LocalDate lendDate; 23 | private LocalDate returnDate; 24 | // 归还书籍状态 0:出借中 1:正常归还 2:逾期归还 3:丢失无法归还 4:损坏归还 5:其他(见备注) 25 | // 1 4 都是有归还,需要将书籍的状态设为0,允许其他人借阅,2 3 5的书籍状态都设为1,其他要注明信息notes 26 | private Integer status; 27 | private String notes; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/dto/LendReturnPageDTO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | 10 | @Data 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class LendReturnPageDTO implements Serializable { 14 | 15 | int page; 16 | int pageSize; 17 | @JsonProperty("rId") 18 | private Integer rId; // 读者名称 19 | @JsonProperty("bId") 20 | private Integer bId; // 书籍名称 21 | private String notes; 22 | } 23 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/dto/ManagerDTO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class ManagerDTO implements Serializable { 13 | 14 | private String name; 15 | private String oldPwd; 16 | private String newPwd; 17 | } 18 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/dto/ManagerLoginDTO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class ManagerLoginDTO implements Serializable { 13 | 14 | private String name; 15 | private String password; 16 | } 17 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/dto/ReaderCatePageDTO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class ReaderCatePageDTO implements Serializable { 13 | 14 | int page; 15 | int pageSize; 16 | private String name; // 读者分类名称 17 | 18 | } 19 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/dto/ReaderCategoryDTO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | import java.time.LocalDate; 9 | 10 | @Data 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class ReaderCategoryDTO implements Serializable { 14 | 15 | private Integer id; 16 | private String name; 17 | private Integer amount; 18 | private Integer lendPeriod; 19 | private LocalDate effectPeriod; 20 | private String notes; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/dto/ReaderDTO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | import java.time.LocalDateTime; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class ReaderDTO implements Serializable { 15 | 16 | private Integer id; 17 | private String name; 18 | private Integer sex; 19 | // 一个字母+一个单词的写法会被转成全小写,无法实现驼峰命名,只能加注解解决 20 | @JsonProperty("wAddress") 21 | private String wAddress; // 工作单位 22 | @JsonProperty("hAddress") 23 | private String hAddress; // 家庭地址 24 | private String phone; 25 | private String email; 26 | private String notes; 27 | private Integer categoryId; 28 | } 29 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/dto/ReaderPageDTO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class ReaderPageDTO implements Serializable { 13 | 14 | int page; 15 | int pageSize; 16 | private String name; // 读者名称 17 | private Integer categoryId; // 读者所属分类 18 | 19 | } 20 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/entity/Book.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | import java.math.BigDecimal; 9 | import java.time.LocalDate; 10 | import java.time.LocalDateTime; 11 | 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class Book implements Serializable { 16 | 17 | private Integer id; 18 | private String name; 19 | private String author; 20 | private String press; 21 | private LocalDate publishDate; 22 | private BigDecimal price; 23 | private Integer pageNumber; 24 | private String keywords; 25 | private LocalDateTime createTime; 26 | private Integer status; 27 | private String notes; 28 | private Integer categoryId; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/entity/BookCategory.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class BookCategory implements Serializable { 13 | 14 | private Integer id; 15 | private String name; 16 | private String keywords; 17 | private String notes; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/entity/LendReturn.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.entity; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | import java.time.LocalDate; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class LendReturn implements Serializable { 15 | 16 | private Integer id; 17 | // 一个字母+一个单词的写法会被转成全小写,无法实现驼峰命名,只能加注解解决 18 | @JsonProperty("rId") 19 | private Integer rId; 20 | @JsonProperty("bId") 21 | private Integer bId; 22 | private LocalDate lendDate; 23 | private LocalDate returnDate; 24 | private Integer status; 25 | private String notes; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/entity/Manager.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class Manager implements Serializable { 13 | 14 | private int id; 15 | private String name; 16 | private String password; 17 | } 18 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/entity/Reader.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.entity; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | import java.time.LocalDate; 10 | import java.time.LocalDateTime; 11 | 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class Reader implements Serializable { 16 | 17 | private Integer id; 18 | private String name; 19 | private Integer sex; 20 | // 一个字母+一个单词的写法会被转成全小写,无法实现驼峰命名,只能加注解解决 21 | @JsonProperty("wAddress") 22 | private String wAddress; // 工作单位 23 | @JsonProperty("hAddress") 24 | private String hAddress; // 家庭地址 25 | private String phone; 26 | private String email; 27 | private LocalDateTime createTime; 28 | private String notes; 29 | private Integer categoryId; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/entity/ReaderCategory.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | import java.time.LocalDate; 9 | 10 | @Data 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class ReaderCategory implements Serializable { 14 | 15 | private Integer id; 16 | private String name; 17 | private Integer amount; 18 | private Integer lendPeriod; 19 | private LocalDate effectPeriod; 20 | private String notes; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/entity/TopInfo.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class TopInfo implements Serializable { 13 | 14 | private String name; 15 | private Integer amount; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/vo/BookCategoryVO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | 10 | @Data 11 | @Builder 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class BookCategoryVO implements Serializable { 15 | 16 | private String bookCategoryNames; // 书籍分类名称列表 17 | private String bookCategoryNums; // 书籍分类对应书的数量 18 | 19 | } 20 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/vo/LendReturnReportVO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | 10 | @Data 11 | @Builder 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class LendReturnReportVO implements Serializable { 15 | 16 | // 日期,以逗号分隔,例如:2022-10-01,2022-10-02,2022-10-03 17 | private String dateList; 18 | // 借书还书数量,以逗号分隔,例如:4,15,7,13 19 | private String lendOrReturnList; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/vo/ManagerLoginVO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | 10 | @Data 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | @Builder // 要能够在controller或者其他地方中快速构造对象,需要在这加上Builder构建器注解 14 | public class ManagerLoginVO implements Serializable { 15 | 16 | private Integer id; 17 | private String name; 18 | private String token; 19 | } 20 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/vo/ReaderCategoryVo.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | 10 | @Data 11 | @Builder 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class ReaderCategoryVo implements Serializable { 15 | 16 | private String readerCategoryNames; // 读者分类名称列表 17 | private String readerCategoryNums; // 读者分类对应读者的数量 18 | 19 | } 20 | -------------------------------------------------------------------------------- /library-behind/pojo/src/main/java/fun/cyhgraph/vo/TopVO.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | 10 | @Data 11 | @Builder 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class TopVO implements Serializable { 15 | 16 | private String nameList; // top的name 17 | private String topList; // name对应的数量 18 | 19 | } 20 | -------------------------------------------------------------------------------- /library-behind/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.2.5 9 | 10 | 11 | fun.cyhgraph 12 | library 13 | 0.0.1-SNAPSHOT 14 | pom 15 | library 16 | library 17 | 18 | common 19 | pojo 20 | 21 | 22 | 17 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | org.mybatis.spring.boot 31 | mybatis-spring-boot-starter 32 | 3.0.3 33 | 34 | 35 | 36 | com.mysql 37 | mysql-connector-j 38 | runtime 39 | 40 | 41 | org.projectlombok 42 | lombok 43 | true 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | test 49 | 50 | 51 | org.mybatis.spring.boot 52 | mybatis-spring-boot-starter-test 53 | 3.0.3 54 | test 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-maven-plugin 63 | 64 | 65 | 66 | org.projectlombok 67 | lombok 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /library-behind/server/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /library-behind/server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.2.5 9 | 10 | 11 | fun.cyhgraph 12 | server 13 | 0.0.1-SNAPSHOT 14 | server 15 | server 16 | 17 | 17 18 | 19 | 20 | 21 | 22 | org.example 23 | common 24 | 0.0.1-SNAPSHOT 25 | 26 | 27 | org.example 28 | pojo 29 | 0.0.1-SNAPSHOT 30 | 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-web 36 | 37 | 38 | org.mybatis.spring.boot 39 | mybatis-spring-boot-starter 40 | 3.0.3 41 | 42 | 43 | 44 | com.mysql 45 | mysql-connector-j 46 | runtime 47 | 48 | 49 | org.projectlombok 50 | lombok 51 | true 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-starter-test 56 | test 57 | 58 | 59 | org.mybatis.spring.boot 60 | mybatis-spring-boot-starter-test 61 | 3.0.3 62 | test 63 | 64 | 65 | 66 | 67 | javax.xml.bind 68 | jaxb-api 69 | 2.3.0 70 | 71 | 72 | com.sun.xml.bind 73 | jaxb-impl 74 | 2.3.0 75 | 76 | 77 | com.sun.xml.bind 78 | jaxb-core 79 | 2.3.0 80 | 81 | 82 | javax.activation 83 | activation 84 | 1.1.1 85 | 86 | 87 | 88 | 89 | com.github.pagehelper 90 | pagehelper-spring-boot-starter 91 | 1.4.6 92 | 93 | 94 | org.springframework.boot 95 | spring-boot-starter-aop 96 | 97 | 98 | commons-lang 99 | commons-lang 100 | 2.6 101 | 102 | 103 | 104 | 105 | 106 | 107 | org.springframework.boot 108 | spring-boot-maven-plugin 109 | 110 | 111 | 112 | org.projectlombok 113 | lombok 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/ServerApplication.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ServerApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ServerApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/annotation/AutoFill.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.annotation; 2 | 3 | import fun.cyhgraph.enumeration.OperationType; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * 自定义注解,用于标识某个方法需要进行功能字段自动填充处理 12 | * 注解接口@interface与普通接口类似,但它们只能包含抽象方法,并且这些方法不能有实现,用于定义自定义注解 13 | */ 14 | @Target(ElementType.METHOD) 15 | @Retention(RetentionPolicy.RUNTIME) 16 | public @interface AutoFill { 17 | // 数据库操作类型:UPDATE INSERT 18 | OperationType value(); 19 | } -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/aspect/AutoFillAspect.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.aspect; 2 | 3 | import fun.cyhgraph.annotation.AutoFill; 4 | import fun.cyhgraph.constant.AutoFillConstant; 5 | import fun.cyhgraph.enumeration.OperationType; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.aspectj.lang.JoinPoint; 8 | import org.aspectj.lang.annotation.Aspect; 9 | import org.aspectj.lang.annotation.Before; 10 | import org.aspectj.lang.annotation.Pointcut; 11 | import org.aspectj.lang.reflect.MethodSignature; 12 | import org.springframework.stereotype.Component; 13 | 14 | import java.lang.reflect.Method; 15 | import java.time.LocalDateTime; 16 | 17 | @Component 18 | @Aspect 19 | @Slf4j 20 | public class AutoFillAspect { 21 | 22 | /** 23 | * 切入点表达式,封装成一个小方法 24 | */ 25 | @Pointcut("execution(* fun.cyhgraph.mapper.*.*(..)) && @annotation(fun.cyhgraph.annotation.AutoFill)") 26 | public void autoFillPointCut() { 27 | } 28 | 29 | /** 30 | * 前置通知,在通知中进行公共字段的赋值 31 | */ 32 | @Before("autoFillPointCut()") // 调用上面的切入点表达式 33 | public void autoFill(JoinPoint joinPoint) { 34 | // 可先进行调试,是否能进入该方法 提前在mapper方法添加AutoFill注解 35 | log.info("开始进行公共字段(create_time等)的自动填充..."); 36 | // 获取到当前被拦截的方法上的数据库操作类型 37 | MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名对象 38 | AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class); // 获得方法上的注解对象 39 | OperationType operationType = autoFill.value(); // 获得数据库操作类型 40 | // 获取到当前被拦截的方法的参数--实体对象 41 | Object[] args = joinPoint.getArgs(); 42 | if (args == null || args.length == 0) { 43 | return; 44 | } 45 | Object entity = args[0]; 46 | // 准备赋值的数据:自动填充当前时间 47 | LocalDateTime now = LocalDateTime.now(); 48 | if (operationType == OperationType.INSERT) { 49 | // 为公共字段(时间字段)赋值,刚开始插入需要设置create字段 50 | try { 51 | Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class); 52 | // 通过反射为对象属性赋值 53 | setCreateTime.invoke(entity, now); 54 | } catch (Exception e) { 55 | e.printStackTrace(); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/config/WebMvcConfiguration.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.config; 2 | 3 | import fun.cyhgraph.interceptor.JwtTokenInterceptor; 4 | import fun.cyhgraph.json.JacksonObjectMapper; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.http.converter.HttpMessageConverter; 10 | import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; 11 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 12 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 13 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * 配置类,注册web层相关组件 19 | */ 20 | @Configuration 21 | @Slf4j 22 | public class WebMvcConfiguration extends WebMvcConfigurationSupport { 23 | 24 | @Autowired 25 | private JwtTokenInterceptor JwtTokenInterceptor; 26 | 27 | /** 28 | * 注册自定义拦截器 29 | * 30 | * @param registry 31 | */ 32 | protected void addInterceptors(InterceptorRegistry registry) { 33 | log.info("开始注册自定义拦截器..."); 34 | registry.addInterceptor(JwtTokenInterceptor) 35 | .addPathPatterns("/**") 36 | .excludePathPatterns("/manager/login") 37 | .excludePathPatterns("/manager/register"); 38 | } 39 | 40 | /** 41 | * 扩展Spring MVC框架的消息转换器 42 | * @param converters 43 | */ 44 | protected void extendMessageConverters(List> converters) { 45 | log.info("扩展消息转换器..."); 46 | // 创建一个消息转换器对象 47 | MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); 48 | // 需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据 49 | converter.setObjectMapper(new JacksonObjectMapper()); 50 | // 将自己的消息转换器加入容器中 51 | converters.add(0, converter); 52 | super.extendMessageConverters(converters); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/controller/BookCategoryController.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.controller; 2 | 3 | import com.github.pagehelper.Page; 4 | import fun.cyhgraph.dto.BookCatePageDTO; 5 | import fun.cyhgraph.dto.BookCategoryDTO; 6 | import fun.cyhgraph.entity.BookCategory; 7 | import fun.cyhgraph.result.PageResult; 8 | import fun.cyhgraph.result.Result; 9 | import fun.cyhgraph.service.BookCategoryService; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.apache.ibatis.annotations.Delete; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | @RestController 16 | @RequestMapping("/bookCategory") 17 | @Slf4j 18 | public class BookCategoryController { 19 | 20 | @Autowired 21 | private BookCategoryService bookCategoryService; 22 | 23 | /** 24 | * 添加书籍分类 25 | * @return 26 | */ 27 | @PostMapping 28 | public Result addCategory(@RequestBody BookCategoryDTO bookCategoryDTO){ 29 | log.info("要添加的书籍分类信息:{}", bookCategoryDTO); 30 | bookCategoryService.addCategory(bookCategoryDTO); 31 | return Result.success(); 32 | } 33 | 34 | /** 35 | * 书籍分类分页查询 36 | * @return 37 | */ 38 | @GetMapping("/page") 39 | public Result page(BookCatePageDTO bookCatePageDTO){ 40 | log.info("分页查询条件:{}", bookCatePageDTO); 41 | PageResult pageResult = bookCategoryService.page(bookCatePageDTO); 42 | return Result.success(pageResult); 43 | } 44 | 45 | /** 46 | * 根据id查询书籍分类 47 | * @param id 48 | * @return 49 | */ 50 | @GetMapping("/{id}") 51 | public Result getById(@PathVariable Integer id){ 52 | log.info("要查询的书籍id:{}", id); 53 | BookCategory bookCategory = bookCategoryService.getById(id); 54 | return Result.success(bookCategory); 55 | } 56 | 57 | /** 58 | * 修改书籍分类 59 | * @param bookCategoryDTO 60 | * @return 61 | */ 62 | @PutMapping 63 | public Result update(@RequestBody BookCategoryDTO bookCategoryDTO){ 64 | log.info("要修改的书籍分类信息:{}", bookCategoryDTO); 65 | bookCategoryService.update(bookCategoryDTO); 66 | return Result.success(); 67 | } 68 | 69 | /** 70 | * 根据id删除书籍分类 71 | * @param id 72 | * @return 73 | */ 74 | @DeleteMapping("/{id}") 75 | public Result deleteById(@PathVariable Integer id){ 76 | log.info("要删除的书籍分类:{}", id); 77 | bookCategoryService.deleteById(id); 78 | return Result.success(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/controller/BookController.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.controller; 2 | 3 | import fun.cyhgraph.dto.BookDTO; 4 | import fun.cyhgraph.dto.BookPageDTO; 5 | import fun.cyhgraph.entity.Book; 6 | import fun.cyhgraph.result.PageResult; 7 | import fun.cyhgraph.result.Result; 8 | import fun.cyhgraph.service.BookService; 9 | import jakarta.websocket.server.PathParam; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.apache.ibatis.annotations.Delete; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | import java.util.List; 16 | 17 | @RestController 18 | @RequestMapping("/book") 19 | @Slf4j 20 | public class BookController { 21 | 22 | @Autowired 23 | private BookService bookService; 24 | 25 | /** 26 | * 新增书籍 27 | * @return 28 | */ 29 | @PostMapping 30 | public Result addBook(@RequestBody BookDTO bookDTO) { 31 | bookService.addBook(bookDTO); 32 | return Result.success(); 33 | } 34 | 35 | /** 36 | * 条件书籍分页查询 37 | * @param bookPageDTO 38 | * @return 39 | */ 40 | @GetMapping("/page") 41 | public Result page(BookPageDTO bookPageDTO) { 42 | log.info("分页条件:{}", bookPageDTO); 43 | PageResult pageResult = bookService.page(bookPageDTO); 44 | return Result.success(pageResult); 45 | } 46 | 47 | /** 48 | * 根据id查询书籍 49 | * @param id 50 | * @return 51 | */ 52 | @GetMapping("/{id}") 53 | public Result getById(@PathVariable Integer id){ 54 | log.info("根据id查询书籍:{}", id); 55 | Book book = bookService.getById(id); 56 | return Result.success(book); 57 | } 58 | 59 | /** 60 | * 修改书籍信息 61 | * @param bookDTO 62 | * @return 63 | */ 64 | @PutMapping 65 | public Result update(@RequestBody BookDTO bookDTO){ 66 | log.info("新的书籍信息:{}", bookDTO); 67 | bookService.update(bookDTO); 68 | return Result.success(bookDTO); 69 | } 70 | 71 | /** 72 | * 根据id修改书籍状态(是否借出),在sql里直接做状态反转 73 | * @return 74 | */ 75 | @PutMapping("/status/{id}") 76 | public Result status(@PathVariable Integer id){ 77 | bookService.status(id); 78 | return Result.success(); 79 | } 80 | 81 | /** 82 | * 批量删除书籍 83 | * 前端传过来的数组是"1,2,3"这种序列化好的字符串,List无法识别 84 | * 所以需要加 @RequestParam 让它强制识别,否则会发生List类型参数报错 85 | * @param ids 86 | * @return 87 | */ 88 | @DeleteMapping 89 | public Result deleteBatch(@RequestParam List ids){ 90 | log.info("批量删除行数据:{}", ids); 91 | bookService.deleteBatch(ids); 92 | return Result.success(); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/controller/BorrowController.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.controller; 2 | 3 | import fun.cyhgraph.dto.LendReturnDTO; 4 | import fun.cyhgraph.dto.LendReturnPageDTO; 5 | import fun.cyhgraph.entity.LendReturn; 6 | import fun.cyhgraph.result.PageResult; 7 | import fun.cyhgraph.result.Result; 8 | import fun.cyhgraph.service.BorrowService; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | import java.util.List; 14 | 15 | @RestController 16 | @RequestMapping("/borrow") 17 | @Slf4j 18 | public class BorrowController { 19 | 20 | @Autowired 21 | private BorrowService borrowService; 22 | 23 | /** 24 | * 新增借还书记录 25 | * @param lendReturnDTO 26 | * @return 27 | */ 28 | @PostMapping 29 | public Result addBorrow(@RequestBody LendReturnDTO lendReturnDTO){ 30 | log.info("新增借还书记录:{}", lendReturnDTO); 31 | borrowService.addBorrow(lendReturnDTO); 32 | return Result.success(); 33 | } 34 | 35 | /** 36 | * 分页查询借还书记录 37 | * @param lendReturnPageDTO 38 | * @return 39 | */ 40 | @GetMapping("/page") 41 | public Result page(LendReturnPageDTO lendReturnPageDTO){ 42 | log.info("分页查询借还书记录的条件:{}", lendReturnPageDTO); 43 | PageResult pageResult = borrowService.page(lendReturnPageDTO); 44 | return Result.success(pageResult); 45 | } 46 | 47 | /** 48 | * 根据书、人的信息查询借阅记录 49 | * @param id 50 | * @return 51 | */ 52 | @GetMapping("/{id}") 53 | public Result getById(@PathVariable Integer id){ 54 | log.info("借书人和书籍分别为:{}", id); 55 | LendReturn lendReturn = borrowService.getById(id); 56 | return Result.success(lendReturn); 57 | } 58 | 59 | /** 60 | * 更新借还书记录 61 | * @param lendReturnDTO 62 | * @return 63 | */ 64 | @PutMapping 65 | public Result update(@RequestBody LendReturnDTO lendReturnDTO){ 66 | log.info("新的借还书记录:{}", lendReturnDTO); 67 | borrowService.update(lendReturnDTO); 68 | return Result.success(); 69 | } 70 | 71 | /** 72 | * 批量删除异常借还书记录(没有异常就不要随便删除记录!) 73 | * @param ids 74 | * @return 75 | */ 76 | @DeleteMapping 77 | public Result deleteBatch(@RequestParam List ids){ 78 | log.info("批量删除异常借还书记录:{}", ids); 79 | borrowService.delete(ids); 80 | return Result.success(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/controller/ChartController.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.controller; 2 | 3 | import fun.cyhgraph.result.Result; 4 | import fun.cyhgraph.service.ChartService; 5 | import fun.cyhgraph.vo.BookCategoryVO; 6 | import fun.cyhgraph.vo.LendReturnReportVO; 7 | import fun.cyhgraph.vo.ReaderCategoryVo; 8 | import fun.cyhgraph.vo.TopVO; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.format.annotation.DateTimeFormat; 12 | import org.springframework.web.bind.annotation.GetMapping; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RestController; 15 | 16 | import java.time.LocalDate; 17 | 18 | @RestController 19 | @RequestMapping("/chart") 20 | @Slf4j 21 | public class ChartController { 22 | 23 | @Autowired 24 | private ChartService chartService; 25 | 26 | 27 | /** 28 | * 获取书籍分类对应书籍数量 29 | * @return 30 | */ 31 | @GetMapping("/bookCategory") 32 | public Result bookPie(){ 33 | log.info("获取书籍分类对应书籍数量"); 34 | return Result.success(chartService.bookPie()); 35 | } 36 | 37 | /** 38 | * 获取读者分类对应读者数量 39 | * @return 40 | */ 41 | @GetMapping("/readerCategory") 42 | public Result readerPie(){ 43 | log.info("获取读者分类对应读者数量"); 44 | return Result.success(chartService.readerPie()); 45 | } 46 | 47 | /** 48 | * 查询近day天的借书数据 49 | * @param day 50 | * @return 51 | */ 52 | @GetMapping("/dayNLend") 53 | public Result dayNLend(Integer day) { 54 | log.info("借书数据 近day天:{}", day); 55 | LendReturnReportVO lendReportVO = chartService.dayNLend(day); 56 | return Result.success(lendReportVO); 57 | } 58 | 59 | /** 60 | * 查询近day天的还书数据 61 | * @param day 62 | * @return 63 | */ 64 | @GetMapping("/dayNReturn") 65 | public Result dayNReturn(Integer day) { 66 | log.info("还书数据 近day天:{}", day); 67 | LendReturnReportVO returnReportVO = chartService.dayNReturn(day); 68 | return Result.success(returnReportVO); 69 | } 70 | 71 | /** 72 | * 查询近day天的书本销量 73 | * @param day 74 | * @return 75 | */ 76 | @GetMapping("/bookTop") 77 | public Result bookTop(Integer day){ 78 | log.info("bookTop 近day天:{}", day); 79 | TopVO topVO = chartService.bookTop(day); 80 | return Result.success(topVO); 81 | } 82 | 83 | /** 84 | * 查询近day天的读者借书排行榜 85 | * @param day 86 | * @return 87 | */ 88 | @GetMapping("/readerTop") 89 | public Result readerTop(Integer day){ 90 | log.info("readerTop 近day天:{}", day); 91 | TopVO topVO = chartService.readerTop(day); 92 | return Result.success(topVO); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/controller/ManagerController.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.controller; 2 | 3 | import fun.cyhgraph.constant.JwtClaimsConstant; 4 | import fun.cyhgraph.dto.ManagerDTO; 5 | import fun.cyhgraph.dto.ManagerLoginDTO; 6 | import fun.cyhgraph.entity.Manager; 7 | import fun.cyhgraph.properties.JwtProperties; 8 | import fun.cyhgraph.result.Result; 9 | import fun.cyhgraph.service.ManagerService; 10 | import fun.cyhgraph.utils.JwtUtil; 11 | import fun.cyhgraph.vo.ManagerLoginVO; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.web.bind.annotation.*; 15 | 16 | import java.util.HashMap; 17 | import java.util.Map; 18 | 19 | @RestController 20 | @RequestMapping("/manager") 21 | @Slf4j 22 | public class ManagerController { 23 | 24 | @Autowired 25 | private ManagerService managerService; 26 | @Autowired 27 | private JwtProperties jwtProperties; 28 | 29 | /** 30 | * 根据id获取管理员信息 31 | * @param id 32 | * @return 33 | */ 34 | @GetMapping("/{id}") 35 | public Result getUserById(@PathVariable Integer id){ 36 | Manager manager = managerService.getManagerById(id); 37 | return Result.success(manager); 38 | } 39 | 40 | /** 41 | * 管理员登录 42 | * @param managerLoginDTO 43 | * @return 44 | */ 45 | @PostMapping("/login") 46 | public Result login(@RequestBody ManagerLoginDTO managerLoginDTO){ 47 | log.info("用户传过来的登录信息DTO:{}", managerLoginDTO); 48 | Manager manager = managerService.login(managerLoginDTO); 49 | // 上面的没抛异常,正常来到这里,说明登录成功 50 | // claims就是用户数据payload部分 51 | Map claims = new HashMap<>(); // jsonwebtoken包底层就是Map格式,不能修改! 52 | claims.put(JwtClaimsConstant.MANAGER_ID, manager.getId()); 53 | // 需要加个token给他,再返回响应 54 | String token = JwtUtil.createJWT( 55 | jwtProperties.getManagerSecretKey(), 56 | jwtProperties.getManagerTtl(), 57 | claims); 58 | ManagerLoginVO managerLoginVO = ManagerLoginVO.builder() 59 | .id(manager.getId()) 60 | .name(manager.getName()) 61 | .token(token) 62 | .build(); 63 | return Result.success(managerLoginVO); 64 | } 65 | 66 | /** 67 | * 管理员注册(其实就是新增操作而已,和token什么的无关!) 68 | * @param managerLoginDTO 69 | * @return 70 | */ 71 | @PostMapping("/register") 72 | public Result register(@RequestBody ManagerLoginDTO managerLoginDTO){ 73 | log.info("用户传过来的注册信息(和登录格式一样的DTO):{}", managerLoginDTO); 74 | managerService.register(managerLoginDTO); 75 | return Result.success(); 76 | } 77 | 78 | /** 79 | * 修改个人信息 80 | * @param managerDTO 81 | * @return 82 | */ 83 | @PutMapping 84 | public Result update(@RequestBody ManagerDTO managerDTO){ 85 | log.info("修改后的用户信息:{}", managerDTO); 86 | managerService.update(managerDTO); 87 | return Result.success(); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/controller/ReaderCategoryController.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.controller; 2 | 3 | import fun.cyhgraph.dto.BookCategoryDTO; 4 | import fun.cyhgraph.dto.ReaderCatePageDTO; 5 | import fun.cyhgraph.dto.ReaderCategoryDTO; 6 | import fun.cyhgraph.entity.BookCategory; 7 | import fun.cyhgraph.entity.ReaderCategory; 8 | import fun.cyhgraph.result.PageResult; 9 | import fun.cyhgraph.result.Result; 10 | import fun.cyhgraph.service.ReaderCategoryService; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | @RestController 16 | @RequestMapping("/readerCategory") 17 | @Slf4j 18 | public class ReaderCategoryController { 19 | 20 | @Autowired 21 | private ReaderCategoryService readerCategoryService; 22 | 23 | /** 24 | * 添加读者种类 25 | * @return 26 | */ 27 | @PostMapping 28 | public Result addCategory(@RequestBody ReaderCategoryDTO readerCategoryDTO){ 29 | log.info("读者种类信息:{}", readerCategoryDTO); 30 | readerCategoryService.addCategory(readerCategoryDTO); 31 | return Result.success(); 32 | } 33 | 34 | /** 35 | * 读者分类分页查询 36 | * @param readerCatePageDTO 37 | * @return 38 | */ 39 | @GetMapping("/page") 40 | public Result page(ReaderCatePageDTO readerCatePageDTO){ 41 | log.info("读者种类分页查询条件:{}", readerCatePageDTO); 42 | PageResult pageResult = readerCategoryService.page(readerCatePageDTO); 43 | return Result.success(pageResult); 44 | } 45 | 46 | /** 47 | * 根据id查询书籍分类 48 | * @param id 49 | * @return 50 | */ 51 | @GetMapping("/{id}") 52 | public Result getById(@PathVariable Integer id){ 53 | log.info("要查询的读者id:{}", id); 54 | ReaderCategory readerCategory = readerCategoryService.getById(id); 55 | return Result.success(readerCategory); 56 | } 57 | 58 | /** 59 | * 修改读者分类 60 | * @param readerCategoryDTO 61 | * @return 62 | */ 63 | @PutMapping 64 | public Result update(@RequestBody ReaderCategoryDTO readerCategoryDTO){ 65 | log.info("要修改的读者分类信息:{}", readerCategoryDTO); 66 | readerCategoryService.update(readerCategoryDTO); 67 | return Result.success(); 68 | } 69 | 70 | /** 71 | * 根据id删除读者分类 72 | * @param id 73 | * @return 74 | */ 75 | @DeleteMapping("/{id}") 76 | public Result deleteById(@PathVariable Integer id){ 77 | log.info("根据id删除读者分类:{}", id); 78 | readerCategoryService.deleteById(id); 79 | return Result.success(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/controller/ReaderController.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.controller; 2 | 3 | import fun.cyhgraph.dto.BookDTO; 4 | import fun.cyhgraph.dto.BookPageDTO; 5 | import fun.cyhgraph.dto.ReaderDTO; 6 | import fun.cyhgraph.dto.ReaderPageDTO; 7 | import fun.cyhgraph.entity.Book; 8 | import fun.cyhgraph.entity.Reader; 9 | import fun.cyhgraph.result.PageResult; 10 | import fun.cyhgraph.result.Result; 11 | import fun.cyhgraph.service.ReaderService; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.web.bind.annotation.*; 15 | 16 | import java.util.List; 17 | 18 | @RestController 19 | @RequestMapping("/reader") 20 | @Slf4j 21 | public class ReaderController { 22 | 23 | @Autowired 24 | private ReaderService readerService; 25 | 26 | /** 27 | * 新增读者 28 | * @param readerDTO 29 | * @return 30 | */ 31 | @PostMapping 32 | public Result addReader(@RequestBody ReaderDTO readerDTO){ 33 | log.info("新增读者的信息:{}", readerDTO); 34 | readerService.addReader(readerDTO); 35 | return Result.success(); 36 | } 37 | 38 | /** 39 | * 条件读者分页查询 40 | * @param readerPageDTO 41 | * @return 42 | */ 43 | @GetMapping("/page") 44 | public Result page(ReaderPageDTO readerPageDTO) { 45 | log.info("分页条件:{}", readerPageDTO); 46 | PageResult pageResult = readerService.page(readerPageDTO); 47 | return Result.success(pageResult); 48 | } 49 | 50 | /** 51 | * 根据id查询读者 52 | * @param id 53 | * @return 54 | */ 55 | @GetMapping("/{id}") 56 | public Result getById(@PathVariable Integer id){ 57 | log.info("根据id查询书籍:{}", id); 58 | Reader reader = readerService.getById(id); 59 | return Result.success(reader); 60 | } 61 | 62 | /** 63 | * 修改读者信息 64 | * @param readerDTO 65 | * @return 66 | */ 67 | @PutMapping 68 | public Result udpate(@RequestBody ReaderDTO readerDTO){ 69 | log.info("新的读者信息:{}", readerDTO); 70 | readerService.update(readerDTO); 71 | return Result.success(readerDTO); 72 | } 73 | 74 | /** 75 | * 批量删除书籍 76 | * 前端传过来的数组是"1,2,3"这种序列化好的字符串,List无法识别 77 | * 所以需要加 @RequestParam 让它强制识别,否则会发生List类型参数报错 78 | * @param ids 79 | * @return 80 | */ 81 | @DeleteMapping 82 | public Result deleteBatch(@RequestParam List ids){ 83 | log.info("批量删除行数据:{}", ids); 84 | readerService.deleteBatch(ids); 85 | return Result.success(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/handler/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.handler; 2 | 3 | import fun.cyhgraph.constant.MessageConstant; 4 | import fun.cyhgraph.exception.BaseException; 5 | import fun.cyhgraph.result.Result; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.bind.annotation.RestControllerAdvice; 9 | 10 | import java.sql.SQLDataException; 11 | import java.sql.SQLException; 12 | import java.sql.SQLIntegrityConstraintViolationException; 13 | 14 | /** 15 | * 全局异常处理器,能对项目中抛出的异常进行捕获和处理 16 | */ 17 | @RestControllerAdvice 18 | @Slf4j 19 | public class GlobalExceptionHandler { 20 | 21 | @ExceptionHandler 22 | public Result excepitonHandler(BaseException ex){ 23 | log.info("异常信息:{}", ex.getMessage()); 24 | return Result.error(ex.getMessage()); 25 | } 26 | 27 | @ExceptionHandler 28 | public Result exceptionHandler(SQLIntegrityConstraintViolationException ex){ 29 | // Duplicate entry 'zhangsan' for key 'employee.idx_username' 30 | String message = ex.getMessage(); 31 | // 打印错误信息(因为可能不止value重复这一种错误!) 32 | log.info("-----------------全局捕获错误信息:" + message); 33 | if (message.contains("Duplicate entry")){ 34 | String[] split = message.split(" "); 35 | String username = split[2]; 36 | String msg = username + MessageConstant.ALREADY_EXiST; 37 | return Result.error(msg); 38 | }else { 39 | return Result.error(MessageConstant.UNKNOWN_ERROR); 40 | } 41 | } 42 | 43 | @ExceptionHandler 44 | public Result exceptionHandler(SQLException ex){ 45 | log.info("----------------全局捕获错误信息:" + ex.getMessage()); 46 | return Result.error(ex.getMessage()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/interceptor/JwtTokenInterceptor.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.interceptor; 2 | 3 | import fun.cyhgraph.constant.JwtClaimsConstant; 4 | import fun.cyhgraph.context.BaseContext; 5 | import fun.cyhgraph.properties.JwtProperties; 6 | import fun.cyhgraph.utils.JwtUtil; 7 | import io.jsonwebtoken.Claims; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.web.method.HandlerMethod; 12 | import org.springframework.web.servlet.HandlerInterceptor; 13 | // 关于servlet的api接口,本身为JavaEE所有,但是SpringBoot3之后换成 Jakarta EE 了 14 | // 原因是 eclipse 拿到 Oracle 转过来的 Java EE 规范之后,因版权问题不能使用 javax 名称,所以需要重命名 15 | import jakarta.servlet.http.HttpServletRequest; 16 | import jakarta.servlet.http.HttpServletResponse; 17 | 18 | /** 19 | * jwt令牌校验的拦截器 20 | */ 21 | @Component 22 | @Slf4j 23 | public class JwtTokenInterceptor implements HandlerInterceptor { 24 | 25 | @Autowired 26 | private JwtProperties jwtProperties; 27 | 28 | /** 29 | * 对controller资源进行请求之前,需要校验jwt 30 | * 31 | * @param request 32 | * @param response 33 | * @param handler 34 | * @return 35 | * @throws Exception 36 | */ 37 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 38 | // 判断当前拦截到的是Controller的方法还是其他资源 39 | if (!(handler instanceof HandlerMethod)) { 40 | // 当前拦截到的不是Controller动态方法,直接放行 41 | return true; 42 | } 43 | // 1、从请求头中获取令牌 44 | String token = request.getHeader(jwtProperties.getManagerTokenName()); 45 | System.out.println("-------------------------------- token -------------------------------- " + token); 46 | // 2、校验令牌 47 | try { 48 | log.info("jwt校验:{}", token); 49 | Claims claims = JwtUtil.parseJWT(jwtProperties.getManagerSecretKey(), token); 50 | Integer EmployeeId = Integer.valueOf(claims.get(JwtClaimsConstant.MANAGER_ID).toString()); 51 | log.info("当前用户id:{}", EmployeeId); 52 | // 将id存到当前线程thread的局部空间里面,并在controller,service或者其他地方进行调用获取id 53 | BaseContext.setCurrentId(EmployeeId); 54 | // 3、通过,放行 55 | return true; 56 | } catch (Exception ex) { 57 | // 4、不通过,响应401状态码 58 | response.setStatus(401); 59 | return false; 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/mapper/BookCategoryMapper.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.mapper; 2 | 3 | import com.github.pagehelper.Page; 4 | import fun.cyhgraph.dto.BookCatePageDTO; 5 | import fun.cyhgraph.entity.BookCategory; 6 | import org.apache.ibatis.annotations.Delete; 7 | import org.apache.ibatis.annotations.Insert; 8 | import org.apache.ibatis.annotations.Mapper; 9 | import org.apache.ibatis.annotations.Select; 10 | 11 | import java.util.List; 12 | 13 | @Mapper 14 | public interface BookCategoryMapper { 15 | 16 | @Insert("insert into b_category (name, keywords, notes) VALUES (#{name}, #{keywords}, #{notes})") 17 | void insert(BookCategory bookCategory); 18 | 19 | Page page(BookCatePageDTO bookCatePageDTO); 20 | 21 | @Select("select * from b_category where id = #{id}") 22 | BookCategory getById(Integer id); 23 | 24 | void update(BookCategory bookCategory); 25 | 26 | @Delete("delete from b_category where id = #{id}") 27 | void deleteById(Integer id); 28 | 29 | @Select("select name from b_category") 30 | List getNames(); 31 | 32 | @Select("select id from b_category") 33 | List getIds(); 34 | } 35 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/mapper/BookMapper.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.mapper; 2 | 3 | import com.github.pagehelper.Page; 4 | import fun.cyhgraph.annotation.AutoFill; 5 | import fun.cyhgraph.dto.BookPageDTO; 6 | import fun.cyhgraph.entity.Book; 7 | import fun.cyhgraph.enumeration.OperationType; 8 | import org.apache.ibatis.annotations.Insert; 9 | import org.apache.ibatis.annotations.Mapper; 10 | import org.apache.ibatis.annotations.Select; 11 | import org.apache.ibatis.annotations.Update; 12 | 13 | import java.util.List; 14 | 15 | @Mapper 16 | public interface BookMapper { 17 | 18 | @AutoFill(value = OperationType.INSERT) 19 | @Insert("insert into book (name, category_id, author, press, publish_date, " + 20 | "price, page_number, keywords, create_time, status, notes) " + 21 | "VALUES " + 22 | "(#{name}, #{categoryId}, #{author}, #{press}, #{publishDate}," + 23 | "#{price}, #{pageNumber}, #{keywords}, #{createTime}, #{status}, #{notes})") 24 | void insert(Book book); 25 | 26 | Page page(BookPageDTO bookPageDTO); 27 | 28 | @Select("select * from book where id = #{id}") 29 | Book getById(Integer id); 30 | 31 | void update(Book book); 32 | 33 | void deleteBatch(List ids); 34 | 35 | @Update("update book set status = IF(status = 1, 0, 1) where id = #{id}") 36 | void status(Integer id); 37 | 38 | @Select("select count(id) from book where category_id = #{id}") 39 | Integer sumByCategoryId(Integer id); 40 | } 41 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/mapper/BorrowMapper.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.mapper; 2 | 3 | import com.github.pagehelper.Page; 4 | import fun.cyhgraph.dto.LendReturnPageDTO; 5 | import fun.cyhgraph.entity.LendReturn; 6 | import org.apache.ibatis.annotations.Insert; 7 | import org.apache.ibatis.annotations.Mapper; 8 | import org.apache.ibatis.annotations.Select; 9 | 10 | import java.time.LocalDate; 11 | import java.util.List; 12 | 13 | @Mapper 14 | public interface BorrowMapper { 15 | 16 | @Insert("insert into lend_return (r_id, b_id, lend_date, return_date, status, notes) VALUES " + 17 | "(#{rId}, #{bId}, #{lendDate}, #{returnDate}, #{status}, #{notes})") 18 | void insert(LendReturn lendReturn); 19 | 20 | Page page(LendReturnPageDTO lendReturnPageDTO); 21 | 22 | @Select("select * from lend_return where id = #{id}") 23 | LendReturn getById(Integer id); 24 | 25 | void update(LendReturn lendReturn); 26 | 27 | void deleteBatch(List ids); 28 | 29 | List getBIdsByDate(LocalDate begin); 30 | 31 | Integer getBookAmount(LocalDate begin, Integer bId); 32 | 33 | List getRIdsByDate(LocalDate begin); 34 | 35 | /** 36 | * 拿到rId读者在begin之后(>=begin)借书的数量 37 | * @param begin 38 | * @param rId 39 | * @return 40 | */ 41 | Integer getReaderAmount(LocalDate begin, Integer rId); 42 | 43 | /** 44 | * 拿到rId读者在lendDate之前(<=lendDate)借书的数量 45 | * @param lendReturn 46 | * @return 47 | */ 48 | Integer getReaderHad(LendReturn lendReturn); 49 | } 50 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/mapper/ChartMapper.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.mapper; 2 | 3 | import org.apache.ibatis.annotations.Mapper; 4 | import org.apache.ibatis.annotations.Select; 5 | 6 | import java.time.LocalDate; 7 | 8 | @Mapper 9 | public interface ChartMapper { 10 | 11 | @Select("select count(id) from lend_return where lend_date = #{date}") 12 | Integer sumByLendDate(LocalDate date); 13 | 14 | @Select("select count(id) from lend_return where return_date = #{date}") 15 | Integer sumByReturnDate(LocalDate date); 16 | } 17 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/mapper/ManagerMapper.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.mapper; 2 | 3 | import fun.cyhgraph.entity.Manager; 4 | import org.apache.ibatis.annotations.Insert; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.apache.ibatis.annotations.Select; 7 | import org.apache.ibatis.annotations.Update; 8 | 9 | @Mapper 10 | public interface ManagerMapper { 11 | 12 | @Select("select * from manager where id = #{id}") 13 | Manager getById(Integer id); 14 | 15 | @Select("select * from manager where name = #{name}") 16 | Manager getByName(String name); 17 | 18 | @Insert("insert into manager (name, password) values (#{name}, #{password})") 19 | void addManager(Manager manager); 20 | 21 | @Update("update manager set name = #{name}, password = #{password} where id = #{id}") 22 | void update(Manager manager); 23 | } 24 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/mapper/ReaderCategoryMapper.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.mapper; 2 | 3 | import com.github.pagehelper.Page; 4 | import fun.cyhgraph.dto.ReaderCatePageDTO; 5 | import fun.cyhgraph.dto.ReaderCategoryDTO; 6 | import fun.cyhgraph.entity.ReaderCategory; 7 | import org.apache.ibatis.annotations.Delete; 8 | import org.apache.ibatis.annotations.Insert; 9 | import org.apache.ibatis.annotations.Mapper; 10 | import org.apache.ibatis.annotations.Select; 11 | 12 | import java.util.List; 13 | 14 | @Mapper 15 | public interface ReaderCategoryMapper { 16 | 17 | @Insert("insert into r_category (name, amount, lend_period, effect_period, notes) VALUES " + 18 | "(#{name}, #{amount}, #{lendPeriod}, #{effectPeriod}, #{notes})") 19 | void insert(ReaderCategory readerCategory); 20 | 21 | Page page(ReaderCatePageDTO readerCatePageDTO); 22 | 23 | @Select("select * from r_category where id = #{id}") 24 | ReaderCategory getById(Integer id); 25 | 26 | void update(ReaderCategory readerCategory); 27 | 28 | @Delete("delete from r_category where id = #{id}") 29 | void deleteById(Integer id); 30 | 31 | @Select("select amount from r_category where id = #{id}") 32 | Integer getAmountById(Integer rId); 33 | 34 | @Select("select name from r_category") 35 | List getNames(); 36 | 37 | @Select("select id from r_category") 38 | List getIds(); 39 | } 40 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/mapper/ReaderMapper.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.mapper; 2 | 3 | import com.github.pagehelper.Page; 4 | import fun.cyhgraph.annotation.AutoFill; 5 | import fun.cyhgraph.dto.ReaderPageDTO; 6 | import fun.cyhgraph.entity.Reader; 7 | import fun.cyhgraph.enumeration.OperationType; 8 | import org.apache.ibatis.annotations.Insert; 9 | import org.apache.ibatis.annotations.Mapper; 10 | import org.apache.ibatis.annotations.Select; 11 | 12 | import java.util.List; 13 | 14 | @Mapper 15 | public interface ReaderMapper { 16 | 17 | @AutoFill(value = OperationType.INSERT) 18 | @Insert("insert into reader (name, category_id, sex, w_address, h_address, phone, email, create_time, notes) " + 19 | "VALUES " + 20 | "(#{name}, #{categoryId}, #{sex}, #{wAddress}, #{hAddress}, #{phone}, #{email}, #{createTime}, #{notes})") 21 | void insert(Reader reader); 22 | 23 | Page page(ReaderPageDTO readerPageDTO); 24 | 25 | @Select("select * from reader where id = #{id}") 26 | Reader getById(Integer id); 27 | 28 | void update(Reader reader); 29 | 30 | void deleteBatch(List ids); 31 | 32 | @Select("select count(id) from reader where category_id = #{id}") 33 | Integer sumByCategoryId(Integer id); 34 | } 35 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/BookCategoryService.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service; 2 | 3 | import fun.cyhgraph.dto.BookCatePageDTO; 4 | import fun.cyhgraph.dto.BookCategoryDTO; 5 | import fun.cyhgraph.entity.BookCategory; 6 | import fun.cyhgraph.result.PageResult; 7 | 8 | public interface BookCategoryService { 9 | void addCategory(BookCategoryDTO bookCategoryDTO); 10 | 11 | PageResult page(BookCatePageDTO bookCatePageDTO); 12 | 13 | BookCategory getById(Integer id); 14 | 15 | void update(BookCategoryDTO bookCategoryDTO); 16 | 17 | void deleteById(Integer id); 18 | } 19 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/BookService.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service; 2 | 3 | import fun.cyhgraph.dto.BookDTO; 4 | import fun.cyhgraph.dto.BookPageDTO; 5 | import fun.cyhgraph.entity.Book; 6 | import fun.cyhgraph.result.PageResult; 7 | 8 | import java.util.List; 9 | 10 | public interface BookService { 11 | void addBook(BookDTO bookDTO); 12 | 13 | PageResult page(BookPageDTO bookPageDTO); 14 | 15 | Book getById(Integer id); 16 | 17 | void update(BookDTO bookDTO); 18 | 19 | void deleteBatch(List ids); 20 | 21 | void status(Integer id); 22 | } 23 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/BorrowService.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service; 2 | 3 | import fun.cyhgraph.dto.LendReturnDTO; 4 | import fun.cyhgraph.dto.LendReturnPageDTO; 5 | import fun.cyhgraph.entity.LendReturn; 6 | import fun.cyhgraph.result.PageResult; 7 | 8 | import java.util.List; 9 | 10 | public interface BorrowService { 11 | void addBorrow(LendReturnDTO lendReturnDTO); 12 | 13 | PageResult page(LendReturnPageDTO lendReturnPageDTO); 14 | 15 | LendReturn getById(Integer id); 16 | 17 | void update(LendReturnDTO lendReturnDTO); 18 | 19 | void delete(List ids); 20 | } 21 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/ChartService.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service; 2 | 3 | import fun.cyhgraph.vo.BookCategoryVO; 4 | import fun.cyhgraph.vo.LendReturnReportVO; 5 | import fun.cyhgraph.vo.ReaderCategoryVo; 6 | import fun.cyhgraph.vo.TopVO; 7 | 8 | public interface ChartService { 9 | BookCategoryVO bookPie(); 10 | 11 | ReaderCategoryVo readerPie(); 12 | LendReturnReportVO dayNLend(Integer day); 13 | 14 | LendReturnReportVO dayNReturn(Integer day); 15 | 16 | TopVO bookTop(Integer day); 17 | 18 | TopVO readerTop(Integer day); 19 | } 20 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/ManagerService.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service; 2 | 3 | import fun.cyhgraph.dto.ManagerDTO; 4 | import fun.cyhgraph.dto.ManagerLoginDTO; 5 | import fun.cyhgraph.entity.Manager; 6 | 7 | public interface ManagerService { 8 | Manager getManagerById(Integer id); 9 | 10 | Manager login(ManagerLoginDTO managerLoginDTO); 11 | 12 | void register(ManagerLoginDTO managerLoginDTO); 13 | 14 | void update(ManagerDTO managerDTO); 15 | } 16 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/ReaderCategoryService.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service; 2 | 3 | import fun.cyhgraph.dto.ReaderCatePageDTO; 4 | import fun.cyhgraph.dto.ReaderCategoryDTO; 5 | import fun.cyhgraph.entity.ReaderCategory; 6 | import fun.cyhgraph.result.PageResult; 7 | 8 | public interface ReaderCategoryService { 9 | void addCategory(ReaderCategoryDTO readerCategoryDTO); 10 | 11 | PageResult page(ReaderCatePageDTO readerCatePageDTO); 12 | 13 | ReaderCategory getById(Integer id); 14 | 15 | void update(ReaderCategoryDTO readerCategoryDTO); 16 | 17 | void deleteById(Integer id); 18 | } 19 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/ReaderService.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service; 2 | 3 | import fun.cyhgraph.dto.ReaderDTO; 4 | import fun.cyhgraph.dto.ReaderPageDTO; 5 | import fun.cyhgraph.entity.Reader; 6 | import fun.cyhgraph.result.PageResult; 7 | 8 | import java.util.List; 9 | 10 | public interface ReaderService { 11 | void addReader(ReaderDTO readerDTO); 12 | 13 | PageResult page(ReaderPageDTO readerPageDTO); 14 | 15 | Reader getById(Integer id); 16 | 17 | void update(ReaderDTO readerDTO); 18 | 19 | void deleteBatch(List ids); 20 | } 21 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/serviceImpl/BookCategoryServiceImpl.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service.serviceImpl; 2 | 3 | import com.github.pagehelper.Page; 4 | import com.github.pagehelper.PageHelper; 5 | import fun.cyhgraph.dto.BookCatePageDTO; 6 | import fun.cyhgraph.dto.BookCategoryDTO; 7 | import fun.cyhgraph.entity.BookCategory; 8 | import fun.cyhgraph.mapper.BookCategoryMapper; 9 | import fun.cyhgraph.result.PageResult; 10 | import fun.cyhgraph.service.BookCategoryService; 11 | import org.springframework.beans.BeanUtils; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Service; 14 | 15 | @Service 16 | public class BookCategoryServiceImpl implements BookCategoryService { 17 | 18 | @Autowired 19 | private BookCategoryMapper bookCategoryMapper; 20 | 21 | /** 22 | * 添加书籍分类 23 | * @param bookCategoryDTO 24 | */ 25 | public void addCategory(BookCategoryDTO bookCategoryDTO) { 26 | BookCategory bookCategory = new BookCategory(); 27 | BeanUtils.copyProperties(bookCategoryDTO, bookCategory); 28 | bookCategoryMapper.insert(bookCategory); 29 | } 30 | 31 | /** 32 | * 书籍分类分页查询 33 | * @param bookCatePageDTO 34 | * @return 35 | */ 36 | public PageResult page(BookCatePageDTO bookCatePageDTO) { 37 | PageHelper.startPage(bookCatePageDTO.getPage(), bookCatePageDTO.getPageSize()); 38 | Page bookCategories = bookCategoryMapper.page(bookCatePageDTO); 39 | return new PageResult(bookCategories.getTotal(), bookCategories.getResult()); 40 | } 41 | 42 | /** 43 | * 根据id查询书籍分类 44 | * @param id 45 | * @return 46 | */ 47 | public BookCategory getById(Integer id) { 48 | return bookCategoryMapper.getById(id); 49 | } 50 | 51 | /** 52 | * 修改书籍分类 53 | * @param bookCategoryDTO 54 | */ 55 | public void update(BookCategoryDTO bookCategoryDTO) { 56 | BookCategory bookCategory = new BookCategory(); 57 | BeanUtils.copyProperties(bookCategoryDTO, bookCategory); 58 | bookCategoryMapper.update(bookCategory); 59 | } 60 | 61 | /** 62 | * 根据id删除书籍分类 63 | * @param id 64 | */ 65 | public void deleteById(Integer id) { 66 | bookCategoryMapper.deleteById(id); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/serviceImpl/BookServiceImpl.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service.serviceImpl; 2 | 3 | import com.github.pagehelper.Page; 4 | import com.github.pagehelper.PageHelper; 5 | import fun.cyhgraph.dto.BookDTO; 6 | import fun.cyhgraph.dto.BookPageDTO; 7 | import fun.cyhgraph.entity.Book; 8 | import fun.cyhgraph.mapper.BookMapper; 9 | import fun.cyhgraph.result.PageResult; 10 | import fun.cyhgraph.service.BookService; 11 | import org.springframework.beans.BeanUtils; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Service; 14 | 15 | import java.util.List; 16 | 17 | @Service 18 | public class BookServiceImpl implements BookService { 19 | 20 | @Autowired 21 | private BookMapper bookMapper; 22 | 23 | /** 24 | * 新增书籍 25 | * @param bookDTO 26 | */ 27 | public void addBook(BookDTO bookDTO) { 28 | Book book = new Book(); 29 | BeanUtils.copyProperties(bookDTO, book); 30 | book.setStatus(0); // 刚开始添加,书还没被借出 31 | bookMapper.insert(book); 32 | } 33 | 34 | /** 35 | * 条件书籍分页查询 36 | * @param bookPageDTO 37 | * @return 38 | */ 39 | public PageResult page(BookPageDTO bookPageDTO) { 40 | PageHelper.startPage(bookPageDTO.getPage(), bookPageDTO.getPageSize()); 41 | Page bookPage = bookMapper.page(bookPageDTO); 42 | return new PageResult(bookPage.getTotal(), bookPage.getResult()); 43 | } 44 | 45 | /** 46 | * 根据id查询书籍 47 | * @param id 48 | * @return 49 | */ 50 | public Book getById(Integer id) { 51 | return bookMapper.getById(id); 52 | } 53 | 54 | /** 55 | * 修改书籍信息 56 | * @param bookDTO 57 | */ 58 | public void update(BookDTO bookDTO) { 59 | Book book = new Book(); 60 | BeanUtils.copyProperties(bookDTO, book); 61 | bookMapper.update(book); 62 | } 63 | 64 | /** 65 | * 根据id修改书籍状态 66 | * @param id 67 | */ 68 | public void status(Integer id) { 69 | bookMapper.status(id); 70 | } 71 | 72 | /** 73 | * 批量删除书籍 74 | * @param ids 75 | */ 76 | public void deleteBatch(List ids) { 77 | bookMapper.deleteBatch(ids); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/serviceImpl/BorrowServiceImpl.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service.serviceImpl; 2 | 3 | import com.github.pagehelper.Page; 4 | import com.github.pagehelper.PageHelper; 5 | import fun.cyhgraph.constant.MessageConstant; 6 | import fun.cyhgraph.dto.LendReturnDTO; 7 | import fun.cyhgraph.dto.LendReturnPageDTO; 8 | import fun.cyhgraph.entity.Book; 9 | import fun.cyhgraph.entity.LendReturn; 10 | import fun.cyhgraph.entity.Reader; 11 | import fun.cyhgraph.entity.ReaderCategory; 12 | import fun.cyhgraph.exception.BorrowMaxException; 13 | import fun.cyhgraph.exception.BorrowTooLongException; 14 | import fun.cyhgraph.mapper.BookMapper; 15 | import fun.cyhgraph.mapper.BorrowMapper; 16 | import fun.cyhgraph.mapper.ReaderCategoryMapper; 17 | import fun.cyhgraph.mapper.ReaderMapper; 18 | import fun.cyhgraph.result.PageResult; 19 | import fun.cyhgraph.service.BorrowService; 20 | import lombok.extern.slf4j.Slf4j; 21 | import org.springframework.beans.BeanUtils; 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.stereotype.Service; 24 | 25 | import java.time.temporal.ChronoUnit; 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | @Service 30 | @Slf4j 31 | public class BorrowServiceImpl implements BorrowService { 32 | 33 | 34 | @Autowired 35 | private BorrowMapper borrowMapper; 36 | @Autowired 37 | private BookMapper bookMapper; 38 | @Autowired 39 | private ReaderCategoryMapper readerCategoryMapper; 40 | @Autowired 41 | private ReaderMapper readerMapper; 42 | 43 | /** 44 | * 新增借还书记录 45 | * 46 | * @param lendReturnDTO 47 | */ 48 | public void addBorrow(LendReturnDTO lendReturnDTO) { 49 | LendReturn lendReturn = new LendReturn(); 50 | BeanUtils.copyProperties(lendReturnDTO, lendReturn); 51 | Reader reader = readerMapper.getById(lendReturn.getRId()); 52 | // 读者种类 53 | ReaderCategory readerCategory = readerCategoryMapper.getById(reader.getCategoryId()); 54 | // 1、如果超过借书有效期,要抛异常 55 | if (lendReturn.getLendDate().isAfter(readerCategory.getEffectPeriod())){ 56 | throw new BorrowTooLongException(MessageConstant.BORROW_OUT_OF_EFFECT_PERIOD); 57 | } 58 | // 2、借书前要看当前借书人可借数量有没有达到上限,达到就抛异常给前端 59 | // 2.1 拿到这个读者当前已借但未还的书本数 return_date = null || return_date > 当前书本的lend_date 60 | Integer amount = borrowMapper.getReaderHad(lendReturn); 61 | log.info("--------------------拿到这个读者当前已借但未还的书本数:{}", amount); 62 | // 2.2 拿到当前读者的categoryId,并查询这种读者可借书本上限 63 | Integer maxBooks = readerCategory.getAmount(); 64 | log.info("--------------------查询这种读者可借书本上限:{}", maxBooks); 65 | // 2.3 比较,达到就抛异常,表示已达上限 66 | if (amount >= maxBooks) { 67 | throw new BorrowMaxException(MessageConstant.BORROW_MAX); 68 | } 69 | // 3、借书需要将对应书籍的状态设置为1,表示已借出 70 | // 3.1 先获取对应借出的书籍 71 | Integer bId = lendReturn.getBId(); 72 | Book book = bookMapper.getById(bId); 73 | // 3.2 更新状态为1 74 | book.setStatus(1); 75 | bookMapper.update(book); 76 | // 3.4 插入借还书记录 77 | borrowMapper.insert(lendReturn); 78 | } 79 | 80 | /** 81 | * 分页查询借还书记录 82 | * 83 | * @return 84 | */ 85 | public PageResult page(LendReturnPageDTO lendReturnPageDTO) { 86 | PageHelper.startPage(lendReturnPageDTO.getPage(), lendReturnPageDTO.getPageSize()); 87 | Page lendReturnPage = borrowMapper.page(lendReturnPageDTO); 88 | return new PageResult(lendReturnPage.getTotal(), lendReturnPage.getResult()); 89 | } 90 | 91 | /** 92 | * 根据2个id查询借还书记录 93 | * 94 | * @param id 95 | * @return 96 | */ 97 | public LendReturn getById(Integer id) { 98 | return borrowMapper.getById(id); 99 | } 100 | 101 | /** 102 | * 修改借还书记录(还书操作) 103 | * 104 | * @param lendReturnDTO 105 | */ 106 | public void update(LendReturnDTO lendReturnDTO) { 107 | LendReturn lendReturn = new LendReturn(); 108 | BeanUtils.copyProperties(lendReturnDTO, lendReturn); 109 | // 1、还书前要看读者借书时长是否过长 110 | Reader reader = readerMapper.getById(lendReturn.getRId()); 111 | // 读者种类 112 | ReaderCategory readerCategory = readerCategoryMapper.getById(reader.getCategoryId()); 113 | // 1.1 拿到当前种类读者最大可借天数 114 | Integer maxDays = readerCategory.getLendPeriod(); 115 | // 1.2 还书日期 - 借书日期,看看借书天数(没设置还书日期就不用判断) 2:逾期归还不用判断 116 | if (lendReturn.getReturnDate() != null && lendReturn.getStatus() != 2) { 117 | long lendDays = ChronoUnit.DAYS.between(lendReturn.getLendDate(), lendReturn.getReturnDate()); 118 | // 1.3 比较,违反就抛异常(如果超过借书有效期,那也要抛异常) 119 | log.info("借书天数{}", lendDays); 120 | log.info("最大借书天数{}", maxDays); 121 | if (lendDays >= maxDays) { 122 | throw new BorrowTooLongException(MessageConstant.BORROW_TOO_LONG); 123 | } else if (lendReturn.getReturnDate().isAfter(readerCategory.getEffectPeriod())){ 124 | throw new BorrowTooLongException(MessageConstant.BORROW_OUT_OF_EFFECT_PERIOD); 125 | } 126 | } 127 | // 先根据这条记录查到对应的书籍信息 128 | Book book = bookMapper.getById(lendReturnDTO.getBId()); 129 | log.info("书籍归还状态:{}", lendReturnDTO.getStatus()); 130 | if (lendReturnDTO.getStatus() == 1 || lendReturnDTO.getStatus() == 4) { 131 | // 可以归还,对应书籍的status设为0 132 | book.setStatus(0); 133 | } else { 134 | // 没有归还,对应书籍的status设为1 135 | book.setStatus(1); 136 | } 137 | // 更新书籍状态和借书记录 138 | bookMapper.update(book); 139 | borrowMapper.update(lendReturn); 140 | } 141 | 142 | /** 143 | * 批量删除异常借还书记录 144 | * 145 | * @param ids 146 | */ 147 | public void delete(List ids) { 148 | // 拿到这些记录对应的书籍记录,储存这些bId 149 | List bIds = new ArrayList<>(); 150 | for (Integer id : ids) { 151 | Integer bId = borrowMapper.getById(id).getBId(); 152 | bIds.add(bId); 153 | } 154 | // 再批量删除记录还有书籍 155 | borrowMapper.deleteBatch(ids); 156 | bookMapper.deleteBatch(bIds); 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/serviceImpl/ChartServiceImpl.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service.serviceImpl; 2 | 3 | import fun.cyhgraph.entity.TopInfo; 4 | import fun.cyhgraph.mapper.*; 5 | import fun.cyhgraph.service.ChartService; 6 | import fun.cyhgraph.vo.BookCategoryVO; 7 | import fun.cyhgraph.vo.LendReturnReportVO; 8 | import fun.cyhgraph.vo.ReaderCategoryVo; 9 | import fun.cyhgraph.vo.TopVO; 10 | import lombok.extern.slf4j.Slf4j; 11 | import net.sf.jsqlparser.statement.select.Top; 12 | import org.apache.commons.lang.StringUtils; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Service; 15 | 16 | import java.time.LocalDate; 17 | import java.util.ArrayList; 18 | import java.util.Comparator; 19 | import java.util.List; 20 | import java.util.stream.Collectors; 21 | 22 | @Service 23 | @Slf4j 24 | public class ChartServiceImpl implements ChartService { 25 | 26 | @Autowired 27 | private ChartMapper chartMapper; 28 | @Autowired 29 | private BookCategoryMapper bookCategoryMapper; 30 | @Autowired 31 | private BookMapper bookMapper; 32 | @Autowired 33 | private ReaderCategoryMapper readerCategoryMapper; 34 | @Autowired 35 | private ReaderMapper readerMapper; 36 | @Autowired 37 | private BorrowMapper borrowMapper; 38 | 39 | 40 | /** 41 | * 获取不同分类下书籍数量 42 | * 43 | * @return 44 | */ 45 | public BookCategoryVO bookPie() { 46 | List names = bookCategoryMapper.getNames(); 47 | List ids = bookCategoryMapper.getIds(); 48 | List bookNumList = new ArrayList<>(); 49 | for (Integer id : ids) { 50 | Integer amount = bookMapper.sumByCategoryId(id); 51 | amount = amount == null ? 0 : amount; 52 | bookNumList.add(amount); 53 | } 54 | return BookCategoryVO.builder() 55 | .bookCategoryNames(StringUtils.join(names,",")) 56 | .bookCategoryNums(StringUtils.join(bookNumList, ",")) 57 | .build(); 58 | } 59 | 60 | /** 61 | * 获取不同分类下读者数量 62 | * @return 63 | */ 64 | public ReaderCategoryVo readerPie() { 65 | List names = readerCategoryMapper.getNames(); 66 | List ids = readerCategoryMapper.getIds(); 67 | List readerNumList = new ArrayList<>(); 68 | for (Integer id : ids) { 69 | Integer amount = readerMapper.sumByCategoryId(id); 70 | amount = amount == null ? 0 : amount; 71 | readerNumList.add(amount); 72 | } 73 | return ReaderCategoryVo.builder() 74 | .readerCategoryNames(StringUtils.join(names,",")) 75 | .readerCategoryNums(StringUtils.join(readerNumList, ",")) 76 | .build(); 77 | } 78 | 79 | /** 80 | * 近n天借书数据 81 | * 82 | * @param day 83 | */ 84 | public LendReturnReportVO dayNLend(Integer day) { 85 | LocalDate end = LocalDate.now(); 86 | // 前n-1天 + 今天 = day天 87 | LocalDate begin = LocalDate.now().minusDays(day - 1); 88 | List dateList = new ArrayList<>(); 89 | dateList.add(begin); 90 | while (!begin.equals(end)) { 91 | begin = begin.plusDays(1); // 日期计算,获得指定日期后1天的日期 92 | dateList.add(begin); 93 | } 94 | List lendList = new ArrayList<>(); 95 | for (LocalDate date : dateList) { 96 | Integer amount = chartMapper.sumByLendDate(date); 97 | // 当天没有记录要补0,不能传null/空字符串给前端! 98 | amount = amount == null ? 0 : amount; 99 | lendList.add(amount); 100 | } 101 | return LendReturnReportVO.builder() 102 | .dateList(StringUtils.join(dateList, ",")) 103 | .lendOrReturnList(StringUtils.join(lendList, ",")) 104 | .build(); 105 | } 106 | 107 | /** 108 | * 近n天还书数据 109 | * 110 | * @param day 111 | * @return 112 | */ 113 | public LendReturnReportVO dayNReturn(Integer day) { 114 | LocalDate end = LocalDate.now(); 115 | // 前n-1天 + 今天 = day天 116 | LocalDate begin = LocalDate.now().minusDays(day - 1); 117 | List dateList = new ArrayList<>(); 118 | dateList.add(begin); 119 | while (!begin.equals(end)) { 120 | begin = begin.plusDays(1); // 日期计算,获得指定日期后1天的日期 121 | dateList.add(begin); 122 | } 123 | List returnList = new ArrayList<>(); 124 | for (LocalDate date : dateList) { 125 | Integer amount = chartMapper.sumByReturnDate(date); 126 | // 当天没有记录要补0,不能传null/空字符串给前端! 127 | amount = amount == null ? 0 : amount; 128 | returnList.add(amount); 129 | } 130 | return LendReturnReportVO.builder() 131 | .dateList(StringUtils.join(dateList, ",")) 132 | .lendOrReturnList(StringUtils.join(returnList, ",")) 133 | .build(); 134 | } 135 | 136 | /** 137 | * 查询近day天的书本销量 138 | * @param day 139 | * @return 140 | */ 141 | public TopVO bookTop(Integer day) { 142 | LocalDate end = LocalDate.now(); 143 | LocalDate begin = LocalDate.now().minusDays(day - 1); 144 | // 在lendReturn表中,查询到 begin - end 这段时间内的所有借阅记录 145 | List bIds = borrowMapper.getBIdsByDate(begin); 146 | // 拿到这些id对应的书名,以及借书数量(用对象数组,方便后续top7处理) 147 | // 创建一个列表来保存读者信息 148 | List bookInfoList = new ArrayList<>(); 149 | // List bookNames = new ArrayList<>(); 150 | // List topList = new ArrayList<>(); 151 | for (Integer bId : bIds){ 152 | String name = bookMapper.getById(bId).getName(); 153 | Integer amount = borrowMapper.getBookAmount(begin, bId); 154 | bookInfoList.add(new TopInfo(name, amount)); 155 | // bookNames.add(name); 156 | // topList.add(amount); 157 | } 158 | // 根据 书被借的次数amount 对书籍信息列表进行降序排序 159 | bookInfoList.sort(Comparator.comparingInt(TopInfo::getAmount).reversed()); 160 | // 选取前7个元素 161 | List topBookNames = bookInfoList.stream().limit(7).map(TopInfo::getName).collect(Collectors.toList()); 162 | List topAmounts = bookInfoList.stream().limit(7).map(TopInfo::getAmount).collect(Collectors.toList()); 163 | 164 | // 封装成VO返回 165 | TopVO topVO = TopVO.builder() 166 | .nameList(StringUtils.join(topBookNames,",")) 167 | .topList(StringUtils.join(topAmounts, ",")) 168 | .build(); 169 | return topVO; 170 | } 171 | 172 | /** 173 | * 查询近day天的读者借书排行榜 174 | * @param day 175 | * @return 176 | */ 177 | public TopVO readerTop(Integer day) { 178 | LocalDate end = LocalDate.now(); 179 | LocalDate begin = LocalDate.now().minusDays(day - 1); 180 | // 在lendReturn表中,查询到 begin - end 这段时间内的所有借阅记录 181 | List rIds = borrowMapper.getRIdsByDate(begin); 182 | log.info("有没有去重!!!" + rIds); 183 | // 拿到这些id对应的书名,以及借书数量 184 | // 创建一个列表来保存读者信息 185 | List readerInfoList = new ArrayList<>(); 186 | for (Integer rId : rIds){ 187 | String name = readerMapper.getById(rId).getName(); 188 | Integer amount = borrowMapper.getReaderAmount(begin, rId); 189 | readerInfoList.add(new TopInfo(name, amount)); 190 | } 191 | // 根据 借书数量amount 对读者信息列表进行降序排序 192 | readerInfoList.sort(Comparator.comparingInt(TopInfo::getAmount).reversed()); 193 | // 选取前7个元素 194 | List topReaderNames = readerInfoList.stream().limit(7).map(TopInfo::getName).collect(Collectors.toList()); 195 | List topAmounts = readerInfoList.stream().limit(7).map(TopInfo::getAmount).collect(Collectors.toList()); 196 | 197 | // 封装成VO返回 198 | TopVO topVO = TopVO.builder() 199 | .nameList(StringUtils.join(topReaderNames,",")) 200 | .topList(StringUtils.join(topAmounts, ",")) 201 | .build(); 202 | return topVO; 203 | } 204 | 205 | } 206 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/serviceImpl/ManagerServiceImpl.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service.serviceImpl; 2 | 3 | import fun.cyhgraph.constant.MessageConstant; 4 | import fun.cyhgraph.context.BaseContext; 5 | import fun.cyhgraph.dto.ManagerDTO; 6 | import fun.cyhgraph.dto.ManagerLoginDTO; 7 | import fun.cyhgraph.entity.Manager; 8 | import fun.cyhgraph.exception.PasswordErrorException; 9 | import fun.cyhgraph.exception.ManagerNotFoundException; 10 | import fun.cyhgraph.mapper.ManagerMapper; 11 | import fun.cyhgraph.service.ManagerService; 12 | import org.springframework.beans.BeanUtils; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Service; 15 | import org.springframework.util.DigestUtils; 16 | 17 | @Service 18 | public class ManagerServiceImpl implements ManagerService { 19 | 20 | @Autowired 21 | private ManagerMapper managerMapper; 22 | 23 | /** 24 | * 根据id获取用户信息 25 | * @return 26 | */ 27 | public Manager getManagerById(Integer id) { 28 | Manager manager = managerMapper.getById(id); 29 | return manager; 30 | } 31 | 32 | /** 33 | * 用户登录 34 | * @param managerLoginDTO 35 | * @return 36 | */ 37 | public Manager login(ManagerLoginDTO managerLoginDTO) { 38 | String name = managerLoginDTO.getName(); 39 | String password = managerLoginDTO.getPassword(); 40 | // 先查数据库,看是否存在该账号 41 | Manager manager = managerMapper.getByName(name); 42 | if (manager == null){ 43 | throw new ManagerNotFoundException(MessageConstant.MANAGER_NOT_FOUND); 44 | } 45 | // 再将前端传过来的密码进行MD5加密 46 | password = DigestUtils.md5DigestAsHex(password.getBytes()); 47 | // 和之前存进数据库的加密的密码进行比对,看看是否一样,不一样要抛异常 48 | if (!password.equals(manager.getPassword())){ 49 | throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR); 50 | } 51 | return manager; 52 | } 53 | 54 | /** 55 | * 注册/新增用户 56 | */ 57 | public void register(ManagerLoginDTO managerLoginDTO) { 58 | // 先对用户的密码进行MD5加密,再存到数据库中 59 | String password = managerLoginDTO.getPassword(); 60 | password = DigestUtils.md5DigestAsHex(password.getBytes()); 61 | managerLoginDTO.setPassword(password); 62 | 63 | Manager manager = new Manager(); 64 | // 将userLoginDTO的属性拷贝到user中 65 | BeanUtils.copyProperties(managerLoginDTO, manager); 66 | managerMapper.addManager(manager); 67 | } 68 | 69 | /** 70 | * 修改管理员信息 71 | * @param managerDTO 72 | */ 73 | public void update(ManagerDTO managerDTO) { 74 | String oldPwd = managerDTO.getOldPwd(); 75 | // 将前端传过来的旧密码进行MD5加密 76 | oldPwd = DigestUtils.md5DigestAsHex(oldPwd.getBytes()); 77 | // 根据id查询当前账号信息 78 | Integer id = BaseContext.getCurrentId(); 79 | Manager manager = managerMapper.getById(id); 80 | // 和之前存进数据库的加密的密码进行比对,看看是否一样,不一样要抛异常 81 | if (!oldPwd.equals(manager.getPassword())){ 82 | throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR); 83 | } 84 | // 旧密码正确,将用户名修改,新密码加密后,进行更新 85 | manager.setName(managerDTO.getName()); 86 | String newPwd = managerDTO.getNewPwd(); 87 | String password = DigestUtils.md5DigestAsHex(newPwd.getBytes()); 88 | manager.setPassword(password); 89 | managerMapper.update(manager); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/serviceImpl/ReaderCategoryServiceImpl.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service.serviceImpl; 2 | 3 | import com.github.pagehelper.Page; 4 | import com.github.pagehelper.PageHelper; 5 | import fun.cyhgraph.dto.ReaderCatePageDTO; 6 | import fun.cyhgraph.dto.ReaderCategoryDTO; 7 | import fun.cyhgraph.entity.ReaderCategory; 8 | import fun.cyhgraph.mapper.ReaderCategoryMapper; 9 | import fun.cyhgraph.result.PageResult; 10 | import fun.cyhgraph.result.Result; 11 | import fun.cyhgraph.service.ReaderCategoryService; 12 | import org.springframework.beans.BeanUtils; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Service; 15 | import org.springframework.web.bind.annotation.PostMapping; 16 | import org.springframework.web.bind.annotation.RequestBody; 17 | 18 | @Service 19 | public class ReaderCategoryServiceImpl implements ReaderCategoryService { 20 | 21 | @Autowired 22 | private ReaderCategoryMapper readerCategoryMapper; 23 | 24 | /** 25 | * 添加读者分类 26 | * @param readerCategoryDTO 27 | */ 28 | public void addCategory(ReaderCategoryDTO readerCategoryDTO) { 29 | ReaderCategory readerCategory = new ReaderCategory(); 30 | BeanUtils.copyProperties(readerCategoryDTO, readerCategory); 31 | readerCategoryMapper.insert(readerCategory); 32 | } 33 | 34 | /** 35 | * 读者种类分页查询 36 | * @param readerCatePageDTO 37 | * @return 38 | */ 39 | public PageResult page(ReaderCatePageDTO readerCatePageDTO) { 40 | PageHelper.startPage(readerCatePageDTO.getPage(), readerCatePageDTO.getPageSize()); 41 | Page readerCategories = readerCategoryMapper.page(readerCatePageDTO); 42 | return new PageResult(readerCategories.getTotal(), readerCategories.getResult()); 43 | } 44 | 45 | /** 46 | * 根据id查询读者 47 | * @param id 48 | * @return 49 | */ 50 | public ReaderCategory getById(Integer id) { 51 | return readerCategoryMapper.getById(id); 52 | } 53 | 54 | /** 55 | * 修改读者分类 56 | * @param readerCategoryDTO 57 | */ 58 | public void update(ReaderCategoryDTO readerCategoryDTO) { 59 | ReaderCategory readerCategory = new ReaderCategory(); 60 | BeanUtils.copyProperties(readerCategoryDTO, readerCategory); 61 | readerCategoryMapper.update(readerCategory); 62 | } 63 | 64 | /** 65 | * 根据id删除读者分类 66 | * @param id 67 | */ 68 | public void deleteById(Integer id) { 69 | readerCategoryMapper.deleteById(id); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /library-behind/server/src/main/java/fun/cyhgraph/service/serviceImpl/ReaderServiceImpl.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.service.serviceImpl; 2 | 3 | import com.github.pagehelper.Page; 4 | import com.github.pagehelper.PageHelper; 5 | import fun.cyhgraph.dto.ReaderDTO; 6 | import fun.cyhgraph.dto.ReaderPageDTO; 7 | import fun.cyhgraph.entity.Reader; 8 | import fun.cyhgraph.mapper.ReaderMapper; 9 | import fun.cyhgraph.result.PageResult; 10 | import fun.cyhgraph.service.ReaderService; 11 | import org.springframework.beans.BeanUtils; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Service; 14 | 15 | import java.util.List; 16 | 17 | @Service 18 | public class ReaderServiceImpl implements ReaderService { 19 | 20 | @Autowired 21 | private ReaderMapper readerMapper; 22 | 23 | /** 24 | * 新增读者 25 | * @param readerDTO 26 | */ 27 | public void addReader(ReaderDTO readerDTO) { 28 | Reader reader = new Reader(); 29 | BeanUtils.copyProperties(readerDTO, reader); 30 | readerMapper.insert(reader); 31 | } 32 | 33 | /** 34 | * 条件分页查询读者 35 | * @param readerPageDTO 36 | * @return 37 | */ 38 | public PageResult page(ReaderPageDTO readerPageDTO) { 39 | PageHelper.startPage(readerPageDTO.getPage(), readerPageDTO.getPageSize()); 40 | Page readerPage = readerMapper.page(readerPageDTO); 41 | return new PageResult(readerPage.getTotal(), readerPage.getResult()); 42 | } 43 | 44 | /** 45 | * 根据id查询读者 46 | * @param id 47 | * @return 48 | */ 49 | public Reader getById(Integer id) { 50 | return readerMapper.getById(id); 51 | } 52 | 53 | /** 54 | * 更新读者信息 55 | * @param readerDTO 56 | */ 57 | public void update(ReaderDTO readerDTO) { 58 | Reader reader = new Reader(); 59 | BeanUtils.copyProperties(readerDTO, reader); 60 | readerMapper.update(reader); 61 | } 62 | 63 | /** 64 | * 批量删除读者 65 | * @param ids 66 | */ 67 | public void deleteBatch(List ids) { 68 | readerMapper.deleteBatch(ids); 69 | } 70 | 71 | 72 | } -------------------------------------------------------------------------------- /library-behind/server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | 4 | spring: 5 | datasource: 6 | driver-class-name: com.mysql.cj.jdbc.Driver 7 | url: jdbc:mysql://localhost:3306/library 8 | username: root 9 | password: 20040111 10 | 11 | # mybatis 12 | mybatis: 13 | mapper-locations: classpath:mapper/*.xml 14 | type-aliases-package: com.example.entity 15 | configuration: 16 | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 17 | map-underscore-to-camel-case: true 18 | 19 | login-reg: 20 | jwt: 21 | manager-secret-key: cyh_yty 22 | manager-ttl: 864000000 23 | manager-token-name: Authorization 24 | -------------------------------------------------------------------------------- /library-behind/server/src/main/resources/mapper/BookCategoryMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 17 | 18 | 19 | update b_category 20 | 21 | name = #{name}, 22 | keywords = #{keywords}, 23 | notes = #{notes} 24 | 25 | where id = #{id} 26 | 27 | -------------------------------------------------------------------------------- /library-behind/server/src/main/resources/mapper/BookMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | delete from book where id in 7 | 8 | #{id} 9 | 10 | 11 | 12 | 26 | 27 | 28 | update book 29 | 30 | name = #{name}, 31 | author = #{author}, 32 | press = #{press}, 33 | publish_date = #{publishDate}, 34 | price = #{price}, 35 | page_number = #{pageNumber}, 36 | keywords = #{keywords}, 37 | status = #{status}, 38 | notes = #{notes}, 39 | category_id = #{categoryId} 40 | 41 | where id = #{id} 42 | 43 | -------------------------------------------------------------------------------- /library-behind/server/src/main/resources/mapper/BorrowMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 20 | 21 | 27 | 28 | 35 | 36 | 42 | 43 | 50 | 51 | 60 | 61 | 62 | update lend_return 63 | 64 | r_id = #{rId}, 65 | b_id = #{bId}, 66 | lend_date = #{lendDate}, 67 | return_date = #{returnDate}, 68 | status = #{status}, 69 | notes = #{notes} 70 | 71 | where id = #{id} 72 | 73 | 74 | 75 | delete from lend_return where id in 76 | 77 | #{id} 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /library-behind/server/src/main/resources/mapper/ReaderCategoryMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 14 | 15 | 16 | update r_category 17 | 18 | name = #{name}, 19 | amount = #{amount}, 20 | lend_period = #{lendPeriod}, 21 | effect_period = #{effectPeriod}, 22 | notes = #{notes} 23 | 24 | where id = #{id} 25 | 26 | -------------------------------------------------------------------------------- /library-behind/server/src/main/resources/mapper/ReaderMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 17 | 18 | 19 | update reader 20 | 21 | name = #{name}, 22 | sex = #{sex}, 23 | w_address = #{wAddress}, 24 | h_address = #{hAddress}, 25 | phone = #{phone}, 26 | email = #{email}, 27 | notes = #{notes}, 28 | category_id = #{categoryId} 29 | 30 | where id = #{id} 31 | 32 | 33 | 34 | delete from reader where id in 35 | 36 | #{id} 37 | 38 | 39 | -------------------------------------------------------------------------------- /library-behind/server/src/test/java/fun/cyhgraph/server/ServerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package fun.cyhgraph.server; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class ServerApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /library-front/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | require('@rushstack/eslint-patch/modern-module-resolution') 3 | 4 | module.exports = { 5 | root: true, 6 | 'extends': [ 7 | 'plugin:vue/vue3-essential', 8 | 'eslint:recommended', 9 | '@vue/eslint-config-typescript', 10 | '@vue/eslint-config-prettier/skip-formatting' 11 | ], 12 | parserOptions: { 13 | ecmaVersion: 'latest' 14 | }, 15 | rules: { 16 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 17 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 18 | 'vue/no-multiple-template-root': 'off', // 允许template下有多个根标签 19 | 'vue/multi-word-component-names': 'off', // 关闭名称校验 20 | 'camelcase': 'off' // 关闭驼峰命名校验 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /library-front/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | *.tsbuildinfo 31 | -------------------------------------------------------------------------------- /library-front/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/prettierrc", 3 | "semi": false, 4 | "tabWidth": 2, 5 | "singleQuote": true, 6 | "printWidth": 100, 7 | "trailingComma": "none" 8 | } -------------------------------------------------------------------------------- /library-front/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Vue.volar", 4 | "dbaeumer.vscode-eslint", 5 | "esbenp.prettier-vscode" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /library-front/README.md: -------------------------------------------------------------------------------- 1 | # class-library 2 | 3 | This template should help get you started developing with Vue 3 in Vite. 4 | 5 | ## Recommended IDE Setup 6 | 7 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). 8 | 9 | ## Type Support for `.vue` Imports in TS 10 | 11 | TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types. 12 | 13 | ## Customize configuration 14 | 15 | See [Vite Configuration Reference](https://vitejs.dev/config/). 16 | 17 | ## Project Setup 18 | 19 | ```sh 20 | npm install 21 | ``` 22 | 23 | ### Compile and Hot-Reload for Development 24 | 25 | ```sh 26 | npm run dev 27 | ``` 28 | 29 | ### Type-Check, Compile and Minify for Production 30 | 31 | ```sh 32 | npm run build 33 | ``` 34 | 35 | ### Lint with [ESLint](https://eslint.org/) 36 | 37 | ```sh 38 | npm run lint 39 | ``` 40 | -------------------------------------------------------------------------------- /library-front/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /library-front/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /library-front/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "class-library", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "run-p type-check \"build-only {@}\" --", 9 | "preview": "vite preview", 10 | "build-only": "vite build", 11 | "type-check": "vue-tsc --build --force", 12 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", 13 | "format": "prettier --write src/" 14 | }, 15 | "dependencies": { 16 | "axios": "^1.6.8", 17 | "echarts": "^5.5.0", 18 | "element-plus": "^2.6.3", 19 | "less": "^4.2.0", 20 | "pinia": "^2.1.7", 21 | "pinia-plugin-persistedstate": "^3.2.1", 22 | "vue": "^3.4.21", 23 | "vue-router": "^4.3.0" 24 | }, 25 | "devDependencies": { 26 | "@rushstack/eslint-patch": "^1.3.3", 27 | "@tsconfig/node20": "^20.1.2", 28 | "@types/node": "^20.11.28", 29 | "@vitejs/plugin-vue": "^5.0.4", 30 | "@vue/eslint-config-prettier": "^8.0.0", 31 | "@vue/eslint-config-typescript": "^12.0.0", 32 | "@vue/tsconfig": "^0.5.1", 33 | "eslint": "^8.49.0", 34 | "eslint-plugin-vue": "^9.17.0", 35 | "npm-run-all2": "^6.1.2", 36 | "prettier": "^3.0.3", 37 | "typescript": "~5.4.0", 38 | "vite": "^5.1.6", 39 | "vue-tsc": "^2.0.6" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /library-front/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/library-front/public/favicon.ico -------------------------------------------------------------------------------- /library-front/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /library-front/src/api/book.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | /** 4 | * 分页获取所有书籍数据 5 | * @param params 分页查询的条件 6 | * @returns 7 | */ 8 | export const getBookPageAPI = (params: any) => { 9 | console.log('根据该条件获取分页书籍列表API', params) 10 | console.log(params) 11 | return request({ 12 | url: '/book/page', 13 | method: 'get', 14 | params 15 | }) 16 | } 17 | 18 | /** 19 | * 新增书籍 20 | * @param params 21 | * @returns 22 | */ 23 | export const addBookAPI = (params: any) => { 24 | console.log('新增书籍API', params) 25 | return request({ 26 | url: '/book', 27 | method: 'post', 28 | data: params 29 | }) 30 | } 31 | 32 | /** 33 | * 根据id获取书籍信息 34 | * @param id 35 | * @returns 36 | */ 37 | export const getBookByIdAPI = (id: number) => { 38 | return request({ 39 | url: `/book/${id}`, 40 | method: 'get', 41 | }) 42 | } 43 | 44 | /** 45 | * 更新书籍信息 46 | * @param params 47 | * @returns 48 | */ 49 | export const updateBookAPI = (params: any) => { 50 | console.log(params) 51 | console.log({ ...params }) 52 | return request({ 53 | url: '/book', 54 | method: 'put', 55 | data: { ...params } 56 | }) 57 | } 58 | 59 | /** 60 | * 更新书籍状态 61 | * @param params 62 | * @returns 63 | */ 64 | export const updateBookStatusAPI = (id: number) => { 65 | return request({ 66 | url: `/book/status/${id}`, 67 | method: 'put', 68 | }) 69 | } 70 | 71 | /** 72 | * 根据ids批量删除书籍信息 73 | * @param id 74 | * @returns 75 | */ 76 | export const deleteBooksAPI = (ids: string) => { 77 | return request({ 78 | url: '/book', 79 | method: 'delete', 80 | params: { ids } 81 | }) 82 | } 83 | -------------------------------------------------------------------------------- /library-front/src/api/bookCategory.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | /** 4 | * 添加分类 5 | * @param params 添加分类的DTO对象 6 | * @returns 7 | */ 8 | export const addBookCategoryAPI = (params: any) => { 9 | return request({ 10 | url: '/bookCategory', 11 | method: 'post', 12 | data: { ...params } 13 | }) 14 | } 15 | 16 | /** 17 | * 获取书籍分类(前端id-name对应关系,通过映射进行文字展示) 18 | * @returns 分页条件 19 | */ 20 | export const getBookCategoryAPI = (params: any) => { 21 | console.log('bc-params', params) 22 | return request({ 23 | url: '/bookCategory/page', 24 | method: 'get', 25 | params 26 | }) 27 | } 28 | 29 | /** 30 | * 根据id获取分类信息,用于回显 31 | * @param id 分类id 32 | * @returns 33 | */ 34 | export const getBookCategoryByIdAPI = (id: number) => { 35 | return request({ 36 | url: `/bookCategory/${id}`, 37 | method: 'get' 38 | }) 39 | } 40 | 41 | /** 42 | * 修改分类信息 43 | * @param params 更新分类信息的DTO对象 44 | * @returns 45 | */ 46 | export const updateBookCategoryAPI = (params: any) => { 47 | return request({ 48 | url: '/bookCategory', 49 | method: 'put', 50 | data: { ...params } 51 | }) 52 | } 53 | 54 | /** 55 | * 修改分类状态 56 | * @param params 分类id 57 | * @returns 58 | */ 59 | export const updateBookCategoryStatusAPI = (id: number) => { 60 | console.log('发请求啊!', id) 61 | return request({ 62 | url: `/bookCategory/status/${id}`, 63 | method: 'put' 64 | }) 65 | } 66 | 67 | /** 68 | * 根据id删除分类 69 | * @param id 分类id 70 | * @returns 71 | */ 72 | export const deleteBookCategoryAPI = (id: number) => { 73 | return request({ 74 | url: `/bookCategory/${id}`, 75 | method: 'delete' 76 | }) 77 | } 78 | -------------------------------------------------------------------------------- /library-front/src/api/data.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | /** 4 | * 获取所有图书类别对应书本的数量API 5 | * @returns 6 | */ 7 | export const getBookCategoryDataAPI = () => { 8 | return request({ 9 | url: '/chart/bookCategory', 10 | method: 'get', 11 | }) 12 | } 13 | 14 | /** 15 | * 获取所有读者类别对应读者的数量API 16 | * @returns 17 | */ 18 | export const getReaderCategoryDataAPI = () => { 19 | return request({ 20 | url: '/chart/readerCategory', 21 | method: 'get', 22 | }) 23 | } 24 | 25 | /** 26 | * 获取近day天的借书数统计表API 27 | * @param params day 28 | * @returns 29 | */ 30 | export const getLendDataAPI = (day: number) => { 31 | console.log('获取近day天的借书数统计表API', day) 32 | console.log(day) 33 | return request({ 34 | url: '/chart/dayNLend', 35 | method: 'get', 36 | params: { day } 37 | }) 38 | } 39 | 40 | /** 41 | * 获取近day天的还书数统计表API 42 | * @param params day 43 | * @returns 44 | */ 45 | export const getReturnDataAPI = (day: number) => { 46 | console.log('获取近day天的还书数统计表API', day) 47 | console.log(day) 48 | return request({ 49 | url: '/chart/dayNReturn', 50 | method: 'get', 51 | params: { day } 52 | }) 53 | } 54 | 55 | /** 56 | * 获取图书销量(借书量)top API 57 | * @returns 58 | */ 59 | export const getBookTopDataAPI = (day: number) => { 60 | console.log('获取图书销量(借书量)top API', day) 61 | return request({ 62 | url: '/chart/bookTop', 63 | method: 'get', 64 | params: { day } 65 | }) 66 | } 67 | 68 | /** 69 | * 获取读者借书排行榜(借书量)top API 70 | * @returns 71 | */ 72 | export const getReaderTopDataAPI = (day: number) => { 73 | console.log('获取读者借书排行榜(借书量)top API', day) 74 | return request({ 75 | url: '/chart/readerTop', 76 | method: 'get', 77 | params: { day } 78 | }) 79 | } -------------------------------------------------------------------------------- /library-front/src/api/lendReturn.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | /** 4 | * 分页获取所有借还书数据 5 | * @param params 6 | * @returns 7 | */ 8 | export const getBorrowPageAPI = (params: any) => { 9 | console.log(params) 10 | return request({ 11 | url: '/borrow/page', 12 | method: 'get', 13 | params 14 | }) 15 | } 16 | 17 | /** 18 | * 添加借阅记录 19 | * @param params 20 | * @returns 21 | */ 22 | export const addBorrowAPI = (params: any) => { 23 | console.log(params) 24 | return request({ 25 | url: '/borrow', 26 | method: 'post', 27 | data: params 28 | }) 29 | } 30 | 31 | /** 32 | * 根据id获取借阅记录 33 | * @param id 34 | * @returns 35 | */ 36 | export const getBorrowByIdAPI = (id: number) => { 37 | return request({ 38 | url: `/borrow/${id}`, 39 | method: 'get', 40 | }) 41 | } 42 | 43 | 44 | // /** 45 | // * 根据bId(书籍id)和rId(读者id)获取借阅记录 46 | // * @param rId 47 | // * @param bId 48 | // * @returns 49 | // */ 50 | // export const getBorrowByIdAPI = (rId: number, bId: number) => { 51 | // return request({ 52 | // url: '/borrow', 53 | // method: 'get', 54 | // params: { rId, bId } 55 | // }) 56 | // } 57 | 58 | /** 59 | * 更新借还书记录 60 | * @param params 61 | * @returns 62 | */ 63 | export const updateBorrowAPI = (params: any) => { 64 | return request({ 65 | url: '/borrow', 66 | method: 'put', 67 | data: params 68 | }) 69 | } 70 | 71 | /** 72 | * 根据ids批量删除借还书记录 73 | * @param ids 74 | * @returns 75 | */ 76 | export const deleteBorrowsAPI = (ids: string) => { 77 | return request({ 78 | url: '/borrow', 79 | method: 'delete', 80 | params: { ids } 81 | }) 82 | } 83 | -------------------------------------------------------------------------------- /library-front/src/api/manager.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' // 引入自定义的axios函数 2 | 3 | /** 4 | * 登录接口(这是JSDoc注释) 5 | * @param {*} param0 {username: 用户名, password: 密码} 6 | * @returns Promise对象 7 | */ 8 | export const loginAPI = (params: any) => { 9 | return request({ 10 | url: '/manager/login', 11 | method: 'post', 12 | data: { ...params } 13 | }) 14 | } 15 | 16 | /** 17 | * 注册接口 18 | * @param params 19 | * @returns 20 | */ 21 | export const registerAPI = (params: any) => { 22 | console.log(params) 23 | console.log({ ...params }) 24 | return request({ 25 | url: '/manager/register', 26 | method: 'post', 27 | data: { ...params } 28 | }) 29 | } 30 | 31 | /** 32 | * 修改密码接口 33 | * @returns 34 | */ 35 | export const updateAPI = (params: any) => { 36 | console.log('修改密码') 37 | return request({ 38 | url: '/manager', 39 | method: 'put', 40 | data: { ...params } 41 | }) 42 | } -------------------------------------------------------------------------------- /library-front/src/api/reader.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | /** 4 | * 分页获取所有读者数据 5 | * @param params 分页查询的条件 6 | * @returns 7 | */ 8 | export const getReaderPageAPI = (params: any) => { 9 | console.log(params) 10 | return request({ 11 | url: '/reader/page', 12 | method: 'get', 13 | params 14 | }) 15 | } 16 | 17 | /** 18 | * 新增读者 19 | * @param params 20 | * @returns 21 | */ 22 | export const addReaderAPI = (params: any) => { 23 | console.log(params) 24 | return request({ 25 | url: '/reader', 26 | method: 'post', 27 | data: params 28 | }) 29 | } 30 | 31 | /** 32 | * 根据id获取读者信息 33 | * @param id 34 | * @returns 35 | */ 36 | export const getReaderByIdAPI = (id: number) => { 37 | return request({ 38 | url: `/reader/${id}`, 39 | method: 'get', 40 | }) 41 | } 42 | 43 | /** 44 | * 更新读者信息 45 | * @param params 46 | * @returns 47 | */ 48 | export const updateReaderAPI = (params: any) => { 49 | console.log(params) 50 | console.log({ ...params }) 51 | return request({ 52 | url: '/reader', 53 | method: 'put', 54 | data: { ...params } 55 | }) 56 | } 57 | 58 | /** 59 | * 根据ids批量删除读者信息 60 | * @param ids 61 | * @returns 62 | */ 63 | export const deleteReadersAPI = (ids: string) => { 64 | return request({ 65 | url: '/reader', 66 | method: 'delete', 67 | params: { ids } 68 | }) 69 | } 70 | -------------------------------------------------------------------------------- /library-front/src/api/readerCategory.ts: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | /** 4 | * 添加分类 5 | * @param params 添加分类的DTO对象 6 | * @returns 7 | */ 8 | export const addReaderCategoryAPI = (params: any) => { 9 | return request({ 10 | url: '/readerCategory', 11 | method: 'post', 12 | data: { ...params } 13 | }) 14 | } 15 | 16 | /** 17 | * 获取所有书籍分类(前端id-name对应关系,通过映射进行文字展示) 18 | * @returns 19 | */ 20 | export const getReaderCategoryAPI = (params: any) => { 21 | return request({ 22 | url: '/readerCategory/page', 23 | method: 'get', 24 | params 25 | }) 26 | } 27 | 28 | /** 29 | * 根据id获取分类信息,用于回显 30 | * @param id 分类id 31 | * @returns 32 | */ 33 | export const getReaderCategoryByIdAPI = (id: number) => { 34 | return request({ 35 | url: `/readerCategory/${id}`, 36 | method: 'get' 37 | }) 38 | } 39 | 40 | /** 41 | * 修改分类信息 42 | * @param params 更新分类信息的DTO对象 43 | * @returns 44 | */ 45 | export const updateReaderCategoryAPI = (params: any) => { 46 | return request({ 47 | url: '/readerCategory', 48 | method: 'put', 49 | data: { ...params } 50 | }) 51 | } 52 | 53 | /** 54 | * 修改分类状态 55 | * @param params 分类id 56 | * @returns 57 | */ 58 | export const updateReaderCategoryStatusAPI = (id: number) => { 59 | console.log('发请求啊!', id) 60 | return request({ 61 | url: `/readerCategory/status/${id}`, 62 | method: 'put' 63 | }) 64 | } 65 | 66 | /** 67 | * 根据id删除分类 68 | * @param id 分类id 69 | * @returns 70 | */ 71 | export const deleteReaderCategoryAPI = (id: number) => { 72 | return request({ 73 | url: `/readerCategory/${id}`, 74 | method: 'delete' 75 | }) 76 | } 77 | -------------------------------------------------------------------------------- /library-front/src/assets/base.css: -------------------------------------------------------------------------------- 1 | /* color palette from */ 2 | /* :root { 3 | --vt-c-white: #ffffff; 4 | --vt-c-white-soft: #f8f8f8; 5 | --vt-c-white-mute: #f2f2f2; 6 | 7 | --vt-c-black: #181818; 8 | --vt-c-black-soft: #222222; 9 | --vt-c-black-mute: #282828; 10 | 11 | --vt-c-indigo: #2c3e50; 12 | 13 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); 14 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); 15 | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); 16 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); 17 | 18 | --vt-c-text-light-1: var(--vt-c-indigo); 19 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66); 20 | --vt-c-text-dark-1: var(--vt-c-white); 21 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); 22 | } */ 23 | 24 | /* semantic color variables for this project */ 25 | /* :root { 26 | --color-background: var(--vt-c-white); 27 | --color-background-soft: var(--vt-c-white-soft); 28 | --color-background-mute: var(--vt-c-white-mute); 29 | 30 | --color-border: var(--vt-c-divider-light-2); 31 | --color-border-hover: var(--vt-c-divider-light-1); 32 | 33 | --color-heading: var(--vt-c-text-light-1); 34 | --color-text: var(--vt-c-text-light-1); 35 | 36 | --section-gap: 160px; 37 | } 38 | 39 | @media (prefers-color-scheme: dark) { 40 | :root { 41 | --color-background: var(--vt-c-black); 42 | --color-background-soft: var(--vt-c-black-soft); 43 | --color-background-mute: var(--vt-c-black-mute); 44 | 45 | --color-border: var(--vt-c-divider-dark-2); 46 | --color-border-hover: var(--vt-c-divider-dark-1); 47 | 48 | --color-heading: var(--vt-c-text-dark-1); 49 | --color-text: var(--vt-c-text-dark-2); 50 | } 51 | } 52 | 53 | *, 54 | *::before, 55 | *::after { 56 | box-sizing: border-box; 57 | margin: 0; 58 | font-weight: normal; 59 | } 60 | 61 | body { 62 | min-height: 100vh; 63 | color: var(--color-text); 64 | background: var(--color-background); 65 | transition: 66 | color 0.5s, 67 | background-color 0.5s; 68 | line-height: 1.6; 69 | font-family: 70 | Inter, 71 | -apple-system, 72 | BlinkMacSystemFont, 73 | 'Segoe UI', 74 | Roboto, 75 | Oxygen, 76 | Ubuntu, 77 | Cantarell, 78 | 'Fira Sans', 79 | 'Droid Sans', 80 | 'Helvetica Neue', 81 | sans-serif; 82 | font-size: 15px; 83 | text-rendering: optimizeLegibility; 84 | -webkit-font-smoothing: antialiased; 85 | -moz-osx-font-smoothing: grayscale; 86 | } */ 87 | -------------------------------------------------------------------------------- /library-front/src/assets/library.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Henryers/library-manage/4ea0202b51a254c4c019e2a993dba080f77bca5f/library-front/src/assets/library.jpg -------------------------------------------------------------------------------- /library-front/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /library-front/src/assets/main.css: -------------------------------------------------------------------------------- 1 | /* @import './base.css'; */ 2 | 3 | /* #app { 4 | max-width: 1280px; 5 | margin: 0 auto; 6 | padding: 2rem; 7 | font-weight: normal; 8 | } 9 | 10 | a, 11 | .green { 12 | text-decoration: none; 13 | color: hsla(160, 100%, 37%, 1); 14 | transition: 0.4s; 15 | padding: 3px; 16 | } 17 | 18 | @media (hover: hover) { 19 | a:hover { 20 | background-color: hsla(160, 100%, 37%, 0.2); 21 | } 22 | } */ 23 | 24 | /* @media (min-width: 1024px) { 25 | body { 26 | 就是这个把原来的 width 该小成 1/3 真是服了... 27 | display: flex; 28 | place-items: center; 29 | } 30 | 31 | #app { 32 | display: grid; 33 | grid-template-columns: 1fr 1fr; 34 | padding: 0 2rem; 35 | } 36 | } */ 37 | -------------------------------------------------------------------------------- /library-front/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | import router from './router' 4 | import { createPinia } from 'pinia' 5 | import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' 6 | import ElementPlus from 'element-plus' 7 | import 'element-plus/dist/index.css' 8 | import * as ElementPlusIconsVue from '@element-plus/icons-vue' 9 | 10 | const app = createApp(App) 11 | const pinia = createPinia() 12 | pinia.use(piniaPluginPersistedstate) 13 | 14 | app.use(router) 15 | app.use(pinia) 16 | app.use(ElementPlus) 17 | // 注册使用 ElementPlusIconsVue 的所有 icon 图标组件 18 | for (const [key, component] of Object.entries(ElementPlusIconsVue)) { 19 | app.component(key, component) 20 | } 21 | 22 | app.mount('#app') -------------------------------------------------------------------------------- /library-front/src/router/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from 'vue-router' 2 | 3 | const router = createRouter({ 4 | history: createWebHistory(import.meta.env.BASE_URL), 5 | routes: [ 6 | { 7 | path: '/', 8 | component: () => import('../views/layout/index.vue'), 9 | redirect: '/home', 10 | children: [ 11 | { 12 | path: '/home', 13 | name: 'home', 14 | // lazy loading 15 | component: () => import('../views/home/index.vue') 16 | }, 17 | { 18 | path: '/bookCategory', 19 | name: 'bookCategory', 20 | component: () => import('../views/bookCategory/index.vue') 21 | }, 22 | { 23 | path: '/bookCategory/update', 24 | name: 'bookCategoryUpdate', 25 | component: () => import('../views/bookCategory/update.vue') 26 | }, 27 | { 28 | path: '/book', 29 | name: 'book', 30 | component: () => import('../views/book/index.vue') 31 | }, 32 | { 33 | path: '/book/update', 34 | name: 'bookUpdate', 35 | component: () => import('../views/book/update.vue') 36 | }, 37 | { 38 | path: '/readerCategory', 39 | name: 'readerCategory', 40 | component: () => import('../views/readerCategory/index.vue') 41 | }, 42 | { 43 | path: '/readerCategory/update', 44 | name: 'readerCategoryUpdate', 45 | component: () => import('../views/readerCategory/update.vue') 46 | }, 47 | { 48 | path: '/reader', 49 | name: 'reader', 50 | component: () => import('../views/reader/index.vue') 51 | }, 52 | { 53 | path: '/reader/update', 54 | name: 'readerUpdate', 55 | component: () => import('../views/reader/update.vue') 56 | }, 57 | { 58 | path: '/lendReturn', 59 | name: 'lendReturn', 60 | component: () => import('../views/lendReturn/index.vue') 61 | }, 62 | { 63 | path: '/lendReturn/add', 64 | name: 'lendReturnAdd', 65 | component: () => import('../views/lendReturn/add.vue') 66 | }, 67 | { 68 | path: '/lendReturn/update', 69 | name: 'lendReturnUpdate', 70 | component: () => import('../views/lendReturn/update.vue') 71 | }, 72 | { 73 | path: '/manager', 74 | name: 'manager', 75 | component: () => import('../views/manager/index.vue') 76 | }, 77 | { 78 | path: '/test', 79 | name: 'test', 80 | component: () => import('../views/test/index.vue') 81 | }, 82 | ] 83 | }, 84 | { 85 | path: '/login', 86 | name: 'login', 87 | // lazy loading 88 | component: () => import('../views/login/index.vue') 89 | }, 90 | { 91 | path: '/reg', 92 | name: 'reg', 93 | // lazy loading 94 | component: () => import('../views/reg/index.vue') 95 | } 96 | ] 97 | }) 98 | 99 | export default router 100 | -------------------------------------------------------------------------------- /library-front/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | import type { ManagerInfo } from '@/types/manager' 3 | import { ref } from 'vue' 4 | 5 | // Pinia 会自动将 Composition API 这些相关函数自动识别为状态管理的相关内容 6 | // ref -> state, computed -> getters, methods -> actions 无 mutation 概念 7 | // 等函数转换为响应式数据 8 | export const useManagerStore = defineStore('managerInfo', { 9 | state: () => { 10 | const managerInfo = ref(null) 11 | return { managerInfo } 12 | }, 13 | persist: true // 持久化存储 14 | }) -------------------------------------------------------------------------------- /library-front/src/types/manager.d.ts: -------------------------------------------------------------------------------- 1 | export type ManagerInfo = { 2 | id: number 3 | name: string 4 | token: string 5 | } -------------------------------------------------------------------------------- /library-front/src/utils/request.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | // import { useRouter } from 'vue-router' // 这个方法是写在组件里的,不是这里的 request.ts ! 3 | import router from '@/router' 4 | import { ElMessage } from 'element-plus' 5 | import { useManagerStore } from '@/store' 6 | 7 | //定义一个变量,记录公共的前缀, baseURL: http://localhost:8080/api 8 | const baseURL = '/api' 9 | const instance = axios.create({ baseURL }) 10 | 11 | const store = useManagerStore() 12 | 13 | // 1.定义"请求"拦截器(前端给后端服务器的请求) 14 | // api里每次调用request方法,都会触发一次请求拦截器 15 | instance.interceptors.request.use( 16 | (config) => { 17 | // config配置对象(要请求后台的参数都在这个对象上) 18 | console.log('------请求拦截器-------') 19 | // 在发起时要统一携带请求头Authorization和token值 20 | // 判断,登录和注册页面,pinia里无token,而且登录接口和注册接口也不需要携带token(其他页面需要——) 21 | const token = store.managerInfo ? store.managerInfo.token : null 22 | if (token) { 23 | // 为请求头挂载 Authorization 字段 24 | config.headers.Authorization = token 25 | } 26 | return config 27 | }, 28 | (error) => { 29 | return Promise.reject(error) 30 | } 31 | ) 32 | /// -------------------- 有 token 就存到 Pinia 里啊!!! -------------------------------------------------- 33 | // 2.定义"响应"拦截器(后端服务器给前端的响应) 34 | instance.interceptors.response.use( 35 | (response) => { 36 | // console.log('------ 2xx,3xx 响应拦截器-------') 37 | console.log(response) 38 | // 如果返回的data里有状态码code并且不是0,说明后端返回了错误信息(token过期等),这时候要给前端提示错误信息 39 | if ('code' in response.data && response.data.code !== 0) { 40 | // "xxx已存在" 等各种重复错误,后端有返回提示信息,此处在前端用ElMessage做统一拦截提示 41 | ElMessage.error(response.data.msg) 42 | } 43 | // 对响应的response先在上面拦截处理,最后再放行,返回response 44 | return response 45 | }, 46 | (error) => { 47 | // 响应状态码是 4xx,5xx 时触发失败的回调,形参中的 error 是“失败的结果” 48 | console.dir(error) 49 | if (error.response.status === 401) { 50 | // 无效的 token (过期,伪造或者被修改) 51 | // token没用了,把 Pinia 中的一切重置为空,并跳转到登录页面(相当于没token的状态) 52 | store.managerInfo = null 53 | ElMessage.error('用户身份已过期~') 54 | router.push('/login') // js无法获取this.$router,所以要引入router来跳转 55 | } 56 | // 响应状态码不是 2xx 时触发失败的回调,形参中的 error 是“失败的结果” 57 | return Promise.reject(error) 58 | } 59 | ) 60 | 61 | export default instance 62 | -------------------------------------------------------------------------------- /library-front/src/views/book/update.vue: -------------------------------------------------------------------------------- 1 | 136 | 137 | 174 | 175 | 182 | 183 | 189 | -------------------------------------------------------------------------------- /library-front/src/views/bookCategory/index.vue: -------------------------------------------------------------------------------- 1 | 152 | 153 | 210 | 211 | 212 | -------------------------------------------------------------------------------- /library-front/src/views/bookCategory/update.vue: -------------------------------------------------------------------------------- 1 | 92 | 93 | 110 | 111 | 118 | 119 | 125 | -------------------------------------------------------------------------------- /library-front/src/views/layout/index.vue: -------------------------------------------------------------------------------- 1 | 97 | 98 | 157 | 158 | 239 | 240 | -------------------------------------------------------------------------------- /library-front/src/views/lendReturn/index.vue: -------------------------------------------------------------------------------- 1 | 200 | 201 | 245 | 246 | 247 | -------------------------------------------------------------------------------- /library-front/src/views/login/index.vue: -------------------------------------------------------------------------------- 1 | 52 | 53 | 70 | 71 | 72 | 124 | 125 | 131 | -------------------------------------------------------------------------------- /library-front/src/views/manager/index.vue: -------------------------------------------------------------------------------- 1 | 92 | 93 | 114 | 115 | 121 | 122 | 128 | -------------------------------------------------------------------------------- /library-front/src/views/reader/update.vue: -------------------------------------------------------------------------------- 1 | 137 | 138 | 174 | 175 | 182 | 183 | 189 | -------------------------------------------------------------------------------- /library-front/src/views/readerCategory/update.vue: -------------------------------------------------------------------------------- 1 | 108 | 109 | 132 | 133 | 140 | 141 | 147 | -------------------------------------------------------------------------------- /library-front/src/views/reg/index.vue: -------------------------------------------------------------------------------- 1 | 79 | 80 | 107 | 108 | 160 | 161 | 167 | -------------------------------------------------------------------------------- /library-front/src/views/test/index.vue: -------------------------------------------------------------------------------- 1 | 83 | 84 | 148 | 149 | -------------------------------------------------------------------------------- /library-front/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | "exclude": ["src/**/__tests__/*"], 5 | "compilerOptions": { 6 | "composite": true, 7 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 8 | 9 | "baseUrl": ".", 10 | "paths": { 11 | "@/*": ["./src/*"] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /library-front/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /library-front/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node20/tsconfig.json", 3 | "include": [ 4 | "vite.config.*", 5 | "vitest.config.*", 6 | "cypress.config.*", 7 | "nightwatch.conf.*", 8 | "playwright.config.*" 9 | ], 10 | "compilerOptions": { 11 | "composite": true, 12 | "noEmit": true, 13 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 14 | 15 | "module": "ESNext", 16 | "moduleResolution": "Bundler", 17 | "types": ["node"] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /library-front/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [vue()], 9 | resolve: { 10 | alias: { 11 | '@': fileURLToPath(new URL('./src', import.meta.url)) 12 | } 13 | }, 14 | // 开启代理 15 | server: { 16 | host: '0.0.0.0', 17 | // public: '0.0.0.0:5173', // 本地的ip:端口号 18 | port: 5173, 19 | open: true, 20 | proxy: { 21 | '/api': { 22 | // 前缀替换成代理地址: 5173 -> 8080 23 | target: 'http://localhost:8080', 24 | ws: false, 25 | secure: false, 26 | changeOrigin: true, 27 | // /api去掉,变成空串,因为它只是一个标识而已,并不是路径 28 | rewrite: (path) => path.replace(/^\/api/, '') 29 | } 30 | } 31 | } 32 | }) 33 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 图书管理系统(数据库课设) 2 | 3 | 4 | 5 | ## 项目导入 6 | 7 | 利用sql文件,创建数据库和表,并使用IDEA进行数据库连接 8 | 9 | library-front library-behind 分别对应前端和后端代码 10 | 11 | 前端代码导入后,可以使用npm i 安装相关依赖,后端的话同理,根据pom.xml文件来构建maven依赖 12 | 13 | 14 | 15 | ## 一、系统目标 16 | 17 | 图书管理信息系统实现的总目标,是使图书馆的信息管理工作系统化、规范化、自动化, 18 | 19 | 从而达到提高企业人事管理效率的目的。要求实现如下目标: 20 | 21 | ### 1、数据输入部分 22 | 23 | 包括图书基本信息的录入、借阅人基本信息的录入、用户基本信息的录入。 24 | 25 | ### 2、数据输出部分 26 | 27 | 主要是各种统计查询,如:根据图书信息(如书名、作者、出版社等)查阅图书及其借阅信息、统计输出图书类型比例等。 28 | 29 | ### 3、数据处理部分 30 | 31 | 主要包括借阅和归还的处理,如一本书借出后,必须在数据库中将该书标记为已借出,以防出现数据库中有书但图书馆无书的情况。一本书归还后,同样必须在数据库中将其标记为已经归还,以便再次借出。 32 | 33 | 34 | 35 | ## 二、功能要求 36 | 37 | 根据以上实现目标,图书管理系统的主要功能包括: 38 | 39 | 1、读者种类的定义、更新、查询 主要实现读者种类标准的制定,如:种类编号、种类名称、借书数量、借书期限、有效期限、备注等。 40 | 41 | 2、读者基本信息的输入、查询、更新 包括读者编号、读者姓名、读者种类、读者性别、工作单位、家庭住址、电话号码、电子邮件地址、登记日期、备注等。 42 | 43 | 3、书籍类别的定义、更新、查询 主要实现书籍类别标准的制定,如:类别编号、类别名称、关键词、备注信息等。 44 | 45 | 4、书籍信息的输入、查询、更新 包括书籍编号、书籍名称、书籍类别、作者姓名、出版社名称、出版日期、价格、书籍页码、关键词、登记日期、是否被借出、备注信息等。 46 | 47 | 5、旧书销毁 对于淘汰、损坏、丢失的书目可及时对数据库进行修改。 48 | 49 | 6、借还书信息的输入、查询、更新 包括借阅编号、读者编号、书籍编号、出借日期、还书日期、备注信息等。 50 | 51 | 7、方便、灵活的查询 如:以书名、作者、出版社、出版时间(确定的时间或时间段、某一时间之前、某一时间之后)等信息进行图书检索,并能反映出图书的借阅情况,以借阅人编号对借阅人信息进行检索,以出版社名称查询出版社联系方式信息等。 52 | 53 | 8、统计分析功能 可以展现出图书类型比例、库存与借出比例等统计信息。 54 | 55 | 56 | 57 | ## 三、数据库设计 58 | 59 | ### 1、E-R图 60 | 61 | 根据上述要求,设计了 E-R 图来表示系统中的实体及实体与实体之间的联系情况,从而直观地看出整个系统的情况。 62 | 63 | E-R 图如下图所示: 64 | 65 | ![img](images/ER1.png) 66 | 67 | (手绘E-R图) 68 | 69 | 70 | 71 | ![img](images/ER2.png) 72 | 73 | (IDEA生成的数据库表关系图) 74 | 75 | ### 2、关系模型 76 | 77 | 我们根据绘制的 E-R 图,转换成关系模型,从而更好地看出表结构以及表设计的内容。 78 | 79 | 关系模型如下所示: 80 | 81 | ``` 82 | 读者种类表r_category 83 | (id,名称,可借数量,借书期限,有效期,备注) 84 | 85 | 读者表reader 86 | (id,姓名,种类id*,性别,工作地址,家庭地址,电话,邮箱,创建时间,备注) 87 | 88 | 书籍种类表b_category 89 | (id,名称,关键词,备注) 90 | 91 | 书籍表book 92 | (id,名称,种类id*,作者,出版社,出版日期,价格,页数,关键词,创建时间,状态,备注) 93 | 94 | 借书还书表lend_return 95 | (id,读者id*,书籍id*,借书日期,还书日期,状态,备注) 96 | 97 | 管理员表 manager 98 | (id,账号,密码) 99 | 100 | 注:下划线 表示该表的主键, *表示有外键约束 101 | ``` 102 | 103 | 其中,每个表的id都作为主键,读者和图书的分类id都需要添加外键约束,分别关联读者分类表、图书分类表的主键id,才能保证数据的关联性和完整性。同时,借还书记录表为一个多对多的关系表,一个读者可以借阅多本书,一本书在不同时间内也可以被多个读者所借阅,因此每条借书记录需要有借书人的id和图书的id信息来标识这条记录,同时借书人的id、图书id也都有外键约束,分别关联着读者表的主键id和图书表的主键id,以保证数据的关联性和完整性。 104 | 105 | ### 3、创新点 106 | 107 | 在根据要求设计数据库的各个表时,我们发现借书还书表只有借书还书时间的属性还不够,由于需要考虑是否还书成功来更新图书状态(是否归还到图书馆中,如果已归还便可以被其他人所借阅),因此还需要设计一个还书状态的属性,根据这个属性来判断书籍是否成功归还。在这个属性中有几个还书状态:出借中、正常归还、逾期归还、丢失无法归还、损坏归还、其他(请备注说明)。若正常归还、损坏归还则说明还书成功,其他情况都视为还书不成功,若其他原因时,在修改信息时需要在备注属性里输入对应值,才能够更新这条借还书记录。 108 | 109 | 110 | 111 | ## 四、开发过程 112 | 113 | ### 1、技术选型 114 | 115 | 使用前后端分离技术进行web网页端开发。 116 | 117 | 前端:html、less、typescript、vue3、ElementPlus、Echarts、Pinia。 118 | 119 | 后端:java语言,利用springboot框架进行开发,使用mybatis来连接mysql数据库,并进行相关sql语句的编写。 120 | 121 | ### 2、前端数据展示 122 | 123 | #### (1)统计报表模块 124 | 125 | 采用ECharts可视化库,来进行各种数据图表的绘制,包括图书读者分类数量,借书还书统计以及人气书籍Top排行榜等,具体展示图如下: 126 | 127 | ![img](images/chart1.png) 128 | 129 | ![img](images/chart2.png) 130 | 131 | #### (2)图书模块 132 | 133 | 包括图书分类和图书列表,均实现了对应的增删改查功能,管理员点击相关按钮即可操作。 134 | 135 | ![img](images/addbook.png) 136 | 137 | (添加分类示意图) 138 | 139 | ![img](images/booklist.png) 140 | 141 | (图书列表分页展示图) 142 | 143 | #### (3)读者模块 144 | 145 | 与图书模块功能类似,读者分类和读者列表均有对应的增删改查功能。 146 | 147 | ![img](images/readerctg.png) 148 | 149 | (读者分类分页查询) 150 | 151 | ![img](images/readerupdate.png) 152 | 153 | (读者信息修改) 154 | 155 | #### (4)借书还书模块 156 | 157 | 进入借书页面,页面下方会分页展示读者列表和图书列表,其中图书都是当前处于图书馆中未被出借的书。管理员可以单选其中一个读者和一本书籍,表示借书,对应的上方表单会回显对应的读者和图书的id,再选择借书日期后便可进行借书记录的新增操作。 158 | 159 | ![img](images/borrow.png) 160 | 161 | (新增借书页面) 162 | 163 | 进入记录展示页面,会分页显示所有借还书记录,同时状态栏还会以不同颜色标准不同的还书状态。 164 | 165 | ![img](images/lendreturn.png) 166 | 167 | (记录展示) 168 | 169 | 进行还书时,需要选择还书日期(在借书日期之后且不能晚于当前日期),填写完相关信息后即可还书,本页面下面还有借书人和对应书籍的详细信息展示。 170 | 171 | ![img](images/return.png) 172 | 173 | (还书页面) 174 | 175 | #### (5)管理员模块 176 | 177 | 在个人设置页面中,管理员可以修改个人信息,修改完密码会跳转到登录页进行重新登录操作,也可以新注册一个管理员账号进行登录,登录模块用到了jwt校验,token生成等知识。 178 | 179 | ![img](images/manager.png) 180 | 181 | (个人信息页) 182 | 183 | ![img](images/login.png) 184 | 185 | (登录页) 186 | 187 | ### 3、后端与数据库关联 188 | 189 | 后端使用java语言编写,利用mybatis来连接mysql数据库,在后端项目的服务层server模块中,分了controller,service,以及mapper三层架构。 190 | 191 | (1)controller负责处理前端发过来的请求接口,并调用service进行处理,最后返回对应数据给前端。 192 | 193 | (2)service负责逻辑处理,比如借书时不仅需要新增借还书记录,还需要设置书籍状态为出借中,这两个处理需要分别调用mapper层的相关sql语句操作。 194 | 195 | (3)mapper层负责sql语句编写,在连接完mysql后,mapper层中的方法一但被service层调用,对应的sql语句便会执行,从而进行数据库的增删改查操作。 196 | 197 | mapper中相关的sql命令如下图: 198 | 199 | ![img](images/mapper1.png) 200 | 201 | (mapper接口中写简单的sql) 202 | 203 | ![img](images/mapper2.png) 204 | 205 | (mapper.xml文件中写较为复杂的sql) 206 | 207 | (4)本项目还有另外common和pojo两个模块,分别存放着一些工具类(常量类、异常类、前后端数据传输格式类等)和项目所需的对象实体类(如图书类、读者类等),通过模块化处理能使项目开发得更规范,开发效率也得到提升。 208 | 209 | ### 4、功能测试 210 | 211 | 本图书管理系统开发过程中进行了许多次调试,并发现了一些bug。如:一个读者借书时,要考虑当前读者已借阅书籍的总数量,若达到总数量则无法进行借书操作,但是前端操作时还是能借书成功;又如:读者借书后,需要将书籍标记为已借出,并不允许别人借书,但是在别人借书的操作页面上,其书籍列表仍然展示着该本被借出的书籍。 212 | 213 | 代码调试后发现:主要是在后端service服务层没处理好,有些变量大小写没注意,或者调用错了sql语句,导致sql没有正常执行,数据库中的信息没有正常更新,因此需要不断进行修改,去除bug。 214 | 215 | 此外,为了防止前端进行某些非法操作,在前端传给后端数据后,后端需要对这些数据进行一系列校验处理,并自定义异常类,将捕获到的这些不合理数据封装起来,响应给前端,前端拿到数据后利用 `ElementPlus` 组件库的消息弹窗组件,将这些信息提示给用户,从而保证前后端数据交互符合逻辑,以及保证数据库相关增删改查的合法性和完整性,不易造成数据丢失,数据不一致等情况。 216 | 217 | 218 | 219 | ## 五、结果分析 220 | 221 | 1、表结构设计较好,在满足实验要求的同时,根据需求进行相应的改进创新,同时利用外键约束将不同表之间联系起来,也保证了数据的完整性约束。此外,表中的字段和前后端的数据格式对应起来,在设计完善好数据库之后再进行开发会较为顺利,提高开发效率。 222 | 223 | 2、前后端交互顺利,对于前端管理员发起的增删改查等操作,后端对应的接口都能识别到,进行相应逻辑处理并执行sql语句,更改数据库中的数据信息,同时相应给前端所需要的格式化数据。使得前端页面操作顺利,交互合理。 224 | 225 | 最后,如果觉得本项目对你有帮助的话,求求点个star🤩吧,谢谢了~ --------------------------------------------------------------------------------