From 1c868815de7aefdb77674239426b067cc0f8041e Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Mon, 23 Dec 2024 23:35:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=99=A8=E6=A8=A1=E6=9D=BF=E7=9A=84=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/lanyuanxiaoyao/bookstore/Entity.kt | 18 +++ .../controller/OptimizationController.kt | 74 ++++++++- .../static/components/optimization.js | 143 +++++++++++++++++ src/main/resources/static/index.html | 144 +++++++----------- 4 files changed, 287 insertions(+), 92 deletions(-) create mode 100644 src/main/resources/static/components/optimization.js diff --git a/src/main/kotlin/com/lanyuanxiaoyao/bookstore/Entity.kt b/src/main/kotlin/com/lanyuanxiaoyao/bookstore/Entity.kt index 6dffdaf..b2819ca 100644 --- a/src/main/kotlin/com/lanyuanxiaoyao/bookstore/Entity.kt +++ b/src/main/kotlin/com/lanyuanxiaoyao/bookstore/Entity.kt @@ -108,3 +108,21 @@ class Line( interface LineRepository : JpaRepository, JpaSpecificationExecutor { fun findAllByChapter_ChapterId(chapterId: String, sort: Sort): List } + +@Entity +@DynamicUpdate +class OptimizationTemplate( + @Id + var templateId: String, + @Column(nullable = false) + var name: String, + var description: String?, + @Lob + @Basic(fetch = FetchType.LAZY) + @Column(nullable = false, length = Int.MAX_VALUE) + var config: String, +) + +@Repository +interface OptimizationTemplateRepository : JpaRepository, + JpaSpecificationExecutor diff --git a/src/main/kotlin/com/lanyuanxiaoyao/bookstore/controller/OptimizationController.kt b/src/main/kotlin/com/lanyuanxiaoyao/bookstore/controller/OptimizationController.kt index affa98d..2d56a83 100644 --- a/src/main/kotlin/com/lanyuanxiaoyao/bookstore/controller/OptimizationController.kt +++ b/src/main/kotlin/com/lanyuanxiaoyao/bookstore/controller/OptimizationController.kt @@ -1,27 +1,35 @@ package com.lanyuanxiaoyao.bookstore.controller +import cn.hutool.core.util.IdUtil +import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.ObjectMapper import com.lanyuanxiaoyao.bookstore.CharWidthOptimization import com.lanyuanxiaoyao.bookstore.ListResponse import com.lanyuanxiaoyao.bookstore.Optimization -import com.lanyuanxiaoyao.bookstore.Optimization.ArgumentType.LIST -import com.lanyuanxiaoyao.bookstore.Optimization.ArgumentType.MAP -import com.lanyuanxiaoyao.bookstore.Optimization.ArgumentType.NONE +import com.lanyuanxiaoyao.bookstore.OptimizationTemplate +import com.lanyuanxiaoyao.bookstore.OptimizationTemplateRepository +import com.lanyuanxiaoyao.bookstore.PageResponse import com.lanyuanxiaoyao.bookstore.SingleResponse import com.lanyuanxiaoyao.bookstore.SliceOptimization import com.lanyuanxiaoyao.bookstore.TrimOptimization -import java.awt.SystemColor.text +import jakarta.transaction.Transactional import org.slf4j.LoggerFactory +import org.springframework.data.domain.PageRequest import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder 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.RequestMapping +import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("optimization") -class OptimizationController(builder: Jackson2ObjectMapperBuilder) { +class OptimizationController( + private val optimizationTemplateRepository: OptimizationTemplateRepository, + builder: Jackson2ObjectMapperBuilder, +) { private val log = LoggerFactory.getLogger(javaClass) private val mapper: ObjectMapper = builder.build() @@ -43,4 +51,60 @@ class OptimizationController(builder: Jackson2ObjectMapperBuilder) { val lines = Optimization.process(root, optimizationMap) return SingleResponse(lines.joinToString("\n")) } + + @GetMapping("list") + fun list( + @RequestParam("page", defaultValue = "1") page: Int, + @RequestParam("size", defaultValue = "10") size: Int, + ): PageResponse { + val pageable = optimizationTemplateRepository.findAll(PageRequest.of(0.coerceAtLeast(page - 1), size)) + return PageResponse( + pageable.content.map { template -> + ViewItem( + templateId = template.templateId, + name = template.name, + description = template.description, + config = mapper.readTree(template.config), + ) + }, + pageable.totalElements, + ) + } + + @Transactional + @PostMapping("save") + fun save(@RequestBody item: ViewItem) { + optimizationTemplateRepository.save( + OptimizationTemplate( + templateId = item.templateId ?: IdUtil.simpleUUID(), + name = item.name, + description = item.description, + config = mapper.writeValueAsString(item.config), + ) + ) + } + + @GetMapping("detail/{templateId}") + fun detail(@PathVariable("templateId") templateId: String): ViewItem { + val template = optimizationTemplateRepository.findById(templateId).orElseThrow() + return ViewItem( + templateId = template.templateId, + name = template.name, + description = template.description, + config = mapper.readTree(template.config), + ) + } + + @Transactional + @GetMapping("remove/{templateId}") + fun remove(@PathVariable("templateId") templateId: String) { + optimizationTemplateRepository.deleteById(templateId) + } + + data class ViewItem( + val templateId: String?, + val name: String, + val description: String?, + val config: JsonNode, + ) } \ No newline at end of file diff --git a/src/main/resources/static/components/optimization.js b/src/main/resources/static/components/optimization.js new file mode 100644 index 0000000..5e499e7 --- /dev/null +++ b/src/main/resources/static/components/optimization.js @@ -0,0 +1,143 @@ +function optimizationTemplateForm() { + return { + debug: true, + type: 'form', + name: 'optimization-template-form', + ...horizontalFormOptions(), + body: [ + { + type: 'hidden', + name: 'templateId', + }, + { + type: 'input-text', + name: 'name', + label: '名称', + required: true, + ...formInputClearable(), + }, + { + type: 'textarea', + name: 'description', + label: '简介', + ...formInputClearable(), + showCounter: true, + trimContents: true, + minRows: 2, + maxRows: 2, + maxLength: 100, + }, + { + type: 'combo', + name: 'config', + label: '优化器', + required: true, + multiLine: true, + multiple: true, + draggable: true, + items: [ + { + name: 'type', + label: '类型', + type: 'select', + required: true, + selectFirst: true, + source: '${base}/optimization/optimizations', + }, + { + visibleOn: "${ENDSWITH(type, 'MAP')}", + type: 'input-kv', + name: 'argument', + label: '参数', + required: true, + }, + { + visibleOn: "${ENDSWITH(type, 'LIST')}", + type: 'combo', + name: 'argument', + label: '参数', + required: true, + multiple: true, + multiLine: true, + flat: true, + items: [ + { + type: 'input-text', + name: 'argument', + label: '目标值', + required: true, + } + ] + }, + ] + }, + { + type: 'textarea', + name: 'text', + label: '测试正文', + ...formInputClearable(), + showCounter: true, + trimContents: true, + minRows: 5, + maxRows: 5, + }, + { + type: 'action', + label: '优化预览', + className: 'w-full mb-5', + level: 'primary', + actionType: 'ajax', + api: { + method: 'post', + url: '${base}/optimization/execute', + data: { + text: '${text|default:undefined}', + optimizations: '${config|default:undefined}' + } + }, + reload: 'optimization-template-form?newText=${item}' + }, + { + disabled: true, + type: 'diff-editor', + name: 'newText', + label: '正文优化', + diffValue: '${text}', + language: 'plain-text' + }, + ], + } +} + +function optimizationTemplateAddDialog() { + return { + type: 'action', + actionType: 'dialog', + dialog: { + title: '新增优化器模板', + size: 'lg', + body: { + ...optimizationTemplateForm(), + api: '${base}/optimization/save', + }, + }, + } +} + +function optimizationTemplateDetailDialog() { + return { + type: 'action', + actionType: 'dialog', + dialog: { + title: '编辑优化器模板', + size: 'lg', + body: [ + { + ...optimizationTemplateForm(), + initApi: '${base}/optimization/detail/${templateId}', + api: '${base}/optimization/save', + }, + ], + }, + } +} diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index d108bfb..511402e 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -28,16 +28,17 @@ +