mirror of https://github.com/jeecgboot/jeecg-boot
Merge branch 'master' into master
commit
e38e395436
|
@ -12,3 +12,4 @@ rebel.xml
|
|||
os_del.cmd
|
||||
os_del_doc.cmd
|
||||
.svn
|
||||
derby.log
|
||||
|
|
10
README-EN.md
10
README-EN.md
|
@ -7,13 +7,13 @@
|
|||
JEECG BOOT Low Code Development Platform
|
||||
===============
|
||||
|
||||
当前最新版本: 3.6.2(发布日期:2024-01-08)
|
||||
当前最新版本: 3.6.3(发布日期:2024-03-11)
|
||||
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://www.jeecg.com)
|
||||
[](https://jeecg.blog.csdn.net)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
|
||||
|
@ -76,7 +76,7 @@ Docker starts the project
|
|||
- [Docker starts the monomer background](https://help.jeecg.com/java/setup/docker/up.html)
|
||||
- [Docker starts the Vue3 front-end](http://help.jeecg.com/publish/docker.html)
|
||||
- [Docker starts the micro-service background](https://help.jeecg.com/java/springcloud/docker.html)
|
||||
|
||||
- [ChatGPT AI Config](https://help.jeecg.com/java/chatgpt.html)
|
||||
|
||||
|
||||
|
||||
|
@ -441,6 +441,10 @@ Technical Architecture:
|
|||
|
||||
### Effect of system
|
||||
|
||||
##### ChatGPT AI Dialog
|
||||
> Go to the JeecgBoot background home page and click "AI Assistant" in the middle of the right side of the home page. The AI Assistant dialog screen is displayed.
|
||||

|
||||
|
||||
|
||||
##### PC
|
||||

|
||||
|
|
10
README.md
10
README.md
|
@ -7,13 +7,13 @@
|
|||
JEECG BOOT 低代码开发平台
|
||||
===============
|
||||
|
||||
当前最新版本: 3.6.2(发布日期:2024-01-08)
|
||||
当前最新版本: 3.6.3(发布日期:2024-03-11)
|
||||
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://jeecg.com/aboutusIndex)
|
||||
[](https://jeecg.blog.csdn.net)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
|
||||
|
@ -69,7 +69,7 @@ Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,
|
|||
- [通过IDEA启动前后端项目](https://help.jeecg.com/java/setup/idea/startup.html)
|
||||
- [Vue3前端项目快速启动](http://help.jeecg.com/setup/startup.html)
|
||||
- [单体快速切换为微服务版](https://help.jeecg.com/java/springcloud/switchcloud/monomer.html)
|
||||
|
||||
- [ChatGPT AI助手配置文档](https://help.jeecg.com/java/chatgpt.html)
|
||||
|
||||
Docker快速启动项目
|
||||
-----------------------------------
|
||||
|
@ -477,6 +477,10 @@ JeecgBoot企业版本默认集成了activiti和flowable两套方案,大家在
|
|||
### 系统效果
|
||||
|
||||
|
||||
##### ChatGPT AI交互
|
||||
> 进入JeecgBoot后台首页,点击首页右侧中间“AI助手”,弹出AI助手对话界面。
|
||||

|
||||
|
||||
|
||||
##### PC端
|
||||

|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-parent</artifactId>
|
||||
<version>3.6.2</version>
|
||||
<version>3.6.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jeecg-boot-base-core</artifactId>
|
||||
|
|
|
@ -22,10 +22,10 @@ public interface CommonAPI {
|
|||
|
||||
/**
|
||||
* 2查询用户权限信息
|
||||
* @param username
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
Set<String> queryUserAuths(String username);
|
||||
Set<String> queryUserAuths(String userId);
|
||||
|
||||
/**
|
||||
* 3根据 id 查询数据库中存储的 DynamicDataSourceModel
|
||||
|
|
|
@ -17,6 +17,8 @@ public class DataLogDTO {
|
|||
|
||||
private String type;
|
||||
|
||||
private String createName;
|
||||
|
||||
public DataLogDTO(){
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,13 @@ public class OnlineAuthDTO implements Serializable {
|
|||
*/
|
||||
private String onlineFormUrl;
|
||||
|
||||
//update-begin---author:chenrui ---date:20240123 for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
|
||||
/**
|
||||
* online工单的地址
|
||||
*/
|
||||
private String onlineWorkOrderUrl;
|
||||
//update-end---author:chenrui ---date:20240123 for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
|
||||
|
||||
public OnlineAuthDTO(){
|
||||
|
||||
}
|
||||
|
|
|
@ -377,6 +377,8 @@ public interface CommonConstant {
|
|||
/**前端vue3版本Header参数名*/
|
||||
String VERSION="X-Version";
|
||||
|
||||
String VERSION_V3 = "v3";
|
||||
|
||||
/**存储在线程变量里的动态表名*/
|
||||
String DYNAMIC_TABLE_NAME="DYNAMIC_TABLE_NAME";
|
||||
/**
|
||||
|
|
|
@ -13,12 +13,16 @@ import java.util.List;
|
|||
public enum RoleIndexConfigEnum {
|
||||
|
||||
/**首页自定义 admin*/
|
||||
ADMIN("admin", "dashboard/Analysis"),
|
||||
// ADMIN("admin", "dashboard/Analysis"),
|
||||
//TEST("test", "dashboard/IndexChart"),
|
||||
/**首页自定义 hr*/
|
||||
HR("hr", "dashboard/IndexBdc");
|
||||
// HR("hr", "dashboard/IndexBdc");
|
||||
|
||||
//DM("dm", "dashboard/IndexTask"),
|
||||
|
||||
// 注:此值仅为防止报错,无任何实际意义
|
||||
ROLE_INDEX_CONFIG_ENUM("RoleIndexConfigEnumDefault", "dashboard/Analysis");
|
||||
|
||||
/**
|
||||
* 角色编码
|
||||
*/
|
||||
|
|
|
@ -28,7 +28,9 @@ import java.io.InputStream;
|
|||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -467,4 +469,19 @@ public class CommonUtils {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出info日志,会捕获异常,防止因为日志问题导致程序异常
|
||||
*
|
||||
* @param msg
|
||||
* @param objects
|
||||
*/
|
||||
public static void logInfo(String msg, Object... objects) {
|
||||
try {
|
||||
log.info(msg, objects);
|
||||
} catch (Exception e) {
|
||||
log.warn("{} —— {}", msg, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -62,8 +62,8 @@ public class DySmsHelper {
|
|||
|
||||
//update-begin-author:taoyan date:20200811 for:配置类数据获取
|
||||
StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class);
|
||||
logger.info("阿里大鱼短信秘钥 accessKeyId:" + staticConfig.getAccessKeyId());
|
||||
logger.info("阿里大鱼短信秘钥 accessKeySecret:"+ staticConfig.getAccessKeySecret());
|
||||
//logger.info("阿里大鱼短信秘钥 accessKeyId:" + staticConfig.getAccessKeyId());
|
||||
//logger.info("阿里大鱼短信秘钥 accessKeySecret:"+ staticConfig.getAccessKeySecret());
|
||||
setAccessKeyId(staticConfig.getAccessKeyId());
|
||||
setAccessKeySecret(staticConfig.getAccessKeySecret());
|
||||
//update-end-author:taoyan date:20200811 for:配置类数据获取
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreato
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
|
@ -30,10 +31,12 @@ import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
|
|||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.filter.DelegatingFilterProxy;
|
||||
import redis.clients.jedis.HostAndPort;
|
||||
import redis.clients.jedis.JedisCluster;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.Duration;
|
||||
|
@ -60,7 +63,6 @@ public class ShiroConfig {
|
|||
|
||||
@Autowired
|
||||
private ApplicationContext ctx;
|
||||
|
||||
/**
|
||||
* Filter Chain定义说明
|
||||
*
|
||||
|
@ -199,6 +201,20 @@ public class ShiroConfig {
|
|||
return shiroFilterFactoryBean;
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20240126 for:【QQYUN-7932】AI助手------------
|
||||
@Bean
|
||||
public FilterRegistrationBean shiroFilterRegistration() {
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
registration.setFilter(new DelegatingFilterProxy("shiroFilterFactoryBean"));
|
||||
registration.setEnabled(true);
|
||||
registration.addUrlPatterns("/*");
|
||||
//支持异步
|
||||
registration.setAsyncSupported(true);
|
||||
registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC);
|
||||
return registration;
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240126 for:【QQYUN-7932】AI助手------------
|
||||
|
||||
@Bean("securityManager")
|
||||
public DefaultWebSecurityManager securityManager(ShiroRealm myRealm) {
|
||||
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
|
||||
|
|
|
@ -62,9 +62,11 @@ public class ShiroRealm extends AuthorizingRealm {
|
|||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
||||
log.debug("===============Shiro权限认证开始============ [ roles、permissions]==========");
|
||||
String username = null;
|
||||
String userId = null;
|
||||
if (principals != null) {
|
||||
LoginUser sysUser = (LoginUser) principals.getPrimaryPrincipal();
|
||||
username = sysUser.getUsername();
|
||||
userId = sysUser.getId();
|
||||
}
|
||||
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
|
||||
|
||||
|
@ -74,7 +76,7 @@ public class ShiroRealm extends AuthorizingRealm {
|
|||
info.setRoles(roleSet);
|
||||
|
||||
// 设置用户拥有的权限集合,比如“sys:role:add,sys:user:add”
|
||||
Set<String> permissionSet = commonApi.queryUserAuths(username);
|
||||
Set<String> permissionSet = commonApi.queryUserAuths(userId);
|
||||
info.addStringPermissions(permissionSet);
|
||||
//System.out.println(permissionSet);
|
||||
log.info("===============Shiro权限认证成功==============");
|
||||
|
|
|
@ -172,7 +172,11 @@ public class HttpUtils {
|
|||
String[] params = param.split("&");
|
||||
for (String s : params) {
|
||||
int index = s.indexOf("=");
|
||||
result.put(s.substring(0, index), s.substring(index + 1));
|
||||
//update-begin---author:chenrui ---date:20240222 for:[issues/5879]数据查询传ds=“”造成的异常------------
|
||||
if (index != -1) {
|
||||
result.put(s.substring(0, index), s.substring(index + 1));
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240222 for:[issues/5879]数据查询传ds=“”造成的异常------------
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -196,7 +200,11 @@ public class HttpUtils {
|
|||
String[] params = param.split("&");
|
||||
for (String s : params) {
|
||||
int index = s.indexOf("=");
|
||||
result.put(s.substring(0, index), s.substring(index + 1));
|
||||
//update-begin---author:chenrui ---date:20240222 for:[issues/5879]数据查询传ds=“”造成的异常------------
|
||||
if (index != -1) {
|
||||
result.put(s.substring(0, index), s.substring(index + 1));
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240222 for:[issues/5879]数据查询传ds=“”造成的异常------------
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jeecg-boot-parent</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.6.2</version>
|
||||
<version>3.6.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -16,6 +16,12 @@
|
|||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-base-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- chatgpt -->
|
||||
<dependency>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-boot-starter-chatgpt</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
34
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/cache/LocalCache.java
vendored
Normal file
34
jeecg-module-demo/src/main/java/org/jeecg/modules/demo/gpt/cache/LocalCache.java
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
package org.jeecg.modules.demo.gpt.cache;
|
||||
|
||||
import cn.hutool.cache.CacheUtil;
|
||||
import cn.hutool.cache.impl.TimedCache;
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
|
||||
//update-begin---author:chenrui ---date:20240126 for:【QQYUN-7932】AI助手------------
|
||||
|
||||
/**
|
||||
* 聊天记录本地缓存
|
||||
* @author chenrui
|
||||
* @date 2024/1/26 20:06
|
||||
*/
|
||||
public class LocalCache {
|
||||
/**
|
||||
* 缓存时长
|
||||
*/
|
||||
public static final long TIMEOUT = 5 * DateUnit.MINUTE.getMillis();
|
||||
/**
|
||||
* 清理间隔
|
||||
*/
|
||||
private static final long CLEAN_TIMEOUT = 5 * DateUnit.MINUTE.getMillis();
|
||||
/**
|
||||
* 缓存对象
|
||||
*/
|
||||
public static final TimedCache<String, Object> CACHE = CacheUtil.newTimedCache(TIMEOUT);
|
||||
|
||||
static {
|
||||
//启动定时任务
|
||||
CACHE.schedulePrune(CLEAN_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
//update-end---author:chenrui ---date:20240126 for:【QQYUN-7932】AI助手------------
|
|
@ -0,0 +1,74 @@
|
|||
package org.jeecg.modules.demo.gpt.controller;
|
||||
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.modules.demo.gpt.service.ChatService;
|
||||
import org.jeecg.modules.demo.gpt.vo.ChatHistoryVO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
//update-begin---author:chenrui ---date:20240126 for:【QQYUN-7932】AI助手------------
|
||||
|
||||
/**
|
||||
* @Description: chatGpt-聊天接口
|
||||
* @Author: chenrui
|
||||
* @Date: 2024/1/9 16:30
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/ai/chat")
|
||||
public class ChatController {
|
||||
|
||||
@Autowired
|
||||
ChatService chatService;
|
||||
|
||||
/**
|
||||
* 创建sse连接
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping(value = "/send")
|
||||
public SseEmitter createConnect(@RequestParam(name = "topicId", required = false) String topicId, @RequestParam(name = "message", required = true) String message) {
|
||||
SseEmitter sse = chatService.createChat();
|
||||
chatService.sendMessage(topicId, message);
|
||||
return sse;
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20240223 for:[QQYUN-8225]聊天记录保存------------
|
||||
/**
|
||||
* 保存聊天记录
|
||||
* @param chatHistoryVO
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2024/2/22 13:54
|
||||
*/
|
||||
@PostMapping(value = "/history/save")
|
||||
@ResponseBody
|
||||
public Result<?> saveHistory(@RequestBody ChatHistoryVO chatHistoryVO) {
|
||||
return chatService.saveHistory(chatHistoryVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询聊天记录
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2024/2/22 14:03
|
||||
*/
|
||||
@GetMapping(value = "/history/get")
|
||||
@ResponseBody
|
||||
public Result<ChatHistoryVO> getHistoryByTopic() {
|
||||
return chatService.getHistoryByTopic();
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240223 for:[QQYUN-8225]聊天记录保存------------
|
||||
|
||||
/**
|
||||
* 关闭连接
|
||||
*/
|
||||
@GetMapping(value = "/close")
|
||||
public void closeConnect() {
|
||||
chatService.closeChat();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240126 for:【QQYUN-7932】AI助手------------
|
|
@ -0,0 +1,136 @@
|
|||
package org.jeecg.modules.demo.gpt.listeners;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse;
|
||||
import com.unfbx.chatgpt.entity.chat.Message;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.sse.EventSource;
|
||||
import okhttp3.sse.EventSourceListener;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
//update-begin---author:chenrui ---date:20240126 for:【QQYUN-7932】AI助手------------
|
||||
/**
|
||||
* OpenAI的SSE监听
|
||||
* @author chenrui
|
||||
* @date 2024/1/26 20:06
|
||||
*/
|
||||
@Slf4j
|
||||
public class OpenAISSEEventSourceListener extends EventSourceListener {
|
||||
|
||||
private long tokens;
|
||||
|
||||
private SseEmitter sseEmitter;
|
||||
|
||||
private String topicId;
|
||||
|
||||
public OpenAISSEEventSourceListener(SseEmitter sseEmitter) {
|
||||
this.sseEmitter = sseEmitter;
|
||||
}
|
||||
|
||||
public OpenAISSEEventSourceListener(String topicId,SseEmitter sseEmitter){
|
||||
this.topicId = topicId;
|
||||
this.sseEmitter = sseEmitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void onOpen(@NotNull EventSource eventSource, @NotNull Response response) {
|
||||
log.info("OpenAI建立sse连接...");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void onEvent(@NotNull EventSource eventSource, String id, String type, @NotNull String data) {
|
||||
log.debug("OpenAI返回数据:{}", data);
|
||||
tokens += 1;
|
||||
if (data.equals("[DONE]")) {
|
||||
log.info("OpenAI返回数据结束了");
|
||||
sseEmitter.send(SseEmitter.event()
|
||||
.id("[TOKENS]")
|
||||
.data("<br/><br/>tokens:" + tokens())
|
||||
.reconnectTime(3000));
|
||||
sseEmitter.send(SseEmitter.event()
|
||||
.id("[DONE]")
|
||||
.data("[DONE]")
|
||||
.reconnectTime(3000));
|
||||
// 传输完成后自动关闭sse
|
||||
sseEmitter.complete();
|
||||
return;
|
||||
}
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
ChatCompletionResponse completionResponse = mapper.readValue(data, ChatCompletionResponse.class); // 读取Json
|
||||
try {
|
||||
sseEmitter.send(SseEmitter.event()
|
||||
.id(this.topicId)
|
||||
.data(completionResponse.getChoices().get(0).getDelta())
|
||||
.reconnectTime(3000));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
eventSource.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClosed(@NotNull EventSource eventSource) {
|
||||
log.info("流式输出返回值总共{}tokens", tokens() - 2);
|
||||
log.info("OpenAI关闭sse连接...");
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void onFailure(@NotNull EventSource eventSource, Throwable t, Response response) {
|
||||
String errMsg = "";
|
||||
ResponseBody body = null == response ? null:response.body();
|
||||
if (Objects.nonNull(body)) {
|
||||
log.error("OpenAI sse连接异常data:{},异常:{}", body.string(), t.getMessage());
|
||||
errMsg = body.string();
|
||||
} else {
|
||||
log.error("OpenAI sse连接异常data:{},异常:{}", response, t.getMessage());
|
||||
errMsg = t.getMessage();
|
||||
}
|
||||
eventSource.cancel();
|
||||
sseEmitter.send(SseEmitter.event()
|
||||
.id("[ERR]")
|
||||
.data(Message.builder().content(explainErr(errMsg)).build())
|
||||
.reconnectTime(3000));
|
||||
sseEmitter.send(SseEmitter.event()
|
||||
.id("[DONE]")
|
||||
.data("[DONE]")
|
||||
.reconnectTime(3000));
|
||||
sseEmitter.complete();
|
||||
}
|
||||
|
||||
private String explainErr(String errMsg){
|
||||
if(StringUtils.isEmpty(errMsg)){
|
||||
return "";
|
||||
}
|
||||
if(errMsg.contains("Rate limit")){
|
||||
return "请求频率太快了,请等待20秒再试.";
|
||||
}
|
||||
return errMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* tokens
|
||||
* @return
|
||||
*/
|
||||
public long tokens() {
|
||||
return tokens;
|
||||
}
|
||||
}
|
||||
|
||||
//update-end---author:chenrui ---date:20240126 for:【QQYUN-7932】AI助手------------
|
|
@ -0,0 +1,56 @@
|
|||
package org.jeecg.modules.demo.gpt.service;
|
||||
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.modules.demo.gpt.vo.ChatHistoryVO;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
//update-begin---author:chenrui ---date:20240126 for:【QQYUN-7932】AI助手------------
|
||||
|
||||
/**
|
||||
* AI助手聊天Service
|
||||
* @author chenrui
|
||||
* @date 2024/1/26 20:08
|
||||
*/
|
||||
public interface ChatService {
|
||||
/**
|
||||
* 创建SSE
|
||||
* @return
|
||||
*/
|
||||
SseEmitter createChat();
|
||||
|
||||
/**
|
||||
* 关闭SSE
|
||||
*/
|
||||
void closeChat();
|
||||
|
||||
/**
|
||||
* 客户端发送消息到服务端
|
||||
*
|
||||
* @param topicId
|
||||
* @param message
|
||||
* @author chenrui
|
||||
* @date 2024/1/26 20:01
|
||||
*/
|
||||
void sendMessage(String topicId, String message);
|
||||
|
||||
//update-begin---author:chenrui ---date:20240223 for:[QQYUN-8225]聊天记录保存------------
|
||||
/**
|
||||
* 保存聊天记录
|
||||
* @param chatHistoryVO
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2024/2/22 13:37
|
||||
*/
|
||||
Result<?> saveHistory(ChatHistoryVO chatHistoryVO);
|
||||
|
||||
/**
|
||||
* 查询聊天记录
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2024/2/22 13:59
|
||||
*/
|
||||
Result<ChatHistoryVO> getHistoryByTopic();
|
||||
//update-end---author:chenrui ---date:20240223 for:[QQYUN-8225]聊天记录保存------------
|
||||
}
|
||||
|
||||
//update-end---author:chenrui ---date:20240126 for:【QQYUN-7932】AI助手------------
|
|
@ -0,0 +1,199 @@
|
|||
package org.jeecg.modules.demo.gpt.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.unfbx.chatgpt.OpenAiStreamClient;
|
||||
import com.unfbx.chatgpt.entity.chat.ChatCompletion;
|
||||
import com.unfbx.chatgpt.entity.chat.Message;
|
||||
import com.unfbx.chatgpt.exception.BaseException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.UUIDGenerator;
|
||||
import org.jeecg.modules.demo.gpt.cache.LocalCache;
|
||||
import org.jeecg.modules.demo.gpt.listeners.OpenAISSEEventSourceListener;
|
||||
import org.jeecg.modules.demo.gpt.service.ChatService;
|
||||
import org.jeecg.modules.demo.gpt.vo.ChatHistoryVO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
//update-begin---author:chenrui ---date:20240126 for:【QQYUN-7932】AI助手------------
|
||||
|
||||
/**
|
||||
* AI助手聊天Service
|
||||
* @author chenrui
|
||||
* @date 2024/1/26 20:07
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ChatServiceImpl implements ChatService {
|
||||
|
||||
//update-begin---author:chenrui ---date:20240223 for:[QQYUN-8225]聊天记录保存------------
|
||||
private static final String CACHE_KEY_PREFIX = "ai:chart:";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final String CACHE_KEY_MSG_CONTEXT = "msg_content";
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final String CACHE_KEY_MSG_HISTORY = "msg_history";
|
||||
|
||||
@Autowired
|
||||
RedisTemplate redisTemplate;
|
||||
//update-end---author:chenrui ---date:20240223 for:[QQYUN-8225]聊天记录保存------------
|
||||
|
||||
private OpenAiStreamClient openAiStreamClient = null;
|
||||
|
||||
//update-begin---author:chenrui ---date:20240131 for:[QQYUN-8212]fix 没有配置启动报错------------
|
||||
public ChatServiceImpl() {
|
||||
try {
|
||||
this.openAiStreamClient = SpringContextUtils.getBean(OpenAiStreamClient.class);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 防止client不能成功注入
|
||||
* @return
|
||||
* @author chenrui
|
||||
* @date 2024/2/3 23:08
|
||||
*/
|
||||
private OpenAiStreamClient ensureClient(){
|
||||
if(null == this.openAiStreamClient){
|
||||
this.openAiStreamClient = SpringContextUtils.getBean(OpenAiStreamClient.class);
|
||||
}
|
||||
return this.openAiStreamClient;
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240131 for:[QQYUN-8212]fix 没有配置启动报错------------
|
||||
|
||||
private String getUserId() {
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
return sysUser.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SseEmitter createChat() {
|
||||
String uid = getUserId();
|
||||
//默认30秒超时,设置为0L则永不超时
|
||||
SseEmitter sseEmitter = new SseEmitter(-0L);
|
||||
//完成后回调
|
||||
sseEmitter.onCompletion(() -> {
|
||||
log.info("[{}]结束连接...................",uid);
|
||||
LocalCache.CACHE.remove(uid);
|
||||
});
|
||||
//超时回调
|
||||
sseEmitter.onTimeout(() -> {
|
||||
log.info("[{}]连接超时...................", uid);
|
||||
});
|
||||
//异常回调
|
||||
sseEmitter.onError(
|
||||
throwable -> {
|
||||
try {
|
||||
log.info("[{}]连接异常,{}", uid, throwable.toString());
|
||||
sseEmitter.send(SseEmitter.event()
|
||||
.id(uid)
|
||||
.name("发生异常!")
|
||||
.data(Message.builder().content("发生异常请重试!").build())
|
||||
.reconnectTime(3000));
|
||||
LocalCache.CACHE.put(uid, sseEmitter);
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
}
|
||||
);
|
||||
try {
|
||||
sseEmitter.send(SseEmitter.event().reconnectTime(5000));
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(),e);
|
||||
}
|
||||
LocalCache.CACHE.put(uid, sseEmitter);
|
||||
log.info("[{}]创建sse连接成功!", uid);
|
||||
return sseEmitter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeChat() {
|
||||
String uid = getUserId();
|
||||
SseEmitter sse = (SseEmitter) LocalCache.CACHE.get(uid);
|
||||
if (sse != null) {
|
||||
sse.complete();
|
||||
//移除
|
||||
LocalCache.CACHE.remove(uid);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String topicId, String message) {
|
||||
String uid = getUserId();
|
||||
if (StrUtil.isBlank(message)) {
|
||||
log.info("参数异常,message为null");
|
||||
throw new BaseException("参数异常,message不能为空~");
|
||||
}
|
||||
if (StrUtil.isBlank(topicId)) {
|
||||
topicId = UUIDGenerator.generate();
|
||||
}
|
||||
//update-begin---author:chenrui ---date:20240223 for:[QQYUN-8225]聊天记录保存------------
|
||||
log.info("话题id:{}", topicId);
|
||||
String cacheKey = CACHE_KEY_PREFIX + uid + "_" + topicId;
|
||||
String messageContext = (String) redisTemplate.opsForHash().get(cacheKey, CACHE_KEY_MSG_CONTEXT);
|
||||
List<Message> msgHistory = new ArrayList<>();
|
||||
if (StrUtil.isNotBlank(messageContext)) {
|
||||
List<Message> messages = JSONArray.parseArray(messageContext, Message.class);
|
||||
msgHistory = messages == null ? new ArrayList<>() : messages;
|
||||
}
|
||||
Message currentMessage = Message.builder().content(message).role(Message.Role.USER).build();
|
||||
msgHistory.add(currentMessage);
|
||||
|
||||
SseEmitter sseEmitter = (SseEmitter) LocalCache.CACHE.get(uid);
|
||||
if (sseEmitter == null) {
|
||||
log.info("聊天消息推送失败uid:[{}],没有创建连接,请重试。", uid);
|
||||
throw new JeecgBootException("聊天消息推送失败uid:[{}],没有创建连接,请重试。~");
|
||||
}
|
||||
OpenAISSEEventSourceListener openAIEventSourceListener = new OpenAISSEEventSourceListener(topicId, sseEmitter);
|
||||
ChatCompletion completion = ChatCompletion
|
||||
.builder()
|
||||
.messages(msgHistory)
|
||||
.model(ChatCompletion.Model.GPT_3_5_TURBO.getName())
|
||||
.build();
|
||||
ensureClient().streamChatCompletion(completion, openAIEventSourceListener);
|
||||
redisTemplate.opsForHash().put(cacheKey, CACHE_KEY_MSG_CONTEXT, JSONUtil.toJsonStr(msgHistory));
|
||||
//update-end---author:chenrui ---date:20240223 for:[QQYUN-8225]聊天记录保存------------
|
||||
Result.ok(completion.tokens());
|
||||
}
|
||||
|
||||
//update-begin---author:chenrui ---date:20240223 for:[QQYUN-8225]聊天记录保存------------
|
||||
@Override
|
||||
public Result<?> saveHistory(ChatHistoryVO chatHistoryVO) {
|
||||
String uid = getUserId();
|
||||
String cacheKey = CACHE_KEY_PREFIX + CACHE_KEY_MSG_HISTORY + ":" + uid;
|
||||
redisTemplate.opsForValue().set(cacheKey, chatHistoryVO.getContent());
|
||||
return Result.OK("保存成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<ChatHistoryVO> getHistoryByTopic() {
|
||||
String uid = getUserId();
|
||||
String cacheKey = CACHE_KEY_PREFIX + CACHE_KEY_MSG_HISTORY + ":" + uid;
|
||||
String historyContent = (String) redisTemplate.opsForValue().get(cacheKey);
|
||||
ChatHistoryVO chatHistoryVO = new ChatHistoryVO();
|
||||
chatHistoryVO.setContent(historyContent);
|
||||
return Result.OK(chatHistoryVO);
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240223 for:[QQYUN-8225]聊天记录保存------------
|
||||
}
|
||||
|
||||
//update-end---author:chenrui ---date:20240126 for:【QQYUN-7932】AI助手------------
|
|
@ -0,0 +1,25 @@
|
|||
package org.jeecg.modules.demo.gpt.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @Description: 聊天记录
|
||||
* @Author: chenrui
|
||||
* @Date: 2024/2/22 13:36
|
||||
*/
|
||||
@Data
|
||||
public class ChatHistoryVO implements Serializable {
|
||||
private static final long serialVersionUID = 3238429500037511283L;
|
||||
|
||||
/**
|
||||
* 话题id
|
||||
*/
|
||||
String topicId;
|
||||
|
||||
/**
|
||||
* 聊天记录内容
|
||||
*/
|
||||
String content;
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jeecg-system-api</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.6.2</version>
|
||||
<version>3.6.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -307,11 +307,11 @@ public interface ISysBaseAPI extends CommonAPI {
|
|||
|
||||
/**
|
||||
* 31获取用户的权限集合
|
||||
* @param username
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/sys/api/getUserPermissionSet")
|
||||
Set<String> getUserPermissionSet(@RequestParam("username") String username);
|
||||
Set<String> getUserPermissionSet(@RequestParam("userId") String userId);
|
||||
|
||||
/**
|
||||
* 32判断是否有online访问的权限
|
||||
|
@ -351,12 +351,12 @@ public interface ISysBaseAPI extends CommonAPI {
|
|||
|
||||
/**
|
||||
* 36查询用户权限信息
|
||||
* @param username
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@GetMapping("/sys/api/queryUserAuths")
|
||||
Set<String> queryUserAuths(@RequestParam("username")String username);
|
||||
Set<String> queryUserAuths(@RequestParam("userId")String userId);
|
||||
|
||||
/**
|
||||
* 37根据 id 查询数据库中存储的 DynamicDataSourceModel
|
||||
|
@ -611,20 +611,6 @@ public interface ISysBaseAPI extends CommonAPI {
|
|||
@PostMapping("/sys/api/saveDataLog")
|
||||
void saveDataLog(DataLogDTO dataLogDto);
|
||||
|
||||
/**
|
||||
* 添加文件到知识库
|
||||
* @param sysFilesModel
|
||||
*/
|
||||
@PostMapping("/sys/api/addSysFiles")
|
||||
void addSysFiles(SysFilesModel sysFilesModel);
|
||||
|
||||
/**
|
||||
* 通过文件路径获取文件id
|
||||
* @param fileId
|
||||
*/
|
||||
@GetMapping("/sys/api/getFileUrl")
|
||||
String getFileUrl(@RequestParam(name="fileId") String fileId);
|
||||
|
||||
/**
|
||||
* 更新头像
|
||||
* @param loginUser
|
||||
|
|
|
@ -71,7 +71,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDepartParentIdsByDepIds(Set depIds) {
|
||||
public Set<String> getDepartParentIdsByDepIds(Set<String> depIds) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getUserPermissionSet(String username) {
|
||||
public Set<String> getUserPermissionSet(String userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -219,7 +219,7 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<String> queryUserAuths(String username) {
|
||||
public Set<String> queryUserAuths(String userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -361,17 +361,6 @@ public class SysBaseAPIFallback implements ISysBaseAPI {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addSysFiles(SysFilesModel sysFilesModel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileUrl(String fileId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAvatar(LoginUser loginUser) { }
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jeecg-system-api</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.6.2</version>
|
||||
<version>3.6.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ public interface ISysBaseAPI extends CommonAPI {
|
|||
* @param depIds
|
||||
* @return 部门 parentIds
|
||||
*/
|
||||
Set<String> getDepartParentIdsByDepIds(Set depIds);
|
||||
Set<String> getDepartParentIdsByDepIds(Set<String> depIds);
|
||||
|
||||
/**
|
||||
* 9通过用户账号查询部门 name
|
||||
|
@ -302,10 +302,10 @@ public interface ISysBaseAPI extends CommonAPI {
|
|||
|
||||
/**
|
||||
* 32获取用户的权限集合
|
||||
* @param username
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
Set<String> getUserPermissionSet(String username);
|
||||
Set<String> getUserPermissionSet(String userId);
|
||||
|
||||
/**
|
||||
* 33判断是否有online访问的权限
|
||||
|
@ -445,19 +445,6 @@ public interface ISysBaseAPI extends CommonAPI {
|
|||
* @param dataLogDto
|
||||
*/
|
||||
void saveDataLog(DataLogDTO dataLogDto);
|
||||
|
||||
/**
|
||||
* 添加文件到知识库
|
||||
* @param sysFilesModel
|
||||
*/
|
||||
void addSysFiles(SysFilesModel sysFilesModel);
|
||||
|
||||
/**
|
||||
* 通过文件路径获取文件id
|
||||
* @param fileId
|
||||
*/
|
||||
String getFileUrl(String fileId);
|
||||
|
||||
/**
|
||||
* 更新头像
|
||||
* @param loginUser
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>jeecg-module-system</artifactId>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<version>3.6.2</version>
|
||||
<version>3.6.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>org.jeecgframework.boot</groupId>
|
||||
<artifactId>jeecg-module-system</artifactId>
|
||||
<version>3.6.2</version>
|
||||
<version>3.6.3</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ public class SystemApiController {
|
|||
* @return 部门 id
|
||||
*/
|
||||
@GetMapping("/getDepartParentIdsByDepIds")
|
||||
Set<String> getDepartParentIdsByDepIds(@RequestParam("depIds") Set depIds){
|
||||
Set<String> getDepartParentIdsByDepIds(@RequestParam("depIds") Set<String> depIds){
|
||||
return sysBaseApi.getDepartParentIdsByDepIds(depIds);
|
||||
}
|
||||
|
||||
|
@ -386,12 +386,12 @@ public class SystemApiController {
|
|||
|
||||
/**
|
||||
* 获取用户的权限集合
|
||||
* @param username
|
||||
* @param userId 用户表ID
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getUserPermissionSet")
|
||||
public Set<String> getUserPermissionSet(@RequestParam("username") String username){
|
||||
return sysBaseApi.getUserPermissionSet(username);
|
||||
public Set<String> getUserPermissionSet(@RequestParam("userId") String userId){
|
||||
return sysBaseApi.getUserPermissionSet(userId);
|
||||
}
|
||||
|
||||
//-----
|
||||
|
@ -419,12 +419,12 @@ public class SystemApiController {
|
|||
|
||||
/**
|
||||
* 查询用户权限信息
|
||||
* @param username
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/queryUserAuths")
|
||||
public Set<String> queryUserAuths(@RequestParam("username") String username){
|
||||
return sysUserService.getUserPermissionsSet(username);
|
||||
public Set<String> queryUserAuths(@RequestParam("userId") String userId){
|
||||
return sysUserService.getUserPermissionsSet(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package org.jeecg.modules.system.constant;
|
||||
|
||||
/**
|
||||
* 默认首页常量
|
||||
*/
|
||||
public interface DefIndexConst {
|
||||
|
||||
/**
|
||||
* 默认首页的roleCode
|
||||
*/
|
||||
String DEF_INDEX_ALL = "DEF_INDEX_ALL";
|
||||
|
||||
/**
|
||||
* 默认首页的缓存key
|
||||
*/
|
||||
String CACHE_KEY = "sys:cache:def_index";
|
||||
|
||||
/**
|
||||
* 默认首页的初始值
|
||||
*/
|
||||
String DEF_INDEX_NAME = "首页";
|
||||
String DEF_INDEX_URL = "/dashboard/analysis";
|
||||
String DEF_INDEX_COMPONENT = "dashboard/Analysis";
|
||||
|
||||
}
|
|
@ -9,8 +9,6 @@ import org.jeecg.common.exception.JeecgBootException;
|
|||
import org.jeecg.common.util.CommonUtils;
|
||||
import org.jeecg.common.util.filter.SsrfFileTypeFilter;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.service.ISysFilesService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
|
|
@ -76,28 +76,20 @@ public class LoginController {
|
|||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
String username = sysLoginModel.getUsername();
|
||||
String password = sysLoginModel.getPassword();
|
||||
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
if(isLoginFailOvertimes(username)){
|
||||
return result.error500("该用户登录失败次数过多,请于10分钟后再次登录!");
|
||||
}
|
||||
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
//update-begin--Author:scott Date:20190805 for:暂时注释掉密码加密逻辑,有点问题
|
||||
//前端密码加密,后端进行密码解密
|
||||
//password = AesEncryptUtil.desEncrypt(sysLoginModel.getPassword().replaceAll("%2B", "\\+")).trim();//密码解密
|
||||
//update-begin--Author:scott Date:20190805 for:暂时注释掉密码加密逻辑,有点问题
|
||||
|
||||
//update-begin-author:taoyan date:20190828 for:校验验证码
|
||||
// step.1 验证码check
|
||||
String captcha = sysLoginModel.getCaptcha();
|
||||
if(captcha==null){
|
||||
result.error500("验证码无效");
|
||||
return result;
|
||||
}
|
||||
String lowerCaseCaptcha = captcha.toLowerCase();
|
||||
//update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
// 加入密钥作为混淆,避免简单的拼接,被外部利用,用户自定义该密钥即可
|
||||
String origin = lowerCaseCaptcha+sysLoginModel.getCheckKey()+jeecgBaseConfig.getSignatureSecret();
|
||||
String realKey = Md5Util.md5Encode(origin, "utf-8");
|
||||
//update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906
|
||||
Object checkCode = redisUtil.get(realKey);
|
||||
//当进入登录页时,有一定几率出现验证码错误 #1714
|
||||
if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) {
|
||||
|
@ -107,40 +99,36 @@ public class LoginController {
|
|||
result.setCode(HttpStatus.PRECONDITION_FAILED.value());
|
||||
return result;
|
||||
}
|
||||
//update-end-author:taoyan date:20190828 for:校验验证码
|
||||
|
||||
//1. 校验用户是否有效
|
||||
//update-begin-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug,if条件永远为false
|
||||
// step.2 校验用户是否存在且有效
|
||||
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysUser::getUsername,username);
|
||||
SysUser sysUser = sysUserService.getOne(queryWrapper);
|
||||
//update-end-author:wangshuai date:20200601 for: 登录代码验证用户是否注销bug,if条件永远为false
|
||||
result = sysUserService.checkUserIsEffective(sysUser);
|
||||
if(!result.isSuccess()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//2. 校验用户名或密码是否正确
|
||||
// step.3 校验用户名或密码是否正确
|
||||
String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt());
|
||||
String syspassword = sysUser.getPassword();
|
||||
if (!syspassword.equals(userpassword)) {
|
||||
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
addLoginFailOvertimes(username);
|
||||
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
result.error500("用户名或密码错误");
|
||||
return result;
|
||||
}
|
||||
|
||||
//用户登录信息
|
||||
|
||||
// step.4 登录成功获取用户信息
|
||||
userInfo(sysUser, result, request);
|
||||
//update-begin--Author:liusq Date:20210126 for:登录成功,删除redis中的验证码
|
||||
|
||||
// step.5 登录成功删除验证码
|
||||
redisUtil.del(realKey);
|
||||
//update-begin--Author:liusq Date:20210126 for:登录成功,删除redis中的验证码
|
||||
redisUtil.del(CommonConstant.LOGIN_FAIL + username);
|
||||
|
||||
// step.6 记录用户登录日志
|
||||
LoginUser loginUser = new LoginUser();
|
||||
BeanUtils.copyProperties(sysUser, loginUser);
|
||||
baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null,loginUser);
|
||||
//update-end--Author:wangshuai Date:20200714 for:登录日志没有记录人员
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -150,12 +138,14 @@ public class LoginController {
|
|||
*/
|
||||
@GetMapping("/user/getUserInfo")
|
||||
public Result<JSONObject> getUserInfo(HttpServletRequest request){
|
||||
long start = System.currentTimeMillis();
|
||||
Result<JSONObject> result = new Result<JSONObject>();
|
||||
String username = JwtUtil.getUserNameByToken(request);
|
||||
if(oConvertUtils.isNotEmpty(username)) {
|
||||
// 根据用户名查询用户信息
|
||||
SysUser sysUser = sysUserService.getUserByName(username);
|
||||
JSONObject obj=new JSONObject();
|
||||
log.info("1 获取用户信息耗时(用户基础信息)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
//update-begin---author:scott ---date:2022-06-20 for:vue3前端,支持自定义首页-----------
|
||||
String vue3Version = request.getHeader(CommonConstant.VERSION);
|
||||
|
@ -170,13 +160,16 @@ public class LoginController {
|
|||
}
|
||||
//update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
|
||||
//update-end---author:scott ---date::2022-06-20 for:vue3前端,支持自定义首页--------------
|
||||
log.info("2 获取用户信息耗时 (首页面配置)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
obj.put("userInfo",sysUser);
|
||||
obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
|
||||
log.info("3 获取用户信息耗时 (字典数据)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
result.setResult(obj);
|
||||
result.success("");
|
||||
}
|
||||
log.info("end 获取用户信息耗时 " + (System.currentTimeMillis() - start) + "毫秒");
|
||||
return result;
|
||||
|
||||
}
|
||||
|
@ -424,8 +417,7 @@ public class LoginController {
|
|||
//update-begin-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
addLoginFailOvertimes(phone);
|
||||
//update-end-author:taoyan date:2022-11-7 for: issues/4109 平台用户登录失败锁定用户
|
||||
result.setMessage("手机验证码错误");
|
||||
return result;
|
||||
return Result.error("手机验证码错误");
|
||||
}
|
||||
//用户信息
|
||||
userInfo(sysUser, result, request);
|
||||
|
@ -552,7 +544,7 @@ public class LoginController {
|
|||
@RequiresRoles({"admin"})
|
||||
@GetMapping(value = "/switchVue3Menu")
|
||||
public Result<String> switchVue3Menu(HttpServletResponse response) {
|
||||
Result<String> res = new Result<String>();
|
||||
Result<String> res = new Result<String>();
|
||||
sysPermissionService.switchVue3Menu();
|
||||
return res;
|
||||
}
|
||||
|
@ -597,10 +589,12 @@ public class LoginController {
|
|||
String orgCode = sysUser.getOrgCode();
|
||||
if(oConvertUtils.isEmpty(orgCode)) {
|
||||
//如果当前用户无选择部门 查看部门关联信息
|
||||
|
||||
List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
|
||||
//update-begin-author:taoyan date:20220117 for: JTC-1068【app】新建用户,没有设置部门及角色,点击登录提示暂未归属部,一直在登录页面 使用手机号登录 可正常
|
||||
if (departs == null || departs.size() == 0) {
|
||||
/*result.error500("用户暂未归属部门,不可登录!");
|
||||
|
||||
return result;*/
|
||||
}else{
|
||||
orgCode = departs.get(0).getOrgCode();
|
||||
|
@ -736,8 +730,8 @@ public class LoginController {
|
|||
if(failTime!=null){
|
||||
val = Integer.parseInt(failTime.toString());
|
||||
}
|
||||
// 10分钟
|
||||
redisUtil.set(key, ++val, 10);
|
||||
// 10分钟,一分钟为60s
|
||||
redisUtil.set(key, ++val, 600);
|
||||
}
|
||||
|
||||
}
|
|
@ -333,6 +333,7 @@ public class SysAnnouncementController {
|
|||
*/
|
||||
@RequestMapping(value = "/listByUser", method = RequestMethod.GET)
|
||||
public Result<Map<String, Object>> listByUser(@RequestParam(required = false, defaultValue = "5") Integer pageSize) {
|
||||
long start = System.currentTimeMillis();
|
||||
Result<Map<String,Object>> result = new Result<Map<String,Object>>();
|
||||
Map<String,Object> sysMsgMap = new HashMap(5);
|
||||
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
|
||||
|
@ -349,12 +350,16 @@ public class SysAnnouncementController {
|
|||
anntMsgList = sysAnnouncementService.querySysCementPageByUserId(anntMsgList,userId,"1");
|
||||
sysMsgMap.put("anntMsgList", anntMsgList.getRecords());
|
||||
sysMsgMap.put("anntMsgTotal", anntMsgList.getTotal());
|
||||
|
||||
log.info("begin 获取用户系统公告 (通知)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
//系统消息
|
||||
Page<SysAnnouncement> sysMsgList = new Page<SysAnnouncement>(0, pageSize);
|
||||
sysMsgList = sysAnnouncementService.querySysCementPageByUserId(sysMsgList,userId,"2");
|
||||
sysMsgMap.put("sysMsgList", sysMsgList.getRecords());
|
||||
sysMsgMap.put("sysMsgTotal", sysMsgList.getTotal());
|
||||
|
||||
log.info("end 获取用户系统公告 (系统消息)" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
result.setSuccess(true);
|
||||
result.setResult(sysMsgMap);
|
||||
|
|
|
@ -600,9 +600,10 @@ public class SysDictController {
|
|||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/deleteList", method = RequestMethod.GET)
|
||||
public Result<List<SysDict>> deleteList() {
|
||||
public Result<List<SysDict>> deleteList(HttpServletRequest request) {
|
||||
Result<List<SysDict>> result = new Result<List<SysDict>>();
|
||||
List<SysDict> list = this.sysDictService.queryDeleteList();
|
||||
String tenantId = TokenUtils.getTenantIdByRequest(request);
|
||||
List<SysDict> list = this.sysDictService.queryDeleteList(tenantId);
|
||||
result.setSuccess(true);
|
||||
result.setResult(list);
|
||||
return result;
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.modules.system.entity.SysFiles;
|
||||
import org.jeecg.modules.system.service.ISysFilesService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Description: 知识库-文档管理
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2022-07-21
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Api(tags = "知识库-文档管理")
|
||||
@RestController
|
||||
@RequestMapping("/sys/files")
|
||||
public class SysFilesController extends JeecgController<SysFiles, ISysFilesService> {
|
||||
@Autowired
|
||||
private ISysFilesService sysFilesService;
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
* @param sysFiles
|
||||
* @param pageNo
|
||||
* @param pageSize
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "知识库-文档管理-分页列表查询")
|
||||
@ApiOperation(value = "知识库-文档管理-分页列表查询", notes = "知识库-文档管理-分页列表查询")
|
||||
@GetMapping(value = "/list")
|
||||
public Result<?> queryPageList(SysFiles sysFiles,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
QueryWrapper<SysFiles> queryWrapper = QueryGenerator.initQueryWrapper(sysFiles, req.getParameterMap());
|
||||
Page<SysFiles> page = new Page<SysFiles>(pageNo, pageSize);
|
||||
IPage<SysFiles> pageList = sysFilesService.page(page, queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param sysFiles
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "知识库-文档管理-添加")
|
||||
@ApiOperation(value = "知识库-文档管理-添加", notes = "知识库-文档管理-添加")
|
||||
@PostMapping(value = "/add")
|
||||
public Result<?> add(@RequestBody SysFiles sysFiles) {
|
||||
sysFilesService.save(sysFiles);
|
||||
return Result.OK("添加成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param sysFiles
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "知识库-文档管理-编辑")
|
||||
@ApiOperation(value = "知识库-文档管理-编辑", notes = "知识库-文档管理-编辑")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||
public Result<?> edit(@RequestBody SysFiles sysFiles) {
|
||||
sysFilesService.updateById(sysFiles);
|
||||
return Result.OK("编辑成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "知识库-文档管理-通过id删除")
|
||||
@ApiOperation(value = "知识库-文档管理-通过id删除", notes = "知识库-文档管理-通过id删除")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
sysFilesService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "知识库-文档管理-批量删除")
|
||||
@ApiOperation(value = "知识库-文档管理-批量删除", notes = "知识库-文档管理-批量删除")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
this.sysFilesService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@AutoLog(value = "知识库-文档管理-通过id查询")
|
||||
@ApiOperation(value = "知识库-文档管理-通过id查询", notes = "知识库-文档管理-通过id查询")
|
||||
@GetMapping(value = "/queryById")
|
||||
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
|
||||
SysFiles sysFiles = sysFilesService.getById(id);
|
||||
return Result.OK(sysFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出excel
|
||||
*
|
||||
* @param request
|
||||
* @param sysFiles
|
||||
*/
|
||||
@RequestMapping(value = "/exportXls")
|
||||
public ModelAndView exportXls(HttpServletRequest request, SysFiles sysFiles) {
|
||||
return super.exportXls(request, sysFiles, SysFiles.class, "知识库-文档管理");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过excel导入数据
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
||||
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
||||
return super.importExcel(request, response, SysFiles.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +1,12 @@
|
|||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
|
@ -19,6 +16,7 @@ import org.jeecg.common.util.Md5Util;
|
|||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.config.JeecgBaseConfig;
|
||||
import org.jeecg.modules.base.service.BaseCommonService;
|
||||
import org.jeecg.modules.system.constant.DefIndexConst;
|
||||
import org.jeecg.modules.system.entity.*;
|
||||
import org.jeecg.modules.system.model.SysPermissionTree;
|
||||
import org.jeecg.modules.system.model.TreeModel;
|
||||
|
@ -246,38 +244,66 @@ public class SysPermissionController {
|
|||
if (oConvertUtils.isEmpty(loginUser)) {
|
||||
return Result.error("请登录系统!");
|
||||
}
|
||||
List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getUsername());
|
||||
List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getId());
|
||||
//添加首页路由
|
||||
//update-begin-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
|
||||
if(!PermissionDataUtil.hasIndexPage(metaList)){
|
||||
SysPermission indexMenu = sysPermissionService.list(new LambdaQueryWrapper<SysPermission>().eq(SysPermission::getName,"首页")).get(0);
|
||||
metaList.add(0,indexMenu);
|
||||
}
|
||||
//update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
|
||||
|
||||
//update-begin--Author:zyf Date:20220425 for:自定义首页地址 LOWCOD-1578
|
||||
String version = request.getHeader(CommonConstant.VERSION);
|
||||
//update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
|
||||
SysRoleIndex roleIndex= sysUserService.getDynamicIndexByUserRole(loginUser.getUsername(),version);
|
||||
//update-end---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑-----------
|
||||
SysRoleIndex defIndexCfg = sysUserService.getDynamicIndexByUserRole(loginUser.getUsername(), version);
|
||||
if (defIndexCfg == null) {
|
||||
defIndexCfg = sysRoleIndexService.initDefaultIndex();
|
||||
}
|
||||
//update-end--Author:zyf Date:20220425 for:自定义首页地址 LOWCOD-1578
|
||||
|
||||
if(roleIndex!=null){
|
||||
List<SysPermission> menus = metaList.stream().filter(sysPermission -> "首页".equals(sysPermission.getName())).collect(Collectors.toList());
|
||||
//update-begin---author:liusq ---date:2022-06-29 for:设置自定义首页地址和组件----------
|
||||
String component = roleIndex.getComponent();
|
||||
String routeUrl = roleIndex.getUrl();
|
||||
boolean route = roleIndex.isRoute();
|
||||
if(oConvertUtils.isNotEmpty(routeUrl)){
|
||||
// 如果没有授权角色首页,则自动添加首页路由
|
||||
if (!PermissionDataUtil.hasIndexPage(metaList, defIndexCfg)) {
|
||||
LambdaQueryWrapper<SysPermission> indexQueryWrapper = new LambdaQueryWrapper<>();
|
||||
indexQueryWrapper.eq(SysPermission::getUrl, defIndexCfg.getUrl());
|
||||
SysPermission indexMenu = sysPermissionService.getOne(indexQueryWrapper);
|
||||
if (indexMenu == null) {
|
||||
indexMenu = new SysPermission();
|
||||
indexMenu.setUrl(defIndexCfg.getUrl());
|
||||
indexMenu.setComponent(defIndexCfg.getComponent());
|
||||
indexMenu.setRoute(defIndexCfg.isRoute());
|
||||
indexMenu.setName(DefIndexConst.DEF_INDEX_NAME);
|
||||
indexMenu.setMenuType(0);
|
||||
}
|
||||
// 如果没有授权一级菜单,则自身变为一级菜单
|
||||
if (indexMenu.getParentId() != null && !PermissionDataUtil.hasMenuById(metaList, indexMenu.getParentId())) {
|
||||
indexMenu.setMenuType(0);
|
||||
indexMenu.setParentId(null);
|
||||
}
|
||||
if (oConvertUtils.isEmpty(indexMenu.getIcon())) {
|
||||
indexMenu.setIcon("ant-design:home");
|
||||
}
|
||||
metaList.add(0, indexMenu);
|
||||
}
|
||||
//update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存
|
||||
|
||||
/* TODO 注: 这段代码的主要作用是:把首页菜单的组件替换成角色菜单的组件,由于现在的逻辑如果角色菜单不存在则自动插入一条,所以这段代码暂时不需要
|
||||
List<SysPermission> menus = metaList.stream().filter(sysPermission -> {
|
||||
if (defIndexCfg.getUrl().equals(sysPermission.getUrl())) {
|
||||
return true;
|
||||
}
|
||||
return defIndexCfg.getUrl().equals(sysPermission.getUrl());
|
||||
}).collect(Collectors.toList());
|
||||
//update-begin---author:liusq ---date:2022-06-29 for:设置自定义首页地址和组件----------
|
||||
if (menus.size() == 1) {
|
||||
String component = defIndexCfg.getComponent();
|
||||
String routeUrl = defIndexCfg.getUrl();
|
||||
boolean route = defIndexCfg.isRoute();
|
||||
if (oConvertUtils.isNotEmpty(routeUrl)) {
|
||||
menus.get(0).setComponent(component);
|
||||
menus.get(0).setRoute(route);
|
||||
menus.get(0).setUrl(routeUrl);
|
||||
}else{
|
||||
} else {
|
||||
menus.get(0).setComponent(component);
|
||||
}
|
||||
//update-end---author:liusq ---date:2022-06-29 for:设置自定义首页地址和组件-----------
|
||||
}
|
||||
|
||||
//update-end---author:liusq ---date:2022-06-29 for:设置自定义首页地址和组件-----------
|
||||
*/
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
JSONArray menujsonArray = new JSONArray();
|
||||
this.getPermissionJsonArray(menujsonArray, metaList, null);
|
||||
|
@ -287,7 +313,7 @@ public class SysPermissionController {
|
|||
JSONArray authjsonArray = new JSONArray();
|
||||
this.getAuthJsonArray(authjsonArray, metaList);
|
||||
//查询所有的权限
|
||||
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
|
||||
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>().select( SysPermission::getName, SysPermission::getPermsType, SysPermission::getPerms, SysPermission::getStatus);
|
||||
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
|
||||
query.eq(SysPermission::getMenuType, CommonConstant.MENU_TYPE_2);
|
||||
//query.eq(SysPermission::getStatus, "1");
|
||||
|
@ -298,6 +324,12 @@ public class SysPermissionController {
|
|||
json.put("menu", menujsonArray);
|
||||
//按钮权限(用户拥有的权限集合)
|
||||
json.put("auth", authjsonArray);
|
||||
// 按钮权限(用户拥有的权限集合)
|
||||
List<String> codeList = metaList.stream()
|
||||
.filter((permission) -> CommonConstant.MENU_TYPE_2.equals(permission.getMenuType()) && CommonConstant.STATUS_1.equals(permission.getStatus()))
|
||||
.collect(ArrayList::new, (list, permission) -> list.add(permission.getPerms()), ArrayList::addAll);
|
||||
// 所拥有的权限编码(vue3专用)
|
||||
json.put("codeList", codeList);
|
||||
//全部权限配置集合(按钮权限,访问权限)
|
||||
json.put("allAuth", allauthjsonArray);
|
||||
//数据源安全模式
|
||||
|
@ -325,7 +357,7 @@ public class SysPermissionController {
|
|||
return Result.error("请登录系统!");
|
||||
}
|
||||
// 获取当前用户的权限集合
|
||||
List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getUsername());
|
||||
List<SysPermission> metaList = sysPermissionService.queryByUser(loginUser.getId());
|
||||
// 按钮权限(用户拥有的权限集合)
|
||||
List<String> codeList = metaList.stream()
|
||||
.filter((permission) -> CommonConstant.MENU_TYPE_2.equals(permission.getMenuType()) && CommonConstant.STATUS_1.equals(permission.getStatus()))
|
||||
|
@ -334,7 +366,7 @@ public class SysPermissionController {
|
|||
JSONArray authArray = new JSONArray();
|
||||
this.getAuthJsonArray(authArray, metaList);
|
||||
// 查询所有的权限
|
||||
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<>();
|
||||
LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>().select( SysPermission::getName, SysPermission::getPermsType, SysPermission::getPerms, SysPermission::getStatus);
|
||||
query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
|
||||
query.eq(SysPermission::getMenuType, CommonConstant.MENU_TYPE_2);
|
||||
List<SysPermission> allAuthList = sysPermissionService.list(query);
|
||||
|
|
|
@ -123,13 +123,8 @@ public class SysRoleController {
|
|||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
Result<IPage<SysRole>> result = new Result<IPage<SysRole>>();
|
||||
|
||||
//update-begin---author:wangshuai---date:2023-11-20---for:【QQYUN-7089】低代码模式 选择组织角色没有数据 在租户角色中添加数据后,列表也无数据展示---
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
//此接口必须通过租户来隔离查询
|
||||
role.setTenantId(oConvertUtils.getInt(!"0".equals(TenantContext.getTenant()) ? TenantContext.getTenant() : "", -1));
|
||||
}
|
||||
//update-end---author:wangshuai---date:2023-11-20---for:【QQYUN-7089】低代码模式 选择组织角色没有数据 在租户角色中添加数据后,列表也无数据展示---
|
||||
//此接口必须通过租户来隔离查询
|
||||
role.setTenantId(oConvertUtils.getInt(!"0".equals(TenantContext.getTenant()) ? TenantContext.getTenant() : "", -1));
|
||||
|
||||
QueryWrapper<SysRole> queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap());
|
||||
Page<SysRole> page = new Page<SysRole>(pageNo, pageSize);
|
||||
|
@ -220,6 +215,12 @@ public class SysRoleController {
|
|||
return Result.error("删除角色失败,当前角色不在此租户中。");
|
||||
}
|
||||
}
|
||||
|
||||
//update-begin---author:wangshuai---date:2024-01-16---for:【QQYUN-7974】禁止删除 admin 角色---
|
||||
//是否存在admin角色
|
||||
sysRoleService.checkAdminRoleRejectDel(id);
|
||||
//update-end---author:wangshuai---date:2024-01-16---for:【QQYUN-7974】禁止删除 admin 角色---
|
||||
|
||||
sysRoleService.deleteRole(id);
|
||||
return Result.ok("删除角色成功");
|
||||
}
|
||||
|
@ -252,6 +253,8 @@ public class SysRoleController {
|
|||
}
|
||||
}
|
||||
}
|
||||
//验证是否为admin角色
|
||||
sysRoleService.checkAdminRoleRejectDel(ids);
|
||||
sysRoleService.deleteBatchRole(ids.split(","));
|
||||
result.success("删除角色成功!");
|
||||
}
|
||||
|
|
|
@ -1,29 +1,26 @@
|
|||
package org.jeecg.modules.system.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.modules.system.entity.SysRoleIndex;
|
||||
import org.jeecg.modules.system.service.ISysRoleIndexService;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.modules.system.entity.SysRoleIndex;
|
||||
import org.jeecg.modules.system.service.ISysRoleIndexService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Description: 角色首页配置
|
||||
|
@ -172,4 +169,32 @@ public class SysRoleIndexController extends JeecgController<SysRoleIndex, ISysRo
|
|||
SysRoleIndex sysRoleIndex = sysRoleIndexService.getOne(new LambdaQueryWrapper<SysRoleIndex>().eq(SysRoleIndex::getRoleCode, roleCode));
|
||||
return Result.OK(sysRoleIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询默认首页配置
|
||||
*/
|
||||
@GetMapping("/queryDefIndex")
|
||||
public Result<SysRoleIndex> queryDefIndex() {
|
||||
SysRoleIndex defIndexCfg = sysRoleIndexService.queryDefaultIndex();
|
||||
return Result.OK(defIndexCfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新默认首页配置
|
||||
*/
|
||||
@RequiresPermissions("system:permission:setDefIndex")
|
||||
@PutMapping("/updateDefIndex")
|
||||
public Result<?> updateDefIndex(
|
||||
@RequestParam("url") String url,
|
||||
@RequestParam("component") String component,
|
||||
@RequestParam("isRoute") Boolean isRoute
|
||||
) {
|
||||
boolean success = sysRoleIndexService.updateDefaultIndex(url, component, isRoute);
|
||||
if (success) {
|
||||
return Result.OK("设置成功");
|
||||
} else {
|
||||
return Result.error("设置失败");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -244,6 +244,7 @@ public class SysUserController {
|
|||
Result<SysUser> result = new Result<SysUser>();
|
||||
try {
|
||||
String ids = jsonObject.getString("ids");
|
||||
sysUserService.checkUserAdminRejectDel(ids);
|
||||
String status = jsonObject.getString("status");
|
||||
String[] arr = ids.split(",");
|
||||
for (String id : arr) {
|
||||
|
@ -1549,7 +1550,8 @@ public class SysUserController {
|
|||
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
||||
@RequestParam(name = "departId", required = false) String departId,
|
||||
@RequestParam(name = "roleId", required = false) String roleId,
|
||||
@RequestParam(name="keyword",required=false) String keyword) {
|
||||
@RequestParam(name="keyword",required=false) String keyword,
|
||||
@RequestParam(name="excludeUserIdList",required = false) String excludeUserIdList) {
|
||||
//------------------------------------------------------------------------------------------------
|
||||
Integer tenantId = null;
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
|
@ -1560,7 +1562,7 @@ public class SysUserController {
|
|||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
IPage<SysUser> pageList = sysUserDepartService.getUserInformation(tenantId, departId,roleId, keyword, pageSize, pageNo);
|
||||
IPage<SysUser> pageList = sysUserDepartService.getUserInformation(tenantId, departId,roleId, keyword, pageSize, pageNo,excludeUserIdList);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ public class SysUserOnlineController {
|
|||
online.setToken(token);
|
||||
//TODO 改成一次性查询
|
||||
LoginUser loginUser = sysBaseApi.getUserByName(JwtUtil.getUsername(token));
|
||||
if (loginUser != null) {
|
||||
if (loginUser != null && !"_reserve_user_external".equals(loginUser.getUsername())) {
|
||||
//update-begin---author:wangshuai ---date:20220104 for:[JTC-382]在线用户查询无效------------
|
||||
//验证用户名是否与传过来的用户名相同
|
||||
boolean isMatchUsername=true;
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
package org.jeecg.modules.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @Description: 知识库-文档管理
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2022-07-21
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_files")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@ApiModel(value="sys_files对象", description="知识库-文档管理")
|
||||
public class SysFiles {
|
||||
|
||||
/**主键id*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@ApiModelProperty(value = "主键id")
|
||||
private String id;
|
||||
/**文件名称*/
|
||||
@Excel(name = "文件名称", width = 15)
|
||||
@ApiModelProperty(value = "文件名称")
|
||||
private String fileName;
|
||||
/**文件地址*/
|
||||
@Excel(name = "文件地址", width = 15)
|
||||
@ApiModelProperty(value = "文件地址")
|
||||
private String url;
|
||||
/**创建人登录名称*/
|
||||
@Excel(name = "创建人登录名称", width = 15)
|
||||
@Dict(dicCode = "username",dicText = "realname",dictTable = "sys_user")
|
||||
@ApiModelProperty(value = "创建人登录名称")
|
||||
private String createBy;
|
||||
/**创建日期*/
|
||||
@Excel(name = "创建日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty(value = "创建日期")
|
||||
private Date createTime;
|
||||
/**更新人登录名称*/
|
||||
@Excel(name = "更新人登录名称", width = 15)
|
||||
@ApiModelProperty(value = "更新人登录名称")
|
||||
private String updateBy;
|
||||
/**更新日期*/
|
||||
@Excel(name = "更新日期", width = 20, format = "yyyy-MM-dd HH:mm:ss")
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty(value = "更新日期")
|
||||
private Date updateTime;
|
||||
/**文档类型(folder:文件夹 excel:excel doc:word pp:ppt image:图片 archive:其他文档 video:视频)*/
|
||||
@Excel(name = "文档类型(folder:文件夹 excel:excel doc:word pp:ppt image:图片 archive:其他文档 video:视频)", width = 15)
|
||||
@ApiModelProperty(value = "文档类型(folder:文件夹 excel:excel doc:word pp:ppt image:图片 archive:其他文档 video:视频)")
|
||||
private String fileType;
|
||||
/**文件上传类型(temp/本地上传(临时文件) manage/知识库 comment)*/
|
||||
@Excel(name = "文件上传类型(temp/本地上传(临时文件) manage/知识库 common(通用上传))", width = 15)
|
||||
@ApiModelProperty(value = "文件上传类型(temp/本地上传(临时文件) manage/知识库)")
|
||||
private String storeType;
|
||||
/**父级id*/
|
||||
@Excel(name = "父级id", width = 15)
|
||||
@ApiModelProperty(value = "父级id")
|
||||
private String parentId;
|
||||
/**租户id*/
|
||||
@Excel(name = "租户id", width = 15)
|
||||
@ApiModelProperty(value = "租户id")
|
||||
private String tenantId;
|
||||
/**文件大小(kb)*/
|
||||
@Excel(name = "文件大小(kb)", width = 15)
|
||||
@ApiModelProperty(value = "文件大小(kb)")
|
||||
private Double fileSize;
|
||||
/**是否文件夹(1:是 0:否)*/
|
||||
@Excel(name = "是否文件夹(1:是 0:否)", width = 15)
|
||||
@ApiModelProperty(value = "是否文件夹(1:是 0:否)")
|
||||
private String izFolder;
|
||||
/**是否为1级文件夹,允许为空 (1:是 )*/
|
||||
@Excel(name = "是否为1级文件夹,允许为空 (1:是 )", width = 15)
|
||||
@ApiModelProperty(value = "是否为1级文件夹,允许为空 (1:是 )")
|
||||
private String izRootFolder;
|
||||
/**是否标星(1:是 0:否)*/
|
||||
@Excel(name = "是否标星(1:是 0:否)", width = 15)
|
||||
@ApiModelProperty(value = "是否标星(1:是 0:否)")
|
||||
private String izStar;
|
||||
/**下载次数*/
|
||||
@Excel(name = "下载次数", width = 15)
|
||||
@ApiModelProperty(value = "下载次数")
|
||||
private Integer downCount;
|
||||
/**阅读次数*/
|
||||
@Excel(name = "阅读次数", width = 15)
|
||||
@ApiModelProperty(value = "阅读次数")
|
||||
private Integer readCount;
|
||||
/**分享链接*/
|
||||
@Excel(name = "分享链接", width = 15)
|
||||
@ApiModelProperty(value = "分享链接")
|
||||
private String shareUrl;
|
||||
/**分享权限(1.关闭分享 2.允许所有联系人查看 3.允许任何人查看)*/
|
||||
@Excel(name = "分享权限(1.关闭分享 2.允许所有联系人查看 3.允许任何人查看)", width = 15)
|
||||
@ApiModelProperty(value = "分享权限(1.关闭分享 2.允许所有联系人查看 3.允许任何人查看)")
|
||||
private String sharePerms;
|
||||
/**是否允许下载(1:是 0:否)*/
|
||||
@Excel(name = "是否允许下载(1:是 0:否)", width = 15)
|
||||
@ApiModelProperty(value = "是否允许下载(1:是 0:否)")
|
||||
private String enableDown;
|
||||
/**是否允许修改(1:是 0:否)*/
|
||||
@Excel(name = "是否允许修改(1:是 0:否)", width = 15)
|
||||
@ApiModelProperty(value = "是否允许修改(1:是 0:否)")
|
||||
private String enableUpdat;
|
||||
/**删除状态(0-正常,1-删除至回收站)*/
|
||||
@Excel(name = "删除状态(0-正常,1-删除至回收站)", width = 15)
|
||||
@ApiModelProperty(value = "删除状态(0-正常,1-删除至回收站)")
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 文件表不存在的字段:用户数据集合
|
||||
*/
|
||||
@TableField(exist=false)
|
||||
private String userData;
|
||||
|
||||
/**
|
||||
* 文件表不存在的字段:用户真实姓名
|
||||
*/
|
||||
@TableField(exist=false)
|
||||
private String realname;
|
||||
|
||||
/**
|
||||
* 文件表不存在的字段:压缩名称
|
||||
*/
|
||||
@TableField(exist=false)
|
||||
private String zipName;
|
||||
}
|
|
@ -9,7 +9,7 @@ import lombok.Data;
|
|||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.jeecg.modules.system.constant.DefIndexConst;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -166,11 +166,11 @@ public class SysPermission implements Serializable {
|
|||
}
|
||||
public SysPermission(boolean index) {
|
||||
if(index) {
|
||||
this.id = "9502685863ab87f0ad1134142788a385";
|
||||
this.name="首页";
|
||||
this.component="dashboard/Analysis";
|
||||
this.componentName="dashboard-analysis";
|
||||
this.url="/dashboard/analysis";
|
||||
this.id = "9502685863ab87f0ad1134142788a385";
|
||||
this.name = DefIndexConst.DEF_INDEX_NAME;
|
||||
this.component = DefIndexConst.DEF_INDEX_COMPONENT;
|
||||
this.componentName = "dashboard-analysis";
|
||||
this.url = DefIndexConst.DEF_INDEX_URL;
|
||||
this.icon="home";
|
||||
this.menuType=0;
|
||||
this.sortNo=0.0;
|
||||
|
|
|
@ -82,6 +82,12 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
|
|||
*/
|
||||
List<DictModelMany> queryManyDictByKeys(@Param("dictCodeList") List<String> dictCodeList, @Param("keys") List<String> keys);
|
||||
|
||||
/**
|
||||
* 查询系统所有字典项
|
||||
* @return
|
||||
*/
|
||||
public List<DictModelMany> queryAllDictItems(List<Integer> tenantIdList);
|
||||
|
||||
/**
|
||||
* 查询所有部门 作为字典信息 id -->value,departName -->text
|
||||
* @return
|
||||
|
@ -187,4 +193,11 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
|
|||
*/
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
List<SysDict> getDictListByLowAppId(@Param("lowAppId") String lowAppId, @Param("tenantId") Integer tenantId);
|
||||
|
||||
/**
|
||||
* 查询被逻辑删除的数据(根据租户id)
|
||||
* @return
|
||||
*/
|
||||
@Select("select * from sys_dict where del_flag = 1 and tenant_id = #{tenantId}")
|
||||
List<SysDict> queryDeleteListBtTenantId(@Param("tenantId") Integer tenantId);
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
package org.jeecg.modules.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.jeecg.modules.system.entity.SysFiles;
|
||||
|
||||
/**
|
||||
* @Description: 知识库-文档管理
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2022-07-21
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface SysFilesMapper extends BaseMapper<SysFiles> {
|
||||
|
||||
}
|
|
@ -29,10 +29,10 @@ public interface SysPermissionMapper extends BaseMapper<SysPermission> {
|
|||
|
||||
/**
|
||||
* 根据用户查询用户权限
|
||||
* @param username 用户账户名称
|
||||
* @param userId 用户ID
|
||||
* @return List<SysPermission>
|
||||
*/
|
||||
public List<SysPermission> queryByUser(@Param("username") String username);
|
||||
public List<SysPermission> queryByUser(@Param("userId") String userId);
|
||||
|
||||
/**
|
||||
* 修改菜单状态字段: 是否子节点
|
||||
|
|
|
@ -57,7 +57,7 @@ public interface SysUserDepartMapper extends BaseMapper<SysUserDepart>{
|
|||
* @param keyword
|
||||
* @return
|
||||
*/
|
||||
IPage<SysUser> getProcessUserList(Page<SysUser> page, @Param("orgCode") String orgCode, @Param("keyword") String keyword, @Param("tenantId") Integer tenantId);
|
||||
IPage<SysUser> getProcessUserList(Page<SysUser> page, @Param("orgCode") String orgCode, @Param("keyword") String keyword, @Param("tenantId") Integer tenantId, @Param("excludeUserIdList") List<String> excludeUserIdList);
|
||||
|
||||
/**
|
||||
* 获取租户下的部门通过前台传过来的部门id
|
||||
|
|
|
@ -171,9 +171,10 @@ public interface SysUserMapper extends BaseMapper<SysUser> {
|
|||
* @param page
|
||||
* @param roleId
|
||||
* @param keyword
|
||||
* @param userIdList
|
||||
* @return
|
||||
*/
|
||||
IPage<SysUser> selectUserListByRoleId(Page<SysUser> page, @Param("roleId") String roleId, @Param("keyword") String keyword, @Param("tenantId") Integer tenantId);
|
||||
IPage<SysUser> selectUserListByRoleId(Page<SysUser> page, @Param("roleId") String roleId, @Param("keyword") String keyword, @Param("tenantId") Integer tenantId, @Param("excludeUserIdList") List<String> excludeUserIdList);
|
||||
|
||||
/**
|
||||
* 更新刪除状态和离职状态
|
||||
|
|
|
@ -63,6 +63,28 @@
|
|||
</foreach>
|
||||
)
|
||||
</select>
|
||||
|
||||
<!-- 获取全部字典项 -->
|
||||
<select id="queryAllDictItems" resultType="org.jeecg.common.system.vo.DictModelMany">
|
||||
SELECT
|
||||
dict.dict_code,
|
||||
item.item_text AS "text",
|
||||
item.item_value AS "value",
|
||||
item.item_color AS "color"
|
||||
FROM
|
||||
sys_dict_item item
|
||||
INNER JOIN sys_dict dict ON dict.id = item.dict_id
|
||||
WHERE dict.del_flag = 0
|
||||
<if test="tenantIdList!=null and tenantIdList.size()>0">
|
||||
AND dict.tenant_id IN (
|
||||
<foreach item="tenantId" collection="tenantIdList" separator=",">
|
||||
#{tenantId}
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
AND item.status =1
|
||||
order by dict.dict_code, item.sort_order
|
||||
</select>
|
||||
|
||||
<!-- 查询部门信息 作为字典数据 -->
|
||||
<select id="queryAllDepartBackDictModel" resultType="org.jeecg.common.system.vo.DictModel">
|
||||
|
|
|
@ -42,46 +42,104 @@
|
|||
<!-- 获取登录用户拥有的权限 -->
|
||||
<select id="queryByUser" parameterType="Object" resultMap="SysPermission">
|
||||
SELECT * FROM (
|
||||
SELECT p.*
|
||||
SELECT p.id,
|
||||
p.parent_id,
|
||||
p.name,
|
||||
p.url,
|
||||
p.component,
|
||||
p.is_route,
|
||||
p.component_name,
|
||||
p.redirect,
|
||||
p.menu_type,
|
||||
p.perms,
|
||||
p.perms_type,
|
||||
p.sort_no,
|
||||
p.always_show,
|
||||
p.icon,
|
||||
p.is_leaf,
|
||||
p.keep_alive,
|
||||
p.hidden,
|
||||
p.hide_tab,
|
||||
p.rule_flag,
|
||||
p.status,
|
||||
p.internal_or_external
|
||||
FROM sys_permission p
|
||||
WHERE (exists(
|
||||
select a.id from sys_role_permission a
|
||||
join sys_role b on a.role_id = b.id
|
||||
join sys_user_role c on c.role_id = b.id
|
||||
join sys_user d on d.id = c.user_id
|
||||
where p.id = a.permission_id AND d.username = #{username,jdbcType=VARCHAR}
|
||||
WHERE p.del_flag = 0
|
||||
AND ( p.id in (
|
||||
SELECT DISTINCT a.permission_id
|
||||
FROM sys_role_permission a
|
||||
JOIN sys_role b ON a.role_id = b.id
|
||||
JOIN sys_user_role c ON c.role_id = b.id AND c.user_id = #{userId,jdbcType=VARCHAR}
|
||||
)
|
||||
or (p.url like '%:code' and p.url like '/online%' and p.hidden = 1)
|
||||
or (p.url like '%:id' and p.url like '/online%' and p.hidden = 1)
|
||||
or p.url = '/online')
|
||||
and p.del_flag = 0
|
||||
or p.url = '/online'
|
||||
)
|
||||
<!--update begin Author:lvdandan Date:20200213 for:加入部门权限 -->
|
||||
UNION
|
||||
SELECT p.*
|
||||
FROM sys_permission p
|
||||
WHERE exists(
|
||||
select a.id from sys_depart_role_permission a
|
||||
join sys_depart_role b on a.role_id = b.id
|
||||
join sys_depart_role_user c on c.drole_id = b.id
|
||||
join sys_user d on d.id = c.user_id
|
||||
where p.id = a.permission_id AND d.username = #{username,jdbcType=VARCHAR}
|
||||
)
|
||||
SELECT p.id,
|
||||
p.parent_id,
|
||||
p.name,
|
||||
p.url,
|
||||
p.component,
|
||||
p.is_route,
|
||||
p.component_name,
|
||||
p.redirect,
|
||||
p.menu_type,
|
||||
p.perms,
|
||||
p.perms_type,
|
||||
p.sort_no,
|
||||
p.always_show,
|
||||
p.icon,
|
||||
p.is_leaf,
|
||||
p.keep_alive,
|
||||
p.hidden,
|
||||
p.hide_tab,
|
||||
p.rule_flag,
|
||||
p.status,
|
||||
p.internal_or_external
|
||||
FROM sys_permission p
|
||||
WHERE p.id in(
|
||||
SELECT DISTINCT a.permission_id
|
||||
FROM sys_depart_role_permission a
|
||||
INNER JOIN sys_depart_role b ON a.role_id = b.id
|
||||
INNER JOIN sys_depart_role_user c ON c.drole_id = b.id AND c.user_id = #{userId,jdbcType=VARCHAR}
|
||||
)
|
||||
and p.del_flag = 0
|
||||
<!--update end Author:lvdandan Date:20200213 for:加入部门权限 -->
|
||||
|
||||
<!-- update begin Author: taoyan Date:20200213 for:QQYUN-4303 【low app】 用户登录的时候 加载low app的套餐权限 加到用户信息 -->
|
||||
UNION
|
||||
SELECT p.*
|
||||
FROM sys_permission p
|
||||
WHERE exists(
|
||||
select a.id from sys_tenant_pack_perms a
|
||||
join sys_tenant_pack b on a.pack_id = b.id
|
||||
join sys_tenant_pack_user c on c.pack_id = b.id
|
||||
join sys_user d on d.id = c.user_id
|
||||
where p.id = a.permission_id AND d.username = #{username,jdbcType=VARCHAR}
|
||||
)
|
||||
and p.del_flag = 0
|
||||
<!-- update end Author: taoyan Date:20200213 for:QQYUN-4303 【low app】 用户登录的时候 加载low app的套餐权限 加到用户信息 -->
|
||||
UNION
|
||||
SELECT p.id,
|
||||
p.parent_id,
|
||||
p.name,
|
||||
p.url,
|
||||
p.component,
|
||||
p.is_route,
|
||||
p.component_name,
|
||||
p.redirect,
|
||||
p.menu_type,
|
||||
p.perms,
|
||||
p.perms_type,
|
||||
p.sort_no,
|
||||
p.always_show,
|
||||
p.icon,
|
||||
p.is_leaf,
|
||||
p.keep_alive,
|
||||
p.hidden,
|
||||
p.hide_tab,
|
||||
p.rule_flag,
|
||||
p.status,
|
||||
p.internal_or_external
|
||||
FROM sys_permission p
|
||||
WHERE p.id in (
|
||||
SELECT distinct a.permission_id
|
||||
FROM sys_tenant_pack_perms a
|
||||
INNER JOIN sys_tenant_pack b ON a.pack_id = b.id AND b.STATUS = '1'
|
||||
INNER JOIN sys_tenant_pack_user c ON c.pack_id = b.id AND c.STATUS = '1' AND c.user_id = #{userId,jdbcType=VARCHAR}
|
||||
)
|
||||
and p.del_flag = 0
|
||||
<!-- update end Author: taoyan Date:20200213 for:QQYUN-4303 【low app】 用户登录的时候 加载low app的套餐权限 加到用户信息 -->
|
||||
|
||||
) h order by h.sort_no ASC
|
||||
</select>
|
||||
|
|
|
@ -74,6 +74,13 @@
|
|||
select user_id from sys_user_tenant where tenant_id = #{tenantId} and status = '1'
|
||||
)
|
||||
</if>
|
||||
<!--【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页 需要将不符合的用户id排除-->
|
||||
<if test="excludeUserIdList!=null and excludeUserIdList.size()>0">
|
||||
and a.id not in
|
||||
<foreach collection="excludeUserIdList" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!--获取租户下的部门-通过前台传过来的部门id-->
|
||||
|
|
|
@ -219,6 +219,14 @@
|
|||
select user_id from sys_user_tenant where tenant_id = #{tenantId} and status = '1'
|
||||
)
|
||||
</if>
|
||||
|
||||
<!--【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页 需要将不符合的用户id排除-->
|
||||
<if test="excludeUserIdList!=null and excludeUserIdList.size()>0">
|
||||
and a.id not in
|
||||
<foreach collection="excludeUserIdList" item="userId" open="(" close=")" separator=",">
|
||||
#{userId}
|
||||
</foreach>
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!--获取租户下的用户离职列表信息-->
|
||||
|
|
|
@ -238,7 +238,7 @@ public interface ISysDictService extends IService<SysDict> {
|
|||
* 查询被逻辑删除的数据
|
||||
* @return
|
||||
*/
|
||||
public List<SysDict> queryDeleteList();
|
||||
public List<SysDict> queryDeleteList(String tenantId);
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
package org.jeecg.modules.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.system.entity.SysFiles;
|
||||
|
||||
/**
|
||||
* @Description: 知识库-文档管理
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2022-07-21
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ISysFilesService extends IService<SysFiles> {
|
||||
|
||||
}
|
|
@ -1,14 +1,43 @@
|
|||
package org.jeecg.modules.system.service;
|
||||
|
||||
import org.jeecg.modules.system.entity.SysRoleIndex;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.system.entity.SysRoleIndex;
|
||||
|
||||
/**
|
||||
* @Description: 角色首页配置
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2022-03-25
|
||||
* @Date: 2022-03-25
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ISysRoleIndexService extends IService<SysRoleIndex> {
|
||||
|
||||
/**
|
||||
* 查询默认首页
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
SysRoleIndex queryDefaultIndex();
|
||||
|
||||
/**
|
||||
* 更新默认首页
|
||||
*
|
||||
* @param url
|
||||
* @param component
|
||||
* @param isRoute 是否是路由页面
|
||||
* @return
|
||||
*/
|
||||
boolean updateDefaultIndex(String url, String component, boolean isRoute);
|
||||
|
||||
/**
|
||||
* 创建最原始的默认首页配置
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
SysRoleIndex initDefaultIndex();
|
||||
|
||||
/**
|
||||
* 清理默认首页的redis缓存
|
||||
*/
|
||||
void cleanDefaultIndexCache();
|
||||
|
||||
}
|
||||
|
|
|
@ -67,4 +67,11 @@ public interface ISysRoleService extends IService<SysRole> {
|
|||
* @return
|
||||
*/
|
||||
Long getRoleCountByTenantId(String id, Integer tenantId);
|
||||
|
||||
/**
|
||||
* 验证是否为admin角色
|
||||
*
|
||||
* @param ids
|
||||
*/
|
||||
void checkAdminRoleRejectDel(String ids);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ public interface ISysUserDepartService extends IService<SysUserDepart> {
|
|||
* @param pageNo
|
||||
* @return
|
||||
*/
|
||||
IPage<SysUser> getUserInformation(Integer tenantId,String departId,String roleId, String keyword, Integer pageSize, Integer pageNo);
|
||||
IPage<SysUser> getUserInformation(Integer tenantId,String departId,String roleId, String keyword, Integer pageSize, Integer pageNo, String excludeUserIdList);
|
||||
|
||||
/**
|
||||
* 通过部门id和租户id获取多个用户
|
||||
|
|
|
@ -190,10 +190,10 @@ public interface ISysUserService extends IService<SysUser> {
|
|||
/**
|
||||
* 通过用户名获取用户权限集合
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param userId 用户id
|
||||
* @return 权限集合
|
||||
*/
|
||||
Set<String> getUserPermissionsSet(String username);
|
||||
Set<String> getUserPermissionsSet(String userId);
|
||||
|
||||
/**
|
||||
* 根据用户名设置部门ID
|
||||
|
@ -411,4 +411,10 @@ public interface ISysUserService extends IService<SysUser> {
|
|||
* @return
|
||||
*/
|
||||
Result<?> importAppUser(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 验证用户是否为管理员
|
||||
* @param ids
|
||||
*/
|
||||
void checkUserAdminRejectDel(String ids);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public interface ISysUserTenantService extends IService<SysUserTenant> {
|
|||
List<SysUser> setUserTenantIds(List<SysUser> records);
|
||||
|
||||
/**
|
||||
* 获取用户id根据用户id
|
||||
* 获取租户id获取用户ids
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
|
|
|
@ -22,7 +22,6 @@ import org.jeecg.common.api.dto.DataLogDTO;
|
|||
import org.jeecg.common.api.dto.OnlineAuthDTO;
|
||||
import org.jeecg.common.api.dto.message.*;
|
||||
import org.jeecg.common.aspect.UrlMatchEnum;
|
||||
import org.jeecg.common.config.TenantContext;
|
||||
import org.jeecg.common.constant.*;
|
||||
import org.jeecg.common.constant.enums.EmailTemplateEnum;
|
||||
import org.jeecg.common.constant.enums.MessageTypeEnum;
|
||||
|
@ -125,8 +124,6 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
|||
@Autowired
|
||||
private ISysDataLogService sysDataLogService;
|
||||
@Autowired
|
||||
private ISysFilesService sysFilesService;
|
||||
@Autowired
|
||||
private ISysRoleService sysRoleService;
|
||||
@Autowired
|
||||
private ISysUserTenantService sysUserTenantService;
|
||||
|
@ -336,7 +333,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDepartParentIdsByDepIds(Set depIds) {
|
||||
public Set<String> getDepartParentIdsByDepIds(Set<String> depIds) {
|
||||
LambdaQueryWrapper<SysDepart> departQuery = new LambdaQueryWrapper<SysDepart>().in(SysDepart::getId, depIds);
|
||||
List<SysDepart> departList = departMapper.selectList(departQuery);
|
||||
|
||||
|
@ -1098,13 +1095,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
|||
|
||||
/**
|
||||
* 查询用户拥有的权限集合
|
||||
* @param username
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getUserPermissionSet(String username) {
|
||||
public Set<String> getUserPermissionSet(String userId) {
|
||||
Set<String> permissionSet = new HashSet<>();
|
||||
List<SysPermission> permissionList = sysPermissionMapper.queryByUser(username);
|
||||
List<SysPermission> permissionList = sysPermissionMapper.queryByUser(userId);
|
||||
//================= begin 开启租户的时候 如果没有test角色,默认加入test角色================
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
if (permissionList == null) {
|
||||
|
@ -1123,7 +1120,7 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
|||
permissionSet.add(po.getPerms());
|
||||
}
|
||||
}
|
||||
log.info("-------通过数据库读取用户拥有的权限Perms------username: "+ username+",Perms size: "+ (permissionSet==null?0:permissionSet.size()) );
|
||||
log.info("-------通过数据库读取用户拥有的权限Perms------userId: "+ userId+",Perms size: "+ (permissionSet==null?0:permissionSet.size()) );
|
||||
return permissionSet;
|
||||
}
|
||||
|
||||
|
@ -1148,7 +1145,13 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
|||
sysPermission.setUrl(onlineFormUrl);
|
||||
int count = sysPermissionMapper.queryCountByUsername(username, sysPermission);
|
||||
if(count<=0){
|
||||
return false;
|
||||
//update-begin---author:chenrui ---date:20240123 for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
|
||||
sysPermission.setUrl(onlineAuthDTO.getOnlineWorkOrderUrl());
|
||||
count = sysPermissionMapper.queryCountByUsername(username, sysPermission);
|
||||
if(count<=0) {
|
||||
return false;
|
||||
}
|
||||
//update-end---author:chenrui ---date:20240123 for:[QQYUN-7992]【online】工单申请下的online表单,未配置online表单开发菜单,操作报错无权限------------
|
||||
}
|
||||
} else {
|
||||
//找到菜单了
|
||||
|
@ -1174,12 +1177,12 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
|||
|
||||
/**
|
||||
* 查询用户拥有的权限集合 common api 里面的接口实现
|
||||
* @param username
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Set<String> queryUserAuths(String username) {
|
||||
return getUserPermissionSet(username);
|
||||
public Set<String> queryUserAuths(String userId) {
|
||||
return getUserPermissionSet(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1591,30 +1594,14 @@ public class SysBaseApiImpl implements ISysBaseAPI {
|
|||
entity.setDataContent(dataLogDto.getContent());
|
||||
entity.setType(dataLogDto.getType());
|
||||
entity.setDataVersion("1");
|
||||
entity.autoSetCreateName();
|
||||
if (oConvertUtils.isNotEmpty(dataLogDto.getCreateName())) {
|
||||
entity.setCreateBy(dataLogDto.getCreateName());
|
||||
} else {
|
||||
entity.autoSetCreateName();
|
||||
}
|
||||
sysDataLogService.save(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSysFiles(SysFilesModel sysFilesModel) {
|
||||
SysFiles sysFiles = new SysFiles();
|
||||
BeanUtils.copyProperties(sysFilesModel,sysFiles);
|
||||
String defaultValue = "0";
|
||||
sysFiles.setIzStar(defaultValue);
|
||||
sysFiles.setIzFolder(defaultValue);
|
||||
sysFiles.setIzRootFolder(defaultValue);
|
||||
sysFiles.setDelFlag(defaultValue);
|
||||
String tenantId = oConvertUtils.getString(TenantContext.getTenant());
|
||||
sysFiles.setTenantId(tenantId);
|
||||
sysFilesService.save(sysFiles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFileUrl(String fileId) {
|
||||
SysFiles sysFiles = sysFilesService.getById(fileId);
|
||||
return sysFiles.getUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAvatar(LoginUser loginUser) {
|
||||
SysUser sysUser = new SysUser();
|
||||
|
|
|
@ -12,14 +12,13 @@ import org.jeecg.common.constant.enums.FileTypeEnum;
|
|||
import org.jeecg.common.constant.enums.MessageTypeEnum;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.common.system.vo.SysFilesModel;
|
||||
import org.jeecg.common.util.CommonUtils;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysComment;
|
||||
import org.jeecg.modules.system.entity.SysFiles;
|
||||
import org.jeecg.modules.system.entity.SysFormFile;
|
||||
import org.jeecg.modules.system.mapper.SysCommentMapper;
|
||||
import org.jeecg.modules.system.mapper.SysFilesMapper;
|
||||
import org.jeecg.modules.system.mapper.SysFormFileMapper;
|
||||
import org.jeecg.modules.system.service.ISysCommentService;
|
||||
import org.jeecg.modules.system.vo.SysCommentFileVo;
|
||||
|
@ -55,8 +54,8 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
|
|||
@Autowired
|
||||
private SysFormFileMapper sysFormFileMapper;
|
||||
|
||||
@Autowired
|
||||
private SysFilesMapper sysFilesMapper;
|
||||
// @Autowired
|
||||
// private IEasyOaBaseApi easyOaBseApi;
|
||||
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
|
@ -158,7 +157,7 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
|
|||
FileTypeEnum fileType = FileTypeEnum.getByType(type);
|
||||
|
||||
//保存至 SysFiles
|
||||
SysFiles sysFiles = new SysFiles();
|
||||
SysFilesModel sysFiles = new SysFilesModel();
|
||||
sysFiles.setFileName(orgName);
|
||||
sysFiles.setUrl(savePath);
|
||||
sysFiles.setFileType(fileType.getValue());
|
||||
|
@ -166,16 +165,13 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
|
|||
if (size > 0) {
|
||||
sysFiles.setFileSize(Double.parseDouble(String.valueOf(size)));
|
||||
}
|
||||
String defaultValue = "0";
|
||||
sysFiles.setIzStar(defaultValue);
|
||||
sysFiles.setIzFolder(defaultValue);
|
||||
sysFiles.setIzRootFolder(defaultValue);
|
||||
sysFiles.setDelFlag(defaultValue);
|
||||
String fileId = String.valueOf(IdWorker.getId());
|
||||
sysFiles.setId(fileId);
|
||||
String tenantId = oConvertUtils.getString(TenantContext.getTenant());
|
||||
sysFiles.setTenantId(tenantId);
|
||||
sysFilesMapper.insert(sysFiles);
|
||||
// //update-begin---author:wangshuai---date:2024-01-04---for:【QQYUN-7821】知识库后端迁移---
|
||||
// easyOaBseApi.addSysFiles(sysFiles);
|
||||
// //update-end---author:wangshuai---date:2024-01-04---for:【QQYUN-7821】知识库后端迁移---
|
||||
|
||||
//保存至 SysFormFile
|
||||
String tableName = SYS_FORM_FILE_TABLE_NAME;
|
||||
|
@ -188,18 +184,20 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
|
|||
sysFormFileMapper.insert(sysFormFile);
|
||||
|
||||
}else{
|
||||
SysFiles sysFiles = sysFilesMapper.selectById(existFileId);
|
||||
if(sysFiles!=null){
|
||||
// //update-begin---author:wangshuai---date:2024-01-04---for:【QQYUN-7821】知识库后端迁移---
|
||||
// SysFilesModel sysFiles = easyOaBseApi.getFileById(existFileId);
|
||||
// //update-end---author:wangshuai---date:2024-01-04---for:【QQYUN-7821】知识库后端迁移---
|
||||
// if(sysFiles!=null){
|
||||
//保存至 SysFormFile
|
||||
String tableName = SYS_FORM_FILE_TABLE_NAME;
|
||||
String tableDataId = request.getParameter("commentId");
|
||||
SysFormFile sysFormFile = new SysFormFile();
|
||||
sysFormFile.setTableName(tableName);
|
||||
sysFormFile.setFileType(sysFiles.getFileType());
|
||||
sysFormFile.setFileType("");
|
||||
sysFormFile.setTableDataId(tableDataId);
|
||||
sysFormFile.setFileId(existFileId);
|
||||
sysFormFileMapper.insert(sysFormFile);
|
||||
}
|
||||
// }
|
||||
}
|
||||
//update-end-author:taoyan date:2023-6-12 for: QQYUN-4310【文件】从文件库选择文件功能未做
|
||||
}
|
||||
|
@ -224,7 +222,7 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
|
|||
FileTypeEnum fileType = FileTypeEnum.getByType(type);
|
||||
|
||||
//保存至 SysFiles
|
||||
SysFiles sysFiles = new SysFiles();
|
||||
SysFilesModel sysFiles = new SysFilesModel();
|
||||
sysFiles.setFileName(orgName);
|
||||
sysFiles.setUrl(savePath);
|
||||
sysFiles.setFileType(fileType.getValue());
|
||||
|
@ -233,16 +231,13 @@ public class SysCommentServiceImpl extends ServiceImpl<SysCommentMapper, SysComm
|
|||
sysFiles.setFileSize(Double.parseDouble(String.valueOf(size)));
|
||||
}
|
||||
String defaultValue = "0";
|
||||
sysFiles.setIzStar(defaultValue);
|
||||
sysFiles.setIzFolder(defaultValue);
|
||||
sysFiles.setIzRootFolder(defaultValue);
|
||||
sysFiles.setDelFlag(defaultValue);
|
||||
String fileId = String.valueOf(IdWorker.getId());
|
||||
sysFiles.setId(fileId);
|
||||
String tenantId = oConvertUtils.getString(TenantContext.getTenant());
|
||||
sysFiles.setTenantId(tenantId);
|
||||
sysFilesMapper.insert(sysFiles);
|
||||
|
||||
// //update-begin---author:wangshuai---date:2024-01-04---for:【QQYUN-7821】知识库后端迁移---
|
||||
// easyOaBseApi.addSysFiles(sysFiles);
|
||||
// //update-end---author:wangshuai---date:2024-01-04---for:【QQYUN-7821】知识库后端迁移---
|
||||
//保存至 SysFormFile
|
||||
String tableName = SYS_FORM_FILE_TABLE_NAME;
|
||||
String tableDataId = request.getParameter("commentId");
|
||||
|
|
|
@ -152,37 +152,36 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
|||
|
||||
@Override
|
||||
public Map<String, List<DictModel>> queryAllDictItems() {
|
||||
Map<String, List<DictModel>> res = new HashMap(5);
|
||||
LambdaQueryWrapper<SysDict> sysDictQueryWrapper = new LambdaQueryWrapper<SysDict>();
|
||||
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
|
||||
long start = System.currentTimeMillis();
|
||||
Map<String, List<DictModel>> sysAllDictItems = new HashMap(5);
|
||||
List<Integer> tenantIds = null;
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
sysDictQueryWrapper.eq(SysDict::getTenantId, oConvertUtils.getInt(TenantContext.getTenant(), 0))
|
||||
.or().eq(SysDict::getTenantId,0);
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
tenantIds = new ArrayList<>();
|
||||
tenantIds.add(0);
|
||||
if (TenantContext.getTenant() != null) {
|
||||
tenantIds.add(oConvertUtils.getInt(TenantContext.getTenant()));
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
List<SysDict> ls = sysDictMapper.selectList(sysDictQueryWrapper);
|
||||
LambdaQueryWrapper<SysDictItem> queryWrapper = new LambdaQueryWrapper<SysDictItem>();
|
||||
queryWrapper.eq(SysDictItem::getStatus, 1);
|
||||
queryWrapper.orderByAsc(SysDictItem::getSortOrder);
|
||||
List<SysDictItem> sysDictItemList = sysDictItemMapper.selectList(queryWrapper);
|
||||
List<DictModelMany> sysDictItemList = sysDictMapper.queryAllDictItems(tenantIds);
|
||||
// 使用groupingBy根据dictCode分组
|
||||
sysAllDictItems = sysDictItemList.stream()
|
||||
.collect(Collectors.groupingBy(DictModelMany::getDictCode,
|
||||
Collectors.mapping(d -> new DictModel(d.getValue(), d.getText(), d.getColor()), Collectors.toList())));
|
||||
log.info(" >>> 1 获取系统字典项耗时(SQL):" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
for (SysDict d : ls) {
|
||||
List<DictModel> dictModelList = sysDictItemList.stream().filter(s -> d.getId().equals(s.getDictId())).map(item -> {
|
||||
DictModel dictModel = new DictModel();
|
||||
dictModel.setText(item.getItemText());
|
||||
dictModel.setValue(item.getItemValue());
|
||||
return dictModel;
|
||||
}).collect(Collectors.toList());
|
||||
res.put(d.getDictCode(), dictModelList);
|
||||
}
|
||||
//update-begin-author:taoyan date:2022-7-8 for: 系统字典数据应该包括自定义的java类-枚举
|
||||
Map<String, List<DictModel>> enumRes = ResourceUtil.getEnumDictData();
|
||||
res.putAll(enumRes);
|
||||
//update-end-author:taoyan date:2022-7-8 for: 系统字典数据应该包括自定义的java类-枚举
|
||||
log.debug("-------登录加载系统字典-----" + res.toString());
|
||||
return res;
|
||||
sysAllDictItems.putAll(enumRes);
|
||||
log.info(" >>> 2 获取系统字典项耗时(Enum):" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
|
||||
log.info(" >>> end 获取系统字典库总耗时:" + (System.currentTimeMillis() - start) + "毫秒");
|
||||
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
|
||||
|
||||
//log.info("-------登录加载系统字典-----" + sysAllDictItems.toString());
|
||||
return sysAllDictItems;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -531,10 +530,12 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
|||
String filterSql = "";
|
||||
String keywordSql = null;
|
||||
String sqlWhere = "where ";
|
||||
String sqlAnd = " and ";
|
||||
|
||||
//【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错
|
||||
if (tableSql.toLowerCase().contains(sqlWhere)) {
|
||||
sqlWhere = CommonUtils.getFilterSqlByTableSql(tableSql) + " and ";
|
||||
boolean tableHasWhere = tableSql.toLowerCase().contains(sqlWhere);
|
||||
if (tableHasWhere) {
|
||||
sqlWhere = CommonUtils.getFilterSqlByTableSql(tableSql);
|
||||
}
|
||||
|
||||
// 下拉搜索组件 支持传入排序信息 查询排序
|
||||
|
@ -565,11 +566,13 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
|||
|
||||
//下拉搜索组件 支持传入排序信息 查询排序
|
||||
if(oConvertUtils.isNotEmpty(condition) && oConvertUtils.isNotEmpty(keywordSql)){
|
||||
filterSql+= sqlWhere + condition + " and " + keywordSql;
|
||||
filterSql += sqlWhere + sqlAnd + condition + sqlAnd + keywordSql;
|
||||
}else if(oConvertUtils.isNotEmpty(condition)){
|
||||
filterSql+= sqlWhere + condition;
|
||||
filterSql += sqlWhere + sqlAnd + condition;
|
||||
}else if(oConvertUtils.isNotEmpty(keywordSql)){
|
||||
filterSql+= sqlWhere + keywordSql;
|
||||
filterSql += sqlWhere + sqlAnd + keywordSql;
|
||||
} else if (tableHasWhere){
|
||||
filterSql += sqlWhere;
|
||||
}
|
||||
|
||||
// 增加排序逻辑
|
||||
|
@ -652,7 +655,15 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<SysDict> queryDeleteList() {
|
||||
public List<SysDict> queryDeleteList(String tenantId) {
|
||||
//update-begin---author:wangshuai---date:2024-02-27---for:【QQYUN-8340】回收站查找软删除记录时,没有判断是否启用多租户,造成可以查找并回收其他租户的数据 #5907---
|
||||
if(MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL){
|
||||
if(oConvertUtils.isEmpty(tenantId)){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return baseMapper.queryDeleteListBtTenantId(oConvertUtils.getInt(tenantId));
|
||||
}
|
||||
//update-end---author:wangshuai---date:2024-02-27---for:【QQYUN-8340】回收站查找软删除记录时,没有判断是否启用多租户,造成可以查找并回收其他租户的数据 #5907---
|
||||
return baseMapper.queryDeleteList();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.modules.system.entity.SysFiles;
|
||||
import org.jeecg.modules.system.mapper.SysFilesMapper;
|
||||
import org.jeecg.modules.system.service.ISysFilesService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
/**
|
||||
* @Description: 知识库-文档管理
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2022-07-21
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class SysFilesServiceImpl extends ServiceImpl<SysFilesMapper, SysFiles> implements ISysFilesService {
|
||||
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.common.constant.CacheConstant;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
|
@ -11,6 +10,7 @@ import org.jeecg.common.util.oConvertUtils;
|
|||
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
|
||||
import org.jeecg.modules.system.entity.SysPermission;
|
||||
import org.jeecg.modules.system.entity.SysPermissionDataRule;
|
||||
import org.jeecg.modules.system.entity.SysRoleIndex;
|
||||
import org.jeecg.modules.system.mapper.SysDepartPermissionMapper;
|
||||
import org.jeecg.modules.system.mapper.SysDepartRolePermissionMapper;
|
||||
import org.jeecg.modules.system.mapper.SysPermissionMapper;
|
||||
|
@ -18,14 +18,15 @@ import org.jeecg.modules.system.mapper.SysRolePermissionMapper;
|
|||
import org.jeecg.modules.system.model.TreeModel;
|
||||
import org.jeecg.modules.system.service.ISysPermissionDataRuleService;
|
||||
import org.jeecg.modules.system.service.ISysPermissionService;
|
||||
import org.jeecg.modules.system.service.ISysRoleIndexService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -53,6 +54,9 @@ public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, S
|
|||
@Resource
|
||||
private SysDepartRolePermissionMapper sysDepartRolePermissionMapper;
|
||||
|
||||
@Autowired
|
||||
private ISysRoleIndexService roleIndexService;
|
||||
|
||||
@Override
|
||||
public void switchVue3Menu() {
|
||||
sysPermissionMapper.backupVue2Menu();
|
||||
|
@ -217,13 +221,21 @@ public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, S
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
// 同步更改默认菜单
|
||||
SysRoleIndex defIndexCfg = this.roleIndexService.queryDefaultIndex();
|
||||
boolean isDefIndex = defIndexCfg.getUrl().equals(p.getUrl());
|
||||
if (isDefIndex) {
|
||||
this.roleIndexService.updateDefaultIndex(sysPermission.getUrl(), sysPermission.getComponent(), sysPermission.isRoute());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysPermission> queryByUser(String username) {
|
||||
List<SysPermission> permissionList = this.sysPermissionMapper.queryByUser(username);
|
||||
public List<SysPermission> queryByUser(String userId) {
|
||||
List<SysPermission> permissionList = this.sysPermissionMapper.queryByUser(userId);
|
||||
//================= begin 开启租户的时候 如果没有test角色,默认加入test角色================
|
||||
if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
|
||||
if (permissionList == null) {
|
||||
|
|
|
@ -1,19 +1,91 @@
|
|||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.util.RedisUtil;
|
||||
import org.jeecg.modules.system.constant.DefIndexConst;
|
||||
import org.jeecg.modules.system.entity.SysRoleIndex;
|
||||
import org.jeecg.modules.system.mapper.SysRoleIndexMapper;
|
||||
import org.jeecg.modules.system.service.ISysRoleIndexService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
/**
|
||||
* @Description: 角色首页配置
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2022-03-25
|
||||
* @Date: 2022-03-25
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
@Service("sysRoleIndexServiceImpl")
|
||||
public class SysRoleIndexServiceImpl extends ServiceImpl<SysRoleIndexMapper, SysRoleIndex> implements ISysRoleIndexService {
|
||||
|
||||
@Autowired
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = DefIndexConst.CACHE_KEY, key = "'" + DefIndexConst.DEF_INDEX_ALL + "'")
|
||||
public SysRoleIndex queryDefaultIndex() {
|
||||
LambdaQueryWrapper<SysRoleIndex> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysRoleIndex::getRoleCode, DefIndexConst.DEF_INDEX_ALL);
|
||||
SysRoleIndex entity = super.getOne(queryWrapper);
|
||||
// 保证不为空
|
||||
if (entity == null) {
|
||||
entity = this.initDefaultIndex();
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateDefaultIndex(String url, String component, boolean isRoute) {
|
||||
// 1. 先查询出配置信息
|
||||
LambdaQueryWrapper<SysRoleIndex> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysRoleIndex::getRoleCode, DefIndexConst.DEF_INDEX_ALL);
|
||||
SysRoleIndex entity = super.getOne(queryWrapper);
|
||||
boolean success = false;
|
||||
// 2. 如果不存在则新增
|
||||
if (entity == null) {
|
||||
entity = this.newDefIndexConfig(url, component, isRoute);
|
||||
success = super.save(entity);
|
||||
} else {
|
||||
// 3. 如果存在则更新
|
||||
entity.setUrl(url);
|
||||
entity.setComponent(component);
|
||||
entity.setRoute(isRoute);
|
||||
success = super.updateById(entity);
|
||||
}
|
||||
// 4. 清理缓存
|
||||
if (success) {
|
||||
this.cleanDefaultIndexCache();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysRoleIndex initDefaultIndex() {
|
||||
return this.newDefIndexConfig(DefIndexConst.DEF_INDEX_URL, DefIndexConst.DEF_INDEX_COMPONENT, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建默认首页配置
|
||||
*
|
||||
* @param indexComponent
|
||||
* @return
|
||||
*/
|
||||
private SysRoleIndex newDefIndexConfig(String indexUrl, String indexComponent, boolean isRoute) {
|
||||
SysRoleIndex entity = new SysRoleIndex();
|
||||
entity.setRoleCode(DefIndexConst.DEF_INDEX_ALL);
|
||||
entity.setUrl(indexUrl);
|
||||
entity.setComponent(indexComponent);
|
||||
entity.setRoute(isRoute);
|
||||
entity.setStatus(CommonConstant.STATUS_1);
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanDefaultIndexCache() {
|
||||
redisUtil.del(DefIndexConst.CACHE_KEY + "::" + DefIndexConst.DEF_INDEX_ALL);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.common.util.ImportExcelUtil;
|
||||
import org.jeecg.modules.system.entity.SysRole;
|
||||
import org.jeecg.modules.system.mapper.SysRoleMapper;
|
||||
|
@ -102,4 +105,15 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
public Long getRoleCountByTenantId(String id, Integer tenantId) {
|
||||
return sysRoleMapper.getRoleCountByTenantId(id,tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkAdminRoleRejectDel(String ids) {
|
||||
LambdaQueryWrapper<SysRole> query = new LambdaQueryWrapper<>();
|
||||
query.in(SysRole::getId,Arrays.asList(ids.split(SymbolConstant.COMMA)));
|
||||
query.eq(SysRole::getRoleCode,"admin");
|
||||
Long adminRoleCount = sysRoleMapper.selectCount(query);
|
||||
if(adminRoleCount>0){
|
||||
throw new JeecgBootException("admin角色,不允许删除!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,11 +128,13 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
|
|||
|
||||
@Override
|
||||
public void addDefaultTenantPack(Integer tenantId) {
|
||||
ISysTenantPackService currentService = SpringContextUtils.getApplicationContext().getBean(ISysTenantPackService.class);
|
||||
// 创建租户超级管理员
|
||||
SysTenantPack superAdminPack = new SysTenantPack(tenantId, "超级管理员", TenantConstant.SUPER_ADMIN);
|
||||
|
||||
//step.1 创建租户套餐包(超级管理员)
|
||||
LambdaQueryWrapper<SysTenantPack> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysTenantPack::getTenantId,tenantId);
|
||||
// 创建超级管理员
|
||||
SysTenantPack superAdminPack = new SysTenantPack(tenantId, "超级管理员", TenantConstant.SUPER_ADMIN);
|
||||
ISysTenantPackService currentService = SpringContextUtils.getApplicationContext().getBean(ISysTenantPackService.class);
|
||||
query.eq(SysTenantPack::getPackCode, TenantConstant.SUPER_ADMIN);
|
||||
SysTenantPack sysTenantPackSuperAdmin = currentService.getOne(query);
|
||||
String packId = "";
|
||||
|
@ -141,13 +143,15 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
|
|||
}else{
|
||||
packId = sysTenantPackSuperAdmin.getId();
|
||||
}
|
||||
//step.1.2 补充人员与套餐包的关系数据
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
SysTenantPackUser packUser = new SysTenantPackUser(tenantId, packId, sysUser.getId());
|
||||
packUser.setRealname(sysUser.getRealname());
|
||||
packUser.setPackName(superAdminPack.getPackName());
|
||||
//添加人员和管理员的关系数据
|
||||
currentService.savePackUser(packUser);
|
||||
|
||||
|
||||
//step.2 创建租户套餐包(组织账户管理员)和 添加人员关系数据
|
||||
query.eq(SysTenantPack::getTenantId,tenantId);
|
||||
query.eq(SysTenantPack::getPackCode, TenantConstant.ACCOUNT_ADMIN);
|
||||
SysTenantPack sysTenantPackAccountAdmin = currentService.getOne(query);
|
||||
if(null == sysTenantPackAccountAdmin){
|
||||
|
@ -155,10 +159,11 @@ public class SysTenantPackServiceImpl extends ServiceImpl<SysTenantPackMapper, S
|
|||
SysTenantPack accountAdminPack = new SysTenantPack(tenantId, "组织账户管理员", TenantConstant.ACCOUNT_ADMIN);
|
||||
currentService.saveOne(accountAdminPack);
|
||||
}
|
||||
|
||||
|
||||
//step.3 创建租户套餐包(组织应用管理员)
|
||||
query.eq(SysTenantPack::getTenantId,tenantId);
|
||||
query.eq(SysTenantPack::getPackCode, TenantConstant.APP_ADMIN);
|
||||
SysTenantPack sysTenantPackAppAdmin = currentService.getOne(query);
|
||||
|
||||
if(null == sysTenantPackAppAdmin){
|
||||
// 创建超级管理员
|
||||
SysTenantPack appAdminPack = new SysTenantPack(tenantId, "组织应用管理员", TenantConstant.APP_ADMIN);
|
||||
|
|
|
@ -27,10 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
@ -262,24 +259,38 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S
|
|||
}
|
||||
|
||||
@Override
|
||||
public IPage<SysUser> getUserInformation(Integer tenantId, String departId,String roleId, String keyword, Integer pageSize, Integer pageNo) {
|
||||
public IPage<SysUser> getUserInformation(Integer tenantId, String departId,String roleId, String keyword, Integer pageSize, Integer pageNo, String excludeUserIdList) {
|
||||
IPage<SysUser> pageList = null;
|
||||
// 部门ID不存在 直接查询用户表即可
|
||||
Page<SysUser> page = new Page<>(pageNo, pageSize);
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
|
||||
List<String> userIdList = new ArrayList<>();
|
||||
if(oConvertUtils.isNotEmpty(excludeUserIdList)){
|
||||
userIdList = Arrays.asList(excludeUserIdList.split(SymbolConstant.COMMA));
|
||||
}
|
||||
if(oConvertUtils.isNotEmpty(departId)){
|
||||
// 有部门ID 需要走自定义sql
|
||||
SysDepart sysDepart = sysDepartService.getById(departId);
|
||||
//update-begin-author:taoyan date:2023-1-3 for: 用户选择组件 加载用户需要根据租户ID过滤
|
||||
pageList = this.baseMapper.getProcessUserList(page, sysDepart.getOrgCode(), keyword, tenantId);
|
||||
//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
pageList = this.baseMapper.getProcessUserList(page, sysDepart.getOrgCode(), keyword, tenantId, userIdList);
|
||||
//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
} else if (oConvertUtils.isNotEmpty(roleId)) {
|
||||
pageList = this.sysUserMapper.selectUserListByRoleId(page, roleId, keyword, tenantId);
|
||||
//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
pageList = this.sysUserMapper.selectUserListByRoleId(page, roleId, keyword, tenantId,userIdList);
|
||||
//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
//update-end-author:taoyan date:2023-1-3 for: 用户选择组件 加载用户需要根据租户ID过滤
|
||||
} else{
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysUser::getStatus,Integer.parseInt(CommonConstant.STATUS_1));
|
||||
query.ne(SysUser::getUsername,"_reserve_user_external");
|
||||
|
||||
//update-begin---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
if(oConvertUtils.isNotEmpty(excludeUserIdList)){
|
||||
query.notIn(SysUser::getId,Arrays.asList(excludeUserIdList.split(SymbolConstant.COMMA)));
|
||||
}
|
||||
//update-end---author:wangshuai---date:2024-02-02---for:【QQYUN-8239】用户角色,添加用户 返回2页数据,实际只显示一页---
|
||||
// 支持租户隔离
|
||||
if (tenantId != null) {
|
||||
List<String> userIds = userTenantMapper.getUserIdsByTenantId(tenantId);
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package org.jeecg.modules.system.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
|
@ -1384,7 +1386,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||
* 保存用户职位
|
||||
*
|
||||
* @param userId
|
||||
* @param postIds
|
||||
* @param positionIds
|
||||
*/
|
||||
private void saveUserPosition(String userId, String positionIds) {
|
||||
if (oConvertUtils.isNotEmpty(positionIds)) {
|
||||
|
@ -1802,5 +1804,15 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||
//update-end---author:wangshuai ---date:20230710 for:【QQYUN-5731】导入用户时,没有提醒------------
|
||||
}
|
||||
//======================================= end 用户与部门 用户列表导入 =========================================
|
||||
|
||||
@Override
|
||||
public void checkUserAdminRejectDel(String userIds) {
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
|
||||
query.in(SysUser::getId,Arrays.asList(userIds.split(SymbolConstant.COMMA)));
|
||||
query.eq(SysUser::getUsername,"admin");
|
||||
Long adminRoleCount = this.baseMapper.selectCount(query);
|
||||
//大于0说明存在管理员用户,不允许删除
|
||||
if(adminRoleCount>0){
|
||||
throw new JeecgBootException("admin用户,不允许删除!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package org.jeecg.modules.system.util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.system.entity.SysPermission;
|
||||
import org.jeecg.modules.system.entity.SysRoleIndex;
|
||||
import org.jeecg.modules.system.service.ISysRoleIndexService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: scott
|
||||
|
@ -82,8 +85,9 @@ public class PermissionDataUtil {
|
|||
*/
|
||||
public static void addIndexPage(List<SysPermission> metaList) {
|
||||
boolean hasIndexMenu = false;
|
||||
SysRoleIndex defIndexCfg = PermissionDataUtil.getDefIndexConfig();
|
||||
for (SysPermission sysPermission : metaList) {
|
||||
if("首页".equals(sysPermission.getName())) {
|
||||
if(defIndexCfg.getUrl().equals(sysPermission.getUrl())) {
|
||||
hasIndexMenu = true;
|
||||
break;
|
||||
}
|
||||
|
@ -98,15 +102,38 @@ public class PermissionDataUtil {
|
|||
* @param metaList
|
||||
* @return
|
||||
*/
|
||||
public static boolean hasIndexPage(List<SysPermission> metaList){
|
||||
public static boolean hasIndexPage(List<SysPermission> metaList, SysRoleIndex defIndexCfg){
|
||||
boolean hasIndexMenu = false;
|
||||
for (SysPermission sysPermission : metaList) {
|
||||
if("首页".equals(sysPermission.getName())) {
|
||||
if(defIndexCfg.getUrl().equals(sysPermission.getUrl())) {
|
||||
hasIndexMenu = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return hasIndexMenu;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过id判断是否授权某个页面
|
||||
*
|
||||
* @param metaList
|
||||
* @return
|
||||
*/
|
||||
public static boolean hasMenuById(List<SysPermission> metaList, String id) {
|
||||
for (SysPermission sysPermission : metaList) {
|
||||
if (id.equals(sysPermission.getId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认首页配置
|
||||
*/
|
||||
public static SysRoleIndex getDefIndexConfig() {
|
||||
ISysRoleIndexService sysRoleIndexService = SpringContextUtils.getBean(ISysRoleIndexService.class);
|
||||
return sysRoleIndexService.queryDefaultIndex();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
package org.jeecg.modules.system.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
* @author: wangshuai
|
||||
* @date: 2022年09月27日 20:56
|
||||
*/
|
||||
@Data
|
||||
public class SysFileLogVo {
|
||||
/**
|
||||
* 文件id
|
||||
*/
|
||||
private String fileId;
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private String userId;
|
||||
/**
|
||||
* 日志内容
|
||||
*/
|
||||
private String dataContent;
|
||||
/**
|
||||
* 真实姓名
|
||||
*/
|
||||
private String realname;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 日志创建时间
|
||||
*/
|
||||
private String createTime;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
private String fileName;
|
||||
|
||||
/**
|
||||
* 路径
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 是否为文件夹
|
||||
*/
|
||||
private String izFolder;
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
package org.jeecg.modules.system.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Description:
|
||||
* @author: wangshuai
|
||||
* @date: 2022年09月21日 17:27
|
||||
*/
|
||||
@Data
|
||||
public class SysFilesVo {
|
||||
/**
|
||||
* 需要复制的文件夹或者文件id
|
||||
*/
|
||||
private String fileId;
|
||||
|
||||
/**
|
||||
* 需要复制到哪个文件夹下的id
|
||||
*/
|
||||
private String copyToFileId;
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 委托人的用户id
|
||||
*/
|
||||
private String msgTo;
|
||||
|
||||
/**
|
||||
* 权限
|
||||
*/
|
||||
private String authority;
|
||||
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
private String fileName;
|
||||
|
||||
|
||||
/**
|
||||
* 删除状态
|
||||
*/
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 文件大小
|
||||
*/
|
||||
private Double fileSize;
|
||||
|
||||
/**
|
||||
* 文件路径
|
||||
*/
|
||||
private String fileUrl;
|
||||
|
||||
/**
|
||||
* 说明(添加到系统日志)
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private String createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private String updateTime;
|
||||
|
||||
/**
|
||||
* 下载数
|
||||
*/
|
||||
private String downCount;
|
||||
|
||||
/**
|
||||
* 阅读数
|
||||
*/
|
||||
private String readCount;
|
||||
|
||||
/**
|
||||
* 父id
|
||||
*/
|
||||
private String parentId;
|
||||
|
||||
/**
|
||||
* 分享地址
|
||||
*/
|
||||
private String shareUrl;
|
||||
|
||||
/**
|
||||
* 是否允许下载(1:是 0:否)
|
||||
*/
|
||||
private String enableDown;
|
||||
|
||||
/**
|
||||
* 分享权限(1.关闭分享 2.允许所有联系人查看 3.允许任何人查看)
|
||||
*/
|
||||
private String sharePerms;
|
||||
|
||||
/**
|
||||
* 是否允许修改(1:是 0:否)
|
||||
*/
|
||||
private String enableUpdat;
|
||||
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 真实姓名
|
||||
*/
|
||||
private String realname;
|
||||
|
||||
/**
|
||||
* 权限方式(enableDown:下载,enableUpdat:修改,sharePerms:分享权限,reduction:还原,rename:重命名,newFile:上传新版本)
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 最上级的id
|
||||
*/
|
||||
private String rootId;
|
||||
|
||||
/**
|
||||
* 是否为文件夹(0否 1是)
|
||||
*/
|
||||
private String izFolder;
|
||||
|
||||
/**
|
||||
* 是否为一级文件夹(0否 1是)
|
||||
*/
|
||||
private String izRootFolder;
|
||||
}
|
|
@ -132,8 +132,14 @@
|
|||
function edit(record) {
|
||||
nextTick(() => {
|
||||
resetFields();
|
||||
const tmpData = {};
|
||||
Object.keys(formData).forEach((key) => {
|
||||
if(record.hasOwnProperty(key)){
|
||||
tmpData[key] = record[key]
|
||||
}
|
||||
})
|
||||
//赋值
|
||||
Object.assign(formData, record);
|
||||
Object.assign(formData, tmpData);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -157,9 +157,15 @@
|
|||
resetFields();
|
||||
expandedRowKeys.value = [];
|
||||
treeData.value = await loadTreeData({ async: false, pcode: '' });
|
||||
const tmpData = {};
|
||||
Object.keys(formData).forEach((key) => {
|
||||
if(record.hasOwnProperty(key)){
|
||||
tmpData[key] = record[key]
|
||||
}
|
||||
})
|
||||
//赋值
|
||||
Object.assign(formData, record);
|
||||
model = record
|
||||
Object.assign(formData,tmpData);
|
||||
model = tmpData
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -131,8 +131,14 @@
|
|||
function edit(record) {
|
||||
nextTick(() => {
|
||||
resetFields();
|
||||
const tmpData = {};
|
||||
Object.keys(formData).forEach((key) => {
|
||||
if(record.hasOwnProperty(key)){
|
||||
tmpData[key] = record[key]
|
||||
}
|
||||
})
|
||||
//赋值
|
||||
Object.assign(formData, record);
|
||||
Object.assign(formData,tmpData);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -100,8 +100,14 @@
|
|||
function edit(record) {
|
||||
nextTick(() => {
|
||||
resetFields();
|
||||
const tmpData = {};
|
||||
Object.keys(formData).forEach((key) => {
|
||||
if(record.hasOwnProperty(key)){
|
||||
tmpData[key] = record[key]
|
||||
}
|
||||
})
|
||||
//赋值
|
||||
Object.assign(formData, record);
|
||||
Object.assign(formData,tmpData);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -241,9 +241,14 @@
|
|||
|
||||
async function queryMainData(id) {
|
||||
const row = await queryDataById(id);
|
||||
Object.keys(row).map(k => {
|
||||
formData[k] = row[k];
|
||||
});
|
||||
const tmpData = {};
|
||||
Object.keys(formData).forEach((key) => {
|
||||
if(row.hasOwnProperty(key)){
|
||||
tmpData[key] = row[key]
|
||||
}
|
||||
})
|
||||
//赋值
|
||||
Object.assign(formData,tmpData);
|
||||
}
|
||||
|
||||
const {getSubFormAndTableData, transformData} = useValidateAntFormAndTable(activeKey, {
|
||||
|
|
|
@ -93,15 +93,20 @@
|
|||
|
||||
async function initFormData(mainId) {
|
||||
resetFields();
|
||||
let tmpData = {}
|
||||
if(mainId){
|
||||
let list = await query${sub.entityName}ListByMainId(mainId);
|
||||
if(list && list.length>0){
|
||||
let temp = list[0];
|
||||
Object.keys(temp).map(k=>{
|
||||
formData[k] = temp[k];
|
||||
Object.keys(formData).forEach((key) => {
|
||||
if(temp.hasOwnProperty(key)){
|
||||
tmpData[key] = temp[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
//赋值
|
||||
Object.assign(formData,tmpData);
|
||||
}
|
||||
|
||||
async function getFormData() {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue