refactor(admin-book): rename Result to ApiResult and tighten return types
- Replace `Result` with `ApiResult` across admin book/borrow modules - Change return type from `Result<Any?>` to `ApiResult<String>` - Reformat multi-arg log statements for readability
This commit is contained in:
@@ -27,6 +27,7 @@ dependencies {
|
||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||
implementation("org.aspectj:aspectjweaver")
|
||||
implementation("org.springframework.security:spring-security-crypto")
|
||||
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:3.0.3")
|
||||
implementation("org.bouncycastle:bcprov-jdk18on:1.84")
|
||||
implementation("com.mysql:mysql-connector-j")
|
||||
implementation("com.baomidou:mybatis-plus-spring-boot4-starter:3.5.15")
|
||||
|
||||
@@ -3,10 +3,10 @@ package com.msksbr.bookmgr.config
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
|
||||
/*
|
||||
* 全局异常处理,将未捕获异常统一转为 Result 格式,避免泄露堆栈信息
|
||||
* 全局异常处理,将未捕获异常统一转为 ApiResult 格式,避免泄露堆栈信息
|
||||
*
|
||||
* 返回格式:
|
||||
* {"code":500,"message":"Internal server error"}
|
||||
@@ -14,8 +14,8 @@ import com.msksbr.bookmgr.template.Result
|
||||
@RestControllerAdvice
|
||||
class GlobalExceptionHandler {
|
||||
@ExceptionHandler(Exception::class)
|
||||
fun handle(ex: Exception): Result<Any?>{
|
||||
fun handle(ex: Exception): ApiResult<Any?>{
|
||||
log.error("[Global] unhandled exception: {}", ex.message)
|
||||
return Result.error("Internal server error")
|
||||
return ApiResult.error("Internal server error")
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package com.msksbr.bookmgr.config
|
||||
|
||||
import com.msksbr.bookmgr.annotation.RequireRole
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
import org.aspectj.lang.ProceedingJoinPoint
|
||||
import org.aspectj.lang.annotation.Around
|
||||
import org.aspectj.lang.annotation.Aspect
|
||||
@@ -44,7 +44,7 @@ class RequireRoleAspect(
|
||||
|
||||
if (username == null) {
|
||||
log.warn("[AUDIT] unauthenticated | ip={} | path={} | required={}", ip, path, requireRole.role)
|
||||
return Result.unauthorized("Missing or invalid token")
|
||||
return ApiResult.unauthorized<Any?>("Missing or invalid token")
|
||||
}
|
||||
|
||||
val allowedRoles = rolePermissions[role] ?: emptySet()
|
||||
@@ -53,7 +53,7 @@ class RequireRoleAspect(
|
||||
"[AUDIT] access denied | user={} | ip={} | path={} | required={} | actual={}",
|
||||
username, ip, path, requireRole.role, role
|
||||
)
|
||||
return Result.forbidden("Access denied: insufficient permissions")
|
||||
return ApiResult.forbidden<Any?>("Access denied: insufficient permissions")
|
||||
}
|
||||
log.info("[AUDIT] access allowed | user={} | ip={} | path={} | role={}",
|
||||
username, ip, path, role)
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.msksbr.bookmgr.dto.BookAddDto
|
||||
import com.msksbr.bookmgr.dto.BookUpdateDto
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import com.msksbr.bookmgr.service.AdminBookService
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.web.bind.annotation.*
|
||||
@@ -35,8 +35,13 @@ class AdminBookController(private val adminBookService: AdminBookService, privat
|
||||
bookAddDto: BookAddDto,
|
||||
request: HttpServletRequest,
|
||||
@RequestAttribute(required = false) username: String?
|
||||
): Result<Any?> {
|
||||
log.info("[AdminBook] add: user={}, name={}, author={}", username ?: "guest", bookAddDto.name, bookAddDto.author)
|
||||
): ApiResult<String> {
|
||||
log.info(
|
||||
"[AdminBook] add: user={}, name={}, author={}",
|
||||
username ?: "guest",
|
||||
bookAddDto.name,
|
||||
bookAddDto.author
|
||||
)
|
||||
log.info("[AdminBook] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return adminBookService.addBook(bookAddDto)
|
||||
}
|
||||
@@ -50,7 +55,7 @@ class AdminBookController(private val adminBookService: AdminBookService, privat
|
||||
bookUpdateDto: BookUpdateDto,
|
||||
request: HttpServletRequest,
|
||||
@RequestAttribute(required = false) username: String?
|
||||
): Result<Any?> {
|
||||
): ApiResult<String> {
|
||||
log.info("[AdminBook] update: user={}, id={}", username ?: "guest", id)
|
||||
log.info("[AdminBook] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return adminBookService.updateBook(id, bookUpdateDto)
|
||||
@@ -62,7 +67,7 @@ class AdminBookController(private val adminBookService: AdminBookService, privat
|
||||
id: Long,
|
||||
request: HttpServletRequest,
|
||||
@RequestAttribute(required = false) username: String?
|
||||
): Result<Any?> {
|
||||
): ApiResult<String> {
|
||||
log.info("[AdminBook] delete: user={}, id={}", username ?: "guest", id)
|
||||
log.info("[AdminBook] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return adminBookService.deleteBook(id)
|
||||
@@ -75,7 +80,7 @@ class AdminBookController(private val adminBookService: AdminBookService, privat
|
||||
stock: Int,
|
||||
request: HttpServletRequest,
|
||||
@RequestAttribute(required = false) username: String?
|
||||
): Result<Any?> {
|
||||
): ApiResult<String> {
|
||||
log.info("[AdminBook] updateStock: user={}, id={}, stock={}", username ?: "guest", id, stock)
|
||||
log.info("[AdminBook] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return adminBookService.updateStock(id, stock)
|
||||
|
||||
@@ -4,7 +4,8 @@ import com.msksbr.bookmgr.annotation.RequireRole
|
||||
import com.msksbr.bookmgr.config.IpExtractor
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import com.msksbr.bookmgr.service.AdminBorrowService
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
import com.msksbr.bookmgr.vo.BorrowInfoVo
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import org.springframework.web.bind.annotation.*
|
||||
|
||||
@@ -37,7 +38,7 @@ class AdminBorrowController(
|
||||
@RequestAttribute(required = false) username: String?,
|
||||
query: String,
|
||||
request: HttpServletRequest
|
||||
): Result<Any?> {
|
||||
): ApiResult<List<BorrowInfoVo>> {
|
||||
log.info("[AdminBorrow] search: user={}, query={}", username ?: "guest", query)
|
||||
log.info("[AdminBorrow] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return adminBorrowService.searchBorrows(query)
|
||||
@@ -53,7 +54,7 @@ class AdminBorrowController(
|
||||
@RequestAttribute(required = false) username: String?,
|
||||
id: Long,
|
||||
request: HttpServletRequest
|
||||
): Result<Any?> {
|
||||
): ApiResult<BorrowInfoVo> {
|
||||
log.info("[AdminBorrow] getOne: user={}, borrow record id={}", username ?: "guest", id)
|
||||
log.info("[AdminBorrow] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return adminBorrowService.getOneBorrow(id)
|
||||
@@ -68,7 +69,7 @@ class AdminBorrowController(
|
||||
fun getAllBorrows(
|
||||
@RequestAttribute(required = false) username: String?,
|
||||
request: HttpServletRequest
|
||||
): Result<Any?> {
|
||||
): ApiResult<List<BorrowInfoVo>> {
|
||||
log.info("[AdminBorrow] getAll: user={}, ip={}", username ?: "guest", ipExtractor.getRealIp(request))
|
||||
log.info("[AdminBorrow] user agent: {}", request.getHeader("User-Agent"))
|
||||
return adminBorrowService.getAllBorrows()
|
||||
@@ -85,7 +86,7 @@ class AdminBorrowController(
|
||||
bookId: Long,
|
||||
userId: Long,
|
||||
request: HttpServletRequest
|
||||
): Result<Any?> {
|
||||
): ApiResult<String> {
|
||||
log.info("[AdminBorrow] borrowBook: user={}, bookId={}, userId={}", username ?: "guest", bookId, userId)
|
||||
log.info("[AdminBorrow] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return adminBorrowService.borrowBook(bookId, userId)
|
||||
@@ -101,7 +102,7 @@ class AdminBorrowController(
|
||||
@RequestAttribute(required = false) username: String?,
|
||||
recordId: Long,
|
||||
request: HttpServletRequest
|
||||
): Result<Any?> {
|
||||
): ApiResult<String> {
|
||||
log.info("[AdminBorrow] returnBook: user={}, recordId={}", username ?: "guest", recordId)
|
||||
log.info("[AdminBorrow] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return adminBorrowService.returnBook(recordId)
|
||||
|
||||
@@ -5,7 +5,8 @@ import com.msksbr.bookmgr.config.JwtUtils
|
||||
import com.msksbr.bookmgr.dto.UserLoginDto
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import com.msksbr.bookmgr.service.AuthService
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
import com.msksbr.bookmgr.vo.LoginVo
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.web.bind.annotation.*
|
||||
@@ -42,7 +43,7 @@ class AuthController(
|
||||
@RequestBody
|
||||
loginDTO: UserLoginDto,
|
||||
request: HttpServletRequest
|
||||
): Result<out Any?> {
|
||||
): ApiResult<LoginVo> {
|
||||
log.info("[Auth] login attempt: user={}, ip={}", loginDTO.username, ipExtractor.getRealIp(request))
|
||||
log.debug("[Auth] user agent: {}", request.getHeader("User-Agent"))
|
||||
val user = authService.login(loginDTO)
|
||||
@@ -50,16 +51,15 @@ class AuthController(
|
||||
// 登录成功,签发 JWT
|
||||
val token = jwtUtils.generateToken(user.username, user.role, user.id!!)
|
||||
log.info("[Auth] login success: user={}", user.username)
|
||||
Result.success(
|
||||
mapOf(
|
||||
"token" to token,
|
||||
"username" to user.username,
|
||||
"role" to user.role
|
||||
)
|
||||
val loginVo = LoginVo(
|
||||
token = token,
|
||||
username = user.username,
|
||||
role = user.role
|
||||
)
|
||||
ApiResult.success(loginVo)
|
||||
} else {
|
||||
log.warn("[Auth] login failed: user={}", loginDTO.username)
|
||||
Result.error("Incorrect username or password")
|
||||
ApiResult.error("Incorrect username or password")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ class AuthController(
|
||||
fun logout(
|
||||
@RequestAttribute(required = false) username: String?,
|
||||
request: HttpServletRequest
|
||||
): Result<String> {
|
||||
): ApiResult<String> {
|
||||
if (username != null) {
|
||||
log.info("[Auth] logout username: {}", username)
|
||||
}
|
||||
@@ -82,6 +82,6 @@ class AuthController(
|
||||
log.debug("[Auth] user agent: {}", request.getHeader("User-Agent"))
|
||||
// JWT 无状态,登出只需客户端删除 token
|
||||
log.info("[Auth] logout success")
|
||||
return Result.success("logout successfully")
|
||||
return ApiResult.success("logout successfully")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package com.msksbr.bookmgr.controller
|
||||
|
||||
import com.msksbr.bookmgr.config.IpExtractor
|
||||
import com.msksbr.bookmgr.entity.Book
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import com.msksbr.bookmgr.service.BookService
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RequestAttribute
|
||||
@@ -26,7 +27,7 @@ class BookController(private val bookService: BookService, private val ipExtract
|
||||
@RequestAttribute(required = false) username: String?,
|
||||
query: String,
|
||||
request: HttpServletRequest
|
||||
): Result<Any?> {
|
||||
): ApiResult<List<Book>> {
|
||||
log.info("[Book] search: user={}, query={}", username ?: "guest", query)
|
||||
log.info("[Book] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return bookService.searchBook(query)
|
||||
@@ -37,7 +38,7 @@ class BookController(private val bookService: BookService, private val ipExtract
|
||||
@RequestAttribute(required = false) username: String?,
|
||||
request: HttpServletRequest,
|
||||
id: Long
|
||||
): Result<Any?> {
|
||||
): ApiResult<Book> {
|
||||
log.info("[Book] getOne: user={}, book id={}", username ?: "guest", id)
|
||||
log.info("[Book] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return bookService.getOneBook(id)
|
||||
@@ -47,7 +48,7 @@ class BookController(private val bookService: BookService, private val ipExtract
|
||||
fun getAllBooks(
|
||||
@RequestAttribute(required = false) username: String?,
|
||||
request: HttpServletRequest
|
||||
): Result<Any?> {
|
||||
): ApiResult<List<Book>> {
|
||||
log.info("[Book] getAll: user={}", username ?: "guest")
|
||||
log.info("[Book] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return bookService.getAllBooks()
|
||||
|
||||
@@ -4,7 +4,8 @@ import com.msksbr.bookmgr.annotation.RequireRole
|
||||
import com.msksbr.bookmgr.config.IpExtractor
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import com.msksbr.bookmgr.service.BorrowService
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
import com.msksbr.bookmgr.vo.MyBorrowVo
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import org.springframework.web.bind.annotation.*
|
||||
|
||||
@@ -37,7 +38,7 @@ class BorrowController(
|
||||
@RequestAttribute(required = false) username: String?,
|
||||
@RequestAttribute(required = false) userId: Long?,
|
||||
request: HttpServletRequest
|
||||
): Result<Any?> {
|
||||
): ApiResult<List<MyBorrowVo>> {
|
||||
log.info("[Borrow] getAll: user={}, userId={}", username ?: "guest", userId)
|
||||
log.info("[Borrow] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return borrowService.getAllMyBorrows(userId!!)
|
||||
@@ -54,7 +55,7 @@ class BorrowController(
|
||||
query: String,
|
||||
@RequestAttribute(required = false) userId: Long?,
|
||||
request: HttpServletRequest
|
||||
): Result<Any?> {
|
||||
): ApiResult<List<MyBorrowVo>> {
|
||||
log.info("[Borrow] search: user={}, userId={}, query={}", username ?: "guest", userId, query)
|
||||
log.info("[Borrow] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return borrowService.searchMyBorrows(query, userId!!)
|
||||
@@ -71,7 +72,7 @@ class BorrowController(
|
||||
borrowId: Long,
|
||||
@RequestAttribute(required = false) userId: Long?,
|
||||
request: HttpServletRequest
|
||||
): Result<Any?> {
|
||||
): ApiResult<MyBorrowVo> {
|
||||
log.info("[Borrow] getOne: user={}, userId={}, borrowId={}", username ?: "guest", userId, borrowId)
|
||||
log.info("[Borrow] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return borrowService.getOneMyBorrow(borrowId, userId!!)
|
||||
@@ -88,7 +89,7 @@ class BorrowController(
|
||||
bookId: Long,
|
||||
@RequestAttribute(required = false) userId: Long?,
|
||||
request: HttpServletRequest
|
||||
): Result<Any?> {
|
||||
): ApiResult<String> {
|
||||
log.info("[Borrow] borrow: user={}, userId={}, bookId={}", username ?: "guest", userId, bookId)
|
||||
log.info("[Borrow] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return borrowService.borrowBookForMe(bookId, userId!!)
|
||||
@@ -105,7 +106,7 @@ class BorrowController(
|
||||
borrowId: Long,
|
||||
@RequestAttribute(required = false) userId: Long?,
|
||||
request: HttpServletRequest
|
||||
): Result<Any?> {
|
||||
): ApiResult<String> {
|
||||
log.info("[Borrow] return: user={}, userId={}, borrowId={}", username ?: "guest", userId, borrowId)
|
||||
log.info("[Borrow] user agent: {}, ip={}", request.getHeader("User-Agent"), ipExtractor.getRealIp(request))
|
||||
return borrowService.returnBookForMe(borrowId, userId!!)
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.msksbr.bookmgr.service
|
||||
|
||||
import com.msksbr.bookmgr.dto.BookAddDto
|
||||
import com.msksbr.bookmgr.dto.BookUpdateDto
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
|
||||
/*
|
||||
* 图书管理服务接口
|
||||
@@ -14,25 +14,28 @@ interface AdminBookService {
|
||||
* @param bookAddDto 包含 name、author、stock
|
||||
* @return 成功返回 200,重复返回 409
|
||||
*/
|
||||
fun addBook(bookAddDto: BookAddDto): Result<Any?>
|
||||
fun addBook(bookAddDto: BookAddDto): ApiResult<String>
|
||||
|
||||
/*
|
||||
* 修改图书信息(名称或作者)
|
||||
* @param id 图书 ID
|
||||
* @param bookUpdateDto 包含可选的 name 和 author
|
||||
* @return 成功返回 200,不存在返回 500,重复返回 409
|
||||
*/
|
||||
fun updateBook(id: Long, bookUpdateDto: BookUpdateDto): Result<Any?>
|
||||
fun updateBook(id: Long, bookUpdateDto: BookUpdateDto): ApiResult<String>
|
||||
|
||||
/*
|
||||
* 删除图书
|
||||
* @param id 图书 ID
|
||||
* @return 成功返回 200,不存在返回 500
|
||||
*/
|
||||
fun deleteBook(id: Long): Result<Any?>
|
||||
fun deleteBook(id: Long): ApiResult<String>
|
||||
|
||||
/*
|
||||
* 调整库存
|
||||
* @param id 图书 ID
|
||||
* @param stock 新的库存数量,必须大于 0
|
||||
* @return 成功返回 200,不存在或库存不合法返回 500
|
||||
*/
|
||||
fun updateStock(id: Long, stock: Int): Result<Any?>
|
||||
fun updateStock(id: Long, stock: Int): ApiResult<String>
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.msksbr.bookmgr.service
|
||||
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
import com.msksbr.bookmgr.vo.BorrowInfoVo
|
||||
|
||||
/*
|
||||
* 借阅管理服务接口
|
||||
@@ -12,20 +13,20 @@ interface AdminBorrowService {
|
||||
* @param query 搜索关键词,按书名或用户名模糊匹配
|
||||
* @return 匹配的借阅记录列表
|
||||
*/
|
||||
fun searchBorrows(query: String): Result<Any?>
|
||||
fun searchBorrows(query: String): ApiResult<List<BorrowInfoVo>>
|
||||
|
||||
/*
|
||||
* 查询单条借阅记录
|
||||
* @param id 借阅记录 ID
|
||||
* @return 借阅记录详情,含关联的图书和用户信息
|
||||
*/
|
||||
fun getOneBorrow(id: Long): Result<Any?>
|
||||
fun getOneBorrow(id: Long): ApiResult<BorrowInfoVo>
|
||||
|
||||
/*
|
||||
* 查询全部借阅记录
|
||||
* @return 所有借阅记录,含关联的图书和用户信息
|
||||
*/
|
||||
fun getAllBorrows(): Result<Any?>
|
||||
fun getAllBorrows(): ApiResult<List<BorrowInfoVo>>
|
||||
|
||||
/*
|
||||
* 管理员手动借书
|
||||
@@ -33,12 +34,12 @@ interface AdminBorrowService {
|
||||
* @param userId 借书的用户 ID
|
||||
* @return 借阅结果
|
||||
*/
|
||||
fun borrowBook(bookId: Long, userId: Long): Result<Any?>
|
||||
fun borrowBook(bookId: Long, userId: Long): ApiResult<String>
|
||||
|
||||
/*
|
||||
* 管理员手动还书
|
||||
* @param recordId 借阅记录 ID
|
||||
* @return 归还结果
|
||||
*/
|
||||
fun returnBook(recordId: Long): Result<Any?>
|
||||
fun returnBook(recordId: Long): ApiResult<String>
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.msksbr.bookmgr.service
|
||||
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.entity.Book
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
|
||||
/*
|
||||
* 图书服务接口
|
||||
@@ -12,17 +13,17 @@ interface BookService {
|
||||
* @param query 搜索关键词,不可为空
|
||||
* @return 搜索结果列表,无匹配时返回 404
|
||||
*/
|
||||
fun searchBook(query: String): Result<Any?>
|
||||
fun searchBook(query: String): ApiResult<List<Book>>
|
||||
|
||||
/*
|
||||
* 根据 ID 查询单本图书
|
||||
* @param id 图书 ID,必须为正整数
|
||||
* @return 图书实体,不存在时返回 404
|
||||
*/
|
||||
fun getOneBook(id: Long): Result<Any?>
|
||||
fun getOneBook(id: Long): ApiResult<Book>
|
||||
/*
|
||||
* 查询全部图书列表
|
||||
* @return 所有图书的列表
|
||||
*/
|
||||
fun getAllBooks(): Result<Any?>
|
||||
fun getAllBooks(): ApiResult<List<Book>>
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.msksbr.bookmgr.service
|
||||
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
import com.msksbr.bookmgr.vo.MyBorrowVo
|
||||
|
||||
/*
|
||||
* 借阅服务接口
|
||||
@@ -12,7 +13,7 @@ interface BorrowService {
|
||||
* @param userId 当前用户的 ID
|
||||
* @return 该用户的所有借阅记录
|
||||
*/
|
||||
fun getAllMyBorrows(userId: Long): Result<Any?>
|
||||
fun getAllMyBorrows(userId: Long): ApiResult<List<MyBorrowVo>>
|
||||
|
||||
/*
|
||||
* 搜索当前用户的借阅记录
|
||||
@@ -20,7 +21,7 @@ interface BorrowService {
|
||||
* @param userId 当前用户的 ID
|
||||
* @return 匹配的借阅记录列表
|
||||
*/
|
||||
fun searchMyBorrows(query: String, userId: Long): Result<Any?>
|
||||
fun searchMyBorrows(query: String, userId: Long): ApiResult<List<MyBorrowVo>>
|
||||
|
||||
/*
|
||||
* 查询单条借阅记录
|
||||
@@ -28,7 +29,7 @@ interface BorrowService {
|
||||
* @param userId 当前用户的 ID
|
||||
* @return 借阅记录详情
|
||||
*/
|
||||
fun getOneMyBorrow(borrowId: Long, userId: Long): Result<Any?>
|
||||
fun getOneMyBorrow(borrowId: Long, userId: Long): ApiResult<MyBorrowVo>
|
||||
|
||||
/*
|
||||
* 借书
|
||||
@@ -36,7 +37,7 @@ interface BorrowService {
|
||||
* @param userId 当前用户的 ID
|
||||
* @return 借阅结果
|
||||
*/
|
||||
fun borrowBookForMe(bookId: Long, userId: Long): Result<Any?>
|
||||
fun borrowBookForMe(bookId: Long, userId: Long): ApiResult<String>
|
||||
|
||||
/*
|
||||
* 还书
|
||||
@@ -44,5 +45,5 @@ interface BorrowService {
|
||||
* @param userId 当前用户的 ID
|
||||
* @return 归还结果
|
||||
*/
|
||||
fun returnBookForMe(borrowId: Long, userId: Long): Result<Any?>
|
||||
fun returnBookForMe(borrowId: Long, userId: Long): ApiResult<String>
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.msksbr.bookmgr.entity.Book
|
||||
import com.msksbr.bookmgr.mapper.BookMapper
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import com.msksbr.bookmgr.service.AdminBookService
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
/*
|
||||
@@ -16,7 +16,7 @@ import org.springframework.stereotype.Service
|
||||
*/
|
||||
@Service
|
||||
class AdminBookServiceImpl(private val bookMapper: BookMapper) : AdminBookService {
|
||||
override fun addBook(bookAddDto: BookAddDto): Result<Any?> {
|
||||
override fun addBook(bookAddDto: BookAddDto): ApiResult<String> {
|
||||
val book = Book(
|
||||
id = null,
|
||||
name = bookAddDto.name,
|
||||
@@ -25,25 +25,25 @@ class AdminBookServiceImpl(private val bookMapper: BookMapper) : AdminBookServic
|
||||
)
|
||||
if (isBookDuplicate(book)) {
|
||||
log.warn("[AdminBook] add: duplicate book, name={}, author={}", book.name, book.author)
|
||||
return Result.conflict("Book already exists, please update the stock instead")
|
||||
return ApiResult.conflict("Book already exists, please update the stock instead")
|
||||
}
|
||||
bookMapper.insert(book)
|
||||
log.info("[AdminBook] add: success, id={}, name={}", book.id, book.name)
|
||||
return Result.success("Book added successfully")
|
||||
return ApiResult.success("Book added successfully")
|
||||
}
|
||||
|
||||
override fun updateBook(
|
||||
id: Long,
|
||||
bookUpdateDto: BookUpdateDto
|
||||
): Result<Any?> {
|
||||
): ApiResult<String> {
|
||||
if (bookUpdateDto.name.isBlank() && bookUpdateDto.author.isBlank()) {
|
||||
log.warn("[AdminBook] update: both name and author are blank, id={}", id)
|
||||
return Result.error("At least one of name or author must be provided")
|
||||
return ApiResult.error("At least one of name or author must be provided")
|
||||
}
|
||||
val existing = bookMapper.selectById(id)
|
||||
?: run {
|
||||
log.warn("[AdminBook] update: book not found, id={}", id)
|
||||
return Result.error("Book does not exist")
|
||||
return ApiResult.error("Book does not exist")
|
||||
}
|
||||
val book = Book(
|
||||
id = id,
|
||||
@@ -53,33 +53,33 @@ class AdminBookServiceImpl(private val bookMapper: BookMapper) : AdminBookServic
|
||||
)
|
||||
if (isBookDuplicate(book, book.id)) {
|
||||
log.warn("[AdminBook] update: duplicate book, name={}, author={}", book.name, book.author)
|
||||
return Result.conflict("Book already exists, please update the stock instead")
|
||||
return ApiResult.conflict("Book already exists, please update the stock instead")
|
||||
}
|
||||
bookMapper.updateById(book)
|
||||
log.info("[AdminBook] update: success, id={}", book.id)
|
||||
return Result.success("Book updated successfully")
|
||||
return ApiResult.success("Book updated successfully")
|
||||
}
|
||||
|
||||
override fun deleteBook(id: Long): Result<Any?> {
|
||||
override fun deleteBook(id: Long): ApiResult<String> {
|
||||
val existing = bookMapper.selectById(id)
|
||||
?: run {
|
||||
log.warn("[AdminBook] delete: book not found, id={}", id)
|
||||
return Result.error("Book does not exist")
|
||||
return ApiResult.error("Book does not exist")
|
||||
}
|
||||
bookMapper.deleteById(id)
|
||||
log.info("[AdminBook] delete: success, id={}, name={}", id, existing.name)
|
||||
return Result.success("Book deleted successfully")
|
||||
return ApiResult.success("Book deleted successfully")
|
||||
}
|
||||
|
||||
override fun updateStock(id: Long, stock: Int): Result<Any?> {
|
||||
override fun updateStock(id: Long, stock: Int): ApiResult<String> {
|
||||
if (stock <= 0) {
|
||||
log.warn("[AdminBook] updateStock: invalid stock={}, id={}", stock, id)
|
||||
return Result.error("Stock must be greater than zero")
|
||||
return ApiResult.error("Stock must be greater than zero")
|
||||
}
|
||||
val existing = bookMapper.selectById(id)
|
||||
?: run {
|
||||
log.warn("[AdminBook] updateStock: book not found, id={}", id)
|
||||
return Result.error("Book does not exist")
|
||||
return ApiResult.error("Book does not exist")
|
||||
}
|
||||
val book = Book(
|
||||
id = id,
|
||||
@@ -89,7 +89,7 @@ class AdminBookServiceImpl(private val bookMapper: BookMapper) : AdminBookServic
|
||||
)
|
||||
bookMapper.updateById(book)
|
||||
log.debug("[AdminBook] updateStock: success, id={}, stock={}", id, stock)
|
||||
return Result.success("Book updated successfully")
|
||||
return ApiResult.success("Book updated successfully")
|
||||
}
|
||||
|
||||
// 查询是否有书名和作者完全相同的书
|
||||
|
||||
@@ -9,7 +9,7 @@ import com.msksbr.bookmgr.mapper.BorrowRecordMapper
|
||||
import com.msksbr.bookmgr.mapper.UserMapper
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import com.msksbr.bookmgr.service.AdminBorrowService
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
import com.msksbr.bookmgr.vo.BorrowInfoVo
|
||||
import com.msksbr.bookmgr.vo.borrow.BookBorrowVo
|
||||
import com.msksbr.bookmgr.vo.borrow.UserBorrowVo
|
||||
@@ -34,10 +34,10 @@ class AdminBorrowServiceImpl(
|
||||
* 搜索借阅记录:并发查询 user 表和 book 表,按用户名、角色、书名或作者匹配
|
||||
* 将匹配到的 userId / bookId 取并集后查询借阅记录,降序排列
|
||||
*/
|
||||
override fun searchBorrows(query: String): Result<Any?> {
|
||||
override fun searchBorrows(query: String): ApiResult<List<BorrowInfoVo>> {
|
||||
if (query.isBlank()) {
|
||||
log.warn("[AdminBorrow] search: query is blank")
|
||||
return Result.error("Search query cannot be empty")
|
||||
return ApiResult.error("Search query cannot be empty")
|
||||
}
|
||||
val (matchedUserIds, matchedBookIds) = runBlocking {
|
||||
val userDeferred = async(Dispatchers.IO) {
|
||||
@@ -60,7 +60,7 @@ class AdminBorrowServiceImpl(
|
||||
}
|
||||
if (matchedUserIds.isEmpty() && matchedBookIds.isEmpty()) {
|
||||
log.info("[AdminBorrow] search: no results for {}", query)
|
||||
return Result.notFound("No matching borrow records found")
|
||||
return ApiResult.notFound("No matching borrow records found")
|
||||
}
|
||||
val borrows = borrowRecordMapper.selectList(
|
||||
QueryWrapper<BorrowRecord>()
|
||||
@@ -75,17 +75,17 @@ class AdminBorrowServiceImpl(
|
||||
buildBorrowVos(borrows, userIds, bookIds)
|
||||
}
|
||||
log.info("[AdminBorrow] search: found {} records for {}", result.size, query)
|
||||
return Result.success(result)
|
||||
return ApiResult.success(result)
|
||||
}
|
||||
|
||||
/*
|
||||
* 查询单条借阅记录,含关联的图书和用户信息
|
||||
*/
|
||||
override fun getOneBorrow(id: Long): Result<Any?> {
|
||||
override fun getOneBorrow(id: Long): ApiResult<BorrowInfoVo> {
|
||||
val borrow = borrowRecordMapper.selectById(id)
|
||||
if (borrow == null) {
|
||||
log.info("[AdminBorrow] getOne: no record for id={}", id)
|
||||
return Result.notFound("Borrow record not found")
|
||||
return ApiResult.notFound("Borrow record not found")
|
||||
}
|
||||
val user = userMapper.selectById(borrow.userId)
|
||||
val book = bookMapper.selectById(borrow.bookId)
|
||||
@@ -106,17 +106,17 @@ class AdminBorrowServiceImpl(
|
||||
)
|
||||
)
|
||||
log.info("[AdminBorrow] getOne: found record id={}, user={}, book={}", id, user.username, book.name)
|
||||
return Result.success(result)
|
||||
return ApiResult.success(result)
|
||||
}
|
||||
|
||||
/*
|
||||
* 查询全部借阅记录,并发加载关联的用户和图书信息
|
||||
*/
|
||||
override fun getAllBorrows(): Result<Any?> {
|
||||
override fun getAllBorrows(): ApiResult<List<BorrowInfoVo>> {
|
||||
val borrows = borrowRecordMapper.selectList(null)
|
||||
if (borrows.isEmpty()) {
|
||||
log.info("[AdminBorrow] getAll: no records")
|
||||
return Result.notFound("No borrow records found")
|
||||
return ApiResult.notFound("No borrow records found")
|
||||
}
|
||||
val userIds = borrows.map { it.userId }.distinct()
|
||||
val bookIds = borrows.map { it.bookId }.distinct()
|
||||
@@ -125,13 +125,13 @@ class AdminBorrowServiceImpl(
|
||||
val result = runBlocking { buildBorrowVos(borrows, userIds, bookIds) }
|
||||
|
||||
log.info("[AdminBorrow] getAll: found {} records", result.size)
|
||||
return Result.success(result)
|
||||
return ApiResult.success(result)
|
||||
}
|
||||
|
||||
/*
|
||||
* 管理员手动借书
|
||||
*/
|
||||
override fun borrowBook(bookId: Long, userId: Long): Result<Any?> {
|
||||
override fun borrowBook(bookId: Long, userId: Long): ApiResult<String> {
|
||||
val (matchedUser, matchedBook) = runBlocking {
|
||||
val userDeferred = async(Dispatchers.IO) {
|
||||
userMapper.selectById(userId)
|
||||
@@ -143,15 +143,15 @@ class AdminBorrowServiceImpl(
|
||||
}
|
||||
if (matchedUser == null) {
|
||||
log.warn("[AdminBorrow] borrowBook: user not found, userId={}", userId)
|
||||
return Result.error("User does not exist")
|
||||
return ApiResult.error("User does not exist")
|
||||
}
|
||||
if (matchedBook == null) {
|
||||
log.warn("[AdminBorrow] borrowBook: book not found, bookId={}", bookId)
|
||||
return Result.error("Book does not exist")
|
||||
return ApiResult.error("Book does not exist")
|
||||
}
|
||||
if (matchedBook.stock < 1) {
|
||||
log.warn("[AdminBorrow] borrowBook: book out of stock, bookId={}, stock={}", bookId, matchedBook.stock)
|
||||
return Result.conflict("Book is out of stock")
|
||||
return ApiResult.conflict("Book is out of stock")
|
||||
}
|
||||
val book = Book(
|
||||
id = matchedBook.id,
|
||||
@@ -170,21 +170,21 @@ class AdminBorrowServiceImpl(
|
||||
bookMapper.updateById(book)
|
||||
borrowRecordMapper.insert(borrow)
|
||||
log.info("[AdminBorrow] borrowBook: success, userId={}, bookId={}, book={}", userId, bookId, matchedBook.name)
|
||||
return Result.success("Book borrowed successfully")
|
||||
return ApiResult.success("Book borrowed successfully")
|
||||
}
|
||||
|
||||
/*
|
||||
* 管理员手动还书
|
||||
*/
|
||||
override fun returnBook(recordId: Long): Result<Any?> {
|
||||
override fun returnBook(recordId: Long): ApiResult<String> {
|
||||
val matchedBorrow = borrowRecordMapper.selectById(recordId)
|
||||
if (matchedBorrow == null) {
|
||||
log.warn("[AdminBorrow] returnBook: record not found, recordId={}", recordId)
|
||||
return Result.error("Borrow record does not exist")
|
||||
return ApiResult.error("Borrow record does not exist")
|
||||
}
|
||||
if (matchedBorrow.status == "RETURNED") {
|
||||
log.warn("[AdminBorrow] returnBook: already returned, recordId={}", recordId)
|
||||
return Result.conflict("Book has already been returned")
|
||||
return ApiResult.conflict("Book has already been returned")
|
||||
}
|
||||
val borrow = BorrowRecord(
|
||||
id = matchedBorrow.id,
|
||||
@@ -197,7 +197,7 @@ class AdminBorrowServiceImpl(
|
||||
val matchedBook = bookMapper.selectById(matchedBorrow.bookId)
|
||||
if (matchedBook == null) {
|
||||
log.warn("[AdminBorrow] returnBook: book not found, bookId={}", matchedBorrow.bookId)
|
||||
return Result.error("Book does not exist")
|
||||
return ApiResult.error("Book does not exist")
|
||||
}
|
||||
val book = Book(
|
||||
id = matchedBook.id,
|
||||
@@ -208,7 +208,7 @@ class AdminBorrowServiceImpl(
|
||||
bookMapper.updateById(book)
|
||||
borrowRecordMapper.updateById(borrow)
|
||||
log.info("[AdminBorrow] returnBook: success, recordId={}, userId={}, book={}", recordId, borrow.userId, matchedBook.name)
|
||||
return Result.success("Book returned successfully")
|
||||
return ApiResult.success("Book returned successfully")
|
||||
}
|
||||
|
||||
// 并发查询用户和图书信息,组装为 BorrowInfoVo 列表
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.msksbr.bookmgr.entity.Book
|
||||
import com.msksbr.bookmgr.mapper.BookMapper
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import com.msksbr.bookmgr.service.BookService
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
/*
|
||||
@@ -14,10 +14,10 @@ import org.springframework.stereotype.Service
|
||||
*/
|
||||
@Service
|
||||
class BookServiceImpl(private val bookMapper: BookMapper) : BookService {
|
||||
override fun searchBook(query: String): Result<Any?> {
|
||||
override fun searchBook(query: String): ApiResult<List<Book>> {
|
||||
if (query.isBlank()) {
|
||||
log.warn("[Book] search: query is blank")
|
||||
return Result.error("Search query cannot be empty")
|
||||
return ApiResult.error("Search query cannot be empty")
|
||||
}
|
||||
val result = bookMapper.selectList(
|
||||
QueryWrapper<Book>()
|
||||
@@ -27,16 +27,16 @@ class BookServiceImpl(private val bookMapper: BookMapper) : BookService {
|
||||
)
|
||||
if (result.isEmpty()) {
|
||||
log.info("[Book] search: no results for {}", query)
|
||||
return Result.notFound("No matching books found")
|
||||
return ApiResult.notFound("No matching books found")
|
||||
}
|
||||
log.info("[Book] search: found {} results for {}", result.size, query)
|
||||
return Result.success(result)
|
||||
return ApiResult.success(result)
|
||||
}
|
||||
|
||||
override fun getOneBook(id: Long): Result<Any?> {
|
||||
override fun getOneBook(id: Long): ApiResult<Book> {
|
||||
if (id < 1) {
|
||||
log.warn("[Book] getOne: invalid id={}", id)
|
||||
return Result.error("Invalid book ID")
|
||||
return ApiResult.error("Invalid book ID")
|
||||
}
|
||||
val result = bookMapper.selectOne(
|
||||
QueryWrapper<Book>()
|
||||
@@ -44,15 +44,15 @@ class BookServiceImpl(private val bookMapper: BookMapper) : BookService {
|
||||
)
|
||||
if (result == null) {
|
||||
log.info("[Book] getOneBook: no results for {}", id)
|
||||
return Result.notFound("Book not found")
|
||||
return ApiResult.notFound("Book not found")
|
||||
}
|
||||
log.info("[Book] getOne: found {}, author={}", result.name, result.author)
|
||||
return Result.success(result)
|
||||
return ApiResult.success(result)
|
||||
}
|
||||
|
||||
override fun getAllBooks(): Result<Any?> {
|
||||
override fun getAllBooks(): ApiResult<List<Book>> {
|
||||
val books = bookMapper.selectList(null)
|
||||
log.info("[Book] getAll: found {} books", books.size)
|
||||
return Result.success(books)
|
||||
return ApiResult.success(books)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.msksbr.bookmgr.mapper.BookMapper
|
||||
import com.msksbr.bookmgr.mapper.BorrowRecordMapper
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import com.msksbr.bookmgr.service.BorrowService
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import com.msksbr.bookmgr.template.ApiResult
|
||||
import com.msksbr.bookmgr.vo.MyBorrowVo
|
||||
import com.msksbr.bookmgr.vo.borrow.BookBorrowVo
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -28,18 +28,18 @@ class BorrowServiceImpl(
|
||||
/*
|
||||
* 查询当前用户的所有借阅记录
|
||||
*/
|
||||
override fun getAllMyBorrows(userId: Long): Result<Any?> {
|
||||
override fun getAllMyBorrows(userId: Long): ApiResult<List<MyBorrowVo>> {
|
||||
val borrows = borrowRecordMapper.selectList(
|
||||
QueryWrapper<BorrowRecord>().eq("user_id", userId).orderByDesc("borrow_time")
|
||||
)
|
||||
if (borrows.isEmpty()) {
|
||||
log.info("[Borrow] getAll: no records for userId={}", userId)
|
||||
return Result.notFound("No borrow records found")
|
||||
return ApiResult.notFound("No borrow records found")
|
||||
}
|
||||
val bookIds = borrows.map { it.bookId }.distinct()
|
||||
val result = runBlocking { buildMyBorrowVos(borrows, bookIds) }
|
||||
log.info("[Borrow] getAll: found {} records for userId={}", result.size, userId)
|
||||
return Result.success(result)
|
||||
return ApiResult.success(result)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -48,10 +48,10 @@ class BorrowServiceImpl(
|
||||
override fun searchMyBorrows(
|
||||
query: String,
|
||||
userId: Long
|
||||
): Result<Any?> {
|
||||
): ApiResult<List<MyBorrowVo>> {
|
||||
if (query.isBlank()) {
|
||||
log.warn("[Borrow] search: query is blank")
|
||||
return Result.error("Search query cannot be empty")
|
||||
return ApiResult.error("Search query cannot be empty")
|
||||
}
|
||||
val matchedBookIds = bookMapper.selectList(
|
||||
QueryWrapper<Book>()
|
||||
@@ -61,7 +61,7 @@ class BorrowServiceImpl(
|
||||
).map { it.id }
|
||||
if (matchedBookIds.isEmpty()) {
|
||||
log.info("[Borrow] search: no results for {}", query)
|
||||
return Result.notFound("No matching borrow records found")
|
||||
return ApiResult.notFound("No matching borrow records found")
|
||||
}
|
||||
val borrows = borrowRecordMapper.selectList(
|
||||
QueryWrapper<BorrowRecord>()
|
||||
@@ -71,12 +71,12 @@ class BorrowServiceImpl(
|
||||
)
|
||||
if (borrows.isEmpty()) {
|
||||
log.info("[Borrow] search: no borrows match for userId={}, query={}", userId, query)
|
||||
return Result.notFound("No matching borrow records found")
|
||||
return ApiResult.notFound("No matching borrow records found")
|
||||
}
|
||||
val bookIds = borrows.map { it.bookId }.distinct()
|
||||
val result = runBlocking { buildMyBorrowVos(borrows, bookIds) }
|
||||
log.info("[Borrow] search: found {} records for userId={}, query={}", result.size, userId, query)
|
||||
return Result.success(result)
|
||||
return ApiResult.success(result)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -85,18 +85,18 @@ class BorrowServiceImpl(
|
||||
override fun getOneMyBorrow(
|
||||
borrowId: Long,
|
||||
userId: Long
|
||||
): Result<Any?> {
|
||||
): ApiResult<MyBorrowVo> {
|
||||
val borrow = borrowRecordMapper.selectById(borrowId)
|
||||
if (borrow == null) {
|
||||
log.info("[Borrow] getOne: record not found, borrowId={}", borrowId)
|
||||
return Result.notFound("Borrow record not found")
|
||||
return ApiResult.notFound("Borrow record not found")
|
||||
}
|
||||
if (borrow.userId != userId) {
|
||||
log.warn(
|
||||
"[Borrow] getOne: OWNERSHIP MISMATCH — userId={} attempted to access borrowId={} belonging to userId={}, bookId={}, status={}",
|
||||
userId, borrowId, borrow.userId, borrow.bookId, borrow.status
|
||||
)
|
||||
return Result.notFound("Borrow record not found")
|
||||
return ApiResult.notFound("Borrow record not found")
|
||||
}
|
||||
val book = bookMapper.selectById(borrow.bookId)
|
||||
val result = MyBorrowVo(
|
||||
@@ -109,7 +109,7 @@ class BorrowServiceImpl(
|
||||
} ?: BookBorrowVo()
|
||||
)
|
||||
log.info("[Borrow] getOne: found record borrowId={}, userId={}, book={}", borrowId, userId, book?.name)
|
||||
return Result.success(result)
|
||||
return ApiResult.success(result)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -118,15 +118,15 @@ class BorrowServiceImpl(
|
||||
override fun borrowBookForMe(
|
||||
bookId: Long,
|
||||
userId: Long
|
||||
): Result<Any?> {
|
||||
): ApiResult<String> {
|
||||
val matchedBook = bookMapper.selectById(bookId)
|
||||
if (matchedBook == null) {
|
||||
log.warn("[Borrow] borrow: book not found, bookId={}", bookId)
|
||||
return Result.error("Book does not exist")
|
||||
return ApiResult.error("Book does not exist")
|
||||
}
|
||||
if (matchedBook.stock < 1) {
|
||||
log.warn("[Borrow] borrow: book out of stock, bookId={}, stock={}", bookId, matchedBook.stock)
|
||||
return Result.conflict("Book is out of stock")
|
||||
return ApiResult.conflict("Book is out of stock")
|
||||
}
|
||||
val book = Book(
|
||||
id = matchedBook.id,
|
||||
@@ -145,7 +145,7 @@ class BorrowServiceImpl(
|
||||
bookMapper.updateById(book)
|
||||
borrowRecordMapper.insert(borrow)
|
||||
log.info("[Borrow] borrow: success, userId={}, bookId={}, book={}", userId, bookId, matchedBook.name)
|
||||
return Result.success("Book borrowed successfully")
|
||||
return ApiResult.success("Book borrowed successfully")
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -154,22 +154,22 @@ class BorrowServiceImpl(
|
||||
override fun returnBookForMe(
|
||||
borrowId: Long,
|
||||
userId: Long
|
||||
): Result<Any?> {
|
||||
): ApiResult<String> {
|
||||
val matchedBorrow = borrowRecordMapper.selectById(borrowId)
|
||||
if (matchedBorrow == null) {
|
||||
log.warn("[Borrow] return: record not found, borrowId={}", borrowId)
|
||||
return Result.error("Borrow record does not exist")
|
||||
return ApiResult.error("Borrow record does not exist")
|
||||
}
|
||||
if (matchedBorrow.userId != userId) {
|
||||
log.warn(
|
||||
"[Borrow] return: OWNERSHIP MISMATCH — userId={} attempted to return borrowId={} belonging to userId={}, bookId={}, status={}",
|
||||
userId, borrowId, matchedBorrow.userId, matchedBorrow.bookId, matchedBorrow.status
|
||||
)
|
||||
return Result.error("Borrow record does not exist")
|
||||
return ApiResult.error("Borrow record does not exist")
|
||||
}
|
||||
if (matchedBorrow.status == "RETURNED") {
|
||||
log.warn("[Borrow] return: already returned, borrowId={}", borrowId)
|
||||
return Result.conflict("Book has already been returned")
|
||||
return ApiResult.conflict("Book has already been returned")
|
||||
}
|
||||
val borrow = BorrowRecord(
|
||||
id = matchedBorrow.id,
|
||||
@@ -182,7 +182,7 @@ class BorrowServiceImpl(
|
||||
val matchedBook = bookMapper.selectById(matchedBorrow.bookId)
|
||||
if (matchedBook == null) {
|
||||
log.warn("[Borrow] return: book not found, bookId={}", matchedBorrow.bookId)
|
||||
return Result.error("Book does not exist")
|
||||
return ApiResult.error("Book does not exist")
|
||||
}
|
||||
val book = Book(
|
||||
id = matchedBook.id,
|
||||
@@ -193,7 +193,7 @@ class BorrowServiceImpl(
|
||||
bookMapper.updateById(book)
|
||||
borrowRecordMapper.updateById(borrow)
|
||||
log.info("[Borrow] return: success, borrowId={}, userId={}, book={}", borrowId, userId, matchedBook.name)
|
||||
return Result.success("Book returned successfully")
|
||||
return ApiResult.success("Book returned successfully")
|
||||
}
|
||||
|
||||
// 并发查询图书信息,组装为 MyBorrowVo 列表
|
||||
|
||||
+13
-13
@@ -13,7 +13,7 @@ package com.msksbr.bookmgr.template
|
||||
* message - 人类可读的提示信息,前端可直接展示
|
||||
* data - 响应数据体,可为 null
|
||||
*/
|
||||
data class Result<T>(
|
||||
data class ApiResult<T>(
|
||||
var code: Int,
|
||||
var message: String,
|
||||
var data: T?
|
||||
@@ -25,8 +25,8 @@ data class Result<T>(
|
||||
*
|
||||
* JSON 输出示例:{ "code": 200, "message": "success", "data": {...} }
|
||||
*/
|
||||
fun <T> success(data: T): Result<T> {
|
||||
return Result(
|
||||
fun <T> success(data: T): ApiResult<T> {
|
||||
return ApiResult(
|
||||
code = 200,
|
||||
message = "success",
|
||||
data = data
|
||||
@@ -39,8 +39,8 @@ data class Result<T>(
|
||||
*
|
||||
* JSON 输出示例:{ "code": 500, "message": "xxx", "data": null }
|
||||
*/
|
||||
fun error(message: String): Result<Any?> {
|
||||
return Result(
|
||||
fun <T> error(message: String): ApiResult<T> {
|
||||
return ApiResult(
|
||||
code = 500,
|
||||
message = message,
|
||||
data = null
|
||||
@@ -53,8 +53,8 @@ data class Result<T>(
|
||||
*
|
||||
* JSON 输出示例:{ "code": 401, "message": "xxx" }
|
||||
*/
|
||||
fun unauthorized(message: String): Result<Any?> {
|
||||
return Result(
|
||||
fun <T> unauthorized(message: String): ApiResult<T> {
|
||||
return ApiResult(
|
||||
code = 401,
|
||||
message = message,
|
||||
data = null
|
||||
@@ -65,8 +65,8 @@ data class Result<T>(
|
||||
* 权限不足响应 — 返回 403
|
||||
* JSON 输出示例:{"code":403,"message":"Access denied: insufficient permissions"}
|
||||
*/
|
||||
fun forbidden(message: String): Result<Any?> {
|
||||
return Result(
|
||||
fun <T> forbidden(message: String): ApiResult<T> {
|
||||
return ApiResult(
|
||||
code = 403,
|
||||
message = message,
|
||||
data = null
|
||||
@@ -79,8 +79,8 @@ data class Result<T>(
|
||||
*
|
||||
* JSON 输出示例:{ "code": 404, "message": "xxx" }
|
||||
*/
|
||||
fun notFound(message: String): Result<Any?> {
|
||||
return Result(
|
||||
fun <T> notFound(message: String): ApiResult<T> {
|
||||
return ApiResult(
|
||||
code = 404,
|
||||
message = message,
|
||||
data = null
|
||||
@@ -93,8 +93,8 @@ data class Result<T>(
|
||||
*
|
||||
* JSON 输出示例:{ "code": 409, "message": "xxx" }
|
||||
*/
|
||||
fun conflict(message: String): Result<Any?> {
|
||||
return Result(
|
||||
fun <T> conflict(message: String): ApiResult<T> {
|
||||
return ApiResult(
|
||||
code = 409,
|
||||
message = message,
|
||||
data = null
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.msksbr.bookmgr.vo
|
||||
|
||||
data class LoginVo(
|
||||
val token: String,
|
||||
val username: String,
|
||||
val role: String
|
||||
)
|
||||
Reference in New Issue
Block a user