初始代码

This commit is contained in:
wangmingwei
2026-04-21 16:49:46 +08:00
parent aae9dc4036
commit f0453ff3a3
2396 changed files with 256575 additions and 0 deletions

205
yunzhupaas-admin/pom.xml Normal file
View File

@@ -0,0 +1,205 @@
<?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-java-boot</artifactId>
<groupId>com.yunzhupaas</groupId>
<version>5.2.0-RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yunzhupaas-admin</artifactId>
<packaging>jar</packaging>
<!--打包WAR包删除注释-->
<!--<packaging>war</packaging>-->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-file-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-extend-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-system-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-scheduletask-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-message-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-permission-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-visualdev-base-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-visualdev-onlinedev-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-visualdev-generater-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-visualdev-portal-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-visualdata-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-exception</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-oauth-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-example-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-app-controller</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 基础信息-->
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-mdm-controller</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 客户关系-->
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-crm-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-pcm-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-visualdev-integrate-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-flowable-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-train-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.yunzhupaas</groupId>
<artifactId>yunzhupaas-common-i18n</artifactId>
</dependency>
<!-- 单点登录相关依赖-Start -->
<!-- <dependency>-->
<!-- <groupId>com.yunzhupaas</groupId>-->
<!-- <artifactId>yunzhupaas-sso-starter-all</artifactId>-->
<!-- <version>${project.version}</version>-->
<!-- </dependency>-->
<!-- 单点登录(用户信息拉取)相关依赖 -->
<!-- <dependency>-->
<!-- <groupId>com.yunzhupaas</groupId>-->
<!-- <artifactId>yunzhupaas-sso-connector</artifactId>-->
<!-- <version>${project.version}</version>-->
<!-- </dependency>-->
<!-- 单点登录(用户信息推送)相关依赖 -->
<!-- <dependency>-->
<!-- <groupId>com.yunzhupaas</groupId>-->
<!-- <artifactId>yunzhupaas-sso-pull</artifactId>-->
<!-- <version>${project.version}</version>-->
<!-- </dependency>-->
<!-- 单点登录相关依赖-End -->
<!--打包WAR包删除注释-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- ... -->
<!--打包WAR包注释插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.yunzhupaas.AdminApplication</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- ... -->
<!--打包WAR包删除注释-->
<!--<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<warSourceExcludes>src/main/resources/**</warSourceExcludes>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>-->
</plugins>
</build>
</project>

View File

@@ -0,0 +1,28 @@
package com.yunzhupaas;
import cn.xuyanwu.spring.file.storage.EnableFileStorage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/15 17:12
*/
@SpringBootApplication(scanBasePackages = { "com.yunzhupaas" }, exclude = { DataSourceAutoConfiguration.class })
@EnableFileStorage
public class AdminApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(AdminApplication.class);
// 添加监听器
// springApplication.addListeners(new YunzhupaasListener());
springApplication.run(args);
System.out.println("YunzhuPaasAdmin启动完成");
}
}

View File

@@ -0,0 +1,88 @@
package com.yunzhupaas.aop;
import cn.dev33.satoken.context.SaHolder;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.config.ConfigValueUtil;
import com.yunzhupaas.database.util.NotTenantPluginHolder;
import com.yunzhupaas.database.util.TenantDataSourceUtil;
import com.yunzhupaas.util.TenantHolder;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.UserProvider;
import com.yunzhupaas.util.data.DataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/15 17:12
*/
@Slf4j
@Aspect
@Component
@Order(1)
public class DataSourceBindAspect {
@Autowired
private ConfigValueUtil configValueUtil;
@Pointcut("within(com.yunzhupaas.*.controller.* || com.yunzhupaas.controller.*)")
public void bindDataSource() {
}
/**
* NoDataSourceBind 不需要绑定数据库的注解
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("bindDataSource() && !@annotation(com.yunzhupaas.util.NoDataSourceBind)")
public Object doAroundService(ProceedingJoinPoint pjp) throws Throwable {
// System.out.println(SaHolder.getRequest().getRequestPath());
if (configValueUtil.isMultiTenancy()) {
if(StringUtil.isEmpty(TenantHolder.getDatasourceId())){
UserInfo userInfo = UserProvider.getUser();
String url = null;
try{
url = SaHolder.getRequest().getRequestPath();
}catch (Exception ee){ }
log.error("租户" + userInfo.getTenantId() + "数据库不存在, URL: {}, TOKEN: {}", url, userInfo.getToken());
return null;
}
return pjp.proceed();
}
Object obj = pjp.proceed();
return obj;
}
/**
* NoDataSourceBind 不需要绑定数据库的注解 加入不切租户库标记
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("bindDataSource() && @annotation(com.yunzhupaas.util.NoDataSourceBind)")
public Object doAroundService2(ProceedingJoinPoint pjp) throws Throwable {
try{
NotTenantPluginHolder.setNotSwitchAlwaysFlag();
//Filter中提前设置租户信息, 不需要切库的方法进行清除切库
TenantDataSourceUtil.clearLocalTenantInfo();
return pjp.proceed();
}finally {
NotTenantPluginHolder.clearNotSwitchAlwaysFlag();
}
}
}

View File

@@ -0,0 +1,77 @@
package com.yunzhupaas.aop;
import cn.xuyanwu.spring.file.storage.FileInfo;
import cn.xuyanwu.spring.file.storage.UploadPretreatment;
import cn.xuyanwu.spring.file.storage.aspect.*;
import cn.xuyanwu.spring.file.storage.platform.FileStorage;
import cn.xuyanwu.spring.file.storage.recorder.FileRecorder;
import com.yunzhupaas.config.ConfigValueUtil;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.exception.DataException;
import com.yunzhupaas.util.PdfUtil;
import com.yunzhupaas.util.XSSEscape;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
import java.util.function.Consumer;
@Slf4j
@Component
public class MyFileAspect implements FileStorageAspect {
@Autowired
private ConfigValueUtil configValueUtil;
@Override
public FileInfo uploadAround(UploadAspectChain chain, FileInfo fileInfo, UploadPretreatment pre, FileStorage fileStorage, FileRecorder fileRecorder) {
checkFilePath(fileInfo);
if(configValueUtil.isCheckFilePdf()) {
try {
String ext = fileInfo.getExt();
if("pdf".equalsIgnoreCase(ext)) {
log.error("检测PDF文件");
if (PdfUtil.containsJavaScript(pre.getFileWrapper().getBytes())) {
throw new DataException(MsgCode.FA053.get());
}
}
} catch (IOException e) {
log.error("PDF文档解析失败: {}", e.getMessage());
}
}
return FileStorageAspect.super.uploadAround(chain, fileInfo, pre, fileStorage, fileRecorder);
}
@Override
public boolean deleteAround(DeleteAspectChain chain, FileInfo fileInfo, FileStorage fileStorage, FileRecorder fileRecorder) {
checkFilePath(fileInfo);
return FileStorageAspect.super.deleteAround(chain, fileInfo, fileStorage, fileRecorder);
}
@Override
public boolean existsAround(ExistsAspectChain chain, FileInfo fileInfo, FileStorage fileStorage) {
checkFilePath(fileInfo);
return FileStorageAspect.super.existsAround(chain, fileInfo, fileStorage);
}
@Override
public void downloadAround(DownloadAspectChain chain, FileInfo fileInfo, FileStorage fileStorage, Consumer<InputStream> consumer) {
checkFilePath(fileInfo);
FileStorageAspect.super.downloadAround(chain, fileInfo, fileStorage, consumer);
}
@Override
public void downloadThAround(DownloadThAspectChain chain, FileInfo fileInfo, FileStorage fileStorage, Consumer<InputStream> consumer) {
checkFilePath(fileInfo);
FileStorageAspect.super.downloadThAround(chain, fileInfo, fileStorage, consumer);
}
private void checkFilePath(FileInfo fileInfo){
//处理特殊文件名
fileInfo.setPath(XSSEscape.escapePath(fileInfo.getPath()));
fileInfo.setFilename(XSSEscape.escapePath(fileInfo.getFilename()));
}
}

View File

@@ -0,0 +1,69 @@
package com.yunzhupaas.aop;
import com.yunzhupaas.constant.PermissionConstant;
import com.yunzhupaas.permission.entity.OrganizeRelationEntity;
import com.yunzhupaas.permission.model.authorize.SaveBatchForm;
import com.yunzhupaas.permission.service.OrganizeRelationService;
import com.yunzhupaas.util.PermissionAspectUtil;
import com.yunzhupaas.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/15 17:12
*/
@Slf4j
@Aspect
@Component
public class PermissionAdminAspect implements PermissionAdminBase{
/**
* 分级管理切点
*/
@Pointcut("within(com.yunzhupaas.*.controller.*) && @annotation(com.yunzhupaas.annotation.OrganizeAdminIsTrator)")
public void pointcut() {
}
/**
* 分级管理切点
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return PermissionAdminBase.permissionCommon(pjp, this);
}
@Override
public Boolean detailPermission(ProceedingJoinPoint pjp, String operatorUserId, String methodName){
switch (methodName) {
case PermissionConstant.METHOD_SAVE:
case PermissionConstant.METHOD_SAVE_BATCH:
return true;
case PermissionConstant.METHOD_UPDATE:
//判断是否有当前组织的修改权限
String organizeId = String.valueOf(pjp.getArgs()[0]);
return PermissionAspectUtil.containPermission(organizeId, operatorUserId, methodName);
default:
return false;
}
}
}

View File

@@ -0,0 +1,40 @@
package com.yunzhupaas.aop;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.util.UserProvider;
import org.aspectj.lang.ProceedingJoinPoint;
public interface PermissionAdminBase{
/**
* 详细的权限判断
* @param pjp AOP切点参数
* @param operatorUserId 操作者对象
*/
Boolean detailPermission(ProceedingJoinPoint pjp, String operatorUserId, String methodName);
/**
* 管理者权限判断
*
*/
static Object permissionCommon(ProceedingJoinPoint pjp, PermissionAdminBase permissionAdminBase) throws Throwable {
// 获取用户信息
UserInfo operatorUser = UserProvider.getUser();
// 是否是管理员
if(operatorUser.getIsAdministrator()){
return pjp.proceed();
}else {
// 获取方法名
String methodName = pjp.getSignature().getName();
// 具体方法权限
if(permissionAdminBase.detailPermission(pjp, operatorUser.getUserId(),methodName)){
return pjp.proceed();
}
}
return ActionResult.fail(MsgCode.FA021.get());
}
}

View File

@@ -0,0 +1,120 @@
package com.yunzhupaas.aop;
import com.yunzhupaas.constant.PermissionConstant;
import com.yunzhupaas.permission.entity.OrganizeEntity;
import com.yunzhupaas.permission.model.organize.OrganizeCrForm;
import com.yunzhupaas.permission.model.organize.OrganizeDepartCrForm;
import com.yunzhupaas.permission.model.organize.OrganizeDepartUpForm;
import com.yunzhupaas.permission.model.organize.OrganizeUpForm;
import com.yunzhupaas.permission.service.OrganizeService;
import com.yunzhupaas.util.PermissionAspectUtil;
import com.yunzhupaas.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.StringJoiner;
/**
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/15 17:12
*/
@Slf4j
@Aspect
@Component
public class PermissionOrgAspect implements PermissionAdminBase {
@Autowired
private OrganizeService organizeService;
/**
* 分级管理切点
*/
@Pointcut("within(com.yunzhupaas.*.controller.*) && @annotation(com.yunzhupaas.annotation.OrganizePermission)")
public void pointcut() {
}
/**
* 分级管理切点
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return PermissionAdminBase.permissionCommon(pjp, this);
}
@Override
public Boolean detailPermission(ProceedingJoinPoint pjp, String operatorUserId, String methodName) {
switch (methodName) {
case PermissionConstant.METHOD_CREATE:
return PermissionAspectUtil.getPermitByOrgIds(
// 操作目标对象表单对象
((OrganizeCrForm) pjp.getArgs()[0]).getParentId(),
operatorUserId,
PermissionConstant.METHOD_CREATE);
case PermissionConstant.METHOD_CREATE_DEPARTMENT:
return PermissionAspectUtil.getPermitByOrgIds(
// 操作目标对象表单对象
((OrganizeDepartCrForm) pjp.getArgs()[0]).getParentId(),
operatorUserId,
PermissionConstant.METHOD_CREATE);
case PermissionConstant.METHOD_UPDATE:
// 当前组织id
String orgId = (String) pjp.getArgs()[0];
// 当前组织父级id
OrganizeEntity info = organizeService.getInfo(orgId);
// 修改后的id
OrganizeUpForm organizeUpForm = (OrganizeUpForm) pjp.getArgs()[1];
StringJoiner stringJoiner = new StringJoiner(",");
stringJoiner.add(orgId);
if (!organizeUpForm.getParentId().equals(info.getParentId()) && !"-1".equals(info.getParentId())) {
stringJoiner.add(info.getParentId());
}
if (!organizeUpForm.getParentId().equals(info.getParentId()) && !"-1".equals(organizeUpForm.getParentId())) {
stringJoiner.add(organizeUpForm.getParentId());
}
return PermissionAspectUtil.getPermitByOrgIds(
// 操作目标对象ID
stringJoiner.toString(),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
case PermissionConstant.METHOD_UPDATE_DEPARTMENT:
// 当前组织id
String orgIds = (String) pjp.getArgs()[0];
// 当前组织父级id
OrganizeEntity infos = organizeService.getInfo(orgIds);
// 修改后的id
OrganizeDepartUpForm organizeDepartUpForm = (OrganizeDepartUpForm) pjp.getArgs()[1];
StringJoiner stringJoiners = new StringJoiner(",");
stringJoiners.add(orgIds);
if (!organizeDepartUpForm.getParentId().equals(infos.getParentId())) {
stringJoiners.add(infos.getParentId());
stringJoiners.add(organizeDepartUpForm.getParentId());
}
return PermissionAspectUtil.getPermitByOrgIds(
// 操作目标对象ID
stringJoiners.toString(),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
case PermissionConstant.METHOD_DELETE:
case PermissionConstant.METHOD_DELETE_DEPARTMENT:
return PermissionAspectUtil.getPermitByOrgIds(
// 操作目标对象ID
pjp.getArgs()[0].toString(),
operatorUserId,
PermissionConstant.METHOD_DELETE);
default:
return false;
}
}
}

View File

@@ -0,0 +1,92 @@
package com.yunzhupaas.aop;
import com.yunzhupaas.constant.PermissionConstant;
import com.yunzhupaas.permission.entity.PositionEntity;
import com.yunzhupaas.permission.model.position.PositionCrForm;
import com.yunzhupaas.permission.model.position.PositionUpForm;
import com.yunzhupaas.permission.service.OrganizeService;
import com.yunzhupaas.permission.service.PositionService;
import com.yunzhupaas.util.PermissionAspectUtil;
import com.yunzhupaas.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/15 17:12
*/
@Slf4j
@Aspect
@Component
public class PermissionPositionAspect implements PermissionAdminBase{
@Autowired
private PositionService positionService;
@Autowired
private OrganizeService organizeService;
/**
* 分级管理切点
*/
@Pointcut("within(com.yunzhupaas.*.controller.*) && @annotation(com.yunzhupaas.annotation.PositionPermission)")
public void pointcut() {
}
/**
* 分级管理切点
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return PermissionAdminBase.permissionCommon(pjp, this);
}
@Override
public Boolean detailPermission(ProceedingJoinPoint pjp, String operatorUserId, String methodName) {
switch (methodName){
case PermissionConstant.METHOD_CREATE:
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
((PositionCrForm) pjp.getArgs()[0]).getOrganizeId(),
operatorUserId,
methodName);
case PermissionConstant.METHOD_UPDATE:
// 得到岗位信息后,判断是否有修改前的权限
PositionEntity info = positionService.getInfo(((String) pjp.getArgs()[0]));
if (PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
info.getOrganizeId(),
operatorUserId,
methodName)) {
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
((PositionUpForm) pjp.getArgs()[1]).getOrganizeId(),
operatorUserId,
methodName);
}
return false;
case PermissionConstant.METHOD_DELETE:
// 获取岗位所关联的组织ID字符串
String positionId = String.valueOf(pjp.getArgs()[0]);
String orgIds = organizeService.getInfo(positionService.getInfo(positionId).getOrganizeId()).getId();
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
orgIds,
operatorUserId,
PermissionConstant.METHOD_DELETE);
default:
return false;
}
}
}

View File

@@ -0,0 +1,153 @@
package com.yunzhupaas.aop;
import com.yunzhupaas.constant.PermissionConstant;
import com.yunzhupaas.permission.entity.OrganizeRelationEntity;
import com.yunzhupaas.permission.entity.RoleEntity;
import com.yunzhupaas.permission.model.role.RoleCrForm;
import com.yunzhupaas.permission.model.role.RoleUpForm;
import com.yunzhupaas.permission.service.OrganizeRelationService;
import com.yunzhupaas.permission.service.PositionService;
import com.yunzhupaas.permission.service.RoleService;
import com.yunzhupaas.util.PermissionAspectUtil;
import com.yunzhupaas.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;
/**
* 角色操作权限
*
* @author 云筑产品开发平台组
* @version V3.2.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/2/10
*/
@Slf4j
@Aspect
@Component
public class PermissionRoleAspect implements PermissionAdminBase {
@Autowired
private RoleService roleService;
@Autowired
private OrganizeRelationService organizeRelationService;
/**
* 分级管理切点
*/
@Pointcut("within(com.yunzhupaas.*.controller.*) && @annotation(com.yunzhupaas.annotation.RolePermission)")
public void pointcut() {
}
/**
* 分级管理切点
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return PermissionAdminBase.permissionCommon(pjp, this);
}
@Override
public Boolean detailPermission(ProceedingJoinPoint pjp, String operatorUserId, String methodName) {
boolean flag = false;
switch (methodName) {
case PermissionConstant.METHOD_CREATE:
RoleCrForm roleCrForm = (RoleCrForm) pjp.getArgs()[0];
if (!checkAdminGlobal(roleCrForm.getGlobalMark())) {
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
getOrganize(roleCrForm.getOrganizeIdsTree()),
operatorUserId,
PermissionConstant.METHOD_CREATE);
}
return true;
case PermissionConstant.METHOD_UPDATE:
RoleUpForm roleUpForm = (RoleUpForm) pjp.getArgs()[0];
// 非管理员情况下
if (!checkAdminGlobal(roleUpForm.getGlobalMark())) {
// 得到以前的组织id
String roleId = (String) pjp.getArgs()[1];
List<String> relationListByRoleId = organizeRelationService.getRelationListByRoleId(roleId).stream().map(OrganizeRelationEntity::getOrganizeId).collect(Collectors.toList());
StringJoiner stringJoiners = new StringJoiner(",");
relationListByRoleId.forEach(t -> {
stringJoiners.add(t);
});
if (PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
stringJoiners.toString(),
operatorUserId,
PermissionConstant.METHOD_UPDATE)) {
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
getOrganize(roleUpForm.getOrganizeIdsTree()),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
}
return false;
}
return true;
case PermissionConstant.METHOD_DELETE:
String roleId = pjp.getArgs()[0].toString();
RoleEntity roleEntity = roleService.getInfo(roleId);
// 获取角色关联的组织信息
List<OrganizeRelationEntity> relationListByRoleId = organizeRelationService.getRelationListByRoleId(roleId);
StringBuilder orgId = new StringBuilder();
relationListByRoleId.stream().forEach(t->{
orgId.append(t.getOrganizeId() + ",");
});
if (roleEntity != null && !checkAdminGlobal(roleEntity.getGlobalMark())) {
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
orgId.toString(),
operatorUserId,
PermissionConstant.METHOD_DELETE);
}
return true;
default:
break;
}
return true;
}
/**
* 转成组织id字符串
* @param orgIdsTree
* @return
*/
private String getOrganize(List<List<String>> orgIdsTree) {
StringBuilder orgIds = new StringBuilder();
for (List<String> list : orgIdsTree) {
if (list.size() > 0) {
String orgId = list.get(list.size() - 1);
orgIds.append(orgId + ",");
}
}
return orgIds.toString();
}
/**
* 全局角色只能超管来操作
*
* @param globalMark 全局标识 1全局 0: 非全局
*/
private Boolean checkAdminGlobal(Integer globalMark) {
if (globalMark != null && globalMark == 1) {
return UserProvider.getUser().getIsAdministrator();
}
return false;
}
}

View File

@@ -0,0 +1,150 @@
package com.yunzhupaas.aop;
import com.yunzhupaas.constant.PermissionConst;
import com.yunzhupaas.constant.PermissionConstant;
import com.yunzhupaas.permission.entity.OrganizeRelationEntity;
import com.yunzhupaas.permission.entity.UserRelationEntity;
import com.yunzhupaas.permission.model.user.form.UserCrForm;
import com.yunzhupaas.permission.model.user.form.UserUpForm;
import com.yunzhupaas.permission.model.userrelation.UserRelationForm;
import com.yunzhupaas.permission.service.*;
import com.yunzhupaas.util.PermissionAspectUtil;
import com.yunzhupaas.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;
/**
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/15 17:12
*/
@Slf4j
@Aspect
@Component
public class PermissionUserAspect implements PermissionAdminBase{
@Autowired
private OrganizeRelationService organizeRelationService;
@Autowired
private PositionService positionService;
@Autowired
private UserRelationService userRelationService;
/**
* 分级管理切点
*/
@Pointcut("within(com.yunzhupaas.*.controller.*) && @annotation(com.yunzhupaas.annotation.UserPermission)")
public void pointcut() {
}
/**
* 分级管理切点
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return PermissionAdminBase.permissionCommon(pjp, this);
}
@Override
public Boolean detailPermission(ProceedingJoinPoint pjp, String operatorUserId, String methodName) {
switch (methodName){
case PermissionConstant.METHOD_CREATE:
UserCrForm userCrForm = (UserCrForm) pjp.getArgs()[0];
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
userCrForm.getOrganizeId(),
operatorUserId,
PermissionConstant.METHOD_CREATE);
case PermissionConstant.METHOD_UPDATE:
// 得到修改的用户以前的信息
String userId = (String) pjp.getArgs()[0];
List<String> collect = userRelationService.getListByUserId(userId, PermissionConst.ORGANIZE).stream().map(UserRelationEntity::getObjectId).collect(Collectors.toList());
StringJoiner stringJoiner = new StringJoiner(",");
collect.forEach(t -> {
stringJoiner.add(t);
});
if (PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
stringJoiner.toString(),
operatorUserId,
PermissionConstant.METHOD_UPDATE)) {
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
((UserUpForm) pjp.getArgs()[1]).getOrganizeId(),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
}
return false;
case PermissionConstant.METHOD_MODIFY_PW:
return PermissionAspectUtil.getPermitByUserId(
// 操作目标对象的ID
String.valueOf(pjp.getArgs()[0]),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
case PermissionConstant.METHOD_DELETE:
return PermissionAspectUtil.getPermitByUserId(
// 操作目标对象的ID
pjp.getArgs()[0].toString(),
operatorUserId,
PermissionConstant.METHOD_DELETE);
case PermissionConstant.METHOD_SAVE:
String objId = pjp.getArgs()[0].toString();
UserRelationForm userRelationForm = (UserRelationForm)pjp.getArgs()[1];
List<String> orgIds = new ArrayList<>();
if(userRelationForm.getObjectType().equals(PermissionConst.ROLE)){
// 角色目前修改为只有超管才能够修改
if(UserProvider.getUser().getIsAdministrator()){
return true;
}
orgIds.addAll(organizeRelationService.getRelationListByRoleId(objId).stream().map(OrganizeRelationEntity::getOrganizeId).collect(Collectors.toList()));
return PermissionAspectUtil.getPermitByOrgId(
// 操作目标对象组织ID集合
String.join(",", orgIds),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
}else {
if(userRelationForm.getObjectType().equals(PermissionConst.GROUP)) {
return true;
}
if(userRelationForm.getObjectType().equals(PermissionConst.POSITION)) {
orgIds.add(positionService.getInfo(objId).getOrganizeId());
}
return PermissionAspectUtil.getPermitByOrgId(
String.join(",", orgIds),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
}
case PermissionConstant.METHOD_DELETE_SOCIALS:
if(pjp.getArgs()[0].toString().equals(operatorUserId)){return true;}
return PermissionAspectUtil.getPermitByUserId(
// 操作目标对象的ID
pjp.getArgs()[0].toString(),
operatorUserId,
PermissionConstant.METHOD_UPDATE);
default:
return false;
}
}
}

View File

@@ -0,0 +1,239 @@
package com.yunzhupaas.aop;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.yunzhupaas.base.LogSortEnum;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.config.ConfigValueUtil;
import com.yunzhupaas.entity.LogEntity;
import com.yunzhupaas.service.LogService;
import com.yunzhupaas.util.*;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.yunzhupaas.annotation.HandleLog;
import org.springframework.web.multipart.MultipartFile;
import java.lang.reflect.Method;
import java.util.Date;
/**
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/15 17:12
*/
@Slf4j
@Aspect
@Component
@Order(2)
public class RequestLogAspect {
@Autowired
private ConfigValueUtil configValueUtil;
@Autowired
private LogService logService;
@Pointcut("within(com.yunzhupaas.*.controller.* || com.yunzhupaas.controller.*)")// && !within(com.yunzhupaas.controller.UtilsController)
public void requestLog() {
}
@Around("requestLog()")
public Object doAroundService(ProceedingJoinPoint pjp) throws Throwable {
long startTime = System.currentTimeMillis();
Object obj = pjp.proceed();
if(ServletUtil.getRequest() == null){
return obj;
}
long costTime = System.currentTimeMillis() - startTime;
UserInfo userInfo = UserProvider.getUser();
if(userInfo.getUserId() != null && (!configValueUtil.isMultiTenancy() || TenantHolder.getLocalTenantCache() != null)) {
// 得到请求参数
Object[] args = pjp.getArgs();
Signature signature = pjp.getSignature();
printLog(userInfo, costTime, obj, args, signature);
try {
// 判断是否需要操作日志
MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
// 得到请求方法
Method method = methodSignature.getMethod();
HandleLog methodAnnotation = method.getAnnotation(HandleLog.class);
if (methodAnnotation != null) {
String moduleName = methodAnnotation.moduleName();
String requestMethod = methodAnnotation.requestMethod();
handleLog(userInfo, costTime, obj, moduleName, requestMethod, args, signature);
}
} catch (Exception e) {
log.error("记录操作日志发生错误:" + e.getMessage());
}
}
return obj;
}
/**
* 请求日志
*
* @param userInfo
* @param costTime
*/
private void printLog(UserInfo userInfo, long costTime, Object obj, Object[] args, Signature signature) {
LogEntity entity = new LogEntity();
entity.setId(RandomUtil.uuId());
entity.setType(LogSortEnum.Request.getCode());
entity.setUserId(userInfo.getUserId());
entity.setUserName(userInfo.getUserName() + "/" + userInfo.getUserAccount());
//请求耗时
entity.setRequestDuration((int) costTime);
entity.setRequestUrl(ServletUtil.getRequest().getServletPath());
entity.setRequestMethod(ServletUtil.getRequest().getMethod());
String ipAddr = IpUtil.getIpAddr();
entity.setIpAddress(ipAddr);
entity.setIpAddressName(IpUtil.getIpCity(ipAddr));
entity.setCreatorTime(new Date());
UserAgent userAgent = UserAgentUtil.parse(ServletUtil.getUserAgent());
if (userAgent != null) {
entity.setPlatForm(userAgent.getPlatform().getName() + " " + userAgent.getOsVersion());
entity.setBrowser(userAgent.getBrowser().getName() + " " + userAgent.getVersion());
}
String declaringTypeName = signature.getDeclaringTypeName();
String name = signature.getName();
entity.setRequestTarget(declaringTypeName + "." + name);
entity.setJsons(obj + "");
StringBuilder stringBuilder = new StringBuilder();
for (Object o : args) {
// 如果是MultipartFile则为导入
if (o instanceof MultipartFile) {
stringBuilder.append("{\"originalFilename\":\"" + ((MultipartFile) o).getOriginalFilename() + "\",");
stringBuilder.append("\"contentType\":\"" + ((MultipartFile) o).getContentType() + "\",");
stringBuilder.append("\"name\":\"" + ((MultipartFile) o).getName() + "\",");
stringBuilder.append("\"resource\":\"" + ((MultipartFile) o).getResource() + "\",");
stringBuilder.append("\"size\":\"" + ((MultipartFile) o).getSize() + "\"}");
}
}
if (stringBuilder.length() > 0) {
entity.setRequestParam(stringBuilder.toString());
} else {
entity.setRequestParam(JsonUtil.getObjectToString(args));
}
ThreadPoolExecutorUtil.getExecutor().execute(()->{
logService.save(entity);
});
}
/**
* 添加操作日志
*
* @param userInfo 用户信息
* @param costTime 操作耗时
* @param obj 请求结果
* @param moduleName 模块名称
* @param requestMethod 请求方法
* @param args 请求参数
*/
private void handleLog(UserInfo userInfo, long costTime, Object obj, String moduleName, String requestMethod, Object[] args, Signature signature) {
LogEntity entity = new LogEntity();
entity.setId(RandomUtil.uuId());
entity.setType(LogSortEnum.Operate.getCode());
entity.setUserId(userInfo.getUserId());
entity.setUserName(userInfo.getUserName() + "/" + userInfo.getUserAccount());
//请求耗时
entity.setRequestDuration((int) costTime);
entity.setRequestMethod(ServletUtil.getRequest().getMethod());
entity.setRequestUrl(ServletUtil.getRequest().getServletPath());
String ipAddr = IpUtil.getIpAddr();
entity.setIpAddress(ipAddr);
entity.setIpAddressName(IpUtil.getIpCity(ipAddr));
entity.setCreatorTime(new Date());
// 请求设备
UserAgent userAgent = UserAgentUtil.parse(ServletUtil.getUserAgent());
if (userAgent != null) {
entity.setPlatForm(userAgent.getPlatform().getName() + " " + userAgent.getOsVersion());
entity.setBrowser(userAgent.getBrowser().getName() + " " + userAgent.getVersion());
}
// 操作模块
entity.setModuleName(moduleName);
String declaringTypeName = signature.getDeclaringTypeName();
String name = signature.getName();
entity.setRequestTarget(declaringTypeName + "." + name);
// 操作记录
StringBuilder stringBuilder = new StringBuilder();
for (Object o : args) {
// 如果是MultipartFile则为导入
if (o instanceof MultipartFile) {
stringBuilder.append("{\"originalFilename\":\"" + ((MultipartFile) o).getOriginalFilename() + "\",");
stringBuilder.append("\"contentType\":\"" + ((MultipartFile) o).getContentType() + "\",");
stringBuilder.append("\"name\":\"" + ((MultipartFile) o).getName() + "\",");
stringBuilder.append("\"resource\":\"" + ((MultipartFile) o).getResource() + "\",");
stringBuilder.append("\"size\":\"" + ((MultipartFile) o).getSize() + "\"}");
}
}
if (stringBuilder.length() > 0) {
entity.setRequestParam(stringBuilder.toString());
} else {
entity.setRequestParam(JsonUtil.getObjectToString(args));
}
entity.setJsons(obj + "");
ThreadPoolExecutorUtil.getExecutor().execute(()->{
logService.save(entity);
});
}
/// 后面可能会用
// /**
// * 判断是否为导入导出
// *
// * @return
// */
// private String getRequestMethod() {
// //得到请求方式
// String methodType = ServletUtil.getRequest().getMethod();
// // 得到当前请求的尾缀
// String endWith = null;
// String servletPath = ServletUtil.getServletPath();
// if (StringUtil.isNotEmpty(servletPath)) {
// String[] path = servletPath.split("/");
// int length = path.length;
// if (length > 5) {
// endWith = path[length - 2] + "/" + path[length - 1];
// }
// }
// // 如果是GET请求且请求后缀是'/Action/Export'则判定为导出
// if (HandleMethodEnum.GET.getRequestType().equals(methodType)) {
// methodType = "Action/Export".equals(endWith) ? "EXPORT" : "GET";
// } else if (HandleMethodEnum.POST.getRequestType().equals(methodType)) {
// methodType = "Action/Import".equals(endWith) ? "IMPORT" : "GET";
// }
// return methodType;
// }
// /**
// * 判断是否为导入导出
// *
// * @return
// */
// private String getRequestModuleName() {
// //得到Url
// String requestURI = ServletUtil.getRequest().getRequestURI();
// // 取模块名
// if (StringUtil.isNotEmpty(requestURI)) {
// String[] split = requestURI.split("/");
// if (split.length > 2) {
// String url = split[1];
// // 得到所在模块
// String moduleName = HandleModuleEnum.getModuleByURL(url);
// return moduleName;
// }
// }
// return "";
// }
///
}

View File

@@ -0,0 +1,47 @@
package com.yunzhupaas.aop;
import com.yunzhupaas.util.RedisUtil;
import com.yunzhupaas.util.ServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.Set;
/**
* 可视化开发缓存数据处理
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司
* @date 2024/3/15 17:12
*/
@Slf4j
//@Aspect
//@Component
public class VisiualOpaAspect {
@Autowired
private RedisUtil redisUtil;
@Pointcut("(execution(* com.yunzhupaas.onlinedev.controller.VisualdevModelDataController.*(..))) || execution(* com.yunzhupaas.onlinedev.controller.VisualdevModelAppController.*(..)))" +
"|| execution(* com.yunzhupaas.generater.controller.VisualdevGenController.*(..)))")
public void visiualOpa() {
}
@After("visiualOpa()")
public void doAroundService(){
String method=ServletUtil.getRequest().getMethod().toLowerCase();
if("put".equals(method)||"delete".equals(method)||"post".equals(method)){
Set<String> allKey=new HashSet<>(16);
allKey.addAll(redisUtil.getAllVisiualKeys());
for(String key:allKey){
redisUtil.remove(key);
}
}
}
}

View File

@@ -0,0 +1,74 @@
package com.yunzhupaas.constant;
/**
* 分级管理常量
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-11-01
*/
public class PermissionConstant {
/**
* 创建方法
*/
public static final String METHOD_CREATE = "create";
/**
* 编辑方法
*/
public static final String METHOD_UPDATE = "update";
/**
* 删除方法
*/
public static final String METHOD_DELETE = "delete";
/**
* 更新状态
*/
public static final String METHOD_DISABLE = "disable";
/**
* 创建方法
*/
public static final String METHOD_CREATE_DEPARTMENT = "createDepartment";
/**
* 编辑方法
*/
public static final String METHOD_UPDATE_DEPARTMENT = "updateDepartment";
/**
* 删除方法
*/
public static final String METHOD_DELETE_DEPARTMENT = "deleteDepartment";
/**
* 保存方法
*/
public static final String METHOD_SAVE = "save";
public static final String METHOD_SAVE_BATCH = "saveBatch";
/**
* 修改用户密码
*/
public static final String METHOD_MODIFY_PW = "modifyPassword";
/**
* 拼接方法名
*/
public static final String GET_METHOD_CREATE = "Add";
public static final String GET_METHOD_UPDATE = "Edit";
public static final String GET_METHOD_DELETE = "Delete";
public static final String GET_METHOD_SELECT = "Select";
public static final String GET_METHOD_THIS = "getThisLayer";
public static final String GET_METHOD_SUB = "getSubLayer";
/**
* 解除绑定方法
*/
public static final String METHOD_DELETE_SOCIALS = "deleteSocials";
}

View File

@@ -0,0 +1,102 @@
package com.yunzhupaas.filter;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.filter.SaFilterAuthStrategy;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.yunzhupaas.base.ActionResultCode;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.consts.AuthConsts;
import com.yunzhupaas.properties.GatewayWhite;
import com.yunzhupaas.util.IpUtil;
import com.yunzhupaas.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 网关验证token
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-03-24
*/
@Slf4j
@Configuration
public class AuthFilter {
@Autowired
private GatewayWhite gatewayWhite;
@Autowired
private SaFilterAuthStrategy defaultBeforeAuthStrategy;
// 注册 Sa-Token全局过滤器
@Bean
public SaServletFilter getSaReactorFilter() {
return new SaServletFilter()
// 拦截地址
.addInclude("/**")
.setExcludeList(gatewayWhite.excludeUrl)
// 鉴权方法:每次访问进入
.setAuth(obj -> {
if(log.isInfoEnabled()){
log.info("请求路径: {}", SaHolder.getRequest().getRequestPath());
}
//拦截路径
SaRouter.match(gatewayWhite.blockUrl).match(o -> {
//禁止访问URL 排除白名单
String ip = getIpAddr();
for (String o1 : gatewayWhite.whiteIp) {
if(ip.startsWith(o1)){
return false;
}
}
log.info("非白名单IP访问限制接口{}, {}", SaHolder.getRequest().getRequestPath(), ip);
return true;
}).back(MsgCode.AD101.get());
//测试不验证 鉴权服务重启测试模式不清除Token就够了
//SaRouter.match((r)->"true".equals(configValueUtil.getTestVersion())).stop();
//白名单不拦截
SaRouter.match(gatewayWhite.whiteUrl).stop();
//内部请求不拦截
SaRouter.match(t->{
String innerToken = SaHolder.getRequest().getHeader(AuthConsts.INNER_TOKEN_KEY);
return UserProvider.isValidInnerToken(innerToken);
}).stop();
// 登录校验 -- 校验多租户管理模块TOKEN
//SaRouter.match("/api/tenant/**", r -> {
// SaManager.getStpLogic(AuthConsts.ACCOUNT_TYPE_TENANT).checkLogin();
//}).stop();
// 登录校验 -- 拦截所有路由
SaRouter.match("/**", r -> {
StpUtil.checkLogin();
}).stop();
}).setError(e -> {
SaHolder.getResponse().addHeader("Content-Type","application/json; charset=utf-8");
if(e instanceof NotLoginException){
return SaResult.error(ActionResultCode.SessionOverdue.getMessage()).setCode(ActionResultCode.SessionOverdue.getCode());
}
log.error(e.getMessage(), e);
return SaResult.error(MsgCode.AD102.get()).setCode(ActionResultCode.Exception.getCode());
})
// 前置函数:在每次认证函数之前执行
.setBeforeAuth(defaultBeforeAuthStrategy);
}
public static String getIpAddr() {
return IpUtil.getIpAddr();
}
}

View File

@@ -0,0 +1,114 @@
package com.yunzhupaas.filter;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.context.model.SaRequest;
import cn.dev33.satoken.context.model.SaResponse;
import cn.dev33.satoken.filter.SaFilterAuthStrategy;
import cn.dev33.satoken.router.SaRouter;
import com.yunzhupaas.properties.MvcSecurityProperties;
import com.yunzhupaas.util.Constants;
import com.yunzhupaas.util.IpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.util.ObjectUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.net.URI;
/**
* mvc配置
*
* @author 云筑产品开发平台组
* @version V5.2.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2025-01-21
*/
@Slf4j
@Configuration(proxyBeanMethods = false)
public class MvcSecurityConfig {
private static final String DOMAIN_FORMAT = "%s://%s";
@Autowired
private MvcSecurityProperties mvcSecurityProperties;
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
// 允许发送凭据
config.setAllowCredentials(true);
//允许任意域名跨域访问接口
config.setAllowedOrigins(mvcSecurityProperties.getCors().getAllowedOrigins());
config.setAllowedOriginPatterns(mvcSecurityProperties.getCors().getAllowedOriginPatterns());
// 允许所有头部信息
config.setAllowedHeaders(mvcSecurityProperties.getCors().getAllowedHeaders());
// 允许所有请求方法
config.setAllowedMethods(mvcSecurityProperties.getCors().getAllowedMethods());
// 应用于所有路径
source.registerCorsConfiguration("/**", config);
return new MyCorsFilter(source);
}
@Bean
@ConditionalOnMissingBean
public SaFilterAuthStrategy defaultBeforeAuthStrategy() {
CorsConfiguration csrfConfiguration;
if(!mvcSecurityProperties.getCsrfOrigins().isEmpty() || !mvcSecurityProperties.getCsrfOriginsPatterns().isEmpty()) {
csrfConfiguration = new CorsConfiguration();
csrfConfiguration.setAllowedOrigins(mvcSecurityProperties.getCsrfOrigins());
csrfConfiguration.setAllowedOriginPatterns(mvcSecurityProperties.getCsrfOriginsPatterns());
} else {
csrfConfiguration = null;
}
return obj -> {
SaRequest request = SaHolder.getRequest();
// ---------- 设置跨域响应头 ----------
SaResponse response = SaHolder.getResponse();
if(!ObjectUtils.isEmpty(mvcSecurityProperties.getHeaders().getServerName())){
response.setServer(mvcSecurityProperties.getHeaders().getServerName());
}
if(!ObjectUtils.isEmpty(mvcSecurityProperties.getHeaders().getXFrameOptions()) && !MvcSecurityProperties.XFrameOptionsMode.DISABLED.equals(mvcSecurityProperties.getHeaders().getXFrameOptions())){
response.setHeader(MvcSecurityProperties.HEADER_XFRAME_OPTIONS, mvcSecurityProperties.getHeaders().getXFrameOptions().getMode());
}
if(!ObjectUtils.isEmpty(mvcSecurityProperties.getHeaders().getXXssProtection()) && !MvcSecurityProperties.XXssProtectionMode.DISABLED.equals(mvcSecurityProperties.getHeaders().getXXssProtection())){
response.setHeader(MvcSecurityProperties.HEADER_XSS_PROTECTION, mvcSecurityProperties.getHeaders().getXXssProtection().getMode());
}
if(!ObjectUtils.isEmpty(mvcSecurityProperties.getHeaders().getXContentTypeOptions()) && !MvcSecurityProperties.XContentTypeOptions.DISABLED.equals(mvcSecurityProperties.getHeaders().getXContentTypeOptions())){
response.setHeader(MvcSecurityProperties.HEADER_Content_Type_Options, mvcSecurityProperties.getHeaders().getXContentTypeOptions().getMode());
}
if(csrfConfiguration != null){
String referer = request.getHeader("referer");
if(!ObjectUtils.isEmpty(referer)) {
URI uri = URI.create(referer);
String refererDomain = String.format(DOMAIN_FORMAT, uri.getScheme(), uri.getAuthority());
String allowOrign = csrfConfiguration.checkOrigin(refererDomain);
if(ObjectUtils.isEmpty(allowOrign)){
log.error("Reject CSRF Request: {}, {}, {}, {}", request.getRequestPath(), referer, IpUtil.getIpAddr(), request.getHeader(Constants.AUTHORIZATION));
response.setStatus(HttpStatus.FORBIDDEN.value());
SaRouter.back("Invalid CSRF Request");
}
}
}
};
}
@Order(-110)
public static class MyCorsFilter extends CorsFilter {
public MyCorsFilter(CorsConfigurationSource configSource) {
super(configSource);
}
}
}

View File

@@ -0,0 +1,166 @@
package com.yunzhupaas.util;
import com.yunzhupaas.constant.PermissionConstant;
import com.yunzhupaas.permission.entity.OrganizeAdministratorEntity;
import com.yunzhupaas.permission.entity.OrganizeEntity;
import com.yunzhupaas.permission.service.OrganizeAdministratorService;
import com.yunzhupaas.permission.service.OrganizeService;
import com.yunzhupaas.util.context.SpringContext;
/**
* 分级管理工具类
*
* @author 云筑产品开发平台组
* @version V3.1.0
* @copyright 深圳市乐程软件有限公司http://www.szlecheng.cn
* @date 2024-11-01
*/
public class PermissionAspectUtil {
private static final OrganizeService organizeService;
private static final OrganizeAdministratorService organizeAdministratorService;
static {
organizeService = SpringContext.getBean(OrganizeService.class);
organizeAdministratorService = SpringContext.getBean(OrganizeAdministratorService.class);
}
/**
* 判断是否存在修改前所在的组织的操作
*
* @param targetUserId 被操作目标对象ID
* @param operatorUsrId 操作者ID
* @param methodName 操作方法
*/
public static Boolean getPermitByUserId(String targetUserId, String operatorUsrId, String methodName) {
for(OrganizeEntity organizeEntity : organizeService.getAllOrgByUserId(targetUserId)){
if (PermissionAspectUtil.containPermission(organizeEntity.getId(), operatorUsrId, methodName)) {
return true;
}
}
return false;
}
/**
* 判断 操作者是否含有该组织的操作权限
*
* @param organizeId 被操作者所在组织ID
* @param operatorUserId 当前操作者用户对象ID
* @param methodName 操作类型:创建、编辑、删除
*/
public static boolean containPermission(String organizeId, String operatorUserId, String methodName) {
OrganizeEntity organizeEntity = organizeService.getInfo(organizeId);
if (organizeEntity != null) {
// 当前用户的所有分级权限
OrganizeAdministratorEntity adminEntity = organizeAdministratorService.getOne(operatorUserId, organizeId);
if(permissionFlag(adminEntity, methodName, true)){
return true;
}
// 查看父级的组织权限是否含有子集权限
return parentPermission(organizeEntity.getParentId(), methodName, operatorUserId);
}
return false;
}
/**
* 判断是否存在修改前所在的组织的操作(拥有所有的组织权限才能操作)
*
* @param organizeIds 组织ID集合字符串
* @param operatorUsrId 操作者ID
* @param methodName 操作方法
*/
public static Boolean getPermitByOrgIds(String organizeIds, String operatorUsrId, String methodName) {
boolean flag = true;
for (String organizeId : organizeIds.split(",")) {
flag = true;
flag = PermissionAspectUtil.containPermission(organizeId, operatorUsrId, methodName);
if (!flag) {
break;
}
}
return flag;
}
/**
* 判断是否可修改所在的组织的操作(只要有一个权限即可操作)
*
* @param organizeIds 组织ID集合字符串
* @param operatorUsrId 操作者ID
* @param methodName 操作方法
*/
public static Boolean getPermitByOrgId(String organizeIds, String operatorUsrId, String methodName) {
for (String organizeId : organizeIds.split(",")) {
if (PermissionAspectUtil.containPermission(organizeId,operatorUsrId, methodName)) {
return true;
}
}
return false;
}
/**
* 判断组织新建权限(从父级给的子集新建操作权限)
*
* @param organizeParentId
* @param methodName
* @param userId
* @return
*/
private static boolean parentPermission(String organizeParentId, String methodName, String userId) {
// 得到父级组织
OrganizeEntity parentOrganizeEntity = organizeService.getInfo(organizeParentId);
if (parentOrganizeEntity != null) {
// 得到父级的权限
if(permissionFlag(organizeAdministratorService.getOne(userId, parentOrganizeEntity.getId()), methodName, false)){
return true;
}
// 当前正在判断的组织已经是顶级则无需递归
if (!"-1".equals(parentOrganizeEntity.getParentId())) {
return parentPermission(parentOrganizeEntity.getParentId(), methodName, userId);
}
}
return false;
}
/**
* 判断是否具有权限
* @param adminEntity 分级管理对象
* @param methodName 操作类型:创建、编辑、删除
* @param thisFlag true:当前组织 false:子组织
*/
private static boolean permissionFlag(OrganizeAdministratorEntity adminEntity, String methodName, Boolean thisFlag) {
if (adminEntity != null) {
String methodType = "";
// 存在则验证是否有当前组织分级管理
try {
switch (methodName) {
case PermissionConstant.METHOD_CREATE:
// 创建权限
methodType = PermissionConstant.GET_METHOD_CREATE;
break;
case PermissionConstant.METHOD_UPDATE:
// 编辑权限
methodType = PermissionConstant.GET_METHOD_UPDATE;
break;
case PermissionConstant.METHOD_DELETE:
// 删除权限
methodType = PermissionConstant.GET_METHOD_DELETE;
break;
default:
break;
}
// 拼接方法名
String method = (thisFlag ? PermissionConstant.GET_METHOD_THIS : PermissionConstant.GET_METHOD_SUB) + methodType;
String selectMethod = (thisFlag ? PermissionConstant.GET_METHOD_THIS : PermissionConstant.GET_METHOD_SUB) + PermissionConstant.GET_METHOD_SELECT;
if ((int)OrganizeAdministratorEntity.class.getMethod(method).invoke(adminEntity) == 1 && (int)OrganizeAdministratorEntity.class.getMethod(selectMethod).invoke(adminEntity) == 1) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
}

View File

@@ -0,0 +1,34 @@
# General
error.size.toolarge=\u8F93\u5165\u592A\u5927\u3002\u5B9E\u9645\u7684\u8F93\u5165\u4E3A{0}\u5B57\u8282\u3002\u5141\u8BB8\u7684\u6700\u5927\u8F93\u5165\u4E3A{1}\u5B57\u8282\u3002
error.comment.removed=\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6CE8\u91CA\u57DF\u5DF2\u88AB\u8FC7\u6EE4\u3002\u6CE8\u91CA\u57DF\u7684\u503C\u4E3A{0}
# Tag related
error.tag.notfound=\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6807\u8BB0{0}\u5DF2\u88AB\u8FC7\u6EE4\u3002\u6807\u8BB0\u7684\u5185\u5BB9\u4FDD\u5B58\u4E0D\u53D8\u3002
error.tag.removed=\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6807\u8BB0{0}\u4E0D\u88AB\u5141\u8BB8\u3002\u6B64\u6807\u8BB0\u4E0D\u5E94\u8BE5\u5F71\u54CD\u8F93\u5165\u7684\u663E\u793A\u3002
error.tag.filtered=\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6807\u8BB0{0}\u5DF2\u88AB\u8FC7\u6EE4\u3002\u6807\u8BB0\u7684\u5185\u5BB9\u4FDD\u5B58\u4E0D\u53D8\u3002
error.tag.encoded=The {0} tag has been encoded for security reasons. The contents of the tag will remain in place.
error.tag.empty=\u5728{0}\u7684\u6807\u7B7E\u662F\u7A7A\u7684\uFF0C\u56E0\u6B64\u6211\u4EEC\u65E0\u6CD5\u5904\u7406\u5B83\u3002\u8BE5\u90AE\u4EF6\u7684\u5176\u4F59\u90E8\u5206\u662F\u5B8C\u6574\u7684\uFF0C\u5176\u642C\u8FC1\u5E94\u8BE5\u6CA1\u6709\u4EFB\u4F55\u526F\u4F5C\u7528\u3002
error.cdata.found=\u4E00\u4E2ACDATA\u90E8\u5206\u88AB\u53D1\u73B0\uFF0C\u8FD9\u662F\u4E0D\u5141\u8BB8\u7684\u3002\u8BE5\u90AE\u4EF6\u7684\u5176\u4F59\u90E8\u5206\u662F\u5B8C\u6574\u7684\uFF0C\u5176\u642C\u8FC1\u4E0D\u5E94\u8BE5\u6709\u4EFB\u4F55\u526F\u4F5C\u7528\u3002\u5728CDATA\u7684\u5185\u5BB9\u662F \"{0}\"\u3002
error.pi.found=XML\u5904\u7406\u6307\u4EE4\u88AB\u53D1\u73B0\uFF0C\u8FD9\u662F\u4E0D\u5141\u8BB8\u7684\u3002\u6D88\u606F\u7684\u5176\u4F59\u90E8\u5206\u662F\u5B8C\u6574\u7684\uFF0C\u5176\u642C\u8FC1\u5E94\u8BE5\u4E0D\u4F1A\u6709\u4EFB\u4F55\u526F\u4F5C\u7528\u3002\u8BE5\u6307\u4EE4\u7684\u5185\u5BB9\u4E3A \"{0}\"\u3002
# Attribute related
error.attribute.notfound=\u6807\u8BB0{0}\u5305\u542B\u4E00\u4E2A\u6CA1\u6CD5\u5904\u7406\u7684\u5C5E\u6027\u3002\u5C5E\u6027{1}\u5DF2\u88AB\u8FC7\u6EE4\uFF0C\u4F46\u6807\u8BB0\u4FDD\u5B58\u4E0D\u53D8\u3002
error.attribute.invalid=\u6807\u8BB0{0}\u5305\u542B\u4E00\u4E2A\u6CA1\u6CD5\u5904\u7406\u7684\u5C5E\u6027\u3002\u5C5E\u6027{1}\u5305\u542B\u4E00\u4E2A\u503C\"{2}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u8FD9\u4E2A\u503C\u6CA1\u6CD5\u88AB\u63A5\u53D7\u3002\u4E3A\u4E86\u5904\u7406\u8FD9\u4E2A\u8F93\u5165\uFF0C\u8FD9\u4E2A\u5C5E\u6027\u5DF2\u88AB\u4ECE\u8FD9\u4E2A\u6807\u8BB0\u4E2D\u53BB\u6389\uFF0C\u6807\u8BB0\u5176\u4ED6\u90E8\u5206\u4FDD\u6301\u4E0D\u53D8\u3002
error.attribute.invalid.filtered=\u6807\u8BB0{0}\u5305\u542B\u4E00\u4E2A\u6CA1\u6CD5\u5904\u7406\u7684\u5C5E\u3002\u5C5E\u6027{1}\u5305\u542B\u4E00\u4E2A\u503C\"{2}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u8FD9\u4E2A\u503C\u6CA1\u6CD5\u88AB\u63A5\u53D7\u3002\u4E3A\u4E86\u8FDB\u4E00\u6B65\u5904\u7406\u8FD9\u4E2A\u8F93\u5165\uFF0C\u6807\u8BB0{0}\u5DF2\u88AB\u8FC7\u6EE4\u3002
error.attribute.invalid.encoded=The {0} tag contained an attribute that we could not process. The {1} attribute had a value of \"{2}\". This value could not be accepted for security reasons. We have chosen to encode the {0} tag in order to continue processing the input.
error.attribute.invalid.removed=\u6807\u8BB0{0}\u5305\u542B\u4E00\u4E2A\u6CA1\u6CD5\u5904\u7406\u7684\u5C5E\u6027\u3002\u5C5E\u6027{1}\u5305\u542B\u4E00\u4E2A\u503C\"{2}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u8FD9\u4E2A\u503C\u6CA1\u6CD5\u88AB\u63A5\u53D7\u3002\u4E3A\u4E86\u8FDB\u4E00\u6B65\u5904\u7406\u8FD9\u4E2A\u8F93\u5165\uFF0C\u6574\u4E2A\u6807\u8BB0{0}\u5DF2\u88AB\u53BB\u6389\u3002
# CSS related
error.css.tag.malformed=The stylesheet code \"{0}\" could not be parsed.
error.css.import.disabled=\u6837\u5F0F\u8868\u7684\u5BFC\u5165\u8FD8\u6CA1\u6709\u88AB\u6FC0\u6D3B\u3002
error.css.import.exceeded=\u4F4D\u4E8E{0}\u7684\u6837\u5F0F\u8868\u8D85\u8FC7\u5141\u8BB8\u5BFC\u5165\u7684\u6837\u5F0F\u8868\u7684\u603B\u6570\uFF0C\u56E0\u6B64\u8BE5\u6837\u5F0F\u8868\u6CA1\u6709\u88AB\u8BFB\u53D6\u3002\u5141\u8BB8\u5BFC\u5165\u7684\u6837\u5F0F\u8868\u7684\u6700\u5927\u6570\u76EE\u4E3A{1}\u3002
error.css.import.failure=\u8F93\u5165\u4E2D\u542B\u6709\u7684\u8FDC\u7A0B\u6837\u5F0F\u8868\u4F4D\u4E8E{0}\uFF0C\u6B64\u6837\u5F0F\u8868\u6CA1\u6CD5\u88AB\u8BFB\u53D6\u3002\u7F51\u7AD9\u53EF\u80FD\u5173\u95ED\u6216\u8005\u4E3B\u673A\u6CA1\u6CD5\u88AB\u8BBF\u95EE\u3002\u8FD9\u4E0D\u5E94\u8BE5\u5F71\u54CD\u8F93\u5165\u7684\u683C\u5F0F\u3002
error.css.import.toolarge=\u4F4D\u4E8E{0}\u7684\u6837\u5F0F\u8868\u4F7F\u5F97\u603B\u8F93\u5165\u592A\u5927\uFF0C\u56E0\u6B64\u6CA1\u6709\u88AB\u5BFC\u5165\u3002\u5141\u8BB8\u7684\u6700\u5927\u8F93\u5165\u4E3A{1}\u5B57\u8282\u3002
error.css.import.url.invalid=\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u7528\u4E8E\u5BFC\u5165\u6837\u5F0F\u8868\u7684url\u6CA1\u6CD5\u88AB\u63A5\u53D7\u3002\u6B64url\u662F{1}\u3002
error.css.stylesheet.relative=\u6837\u5F0F\u8868\u5F15\u7528\u4E86\u4E00\u4E2A\u6CA1\u6CD5\u8BFB\u53D6\u7684\u76F8\u5BF9\u6837\u5F0F\u8868\"{0}\"\u3002
error.css.tag.relative=\u6807\u8BB0{0}\u4E2D\u7684\u4E00\u4E2A\u6837\u5F0F\u5C5E\u6027\u6307\u5B9A\u4E86\u4E00\u4E2A\u6CA1\u6CD5\u8BFB\u53D6\u7684\u76F8\u5BF9\u6837\u5F0F\u8868\u5E94\u7528\"{0}\"\u3002
error.css.stylesheet.rule.notfound=\u6837\u5F0F\u8868\u4F7F\u7528\u4E86\u4E00\u4E2A\u4E0D\u88AB\u652F\u6301\u7684\u89C4\u5219\"{0}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u89C4\u5219\u5DF2\u88AB\u53BB\u6389\u3002
error.css.tag.rule.notfound=\u6807\u8BB0{0}\u4E2D\u7684\u4E00\u4E2A\u6837\u5F0F\u5C5E\u6027\u4F7F\u7528\u4E86\u4E00\u4E2A\u4E0D\u88AB\u652F\u6301\u7684\u89C4\u5219\"{0}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u89C4\u5219\u5DF2\u88AB\u53BB\u6389\u3002
error.css.stylesheet.selector.notfound=\u6837\u5F0F\u8868\u4F7F\u7528\u4E86\u4E00\u4E2A\u6CA1\u6CD5\u5904\u7406\u7684\u9009\u62E9\u5668\"{0}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u9009\u62E9\u5668\u5DF2\u88AB\u53BB\u6389\u3002
error.css.tag.selector.notfound=\u6807\u8BB0{0}\u4E2D\u7684\u4E00\u4E2A\u6837\u5F0F\u5C5E\u6027\u4F7F\u7528\u4E86\u4E00\u4E2A\u6CA1\u6CD5\u5904\u7406\u7684\u9009\u62E9\u5668\"{0}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u89C4\u5219\u5DF2\u88AB\u53BB\u6389\u3002
error.css.stylesheet.selector.disallowed=\u6837\u5F0F\u8868\u4F7F\u7528\u4E86\u4E00\u4E2A\u9009\u62E9\u5668\"{0}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u9009\u62E9\u5668\u4E0D\u88AB\u5141\u8BB8\u3002
error.css.tag.selector.disallowed=\u6807\u8BB0{0}\u4E2D\u7684\u4E00\u4E2A\u6837\u5F0F\u5C5E\u6027\u4F7F\u7528\u4E86\u4E00\u4E2A\u9009\u62E9\u5668\"{1}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u9009\u62E9\u5668\u4E0D\u88AB\u5141\u8BB8\u3002
error.css.stylesheet.property.invalid=\u6837\u5F0F\u8868\u542B\u6709\u4E00\u4E2A\u5C5E\uFF08property)\"{0}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u5C5E\u6027\u4E0D\u88AB\u5141\u8BB8\u3002
error.css.tag.property.invalid=\u6807\u8BB0{0}\u4E2D\u542B\u6709\u4E00\u4E2A\u6837\u5F0F\u5C5E\u6027\"{1}\"\u3002\u51FA\u4E8E\u5B89\u5168\u7684\u539F\u56E0\uFF0C\u6B64\u5C5E\u6027\u4E0D\u88AB\u5141\u8BB8\u3002

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!--
W3C rules retrieved from:
http://www.w3.org/TR/html401/struct/global.html
-->
<anti-samy-rules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="antisamy.xsd">
<directives>
<directive name="omitXmlDeclaration" value="true"/>
<directive name="omitDoctypeDeclaration" value="true"/>
<directive name="maxInputSize" value="0"/>
<directive name="useXHTML" value="true"/>
<directive name="formatOutput" value="false"/>
<!--
remember, this won't work for relative URIs - AntiSamy doesn't
know anything about the URL or your web structure
-->
<directive name="embedStyleSheets" value="false"/>
</directives>
<common-regexps>
</common-regexps>
<!--
Tag.name = a, b, div, body, etc.
Tag.action = filter: remove tags, but keep content, validate: keep content as long as it passes rules, remove: remove tag and contents
Attribute.name = id, class, href, align, width, etc.
Attribute.onInvalid = what to do when the attribute is invalid, e.g., remove the tag (removeTag), remove the attribute (removeAttribute), filter the tag (filterTag)
Attribute.description = What rules in English you want to tell the users they can have for this attribute. Include helpful things so they'll be able to tune their HTML
-->
<!--
Some attributes are common to all (or most) HTML tags. There aren't many that qualify for this. You have to make sure there's no
collisions between any of these attribute names with attribute names of other tags that are for different purposes.
-->
<common-attributes>
</common-attributes>
<!--
This requires normal updates as browsers continue to diverge from the W3C and each other. As long as the browser wars continue
this is going to continue. I'm not sure war is the right word for what's going on. Doesn't somebody have to win a war after
a while? Even wars of attrition, surely?
-->
<global-tag-attributes>
</global-tag-attributes>
<tags-to-encode>
</tags-to-encode>
<tag-rules>
</tag-rules>
<!-- CSS validation processing rules -->
<css-rules>
<!-- end manual properties -->
</css-rules>
<allowed-empty-tags>
</allowed-empty-tags>
</anti-samy-rules>

View File

@@ -0,0 +1,368 @@
# 应用服务器
server:
tomcat:
uri-encoding: UTF-8 #tomcat编码
port: 30000 #tomcat端口
spring:
messages:
basename: i18n/message
# 一天刷新一次
cache-duration: 24H
devtools: #spring开发者工具模块
restart:
enabled: true #热部署开关
freemarker:
cache: false #spring内置freemarker缓存
thymeleaf:
cache: false #spring内置thymeleaf缓存
# ===================== 数据源配置 =====================
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure #排除自动配置手动配置druid
datasource:
db-type: MySQL #数据库类型(可选值 MySQL、SQLServer、Oracle、DM8、KingbaseES、PostgreSQL请严格按可选值填写)
host: aliyun.szlecheng.cn
port: 13306
username: DBA_YZD
password: x8MkGwWsRftJGhyr
db-name: yunzhupaas_demo
db-schema: #金仓达梦选填
prepare-url: #自定义url
# ===================== 动态多数据源 =====================
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: true #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
druid:
# 空闲时执行连接测试
test-while-idle: true
# 连接测试最小间隔
time-between-eviction-runs-millis: 60000
# 获取连接等待3秒 根据网络情况设定
max-wait: 3000
# 初始化4个连接
initial-size: 4
# 最大20个连接
max-active: 20
# 最少保持4个空闲连接
min-idle: 4
# 空闲连接保活, 超过配置的空闲时间会进行连接检查完成保活操作(数据库自身会断开达到空闲时间的连接, 程序使用断开的连接会报错)
keep-alive: true
# 连接超时
connect-timeout: 10000
# 连接超时
socket-timeout: 10000
# 查询超时
query-timeout: 90000
# 事务查询超时
transaction-query-timeout: 90000
# 解除注释后Druid连接池打印SQL语句 忽略日志等级配置
# filters: slf4j
slf4j:
statementLogEnabled: true
resultSetLogEnabled: false
connectionLogEnabled: false
dataSourceLogEnabled: false
statementCreateAfterLogEnabled: false
statementCloseAfterLogEnabled: false
statementExecuteAfterLogEnabled: false
#打印SQL替换参数
statementExecutableSqlLogEnable: true
statementPrepareAfterLogEnabled: false
statementPrepareCallAfterLogEnabled: false
statementParameterSetLogEnabled: false
# datasource:
# master:
# url: jdbc:mysql://${spring.datasource.host}:${spring.datasource.port}/${spring.datasource.dbname}?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC
# username: ${spring.datasource.username}
# password: ${spring.datasource.password}
# driver-class-name: com.mysql.cj.jdbc.Driver
# ===================== Redis配置 =====================
# redis单机模式
data:
redis:
database: 10
host: 127.0.0.1
port: 6379
# password: redis_JtjYRD # 密码为空时,请将本行注释
timeout: 3000 #超时时间(单位:秒)
lettuce: #Lettuce为Redis的Java驱动包
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
# redis集群模式
# redis:
# cluster:
# nodes:
# - 192.168.0.225:6380
# - 192.168.0.225:6381
# - 192.168.0.225:6382
# - 192.168.0.225:6383
# - 192.168.0.225:6384
# - 192.168.0.225:6385
# password: 123456 # 密码为空时,请将本行注释
# timeout: 3000 # 超时时间(单位:秒)
# lettuce: #Lettuce为Redis的Java驱动包
# pool:
# max-active: 8 # 连接池最大连接数
# max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# min-idle: 0 # 连接池中的最小空闲连接
# max-idle: 8 # 连接池中的最大空闲连接
# ===================== Redis配置-End =====================
# ===================== 单点登录(用户信息同步)配置-Start =====================
cloud:
stream:
# 若使用RocketMQ-Start
rocketmq:
binder:
name-server: 192.168.10.6:30094
group: maxkey_identity
# 若使用RocketMQ-End
# 若使用RabbitMQ-Start
# binders:
# defaultRabbit: # 表示定义的名称用于binding整合
# type: rabbit # 消息组件类型
# environment: # 设置rabbitmq的相关环境配置
# spring:
# rabbitmq:
# host: 192.168.10.6
# port: 5672
# username: rabbitmq
# password: rabbitmq
# 若使用RabbitMQ-End
# 若使用Kafka-Start
# kafka:
# # KafkaBinderConfigurationProperties
# binder:
# brokers: 192.168.10.6:9092
# 若使用Kafka-End
bindings:
ssoEventReceiver-in-0:
content-type: text/json
destination: MXK_IDENTITY_MAIN_TOPIC
group: maxkey_identity
# ===================== 单点登录(用户信息同步)配置-End =====================
# ===================== AI配置-Start =====================
ai:
openai:
enabled: true
# 超时时间, 秒, 根据AI平台性能调整超时时间
timeout: 300
# 阿里百联平台
api-host: https://dashscope.aliyuncs.com/compatible-mode/
api-key: sk-def0e6d9d0f8497cb5bcfff8c0c19935
chat:
mode: qwen-max
# GPT转发平台
# api-host: https://api.chatanywhere.tech/
# api-key:
# chat:
# mode: gpt-3.5-turbo
# DeepSeek
# api-host: https://api.deepseek.com/v1/
# api-key:
# chat:
# mode: deepseek-chat
# ===================== AI配置-End =====================
# SpringDoc接口文档 访问地址http://127.0.0.1:30000/doc.html
springdoc:
default-flat-param-object: true
api-docs:
enabled: true
#SpringDoc增强
#knife4j:
# enable: true
# basic: #接口文档访问鉴权
# enable: true
# username: yunzhupaas
# password: 123456
lock4j:
aop:
# Lock4j注解是否启用
enabled: false
config:
# ===================== 是否开启测试环境 =====================
TestVersion: false
# ===================== ApacheShardingSphere 配置开关 =====================
sharding-sphere-enabled: false
# ===================== 文件存储配置-Start =====================
file-storage: #文件存储配置,不使用的情况下可以不写
default-platform: local-plus-1 #默认使用的存储平台
thumbnail-suffix: ".thumb.jpg" #缩略图后缀,例如【.min.jpg】【.png】
local-plus: # 本地存储升级版
- platform: local-plus-1 # 存储平台标识
enable-storage: true #启用存储
enable-access: true #启用访问(线上请使用 Nginx 配置,效率更高)
domain: "" # 访问域名例如“http://127.0.0.1:8030/”,注意后面要和 path-patterns 保持一致,“/”结尾,本地存储建议使用相对路径,方便后期更换域名
# base-path: /data/work-data/upload/jnpfsoft/yunzhupaas-resources/ # 基础路径
base-path: E:/XiangMu/yunzhu/zero-resources/ # 基础路径
path-patterns: /** # 访问路径
storage-path: # 存储路径
aliyun-oss: # 阿里云 OSS ,不使用的情况下可以不写
- platform: aliyun-oss-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
end-point: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.oss-cn-shanghai.aliyuncs.com/
base-path: hy/ # 基础路径
qiniu-kodo: # 七牛云 kodo ,不使用的情况下可以不写
- platform: qiniu-kodo-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如http://abc.hn-bkt.clouddn.com/
base-path: base/ # 基础路径
tencent-cos: # 腾讯云 COS
- platform: tencent-cos-1 # 存储平台标识
enable-storage: false # 启用存储
secret-id: ??
secret-key: ??
region: ?? #存仓库所在地域
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.cos.ap-nanjing.myqcloud.com/
base-path: hy/ # 基础路径
minio: # MinIO由于 MinIO SDK 支持 AWS S3其它兼容 AWS S3 协议的存储平台也都可配置在这里
- platform: minio-1 # 存储平台标识
enable-storage: true # 启用存储
access-key: 9Y3sjaDWgbxKjXjm
secret-key: Bs2GyJwmOLpqNsQwbDjdinyUJQHtM0rc
end-point: http://192.168.0.207:9000/
bucket-name: v350
domain: ${config.file-storage.minio[0].end-point} # 访问域名,注意“/”结尾例如http://minio.abc.com/abc/
base-path: # 基础路径
# ===================== 文件存储配置-End =====================
# ===================== 第三方登录配置-Start =====================
socials:
# 第三方登录功能开关(false-关闭true-开启)
socials-enabled: false
config:
- # 微信
provider: wechat_open
client-id: your-client-id
client-secret: your-client-secret
- # qq
provider: qq
client-id: your-client-id
client-secret: your-client-secret
- # 企业微信
provider: wechat_enterprise
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 钉钉
provider: dingtalk
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 飞书
provider: feishu
client-id: your-client-id
client-secret: your-client-secret
- # 小程序
provider: wechat_applets
client-id: your-client-id
client-secret: your-client-secret
# ===================== 第三方登录配置-End =====================
# ===================== 任务调度配置-Start =====================
xxl:
job:
accessToken: '432e62f3b488bc861d91b0e274e850cc'
i18n: zh_CN
logretentiondays: 30
triggerpool:
fast:
max: 200
slow:
max: 100
# xxl-job服务端地址
admin:
addresses: http://127.0.0.1:30020/xxl-job-admin/
executor:
address: ''
appname: xxl-job-executor-sample1
ip: ''
logpath: /data/applogs/xxl-job/jobhandler
logretentiondays: 30
port: 39999
# rest调用xxl-job接口地址
admin:
register:
handle-query-address: ${xxl.job.admin.addresses}api/handler/queryList
job-info-address: ${xxl.job.admin.addresses}api/jobinfo
log-query-address: ${xxl.job.admin.addresses}api/log
task-list-address: ${xxl.job.admin.addresses}api/ScheduleTask/List
task-info-address: ${xxl.job.admin.addresses}api/ScheduleTask/getInfo
task-save-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-update-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/remove
task-start-or-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/updateTask
# ===================== 任务调度配置-End =====================
# ===================== 单点登录(SSO)配置-Start =====================
yunzhupaas:
sso:
# ===================== 单点登录(用户信息拉取)配置-Start =====================
connector:
# 是否开启用户信息拉取
enabled: false
# ===================== 单点登录(用户信息拉取)配置-End =====================
# ===================== 单点登录(用户信息推送)配置-Start =====================
pull:
# 是否开启用户信息推送
enabled: false
create-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account
replace-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account
change-password-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account/changePassword
delete-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account
credential-type: Basic
user-name: 747887288041603072
password: MYgMMjIwNzIwMjIxNTU4MTAxNzQlKQ
# ===================== 单点登录(用户信息推送)配置-End =====================
oauth:
#启用单点登录, 普通登录不可用
ssoEnabled: false
#轮询票据有效期
ticketTimeout: 120
#默认单点登录协议
defaultSSO: cas
#后端登录接口地址
loginPath: http://127.0.0.1:30000/api/oauth/Login
#login:
#JWT生成秘钥 不填写为默认值
#jwtSecretKey: WviMjFNC72VKwGqm5LPoheQo5XN9iN4d
sso:
#单点登录系统地址
baseUrl: http://127.0.0.1:8527
#登录成功后跳转到前端的页面
sucessFrontUrl: http://127.0.0.1:3100/sso
#错误信息是否输出到页面
ticketOutMessage: false
#logoutFrontUrl: http://sso.maxkey.top:8527/maxkey
#单点注销后端接口地址, 配置启用后YUNZHUPAAS退出会请求单点系统退出, 触发单点注销退出全部应用
#ssoLogoutApiUrl: ${oauth.sso.baseUrl}/sign/logout
auth2:
enabled: true
clientId: 747887288041603072
clientSecret: MYgMMjIwNzIwMjIxNTU4MTAxNzQlKQ
baseUrl: ${oauth.sso.baseUrl}
authorizeUrl: ${oauth.sso.auth2.baseUrl}/sign/authz/oauth/v20/authorize
accessTokenUrl: ${oauth.sso.auth2.baseUrl}/sign/authz/oauth/v20/token
userInfoUrl: ${oauth.sso.auth2.baseUrl}/sign/api/oauth/v20/me
cas:
enabled: true
baseUrl: ${oauth.sso.baseUrl}
serverLoginUrl: ${oauth.sso.cas.baseUrl}/sign/authz/cas/login
serverValidateUrl: ${oauth.sso.cas.baseUrl}/sign/authz/cas
# ===================== 单点登录(SSO)配置-End =====================

View File

@@ -0,0 +1,336 @@
# 应用服务器
server:
tomcat:
uri-encoding: UTF-8 #tomcat编码
port: 30000 #tomcat端口
spring:
messages:
basename: i18n/message
# 一天刷新一次
cache-duration: 24H
devtools: #spring开发者工具模块
restart:
enabled: true #热部署开关
freemarker:
cache: false #spring内置freemarker缓存
thymeleaf:
cache: false #spring内置thymeleaf缓存
# ===================== 数据源配置 =====================
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure #排除自动配置手动配置druid
datasource:
db-type: MySQL #数据库类型(可选值 MySQL、SQLServer、Oracle、DM、KingbaseES、PostgreSQL请严格按可选值填写)
host: 127.0.0.1
port: 3306
username: root
password: 123456
db-name: yunzhupaas_init
db-schema: #金仓达梦选填
prepare-url: #自定义url
# ===================== 动态多数据源 =====================
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: true #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
druid:
# 空闲时执行连接测试
test-while-idle: true
# 连接测试最小间隔
time-between-eviction-runs-millis: 60000
# 获取连接等待3秒 根据网络情况设定
max-wait: 3000
# 初始化4个连接
initial-size: 4
# 最大20个连接
max-active: 20
# 最少保持4个空闲连接
min-idle: 4
# 空闲连接保活, 超过配置的空闲时间会进行连接检查完成保活操作(数据库自身会断开达到空闲时间的连接, 程序使用断开的连接会报错)
keep-alive: true
# 连接超时
connect-timeout: 10000
# 连接超时
socket-timeout: 10000
# 查询超时
query-timeout: 90000
# 事务查询超时
transaction-query-timeout: 90000
# 解除注释后Druid连接池打印SQL语句 忽略日志等级配置
# filters: slf4j
slf4j:
statementLogEnabled: true
resultSetLogEnabled: false
connectionLogEnabled: false
dataSourceLogEnabled: false
statementCreateAfterLogEnabled: false
statementCloseAfterLogEnabled: false
statementExecuteAfterLogEnabled: false
#打印SQL替换参数
statementExecutableSqlLogEnable: true
statementPrepareAfterLogEnabled: false
statementPrepareCallAfterLogEnabled: false
statementParameterSetLogEnabled: false
# datasource:
# master:
# url: jdbc:mysql://${spring.datasource.host}:${spring.datasource.port}/${spring.datasource.dbname}?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC
# username: ${spring.datasource.username}
# password: ${spring.datasource.password}
# driver-class-name: com.mysql.cj.jdbc.Driver
# ===================== Redis配置-Start =====================
# redis单机模式
redis:
database: 1 #缓存库编号
host: 127.0.0.1
port: 6379
password: 123456 # 密码为空时,请将本行注释
timeout: 3000 #超时时间(单位:秒)
lettuce: #Lettuce为Redis的Java驱动包
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
# redis集群模式
# redis:
# cluster:
# nodes:
# - 192.168.0.225:6380
# - 192.168.0.225:6381
# - 192.168.0.225:6382
# - 192.168.0.225:6383
# - 192.168.0.225:6384
# - 192.168.0.225:6385
# password: 123456 # 密码为空时,请将本行注释
# timeout: 3000 # 超时时间(单位:秒)
# lettuce: #Lettuce为Redis的Java驱动包
# pool:
# max-active: 8 # 连接池最大连接数
# max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# min-idle: 0 # 连接池中的最小空闲连接
# max-idle: 8 # 连接池中的最大空闲连接
# ===================== Redis配置-End =====================
# ===================== 单点登录(用户信息同步)配置-Start =====================
cloud:
stream:
# 若使用RocketMQ-Start
rocketmq:
binder:
name-server: 192.168.10.6:30094
group: maxkey_identity
# 若使用RocketMQ-End
# 若使用RabbitMQ-Start
# binders:
# defaultRabbit: # 表示定义的名称用于binding整合
# type: rabbit # 消息组件类型
# environment: # 设置rabbitmq的相关环境配置
# spring:
# rabbitmq:
# host: 192.168.10.6
# port: 5672
# username: rabbitmq
# password: rabbitmq
# 若使用RabbitMQ-End
# 若使用Kafka-Start
# kafka:
# # KafkaBinderConfigurationProperties
# binder:
# brokers: 192.168.10.6:9092
# 若使用Kafka-End
bindings:
ssoEventReceiver-in-0:
content-type: text/json
destination: MXK_IDENTITY_MAIN_TOPIC
group: maxkey_identity
# ===================== 单点登录(用户信息同步)配置-End =====================
# SpringDoc接口文档 访问地址http://127.0.0.1:30000/doc.html
springdoc:
default-flat-param-object: true
api-docs:
enabled: true
#SpringDoc增强
#knife4j:
# enable: true
# basic: #接口文档访问鉴权
# enable: true
# username: yunzhupaas
# password: 123456
lock4j:
aop:
# Lock4j注解是否启用
enabled: false
config:
# ===================== 是否开启测试环境 =====================
TestVersion: false
# ===================== ApacheShardingSphere 配置开关 =====================
sharding-sphere-enabled: false
# ===================== 文件存储配置-Start =====================
file-storage: #文件存储配置,不使用的情况下可以不写
default-platform: local-plus-1 #默认使用的存储平台
thumbnail-suffix: ".thumb.jpg" #缩略图后缀,例如【.min.jpg】【.png】
local-plus: # 本地存储升级版
- platform: local-plus-1 # 存储平台标识
enable-storage: true #启用存储
enable-access: true #启用访问(线上请使用 Nginx 配置,效率更高)
domain: "" # 访问域名例如“http://127.0.0.1:8030/”,注意后面要和 path-patterns 保持一致,“/”结尾,本地存储建议使用相对路径,方便后期更换域名
base-path: D:/project/yunzhupaas-resources/ # 基础路径
path-patterns: /** # 访问路径
storage-path: # 存储路径
aliyun-oss: # 阿里云 OSS ,不使用的情况下可以不写
- platform: aliyun-oss-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
end-point: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.oss-cn-shanghai.aliyuncs.com/
base-path: hy/ # 基础路径
qiniu-kodo: # 七牛云 kodo ,不使用的情况下可以不写
- platform: qiniu-kodo-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如http://abc.hn-bkt.clouddn.com/
base-path: base/ # 基础路径
tencent-cos: # 腾讯云 COS
- platform: tencent-cos-1 # 存储平台标识
enable-storage: false # 启用存储
secret-id: ??
secret-key: ??
region: ?? #存仓库所在地域
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.cos.ap-nanjing.myqcloud.com/
base-path: hy/ # 基础路径
minio: # MinIO由于 MinIO SDK 支持 AWS S3其它兼容 AWS S3 协议的存储平台也都可配置在这里
- platform: minio-1 # 存储平台标识
enable-storage: true # 启用存储
access-key: 9Y3sjaDWgbxKjXjm
secret-key: Bs2GyJwmOLpqNsQwbDjdinyUJQHtM0rc
end-point: http://192.168.0.207:9000/
bucket-name: v350
domain: ${config.file-storage.minio[0].end-point} # 访问域名,注意“/”结尾例如http://minio.abc.com/abc/
base-path: # 基础路径
# ===================== 文件存储配置-End =====================
# ===================== 第三方登录配置-Start =====================
socials:
# 第三方登录功能开关(false-关闭true-开启)
socials-enabled: false
config:
- # 微信
provider: wechat_open
client-id: your-client-id
client-secret: your-client-secret
- # qq
provider: qq
client-id: your-client-id
client-secret: your-client-secret
- # 企业微信
provider: wechat_enterprise
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 钉钉
provider: dingtalk
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 飞书
provider: feishu
client-id: your-client-id
client-secret: your-client-secret
- # 小程序
provider: wechat_applets
client-id: your-client-id
client-secret: your-client-secret
# ===================== 第三方登录配置-End =====================
# ===================== 任务调度配置-Start =====================
xxl:
job:
accessToken: '432e62f3b488bc861d91b0e274e850cc'
i18n: zh_CN
logretentiondays: 30
triggerpool:
fast:
max: 200
slow:
max: 100
# xxl-job服务端地址
admin:
addresses: http://127.0.0.1:30020/xxl-job-admin/
executor:
address: ''
appname: xxl-job-executor-sample1
ip: ''
logpath: /data/applogs/xxl-job/jobhandler
logretentiondays: 30
port: 39999
# rest调用xxl-job接口地址
admin:
register:
handle-query-address: ${xxl.job.admin.addresses}api/handler/queryList
job-info-address: ${xxl.job.admin.addresses}api/jobinfo
log-query-address: ${xxl.job.admin.addresses}api/log
task-list-address: ${xxl.job.admin.addresses}api/ScheduleTask/List
task-info-address: ${xxl.job.admin.addresses}api/ScheduleTask/getInfo
task-save-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-update-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/remove
task-start-or-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/updateTask
# ===================== 任务调度配置-End =====================
# ===================== 单点登录(SSO)配置-Start =====================
yunzhupaas:
sso:
# ===================== 单点登录(用户信息拉取)配置-Start =====================
connector:
# 是否开启用户信息拉取
enabled: false
# ===================== 单点登录(用户信息拉取)配置-End =====================
# ===================== 单点登录(用户信息推送)配置-Start =====================
pull:
# 是否开启用户信息推送
enabled: false
create-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account
replace-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account
change-password-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account/changePassword
delete-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account
credential-type: Basic
user-name: 747887288041603072
password: MYgMMjIwNzIwMjIxNTU4MTAxNzQlKQ
# ===================== 单点登录(用户信息推送)配置-End =====================
oauth:
#启用单点登录, 普通登录不可用
ssoEnabled: false
#轮询票据有效期
ticketTimeout: 120
#默认单点登录协议
defaultSSO: cas
#后端登录接口地址
loginPath: http://127.0.0.1:30000/api/oauth/Login
#轮询登录模式是否输出结果
ticketOutMessage: false
login:
#JWT生成秘钥 不填写为默认值
#jwtSecretKey: WviMjFNC72VKwGqm5LPoheQo5XN9iN4d
sso:
#登录成功后跳转到前端的页面
sucessFrontUrl: http://127.0.0.1:3000/sso
#logoutFrontUrl: http://sso.maxkey.top:8527/maxkey
auth2:
enabled: true
clientId: 747887288041603072
clientSecret: MYgMMjIwNzIwMjIxNTU4MTAxNzQlKQ
baseUrl: http://127.0.0.1:8527
authorizeUrl: ${oauth.sso.auth2.baseUrl}/sign/authz/oauth/v20/authorize
accessTokenUrl: ${oauth.sso.auth2.baseUrl}/sign/authz/oauth/v20/token
userInfoUrl: ${oauth.sso.auth2.baseUrl}/sign/api/oauth/v20/me
cas:
enabled: true
baseUrl: ${oauth.sso.auth2.baseUrl}
serverLoginUrl: ${oauth.sso.cas.baseUrl}/sign/authz/cas/login
serverValidateUrl: ${oauth.sso.cas.baseUrl}/sign/authz/cas
# ===================== 单点登录(SSO)配置-End =====================

View File

@@ -0,0 +1,336 @@
# 应用服务器
server:
tomcat:
uri-encoding: UTF-8 #tomcat编码
port: 30000 #tomcat端口
spring:
messages:
basename: i18n/message
# 一天刷新一次
cache-duration: 24H
devtools: #spring开发者工具模块
restart:
enabled: true #热部署开关
freemarker:
cache: false #spring内置freemarker缓存
thymeleaf:
cache: false #spring内置thymeleaf缓存
# ===================== 数据源配置 =====================
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure #排除自动配置手动配置druid
datasource:
db-type: MySQL #数据库类型(可选值 MySQL、SQLServer、Oracle、DM、KingbaseES、PostgreSQL请严格按可选值填写)
host: 127.0.0.1
port: 3306
username: root
password: 123456
db-name: yunzhupaas_init
db-schema: #金仓达梦选填
prepare-url: #自定义url
# ===================== 动态多数据源 =====================
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: true #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
druid:
# 空闲时执行连接测试
test-while-idle: true
# 连接测试最小间隔
time-between-eviction-runs-millis: 60000
# 获取连接等待3秒 根据网络情况设定
max-wait: 3000
# 初始化4个连接
initial-size: 4
# 最大20个连接
max-active: 20
# 最少保持4个空闲连接
min-idle: 4
# 空闲连接保活, 超过配置的空闲时间会进行连接检查完成保活操作(数据库自身会断开达到空闲时间的连接, 程序使用断开的连接会报错)
keep-alive: true
# 连接超时
connect-timeout: 10000
# 连接超时
socket-timeout: 10000
# 查询超时
query-timeout: 90000
# 事务查询超时
transaction-query-timeout: 90000
# 解除注释后Druid连接池打印SQL语句 忽略日志等级配置
# filters: slf4j
slf4j:
statementLogEnabled: true
resultSetLogEnabled: false
connectionLogEnabled: false
dataSourceLogEnabled: false
statementCreateAfterLogEnabled: false
statementCloseAfterLogEnabled: false
statementExecuteAfterLogEnabled: false
#打印SQL替换参数
statementExecutableSqlLogEnable: true
statementPrepareAfterLogEnabled: false
statementPrepareCallAfterLogEnabled: false
statementParameterSetLogEnabled: false
# datasource:
# master:
# url: jdbc:mysql://${spring.datasource.host}:${spring.datasource.port}/${spring.datasource.dbname}?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC
# username: ${spring.datasource.username}
# password: ${spring.datasource.password}
# driver-class-name: com.mysql.cj.jdbc.Driver
# ===================== Redis配置-Start =====================
# redis单机模式
redis:
database: 1 #缓存库编号
host: 127.0.0.1
port: 6379
password: 123456 # 密码为空时,请将本行注释
timeout: 3000 #超时时间(单位:秒)
lettuce: #Lettuce为Redis的Java驱动包
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
# redis集群模式
# redis:
# cluster:
# nodes:
# - 192.168.0.225:6380
# - 192.168.0.225:6381
# - 192.168.0.225:6382
# - 192.168.0.225:6383
# - 192.168.0.225:6384
# - 192.168.0.225:6385
# password: 123456 # 密码为空时,请将本行注释
# timeout: 3000 # 超时时间(单位:秒)
# lettuce: #Lettuce为Redis的Java驱动包
# pool:
# max-active: 8 # 连接池最大连接数
# max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# min-idle: 0 # 连接池中的最小空闲连接
# max-idle: 8 # 连接池中的最大空闲连接
# ===================== Redis配置-End =====================
# ===================== 单点登录(用户信息同步)配置-Start =====================
cloud:
stream:
# 若使用RocketMQ-Start
rocketmq:
binder:
name-server: 192.168.10.6:30094
group: maxkey_identity
# 若使用RocketMQ-End
# 若使用RabbitMQ-Start
# binders:
# defaultRabbit: # 表示定义的名称用于binding整合
# type: rabbit # 消息组件类型
# environment: # 设置rabbitmq的相关环境配置
# spring:
# rabbitmq:
# host: 192.168.10.6
# port: 5672
# username: rabbitmq
# password: rabbitmq
# 若使用RabbitMQ-End
# 若使用Kafka-Start
# kafka:
# # KafkaBinderConfigurationProperties
# binder:
# brokers: 192.168.10.6:9092
# 若使用Kafka-End
bindings:
ssoEventReceiver-in-0:
content-type: text/json
destination: MXK_IDENTITY_MAIN_TOPIC
group: maxkey_identity
# ===================== 单点登录(用户信息同步)配置-End =====================
# SpringDoc接口文档 访问地址http://127.0.0.1:30000/doc.html
springdoc:
default-flat-param-object: true
api-docs:
enabled: true
#SpringDoc增强
#knife4j:
# enable: true
# basic: #接口文档访问鉴权
# enable: true
# username: yunzhupaas
# password: 123456
lock4j:
aop:
# Lock4j注解是否启用
enabled: false
config:
# ===================== 是否开启测试环境 =====================
TestVersion: false
# ===================== ApacheShardingSphere 配置开关 =====================
sharding-sphere-enabled: false
# ===================== 文件存储配置-Start =====================
file-storage: #文件存储配置,不使用的情况下可以不写
default-platform: local-plus-1 #默认使用的存储平台
thumbnail-suffix: ".thumb.jpg" #缩略图后缀,例如【.min.jpg】【.png】
local-plus: # 本地存储升级版
- platform: local-plus-1 # 存储平台标识
enable-storage: true #启用存储
enable-access: true #启用访问(线上请使用 Nginx 配置,效率更高)
domain: "" # 访问域名例如“http://127.0.0.1:8030/”,注意后面要和 path-patterns 保持一致,“/”结尾,本地存储建议使用相对路径,方便后期更换域名
base-path: D:/project/yunzhupaas-resources/ # 基础路径
path-patterns: /** # 访问路径
storage-path: # 存储路径
aliyun-oss: # 阿里云 OSS ,不使用的情况下可以不写
- platform: aliyun-oss-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
end-point: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.oss-cn-shanghai.aliyuncs.com/
base-path: hy/ # 基础路径
qiniu-kodo: # 七牛云 kodo ,不使用的情况下可以不写
- platform: qiniu-kodo-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如http://abc.hn-bkt.clouddn.com/
base-path: base/ # 基础路径
tencent-cos: # 腾讯云 COS
- platform: tencent-cos-1 # 存储平台标识
enable-storage: false # 启用存储
secret-id: ??
secret-key: ??
region: ?? #存仓库所在地域
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.cos.ap-nanjing.myqcloud.com/
base-path: hy/ # 基础路径
minio: # MinIO由于 MinIO SDK 支持 AWS S3其它兼容 AWS S3 协议的存储平台也都可配置在这里
- platform: minio-1 # 存储平台标识
enable-storage: true # 启用存储
access-key: 9Y3sjaDWgbxKjXjm
secret-key: Bs2GyJwmOLpqNsQwbDjdinyUJQHtM0rc
end-point: http://192.168.0.207:9000/
bucket-name: v350
domain: ${config.file-storage.minio[0].end-point} # 访问域名,注意“/”结尾例如http://minio.abc.com/abc/
base-path: # 基础路径
# ===================== 文件存储配置-End =====================
# ===================== 第三方登录配置-Start =====================
socials:
# 第三方登录功能开关(false-关闭true-开启)
socials-enabled: false
config:
- # 微信
provider: wechat_open
client-id: your-client-id
client-secret: your-client-secret
- # qq
provider: qq
client-id: your-client-id
client-secret: your-client-secret
- # 企业微信
provider: wechat_enterprise
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 钉钉
provider: dingtalk
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 飞书
provider: feishu
client-id: your-client-id
client-secret: your-client-secret
- # 小程序
provider: wechat_applets
client-id: your-client-id
client-secret: your-client-secret
# ===================== 第三方登录配置-End =====================
# ===================== 任务调度配置-Start =====================
xxl:
job:
accessToken: '432e62f3b488bc861d91b0e274e850cc'
i18n: zh_CN
logretentiondays: 30
triggerpool:
fast:
max: 200
slow:
max: 100
# xxl-job服务端地址
admin:
addresses: http://127.0.0.1:30020/xxl-job-admin/
executor:
address: ''
appname: xxl-job-executor-sample1
ip: ''
logpath: /data/applogs/xxl-job/jobhandler
logretentiondays: 30
port: 39999
# rest调用xxl-job接口地址
admin:
register:
handle-query-address: ${xxl.job.admin.addresses}api/handler/queryList
job-info-address: ${xxl.job.admin.addresses}api/jobinfo
log-query-address: ${xxl.job.admin.addresses}api/log
task-list-address: ${xxl.job.admin.addresses}api/ScheduleTask/List
task-info-address: ${xxl.job.admin.addresses}api/ScheduleTask/getInfo
task-save-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-update-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/remove
task-start-or-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/updateTask
# ===================== 任务调度配置-End =====================
# ===================== 单点登录(SSO)配置-Start =====================
yunzhupaas:
sso:
# ===================== 单点登录(用户信息拉取)配置-Start =====================
connector:
# 是否开启用户信息拉取
enabled: false
# ===================== 单点登录(用户信息拉取)配置-End =====================
# ===================== 单点登录(用户信息推送)配置-Start =====================
pull:
# 是否开启用户信息推送
enabled: false
create-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account
replace-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account
change-password-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account/changePassword
delete-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account
credential-type: Basic
user-name: 747887288041603072
password: MYgMMjIwNzIwMjIxNTU4MTAxNzQlKQ
# ===================== 单点登录(用户信息推送)配置-End =====================
oauth:
#启用单点登录, 普通登录不可用
ssoEnabled: false
#轮询票据有效期
ticketTimeout: 120
#默认单点登录协议
defaultSSO: cas
#后端登录接口地址
loginPath: http://127.0.0.1:30000/api/oauth/Login
#轮询登录模式是否输出结果
ticketOutMessage: false
login:
#JWT生成秘钥 不填写为默认值
#jwtSecretKey: WviMjFNC72VKwGqm5LPoheQo5XN9iN4d
sso:
#登录成功后跳转到前端的页面
sucessFrontUrl: http://127.0.0.1:3000/sso
#logoutFrontUrl: http://sso.maxkey.top:8527/maxkey
auth2:
enabled: true
clientId: 747887288041603072
clientSecret: MYgMMjIwNzIwMjIxNTU4MTAxNzQlKQ
baseUrl: http://127.0.0.1:8527
authorizeUrl: ${oauth.sso.auth2.baseUrl}/sign/authz/oauth/v20/authorize
accessTokenUrl: ${oauth.sso.auth2.baseUrl}/sign/authz/oauth/v20/token
userInfoUrl: ${oauth.sso.auth2.baseUrl}/sign/api/oauth/v20/me
cas:
enabled: true
baseUrl: ${oauth.sso.auth2.baseUrl}
serverLoginUrl: ${oauth.sso.cas.baseUrl}/sign/authz/cas/login
serverValidateUrl: ${oauth.sso.cas.baseUrl}/sign/authz/cas
# ===================== 单点登录(SSO)配置-End =====================

View File

@@ -0,0 +1,370 @@
# 应用服务器
server:
tomcat:
uri-encoding: UTF-8 #tomcat编码
port: 30000 #tomcat端口
spring:
messages:
basename: i18n/message
# 一天刷新一次
cache-duration: 24H
devtools: #spring开发者工具模块
restart:
enabled: true #热部署开关
freemarker:
cache: false #spring内置freemarker缓存
thymeleaf:
cache: false #spring内置thymeleaf缓存
# ===================== 数据源配置 =====================
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure #排除自动配置手动配置druid
datasource:
db-type: MySQL #数据库类型(可选值 MySQL、SQLServer、Oracle、DM8、KingbaseES、PostgreSQL请严格按可选值填写)
# host: aliyun.szlecheng.cn
host: mysql.szlecheng.cn
port: 13306
username: jnpfsoft
password: ZtRmzjij4CiaXpSE
db-name: jnpfsoft_dev
db-schema: #金仓达梦选填
prepare-url: #自定义url
# ===================== 动态多数据源 =====================
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: true #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
druid:
# 空闲时执行连接测试
test-while-idle: true
# 连接测试最小间隔
time-between-eviction-runs-millis: 60000
# 获取连接等待3秒 根据网络情况设定
max-wait: 3000
# 初始化4个连接
initial-size: 4
# 最大20个连接
max-active: 20
# 最少保持4个空闲连接
min-idle: 4
# 空闲连接保活, 超过配置的空闲时间会进行连接检查完成保活操作(数据库自身会断开达到空闲时间的连接, 程序使用断开的连接会报错)
keep-alive: true
# 连接超时
connect-timeout: 10000
# 连接超时
socket-timeout: 10000
# 查询超时
query-timeout: 90000
# 事务查询超时
transaction-query-timeout: 90000
# 解除注释后Druid连接池打印SQL语句 忽略日志等级配置
# filters: slf4j
slf4j:
statementLogEnabled: true
resultSetLogEnabled: false
connectionLogEnabled: false
dataSourceLogEnabled: false
statementCreateAfterLogEnabled: false
statementCloseAfterLogEnabled: false
statementExecuteAfterLogEnabled: false
#打印SQL替换参数
statementExecutableSqlLogEnable: true
statementPrepareAfterLogEnabled: false
statementPrepareCallAfterLogEnabled: false
statementParameterSetLogEnabled: false
# datasource:
# master:
# url: jdbc:mysql://${spring.datasource.host}:${spring.datasource.port}/${spring.datasource.dbname}?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&serverTimezone=UTC
# username: ${spring.datasource.username}
# password: ${spring.datasource.password}
# driver-class-name: com.mysql.cj.jdbc.Driver
# ===================== Redis配置 =====================
# redis单机模式
data:
redis:
database: 10
host: 127.0.0.1
port: 6379
# password: redis_JtjYRD # 密码为空时,请将本行注释
timeout: 3000 #超时时间(单位:秒)
lettuce: #Lettuce为Redis的Java驱动包
pool:
max-active: 8 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 8 # 连接池中的最大空闲连接
# redis集群模式
# redis:
# cluster:
# nodes:
# - 192.168.0.225:6380
# - 192.168.0.225:6381
# - 192.168.0.225:6382
# - 192.168.0.225:6383
# - 192.168.0.225:6384
# - 192.168.0.225:6385
# password: 123456 # 密码为空时,请将本行注释
# timeout: 3000 # 超时时间(单位:秒)
# lettuce: #Lettuce为Redis的Java驱动包
# pool:
# max-active: 8 # 连接池最大连接数
# max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
# min-idle: 0 # 连接池中的最小空闲连接
# max-idle: 8 # 连接池中的最大空闲连接
# ===================== Redis配置-End =====================
# ===================== 单点登录(用户信息同步)配置-Start =====================
cloud:
stream:
# 若使用RocketMQ-Start
rocketmq:
binder:
name-server: 192.168.10.6:30094
group: maxkey_identity
# 若使用RocketMQ-End
# 若使用RabbitMQ-Start
# binders:
# defaultRabbit: # 表示定义的名称用于binding整合
# type: rabbit # 消息组件类型
# environment: # 设置rabbitmq的相关环境配置
# spring:
# rabbitmq:
# host: 192.168.10.6
# port: 5672
# username: rabbitmq
# password: rabbitmq
# 若使用RabbitMQ-End
# 若使用Kafka-Start
# kafka:
# # KafkaBinderConfigurationProperties
# binder:
# brokers: 192.168.10.6:9092
# 若使用Kafka-End
bindings:
ssoEventReceiver-in-0:
content-type: text/json
destination: MXK_IDENTITY_MAIN_TOPIC
group: maxkey_identity
# ===================== 单点登录(用户信息同步)配置-End =====================
# ===================== AI配置-Start =====================
ai:
openai:
enabled: true
# 超时时间, 秒, 根据AI平台性能调整超时时间
timeout: 300
# 阿里百联平台
api-host: https://dashscope.aliyuncs.com/compatible-mode/
api-key: sk-def0e6d9d0f8497cb5bcfff8c0c19935
chat:
mode: qwen-max
# GPT转发平台
# api-host: https://api.chatanywhere.tech/
# api-key:
# chat:
# mode: gpt-3.5-turbo
# DeepSeek
# api-host: https://api.deepseek.com/v1/
# api-key:
# chat:
# mode: deepseek-chat
# ===================== AI配置-End =====================
# SpringDoc接口文档 访问地址http://127.0.0.1:30000/doc.html
springdoc:
default-flat-param-object: true
api-docs:
enabled: true
#SpringDoc增强
#knife4j:
# enable: true
# basic: #接口文档访问鉴权
# enable: true
# username: yunzhupaas
# password: 123456
lock4j:
aop:
# Lock4j注解是否启用
enabled: false
config:
# ===================== 是否开启测试环境 =====================
TestVersion: false
# ===================== ApacheShardingSphere 配置开关 =====================
sharding-sphere-enabled: false
# ===================== 文件存储配置-Start =====================
file-storage: #文件存储配置,不使用的情况下可以不写
default-platform: local-plus-1 #默认使用的存储平台
thumbnail-suffix: ".thumb.jpg" #缩略图后缀,例如【.min.jpg】【.png】
local-plus: # 本地存储升级版
- platform: local-plus-1 # 存储平台标识
enable-storage: true #启用存储
enable-access: true #启用访问(线上请使用 Nginx 配置,效率更高)
domain: "" # 访问域名例如“http://127.0.0.1:8030/”,注意后面要和 path-patterns 保持一致,“/”结尾,本地存储建议使用相对路径,方便后期更换域名
# base-path: /data/work-data/upload/jnpfsoft/yunzhupaas-resources/ # 基础路径
base-path: E:/XiangMu/yunzhu/zero-resources/ # 基础路径
path-patterns: /** # 访问路径
storage-path: # 存储路径
aliyun-oss: # 阿里云 OSS ,不使用的情况下可以不写
- platform: aliyun-oss-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
end-point: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.oss-cn-shanghai.aliyuncs.com/
base-path: hy/ # 基础路径
qiniu-kodo: # 七牛云 kodo ,不使用的情况下可以不写
- platform: qiniu-kodo-1 # 存储平台标识
enable-storage: false # 启用存储
access-key: ??
secret-key: ??
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如http://abc.hn-bkt.clouddn.com/
base-path: base/ # 基础路径
tencent-cos: # 腾讯云 COS
- platform: tencent-cos-1 # 存储平台标识
enable-storage: false # 启用存储
secret-id: ??
secret-key: ??
region: ?? #存仓库所在地域
bucket-name: ??
domain: ?? # 访问域名,注意“/”结尾例如https://abc.cos.ap-nanjing.myqcloud.com/
base-path: hy/ # 基础路径
minio: # MinIO由于 MinIO SDK 支持 AWS S3其它兼容 AWS S3 协议的存储平台也都可配置在这里
- platform: minio-1 # 存储平台标识
enable-storage: true # 启用存储
access-key: 9Y3sjaDWgbxKjXjm
secret-key: Bs2GyJwmOLpqNsQwbDjdinyUJQHtM0rc
end-point: http://192.168.0.207:9000/
bucket-name: v350
domain: ${config.file-storage.minio[0].end-point} # 访问域名,注意“/”结尾例如http://minio.abc.com/abc/
base-path: # 基础路径
# ===================== 文件存储配置-End =====================
# ===================== 第三方登录配置-Start =====================
socials:
# 第三方登录功能开关(false-关闭true-开启)
socials-enabled: false
config:
- # 微信
provider: wechat_open
client-id: your-client-id
client-secret: your-client-secret
- # qq
provider: qq
client-id: your-client-id
client-secret: your-client-secret
- # 企业微信
provider: wechat_enterprise
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 钉钉
provider: dingtalk
client-id: your-client-id
client-secret: your-client-secret
agentId: your-agentId
- # 飞书
provider: feishu
client-id: your-client-id
client-secret: your-client-secret
- # 小程序
provider: wechat_applets
client-id: your-client-id
client-secret: your-client-secret
# ===================== 第三方登录配置-End =====================
# ===================== 任务调度配置-Start =====================
xxl:
job:
accessToken: '432e62f3b488bc861d91b0e274e850cc'
i18n: zh_CN
logretentiondays: 30
triggerpool:
fast:
max: 200
slow:
max: 100
# xxl-job服务端地址
admin:
addresses: http://127.0.0.1:30020/xxl-job-admin/
executor:
address: ''
appname: xxl-job-executor-sample1
ip: ''
logpath: /data/applogs/xxl-job/jobhandler
logretentiondays: 30
port: 39999
# rest调用xxl-job接口地址
admin:
register:
handle-query-address: ${xxl.job.admin.addresses}api/handler/queryList
job-info-address: ${xxl.job.admin.addresses}api/jobinfo
log-query-address: ${xxl.job.admin.addresses}api/log
task-list-address: ${xxl.job.admin.addresses}api/ScheduleTask/List
task-info-address: ${xxl.job.admin.addresses}api/ScheduleTask/getInfo
task-save-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-update-address: ${xxl.job.admin.addresses}api/ScheduleTask
task-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/remove
task-start-or-remove-address: ${xxl.job.admin.addresses}api/ScheduleTask/updateTask
# ===================== 任务调度配置-End =====================
# ===================== 单点登录(SSO)配置-Start =====================
yunzhupaas:
sso:
# ===================== 单点登录(用户信息拉取)配置-Start =====================
connector:
# 是否开启用户信息拉取
enabled: false
# ===================== 单点登录(用户信息拉取)配置-End =====================
# ===================== 单点登录(用户信息推送)配置-Start =====================
pull:
# 是否开启用户信息推送
enabled: false
create-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account
replace-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account
change-password-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account/changePassword
delete-rest-address: http://localhost:9526/sso-mgt-api/api/idm/Account
credential-type: Basic
user-name: 747887288041603072
password: MYgMMjIwNzIwMjIxNTU4MTAxNzQlKQ
# ===================== 单点登录(用户信息推送)配置-End =====================
oauth:
#启用单点登录, 普通登录不可用
ssoEnabled: false
#轮询票据有效期
ticketTimeout: 120
#默认单点登录协议
defaultSSO: cas
#后端登录接口地址
loginPath: http://127.0.0.1:30000/api/oauth/Login
#login:
#JWT生成秘钥 不填写为默认值
#jwtSecretKey: WviMjFNC72VKwGqm5LPoheQo5XN9iN4d
sso:
#单点登录系统地址
baseUrl: http://127.0.0.1:8527
#登录成功后跳转到前端的页面
sucessFrontUrl: http://127.0.0.1:3100/sso
#错误信息是否输出到页面
ticketOutMessage: false
#logoutFrontUrl: http://sso.maxkey.top:8527/maxkey
#单点注销后端接口地址, 配置启用后YUNZHUPAAS退出会请求单点系统退出, 触发单点注销退出全部应用
#ssoLogoutApiUrl: ${oauth.sso.baseUrl}/sign/logout
auth2:
enabled: true
clientId: 747887288041603072
clientSecret: MYgMMjIwNzIwMjIxNTU4MTAxNzQlKQ
baseUrl: ${oauth.sso.baseUrl}
authorizeUrl: ${oauth.sso.auth2.baseUrl}/sign/authz/oauth/v20/authorize
accessTokenUrl: ${oauth.sso.auth2.baseUrl}/sign/authz/oauth/v20/token
userInfoUrl: ${oauth.sso.auth2.baseUrl}/sign/api/oauth/v20/me
cas:
enabled: true
baseUrl: ${oauth.sso.baseUrl}
serverLoginUrl: ${oauth.sso.cas.baseUrl}/sign/authz/cas/login
serverValidateUrl: ${oauth.sso.cas.baseUrl}/sign/authz/cas
# ===================== 单点登录(SSO)配置-End =====================
userUrl: http://192.168.3.31:8000/api-web/sys/user/save

View File

@@ -0,0 +1,163 @@
spring:
application:
name: yunzhupaas-boot
profiles:
# 指定环境配置 dev(开发环境-默认)、test(测试环境)、preview(预生产)、prod(生产环境)
active: test
servlet:
multipart: #文件传输配置
max-file-size: 100MB #单个数据大小限制
max-request-size: 100MB #请求总数据大小限制
enabled: true #是否启用分段上传支持
mvc:
#csrf-origins: ${config.FrontDomain}
cors:
# 允许跨域的域名
#allowed-origins: ${config.FrontDomain}
# 允许跨域的域名正则匹配 如需全部匹配设置为 '**', 因为包含凭据的请求不允许直接写* 这个写法可以直接返回当前请求域名
allowed-origin-patterns: '**'
# 允许跨域的请求方法 GET, POST, PUT, DELETE
allowed-methods: "*"
# 允许跨域的头部信息 Content-Type, Authorization
allowed-headers: "*"
options-max-age: 18000
headers:
server-name: ''
x-frame-options: sameorigin
x-content-type-options: disabled
x-xss-protection: enabled_mode_block
hiddenmethod: #隐式方法过滤器
filter:
enabled: true #默认开启。开启以支持PUT,DELETE表单提交方法
jackson: #序列化和反序列化json框架
serialization:
write-dates-as-timestamps: true #是否写入日期时间时间戳格式
time-zone: GMT+8 #指定日期格式化时区
main:
allow-bean-definition-overriding: true #允许同名bean后者覆盖,默认true
allow-circular-references: true #允许Bean相互引用,默认false
config:
# ===============静态资源目录映射==================
WebAnnexFilePath: WebAnnexFile
DataBackupFilePath: DataBackupFile
TemporaryFilePath: TemporaryFile
SystemFilePath: SystemFile
TemplateFilePath: TemplateFile
EmailFilePath: EmailFile
DocumentFilePath: DocumentFile
DocumentPreviewPath: DocumentPreview
UserAvatarFilePath: UserAvatar
IMContentFilePath: IMContentFile
MPMaterialFilePath: MPMaterial
TemplateCodePath: TemplateCode
BiVisualPath: BiVisualPath
# ===============功能格式限制==================
MPUploadFileType: bmp,png,jpeg,jpg,gif,mp3,wma,wav,amr,mp4
WeChatUploadFileType: jpg,png,doc,docx,ppt,pptx,xls,xlsx,pdf,txt,rar,zip,csv,amr,mp4
AllowUploadImageType: jpg,gif,png,bmp,jpeg,tiff,psd,swf,svg,pcx,dxf,wmf,emf,lic,eps,tga #允许上传图片类型
AllowUploadFileType: jpg,gif,png,bmp,jpeg,doc,docx,ppt,pptx,xls,xlsx,pdf,txt,rar,zip,csv,mp3,aac #允许上传文件类型
AllowPreviewFileType: doc,docx,xls,xlsx,ppt,pptx,pdf,jpg,gif,png,bmp,jpeg #允许预览文件类型
PreviewType: kkfile #文件预览方式 1.yozo 2.kkfile默认使用kkfile
kkFileUrl: http://127.0.0.1:30090/FileServer/ #kkfile文件预览服务地址
ApiDomain: http://127.0.0.1:30000 #后端域名(文档预览中使用)
FrontDomain: http://127.0.0.1:3100 #前端域名(文档预览中使用)
AppDomain: http://127.0.0.1:8080 #app/h5端域名配置(文档预览中使用)
FlowDomain: http://127.0.0.1:31000 #流程引擎接口地址
CodeAreasName: example #代码生成器模块命名
#===================== unipush =====================
AppPushUrl: https://8e84eea8-6922-4033-8e86-67ad7442e692.bspapp.com/unipush
#===================== 多租户配置 =====================
MultiTenancy: false #是否开启
MultiTenancyUrl: http://127.0.0.1:30006/api/tenant/DbName/ #多租户项目地址
#===================== 系统及错误报告反馈相关 =====================
SoftName: yunzhupaas-java-boot #项目名
SoftFullName: 集团信息化平台 #项目全名
SoftVersion: v5.2.0 #版本号
RecordLog: true #系统日志启用
ErrorReport: false #软件错误报告
ErrorReportTo: surrpot@yunzhupaas.com #软件错误报告接收者
IgexinEnabled: true #推送启动
#===================== APP =====================
AppVersion: v5.2.0 #APP版本号
IgexinAppid: HLFY9T2d1z7MySY8hwGwh4 #APPID应用的唯一标识
IgexinAppkey: 6Uiduugq648YDChhCjAt59 #APPKEY公匙相当于账号
IgexinMastersecret: pEyQm156SJ9iS7PbyjLCZ6 #Mastersecret私匙相当于密码
AppUpdateContent: ; #APP更新内容
#===================== 永中office在线预览配置 =====================
YozoDomain: //dcsapi.com/ #永中api域名
YozoDomainKey: 57462250284462899305150 #域名key
YozoCloudDomain: //dmc.yozocloud.cn #云预览
YozoAppId: yozoAgR41jgC0062 #appid
YozoAppKey: fc3134a9ba8bc6f4c69d635f9adf #app秘钥
YozoEditDomain: //eic.yozocloud.cn #云编辑
#===================== 系统功能配置 =====================
EnableLogicDelete: false #是否开启逻辑删除
CodeCertificateTimeout: 180 # 秒
check-file-pdf: false #检查上传的PDF文件安全
security:
# AES加密秘钥
security-key: EY8WePvjM5GGwQzn
# 是否开启接口鉴权
enable-pre-auth: true
# 接口加密
enable-rest-encrypt: true
# 事件配置
event:
# 默认时间发布、监听渠道: redis, mq
event-publish-type: redis
# Redis监听模式current, all
redis-publish-type: current
# 接口放行地址 与GatewayWhite中的默认URL合并
gateway:
# 禁止访问接口
block-url:
## 配置示例
#- /api/message/Notice
#- /api/permission/Users/*
# 不验证Token, 放行接口(默认记录日志)
white-url:
# # 配置示例
#- /api/message/Notice
#- /api/permission/Users/*
# 放行接口(不记录日志)
exclude-url:
# # 配置示例
#- /api/message/Notice
#- /api/permission/Users/*
# 入站IP禁止配置以外的IP访问block-url配置的接口
white-ip:
#- 192.168.0.10
#- 192.168.0.20
# 日志配置
logging:
config: classpath:logback-spring.xml
level:
#自定义第三方包名日志等级
# 解除注释后Druid连接池打印SQL语句
druid.sql.Statement: debug
# druid.sql.DataSource: debug
# druid.sql.Connection: debug
# druid.sql.ResultSet: debug
log:
level:
# 等级 TRACE,DEBUG,INFO,WARN,ERROR(不区分大小写)
root: info
path: log/${spring.application.name}
mybatis:
mapper-locations: classpath*:com/**/mapper/**/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,335 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--日志格式应用spring boot默认的格式也可以自己更改-->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<property name="FILE_LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] [%thread] [%logger{50}] [%M] [%line] - %msg%n" />
<springProperty scope="context" name="SERVICE_NAME" source="spring.application.name" defaultValue="yunzhupaas"/>
<!--定义日志存放的位置,默认存放在项目启动的相对路径的目录-->
<springProperty scope="context" name="LOG_PATH" source="log.path" defaultValue="log/${SERVICE_NAME}"/>
<!-- 全局日志等级 -->
<springProperty scope="context" name="LOG_LEVEL_ROOT" source="log.level.root" defaultValue="INFO"/>
<!-- 服务自定义等级 如需自定义服务日志等级 修改下方的【自定义服务名】与nacos上的log.level.自定义服务名=等级 -->
<springProperty scope="context" name="LOG_LEVEL" source="log.level.yunzhupaas-boot" defaultValue="${LOG_LEVEL_ROOT}"/>
<!-- 日志记录器日期滚动记录level为 ERROR 日志 -->
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_error.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/error/%d{yyyy-MM-dd,aux}/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志最大的历史7天-->
<maxHistory>7</maxHistory>
<!-- 除按日志记录之外还配置了日志文件不能超过2M若超过2M日志文件会以索引0开始
命名日志文件例如log-error-2013-12-21.0.log -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录error级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志记录器日期滚动记录level为 INFO 日志 -->
<appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_info.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/info/%d{yyyy-MM-dd,aux}/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志最大的历史7天-->
<maxHistory>7</maxHistory>
<!-- 除按日志记录之外还配置了日志文件不能超过2M若超过2M日志文件会以索引0开始
命名日志文件例如log-error-2013-12-21.0.log -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志记录器日期滚动记录level为 WARN 日志 -->
<appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_warn.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/warn/%d{yyyy-MM-dd,aux}/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志最大的历史7天-->
<maxHistory>7</maxHistory>
<!-- 除按日志记录之外还配置了日志文件不能超过2M若超过2M日志文件会以索引0开始
命名日志文件例如log-error-2013-12-21.0.log -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志记录器日期滚动记录level为 DEBUG 日志 -->
<appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_debug.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/debug/%d{yyyy-MM-dd,aux}/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志最大的历史7天-->
<maxHistory>7</maxHistory>
<!-- 除按日志记录之外还配置了日志文件不能超过2M若超过2M日志文件会以索引0开始
命名日志文件例如log-error-2013-12-21.0.log -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录debug级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 日志记录器,日期滚动记录,所有日志 -->
<appender name="FILE_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_total.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/total/%d{yyyy-MM-dd,aux}/log-total-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志最大的历史7天-->
<maxHistory>7</maxHistory>
<!-- 除按日志记录之外还配置了日志文件不能超过2M若超过2M日志文件会以索引0开始
命名日志文件例如log-error-2013-12-21.0.log -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<!-- 日志记录器日期滚动记录level 根据配置动态输出日志 -->
<appender name="FILE_RELEASE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${LOG_PATH}/log_release.log</file>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 归档的日志文件的路径,%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
<fileNamePattern>${LOG_PATH}/release/%d{yyyy-MM-dd,aux}/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--日志最大的历史7天-->
<maxHistory>7</maxHistory>
<!-- 除按日志记录之外还配置了日志文件不能超过2M若超过2M日志文件会以索引0开始
命名日志文件例如log-error-2013-12-21.0.log -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<!-- 追加方式记录日志 -->
<append>true</append>
<!-- 日志文件的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${FILE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>${LOG_LEVEL}</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 异步输出 DEBUG -->
<appender name="ASYNC_FILE_DEBUG" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="FILE_DEBUG"/>
</appender>
<!-- 异步输出 INFO -->
<appender name="ASYNC_FILE_INFO" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="FILE_INFO"/>
</appender>
<!-- 异步输出 WARN -->
<appender name="ASYNC_FILE_WARN" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="FILE_WARN"/>
</appender>
<!-- 异步输出 ERROR -->
<appender name="ASYNC_FILE_ERROR" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="FILE_ERROR"/>
</appender>
<!-- 异步输出 ALL -->
<appender name="ASYNC_FILE_ALL" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="FILE_ALL"/>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<!-- 异步输出 控制台 -->
<appender name="ASYNC_STDOUT" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="STDOUT"/>
</appender>
<!--<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
&lt;!&ndash; 必填目标LogStash的 IP:Port &ndash;&gt;
<destination>192.168.0.50:50000</destination>
&lt;!&ndash; 可选:保持程序存活时间 &ndash;&gt;
<keepAliveDuration>5 minutes</keepAliveDuration>
&lt;!&ndash; 可选:重连延迟时长 &ndash;&gt;
<reconnectionDelay>10 second</reconnectionDelay>
&lt;!&ndash; 可选:等待策略 &ndash;&gt;
<waitStrategyType>sleeping</waitStrategyType>
&lt;!&ndash; ============ encoder必须配置,有多种可选 ============= &ndash;&gt;
&lt;!&ndash; 编码器二LoggingEventCompositeJsonEncoder &ndash;&gt;
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
&lt;!&ndash; 时间戳:时区 &ndash;&gt;
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
&lt;!&ndash; 模式 &ndash;&gt;
<pattern>
<pattern>
{
"severity": "%level",
"service": "${SERVICE_NAME:-}",
"trace": "%X{X-B3-TraceId:-}",
"span": "%X{X-B3-SpanId:-}",
"exportable": "%X{X-Span-Export:-}",
"pid": "${PID:-}",
"thread": "%thread",
"class": "%logger{40}",
"msg": "%message"
&lt;!&ndash;"idx_pre": "elk-original-third-access",&ndash;&gt;
&lt;!&ndash;"json": "#asJson{%message}" 这个asJson可以把对应的字符串作为json对象取出来这样es可以对json里面的字段索引了&ndash;&gt;
}
</pattern>
</pattern>
</providers>
</encoder>
</appender>-->
<!--<appender name="skywalking-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern>
</layout>
</encoder>
</appender>-->
<root level="${LOG_LEVEL}">
<appender-ref ref="ASYNC_STDOUT"/>
<appender-ref ref="ASYNC_FILE_ERROR"/>
<appender-ref ref="ASYNC_FILE_INFO"/>
<appender-ref ref="ASYNC_FILE_WARN"/>
<appender-ref ref="ASYNC_FILE_DEBUG"/>
<appender-ref ref="ASYNC_FILE_ALL"/>
<!--<appender-ref ref="LOGSTASH"/>-->
<!--<appender-ref ref="skywalking-log"/>-->
</root>
</configuration>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.CrmCustomerMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.CrmLeadMapper">
</mapper>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.CrmOpportunityMapper">
<update id="updateByCustomerByCustomerId">
update crm_customer set last_followup_date=#{lastFollowupDate} where company_id=#{customerId}
</update>
<select id="selectCustomerBycustomerId" resultType="java.lang.String">
select company_name from mdm_company where company_id=#{customerId}
</select>
</mapper>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.mapper.BigDataMapper">
<select id="maxCode" resultType="Integer">
SELECT MAX(F_EN_CODE) FROM ext_big_data
</select>
</mapper>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.mapper.FlowFormMapper">
<resultMap id="flowInfo" type="com.yunzhupaas.base.model.flow.FlowTempInfoModel">
<id column="F_Id" property="id"/>
<result column="F_EnCode" property="enCode"/>
</resultMap>
<select id="findFLowInfo" parameterType="String" resultMap="flowInfo">
SELECT ft.F_En_Code as F_EnCode,ft.F_Id as F_Id,F_Enabled_Mark as enabledMark FROM flow_template ft where ft.F_Id =#{tempId}
</select>
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.BcmProjectTypeMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.MdmCompanyBankMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.MdmCompanyContactMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.MdmCompanyMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.MdmContractTypeMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.MdmProjectMapper">
</mapper>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.PcmContractMapper">
<insert id="addPcmDocument">
insert into pcm_document (document_id,file_size,file_name,file_ext_name,local_path)
values (#{fileId},#{fileSize},#{name},#{fileExtension},#{url})
</insert>
<insert id="addPcmBusinessDocument">
insert into pcm_business_document (table_name,business_object_id,document_id)
values (#{tableName},#{businessObjectId},#{documentId})
</insert>
<delete id="deleteByBusinessObjectId">
delete from pcm_business_document where business_object_id=#{businessObjectId} and table_name =#{tableName}
</delete>
<select id="selectByIdAndTableName" resultType="com.yunzhupaas.base.model.pcmcontract.PcmDocument">
select document.document_id fileId,document.file_size fileSize,document.
file_name 'name',document.file_ext_name fileExtension,document.local_path url
from pcm_business_document business
left join pcm_document document on business.document_id=document.document_id
where business.table_name=#{tableName} and business.business_object_id=#{id}
</select>
<select id="selectByFEnCode" resultType="java.lang.String">
select f_full_name from base_dictionary_data where f_en_code=#{resourcesName} and f_dictionary_type_id='808608974935952773'
</select>
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.Pcm_contract_itemMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.Pcm_payment_planMapper">
</mapper>

View File

@@ -0,0 +1,243 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.permission.mapper.AuthorizeMapper">
<resultMap id="ModuleVO" type="com.yunzhupaas.base.model.module.ModuleModel">
<id column="f_id" property="id"/>
<result column="f_parent_id" property="parentId"/>
<result column="f_full_name" property="fullName"/>
<result column="f_en_code" property="enCode"/>
<result column="f_type" property="type"/>
<result column="f_url_address" property="urlAddress"/>
<result column="f_link_target" property="linkTarget"/>
<result column="f_category" property="category"/>
<result column="f_icon" property="icon"/>
<result column="f_sort_code" property="sortCode"/>
<result column="f_property_json" property="propertyJson"/>
<result column="f_system_id" property="systemId"/>
<result column="f_description" property="description"/>
<result column="f_creator_time" property="creatorTimes"/>
</resultMap>
<resultMap id="ButtonVO" type="com.yunzhupaas.base.model.button.ButtonModel">
<id column="f_id" property="id"/>
<result column="f_parent_id" property="parentId"/>
<result column="f_full_name" property="fullName"/>
<result column="f_en_code" property="enCode"/>
<result column="f_icon" property="icon"/>
<result column="f_url_address" property="urlAddress"/>
<result column="f_module_id" property="moduleId"/>
<result column="f_creator_time" property="creatorTimes"/>
<result column="f_sort_code" property="sortCode"/>
</resultMap>
<resultMap id="ColumnVO" type="com.yunzhupaas.base.model.column.ColumnModel">
<id column="f_id" property="id"/>
<result column="f_parent_id" property="parentId"/>
<result column="f_full_name" property="fullName"/>
<result column="f_en_code" property="enCode"/>
<result column="f_bind_table" property="bindTable"/>
<result column="f_bind_table_name" property="bindTableName"/>
<result column="f_module_id" property="moduleId"/>
<result column="f_creator_time" property="creatorTimes"/>
<result column="f_sort_code" property="sortCode"/>
</resultMap>
<resultMap id="ResourceVO" type="com.yunzhupaas.base.model.resource.ResourceModel">
<id column="f_id" property="id"/>
<result column="f_full_name" property="fullName"/>
<result column="f_en_code" property="enCode"/>
<result column="f_condition_json" property="conditionJson"/>
<result column="f_condition_text" property="conditionText"/>
<result column="f_module_id" property="moduleId"/>
<result column="f_match_logic" property="matchLogic"/>
<result column="f_object_id" property="objectId"/>
<result column="f_creator_time" property="creatorTimes"/>
<result column="f_sort_code" property="sortCode"/>
</resultMap>
<resultMap id="FormVO" type="com.yunzhupaas.base.model.form.ModuleFormModel">
<id column="f_id" property="id"/>
<result column="f_parent_id" property="parentId"/>
<result column="f_full_name" property="fullName"/>
<result column="f_en_code" property="enCode"/>
<result column="f_module_id" property="moduleId"/>
<result column="f_creator_time" property="creatorTimes"/>
<result column="f_sort_code" property="sortCode"/>
</resultMap>
<resultMap id="SystemVO" type="com.yunzhupaas.base.model.base.SystemBaeModel">
<id column="f_id" property="id"/>
<result column="f_full_name" property="fullName"/>
<result column="f_en_code" property="enCode"/>
<result column="f_icon" property="icon"/>
<result column="f_property_json" property="propertyJson"/>
<result column="f_description" property="description"/>
<result column="f_sort_code" property="sortCode"/>
<result column="f_enabled_mark" property="enabledMark"/>
<result column="f_workflow_enabled" property="workflowEnabled"/>
<result column="f_navigation_icon" property="navigationIcon"/>
<result column="f_work_logo_icon" property="workLogoIcon"/>
<result column="f_creator_time" property="creatorTimes"/>
</resultMap>
<select id="findModule" parameterType="String" resultMap="ModuleVO">
SELECT * FROM base_module WHERE 1=1
AND (f_id IN
<trim suffixOverrides=" OR f_id IN()">
<foreach collection="objectId" item="id" index="index" open="(" close=")" >
<if test="index != 0">
<choose>
<when test="index % 1000 == 999">) OR f_id IN (</when>
<otherwise>,</otherwise>
</choose>
</if>
#{id}
</foreach>
</trim>
)
<if test="mark == 1">
and f_enabled_mark = #{mark}
</if>
<if test="systemId != null and systemId.size > 0">
and f_system_id in
<foreach collection="systemId" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</if>
and f_en_code not in
<foreach collection="moduleCode" item="urlAddress" open="(" close=")" separator=",">
#{urlAddress}
</foreach>
<if test="moduleAuthorize != null and moduleAuthorize.size > 0">
and f_id not in
<foreach collection="moduleAuthorize" item="moduleId" open="(" close=")" separator=",">
#{moduleId}
</foreach>
</if>
<if test="moduleUrlAddressAuthorize != null and moduleUrlAddressAuthorize.size > 0">
and
((f_url_address not in
<foreach collection="moduleUrlAddressAuthorize" item="urlAddress" open="(" close=")" separator=",">
#{urlAddress}
</foreach>
)
or f_url_address is null
)
</if>
Order by f_sort_code asc,f_creator_time desc
</select>
<select id="findButton" parameterType="String" resultMap="ButtonVO">
SELECT * FROM base_module_button WHERE 1=1
AND (f_id IN
<trim suffixOverrides=" OR f_id IN()">
<foreach collection="objectId" item="id" index="index" open="(" close=")">
<if test="index != 0">
<choose>
<when test="index % 1000 == 999">) OR f_id IN (</when>
<otherwise>,</otherwise>
</choose>
</if>
#{id}
</foreach>
</trim>
)
and f_enabled_mark = 1 Order by f_sort_code asc,f_creator_time desc
</select>
<select id="findColumn" parameterType="String" resultMap="ColumnVO">
SELECT * FROM base_module_column WHERE 1=1
AND (f_id IN
<trim suffixOverrides=" OR f_id IN()">
<foreach collection="objectId" item="id" index="index" open="(" close=")">
<if test="index != 0">
<choose>
<when test="index % 1000 == 999">) OR f_id IN (</when>
<otherwise>,</otherwise>
</choose>
</if>
#{id}
</foreach>
</trim>
)
and f_enabled_mark = 1 Order by f_sort_code asc,f_creator_time desc
</select>
<select id="findForms" parameterType="String" resultMap="FormVO">
SELECT * FROM base_module_form WHERE 1=1
AND (f_id IN
<trim suffixOverrides=" OR f_id IN()">
<foreach collection="objectId" item="id" index="index" open="(" close=")">
<if test="index != 0">
<choose>
<when test="index % 1000 == 999">) OR f_id IN (</when>
<otherwise>,</otherwise>
</choose>
</if>
#{id}
</foreach>
</trim>
)
and f_enabled_mark = 1 Order by f_sort_code asc,f_creator_time desc
</select>
<select id="findSystem" parameterType="String" resultMap="SystemVO">
SELECT * FROM base_system WHERE f_id IN
<foreach collection="objectId" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
<if test="mark == 1">
and f_enabled_mark = #{mark}
</if>
<if test="enCode != null and enCode != ''">
and f_en_code != #{enCode}
</if>
<if test="moduleAuthorize != null and moduleAuthorize.size > 0">
and f_id not in
<foreach collection="moduleAuthorize" item="moduleId" open="(" close=")" separator=",">
#{moduleId}
</foreach>
</if>
Order by f_sort_code asc,f_creator_time desc
</select>
<select id="findResource" parameterType="String" resultMap="ResourceVO">
select s.*, a.f_object_id from base_module_scheme s
LEFT JOIN base_authorize a on s.f_id = a.f_item_id
where 1=1
AND (s.f_id IN
<trim suffixOverrides=" OR s.f_id IN()">
<foreach collection="objectId" item="id" index="index" open="(" close=")">
<if test="index != 0">
<choose>
<when test="index % 1000 == 999">) OR s.f_id IN (</when>
<otherwise>,</otherwise>
</choose>
</if>
#{id}
</foreach>
</trim>
)
and s.f_enabled_mark = 1 Order by s.f_sort_code asc,s.f_creator_time desc
</select>
<select id="findButtonAdmin" parameterType="Integer" resultMap="ButtonVO">
SELECT * FROM base_module_button WHERE f_enabled_mark = #{mark} Order by f_sort_code asc,f_creator_time desc
</select>
<select id="findColumnAdmin" parameterType="Integer" resultMap="ColumnVO">
SELECT * FROM base_module_column WHERE f_enabled_mark = #{mark} Order by f_sort_code asc,f_creator_time desc
</select>
<select id="findFormsAdmin" parameterType="Integer" resultMap="FormVO">
SELECT * FROM base_module_form WHERE f_enabled_mark = #{mark} Order by f_sort_code asc,f_creator_time desc
</select>
<select id="findResourceAdmin" parameterType="Integer" resultMap="ResourceVO">
SELECT * FROM base_module_scheme WHERE f_enabled_mark = #{mark} Order by f_sort_code asc,f_creator_time desc
</select>
</mapper>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.message.mapper.ImContentMapper">
<!-- <update id="SendMessage" parameterType="com.yunzhupaas.system.entity.IMContentEntity">
<id column="F_Id" property="id"/>
<result column="F_SENDUSERID" property="sendUserId"/>
<result column="F_SENDTIME" property="sendTime"/>
<result column="F_RECEIVEUSERID" property="receiveUserId"/>
<result column="F_RECEIVETIME" property="receiveTime"/>
<result column="f_content" property="content"/>
<result column="f_content_type" property="contentType"/>
<result column="F_STATE" property="state"/>
</update>-->
<select id="getUnreadList" parameterType="String" resultType="com.yunzhupaas.message.model.ImUnreadNumModel">
SELECT * FROM (
SELECT SUM(CASE WHEN f_enabled_mark = 0 THEN 1 ELSE 0 END) UnreadNum, f_send_user_id SendUserId, f_receive_user_id ReceiveUserId
FROM base_im_content WHERE 1 = 1 AND f_receive_user_id = #{receiveUserId} GROUP BY f_send_user_id, f_receive_user_id
) t WHERE UnreadNum > 0
</select>
<select id="getUnreadLists" parameterType="String" resultType="com.yunzhupaas.message.model.ImUnreadNumModel">
select f_send_user_id SendUserId, f_content DefaultMessage,f_content_type DefaultMessageType, f_send_time DefaultMessageTime from base_im_content WHERE 1 = 1 AND f_receive_user_id = #{receiveUserId} AND f_enabled_mark = 0 order by f_send_time desc
</select>
<update id="readMessage" parameterType="map">
UPDATE base_im_content SET f_enabled_mark = 1, f_receive_time = #{map.receiveTime} WHERE 1 = 1 AND f_enabled_mark = 0 AND f_send_user_id = #{map.sendUserId} AND f_receive_user_id = #{map.receiveUserId}
</update>
</mapper>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.message.mapper.ImReplyMapper">
<resultMap id="imReplyList" type="com.yunzhupaas.message.model.ImReplyListModel">
<id column="f_receive_user_id" property="id"/>
<result column="f_user_id" property="userId"/>
<result column="F_HEAD_ICON" property="headIcon"/>
<result column="f_receive_time" property="latestDate"/>
<result column="f_content_type" property="messageType"/>
<result column="f_content" property="latestMessage"/>
<result column="f_delete_user_id" property="deleteUserId"/>
<result column="f_delete_mark" property="deleteMark"/>
</resultMap>
<select id="getImReplyList" resultMap="imReplyList" parameterType="com.yunzhupaas.message.model.ImReplyListVo">
SELECT
ir.f_user_id,
ir.f_receive_user_id,
ir.f_delete_user_id,
bu.F_HEAD_ICON,
ir.f_receive_time,
ic.f_content_type,
ic.f_content,
ic.f_delete_user_id,
ic.f_delete_mark
FROM
base_im_reply ir
LEFT JOIN base_user bu ON ir.f_user_id = bu.F_Id
LEFT JOIN base_im_content ic ON ic.f_send_user_id = bu.F_Id
AND ir.f_user_id = ic.f_send_user_id
AND ir.f_receive_user_id = ic.f_receive_user_id
AND ir.f_receive_time = ic.f_send_time
AND (ir.f_delete_mark != 1 OR ir.f_delete_mark IS NULL)
</select>
</mapper>

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.message.mapper.MessageMapper">
<resultMap id="Message" type="com.yunzhupaas.message.entity.MessageReceiveEntity">
<id column="f_id" property="id"/>
<result column="f_title" property="title"/>
<result column="f_type" property="type"/>
<result column="f_creator_time" property="creatorTime"/>
<result column="f_creator_user_id" property="creatorUserId"/>
<result column="f_last_modify_time" property="lastModifyTime"/>
<result column="f_enabled_mark" property="enabledMark"/>
<result column="f_is_read" property="isRead"/>
<result column="f_last_modify_user_id" property="lastModifyUserId"/>
</resultMap>
<select id="getMessageList" parameterType="map" resultMap="Message">
SELECT r.f_id, r.f_title, r.f_type, r.f_is_read, r.f_creator_time, r.f_creator_user_id, r.f_last_modify_time, r.f_last_modify_user_id,
u.f_real_name,u.f_account FROM base_message r
LEFT JOIN base_user u ON u.f_id = r.f_user_id where 1 = 1
<if test="map.userId != null">
AND r.f_user_id= #{map.userId}
</if>
<if test="map.keyword != null">
AND (r.f_title like #{map.keyword} OR u.f_real_name LIKE #{map.keyword} OR u.f_account LIKE #{map.keyword})
</if>
<if test="map.type != null">
AND r.f_type = #{map.type}
</if>
<if test="map.isRead != null">
AND r.f_is_read = #{map.isRead}
</if>
ORDER BY r.f_last_modify_time desc
</select>
<select id="getUnreadCount" resultType="int">
SELECT COUNT(1) FROM base_message
WHERE f_user_id = #{userId} AND f_is_read = 0 AND f_type = #{type}
</select>
<select id="getInfoDefault" parameterType="int" resultMap="Message">
SELECT * FROM base_message WHERE 1 = 1 AND f_type = #{type} ORDER BY f_creator_time DESC
</select>
</mapper>

View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.PortalManageMapper">
<sql id="selectPages">
SELECT
<!-- 门户管理表 -->
bpm.f_id id,
bpm.f_enabled_mark enabledMark,
bpm.f_platform platform,
bpm.f_description description,
bpm.F_Tenant_Id tenantId,
bpm.f_sort_code sortCode,
bpm.f_system_id systemId,
bpm.f_portal_id portalId,
bpm.f_creator_time creatorTime,
bpm.f_last_modify_time lastModifyTime,
<!-- 门户表 -->
bp.f_category categoryId,
bp.f_full_name portalName,
bd.f_full_name categoryName,
<!-- 用户表 -->
us.F_Real_Name createUserName,
us.F_Account createUserAccount,
us2.F_Real_Name modifyUserName,
us2.F_Account modifyUserAccount
FROM
base_portal_manage bpm
LEFT JOIN
base_portal bp
ON
bpm.f_portal_id = bp.f_id
LEFT JOIN
base_user us
ON
bpm.F_Creator_User_Id = us.f_id
LEFT JOIN
base_user us2
ON
bpm.F_Last_Modify_User_Id = us2.f_id
LEFT JOIN
base_dictionary_data bd
ON bp.f_category = bd.f_id
WHERE 1 = 1
<if test="pmPage.keyword != null and pmPage.keyword != ''">
AND (bp.f_full_name LIKE #{pmPage.keyword} OR bpm.f_description LIKE #{pmPage.keyword})
</if>
<if test="pmPage.category != null and pmPage.category != ''">
AND
bp.f_category = #{pmPage.category}
</if>
<if test="pmPage.enabledMark != null">
AND
bpm.f_enabled_mark = #{pmPage.enabledMark}
<!-- AND bp.f_enabled_mark = #{pmPage.enabledMark} -->
</if>
<if test="pmPage.platform != null and pmPage.platform != ''">
AND
bpm.f_platform LIKE #{pmPage.platform}
</if>
<if test="pmPage.systemId != null and pmPage.systemId != ''">
AND
bpm.f_system_id = #{pmPage.systemId}
</if>
<if test="pmPage.state != null and pmPage.state != ''">
AND
bp.F_state != #{pmPage.state}
</if>
</sql>
<select id="selectPortalManageDoPage" resultType="com.yunzhupaas.base.model.portalManage.PortalManagePageDO" parameterType="com.yunzhupaas.base.model.portalManage.PortalManagePage">
SELECT
*
FROM (<include refid="selectPages"></include>) TempTable
ORDER BY
sortCode ASC,
creatorTime DESC
</select>
<select id="selectPortalManageDoList" resultType="com.yunzhupaas.base.model.portalManage.PortalManagePageDO" parameterType="com.yunzhupaas.base.model.portalManage.PortalManagePage">
SELECT
*
FROM (<include refid="selectPages"></include>) TempTable
ORDER BY
sortCode ASC,
creatorTime DESC
</select>
<select id="selectPortalBySystemIds" resultType="com.yunzhupaas.base.model.portalManage.PortalManagePageDO" parameterType="java.lang.String">
SELECT
bpm.f_id id,
bpm.f_enabled_mark enabledMark,
bpm.f_platform platform,
bpm.f_description description,
bpm.f_sort_code sortCode,
bpm.f_system_id systemId,
bpm.f_portal_id portalId,
bpm.f_creator_time creatorTime,
bpm.f_last_modify_time lastModifyTime,
bp.f_category categoryId,
bp.f_full_name portalName,
bd.f_full_name categoryName
FROM
base_portal bp
LEFT JOIN base_portal_manage bpm ON bpm.f_portal_id = bp.f_id
LEFT JOIN base_dictionary_data bd ON bp.f_category = bd.f_id
WHERE bpm.f_system_id IN
<foreach collection="systemIds"
item="systemId" index="index" separator="," open="(" close=")">
#{systemId}
</foreach>
<if test="collect != null and collect.size > 0">
AND bpm.f_id IN
<foreach collection="collect"
item="managerId" index="index" separator="," open="(" close=")">
#{managerId}
</foreach>
</if>
AND bpm.f_enabled_mark = 1
ORDER BY
bpm.f_sort_code ASC,
bpm.f_creator_time DESC
</select>
</mapper>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.permission.mapper.PositionMapper">
<select id="getListByUserId" parameterType="String" resultType="com.yunzhupaas.permission.entity.PositionEntity">
SELECT * FROM base_position WHERE F_ID IN(SELECT F_OBJECT_ID FROM base_user_relation WHERE F_USER_ID = #{userId}) ORDER BY F_SORT_CODE
</select>
</mapper>

View File

@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.permission.mapper.RoleMapper">
<select id="getListId" resultType="java.lang.String">
SELECT * FROM base_role WHERE F_ID IN(SELECT F_OBJECT_ID FROM base_user_relation WHERE F_USER_ID = #{userId}) ORDER BY F_SORT_CODE
</select>
<select id="query" resultType="java.lang.String">
SELECT F_Id FROM base_role
<if test="globalMark != 1">
WHERE 1 = 1
AND F_Id IN (
SELECT DISTINCT
a.F_Id
FROM
(
SELECT
br.F_Id
FROM
base_organize bo
LEFT JOIN base_organize_relation bor ON bo.F_Id = bor.F_Organize_Id
LEFT JOIN base_role br ON br.F_Id = bor.F_Object_Id
WHERE
bor.F_Object_Type = 'Role'
AND bor.F_Object_Type IS NOT NULL
<if test="orgIdList != null and orgIdList.size() != 0">
AND bo.F_Id IN
<foreach collection="orgIdList"
item="orgIds" index="index" separator="," open="(" close=")">
#{orgIds}
</foreach>
</if>
) a
)
</if>
<if test="globalMark == -1 or globalMark == 1">
<if test="globalMark != 1">
OR
</if>
<if test="globalMark == 1">
Where
</if>
F_Id IN
(
SELECT F_Id FROM base_role WHERE F_Global_Mark = 1
)
</if>
<if test="keyword != null and keyword != ''">
AND (F_Full_Name LIKE #{keyword} OR F_En_Code LIKE #{keyword})
</if>
<if test="enabledMark != null">
AND (f_enabled_Mark = #{enabledMark})
</if>
ORDER BY f_sort_code asc, f_creator_time desc
</select>
<select id="count" resultType="java.lang.Long">
SELECT count(F_Id) FROM base_role
<if test="globalMark != 1">
WHERE 1 = 1
AND F_Id IN (
SELECT DISTINCT
a.F_Id
FROM
(
SELECT
br.F_Id
FROM
base_organize bo
LEFT JOIN base_organize_relation bor ON bo.F_Id = bor.F_Organize_Id
LEFT JOIN base_role br ON br.F_Id = bor.F_Object_Id
WHERE
bor.F_Object_Type = 'Role'
AND bor.F_Object_Type IS NOT NULL
<if test="orgIdList != null and orgIdList.size() != 0">
AND bo.F_Id IN
<foreach collection="orgIdList"
item="orgIds" index="index" separator="," open="(" close=")">
#{orgIds}
</foreach>
</if>
) a
)
</if>
<if test="globalMark == -1 or globalMark == 1">
<if test="globalMark != 1">
OR
</if>
<if test="globalMark == 1">
Where
</if>
F_Id IN
(
SELECT F_Id FROM base_role WHERE F_Global_Mark = 1
)
</if>
<if test="keyword != null and keyword != ''">
AND (F_Full_Name LIKE #{keyword} OR F_En_Code LIKE #{keyword})
</if>
<if test="enabledMark != null">
AND (f_enabled_Mark = #{enabledMark})
</if>
</select>
</mapper>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.base.mapper.SysconfigMapper">
<delete id="deleteFig">
delete from base_sys_config where F_Category ='SysConfig'
</delete>
<delete id="deleteMpFig">
delete from base_sys_config where F_Category='MPConfig'
</delete>
<delete id="deleteQyhFig">
delete from base_sys_config where F_Category='QYHConfig'
</delete>
</mapper>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.permission.mapper.UserMapper">
<select id="getListId" resultType="java.lang.String">
SELECT F_Id from base_user WHERE F_Enabled_Mark = 1
</select>
<select id="query" resultType="java.lang.String">
SELECT F_Id FROM
(SELECT DISTINCT u.F_Id,u.F_Sort_Code,u.F_Creator_Time
FROM base_user_relation ul1,base_user u
WHERE u.F_Id = ul1.F_User_Id
AND u.f_account != 'admin'
<if test="enabledMark != null">
AND u.f_enabled_mark = #{enabledMark}
</if>
<if test="gender != null and gender != ''">
AND u.f_gender = #{gender}
</if>
<if test="account != null and account != ''">
and (u.F_Account like #{account} or u.F_Real_Name like #{account} or u.F_Mobile_Phone like
#{account})
</if>
<if test="orgIdList != null and orgIdList.size > 0">
AND (ul1.F_Object_Id IN
<trim suffixOverrides=" OR ul1.F_Object_Id IN()">
<foreach collection="orgIdList" item="orgIds" index="index" open="(" close=")">
<if test="index != 0">
<choose>
<when test="index % 1000 == 999">) OR ul1.F_Object_Id IN (</when>
<otherwise>,</otherwise>
</choose>
</if>
#{orgIds}
</foreach>
</trim>
)
</if>
ORDER BY u.F_Sort_Code ASC,u.F_Creator_Time DESC) uu
</select>
<select id="count" resultType="java.lang.Long">
SELECT count(F_Id) FROM
(SELECT DISTINCT u.F_Id,u.F_Sort_Code,u.F_Creator_Time
FROM base_user_relation ul1,base_user u
WHERE u.F_Id = ul1.F_User_Id
AND u.F_Account != 'admin'
<if test="enabledMark != null">
AND u.f_enabled_mark = #{enabledMark}
</if>
<if test="gender != null and gender != ''">
AND u.f_gender = #{gender}
</if>
<if test="account != null and account != ''">
and (u.F_Account like #{account} or u.F_Real_Name like #{account} or u.F_Mobile_Phone like
#{account})
</if>
<if test="orgIdList != null and orgIdList.size > 0">
AND (ul1.F_Object_Id IN
<trim suffixOverrides=" OR ul1.F_Object_Id IN()">
<foreach collection="orgIdList" item="orgIds" index="index" open="(" close=")">
<if test="index != 0">
<choose>
<when test="index % 1000 == 999">) OR ul1.F_Object_Id IN (</when>
<otherwise>,</otherwise>
</choose>
</if>
#{orgIds}
</foreach>
</trim>
)
</if>) uu
</select>
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.mapper.TrainExamRecordsMapper">
</mapper>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.mapper.TrainLibraryEssayQuestionMapper">
<select id="getListByParentId" resultType="com.yunzhupaas.entity.TrainLibraryEssayQuestionEntity">
select f_id as id,
f_bank_id as fbankId,
f_full_name as ffullName,
f_answer as fanswer,
f_result as fresult
from make_train_library_essay_question
where f_bank_id = #{parentId}
</select>
<update id="updateResult">
<foreach collection="items" item="item" separator=";">
update make_train_library_essay_question
set f_result = #{item.result}
where f_id = #{item.id}
</foreach>
</update>
</mapper>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.mapper.TrainLibraryJudgmentMapper">
<select id="getListByParentId" resultType="com.yunzhupaas.entity.TrainLibraryJudgmentEntity">
select f_id as id,
f_bank_id as fbankId,
f_full_name as ffullName,
f_answer as fanswer
from make_train_library_judgment
where f_bank_id = #{parentId}
</select>
</mapper>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.mapper.TrainLibraryMoreMapper">
<select id="getListByParentId" resultType="com.yunzhupaas.entity.TrainLibraryMoreEntity">
select f_id as id,
f_bank_id as fbankId,
f_full_name as ffullName,
f_options_a as foptionsA,
f_options_b as foptionsB,
f_options_c as foptionsC,
f_options_d as foptionsD,
f_answer as fanswer
from make_train_library_more
where f_bank_id = #{parentId}
</select>
</mapper>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.mapper.TrainLibrarySingleMapper">
<select id="getListByParentId" resultType="com.yunzhupaas.entity.TrainLibrarySingleEntity">
select f_id as id,
f_bank_id as fbankId,
f_full_name as ffullName,
f_options_a as foptionsA,
f_options_b as foptionsB,
f_options_c as foptionsC,
f_options_d as foptionsD,
f_answer as fanswer
from make_train_library_single
where f_bank_id = #{parentId}
</select>
</mapper>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yunzhupaas.mapper.TrainTestPaperLibraryMapper">
<insert id="saveRecords">
INSERT INTO make_train_exam_records
(f_id, f_number,f_library_id, f_examiners, f_full_name, f_sort, f_mark, f_result_score, f_basic_score, f_question_flag,
f_question_status, f_question_score, f_enabled_mark, f_sort_code, f_organize_id, f_creator_time,
f_creator_user_id,f_question_num,f_per_question)
VALUE (#{id}, #{fnumber},#{flibraryId} ,#{fexaminers}, #{ffullName}, #{fsort}, #{fmark}, #{fresultScore}, #{fbasicScore},
#{fquestionFlag},
#{fquestionStatus}, #{fquestionScore}, #{fenabledMark}, #{fsortCode}, #{forganizeId}, #{fcreatorTime},
#{fcreatorUserId},#{fquestionNum},#{fperQuestion})
</insert>
</mapper>

View File

@@ -0,0 +1,52 @@
databaseName: myshardingsphere
dataSources: # 数据源配置 =============
# <数据源_0>: # 自定义数据源名称
# dataSourceClassName: com.zaxxer.hikari.HikariDataSource # 连接池提供方完整类名Spring默认Hikari
# driverClassName: com.mysql.jdbc.Driver # JDBC驱动
# jdbcUrl: jdbc:mysql://{host}:{port}/{dbName}?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8 # 数据库连接URL
# username: {username} # 用户
# password: {password} # 密码
ds0: # 自定义数据源名称
dataSourceClassName: com.alibaba.druid.pool.DruidDataSource # 连接池提供方完整类名Spring默认Hikari
driverClassName: com.mysql.jdbc.Driver # JDBC驱动
url: jdbc:mysql://127.0.0.1:3306/sharding1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8 # 数据库连接URL
username: root # 用户
password: 123456 # 密码
ds1: # 自定义数据源名称
dataSourceClassName: com.alibaba.druid.pool.DruidDataSource # 连接池提供方完整类名Spring默认Hikari
driverClassName: com.mysql.jdbc.Driver # JDBC驱动
url: jdbc:mysql://127.0.0.1:3306/sharding2?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8 # 数据库连接URL
username: root # 用户
password: 123456 # 密码
rules: # 规则 =============
- !SHARDING # 注意类似“- !SHARDING”标识不能省略
tables:
ext_bigdata: # 自定义逻辑表名
actualDataNodes: ds${0..1}.ext_bigdata_$->{0..1} # 由数据源名 + 表名组成(参考 Inline 语法规则)
databaseStrategy:
standard:
shardingColumn: F_Id # 分表依据字段
shardingAlgorithmName: myDataSourceAlgorithm
tableStrategy: # 表策略 -------
standard:
shardingColumn: F_Id # 分表依据字段
shardingAlgorithmName: myTableAlgorithm
# defaultDatabaseStrategy: # 库策略 -------
# standard:
# shardingColumn: F_Id
# shardingAlgorithmName: myDataSourceAlgorithm
shardingAlgorithms: # 分片算法 -------
myDataSourceAlgorithm: # 自定义算法名
type: INLINE
props:
algorithm-expression: ds${(long)(Long.parseLong(F_Id)/10) % 2}
myTableAlgorithm: # 自定义算法名
type: INLINE
props:
algorithm-expression: ext_bigdata_${(long)(Long.parseLong(F_Id)/10 / 2) % 2}
# keyGenerators:
# dsKey: # 自定义主键策略名
# type: SNOWFLAKE
props:
sql-show: true