From 2b9838907c18000a0619b175922f531ea2cc617e Mon Sep 17 00:00:00 2001 From: mengnankkkk Date: Thu, 4 Jun 2026 18:07:58 +0800 Subject: [PATCH 1/8] feat: add domain --- .../agent/tools/GetDomainsTool.java | 25 ++++ .../malonetalk/agent/tools/GetTablesTool.java | 21 +++- .../controller/DomainController.java | 58 +++++++++ .../malonetalk/dto/DomainCreateRequest.java | 6 + .../malonetalk/dto/DomainPageQuery.java | 11 ++ .../malonetalk/dto/DomainUpdateRequest.java | 7 ++ .../github/malonetalk/entity/DomainInfo.java | 14 +++ .../malonetalk/mapper/DomainInfoMapper.java | 24 ++++ .../malonetalk/mapper/TableInfoMapper.java | 4 + .../malonetalk/service/DomainService.java | 23 ++++ .../service/impl/DomainServiceImpl.java | 116 ++++++++++++++++++ .../semantic/table/TableSemanticService.java | 2 + .../table/TableSemanticServiceImpl.java | 12 ++ .../resources/mapper/DomainInfoMapper.xml | 69 +++++++++++ .../main/resources/mapper/TableInfoMapper.xml | 10 ++ skills/data-query/SKILL.md | 12 +- sql/data_source.sql | 14 +++ 17 files changed, 420 insertions(+), 8 deletions(-) create mode 100644 data-agent-backend/src/main/java/io/github/malonetalk/agent/tools/GetDomainsTool.java create mode 100644 data-agent-backend/src/main/java/io/github/malonetalk/controller/DomainController.java create mode 100644 data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainCreateRequest.java create mode 100644 data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainPageQuery.java create mode 100644 data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainUpdateRequest.java create mode 100644 data-agent-backend/src/main/java/io/github/malonetalk/entity/DomainInfo.java create mode 100644 data-agent-backend/src/main/java/io/github/malonetalk/mapper/DomainInfoMapper.java create mode 100644 data-agent-backend/src/main/java/io/github/malonetalk/service/DomainService.java create mode 100644 data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java create mode 100644 data-agent-backend/src/main/resources/mapper/DomainInfoMapper.xml diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/agent/tools/GetDomainsTool.java b/data-agent-backend/src/main/java/io/github/malonetalk/agent/tools/GetDomainsTool.java new file mode 100644 index 0000000..adec03a --- /dev/null +++ b/data-agent-backend/src/main/java/io/github/malonetalk/agent/tools/GetDomainsTool.java @@ -0,0 +1,25 @@ +package io.github.malonetalk.agent.tools; + +import io.agentscope.core.tool.Tool; +import io.github.malonetalk.service.DomainService; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@AllArgsConstructor +public class GetDomainsTool implements MarkAgentTool { + + private final DomainService domainService; + + @Tool( + name = "get_domains", + description = + "Get available data domains in the datasource. Call this tool first to discover" + + " what domains are available before querying tables.") + public List getDomains() { + return domainService.listDomainNames(); + } +} diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/agent/tools/GetTablesTool.java b/data-agent-backend/src/main/java/io/github/malonetalk/agent/tools/GetTablesTool.java index c98eb91..3ee500a 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/agent/tools/GetTablesTool.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/agent/tools/GetTablesTool.java @@ -18,6 +18,7 @@ package io.github.malonetalk.agent.tools; import io.agentscope.core.tool.Tool; +import io.agentscope.core.tool.ToolParam; import io.github.malonetalk.entity.Datasource; import io.github.malonetalk.entity.TableInfo; import io.github.malonetalk.enums.Status; @@ -37,8 +38,22 @@ public class GetTablesTool implements MarkAgentTool { private final DatasourceService dataSourceService; private final TableSemanticService tableSemanticService; - @Tool(name = "get_tables", description = "获取数据库中的表信息,包括表名和表描述") - public List getTables() { + @Tool( + name = "get_tables", + description = + "Get table information from the database, including table name and description." + + " Optionally filter by domains; returns all tables if domains is not" + + " provided. It is recommended to call get_domains first to discover" + + " available domains.") + public List getTables( + @ToolParam( + name = "domains", + description = + "Optional list of domain names. Only tables belonging to these" + + " domains will be returned. If not provided or empty," + + " returns all tables.", + required = false) + List domains) { List activeDataSources = dataSourceService.findByStatus(Status.ACTIVE.getCode()); @@ -54,6 +69,6 @@ public List getTables() { } Datasource dataSource = activeDataSources.get(0); - return tableSemanticService.listTableInfosByDatasourceId(dataSource.getId()); + return tableSemanticService.listTableInfosByDomains(dataSource.getId(), domains); } } diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/controller/DomainController.java b/data-agent-backend/src/main/java/io/github/malonetalk/controller/DomainController.java new file mode 100644 index 0000000..c814d8f --- /dev/null +++ b/data-agent-backend/src/main/java/io/github/malonetalk/controller/DomainController.java @@ -0,0 +1,58 @@ +package io.github.malonetalk.controller; + +import io.github.malonetalk.common.Result; +import io.github.malonetalk.dto.DomainCreateRequest; +import io.github.malonetalk.dto.DomainPageQuery; +import io.github.malonetalk.dto.DomainUpdateRequest; +import io.github.malonetalk.dto.pagination.PageResponse; +import io.github.malonetalk.entity.DomainInfo; +import io.github.malonetalk.service.DomainService; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.DeleteMapping; +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.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/domains") +@RequiredArgsConstructor +public class DomainController { + + private final DomainService domainService; + + @GetMapping + public Result> findDomains(@Valid DomainPageQuery query) { + return Result.success(domainService.getDomainPage(query)); + } + + @GetMapping("/{id}") + public Result findById(@PathVariable Integer id) { + DomainInfo domain = domainService.findById(id); + if (domain == null) { + return Result.error(404, "领域不存在"); + } + return Result.success(domain); + } + + @PostMapping + public Result create(@Valid @RequestBody DomainCreateRequest request) { + return Result.success(domainService.create(request)); + } + + @PutMapping("/{id}") + public Result update( + @PathVariable Integer id, @Valid @RequestBody DomainUpdateRequest request) { + return Result.success(domainService.update(id, request)); + } + + @DeleteMapping("/{id}") + public Result delete(@PathVariable Integer id) { + domainService.delete(id); + return Result.success(true); + } +} diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainCreateRequest.java b/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainCreateRequest.java new file mode 100644 index 0000000..60caa84 --- /dev/null +++ b/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainCreateRequest.java @@ -0,0 +1,6 @@ +package io.github.malonetalk.dto; + +import jakarta.validation.constraints.NotBlank; + +public record DomainCreateRequest( + @NotBlank(message = "领域名称不能为空") String name, String description) {} diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainPageQuery.java b/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainPageQuery.java new file mode 100644 index 0000000..87a02b5 --- /dev/null +++ b/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainPageQuery.java @@ -0,0 +1,11 @@ +package io.github.malonetalk.dto; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Pattern; + +public record DomainPageQuery( + @Min(1) Integer page, + @Min(1) Integer pageSize, + String keyword, + @Pattern(regexp = "^(?i)(asc|desc)$", message = "sortOrder must be asc or desc.") + String sortOrder) {} diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainUpdateRequest.java b/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainUpdateRequest.java new file mode 100644 index 0000000..2b0c0fc --- /dev/null +++ b/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainUpdateRequest.java @@ -0,0 +1,7 @@ +package io.github.malonetalk.dto; + +import jakarta.validation.constraints.NotBlank; + +public record DomainUpdateRequest( + @NotBlank(message = "领域名称不能为空") String name, + String description) {} diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/entity/DomainInfo.java b/data-agent-backend/src/main/java/io/github/malonetalk/entity/DomainInfo.java new file mode 100644 index 0000000..05081a0 --- /dev/null +++ b/data-agent-backend/src/main/java/io/github/malonetalk/entity/DomainInfo.java @@ -0,0 +1,14 @@ +package io.github.malonetalk.entity; + +import java.time.LocalDateTime; +import lombok.Data; + +@Data +public class DomainInfo { + + private Integer id; + private String name; + private String description; + private LocalDateTime createTime; + private LocalDateTime updateTime; +} diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/mapper/DomainInfoMapper.java b/data-agent-backend/src/main/java/io/github/malonetalk/mapper/DomainInfoMapper.java new file mode 100644 index 0000000..90fc58b --- /dev/null +++ b/data-agent-backend/src/main/java/io/github/malonetalk/mapper/DomainInfoMapper.java @@ -0,0 +1,24 @@ +package io.github.malonetalk.mapper; + +import io.github.malonetalk.dto.DomainPageQuery; +import io.github.malonetalk.entity.DomainInfo; +import java.util.List; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +@Mapper +public interface DomainInfoMapper { + + int insert(DomainInfo domainInfo); + + int update(DomainInfo domainInfo); + + int deleteByIds(@Param("ids") List ids); + + List selectAll(); + + List selectPage( + @Param("query") DomainPageQuery query, @Param("sortDescending") boolean sortDescending); + + DomainInfo selectByName(@Param("name") String name); +} diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/mapper/TableInfoMapper.java b/data-agent-backend/src/main/java/io/github/malonetalk/mapper/TableInfoMapper.java index 9c41458..f4c5869 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/mapper/TableInfoMapper.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/mapper/TableInfoMapper.java @@ -41,4 +41,8 @@ List selectPageByDatasourceId( TableInfo selectByDatasourceIdAndTableName( @Param("datasourceId") Integer datasourceId, @Param("tableName") String tableName); + + List selectByDatasourceIdAndDomains( + @Param("datasourceId") Integer datasourceId, + @Param("domains") List domains); } diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/service/DomainService.java b/data-agent-backend/src/main/java/io/github/malonetalk/service/DomainService.java new file mode 100644 index 0000000..d60a36b --- /dev/null +++ b/data-agent-backend/src/main/java/io/github/malonetalk/service/DomainService.java @@ -0,0 +1,23 @@ +package io.github.malonetalk.service; + +import io.github.malonetalk.dto.DomainCreateRequest; +import io.github.malonetalk.dto.DomainPageQuery; +import io.github.malonetalk.dto.DomainUpdateRequest; +import io.github.malonetalk.dto.pagination.PageResponse; +import io.github.malonetalk.entity.DomainInfo; +import java.util.List; + +public interface DomainService { + + PageResponse getDomainPage(DomainPageQuery query); + + DomainInfo findById(Integer id); + + DomainInfo create(DomainCreateRequest request); + + DomainInfo update(Integer id, DomainUpdateRequest request); + + void delete(Integer id); + + List listDomainNames(); +} diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java b/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java new file mode 100644 index 0000000..7226fe8 --- /dev/null +++ b/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java @@ -0,0 +1,116 @@ +package io.github.malonetalk.service.impl; + +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import io.github.malonetalk.common.SemanticConstants; +import io.github.malonetalk.dto.DomainCreateRequest; +import io.github.malonetalk.dto.DomainPageQuery; +import io.github.malonetalk.dto.DomainUpdateRequest; +import io.github.malonetalk.dto.pagination.PageResponse; +import io.github.malonetalk.entity.DomainInfo; +import io.github.malonetalk.mapper.DomainInfoMapper; +import io.github.malonetalk.service.DomainService; +import io.github.malonetalk.utils.SemanticUtils; +import java.time.LocalDateTime; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class DomainServiceImpl implements DomainService { + + private final DomainInfoMapper domainInfoMapper; + + @Override + public PageResponse getDomainPage(DomainPageQuery query) { + int pageNumber = PageResponse.resolvePage(query.page()); + int pageSize = PageResponse.resolvePageSize(query.pageSize()); + SemanticUtils.validateSortOrder(query.sortOrder()); + boolean sortDescending = + SemanticConstants.SORT_ORDER_DESC.equalsIgnoreCase(query.sortOrder()); + PageHelper.startPage(pageNumber, pageSize); + @SuppressWarnings("unchecked") + Page page = + (Page) + domainInfoMapper.selectPage( + new DomainPageQuery( + pageNumber, + pageSize, + SemanticUtils.normalizeBlankToNull(query.keyword()), + query.sortOrder()), + sortDescending); + List items = page.getResult(); + long total = page.getTotal(); + return PageResponse.of(items, total, pageNumber, pageSize); + } + + @Override + public DomainInfo findById(Integer id) { + if (id == null) { + throw new IllegalArgumentException("id 不能为空"); + } + return domainInfoMapper.selectAll().stream() + .filter(d -> d.getId().equals(id)) + .findFirst() + .orElse(null); + } + + @Override + public DomainInfo create(DomainCreateRequest request) { + String normalizedName = SemanticUtils.requireName(request.name(), "领域名称"); + DomainInfo existing = domainInfoMapper.selectByName(normalizedName); + if (existing != null) { + throw new IllegalArgumentException("领域名称已存在: " + normalizedName); + } + DomainInfo domainInfo = new DomainInfo(); + domainInfo.setName(normalizedName); + domainInfo.setDescription(SemanticUtils.normalizeBlankToNull(request.description())); + domainInfo.setCreateTime(LocalDateTime.now()); + domainInfo.setUpdateTime(LocalDateTime.now()); + domainInfoMapper.insert(domainInfo); + return domainInfo; + } + + @Override + public DomainInfo update(Integer id, DomainUpdateRequest request) { + if (id == null) { + throw new IllegalArgumentException("id 不能为空"); + } + DomainInfo existing = findById(id); + if (existing == null) { + throw new IllegalArgumentException("领域不存在: id=" + id); + } + String normalizedName = SemanticUtils.requireName(request.name(), "领域名称"); + DomainInfo nameConflict = domainInfoMapper.selectByName(normalizedName); + if (nameConflict != null && !nameConflict.getId().equals(id)) { + throw new IllegalArgumentException("领域名称已存在: " + normalizedName); + } + existing.setName(normalizedName); + existing.setDescription(SemanticUtils.normalizeBlankToNull(request.description())); + existing.setUpdateTime(LocalDateTime.now()); + domainInfoMapper.update(existing); + return existing; + } + + @Override + public void delete(Integer id) { + if (id == null) { + throw new IllegalArgumentException("id 不能为空"); + } + DomainInfo existing = findById(id); + if (existing == null) { + throw new IllegalArgumentException("领域不存在: id=" + id); + } + domainInfoMapper.deleteByIds(List.of(id)); + } + + @Override + public List listDomainNames() { + return domainInfoMapper.selectAll().stream() + .map(DomainInfo::getName) + .distinct() + .sorted(String::compareToIgnoreCase) + .toList(); + } +} diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/service/semantic/table/TableSemanticService.java b/data-agent-backend/src/main/java/io/github/malonetalk/service/semantic/table/TableSemanticService.java index 83e8717..0d80e2e 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/service/semantic/table/TableSemanticService.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/service/semantic/table/TableSemanticService.java @@ -34,6 +34,8 @@ public interface TableSemanticService { void updateTableSemantic(TableSemanticUpdateRequest request); + List listTableInfosByDomains(Integer datasourceId, List domains); + void resetTableSemantic(Integer datasourceId, String tableName); int resetTableSemantics(Integer datasourceId, List tableNames); diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/service/semantic/table/TableSemanticServiceImpl.java b/data-agent-backend/src/main/java/io/github/malonetalk/service/semantic/table/TableSemanticServiceImpl.java index e1223e3..7f161da 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/service/semantic/table/TableSemanticServiceImpl.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/service/semantic/table/TableSemanticServiceImpl.java @@ -94,6 +94,18 @@ public List listTableInfosByDatasourceId(Integer datasourceId) { return tableInfoMapper.selectByDatasourceId(datasourceId); } + @Override + public List listTableInfosByDomains(Integer datasourceId, List domains) { + SemanticUtils.requireDatasourceId(datasourceId); + if (datasourceService.findById(datasourceId) == null) { + return List.of(); + } + if (domains == null || domains.isEmpty()) { + return listTableInfosByDatasourceId(datasourceId); + } + return tableInfoMapper.selectByDatasourceIdAndDomains(datasourceId, domains); + } + @Override public void updateTableSemantic(TableSemanticUpdateRequest request) { requireDatasource(request.datasourceId()); diff --git a/data-agent-backend/src/main/resources/mapper/DomainInfoMapper.xml b/data-agent-backend/src/main/resources/mapper/DomainInfoMapper.xml new file mode 100644 index 0000000..67da044 --- /dev/null +++ b/data-agent-backend/src/main/resources/mapper/DomainInfoMapper.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + INSERT INTO domain_info ( + name, description, + create_time, update_time + ) VALUES ( + #{name}, #{description}, + #{createTime}, #{updateTime} + ) + + + + UPDATE domain_info + + name = #{name}, + description = #{description}, + update_time = #{updateTime}, + + WHERE id = #{id} + + + + DELETE FROM domain_info + WHERE id IN + + #{id} + + + + diff --git a/data-agent-backend/src/main/resources/mapper/TableInfoMapper.xml b/data-agent-backend/src/main/resources/mapper/TableInfoMapper.xml index c308e2f..e0ad350 100644 --- a/data-agent-backend/src/main/resources/mapper/TableInfoMapper.xml +++ b/data-agent-backend/src/main/resources/mapper/TableInfoMapper.xml @@ -66,6 +66,16 @@ WHERE id = #{id} + + DELETE FROM table_info WHERE datasource_id = #{datasourceId} diff --git a/skills/data-query/SKILL.md b/skills/data-query/SKILL.md index afcb7f8..139f988 100644 --- a/skills/data-query/SKILL.md +++ b/skills/data-query/SKILL.md @@ -7,14 +7,16 @@ description: A skill for querying database tables and generating SQL queries bas You are a data query assistant. When the user asks a data-related question, follow these steps: -1. Use the `get_tables` tool to get available database tables -2. Use the `get_table_schema` tool to get the schema of relevant tables -3. Generate a SELECT SQL statement based on the table structure -4. Use the `execute_sql` tool to execute the query -5. Summarize the query results for the user +1. Use the `get_domains` tool to get available data domains +2. Based on the user's question, select the relevant domain(s), then use `get_tables(domains=[...])` to get tables in those domains +3. Use the `get_table_schema` tool to get the schema of relevant tables +4. Generate a SELECT SQL statement based on the table structure +5. Use the `execute_sql` tool to execute the query +6. Summarize the query results for the user ## Notes - Only SELECT queries are supported, no modification operations - Always check the table schema before generating SQL to ensure column names and types are correct - If the query result is empty, suggest the user check the query conditions +- When the user's question is ambiguous about which domain to use, query multiple domains to increase coverage diff --git a/sql/data_source.sql b/sql/data_source.sql index 9822f29..d66aae3 100644 --- a/sql/data_source.sql +++ b/sql/data_source.sql @@ -74,3 +74,17 @@ CREATE TABLE IF NOT EXISTS `logical_table_relation` ( (`datasource_id`, `source_table_name`, `target_table_name`, `id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='逻辑表关系表'; +CREATE TABLE IF NOT EXISTS `domain_info` ( + `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `name` VARCHAR(255) NOT NULL COMMENT '领域名称', + `description` VARCHAR(500) DEFAULT NULL COMMENT '领域描述', + `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_domain_name` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='数据领域表'; + +INSERT INTO `domain_info` (`name`, `description`, `create_time`, `update_time`) +SELECT 'default', '默认领域', NOW(), NOW() +WHERE NOT EXISTS (SELECT 1 FROM `domain_info` WHERE `name` = 'default'); + From 881e69cc453bc2b6e7b1aaf084c7abf8a30bc72c Mon Sep 17 00:00:00 2001 From: mengnankkkk Date: Thu, 4 Jun 2026 20:23:28 +0800 Subject: [PATCH 2/8] feat: add frontend --- .../malonetalk/config/DataSourceConfig.java | 6 + data-agent-frontend/src/api/domain.ts | 74 +++++ .../src/components/layout/AppSidebar.vue | 1 + data-agent-frontend/src/router/index.ts | 6 + .../src/views/semantic/SemanticManage.vue | 146 +++++++++ .../semantic/components/DomainManage.vue | 298 ++++++++++++++++++ data-agent-frontend/vite.config.ts | 3 +- 7 files changed, 532 insertions(+), 2 deletions(-) create mode 100644 data-agent-frontend/src/api/domain.ts create mode 100644 data-agent-frontend/src/views/semantic/SemanticManage.vue create mode 100644 data-agent-frontend/src/views/semantic/components/DomainManage.vue diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/config/DataSourceConfig.java b/data-agent-backend/src/main/java/io/github/malonetalk/config/DataSourceConfig.java index e9e8c23..0a8c7ba 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/config/DataSourceConfig.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/config/DataSourceConfig.java @@ -17,6 +17,7 @@ */ package io.github.malonetalk.config; +import com.fasterxml.jackson.databind.ObjectMapper; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import javax.sql.DataSource; @@ -66,4 +67,9 @@ public DataSource dataSource() { return new HikariDataSource(config); } + + @Bean + public ObjectMapper objectMapper() { + return new ObjectMapper(); + } } diff --git a/data-agent-frontend/src/api/domain.ts b/data-agent-frontend/src/api/domain.ts new file mode 100644 index 0000000..b4a37be --- /dev/null +++ b/data-agent-frontend/src/api/domain.ts @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2026 github.com/MaloneTalk + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import request from './request'; +import type { ApiResponse } from './request'; + +export interface PageResponse { + page: number; + pageSize: number; + total: number; + totalPages: number; + hasPrevious: boolean; + hasNext: boolean; + items: T[]; +} + +export interface DomainInfo { + id: number; + name: string; + description: string | null; + createTime: string; + updateTime: string; +} + +export interface DomainPageQuery { + page?: number; + pageSize?: number; + keyword?: string; + sortOrder?: 'asc' | 'desc'; +} + +export interface DomainCreateRequest { + name: string; + description?: string; +} + +export interface DomainUpdateRequest { + name: string; + description?: string; +} + +export function getDomainPage(query: DomainPageQuery) { + return request.get>>('/domains', { params: query }); +} + +export function getDomainById(id: number) { + return request.get>(`/domains/${id}`); +} + +export function createDomain(data: DomainCreateRequest) { + return request.post>('/domains', data); +} + +export function updateDomain(id: number, data: DomainUpdateRequest) { + return request.put>(`/domains/${id}`, data); +} + +export function deleteDomain(id: number) { + return request.delete>(`/domains/${id}`); +} diff --git a/data-agent-frontend/src/components/layout/AppSidebar.vue b/data-agent-frontend/src/components/layout/AppSidebar.vue index d936f73..a09a76b 100644 --- a/data-agent-frontend/src/components/layout/AppSidebar.vue +++ b/data-agent-frontend/src/components/layout/AppSidebar.vue @@ -27,6 +27,7 @@ const menuItems = [ { path: '/chat', title: 'AI 智能分析', icon: 'ChatDotRound' }, { path: '/data-source', title: '数据源管理', icon: 'Connection' }, + { path: '/semantic', title: '语义管理', icon: 'Collection' }, ]; const activeMenu = computed(() => route.path); diff --git a/data-agent-frontend/src/router/index.ts b/data-agent-frontend/src/router/index.ts index ad13e31..6892db4 100644 --- a/data-agent-frontend/src/router/index.ts +++ b/data-agent-frontend/src/router/index.ts @@ -41,6 +41,12 @@ const routes: RouteRecordRaw[] = [ component: () => import('@/views/data-source/DataSource.vue'), meta: { title: '数据源管理' }, }, + { + path: '/semantic', + name: 'SemanticManage', + component: () => import('@/views/semantic/SemanticManage.vue'), + meta: { title: '语义管理' }, + }, ]; const router = createRouter({ diff --git a/data-agent-frontend/src/views/semantic/SemanticManage.vue b/data-agent-frontend/src/views/semantic/SemanticManage.vue new file mode 100644 index 0000000..4164b2d --- /dev/null +++ b/data-agent-frontend/src/views/semantic/SemanticManage.vue @@ -0,0 +1,146 @@ + + + + + + + + diff --git a/data-agent-frontend/src/views/semantic/components/DomainManage.vue b/data-agent-frontend/src/views/semantic/components/DomainManage.vue new file mode 100644 index 0000000..94a9b10 --- /dev/null +++ b/data-agent-frontend/src/views/semantic/components/DomainManage.vue @@ -0,0 +1,298 @@ + + + + + + + diff --git a/data-agent-frontend/vite.config.ts b/data-agent-frontend/vite.config.ts index 7b949a3..c649ee9 100644 --- a/data-agent-frontend/vite.config.ts +++ b/data-agent-frontend/vite.config.ts @@ -18,7 +18,6 @@ import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import eslint from 'vite-plugin-eslint'; -import { resolve } from 'path'; /** * Vite configuration file @@ -32,7 +31,7 @@ export default defineConfig({ // Allows importing like: import xxx from '@/components/xxx' resolve: { alias: { - '@': resolve(__dirname, 'src'), + '@': '/src', }, }, // Development server configuration From 731c16a5bbb6e4b20a6a1c87a7fdd858db6f3e52 Mon Sep 17 00:00:00 2001 From: mengnankkkk Date: Thu, 4 Jun 2026 20:42:34 +0800 Subject: [PATCH 3/8] fix: ci --- .../agent/tools/GetDomainsTool.java | 17 ++++++++++++++++ .../malonetalk/common/SemanticConstants.java | 1 + .../controller/DomainController.java | 17 ++++++++++++++++ .../malonetalk/dto/DomainCreateRequest.java | 17 ++++++++++++++++ .../malonetalk/dto/DomainPageQuery.java | 17 ++++++++++++++++ .../malonetalk/dto/DomainUpdateRequest.java | 20 +++++++++++++++++-- .../github/malonetalk/entity/DomainInfo.java | 17 ++++++++++++++++ .../malonetalk/mapper/DomainInfoMapper.java | 17 ++++++++++++++++ .../malonetalk/mapper/TableInfoMapper.java | 3 +-- .../malonetalk/service/DomainService.java | 17 ++++++++++++++++ .../service/impl/DomainServiceImpl.java | 17 ++++++++++++++++ .../table/TableSemanticServiceImpl.java | 9 +++++++-- .../src/views/semantic/SemanticManage.vue | 1 - 13 files changed, 163 insertions(+), 7 deletions(-) diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/agent/tools/GetDomainsTool.java b/data-agent-backend/src/main/java/io/github/malonetalk/agent/tools/GetDomainsTool.java index adec03a..c53fcf0 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/agent/tools/GetDomainsTool.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/agent/tools/GetDomainsTool.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2026 github.com/MaloneTalk + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * limitations under the License. + */ package io.github.malonetalk.agent.tools; import io.agentscope.core.tool.Tool; diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/common/SemanticConstants.java b/data-agent-backend/src/main/java/io/github/malonetalk/common/SemanticConstants.java index 66a72ba..4f08ded 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/common/SemanticConstants.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/common/SemanticConstants.java @@ -22,6 +22,7 @@ public final class SemanticConstants { public static final String RELATION_KEY_SEPARATOR = "|"; public static final String SORT_ORDER_ASC = "asc"; public static final String SORT_ORDER_DESC = "desc"; + public static final String DEFAULT_DOMAIN = "default"; private SemanticConstants() {} } diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/controller/DomainController.java b/data-agent-backend/src/main/java/io/github/malonetalk/controller/DomainController.java index c814d8f..c479bff 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/controller/DomainController.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/controller/DomainController.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2026 github.com/MaloneTalk + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * limitations under the License. + */ package io.github.malonetalk.controller; import io.github.malonetalk.common.Result; diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainCreateRequest.java b/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainCreateRequest.java index 60caa84..7f77fb6 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainCreateRequest.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainCreateRequest.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2026 github.com/MaloneTalk + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * limitations under the License. + */ package io.github.malonetalk.dto; import jakarta.validation.constraints.NotBlank; diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainPageQuery.java b/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainPageQuery.java index 87a02b5..d35bebb 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainPageQuery.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainPageQuery.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2026 github.com/MaloneTalk + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * limitations under the License. + */ package io.github.malonetalk.dto; import jakarta.validation.constraints.Min; diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainUpdateRequest.java b/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainUpdateRequest.java index 2b0c0fc..eb6f472 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainUpdateRequest.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/dto/DomainUpdateRequest.java @@ -1,7 +1,23 @@ +/* + * Copyright (C) 2026 github.com/MaloneTalk + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * limitations under the License. + */ package io.github.malonetalk.dto; import jakarta.validation.constraints.NotBlank; public record DomainUpdateRequest( - @NotBlank(message = "领域名称不能为空") String name, - String description) {} + @NotBlank(message = "领域名称不能为空") String name, String description) {} diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/entity/DomainInfo.java b/data-agent-backend/src/main/java/io/github/malonetalk/entity/DomainInfo.java index 05081a0..fad3e82 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/entity/DomainInfo.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/entity/DomainInfo.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2026 github.com/MaloneTalk + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * limitations under the License. + */ package io.github.malonetalk.entity; import java.time.LocalDateTime; diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/mapper/DomainInfoMapper.java b/data-agent-backend/src/main/java/io/github/malonetalk/mapper/DomainInfoMapper.java index 90fc58b..bf15775 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/mapper/DomainInfoMapper.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/mapper/DomainInfoMapper.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2026 github.com/MaloneTalk + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * limitations under the License. + */ package io.github.malonetalk.mapper; import io.github.malonetalk.dto.DomainPageQuery; diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/mapper/TableInfoMapper.java b/data-agent-backend/src/main/java/io/github/malonetalk/mapper/TableInfoMapper.java index f4c5869..d3e48f2 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/mapper/TableInfoMapper.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/mapper/TableInfoMapper.java @@ -43,6 +43,5 @@ TableInfo selectByDatasourceIdAndTableName( @Param("datasourceId") Integer datasourceId, @Param("tableName") String tableName); List selectByDatasourceIdAndDomains( - @Param("datasourceId") Integer datasourceId, - @Param("domains") List domains); + @Param("datasourceId") Integer datasourceId, @Param("domains") List domains); } diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/service/DomainService.java b/data-agent-backend/src/main/java/io/github/malonetalk/service/DomainService.java index d60a36b..cfb6117 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/service/DomainService.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/service/DomainService.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2026 github.com/MaloneTalk + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * limitations under the License. + */ package io.github.malonetalk.service; import io.github.malonetalk.dto.DomainCreateRequest; diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java b/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java index 7226fe8..4addce1 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2026 github.com/MaloneTalk + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * limitations under the License. + */ package io.github.malonetalk.service.impl; import com.github.pagehelper.Page; diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/service/semantic/table/TableSemanticServiceImpl.java b/data-agent-backend/src/main/java/io/github/malonetalk/service/semantic/table/TableSemanticServiceImpl.java index 7f161da..d064889 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/service/semantic/table/TableSemanticServiceImpl.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/service/semantic/table/TableSemanticServiceImpl.java @@ -119,7 +119,7 @@ public void updateTableSemantic(TableSemanticUpdateRequest request) { tableInfo.setTableName(normalizedTableName); tableInfo.setTableDescription( SemanticUtils.normalizeBlankToNull(request.tableDescription())); - tableInfo.setDomain(SemanticUtils.normalizeBlankToNull(request.domain())); + tableInfo.setDomain(normalizeDomain(request.domain())); tableInfo.setIsVisible(request.isVisible()); tableInfo.setCreateTime(LocalDateTime.now()); tableInfo.setUpdateTime(LocalDateTime.now()); @@ -129,7 +129,7 @@ public void updateTableSemantic(TableSemanticUpdateRequest request) { existing.setTableName(normalizedTableName); existing.setTableDescription( SemanticUtils.normalizeBlankToNull(request.tableDescription())); - existing.setDomain(SemanticUtils.normalizeBlankToNull(request.domain())); + existing.setDomain(normalizeDomain(request.domain())); existing.setIsVisible(request.isVisible()); existing.setUpdateTime(LocalDateTime.now()); tableInfoMapper.update(existing); @@ -202,4 +202,9 @@ private TableSemanticResponse mapResponse(TableInfo tableInfo) { private String normalizeName(String value) { return SemanticUtils.requireName(value, "tableName").toLowerCase(Locale.ROOT); } + + private String normalizeDomain(String value) { + String normalized = SemanticUtils.normalizeBlankToNull(value); + return normalized == null ? SemanticConstants.DEFAULT_DOMAIN : normalized; + } } diff --git a/data-agent-frontend/src/views/semantic/SemanticManage.vue b/data-agent-frontend/src/views/semantic/SemanticManage.vue index 4164b2d..e4d0444 100644 --- a/data-agent-frontend/src/views/semantic/SemanticManage.vue +++ b/data-agent-frontend/src/views/semantic/SemanticManage.vue @@ -143,4 +143,3 @@ } } - From 5aa071f7c2044d42e19d4d749a1d3c6bc13fa68c Mon Sep 17 00:00:00 2001 From: mengnankkkk Date: Thu, 4 Jun 2026 20:57:12 +0800 Subject: [PATCH 4/8] fix: add check in domain --- .../io/github/malonetalk/mapper/DomainInfoMapper.java | 2 ++ .../io/github/malonetalk/mapper/TableInfoMapper.java | 2 ++ .../malonetalk/service/impl/DomainServiceImpl.java | 11 +++++++---- .../src/main/resources/mapper/DomainInfoMapper.xml | 6 ++++++ .../src/main/resources/mapper/TableInfoMapper.xml | 5 +++++ 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/mapper/DomainInfoMapper.java b/data-agent-backend/src/main/java/io/github/malonetalk/mapper/DomainInfoMapper.java index bf15775..d727b62 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/mapper/DomainInfoMapper.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/mapper/DomainInfoMapper.java @@ -37,5 +37,7 @@ public interface DomainInfoMapper { List selectPage( @Param("query") DomainPageQuery query, @Param("sortDescending") boolean sortDescending); + DomainInfo selectById(@Param("id") Integer id); + DomainInfo selectByName(@Param("name") String name); } diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/mapper/TableInfoMapper.java b/data-agent-backend/src/main/java/io/github/malonetalk/mapper/TableInfoMapper.java index d3e48f2..92bfee3 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/mapper/TableInfoMapper.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/mapper/TableInfoMapper.java @@ -44,4 +44,6 @@ TableInfo selectByDatasourceIdAndTableName( List selectByDatasourceIdAndDomains( @Param("datasourceId") Integer datasourceId, @Param("domains") List domains); + + int countByDomain(@Param("domain") String domain); } diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java b/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java index 4addce1..4659bfd 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java @@ -26,6 +26,7 @@ import io.github.malonetalk.dto.pagination.PageResponse; import io.github.malonetalk.entity.DomainInfo; import io.github.malonetalk.mapper.DomainInfoMapper; +import io.github.malonetalk.mapper.TableInfoMapper; import io.github.malonetalk.service.DomainService; import io.github.malonetalk.utils.SemanticUtils; import java.time.LocalDateTime; @@ -38,6 +39,7 @@ public class DomainServiceImpl implements DomainService { private final DomainInfoMapper domainInfoMapper; + private final TableInfoMapper tableInfoMapper; @Override public PageResponse getDomainPage(DomainPageQuery query) { @@ -67,10 +69,7 @@ public DomainInfo findById(Integer id) { if (id == null) { throw new IllegalArgumentException("id 不能为空"); } - return domainInfoMapper.selectAll().stream() - .filter(d -> d.getId().equals(id)) - .findFirst() - .orElse(null); + return domainInfoMapper.selectById(id); } @Override @@ -119,6 +118,10 @@ public void delete(Integer id) { if (existing == null) { throw new IllegalArgumentException("领域不存在: id=" + id); } + int referenceCount = tableInfoMapper.countByDomain(existing.getName()); + if (referenceCount > 0) { + throw new IllegalArgumentException("领域正在被占用" + existing.getName()); + } domainInfoMapper.deleteByIds(List.of(id)); } diff --git a/data-agent-backend/src/main/resources/mapper/DomainInfoMapper.xml b/data-agent-backend/src/main/resources/mapper/DomainInfoMapper.xml index 67da044..9116ce8 100644 --- a/data-agent-backend/src/main/resources/mapper/DomainInfoMapper.xml +++ b/data-agent-backend/src/main/resources/mapper/DomainInfoMapper.xml @@ -32,6 +32,12 @@ + + + + DELETE FROM table_info WHERE datasource_id = #{datasourceId} From 72fcba6de3b154af2acb8cee470a3b722d6679d1 Mon Sep 17 00:00:00 2001 From: mengnankkkk Date: Thu, 4 Jun 2026 21:03:06 +0800 Subject: [PATCH 5/8] fix: add check in domain --- .../io/github/malonetalk/service/impl/DomainServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java b/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java index 4659bfd..b3123ea 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java @@ -118,6 +118,9 @@ public void delete(Integer id) { if (existing == null) { throw new IllegalArgumentException("领域不存在: id=" + id); } + if (SemanticConstants.DEFAULT_DOMAIN.equalsIgnoreCase(existing.getName())) { + throw new IllegalArgumentException("无法删除的领域" + existing.getName()); + } int referenceCount = tableInfoMapper.countByDomain(existing.getName()); if (referenceCount > 0) { throw new IllegalArgumentException("领域正在被占用" + existing.getName()); From e08d4a07bf1a006e38717b689654b1b40e16e22d Mon Sep 17 00:00:00 2001 From: mengnankkkk Date: Sat, 6 Jun 2026 14:48:20 +0800 Subject: [PATCH 6/8] fix: remove impl --- .../malonetalk/service/{impl => }/DomainServiceImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename data-agent-backend/src/main/java/io/github/malonetalk/service/{impl => }/DomainServiceImpl.java (98%) diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java b/data-agent-backend/src/main/java/io/github/malonetalk/service/DomainServiceImpl.java similarity index 98% rename from data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java rename to data-agent-backend/src/main/java/io/github/malonetalk/service/DomainServiceImpl.java index b3123ea..3f68bc1 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/service/impl/DomainServiceImpl.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/service/DomainServiceImpl.java @@ -15,7 +15,7 @@ * along with this program. If not, see . * limitations under the License. */ -package io.github.malonetalk.service.impl; +package io.github.malonetalk.service; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; @@ -27,7 +27,6 @@ import io.github.malonetalk.entity.DomainInfo; import io.github.malonetalk.mapper.DomainInfoMapper; import io.github.malonetalk.mapper.TableInfoMapper; -import io.github.malonetalk.service.DomainService; import io.github.malonetalk.utils.SemanticUtils; import java.time.LocalDateTime; import java.util.List; From 138c38f84cc80ff46503154b0d2650a24b30886f Mon Sep 17 00:00:00 2001 From: mengnankkkk Date: Sat, 6 Jun 2026 21:20:04 +0800 Subject: [PATCH 7/8] fix: frontend bug --- data-agent-frontend/vite.config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data-agent-frontend/vite.config.ts b/data-agent-frontend/vite.config.ts index c649ee9..90eab16 100644 --- a/data-agent-frontend/vite.config.ts +++ b/data-agent-frontend/vite.config.ts @@ -18,6 +18,7 @@ import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import eslint from 'vite-plugin-eslint'; +import { fileURLToPath, URL } from 'node:url'; /** * Vite configuration file @@ -31,7 +32,7 @@ export default defineConfig({ // Allows importing like: import xxx from '@/components/xxx' resolve: { alias: { - '@': '/src', + '@': fileURLToPath(new URL('./src', import.meta.url)), }, }, // Development server configuration From 053eca5d2a7d03404d942b9ec3ba21bf4800e583 Mon Sep 17 00:00:00 2001 From: mengnankkkk Date: Wed, 10 Jun 2026 23:12:50 +0800 Subject: [PATCH 8/8] Update DomainController.java --- .../github/malonetalk/controller/DomainController.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/data-agent-backend/src/main/java/io/github/malonetalk/controller/DomainController.java b/data-agent-backend/src/main/java/io/github/malonetalk/controller/DomainController.java index c479bff..3f905c1 100644 --- a/data-agent-backend/src/main/java/io/github/malonetalk/controller/DomainController.java +++ b/data-agent-backend/src/main/java/io/github/malonetalk/controller/DomainController.java @@ -49,6 +49,9 @@ public Result> findDomains(@Valid DomainPageQuery query @GetMapping("/{id}") public Result findById(@PathVariable Integer id) { + if (id == null || id < 0) { + return Result.error(400, "ID必须为非负数"); + } DomainInfo domain = domainService.findById(id); if (domain == null) { return Result.error(404, "领域不存在"); @@ -64,11 +67,17 @@ public Result create(@Valid @RequestBody DomainCreateRequest request @PutMapping("/{id}") public Result update( @PathVariable Integer id, @Valid @RequestBody DomainUpdateRequest request) { + if (id == null || id < 0) { + return Result.error(400, "ID必须为非负数"); + } return Result.success(domainService.update(id, request)); } @DeleteMapping("/{id}") public Result delete(@PathVariable Integer id) { + if (id == null || id < 0) { + return Result.error(400, "ID必须为非负数"); + } domainService.delete(id); return Result.success(true); }