微服务后端空项目初始化

This commit is contained in:
yaoyn
2025-04-28 15:12:21 +08:00
parent 9b7d27a2b4
commit 03225ee88a
1927 changed files with 2448 additions and 359209 deletions

237
facade-service/pom.xml Normal file
View File

@ -0,0 +1,237 @@
<?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.geg</groupId>
<artifactId>ms-demo</artifactId>
<version>${revision}</version>
</parent>
<artifactId>facade-service</artifactId>
<name>facade-service</name>
<description>facade-service</description>
<properties>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.geg</groupId>
<artifactId>itc-ms-common-service</artifactId>
<version>${framework.version}</version>
</dependency>
<dependency>
<groupId>com.geg</groupId>
<artifactId>itc-ms-facade-api</artifactId>
<version>${framework.version}</version>
</dependency>
<!-- springCloud 整合的openFeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!--引入nacos依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--引入spring-cloud-alibaba-nacos-config依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--引入spring-cloud-alibaba-nacos-config bootstrap依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--引入sentinel依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!-- mybatis-plus 多表关联 -->
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join</artifactId>
</dependency>
<dependency>
<groupId>com.cloud.govern</groupId>
<artifactId>service-invoke-sdk</artifactId>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<dependency>
<groupId>com.unfbx</groupId>
<artifactId>chatgpt-java</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>tech.powerjob</groupId>
<artifactId>powerjob-worker-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authz-client</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.ews-java-api</groupId>
<artifactId>ews-java-api</artifactId>
</dependency>
<dependency>
<groupId>tech.powerjob</groupId>
<artifactId>powerjob-official-processors</artifactId>
</dependency>
<dependency>
<groupId>tech.powerjob</groupId>
<artifactId>powerjob-worker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.smallbun.screw</groupId>
<artifactId>screw-core</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.6</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<!--<classifier>classes</classifier>-->
<attach>false</attach>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.vm</include>
<include>**/*.ftl</include>
<include>**/*.jpg</include>
<include>**/*.png</include>
<include>**/*.xls</include>
<include>**/*.xlsx</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>

View File

@ -0,0 +1,25 @@
package com.xjrsoft;
import com.xjrsoft.common.annotation.UniqueNameGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* @author Zexy
*/
@SpringBootApplication
@EnableAspectJAutoProxy(exposeProxy = true)
@ComponentScan(nameGenerator = UniqueNameGenerator.class)
@EnableFeignClients
@EnableDiscoveryClient
public class ITCFacadeApplication {
public static void main(String[] args) {
SpringApplication.run(ITCFacadeApplication.class, args);
}
}

View File

@ -0,0 +1,42 @@
package com.xjrsoft.module.magicapi.client;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.module.magicapi.dto.ExecuteWorkflowApiDto;
import com.xjrsoft.module.magicapi.vo.MagicApiInfoVo;
import com.xjrsoft.module.magicapi.service.IMagicApiService;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
* @Author: tzx
* @Date: 2023/10/10 17:43
*/
@Api(hidden = true)
@RestController
@RequestMapping(GlobalConstant.CLIENT_API_PRE + GlobalConstant.MAGICAPI_MODULE_PREFIX + "/magic-api")
@AllArgsConstructor
public class MagicApiClientImpl implements IMagicApiClient {
private IMagicApiService magicApiService;
@Override
@GetMapping("/executeApi")
public Object executeApi(@RequestParam("id") String id) {
return magicApiService.executeApi(id);
}
@PostMapping("/executeWorkflowApi")
@Override
public Object executeWorkflowApi(@RequestBody ExecuteWorkflowApiDto dto) {
return magicApiService.executeWorkflowApi(dto.getApiConfig(), dto.getProcessParam(), dto.getVarMap(), dto.getProcessInstId(), dto.getExecutionId());
}
@GetMapping("/info")
@Override
public MagicApiInfoVo info(@RequestParam("id") String id) {
return magicApiService.info(id);
}
}

View File

@ -0,0 +1,64 @@
package com.xjrsoft.module.magicapi.controller;
import com.xjrsoft.common.annotation.XjrLog;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.model.result.R;
import com.xjrsoft.module.magicapi.vo.MagicApiTreeVo;
import com.xjrsoft.module.magicapi.service.IMagicApiService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* magic-api模块接口
* </p>
*
* @author tzx
* @since 2022-10-30
*/
@RestController
@RequestMapping(GlobalConstant.MAGICAPI_MODULE_PREFIX)
@Api(value = GlobalConstant.MAGICAPI_MODULE_PREFIX, tags = "magic-api模块接口")
@AllArgsConstructor
public class MagicApiController {
private final IMagicApiService magicApiService;
@GetMapping(value = "/tree")
@ApiOperation("查询所有分组以及api 树结构")
@XjrLog(value = "查询所有分组以及api 树结构")
public R tree(@RequestParam(required = false) String keyword ) {
List<MagicApiTreeVo> tree = magicApiService.tree(keyword);
return R.ok(tree);
}
@GetMapping(value = "/group/tree")
@ApiOperation("查询所有树结构分组")
@XjrLog(value = "查询所有树结构分组")
public R groupTree(){
return R.ok(magicApiService.groupTree());
}
@GetMapping(value = "/info")
@ApiOperation("查询api详情")
@XjrLog(value = "查询api详情")
public R info(@RequestParam String id){
return R.ok(magicApiService.info(id));
}
@GetMapping(value = "/list")
@ApiOperation("根据分组id 查询所有api")
@XjrLog(value = "根据分组id 查询所有api")
public R list(@RequestParam String groupId){
return R.ok(magicApiService.list(groupId));
}
}

View File

@ -0,0 +1,55 @@
package com.xjrsoft.module.magicapi.service;
import com.xjrsoft.module.magicapi.vo.MagicApiGroupTreeVo;
import com.xjrsoft.module.magicapi.vo.MagicApiInfoVo;
import com.xjrsoft.module.magicapi.vo.MagicApiTreeVo;
import com.xjrsoft.module.workflow.model.ApiConfig;
import java.util.List;
import java.util.Map;
public interface IMagicApiService {
/**
* 分组以及api 树结构
* @return
*/
List<MagicApiTreeVo> tree(String keyword);
/**
* 分组树
* @return
*/
List<MagicApiGroupTreeVo> groupTree();
/**
* 根据 id 获取 接口信息
* @param id
* @return
*/
MagicApiInfoVo info(String id);
/**
* 根据分组查询所有接口
* @param groupId
* @return
*/
List<MagicApiInfoVo> list(String groupId);
/**
* 执行API
* @param id 接口id
* @param <T>
* @return
*/
<T> T executeApi(String id);
/**
* 执行工作流api
* @param apiConfig
* @param processParam
* @param varMap
* @return
*/
Object executeWorkflowApi(ApiConfig apiConfig, Map<String, Object> processParam, Map<String, Object> varMap,String processInstId,String executionId);
}

View File

@ -0,0 +1,195 @@
package com.xjrsoft.module.magicapi.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.xjrsoft.common.utils.TreeUtil;
import com.xjrsoft.module.magicapi.vo.MagicApiGroupTreeVo;
import com.xjrsoft.module.magicapi.vo.MagicApiInfoVo;
import com.xjrsoft.module.magicapi.vo.MagicApiTreeVo;
import com.xjrsoft.module.workflow.model.ApiConfig;
import com.xjrsoft.module.workflow.model.ApiRequestParamsConfig;
import com.xjrsoft.module.magicapi.service.IMagicApiService;
import com.xjrsoft.module.magicapi.utils.MagicApiUtil;
import lombok.AllArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.ssssssss.magicapi.core.model.*;
import org.ssssssss.magicapi.core.service.MagicAPIService;
import org.ssssssss.magicapi.core.service.MagicResourceService;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* magic-api服务
*
* @author apple
*/
@Service
@AllArgsConstructor
public class MagicApiServiceImpl implements IMagicApiService {
private final MagicResourceService magicResourceService;
private final MagicAPIService magicAPIService;
@Override
public List<MagicApiTreeVo> tree(String keyword) {
TreeNode<Group> tree = magicResourceService.tree("api");
List<TreeNode<Group>> children = tree.getChildren();
return TreeUtil.build(buildTreeData(children, keyword));
}
@Override
public List<MagicApiGroupTreeVo> groupTree() {
TreeNode<Group> tree = magicResourceService.tree("api");
List<TreeNode<Group>> children = tree.getChildren();
List<MagicApiGroupTreeVo> treeVoList = new ArrayList<>();
buildGroupTreeData(treeVoList, children);
return TreeUtil.build(treeVoList);
}
@Override
public MagicApiInfoVo info(String id) {
MagicEntity entity = magicResourceService.file(id);
BaseDefinition requestBodyDefinition = ((ApiInfo) entity).getRequestBodyDefinition();
MagicApiInfoVo magicApiInfoVo = BeanUtil.toBean(entity, MagicApiInfoVo.class);
String groupId = entity.getGroupId();
if (StringUtils.isNotEmpty(groupId)) {
String groupPath = magicResourceService.getGroupPath(groupId);
magicApiInfoVo.setPath(groupPath + magicApiInfoVo.getPath());
}
magicApiInfoVo.setRequestBodyDefinition(requestBodyDefinition);
return magicApiInfoVo;
}
@Override
public List<MagicApiInfoVo> list(String groupId) {
String groupPath = magicResourceService.getGroupPath(groupId);
List<MagicEntity> magicEntities = magicResourceService.listFiles(groupId);
List<MagicApiInfoVo> magicApiInfoVos = BeanUtil.copyToList(magicEntities, MagicApiInfoVo.class);
for (MagicApiInfoVo magicApiInfoVo : magicApiInfoVos) {
magicApiInfoVo.setPath(groupPath + magicApiInfoVo.getPath());
}
return magicApiInfoVos;
}
public <T> T executeApi(String id) {
MagicApiInfoVo info = info(id);
return magicAPIService.execute(info.getMethod(), info.getPath(), new HashMap<>());
}
public Object executeWorkflowApi(ApiConfig apiConfig, Map<String, Object> processParam, Map<String, Object> varMap,String processInstId,String executionId){
MagicApiInfoVo info = info(apiConfig.getId());
Map<String, Object> params = new HashMap<>();
for(List<ApiRequestParamsConfig>requestParamsConfigs:new List[]{
apiConfig.getRequestParamsConfigs(),
apiConfig.getRequestHeaderConfigs(),
apiConfig.getRequestBodyConfigs()
}){
for (ApiRequestParamsConfig requestParamsConfig : requestParamsConfigs) {
MagicApiUtil.initApiParams(processParam,varMap,params,requestParamsConfig);
}
}
//补充流程参数
params.put("processInstId",processInstId);
params.put("executionId",executionId);
Object result = magicAPIService.execute(info.getMethod(), info.getPath(), params);
return result;
}
/**
* 查询分组以及api 树结构
*
* @param treeNodes
* @return
*/
private List<MagicApiTreeVo> buildTreeData(List<TreeNode<Group>> treeNodes, String keyword) {
List<MagicApiTreeVo> treeVoList = new ArrayList<>();
for (TreeNode<Group> treeNode : treeNodes) {
Group node = treeNode.getNode();
List<MagicEntity> nodeEntity = magicResourceService.listFiles(node.getId());
if(StringUtils.isNotBlank(keyword) && !node.getName().contains(keyword) && nodeEntity.stream().noneMatch(x -> x.getName().contains(keyword) || ((ApiInfo)x).getPath().contains(keyword))){
continue;
}
MagicApiTreeVo groupVo = new MagicApiTreeVo();
groupVo.setId(node.getId());
groupVo.setParentId(node.getParentId());
groupVo.setType("group");
groupVo.setName(node.getName());
treeVoList.add(groupVo);
for (MagicEntity magicEntity : nodeEntity) {
MagicApiTreeVo vo = new MagicApiTreeVo();
ApiInfo apiInfo = (ApiInfo) magicEntity;
if(StringUtils.isNotBlank(keyword) && !magicEntity.getName().contains(keyword) && !apiInfo.getPath().contains(keyword)){
continue;
}
vo.setId(magicEntity.getId());
vo.setType("api");
vo.setParentId(magicEntity.getGroupId());
vo.setName(magicEntity.getName());
String groupPath = StringUtils.isEmpty(node.getPath()) ? StringPool.EMPTY : node.getPath();
vo.setPath(groupPath + apiInfo.getPath());
vo.setMethod(apiInfo.getMethod());
treeVoList.add(vo);
}
if (treeNode.getChildren().size() > 0) {
treeVoList.addAll(buildTreeData(treeNode.getChildren(), keyword));
}
}
return treeVoList;
}
/**
* 构建 分组树结构
*
* @param treeNodes
* @return
*/
private void buildGroupTreeData(List<MagicApiGroupTreeVo> treeVoList, List<TreeNode<Group>> treeNodes) {
for (TreeNode<Group> treeNode : treeNodes) {
Group node = treeNode.getNode();
MagicApiGroupTreeVo groupVo = new MagicApiGroupTreeVo();
groupVo.setId(node.getId());
groupVo.setParentId(node.getParentId());
groupVo.setName(node.getName());
treeVoList.add(groupVo);
List<TreeNode<Group>> children = treeNode.getChildren();
if (CollectionUtils.isNotEmpty(children)) {
buildGroupTreeData(treeVoList, children);
}
}
}
}

View File

@ -0,0 +1,77 @@
package com.xjrsoft.module.magicapi.utils;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.map.MapUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.utils.RedisUtil;
import com.xjrsoft.module.organization.dto.DepartmentDto;
import com.xjrsoft.module.organization.dto.UserDeptRelationDto;
import com.xjrsoft.module.organization.dto.UserDto;
import com.xjrsoft.module.workflow.constant.WorkflowConstant;
import com.xjrsoft.module.workflow.model.ApiRequestParamsConfig;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author: yjw
* @since: 2025/3/17
*/
public class MagicApiUtil {
public static void initApiParams(Map<String, Object> processParam, Map<String, Object> varMap, Map<String, Object> params, ApiRequestParamsConfig requestParamsConfig) {
if (Objects.equals(requestParamsConfig.getAssignmentType(), "value")) { //值
params.put(requestParamsConfig.getName(), requestParamsConfig.getValue());
} else if (Objects.equals(requestParamsConfig.getAssignmentType(), "processParameter")) { //流程参数
params.put(requestParamsConfig.getName(), processParam.get(requestParamsConfig.getConfig()));
} else if (Objects.equals(requestParamsConfig.getAssignmentType(), "originator")) {//发起人信息
dealApiParam(requestParamsConfig,params,varMap);
} else {//表单数据
//使用3下划线切割
String[] split = requestParamsConfig.getConfig().split(StringPool.UNDERSCORE + StringPool.UNDERSCORE + StringPool.UNDERSCORE);
String formKey = split[1];
Map<String, Object> formData = MapUtil.get(varMap, formKey, new TypeReference<Map<String, Object>>() {
});
Object fieldValue = MapUtil.get(formData, split[2], Object.class);
params.put(requestParamsConfig.getName(), fieldValue);
}
}
private static void dealApiParam(ApiRequestParamsConfig requestParamsConfig, Map<String, Object> params, Map<String, Object> varMap){
Long startUserId;
if (CollectionUtils.isEmpty(varMap)) {//为空就是发起时的数据
//如果是拿发起人的数据,作为流程参数,发起和重新发起赋值,使用当前登录人的信息,如果是其它节点,使用流程的发起人数据信息
SaSession tokenSession = StpUtil.getTokenSession();
UserDto user = tokenSession.get(GlobalConstant.LOGIN_USER_INFO_KEY, new UserDto());
startUserId = user.getId();
}else {
startUserId = MapUtil.get(varMap, WorkflowConstant.PROCESS_START_USER_ID_KEY, Long.class);
}
//如果是设置的发起人
if (requestParamsConfig.getConfig().contains("initiator_id")) {
params.put(requestParamsConfig.getName(), startUserId);
}
//组织架构名称
if (requestParamsConfig.getConfig().contains("initiator_dept_name")) {
RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);
List<UserDeptRelationDto> userDeptRelations = redisUtil.get(GlobalConstant.USER_DEPT_RELATION_CACHE_KEY, new TypeReference<List<UserDeptRelationDto>>() {
});
List<DepartmentDto> departmentList = redisUtil.get(GlobalConstant.DEP_CACHE_KEY, new TypeReference<List<DepartmentDto>>() {
});
List<UserDeptRelationDto> startUserDeptRelation = userDeptRelations.stream().filter(x -> x.getUserId().equals(startUserId)).collect(Collectors.toList());
List<Long> allDeptIds = startUserDeptRelation.stream().map(UserDeptRelationDto::getDeptId).collect(Collectors.toList());
List<DepartmentDto> allDept = departmentList.stream().filter(x -> allDeptIds.contains(x.getId())).collect(Collectors.toList());
params.put(requestParamsConfig.getName(), allDept.stream().map(DepartmentDto::getName).collect(Collectors.joining(",")));
}
}
}

View File

@ -0,0 +1,87 @@
package com.xjrsoft.module.workflow.client;
import cn.hutool.extra.spring.SpringUtil;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.module.workflow.dto.WorkflowBusinessInvokeDto;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
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;
import javax.validation.Valid;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author: tzx
* @Date: 2023/10/10 17:43
*/
@Api(hidden = true)
@RestController
@RequestMapping(GlobalConstant.CLIENT_API_PRE + GlobalConstant.MAGICAPI_MODULE_PREFIX + "/invoke")
@AllArgsConstructor
public class WorkflowBusinessClientImpl implements IWorkflowBusinessClient {
/**
* 统一调用方法
*
*/
@Transactional(rollbackFor = Exception.class)
@PostMapping("/invoke")
@Override
public Boolean invoke(@RequestBody @Valid WorkflowBusinessInvokeDto dto) {
String classNameAndMethodName = dto.getClassNameAndMethodName();
try {
// 分割类名和方法名
String[] parts = classNameAndMethodName.split("\\.");
if (parts.length < 2) {
throw new IllegalArgumentException("Invalid format: className.methodName");
}
String className = String.join(".", java.util.Arrays.copyOf(parts, parts.length - 1));
String methodName = parts[parts.length - 1];
// 动态加载类
Class<?> clazz = Class.forName(className);
// 获取方法的参数类型
List<Object> args = dto.getArgs();
Class<?>[] parameterTypes = new Class[args.size()];
for (int i = 0; i < dto.getArgs().size(); i++) {
if (dto.getArgs().get(i) instanceof HashMap) {
parameterTypes[i] = Map.class;
} else {
parameterTypes[i] = args.get(i).getClass();
}
}
// 获取方法对象
Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
method.setAccessible(true); // 确保可以访问私有方法
// 判断是否为静态方法
boolean isStatic = java.lang.reflect.Modifier.isStatic(method.getModifiers());
// 调用方法
if (isStatic) {
return (Boolean) method.invoke(null, args.toArray()); // 静态方法,传入 null
} else {
Object bean = SpringUtil.getBean(className);
if (bean != null) {
Method methodBean = bean.getClass().getMethod(methodName, parameterTypes);
return (Boolean) methodBean.invoke(bean, args.toArray());
} else {
Object instance = clazz.getDeclaredConstructor().newInstance(); // 创建实例
return (Boolean) method.invoke(instance, args.toArray()); // 实例方法,传入实例
}
}
} catch (Exception e) {
throw new RuntimeException("Failed to invoke method: " + classNameAndMethodName, e);
}
}
}

View File

@ -0,0 +1,3 @@
spring:
profiles:
active: dev

View File

@ -0,0 +1,6 @@
██╗ ██╗ ██╗██████╗ ███████╗ ██████╗ ███████╗████████╗
╚██╗██╔╝ ██║██╔══██╗██╔════╝██╔═══██╗██╔════╝╚══██╔══╝
╚███╔╝ ██║██████╔╝███████╗██║ ██║█████╗ ██║
██╔██╗ ██ ██║██╔══██╗╚════██║██║ ██║██╔══╝ ██║
██╔╝ ██╗╚█████╔╝██║ ██║███████║╚██████╔╝██║ ██║
╚═╝ ╚═╝ ╚════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝

View File

@ -0,0 +1,70 @@
server:
port: 8094
spring:
application:
name: facade-service
main:
allow-bean-definition-overriding: true
# autoconfigure:
# #自动化配置 例外处理
# exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
cloud:
nacos: #nacos监控
discovery:
server-addr: 10.0.252.1:8848
namespace: ITC-MS
group: DNE
username: nacos
password: ABcd1234@
config:
server-addr: 10.0.252.1:8848 # nacos 配置中心地址
namespace: ITC-MS
group: DNE
username: nacos
password: ABcd1234@
file-extension: yml # 默认配置 ${spring.application.name}-${spring.profiles.active}.${file-extension}
extension-configs:
- data-id: magicapi-config.yml
refresh: true
group: DNE
- data-id: global-config.yml
refresh: true
group: DNE
- data-id: sa-token-client-config.yml
refresh: true
group: DNE
- data-id: redis-config.yml
refresh: true
group: DNE
- data-id: datasource-config.yml
refresh: true
group: DNE
- data-id: seata-config.yml
refresh: true
group: DNE
- data-id: camunda-config.yml
refresh: true
group: DNE
- data-id: system-config.yml
refresh: true
group: DNE
sentinel:
transport:
dashboard: localhost:8080 #sentinel dashboard 地址
port: 8719 #默认端口, 如果 被占用,会一直+1 直到未被占用为止
#springdoc:
# swagger-ui:
# path: /swagger-ui.html
# tags-sorter: alpha
# operations-sorter: alpha
# show-extensions: true
# api-docs:
# path: /system/v3/api-docs
# group-configs:
# - group: 'default'
# paths-to-match: '/system/**'
# packages-to-scan: com.xjrsoft.system
# default-flat-param-object: false

Binary file not shown.

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->
<!-- 日志存放路径 -->
<property name="log.path" value="./logs" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}][fcd2-ma][%-5p][%t][%c.%M:%L] %msg%xEx%n" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 用户访问日志输出 -->
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-user.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="console" />
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
<!--系统用户操作日志-->
<logger name="sys-user" level="info">
<appender-ref ref="sys-user"/>
</logger>
<!-- 系统模块日志级别控制 -->
<!--<logger name="com.xjrsoft" level="info" />-->
<!-- Spring日志级别控制 -->
<!--<logger name="org.springframework" level="info" />
<logger name="org.springframework.web" level="INFO"/>
<logger name="org.springboot.sample" level="TRACE" />-->
<!-- 开发、测试环境 -->
<springProfile name="dev,test">
<logger name="org.springframework.web" level="INFO"/>
<logger name="org.springboot.sample" level="INFO" />
<logger name="com.xjrsoft" level="DEBUG" />
</springProfile>
<!-- 生产环境 -->
<springProfile name="prod">
<logger name="org.springframework.web" level="ERROR"/>
<logger name="org.springboot.sample" level="ERROR" />
<logger name="com.xjrsoft" level="ERROR" />
</springProfile>
</configuration>

View File

@ -0,0 +1,21 @@
var MAGIC_EDITOR_CONFIG = {
title: 'Admin Web IDE',
header: {
skin: true, // 屏蔽皮肤按钮
document: false, // 屏蔽文档按钮
repo: false, // 屏蔽gitee和github
qqGroup: false // 屏蔽加入QQ群
},
// 其它配置参考本页中其它配置项
request: {
beforeSend: function (config) {
// console.log('请求设置', window.location.href);
config.headers.Authorization = "Bearer " + window.location.href.split('Authorization=')[1];
return config;
},
onError: function (err) {
// console.log('请求出错');
return Promise.reject(err)
}
},
}

View File

@ -0,0 +1,4 @@
# spy.properties
driverlist=com.kingbase8.Driver
appender=com.p6spy.engine.spy.appender.Slf4JLogger
logMessageFormat=com.xjrsoft.common.handler.P6spySqlLogHandler