chore: initialize qiming workspace repository

This commit is contained in:
Codex
2026-05-29 14:22:48 +08:00
commit bfd67a0f2c
10750 changed files with 1885711 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xspaceagi</groupId>
<artifactId>app-platform-compose</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>app-platform-compose-ui</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.xspaceagi</groupId>
<artifactId>app-platform-compose-application</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,35 @@
package com.xspaceagi.compose.ui.base;
import com.xspaceagi.system.spec.common.RequestContext;
import com.xspaceagi.system.spec.common.UserContext;
import com.xspaceagi.system.application.dto.UserDto;
import com.xspaceagi.system.infra.dao.entity.User;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public abstract class BaseController {
/**
* 获取当前登录用户信息
*
* @return
*/
public UserContext getUser() {
var userDto = (UserDto) RequestContext.get().getUser();
return UserContext.builder()
.userId(userDto.getId())
.userName(userDto.getUserName())
.nickName(userDto.getNickName())
.email(userDto.getEmail())
.phone(userDto.getPhone())
.status(userDto.getStatus() == User.Status.Enabled ? 1 : -1)
.tenantId(userDto.getTenantId())
.tenantName(null)
.orgId(null)
.orgName(null)
.roleType(null)
.build();
}
}

View File

@@ -0,0 +1,177 @@
package com.xspaceagi.compose.ui.controller;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import java.util.Objects;
import com.xspaceagi.system.domain.log.LogPrint;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.xspaceagi.compose.application.service.CustomTableDefinitionApplicationService;
import com.xspaceagi.compose.domain.dto.CustomAddBusinessRowDataVo;
import com.xspaceagi.compose.domain.dto.CustomDeleteBusinessRowDataVo;
import com.xspaceagi.compose.domain.dto.CustomUpdateBusinessRowDataVo;
import com.xspaceagi.compose.domain.model.CustomDorisDataRequest;
import com.xspaceagi.compose.sdk.DorisDataPage;
import com.xspaceagi.compose.spec.utils.ComposeExceptionUtils;
import com.xspaceagi.compose.ui.base.BaseController;
import com.xspaceagi.compose.ui.util.ComposeControllerUtil;
import com.xspaceagi.system.sdk.operate.ActionType;
import com.xspaceagi.system.sdk.operate.OperationLogReporter;
import com.xspaceagi.system.sdk.operate.SystemEnum;
import com.xspaceagi.system.spec.dto.ReqResult;
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
import com.xspaceagi.system.spec.exception.ComposeException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Tag(name = "数据表组件-业务数据管理")
@RestController
@RequestMapping("/api/compose/db/table")
public class ComposeDbBusinessDataController extends BaseController {
@Resource
private CustomTableDefinitionApplicationService customTableDefinitionApplicationService;
@OperationLogReporter(actionType = ActionType.QUERY, action = "查询数据表业务数据", objectName = "业务数据操作", systemCode = SystemEnum.DB_TABLE)
@LogPrint(step = "业务数据操作-查询数据表业务数据")
@Operation(summary = "查询数据表业务数据")
@RequestMapping(path = "/getTableDataById", method = RequestMethod.GET)
public ReqResult<DorisDataPage<Map<String, Object>>> getTableDataById(CustomDorisDataRequest request) {
DorisDataPage<Map<String, Object>> data = customTableDefinitionApplicationService
.queryPageDorisTableDataForWeb(request);
return ReqResult.success(data);
}
@OperationLogReporter(actionType = ActionType.ADD, action = "新增业务数据", objectName = "业务数据操作", systemCode = SystemEnum.DB_TABLE, spelExpression = "#request")
@LogPrint(step = "业务数据操作-新增业务数据")
@Operation(summary = "新增业务数据")
@RequestMapping(path = "/addBusinessData", method = RequestMethod.POST)
public ReqResult<Map<String, Object>> addBusinessData(@RequestBody CustomAddBusinessRowDataVo request) {
var userContext = this.getUser();
// 需要根据 DefaultTableFieldEnum 里面的关键系统字段,进行替换,具体字段:UID,USER_NAME,NICK_NAME
// 另外需要去掉数据中的主键id字段: ID; 业务行数据id是通过请求参数中的:rowId
ComposeControllerUtil.enrichRowDataWithUserInfo(request.getRowData(), userContext);
customTableDefinitionApplicationService.addBusinessData(request, userContext);
return ReqResult.success();
}
@OperationLogReporter(actionType = ActionType.MODIFY, action = "修改业务数据", objectName = "业务数据操作", systemCode = SystemEnum.DB_TABLE, spelExpression = "#request")
@LogPrint(step = "业务数据操作-修改业务数据")
@Operation(summary = "修改业务数据")
@RequestMapping(path = "/updateBusinessData", method = RequestMethod.POST)
public ReqResult<Map<String, Object>> updateBusinessData(@RequestBody CustomUpdateBusinessRowDataVo request) {
var userContext = this.getUser();
// 需要根据 DefaultTableFieldEnum 里面的关键系统字段,进行替换,具体字段:UID,USER_NAME,NICK_NAME
// 另外需要去掉数据中的主键id字段: ID; 业务行数据id是通过请求参数中的:rowId
ComposeControllerUtil.enrichRowDataWithUserInfo(request.getRowData(), userContext);
customTableDefinitionApplicationService.updateBusinessData(request, userContext);
return ReqResult.success();
}
@LogPrint(step = "业务数据操作-删除业务数据")
@Operation(summary = "删除业务数据")
@RequestMapping(path = "/deleteBusinessData", method = RequestMethod.POST)
public ReqResult<Void> deleteBusinessData(@RequestBody CustomDeleteBusinessRowDataVo request) {
var userContext = this.getUser();
// 1. 查询完整的行数据(用于日志记录,便于后续恢复)
Map<String, Object> rowData = customTableDefinitionApplicationService
.queryRowDataByTableIdAndRowId(request.getTableId(), request.getRowId());
// 2. 调用 Service 层删除(带上 @OperationLogReporter 注解)
customTableDefinitionApplicationService.deleteBusinessData(request, rowData, userContext);
return ReqResult.success();
}
@OperationLogReporter(actionType = ActionType.QUERY, action = "导出业务表数据为Excel", objectName = "业务数据操作", systemCode = SystemEnum.DB_TABLE)
@LogPrint(step = "业务数据操作-导出业务表数据为Excel")
@Operation(summary = "导出业务表数据为Excel")
@GetMapping("/exportExcel/{tableId}")
public void exportTableDataExcel(@PathVariable Long tableId, HttpServletResponse response) throws IOException {
var userContext = this.getUser();
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("UTF-8");
String fileName = "exported_data_" + tableId + ".xlsx";
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
OutputStream outputStream = response.getOutputStream();
customTableDefinitionApplicationService.exportTableDataToExcel(tableId, outputStream, userContext);
}
@OperationLogReporter(actionType = ActionType.DELETE, action = "清空业务数据", objectName = "业务数据操作", systemCode = SystemEnum.DB_TABLE)
@LogPrint(step = "业务数据操作-清空业务数据")
@Operation(summary = "清空业务数据")
@RequestMapping(path = "/clearBusinessData/{tableId}", method = RequestMethod.GET)
public ReqResult<Void> clearBusinessData(@PathVariable Long tableId) {
var userContext = this.getUser();
// check tableId 不为空
if (Objects.isNull(tableId)) {
throw ComposeException.build(BizExceptionCodeEnum.fieldRequiredButEmpty, "表Id");
}
customTableDefinitionApplicationService.clearBusinessData(tableId, userContext);
return ReqResult.success();
}
@OperationLogReporter(actionType = ActionType.ADD, action = "导入业务表数据Excel", objectName = "业务数据操作", systemCode = SystemEnum.DB_TABLE)
@LogPrint(step = "业务数据操作-导入业务表数据Excel")
@Operation(summary = "导入业务表数据Excel")
@PostMapping("/importExcel/{tableId}")
public ReqResult<Void> importTableDataExcel(@PathVariable Long tableId, @RequestParam("file") MultipartFile file) {
var userContext = this.getUser();
try {
customTableDefinitionApplicationService.importTableDataFromExcel(tableId, file.getInputStream(),
userContext);
return ReqResult.success();
} catch (Exception e) {
log.error("Import Excel failed", e);
// 使用用户友好的错误信息,提供更清晰的错误提示
String friendlyMessage = ComposeExceptionUtils.getUserFriendlyErrorMessage(e);
return ReqResult.error("导入Excel数据失败: " + friendlyMessage);
}
}
@OperationLogReporter(actionType = ActionType.ADD, action = "恢复被删除的业务数据", objectName = "业务数据操作", systemCode = SystemEnum.DB_TABLE, spelExpression = "#extraContent")
@LogPrint(step = "业务数据操作-恢复被删除的业务数据")
@Operation(summary = "恢复被删除的业务数据")
@PostMapping(value = "/restoreBusinessData", consumes = "application/x-www-form-urlencoded")
public ReqResult<String> restoreBusinessData(
@RequestParam("extraContent") String extraContent,
@RequestParam(value = "forceRestore", defaultValue = "false") Boolean forceRestore) {
var userContext = this.getUser();
try {
String result = customTableDefinitionApplicationService.restoreBusinessDataByExtraContent(
extraContent,
forceRestore,
userContext
);
return ReqResult.success(result);
} catch (Exception e) {
log.error("Failed to restore data", e);
return ReqResult.error("恢复数据失败: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,173 @@
package com.xspaceagi.compose.ui.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xspaceagi.compose.application.service.CustomTableDefinitionApplicationService;
import com.xspaceagi.compose.domain.model.CustomTableDefinitionModel;
import com.xspaceagi.compose.domain.repository.ICustomTableDefinitionRepository;
import com.xspaceagi.compose.ui.base.BaseController;
import com.xspaceagi.compose.ui.dto.*;
import com.xspaceagi.system.application.util.DefaultIconUrlUtil;
import com.xspaceagi.system.domain.log.LogPrint;
import com.xspaceagi.system.infra.service.QueryVoListDelegateService;
import com.xspaceagi.system.sdk.operate.ActionType;
import com.xspaceagi.system.sdk.operate.OperationLogReporter;
import com.xspaceagi.system.sdk.operate.SystemEnum;
import com.xspaceagi.system.sdk.permission.SpacePermissionService;
import com.xspaceagi.system.sdk.permission.IUserDataPermissionRpcService;
import com.xspaceagi.system.sdk.service.dto.UserDataPermissionDto;
import com.xspaceagi.system.spec.annotation.RequireResource;
import com.xspaceagi.system.spec.common.RequestContext;
import com.xspaceagi.system.spec.common.UserContext;
import com.xspaceagi.system.spec.dto.ReqResult;
import com.xspaceagi.system.spec.enums.ResourceEnum;
import com.xspaceagi.system.spec.page.PageQueryParamVo;
import com.xspaceagi.system.spec.page.PageQueryVo;
import com.xspaceagi.system.spec.page.SuperPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
@Tag(name = "数据表组件-表结构配置")
@RestController
@RequestMapping("/api/compose/db/table")
public class ComposeDbTableConfigController extends BaseController {
@Resource
private CustomTableDefinitionApplicationService customTableDefinitionApplicationService;
@Resource
private ICustomTableDefinitionRepository customTableDefinitionRepository;
@Resource
private QueryVoListDelegateService queryVoListDelegateService;
@Resource
private IUserDataPermissionRpcService userDataPermissionRpcService;
@Resource
private SpacePermissionService spacePermissionService;
@RequireResource(ResourceEnum.COMPONENT_LIB_CREATE)
@OperationLogReporter(actionType = ActionType.ADD, action = "新增表定义", objectName = "表定义配置", systemCode = SystemEnum.DB_TABLE)
@LogPrint(step = "表定义配置-新增表定义")
@Operation(summary = "新增表定义")
@PostMapping("/add")
public ReqResult<Long> addTableDefinition(@RequestBody CustomTableAddRequest request) {
UserContext userContext = this.getUser();
UserDataPermissionDto userDataPermission = userDataPermissionRpcService.getUserDataPermission(userContext.getUserId());
Long ct = customTableDefinitionApplicationService.countUserTotalTable(userContext.getUserId());
userDataPermission.checkMaxDataTableCount(ct.intValue());
var model = CustomTableAddRequest.convert2Model(request);
var data = customTableDefinitionApplicationService
.addInfo(model, userContext);
return ReqResult.success(data);
}
@RequireResource(ResourceEnum.COMPONENT_LIB_MODIFY)
@OperationLogReporter(actionType = ActionType.MODIFY, action = "更新表定义", objectName = "表定义配置", systemCode = SystemEnum.DB_TABLE)
@LogPrint(step = "表定义配置-更新表名称和描述信息")
@Operation(summary = "更新表名称和描述信息")
@PostMapping("/updateTableName")
public ReqResult<Void> updateTableName(@RequestBody CustomTableUpdateNameRequest request) {
UserContext userContext = this.getUser();
var model = CustomTableUpdateNameRequest.convert2Model(request);
customTableDefinitionApplicationService.updateTableName(model, userContext);
return ReqResult.success();
}
@RequireResource(ResourceEnum.COMPONENT_LIB_MODIFY)
@OperationLogReporter(actionType = ActionType.MODIFY, action = "更新表定义", objectName = "表定义配置", systemCode = SystemEnum.DB_TABLE)
@LogPrint(step = "表定义配置-更新表定义")
@Operation(summary = "更新表定义")
@PostMapping("/updateTableDefinition")
public ReqResult<Void> updateTableDefinition(@RequestBody CustomTableUpdateDefineRequest request) {
UserContext userContext = this.getUser();
var fieldList = CustomTableUpdateDefineRequest.convert2Model(request);
var tableId = request.getId();
customTableDefinitionApplicationService.updateInfo(tableId, fieldList, userContext);
return ReqResult.success();
}
@RequireResource(ResourceEnum.COMPONENT_LIB_DELETE)
@OperationLogReporter(actionType = ActionType.DELETE, action = "删除表定义", objectName = "表定义配置", systemCode = SystemEnum.DB_TABLE)
@LogPrint(step = "表定义配置-删除表定义")
@Operation(summary = "删除表定义")
@PostMapping("/delete/{id}")
public ReqResult<Void> deleteTableDefinition(@PathVariable("id") Long id) {
UserContext userContext = this.getUser();
customTableDefinitionApplicationService.deleteById(id, userContext);
return ReqResult.success();
}
@RequireResource(ResourceEnum.COMPONENT_LIB_QUERY_LIST)
@OperationLogReporter(actionType = ActionType.QUERY, action = "查询表定义列表", objectName = "表定义配置", systemCode = SystemEnum.DB_TABLE)
@LogPrint(step = "表定义配置-查询表定义列表")
@Operation(summary = "查询表定义列表")
@RequestMapping(path = "/list", method = RequestMethod.POST)
public ReqResult<IPage<CustomTableDefinitionModel>> list(
@RequestBody PageQueryVo<CustomTableQueryRequest> pageQueryVo) {
Assert.notNull(pageQueryVo, "pageQueryVo is null");
Assert.notNull(pageQueryVo.getQueryFilter(), "queryFilter is null");
Assert.notNull(pageQueryVo.getQueryFilter().getSpaceId(), "spaceId is null");
spacePermissionService.checkSpaceUserPermission(pageQueryVo.getQueryFilter().getSpaceId());
var filter = pageQueryVo.getQueryFilter();
pageQueryVo.setQueryFilter(filter);
PageQueryParamVo pageQueryParamVo = new PageQueryParamVo(pageQueryVo);
SuperPage<CustomTableDefinitionModel> superPage = this.queryVoListDelegateService.queryVoList(
this.customTableDefinitionRepository,
pageQueryParamVo, null);
superPage.getRecords().forEach(item -> item.setIcon(DefaultIconUrlUtil.setDefaultIconUrl(item.getIcon(), item.getTableName(), "table")));
return ReqResult.success(superPage);
}
@RequireResource(ResourceEnum.COMPONENT_LIB_QUERY_DETAIL)
@OperationLogReporter(actionType = ActionType.QUERY, action = "查询表定义详情", objectName = "表定义配置", systemCode = SystemEnum.DB_TABLE)
@LogPrint(step = "表定义配置-查询表定义详情")
@Operation(summary = "查询表定义详情")
@RequestMapping(path = "/detailById", method = RequestMethod.GET)
public ReqResult<FrontTableDefineResponseVo> getTableDefinitionById(@RequestParam("id") Long id) {
var tableModel = customTableDefinitionApplicationService.queryOneTableDefineVo(id);
var tableDefineVo = FrontTableDefineResponseVo.convert2FrontTableDefineResponseVo(tableModel);
// 查询业务数据,是否存在数据了
var existTableDataFlag = customTableDefinitionApplicationService.existTableData(id);
tableDefineVo.setExistTableDataFlag(existTableDataFlag);
tableDefineVo.setIcon(DefaultIconUrlUtil.setDefaultIconUrl(tableDefineVo.getIcon(), tableDefineVo.getTableName(), "table"));
return ReqResult.success(tableDefineVo);
}
@RequireResource(ResourceEnum.COMPONENT_LIB_QUERY_DETAIL)
@OperationLogReporter(actionType = ActionType.QUERY, action = "查询表是否存在业务数据", objectName = "表定义配置", systemCode = SystemEnum.DB_TABLE)
@LogPrint(step = "表定义配置-查询表是否存在业务数据")
@Operation(summary = "查询表是否存在业务数据")
@RequestMapping(path = "/existTableData", method = RequestMethod.GET)
public ReqResult<Boolean> existTableData(@RequestParam("tableId") Long tableId) {
Boolean existTableDataFlag = customTableDefinitionApplicationService.existTableData(tableId);
return ReqResult.success(existTableDataFlag);
}
@RequireResource(ResourceEnum.COMPONENT_LIB_COPY)
@OperationLogReporter(actionType = ActionType.ADD, action = "复制表结构定义", objectName = "表定义配置", systemCode = SystemEnum.DB_TABLE)
@LogPrint(step = "表定义配置-复制表结构定义")
@Operation(summary = "复制表结构定义")
@RequestMapping(path = "/copyTableDefinition", method = RequestMethod.POST)
public ReqResult<Long> copyTableDefinition(@RequestParam("tableId") Long tableId) {
UserDataPermissionDto userDataPermission = userDataPermissionRpcService.getUserDataPermission(RequestContext.get().getUserId());
userDataPermission.checkMaxDataTableCount(customTableDefinitionApplicationService.countUserTotalTable(userDataPermission.getUserId()).intValue());
UserContext userContext = this.getUser();
Long newTableId = customTableDefinitionApplicationService.copyTableDefinition(tableId, userContext);
return ReqResult.success(newTableId);
}
}

View File

@@ -0,0 +1,35 @@
package com.xspaceagi.compose.ui.dto;
import com.xspaceagi.compose.domain.dto.CustomEmptyTableVo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "新增表定义请求")
public class CustomTableAddRequest {
@Schema(description = "表名称")
private String tableName;
@Schema(description = "表描述")
private String tableDescription;
@Schema(description = "空间ID")
private Long spaceId;
@Schema(description = "图标")
private String icon;
public static CustomEmptyTableVo convert2Model(CustomTableAddRequest request) {
if (request == null) {
return null;
}
CustomEmptyTableVo model = new CustomEmptyTableVo();
model.setTableName(request.getTableName());
model.setTableDescription(request.getTableDescription());
model.setSpaceId(request.getSpaceId());
model.setIcon(request.getIcon());
return model;
}
}

View File

@@ -0,0 +1,18 @@
package com.xspaceagi.compose.ui.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "查询表定义请求")
public class CustomTableQueryRequest {
@Schema(description = "表名称")
private String tableName;
@Schema(description = "表描述")
private String tableDescription;
@Schema(description = "空间ID")
private Long spaceId;
}

View File

@@ -0,0 +1,37 @@
package com.xspaceagi.compose.ui.dto;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.xspaceagi.compose.domain.model.CustomFieldDefinitionModel;
import com.xspaceagi.compose.domain.model.CustomTableDefinitionModel;
import com.xspaceagi.compose.sdk.vo.data.FrontColumnDefineVo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
import java.util.stream.Collectors;
@Data
@Schema(description = "更新表结构定义")
public class CustomTableUpdateDefineRequest {
@Schema(description = "表ID")
private Long id;
@Schema(description = "表下面的字段定义列表")
@JsonPropertyDescription("表下面的字段定义列表")
private List<FrontColumnDefineVo> fieldList;
/**
* 转换为模型 ,前端给的字段
*/
public static List<CustomFieldDefinitionModel> convert2Model(CustomTableUpdateDefineRequest request) {
if (request == null) {
return null;
}
// 字段转换
List<CustomFieldDefinitionModel> fieldList = request.getFieldList().stream()
.map(CustomTableDefinitionModel::convert2Model)
.collect(Collectors.toList());
return fieldList;
}
}

View File

@@ -0,0 +1,34 @@
package com.xspaceagi.compose.ui.dto;
import com.xspaceagi.compose.domain.model.CustomTableDefinitionModel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "更新表名称和描述请求")
public class CustomTableUpdateNameRequest {
@Schema(description = "表ID")
private Long id;
@Schema(description = "表名称")
private String tableName;
@Schema(description = "表描述")
private String tableDescription;
@Schema(description = "表图标")
private String icon;
public static CustomTableDefinitionModel convert2Model(CustomTableUpdateNameRequest request) {
if (request == null) {
return null;
}
CustomTableDefinitionModel model = new CustomTableDefinitionModel();
model.setId(request.getId());
model.setTableName(request.getTableName());
model.setTableDescription(request.getTableDescription());
model.setIcon(request.getIcon());
return model;
}
}

View File

@@ -0,0 +1,136 @@
package com.xspaceagi.compose.ui.dto;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.xspaceagi.compose.domain.model.CustomFieldDefinitionModel;
import com.xspaceagi.compose.domain.model.CustomTableDefinitionModel;
import com.xspaceagi.compose.sdk.vo.data.FrontColumnDefineVo;
import com.xspaceagi.system.spec.enums.YnEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Schema(description = "表结构定义")
@Getter
@Setter
@Builder
public class FrontTableDefineResponseVo {
/**
* 主键ID
*/
@Schema(description = "主键ID")
@JsonPropertyDescription("主键ID")
private Long id;
/**
* 租户ID
*/
@Schema(description = "租户ID")
@JsonPropertyDescription("租户ID")
private Long tenantId;
/**
* 所属空间ID
*/
@Schema(description = "所属空间ID")
@JsonPropertyDescription("所属空间ID")
private Long spaceId;
/**
* 图标图片地址
*/
@Schema(description = "图标图片地址")
@JsonPropertyDescription("图标图片地址")
private String icon;
/**
* 表名
*/
@Schema(description = "表名")
@JsonPropertyDescription("表名")
private String tableName;
/**
* 表描述
*/
@Schema(description = "表描述")
@JsonPropertyDescription("表描述")
private String tableDescription;
/**
* Doris数据库名
*/
@Schema(description = "Doris数据库名")
@JsonPropertyDescription("Doris数据库名")
private String dorisDatabase;
/**
* Doris表名
*/
@Schema(description = "Doris表名")
@JsonPropertyDescription("Doris表名")
private String dorisTable;
@Schema(description = "表下面的字段定义列表")
@JsonPropertyDescription("表下面的字段定义列表")
private List<FrontColumnDefineVo> fieldList;
@Schema(description = "原始建表DDL")
@JsonPropertyDescription("原始建表DDL")
private String createTableDdl;
@Schema(description = "是否存在业务数据,true:存在数据;false:不存在数据")
@JsonPropertyDescription("是否存在业务数据,true:存在数据;false:不存在数据")
private Boolean existTableDataFlag;
/**
* 转换为前端表定义响应VO
*
* @param tableModel 表定义模型
* @return 前端表定义响应VO
*/
public static FrontTableDefineResponseVo convert2FrontTableDefineResponseVo(CustomTableDefinitionModel tableModel) {
FrontTableDefineResponseVo responseVo = FrontTableDefineResponseVo.builder()
.id(tableModel.getId())
.tenantId(tableModel.getTenantId())
.spaceId(tableModel.getSpaceId())
.icon(tableModel.getIcon())
.tableName(tableModel.getTableName())
.tableDescription(tableModel.getTableDescription())
.dorisDatabase(tableModel.getDorisDatabase())
.dorisTable(tableModel.getDorisTable())
.createTableDdl(tableModel.getCreateTableDdl())
.existTableDataFlag(true)
.build();
// 字段列表
List<FrontColumnDefineVo> fieldList = new ArrayList<>();
for (CustomFieldDefinitionModel field : tableModel.getFieldList()) {
FrontColumnDefineVo columnDefineVo = FrontColumnDefineVo.builder()
.id(field.getId())
.systemFieldFlag(field.getSystemFieldFlag() == YnEnum.Y.getKey())
.fieldName(field.getFieldName())
.fieldDescription(field.getFieldDescription())
.fieldType(field.getFieldType())
.nullableFlag(field.getNullableFlag() == YnEnum.Y.getKey())
.defaultValue(field.getDefaultValue())
.uniqueFlag(field.getUniqueFlag() == YnEnum.Y.getKey())
.enabledFlag(field.getEnabledFlag() == YnEnum.Y.getKey())
.sortIndex(field.getSortIndex())
.build();
fieldList.add(columnDefineVo);
}
responseVo.setFieldList(fieldList);
responseVo.setCreateTableDdl(tableModel.getCreateTableDdl());
return responseVo;
}
}

View File

@@ -0,0 +1,88 @@
package com.xspaceagi.compose.ui.util;
import java.util.Map;
import java.util.Objects;
import com.xspaceagi.compose.sdk.enums.DefaultTableFieldEnum;
import com.xspaceagi.system.spec.common.UserContext;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* Compose UI 控制器相关的工具类
*/
@Slf4j
@NoArgsConstructor
public class ComposeControllerUtil {
/**
* 使用用户信息丰富或覆盖rowData并移除其中的主键ID和其它系统管理字段。
* UID 必须存在,会覆盖。
* USER_NAME 和 NICK_NAME 如果在 UserContext 中存在非null则覆盖如果为null则从 rowData 中移除。
* ID, AGENT_ID, AGENT_NAME, CREATED 字段会从 rowData 中移除,防止用户传递。
* 直接修改传入的 rowData Map。
*
* @param rowData 业务数据Map将被修改。
* @param userContext 当前用户上下文。
*/
public static void enrichRowDataWithUserInfo(Map<String, Object> rowData, UserContext userContext) {
if (rowData == null || userContext == null) {
log.warn("enrichRowDataWithUserInfo: rowData or userContext null, skip.");
return;
}
log.debug("Process rowData (user fields / system fields). UserContext: {}, rowData: {}", userContext, rowData);
// UID: 必须存在,直接设置(或覆盖)
String uid = null;
if(Objects.isNull(userContext.getUid() )){
uid = userContext.getUserId().toString();
} else {
uid = userContext.getUid();
}
rowData.put(DefaultTableFieldEnum.UID.getFieldName(), uid);
// USER_NAME: 如果非空则设置,如果为空则移除
String userName = userContext.getUserName();
if (userName != null) {
rowData.put(DefaultTableFieldEnum.USER_NAME.getFieldName(), userName);
} else {
rowData.remove(DefaultTableFieldEnum.USER_NAME.getFieldName());
log.debug("userName null, removed key: {}",
DefaultTableFieldEnum.USER_NAME.getFieldName());
}
// NICK_NAME: 如果非空则设置,如果为空则移除
String nickName = userContext.getNickName();
if (nickName != null) {
rowData.put(DefaultTableFieldEnum.NICK_NAME.getFieldName(), nickName);
} else {
rowData.remove(DefaultTableFieldEnum.NICK_NAME.getFieldName());
log.debug("nickName null, removed key: {}",
DefaultTableFieldEnum.NICK_NAME.getFieldName());
}
// 移除系统管理的字段,防止用户传递
removeSystemField(rowData, DefaultTableFieldEnum.ID);
removeSystemField(rowData, DefaultTableFieldEnum.AGENT_ID);
removeSystemField(rowData, DefaultTableFieldEnum.AGENT_NAME);
removeSystemField(rowData, DefaultTableFieldEnum.CREATED);
removeSystemField(rowData, DefaultTableFieldEnum.MODIFIED);
log.debug("Processed rowData: {}", rowData);
}
/**
* 从 rowData 中移除指定的系统字段,并记录日志。
*/
private static void removeSystemField(Map<String, Object> rowData, DefaultTableFieldEnum fieldEnum) {
if (fieldEnum == null)
return;
String fieldName = fieldEnum.getFieldName();
if (rowData.containsKey(fieldName)) {
Object removedValue = rowData.remove(fieldName);
log.debug("Removed system field '{}' from rowData, value: {}", fieldName, removedValue);
}
}
}