diff --git a/src/main/kotlin/top/fatweb/oxygen/api/controller/tool/EditController.kt b/src/main/kotlin/top/fatweb/oxygen/api/controller/tool/EditController.kt index af6335f..318fadd 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/controller/tool/EditController.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/controller/tool/EditController.kt @@ -2,14 +2,12 @@ package top.fatweb.oxygen.api.controller.tool import io.swagger.v3.oas.annotations.Operation import jakarta.validation.Valid -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.PostMapping -import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.* import top.fatweb.oxygen.api.annotation.BaseController import top.fatweb.oxygen.api.entity.common.ResponseCode import top.fatweb.oxygen.api.entity.common.ResponseResult import top.fatweb.oxygen.api.param.tool.ToolCreateParam +import top.fatweb.oxygen.api.param.tool.ToolUpgradeParam import top.fatweb.oxygen.api.service.tool.IEditService import top.fatweb.oxygen.api.vo.tool.ToolCategoryVo import top.fatweb.oxygen.api.vo.tool.ToolTemplateVo @@ -79,6 +77,17 @@ class EditController( fun create(@RequestBody @Valid toolCreateParam: ToolCreateParam): ResponseResult = ResponseResult.databaseSuccess(ResponseCode.DATABASE_INSERT_SUCCESS, data = editService.create(toolCreateParam)) + /** + * Upgrade tool + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ + @Operation(summary = "更新工具") + @PatchMapping + fun upgrade(@RequestBody @Valid toolUpgradeParam: ToolUpgradeParam): ResponseResult = + ResponseResult.databaseSuccess(ResponseCode.DATABASE_UPDATE_SUCCESS, data = editService.upgrade(toolUpgradeParam)) + /** * Get personal tool * @@ -103,4 +112,16 @@ class EditController( ResponseCode.DATABASE_SELECT_SUCCESS, data = editService.detail(username, toolId, ver) ) + + /** + * Delete tool + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ + @Operation(summary = "删除工具") + @DeleteMapping("/{id}") + fun delete(@PathVariable id: Long): ResponseResult = + if (editService.delete(id)) ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS) + else ResponseResult.databaseFail(ResponseCode.DATABASE_DELETE_FAILED) } \ No newline at end of file diff --git a/src/main/kotlin/top/fatweb/oxygen/api/entity/common/BusinessCode.kt b/src/main/kotlin/top/fatweb/oxygen/api/entity/common/BusinessCode.kt index 5c3a4d2..5b1f363 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/entity/common/BusinessCode.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/entity/common/BusinessCode.kt @@ -31,6 +31,14 @@ enum class BusinessCode(val code: Int) { */ DATABASE(300), + /** + * Tool + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ + TOOL(400), + /** * Avatar API * diff --git a/src/main/kotlin/top/fatweb/oxygen/api/entity/common/ResponseCode.kt b/src/main/kotlin/top/fatweb/oxygen/api/entity/common/ResponseCode.kt index 047c15f..738f9ae 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/entity/common/ResponseCode.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/entity/common/ResponseCode.kt @@ -58,6 +58,8 @@ enum class ResponseCode(val code: Int) { DATABASE_DUPLICATE_KEY(BusinessCode.DATABASE, 51), DATABASE_NO_RECORD_FOUND(BusinessCode.DATABASE, 52), + TOOL_ILLEGAL_VERSION(BusinessCode.TOOL, 50), + API_AVATAR_SUCCESS(BusinessCode.API_AVATAR, 0), API_AVATAR_ERROR(BusinessCode.API_AVATAR, 50); diff --git a/src/main/kotlin/top/fatweb/oxygen/api/exception/IllegalVersionException.kt b/src/main/kotlin/top/fatweb/oxygen/api/exception/IllegalVersionException.kt new file mode 100644 index 0000000..3ee96ae --- /dev/null +++ b/src/main/kotlin/top/fatweb/oxygen/api/exception/IllegalVersionException.kt @@ -0,0 +1,3 @@ +package top.fatweb.oxygen.api.exception + +class IllegalVersionException : RuntimeException("Illegal Version") \ No newline at end of file diff --git a/src/main/kotlin/top/fatweb/oxygen/api/handler/ExceptionHandler.kt b/src/main/kotlin/top/fatweb/oxygen/api/handler/ExceptionHandler.kt index 879627a..e558606 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/handler/ExceptionHandler.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/handler/ExceptionHandler.kt @@ -211,6 +211,12 @@ class ExceptionHandler { ResponseResult.fail(ResponseCode.DATABASE_EXECUTE_ERROR, e.localizedMessage, null) } + /* Tool */ + is IllegalVersionException -> { + logger.debug(e.localizedMessage, e) + ResponseResult.fail(ResponseCode.TOOL_ILLEGAL_VERSION, e.localizedMessage, null) + } + /* Other */ is MatchSensitiveWordException -> { logger.debug(e.localizedMessage, e) diff --git a/src/main/kotlin/top/fatweb/oxygen/api/param/tool/ToolUpgradeParam.kt b/src/main/kotlin/top/fatweb/oxygen/api/param/tool/ToolUpgradeParam.kt new file mode 100644 index 0000000..eb140f2 --- /dev/null +++ b/src/main/kotlin/top/fatweb/oxygen/api/param/tool/ToolUpgradeParam.kt @@ -0,0 +1,39 @@ +package top.fatweb.oxygen.api.param.tool + +import io.swagger.v3.oas.annotations.media.Schema +import jakarta.validation.constraints.NotBlank +import jakarta.validation.constraints.Pattern + +/** + * Upgrade tool parameters + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ +@Schema(description = "更新工具请求参数") +data class ToolUpgradeParam( + /** + * Tool ID + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ + @Schema(description = "工具唯一 ID", required = true, example = "tool_a") + @field: NotBlank(message = "ToolId can not be blank") + @field: Pattern( + regexp = "^[a-zA-Z-_][0-9a-zA-Z-_]{2,19}\$", + message = "Ver can only match '^[a-zA-Z-_][0-9a-zA-Z-_]{2,19}\$'" + ) + val toolId: String?, + + /** + * Version + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ + @Schema(description = "版本", required = true, example = "1.0.3") + @field: NotBlank(message = "Ver can not be blank") + @field: Pattern(regexp = "^\\d+\\.\\d+\\.\\d+\$", message = "Ver can only match '..'") + val ver: String? +) diff --git a/src/main/kotlin/top/fatweb/oxygen/api/service/permission/impl/AuthenticationServiceImpl.kt b/src/main/kotlin/top/fatweb/oxygen/api/service/permission/impl/AuthenticationServiceImpl.kt index 45c7a58..f9e4982 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/service/permission/impl/AuthenticationServiceImpl.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/service/permission/impl/AuthenticationServiceImpl.kt @@ -99,7 +99,7 @@ class AuthenticationServiceImpl( @Transactional override fun resend() { - val user = userService.getById(WebUtil.getLoginUserId()) ?: throw AccessDeniedException("Access Denied") + val user = userService.getById(WebUtil.getLoginUserId()) user.verify ?: throw NoVerificationRequiredException() @@ -124,7 +124,7 @@ class AuthenticationServiceImpl( @EventLogRecord(EventLog.Event.VERIFY) @Transactional override fun verify(verifyParam: VerifyParam) { - val user = userService.getById(WebUtil.getLoginUserId()) ?: throw AccessDeniedException("Access Denied") + val user = userService.getById(WebUtil.getLoginUserId()) user.verify ?: throw NoVerificationRequiredException() if (LocalDateTime.ofInstant(Instant.ofEpochMilli(user.verify!!.split("-").first().toLong()), ZoneOffset.UTC) .isBefore(LocalDateTime.now(ZoneOffset.UTC).minusHours(2)) || user.verify != verifyParam.code diff --git a/src/main/kotlin/top/fatweb/oxygen/api/service/tool/IEditService.kt b/src/main/kotlin/top/fatweb/oxygen/api/service/tool/IEditService.kt index b8717ea..7f8e197 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/service/tool/IEditService.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/service/tool/IEditService.kt @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService import top.fatweb.oxygen.api.entity.tool.Tool import top.fatweb.oxygen.api.param.tool.ToolCreateParam import top.fatweb.oxygen.api.param.tool.ToolUpdateParam +import top.fatweb.oxygen.api.param.tool.ToolUpgradeParam import top.fatweb.oxygen.api.vo.tool.ToolCategoryVo import top.fatweb.oxygen.api.vo.tool.ToolTemplateVo import top.fatweb.oxygen.api.vo.tool.ToolVo @@ -51,6 +52,7 @@ interface IEditService : IService { /** * Get tool by ID * + * @param * @author FatttSnake, fatttsnake@gmail.com * @since 1.0.0 */ @@ -64,6 +66,16 @@ interface IEditService : IService { */ fun create(toolCreateParam: ToolCreateParam): ToolVo + /** + * Upgrade tool + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + * @see ToolUpgradeParam + * @see ToolVo + */ + fun upgrade(toolUpgradeParam: ToolUpgradeParam): ToolVo + /** * Update tool * @@ -87,4 +99,12 @@ interface IEditService : IService { * @since 1.0.0 */ fun detail(username: String, toolId: String, ver: String): ToolVo + + /** + * Delete tool + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ + fun delete(id: Long): Boolean } \ No newline at end of file diff --git a/src/main/kotlin/top/fatweb/oxygen/api/service/tool/impl/EditServiceImpl.kt b/src/main/kotlin/top/fatweb/oxygen/api/service/tool/impl/EditServiceImpl.kt index 58c0a4b..f0ee779 100644 --- a/src/main/kotlin/top/fatweb/oxygen/api/service/tool/impl/EditServiceImpl.kt +++ b/src/main/kotlin/top/fatweb/oxygen/api/service/tool/impl/EditServiceImpl.kt @@ -2,17 +2,19 @@ package top.fatweb.oxygen.api.service.tool.impl import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl +import org.springframework.dao.DuplicateKeyException import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import top.fatweb.oxygen.api.converter.tool.ToolCategoryConverter import top.fatweb.oxygen.api.converter.tool.ToolConverter import top.fatweb.oxygen.api.converter.tool.ToolTemplateConverter import top.fatweb.oxygen.api.entity.tool.* +import top.fatweb.oxygen.api.exception.IllegalVersionException import top.fatweb.oxygen.api.exception.NoRecordFoundException -import top.fatweb.oxygen.api.exception.UserNotFoundException import top.fatweb.oxygen.api.mapper.tool.EditMapper import top.fatweb.oxygen.api.param.tool.ToolCreateParam import top.fatweb.oxygen.api.param.tool.ToolUpdateParam +import top.fatweb.oxygen.api.param.tool.ToolUpgradeParam import top.fatweb.oxygen.api.service.tool.* import top.fatweb.oxygen.api.util.WebUtil import top.fatweb.oxygen.api.vo.tool.ToolCategoryVo @@ -49,11 +51,15 @@ class EditServiceImpl( .map(ToolCategoryConverter::toolCategoryToToolCategoryVo) override fun getOne(id: Long): ToolVo = - baseMapper.selectOne(id, WebUtil.getLoginUserId() ?: throw UserNotFoundException()) + baseMapper.selectOne(id, WebUtil.getLoginUserId()!!) ?.let(ToolConverter::toolToToolVo) ?: throw NoRecordFoundException() @Transactional override fun create(toolCreateParam: ToolCreateParam): ToolVo { + baseMapper.selectOne( + KtQueryWrapper(Tool()).eq(Tool::toolId, toolCreateParam.toolId!!) + .eq(Tool::authorId, WebUtil.getLoginUserId()!!) + )?.let { throw DuplicateKeyException("Duplicate Key") } val template = this.getTemplate(toolCreateParam.templateId!!) val newSource = ToolData().apply { data = template.source!!.data } val newDist = ToolData().apply { data = "" } @@ -65,11 +71,12 @@ class EditServiceImpl( icon = toolCreateParam.icon description = toolCreateParam.description baseId = template.base!!.id - authorId = WebUtil.getLoginUserId() ?: throw UserNotFoundException() + authorId = WebUtil.getLoginUserId()!! ver = toolCreateParam.ver!!.split(".").map(String::toLong).joinToString(".") keywords = toolCreateParam.keywords sourceId = newSource.id distId = newDist.id + entryPoint = template.entryPoint } this.save(tool) @@ -85,13 +92,60 @@ class EditServiceImpl( return this.getOne(tool.id!!) } + @Transactional + override fun upgrade(toolUpgradeParam: ToolUpgradeParam): ToolVo { + val originalTool = this.detail("!", toolUpgradeParam.toolId!!, "latest") + + val originalVersion = originalTool.ver!! + if (originalVersion.split(".").map(String::toLong).joinToString(".") == toolUpgradeParam.ver!!.split(".") + .map(String::toLong).joinToString(".") + ) { + throw IllegalVersionException() + } + originalVersion.split(".").forEachIndexed { index, s -> + if ((toolUpgradeParam.ver.split(".")[index].toLong() < s.toLong())) { + throw IllegalVersionException() + } + } + + val newSource = ToolData().apply { data = originalTool.source!!.data } + val newDist = ToolData().apply { data = "" } + toolDataService.saveBatch(listOf(newSource, newDist)) + + val tool = Tool().apply { + name = originalTool.name!! + toolId = originalTool.toolId + icon = originalTool.icon + description = originalTool.description + baseId = originalTool.base!!.id + authorId = WebUtil.getLoginUserId()!! + ver = toolUpgradeParam.ver.split(".").map(String::toLong).joinToString(".") + keywords = originalTool.keywords + sourceId = newSource.id + distId = newDist.id + entryPoint = originalTool.entryPoint + } + + this.save(tool) + + originalTool.categories!!.forEach { + toolCategoryService.getById(it.id) ?: throw NoRecordFoundException() + rToolCategoryService.save(RToolCategory().apply { + toolId = tool.id + categoryId = it.id + }) + } + + return this.getOne(tool.id!!) + } + @Transactional override fun update(toolUpdateParam: ToolUpdateParam): ToolVo { TODO("Not yet implemented") } override fun get(): List = - baseMapper.selectPersonal(WebUtil.getLoginUserId() ?: throw UserNotFoundException()) + baseMapper.selectPersonal(WebUtil.getLoginUserId()!!) .map(ToolConverter::toolToToolVo) override fun detail(username: String, toolId: String, ver: String): ToolVo { @@ -102,4 +156,16 @@ class EditServiceImpl( return baseMapper.detail(username, toolId, ver, WebUtil.getLoginUsername())?.let(ToolConverter::toolToToolVo) ?: throw NoRecordFoundException() } + + @Transactional + override fun delete(id: Long): Boolean { + val tool = baseMapper.selectOne( + KtQueryWrapper(Tool()).eq(Tool::id, id) + .eq(Tool::authorId, WebUtil.getLoginUserId()!!) + ) ?: throw NoRecordFoundException() + + toolDataService.removeBatchByIds(listOf(tool.sourceId, tool.distId)) + rToolCategoryService.remove(KtQueryWrapper(RToolCategory()).eq(RToolCategory::toolId, tool.id)) + return this.removeById(id) + } } \ No newline at end of file diff --git a/src/main/resources/mapper/tool/EditMapper.xml b/src/main/resources/mapper/tool/EditMapper.xml index b8ab555..9250171 100644 --- a/src/main/resources/mapper/tool/EditMapper.xml +++ b/src/main/resources/mapper/tool/EditMapper.xml @@ -31,50 +31,50 @@ - + @@ -236,8 +238,9 @@ - - + +