wangyf10 преди 1 ден
родител
ревизия
924e747ec8
променени са 22 файла, в които са добавени 1335 реда и са изтрити 3 реда
  1. 19 0
      pom.xml
  2. 11 1
      yusys-ai-common/pom.xml
  3. 42 0
      yusys-ai-common/src/main/java/cn/com/yusys/ai/common/BizException.java
  4. 55 0
      yusys-ai-common/src/main/java/cn/com/yusys/ai/common/MessageUtils.java
  5. 78 0
      yusys-ai-common/src/main/java/cn/com/yusys/ai/common/ResultDto.java
  6. 18 1
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/pom.xml
  7. 89 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/MarketCons.java
  8. 75 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/common/Result.java
  9. 208 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/controller/YusysAiSkillController.java
  10. 13 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/dao/YusysAiSkillMapper.java
  11. 101 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/dto/SkillCreateDTO.java
  12. 75 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/dto/SkillQueryDTO.java
  13. 101 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/dto/SkillUpdateDTO.java
  14. 173 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/entity/YusysAiSkill.java
  15. 109 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/service/YusysAiSkillService.java
  16. 132 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/service/impl/YusysAiSkillServiceImpl.java
  17. 13 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/resources/messages.properties
  18. 0 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/resources/messages/yusp_ai_market_en_US.properties
  19. 0 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/resources/messages/yusp_ai_market_zh_CN.properties
  20. 13 0
      yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/resources/messages_zh_CN.properties
  21. 2 1
      yusys-ai-plus/yusys-ai-plus-starter/src/main/java/cn/com/yusys/ai/plus/PlusApplication.java
  22. 8 0
      yusys-ai-plus/yusys-ai-plus-starter/src/main/resources/application.yml

+ 19 - 0
pom.xml

@@ -25,6 +25,7 @@
         <module>yusys-ai-demo-agent</module>
         <module>yusys-ai-demo-mcp</module>
         <module>yusys-ai-plus</module>
+        <module>yusys-ai-common</module>
     </modules>
 
     <properties>
@@ -37,6 +38,9 @@
         <agentscope.version>2.0.2</agentscope.version>
         <hutool.version>5.8.46</hutool.version>
         <nacos.version>3.2.2</nacos.version>
+        <mybatis-plus.version>3.5.17</mybatis-plus.version>
+        <mysql.version>8.0.33</mysql.version>
+        <springdoc.version>3.1.0</springdoc.version>
     </properties>
 
     <dependencyManagement>
@@ -86,6 +90,21 @@
                 <artifactId>nacos-client</artifactId>
                 <version>${nacos.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>mybatis-plus-spring-boot4-starter</artifactId>
+                <version>${mybatis-plus.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>mysql</groupId>
+                <artifactId>mysql-connector-java</artifactId>
+                <version>${mysql.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springdoc</groupId>
+                <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+                <version>${springdoc.version}</version>
+            </dependency>
         </dependencies>
 
     </dependencyManagement>

+ 11 - 1
yusys-ai-common/pom.xml

@@ -10,10 +10,20 @@
         <version>1.0</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
+
     <artifactId>yusys-ai-common</artifactId>
     <name>yusys-ai-common</name>
     <description>yusys-ai-common</description>
     <dependencies>
-
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-spring-boot4-starter</artifactId>
+            <optional>true</optional>
+        </dependency>
     </dependencies>
 </project>

+ 42 - 0
yusys-ai-common/src/main/java/cn/com/yusys/ai/common/BizException.java

@@ -0,0 +1,42 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package cn.com.yusys.ai.common;
+
+import org.springframework.context.i18n.LocaleContextHolder;
+
+public class BizException extends RuntimeException {
+    private static final long serialVersionUID = -8117333306446025694L;
+    private String code;
+    private String message;
+
+    public static BizException of(String code, Object... data) {
+        String messageT = MessageUtils.getMessage(code, null, LocaleContextHolder.getLocale().toString(), data);
+        return new BizException(code, messageT);
+    }
+
+    public BizException(String code, String message) {
+        super(message);
+        this.message = message;
+        this.code = code;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}

+ 55 - 0
yusys-ai-common/src/main/java/cn/com/yusys/ai/common/MessageUtils.java

@@ -0,0 +1,55 @@
+package cn.com.yusys.ai.common;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.support.ResourceBundleMessageSource;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+
+public class MessageUtils {
+    private static final Logger log = LoggerFactory.getLogger(MessageUtils.class);
+    private static final ResourceBundleMessageSource RESOURCE_BUNDLE = new ResourceBundleMessageSource();
+    private static final HashMap<String, Locale> LOCALS = new HashMap();
+    private static final Locale DEFAULT_LOCALE;
+    private static final String KEY_WORDS = "_msg";
+    private static final String PATH = "classpath*:messages/*_msg*.properties";
+
+    public static String getMessage(String messageCode, String defaultMessage, String langCode, Object... args) {
+        String langCodeT = System.getProperty("langCode");
+        if (null != langCodeT && !"".equals(langCodeT)) {
+            langCode = langCodeT;
+        }
+        return RESOURCE_BUNDLE.getMessage(messageCode, args, defaultMessage, (Locale)LOCALS.getOrDefault(langCode, DEFAULT_LOCALE));
+    }
+
+
+    static {
+        DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;
+
+        try {
+            RESOURCE_BUNDLE.setDefaultEncoding("UTF-8");
+            LOCALS.put(Locale.SIMPLIFIED_CHINESE.toString(), Locale.SIMPLIFIED_CHINESE);
+            LOCALS.put(Locale.ENGLISH.toString(), Locale.ENGLISH);
+            LOCALS.put(Locale.US.toString(), Locale.US);
+            PathMatchingResourcePatternResolver pattern = new PathMatchingResourcePatternResolver();
+            HashSet<String> nameList = new HashSet();
+            Resource[] resources = pattern.getResources(PATH);
+
+            for(Resource re : resources) {
+                String fileName = re.getFilename();
+                String baseName = "messages/" + fileName.substring(0, fileName.indexOf(KEY_WORDS) + KEY_WORDS.length());
+                if (nameList.add(baseName)) {
+                    log.info("find .properties file, name={}", baseName);
+                }
+            }
+
+            RESOURCE_BUNDLE.setBasenames((String[])nameList.toArray(new String[nameList.size()]));
+        } catch (Exception e) {
+            log.error("find .properties file error", e);
+        }
+    }
+}

+ 78 - 0
yusys-ai-common/src/main/java/cn/com/yusys/ai/common/ResultDto.java

@@ -0,0 +1,78 @@
+package cn.com.yusys.ai.common;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+public class ResultDto<T> {
+    private String code = "0";
+    private long total = 0;
+    private String message;
+    private T data;
+
+    public static <T> ResultDto<T> success() {
+        return success(null);
+    }
+
+    public static <T> ResultDto<T> success(T data) {
+        ResultDto<T> resultDto = new ResultDto<T>();
+        if(data instanceof Page){
+            Page dataT= (Page)data;
+            T records = (T)dataT.getRecords();
+            resultDto.setData(records);
+        }else {
+            resultDto.setData(data);
+        }
+        return resultDto;
+    }
+
+    public ResultDto<T> total(long total) {
+        this.total = total;
+        return this;
+    }
+
+    public ResultDto<T> data(T data) {
+        this.data = data;
+        return this;
+    }
+
+    public ResultDto<T> message(String message) {
+        this.message = message;
+        return this;
+    }
+
+    public ResultDto<T> code(String code) {
+        this.code = code;
+        return this;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public long getTotal() {
+        return total;
+    }
+
+    public void setTotal(long total) {
+        this.total = total;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+}

+ 18 - 1
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/pom.xml

@@ -18,11 +18,28 @@
     <dependencies>
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter</artifactId>
+            <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
         <dependency>
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-all</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-spring-boot4-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.com.yusys.ai</groupId>
+            <artifactId>yusys-ai-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springdoc</groupId>
+            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+        </dependency>
     </dependencies>
 </project>

+ 89 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/MarketCons.java

@@ -0,0 +1,89 @@
+package cn.com.yusys.ai.plus.market;
+
+/**
+ * 市场模块常量类
+ */
+public class MarketCons {
+
+    /**
+     * 技能状态:生效
+     */
+    public static final String SKILL_STATUS_ENABLED = "Y";
+
+    /**
+     * 技能状态:待生效
+     */
+    public static final String SKILL_STATUS_DISABLED = "N";
+
+    /**
+     * 发布状态:已发布
+     */
+    public static final String PUBLISH_STATUS_YES = "Y";
+
+    /**
+     * 发布状态:未发布
+     */
+    public static final String PUBLISH_STATUS_NO = "N";
+
+    /**
+     * 返回码:成功
+     */
+    public static final String CODE_SUCCESS = "0";
+
+    /**
+     * 返回码:失败
+     */
+    public static final String CODE_ERROR = "-1";
+
+    // ==================== 错误码常量 ====================
+
+    /**
+     * 技能不存在
+     */
+    public static final String ERROR_SKILL_NOT_FOUND = "market.skill.not.found";
+
+    /**
+     * 技能名称已存在
+     */
+    public static final String ERROR_SKILL_NAME_EXISTS = "market.skill.name.exists";
+
+    /**
+     * 技能ID不能为空
+     */
+    public static final String ERROR_SKILL_ID_EMPTY = "market.skill.id.empty";
+
+    /**
+     * 创建技能失败
+     */
+    public static final String ERROR_SKILL_CREATE_FAILED = "market.skill.create.failed";
+
+    /**
+     * 更新技能失败
+     */
+    public static final String ERROR_SKILL_UPDATE_FAILED = "market.skill.update.failed";
+
+    /**
+     * 删除技能失败
+     */
+    public static final String ERROR_SKILL_DELETE_FAILED = "market.skill.delete.failed";
+
+    /**
+     * 发布技能失败
+     */
+    public static final String ERROR_SKILL_PUBLISH_FAILED = "market.skill.publish.failed";
+
+    /**
+     * 取消发布技能失败
+     */
+    public static final String ERROR_SKILL_UNPUBLISH_FAILED = "market.skill.unpublish.failed";
+
+    /**
+     * 启用技能失败
+     */
+    public static final String ERROR_SKILL_ENABLE_FAILED = "market.skill.enable.failed";
+
+    /**
+     * 禁用技能失败
+     */
+    public static final String ERROR_SKILL_DISABLE_FAILED = "market.skill.disable.failed";
+}

+ 75 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/common/Result.java

@@ -0,0 +1,75 @@
+package cn.com.yusys.ai.plus.market.common;
+
+/**
+ * 统一返回结果
+ */
+public class Result<T> {
+
+    /**
+     * 状态码
+     */
+    private Integer code;
+
+    /**
+     * 消息
+     */
+    private String message;
+
+    /**
+     * 数据
+     */
+    private T data;
+
+    public Result() {
+    }
+
+    public Result(Integer code, String message, T data) {
+        this.code = code;
+        this.message = message;
+        this.data = data;
+    }
+
+    public static <T> Result<T> success(T data) {
+        return new Result<>(200, "操作成功", data);
+    }
+
+    public static <T> Result<T> success(String message, T data) {
+        return new Result<>(200, message, data);
+    }
+
+    public static <T> Result<T> success() {
+        return new Result<>(200, "操作成功", null);
+    }
+
+    public static <T> Result<T> error(String message) {
+        return new Result<>(500, message, null);
+    }
+
+    public static <T> Result<T> error(Integer code, String message) {
+        return new Result<>(code, message, null);
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+}

+ 208 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/controller/YusysAiSkillController.java

@@ -0,0 +1,208 @@
+package cn.com.yusys.ai.plus.market.controller;
+
+import cn.com.yusys.ai.plus.market.MarketCons;
+import cn.com.yusys.ai.plus.market.dto.SkillCreateDTO;
+import cn.com.yusys.ai.plus.market.dto.SkillQueryDTO;
+import cn.com.yusys.ai.plus.market.dto.SkillUpdateDTO;
+import cn.com.yusys.ai.plus.market.entity.YusysAiSkill;
+import cn.com.yusys.ai.plus.market.service.YusysAiSkillService;
+import cn.com.yusys.ai.common.BizException;
+import cn.com.yusys.ai.common.ResultDto;
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * AI技能 Controller
+ */
+@RestController
+@RequestMapping("/api/market/skill")
+public class YusysAiSkillController {
+
+    @Autowired
+    private YusysAiSkillService skillService;
+
+    /**
+     * 分页查询技能列表
+     */
+    @PostMapping("/page")
+    public ResultDto<Page<YusysAiSkill>> pageQuery(@RequestBody SkillQueryDTO queryDTO) {
+        Page<YusysAiSkill> page = skillService.pageQuery(
+                queryDTO.getPageNum(),
+                queryDTO.getPageSize(),
+                queryDTO.getSkillName(),
+                queryDTO.getSkillGroup(),
+                queryDTO.getSkillStatus()
+        );
+        return ResultDto.success(page).total(page.getTotal());
+    }
+
+    /**
+     * 根据ID查询技能详情
+     */
+    @PostMapping("/getById")
+    public ResultDto<YusysAiSkill> getById(@RequestBody String id) {
+        YusysAiSkill skill = skillService.getById(id);
+        if (skill == null) {
+            throw BizException.of(MarketCons.ERROR_SKILL_NOT_FOUND);
+        }
+        return ResultDto.success(skill);
+    }
+
+    /**
+     * 根据技能名称查询
+     */
+    @PostMapping("/getByName")
+    public ResultDto<YusysAiSkill> getByName(@RequestBody String skillName) {
+        YusysAiSkill skill = skillService.getBySkillName(skillName);
+        if (skill == null) {
+            throw BizException.of(MarketCons.ERROR_SKILL_NOT_FOUND);
+        }
+        return ResultDto.success(skill);
+    }
+
+    /**
+     * 根据分组查询技能列表
+     */
+    @PostMapping("/listByGroup")
+    public ResultDto<List<YusysAiSkill>> listByGroup(@RequestBody String skillGroup) {
+        List<YusysAiSkill> list = skillService.listByGroup(skillGroup);
+        return ResultDto.success(list).total(list.size());
+    }
+
+    /**
+     * 查询已发布的技能列表
+     */
+    @PostMapping("/listPublic")
+    public ResultDto<List<YusysAiSkill>> listPublic() {
+        List<YusysAiSkill> list = skillService.listPublic();
+        return ResultDto.success(list).total(list.size());
+    }
+
+    /**
+     * 创建技能
+     */
+    @PostMapping
+    public ResultDto<YusysAiSkill> create(@RequestBody SkillCreateDTO createDTO) {
+        // 检查技能名称是否已存在
+        YusysAiSkill existSkill = skillService.getBySkillName(createDTO.getSkillName());
+        if (existSkill != null) {
+            throw BizException.of(MarketCons.ERROR_SKILL_NAME_EXISTS);
+        }
+
+        YusysAiSkill skill = new YusysAiSkill();
+        BeanUtil.copyProperties(createDTO, skill);
+        skill.setCreatedAt(LocalDateTime.now());
+        skill.setUpdatedAt(LocalDateTime.now());
+
+        skillService.save(skill);
+        return new ResultDto<YusysAiSkill>().code("0").message("创建成功").data(skill);
+    }
+
+    /**
+     * 更新技能
+     */
+    @PostMapping("/update")
+    public ResultDto<YusysAiSkill> update(@RequestBody SkillUpdateDTO updateDTO) {
+        if (updateDTO.getPkId() == null || updateDTO.getPkId().isEmpty()) {
+            throw BizException.of(MarketCons.ERROR_SKILL_ID_EMPTY);
+        }
+
+        YusysAiSkill skill = skillService.getById(updateDTO.getPkId());
+        if (skill == null) {
+            throw BizException.of(MarketCons.ERROR_SKILL_NOT_FOUND);
+        }
+
+        // 如果修改了技能名称,检查新名称是否已被占用
+        if (updateDTO.getSkillName() != null && !updateDTO.getSkillName().equals(skill.getSkillName())) {
+            YusysAiSkill existSkill = skillService.getBySkillName(updateDTO.getSkillName());
+            if (existSkill != null) {
+                throw BizException.of(MarketCons.ERROR_SKILL_NAME_EXISTS);
+            }
+        }
+
+        BeanUtil.copyProperties(updateDTO, skill, "pkId", "createdAt", "createBy");
+        skill.setUpdatedAt(LocalDateTime.now());
+
+        skillService.updateById(skill);
+        return new ResultDto<YusysAiSkill>().code("0").message("更新成功").data(skill);
+    }
+
+    /**
+     * 删除技能
+     */
+    @PostMapping("/delete")
+    public ResultDto<Void> delete(@RequestBody String id) {
+        YusysAiSkill skill = skillService.getById(id);
+        if (skill == null) {
+            throw BizException.of(MarketCons.ERROR_SKILL_NOT_FOUND);
+        }
+        skillService.removeById(id);
+        return ResultDto.success();
+    }
+
+    /**
+     * 批量删除技能
+     */
+    @PostMapping("/deleteBatch")
+    public ResultDto<Void> deleteBatch(@RequestBody List<String> ids) {
+        skillService.removeByIds(ids);
+        return ResultDto.success();
+    }
+
+    /**
+     * 发布技能
+     */
+    @PostMapping("/publish")
+    public ResultDto<Void> publish(@RequestBody String id) {
+        YusysAiSkill skill = skillService.getById(id);
+        if (skill == null) {
+            throw BizException.of(MarketCons.ERROR_SKILL_NOT_FOUND);
+        }
+        skillService.publish(id);
+        return ResultDto.success();
+    }
+
+    /**
+     * 取消发布技能
+     */
+    @PostMapping("/unpublish")
+    public ResultDto<Void> unpublish(@RequestBody String id) {
+        YusysAiSkill skill = skillService.getById(id);
+        if (skill == null) {
+            throw BizException.of(MarketCons.ERROR_SKILL_NOT_FOUND);
+        }
+        skillService.unpublish(id);
+        return ResultDto.success();
+    }
+
+    /**
+     * 启用技能
+     */
+    @PostMapping("/enable")
+    public ResultDto<Void> enable(@RequestBody String id) {
+        YusysAiSkill skill = skillService.getById(id);
+        if (skill == null) {
+            throw BizException.of(MarketCons.ERROR_SKILL_NOT_FOUND);
+        }
+        skillService.enable(id);
+        return ResultDto.success();
+    }
+
+    /**
+     * 禁用技能
+     */
+    @PostMapping("/disable")
+    public ResultDto<Void> disable(@RequestBody String id) {
+        YusysAiSkill skill = skillService.getById(id);
+        if (skill == null) {
+            throw BizException.of(MarketCons.ERROR_SKILL_NOT_FOUND);
+        }
+        skillService.disable(id);
+        return ResultDto.success();
+    }
+}

+ 13 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/dao/YusysAiSkillMapper.java

@@ -0,0 +1,13 @@
+package cn.com.yusys.ai.plus.market.dao;
+
+import cn.com.yusys.ai.plus.market.entity.YusysAiSkill;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * AI技能 Mapper 接口
+ */
+@Mapper
+public interface YusysAiSkillMapper extends BaseMapper<YusysAiSkill> {
+
+}

+ 101 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/dto/SkillCreateDTO.java

@@ -0,0 +1,101 @@
+package cn.com.yusys.ai.plus.market.dto;
+
+/**
+ * 技能创建DTO
+ */
+public class SkillCreateDTO {
+
+    /**
+     * 技能名称
+     */
+    private String skillName;
+
+    /**
+     * 技能描述
+     */
+    private String skillDescription;
+
+    /**
+     * 技能内容(skill.md)
+     */
+    private String skillContent;
+
+    /**
+     * 创建人
+     */
+    private String createBy;
+
+    /**
+     * 技能分组
+     */
+    private String skillGroup;
+
+    /**
+     * 技能状态(Y-生效  N-待生效)
+     */
+    private String skillStatus = "N";
+
+    /**
+     * 是否发布(Y-已发布 N-未发布)
+     */
+    private String isPublic = "N";
+
+    public SkillCreateDTO() {
+    }
+
+    public String getSkillName() {
+        return skillName;
+    }
+
+    public void setSkillName(String skillName) {
+        this.skillName = skillName;
+    }
+
+    public String getSkillDescription() {
+        return skillDescription;
+    }
+
+    public void setSkillDescription(String skillDescription) {
+        this.skillDescription = skillDescription;
+    }
+
+    public String getSkillContent() {
+        return skillContent;
+    }
+
+    public void setSkillContent(String skillContent) {
+        this.skillContent = skillContent;
+    }
+
+    public String getCreateBy() {
+        return createBy;
+    }
+
+    public void setCreateBy(String createBy) {
+        this.createBy = createBy;
+    }
+
+    public String getSkillGroup() {
+        return skillGroup;
+    }
+
+    public void setSkillGroup(String skillGroup) {
+        this.skillGroup = skillGroup;
+    }
+
+    public String getSkillStatus() {
+        return skillStatus;
+    }
+
+    public void setSkillStatus(String skillStatus) {
+        this.skillStatus = skillStatus;
+    }
+
+    public String getIsPublic() {
+        return isPublic;
+    }
+
+    public void setIsPublic(String isPublic) {
+        this.isPublic = isPublic;
+    }
+}

+ 75 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/dto/SkillQueryDTO.java

@@ -0,0 +1,75 @@
+package cn.com.yusys.ai.plus.market.dto;
+
+/**
+ * 技能查询DTO
+ */
+public class SkillQueryDTO {
+
+    /**
+     * 当前页
+     */
+    private Integer pageNum = 1;
+
+    /**
+     * 每页大小
+     */
+    private Integer pageSize = 10;
+
+    /**
+     * 技能名称(模糊查询)
+     */
+    private String skillName;
+
+    /**
+     * 技能分组
+     */
+    private String skillGroup;
+
+    /**
+     * 技能状态
+     */
+    private String skillStatus;
+
+    public SkillQueryDTO() {
+    }
+
+    public Integer getPageNum() {
+        return pageNum;
+    }
+
+    public void setPageNum(Integer pageNum) {
+        this.pageNum = pageNum;
+    }
+
+    public Integer getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(Integer pageSize) {
+        this.pageSize = pageSize;
+    }
+
+    public String getSkillName() {
+        return skillName;
+    }
+
+    public void setSkillName(String skillName) {
+        this.skillName = skillName;
+    }
+
+    public String getSkillGroup() {
+        return skillGroup;
+    }
+
+    public void setSkillGroup(String skillGroup) {
+        this.skillGroup = skillGroup;
+    }
+
+    public String getSkillStatus() {
+        return skillStatus;
+    }
+
+    public void setSkillStatus(String skillStatus) {
+        this.skillStatus = skillStatus;
+    }
+}

+ 101 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/dto/SkillUpdateDTO.java

@@ -0,0 +1,101 @@
+package cn.com.yusys.ai.plus.market.dto;
+
+/**
+ * 技能更新DTO
+ */
+public class SkillUpdateDTO {
+
+    /**
+     * 主键
+     */
+    private String pkId;
+
+    /**
+     * 技能名称
+     */
+    private String skillName;
+
+    /**
+     * 技能描述
+     */
+    private String skillDescription;
+
+    /**
+     * 技能内容(skill.md)
+     */
+    private String skillContent;
+
+    /**
+     * 技能分组
+     */
+    private String skillGroup;
+
+    /**
+     * 技能状态(Y-生效  N-待生效)
+     */
+    private String skillStatus;
+
+    /**
+     * 是否发布(Y-已发布 N-未发布)
+     */
+    private String isPublic;
+
+    public SkillUpdateDTO() {
+    }
+
+    public String getPkId() {
+        return pkId;
+    }
+
+    public void setPkId(String pkId) {
+        this.pkId = pkId;
+    }
+
+    public String getSkillName() {
+        return skillName;
+    }
+
+    public void setSkillName(String skillName) {
+        this.skillName = skillName;
+    }
+
+    public String getSkillDescription() {
+        return skillDescription;
+    }
+
+    public void setSkillDescription(String skillDescription) {
+        this.skillDescription = skillDescription;
+    }
+
+    public String getSkillContent() {
+        return skillContent;
+    }
+
+    public void setSkillContent(String skillContent) {
+        this.skillContent = skillContent;
+    }
+
+    public String getSkillGroup() {
+        return skillGroup;
+    }
+
+    public void setSkillGroup(String skillGroup) {
+        this.skillGroup = skillGroup;
+    }
+
+    public String getSkillStatus() {
+        return skillStatus;
+    }
+
+    public void setSkillStatus(String skillStatus) {
+        this.skillStatus = skillStatus;
+    }
+
+    public String getIsPublic() {
+        return isPublic;
+    }
+
+    public void setIsPublic(String isPublic) {
+        this.isPublic = isPublic;
+    }
+}

+ 173 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/entity/YusysAiSkill.java

@@ -0,0 +1,173 @@
+package cn.com.yusys.ai.plus.market.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.time.LocalDateTime;
+
+/**
+ * AI技能实体类
+ */
+@TableName("yusys_ai_skill")
+public class YusysAiSkill {
+
+    /**
+     * 主键
+     */
+    @TableId(value = "pk_id", type = IdType.ASSIGN_ID)
+    private String pkId;
+
+    /**
+     * 技能名称
+     */
+    @TableField("skill_name")
+    private String skillName;
+
+    /**
+     * 技能描述
+     */
+    @TableField("skill_description")
+    private String skillDescription;
+
+    /**
+     * 技能内容(skill.md)
+     */
+    @TableField("skill_content")
+    private String skillContent;
+
+    /**
+     * 创建时间
+     */
+    @TableField("created_at")
+    private LocalDateTime createdAt;
+
+    /**
+     * 更新时间
+     */
+    @TableField("updated_at")
+    private LocalDateTime updatedAt;
+
+    /**
+     * 创建人
+     */
+    @TableField("create_by")
+    private String createBy;
+
+    /**
+     * 技能分组
+     */
+    @TableField("skill_group")
+    private String skillGroup;
+
+    /**
+     * Y-生效  N-待生效
+     */
+    @TableField("skill_status")
+    private String skillStatus;
+
+    /**
+     * Y-已发布 N-未发布
+     */
+    @TableField("is_public")
+    private String isPublic;
+
+    public YusysAiSkill() {
+    }
+
+    public String getPkId() {
+        return pkId;
+    }
+
+    public void setPkId(String pkId) {
+        this.pkId = pkId;
+    }
+
+    public String getSkillName() {
+        return skillName;
+    }
+
+    public void setSkillName(String skillName) {
+        this.skillName = skillName;
+    }
+
+    public String getSkillDescription() {
+        return skillDescription;
+    }
+
+    public void setSkillDescription(String skillDescription) {
+        this.skillDescription = skillDescription;
+    }
+
+    public String getSkillContent() {
+        return skillContent;
+    }
+
+    public void setSkillContent(String skillContent) {
+        this.skillContent = skillContent;
+    }
+
+    public LocalDateTime getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(LocalDateTime createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public LocalDateTime getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public void setUpdatedAt(LocalDateTime updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public String getCreateBy() {
+        return createBy;
+    }
+
+    public void setCreateBy(String createBy) {
+        this.createBy = createBy;
+    }
+
+    public String getSkillGroup() {
+        return skillGroup;
+    }
+
+    public void setSkillGroup(String skillGroup) {
+        this.skillGroup = skillGroup;
+    }
+
+    public String getSkillStatus() {
+        return skillStatus;
+    }
+
+    public void setSkillStatus(String skillStatus) {
+        this.skillStatus = skillStatus;
+    }
+
+    public String getIsPublic() {
+        return isPublic;
+    }
+
+    public void setIsPublic(String isPublic) {
+        this.isPublic = isPublic;
+    }
+
+    @Override
+    public String toString() {
+        return "YusysAiSkill{" +
+                "pkId='" + pkId + '\'' +
+                ", skillName='" + skillName + '\'' +
+                ", skillDescription='" + skillDescription + '\'' +
+                ", skillContent='" + skillContent + '\'' +
+                ", createdAt=" + createdAt +
+                ", updatedAt=" + updatedAt +
+                ", createBy='" + createBy + '\'' +
+                ", skillGroup='" + skillGroup + '\'' +
+                ", skillStatus='" + skillStatus + '\'' +
+                ", isPublic='" + isPublic + '\'' +
+                '}';
+    }
+}

+ 109 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/service/YusysAiSkillService.java

@@ -0,0 +1,109 @@
+package cn.com.yusys.ai.plus.market.service;
+
+import cn.com.yusys.ai.plus.market.entity.YusysAiSkill;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import java.util.List;
+
+/**
+ * AI技能服务接口
+ */
+public interface YusysAiSkillService {
+
+    /**
+     * 保存技能
+     */
+    boolean save(YusysAiSkill skill);
+
+    /**
+     * 根据ID删除技能
+     */
+    boolean removeById(String id);
+
+    /**
+     * 批量删除技能
+     */
+    boolean removeByIds(List<String> ids);
+
+    /**
+     * 根据ID更新技能
+     */
+    boolean updateById(YusysAiSkill skill);
+
+    /**
+     * 根据ID查询技能
+     */
+    YusysAiSkill getById(String id);
+
+    /**
+     * 查询所有技能
+     */
+    List<YusysAiSkill> list();
+
+    /**
+     * 分页查询技能列表
+     *
+     * @param pageNum  当前页
+     * @param pageSize 每页大小
+     * @param skillName 技能名称(可选)
+     * @param skillGroup 技能分组(可选)
+     * @param skillStatus 技能状态(可选)
+     * @return 分页结果
+     */
+    Page<YusysAiSkill> pageQuery(Integer pageNum, Integer pageSize, String skillName, String skillGroup, String skillStatus);
+
+    /**
+     * 根据技能名称查询
+     *
+     * @param skillName 技能名称
+     * @return 技能信息
+     */
+    YusysAiSkill getBySkillName(String skillName);
+
+    /**
+     * 根据技能分组查询列表
+     *
+     * @param skillGroup 技能分组
+     * @return 技能列表
+     */
+    List<YusysAiSkill> listByGroup(String skillGroup);
+
+    /**
+     * 查询已发布的技能列表
+     *
+     * @return 技能列表
+     */
+    List<YusysAiSkill> listPublic();
+
+    /**
+     * 发布技能
+     *
+     * @param pkId 主键
+     * @return 是否成功
+     */
+    boolean publish(String pkId);
+
+    /**
+     * 取消发布技能
+     *
+     * @param pkId 主键
+     * @return 是否成功
+     */
+    boolean unpublish(String pkId);
+
+    /**
+     * 启用技能
+     *
+     * @param pkId 主键
+     * @return 是否成功
+     */
+    boolean enable(String pkId);
+
+    /**
+     * 禁用技能
+     *
+     * @param pkId 主键
+     * @return 是否成功
+     */
+    boolean disable(String pkId);
+}

+ 132 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/java/cn/com/yusys/ai/plus/market/service/impl/YusysAiSkillServiceImpl.java

@@ -0,0 +1,132 @@
+package cn.com.yusys.ai.plus.market.service.impl;
+
+import cn.com.yusys.ai.plus.market.dao.YusysAiSkillMapper;
+import cn.com.yusys.ai.plus.market.entity.YusysAiSkill;
+import cn.com.yusys.ai.plus.market.service.YusysAiSkillService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * AI技能服务实现类
+ */
+@Service
+public class YusysAiSkillServiceImpl implements YusysAiSkillService {
+
+    @Autowired
+    private YusysAiSkillMapper skillMapper;
+
+    @Override
+    public boolean save(YusysAiSkill skill) {
+        return skillMapper.insert(skill) > 0;
+    }
+
+    @Override
+    public boolean removeById(String id) {
+        return skillMapper.deleteById(id) > 0;
+    }
+
+    @Override
+    public boolean removeByIds(List<String> ids) {
+        return skillMapper.deleteBatchIds(ids) > 0;
+    }
+
+    @Override
+    public boolean updateById(YusysAiSkill skill) {
+        return skillMapper.updateById(skill) > 0;
+    }
+
+    @Override
+    public YusysAiSkill getById(String id) {
+        return skillMapper.selectById(id);
+    }
+
+    @Override
+    public List<YusysAiSkill> list() {
+        return skillMapper.selectList(null);
+    }
+
+    @Override
+    public Page<YusysAiSkill> pageQuery(Integer pageNum, Integer pageSize, String skillName, String skillGroup, String skillStatus) {
+        Page<YusysAiSkill> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<YusysAiSkill> wrapper = Wrappers.lambdaQuery();
+
+        if (skillName != null && !skillName.isEmpty()) {
+            wrapper.like(YusysAiSkill::getSkillName, skillName);
+        }
+        if (skillGroup != null && !skillGroup.isEmpty()) {
+            wrapper.eq(YusysAiSkill::getSkillGroup, skillGroup);
+        }
+        if (skillStatus != null && !skillStatus.isEmpty()) {
+            wrapper.eq(YusysAiSkill::getSkillStatus, skillStatus);
+        }
+
+        wrapper.orderByDesc(YusysAiSkill::getCreatedAt);
+        return skillMapper.selectPage(page, wrapper);
+    }
+
+    @Override
+    public YusysAiSkill getBySkillName(String skillName) {
+        return skillMapper.selectOne(Wrappers.<YusysAiSkill>lambdaQuery()
+                .eq(YusysAiSkill::getSkillName, skillName));
+    }
+
+    @Override
+    public List<YusysAiSkill> listByGroup(String skillGroup) {
+        return skillMapper.selectList(Wrappers.<YusysAiSkill>lambdaQuery()
+                .eq(YusysAiSkill::getSkillGroup, skillGroup)
+                .orderByDesc(YusysAiSkill::getCreatedAt));
+    }
+
+    @Override
+    public List<YusysAiSkill> listPublic() {
+        return skillMapper.selectList(Wrappers.<YusysAiSkill>lambdaQuery()
+                .eq(YusysAiSkill::getIsPublic, "Y")
+                .eq(YusysAiSkill::getSkillStatus, "Y")
+                .orderByDesc(YusysAiSkill::getCreatedAt));
+    }
+
+    @Override
+    public boolean publish(String pkId) {
+        YusysAiSkill skill = getById(pkId);
+        if (skill == null) {
+            return false;
+        }
+        skill.setIsPublic("Y");
+        return updateById(skill);
+    }
+
+    @Override
+    public boolean unpublish(String pkId) {
+        YusysAiSkill skill = getById(pkId);
+        if (skill == null) {
+            return false;
+        }
+        skill.setIsPublic("N");
+        return updateById(skill);
+    }
+
+    @Override
+    public boolean enable(String pkId) {
+        YusysAiSkill skill = getById(pkId);
+        if (skill == null) {
+            return false;
+        }
+        skill.setSkillStatus("Y");
+        return updateById(skill);
+    }
+
+    @Override
+    public boolean disable(String pkId) {
+        YusysAiSkill skill = getById(pkId);
+        if (skill == null) {
+            return false;
+        }
+        skill.setSkillStatus("N");
+        return updateById(skill);
+    }
+}

+ 13 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/resources/messages.properties

@@ -0,0 +1,13 @@
+# AI Market Error Messages
+
+# Skill errors
+market.skill.not.found=Skill not found
+market.skill.name.exists=Skill name already exists
+market.skill.id.empty=Skill ID cannot be empty
+market.skill.create.failed=Failed to create skill
+market.skill.update.failed=Failed to update skill
+market.skill.delete.failed=Failed to delete skill
+market.skill.publish.failed=Failed to publish skill
+market.skill.unpublish.failed=Failed to unpublish skill
+market.skill.enable.failed=Failed to enable skill
+market.skill.disable.failed=Failed to disable skill

+ 0 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/resources/messages/yusp_ai_market_en_US.properties


+ 0 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/resources/messages/yusp_ai_market_zh_CN.properties


+ 13 - 0
yusys-ai-plus/yusys-ai-market/yusys-ai-market-core/src/main/resources/messages_zh_CN.properties

@@ -0,0 +1,13 @@
+# AI 市场错误消息
+
+# 技能相关错误
+market.skill.not.found=技能不存在
+market.skill.name.exists=技能名称已存在
+market.skill.id.empty=技能ID不能为空
+market.skill.create.failed=创建技能失败
+market.skill.update.failed=更新技能失败
+market.skill.delete.failed=删除技能失败
+market.skill.publish.failed=发布技能失败
+market.skill.unpublish.failed=取消发布技能失败
+market.skill.enable.failed=启用技能失败
+market.skill.disable.failed=禁用技能失败

+ 2 - 1
yusys-ai-plus/yusys-ai-plus-starter/src/main/java/cn/com/yusys/ai/plus/PlusApplication.java

@@ -1,11 +1,12 @@
 package cn.com.yusys.ai.plus;
 
+import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 
 @SpringBootApplication
+@MapperScan("cn.com.yusys.ai.plus.**.dao")
 public class PlusApplication {
-
     public static void main(String[] args) {
         SpringApplication.run(PlusApplication.class, args);
     }

+ 8 - 0
yusys-ai-plus/yusys-ai-plus-starter/src/main/resources/application.yml

@@ -4,6 +4,14 @@ server:
 spring:
   application:
     name: yusys-ai-plus
+  datasource:
+    # 数据库驱动(Spring Boot 3.x 使用 Jakarta 版驱动)
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    url: jdbc:mysql://10.192.72.11:3306/yusp-ai-plus?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8
+    username: root
+    password: 123456
+    hikari:
+      maximum-pool-size: 20
 management:
   endpoints:
     web: