upd: 控制器

This commit is contained in:
骑着蜗牛追导弹 2024-12-06 21:11:38 +08:00
parent 1bbca46b72
commit 3a0a233f6a
15 changed files with 415 additions and 77 deletions

View File

@ -7,8 +7,9 @@ package cn.odboy.constant;
* @date 2024-09-13
*/
public interface RegexConst {
// 正则表达式用于匹配中国大陆手机号码
/** 正则表达式,用于匹配中国大陆手机号码 */
String PHONE_NUMBER = "^1[3-9]\\d{9}$";
// 小写字母和下划线
/** 小写字母和下划线 */
String LOW_CHAR_LINE = "^[a-z_]+$";
}

View File

@ -1,17 +1,19 @@
package cn.odboy.domain;
import cn.odboy.base.MyObject;
import cn.odboy.base.MyLogicEntity;
import cn.odboy.base.MyNormalEntity;
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 javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 配置应用
* </p>
*
* @author odboy
* @since 2024-12-05
@ -19,18 +21,46 @@ import lombok.Setter;
@Getter
@Setter
@TableName("config_app")
public class ConfigApp extends MyObject {
public class ConfigApp extends MyNormalEntity {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 应用名称
*/
/** 应用名称 */
@TableField("app_name")
private String appName;
/**
* 应用说明
*/
/** 应用说明 */
@TableField("description")
private String description;
@Data
public static class CreateArgs {
@NotBlank(message = "必填")
private String appName;
@NotBlank(message = "必填")
private String description;
}
@Data
public static class ModifyDescriptionArgs {
@NotNull(message = "必填")
private Long id;
@NotBlank(message = "必填")
private String description;
}
@Data
public static class RemoveArgs{
@NotNull(message = "必填")
private Long id;
}
@Data
public static class ClientInfo{
private String ip;
private Boolean isActive = false;
}
}

View File

@ -0,0 +1,25 @@
package cn.odboy.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
/**
* 配置应用与用户关联关系
*
* @author odboy
* @since 2024-12-06
*/
@Getter
@Setter
@TableName("config_app_user")
public class ConfigAppUser {
/** 应用名称 */
@TableField("app_id")
private Long appId;
/** 应用名称 */
@TableField("user_id")
private Long userId;
}

View File

@ -1,18 +1,21 @@
package cn.odboy.domain;
import cn.odboy.base.MyObject;
import cn.odboy.base.MyNormalEntity;
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 javax.mail.Multipart;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.web.multipart.MultipartFile;
/**
* <p>
* 配置文件
* </p>
*
* @author odboy
* @since 2024-12-05
@ -20,26 +23,51 @@ import lombok.Setter;
@Getter
@Setter
@TableName("config_file")
public class ConfigFile extends MyObject {
public class ConfigFile extends MyNormalEntity {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@TableField("app_name")
private String appName;
/** configAppId */
@TableField("app_id")
private Long appId;
/** 环境编码 */
@TableField("env")
private String env;
/**
* 例如: application-daily.properties
*/
/** 例如: application-daily.properties */
@TableField("file_name")
private String fileName;
/**
* 当前配置内容版本
*/
/** 当前配置内容版本 */
@TableField("version")
private Long version;
@Data
public static class CreateArgs {
@NotNull(message = "必填")
private Long appId;
@NotBlank(message = "必填")
private String env;
@NotNull(message = "必填")
private MultipartFile file;
}
@Data
public static class ModifyFileContentArgs {
@NotNull(message = "必填")
private Long id;
@NotBlank(message = "必填")
private String fileContent;
}
@Data
public class RemoveArgs {
@NotNull(message = "必填")
private Long id;
}
}

View File

@ -1,17 +1,13 @@
package cn.odboy.domain;
import cn.odboy.base.MyObject;
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 lombok.Getter;
import lombok.Setter;
/**
* <p>
* 配置内容版本
* </p>
*
* @author odboy
* @since 2024-12-05
@ -20,9 +16,15 @@ import lombok.Setter;
@Setter
@TableName("config_version")
public class ConfigVersion extends MyObject {
/** 文件id */
@TableField("file_id")
private Long fileId;
/** 配置文件内容 */
@TableField("file_content")
private byte[] fileContent;
private String fileContent;
/** 配置文件内容版本 */
@TableField("version")
private Long version;
}

View File

@ -0,0 +1,14 @@
package cn.odboy.mapper;
import cn.odboy.domain.ConfigVersion;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 配置版本 Mapper 接口
*
* @author odboy
* @since 2024-12-05
*/
@Mapper
public interface ConfigVersionMapper extends BaseMapper<ConfigVersion> {}

View File

@ -0,0 +1,58 @@
package cn.odboy.rest;
import cn.odboy.base.model.SelectOption;
import cn.odboy.domain.ConfigApp;
import cn.odboy.infra.exception.BadRequestException;
import cn.odboy.infra.netty.ConfigClientManage;
import cn.odboy.infra.response.PageArgs;
import cn.odboy.infra.response.PageResult;
import cn.odboy.infra.rest.AnonymousAccess;
import cn.odboy.modules.system.domain.User;
import cn.odboy.modules.system.domain.vo.UserQueryCriteria;
import cn.odboy.service.ConfigAppService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
/**
* 配置文件 前端控制器
*
* @author odboy
* @since 2024-12-05
*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/config/app")
public class ConfigAppController {
private final ConfigAppService configAppService;
@PostMapping("/create")
public ResponseEntity<Object> create(@Validated @RequestBody ConfigApp.CreateArgs args) {
configAppService.create(args);
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/remove")
public ResponseEntity<Object> remove(@Validated @RequestBody ConfigApp.RemoveArgs args) {
configAppService.remove(args);
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/modifyDescription")
public ResponseEntity<Object> modifyDescription(@Validated @RequestBody ConfigApp.ModifyDescriptionArgs args) {
configAppService.modifyDescription(args);
return new ResponseEntity<>(HttpStatus.OK);
}
@AnonymousAccess
@GetMapping("/queryClientList")
public ResponseEntity<Object> queryClientList() {
return new ResponseEntity<>(ConfigClientManage.queryClientInfos("daily", "kenaito-config-demo"), HttpStatus.OK);
}
}

View File

@ -1,18 +1,44 @@
package cn.odboy.rest;
import cn.odboy.domain.ConfigApp;
import cn.odboy.domain.ConfigFile;
import cn.odboy.service.ConfigFileService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
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.RestController;
/**
* <p>
* 配置文件 前端控制器
* </p>
*
* @author odboy
* @since 2024-12-05
*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/configFile")
@RequestMapping("/api/config/file")
public class ConfigFileController {
private final ConfigFileService configFileService;
@PostMapping("/create")
public ResponseEntity<Object> create(@Validated @RequestBody ConfigFile.CreateArgs args) throws Exception {
configFileService.create(args);
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/remove")
public ResponseEntity<Object> remove(@Validated @RequestBody ConfigFile.RemoveArgs args) {
configFileService.remove(args);
return new ResponseEntity<>(HttpStatus.OK);
}
@PostMapping("/modifyFileContent")
public ResponseEntity<Object> modifyFileContent(@Validated @RequestBody ConfigFile.ModifyFileContentArgs args) {
configFileService.modifyFileContent(args);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@ -14,4 +14,9 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface ConfigAppService extends IService<ConfigApp> {
void create(ConfigApp.CreateArgs args);
void remove(ConfigApp.RemoveArgs args);
void modifyDescription(ConfigApp.ModifyDescriptionArgs args);
}

View File

@ -1,22 +1,26 @@
package cn.odboy.service;
import cn.odboy.config.model.msgtype.ConfigFileInfo;
import cn.odboy.domain.ConfigFile;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 配置文件 服务类
* </p>
*
* @author odboy
* @since 2024-12-05
*/
public interface ConfigFileService {
public interface ConfigFileService extends IService<ConfigFile> {
/**
* @param env 环境编码
* @param dataId 数据ID这里是应用名称
* @return /
*/
List<ConfigFileInfo> getFileList(String env, String dataId);
List<ConfigFile> queryInAppId(Long appId);
void create(ConfigFile.CreateArgs args) throws Exception;
void remove(ConfigFile.RemoveArgs args);
void modifyFileContent(ConfigFile.ModifyFileContentArgs args);
}

View File

@ -0,0 +1,17 @@
package cn.odboy.service;
import cn.odboy.domain.ConfigVersion;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 配置版本 服务类
*
* @author odboy
* @since 2024-12-05
*/
public interface ConfigVersionService extends IService<ConfigVersion> {
List<ConfigVersion> queryInFileId(List<Long> fileIds);
void removeBatchByFileId(Long fileId);
}

View File

@ -1,23 +1,66 @@
package cn.odboy.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.odboy.domain.ConfigApp;
import cn.odboy.domain.ConfigFile;
import cn.odboy.domain.ConfigVersion;
import cn.odboy.mapper.ConfigAppMapper;
import cn.odboy.mapper.ConfigFileMapper;
import cn.odboy.service.ConfigAppService;
import cn.odboy.service.ConfigFileService;
import cn.odboy.service.ConfigVersionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* 配置应用 服务实现类
* </p>
*
* @author odboy
* @since 2024-12-05
*/
@Service
public class ConfigAppServiceImpl extends ServiceImpl<ConfigAppMapper, ConfigApp> implements ConfigAppService {
@RequiredArgsConstructor
public class ConfigAppServiceImpl extends ServiceImpl<ConfigAppMapper, ConfigApp>
implements ConfigAppService {
private final ConfigFileService configFileService;
private final ConfigVersionService configVersionService;
@Override
@Transactional(rollbackFor = Exception.class)
public void create(ConfigApp.CreateArgs args) {
save(BeanUtil.copyProperties(args, ConfigApp.class));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void remove(ConfigApp.RemoveArgs args) {
removeById(args.getId());
List<ConfigFile> configFileList = configFileService.queryInAppId(args.getId());
if (configFileList.isEmpty()) {
return;
}
List<Long> configFileIds =
configFileList.stream().map(ConfigFile::getId).distinct().collect(Collectors.toList());
configFileService.removeBatchByIds(configFileIds);
List<ConfigVersion> configVersionList = configVersionService.queryInFileId(configFileIds);
if (configVersionList.isEmpty()) {
return;
}
List<Long> configVersionIds =
configVersionList.stream()
.map(ConfigVersion::getFileId)
.distinct()
.collect(Collectors.toList());
configVersionService.removeBatchByIds(configVersionIds);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void modifyDescription(ConfigApp.ModifyDescriptionArgs args) {
ConfigApp configApp = BeanUtil.copyProperties(args, ConfigApp.class);
updateById(configApp);
}
}

View File

@ -1,28 +1,81 @@
package cn.odboy.service.impl;
import cn.hutool.core.util.StrUtil;
import cn.odboy.config.model.msgtype.ConfigFileInfo;
import cn.odboy.domain.ConfigFile;
import cn.odboy.domain.ConfigVersion;
import cn.odboy.mapper.ConfigFileMapper;
import cn.odboy.service.ConfigFileService;
import cn.odboy.service.ConfigVersionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.nio.charset.StandardCharsets;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
/**
* <p>
* 配置文件 服务实现类
* </p>
*
* @author odboy
* @since 2024-12-05
*/
@Service
@RequiredArgsConstructor
public class ConfigFileServiceImpl implements ConfigFileService {
private final ConfigFileMapper configFileMapper;
public class ConfigFileServiceImpl extends ServiceImpl<ConfigFileMapper, ConfigFile>
implements ConfigFileService {
private final ConfigVersionService configVersionService;
@Override
public List<ConfigFileInfo> getFileList(String env, String dataId) {
return configFileMapper.selectByEnvAndAppName(env, dataId);
return getBaseMapper().selectByEnvAndAppName(env, dataId);
}
@Override
public List<ConfigFile> queryInAppId(Long appId) {
return list(new LambdaQueryWrapper<ConfigFile>().in(ConfigFile::getAppId, appId));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(ConfigFile.CreateArgs args) throws Exception {
MultipartFile file = args.getFile();
Long version = 1L;
ConfigFile configFile = new ConfigFile();
configFile.setEnv(args.getEnv());
configFile.setAppId(args.getAppId());
configFile.setFileName(file.getOriginalFilename());
configFile.setVersion(version);
save(configFile);
ConfigVersion configVersion = new ConfigVersion();
configVersion.setFileId(configFile.getId());
configVersion.setFileContent(StrUtil.str(file.getBytes(), StandardCharsets.UTF_8));
configVersion.setVersion(version);
configVersionService.save(configVersion);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void remove(ConfigFile.RemoveArgs args) {
removeById(args.getId());
configVersionService.removeBatchByFileId(args.getId());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void modifyFileContent(ConfigFile.ModifyFileContentArgs args) {
ConfigFile originConfigFile = getById(args.getId());
long newVersion = originConfigFile.getVersion() + 1;
ConfigFile updVersion = new ConfigFile();
updVersion.setId(originConfigFile.getId());
updVersion.setVersion(newVersion);
updateById(updVersion);
ConfigVersion lastConfigVersion = new ConfigVersion();
lastConfigVersion.setFileId(originConfigFile.getId());
lastConfigVersion.setFileContent(args.getFileContent());
lastConfigVersion.setVersion(newVersion);
configVersionService.save(lastConfigVersion);
}
}

View File

@ -0,0 +1,31 @@
package cn.odboy.service.impl;
import cn.odboy.domain.ConfigVersion;
import cn.odboy.mapper.ConfigVersionMapper;
import cn.odboy.service.ConfigVersionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.List;
import org.springframework.stereotype.Service;
/**
* 配置版本 服务实现类
*
* @author odboy
* @since 2024-12-05
*/
@Service
public class ConfigVersionServiceImpl extends ServiceImpl<ConfigVersionMapper, ConfigVersion>
implements ConfigVersionService {
@Override
public List<ConfigVersion> queryInFileId(List<Long> fileIds) {
return list(new LambdaQueryWrapper<ConfigVersion>().in(ConfigVersion::getFileId, fileIds));
}
@Override
public void removeBatchByFileId(Long fileId) {
remove(new LambdaQueryWrapper<ConfigVersion>()
.eq(ConfigVersion::getFileId, fileId)
);
}
}

View File

@ -2,12 +2,13 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.odboy.mapper.ConfigFileMapper">
<select id="selectByEnvAndAppName" resultType="cn.odboy.config.model.msgtype.ConfigFileInfo">
SELECT t1.file_name,
t2.file_content
FROM config_file t1
LEFT JOIN config_version t2 ON t1.id = t2.file_id
AND t1.version = t2.version
WHERE t1.env = #{env}
SELECT t2.file_name,
t3.file_content
FROM config_app t1
LEFT JOIN config_file t2 ON t1.id = t2.app_id
LEFT JOIN config_version t3 ON t1.id = t3.file_id
AND t2.version = t3.version
WHERE t2.env = #{env}
AND t1.app_name = #{dataId}
</select>
</mapper>