Refactor: Refactor OrdersController and OrdersService to improve order creation and retrieval functionality

This commit is contained in:
grtsinry43 2025-05-22 16:32:26 +08:00
parent 276bc8ec62
commit f4d8134fe5
Signed by: grtsinry43
GPG Key ID: F3305FB3A978C934
9 changed files with 488 additions and 157 deletions

4
.gitignore vendored
View File

@ -32,4 +32,6 @@ build/
### VS Code ###
.vscode/
src/main/resources/application-secret.yml
src/main/resources/application-secret.yml
logs/

View File

@ -1093,3 +1093,311 @@ org.springframework.web.servlet.resource.NoResourceFoundException: No static res
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:840)
2025-05-22 12:28:13.794 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.BookMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 12:28:13.796 | [main] | WARN | c.b.m.core.injector.methods.Delete | [com.grtsinry43.bookmanagement.mapper.BookMapper.delete] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Delete]
2025-05-22 12:28:13.797 | [main] | WARN | c.b.m.core.injector.methods.Update | [com.grtsinry43.bookmanagement.mapper.BookMapper.update] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Update]
2025-05-22 12:28:13.805 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.OrderItemMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 12:28:13.813 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.OrdersMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 12:28:13.821 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.PublisherMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 12:28:13.822 | [main] | WARN | c.b.m.core.injector.methods.Delete | [com.grtsinry43.bookmanagement.mapper.PublisherMapper.delete] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Delete]
2025-05-22 12:28:13.822 | [main] | WARN | c.b.m.core.injector.methods.Update | [com.grtsinry43.bookmanagement.mapper.PublisherMapper.update] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Update]
2025-05-22 12:28:13.830 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.ReaderMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 12:28:14.121 | [main] | INFO | c.b.m.e.s.MybatisPlusApplicationContextAware | Register ApplicationContext instances org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@7b139eab
2025-05-22 12:28:16.308 | [http-nio-8080-exec-3] | ERROR | c.g.b.c.GlobalExceptionHandler | 系统异常: No static resource favicon.ico.
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource favicon.ico.
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:585)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:840)
2025-05-22 12:28:19.386 | [http-nio-8080-exec-5] | ERROR | c.g.b.c.GlobalExceptionHandler | 系统异常: No static resource favicon.ico.
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource favicon.ico.
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:585)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:840)
2025-05-22 12:36:43.061 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.BookMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 12:36:43.062 | [main] | WARN | c.b.m.core.injector.methods.Delete | [com.grtsinry43.bookmanagement.mapper.BookMapper.delete] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Delete]
2025-05-22 12:36:43.063 | [main] | WARN | c.b.m.core.injector.methods.Update | [com.grtsinry43.bookmanagement.mapper.BookMapper.update] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Update]
2025-05-22 12:36:43.071 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.OrderItemMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 12:36:43.079 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.OrdersMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 12:36:43.088 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.PublisherMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 12:36:43.088 | [main] | WARN | c.b.m.core.injector.methods.Delete | [com.grtsinry43.bookmanagement.mapper.PublisherMapper.delete] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Delete]
2025-05-22 12:36:43.089 | [main] | WARN | c.b.m.core.injector.methods.Update | [com.grtsinry43.bookmanagement.mapper.PublisherMapper.update] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Update]
2025-05-22 12:36:43.099 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.ReaderMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 12:36:43.396 | [main] | INFO | c.b.m.e.s.MybatisPlusApplicationContextAware | Register ApplicationContext instances org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@3f2ef586
2025-05-22 12:36:47.001 | [http-nio-8080-exec-1] | ERROR | c.g.b.c.GlobalExceptionHandler | 系统异常: Required request body is missing: public com.grtsinry43.bookmanagement.common.ApiResponse<java.util.Map<java.lang.String, java.lang.Object>> com.grtsinry43.bookmanagement.controller.ReaderController.login(com.grtsinry43.bookmanagement.dto.LoginRequest)
org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public com.grtsinry43.bookmanagement.common.ApiResponse<java.util.Map<java.lang.String, java.lang.Object>> com.grtsinry43.bookmanagement.controller.ReaderController.login(com.grtsinry43.bookmanagement.dto.LoginRequest)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:179)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:150)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:227)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:181)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:986)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:891)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:840)
2025-05-22 12:36:50.370 | [http-nio-8080-exec-3] | ERROR | c.g.b.c.GlobalExceptionHandler | 系统异常: Required request body is missing: public com.grtsinry43.bookmanagement.common.ApiResponse<java.util.Map<java.lang.String, java.lang.Object>> com.grtsinry43.bookmanagement.controller.ReaderController.login(com.grtsinry43.bookmanagement.dto.LoginRequest)
org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public com.grtsinry43.bookmanagement.common.ApiResponse<java.util.Map<java.lang.String, java.lang.Object>> com.grtsinry43.bookmanagement.controller.ReaderController.login(com.grtsinry43.bookmanagement.dto.LoginRequest)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:179)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:150)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:227)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:181)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:986)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:891)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:840)
2025-05-22 16:29:06.522 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.BookMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 16:29:06.524 | [main] | WARN | c.b.m.core.injector.methods.Delete | [com.grtsinry43.bookmanagement.mapper.BookMapper.delete] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Delete]
2025-05-22 16:29:06.525 | [main] | WARN | c.b.m.core.injector.methods.Update | [com.grtsinry43.bookmanagement.mapper.BookMapper.update] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Update]
2025-05-22 16:29:06.535 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.OrderItemMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 16:29:06.544 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.OrdersMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 16:29:06.553 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.PublisherMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 16:29:06.554 | [main] | WARN | c.b.m.core.injector.methods.Delete | [com.grtsinry43.bookmanagement.mapper.PublisherMapper.delete] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Delete]
2025-05-22 16:29:06.554 | [main] | WARN | c.b.m.core.injector.methods.Update | [com.grtsinry43.bookmanagement.mapper.PublisherMapper.update] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Update]
2025-05-22 16:29:06.563 | [main] | WARN | c.b.m.core.injector.methods.Insert | [com.grtsinry43.bookmanagement.mapper.ReaderMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
2025-05-22 16:29:06.897 | [main] | INFO | c.b.m.e.s.MybatisPlusApplicationContextAware | Register ApplicationContext instances org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@7b139eab
2025-05-22 16:29:09.661 | [http-nio-8080-exec-2] | ERROR | c.g.b.c.GlobalExceptionHandler | 系统异常: No static resource favicon.ico.
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource favicon.ico.
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:585)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:840)
2025-05-22 16:29:22.182 | [http-nio-8080-exec-4] | ERROR | c.g.b.c.GlobalExceptionHandler | 系统异常: No static resource favicon.ico.
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource favicon.ico.
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:585)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:840)

View File

@ -2,13 +2,10 @@ package com.grtsinry43.bookmanagement.controller;
import com.grtsinry43.bookmanagement.annotation.AuthCheck;
import com.grtsinry43.bookmanagement.common.ApiResponse;
import com.grtsinry43.bookmanagement.common.BusinessException;
import com.grtsinry43.bookmanagement.common.ErrorCode;
import com.grtsinry43.bookmanagement.common.PageResponse;
import com.grtsinry43.bookmanagement.common.UserRole;
import com.grtsinry43.bookmanagement.dto.CreateOrderRequest;
import com.grtsinry43.bookmanagement.entity.OrderItem;
import com.grtsinry43.bookmanagement.entity.Orders;
import com.grtsinry43.bookmanagement.service.OrderItemService; // Keep for future use if OrderItem specific endpoints are added
import com.grtsinry43.bookmanagement.dto.OrderCreateDTO;
import com.grtsinry43.bookmanagement.vo.OrderVO;
import com.grtsinry43.bookmanagement.service.OrdersService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
@ -16,133 +13,41 @@ import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
* 订单前端控制器
* </p>
*
* @author grtsinry43
* @since 2025-05-19
*/
@RestController
@RequestMapping("/orders")
public class OrdersController {
@Autowired
private OrdersService ordersService;
// @Autowired
// private OrderItemService orderItemService; // 如果需要单独操作订单项则保留
/**
* 顾客创建新订单
* @param createOrderRequest 包含订单信息和订单项列表的请求体
* @param request HTTP请求对象用于获取用户ID
* @return 包含创建的订单信息的API响应
*/
@PostMapping("/create")
@AuthCheck(requiredRole = UserRole.USER) // 需要用户登录才能创建订单
public ApiResponse<Orders> createOrder(@RequestBody CreateOrderRequest createOrderRequest, HttpServletRequest request) {
// 从HttpServletRequest中获取用户ID
Object userIdObject = request.getAttribute("userId");
if (userIdObject == null) {
throw new BusinessException(ErrorCode.NOT_LOGIN);
}
Integer userId = (Integer) userIdObject;
// 基本验证订单项不能为空
if (createOrderRequest.getItems() == null || createOrderRequest.getItems().isEmpty()) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Orders orderToCreate = createOrderRequest.getOrder();
if (orderToCreate == null) {
// 如果请求中没有order部分或者需要初始化一个
orderToCreate = new Orders();
}
// 设置订单的读者ID为当前登录用户的ID
orderToCreate.setReaderId(userId);
// 调用服务创建订单
// 服务层中的 createOrder 方法应该处理库存检查等业务逻辑并在发生错误时抛出 BusinessException
Orders createdOrder = ordersService.createOrder(orderToCreate, createOrderRequest.getItems());
return ApiResponse.success(createdOrder);
@AuthCheck(requiredRole = UserRole.USER)
public ApiResponse<OrderVO> createOrder(@RequestBody OrderCreateDTO dto, HttpServletRequest request) {
Integer userId = (Integer) request.getAttribute("userId");
return ApiResponse.success(ordersService.createOrder(dto, userId));
}
/**
* 顾客查看自己的订单列表
* @param request HTTP请求对象用于获取用户ID
* @return 包含用户订单列表的API响应
*/
@GetMapping("/my-orders") // 移除了{readerId}路径参数
@AuthCheck(requiredRole = UserRole.USER) // 需要用户登录才能查看订单
public ApiResponse<List<Orders>> getMyOrders(HttpServletRequest request) {
// 从HttpServletRequest中获取用户ID
Object userIdObject = request.getAttribute("userId");
if (userIdObject == null) {
throw new BusinessException(ErrorCode.NOT_LOGIN);
}
Integer userId = (Integer) userIdObject;
List<Orders> orders = ordersService.getOrdersByReaderId(userId);
return ApiResponse.success(orders);
}
/**
* 顾客和管理员查看特定订单详情
* (对于顾客应在服务层或此处增加逻辑校验订单是否属于该顾客除非拦截器已处理)
* @param orderId 订单ID
* @param request HTTP请求对象 (如果需要根据用户角色或ID进行权限校验)
* @return 包含订单详情的API响应
*/
@GetMapping("/{orderId}")
@AuthCheck(requiredRole = UserRole.USER) // 需要用户登录才能查看订单详情
public ApiResponse<Orders> getOrderDetails(@PathVariable Integer orderId, HttpServletRequest request) {
// 示例如果需要基于用户ID的权限检查可以从request中获取userId
Object userIdObject = request.getAttribute("userId");
Integer currentUserId = (userIdObject != null) ? (Integer) userIdObject : null;
// TODO: 根据业务需求添加权限校验逻辑例如检查订单是否属于当前用户如果非管理员
Orders order = ordersService.getOrderById(orderId);
if (order == null) {
throw new BusinessException(ErrorCode.NOT_FOUND);
}
if (order.getReaderId() != null && !order.getReaderId().equals(currentUserId)) {
// 如果订单属于其他用户且当前用户不是管理员则抛出权限异常
throw new BusinessException(ErrorCode.UNAUTHORIZED);
}
// 考虑如果用户不是管理员且订单不属于该用户也应抛出权限异常
return ApiResponse.success(order);
@AuthCheck(requiredRole = UserRole.USER)
public ApiResponse<OrderVO> getOrderDetail(@PathVariable Integer orderId, HttpServletRequest request) {
Integer userId = (Integer) request.getAttribute("userId");
OrderVO vo = ordersService.getOrderDetailApi(orderId, userId);
return ApiResponse.success(vo);
}
@GetMapping("/my")
@AuthCheck(requiredRole = UserRole.USER)
public ApiResponse<PageResponse<List<OrderVO>>> getOrdersByReaderId(@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize,
HttpServletRequest request) {
Integer userId = (Integer) request.getAttribute("userId");
return ApiResponse.success(ordersService.getOrdersByReaderId(userId, pageNum, pageSize));
}
/**
* 管理员查看所有订单列表
* (假设已有管理员权限拦截器)
* @return 包含所有订单列表的API响应
*/
@GetMapping("/admin/all")
@AuthCheck(requiredRole = UserRole.ADMIN) // 需要管理员权限才能查看所有订单
public ApiResponse<List<Orders>> getAllOrders() {
List<Orders> orders = ordersService.getAllOrders();
return ApiResponse.success(orders);
}
/**
* 管理员更新订单状态
* (假设已有管理员权限拦截器)
* @param orderId 订单ID
* @param status 新的订单状态
* @return 操作结果的API响应
*/
@PutMapping("/admin/update-status/{orderId}")
@AuthCheck(requiredRole = UserRole.ADMIN) // 需要管理员权限才能更新订单状态
public ApiResponse<String> updateOrderStatus(@PathVariable Integer orderId, @RequestParam String status) {
// TODO: 可以增加对status参数有效性的校验
if (status == null || status.trim().isEmpty()) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
ordersService.updateOrderStatus(orderId, status);
// 更新成功通常返回成功的消息data部分可以为null或包含更新后的对象如果服务层返回
return ApiResponse.success(null);
@AuthCheck(requiredRole = UserRole.ADMIN)
public ApiResponse<PageResponse<List<OrderVO>>> getAllOrders(@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize) {
return ApiResponse.success(ordersService.getAllOrders(pageNum, pageSize));
}
}

View File

@ -0,0 +1,13 @@
package com.grtsinry43.bookmanagement.dto;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.Data;
import java.util.List;
@Data
public class OrderCreateDTO {
@NotNull(message = "订单项不能为空")
private List<OrderItemCreateDTO> items;
}

View File

@ -0,0 +1,15 @@
package com.grtsinry43.bookmanagement.dto;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.Data;
@Data
public class OrderItemCreateDTO {
@NotNull(message = "图书ID不能为空")
private Integer bookId;
@NotNull(message = "数量不能为空")
@Positive(message = "数量必须大于0")
private Integer quantity;
}

View File

@ -2,6 +2,9 @@ package com.grtsinry43.bookmanagement.service;
import com.grtsinry43.bookmanagement.entity.Orders;
import com.grtsinry43.bookmanagement.entity.OrderItem;
import com.grtsinry43.bookmanagement.dto.OrderCreateDTO;
import com.grtsinry43.bookmanagement.vo.OrderVO;
import com.grtsinry43.bookmanagement.common.PageResponse;
import java.util.List;
@ -14,13 +17,13 @@ import java.util.List;
* @since 2025-05-19
*/
public interface OrdersService {
Orders getOrderById(Integer orderId);
void updateOrderStatus(Integer orderId, String status);
List<Orders> getAllOrders(); // For admin
OrderVO createOrder(OrderCreateDTO orderCreateDTO, Integer userId);
List<Orders> getOrdersByReaderId(Integer readerId);
OrderVO getOrderDetailApi(Integer orderId, Integer userId);
Orders createOrder(Orders order, List<OrderItem> items); // Simplified: pass items directly
PageResponse<List<OrderVO>> getOrdersByReaderId(Integer userId, int pageNum, int pageSize);
void updateOrderStatus(Integer orderId, String status); // Simplified
PageResponse<List<OrderVO>> getAllOrders(int pageNum, int pageSize);
}

View File

@ -1,6 +1,8 @@
package com.grtsinry43.bookmanagement.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.grtsinry43.bookmanagement.common.BusinessException;
import com.grtsinry43.bookmanagement.common.ErrorCode;
import com.grtsinry43.bookmanagement.entity.Book;
import com.grtsinry43.bookmanagement.entity.OrderItem;
import com.grtsinry43.bookmanagement.entity.Orders;
@ -8,24 +10,31 @@ import com.grtsinry43.bookmanagement.mapper.BookMapper;
import com.grtsinry43.bookmanagement.mapper.OrderItemMapper;
import com.grtsinry43.bookmanagement.mapper.OrdersMapper;
import com.grtsinry43.bookmanagement.service.OrdersService;
import com.grtsinry43.bookmanagement.dto.OrderCreateDTO;
import com.grtsinry43.bookmanagement.dto.OrderItemCreateDTO;
import com.grtsinry43.bookmanagement.vo.OrderVO;
import com.grtsinry43.bookmanagement.vo.OrderItemVO;
import com.grtsinry43.bookmanagement.common.PageResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 服务实现类
* 服务实现类
* </p>
*
* @author grtsinry43
* @since 2025-05-19
*/
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper,Orders> implements OrdersService {
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {
@Autowired
private OrdersMapper ordersMapper;
@ -34,55 +43,99 @@ public class OrdersServiceImpl extends ServiceImpl<OrdersMapper,Orders> implemen
private OrderItemMapper orderItemMapper;
@Autowired
private BookMapper bookMapper; // To update stock and get price
private BookMapper bookMapper;
@Override
public Orders getOrderById(Integer orderId) {
return ordersMapper.findById(orderId);
}
@Override
public List<Orders> getAllOrders() {
return ordersMapper.findAll();
}
@Override
public List<Orders> getOrdersByReaderId(Integer readerId) {
return ordersMapper.findByReaderId(readerId);
}
@Override
@Transactional // Ensure atomicity
public Orders createOrder(Orders order, List<OrderItem> items) {
@Transactional
public OrderVO createOrder(OrderCreateDTO orderCreateDTO, Integer userId) {
Orders order = new Orders();
order.setOrderDate(LocalDateTime.now());
order.setStatus("PENDING");
BigDecimal totalAmount = BigDecimal.ZERO;
for (OrderItem item : items) {
Book book = bookMapper.findById(item.getBookId());
if (book == null || book.getStock() < item.getQuantity()) {
throw new RuntimeException("Book not found or insufficient stock for: " + (book != null ? book.getTitle() : item.getBookId()));
List<OrderItem> items = new ArrayList<>();
for (OrderItemCreateDTO itemDTO : orderCreateDTO.getItems()) {
Book book = bookMapper.findById(itemDTO.getBookId());
if (book == null || book.getStock() < itemDTO.getQuantity()) {
throw new RuntimeException("Book not found or insufficient stock for: " + itemDTO.getBookId());
}
OrderItem item = new OrderItem();
item.setBookId(itemDTO.getBookId());
item.setQuantity(itemDTO.getQuantity());
item.setUnitPrice(book.getPrice());
totalAmount = totalAmount.add(book.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())));
totalAmount = totalAmount.add(book.getPrice().multiply(BigDecimal.valueOf(itemDTO.getQuantity())));
items.add(item);
}
order.setTotalAmount(totalAmount);
ordersMapper.insert(order);
for (OrderItem item : items) {
item.setOrderId(order.getOrderId());
orderItemMapper.insert(item);
Book book = bookMapper.findById(item.getBookId());
book.setStock(book.getStock() - item.getQuantity());
bookMapper.update(book);
}
return order;
return getOrderDetail(order.getOrderId());
}
@Override
public OrderVO getOrderDetailApi(Integer orderId, Integer userId) {
Orders order = ordersMapper.findById(orderId);
if (order == null) {
throw new BusinessException(ErrorCode.NOT_FOUND);
} else if (!order.getReaderId().equals(userId)) {
throw new BusinessException(ErrorCode.UNAUTHORIZED);
}
return getOrderDetail(orderId);
}
@Override
public PageResponse<List<OrderVO>> getOrdersByReaderId(Integer userId, int pageNum, int pageSize) {
List<Orders> orders = ordersMapper.findByReaderId(userId);
int total = orders.size();
int fromIndex = Math.max(0, (pageNum - 1) * pageSize);
int toIndex = Math.min(fromIndex + pageSize, total);
List<OrderVO> voList = new ArrayList<>();
for (Orders order : orders.subList(fromIndex, toIndex)) {
voList.add(getOrderDetail(order.getOrderId()));
}
return new PageResponse<>(pageNum, pageSize, (long) total, voList);
}
@Override
public PageResponse<List<OrderVO>> getAllOrders(int pageNum, int pageSize) {
List<Orders> orders = ordersMapper.findAll();
int total = orders.size();
int fromIndex = Math.max(0, (pageNum - 1) * pageSize);
int toIndex = Math.min(fromIndex + pageSize, total);
List<OrderVO> voList = new ArrayList<>();
for (Orders order : orders.subList(fromIndex, toIndex)) {
voList.add(getOrderDetail(order.getOrderId()));
}
return new PageResponse<>(pageNum, pageSize, (long) total, voList);
}
@Override
public void updateOrderStatus(Integer orderId, String status) {
ordersMapper.updateStatus(orderId, status);
}
public OrderVO getOrderDetail(Integer orderId) {
Orders order = ordersMapper.findById(orderId);
if (order == null) {
throw new BusinessException(ErrorCode.NOT_FOUND);
}
OrderVO vo = new OrderVO();
BeanUtils.copyProperties(order, vo);
List<OrderItem> items = orderItemMapper.findByOrderId(orderId);
List<OrderItemVO> itemVOs = new ArrayList<>();
for (OrderItem item : items) {
OrderItemVO itemVO = new OrderItemVO();
BeanUtils.copyProperties(item, itemVO);
Book book = bookMapper.findById(item.getBookId());
if (book != null) itemVO.setBookTitle(book.getTitle());
itemVOs.add(itemVO);
}
vo.setItems(itemVOs);
return vo;
}
}

View File

@ -0,0 +1,14 @@
package com.grtsinry43.bookmanagement.vo;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class OrderItemVO {
private Integer orderItemId;
private Integer bookId;
private String bookTitle;
private Integer quantity;
private BigDecimal unitPrice;
}

View File

@ -0,0 +1,18 @@
package com.grtsinry43.bookmanagement.vo;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class OrderVO {
private Integer orderId;
private Integer readerId;
private String readerName;
private LocalDateTime orderDate;
private BigDecimal totalAmount;
private String status;
private List<OrderItemVO> items;
}