初始代码

This commit is contained in:
wangmingwei
2026-04-21 17:41:09 +08:00
parent 186ec6683a
commit b686ecac5f
493 changed files with 52349 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
<?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">
<parent>
<artifactId>yunzhupaas-common</artifactId>
<groupId>com.yunzhupaas</groupId>
<version>5.2.0-RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yunzhupaas-boot-common</artifactId>
<packaging>pom</packaging>
<modules>
<module>yunzhupaas-common-core</module>
<module>yunzhupaas-common-database</module>
<module>yunzhupaas-common-redis</module>
<module>yunzhupaas-common-auth</module>
<module>yunzhupaas-common-security</module>
<module>yunzhupaas-common-swagger</module>
<module>yunzhupaas-common-connector</module>
<module>yunzhupaas-common-file</module>
<module>yunzhupaas-common-office</module>
<module>yunzhupaas-common-scheduletask</module>
<module>yunzhupaas-common-sms</module>
<module>yunzhupaas-common-shardingsphere</module>
<module>yunzhupaas-common-selenium</module>
<module>yunzhupaas-common-i18n</module>
<module>yunzhupaas-common-event</module>
<module>yunzhupaas-common-ai</module>
</modules>
<dependencies>
</dependencies>
<!-- 手机个推 -->
<repositories>
<repository>
<id>getui-nexus</id>
<url>http://mvn.gt.igexin.com/nexus/content/repositories/releases/</url>
</repository>
</repositories>
<profiles>
<profile>
<id>boot3</id>
<activation>
<jdk>[17,)</jdk>
</activation>
<modules>
<module>yunzhupaas-common-compatible/yunzhupaas-common-office-v3</module>
</modules>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,25 @@
<?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.yunzhupaas</groupId>
<artifactId>yunzhupaas-boot-common</artifactId>
<version>5.2.0-RELEASE</version>
</parent>
<artifactId>yunzhupaas-common-ai</artifactId>
<dependencies>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-common-core</artifactId>
</dependency>
<dependency>
<groupId>com.unfbx</groupId>
<artifactId>chatgpt-java</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,203 @@
package com.yunzhupaas.config;
import com.unfbx.chatgpt.OpenAiClient;
import com.unfbx.chatgpt.function.KeyRandomStrategy;
import com.unfbx.chatgpt.function.KeyStrategyFunction;
import com.unfbx.chatgpt.interceptor.DefaultOpenAiAuthInterceptor;
import com.unfbx.chatgpt.interceptor.OpenAiAuthInterceptor;
import com.yunzhupaas.constants.AiConstants;
import com.yunzhupaas.service.OpenAiService;
import com.yunzhupaas.service.impl.DefaultOpenAiServiceImpl;
import com.yunzhupaas.service.impl.DisabledOpenAiServiceImpl;
import com.yunzhupaas.util.StringUtil;
import okhttp3.Authenticator;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* AI客户端 自动配置
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
* @date 2024/10/9 14:03
*/
@Configuration(proxyBeanMethods = false)
public class AiAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = AiConstants.CONFIGURATION_PREFIX, name = "enabled", havingValue = "false", matchIfMissing = true)
public OpenAiService getDisabledOpenAiService() {
return new DisabledOpenAiServiceImpl();
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = AiConstants.CONFIGURATION_PREFIX, name = "enabled", havingValue = "true")
public static class AiEnabledConfiguration {
@Bean
@ConfigurationProperties(prefix = AiConstants.CONFIGURATION_PREFIX)
public AiProperties getAiProperties() {
return new AiProperties();
}
@Bean
public OpenAiService getDefaultOpenAiService(OpenAiClient openAiClient, AiProperties aiProperties) {
return new DefaultOpenAiServiceImpl(openAiClient, aiProperties);
}
@Bean
@ConditionalOnMissingBean
public OpenAiClient getOpenAiClient(
@Qualifier(AiConstants.DEFAULT_HTTP_CLIENT_BEAN_NAME) OkHttpClient okHttpClient,
KeyStrategyFunction<List<String>, String> keyStrategyFunction, OpenAiAuthInterceptor authInterceptor,
AiProperties aiProperties) {
String apiHost = aiProperties.getApiHost();
// 需要以 / 结尾
if (!apiHost.isEmpty() && !apiHost.endsWith("/")) {
apiHost += "/";
}
// 构造openAiClient
return OpenAiClient.builder()
.apiHost(apiHost)
.apiKey(aiProperties.getApiKey())
.keyStrategy(keyStrategyFunction)
.authInterceptor(authInterceptor)
.okHttpClient(okHttpClient)
.build();
}
/*
* @Bean
*
* @ConditionalOnMissingBean
* public OpenAiStreamClient
* getOpenAiStreamClient(@Qualifier(AiConstants.DEFAULT_HTTP_CLIENT_BEAN_NAME)
* OkHttpClient okHttpClient
* , KeyStrategyFunction<List<String>, String> keyStrategyFunction,
* OpenAiAuthInterceptor authInterceptor, AiProperties aiProperties) {
* String apiHost = aiProperties.getApiHost();
* // 需要以 / 结尾
* if(!apiHost.isEmpty() && !apiHost.endsWith("/")){
* apiHost +="/";
* }
* // 构造openAiClient
* return OpenAiStreamClient.builder()
* .apiHost(apiHost)
* .apiKey(aiProperties.getApiKey())
* .keyStrategy(keyStrategyFunction)
* .authInterceptor(authInterceptor)
* .okHttpClient(okHttpClient)
* .build();
* }
*/
/**
* 多 Key 选择策略
*/
@Bean
@ConditionalOnMissingBean
public KeyStrategyFunction<List<String>, String> getDefaultOpenAiKeyStrategyFunction() {
return new KeyRandomStrategy();
}
/**
* 认证拦截器
*
* @see com.unfbx.chatgpt.interceptor.DynamicKeyOpenAiAuthInterceptor 动态移除无效Key
*/
@Bean
@ConditionalOnMissingBean
public OpenAiAuthInterceptor getDefaultOpenAiAuthInterceptor() {
return new DefaultOpenAiAuthInterceptor();
}
/**
* 默认okhttpclient
*/
@Bean(name = AiConstants.DEFAULT_HTTP_CLIENT_BEAN_NAME)
@ConditionalOnMissingBean(name = AiConstants.DEFAULT_HTTP_CLIENT_BEAN_NAME)
public OkHttpClient getDefaultOpenAiOkHttpClient(AiProperties aiProperties) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (aiProperties.getProxy() != null
&& StringUtil.isNotEmpty(aiProperties.getProxy().getHost())
&& aiProperties.getProxy().getPort() != null) {
// 设置代理
builder.proxy(new Proxy(aiProperties.getProxy().getType(),
new InetSocketAddress(aiProperties.getProxy().getHost(), aiProperties.getProxy().getPort())));
// 设置代理认证
if (StringUtil.isNotEmpty(aiProperties.getProxy().getUsername())
&& StringUtil.isNotEmpty(aiProperties.getProxy().getPassword())) {
builder.proxyAuthenticator(Authenticator.JAVA_NET_AUTHENTICATOR);
java.net.Authenticator.setDefault(new java.net.Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 返回代理的用户名和密码
return new PasswordAuthentication(aiProperties.getProxy().getUsername(),
aiProperties.getProxy().getPassword().toCharArray());
}
});
}
}
/*
* try {
* // 创建一个信任所有证书的 TrustManager
* final TrustManager[] trustAllCerts = new TrustManager[]{
* new X509TrustManager() {
*
* @Override
* public void checkClientTrusted(X509Certificate[] chain, String authType)
* throws CertificateException {
* }
*
* @Override
* public void checkServerTrusted(X509Certificate[] chain, String authType)
* throws CertificateException {
* }
*
* @Override
* public X509Certificate[] getAcceptedIssuers() {
* return new X509Certificate[]{};
* }
* }
* };
*
* // 安装所有信任管理器
* final SSLContext sslContext = SSLContext.getInstance("SSL");
* sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
*
* // 创建 OkHttpClient 并配置 SSL socket factory 和 hostname verifier
* final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
*
* // 信任所有证书
* builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)
* trustAllCerts[0]);
* builder.hostnameVerifier((hostname, session) -> true);
* } catch (Exception e) {
* throw new RuntimeException(e);
* }
*/
return builder
.callTimeout(aiProperties.getTimeout(), TimeUnit.SECONDS)
.connectTimeout(aiProperties.getTimeout(), TimeUnit.SECONDS)
.writeTimeout(aiProperties.getTimeout(), TimeUnit.SECONDS)
.readTimeout(aiProperties.getTimeout(), TimeUnit.SECONDS)
.build();
}
}
}

View File

@@ -0,0 +1,134 @@
package com.yunzhupaas.config;
import com.yunzhupaas.constants.AiConstants;
import lombok.Data;
import java.time.Duration;
import java.util.List;
/**
* AI 配置
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
* @date 2024/10/9 14:03
*/
@Data
public class AiProperties {
/**
* 是否启用
*/
private boolean enabled;
/**
* openai服务器
*/
private String apiHost = AiConstants.OPENAI_HOST;
/**
* openai key
*/
private List<String> apiKey;
/**
* 超时时间
*/
private Long timeout = 30L;
/**
* 每个用户限制时间内的请求次数
*/
private Integer userLimitCount = 1;
/**
* 每个用户限制时间频率
*/
private Duration userLimitTime = Duration.ofSeconds(3);
/**
* 全部请求限制时间内的请求次数
*/
private Integer totalLimitCount = 500;
/**
* 全部请求限制时间频率
*/
private Duration totalLimitTime = Duration.ofMinutes(1L);
/**
* 代理配置
*/
private Proxy proxy = new Proxy();
/**
* 对话配置
*/
private ChatOption chat = new ChatOption();
@Data
public class ChatOption{
/**
* @see AiConstants.Model
*/
private String mode = AiConstants.Model.QWEN_25_3;
/**
* 设置seed参数会使文本生成过程更具有确定性通常用于使模型每次运行的结果一致。
* 在每次模型调用时传入相同的seed值由您指定并保持其他参数不变模型将很可能返回相同的结果。
*/
private Integer seed = 1234;
/**
* 允许模型生成的最大Token数。
*/
private Integer maxTokens = 1500;
/**
* 核采样的概率阈值,用于控制模型生成文本的多样性。
* top_p越高生成的文本更多样。反之生成的文本更确定。
* 由于temperature与top_p均可以控制生成文本的多样性因此建议您只设置其中一个值。
*/
private Double topP = 0.8;
/**
* 采样温度,用于控制模型生成文本的多样性。
* temperature越高生成的文本更多样反之生成的文本更确定。
* 由于temperature与top_p均可以控制生成文本的多样性因此建议您只设置其中一个值。
*/
private Double temperature = 0.85;
private boolean enableSearch = true;
}
@Data
public class Proxy{
/**
* HTTP, SOCKS
*/
private java.net.Proxy.Type type = java.net.Proxy.Type.HTTP;
/**
* 代理域名
*/
private String host;
/**
* 代理端口
*/
private Integer port;
/**
* 代理用户名
*/
private String username;
/**
* 代理密码
*/
private String password;
}
}

View File

@@ -0,0 +1,58 @@
package com.yunzhupaas.constants;
/**
* AI 常量
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
* @date 2024/10/9 14:05
*/
public class AiConstants {
public static final String OPENAI_HOST = "https://dashscope.aliyuncs.com/compatible-mode/";
public static final String CONFIGURATION_PREFIX = "spring.cloud.ai.openai";
public static final String DEFAULT_HTTP_CLIENT_BEAN_NAME = "defaultOpenAiHttpClient";
public static final String GEN_MODEL_COMPNENT = "- input - textarea - inputNumber - switch - radio - checkbox - select - datePicker - timePicker - uploadFile - uploadImg - colorPicker - rate - slider - editor - depSelect - posSelect - userSelect - roleSelect - areaSelect - signature - sign - location";
public static final String GEN_MODEL_QUETION = "根据当前业务需求设计相应的表单结构。请仅返回JSON数据不包含其他任何形式的内容。预期结果是一个JSON数组因涉及不同表单需求故可能包含多个表单对象。请确保命名规避数据库与编程保留字。\n"
+
"所需表单应充分利用以下组件列表进行设计: " + GEN_MODEL_COMPNENT + "\n" +
"参考给定的JSON格式属性包含中文名tableTitle)、英文名(tableName)、字段列表(fields)字段列表是一个json数组包含字段英文名(fieldName)、字段中文名(fieldTitle)等;"
+
"创建表单结构,示例如下: [ { \"tableTitle\": \"商城订单\", \"tableName\": \"online_order_form\", \"fields\": [ {\"fieldTitle\": \"订单编号\", \"fieldName\": \"order_id\", \"fieldDbType\": \"varchar\", \"fieldComponent\": \"input\"}, {\"fieldTitle\": \"订单状态\", \"fieldName\": \"order_status\", \"fieldDbType\": \"int\", \"fieldComponent\": \"radio\", \"fieldOptions\":[{\"id\":\"1\", \"fullName\":\"未付款\"},{\"id\":\"2\", \"fullName\":\"已付款\"}]}] }, { \"tableTitle\": \"订单商品明细\", \"tableName\": \"order_item_details\", \"fields\": [ {\"fieldTitle\": \"订单ID外键\", \"fieldName\": \"order_id_fk\", \"fieldDbType\": \"varchar\", \"fieldComponent\": \"input\"}, {\"fieldTitle\": \"商品名称\", \"fieldName\": \"product_name\", \"fieldDbType\": \"varchar\", \"fieldComponent\": \"input\"}, {\"fieldTitle\": \"商品数量\", \"fieldName\": \"quantity\", \"fieldDbType\": \"int\", \"fieldComponent\": \"inputNumber\"}] } ]\n"
+
"请依据实际业务逻辑,合理选择组件与字段类型,确保设计的表单既能满足数据收集需求,又便于用户操作。";
public static final String CHAT_PRE_QUETION = "深圳市乐程软件有限公司下的低代码产品YUNZHUPAAS介绍";
/**
* 模型名称
*
* @see com.unfbx.chatgpt.entity.chat.ChatCompletion.Model
* <a href=
* "https://help.aliyun.com/zh/model-studio/getting-started/models">阿里官方稳定模型列表</a>
*/
public static class Model {
/**
* 通义千问系列效果最好的模型,适合复杂、多步骤的任务。
*/
public static final String QWEN_MAX = "qwen-max";
/**
* 通义千问系列速度最快、成本很低的模型,适合简单任务。
*/
public static final String QWEN_TURBO = "qwen-turbo";
/**
* 通义千问开源版, 可部署参数最高的版本, 云版本收费
*/
public static final String QWEN_25_72 = "qwen2.5-72b-instruct";
/**
* 通义千问开源版, 官方提供接口免费版本, 云版本限时免费
*/
public static final String QWEN_25_3 = "qwen2.5-3b-instruct";
}
}

View File

@@ -0,0 +1,42 @@
package com.yunzhupaas.service;
import com.unfbx.chatgpt.entity.chat.Message;
import com.yunzhupaas.model.ai.AiFormModel;
import java.util.List;
/**
* AI服务工具
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
* @date 2024/10/9 14:38
*/
public interface OpenAiService {
/**
* 简单对话
* @param prompt
*/
String completion(String prompt);
/**
* 连续对话
* @param messages 历史对话内容
*/
String completion(Message... messages);
/**
* 生成表单
* @param businessName 业务名称
* @return
*/
String generatorModelStr(String businessName);
/**
* 生成表单
* @param prompt
* @return
*/
List<AiFormModel> generatorModelVO(String prompt);
}

View File

@@ -0,0 +1,101 @@
package com.yunzhupaas.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.unfbx.chatgpt.OpenAiClient;
import com.unfbx.chatgpt.entity.chat.ChatCompletion;
import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse;
import com.unfbx.chatgpt.entity.chat.Message;
import com.yunzhupaas.config.AiProperties;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.constants.AiConstants;
import com.yunzhupaas.exception.DataException;
import com.yunzhupaas.model.ai.AiFormModel;
import com.yunzhupaas.service.OpenAiService;
import com.yunzhupaas.util.StringUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* OpenAi 实现类
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
* @date 2024/10/9 14:39
*/
@Slf4j
@AllArgsConstructor
public class DefaultOpenAiServiceImpl implements OpenAiService {
private OpenAiClient openAiClient;
private AiProperties aiProperties;
@Override
public String completion(String prompt) {
Message sendMessage = Message.builder().role(Message.Role.USER).content(prompt).build();
ChatCompletion chatCompletion;
if (StringUtil.isNotEmpty(prompt) && prompt.toLowerCase().contains("com.yunzhupaas")) {
Message sysMessage = Message.builder().role(Message.Role.SYSTEM).content(AiConstants.CHAT_PRE_QUETION).build();
chatCompletion = getDefaultChatComletion(sysMessage, sendMessage);
} else {
chatCompletion = getDefaultChatComletion(sendMessage);
}
ChatCompletionResponse chatCompletionResponse = openAiClient.chatCompletion(chatCompletion);
return chatCompletionResponse.getChoices().stream().map(chatChoice -> chatChoice.getMessage().getContent()).collect(Collectors.joining());
}
@Override
public String generatorModelStr(String businessName) {
Message sysMessage = Message.builder().role(Message.Role.SYSTEM).content(AiConstants.GEN_MODEL_QUETION).build();
String userTemplate = "当前业务需求是:";
Message sendMessage = Message.builder().role(Message.Role.USER).content(userTemplate + businessName).build();
ChatCompletion chatCompletion = getDefaultChatComletion(sysMessage, sendMessage);
ChatCompletionResponse chatCompletionResponse = openAiClient.chatCompletion(chatCompletion);
return chatCompletionResponse.getChoices().stream().map(chatChoice -> chatChoice.getMessage().getContent()).collect(Collectors.joining());
}
@Override
public List<AiFormModel> generatorModelVO(String prompt) {
String result = "";
List<AiFormModel> aiFormModels;
try {
result = generatorModelStr(prompt);
int startIndex = result.indexOf("[");
int endIndex = result.lastIndexOf("]");
if (startIndex != -1 && endIndex != -1 && startIndex < endIndex) {
result = result.substring(startIndex, endIndex + 1).trim();
}
aiFormModels = JSON.parseObject(result, new TypeReference<List<AiFormModel>>() {
});
} catch (Exception e) {
log.error("AI表单生成转换失败: {}, {}", result, e.getMessage());
throw new DataException(MsgCode.SYS181.get());
}
return aiFormModels;
}
@Override
public String completion(Message... messages) {
ChatCompletion chatCompletion = getDefaultChatComletion(messages);
ChatCompletionResponse chatCompletionResponse = openAiClient.chatCompletion(chatCompletion);
return chatCompletionResponse.getChoices().stream().map(chatChoice -> chatChoice.getMessage().getContent()).collect(Collectors.joining());
}
private ChatCompletion getDefaultChatComletion(Message... messages) {
AiProperties.ChatOption chatOption = aiProperties.getChat();
return ChatCompletion.builder()
.model(chatOption.getMode())
.temperature(chatOption.getTemperature())
.topP(chatOption.getTopP())
.seed(chatOption.getSeed())
.maxTokens(chatOption.getMaxTokens())
.messages(Arrays.asList(messages)).build();
}
}

View File

@@ -0,0 +1,41 @@
package com.yunzhupaas.service.impl;
import com.unfbx.chatgpt.entity.chat.Message;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.exception.DataException;
import com.yunzhupaas.model.ai.AiFormModel;
import com.yunzhupaas.service.OpenAiService;
import java.util.List;
/**
* 未启用是空实现
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
* @date 2024/10/15 17:00
*/
public class DisabledOpenAiServiceImpl implements OpenAiService {
@Override
public String completion(String prompt) {
return throwError();
}
@Override
public String completion(Message... messages) {
return throwError();
}
@Override
public String generatorModelStr(String businessName) {
return throwError();
}
@Override
public List<AiFormModel> generatorModelVO(String prompt) {
return throwError();
}
public <T> T throwError(){
throw new DataException(MsgCode.SYS180.get());
}
}

View File

@@ -0,0 +1,51 @@
package com.yunzhupaas.util;
import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import com.yunzhupaas.config.AiProperties;
import java.util.concurrent.atomic.AtomicInteger;
/**
* AI接口限流
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
* @date 2025/3/7 10:00
*/
public class AiLimitUtil {
private static AiProperties aiProperties;
private static TimedCache<String, AtomicInteger> limit = null;
private static final String TOTAL_KEY = "ai_limit_total";
public AiLimitUtil(AiProperties aiProperties) {
AiLimitUtil.aiProperties = aiProperties;
if (limit == null) {
limit = CacheUtil.newTimedCache(aiProperties.getUserLimitTime().toMillis());
// 一分钟清理一次无用数据
limit.schedulePrune(1000L * 60);
}
}
/**
* 是否可以请求
* @param userId
* @return
*/
public static boolean tryAcquire(String userId) {
if (StringUtil.isNotEmpty(userId)) {
// 按用户限制
AtomicInteger userCount = limit.get(userId, false, AtomicInteger::new);
if (userCount.incrementAndGet() > aiProperties.getUserLimitCount()) {
return false;
}
}
// 所有请求限制
AtomicInteger totalCount = limit.get(TOTAL_KEY, false, aiProperties.getTotalLimitTime().toMillis(), AtomicInteger::new);
return totalCount.incrementAndGet() <= aiProperties.getTotalLimitCount();
}
}

View File

@@ -0,0 +1,71 @@
<?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">
<parent>
<artifactId>yunzhupaas-boot-common</artifactId>
<groupId>com.yunzhupaas</groupId>
<version>5.2.0-RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yunzhupaas-common-auth</artifactId>
<dependencies>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-common-redis</artifactId>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId>
<exclusions>
<exclusion>
<groupId>cn.hutool</groupId>
<artifactId>hutool-jwt</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
<!--<exclusions>
<exclusion>
<artifactId>spring-boot-starter-data-redis</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>-->
</dependency>
</dependencies>
<profiles>
<profile>
<id>boot3</id>
<activation>
<jdk>[17,)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>boot2</id>
<activation>
<jdk>(,17)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,149 @@
package com.yunzhupaas.config;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.model.tenant.TenantVO;
import com.yunzhupaas.util.TenantHolder;
import com.yunzhupaas.util.UserProvider;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 提供一个全局的Spring线程池对象
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-12-10
*/
@Slf4j
@Configuration
@EnableAsync(proxyTargetClass = true)
@AllArgsConstructor
public class AsyncConfig implements AsyncConfigurer {
// private final Map<Object, Integer> asyncTaskCount = new HashMap<>();
@Primary
@Bean("threadPoolTaskExecutor")
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置线程池核心容量
executor.setCorePoolSize(10);
// 设置线程池最大容量
executor.setMaxPoolSize(50);
// 设置任务队列长度
executor.setQueueCapacity(2000);
// 设置线程超时时间
executor.setKeepAliveSeconds(30);
// 设置线程名称前缀
executor.setThreadNamePrefix("sysTaskExecutor");
// 设置任务丢弃后的处理策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setTaskDecorator( r ->{
//实现线程上下文穿透, 异步线程内无法获取之前的Request租户信息等 如有新的上下文对象在此处添加
//此方法在请求结束后在无法获取request, 下方完整异步Servlet请求
// RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
TenantVO tenantVO = TenantHolder.getLocalTenantCache();
UserInfo userInfo = UserProvider.getUser();
return () -> {
try {
// if(attributes!= null) {
// RequestContextHolder.setRequestAttributes(attributes);
// }
if(tenantVO != null){
TenantHolder.setLocalTenantCache(tenantVO);
}
UserProvider.setLocalLoginUser(userInfo);
r.run();
} finally {
UserProvider.clearLocalUser();
RequestContextHolder.resetRequestAttributes();
TenantHolder.clearLocalTenantCache();
}
};
});
/*
//Tomcat异步Servlet只能增加吞吐量, 不能减少响应时间
executor.setTaskDecorator( r ->{
//实现线程上下文穿透, 异步线程内无法获取之前的Request租户信息等 如有新的上下文对象在此处添加
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
String dataSourceId = DataSourceContextHolder.getDatasourceId();
String dataSourceName = DataSourceContextHolder.getDatasourceName();
final AsyncContext asyncContext = (AsyncContext) Optional.ofNullable(null).orElseGet(()->{
if(attributes!= null) {
HttpServletRequest request = ((ServletRequestAttributes) attributes).getRequest();
HttpServletResponse response = ((ServletRequestAttributes) attributes).getResponse();
synchronized (AsyncConfig.class) {
//开启多个异步
AsyncContext tmpAsyncContext = request.isAsyncStarted() ? request.getAsyncContext() : request.startAsync(request, response);
asyncTaskCount.put(tmpAsyncContext, asyncTaskCount.getOrDefault(tmpAsyncContext, 0) +1);
return tmpAsyncContext;
}
}
return null;
});
return () -> {
if (asyncContext != null) {
asyncContext.start(() -> {
if (dataSourceId != null || dataSourceName != null) {
DataSourceContextHolder.setDatasource(dataSourceId, dataSourceName);
}
RequestContextHolder.setRequestAttributes(attributes);
try {
r.run();
}finally{
synchronized (AsyncConfig.class){
//多个异步 最后一个执行关闭
int count = asyncTaskCount.get(asyncContext)-1;
if(count > 0){
asyncTaskCount.put(asyncContext, count);
}else{
asyncTaskCount.remove(asyncContext);
asyncContext.complete();
}
}
RequestContextHolder.resetRequestAttributes();
DataSourceContextHolder.clearDatasourceType();
}
});
} else {
if (dataSourceId != null || dataSourceName != null) {
DataSourceContextHolder.setDatasource(dataSourceId, dataSourceName);
}
try {
r.run();
}finally{
DataSourceContextHolder.clearDatasourceType();
}
}
};
});
*/
return executor;
}
@Bean("defaultExecutor")
public ThreadPoolTaskExecutor getAsyncExecutorDef(@Qualifier("threadPoolTaskExecutor") Executor executor) {
return (ThreadPoolTaskExecutor) executor;
}
}

View File

@@ -0,0 +1,45 @@
package com.yunzhupaas.config;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
import cn.dev33.satoken.stp.StpLogic;
import com.yunzhupaas.consts.AuthConsts;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
*/
@Configuration
public class AuthAutoConfigration {
@Primary
@Bean
@ConfigurationProperties(prefix = "oauth.login")
public SaTokenConfig getYunzhupaasTokenConfig() {
return new YunzhupaasTokenConfig();
}
@Bean
@ConditionalOnMissingBean
@ConfigurationProperties(prefix = YunzhupaasOauthConfig.PREFIX)
public YunzhupaasOauthConfig getYunzhupaasOauthConfig() {
return new YunzhupaasOauthConfig();
}
@Primary
@Bean(AuthConsts.ACCOUNT_LOGIC_BEAN_DEFAULT)
public StpLogic getYunzhupaasTokenJwtLogic() {
return new StpLogicJwtForSimple(AuthConsts.ACCOUNT_TYPE_DEFAULT);
}
@Bean(AuthConsts.ACCOUNT_LOGIC_BEAN_TENANT)
public StpLogic getYunzhupaasTenantTokenJwtLogic() {
return new StpLogicJwtForSimple(AuthConsts.ACCOUNT_TYPE_TENANT);
}
}

View File

@@ -0,0 +1,63 @@
package com.yunzhupaas.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
/**
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
*/
@Data
public class YunzhupaasOauthConfig {
public static final String PREFIX = "oauth";
/**
* 服务器域名
*
* @see ConfigValueUtil#getApiDomain()
*/
@Deprecated
@Value("${config.ApiDomain:}")
private String yunzhupaasDomain;
/**
* 开启单点登录, 需额外代码支持
*/
private Boolean ssoEnabled = false;
/**
* 后端登录完整路径路径
*/
private String loginPath;
/**
* 默认发起的登录协议
*/
private String defaultSSO = "cas";
/**
* 轮询Ticket有效期, 秒
*/
private long ticketTimeout = 60;
/**
* pc端服务器域名
*
* @see ConfigValueUtil#getFrontDomain()
*/
@Deprecated
@Value("${config.FrontDomain:}")
private String yunzhupaasFrontDomain;
/**
* app端服务器域名
*
* @see ConfigValueUtil#getAppDomain()
*/
@Deprecated
@Value("${config.AppDomain:}")
private String yunzhupaasAppDomain;
}

View File

@@ -0,0 +1,101 @@
package com.yunzhupaas.config;
import cn.dev33.satoken.config.SaTokenConfig;
import com.yunzhupaas.consts.AuthConsts;
import com.yunzhupaas.model.BaseSystemInfo;
import com.yunzhupaas.util.Constants;
import com.yunzhupaas.util.TenantProvider;
import java.util.Optional;
/**
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
*/
public class YunzhupaasTokenConfig extends SaTokenConfig {
@Override
public long getTimeout() {
BaseSystemInfo baseSystemInfo = getSycConfig();
if (baseSystemInfo == null) {
return super.getTimeout();
} else {
return Long.parseLong(getSycConfig().getTokenTimeout()) * 60L;
}
}
@Override
public Boolean getIsConcurrent() {
BaseSystemInfo baseSystemInfo = getSycConfig();
if (baseSystemInfo == null) {
return super.getIsConcurrent();
} else {
return Optional.ofNullable(getSycConfig().getSingleLogin()).orElse(1) == 2;
}
}
@Override
public String getJwtSecretKey() {
String secrekey = super.getJwtSecretKey();
if (secrekey == null) {
return AuthConsts.JWT_SECRET;
}
return secrekey;
}
@Override
public String getCurrDomain() {
return super.getCurrDomain();
}
@Override
public String getTokenPrefix() {
return AuthConsts.TOKEN_PREFIX;
}
@Override
public Boolean getTokenSessionCheckLogin() {
return false;
}
@Override
public Boolean getIsPrint() {
return false;
}
@Override
public Boolean getIsShare() {
return false;
}
@Override
public String getTokenName() {
return Constants.AUTHORIZATION;
}
@Override
public Boolean getIsReadCookie() {
return false;
}
@Override
public Boolean getIsReadBody() {
return false;
}
@Override
public Boolean getIsReadHeader() {
return true;
}
@Override
public int getMaxLoginCount() {
return -1;
}
private BaseSystemInfo getSycConfig() {
return TenantProvider.getBaseSystemInfo();
}
}

View File

@@ -0,0 +1,81 @@
package com.yunzhupaas.consts;
import cn.dev33.satoken.same.SaSameUtil;
import com.yunzhupaas.service.UserDetailService;
/**
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
*/
public class AuthConsts {
public static final String DEF_TENANT_ID = "";
public static final String DEF_TENANT_DB = "";
public static final String ACCOUNT_TYPE_DEFAULT = "login";
public static final String ACCOUNT_TYPE_TENANT = "tenant";
public static final String ACCOUNT_LOGIC_BEAN_DEFAULT = "defaultStpLogic";
public static final String ACCOUNT_LOGIC_BEAN_TENANT = "tenantStpLogic";
public static final String PAR_GRANT_TYPE = "grant_type";
public static final String SYSTEM_INFO = "system_info";
/**
* 跨服务调用验证KEY
*/
public static final String INNER_TOKEN_KEY = SaSameUtil.SAME_TOKEN;
/**
* 网关调用验证KEY
*/
public static final String INNER_GATEWAY_TOKEN_KEY = INNER_TOKEN_KEY + "_GATEWAY";
public static final String TENANT_SESSION = "tenant:";
public static final String TOKEN_PREFIX = "bearer";
public static final String TOKEN_PREFIX_SP = TOKEN_PREFIX + " ";
public static final String PARAMS_YUNZHUPAAS_TICKET = "yunzhupaas_ticket";
public static final String PARAMS_SSO_LOGOUT_TICKET = "ticket";
public static final Integer REDIRECT_PAGETYPE_LOGIN = 1;
public static final Integer REDIRECT_PAGETYPE_LOGOUT = 2;
public static final Integer TMP_TOKEN_UNLOGIN = -1;
public static final Integer TMP_TOKEN_ERRLOGIN = -2;
public static final String ONLINE_TICKET_KEY = "online_ticket:";
public static final String ONLINE_TICKET_TOKEN = "online_token";
public static final String JWT_SECRET = "WviMjFNC72VKwGqm5LPoheQo5XN9iN4d";
/**
* clientId
*/
public static final String Client_Id = "Client_Id";
/**
* 用户信息获取方式 account
*/
public static final String USERDETAIL_ACCOUNT = UserDetailService.USER_DETAIL_PREFIX + "UserAccount";
/**
* 用户信息获取方式 user_id
*/
public static final String USERDETAIL_USER_ID = UserDetailService.USER_DETAIL_PREFIX + "UserId";
/**
* 认证方式 常规账号密码
*/
public static final String GRANT_TYPE_PASSWORD = "password";
/**
* 认证方式 单点 CAS
*/
public static final String GRANT_TYPE_CAS = "cas";
/**
* 认证方式 单点 OAUTH
*/
public static final String GRANT_TYPE_OAUTH = "auth2";
}

View File

@@ -0,0 +1,41 @@
package com.yunzhupaas.consts;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
*/
@Getter
@AllArgsConstructor
public enum DeviceType {
/**
* pc端
*/
PC("PC"),
/**
* app端 手机都归为移动 自行扩展
*/
APP("APP"),
/**
* 程序运行中使用的无限制临时用户
*/
TEMPUSER("TEMPUSER"),
/**
* 程序运行中使用的限制临时用户, 不可访问主系统, CurrentUser接口报错
*/
TEMPUSERLIMITED("TEMPUSERLIMITED");
private final String device;
}

View File

@@ -0,0 +1,47 @@
package com.yunzhupaas.consts;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
*/
@Getter
@AllArgsConstructor
public enum LoginTicketStatus {
/**
* 登录成功
*/
Success(1),
/**
* 未登录
*/
UnLogin(2),
/**
* 登录失败
*/
ErrLogin(3),
/**
* 未绑定
*/
UnBind(4),
/**
* 失效
*/
Invalid(5),
/**
* 多租户
*/
Multitenancy(6),
/**
* 第三方账号未绑定账号,请绑定后重试
*/
UnBindMes(7),;
private int status;
}

View File

@@ -0,0 +1,30 @@
package com.yunzhupaas.consts;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ScanCodeTicketStatus {
/**
* 已失效
*/
Invalid(-1),
/**
* 未扫码
*/
UnScanCode(0),
/**
* 已扫码
*/
ScanCode(1),
/**
* 登录成功
*/
Success(2);
private int status;
}

View File

@@ -0,0 +1,292 @@
package com.yunzhupaas.granter;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.config.ConfigValueUtil;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.consts.AuthConsts;
import com.yunzhupaas.consts.DeviceType;
import com.yunzhupaas.consts.LoginTicketStatus;
import com.yunzhupaas.exception.LoginException;
import com.yunzhupaas.exception.TenantDatabaseException;
import com.yunzhupaas.model.BaseSystemInfo;
import com.yunzhupaas.model.LoginTicketModel;
import com.yunzhupaas.model.logout.LogoutResultModel;
import com.yunzhupaas.model.tenant.TenantVO;
import com.yunzhupaas.service.LoginService;
import com.yunzhupaas.util.RedisUtil;
import com.yunzhupaas.util.TenantProvider;
import com.yunzhupaas.util.TicketUtil;
import com.yunzhupaas.util.UserProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import java.util.HashMap;
import java.util.Map;
import static com.yunzhupaas.consts.AuthConsts.DEF_TENANT_DB;
import static com.yunzhupaas.consts.AuthConsts.DEF_TENANT_ID;
/**
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
*/
public abstract class AbstractTokenGranter implements TokenGranter, Ordered {
@Autowired(required = false)
protected LoginService loginService;
@Autowired
protected UserProvider userProvider;
@Autowired
protected ConfigValueUtil configValueUtil;
@Autowired
protected RedisUtil redisUtil;
protected static PathMatcher pathMatcher = new AntPathMatcher();
private String authenticationUrl;
public AbstractTokenGranter(String authenticationUrl) {
this.authenticationUrl = authenticationUrl;
}
/**
* 最终登录用户
*
* @param userInfo 包含账户名, 登录方式
* @return
*/
protected String loginAccount(UserInfo userInfo, BaseSystemInfo baseSystemInfo) throws LoginException {
try {
// 获取用户实现类接口名称
userInfo.setUserDetailKey(getUserDetailKey());
// 获取登录信息
userInfo = getUserInfo(userInfo, baseSystemInfo);
// 预登陆
preLogin(userInfo, baseSystemInfo);
// 登录
login(userInfo, baseSystemInfo);
} catch (Exception e) {
try {
loginFailure(userInfo, baseSystemInfo, e);
} catch (Exception e1) {
throw e1;
}
throw e;
}
loginSuccess(userInfo, baseSystemInfo);
// 返回token信息
return userInfo.getToken();
}
/**
* 切换多租户
*
* @param userInfo
* @return userAccount, tenantId, tenandDb
* @throws LoginException
*/
protected UserInfo switchTenant(UserInfo userInfo) throws LoginException {
if (configValueUtil.isMultiTenancy()) {
userInfo = loginService.getTenantAccount(userInfo);
return userInfo;
}
userInfo.setTenantId(DEF_TENANT_ID);
userInfo.setTenantDbConnectionString(DEF_TENANT_DB);
userInfo.setTenantDbType(TenantVO.NONE);
return userInfo;
}
/**
* 获取系统配置
*
* @param userInfo
* @return
*/
protected BaseSystemInfo getSysconfig(UserInfo userInfo) throws LoginException {
BaseSystemInfo baseSystemInfo = loginService.getBaseSystemConfig(userInfo.getTenantId());
if (baseSystemInfo != null && baseSystemInfo.getSingleLogin() != null) {
TenantProvider.setBaseSystemInfo(baseSystemInfo);
} else {
throw new TenantDatabaseException().setLogMsg(MsgCode.LOG110.get());
}
return baseSystemInfo;
}
/**
* 获取登录设备
*
* @return
*/
protected DeviceType getDeviceType() {
return UserProvider.getDeviceForAgent();
}
/**
* 生成登录用户信息
*
* @param userInfo
* @return
*/
protected UserInfo getUserInfo(UserInfo userInfo, BaseSystemInfo sysConfigInfo) throws LoginException {
userInfo.setGrantType(getGrantType());
userInfo = loginService.userInfo(userInfo, sysConfigInfo);
return userInfo;
}
/**
* 登录前执行
*
* @param userInfo
* @param baseSystemInfo
*/
protected void preLogin(UserInfo userInfo, BaseSystemInfo baseSystemInfo) throws LoginException {
}
/**
* 登录操作
*
* @param userInfo
* @param baseSystemInfo
*/
protected void login(UserInfo userInfo, BaseSystemInfo baseSystemInfo) throws LoginException {
UserProvider.login(userInfo, getLoginModel(userInfo, baseSystemInfo));
}
/**
* 登录成功触发
*
* @param userInfo
* @param baseSystemInfo
*/
protected void loginSuccess(UserInfo userInfo, BaseSystemInfo baseSystemInfo) {
}
/**
* 登录失败触发
*
* @param baseSystemInfo
*/
protected void loginFailure(UserInfo userInfo, BaseSystemInfo baseSystemInfo, Exception e) {
}
protected abstract String getUserDetailKey();
protected String createToken(UserInfo userInfo, BaseSystemInfo baseSystemInfo) {
// 登录
UserProvider.login(userInfo, getLoginModel(userInfo, baseSystemInfo));
return StpUtil.getTokenValueNotCut();
}
/**
* 更新轮询结果为成功
*/
protected void updateTicketSuccess(UserInfo userInfo) {
String ticket = getYunzhupaasTicket();
if (!ticket.isEmpty()) {
LoginTicketModel loginTicketModel = new LoginTicketModel()
.setStatus(LoginTicketStatus.Success.getStatus())
.setValue(StpUtil.getTokenValueNotCut())
.setTheme(userInfo.getTheme());
TicketUtil.updateTicket(ticket, loginTicketModel, null);
}
}
/**
* 更新轮询结果为失败
*/
protected void updateTicketError(String msg) {
String ticket = getYunzhupaasTicket();
if (!ticket.isEmpty()) {
LoginTicketModel loginTicketModel = new LoginTicketModel()
.setStatus(LoginTicketStatus.ErrLogin.getStatus())
.setValue(msg);
TicketUtil.updateTicket(ticket, loginTicketModel, null);
}
}
/**
* 获取轮询ticket
*
* @return
*/
protected String getYunzhupaasTicket() {
return SaHolder.getRequest().getParam(AuthConsts.PARAMS_YUNZHUPAAS_TICKET, "");
}
protected boolean isValidYunzhupaasTicket() {
String yunzhupaasTicket = getYunzhupaasTicket();
if (!yunzhupaasTicket.isEmpty()) {
LoginTicketModel loginTicketModel = TicketUtil.parseTicket(yunzhupaasTicket);
if (loginTicketModel == null) {
return false;
}
}
return true;
}
/**
* 获取登录参数
*
* @param userInfo
* @param baseSystemInfo
* @return
*/
protected SaLoginModel getLoginModel(UserInfo userInfo, BaseSystemInfo baseSystemInfo) {
SaLoginModel loginModel = new SaLoginModel();
loginModel.setTimeout(userInfo.getTokenTimeout() * 60L);
loginModel.setExtraData(getTokenExtraData(userInfo, baseSystemInfo));
if (userInfo.getLoginDevice() == null) {
loginModel.setDevice(getDeviceType().getDevice());
userInfo.setLoginDevice(loginModel.device);
} else {
loginModel.setDevice(userInfo.getLoginDevice());
}
return loginModel;
}
/**
* 获取额外的JWT内容
*
* @param userInfo
* @param baseSystemInfo
* @return
*/
protected Map<String, Object> getTokenExtraData(UserInfo userInfo, BaseSystemInfo baseSystemInfo) {
Map<String, Object> tokenInfo = new HashMap<>();
// tokenInfo.put("token", StpUtil.getTokenValue());
tokenInfo.put("singleLogin", baseSystemInfo == null ? null : baseSystemInfo.getSingleLogin());
tokenInfo.put("user_name", userInfo.getUserAccount());
tokenInfo.put("user_id", userInfo.getUserId());
tokenInfo.put("exp", userInfo.getOverdueTime().getTime());
tokenInfo.put("token", userInfo.getId());
return tokenInfo;
}
@Override
public ActionResult<LogoutResultModel> logout() {
UserProvider.logout();
return ActionResult.success();
}
protected abstract String getGrantType();
@Override
public boolean requiresAuthentication() {
String path = SaHolder.getRequest().getRequestPath();
if (path != null && path.startsWith("/api/oauth")) {
path = path.replace("/api/oauth", "");
}
return pathMatcher.match(authenticationUrl, path);
}
}

View File

@@ -0,0 +1,25 @@
package com.yunzhupaas.granter;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.exception.LoginException;
import com.yunzhupaas.model.logout.LogoutResultModel;
import java.util.Map;
/**
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
*/
public interface TokenGranter {
ActionResult granter(Map<String, String> loginParameters) throws LoginException;
ActionResult<LogoutResultModel> logout();
boolean requiresAuthentication();
}

View File

@@ -0,0 +1,82 @@
package com.yunzhupaas.granter;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.config.YunzhupaasOauthConfig;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.consts.AuthConsts;
import com.yunzhupaas.exception.LoginException;
import com.yunzhupaas.util.UserProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
*/
@Component
public class TokenGranterBuilder {
@Autowired
private UserProvider userProvider;
@Autowired
private YunzhupaasOauthConfig oauthConfig;
private final Map<String, TokenGranter> granterPool = new ConcurrentHashMap<>();
public TokenGranterBuilder(Map<String, TokenGranter> granterPool) {
granterPool.forEach(this.granterPool::put);
}
/**
* 获取TokenGranter
*
* @param grantType 授权类型
* @return ITokenGranter
*/
public TokenGranter getGranter(String grantType) throws LoginException {
TokenGranter tokenGranter = null;
if (!oauthConfig.getSsoEnabled()) {
tokenGranter = granterPool.get(grantType);
}
if (tokenGranter == null) {
// URL匹配
for (TokenGranter value : granterPool.values()) {
if (value.requiresAuthentication()) {
tokenGranter = value;
break;
}
}
}
if (tokenGranter == null) {
if (oauthConfig.getSsoEnabled()) {
throw new LoginException(MsgCode.LOG111.get());
} else {
throw new LoginException(MsgCode.LOG112.get());
}
}
return tokenGranter;
}
/**
* 获取当前登录用户的TokenGranter
*
* @return
* @throws LoginException
*/
public TokenGranter getGranterByLogin(String grandType) {
if (grandType == null || grandType.isEmpty()) {
UserInfo userInfo = userProvider.get();
if (userInfo.getGrantType() != null) {
grandType = userInfo.getGrantType();
} else {
grandType = AuthConsts.GRANT_TYPE_PASSWORD;
}
}
return granterPool.get(grandType);
}
}

View File

@@ -0,0 +1,39 @@
package com.yunzhupaas.granter;
import com.yunzhupaas.consts.AuthConsts;
import com.yunzhupaas.service.UserDetailService;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
*/
@Component
public class UserDetailsServiceBuilder {
private final Map<String, UserDetailService> userDetailServices = new ConcurrentHashMap<>();
public UserDetailsServiceBuilder(Map<String, UserDetailService> userDetailServices) {
userDetailServices.forEach(this.userDetailServices::put);
}
/**
* 根据类型获取合适的UserDetailService
* @param detailType
* @return
*/
public UserDetailService getUserDetailService(String detailType){
if(detailType == null){
detailType = AuthConsts.USERDETAIL_ACCOUNT;
}
return userDetailServices.get(detailType);
}
}

View File

@@ -0,0 +1,38 @@
package com.yunzhupaas.model;
import com.yunzhupaas.consts.LoginTicketStatus;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NonNull;
import lombok.experimental.Accessors;
/**
* 轮询登录模型
*/
@Data
@Accessors(chain = true)
public class LoginTicketModel {
/**
* 状态
* @see LoginTicketStatus
*/
@NonNull
private int status = LoginTicketStatus.UnLogin.getStatus();
/**
* 额外的值, 登录Token、第三方登录的ID
*/
private String value;
/**
* 前端主题
*/
private String theme;
/**
* 票据有效期, 时间戳
*/
private Long ticketTimeout;
}

View File

@@ -0,0 +1,26 @@
package com.yunzhupaas.model;
import com.yunzhupaas.consts.ScanCodeTicketStatus;
import lombok.Data;
import lombok.NonNull;
@Data
public class ScanCodeLoginConfigModel {
/**
* 状态
* @see ScanCodeTicketStatus
*/
@NonNull
private int status = ScanCodeTicketStatus.UnScanCode.getStatus();
/**
* 额外的值, 登录Token、第三方登录的ID
*/
private String value;
/**
* 票据有效期, 时间戳
*/
private Long ticketTimeout;
}

View File

@@ -0,0 +1,62 @@
package com.yunzhupaas.service;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.exception.LoginException;
import com.yunzhupaas.model.BaseSystemInfo;
import com.yunzhupaas.model.login.PcUserVO;
/**
* 登陆业务层
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-03-23
*/
public interface LoginService {
/**
* 租戶登录验证
*
* @param userInfo
* @return userAccount, tenantId, tenandDb
* @throws LoginException
*/
UserInfo getTenantAccount(UserInfo userInfo) throws LoginException;
/**
* 生成用户登录信息
* @param userInfo 账户信息
* @param sysConfigInfo 系统配置
* @return
* @throws LoginException
*/
UserInfo userInfo(UserInfo userInfo, BaseSystemInfo sysConfigInfo) throws LoginException;
/**
* 获取用户登陆信息
*
* @return
*/
PcUserVO getCurrentUser(String type, String systemCode);
/**
* 修改密码信息发送
*
* @return
*/
void updatePasswordMessage();
/**
*
* @param tenantId
* @param tenantDb
* @param isAssignDataSource 是否租户指定数据源
* @return
*/
BaseSystemInfo getBaseSystemConfig(String tenantId);
}

View File

@@ -0,0 +1,20 @@
package com.yunzhupaas.service;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.exception.LoginException;
import org.springframework.core.Ordered;
public interface UserDetailService extends Ordered {
static final String USER_DETAIL_PREFIX = "USERDETAIL_";
/**
* 获取用户信息
* @param userInfo
* @return UserEntity
* @param <T>
*/
<T> T loadUserEntity(UserInfo userInfo) throws LoginException;
}

View File

@@ -0,0 +1,122 @@
package com.yunzhupaas.util;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.SaSessionCustomUtil;
import com.yunzhupaas.model.BaseSystemInfo;
import lombok.extern.slf4j.Slf4j;
import static com.yunzhupaas.consts.AuthConsts.DEF_TENANT_ID;
import static com.yunzhupaas.consts.AuthConsts.TENANT_SESSION;
/**
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
*/
@Slf4j
public class TenantProvider {
private static final long tenantTimeout = 60 * 60 * 24 * 30L;
/**
* 获取租户Redis存储对象
*
* @param tenantId
* @return
*/
public static SaSession getTenantSession(String tenantId) {
if (tenantId == null) {
// tenantId = TenantHolder.getDatasourceId();
// if (tenantId == null) {
tenantId = DEF_TENANT_ID;
// }
}
SaSession saSession = SaSessionCustomUtil.getSessionById(TENANT_SESSION + tenantId);
if (saSession != null && !saSession.get("init", false)) {
saSession.set("init", true);
saSession.updateTimeout(tenantTimeout);
}
return saSession;
}
/**
* 存入租户缓存空间
*
* @param tenantId
* @param key
* @param value
*/
public static void putTenantCache(String tenantId, String key, Object value) {
SaSession saSession = getTenantSession(tenantId);
if (saSession != null) {
saSession.set(key, value).updateTimeout(tenantTimeout);
}
}
/**
* 获取租户缓存数据
*
* @param tenantId
* @param key
* @param <T>
* @return
*/
public static <T> T getTenantCache(String tenantId, String key) {
SaSession saSession = getTenantSession(tenantId);
if (saSession != null) {
return (T) saSession.get(key);
}
return null;
}
/**
* 删除租户缓存数据
*
* @param tenantId
* @param key
*/
public static void delTenantCache(String tenantId, String key) {
SaSession saSession = getTenantSession(tenantId);
if (saSession != null) {
saSession.delete(key);
}
}
public static void renewTimeout(String tenantId, long timeout) {
if (tenantId == null) {
tenantId = DEF_TENANT_ID;
}
SaSession saSession = getTenantSession(tenantId);
if (saSession != null) {
saSession.updateTimeout(timeout);
}
}
private static ThreadLocal<BaseSystemInfo> systemInfoThreadLocal = new ThreadLocal<>();
/**
* 获取系统设置信息
*
* @return
*/
public static BaseSystemInfo getBaseSystemInfo() {
BaseSystemInfo systemInfo = systemInfoThreadLocal.get();
return systemInfo;
}
public static void setBaseSystemInfo(BaseSystemInfo baseSystemInfo) {
systemInfoThreadLocal.set(baseSystemInfo);
}
public static void clearBaseSystemIfo() {
systemInfoThreadLocal.remove();
}
}

View File

@@ -0,0 +1,69 @@
package com.yunzhupaas.util;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.temp.SaTempUtil;
import cn.dev33.satoken.util.SaTokenConsts;
import org.springframework.stereotype.Component;
/**
*
* @author 云筑产品开发平台组
* @copyright 深圳市乐程软件有限公司
*/
@Component
public class TicketUtil {
/**
* 创建临时TOKEN
* @param value 值
* @param timeout 有效时间, 秒
* @return
*/
public static String createTicket(Object value, long timeout){
return SaTempUtil.createToken(value, timeout);
}
/**
* 获取临时TOKEN内的数据
* @see #createTicket(Object, long)
* @param ticket 票据
* @return
* @param <T>
*/
public static <T> T parseTicket(String ticket){
return (T) SaTempUtil.parseToken(ticket);
}
/**
* 移除临时Token
* @param ticket
*/
public static void deleteTicket(String ticket){
SaTempUtil.deleteToken(ticket);
}
/**
* 更新Ticket内的内容
* @see #createTicket(Object, long)
* @param ticket 票据
* @param value 新值
* @param timeout 超时时间, 秒, 可空为不更新
*/
public static void updateTicket(String ticket, Object value, Long timeout){
Object obj = parseTicket(ticket);
if(obj == null) return;
String key = getTicketKey(ticket);
if(timeout != null){
SaManager.getSaTokenDao().setObject(key, value, timeout);
}else{
SaManager.getSaTokenDao().updateObject(key, value);
}
}
private static String getTicketKey(String ticket){
return SaManager.getSaTemp().splicingKeyTempToken(SaTokenConsts.DEFAULT_TEMP_TOKEN_SERVICE, ticket);
}
}

View File

@@ -0,0 +1,546 @@
package com.yunzhupaas.util;
import cn.dev33.satoken.same.SaSameUtil;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.TokenSign;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.text.StrPool;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.consts.DeviceType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import java.util.List;
import java.util.stream.Collectors;
import static com.yunzhupaas.consts.AuthConsts.TOKEN_PREFIX_SP;
/**
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:57
*/
@Slf4j
@Component
public class UserProvider {
private static RedisUtil redisUtil;
private static CacheKeyUtil cacheKeyUtil;
public static final String USER_INFO_KEY = "userInfo";
private static final ThreadLocal<UserInfo> USER_CACHE = new ThreadLocal<>();
public UserProvider(RedisUtil redisUtil, CacheKeyUtil cacheKeyUtil) {
UserProvider.redisUtil = redisUtil;
UserProvider.cacheKeyUtil = cacheKeyUtil;
}
// =================== 登录相关操作 ===================
/**
* 登录系统 适用于Request环境
*
* @param userInfo 登录用户信息
*/
public static void login(UserInfo userInfo) {
setLocalLoginUser(userInfo);
StpUtil.login(splicingLoginId(userInfo.getUserId()));
userInfo.setToken(StpUtil.getTokenValueNotCut());
setLoginUser(userInfo);
}
/**
* 登录系统 适用于Request环境
*
* @param userInfo 用户信息
* @param loginModel 登录参数
*/
public static void login(UserInfo userInfo, SaLoginModel loginModel) {
setLocalLoginUser(userInfo);
StpUtil.login(splicingLoginId(userInfo.getUserId()), loginModel);
userInfo.setToken(StpUtil.getTokenValueNotCut());
setLoginUser(userInfo);
}
/**
* 适用于非Request环境
* @param userInfo
* @param loginModel
*/
public static void loginNoRequest(UserInfo userInfo, SaLoginModel loginModel) {
setLocalLoginUser(userInfo);
String token = StpUtil.createLoginSession(splicingLoginId(userInfo.getUserId()), loginModel);
userInfo.setToken(TOKEN_PREFIX_SP + token);
setLoginUser(userInfo);
}
// =================== 登录用户ID相关操作 ===================
/**
* 获取指定TOKEN用户ID
*
* @param token
* @return
*/
public static String getLoginUserId(String token) {
String loginId = (String) StpUtil.getLoginIdByToken(token);
return parseLoginId(loginId);
}
/**
* 获取当前用户ID, 包含临时切换用户ID
*
* @return
*/
public static String getLoginUserId() {
String loginId = getUser().getUserId();
return parseLoginId(loginId);
}
// =================== 用户ID拼接相关操作 ===================
/**
* 拼接租户下的用户ID
*
* @param userId
* @return
*/
public static String splicingLoginId(String userId) {
return splicingLoginId(userId, null);
}
/**
* 拼接租户下的用户ID
* @param userId
* @param tenantId
* @return
*/
private static String splicingLoginId(String userId, String tenantId) {
if(StringUtil.isEmpty(tenantId)){
tenantId = TenantHolder.getDatasourceId();
}
if (!StringUtil.isEmpty(tenantId)) {
return tenantId + StrPool.COLON + userId;
}
return userId;
}
/**
* 解析租户下的登录ID
* @param loginId
* @return
*/
private static String parseLoginId(String loginId) {
if (loginId != null && loginId.contains(StrPool.COLON)) {
loginId = loginId.substring(loginId.indexOf(StrPool.COLON) + 1);
}
return loginId;
}
/**
* Token是否有效
*
* @param token
* @return
*/
public static Boolean isValidToken(String token) {
UserInfo userInfo = getUser(token);
return userInfo.getUserId() != null;
}
// =================== UserInfo缓存相关操作 ===================
/**
* 设置Redis用户数据
*/
public static void setLoginUser(UserInfo userInfo) {
StpUtil.getTokenSessionByToken(cutToken(userInfo.getToken())).set(USER_INFO_KEY, userInfo);
}
/**
* 设置本地用户数据
*/
public static void setLocalLoginUser(UserInfo userInfo) {
USER_CACHE.set(userInfo);
}
/**
* 获取本地用户数据
*/
public static UserInfo getLocalLoginUser() {
return USER_CACHE.get();
}
/**
* 清空本地用户数据
*/
public static void clearLocalUser() {
USER_CACHE.remove();
}
/**
* 获取用户缓存
* 保留旧方法
*
* @param token
* @return
*/
public UserInfo get(String token) {
return UserProvider.getUser(token);
}
/**
* 获取用户缓存
*
* @return
*/
public UserInfo get() {
return UserProvider.getUser();
}
/**
* 根据用户ID, 租户ID获取随机获取一个UserInfo
* @param userId
* @param tenantId
* @return
*/
public static UserInfo getUser(String userId, String tenantId){
return getUser(userId, tenantId, null, null);
}
/**
* 根据用户ID, 租户ID, 设备类型获取随机获取一个UserInfo
* @param userId
* @param tenantId
* @param includeDevice 指定的设备类型中查找
* @param excludeDevice 排除指定设备类型
* @return
*/
public static UserInfo getUser(String userId, String tenantId, List<String> includeDevice, List<String> excludeDevice){
SaSession session = StpUtil.getSessionByLoginId(splicingLoginId(userId, tenantId), false);
if (session != null) {
List<TokenSign> tokenSignList = session.tokenSignListCopy();
if (!tokenSignList.isEmpty()) {
tokenSignList = tokenSignList.stream().filter(tokenSign -> {
if(!ObjectUtils.isEmpty(excludeDevice)){
if(excludeDevice.contains(tokenSign.getDevice())){
return false;
}
}
if(!ObjectUtils.isEmpty(includeDevice)){
if(!includeDevice.contains(tokenSign.getDevice())){
return false;
}
}
return true;
}).collect(Collectors.toList());
if(!tokenSignList.isEmpty()){
return getUser(tokenSignList.get(0).getValue());
}
}
}
return new UserInfo();
}
/**
* 获取用户缓存
*
* @param token
* @return
*/
public static UserInfo getUser(String token) {
UserInfo userInfo = null;
String tokens = null;
if (token != null) {
tokens = cutToken(token);
} else {
try {
//处理非Web环境报错
tokens = StpUtil.getTokenValue();
} catch (Exception e) {
}
}
if (tokens != null) {
if (StpUtil.getLoginIdByToken(tokens) != null) {
userInfo = (UserInfo) StpUtil.getTokenSessionByToken(tokens).get(USER_INFO_KEY);
}
}
if (userInfo == null) {
userInfo = new UserInfo();
}
return userInfo;
}
/**
* 获取用户缓存
*
* @return
*/
public static UserInfo getUser() {
// if(StpUtil.getTokenValue() == null){
// return new UserInfo();
// }
UserInfo userInfo = USER_CACHE.get();
if (userInfo != null) {
return userInfo;
}
userInfo = UserProvider.getUser(null);
if (userInfo.getUserId() != null) {
USER_CACHE.set(userInfo);
}
return userInfo;
}
// =================== Token相关操作 ===================
/**
* 去除Token前缀
*
* @param token
* @return
*/
public static String cutToken(String token) {
if (token != null && token.startsWith(TOKEN_PREFIX_SP)) {
token = token.substring(TOKEN_PREFIX_SP.length());
}
return token;
}
/**
* 获取token
*/
public static String getToken() {
String toke = getAuthorize();
return toke;
}
/**
* 获取Authorize
*/
public static String getAuthorize() {
String authorize = ServletUtil.getHeader(Constants.AUTHORIZATION);
return authorize;
}
/**
* TOKEN续期
*/
public static void renewTimeout() {
if (StpUtil.getTokenValue() != null) {
UserInfo userInfo = UserProvider.getUser();
if(userInfo.getUserId() == null || userInfo.getTokenTimeout() == null) {
//避免请求过网关之后TOKEN失效(携带TOKEN调用登录接口之后账号被顶替)
return;
}
StpUtil.renewTimeout(userInfo.getTokenTimeout() * 60L);
SaSession saSession = StpUtil.getSessionByLoginId(splicingLoginId(userInfo.getUserId()), false);
if (saSession != null) {
saSession.updateTimeout(userInfo.getTokenTimeout() * 60L);
}
}
}
/**
* 获取所有Token记录
* 包含无效状态的用户、临时用户
*
* @return
*/
public static List<String> getLoginUserListToken() {
return StpUtil.searchTokenValue("", -1, -1, true).stream().map(token -> token.replace(StpUtil.stpLogic.splicingKeyTokenValue(""), "")).collect(Collectors.toList());
}
// =================== 临时Token相关操作 ===================
/**
* 获取内部服务传递验证TOKEN
*
* @return
*/
public static String getInnerAuthToken() {
return SaSameUtil.getToken();
}
/**
* 验证内部传递Token是否有效 抛出异常
* @param token
*/
public static void checkInnerToken(String token){
SaSameUtil.checkToken(token);
}
/**
* 验证内部传递Token是否有效
* @param token
*/
public static boolean isValidInnerToken(String token){
return SaSameUtil.isValid(token);
}
// =================== 退出相关操作 ===================
/**
* 根据用户ID踢出全部用户
* @param userId
*/
public static void kickoutByUserId(String userId, String tenantId) {
StpUtil.kickout(splicingLoginId(userId, tenantId));
}
/**
* 根据Token踢出指定会话
* @param tokens
*/
public static void kickoutByToken(String... tokens) {
for (String token : tokens) {
StpUtil.kickoutByTokenValue(token);
}
}
/**
* 退出当前Token, 不清除用户其他系统缓存
*/
public static void logout() {
StpUtil.logout();
}
/**
* 退出指定Token, 不清除用户其他系统缓存
*
* @param token
*/
public static void logoutByToken(String token) {
if (token == null) {
logout();
} else {
StpUtil.logoutByTokenValue(cutToken(token));
}
}
/**
* 退出指定设备类型的用户的全部登录信息, 不清除用户其他系统缓存
*
* @param userId
* @param deviceType
*/
public static void logoutByUserId(String userId, DeviceType deviceType) {
StpUtil.logout(splicingLoginId(userId), deviceType.getDevice());
}
/**
* 退出指定用户的全部登录信息, 清除相关缓存
*
* @param userId
*/
public static void logoutByUserId(String userId) {
StpUtil.logout(splicingLoginId(userId));
removeOtherCache(userId);
}
// =================== 用户权限 ===================
/**
* 获取当前用户拥有的权限列表(菜单编码列表、功能ID列表)
* @return
*/
public static List<String> getPermissionList(){
return StpUtil.getPermissionList();
}
/**
* 获取当前用户拥有的角色列表
* @return
*/
public static List<String> getRoleList(){
return StpUtil.getRoleList();
}
// =================== 其他缓存相关操作 ===================
/**
* 移除
*/
public static void removeOtherCache(String userId) {
redisUtil.remove(cacheKeyUtil.getUserAuthorize() + userId);
redisUtil.remove(cacheKeyUtil.getSystemInfo());
}
/**
* 是否在线
*/
public boolean isOnLine(String userId) {
return StpUtil.getTokenValueByLoginId(splicingLoginId(userId), getDeviceForAgent().getDevice()) != null;
}
/**
* 是否登陆
*/
public static boolean isLogined() {
return StpUtil.isLogin();
}
/**
* 指定Token是否有效
* @param token
* @return
*/
public static boolean isValid(String token) {
return StpUtil.getLoginIdByToken(token) != null;
}
public static DeviceType getDeviceForAgent() {
if (ServletUtil.getIsMobileDevice()) {
return DeviceType.APP;
} else {
return DeviceType.PC;
}
}
/**
* 判断用户是否是临时用户
* @param userInfo
* @return
*/
public static boolean isTempUser(UserInfo userInfo){
if(userInfo == null){
userInfo = getUser();
}
return DeviceType.TEMPUSER.getDevice().equals(userInfo.getLoginDevice())
|| DeviceType.TEMPUSERLIMITED.getDevice().equals(userInfo.getLoginDevice());
}
}

View File

@@ -0,0 +1,23 @@
<?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>
<artifactId>yunzhupaas-boot-common</artifactId>
<groupId>com.yunzhupaas</groupId>
<version>5.2.0-RELEASE</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>yunzhupaas-common-office-v3</artifactId>
<dependencies>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-common-office</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,70 @@
package cn.afterturn.easypoi.util;
import cn.afterturn.easypoi.excel.annotation.Excel;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
/**
* 导入可选校验 ImportParams.needVerify
* HIBERNATE 校验工具类
*
* @author JueYue
* 2015年11月11日 下午10:04:07
*/
public class PoiValidationUtil {
private final static Validator VALIDATOR;
static {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
VALIDATOR = factory.getValidator();
}
public static String validation(Object obj, Class[] verfiyGroup) {
Set<ConstraintViolation<Object>> set = null;
if (verfiyGroup != null) {
set = VALIDATOR.validate(obj, verfiyGroup);
} else {
set = VALIDATOR.validate(obj);
}
if (set != null && set.size() > 0) {
return getValidateErrMsg(set);
}
return null;
}
private static String getValidateErrMsg(Set<ConstraintViolation<Object>> set) {
StringBuilder builder = new StringBuilder();
for (ConstraintViolation<Object> constraintViolation : set) {
Class<?> cls = constraintViolation.getRootBean().getClass();
String fieldName = constraintViolation.getPropertyPath().toString();
List<Field> fields = new ArrayList<>(Arrays.asList(cls.getDeclaredFields()));
Class<?> superClass = cls.getSuperclass();
if (superClass != null) {
fields.addAll(Arrays.asList(superClass.getDeclaredFields()));
}
String name = null;
for (Field field : fields) {
if (field.getName().equals(fieldName) && field.isAnnotationPresent(Excel.class)) {
name = field.getAnnotation(Excel.class).name();
break;
}
}
if (name == null) {
name = fieldName;
}
builder.append(name).append(constraintViolation.getMessage()).append(",");
}
return builder.substring(0, builder.length() - 1);
}
}

View File

@@ -0,0 +1,16 @@
<?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">
<parent>
<artifactId>yunzhupaas-boot-common</artifactId>
<groupId>com.yunzhupaas</groupId>
<version>5.2.0-RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yunzhupaas-common-connector</artifactId>
</project>

View File

@@ -0,0 +1,25 @@
package com.yunzhupaas.permission.connector;
import java.util.Map;
/**
* 用户推送
*
* @author :云筑产品开发平台组
* @version: V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2022/8/3 13:50
*/
public interface HttpRequestUserInfoService {
/**
* 同步数据到本地数据库
*
* @param userEntity
* @param method
* @param tenantId
*/
void syncUserInfo(Map<String, Object> userEntity, String method, String tenantId);
}

View File

@@ -0,0 +1,44 @@
package com.yunzhupaas.permission.connector;
import java.util.Map;
/**
* 拉取用户
*
* @author :云筑产品开发平台组
* @version: V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2022/7/28 14:27
*/
public interface UserInfoService {
/**
* 添加
*
* @param map
*/
Boolean create(Map<String, Object> map);
/**
* 修改
*
* @param map
*/
Boolean update(Map<String, Object> map);
/**
* 删除
*
* @param map
*/
Boolean delete(Map<String, Object> map);
/**
* 获取信息
*
* @param id
*/
Map<String, Object> getInfo(String id);
}

View File

@@ -0,0 +1,315 @@
<?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">
<parent>
<artifactId>yunzhupaas-boot-common</artifactId>
<groupId>com.yunzhupaas</groupId>
<version>5.2.0-RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yunzhupaas-common-core</artifactId>
<dependencies>
<!-- Lombok 依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-annotation</artifactId>
</dependency>
<!--<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>-->
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
</dependency>
<!-- Alibaba Fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!-- lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- excel工具 -->
<!-- Quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<exclusions>
<exclusion>
<artifactId>HikariCP-java7</artifactId>
<groupId>com.zaxxer</groupId>
</exclusion>
</exclusions>
</dependency>
<!--二维码-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
</dependency>
<!-- 拼音 -->
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
</dependency>
<!-- Jackson -->
<!--<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>-->
<!-- 公共资源池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
</dependency>
<!-- 字段验证 -->
<!--<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>-->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>org.owasp.antisamy</groupId>
<artifactId>antisamy</artifactId>
<exclusions>
<exclusion>
<artifactId>commons-io</artifactId>
<groupId>commons-io</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- commons-text -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
</dependency>
<dependency>
<groupId>com.github.yitter</groupId>
<artifactId>yitter-idgenerator</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>${mybatis-plus.vesion}</version>
</dependency>
<!-- 淘汰配置兼容 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>
<scope>runtime</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>javax.servlet</groupId>-->
<!-- <artifactId>javax.servlet-api</artifactId>-->
<!-- <optional>true</optional>-->
<!-- <scope>provided</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>jakarta.servlet</groupId>-->
<!-- <artifactId>jakarta.servlet-api</artifactId>-->
<!-- <optional>true</optional>-->
<!-- <scope>provided</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>jakarta.annotation</groupId>-->
<!-- <artifactId>jakarta.annotation-api</artifactId>-->
<!-- <version>2.1.1</version>-->
<!-- <optional>true</optional>-->
<!-- <scope>provided</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>javax.annotation</groupId>-->
<!-- <artifactId>javax.annotation-api</artifactId>-->
<!-- <version>1.3.2</version>-->
<!-- <optional>true</optional>-->
<!-- <scope>provided</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>jakarta.validation</groupId>-->
<!-- <artifactId>jakarta.validation-api</artifactId>-->
<!-- <version>3.0.2</version>-->
<!-- <optional>true</optional>-->
<!-- <scope>provided</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>javax.validation</groupId>-->
<!-- <artifactId>validation-api</artifactId>-->
<!-- <version>2.0.1.Final</version>-->
<!-- <optional>true</optional>-->
<!-- <scope>provided</scope>-->
<!-- </dependency>-->
<!--集成logstash-->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<exclusions>
<exclusion>
<artifactId>jackson-databind</artifactId>
<groupId>com.fasterxml.jackson.core</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- Skywalking 日志上报 -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>boot3</id>
<activation>
<jdk>[17,)</jdk>
</activation>
<dependencies>
<!-- Java Servlet -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations-jakarta</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-models-jakarta</artifactId>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>boot2</id>
<activation>
<jdk>(,17)</jdk>
</activation>
<dependencies>
<!-- Java Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- 同时添加 jakarta 依赖以支持代码中的 jakarta 包 -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-models</artifactId>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</dependency>
<!-- 同时添加 jakarta validation 依赖 -->
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,28 @@
package com.yunzhupaas.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 接口传输加密
* 加密请求和返回结果: @EncryptApi
* 只加密请求: @EncryptApi(encryptRequest = false)
* 只加密返回结果: @EncryptApi(encryptResponse = false)
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.PARAMETER})
public @interface EncryptApi {
/**
* 加密请求内容
*/
boolean encryptRequest() default true;
/**
* 加密返回结果
*/
boolean encryptResponse() default true;
}

View File

@@ -0,0 +1,33 @@
package com.yunzhupaas.annotation;
import java.lang.annotation.*;
/**
* 请求日志注解
*
* @author :云筑产品开发平台组
* @version: V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2022/3/15 11:19
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface HandleLog {
/**
* 操作模块
*
* @return
*/
String moduleName() default "";
/**
* 操作方式
*
* @return
*/
String requestMethod() default "";
}

View File

@@ -0,0 +1,19 @@
package com.yunzhupaas.annotation;
import java.lang.annotation.*;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 8:53
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface OrganizeAdminIsTrator {
String value() default "";
}

View File

@@ -0,0 +1,18 @@
package com.yunzhupaas.annotation;
import java.lang.annotation.*;
/**
* 组织权限验证
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-10-30
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface OrganizePermission {
}

View File

@@ -0,0 +1,18 @@
package com.yunzhupaas.annotation;
import java.lang.annotation.*;
/**
* 组织权限验证
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-10-30
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PositionPermission {
}

View File

@@ -0,0 +1,19 @@
package com.yunzhupaas.annotation;
import java.lang.annotation.*;
/**
* 角色权限验证
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-10-30
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RolePermission {
}

View File

@@ -0,0 +1,24 @@
package com.yunzhupaas.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 内部请求校验:校验是否来自内部请求
*
* <p> 可标注在方法、类上(效果等同于标注在此类的所有方法上)
*
* @author 云筑产品开发平台组
* @version V5.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-12-31
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface SaCheckSame {
}

View File

@@ -0,0 +1,18 @@
package com.yunzhupaas.annotation;
import java.lang.annotation.*;
/**
* 组织权限验证
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-10-30
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserPermission {
}

View File

@@ -0,0 +1,117 @@
package com.yunzhupaas.annotation;
import java.lang.annotation.*;
/**
* 控件属性
*
* @author 云筑产品开发平台组
* @version V3.4.3
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2022/9/19
*/
@Documented
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface YunzhupaasField {
String vModel() default "";
String label() default "";
/**
* 是否多选
*/
boolean multiple() default false;
String yunzhupaasKey() default "";
/**
* 显示层级
*/
String showLevel() default "";
/**
* 省市区显示层级
*/
String level() default "0";
/**
* 单据规则
*/
String rule() default "";
String activeTxt() default "";
String inactiveTxt() default "";
int min() default -1;
int max() default -1;
/**
*
* 是否唯一
*/
boolean unique() default false;
boolean isUpdate() default false;
/**
* 单行输入正则
*/
String regex() default "";
/**
* 表名
*/
String relationTable() default "";
String tableName() default "";
/**
* 时间
*/
String format() default "";
/**
* 数据接口
*/
String dataType() default "";
String dataLabel() default "fullName";
String dataValue() default "id";
String dataChildren() default "children";
String propsUrl() default "";
String dictionaryType() default "";
String options() default "";
String ableDepIds() default "[]";
String ablePosIds() default "[]";
String ableUserIds() default "[]";
String ableRoleIds() default "[]";
String ableGroupIds() default "[]";
String ableIds() default "[]";
String selectType() default "";
/**
* 开始时间
*/
String startTime() default "";
/**
* 结束时间
*/
String endTime() default "";
}

View File

@@ -0,0 +1,114 @@
package com.yunzhupaas.base;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.yunzhupaas.base.vo.PageListVO;
import com.yunzhupaas.base.vo.PaginationVO;
import com.yunzhupaas.constant.MsgCode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:45
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ActionResult<T> {
@Schema(description = "状态码")
private Integer code;
@Schema(description = "返回信息")
private String msg;
@Schema(description = "返回数据")
private T data;
/* ============== success ============ */
public static <T> ActionResult<T> success() {
ActionResult<T> jsonData = new ActionResult<>();
jsonData.setCode(200);
jsonData.setMsg(MsgCode.SU000.get());
return jsonData;
}
public static <T> ActionResult<T> success(String msg) {
ActionResult<T> jsonData = new ActionResult<>();
jsonData.setCode(200);
jsonData.setMsg(msg);
return jsonData;
}
public static <T> ActionResult<T> success(T object) {
ActionResult<T> jsonData = new ActionResult<>();
jsonData.setData(object);
jsonData.setCode(200);
jsonData.setMsg(MsgCode.SU000.get());
return jsonData;
}
public static <T> ActionResult<T> success(String msg, T object) {
ActionResult<T> jsonData = new ActionResult<>();
jsonData.setData(object);
jsonData.setCode(200);
jsonData.setMsg(msg);
return jsonData;
}
/* ============== fail ============ */
public static <T> ActionResult<T> fail(Integer code, String message) {
ActionResult<T> jsonData = new ActionResult<>();
jsonData.setCode(code);
jsonData.setMsg(message);
return jsonData;
}
public static ActionResult<String> fail(String msg, String data) {
ActionResult<String> jsonData = new ActionResult<>();
jsonData.setMsg(msg);
jsonData.setData(data);
return jsonData;
}
public static <T> ActionResult<T> fail(String msg) {
ActionResult<T> jsonData = new ActionResult<>();
jsonData.setMsg(msg);
jsonData.setCode(400);
return jsonData;
}
/* ============== page ============ */
public static <T> ActionResult<PageListVO<T>> page(List<T> list, PaginationVO pagination) {
ActionResult<PageListVO<T>> jsonData = new ActionResult<>();
PageListVO<T> vo = new PageListVO<>();
vo.setList(list);
vo.setPagination(pagination);
jsonData.setData(vo);
jsonData.setCode(200);
jsonData.setMsg(MsgCode.SU000.get());
return jsonData;
}
public static <T> ActionResult<DataInterfacePageListVO<T>> page(List<T> list, PaginationVO pagination, String dataProcessing) {
ActionResult<DataInterfacePageListVO<T>> jsonData = new ActionResult<>();
DataInterfacePageListVO<T> vo = new DataInterfacePageListVO<>();
vo.setList(list);
vo.setPagination(pagination);
vo.setDataProcessing(dataProcessing);
jsonData.setCode(200);
jsonData.setData(vo);
jsonData.setMsg(MsgCode.SU000.get());
return jsonData;
}
}

View File

@@ -0,0 +1,69 @@
package com.yunzhupaas.base;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.constant.model.MCode;
/**
* 错误提示枚举类
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-09-26 上午9:18
*/
public enum ActionResultCode {
/**
* 成功
*/
Success(200, MsgCode.GT101),
/**
* 失败
*/
Fail(400, MsgCode.GT102),
/**
* 验证错误
*/
ValidateError(401, MsgCode.GT103),
/**
* 异常
*/
Exception(500, MsgCode.GT104),
/**
* 登录过期提示
*/
SessionOverdue(600, MsgCode.GT105),
/**
* 踢出提示
*/
SessionOffLine(601, MsgCode.GT106),
/**
* token失效
*/
SessionError(602, MsgCode.GT107);
private int code;
private MCode message;
ActionResultCode(int code, MCode message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message.get();
}
public void setMessage(MCode message) {
this.message = message;
}
}

View File

@@ -0,0 +1,19 @@
package com.yunzhupaas.base;
import com.yunzhupaas.base.vo.PageListVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 数据接口弹窗选择
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-12-31
*/
@Data
public class DataInterfacePageListVO<T> extends PageListVO {
private String dataProcessing;
}

View File

@@ -0,0 +1,43 @@
package com.yunzhupaas.base;
/**
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-04-07
*/
public class DataSourceInfo {
public static final String mysqlUrl="jdbc:mysql://{host}:{port}/{dbName}?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC";
public static final String mysqlDriver="com.mysql.cj.jdbc.Driver";
public static final String oracleUrl="jdbc:oracle:thin:@{host}:{port}:{dbName}";
public static final String oracleDriver="oracle.jdbc.OracleDriver";
public static final String sqlserverUrl="jdbc:sqlserver://{host}:{port};Databasename={dbName}";
public static final String sqlserverDriver="com.microsoft.sqlserver.jdbc.SQLServerDriver";
public static final String dmUrl="jdbc:dm://{host}:{port}/{dbName}?yunzhupaasDateTimeBehavior=convertToNull&useUnicode" +
"=true&characterEncoding=utf-8";
public static final String dmDriver="dm.jdbc.driver.DmDriver";
public static final String kingBaseUrl = "jdbc:kingbase8://{host}:{port}/{dbName}";
public static final String kingBaseDriver = "com.kingbase8.Driver";
public static final String postgreUrl = "jdbc:postgresql://{host}:{port}/{dbName}" ;
public static final String postgreDriver = "org.postgresql.Driver";
}

View File

@@ -0,0 +1,86 @@
package com.yunzhupaas.base;
/**
* 日志分类
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-09-26 上午9:18
*/
public enum LogSortEnum {
/**
* 登录
*/
Login(1, "登录"),
/**
* 访问
*/
Visit(2, "访问"),
/**
* 操作
*/
Operate(3, "操作"),
/**
* 异常
*/
Exception(4, "异常"),
/**
* 请求
*/
Request(5, "请求");
private int code;
private String message;
LogSortEnum(int code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
/**
* 根据状态code获取枚举名称
*
* @return
*/
public static String getMessageByCode(Integer code) {
for (LogSortEnum status : LogSortEnum.values()) {
if (status.getCode().equals(code)) {
return status.message;
}
}
return null;
}
/**
* 根据状态code获取枚举值
*
* @return
*/
public static LogSortEnum getByCode(Integer code) {
for (LogSortEnum status : LogSortEnum.values()) {
if (status.getCode().equals(code)) {
return status;
}
}
return null;
}
}

View File

@@ -0,0 +1,90 @@
package com.yunzhupaas.base;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.v3.oas.annotations.media.Schema;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.exception.DataException;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* 联合主键
*
* 门户管理单条数据可以由平台、门户ID、系统ID 三种数据定位
* 它们组合成门户管理的联合主键此类将其看成一个主键来配合QueryWrapper使用
*
* @author 云筑产品开发平台组
* @version v3.4.8
* @copyrignt 深圳市乐程软件有限公司
* @date 2023-04-20
*/
public abstract class MyBatisPrimaryBase<T> {
{
ParameterizedType parameterizedType = (ParameterizedType) this.getClass().getGenericSuperclass();
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
Class<T> clz = (Class<T>)actualTypeArguments[0];
try {
entity = clz.getDeclaredConstructor().newInstance();
} catch (Exception ignore) {}
}
@Schema(description = "查询器")
protected QueryWrapper<T> queryWrapper = new QueryWrapper<>();
private T entity;
@Schema(description = "获取处理后的查询器")
public QueryWrapper<T> getQuery(){
try{
for (Field field : this.getClass().getDeclaredFields()) {
try{
TableField annotation = entity.getClass().getDeclaredField(field.getName()).getAnnotation(TableField.class);
String columnName;
if(annotation != null) {
columnName = annotation.value();
}else if(field.getName().equalsIgnoreCase("id")) {
columnName = "F_Id";
}else if(field.getName().equalsIgnoreCase("creatorId")){
columnName = "F_Creator_Id";
}else {
columnName = field.getName();
}
field.setAccessible(true);
Object value = field.get(this);
if(value != null) queryWrapper.eq(columnName, value);
}catch (Exception ignore){}
}
}catch (Exception ignore){}
return queryWrapper;
}
@Schema(description = "获取实例")
public T getEntity() throws Exception {
checkEntity();
for (Field field : this.getClass().getDeclaredFields()) {
for (Field entityField : entity.getClass().getDeclaredFields()) {
if(entityField.getName().equals(field.getName())){
entityField.setAccessible(true);
field.setAccessible(true);
entityField.set(entity, field.get(this));
}
}
}
return entity;
}
private void checkEntity() throws Exception{
for (Field field : this.getClass().getFields()) {
Object o = field.get(this);
if(o == null){
throw new DataException(MsgCode.DB011.get(field.getName()));
}
}
}
}

View File

@@ -0,0 +1,16 @@
package com.yunzhupaas.base;
import lombok.Data;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:51
*/
@Data
public class Page {
private String keyword="";
}

View File

@@ -0,0 +1,59 @@
package com.yunzhupaas.base;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:51
*/
@Data
public class PageModel {
/**
* 每页行数
*/
private int rows;
/**
* 当前页
*/
private int page;
/**
* 总页数
*/
private long total;
/**
* 总记录数
*/
private long records;
/**
* 排序列
*/
private String sidx;
/**
* 排序类型
*/
private String sord;
/**
* 查询条件
*/
private String queryJson;
/**
* 查询关键字
*/
private String keyword;
public <T> List<T> setData(List<T> data, long records) {
this.records = records;
if(this.records>0){
this.total = this.records % this.rows == 0 ? this.records / this.rows : this.records/this.rows+1;
}else {
this.total = 0;
}
return data;
}
}

View File

@@ -0,0 +1,34 @@
package com.yunzhupaas.base;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:51
*/
@Data
public class Pagination extends Page{
private long pageSize=20;
private String sort="DESC";
private String sidx="";
private long currentPage=1;
@JsonIgnore
private long total;
@JsonIgnore
private long records;
public <T> List<T> setData(List<T> data, long records) {
this.total = records;
return data;
}
}

View File

@@ -0,0 +1,18 @@
package com.yunzhupaas.base;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:51
*/
@Data
public class PaginationTime extends Pagination {
private Long startTime;
private Long endTime;
// private String type;
}

View File

@@ -0,0 +1,30 @@
package com.yunzhupaas.base;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 发送短信配置模型
*
* @版本: V3.1.0
* @版权: 深圳市乐程软件有限公司http://www.szlecheng.cn
* @作者: 云筑产品开发平台组
* @日期: 2021/4/20 14:22
*/
@Data
public class SmsModel {
/**
* 阿里
*/
private String aliAccessKey;
private String aliSecret;
/**
* 腾讯
*/
private String tencentSecretId;
private String tencentSecretKey;
private String tencentAppId;
private String tencentAppKey;
}

View File

@@ -0,0 +1,215 @@
package com.yunzhupaas.base;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 登录者信息
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024-09-26 上午9:18
*/
@Data
public class UserInfo implements Serializable {
/**
* 唯一Id
*/
private String id;
/**
* 用户主键
*/
private String userId;
/**
* 用户账户
*/
private String userAccount;
/**
* 用户姓名
*/
private String userName;
/**
* 用户头像
*/
private String userIcon;
/**
* 用户性别
*/
private String userGender;
/**
* 主题
*/
private String theme;
/**
* 机构主键
*/
private String organizeId;
/**
* 机构主键
*/
private String departmentId;
/**
* 我的主管
*/
private String managerId;
/**
* 下属机构
*/
private String[] subOrganizeIds;
/**
* 我的下属
*/
private List<String> subordinateIds;
/**
* 岗位主键
*/
private String[] positionIds;
/**
* 角色主键
*/
private List<String> roleIds;
/**
* 登录时间
*/
private String loginTime;
/**
* 登录IP地址
*/
private String loginIpAddress;
/**
* 登录IP地址所在城市
*/
private String loginIpAddressName;
/**
* 登录MAC地址
*/
private String macAddress;
/**
* 登录平台设备(UA)
*/
private String loginPlatForm;
/**
* 登录平台名称
*/
private String loginDevice;
/**
* 上次登录时间
*/
private Date prevLoginTime;
/**
* 上次登录IP地址
*/
private String prevLoginIpAddress;
/**
* 上次登录IP地址所在城市
*/
private String prevLoginIpAddressName;
/**
* 是否超级管理员
*/
private Boolean isAdministrator = true;
/**
* 过期时间
*/
private Date overdueTime;
/**
* 系统配置超时时间
*/
private Integer tokenTimeout;
/**
* 租户编码
*/
private String tenantId;
public String getTenantId() {
return tenantId = tenantId == null ? "" : tenantId;
}
/**
* 租户数据库连接串(注意:主要解决多租户系统用的。每个租户连接数据库都是唯一的)
*/
/**
* 目前就支持一个数据库。如果业务需要多个数据库,手动去添加 ConnectionString1、ConnectionString2 等等
*/
@Deprecated
private String tenantDbConnectionString;
/**
* 租户数据源类型
* @see com.yunzhupaas.model.tenant.TenantVO
*/
private int tenantDbType;
private String portalId;
/**
* 系统id
*/
private String systemId;
/**
* 系统id
*/
private List<String> systemIds;
/**
* APP系统id
*/
private String appSystemId;
/**
* 登录类型
*/
private String grantType;
/**
* 单点登录用户票据, 用于单点注销
*/
private String onlineTicket;
/**
* Token
*/
private String token;
/**
* 用户信息实现接口
*/
private String userDetailKey;
private List<String> groupIds;
private List<String> groupNames;
/**
* 浏览器
*/
private String browser;
/**
* 所属组织
*/
private String organize;
/**
* 独立URL Code
*/
private String systemCode;
/**
* 手机号
*/
private String mobilePhone;
/**
* 邮箱
*/
private String email;
/**
* 启用状态
*/
private Integer enabledMark;
/**
* 创建时间
*/
private Date createTime;
}

View File

@@ -0,0 +1,133 @@
package com.yunzhupaas.base.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.v3.oas.annotations.media.Schema;
import com.yunzhupaas.constant.TableFieldsNameConst;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.io.Serializable;
import java.util.Date;
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public abstract class SuperBaseEntity implements Serializable {
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public static abstract class SuperIBaseEntity<T> extends SuperBaseEntity {
/**
* 主键
*/
@TableId(TableFieldsNameConst.F_ID)
public T id;
}
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public static abstract class SuperTBaseEntity<T> extends SuperIBaseEntity<T> {
/**
* 租户id
*/
@TableField(value = TableFieldsNameConst.F_TENANT_ID, fill = FieldFill.INSERT_UPDATE)
private String tenantId;
}
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public static abstract class SuperCBaseEntity<T> extends SuperTBaseEntity<T> {
/**
* 创建时间
*/
@TableField(value = TableFieldsNameConst.F_CREATOR_TIME, fill = FieldFill.INSERT)
private Date creatorTime;
/**
* 创建用户
*/
@TableField(value = TableFieldsNameConst.F_CREATOR_USER_ID, fill = FieldFill.INSERT)
private String creatorUserId;
}
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public static abstract class SuperCUBaseEntity<T> extends SuperCBaseEntity<T> {
/**
* 修改时间
*/
@TableField(value = TableFieldsNameConst.F_LAST_MODIFY_TIME, fill = FieldFill.UPDATE)
private Date lastModifyTime;
/**
* 修改用户
*/
@TableField(value = TableFieldsNameConst.F_LAST_MODIFY_USER_ID, fill = FieldFill.UPDATE)
private String lastModifyUserId;
}
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public static abstract class SuperCUDBaseEntity<T> extends SuperCUBaseEntity<T> {
/**
* 删除标志
*/
@TableField(value = TableFieldsNameConst.F_DELETE_MARK, updateStrategy = FieldStrategy.IGNORED)
private Integer deleteMark;
/**
* 删除时间
*/
@TableField(value = TableFieldsNameConst.F_DELETE_TIME, fill = FieldFill.UPDATE)
private Date deleteTime;
/**
* 删除用户
*/
@TableField(value = TableFieldsNameConst.F_DELETE_USER_ID, fill = FieldFill.UPDATE)
private String deleteUserId;
}
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public static abstract class SuperCDBaseEntity<T> extends SuperCBaseEntity<T> {
/**
* 删除标志
*/
@TableField(value = TableFieldsNameConst.F_DELETE_MARK, updateStrategy = FieldStrategy.IGNORED)
private Integer deleteMark;
/**
* 删除时间
*/
@TableField(value = TableFieldsNameConst.F_DELETE_TIME, fill = FieldFill.UPDATE)
private Date deleteTime;
/**
* 删除用户
*/
@TableField(value = TableFieldsNameConst.F_DELETE_USER_ID, fill = FieldFill.UPDATE)
private String deleteUserId;
}
}

View File

@@ -0,0 +1,12 @@
package com.yunzhupaas.base.entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public abstract class SuperEntity<T> extends SuperBaseEntity.SuperCUDBaseEntity<T> {
}

View File

@@ -0,0 +1,67 @@
package com.yunzhupaas.base.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.yunzhupaas.constant.TableFieldsNameConst;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public abstract class SuperExtendEntity<T> extends SuperEntity<T> {
/**
* 排序码
*/
@TableField(TableFieldsNameConst.F_SORT_CODE)
private Long sortCode;
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public static abstract class SuperExtendDescriptionEntity<T> extends SuperExtendEntity<T> {
/**
* 描述
*/
@TableField(TableFieldsNameConst.F_DESCRIPTION)
private String description;
}
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public static abstract class SuperExtendEnabledEntity<T> extends SuperExtendEntity<T> {
/**
* 有效标志 (0-默认禁用1-启用)
*/
@TableField(value = TableFieldsNameConst.F_ENABLED_MARK, fill = FieldFill.INSERT)
private Integer enabledMark;
}
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public static abstract class SuperExtendDEEntity<T> extends SuperExtendEntity<T> {
/**
* 描述
*/
@TableField(TableFieldsNameConst.F_DESCRIPTION)
private String description;
/**
* 有效标志 (0-默认禁用1-启用)
*/
@TableField(value = TableFieldsNameConst.F_ENABLED_MARK, fill = FieldFill.INSERT)
private Integer enabledMark;
}
}

View File

@@ -0,0 +1,29 @@
package com.yunzhupaas.base.user;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
/**
* 用户租户信息
*
* @author :云筑产品开发平台组
* @version: V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2022/5/10 16:13
*/
@Data
public class UserTenantModel implements Serializable {
/**
* 租户手机号
*/
private String tenantId;
public UserTenantModel() {
}
public UserTenantModel(String tenantId) {
this.tenantId = tenantId;
}
}

View File

@@ -0,0 +1,27 @@
package com.yunzhupaas.base.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:51
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DownloadVO {
@Schema(description = "名称")
private String name;
@Schema(description = "请求接口")
private String url;
}

View File

@@ -0,0 +1,25 @@
package com.yunzhupaas.base.vo;
import lombok.AllArgsConstructor;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:51
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ListVO<T> {
private List<T> list;
}

View File

@@ -0,0 +1,20 @@
package com.yunzhupaas.base.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:51
*/
@Data
public class PageListVO<T> {
private List<T> list;
PaginationVO pagination;
}

View File

@@ -0,0 +1,19 @@
package com.yunzhupaas.base.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 需要分页的模型
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-03-15 09:50
*/
@Data
public class PaginationVO {
private Long currentPage;
private Long pageSize;
private Integer total;
}

View File

@@ -0,0 +1,63 @@
package com.yunzhupaas.config;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.SmartInitializingSingleton;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 程序启动线程初始化类
*/
@Slf4j
public class ApplicationStartErrorCheck implements SmartInitializingSingleton {
private static boolean startError = false;
@Getter
private static final ThreadPoolExecutor applicationInitThreadPool = new ThreadPoolExecutor(10, Integer.MAX_VALUE,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
public static void setStartError() {
ApplicationStartErrorCheck.startError = true;
}
@SneakyThrows
@Override
public void afterSingletonsInstantiated() {
long count = 0;
long sleep = 100L;
//最多等待程序启动5分钟
long maxCount = 5 * 60000 / sleep;
boolean isComplete = true;
// 等待异步初始化全部完成
while(!applicationInitThreadPool.getQueue().isEmpty() || applicationInitThreadPool.getActiveCount() > 0){
if(log.isDebugEnabled()) {
log.error("等待初始化线程全部结束");
}
Thread.sleep(sleep);
if(++count > maxCount){
isComplete = false;
break;
}
}
if(!isComplete){
log.error("容器初始化时间过长 请检查是否存在问题");
System.exit(0);
}
if(startError){
log.error("Bean初始化发生错误, 请检查启动日志");
System.exit(0);
}
// System.out.println("延迟五秒");
// Thread.sleep(5000L);
if(log.isDebugEnabled()) {
log.debug("容器初始化结束");
}
}
}

View File

@@ -0,0 +1,53 @@
package com.yunzhupaas.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.core.env.PropertySource;
/**
* 将Spring中的配置设置到系统属性中
* conf2system:
* csp.sentinel.log.dir: log/${spring.application.name}/sentinel
* rocketmq.log.level: "OFF"
* demo.enabled: false
*
* @author 云筑产品开发平台组
* @version V5.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-12-17
*/
@Slf4j
public class Conf2SystemConfiguration implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
private static final String PREFIX = "conf2system.";
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
for (PropertySource<?> source : applicationContext.getEnvironment().getPropertySources()) {
if(source instanceof EnumerablePropertySource){
for (String propertyName : ((EnumerablePropertySource<?>) source).getPropertyNames()) {
if(propertyName.startsWith(PREFIX)){
Object value = environment.getProperty(propertyName);
if(value != null){
System.setProperty(propertyName.substring(PREFIX.length()), String.valueOf(value));
if(log.isDebugEnabled()){
log.debug("Setting system property [{}] to [{}]", propertyName.substring(PREFIX.length()), value);
}
}
}
}
}
}
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE+1000;
}
}

View File

@@ -0,0 +1,379 @@
package com.yunzhupaas.config;
import cn.hutool.core.net.url.UrlBuilder;
import com.yunzhupaas.constant.ConfigConst;
import com.yunzhupaas.constant.TableFieldsNameConst;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.XSSEscape;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 8:47
*/
@Data
public class ConfigValueUtil {
public static final String PREFIX = "config";
@Value("spring.application.name:YUNZHUPAAS")
private String applicationName;
// /**
// * 环境路径
// */
// @Value("${config.Path:}")
// private String path;
/**
* 数据库备份文件路径
*/
private String dataBackupFilePath;
/**
* 临时文件存储路径
*/
private String temporaryFilePath;
/**
* 系统文件存储路径
*/
private String systemFilePath;
/**
* 文件模板存储路径
*/
private String templateFilePath;
/**
* 代码模板存储路径
*/
private String templateCodePath;
/**
* vue3代码模板存储路径
*/
private String templateCodePathVue3;
/**
* 邮件文件存储路径
*/
private String emailFilePath;
/**
* 大屏图片存储目录
*/
private String biVisualPath;
/**
* 文档管理存储路径
*/
private String documentFilePath;
/**
* 文件在线预览存储pdf
*/
private String documentPreviewPath;
/**
* 用户头像存储路径
*/
private String userAvatarFilePath;
/**
* IM聊天图片+语音存储路径
*/
private String imContentFilePath;
/**
* 允许上传文件类型
*/
private String allowUploadFileType;
/**
* 允许图片类型
*/
private String allowUploadImageType;
/**
* 允许预览类型
*/
private String allowPreviewFileType;
/**
* 预览方式
*/
private String previewType;
/**
* 预览方式
*/
private String kkFileUrl;
/**
* 多语言json路径
*/
private String baseLanguagePath;
/**
* 前端文件目录
*/
private String serviceDirectoryPath = ConfigConst.CODE_TEMP_FOLDER;
/**
* 代码生成器命名空间
*/
private String codeAreasName;
/**
* 前端附件文件目录
*/
private String webAnnexFilePath;
/**
* ApacheShardingSphere 配置开关
*/
private boolean shardingSphereEnabled;
/**
* 软件的错误报告
*/
private String errorReport;
/**
* 软件的错误报告发给谁
*/
private String errorReportTo;
/**
* 系统日志启用true、false
*/
private String recordLog;
/**
* 多租户启用true、false
*/
private boolean multiTenancy;
/**
* 多租户接口
*/
private String multiTenancyUrl;
/**
* 多租户字段
*/
private String multiTenantColumn = TableFieldsNameConst.F_TENANT_ID;
/**
* 字段多租户忽略表
*/
private List<String> multiTenantIgnoreTable = initMultiTenantIgnoreTable();
/**
* 多租户登录短信验证接口
*/
private String multiTenancyOfficialLoginCodeUrl = null;
/**
* 多租户重置密码短信验证接口
*/
private String multiTenancyOfficialResetCodeUrl = null;
/**
* 开启逻辑删除功能
*/
private boolean enableLogicDelete = false;
/**
* 扫码登录过期时间
*/
private Long codeCertificateTimeout = 180L;
/**
* 逻辑删除字段
*/
private String logicDeleteColumn = TableFieldsNameConst.F_DELETE_MARK;
/**
* 版本
*/
private String softVersion;
/**
* 推送是否启动false、true
*/
private String igexinEnabled;
/**
* APPID
*/
private String igexinAppid;
/**
* APPKEY
*/
private String igexinAppkey;
/**
* MASTERSECRET
*/
private String igexinMastersecret;
private String appUpdateContent;
private String appVersion;
/**
* pc端服务器域名
*/
private String frontDomain;
/**
* app端服务器域名
*/
private String appDomain;
/**
* 服务器域名
*/
private String apiDomain;
/**
* 工作流域名
*/
private String flowDomain;
/**
* 检查PDF文件安全
*/
private boolean checkFilePdf;
/**
* -------------跨域配置-----------
*/
// @Value("${config.Origins}")
// private String origins;
// @Value("${config.Methods}")
// private String methods;
/**
* -------------是否开启测试环境admin账户可以无限登陆并且无法修改密码-----------
*/
private String testVersion;
/**
* -------------uniPush在线-----------
*/
private String appPushUrl;
public String getMultiTenancyOfficialLoginCodeUrl() {
if (multiTenancyOfficialLoginCodeUrl == null) {
if (StringUtil.isNotEmpty(multiTenancyUrl)) {
UrlBuilder urlBuilder1 = UrlBuilder.of(multiTenancyUrl);
multiTenancyOfficialLoginCodeUrl = String.format("%s://%s:%s/api/Saas/Tenant/LoginSmsCodeCheck/",
urlBuilder1.getSchemeWithDefault(), urlBuilder1.getHost(), urlBuilder1.getPortWithDefault());
} else {
multiTenancyOfficialLoginCodeUrl = "";
}
}
return multiTenancyOfficialLoginCodeUrl;
}
public String getMultiTenancyOfficialResetCodeUrl() {
if (multiTenancyOfficialResetCodeUrl == null) {
if (StringUtil.isNotEmpty(multiTenancyUrl)) {
UrlBuilder urlBuilder1 = UrlBuilder.of(multiTenancyUrl);
multiTenancyOfficialResetCodeUrl = String.format(
"%s://%s:%s/api/Saas/Tenant/ResetPasswordSmsCodeCheck/", urlBuilder1.getSchemeWithDefault(),
urlBuilder1.getHost(), urlBuilder1.getPortWithDefault());
} else {
multiTenancyOfficialResetCodeUrl = "";
}
}
return multiTenancyOfficialResetCodeUrl;
}
public String getServiceDirectoryPath() {
String folder = StringUtil.isNotEmpty(serviceDirectoryPath) ? serviceDirectoryPath
: ConfigConst.CODE_TEMP_FOLDER;
return getXssPath(folder + "/");
}
public String getDataBackupFilePath() {
String folder = StringUtil.isNotEmpty(dataBackupFilePath) ? dataBackupFilePath : ConfigConst.DATA_BACKUP_FOLDER;
return getXssPath(folder + "/");
}
public String getTemporaryFilePath() {
String folder = StringUtil.isNotEmpty(temporaryFilePath) ? temporaryFilePath : ConfigConst.TEMPORARY_FOLDER;
return getXssPath(folder + "/");
}
public String getSystemFilePath() {
String folder = StringUtil.isNotEmpty(systemFilePath) ? systemFilePath : ConfigConst.SYSTEM_FOLDER;
return getXssPath(folder + "/");
}
public String getTemplateFilePath() {
String folder = StringUtil.isNotEmpty(templateFilePath) ? templateFilePath : ConfigConst.TEMPLATE_FOLDER;
return getXssPath(folder + "/");
}
public String getTemplateCodePath() {
String folder = StringUtil.isNotEmpty(templateCodePath) ? templateCodePath : ConfigConst.TEMPLATE_CODE_FOLDER;
return getXssPath(folder + "/");
}
public String getTemplateCodePathVue3() {
String folder = StringUtil.isNotEmpty(templateCodePathVue3) ? templateCodePathVue3
: ConfigConst.TEMPLATEVUE3_CODE_FOLDER;
return getXssPath(folder + "/");
}
public String getEmailFilePath() {
String folder = StringUtil.isNotEmpty(emailFilePath) ? emailFilePath : ConfigConst.EMAIL_FOLDER;
return getXssPath(folder + "/");
}
public String getDocumentPreviewPath() {
String folder = StringUtil.isNotEmpty(documentPreviewPath) ? documentPreviewPath
: ConfigConst.DOCUMENT_PREVIEW_FOLDER;
return getXssPath(folder + "/");
}
public String getUserAvatarFilePath() {
String folder = StringUtil.isNotEmpty(userAvatarFilePath) ? userAvatarFilePath : ConfigConst.USER_AVATAR_FOLDER;
return getXssPath(folder + "/");
}
public String getImContentFilePath() {
String folder = StringUtil.isNotEmpty(imContentFilePath) ? imContentFilePath : ConfigConst.IM_CONTENT_FOLDER;
return getXssPath(folder + "/");
}
public String getDocumentFilePath() {
String folder = StringUtil.isNotEmpty(documentFilePath) ? documentFilePath : ConfigConst.DOCUMENT_FOLDER;
return getXssPath(folder + "/");
}
public String getWebAnnexFilePath() {
String folder = StringUtil.isNotEmpty(webAnnexFilePath) ? webAnnexFilePath : ConfigConst.WEB_ANNEX_FOLDER;
return getXssPath(folder + "/");
}
public String getBiVisualPath() {
String folder = StringUtil.isNotEmpty(biVisualPath) ? biVisualPath : ConfigConst.BI_VISUAL_FOLDER;
return getXssPath(folder + "/");
}
public String getBaseLanguagePath() {
String folder = StringUtil.isNotEmpty(baseLanguagePath) ? baseLanguagePath : ConfigConst.BASE_LANGUAGE;
return getXssPath(folder + "/");
}
private String getXssPath(String path) {
String xssPath = XSSEscape.escapePath(path);
return xssPath;
}
public void setMultiTenantIgnoreTable(List<String> multiTenantIgnoreTable) {
initMultiTenantIgnoreTable();
this.multiTenantIgnoreTable.addAll(multiTenantIgnoreTable);
// 全部转小写, 对比时也转小写
this.multiTenantIgnoreTable = this.multiTenantIgnoreTable.stream().map(String::toLowerCase)
.collect(Collectors.toList());
}
public List<String> getMultiTenantIgnoreTable() {
return new ArrayList<>(this.multiTenantIgnoreTable);
}
private List<String> initMultiTenantIgnoreTable() {
List<String> multiTenantIgnoreTable = this.multiTenantIgnoreTable;
if (multiTenantIgnoreTable == null) {
multiTenantIgnoreTable = new ArrayList<>();
} else {
multiTenantIgnoreTable.clear();
}
multiTenantIgnoreTable.add("dual");
return multiTenantIgnoreTable;
}
}

View File

@@ -0,0 +1,75 @@
package com.yunzhupaas.config;
import cn.hutool.http.useragent.*;
import com.yunzhupaas.i18n.config.I18nProperties;
import com.yunzhupaas.properties.GatewayWhite;
import com.yunzhupaas.properties.MvcSecurityProperties;
import com.yunzhupaas.properties.SecurityProperties;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration(proxyBeanMethods = false)
public class CoreAutoConfiguration implements InitializingBean {
@Bean
@ConditionalOnMissingBean
@ConfigurationProperties(prefix = GatewayWhite.PREFIX)
public GatewayWhite getGateWhite(){
return new GatewayWhite();
}
@Bean
@ConditionalOnMissingBean
@ConfigurationProperties(prefix = SecurityProperties.PREFIX)
public SecurityProperties getSecurityProperties(){
return new SecurityProperties();
}
@Bean
@ConditionalOnMissingBean
@ConfigurationProperties(prefix = ConfigValueUtil.PREFIX)
public ConfigValueUtil getConfigValueUtil(){
return new ConfigValueUtil();
}
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.messages")
public I18nProperties getI18nProperties(){
return new I18nProperties();
}
@Bean
@ConditionalOnMissingBean
@ConfigurationProperties(prefix = MvcSecurityProperties.PREFIX)
public MvcSecurityProperties getCorsProperties(){
return new MvcSecurityProperties();
}
@Bean
public ApplicationStartErrorCheck getApplicationStartupErrorCheck(){
return new ApplicationStartErrorCheck();
}
@Override
public void afterPropertiesSet() {
// UserAgent
initUserAgent();
}
private void initUserAgent(){
// Harmony 鸿蒙OS
OS.addCustomOs("OpenHarmony", "OpenHarmony", "OpenHarmony\\s+(\\d+([._]\\d+)*)");
// 鸿蒙OS移动端
Platform platform = new Platform("OpenHarmony", "Phone;\\s*OpenHarmony\\s*");
Platform.mobilePlatforms.add(platform);
Platform.platforms.add(platform);
Browser.browers.add(0, new Browser("OpenHarmony", "Phone;\\s*OpenHarmony.*ArkWeb", "ArkWeb\\/([\\d\\w\\.\\-]+)"));
}
}

View File

@@ -0,0 +1,87 @@
package com.yunzhupaas.constant;
/**
* 配置静态参数
*
* @author 云筑产品开发平台组
* @version V3.2.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/12/15
*/
public class ConfigConst {
/**
* 前端附件文件夹
*/
public final static String WEB_ANNEX_FOLDER = "WebAnnexFile";
/**
* 临时文件夹
*/
public final static String TEMPORARY_FOLDER = "TemporaryFile";
/**
* 系统文件夹
*/
public final static String SYSTEM_FOLDER = "SystemFile";
/**
* 文件模板文件夹
*/
public final static String TEMPLATE_FOLDER = "TemplateFile";
/**
* 邮件文件夹
*/
public final static String EMAIL_FOLDER = "EmailFile";
/**
* 文档管理文件夹
*/
public final static String DOCUMENT_FOLDER = "DocumentFile";
/**
* 文档预览文件夹
*/
public final static String DOCUMENT_PREVIEW_FOLDER = "DocumentPreview";
/**
* 用户头像文件夹
*/
public final static String USER_AVATAR_FOLDER = "UserAvatar";
/**
* IM聊天图片+语音存储文件夹
*/
public final static String IM_CONTENT_FOLDER = "IMContentFile";
/**
* 代码模板文件夹
*/
public final static String TEMPLATE_CODE_FOLDER = "TemplateCode";
/**
* vue3代码模板文件夹
*/
public final static String TEMPLATEVUE3_CODE_FOLDER = "TemplateCodeVue3";
/**
* 大屏图片文件夹
*/
public final static String BI_VISUAL_FOLDER = "BiVisualPath";
/**
* 数据库备份文件夹
*/
public final static String DATA_BACKUP_FOLDER = "DataBackupFile";
/**
* 前端模板文件夹
*/
public final static String CODE_TEMP_FOLDER = "CodeTemp";
/**
* 多语言文件夹
*/
public final static String BASE_LANGUAGE = "Language";
}

View File

@@ -0,0 +1,88 @@
package com.yunzhupaas.constant;
/**
* 接口数据配置系统变量
*
* @author 云筑产品开发平台组
* @version V3.4.2
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024/6、29
*/
public class DataInterfaceVarConst {
/**
* 当前用户
*/
public static final String USER = "@userId";
/**
* 当前用户及下属
*/
public static final String USERANDSUB = "@userAndSubordinates";
/**
* 当前组织
*/
public static final String ORG = "@organizeId";
/**
* 当前组织及子组织
*/
public static final String ORGANDSUB = "@organizationAndSuborganization";
/**
* 当前分管组织
*/
public static final String CHARORG = "@branchManageOrganize";
/**
* 页行数
*/
public static final String PAGESIZE = "@pageSize";
/**
* 关键字
*/
public static final String KEYWORD = "@keyword";
/**
* 当前页
*/
public static final String CURRENTPAGE = "@currentPage";
/**
* 条数
*/
public static final String OFFSETSIZE = "@offsetSize";
/**
* 当前分管组织及子组织
*/
public static final String SHOWKEY = "@showKey";
/**
* 当前分管组织及子组织
*/
public static final String SHOWVALUE = "@showValue";
/**
* 生成雪花id
*/
public static final String ID = "@snowFlakeID";
/**
* 每次生成新的雪花id
*/
public static final String ID_LOT = "@lotSnowID";
/**
* 表单id
*/
public static final String FORM_ID = "@formId";
/**
* 当前岗位
*/
public static final String POSITIONID = "@positionId";
/**
* 当前部门
*/
public static final String DEPID = "@depId";
/**
* 当前部门及下级部门
*/
public static final String DEPANDSUBORDINATES = "@depAndSubordinates";
/**
* 当前时间
*/
public static final String CURRENTTIME = "@currentTime";
}

View File

@@ -0,0 +1,33 @@
package com.yunzhupaas.constant;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 数据库敏感词
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-01-12
*/
@Data
public class DbSensitiveConstant {
/**
* 数据库敏感词
* INSERT,DELETE,UPDATE 不为敏感字
*/
public static final String SENSITIVE = "CREATE,UNIQUE,CHECK,DEFAULT,DROP,INDEX,ALTER,TABLE,VIEW";
/**
* 数据库敏感词
* INSERT,DELETE,UPDATE 不为敏感字
*/
public static final String PRINT_SENSITIVE = SENSITIVE + ",INSERT,DELETE,UPDATE";
/**
* 文件路径敏感词
*/
public static final String FILE_SENSITIVE = "<,>,/,\\\\,:,|";
}

View File

@@ -0,0 +1,36 @@
package com.yunzhupaas.constant;
import java.util.ArrayList;
import java.util.List;
/**
* 数据集参数类型常量
*
* @author 云筑产品开发平台组
* @version v5.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/9/13 16:15:14
*/
public class DsKeyConst {
public static final String TEXT = "text";
public static final String DOUBLE = "double";
public static final String BIGINT = "bigint";
public static final String DATE = "date";
public static final String TIME = "time";
public static final List<String> DateSelect = new ArrayList<String>() {
{
add(DATE);
add(TIME);
}
};
public static final List<String> BetweenSelect = new ArrayList<String>() {
{
add(DATE);
add(TIME);
add(BIGINT);
add(DOUBLE);
}
};
}

View File

@@ -0,0 +1,11 @@
package com.yunzhupaas.constant;
/**
* 事件常量
*/
public class EventConst {
public static final String EVENT_USER_LOGIN = "user_login";
public static final String EVENT_INIT_LOGIN_PERMISSION = "init_login_permission";
}

View File

@@ -0,0 +1,96 @@
package com.yunzhupaas.constant;
/**
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:51
*/
public class FileTypeConstant {
/**
* 用户头像存储路径
*/
public static final String USERAVATAR = "useravatar";
/**
* 邮件文件存储路径
*/
public static final String MAIL = "mail";
/**
* IM聊天图片+语音存储路径
*/
public static final String IM = "im";
/**
*临时文件存储路径
*/
public static final String WORKFLOW="workflow";
/**
*前端附件文件目录
*/
public static final String ANNEX="annex";
public static final String ANNEXPIC="annexpic";
/**
*数据库备份文件路径
*/
public static final String DATABACKUP="dataBackup";
/**
*文档管理存储路径
*/
public static final String DOCUMENT="document";
/**
*临时文件存储路径
*/
public static final String TEMPORARY="temporary";
/**
*允许上传文件类型
*/
public static final String ALLOWUPLOADFILETYPE="allowuploadfiletype";
/**
*文件在线预览存储pdf
*/
public static final String DOCUMENTPREVIEWPATH="preview";
/**
*文件模板存储路径
*/
public static final String TEMPLATEFILE="templatefile";
/**
*前端文件目录
*/
public static final String SERVICEDIRECTORY="servicedirectory";
/**
*后端文件目录
*/
public static final String WEBDIRECTORY="webdirectory";
/**
* 代码生成器生成位置
*/
public static final String CODETEMP = "codetemp";
/**
* 导出
*/
public static final String EXPORT = "export";
/**
* 文件预览
*/
public static final String DOCUMENTPREVIEW = "documentpreview";
/**
* 大屏路径
*/
public static final String BIVISUALPATH = "bivisualpath";
/**
* 初始化模板
*/
public static final String TEMPLATECODEPATH = "templatecodepath";
/**
* 报表路径
*/
public static final String REPORTPATH = "reportfile";
/**
* 文件zip打包下载临时文件路径
*/
public static final String FILEZIPDOWNTEMPPATH = "filezipdownloadtemppath";
}

View File

@@ -0,0 +1,380 @@
package com.yunzhupaas.constant;
import com.yunzhupaas.util.StringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author 云筑产品开发平台组
* @version V3.5.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024/5/31
*/
public class GenerateConstant {
/**
* 作者
*/
public static final String AUTHOR = "云筑产品开发平台组";
/**
* 版本
*/
public static final String VERSION = "V5.2.0";
/**
* 版权
*/
public static final String COPYRIGHT = "深圳市乐程软件有限公司http://www.szlecheng.cn";
/**
* 描述
*/
public static final String DESCRIPTION = "";
/**
* 文件本地服务器标识
*/
public static final String LOCAL = "local";
/**
* 系统配置信息key
*/
public static final String SYSCONFIG = "SysConfig";
// 文件名前缀
/**
* 实体后缀
*/
public static final String ENTITY = "Entity";
/**
* Mapper XML后缀
*/
public static final String MAPPER_XML = "Mapper";
/**
* Mapper后缀
*/
public static final String MAPPER = "Mapper";
/**
* Service后缀
*/
public static final String SERVICE = "Service";
/**
* SERVICEIMPL后缀
*/
public static final String SERVICEIMPL = "ServiceImpl";
/**
* controller后缀
*/
public static final String CONTROLLER = "Controller";
/**
* 包名
*/
public static final String PACKAGE_NAME = "com.yunzhupaas";
/**
* 系统关键字
*/
public static final List<String> SYS_KEYWORD = Arrays.asList("tenantid", "id", "foreignid", "flowid", "flowtaskid",
"deleteuserid", "deletetime", "deletemark",
"version", "tenant_id", "foreign_id", "flow_id", "flow_task_id", "delete_user_id", "delete_time",
"delete_mark", "f_tenant_id", "f_id", "f_foreign_id",
"f_flow_id", "f_flow_task_id", "f_delete_user_id", "f_delete_time", "f_delete_mark", "f_version");
/**
* JAVA关键字
*/
public static final List<String> JAVA_KEYWORD = Arrays.asList("abstract", "boolean", "break", "byte", "catch",
"char", "class", "continue", "default", "do", "double",
"else", "extends", "final", "finally", "float", "for", "if", "implements", "import", "instanceof", "int",
"interface", "long", "native", "new", "null",
"package", "private", "protected", "public", "short", "static", "super", "switch", "synchronized", "this",
"throw", "throws", "transient", "try", "void",
"volatile", "while");
/**
* 数据库关键字
*/
public static final List<String> SQL_KEYWORD = Arrays.asList("abort", "abs", "absent", "absolute", "abstract",
"access", "accessed", "accessible", "according", "account", "across", "action", "activate", "ada", "add",
"admin", "administer", "administrator", "advanced", "advise", "advisor", "after", "against", "aggregate",
"algorithm", "alias", "all", "all_rows", "allocate", "allow", "allow_datetime", "allow_ip", "also", "alter",
"always", "analyse", "analyze", "ancillary", "and", "and_equal", "antijoin", "any", "append", "apply",
"apr", "archive", "archivedir", "archivelog", "archivestyle", "are", "array", "array_agg",
"array_max_cardinality", "arraylen", "as", "asc", "ascii", "asensitive", "asin", "assertion", "assign",
"assignment", "associate", "asymmetric", "asynchronous", "at", "atach", "atan", "atomic", "attach",
"attribute", "attributes", "audit", "aug", "authenticated", "authentication", "authid", "authorization",
"auto", "auto_increment", "autoallocate", "autoextend", "autoextend_size", "automatic",
"autonomous_transaction", "availability", "avg", "avg_row_length", "backed", "backup", "backupdir",
"backupinfo", "backupset", "backward", "badfile", "bakfile", "base", "base64", "batch", "become", "before",
"begin", "begin_frame", "begin_partition", "behalf", "bernoulli", "between", "bfile", "bigdatediff",
"bigfile", "bigint", "binary", "binary_double", "binary_double_infinity", "binary_double_nan",
"binary_float", "binary_float_infinity", "binary_float_nan", "binding", "binlog", "bit", "bit_length",
"bitmap", "bits", "bitvar", "blob", "block", "block_range", "blocked", "blocks", "blocksize", "body", "bom",
"bool", "boolean", "both", "bound", "branch", "breadth", "break", "broadcast", "browse", "bstring", "btree",
"buffer", "buffer_cache", "buffer_pool", "build", "bulk", "by", "byday", "byhour", "byminute", "bymonth",
"bymonthday", "bypass_recursive_check", "bypass_ujvc", "bysecond", "byte", "byweekno", "byyearday", "cache",
"cache_cb", "cache_instances", "cache_temp_table", "calculate", "call", "called", "cancel", "cardinality",
"cascade", "cascaded", "case", "cast", "catalog", "catalog_name", "catch", "category", "ceil", "ceiling",
"certificate", "cfile", "chain", "chained", "chaining", "change", "changed", "channel", "char", "char_cs",
"char_length", "character", "character_length", "character_set_catalog", "character_set_name",
"character_set_schema", "characteristics", "characters", "charset", "check", "checked", "checkpoint",
"checksum", "child", "choose", "chunk", "cipher", "civ_gb", "class", "class_origin", "classifies", "clear",
"client", "clob", "clone", "close", "close_cached_open_cursors", "cluster", "clusterbtr", "clustered",
"clustering_factor", "coalesce", "coarse", "cobol", "code", "collate", "collation", "collation_catalog",
"collation_name", "collation_schema", "collect", "collections_get_refs", "column", "column_format",
"column_name", "column_stats", "column_value", "columns", "command_function", "command_function_code",
"comment", "comments", "commit", "committed", "commitwork", "compact", "compatibility", "compile",
"complete", "completion", "composite_limit", "compress", "compressed", "compression", "compute", "concat",
"concurrent", "concurrently", "condition", "condition_number", "conditional", "configuration", "conflict",
"conforming", "connect", "connect_by_iscycle", "connect_by_isleaf", "connect_by_root", "connect_idle_time",
"connect_time", "connection", "connection_name", "consider", "consistent", "const", "constant",
"constraint", "constraint_catalog", "constraint_name", "constraint_schema", "constraints", "constructor",
"container", "contains", "containstable", "content", "contents", "context", "continue", "control",
"controlfile", "conversion", "convert", "copy", "corr", "corresponding", "corrupt", "corruption", "cos",
"cosh", "cost", "count", "counter", "covar_pop", "covar_samp", "cpu", "cpu_costing", "cpu_per_call",
"cpu_per_session", "create", "create_stored_outlines", "createdb", "createuser", "cross", "crypto", "csv",
"ctlfile", "cube", "cube_gb", "cume_dist", "cumulative", "current", "current_catalog", "current_date",
"current_default_transform_group", "current_path", "current_role", "current_row", "current_schema",
"current_time", "current_timestamp", "current_transform_group_for_type", "current_user", "cursor",
"cursor_name", "cursor_sharing_exact", "cursor_specific_segment", "cycle", "daily", "dangling", "data",
"database", "databases", "datafile", "datafiles", "datalink", "dataobjno", "date", "date_mode", "dateadd",
"datediff", "datepart", "datetime", "datetime_interval_code", "datetime_interval_precision", "day",
"day_hour", "day_microsecond", "day_minute", "day_second", "db", "dba", "dba_recyclebin", "dbcc", "dbfile",
"dbtimezone", "ddl", "ddl_clone", "deallocate", "debug", "dec", "decfloat", "decimal", "declare", "decode",
"decrement", "default", "default_auth", "defaults", "deferrable", "deferred", "define", "defined",
"definer", "degree", "delay", "delay_key_write", "delayed", "delete", "deleting", "delimited", "delimiter",
"delimiters", "delta", "demand", "dense_rank", "deny", "depends", "depth", "deref", "deref_no_rewrite",
"derived", "des_key_file", "desc", "describe", "descriptor", "destroy", "destructor", "detach", "detached",
"determines", "deterministic", "device", "diagnostics", "dictionary", "dimension", "directory", "disable",
"disassociate", "discard", "disconnect", "disk", "diskgroup", "disks", "diskspace", "dismount", "dispatch",
"distinct", "distinctrow", "distinguished", "distributed", "div", "dlnewcopy", "dlpreviouscopy",
"dlurlcomplete", "dlurlcompleteonly", "dlurlcompletewrite", "dlurlpath", "dlurlpathonly", "dlurlpathwrite",
"dlurlscheme", "dlurlserver", "dlvalue", "dml", "dml_update", "do", "document", "domain",
"domain_index_no_sort", "domain_index_sort", "double", "down", "downgrade", "driving_site", "drop", "dual",
"dump", "dumpfile", "duplicate", "dynamic", "dynamic_function", "dynamic_function_code", "dynamic_sampling",
"dynamic_sampling_est_cdn", "each", "editionable", "element", "else", "elseif", "elsif", "empty", "enable",
"enclosed", "encoding", "encrypt", "encrypted", "encryption", "end", "end_frame", "end_partition",
"end-exec", "ends", "enforce", "enforced", "engine", "engines", "entry", "enum", "equ", "equals", "errlvl",
"error", "error_on_overlap_time", "errors", "escape", "escaped", "estimate", "event", "eventinfo", "events",
"every", "except", "exception", "exception_init", "exceptions", "exchange", "exclude", "excluding",
"exclusive", "exec", "execute", "exempt", "existing", "exists", "exit", "exp", "expand_gset_to_union",
"expansion", "expire", "explain", "explosion", "export", "expr_corr_check", "expression", "extend",
"extended", "extends", "extension", "extent", "extent_size", "extents", "extern", "external", "externally",
"extract", "fact", "failed", "failed_login_attemps", "failed_login_attempts", "failgroup", "family", "fast",
"faults", "fbtscan", "feb", "fetch", "fic_civ", "fic_piv", "fields", "file", "file_block_size", "filegroup",
"filesize", "fillfactor", "filter", "final", "finally", "fine", "finish", "first", "first_rows",
"first_value", "fixed", "flag", "flagger", "flashback", "float", "float4", "float8", "flob", "floor",
"flush", "following", "follows", "for", "forall", "force", "force_xml_query_rewrite", "foreign",
"foreign key", "format", "fortran", "forward", "found", "frame_row", "free", "freelist", "freelists",
"freepools", "freetext", "freetexttable", "freeze", "freq", "frequence", "fresh", "fri", "from", "fs",
"fulfill", "full", "full join", "fulltext", "fulltexttable", "fully", "function", "functions", "fusion",
"gather_plan_statistics", "gby_conc_rollup", "general", "generated", "geometry", "geometrycollection",
"get", "get_format", "gight", "global", "global_name", "global_topic_enabled", "globally", "go", "goto",
"grant", "granted", "grants", "great", "greatest", "group", "group by", "group_by", "group_replication",
"grouping", "groups", "guarantee", "guaranteed", "guard", "handler", "hash", "hash_aj", "hash_sj",
"hashkeys", "hashpartmap", "having", "header", "heap", "help", "hex", "hextoraw", "hierarchy", "high",
"high_priority", "hintset_begin", "hintset_end", "hold", "holdlock", "host", "hosts", "hour",
"hour_microsecond", "hour_minute", "hour_second", "hourly", "huge", "hwm_brokered", "id", "identified",
"identifier", "identity", "identity_insert", "identitycol", "idgenerators", "idle_time", "if", "ifnull",
"ignore", "ignore_on_clause", "ignore_optim_embedded_hints", "ignore_row_on_dupkey_index",
"ignore_server_ids", "ignore_where_clause", "ilike", "image", "immediate", "immediately", "immutable",
"implementation", "implicit", "import", "in", "in_memory_metadata", "include", "include_version",
"including", "increase", "increment", "incremental", "indent", "index", "index_asc", "index_combine",
"index_desc", "index_ffs", "index_filter", "index_join", "index_rows", "index_rrs", "index_scan",
"index_skip_scan", "index_ss", "index_ss_asc", "index_ss_desc", "index_stats", "indexed", "indexes",
"indextype", "indextypes", "indicator", "indices", "infile", "infinite", "informational", "inherit",
"inherits", "initial", "initial_size", "initialize", "initialized", "initially", "initrans", "inline",
"inner", "inner join", "innerid", "inout", "input", "insensitive", "insert", "insert_method", "inserting",
"install", "instance", "instances", "instantiable", "instantly", "instead", "int", "int1", "int2", "int3",
"int4", "int8", "integer", "integrity", "intent", "intermediate", "internal_convert", "internal_use",
"interpreted", "intersect", "intersection", "interval", "into", "invalidate", "invisible", "invoker", "io",
"io_after_gtids", "io_before_gtids", "io_thread", "ipc", "is", "isnull", "isolation", "isolation_level",
"issuer", "iterate", "iteration_number", "jan", "java", "job", "join", "json", "json_array",
"json_arrayagg", "json_exists", "json_object", "json_objectagg", "json_query", "json_table",
"json_table_primitive", "json_value", "jul", "jun", "keep", "kerberos", "key", "key_block_size",
"key_length", "key_member", "key_type", "keyfile", "keys", "keysize", "kill", "label", "lag", "language",
"large", "last", "last_value", "lateral", "lax", "layer", "ldap_reg_sync_interval", "ldap_registration",
"ldap_registration_enabled", "lead", "leading", "leakproof", "least", "leave", "leaves", "left",
"left join", "length", "less", "level", "levels", "lexer", "library", "like", "like_expand", "like_regex",
"like2", "like4", "likec", "limit", "linear", "lineno", "lines", "linestring", "link", "list", "listagg",
"listen", "ln", "lnnvl", "load", "lob", "local", "local_indexes", "local_object", "locally", "localtime",
"localtimestamp", "location", "locator", "lock", "locked", "locks", "log", "log10", "logfile", "logged",
"logging", "logical", "logical_reads_per_call", "logical_reads_per_session", "login", "logoff", "logon",
"logout", "logs", "long", "longblob", "longtext", "longvarbinary", "longvarchar", "loop", "low_priority",
"lower", "lsn", "main", "manage", "managed", "management", "manual", "map", "mapped", "mapping", "mar",
"master", "master_auto_position", "master_bind", "master_connect_retry", "master_delay",
"master_heartbeat_period", "master_host", "master_log_file", "master_log_pos", "master_password",
"master_port", "master_retry_count", "master_server_id", "master_ssl", "master_ssl_ca", "master_ssl_capath",
"master_ssl_cert", "master_ssl_cipher", "master_ssl_crl", "master_ssl_crlpath", "master_ssl_key",
"master_ssl_verify_server_cert", "master_tls_version", "master_user", "match", "match_number",
"match_recognize", "matched", "matches", "materialize", "materialized", "max", "max_connections_per_hour",
"max_queries_per_hour", "max_rows", "max_run_duration", "max_size", "max_statement_time",
"max_updates_per_hour", "max_user_connections", "maxarchlogs", "maxdatafiles", "maxextents", "maximize",
"maxinstances", "maxlogfiles", "maxloghistory", "maxlogmembers", "maxpiecesize", "maxsize", "maxtrans",
"maxvalue", "may", "measures", "medium", "mediumblob", "mediumint", "mediumtext", "mem_space", "member",
"memory", "merge", "merge_aj", "merge_const_on", "merge_sj", "message_length", "message_octet_length",
"message_text", "method", "micro", "microsecond", "middleint", "migrate", "min", "min_rows", "minextents",
"minimize", "minimum", "minus", "minute", "minute_microsecond", "minute_second", "minutely", "minvalue",
"mirror", "mlslabel", "mod", "mode", "model", "model_dontverify_uniqueness", "model_min_analysis",
"model_no_analysis", "model_pby", "model_push_ref", "modifies", "modify", "module", "mon", "money",
"monitoring", "month", "monthly", "more", "mount", "move", "movement", "multilinestring", "multipoint",
"multipolygon", "multiset", "mumps", "mutex", "mv_merge", "mysql_errno", "name", "named", "names",
"namespace", "nan", "national", "native", "natural", "nav", "nchar", "nchar_cs", "ncharacter", "nclob",
"ndb", "ndbcluster", "needed", "nested", "nested_table_fast_insert", "nested_table_get_refs",
"nested_table_id", "nested_table_set_refs", "nested_table_set_setid", "nesting", "network", "never", "new",
"next", "nfc", "nfd", "nfkc", "nfkd", "nil", "nl_aj", "nl_sj", "nls_calendar", "nls_characterset",
"nls_comp", "nls_currency", "nls_date_format", "nls_date_language", "nls_iso_currency", "nls_lang",
"nls_language", "nls_length_semantics", "nls_nchar_conv_excp", "nls_numeric_characters", "nls_sort",
"nls_special_chars", "nls_territory", "no", "no_access", "no_basetable_multimv_rewrite", "no_buffer",
"no_cpu_costing", "no_expand", "no_expand_gset_to_union", "no_fact", "no_filtering", "no_index",
"no_index_ffs", "no_index_ss", "no_merge", "no_model_push_ref", "no_monitoring", "no_multimv_rewrite",
"no_order_rollups", "no_parallel", "no_parallel_index", "no_partial_commit", "no_prune_gsets",
"no_push_pred", "no_push_subq", "no_qkn_buff", "no_query_transformation", "no_ref_cascade", "no_rewrite",
"no_semijoin", "no_set_to_join", "no_star_transformation", "no_stats_gsets", "no_swap_join_inputs",
"no_trigger", "no_unnest", "no_use_hash", "no_use_merge", "no_use_nl", "no_wait", "no_write_to_binlog",
"no_xml_query_rewrite", "noappend", "noarchivelog", "noaudit", "nobranch", "nocache", "nocheck",
"nocompress", "nocopy", "nocpu_costing", "nocycle", "node", "nodegroup", "nodelay", "noforce",
"noguarantee", "nologging", "nomapping", "nomaxvalue", "nominimize", "nominvalue", "nomonitoring",
"nonblocking", "nonclustered", "none", "noneditionable", "noorder", "nooverride", "noparallel",
"noparallel_index", "norely", "norepair", "noresetlogs", "noreverse", "norewrite", "normal", "normalize",
"normalized", "norowdependencies", "nosegment", "nosort", "nostrict", "noswitch", "not",
"not_allow_datetime", "not_allow_ip", "nothing", "notify", "notnull", "nov", "novalidate", "nowait",
"nth_value", "ntile", "null", "nullable", "nullif", "nulls", "number", "numeric", "nvarchar", "nvarchar2",
"object", "objno", "objno_reuse", "occurrences_regex", "oct", "octet_length", "octets", "of", "off",
"offline", "offset", "offsets", "oid", "oidindex", "oids", "old", "old_password", "omit", "on", "once",
"one", "online", "only", "opaque", "opaque_transform", "opaque_xcanonical", "opcode", "open",
"opendatasource", "openquery", "openrowset", "openxml", "operation", "operator", "opt_estimate", "optimal",
"optimize", "optimizer_costs", "optimizer_features_enable", "optimizer_goal", "option", "optionally",
"options", "or", "or_expand", "ora_rowscn", "order", "order by", "ordered", "ordered_predicates",
"ordering", "ordinality", "organization", "others", "out", "out_of_line", "outer", "outfile", "outline",
"output", "over", "overflow", "overflow_nomove", "overlaps", "overlay", "override", "overriding", "own",
"owned", "owner", "pack_keys", "package", "packages", "pad", "page", "parallel", "parallel_enable",
"parallel_index", "parameter", "parameter_mode", "parameter_name", "parameter_ordinal_position",
"parameter_specific_catalog", "parameter_specific_name", "parameter_specific_schema", "parameters",
"parent", "parity", "parms", "parse_gcol_expr", "parser", "partial", "partially", "partition",
"partition_hash", "partition_list", "partition_range", "partitioning", "partitions", "pascal", "pass",
"passing", "passthrough", "password", "password_grace_time", "password_life_time", "password_lock_time",
"password_policy", "password_reuse_max", "password_reuse_time", "password_verify_function", "past", "path",
"pattern", "pctfree", "pctincrease", "pctthreshold", "pctused", "pctversion", "pendant", "per", "percent",
"percent_rank", "percentile_cont", "percentile_disc", "performance", "period", "permanent", "permission",
"permute", "pfile", "phase", "physical", "pipe", "pipelined", "piv_gb", "piv_ssf", "pivot", "placing",
"plan", "plans", "pli", "pls_integer", "plsql_code_type", "plsql_debug", "plsql_optimize_level",
"plsql_warnings", "plugin", "plugin_dir", "plugins", "point", "policy", "polygon", "port", "portion",
"position", "position_regex", "post_transaction", "postfix", "power", "pq_distribute", "pq_map", "pq_nomap",
"pragma", "prebuilt", "precedes", "preceding", "precision", "prefix", "preorder", "prepare", "prepared",
"present", "preserve", "pretty", "primary", "primary key", "print", "prior", "private", "private_sga",
"privilege", "privileges", "proc", "procedural", "procedure", "procedures", "processlist", "profile",
"profiles", "program", "project", "protected", "protection", "proxy", "prune", "ptf", "public",
"publication", "purge", "push_pred", "push_subq", "px_granule", "qb_name", "quarter", "query",
"query_block", "query_rewrite_integrity", "queue", "queue_curr", "queue_rowp", "quick", "quiesce", "quota",
"quote", "quotes", "raid0", "raise", "raiserror", "random", "randomly", "range", "rank", "rapidly", "raw",
"rawtohex", "rba", "read", "read_only", "read_per_call", "read_per_session", "read_write", "readonly",
"reads", "readtext", "real", "reassign", "rebalance", "rebuild", "recheck", "reconfigure", "record",
"records", "records_per_block", "recover", "recoverable", "recovery", "recursive", "recycle", "recyclebin",
"redo_buffer_size", "redofile", "reduced", "redundancy", "redundant", "ref", "ref_cascade_cursor",
"reference", "referenced", "references", "referencing", "refresh", "regexp", "regexp_like", "register",
"regr_avgx", "regr_avgy", "regr_count", "regr_intercept", "regr_r2", "regr_slope", "regr_sxx", "regr_sxy",
"regr_syy", "reindex", "reject", "rekey", "related", "relational", "relative", "relay", "relay_log_file",
"relay_log_pos", "relay_thread", "relaylog", "release", "reload", "rely", "remote_mapped", "remove",
"rename", "reorganize", "repair", "repeat", "repeatable", "replace", "replay", "replica", "replicate",
"replicate_do_db", "replicate_do_table", "replicate_ignore_db", "replicate_ignore_table",
"replicate_rewrite_db", "replicate_wild_do_table", "replicate_wild_ignore_table", "replication", "require",
"required", "requiring", "reset", "resetlogs", "resignal", "resize", "resolve", "resolver", "resource",
"respect", "restart", "restore", "restore_as_intervals", "restrict", "restrict_all_ref_cons",
"restrict_references", "restricted", "result", "result_cache", "resumable", "resume", "retention", "return",
"returned_cardinality", "returned_length", "returned_octet_length", "returned_sqlstate", "returning",
"returns", "reuse", "reverse", "revert", "revoke", "rewrite", "rewrite_or_error", "right", "right join",
"rlike", "role", "roles", "rollback", "rollfile", "rollup", "root", "rotate", "round", "routine",
"routine_catalog", "routine_name", "routine_schema", "routines", "row", "row_count", "row_format",
"row_length", "row_number", "rowcount", "rowdependencies", "rowguidcol", "rowid", "rownum", "rows", "rtree",
"rule", "rules", "running", "salt", "sample", "sat", "save", "save_as_intervals", "savepoint", "sb4",
"sbyte", "scalar", "scale", "scale_rows", "scan", "scan_instances", "schedule", "scheduler", "schema",
"schema_name", "schemas", "scn", "scn_ascending", "scope", "scope_catalog", "scope_name", "scope_schema",
"scroll", "sd_all", "sd_inhibit", "sd_show", "sealed", "search", "second", "second_microsecond", "secondly",
"section", "security", "securityaudit", "seed", "seg_block", "seg_file", "segment", "select", "selective",
"selectivity", "self", "semijoin", "semijoin_driver", "sensitive", "sep", "separator", "sequence",
"sequenced", "sequences", "sequential", "sererr", "serial", "serializable", "server", "server_name",
"servererror", "session", "session_cached_cursors", "session_per_user", "session_user", "sessions_per_user",
"sessiontimezone", "sessiontzname", "set", "set_to_join", "setof", "sets", "settings", "setuser", "severe",
"share", "shared", "shared_pool", "short", "show", "shrink", "shutdown", "siblings", "sid", "signal",
"signed", "similar", "simple", "sin", "since", "single", "singletask", "sinh", "size", "sizeof", "skip",
"skip_ext_optimizer", "skip_unq_unusable_idx", "skip_unusable_indexes", "slave", "slow", "smallfile",
"smallint", "snapshot", "socket", "some", "soname", "sort", "sound", "sounds", "source", "space", "span",
"spatial", "specific", "specific_name", "specification", "specifictype", "speed", "spfile", "split",
"spreadsheet", "sql", "sql_after_gtids", "sql_after_mts_gaps", "sql_before_gtids", "sql_big_result",
"sql_buffer_result", "sql_cache", "sql_calc_found_rows", "sql_no_cache", "sql_small_result", "sql_thread",
"sql_trace", "sql_tsi_day", "sql_tsi_hour", "sql_tsi_minute", "sql_tsi_month", "sql_tsi_quarter",
"sql_tsi_second", "sql_tsi_week", "sql_tsi_year", "sqlca", "sqlcode", "sqlerror", "sqlexception", "sqlldr",
"sqlstate", "sqlwarning", "sqrt", "ssl", "stable", "stacked", "standalone", "standby", "star",
"star_transformation", "start", "starting", "starts", "startup", "stat", "state", "statement",
"statement_id", "static", "statistics", "stats_auto_recalc", "stats_persistent", "stats_sample_pages",
"status", "stddev", "stddev_pop", "stddev_samp", "stdin", "stdout", "stop", "storage", "store", "stored",
"straight_join", "streams", "strict", "string", "strip", "struct", "structure", "style", "subclass_origin",
"subject", "submultiset", "subpartition", "subpartition_rel", "subpartitions", "subscription", "subset",
"substitutable", "substring", "substring_regex", "subtype", "succeeds", "successful", "sum", "summary",
"sun", "super", "supplemental", "support", "suspend", "swap_join_inputs", "swaps", "switch", "switches",
"switchover", "symmetric", "sync", "synchronous", "synonym", "sys_connect_by_path", "sys_dl_cursor",
"sys_fbt_insdel", "sys_op_bitvec", "sys_op_cast", "sys_op_col_present", "sys_op_enforce_not_null$",
"sys_op_mine_value", "sys_op_noexpand", "sys_op_ntcimg$", "sys_parallel_txn", "sys_rid_order", "sysaux",
"sysdate", "sysdba", "sysid", "sysoper", "system", "system_time", "system_user", "systimestamp", "table",
"table_checksum", "table_name", "table_stats", "tables", "tablesample", "tablespace", "tablespace_no",
"tabno", "tan", "tanh", "task", "temp", "tempfile", "template", "temporary", "temptable", "terminate",
"terminated", "test", "text", "textsize", "than", "the", "then", "thread", "through", "throw", "thu",
"ties", "time", "time_zone", "timeout", "timer", "times", "timestamp", "timestampadd", "timestampdiff",
"timezone_abbr", "timezone_hour", "timezone_minute", "timezone_region", "tinyblob", "tinyint", "tinytext",
"tiv_gb", "tiv_ssf", "to", "token", "top", "top_level_count", "toplevel", "trace", "tracing", "tracking",
"trailing", "tran", "transaction", "transaction_active", "transactional", "transactions_committed",
"transactions_rolled_back", "transform", "transforms", "transitional", "translate", "translate_regex",
"translation", "treat", "trigger", "trigger_catalog", "trigger_name", "trigger_schema", "triggers", "trim",
"trim_array", "truncate", "truncsize", "trusted", "trxid", "try", "tsequal", "tue", "tuning", "tx", "type",
"typedef", "typeof", "types", "tz_offset", "ub2", "uba", "uescape", "uid", "uint", "ulong", "unarchived",
"unbound", "unbounded", "uncommitted", "unconditional", "undefined", "under", "undo", "undo_buffer_size",
"undofile", "undrop", "unencrypted", "unicode", "uniform", "uninstall", "union", "unique", "unknown",
"unlimited", "unlink", "unlisten", "unlock", "unlogged", "unmatched", "unnamed", "unnest", "unpacked",
"unpivot", "unprotected", "unquiesce", "unrecoverable", "unsigned", "until", "untyped", "unusable",
"unused", "up", "upd_indexes", "upd_joinindex", "updatable", "update", "updated", "updatetext", "updating",
"upgrade", "upper", "upsert", "uri", "urowid", "usage", "use", "use_anti", "use_concat", "use_frm",
"use_hash", "use_merge", "use_nl", "use_nl_with_index", "use_private_outlines", "use_semi",
"use_stored_outlines", "use_ttt_for_gsets", "use_weak_name_resl", "user", "user_defined",
"user_defined_type_catalog", "user_defined_type_code", "user_defined_type_name", "user_defined_type_schema",
"user_recyclebin", "user_resources", "ushort", "using", "utc_date", "utc_time", "utc_timestamp", "utf16",
"utf32", "utf8", "vacuum", "valid", "validate", "validation", "validator", "value", "value_of", "values",
"var_pop", "var_samp", "varbinary", "varchar", "varchar2", "varcharacter", "variable", "variables",
"variadic", "variance", "varray", "varying", "vector_read", "vector_read_trace", "verbose", "verify",
"version", "versioning", "versions", "versions_endtime", "versions_endtrxid", "versions_operation",
"versions_starttime", "versions_starttrxid", "vertical", "view", "views", "virtual", "visible", "void",
"volatile", "vsize", "wait", "waitfor", "warnings", "wed", "week", "weekly", "weight_string", "wellformed",
"when", "whenever", "where", "while", "whitespace", "width_bucket", "window", "with", "within", "without",
"work", "wrapped", "wrapper", "write", "writetext", "x_dyn_prune", "x509", "xa", "xid", "xml", "xmlagg",
"xmlattributes", "xmlbinary", "xmlcast", "xmlcolattval", "xmlcomment", "xmlconcat", "xmldeclaration",
"xmldocument", "xmlelement", "xmlexists", "xmlforest", "xmliterate", "xmlnamespaces", "xmlparse", "xmlpi",
"xmlquery", "xmlroot", "xmlschema", "xmlserialize", "xmltable", "xmltext", "xmltype", "xmlvalidate", "xor",
"year", "year_month", "yearly", "yes", "yunzhupaasfill", "zone", "false", "true");
/**
* 系统,语言,数据关键字
*/
public static final List<String> getAllKeyWord() {
List<String> allKeyWord = new ArrayList<>();
allKeyWord.addAll(SYS_KEYWORD);
allKeyWord.addAll(JAVA_KEYWORD);
allKeyWord.addAll(SQL_KEYWORD);
return allKeyWord;
}
/**
* 系统,语言,数据关键字是否包含
*/
public static final boolean containKeyword(String keyword) {
if (StringUtil.isEmpty(keyword)) {
return false;
}
List<String> allKeyWord = getAllKeyWord();
return allKeyWord.contains(keyword.toLowerCase());
}
}

View File

@@ -0,0 +1,33 @@
package com.yunzhupaas.constant;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class GlobalConst {
/**
* 网关、Feign转发后携带原有HOST(网关或者FEIGN转发后HOST不准确)
*/
public static final String HEADER_HOST = "MY_HOST";
/**
* 默认租户字段值
*/
public static final String DEFAULT_TENANT_VALUE = "0";
public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
public static final String DEFAULT_CHARSET_STR = DEFAULT_CHARSET.name();
/**
* 默认语种
*/
public static final String DEFAULT_LANGUAGE = "zh-CN";
/**
* 扫包路径 多个使用封号分割
*/
public static final String PROJECT_SCAN_PACKAGES = "com.yunzhupaas";
}

View File

@@ -0,0 +1,32 @@
package com.yunzhupaas.constant;
/**
* 项目模块应用名称
*/
public class ModuleName {
public static final String SYSTEM_SERVER_NAME = "yunzhupaas-system" ;
public static final String MESSAGE_SERVER_NAME = "yunzhupaas-message" ;
public static final String VUSUALDEV_SERVER_NAME = "yunzhupaas-visualdev" ;
public static final String EXAMPLE_SERVER_NAME = "yunzhupaas-example" ;
public static final String EXTEND_SERVER_NAME = "yunzhupaas-extend" ;
public static final String APP_SERVER_NAME = "yunzhupaas-app" ;
public static final String WORKFLOW_SERVER_NAME = "yunzhupaas-workflow" ;
public static final String FILE_SERVER_NAME = "yunzhupaas-file";
public static final String PERMISSION_SERVER_NAME = "yunzhupaas-permission";
public static final String FORM_SERVER_NAME = "yunzhupaas-flowForm";
public static final String OAUTH_SERVER_NAME = "yunzhupaas-oauth";
public static final String SCHEDULE_SERVER_NAME = "yunzhupaas-scheduletask" ;
}

View File

@@ -0,0 +1,740 @@
package com.yunzhupaas.constant;
import com.yunzhupaas.constant.model.MCode;
/**
* 常用提示信息
*
* @author 云筑产品开发平台组
* @version V3.2.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/12/20
*/
public interface MsgCode {
/**
* 编码和提示语正则提取 MCode\s+[\w\d]+\s+=\s+[\w\d]+[(]"([\w\d]+)"\s*,\s*"(.+)"[)];
*/
/**
* 执行成功SUsuccess
*/
MCode SU000 = MSG("SU000", "Success");
MCode SU001 = MSG("SU001", "新建成功");
MCode SU002 = MSG("SU002", "保存成功");
MCode SU003 = MSG("SU003", "删除成功");
MCode SU004 = MSG("SU004", "更新成功");
MCode SU005 = MSG("SU005", "操作成功");
MCode SU006 = MSG("SU006", "提交成功,请耐心等待");
MCode SU007 = MSG("SU007", "复制成功");
MCode SU008 = MSG("SU008", "停止成功");
MCode SU009 = MSG("SU009", "终止成功");
MCode SU010 = MSG("SU010", "还原成功");
MCode SU011 = MSG("SU011", "发布成功");
MCode SU012 = MSG("SU012", "发送成功");
MCode SU013 = MSG("SU013", "接口修改成功");
MCode SU014 = MSG("SU014", "更新接口状态成功");
MCode SU015 = MSG("SU015", "上传成功");
MCode SU016 = MSG("SU016", "设置成功");
MCode SU017 = MSG("SU017", "验证成功");
MCode SU018 = MSG("SU018", "添加成功");
MCode SU019 = MSG("SU019", "获取成功");
MCode SU020 = MSG("SU020", "回滚成功");
MCode SU021 = MSG("SU021", "移除成功");
MCode SU022 = MSG("SU022", "查询成功");
/**
* 执行失败FAfail
*/
MCode FA001 = MSG("FA001", "数据不存在");
MCode FA002 = MSG("FA002", "更新失败,数据不存在");
MCode FA003 = MSG("FA003", "删除失败,数据不存在");
MCode FA004 = MSG("FA004", "复制失败,数据不存在");
MCode FA005 = MSG("FA005", "发送失败,数据不存在");
MCode FA006 = MSG("FA006", "下载失败,数据不存在");
MCode FA007 = MSG("FA007", "操作失败,数据不存在");
MCode FA008 = MSG("FA008", "停止失败,数据不存在");
MCode FA009 = MSG("FA009", "终止失败,数据不存在");
MCode FA010 = MSG("FA010", "还原失败,数据不存在");
MCode FA011 = MSG("FA011", "发布失败,数据不存在");
MCode FA012 = MSG("FA012", "获取失败,数据不存在");
MCode FA013 = MSG("FA013", "接口修改失败,数据不存在");
MCode FA014 = MSG("FA014", "更新接口状态失败,数据不存在");
MCode FA015 = MSG("FA015", "预览失败,数据不存在");
MCode FA016 = MSG("FA016", "删除失败,该文件夹存在数据");
MCode FA017 = MSG("FA017", "文件格式不正确");
MCode FA018 = MSG("FA018", "文件不存在");
MCode FA019 = MSG("FA019", "已失效");
MCode FA020 = MSG("FA020", "未查到信息");
MCode FA021 = MSG("FA021", "操作失败!您没有权限操作");
MCode FA022 = MSG("FA022", "更新失败!您没有权限操作 (角色只有超级管理员才能够操作)");
MCode FA023 = MSG("FA023", "更新失败!已绑定用户,无法切换组织");
MCode FA024 = MSG("FA024", "删除失败!已绑定用户");
MCode FA025 = MSG("FA025", "该组织内权限为空,组织切换失败!");
MCode FA031 = MSG("FA031", "该组织无本应用权限,切换失败");
MCode FA026 = MSG("FA026", "更新失败,关联组织不存在,请重新登录,或者刷新页面");
MCode FA027 = MSG("FA027", "该系统下菜单为空,系统切换失败");
MCode FA028 = MSG("FA028", "新增数据失败");
MCode FA029 = MSG("FA029", "修改数据失败");
MCode FA030 = MSG("FA030", "更新失败!已绑定用户,无法修改状态");
MCode FA032 = MSG("FA032", "上传文件不能为空");
MCode FA033 = MSG("FA033", "文件上传失败!");
MCode FA034 = MSG("FA034", "非法请求, 缺少认证信息");
MCode FA035 = MSG("FA035", "未获取到租户指定数据源信息");
MCode FA036 = MSG("FA036", "常用数据已存在");
MCode FA037 = MSG("FA037", "接口请求失败");
MCode FA038 = MSG("FA038", "文件存储路径错误");
MCode FA039 = MSG("FA039", "链接已失效");
MCode FA040 = MSG("FA040", "预览失败,请检查文件类型是否规范");
MCode FA041 = MSG("FA041", "预览失败,请重新上传文件");
MCode FA042 = MSG("FA042", "请输入正确的文件格式");
MCode FA043 = MSG("FA043", "存在同名文件!");
MCode FA044 = MSG("FA044", "不存在该文件");
MCode FA045 = MSG("FA045", "删除文件:{0}失败");
MCode FA046 = MSG("FA046", "文件读取失败");
MCode FA047 = MSG("FA047", "未发现文件");
MCode FA048 = MSG("FA048", "微信公众号原始id不能重复");
MCode FA049 = MSG("FA049", "此记录与“消息发送配置”关联引用,不允许被禁用");
MCode FA050 = MSG("FA050", "此记录与“消息发送配置”关联引用,不允许被删除");
MCode FA051 = MSG("FA051", "接口已配置加密, 数据解密失败.");
MCode FA052 = MSG("FA052", "该身份未分配权限");
MCode FA053 = MSG("FA053", "上传失败, 文件中包含不安全内容");
/*======1 短语======*/
MCode FA101 = MSG("FA101", "保存失败");
MCode FA102 = MSG("FA102", "更新失败");
MCode FA103 = MSG("FA103", "删除失败");
MCode FA104 = MSG("FA104", "获取失败");
MCode FA105 = MSG("FA105", "预览失败,请先保存在预览数据");
MCode FA106 = MSG("FA106", "预览失败,单元格配置出现死循环");
MCode FA107 = MSG("FA107", "报表导出报错");
/**
* 重名判断
*/
MCode EXIST001 = MSG("EXIST001", "名称不能重复");
MCode EXIST002 = MSG("EXIST002", "编码不能重复");
MCode EXIST003 = MSG("EXIST003", "模板名已存在");
MCode EXIST004 = MSG("EXIST004", "文件夹名称不能重复");
MCode EXIST005 = MSG("EXIST005", "模板名称超过了限制长度");
MCode EXIST101 = MSG("EXIST101", "名称重复,请重新输入");
MCode EXIST102 = MSG("EXIST102", "编码重复,请重新输入");
MCode EXIST103 = MSG("EXIST103", "不能重复");
/**
* 导入导出IMPimport/export
*/
MCode IMP001 = MSG("IMP001", "导入成功");
MCode IMP002 = MSG("IMP002", "导入失败,文件格式错误");
MCode IMP003 = MSG("IMP003", "导入失败,数据已存在");
MCode IMP004 = MSG("IMP004", "导入失败,数据有误");
MCode IMP005 = MSG("IMP005", "导出失败");
MCode IMP006 = MSG("IMP006", "导入数据格式不正确");
MCode IMP007 = MSG("IMP007", "重复");
MCode IMP008 = MSG("IMP008", "名称");
MCode IMP009 = MSG("IMP009", "编码");
MCode IMP010 = MSG("IMP010", "导入失败,查询不到上级分类");
MCode IMP011 = MSG("IMP011", "请选择导出字段");
/**
* 其他
*/
// 打印模板 (print)
MCode PRI001 = MSG("PRI001", "打印模板不存在");
MCode PRI002 = MSG("PRI002", "数字字典不存在printDev的字典分类");
MCode PRI003 = MSG("PRI003", "第1条SQL语句查询出多条表头信息");
MCode PRI004 = MSG("PRI004", "第1条SQL语句未查出表头信息");
MCode PRI005 = MSG("PRI005", "第{index}条SQL语句");
MCode PRI006 = MSG("PRI006", "已到达该模板复制上限,请复制源模板");
MCode COD001 = MSG("COD001", "集合条件过滤获得目标为空");
MCode PRI007 = MSG("PRI007", "Sql语法错误");
MCode PRI008 = MSG("PRI008", "该报表已删除");
/**
* 复制
*/
MCode COPY001 = MSG("COPY001", "复制名称长度超过了限制长度");
/**
* 登录相关
*/
/*=====0-账号相关====*/
MCode LOG001 = MSG("LOG001", "账户异常");
MCode LOG002 = MSG("LOG002", "注销成功");
MCode LOG004 = MSG("LOG004", "账号异常,请联系管理员修改所属组织信息");
MCode LOG005 = MSG("LOG005", "账号未被激活");
MCode LOG006 = MSG("LOG006", "账号已被禁用");
MCode LOG007 = MSG("LOG007", "账号已被删除");
MCode LOG010 = MSG("LOG010", "此IP未在白名单中");
MCode LOG011 = MSG("LOG011", "登录失败,用户暂未绑定角色");
MCode LOG012 = MSG("LOG012", "账号已被锁定,请联系管理员解除锁定");
/*======1-登录相关======*/
MCode LOG101 = LOG("LOG101", "账号或密码错误");
MCode LOG102 = LOG("LOG102", "账号有误,请重新输入");
MCode LOG103 = LOG("LOG103", "请输入验证码");
MCode LOG104 = LOG("LOG104", "验证码错误");
MCode LOG107 = LOG("LOG107", "验证码已失效");
MCode LOG105 = LOG("LOG105", "连接租户服务失败,请稍后再试");
MCode LOG106 = LOG("LOG106", "短信验证码错误");
MCode LOG108 = MSG("LOG108", "请等待{0}分钟后再进行登录,或联系管理员解除锁定");
MCode LOG109 = LOG("LOG109", "租户登录失败,请用手机验证码登录");
MCode LOG110 = LOG("LOG110", "数据库异常,请联系管理员处理");
MCode LOG111 = LOG("LOG111", "已开启单点登录, 不支持此登录方式");
MCode LOG112 = LOG("LOG112", "不支持此登录方式");
MCode LOG113 = LOG("LOG113", "未设置租户信息");
MCode LOG114 = LOG("LOG114", "租户编码不允许为空");
MCode LOG115 = LOG("LOG115", "租户信息获取失败");
MCode LOG116 = LOG("LOG116", "不支持此验证");
MCode LOG117 = LOG("LOG117", "短信验证码验证失败:{0}");
MCode LOG118 = LOG("LOG118", "租户库名为空");
/*======2-密码修改========*/
MCode LOG201 = LOG("LOG201", "旧密码错误");
MCode LOG202 = LOG("LOG202", "修改成功,请牢记新密码");
MCode LOG203 = LOG("LOG203", "修改失败,账号不存在");
MCode LOG204 = LOG("LOG204", "修改失败,新建密码不能与旧密码一样");
MCode LOG205 = LOG("LOG205", "重置密码成功");
MCode LOG206 = LOG("LOG206", "重置密码失败");
//oauth
MCode OA001 = OA("OA001", "用户登录");
MCode OA002 = OA("OA002", "设备");
MCode OA003 = OA("OA003", "TOKEN");
MCode OA004 = OA("OA004", "用户退出");
MCode OA005 = OA("OA005", "用户踢出");
MCode OA006 = OA("OA006", "用户顶替");
MCode OA007 = OA("OA007", "登录异常");
MCode OA008 = OA("OA008", "登录获取系统配置失败");
MCode OA009 = OA("OA009", "该用户未分配权限");
MCode OA010 = OA("OA010", "仅支持pc端访问,APP端不支持");
MCode OA011 = OA("OA011", "应用不存在");
MCode OA012 = OA("OA012", "当前应用已被禁用");
MCode OA013 = OA("OA013", "登录密码解密失败");
MCode OA014 = OA("OA014", "注销成功");
MCode OA015 = OA("OA015", "登录成功");
MCode OA016 = OA("OA016", "登录票据已失效");
MCode OA017 = OA("OA017", "第三方未绑定账号");
MCode OA018 = OA("OA018", "不允许访问此登录接口");
MCode OA019 = OA("OA019", "账号不存在");
MCode OA020 = OA("OA020", "账户或密码错误,请重新输入");
MCode OA021 = OA("OA021", "验证成功");
MCode OA022 = OA("OA022", "限制会话, 不允许访问系统");
MCode OA023 = OA("OA023", "管理员不能注销");
MCode OA024 = OA("OA024", "登录失败");
MCode OA025 = OA("OA025", "超级管理员");
MCode OA026 = OA("OA026", "普通管理员");
MCode OA027 = OA("OA027", "普通用户");
MCode OA028 = OA("OA028", "未知来源");
//oauth
MCode PS001 = PS("PS001", "此记录与\"{0}\"关联引用,不允许被删除");
MCode PS003 = PS("PS003", "组织");
MCode PS004 = PS("PS004", "岗位");
MCode PS005 = PS("PS005", "用户");
MCode PS006 = PS("PS006", "角色");
MCode PS007 = PS("PS007", "账号不能为空");
MCode PS008 = PS("PS008", "姓名不能为空");
MCode PS009 = PS("PS009", "用户额度已达到上限");
MCode PS010 = PS("PS010", "权限已变更,请重新登录");
MCode PS011 = PS("PS011", "密码已变更,请重新登录");
MCode PS012 = PS("PS012", "类型不能为空");
MCode PS013 = PS("PS013", "当前机构Id不能与父机构Id相同");
MCode PS014 = PS("PS014", "该应用已禁用");
MCode PS015 = PS("PS015", "无法设置当前用户为分级管理员");
MCode PS016 = PS("PS016", "无法设置超管为分级管理员");
MCode PS017 = PS("PS017", "无法设置当前用户操作权限");
MCode PS018 = PS("PS018", "解绑失败");
MCode PS019 = PS("PS019", "第三方登录未配置");
MCode PS020 = PS("PS020", "性别不能为空");
MCode PS021 = PS("PS021", "无法禁用管理员用户");
MCode PS022 = PS("PS022", "管理员只能修改自己,不能修改其他管理员");
MCode PS023 = PS("PS023", "无法修改管理员账户");
MCode PS024 = PS("PS024", "直属主管不能是自己");
MCode PS025 = PS("PS025", "直属主管不能是我的下属用户");
MCode PS026 = PS("PS026", "无法删除管理员账户");
MCode PS027 = PS("PS027", "此用户为某部门主管,无法删除");
MCode PS028 = PS("PS028", "此用户有下属,无法删除");
MCode PS029 = PS("PS029", "无法修改管理员账户状态");
MCode PS030 = PS("PS030", "用户信息已变更,请重新登录");
MCode PS031 = PS("PS031", "该应用已删除");
MCode PS032 = PS("PS032", "该组织无本应用权限,切换失败");
MCode PS033 = PS("PS033", "工作交接成功!");
MCode PS034 = PS("PS034", "工作交接无法转移给管理员");
MCode PS035 = PS("PS035", "工作交接无法转移给本人");
/**
* 数据库
*/
MCode DB001 = DB("DB001", "数据类型编码不符合标准请注意大小写。MySQL , SQLServer , Oracle , DM , KingbaseES , PostgreSQL");
MCode DB002 = DB("DB002", "请检查 1、连接信息 2、网络通信 3、数据库服务启动状态。 详情:{0}");
MCode DB003 = DB("DB003", "通过url找不到对应数据库");
MCode DB004 = DB("DB004", "查询结果集为空。");
MCode DB005 = DB("DB005", "未找到对应数据库类型:{0}({1})");
MCode DB006 = DB("DB006", "未找到对应数据类型转换");
MCode DB007 = DB("DB007", "导入表名存在重复");
MCode DB008 = DB("DB008", "建表数据与当前操作数据库不匹配: {0} -> {1}");
MCode DB009 = DB("DB009", "未找到表信息: {0}");
MCode DB010 = DB("DB010", "数据库{0},未找到此表:{1}");
MCode DB011 = DB("DB011", "联合主键类缺少“{0}”字段值");
MCode DB012 = DB("DB012", "表示对应获取数值失败");
MCode DB013 = DB("DB013", "目前还未支持{0}数据类型:{1}");
MCode DB014 = DB("DB014", "\"{0}\"中字段 \"{1}\" 为主键,不允许数据类型 \"{2}\" ");
MCode DB015 = DB("DB015", "未找到字段SQL语句");
MCode DB016 = DB("DB016", "没有初始字段");
MCode DB017 = DB("DB017", "sql异常{0}");
MCode DB018 = DB("DB018", "请在数据库中添加对应的数据表");
MCode DB019 = DB("DB019", "添加失败");
/*== 系统自带表 DB1 ==*/
MCode DB101 = DB("DB101", "系统自带表,不允许被删除");
MCode DB102 = DB("DB102", "系统自带表,不允许被编辑");
/*== 表已经被使用 DB2 ==*/
MCode DB201 = DB("DB201", "表已经被使用,不允许被删除");
MCode DB202 = DB("DB202", "表已经被使用,不允许被编辑");
/*== 数据库连接问题 ==*/
MCode DB301 = DB("DB301", "数据库连接成功");
MCode DB302 = DB("DB302", "数据库连接失败");
/**
* 工作流相关错误码
*/
MCode WF001 = WF("WF001","审核成功");
MCode WF002 = WF("WF002","退回成功");
MCode WF003 = WF("WF003","转办成功");
MCode WF004 = WF("WF004","加签成功");
MCode WF005 = WF("WF005","当前流程被退回,无法撤回流程");
MCode WF006 = WF("WF006","流程已撤回,不能重复操作");
MCode WF007 = WF("WF007","撤回失败,转向数据无法撤回");
MCode WF008 = WF("WF008","撤回成功");
MCode WF009 = WF("WF009","功能流程不能终止");
MCode WF010 = WF("WF010","指派成功");
MCode WF011 = WF("WF011","批量操作完成");
MCode WF012 = WF("WF012","该流程不能操作");
MCode WF013 = WF("WF013","复活成功");
MCode WF014 = WF("WF014","变更成功");
MCode WF015 = WF("WF015","挂起成功");
MCode WF016 = WF("WF016","恢复成功");
MCode WF017 = WF("WF017","委托人和被委托人相同,委托失败");
MCode WF018 = WF("WF018","操作失败,同一时间内有相同流程的委托");
MCode WF019 = WF("WF019","操作失败,同一时间内有相同流程,不能相互委托");
MCode WF020 = WF("WF020","功能流程不能删除");
MCode WF021 = WF("WF021","不能删除");
MCode WF022 = WF("WF022","催办成功");
MCode WF023 = WF("WF023","未找到催办人");
MCode WF024 = WF("WF024", "该功能已被流程引用,请重新选择关联功能");
MCode WF025 = WF("WF025","启用失败,流程未设计");
MCode WF026 = WF("WF026","启用成功");
MCode WF027 = WF("WF027","禁用成功");
MCode WF028 = WF("WF028","该版本内有工单任务流转,无法删除");
MCode WF029 = WF("WF029","您没有发起该流程的权限");
MCode WF030 = WF("WF030","表单未找到");
MCode WF031 = WF("WF031","已审核完成");
MCode WF032 = WF("WF032","冻结不能操作");
MCode WF033 = WF("WF033","转向节点不存在或配置错误");
MCode WF034 = WF("WF034","转向失败,转向节点未审批");
MCode WF035 = WF("WF035","退回至您的审批,不能再发起退回");
MCode WF036 = WF("WF036","流程已处理,无法撤回");
MCode WF037 = WF("WF037","当前流程包含子流程,无法撤回");
MCode WF038 = WF("WF038","子流程无法撤回");
MCode WF039 = WF("WF039","下一节点为选择分支无法批量审批");
MCode WF040 = WF("WF040","条件流程包含候选人无法批量通过");
MCode WF041 = WF("WF041","该流程工单已终止");
MCode WF042 = WF("WF042","该流程工单已撤回");
MCode WF043 = WF("WF043","该节点没有数据,无法复活");
MCode WF044 = WF("WF044","此流程不支持变更");
MCode WF045 = WF("WF045","当前节点有子流程无法变更");
MCode WF046 = WF("WF046","退回节点包含子流程,退回失败");
MCode WF047 = WF("WF047","当前节点未审批,不能退回");
MCode WF048 = WF("WF048","流程处于挂起状态,不可操作");
MCode WF049 = WF("WF049","当前流程正在运行不能删除");
MCode WF050 = WF("WF050","已被挂起不能删除");
MCode WF051 = WF("WF051","没有删除权限");
MCode WF052 = WF("WF052","主版本没有内容");
MCode WF053 = WF("WF053","流程没有启用");
MCode WF054 = WF("WF054","流程编码不能重复");
MCode WF055 = WF("WF055","流程表单不一致,请重新选择");
MCode WF056 = WF("WF056","该流程由在线开发生成的,无法直接删除,请在功能设计中删除相关功能");
MCode WF057 = WF("WF057","该流程内工单任务流转未结束,无法删除");
MCode WF058 = WF("WF058","当前流程正在运行不能重复提交");
MCode WF059 = WF("WF059","流程自动发起审批失败");
MCode WF060 = WF("WF060","驳回节点不能是子流程");
MCode WF061 = WF("WF061", "下一节点无审批人员请联系管理员");
MCode WF062 = WF("WF062", "表单已被引用,请重新选择");
MCode WF063 = WF("WF063", "流程已发起,无法删除");
MCode WF064 = WF("WF064", "任务不存在,或者已处理");
MCode WF065 = WF("WF065", "拒绝成功");
MCode WF066 = WF("WF066", "同意成功");
MCode WF067 = WF("WF067", "协办成功");
MCode WF068 = WF("WF068", "协办保存成功");
MCode WF069 = WF("WF069", "减签成功");
MCode WF070 = WF("WF070", "撤销成功");
MCode WF071 = WF("WF071", "最后一条数据不能删除");
MCode WF072 = WF("WF072", "启用版本不能删除");
MCode WF073 = WF("WF073", "归档版本不能删除");
MCode WF074 = WF("WF074", "暂停成功");
MCode WF075 = WF("WF075", "条件不满足无法流转");
MCode WF076 = WF("WF076", "节点不存在");
MCode WF077 = WF("WF077", "流程无法撤回");
MCode WF078 = WF("WF078", "流程未同意,无法撤销");
MCode WF079 = WF("WF079", "归档异常");
MCode WF080 = WF("WF080", "选择的数据不能退签");
MCode WF081 = WF("WF081", "无法加签");
MCode WF082 = WF("WF082", "无法减签");
MCode WF083 = WF("WF083", "无法退回");
MCode WF084 = WF("WF084", "无法转审");
MCode WF085 = WF("WF085", "无法协办");
MCode WF086 = WF("WF086", "无法批量审批");
MCode WF087 = WF("WF087", "经办未签收");
MCode WF088 = WF("WF088", "经办未开始办理");
MCode WF089 = WF("WF089", "流程发布失败");
MCode WF090 = WF("WF090", "流程发布失败");
MCode WF091 = WF("WF091", "流程提交失败");
MCode WF092 = WF("WF092", "获取引擎当前任务失败");
MCode WF093 = WF("WF093", "流程删除失败");
MCode WF094 = WF("WF094", "获取出线集合失败");
MCode WF095 = WF("WF095", "获取线之后的任务节点失败");
MCode WF096 = WF("WF096", "获取下一级任务节点集合失败");
MCode WF097 = WF("WF097", "获取上一级任务节点集合失败");
MCode WF098 = WF("WF098", "任务完成失败");
MCode WF099 = WF("WF099", "获取流程实例失败");
MCode WF100 = WF("WF100", "获取未经过的节点失败");
MCode WF101 = WF("WF101", "获取节点的后续节点失败");
MCode WF102 = WF("WF102", "获取可回退的节点失败");
MCode WF103 = WF("WF103", "退回失败");
MCode WF104 = WF("WF104", "节点跳转失败");
MCode WF105 = WF("WF105", "补偿失败");
MCode WF106 = WF("WF106", "不能加签给自己");
MCode WF107 = WF("WF107", "不能转审给自己");
MCode WF108 = WF("WF108", "不能协办给自己");
MCode WF109 = WF("WF109", "必须保留一名加签人员");
MCode WF110 = WF("WF110", "审批异常无法撤销");
MCode WF111 = WF("WF111", "所选流程包含条件候选人");
MCode WF112 = WF("WF112", "选择的数据对应流程已暂停");
MCode WF113 = WF("WF113", "已被暂停不能删除");
MCode WF114 = WF("WF114","流程处于暂停状态,不可操作");
MCode WF115 = WF("WF115", "流程已受理,无法删除");
MCode WF116 = WF("WF116", "不能加签给委托人");
MCode WF117 = WF("WF117", "不能转审给委托人");
MCode WF118 = WF("WF118", "不能协办给委托人");
MCode WF119 = WF("WF119", "设置了流转条件,无法批量审批");
MCode WF120 = WF("WF120", "下一节点审批异常,无法批量审批");
MCode WF121 = WF("WF121", "子流程自动发起审批失败");
MCode WF122 = WF("WF122", "流程不存在");
MCode WF123 = WF("WF123", "流程处于终止状态,不可操作");
MCode WF124 = WF("WF124", "该流程已发起数据,无法删除!");
MCode WF125 = WF("WF125", "您没有发起委托流程");
MCode WF126 = WF("WF126", "撤销流程不能转审");
MCode WF127 = WF("WF127", "撤销流程不能退回");
MCode WF128 = WF("WF128", "该用户已审批,请重新打开界面");
MCode WF129 = WF("WF129", "委托人已无该流程权限");
MCode WF130 = WF("WF130", "管理员不能新建委托/代理");
MCode WF131 = WF("WF131", "不能选择admin");
MCode WF132 = WF("WF132", "已有人接受,不可编辑");
MCode WF133 = WF("WF133", "流转条件不满足,无法发起审批");
MCode WF134 = WF("WF134", "第一个审批节点设置候选人,无法发起审批");
MCode WF135 = WF("WF135", "第一个审批节点异常,无法发起审批");
MCode WF136 = WF("WF136", "找不到发起人,发起失败");
MCode WF137 = WF("WF137","代理人和被代理人相同,代理失败");
MCode WF138 = WF("WF138","存在未签收的数据,无法关闭");
MCode WF139 = WF("WF139","该流程已触发了任务,无法删除");
MCode WF140 = WF("WF140","该流程已下架");
MCode WF141 = WF("WF141","存在待办理的数据,无法关闭");
MCode WF142 = WF("WF142","流程引擎异常");
MCode WF143 = WF("WF143","已到达加签限制层级,无法再加签");
MCode WF144 = WF("WF144","操作失败,同一时间内有相同流程的代理");
MCode WF145 = WF("WF145","操作失败,同一时间内有相同流程,不能相互代理");
MCode WF146 = WF("WF146","该任务流程已下架");
MCode WF147 = WF("WF147","发起节点设置了选择分支,无法发起审批");
MCode WF148 = WF("WF148","办理成功");
MCode WF149 = WF("WF149", "不能转办给自己");
MCode WF150 = WF("WF150", "不能转办给委托人");
MCode WF151 = WF("WF151", "无法转办");
MCode WF152 = WF("WF152", "转审成功");
/**
* 在线开发相关错误码
*/
/*=========1-错误提示=========*/
MCode VS401 = VS("VS401", "该模板内表单内容为空,无法");
MCode VS402 = VS("VS402", "该模板内列表内容为空,无法");
MCode VS403 = VS("VS403", "该功能未配置流程不可用");
MCode VS404 = VS("VS404", "单行输入不能重复");
MCode VS405 = VS("VS405", "当前表单原数据已被调整,请重新进入该页面编辑并提交数据");
MCode VS406 = VS("VS406", "该功能配置的流程处于停用");
MCode VS407 = VS("VS407", "表头名称不可更改,表头行不能删除");
MCode VS408 = VS("VS408", "请至少选择一个数据表");
MCode VS409 = VS("VS409", "未找到主表信息");
MCode VS410 = VS("VS410", "请导入对应功能的json文件");
MCode VS411 = VS("VS411", "已存在相同功能");
MCode VS412 = VS("VS412", "该表单已删除");
MCode VS413 = VS("VS413", "应用不能为空");
MCode VS414 = VS("VS414", "门户数据信息存在重复");
MCode VS415 = VS("VS415", "该门户已删除");
//base
MCode VS001 = VS("VS001", "同步到流程时,{0}");
MCode VS002 = VS("VS002", "发布失败,流程未设计!");
MCode VS003 = VS("VS003", "无表生成有表失败");
MCode VS004 = VS("VS004", "发布");
MCode VS005 = VS("VS005", "预览");
MCode VS006 = VS("VS006", "下载");
MCode VS007 = VS("VS007", "同步成功");
MCode VS008 = VS("VS008", "回滚失败,暂无线上版本");
MCode VS009 = VS("VS009", "参数解析错误!");
MCode VS010 = VS("VS010", "无效链接");
MCode VS011 = VS("VS011", "密码错误");
MCode VS012 = VS("VS012", "未找到该功能表单");
MCode VS013 = VS("VS013", "未开启表单外链!");
MCode VS014 = VS("VS014", "下载链接已失效");
MCode VS015 = VS("VS015", "字段不能为空");
MCode VS016 = VS("VS016", "路径错误");
MCode VS017 = VS("VS017", "集成助手被禁用");
MCode VS018 = VS("VS018", "表规范名称不能重复");
MCode VS019 = VS("VS019", "规范名称不能使用系统关键字或JAVA关键字");
MCode VS020 = VS("VS020", "字段规范名称不能重复");
MCode VS021 = VS("VS021", "“{0}”命名不符合规范");
MCode VS022 = VS("VS022", "主键策略:[雪花ID],表[ {0} ]主键设置不支持!");
MCode VS023 = VS("VS023", "主键策略:[自增ID],表[ {0} ]主键设置不支持!");
MCode VS024 = VS("VS024", "表单不存在或者未发布!");
MCode VS025 = VS("VS025", "未获取到流程发起人");
MCode VS026 = VS("VS026", "规范名称前两字母必须小写");
MCode VS027 = VS("VS027", "自动生成的【{0}】超出长度,提交失败!");
MCode VS028 = VS("VS028", "视图最多新建5个");
MCode VS029 = VS("VS029", "设置视图主键后才能正常使用");
/**
* 网关
*/
MCode GT101 = GT("GT101", "成功");
MCode GT102 = GT("GT102", "失败");
MCode GT103 = GT("GT103", "验证错误");
MCode GT104 = GT("GT104", "异常");
MCode GT105 = GT("GT105", "登录过期,请重新登录");
MCode GT106 = GT("GT106", "您的帐号在其他地方已登录,被强制踢出");
MCode GT107 = GT("GT107", "Token验证失败");
MCode GT108 = GT("GT108", "请求超过最大数");
/**
* 调度
*/
MCode SC001 = SCHEDULE("SC001", "操作失败,任务不存在");
/**
* admin exception
*/
MCode AD101 = MSG("AD101", "接口无法访问");
MCode AD102 = MSG("AD102", "系统异常");
MCode AD103 = MSG("AD103", "操作过于频繁");
MCode AD104 = MSG("AD104", "没有访问权限,请联系管理员授权");
MCode AD105 = MSG("AD105", "认证失败,无法访问系统资源");
MCode AD106 = MSG("AD106", "无效内部认证,无法访问系统资源");
/**
* extend
*/
MCode ETD101 = MSG("ETD101", "操作失败,原文件不存在");
MCode ETD102 = MSG("ETD102", "找不到父级");
MCode ETD103 = MSG("ETD103", "不能移动到自己的文件夹");
MCode ETD104 = MSG("ETD104", "未能找到此订单");
MCode ETD105 = MSG("ETD105", "新建成功10000条数据");
MCode ETD106 = MSG("ETD106", "获取失败");
MCode ETD107 = MSG("ETD107", "账户认证错误");
MCode ETD108 = MSG("ETD108", "你还没有设置邮件的帐户");
MCode ETD109 = MSG("ETD109", "文件导出失败");
MCode ETD110 = MSG("ETD110", "文件格式不正确");
MCode ETD111 = MSG("ETD111", "文件找不到");
MCode ETD112 = MSG("ETD112", "此记录被关联引用,不允许被删除");
MCode ETD113 = MSG("ETD113", "防止恶意创建过多数据");
MCode ETD114 = MSG("ETD114", "保存失败,请重新登陆");
MCode ETD115 = MSG("ETD115", "请输入预览的url");
MCode ETD116 = MSG("ETD116", "请选择正确的预览方式");
MCode ETD117 = MSG("ETD117", "数据超过1000条");
/**
* form
*/
MCode FM001 = MSG("FM001", "未找到接口");
MCode FM002 = MSG("FM002", "表单信息不存在");
MCode FM003 = MSG("FM003", "子表重复");
MCode FM004 = MSG("FM004", "已到达该模板复制上限,请复制源模板!");
MCode FM005 = MSG("FM005", "该表单已被流程引用,无法删除!");
MCode FM006 = MSG("FM006", "该表单未发布,无法回滚表单内容");
MCode FM007 = MSG("FM007", "该模板内表单内容为空,无法发布");
MCode FM008 = MSG("FM008", "该功能未导入流程表单");
MCode FM009 = MSG("FM009", "流程未设计,请先设计流程!");
MCode FM010 = MSG("FM010", "该功能流程处于停用状态!");
MCode FM011 = MSG("FM011", "表[{0}]无主键!");
MCode FM012 = MSG("FM012", "主键策略:{0},与表[{1}]主键策略不一致!");
MCode FM013 = MSG("FM013", "表新增错误:{0}");
/**
* message的消息提示
*/
MCode MSERR101 = MSG("MSERR101", "发送失败失败原因SMTP服务为空");
MCode MSERR102 = MSG("MSERR102", "发送失败,失败原因:发件人邮箱为空");
MCode MSERR103 = MSG("MSERR103", "发送失败,失败原因:发件人密码为空");
MCode MSERR104 = MSG("MSERR104", "发送失败,失败原因:接收人为空");
MCode MSERR105 = MSG("MSERR105", "发送失败。失败原因:{0}的邮箱账号格式有误!");
MCode MSERR106 = MSG("MSERR106", "发送失败。失败原因:{0}的邮箱账号为空!");
MCode MSERR107 = MSG("MSERR107", "发送失败。失败原因:接收人对应的邮箱全部为空");
MCode MSERR108 = MSG("MSERR108", "发送失败。失败原因:{0}");
MCode MSERR109 = MSG("MSERR109", "连接成功");
MCode MSERR110 = MSG("MSERR110", "连接失败。失败原因:{0}");
MCode MSERR111 = MSG("MSERR111", "已发送");
MCode MSERR112 = MSG("MSERR112", "内容不能包含<符号");
MCode MSERR113 = MSG("MSERR113", "暂无未读消息");
MCode MSERR114 = MSG("MSERR114", "自定义模板编码不能使用系统模板编码规则");
MCode MSERR115 = MSG("MSERR115", "创建失败,存在多个标题参数");
MCode MSERR116 = MSG("MSERR116", "创建失败,不存在标题参数");
MCode MSERR117 = MSG("MSERR117", "更新失败,存在多个标题参数");
MCode MSERR118 = MSG("MSERR118", "更新失败,不存在标题参数");
MCode MSERR119 = MSG("MSERR119", "请先前往系统同步设置,配置钉钉账号");
MCode MSERR120 = MSG("MSERR120", "请先前往系统同步设置,配置企业微信账号");
MCode MSERR121 = MSG("MSERR121", "配置模板无数据,无法测试");
/********************
* system
********************/
MCode SYS001 = SYS("SYS001", "区域编码不能重复");
MCode SYS002 = SYS("SYS002", "删除失败,当前有子节点数据");
MCode SYS003 = SYS("SYS003", "单据已经被使用,不允许被删除");
MCode SYS004 = SYS("SYS004", "清理成功");
MCode SYS005 = SYS("SYS005", "接口创建成功");
MCode SYS006 = SYS("SYS006", "当前SQL含有敏感字:{0}");
MCode SYS007 = SYS("SYS007", "接口请求成功");
MCode SYS008 = SYS("SYS008", "接口不符合规范");
MCode SYS009 = SYS("SYS009", "变量名不能包含敏感字符");
MCode SYS010 = SYS("SYS010", "变量名已存在");
MCode SYS011 = SYS("SYS011", "数据库连接不能相同");
MCode SYS012 = SYS("SYS012", "请检查,同一数据库下无法同步数据");
MCode SYS013 = SYS("SYS013", "同步失败:{0}");
MCode SYS014 = SYS("SYS014", "字典类型下面有字典值禁止删除");
MCode SYS015 = SYS("SYS015", "模板不存在");
MCode SYS016 = SYS("SYS016", "当前目录存在数据,不能修改类型");
MCode SYS017 = SYS("SYS017", "删除失败,请先删除子菜单");
MCode SYS018 = SYS("SYS018", "当前导入菜单为{0}端菜单,请在对应模块下导入!");
MCode SYS019 = SYS("SYS019", "请在顶级节点下创建目录后再进行菜单导入");
MCode SYS020 = SYS("SYS020", "该字段在方案{0}中已被使用");
MCode SYS021 = SYS("SYS021", "修改失败,该方案不允许编辑");
MCode SYS022 = SYS("SYS022", "编码错误");
MCode SYS023 = SYS("SYS023", "请求发生错误!");
MCode SYS024 = SYS("SYS024", "获取不到数据!");
MCode SYS025 = SYS("SYS025", "获取企业微信access_token失败");
MCode SYS026 = SYS("SYS026", "正在进行同步,请稍后再试");
MCode SYS027 = SYS("SYS027", "请先从企业微信同步部门到本地");
MCode SYS028 = SYS("SYS028", "请先从钉钉同步部门到本地");
MCode SYS029 = SYS("SYS029", "验证码位数不能大于6");
MCode SYS030 = SYS("SYS030", "验证码位数不能小于3");
MCode SYS031 = SYS("SYS031", "测试发送消息的连接失败:{0}");
MCode SYS032 = SYS("SYS032", "测试发送消息连接成功");
MCode SYS033 = SYS("SYS033", "测试组织同步的连接失败:{0}");
MCode SYS034 = SYS("SYS034", "测试组织同步连接成功");
MCode SYS035 = SYS("SYS035", "测试连接类型错误");
MCode SYS036 = SYS("SYS036", "测试钉钉连接失败:");
MCode SYS037 = SYS("SYS037", "测试连接成功");
MCode SYS038 = SYS("SYS038", "表信息抽取异常");
MCode SYS039 = MSG("SYS039", "删除失败,请先删除该应用下的菜单和门户");
MCode SYS040 = MSG("SYS040", "删除失败,请先删除该应用下的菜单");
MCode SYS041 = MSG("SYS041", "删除失败,请先删除该应用下的门户");
MCode SYS042 = MSG("SYS042", "该日程已被删除");
MCode SYS043 = MSG("SYS043", "最后一条数据不能删除");
MCode SYS044 = MSG("SYS044", "启用版本不能删除");
MCode SYS045 = MSG("SYS045", "归档版本不能删除");
MCode SYS046 = MSG("SYS046", "数据集不能重名");
MCode SYS047 = MSG("SYS047", "SQL语句仅支持查询语句");
MCode SYS048 = MSG("SYS048", "SQL语句需带上@formId条件");
MCode SYS049 = MSG("SYS049", "正在进行同步,请稍等");
MCode SYS050 = MSG("SYS050", "只能输入字母、数字、点、横线和下划线,且以字母开头");
MCode SYS051 = MSG("SYS051", "翻译标记不能重复");
MCode SYS052 = MSG("SYS052", "翻译语言至少填写一项");
MCode SYS053 = SYS("SYS053", "获取钉钉access_token失败");
/**
* 应用
*/
MCode SYS101 = SYS("SYS101", "更新失败,主系统不允许禁用");
MCode SYS102 = SYS("SYS102", "主系统不允许删除");
MCode SYS103 = SYS("SYS103", "系统在审批常用语中被使用,不允许删除");
MCode SYS104 = SYS("SYS104", "更新失败,主系统不允许修改编码");
MCode SYS105 = SYS("SYS105", "常用语已存在");
/**
* 数据接口
*/
MCode SYS121 = SYS("SYS121", "接口暂只支持HTTP和HTTPS方式");
MCode SYS122 = SYS("SYS122", "接口请求失败");
MCode SYS123 = SYS("SYS123", "接口请求失败, JS调用失败,错误:{0}");
MCode SYS124 = SYS("SYS124", "验证请求超时");
MCode SYS125 = SYS("SYS125", "appSecret错误");
MCode SYS126 = SYS("SYS126", "appId使用期限已到期");
MCode SYS127 = SYS("SYS127", "appId参数错误");
MCode SYS128 = SYS("SYS128", "{0}不能使用系统、开发语言及数据库关键字命名");
MCode SYS129 = SYS("SYS129", "当前数据源不支持全连接");
MCode SYS130 = SYS("SYS130", "标题不能为空");
MCode SYS131 = SYS("SYS131", "结束时间必须晚于开始时间");
MCode SYS132 = SYS("SYS132", "结束重复必须晚于开始时间");
MCode SYS133 = SYS("SYS133", "请先设置数据接口的字段列表!");
/**
* AI
*/
MCode SYS180 = SYS("SYS180", "AI功能未配置启用");
MCode SYS181 = SYS("SYS181", "AI结果获取失败, 请稍后再尝试");
MCode SYS182 = SYS("SYS182", "AI请求频率达到限制, 请稍后再尝试");
/********************
* system
********************/
static MCode MSG(String code, String desc){
return new MCode("message", code, desc);
}
static MCode LOG(String code, String desc){
return new MCode("login", code, desc);
}
static MCode DB(String code, String desc){
return new MCode("database", code, desc);
}
static MCode WF(String code, String desc){
return new MCode("workflow", code, desc);
}
static MCode VS(String code, String desc){
return new MCode("visual", code, desc);
}
static MCode GT(String code, String desc){
return new MCode("gateway", code, desc);
}
static MCode OA(String code, String desc){
return new MCode("oauth", code, desc);
}
static MCode PS(String code, String desc){
return new MCode("permission", code, desc);
}
static MCode SCHEDULE(String code, String desc){
return new MCode("schedule", code, desc);
}
static MCode SYS(String code, String desc){
return new MCode("system", code, desc);
}
}

View File

@@ -0,0 +1,62 @@
package com.yunzhupaas.constant;
public class PermissionConst {
/**
* 组织标识
*/
public static final String ORGANIZE = "Organize";
/**
* 岗位标识
*/
public static final String POSITION = "Position";
/**
* 角色标识
*/
public static final String ROLE = "Role";
public static final String COMPANY = "company";
public static final String DEPARTMENT = "department";
/**
* 分组
*/
public static final String GROUP = "Group";
/**
* 应用
*/
public static final String SYSTEM = "System";
/**
* 身份
*/
public static final String STAND = "Standing";
/**
* 菜单
*/
public static final String MODULE = "Module";
/**
* 用户
*/
public static final String USER = "user";
/**
* 在线开发常用按钮权限
*/
public static final String BTN_ADD = "btn_add";
public static final String BTN_EDIT = "btn_edit";
public static final String BTN_REMOVE = "btn_remove";
public static final String BTN_DETAIL = "btn_detail";
public static final String BTN_UPLOAD = "btn_upload";
public static final String BTN_DOWNLOAD = "btn_download";
public static final String BTN_BATCHREMOVE = "btn_batchRemove";
public static final String BTN_BATCHPRINT = "btn_batchPrint";
}

View File

@@ -0,0 +1,23 @@
package com.yunzhupaas.constant;
public class TableFieldsNameConst {
public static final String ID = "id";
public static final String F_ID = "f_id";
public static final String F_TENANT_ID = "f_tenant_id";
public static final String F_VERSION = "f_version";
public static final String F_FLOW_TASK_ID = "f_flow_task_id";
public static final String F_FLOW_ID = "f_flow_id";
public static final String F_DELETE_MARK = "f_delete_mark";
public static final String F_DELETE_TIME = "f_delete_time";
public static final String F_DELETE_USER_ID = "f_delete_user_id";
public static final String F_FOREIGN_ID = "f_foreign_id";
public static final String F_CREATOR_TIME = "f_creator_time";
public static final String F_CREATOR_USER_ID = "f_creator_user_id";
public static final String F_LAST_MODIFY_TIME = "f_last_modify_time";
public static final String F_LAST_MODIFY_USER_ID = "f_last_modify_user_id";
public static final String F_SORT_CODE = "f_sort_code";
public static final String F_DESCRIPTION = "f_description";
public static final String F_ENABLED_MARK = "f_enabled_mark";
}

View File

@@ -0,0 +1,99 @@
package com.yunzhupaas.constant;
import lombok.Data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 功能中所用常量
*
* @author 云筑产品开发平台组
* @version V3.5.0
* @copyright 深圳市乐程软件有限公司
* @date 2023/6/6 15:08:10
*/
@Data
public class YunzhupaasConst {
/**
* 被过滤的系统菜单常量
*/
public static final String MAIN_SYSTEM_CODE = "mainSystem";
/**
* 业务平台编码
*/
public static final String WORK_SYSTEM_CODE = "workSystem";
/**
* 被过滤的系统菜单常量
*/
public static final List<String> MODULE_CODE = new ArrayList<String>() {
{
add("workFlow.addFlow");
add("workFlow.flowLaunch");
add("workFlow.entrust");
add("workFlow");
add("workFlow.flowTodo");
add("workFlow.flowDone");
add("workFlow.flowCirculate");
add("workFlow.document");
add("workFlow.schedule");
add("workFlow.flowToSign");
add("workFlow.flowDoing");
add("workFlow.printTemplate");
}
};
/**
* 当前组织
*/
public static final String CURRENT_ORG = "@currentOrg";
public static final String CURRENT_ORG_TYPE = "@currentOrg--system";
/**
* 当前组织及子组织
*/
public static final String CURRENT_ORG_SUB = "@currentOrgAndSubOrg";
public static final String CURRENT_ORG_SUB_TYPE = "@currentOrgAndSubOrg--system";
/**
* 当前分管组织
*/
public static final String CURRENT_GRADE = "@currentGradeOrg";
public static final String CURRENT_GRADE_TYPE = "@currentGradeOrg--system";
/**
* 高级控件系统参数
*/
public static final Map<String, String> SYSTEM_PARAM = new HashMap<String, String>() {
{
put(CURRENT_ORG, "当前组织");
put(CURRENT_ORG_SUB, "当前组织及子组织");
put(CURRENT_GRADE, "当前分管组织");
put(CURRENT_ORG_TYPE, "当前组织");
put(CURRENT_ORG_SUB_TYPE, "当前组织及子组织");
put(CURRENT_GRADE_TYPE, "当前分管组织");
}
};
/**
* 在线开发数据日志事件key
*/
public static final String VSLOG_EVENT_KEY = "vslogEventKey";
/**
* 流程签收菜单
*/
public static final String WORK_FLOWSIGN = "workFlow.flowToSign";
/**
* 流程办理菜单
*/
public static final String WORK_FLOWTODO = "workFlow.flowTodo";
public static String FIELD_SUFFIX_YUNZHUPAASID = "_yunzhupaasId";
}

View File

@@ -0,0 +1,48 @@
package com.yunzhupaas.constant.model;
import com.yunzhupaas.i18n.util.I18nUtil;
import lombok.Data;
/**
* 类功能
*
* @author 云筑产品开发平台组
* @version V3.2.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/12/20
*/
@Data
public class MCode {
/**
* 提示信息类型
*/
private final String type;
/**
* 错误编码
*/
private final String code;
/**
* description 描述
*/
private final String desc;
public MCode(String type, String code, String desc){
this.type = type;
this.code = code;
this.desc = desc;
}
public String get(Object... args){
return I18nUtil.getMessageStr(this, args);
}
public String getMsg(){
return type + ":" + code + " " + desc;
}
}

View File

@@ -0,0 +1,39 @@
package com.yunzhupaas.emnus;
/**
* 数据权限字段类型
*
* @author 云筑产品开发平台组
* @version V3.2
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2021/10/8
*/
public enum DataFieldType {
/**
* 浮点型
*/
Double("Double"),
/**
* 字符型
*/
Varchar("String"),
/**
* 数值型
*/
Number("Int32");
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
DataFieldType(String message) {
this.message = message;
}
}

View File

@@ -0,0 +1,33 @@
package com.yunzhupaas.emnus;
/**
* 数据及关联数据类型枚举
*
* @author 云筑产品开发平台组
* @version v5.0.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/5/7 10:56:58
*/
public enum DataSetTypeEnum {
PRINT_VER("printVersion", "打印版本"),
REPORT_VER("reportVersion", "报表版本");
private final String code;
private final String msg;
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
DataSetTypeEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
}

View File

@@ -0,0 +1,39 @@
package com.yunzhupaas.emnus;
/**
* 数据库驱动枚举类
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-03-23
*/
public enum DbDriverEnum {
/**
* mysql
*/
MYSQL("com.mysql.cj.jdbc.Driver"),
/**
* oracle
*/
ORACLE("oracle.jdbc.OracleDriver"),
/**
* sqlserver
*/
SQLSERVER("com.microsoft.sqlserver.jdbc.SQLServerDriver");
private String dbDriver;
DbDriverEnum(String dbDriver) {
this.dbDriver = dbDriver;
}
public String getDbDriver() {
return dbDriver;
}
public void setDbDriver(String dbDriver) {
this.dbDriver = dbDriver;
}
}

View File

@@ -0,0 +1,64 @@
package com.yunzhupaas.emnus;
/**
* 连接关系枚举
*
* @author 云筑产品开发平台组
* @version v5.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/9/12 9:36:05
*/
public enum DsJoinTypeEnum {
LEFT_JOIN(1, "LEFT JOIN", "左连接"),
RIGHT_JOIN(2, "LEFT JOIN", "右连接"),
INNER_JOIN(3, "INNER JOIN", "内连接"),
FULL_JOIN(4, "FULL JOIN", "全连接");
private Integer type;
private String code;
private String fullName;
DsJoinTypeEnum(Integer type, String code, String fullName) {
this.type = type;
this.code = code;
this.fullName = fullName;
}
public Integer getType() {
return type;
}
public String getCode() {
return code;
}
public String getFullName() {
return fullName;
}
public static String getCodeByType(Integer type) {
String code = null;
switch (type) {
case 1:
code = LEFT_JOIN.getCode();
break;
case 2:
code = RIGHT_JOIN.getCode();
break;
case 3:
code = INNER_JOIN.getCode();
break;
case 4:
code = FULL_JOIN.getCode();
break;
default:
code = LEFT_JOIN.getCode();
break;
}
return code;
}
}

View File

@@ -0,0 +1,43 @@
package com.yunzhupaas.emnus;
/**
* 导入导出模板类型
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2021/7/15
*/
public enum ExportModelTypeEnum {
/**
* 功能设计
*/
Design(1,"design"),
/**
* APP
*/
App(2,"app"),
/**
*门户
*/
Portal(5,"portal");
private final int code;
private final String message;
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
ExportModelTypeEnum(int code, String message) {
this.code = code;
this.message = message;
}
}

View File

@@ -0,0 +1,25 @@
package com.yunzhupaas.emnus;
/**
* 文件预览方式
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2021/5/6
*/
public enum FilePreviewTypeEnum {
/**
* yozo:永中预览; doc:kk文档预览;
*/
YOZO_ONLINE_PREVIEW("yozoOnlinePreview"),
LOCAL_PREVIEW("localPreview");
FilePreviewTypeEnum(String type) {
this.type = type;
}
private String type;
public String getType() {
return type;
}
}

View File

@@ -0,0 +1,104 @@
package com.yunzhupaas.emnus;
/**
* 功能分类枚举
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-10-27
*/
public enum ModuleTypeEnum {
/**
* 数据接口类型
*/
SYSTEM_DATAINTEFASE("bd"),
/**
* 数据接口类型
*/
SYSTEM_DATAINTEFASE_VARIATE("ffa"),
/**
* 单据规则
*/
SYSTEM_BILLRULE("bb"),
/**
* 菜单
*/
SYSTEM_MODULE("bm"),
/**
* 数据建模
*/
SYSTEM_DBTABLE("bdb"),
/**
* 数据字典
*/
SYSTEM_DICTIONARYDATA("bdd"),
/**
* 打印模板
*/
SYSTEM_PRINT("bp"),
/**
* 表单套件
*/
SYSTEM_KIT("bvk"),
/**
* 大屏导出
*/
VISUAL_DATA("vd"),
/**
* 在线开发
*/
VISUAL_DEV("vdd"),
/**
* APP导出
*/
VISUAL_APP("va"),
/**
* 门户导出
*/
VISUAL_PORTAL("vp"),
/**
* 流程设计
*/
FLOW_FLOWENGINE("ffe"),
/**
* 账号配置
*/
ACCOUNT_CONFIG("mac"),
/**
* 消息模板
*/
MESSAGE_TEMPLATE("mes"),
/**
* 消息模板
*/
MESSAGE_SEND_CONFIG("msc"),
/**
* 流程表单
*/
FLOW_FLOWDFORM("fff"),
/**
* 流程表单
*/
BASE_INTEGRATE("bi"),
/**
* 报表
*/
REPORT_TEMPLATE("rp"),
;
ModuleTypeEnum(String moduleName) {
this.tableName = moduleName;
}
private String tableName;
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
}

View File

@@ -0,0 +1,109 @@
package com.yunzhupaas.emnus;
/**
* 查询功能
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024-09-26 上午9:18
*/
public enum SearchMethodEnum {
/**
* 等于
*/
Equal("==", "等于"),
/**
* 介于
*/
Between("between", "介于"),
/**
* 不等于
*/
NotEqual("<>", "不等于"),
/**
* 大于
*/
GreaterThan(">", "大于"),
/**
* 大于等于
*/
GreaterThanOrEqual(">=", "大于等于"),
/**
* 小于
*/
LessThan("<", "小于"),
/**
* 小于等于
*/
LessThanOrEqual("<=", "小于等于"),
/**
* 包含任意一个
*/
Included("in", "包含任意一个"),
/**
* 不包含任意一个
*/
NotIncluded("notIn", "不包含任意一个"),
/**
* 为空
*/
IsNull("null", "为空"),
/**
* 不为空
*/
IsNotNull("notNull", "不为空"),
/**
* 包含
*/
Like("like", "包含"),
/**
* 不包含
*/
NotLike("notLike", "不包含"),
/**
* 并且
*/
And("and", "并且"),
/**
* 或者
*/
Or("or", "或者");
SearchMethodEnum(String symbol, String message) {
this.symbol = symbol;
this.message = message;
}
private String symbol;
private String message;
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public static SearchMethodEnum getSearchMethod(String symbol) {
for (SearchMethodEnum status : SearchMethodEnum.values()) {
if (status.getSymbol().equals(symbol)) {
return status;
}
}
return Equal;
}
}

View File

@@ -0,0 +1,76 @@
package com.yunzhupaas.emnus;
import cn.hutool.core.util.ObjectUtil;
/**
* 接口类型
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024-09-26 上午9:18
*/
public enum TemplateEnum {
//字段
Field(1, "字段"),
//自定义
Custom(2, "自定义"),
//为空
Empty(3, "为空"),
//系统
System(4, "系统");
private Integer code;
private String message;
TemplateEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
/**
* 根据状态code获取枚举名称
*
* @return
*/
public static String getMessageByCode(Integer code) {
for (TemplateEnum status : TemplateEnum.values()) {
if (ObjectUtil.equal(status.getCode(), code)) {
return status.message;
}
}
return null;
}
/**
* 根据状态code获取枚举值
*
* @return
*/
public static TemplateEnum getByCode(Integer code) {
for (TemplateEnum status : TemplateEnum.values()) {
if (ObjectUtil.equal(status.getCode(), code)) {
return status;
}
}
return null;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@@ -0,0 +1,54 @@
package com.yunzhupaas.emnus;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:56
*/
public enum TimetaskTypes {
/**
* 执行一次
*/
One(1, "执行一次"),
/**
* 重复执行
*/
Two(2, "重复执行"),
/**
* 调度明细
*/
Three(3, "调度明细"),
/**
* 调度任务
*/
Four(4, "调度任务");
private int code;
private String message;
TimetaskTypes(int code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@@ -0,0 +1,9 @@
package com.yunzhupaas.exception;
public class ConnectDatabaseException extends RuntimeException {
public ConnectDatabaseException(String reason, Throwable cause) {
super(reason, cause);
}
}

View File

@@ -0,0 +1,45 @@
package com.yunzhupaas.exception;
import com.yunzhupaas.constant.MsgCode;
import java.sql.Connection;
import java.sql.SQLException;
/**
* 数据库异常类
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:10
*/
public class DataException extends RuntimeException {
public DataException(){
super();
}
public DataException(String message) {
super(message);
}
public static DataException errorLink(String warning) {
return new DataException(MsgCode.DB002.get(warning));
}
public static SQLException rollbackDataException(SQLException e, Connection rollbackConn) {
executeRollback(rollbackConn);
return e;
}
private static void executeRollback(Connection conn){
try {
conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,10 @@
package com.yunzhupaas.exception;
public class DataTypeException extends Exception {
public DataTypeException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,16 @@
package com.yunzhupaas.exception;
/**
* 数据加密异常
*/
public class EncryptFailException extends RuntimeException{
public EncryptFailException(String message) {
super(message);
}
public EncryptFailException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,8 @@
package com.yunzhupaas.exception;
public class ImportException extends Exception {
public ImportException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,28 @@
package com.yunzhupaas.exception;
import lombok.Getter;
import lombok.Setter;
/**
* 登录异常
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/16 10:53
*/
public class LoginException extends RuntimeException {
@Getter
@Setter
private Object data;
public LoginException(String message) {
super(message);
}
public LoginException(String message, Object data) {
super(message);
this.data = data;
}
}

View File

@@ -0,0 +1,23 @@
package com.yunzhupaas.exception;
import lombok.experimental.Accessors;
/**
* 租户数据库相关异常
*/
@Accessors(chain = true)
public class TenantDatabaseException extends TenantInvalidException {
public TenantDatabaseException() {
super();
}
public TenantDatabaseException(String message) {
super(message);
}
public TenantDatabaseException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,32 @@
package com.yunzhupaas.exception;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* 租户无效异常
*/
@Accessors(chain = true)
public class TenantInvalidException extends RuntimeException{
@Getter
@Setter
private String logMsg;
@Getter
@Setter
private Object data;
public TenantInvalidException() {
super();
}
public TenantInvalidException(String message) {
super(message);
}
public TenantInvalidException(String message, Throwable cause) {
super(message, cause);
}
}

Some files were not shown because too many files have changed in this diff Show More