diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/init/SystemInitListener.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/init/SystemInitListener.java index 40c6188..5862ea9 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/init/SystemInitListener.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/config/init/SystemInitListener.java @@ -28,7 +28,8 @@ public class SystemInitListener implements ApplicationListener<ApplicationReadyE public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { log.info(" 服务已启动,初始化路由配置 ###################"); - if (applicationReadyEvent.getApplicationContext().getDisplayName().indexOf("AnnotationConfigServletWebServerApplicationContext") > -1) { + String context = "AnnotationConfigServletWebServerApplicationContext"; + if (applicationReadyEvent.getApplicationContext().getDisplayName().indexOf(context) > -1) { sysGatewayRouteService.addRoute2Redis(CacheConstant.GATEWAY_ROUTES); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/controller/SystemApiController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/controller/SystemApiController.java new file mode 100644 index 0000000..832d73a --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/api/controller/SystemApiController.java @@ -0,0 +1,663 @@ +package org.jeecg.modules.api.controller; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.api.dto.OnlineAuthDTO; +import org.jeecg.common.api.dto.message.*; +import org.jeecg.common.system.vo.*; +import org.jeecg.modules.system.service.ISysUserService; +import org.jeecg.modules.system.service.impl.SysBaseApiImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; +import java.util.Set; + + +/** + * 服务化 system模块 对外接口请求类 + * @author: jeecg-boot + */ +@Slf4j +@RestController +@RequestMapping("/sys/api") +public class SystemApiController { + + @Autowired + private SysBaseApiImpl sysBaseApi; + @Autowired + private ISysUserService sysUserService; + + + /** + * 发送系统消息 + * @param message 使用构造器赋值参数 如果不设置category(消息类型)则默认为2 发送系统消息 + */ + @PostMapping("/sendSysAnnouncement") + public void sendSysAnnouncement(@RequestBody MessageDTO message){ + sysBaseApi.sendSysAnnouncement(message); + } + + /** + * 发送消息 附带业务参数 + * @param message 使用构造器赋值参数 + */ + @PostMapping("/sendBusAnnouncement") + public void sendBusAnnouncement(@RequestBody BusMessageDTO message){ + sysBaseApi.sendBusAnnouncement(message); + } + + /** + * 通过模板发送消息 + * @param message 使用构造器赋值参数 + */ + @PostMapping("/sendTemplateAnnouncement") + public void sendTemplateAnnouncement(@RequestBody TemplateMessageDTO message){ + sysBaseApi.sendTemplateAnnouncement(message); + } + + /** + * 通过模板发送消息 附带业务参数 + * @param message 使用构造器赋值参数 + */ + @PostMapping("/sendBusTemplateAnnouncement") + public void sendBusTemplateAnnouncement(@RequestBody BusTemplateMessageDTO message){ + sysBaseApi.sendBusTemplateAnnouncement(message); + } + + /** + * 通过消息中心模板,生成推送内容 + * @param templateDTO 使用构造器赋值参数 + * @return + */ + @PostMapping("/parseTemplateByCode") + public String parseTemplateByCode(@RequestBody TemplateDTO templateDTO){ + return sysBaseApi.parseTemplateByCode(templateDTO); + } + + /** + * 根据业务类型busType及业务busId修改消息已读 + */ + @GetMapping("/updateSysAnnounReadFlag") + public void updateSysAnnounReadFlag(@RequestParam("busType") String busType, @RequestParam("busId")String busId){ + sysBaseApi.updateSysAnnounReadFlag(busType, busId); + } + + /** + * 根据用户账号查询用户信息 + * @param username + * @return + */ + @GetMapping("/getUserByName") + public LoginUser getUserByName(@RequestParam("username") String username){ + return sysBaseApi.getUserByName(username); + } + + /** + * 根据用户id查询用户信息 + * @param id + * @return + */ + @GetMapping("/getUserById") + LoginUser getUserById(@RequestParam("id") String id){ + return sysBaseApi.getUserById(id); + } + + /** + * 通过用户账号查询角色集合 + * @param username + * @return + */ + @GetMapping("/getRolesByUsername") + List<String> getRolesByUsername(@RequestParam("username") String username){ + return sysBaseApi.getRolesByUsername(username); + } + + /** + * 通过用户账号查询部门集合 + * @param username + * @return 部门 id + */ + @GetMapping("/getDepartIdsByUsername") + List<String> getDepartIdsByUsername(@RequestParam("username") String username){ + return sysBaseApi.getDepartIdsByUsername(username); + } + + /** + * 通过用户账号查询部门 name + * @param username + * @return 部门 name + */ + @GetMapping("/getDepartNamesByUsername") + List<String> getDepartNamesByUsername(@RequestParam("username") String username){ + return sysBaseApi.getDepartNamesByUsername(username); + } + + + /** + * 获取数据字典 + * @param code + * @return + */ + @GetMapping("/queryDictItemsByCode") + List<DictModel> queryDictItemsByCode(@RequestParam("code") String code){ + return sysBaseApi.queryDictItemsByCode(code); + } + + /** + * 获取有效的数据字典 + * @param code + * @return + */ + @GetMapping("/queryEnableDictItemsByCode") + List<DictModel> queryEnableDictItemsByCode(@RequestParam("code") String code){ + return sysBaseApi.queryEnableDictItemsByCode(code); + } + + + /** 查询所有的父级字典,按照create_time排序 */ + @GetMapping("/queryAllDict") + List<DictModel> queryAllDict(){ +// try{ +// //睡10秒,gateway网关5秒超时,会触发熔断降级操作 +// Thread.sleep(10000); +// }catch (Exception e){ +// e.printStackTrace(); +// } + + log.info("--我是jeecg-system服务节点,微服务接口queryAllDict被调用--"); + return sysBaseApi.queryAllDict(); + } + + /** + * 查询所有分类字典 + * @return + */ + @GetMapping("/queryAllSysCategory") + List<SysCategoryModel> queryAllSysCategory(){ + return sysBaseApi.queryAllSysCategory(); + } + + + /** + * 查询所有部门 作为字典信息 id -->value,departName -->text + * @return + */ + @GetMapping("/queryAllDepartBackDictModel") + List<DictModel> queryAllDepartBackDictModel(){ + return sysBaseApi.queryAllDepartBackDictModel(); + } + + /** + * 获取所有角色 带参 + * roleIds 默认选中角色 + * @return + */ + @GetMapping("/queryAllRole") + public List<ComboModel> queryAllRole(@RequestParam(name = "roleIds",required = false)String[] roleIds){ + if(roleIds==null || roleIds.length==0){ + return sysBaseApi.queryAllRole(); + }else{ + return sysBaseApi.queryAllRole(roleIds); + } + } + + /** + * 通过用户账号查询角色Id集合 + * @param username + * @return + */ + @GetMapping("/getRoleIdsByUsername") + public List<String> getRoleIdsByUsername(@RequestParam("username")String username){ + return sysBaseApi.getRoleIdsByUsername(username); + } + + /** + * 通过部门编号查询部门id + * @param orgCode + * @return + */ + @GetMapping("/getDepartIdsByOrgCode") + public String getDepartIdsByOrgCode(@RequestParam("orgCode")String orgCode){ + return sysBaseApi.getDepartIdsByOrgCode(orgCode); + } + + /** + * 查询所有部门 + * @return + */ + @GetMapping("/getAllSysDepart") + public List<SysDepartModel> getAllSysDepart(){ + return sysBaseApi.getAllSysDepart(); + } + + /** + * 根据 id 查询数据库中存储的 DynamicDataSourceModel + * + * @param dbSourceId + * @return + */ + @GetMapping("/getDynamicDbSourceById") + DynamicDataSourceModel getDynamicDbSourceById(@RequestParam("dbSourceId")String dbSourceId){ + return sysBaseApi.getDynamicDbSourceById(dbSourceId); + } + + + + /** + * 根据部门Id获取部门负责人 + * @param deptId + * @return + */ + @GetMapping("/getDeptHeadByDepId") + public List<String> getDeptHeadByDepId(@RequestParam("deptId") String deptId){ + return sysBaseApi.getDeptHeadByDepId(deptId); + } + + /** + * 查找父级部门 + * @param departId + * @return + */ + @GetMapping("/getParentDepartId") + public DictModel getParentDepartId(@RequestParam("departId")String departId){ + return sysBaseApi.getParentDepartId(departId); + } + + /** + * 根据 code 查询数据库中存储的 DynamicDataSourceModel + * + * @param dbSourceCode + * @return + */ + @GetMapping("/getDynamicDbSourceByCode") + public DynamicDataSourceModel getDynamicDbSourceByCode(@RequestParam("dbSourceCode") String dbSourceCode){ + return sysBaseApi.getDynamicDbSourceByCode(dbSourceCode); + } + + /** + * 给指定用户发消息 + * @param userIds + * @param cmd + */ + @GetMapping("/sendWebSocketMsg") + public void sendWebSocketMsg(String[] userIds, String cmd){ + sysBaseApi.sendWebSocketMsg(userIds, cmd); + } + + + /** + * 根据id获取所有参与用户 + * userIds + * @return + */ + @GetMapping("/queryAllUserByIds") + public List<LoginUser> queryAllUserByIds(@RequestParam("userIds") String[] userIds){ + return sysBaseApi.queryAllUserByIds(userIds); + } + + /** + * 查询所有用户 返回ComboModel + * @return + */ + @GetMapping("/queryAllUserBackCombo") + public List<ComboModel> queryAllUserBackCombo(){ + return sysBaseApi.queryAllUserBackCombo(); + } + + /** + * 分页查询用户 返回JSONObject + * @return + */ + @GetMapping("/queryAllUser") + public JSONObject queryAllUser(@RequestParam(name="userIds",required=false)String userIds, @RequestParam(name="pageNo",required=false) Integer pageNo,@RequestParam(name="pageSize",required=false) int pageSize){ + return sysBaseApi.queryAllUser(userIds, pageNo, pageSize); + } + + + + /** + * 将会议签到信息推动到预览 + * userIds + * @return + * @param userId + */ + @GetMapping("/meetingSignWebsocket") + public void meetingSignWebsocket(@RequestParam("userId")String userId){ + sysBaseApi.meetingSignWebsocket(userId); + } + + /** + * 根据name获取所有参与用户 + * userNames + * @return + */ + @GetMapping("/queryUserByNames") + public List<LoginUser> queryUserByNames(@RequestParam("userNames")String[] userNames){ + return sysBaseApi.queryUserByNames(userNames); + } + + /** + * 获取用户的角色集合 + * @param username + * @return + */ + @GetMapping("/getUserRoleSet") + public Set<String> getUserRoleSet(@RequestParam("username")String username){ + return sysBaseApi.getUserRoleSet(username); + } + + /** + * 获取用户的权限集合 + * @param username + * @return + */ + @GetMapping("/getUserPermissionSet") + public Set<String> getUserPermissionSet(@RequestParam("username") String username){ + return sysBaseApi.getUserPermissionSet(username); + } + + //----- + + /** + * 判断是否有online访问的权限 + * @param onlineAuthDTO + * @return + */ + @PostMapping("/hasOnlineAuth") + public boolean hasOnlineAuth(@RequestBody OnlineAuthDTO onlineAuthDTO){ + return sysBaseApi.hasOnlineAuth(onlineAuthDTO); + } + + /** + * 查询用户角色信息 + * @param username + * @return + */ + @GetMapping("/queryUserRoles") + public Set<String> queryUserRoles(@RequestParam("username") String username){ + return sysUserService.getUserRolesSet(username); + } + + + /** + * 查询用户权限信息 + * @param username + * @return + */ + @GetMapping("/queryUserAuths") + public Set<String> queryUserAuths(@RequestParam("username") String username){ + return sysUserService.getUserPermissionsSet(username); + } + + /** + * 通过部门id获取部门全部信息 + */ + @GetMapping("/selectAllById") + public SysDepartModel selectAllById(@RequestParam("id") String id){ + return sysBaseApi.selectAllById(id); + } + + /** + * 根据用户id查询用户所属公司下所有用户ids + * @param userId + * @return + */ + @GetMapping("/queryDeptUsersByUserId") + public List<String> queryDeptUsersByUserId(@RequestParam("userId") String userId){ + return sysBaseApi.queryDeptUsersByUserId(userId); + } + + + /** + * 查询数据权限 + * @return + */ + @GetMapping("/queryPermissionDataRule") + public List<SysPermissionDataRuleModel> queryPermissionDataRule(@RequestParam("component") String component, @RequestParam("requestPath")String requestPath, @RequestParam("username") String username){ + return sysBaseApi.queryPermissionDataRule(component, requestPath, username); + } + + /** + * 查询用户信息 + * @param username + * @return + */ + @GetMapping("/getCacheUser") + public SysUserCacheInfo getCacheUser(@RequestParam("username") String username){ + return sysBaseApi.getCacheUser(username); + } + + /** + * 普通字典的翻译 + * @param code + * @param key + * @return + */ + @GetMapping("/translateDict") + public String translateDict(@RequestParam("code") String code, @RequestParam("key") String key){ + return sysBaseApi.translateDict(code, key); + } + + + /** + * 36根据多个用户账号(逗号分隔),查询返回多个用户信息 + * @param usernames + * @return + */ + @RequestMapping("/queryUsersByUsernames") + List<JSONObject> queryUsersByUsernames(@RequestParam("usernames") String usernames){ + return this.sysBaseApi.queryUsersByUsernames(usernames); + } + + /** + * 37根据多个用户id(逗号分隔),查询返回多个用户信息 + * @param ids + * @return + */ + @RequestMapping("/queryUsersByIds") + List<JSONObject> queryUsersByIds(@RequestParam("ids") String ids){ + return this.sysBaseApi.queryUsersByIds(ids); + } + + /** + * 38根据多个部门编码(逗号分隔),查询返回多个部门信息 + * @param orgCodes + * @return + */ + @GetMapping("/queryDepartsByOrgcodes") + List<JSONObject> queryDepartsByOrgcodes(@RequestParam("orgCodes") String orgCodes){ + return this.sysBaseApi.queryDepartsByOrgcodes(orgCodes); + } + + /** + * 39根据多个部门ID(逗号分隔),查询返回多个部门信息 + * @param ids + * @return + */ + @GetMapping("/queryDepartsByIds") + List<JSONObject> queryDepartsByIds(@RequestParam("ids") String ids){ + return this.sysBaseApi.queryDepartsByIds(ids); + } + + /** + * 40发送邮件消息 + * @param email + * @param title + * @param content + */ + @GetMapping("/sendEmailMsg") + public void sendEmailMsg(@RequestParam("email")String email,@RequestParam("title")String title,@RequestParam("content")String content){ + this.sysBaseApi.sendEmailMsg(email,title,content); + }; + /** + * 41 获取公司下级部门和公司下所有用户信息 + * @param orgCode + */ + @GetMapping("/getDeptUserByOrgCode") + List<Map> getDeptUserByOrgCode(@RequestParam("orgCode")String orgCode){ + return this.sysBaseApi.getDeptUserByOrgCode(orgCode); + } + + /** + * 查询分类字典翻译 + * + * @param ids 分类字典表id + * @return + */ + @GetMapping("/loadCategoryDictItem") + public List<String> loadCategoryDictItem(@RequestParam("ids") String ids) { + return sysBaseApi.loadCategoryDictItem(ids); + } + + /** + * 根据字典code加载字典text + * + * @param dictCode 顺序:tableName,text,code + * @param keys 要查询的key + * @return + */ + @GetMapping("/loadDictItem") + public List<String> loadDictItem(@RequestParam("dictCode") String dictCode, @RequestParam("keys") String keys) { + return sysBaseApi.loadDictItem(dictCode, keys); + } + + /** + * 根据字典code查询字典项 + * + * @param dictCode 顺序:tableName,text,code + * @param dictCode 要查询的key + * @return + */ + @GetMapping("/getDictItems") + public List<DictModel> getDictItems(@RequestParam("dictCode") String dictCode) { + return sysBaseApi.getDictItems(dictCode); + } + + /** + * 根据多个字典code查询多个字典项 + * + * @param dictCodeList + * @return key = dictCode ; value=对应的字典项 + */ + @RequestMapping("/getManyDictItems") + public Map<String, List<DictModel>> getManyDictItems(@RequestParam("dictCodeList") List<String> dictCodeList) { + return sysBaseApi.getManyDictItems(dictCodeList); + } + + /** + * 【下拉搜索】 + * 大数据量的字典表 走异步加载,即前端输入内容过滤数据 + * + * @param dictCode 字典code格式:table,text,code + * @param keyword 过滤关键字 + * @return + */ + @GetMapping("/loadDictItemByKeyword") + public List<DictModel> loadDictItemByKeyword(@RequestParam("dictCode") String dictCode, @RequestParam("keyword") String keyword, @RequestParam(value = "pageSize", required = false) Integer pageSize) { + return sysBaseApi.loadDictItemByKeyword(dictCode, keyword, pageSize); + } + + /** + * 48 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割 + * @param dictCodes + * @param keys + * @return + */ + @GetMapping("/translateManyDict") + public Map<String, List<DictModel>> translateManyDict(@RequestParam("dictCodes") String dictCodes, @RequestParam("keys") String keys){ + return this.sysBaseApi.translateManyDict(dictCodes, keys); + } + + + /** + * 获取表数据字典 【接口签名验证】 + * @param table + * @param text + * @param code + * @return + */ + @GetMapping("/queryTableDictItemsByCode") + List<DictModel> queryTableDictItemsByCode(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code){ + return sysBaseApi.queryTableDictItemsByCode(table, text, code); + } + + /** + * 查询表字典 支持过滤数据 【接口签名验证】 + * @param table + * @param text + * @param code + * @param filterSql + * @return + */ + @GetMapping("/queryFilterTableDictInfo") + List<DictModel> queryFilterTableDictInfo(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("filterSql") String filterSql){ + return sysBaseApi.queryFilterTableDictInfo(table, text, code, filterSql); + } + + /** + * 【接口签名验证】 + * 查询指定table的 text code 获取字典,包含text和value + * @param table + * @param text + * @param code + * @param keyArray + * @return + */ + @Deprecated + @GetMapping("/queryTableDictByKeys") + public List<String> queryTableDictByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keyArray") String[] keyArray){ + return sysBaseApi.queryTableDictByKeys(table, text, code, keyArray); + } + + + /** + * 字典表的 翻译【接口签名验证】 + * @param table + * @param text + * @param code + * @param key + * @return + */ + @GetMapping("/translateDictFromTable") + public String translateDictFromTable(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("key") String key){ + return sysBaseApi.translateDictFromTable(table, text, code, key); + } + + + /** + * 【接口签名验证】 + * 49 字典表的 翻译,可批量 + * + * @param table + * @param text + * @param code + * @param keys 多个用逗号分割 + * @return + */ + @GetMapping("/translateDictFromTableByKeys") + public List<DictModel> translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys) { + return this.sysBaseApi.translateDictFromTableByKeys(table, text, code, keys); + } + + /** + * 发送模板信息 + * @param message + */ + @PostMapping("/sendTemplateMessage") + public void sendTemplateMessage(@RequestBody MessageDTO message){ + sysBaseApi.sendTemplateMessage(message); + } + + /** + * 获取消息模板内容 + * @param code + * @return + */ + @GetMapping("/getTemplateContent") + public String getTemplateContent(@RequestParam("code") String code){ + return this.sysBaseApi.getTemplateContent(code); + } + +} diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/controller/CasClientController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/controller/CasClientController.java index 4da744a..4b271a6 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/controller/CasClientController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/controller/CasClientController.java @@ -5,21 +5,17 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import cn.hutool.crypto.SecureUtil; import org.apache.commons.lang.StringUtils; import org.jeecg.common.api.vo.Result; -import org.jeecg.common.constant.CacheConstant; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.system.util.JwtUtil; -import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.RedisUtil; -import org.jeecg.modules.cas.util.CASServiceUtil; +import org.jeecg.modules.cas.util.CasServiceUtil; import org.jeecg.modules.cas.util.XmlUtils; import org.jeecg.modules.system.entity.SysDepart; import org.jeecg.modules.system.entity.SysUser; import org.jeecg.modules.system.service.ISysDepartService; import org.jeecg.modules.system.service.ISysUserService; -import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; @@ -65,7 +61,7 @@ public class CasClientController { log.info("Rest api login."); try { String validateUrl = prefixUrl+"/p3/serviceValidate"; - String res = CASServiceUtil.getSTValidate(validateUrl, ticket, service); + String res = CasServiceUtil.getStValidate(validateUrl, ticket, service); log.info("res."+res); final String error = XmlUtils.getTextForElement(res, "authenticationFailure"); if(StringUtils.isNotEmpty(error)) { diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/util/CasServiceUtil.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/util/CasServiceUtil.java new file mode 100644 index 0000000..12fcec1 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/util/CasServiceUtil.java @@ -0,0 +1,107 @@ +package org.jeecg.modules.cas.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.security.cert.X509Certificate; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.conn.socket.LayeredConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; + +/** + * @Description: CasServiceUtil + * @author: jeecg-boot + */ +public class CasServiceUtil { + + public static void main(String[] args) { + String serviceUrl = "https://cas.8f8.com.cn:8443/cas/p3/serviceValidate"; + String service = "http://localhost:3003/user/login"; + String ticket = "ST-5-1g-9cNES6KXNRwq-GuRET103sm0-DESKTOP-VKLS8B3"; + String res = getStValidate(serviceUrl,ticket, service); + + System.out.println("---------res-----"+res); + } + + + /** + * 验证ST + */ + public static String getStValidate(String url, String st, String service){ + try { + url = url+"?service="+service+"&ticket="+st; + CloseableHttpClient httpclient = createHttpClientWithNoSsl(); + HttpGet httpget = new HttpGet(url); + HttpResponse response = httpclient.execute(httpget); + String res = readResponse(response); + return res == null ? null : (res == "" ? null : res); + } catch (Exception e) { + e.printStackTrace(); + } + return ""; + } + + + /** + * 读取 response body 内容为字符串 + * + * @param response + * @return + * @throws IOException + */ + private static String readResponse(HttpResponse response) throws IOException { + BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); + String result = new String(); + String line; + while ((line = in.readLine()) != null) { + result += line; + } + return result; + } + + + /** + * 创建模拟客户端(针对 https 客户端禁用 SSL 验证) + * + * @param cookieStore 缓存的 Cookies 信息 + * @return + * @throws Exception + */ + private static CloseableHttpClient createHttpClientWithNoSsl() throws Exception { + // Create a trust manager that does not validate certificate chains + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkClientTrusted(X509Certificate[] certs, String authType) { + // don't check + } + + @Override + public void checkServerTrusted(X509Certificate[] certs, String authType) { + // don't check + } + } + }; + + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(null, trustAllCerts, null); + LayeredConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(ctx); + return HttpClients.custom() + .setSSLSocketFactory(sslSocketFactory) + .build(); + } + +} diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/util/XmlUtils.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/util/XmlUtils.java index bcd7d64..408a100 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/util/XmlUtils.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/cas/util/XmlUtils.java @@ -14,6 +14,7 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import org.jeecg.common.constant.CommonConstant; import org.w3c.dom.Document; import org.xml.sax.Attributes; import org.xml.sax.InputSource; @@ -31,6 +32,11 @@ import lombok.extern.slf4j.Slf4j; public final class XmlUtils { /** + * attributes + */ + private static final String ATTRIBUTES = "attributes"; + + /** * Creates a new namespace-aware DOM document object by parsing the given XML. * * @param xml XML content. @@ -218,9 +224,9 @@ public final class XmlUtils { } @Override - public void startElement(final String namespaceURI, final String localName, final String qName, - final Attributes attributes) throws SAXException { - if ("attributes".equals(localName)) { + public void startElement(final String nameSpaceUri, final String localName, final String qName, + final Attributes attributes) throws SAXException { + if (ATTRIBUTES.equals(localName)) { this.foundAttributes = true; } else if (this.foundAttributes) { this.value = new StringBuilder(); @@ -236,9 +242,9 @@ public final class XmlUtils { } @Override - public void endElement(final String namespaceURI, final String localName, final String qName) + public void endElement(final String nameSpaceUri, final String localName, final String qName) throws SAXException { - if ("attributes".equals(localName)) { + if (ATTRIBUTES.equals(localName)) { this.foundAttributes = false; this.currentAttribute = null; } else if (this.foundAttributes) { diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/controller/SysMessageTemplateController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/controller/SysMessageTemplateController.java index ec1ce07..3325b88 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/controller/SysMessageTemplateController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/controller/SysMessageTemplateController.java @@ -6,9 +6,12 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.jeecg.common.api.dto.message.MessageDTO; import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.system.base.controller.JeecgController; import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.message.entity.MsgParams; import org.jeecg.modules.message.entity.SysMessageTemplate; import org.jeecg.modules.message.service.ISysMessageTemplateService; @@ -46,6 +49,9 @@ public class SysMessageTemplateController extends JeecgController<SysMessageTemp @Autowired private PushMsgUtil pushMsgUtil; + @Autowired + private ISysBaseAPI sysBaseApi; + /** * 分页列表查询 * @@ -152,19 +158,23 @@ public class SysMessageTemplateController extends JeecgController<SysMessageTemp @PostMapping(value = "/sendMsg") public Result<SysMessageTemplate> sendMessage(@RequestBody MsgParams msgParams) { Result<SysMessageTemplate> result = new Result<SysMessageTemplate>(); - Map<String, String> map = null; try { - map = (Map<String, String>) JSON.parse(msgParams.getTestData()); + MessageDTO md = new MessageDTO(); + md.setToAll(false); + md.setTitle("消息发送测试"); + md.setTemplateCode(msgParams.getTemplateCode()); + md.setToUser(msgParams.getReceiver()); + md.setType(msgParams.getMsgType()); + String testData = msgParams.getTestData(); + if(oConvertUtils.isNotEmpty(testData)){ + Map<String, Object> data = JSON.parseObject(testData, Map.class); + md.setData(data); + } + sysBaseApi.sendTemplateMessage(md); + return result.success("消息发送成功!"); } catch (Exception e) { - result.error500("解析Json出错!"); - return result; - } - boolean is_sendSuccess = pushMsgUtil.sendMessage(msgParams.getMsgType(), msgParams.getTemplateCode(), map, msgParams.getReceiver()); - if (is_sendSuccess) { - result.success("发送消息任务添加成功!"); - } else { - result.error500("发送消息任务添加失败!"); + log.error("发送消息出错", e.getMessage()); + return result.error500("发送消息出错!"); } - return result; } } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/entity/SysMessage.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/entity/SysMessage.java index 9faa53e..f3555e3 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/entity/SysMessage.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/entity/SysMessage.java @@ -50,9 +50,11 @@ public class SysMessage extends JeecgEntity { /**消息标题*/ @Excel(name = "消息标题", width = 15) private java.lang.String esTitle; - /**推送方式:1短信 2邮件 3微信*/ - @Excel(name = "推送方式:1短信 2邮件 3微信", width = 15) - @Dict(dicCode = "msgType") + /** + * 推送方式:参考枚举类MessageTypeEnum + */ + @Excel(name = "推送方式", width = 15) + @Dict(dicCode = "messageType") private java.lang.String esType; /**备注*/ @Excel(name = "备注", width = 15) diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/entity/SysMessageTemplate.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/entity/SysMessageTemplate.java index 929937a..1ea966e 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/entity/SysMessageTemplate.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/entity/SysMessageTemplate.java @@ -35,4 +35,9 @@ public class SysMessageTemplate extends JeecgEntity{ /**模板类型*/ @Excel(name = "模板类型", width = 15) private java.lang.String templateType; + + /**已经应用/未应用 1是0否*/ + @Excel(name = "应用状态", width = 15) + private String useStatus; + } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/ISendMsgHandle.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/ISendMsgHandle.java index 1be8274..a58300c 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/ISendMsgHandle.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/ISendMsgHandle.java @@ -1,5 +1,7 @@ package org.jeecg.modules.message.handle; +import org.jeecg.common.api.dto.message.MessageDTO; + /** * @Description: 发送信息接口 * @author: jeecg-boot @@ -8,9 +10,17 @@ public interface ISendMsgHandle { /** * 发送信息 - * @param es_receiver 发送人 - * @param es_title 标题 - * @param es_content 内容 + * @param esReceiver 发送人 + * @param esTitle 标题 + * @param esContent 内容 + */ + void sendMsg(String esReceiver, String esTitle, String esContent); + + /** + * 发送信息 + * @param messageDTO */ - void SendMsg(String es_receiver, String es_title, String es_content); + default void sendMessage(MessageDTO messageDTO){ + + } } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/DdSendMsgHandle.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/DdSendMsgHandle.java new file mode 100644 index 0000000..e6741de --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/DdSendMsgHandle.java @@ -0,0 +1,37 @@ +package org.jeecg.modules.message.handle.impl; + +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.api.dto.message.MessageDTO; +import org.jeecg.modules.message.handle.ISendMsgHandle; +import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @Description: 发钉钉消息模板 + * @author: jeecg-boot + */ +@Slf4j +@Component("ddSendMsgHandle") +public class DdSendMsgHandle implements ISendMsgHandle { + + @Autowired + private ThirdAppDingtalkServiceImpl dingtalkService; + + @Override + public void sendMsg(String esReceiver, String esTitle, String esContent) { + log.info("发微信消息模板"); + MessageDTO messageDTO = new MessageDTO(); + messageDTO.setToUser(esReceiver); + messageDTO.setTitle(esTitle); + messageDTO.setContent(esContent); + messageDTO.setToAll(false); + sendMessage(messageDTO); + } + + @Override + public void sendMessage(MessageDTO messageDTO) { + dingtalkService.sendMessage(messageDTO, true); + } + +} diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/EmailSendMsgHandle.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/EmailSendMsgHandle.java index 92addb1..828d878 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/EmailSendMsgHandle.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/EmailSendMsgHandle.java @@ -1,20 +1,34 @@ package org.jeecg.modules.message.handle.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.api.dto.message.MessageDTO; +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.system.util.JwtUtil; +import org.jeecg.common.util.RedisUtil; import org.jeecg.common.util.SpringContextUtils; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.StaticConfig; import org.jeecg.modules.message.handle.ISendMsgHandle; -import org.springframework.mail.SimpleMailMessage; +import org.jeecg.modules.system.entity.SysUser; +import org.jeecg.modules.system.mapper.SysUserMapper; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Component; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.List; /** * @Description: 邮箱发送信息 * @author: jeecg-boot */ +@Slf4j +@Component("emailSendMsgHandle") public class EmailSendMsgHandle implements ISendMsgHandle { static String emailFrom; @@ -22,8 +36,16 @@ public class EmailSendMsgHandle implements ISendMsgHandle { EmailSendMsgHandle.emailFrom = emailFrom; } + @Autowired + SysUserMapper sysUserMapper; + + @Autowired + private RedisUtil redisUtil; + + + @Override - public void SendMsg(String es_receiver, String es_title, String es_content) { + public void sendMsg(String esReceiver, String esTitle, String esContent) { JavaMailSender mailSender = (JavaMailSender) SpringContextUtils.getBean("mailSender"); MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = null; @@ -37,13 +59,53 @@ public class EmailSendMsgHandle implements ISendMsgHandle { helper = new MimeMessageHelper(message, true); // 设置发送方邮箱地址 helper.setFrom(emailFrom); - helper.setTo(es_receiver); - helper.setSubject(es_title); - helper.setText(es_content, true); + helper.setTo(esReceiver); + helper.setSubject(esTitle); + helper.setText(esContent, true); mailSender.send(message); } catch (MessagingException e) { e.printStackTrace(); } } + + @Override + public void sendMessage(MessageDTO messageDTO) { + String[] arr = messageDTO.getToUser().split(","); + LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<SysUser>().in(SysUser::getUsername, arr); + List<SysUser> list = sysUserMapper.selectList(query); + String content = messageDTO.getContent(); + String title = messageDTO.getTitle(); + for(SysUser user: list){ + String email = user.getEmail(); + if(email==null || "".equals(email)){ + continue; + } + + if(content.indexOf(CommonConstant.LOGIN_TOKEN)>0){ + String token = getToken(user); + try { + content = content.replace(CommonConstant.LOGIN_TOKEN, URLEncoder.encode(token, "UTF-8")); + } catch (UnsupportedEncodingException e) { + log.error("邮件消息token编码失败", e.getMessage()); + } + } + log.info("邮件内容:"+ content); + sendMsg(email, title, content); + } + } + + /** + * 获取token + * @param user + * @return + */ + private String getToken(SysUser user) { + // 生成token + String token = JwtUtil.sign(user.getUsername(), user.getPassword()); + redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); + // 设置超时时间 1个小时 + redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 1 / 1000); + return token; + } } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/QywxSendMsgHandle.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/QywxSendMsgHandle.java new file mode 100644 index 0000000..46afeb6 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/QywxSendMsgHandle.java @@ -0,0 +1,37 @@ +package org.jeecg.modules.message.handle.impl; + +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.api.dto.message.MessageDTO; +import org.jeecg.modules.message.handle.ISendMsgHandle; +import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * @Description: 发企业微信消息模板 + * @author: jeecg-boot + */ +@Slf4j +@Component("qywxSendMsgHandle") +public class QywxSendMsgHandle implements ISendMsgHandle { + + @Autowired + private ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService; + + @Override + public void sendMsg(String esReceiver, String esTitle, String esContent) { + log.info("发微信消息模板"); + MessageDTO messageDTO = new MessageDTO(); + messageDTO.setToUser(esReceiver); + messageDTO.setTitle(esTitle); + messageDTO.setContent(esContent); + messageDTO.setToAll(false); + sendMessage(messageDTO); + } + + @Override + public void sendMessage(MessageDTO messageDTO) { + wechatEnterpriseService.sendMessage(messageDTO, true); + } + +} diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/SmsSendMsgHandle.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/SmsSendMsgHandle.java index c08ac2d..5063ddf 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/SmsSendMsgHandle.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/SmsSendMsgHandle.java @@ -11,7 +11,7 @@ import org.jeecg.modules.message.handle.ISendMsgHandle; public class SmsSendMsgHandle implements ISendMsgHandle { @Override - public void SendMsg(String es_receiver, String es_title, String es_content) { + public void sendMsg(String esReceiver, String esTitle, String esContent) { // TODO Auto-generated method stub log.info("发短信"); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/SystemSendMsgHandle.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/SystemSendMsgHandle.java index 0ad5007..7a2d2ef 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/SystemSendMsgHandle.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/SystemSendMsgHandle.java @@ -1,28 +1,129 @@ package org.jeecg.modules.message.handle.impl; +import com.alibaba.fastjson.JSONObject; import org.jeecg.common.api.dto.message.MessageDTO; +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.constant.WebsocketConst; import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.util.SpringContextUtils; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.message.handle.ISendMsgHandle; +import org.jeecg.modules.message.websocket.WebSocket; +import org.jeecg.modules.system.entity.SysAnnouncement; +import org.jeecg.modules.system.entity.SysAnnouncementSend; +import org.jeecg.modules.system.entity.SysUser; +import org.jeecg.modules.system.mapper.SysAnnouncementMapper; +import org.jeecg.modules.system.mapper.SysAnnouncementSendMapper; +import org.jeecg.modules.system.mapper.SysUserMapper; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.Map; /** * @Description: 发送系统消息 * @Author: wangshuai * @Date: 2022年3月22日 18:48:20 */ +@Component("systemSendMsgHandle") public class SystemSendMsgHandle implements ISendMsgHandle { public static final String FROM_USER="system"; + @Resource + private SysAnnouncementMapper sysAnnouncementMapper; + + @Resource + private SysUserMapper userMapper; + + @Resource + private SysAnnouncementSendMapper sysAnnouncementSendMapper; + + @Resource + private WebSocket webSocket; + + /** + * 该方法会发送3种消息:系统消息、企业微信 钉钉 + * @param esReceiver 发送人 + * @param esTitle 标题 + * @param esContent 内容 + */ @Override - public void SendMsg(String es_receiver, String es_title, String es_content) { - if(oConvertUtils.isEmpty(es_receiver)){ + public void sendMsg(String esReceiver, String esTitle, String esContent) { + if(oConvertUtils.isEmpty(esReceiver)){ throw new JeecgBootException("被发送人不能为空"); } - ISysBaseAPI sysBaseAPI = SpringContextUtils.getBean(ISysBaseAPI.class); - MessageDTO messageDTO = new MessageDTO(FROM_USER,es_receiver,es_title,es_content); - sysBaseAPI.sendSysAnnouncement(messageDTO); + ISysBaseAPI sysBaseApi = SpringContextUtils.getBean(ISysBaseAPI.class); + MessageDTO messageDTO = new MessageDTO(FROM_USER,esReceiver,esTitle,esContent); + sysBaseApi.sendSysAnnouncement(messageDTO); + } + + /** + * 仅发送系统消息 + * @param messageDTO + */ + @Override + public void sendMessage(MessageDTO messageDTO) { + //原方法不支持 sysBaseApi.sendSysAnnouncement(messageDTO); 有企业微信消息逻辑, + String title = messageDTO.getTitle(); + String content = messageDTO.getContent(); + String fromUser = messageDTO.getFromUser(); + Map<String,Object> data = messageDTO.getData(); + String[] arr = messageDTO.getToUser().split(","); + for(String username: arr){ + doSend(title, content, fromUser, username, data); + } + } + + private void doSend(String title, String msgContent, String fromUser, String toUser, Map<String, Object> data){ + SysAnnouncement announcement = new SysAnnouncement(); + if(data!=null){ + //摘要信息 + Object msgAbstract = data.get(CommonConstant.NOTICE_MSG_SUMMARY); + if(msgAbstract!=null){ + announcement.setMsgAbstract(msgAbstract.toString()); + } + // 任务节点ID + Object taskId = data.get(CommonConstant.NOTICE_MSG_BUS_ID); + if(taskId!=null){ + announcement.setBusId(taskId.toString()); + } + } + announcement.setTitile(title); + announcement.setMsgContent(msgContent); + announcement.setSender(fromUser); + announcement.setPriority(CommonConstant.PRIORITY_M); + announcement.setMsgType(CommonConstant.MSG_TYPE_UESR); + announcement.setSendStatus(CommonConstant.HAS_SEND); + announcement.setSendTime(new Date()); + //系统消息 + announcement.setMsgCategory("2"); + announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0)); + sysAnnouncementMapper.insert(announcement); + // 2.插入用户通告阅读标记表记录 + String userId = toUser; + String[] userIds = userId.split(","); + String anntId = announcement.getId(); + for(int i=0;i<userIds.length;i++) { + if(oConvertUtils.isNotEmpty(userIds[i])) { + SysUser sysUser = userMapper.getUserByName(userIds[i]); + if(sysUser==null) { + continue; + } + SysAnnouncementSend announcementSend = new SysAnnouncementSend(); + announcementSend.setAnntId(anntId); + announcementSend.setUserId(sysUser.getId()); + announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG); + sysAnnouncementSendMapper.insert(announcementSend); + JSONObject obj = new JSONObject(); + obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER); + obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId()); + obj.put(WebsocketConst.MSG_ID, announcement.getId()); + obj.put(WebsocketConst.MSG_TXT, announcement.getTitile()); + webSocket.sendMessage(sysUser.getId(), obj.toJSONString()); + } + } } } \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/WxSendMsgHandle.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/WxSendMsgHandle.java index a1d76f7..8181cfa 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/WxSendMsgHandle.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/handle/impl/WxSendMsgHandle.java @@ -11,7 +11,7 @@ import org.jeecg.modules.message.handle.ISendMsgHandle; public class WxSendMsgHandle implements ISendMsgHandle { @Override - public void SendMsg(String es_receiver, String es_title, String es_content) { + public void sendMsg(String esReceiver, String esTitle, String esContent) { // TODO Auto-generated method stub log.info("发微信消息模板"); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/job/SendMsgJob.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/job/SendMsgJob.java index 6230074..7be7085 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/job/SendMsgJob.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/message/job/SendMsgJob.java @@ -1,21 +1,19 @@ package org.jeecg.modules.message.job; -import java.util.List; - +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.api.dto.message.MessageDTO; +import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.util.DateUtils; import org.jeecg.modules.message.entity.SysMessage; -import org.jeecg.modules.message.handle.ISendMsgHandle; import org.jeecg.modules.message.handle.enums.SendMsgStatusEnum; -import org.jeecg.modules.message.handle.enums.SendMsgTypeEnum; import org.jeecg.modules.message.service.ISysMessageService; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; - -import lombok.extern.slf4j.Slf4j; +import java.util.List; /** * 发送消息任务 @@ -28,6 +26,9 @@ public class SendMsgJob implements Job { @Autowired private ISysMessageService sysMessageService; + @Autowired + private ISysBaseAPI sysBaseAPI; + @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { @@ -41,32 +42,19 @@ public class SendMsgJob implements Job { System.out.println(sysMessages); // 2.根据不同的类型走不通的发送实现类 for (SysMessage sysMessage : sysMessages) { - ISendMsgHandle sendMsgHandle = null; - try { - if (sysMessage.getEsType().equals(SendMsgTypeEnum.EMAIL.getType())) { - sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.EMAIL.getImplClass()).newInstance(); - } else if (sysMessage.getEsType().equals(SendMsgTypeEnum.SMS.getType())) { - sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.SMS.getImplClass()).newInstance(); - } else if (sysMessage.getEsType().equals(SendMsgTypeEnum.WX.getType())) { - sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.WX.getImplClass()).newInstance(); - } else if(sysMessage.getEsType().equals(SendMsgTypeEnum.SYSTEM_MESSAGE.getType())){ - //update-begin---author:wangshuai ---date:20220323 for:[issues/I4X698]根据模板发送系统消息,发送失败------------ - sendMsgHandle = (ISendMsgHandle) Class.forName(SendMsgTypeEnum.SYSTEM_MESSAGE.getImplClass()).newInstance(); - //update-end---author:wangshuai ---date:20220323 for:[issues/I4X698]根据模板发送系统消息,发送失败------------ - } - } catch (Exception e) { - log.error(e.getMessage(),e); - } + //update-begin-author:taoyan date:2022-7-8 for: 模板消息发送测试调用方法修改 Integer sendNum = sysMessage.getEsSendNum(); try { - //update-begin---author:wangshuai ---date:20220323 for:[issues/I4X698]模板管理发送消息出现NullPointerException 錯誤------------ - if(null != sendMsgHandle){ - sendMsgHandle.SendMsg(sysMessage.getEsReceiver(), sysMessage.getEsTitle(), - sysMessage.getEsContent().toString()); - //发送消息成功 - sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode()); - } - //update-end---author:wangshuai ---date:20220323 for:[issues/I4X698]模板管理发送消息出现NullPointerException 錯誤------------ + MessageDTO md = new MessageDTO(); + md.setTitle(sysMessage.getEsTitle()); + md.setContent(sysMessage.getEsContent()); + md.setToUser(sysMessage.getEsReceiver()); + md.setType(sysMessage.getEsType()); + md.setToAll(false); + sysBaseAPI.sendTemplateMessage(md); + //发送消息成功 + sysMessage.setEsSendStatus(SendMsgStatusEnum.SUCCESS.getCode()); + //update-end-author:taoyan date:2022-7-8 for: 模板消息发送测试调用方法修改 } catch (Exception e) { e.printStackTrace(); // 发送消息出现异常 diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/monitor/service/impl/RedisServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/monitor/service/impl/RedisServiceImpl.java index 5ab7213..5bdcb45 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/monitor/service/impl/RedisServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/monitor/service/impl/RedisServiceImpl.java @@ -12,6 +12,7 @@ import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Maps; +import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.monitor.domain.RedisInfo; import org.jeecg.modules.monitor.exception.RedisConnectException; @@ -34,6 +35,11 @@ public class RedisServiceImpl implements RedisService { @Resource private RedisConnectionFactory redisConnectionFactory; + /** + * redis信息 + */ + private static final String REDIS_MESSAGE = "3"; + /** * Redis详细信息 */ @@ -88,7 +94,7 @@ public class RedisServiceImpl implements RedisService { public Map<String, JSONArray> getMapForReport(String type) throws RedisConnectException { Map<String,JSONArray> mapJson=new HashMap(5); JSONArray json = new JSONArray(); - if("3".equals(type)){ + if(REDIS_MESSAGE.equals(type)){ List<RedisInfo> redisInfo = getRedisInfo(); for(RedisInfo info:redisInfo){ Map<String, Object> map= Maps.newHashMap(); @@ -101,7 +107,8 @@ public class RedisServiceImpl implements RedisService { mapJson.put("data",json); return mapJson; } - for(int i = 0; i < 5; i++){ + int length = 5; + for(int i = 0; i < length; i++){ JSONObject jo = new JSONObject(); Map<String, Object> map; if("1".equals(type)){ @@ -109,11 +116,11 @@ public class RedisServiceImpl implements RedisService { jo.put("value",map.get("dbSize")); }else{ map = getMemoryInfo(); - Integer used_memory = Integer.valueOf(map.get("used_memory").toString()); - jo.put("value",used_memory/1000); + Integer usedMemory = Integer.valueOf(map.get("used_memory").toString()); + jo.put("value",usedMemory/1000); } - String create_time = DateUtil.formatTime(DateUtil.date((Long) map.get("create_time")-(4-i)*1000)); - jo.put("name",create_time); + String createTime = DateUtil.formatTime(DateUtil.date((Long) map.get("create_time")-(4-i)*1000)); + jo.put("name",createTime); json.add(jo); } mapJson.put("data",json); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/ngalain/service/impl/NgAlainServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/ngalain/service/impl/NgAlainServiceImpl.java index 6e93496..bcad44a 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/ngalain/service/impl/NgAlainServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/ngalain/service/impl/NgAlainServiceImpl.java @@ -2,6 +2,8 @@ package org.jeecg.modules.ngalain.service.impl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.ngalain.service.NgAlainService; import org.jeecg.modules.system.entity.SysPermission; @@ -123,12 +125,13 @@ public class NgAlainServiceImpl implements NgAlainService { private JSONObject getPermissionJsonObject(SysPermission permission) { JSONObject json = new JSONObject(); //类型(0:一级菜单 1:子菜单 2:按钮) - if(permission.getMenuType()==2) { + if(CommonConstant.MENU_TYPE_2.equals(permission.getMenuType())) { json.put("action", permission.getPerms()); json.put("describe", permission.getName()); - }else if(permission.getMenuType()==0||permission.getMenuType()==1) { + }else if(CommonConstant.MENU_TYPE_0.equals(permission.getMenuType()) || CommonConstant.MENU_TYPE_1.equals(permission.getMenuType())) { json.put("id", permission.getId()); - if(permission.getUrl()!=null&&(permission.getUrl().startsWith("http://")||permission.getUrl().startsWith("https://"))) { + boolean flag = permission.getUrl()!=null&&(permission.getUrl().startsWith(CommonConstant.HTTP_PROTOCOL)||permission.getUrl().startsWith(CommonConstant.HTTPS_PROTOCOL)); + if(flag) { String url= new String(Base64.getUrlEncoder().encode(permission.getUrl().getBytes())); json.put("path", "/sys/link/" +url.replaceAll("=","")); }else { @@ -156,7 +159,7 @@ public class NgAlainServiceImpl implements NgAlainService { }else { meta.put("icon", oConvertUtils.getString(permission.getIcon(), "")); } - if(permission.getUrl()!=null&&(permission.getUrl().startsWith("http://")||permission.getUrl().startsWith("https://"))) { + if(flag) { meta.put("url", permission.getUrl()); } json.put("meta", meta); @@ -172,7 +175,7 @@ public class NgAlainServiceImpl implements NgAlainService { */ private String urlToRouteName(String url) { if(oConvertUtils.isNotEmpty(url)) { - if(url.startsWith("/")) { + if(url.startsWith(SymbolConstant.SINGLE_SLASH)) { url = url.substring(1); } url = url.replace("/", "-"); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/controller/OssFileController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/controller/OssFileController.java new file mode 100644 index 0000000..7939759 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/controller/OssFileController.java @@ -0,0 +1,95 @@ +package org.jeecg.modules.oss.controller; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.shiro.authz.annotation.RequiresRoles; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.query.QueryGenerator; +import org.jeecg.modules.oss.entity.OssFile; +import org.jeecg.modules.oss.service.IOssFileService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import lombok.extern.slf4j.Slf4j; + +/** + * 云存储示例 DEMO + * @author: jeecg-boot + */ +@Slf4j +@Controller +@RequestMapping("/sys/oss/file") +public class OssFileController { + + @Autowired + private IOssFileService ossFileService; + + @ResponseBody + @GetMapping("/list") + public Result<IPage<OssFile>> queryPageList(OssFile file, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { + Result<IPage<OssFile>> result = new Result<>(); + QueryWrapper<OssFile> queryWrapper = QueryGenerator.initQueryWrapper(file, req.getParameterMap()); + Page<OssFile> page = new Page<>(pageNo, pageSize); + IPage<OssFile> pageList = ossFileService.page(page, queryWrapper); + result.setSuccess(true); + result.setResult(pageList); + return result; + } + + @ResponseBody + @PostMapping("/upload") + //@RequiresRoles("admin") + public Result upload(@RequestParam("file") MultipartFile multipartFile) { + Result result = new Result(); + try { + ossFileService.upload(multipartFile); + result.success("上传成功!"); + } + catch (Exception ex) { + log.info(ex.getMessage(), ex); + result.error500("上传失败"); + } + return result; + } + + @ResponseBody + @DeleteMapping("/delete") + public Result delete(@RequestParam(name = "id") String id) { + Result result = new Result(); + OssFile file = ossFileService.getById(id); + if (file == null) { + result.error500("未找到对应实体"); + }else { + boolean ok = ossFileService.delete(file); + result.success("删除成功!"); + } + return result; + } + + /** + * 通过id查询. + */ + @ResponseBody + @GetMapping("/queryById") + public Result<OssFile> queryById(@RequestParam(name = "id") String id) { + Result<OssFile> result = new Result<>(); + OssFile file = ossFileService.getById(id); + if (file == null) { + result.error500("未找到对应实体"); + } + else { + result.setResult(file); + result.setSuccess(true); + } + return result; + } + +} diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/entity/OssFile.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/entity/OssFile.java new file mode 100644 index 0000000..ba4e073 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/entity/OssFile.java @@ -0,0 +1,28 @@ +package org.jeecg.modules.oss.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecg.common.system.base.entity.JeecgEntity; +import org.jeecgframework.poi.excel.annotation.Excel; + +/** + * @Description: oss云存储实体类 + * @author: jeecg-boot + */ +@Data +@TableName("oss_file") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class OssFile extends JeecgEntity { + + private static final long serialVersionUID = 1L; + + @Excel(name = "文件名称") + private String fileName; + + @Excel(name = "文件地址") + private String url; + +} diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/mapper/OssFileMapper.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/mapper/OssFileMapper.java new file mode 100644 index 0000000..36a9955 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/mapper/OssFileMapper.java @@ -0,0 +1,12 @@ +package org.jeecg.modules.oss.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.jeecg.modules.oss.entity.OssFile; + +/** + * @Description: oss云存储Mapper + * @author: jeecg-boot + */ +public interface OssFileMapper extends BaseMapper<OssFile> { + +} diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/service/IOssFileService.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/service/IOssFileService.java new file mode 100644 index 0000000..8a82a48 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/service/IOssFileService.java @@ -0,0 +1,29 @@ +package org.jeecg.modules.oss.service; + +import java.io.IOException; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.modules.oss.entity.OssFile; +import org.springframework.web.multipart.MultipartFile; + +/** + * @Description: OOS云存储service接口 + * @author: jeecg-boot + */ +public interface IOssFileService extends IService<OssFile> { + + /** + * oss文件上传 + * @param multipartFile + * @throws IOException + */ + void upload(MultipartFile multipartFile) throws IOException; + + /** + * oss文件删除 + * @param ossFile OSSFile对象 + * @return + */ + boolean delete(OssFile ossFile); + +} diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/service/impl/OssFileServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/service/impl/OssFileServiceImpl.java new file mode 100644 index 0000000..539d90f --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/oss/service/impl/OssFileServiceImpl.java @@ -0,0 +1,48 @@ +package org.jeecg.modules.oss.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.jeecg.common.util.CommonUtils; +import org.jeecg.common.util.oss.OssBootUtil; +import org.jeecg.modules.oss.entity.OssFile; +import org.jeecg.modules.oss.mapper.OssFileMapper; +import org.jeecg.modules.oss.service.IOssFileService; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +/** + * @Description: OSS云存储实现类 + * @author: jeecg-boot + */ +@Service("ossFileService") +public class OssFileServiceImpl extends ServiceImpl<OssFileMapper, OssFile> implements IOssFileService { + + @Override + public void upload(MultipartFile multipartFile) throws IOException { + String fileName = multipartFile.getOriginalFilename(); + fileName = CommonUtils.getFileName(fileName); + OssFile ossFile = new OssFile(); + ossFile.setFileName(fileName); + String url = OssBootUtil.upload(multipartFile,"upload/test"); + //update-begin--Author:scott Date:20201227 for:JT-361【文件预览】阿里云原生域名可以文件预览,自己映射域名kkfileview提示文件下载失败------------------- + // 返回阿里云原生域名前缀URL + ossFile.setUrl(OssBootUtil.getOriginalUrl(url)); + //update-end--Author:scott Date:20201227 for:JT-361【文件预览】阿里云原生域名可以文件预览,自己映射域名kkfileview提示文件下载失败------------------- + this.save(ossFile); + } + + @Override + public boolean delete(OssFile ossFile) { + try { + this.removeById(ossFile.getId()); + OssBootUtil.deleteUrl(ossFile.getUrl()); + } + catch (Exception ex) { + log.error(ex.getMessage(),ex); + return false; + } + return true; + } + +} diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java index 881e8ae..d61c720 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/quartz/controller/QuartzJobController.java @@ -10,6 +10,7 @@ import org.apache.shiro.SecurityUtils; 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; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.ImportExcelUtil; @@ -132,7 +133,7 @@ public class QuartzJobController { if (ids == null || "".equals(ids.trim())) { return Result.error("参数不识别!"); } - for (String id : Arrays.asList(ids.split(","))) { + for (String id : Arrays.asList(ids.split(SymbolConstant.COMMA))) { QuartzJob job = quartzJobService.getById(id); quartzJobService.deleteAndStopJob(job); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/CommonController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/CommonController.java index 760efa2..24c4a77 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/CommonController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/CommonController.java @@ -5,8 +5,8 @@ import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; 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.system.api.ISysBaseAPI; import org.jeecg.common.util.CommonUtils; import org.jeecg.common.util.RestUtil; import org.jeecg.common.util.TokenUtils; @@ -72,8 +72,10 @@ public class CommonController { String bizPath = request.getParameter("biz"); //LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞 - if (oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\"))) { - throw new JeecgBootException("上传目录bizPath,格式非法!"); + if (oConvertUtils.isNotEmpty(bizPath)) { + if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){ + throw new JeecgBootException("上传目录bizPath,格式非法!"); + } } MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; @@ -138,7 +140,7 @@ public class CommonController { // 获取文件名 String orgName = mf.getOriginalFilename(); orgName = CommonUtils.getFileName(orgName); - if(orgName.indexOf(".")!=-1){ + if(orgName.indexOf(SymbolConstant.SPOT)!=-1){ fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf(".")); }else{ fileName = orgName+ "_" + System.currentTimeMillis(); @@ -152,8 +154,8 @@ public class CommonController { }else{ dbpath = fileName; } - if (dbpath.contains("\\")) { - dbpath = dbpath.replace("\\", "/"); + if (dbpath.contains(SymbolConstant.DOUBLE_BACKSLASH)) { + dbpath = dbpath.replace(SymbolConstant.DOUBLE_BACKSLASH, SymbolConstant.SINGLE_SLASH); } return dbpath; } catch (IOException e) { @@ -210,7 +212,7 @@ public class CommonController { public void view(HttpServletRequest request, HttpServletResponse response) { // ISO-8859-1 ==> UTF-8 进行编码转换 String imgPath = extractPathFromPattern(request); - if(oConvertUtils.isEmpty(imgPath) || imgPath=="null"){ + if(oConvertUtils.isEmpty(imgPath) || CommonConstant.STRING_NULL.equals(imgPath)){ return; } // 其余处理略 @@ -218,7 +220,7 @@ public class CommonController { OutputStream outputStream = null; try { imgPath = imgPath.replace("..", "").replace("../",""); - if (imgPath.endsWith(",")) { + if (imgPath.endsWith(SymbolConstant.COMMA)) { imgPath = imgPath.substring(0, imgPath.length() - 1); } String filePath = uploadpath + File.separator + imgPath; @@ -349,7 +351,7 @@ public class CommonController { * @return */ @RequestMapping("/transitRESTful") - public Result transitRESTful(@RequestParam("url") String url, HttpServletRequest request) { + public Result transitRestful(@RequestParam("url") String url, HttpServletRequest request) { try { ServletServerHttpRequest httpRequest = new ServletServerHttpRequest(request); // 中转请求method、body @@ -368,8 +370,8 @@ public class CommonController { HttpHeaders headers = new HttpHeaders(); headers.set("X-Access-Token", token); // 发送请求 - String httpURL = URLDecoder.decode(url, "UTF-8"); - ResponseEntity<String> response = RestUtil.request(httpURL, method, headers , variables, params, String.class); + String httpUrl = URLDecoder.decode(url, "UTF-8"); + ResponseEntity<String> response = RestUtil.request(httpUrl, method, headers , variables, params, String.class); // 封装返回结果 Result<Object> result = new Result<>(); int statusCode = response.getStatusCodeValue(); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/LoginController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/LoginController.java index b8490ec..18341cf 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/LoginController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/LoginController.java @@ -12,12 +12,14 @@ import org.apache.shiro.SecurityUtils; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CacheConstant; import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.*; import org.jeecg.common.util.encryption.EncryptedString; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.modules.system.entity.SysDepart; +import org.jeecg.modules.system.entity.SysRoleIndex; import org.jeecg.modules.system.entity.SysTenant; import org.jeecg.modules.system.entity.SysUser; import org.jeecg.modules.system.model.SysLoginModel; @@ -26,6 +28,7 @@ import org.jeecg.modules.system.service.impl.SysBaseApiImpl; import org.jeecg.modules.system.util.RandImageUtil; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -59,6 +62,8 @@ public class LoginController { @Resource private BaseCommonService baseCommonService; + private final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890"; + @ApiOperation("登录接口") @RequestMapping(value = "/login", method = RequestMethod.POST) public Result<JSONObject> login(@RequestBody SysLoginModel sysLoginModel){ @@ -83,6 +88,8 @@ public class LoginController { if(checkCode==null || !checkCode.toString().equals(lowerCaseCaptcha)) { log.warn("验证码错误,key= {} , Ui checkCode= {}, Redis checkCode = {}", sysLoginModel.getCheckKey(), lowerCaseCaptcha, checkCode); result.error500("验证码错误"); + // 改成特殊的code 便于前端判断 + result.setCode(HttpStatus.PRECONDITION_FAILED.value()); return result; } //update-end-author:taoyan date:20190828 for:校验验证码 @@ -97,7 +104,7 @@ public class LoginController { if(!result.isSuccess()) { return result; } - + //2. 校验用户名或密码是否正确 String userpassword = PasswordUtil.encrypt(username, password, sysUser.getSalt()); String syspassword = sysUser.getPassword(); @@ -130,6 +137,21 @@ public class LoginController { // 根据用户名查询用户信息 SysUser sysUser = sysUserService.getUserByName(username); JSONObject obj=new JSONObject(); + + //update-begin---author:scott ---date:2022-06-20 for:vue3前端,支持自定义首页----------- + String version = request.getHeader(CommonConstant.VERSION); + //update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑----------- + SysRoleIndex roleIndex = sysUserService.getDynamicIndexByUserRole(username, version); + if (oConvertUtils.isNotEmpty(version) && roleIndex != null && oConvertUtils.isNotEmpty(roleIndex.getUrl())) { + String homePath = roleIndex.getUrl(); + if (!homePath.startsWith(SymbolConstant.SINGLE_SLASH)) { + homePath = SymbolConstant.SINGLE_SLASH + homePath; + } + sysUser.setHomePath(homePath); + } + //update-begin---author:liusq ---date:2022-06-29 for:接口返回值修改,同步修改这里的判断逻辑----------- + //update-end---author:scott ---date::2022-06-20 for:vue3前端,支持自定义首页-------------- + obj.put("userInfo",sysUser); obj.put("sysAllDictItems", sysDictService.queryAllDictItems()); result.setResult(obj); @@ -294,7 +316,8 @@ public class LoginController { result = sysUserService.checkUserIsEffective(sysUser); if(!result.isSuccess()) { String message = result.getMessage(); - if("该用户不存在,请注册".equals(message)){ + String userNotExist="该用户不存在,请注册"; + if(userNotExist.equals(message)){ result.error500("该用户不存在或未绑定手机号"); } return result; @@ -400,7 +423,7 @@ public class LoginController { String tenantIds = sysUser.getRelTenantIds(); if (oConvertUtils.isNotEmpty(tenantIds)) { List<Integer> tenantIdList = new ArrayList<>(); - for(String id: tenantIds.split(",")){ + for(String id: tenantIds.split(SymbolConstant.COMMA)){ tenantIdList.add(Integer.valueOf(id)); } // 该方法仅查询有效的租户,如果返回0个就说明所有的租户均无效。 @@ -451,7 +474,6 @@ public class LoginController { Result<String> res = new Result<String>(); try { //生成验证码 - final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890"; String code = RandomUtil.randomString(BASE_CHECK_CODES,4); //存到redis中 diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java index e3f78e1..e57e4a0 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementController.java @@ -27,7 +27,7 @@ import org.jeecg.modules.system.service.ISysAnnouncementService; import org.jeecg.modules.system.service.impl.SysBaseApiImpl; import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl; import org.jeecg.modules.system.service.impl.ThirdAppWechatEnterpriseServiceImpl; -import org.jeecg.modules.system.util.XSSUtils; +import org.jeecg.modules.system.util.XssUtils; import org.jeecgframework.poi.excel.ExcelImportUtil; import org.jeecgframework.poi.excel.def.NormalExcelConstants; import org.jeecgframework.poi.excel.entity.ExportParams; @@ -125,7 +125,7 @@ public class SysAnnouncementController { Result<SysAnnouncement> result = new Result<SysAnnouncement>(); try { // update-begin-author:liusq date:20210804 for:标题处理xss攻击的问题 - String title = XSSUtils.striptXSS(sysAnnouncement.getTitile()); + String title = XssUtils.scriptXss(sysAnnouncement.getTitile()); sysAnnouncement.setTitile(title); // update-end-author:liusq date:20210804 for:标题处理xss攻击的问题 sysAnnouncement.setDelFlag(CommonConstant.DEL_FLAG_0.toString()); @@ -153,7 +153,7 @@ public class SysAnnouncementController { result.error500("未找到对应实体"); }else { // update-begin-author:liusq date:20210804 for:标题处理xss攻击的问题 - String title = XSSUtils.striptXSS(sysAnnouncement.getTitile()); + String title = XssUtils.scriptXss(sysAnnouncement.getTitile()); sysAnnouncement.setTitile(title); // update-end-author:liusq date:20210804 for:标题处理xss攻击的问题 boolean ok = sysAnnouncementService.upDateAnnouncement(sysAnnouncement); @@ -488,15 +488,15 @@ public class SysAnnouncementController { public ModelAndView showContent(ModelAndView modelAndView, @PathVariable("id") String id, HttpServletRequest request) { SysAnnouncement announcement = sysAnnouncementService.getById(id); if (announcement != null) { - boolean tokenOK = false; + boolean tokenOk = false; try { // 验证Token有效性 - tokenOK = TokenUtils.verifyToken(request, sysBaseApi, redisUtil); + tokenOk = TokenUtils.verifyToken(request, sysBaseApi, redisUtil); } catch (Exception ignored) { } // 判断是否传递了Token,并且Token有效,如果传了就不做查看限制,直接返回 // 如果Token无效,就做查看限制:只能查看已发布的 - if (tokenOK || ANNOUNCEMENT_SEND_STATUS_1.equals(announcement.getSendStatus())) { + if (tokenOk || ANNOUNCEMENT_SEND_STATUS_1.equals(announcement.getSendStatus())) { modelAndView.addObject("data", announcement); modelAndView.setViewName("announcement/showContent"); return modelAndView; diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java index ac2087c..67464e3 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysAnnouncementSendController.java @@ -8,6 +8,7 @@ import javax.servlet.http.HttpServletRequest; import org.apache.shiro.SecurityUtils; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.constant.DataBaseConstant; import org.jeecg.common.constant.WebsocketConst; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.SqlInjectionUtil; @@ -76,7 +77,7 @@ public class SysAnnouncementSendController { SqlInjectionUtil.filterContent(order); if(oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) { - if("asc".equals(order)) { + if(DataBaseConstant.SQL_ASC.equals(order)) { queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column)); }else { queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column)); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java index 719adcc..9ab89a7 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysCategoryController.java @@ -14,6 +14,7 @@ import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.DictModel; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.ImportExcelUtil; +import org.jeecg.common.util.SqlInjectionUtil; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.system.entity.SysCategory; import org.jeecg.modules.system.model.TreeSelectModel; @@ -47,7 +48,12 @@ import java.util.stream.Collectors; public class SysCategoryController { @Autowired private ISysCategoryService sysCategoryService; - + + /** + * 分类编码0 + */ + private static final String CATEGORY_ROOT_CODE = "0"; + /** * 分页列表查询 * @param sysCategory @@ -294,7 +300,12 @@ public class SysCategoryController { public Result<SysCategory> loadOne(@RequestParam(name="field") String field,@RequestParam(name="val") String val) { Result<SysCategory> result = new Result<SysCategory>(); try { - + //update-begin-author:taoyan date:2022-5-6 for: issues/3663 sql注入问题 + boolean isClassField = SqlInjectionUtil.isClassField(field, SysCategory.class); + if (!isClassField) { + return Result.error("字段无效,请检查!"); + } + //update-end-author:taoyan date:2022-5-6 for: issues/3663 sql注入问题 QueryWrapper<SysCategory> query = new QueryWrapper<SysCategory>(); query.eq(field, val); List<SysCategory> ls = this.sysCategoryService.list(query); @@ -463,7 +474,7 @@ public class SysCategoryController { public Result<List<DictModel>> loadAllData(@RequestParam(name="code",required = true) String code) { Result<List<DictModel>> result = new Result<List<DictModel>>(); LambdaQueryWrapper<SysCategory> query = new LambdaQueryWrapper<SysCategory>(); - if(oConvertUtils.isNotEmpty(code) && !"0".equals(code)){ + if(oConvertUtils.isNotEmpty(code) && !CATEGORY_ROOT_CODE.equals(code)){ query.likeRight(SysCategory::getCode,code); } List<SysCategory> list = this.sysCategoryService.list(query); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDataSourceController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDataSourceController.java index 98417c1..a39a630 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDataSourceController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDataSourceController.java @@ -1,12 +1,11 @@ package org.jeecg.modules.system.controller; -import cn.hutool.core.util.CharsetUtil; -import cn.hutool.core.util.HexUtil; -import cn.hutool.crypto.SecureUtil; -import cn.hutool.crypto.symmetric.SymmetricAlgorithm; -import cn.hutool.crypto.symmetric.SymmetricCrypto; + import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; +import com.baomidou.dynamic.datasource.creator.DruidDataSourceCreator; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -29,6 +28,7 @@ import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.sql.DataSource; import java.util.Arrays; import java.util.List; @@ -69,18 +69,6 @@ public class SysDataSourceController extends JeecgController<SysDataSource, ISys QueryWrapper<SysDataSource> queryWrapper = QueryGenerator.initQueryWrapper(sysDataSource, req.getParameterMap()); Page<SysDataSource> page = new Page<>(pageNo, pageSize); IPage<SysDataSource> pageList = sysDataSourceService.page(page, queryWrapper); - try { - List<SysDataSource> records = pageList.getRecords(); - records.forEach(item->{ - String dbPassword = item.getDbPassword(); - if(StringUtils.isNotBlank(dbPassword)){ - String decodedStr = SecurityUtil.jiemi(dbPassword); - item.setDbPassword(decodedStr); - } - }); - } catch (Exception e) { - e.printStackTrace(); - } return Result.ok(pageList); } @@ -109,17 +97,7 @@ public class SysDataSourceController extends JeecgController<SysDataSource, ISys @ApiOperation(value = "多数据源管理-添加", notes = "多数据源管理-添加") @PostMapping(value = "/add") public Result<?> add(@RequestBody SysDataSource sysDataSource) { - try { - String dbPassword = sysDataSource.getDbPassword(); - if(StringUtils.isNotBlank(dbPassword)){ - String encrypt = SecurityUtil.jiami(dbPassword); - sysDataSource.setDbPassword(encrypt); - } - sysDataSourceService.save(sysDataSource); - } catch (Exception e) { - e.printStackTrace(); - } - return Result.ok("添加成功!"); + return sysDataSourceService.saveDataSource(sysDataSource); } /** @@ -132,19 +110,7 @@ public class SysDataSourceController extends JeecgController<SysDataSource, ISys @ApiOperation(value = "多数据源管理-编辑", notes = "多数据源管理-编辑") @RequestMapping(value = "/edit", method ={RequestMethod.PUT, RequestMethod.POST}) public Result<?> edit(@RequestBody SysDataSource sysDataSource) { - try { - SysDataSource d = sysDataSourceService.getById(sysDataSource.getId()); - DataSourceCachePool.removeCache(d.getCode()); - String dbPassword = sysDataSource.getDbPassword(); - if(StringUtils.isNotBlank(dbPassword)){ - String encrypt = SecurityUtil.jiami(dbPassword); - sysDataSource.setDbPassword(encrypt); - } - sysDataSourceService.updateById(sysDataSource); - } catch (Exception e) { - e.printStackTrace(); - } - return Result.ok("编辑成功!"); + return sysDataSourceService.editDataSource(sysDataSource); } /** @@ -157,10 +123,7 @@ public class SysDataSourceController extends JeecgController<SysDataSource, ISys @ApiOperation(value = "多数据源管理-通过id删除", notes = "多数据源管理-通过id删除") @DeleteMapping(value = "/delete") public Result<?> delete(@RequestParam(name = "id") String id) { - SysDataSource sysDataSource = sysDataSourceService.getById(id); - DataSourceCachePool.removeCache(sysDataSource.getCode()); - sysDataSourceService.removeById(id); - return Result.ok("删除成功!"); + return sysDataSourceService.deleteDataSource(id); } /** @@ -191,8 +154,14 @@ public class SysDataSourceController extends JeecgController<SysDataSource, ISys @AutoLog(value = "多数据源管理-通过id查询") @ApiOperation(value = "多数据源管理-通过id查询", notes = "多数据源管理-通过id查询") @GetMapping(value = "/queryById") - public Result<?> queryById(@RequestParam(name = "id") String id) { + public Result<?> queryById(@RequestParam(name = "id") String id) throws InterruptedException { SysDataSource sysDataSource = sysDataSourceService.getById(id); + //密码解密 + String dbPassword = sysDataSource.getDbPassword(); + if(StringUtils.isNotBlank(dbPassword)){ + String decodedStr = SecurityUtil.jiemi(dbPassword); + sysDataSource.setDbPassword(decodedStr); + } return Result.ok(sysDataSource); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java index 378ae6d..fcfd21a 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java @@ -123,13 +123,14 @@ public class SysDepartController { * 异步查询部门list * @param parentId 父节点 异步加载时传递 * @param ids 前端回显是传递 + * @param primaryKey 主键字段(id或者orgCode) * @return */ @RequestMapping(value = "/queryDepartTreeSync", method = RequestMethod.GET) - public Result<List<SysDepartTreeModel>> queryDepartTreeSync(@RequestParam(name = "pid", required = false) String parentId,@RequestParam(name = "ids", required = false) String ids) { + public Result<List<SysDepartTreeModel>> queryDepartTreeSync(@RequestParam(name = "pid", required = false) String parentId,@RequestParam(name = "ids", required = false) String ids, @RequestParam(name = "primaryKey", required = false) String primaryKey) { Result<List<SysDepartTreeModel>> result = new Result<>(); try { - List<SysDepartTreeModel> list = sysDepartService.queryTreeListByPid(parentId,ids); + List<SysDepartTreeModel> list = sysDepartService.queryTreeListByPid(parentId,ids, primaryKey); result.setResult(list); result.setSuccess(true); } catch (Exception e) { @@ -460,7 +461,7 @@ public class SysDepartController { LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>(); query.orderByAsc(SysDepart::getOrgCode); if(oConvertUtils.isNotEmpty(id)){ - String arr[] = id.split(","); + String[] arr = id.split(","); query.in(SysDepart::getId,arr); } List<SysDepart> ls = this.sysDepartService.list(query); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java index 74a765a..8edb12b 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDepartPermissionController.java @@ -237,7 +237,7 @@ public class SysDepartPermissionController extends JeecgController<SysDepartPerm Result<List<String>> result = new Result<>(); try { List<SysDepartRolePermission> list = sysDepartRolePermissionService.list(new QueryWrapper<SysDepartRolePermission>().lambda().eq(SysDepartRolePermission::getRoleId, roleId)); - result.setResult(list.stream().map(SysDepartRolePermission -> String.valueOf(SysDepartRolePermission.getPermissionId())).collect(Collectors.toList())); + result.setResult(list.stream().map(sysDepartRolePermission -> String.valueOf(sysDepartRolePermission.getPermissionId())).collect(Collectors.toList())); result.setSuccess(true); } catch (Exception e) { log.error(e.getMessage(), e); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDictController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDictController.java index 121bf32..172cdc7 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDictController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysDictController.java @@ -12,6 +12,7 @@ import org.apache.shiro.authz.annotation.RequiresRoles; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CacheConstant; import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.DictModel; import org.jeecg.common.system.vo.DictQuery; @@ -277,8 +278,8 @@ public class SysDictController { } //update-end-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口,加一些安全机制 try { - if(dictCode.indexOf(",")!=-1) { - String[] params = dictCode.split(","); + if(dictCode.indexOf(SymbolConstant.COMMA)!=-1) { + String[] params = dictCode.split(SymbolConstant.COMMA); if(params.length!=3) { result.error500("字典Code格式不正确!"); return result; diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysLogController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysLogController.java index 9409845..1853a7f 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysLogController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysLogController.java @@ -6,6 +6,7 @@ import java.util.Arrays; import javax.servlet.http.HttpServletRequest; import org.jeecg.common.api.vo.Result; +import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.system.entity.SysLog; @@ -38,7 +39,12 @@ public class SysLogController { @Autowired private ISysLogService sysLogService; - + + /** + * 全部清除 + */ + private static final String ALL_ClEAR = "allclear"; + /** * @功能:查询日志记录 * @param syslog @@ -103,7 +109,7 @@ public class SysLogController { if(ids==null || "".equals(ids.trim())) { result.error500("参数不识别!"); }else { - if("allclear".equals(ids)) { + if(ALL_ClEAR.equals(ids)) { this.sysLogService.removeAll(); result.success("清除成功!"); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java index 8471b6b..0e8217a 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysPermissionController.java @@ -1,5 +1,6 @@ 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; @@ -10,11 +11,12 @@ import org.apache.shiro.SecurityUtils; 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; import org.jeecg.common.constant.enums.RoleIndexConfigEnum; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.Md5Util; import org.jeecg.common.util.oConvertUtils; -import org.jeecg.config.JeeccgBaseConfig; +import org.jeecg.config.JeecgBaseConfig; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.modules.system.entity.*; import org.jeecg.modules.system.model.SysPermissionTree; @@ -57,7 +59,7 @@ public class SysPermissionController { private ISysUserService sysUserService; @Autowired - private JeeccgBaseConfig jeeccgBaseConfig; + private JeecgBaseConfig jeecgBaseConfig; @Autowired private BaseCommonService baseCommonService; @@ -65,6 +67,11 @@ public class SysPermissionController { @Autowired private ISysRoleIndexService sysRoleIndexService; + /** + * 子菜单 + */ + private static final String CHILDREN = "children"; + /** * 加载数据节点 * @@ -212,6 +219,7 @@ public class SysPermissionController { * @return */ @RequestMapping(value = "/getUserPermissionByToken", method = RequestMethod.GET) + //@DynamicTable(value = DynamicTableConstant.SYS_ROLE_INDEX) public Result<?> getUserPermissionByToken(HttpServletRequest request) { Result<JSONObject> result = new Result<JSONObject>(); try { @@ -229,14 +237,29 @@ public class SysPermissionController { } //update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存 - //update-begin--Author:liusq Date:20210624 for:自定义首页地址LOWCOD-1578 - List<String> roles = sysUserService.getRole(loginUser.getUsername()); - String compUrl = RoleIndexConfigEnum.getIndexByRoles(roles); - if(StringUtils.isNotBlank(compUrl)){ + //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:接口返回值修改,同步修改这里的判断逻辑----------- + //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()); - menus.get(0).setComponent(compUrl); + //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)){ + menus.get(0).setComponent(component); + menus.get(0).setRoute(route); + menus.get(0).setUrl(routeUrl); + }else{ + menus.get(0).setComponent(component); + } + //update-end---author:liusq ---date:2022-06-29 for:设置自定义首页地址和组件----------- } - //update-end--Author:liusq Date:20210624 for:自定义首页地址LOWCOD-1578 + JSONObject json = new JSONObject(); JSONArray menujsonArray = new JSONArray(); this.getPermissionJsonArray(menujsonArray, metaList, null); @@ -259,7 +282,7 @@ public class SysPermissionController { json.put("auth", authjsonArray); //全部权限配置集合(按钮权限,访问权限) json.put("allAuth", allauthjsonArray); - json.put("sysSafeMode", jeeccgBaseConfig.getSafeMode()); + json.put("sysSafeMode", jeecgBaseConfig.getSafeMode()); result.setResult(json); } catch (Exception e) { result.error500("查询失败:" + e.getMessage()); @@ -306,7 +329,7 @@ public class SysPermissionController { //全部权限配置集合(按钮权限,访问权限) result.put("allAuth", allAuthArray); // 系统安全模式 - result.put("sysSafeMode", jeeccgBaseConfig.getSafeMode()); + result.put("sysSafeMode", jeecgBaseConfig.getSafeMode()); return Result.OK(result); } catch (Exception e) { log.error(e.getMessage(), e); @@ -418,7 +441,7 @@ public class SysPermissionController { List<TreeModel> treeList = new ArrayList<>(); getTreeModelList(treeList, list, null); - Map<String, Object> resMap = new HashMap<String, Object>(); + Map<String, Object> resMap = new HashMap<String, Object>(5); // 全部树节点数据 resMap.put("treeList", treeList); // 全部树ids @@ -464,7 +487,7 @@ public class SysPermissionController { Result<List<String>> result = new Result<>(); try { List<SysRolePermission> list = sysRolePermissionService.list(new QueryWrapper<SysRolePermission>().lambda().eq(SysRolePermission::getRoleId, roleId)); - result.setResult(list.stream().map(SysRolePermission -> String.valueOf(SysRolePermission.getPermissionId())).collect(Collectors.toList())); + result.setResult(list.stream().map(sysRolePermission -> String.valueOf(sysRolePermission.getPermissionId())).collect(Collectors.toList())); result.setSuccess(true); } catch (Exception e) { log.error(e.getMessage(), e); @@ -546,8 +569,8 @@ public class SysPermissionController { jsonArray = jsonArray.stream().map(obj -> { JSONObject returnObj = new JSONObject(); JSONObject jsonObj = (JSONObject)obj; - if(jsonObj.containsKey("children")){ - JSONArray childrens = jsonObj.getJSONArray("children"); + if(jsonObj.containsKey(CHILDREN)){ + JSONArray childrens = jsonObj.getJSONArray(CHILDREN); childrens = childrens.stream().filter(arrObj -> !"true".equals(((JSONObject) arrObj).getString("hidden"))).collect(Collectors.toCollection(JSONArray::new)); if(childrens==null || childrens.size()==0){ jsonObj.put("hidden",true); @@ -675,7 +698,7 @@ public class SysPermissionController { json.put("route", "0"); } - if (isWWWHttpUrl(permission.getUrl())) { + if (isWwwHttpUrl(permission.getUrl())) { json.put("path", Md5Util.md5Encode(permission.getUrl(), "utf-8")); } else { json.put("path", permission.getUrl()); @@ -736,7 +759,7 @@ public class SysPermissionController { meta.put("icon", permission.getIcon()); } } - if (isWWWHttpUrl(permission.getUrl())) { + if (isWwwHttpUrl(permission.getUrl())) { meta.put("url", permission.getUrl()); } // update-begin--Author:sunjianlei Date:20210918 for:新增适配vue3项目的隐藏tab功能 @@ -756,8 +779,9 @@ public class SysPermissionController { * * @return */ - private boolean isWWWHttpUrl(String url) { - if (url != null && (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("{{"))) { + private boolean isWwwHttpUrl(String url) { + boolean flag = url != null && (url.startsWith(CommonConstant.HTTP_PROTOCOL) || url.startsWith(CommonConstant.HTTPS_PROTOCOL) || url.startsWith(SymbolConstant.DOUBLE_LEFT_CURLY_BRACKET)); + if (flag) { return true; } return false; @@ -771,7 +795,7 @@ public class SysPermissionController { */ private String urlToRouteName(String url) { if (oConvertUtils.isNotEmpty(url)) { - if (url.startsWith("/")) { + if (url.startsWith(SymbolConstant.SINGLE_SLASH)) { url = url.substring(1); } url = url.replace("/", "-"); @@ -883,7 +907,7 @@ public class SysPermissionController { Result<List<String>> result = new Result<>(); try { List<SysDepartPermission> list = sysDepartPermissionService.list(new QueryWrapper<SysDepartPermission>().lambda().eq(SysDepartPermission::getDepartId, departId)); - result.setResult(list.stream().map(SysDepartPermission -> String.valueOf(SysDepartPermission.getPermissionId())).collect(Collectors.toList())); + result.setResult(list.stream().map(sysDepartPermission -> String.valueOf(sysDepartPermission.getPermissionId())).collect(Collectors.toList())); result.setSuccess(true); } catch (Exception e) { log.error(e.getMessage(), e); @@ -914,4 +938,5 @@ public class SysPermissionController { } return result; } + } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java index fb15615..8f48814 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysRoleIndexController.java @@ -68,7 +68,8 @@ public class SysRoleIndexController extends JeecgController<SysRoleIndex, ISysRo @AutoLog(value = "角色首页配置-添加") @ApiOperation(value = "角色首页配置-添加", notes = "角色首页配置-添加") @PostMapping(value = "/add") - public Result<?> add(@RequestBody SysRoleIndex sysRoleIndex) { + //@DynamicTable(value = DynamicTableConstant.SYS_ROLE_INDEX) + public Result<?> add(@RequestBody SysRoleIndex sysRoleIndex,HttpServletRequest request) { sysRoleIndexService.save(sysRoleIndex); return Result.OK("添加成功!"); } @@ -82,7 +83,8 @@ public class SysRoleIndexController extends JeecgController<SysRoleIndex, ISysRo @AutoLog(value = "角色首页配置-编辑") @ApiOperation(value = "角色首页配置-编辑", notes = "角色首页配置-编辑") @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) - public Result<?> edit(@RequestBody SysRoleIndex sysRoleIndex) { + //@DynamicTable(value = DynamicTableConstant.SYS_ROLE_INDEX) + public Result<?> edit(@RequestBody SysRoleIndex sysRoleIndex,HttpServletRequest request) { sysRoleIndexService.updateById(sysRoleIndex); return Result.OK("编辑成功!"); } @@ -161,7 +163,8 @@ public class SysRoleIndexController extends JeecgController<SysRoleIndex, ISysRo @AutoLog(value = "角色首页配置-通过code查询") @ApiOperation(value = "角色首页配置-通过code查询", notes = "角色首页配置-通过code查询") @GetMapping(value = "/queryByCode") - public Result<?> queryByCode(@RequestParam(name = "roleCode", required = true) String roleCode) { + //@DynamicTable(value = DynamicTableConstant.SYS_ROLE_INDEX) + public Result<?> queryByCode(@RequestParam(name = "roleCode", required = true) String roleCode,HttpServletRequest request) { SysRoleIndex sysRoleIndex = sysRoleIndexService.getOne(new LambdaQueryWrapper<SysRoleIndex>().eq(SysRoleIndex::getRoleCode, roleCode)); return Result.OK(sysRoleIndex); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java index 6001b94..7897bdc 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysTenantController.java @@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; import org.jeecg.common.api.vo.Result; import org.jeecg.common.aspect.annotation.PermissionData; +import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; @@ -204,7 +205,7 @@ public class SysTenantController { Map<String,Object> map = new HashMap(5); if (oConvertUtils.isNotEmpty(tenantIds)) { List<Integer> tenantIdList = new ArrayList<>(); - for(String id: tenantIds.split(",")){ + for(String id: tenantIds.split(SymbolConstant.COMMA)){ tenantIdList.add(Integer.valueOf(id)); } // 该方法仅查询有效的租户,如果返回0个就说明所有的租户均无效。 diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUploadController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUploadController.java index 45d6934..ad0bf40 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUploadController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUploadController.java @@ -6,8 +6,8 @@ import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.util.CommonUtils; import org.jeecg.common.util.MinioUtil; import org.jeecg.common.util.oConvertUtils; -import org.jeecg.modules.oss.entity.OSSFile; -import org.jeecg.modules.oss.service.IOSSFileService; +import org.jeecg.modules.oss.entity.OssFile; +import org.jeecg.modules.oss.service.IOssFileService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -26,7 +26,7 @@ import javax.servlet.http.HttpServletRequest; @RequestMapping("/sys/upload") public class SysUploadController { @Autowired - private IOSSFileService ossFileService; + private IOssFileService ossFileService; /** * 上传 @@ -38,7 +38,8 @@ public class SysUploadController { String bizPath = request.getParameter("biz"); //LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞 - if (oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\"))) { + boolean flag = oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\")); + if (flag) { throw new JeecgBootException("上传目录bizPath,格式非法!"); } @@ -51,16 +52,16 @@ public class SysUploadController { // 获取文件名 String orgName = file.getOriginalFilename(); orgName = CommonUtils.getFileName(orgName); - String file_url = MinioUtil.upload(file,bizPath); - if(oConvertUtils.isEmpty(file_url)){ + String fileUrl = MinioUtil.upload(file,bizPath); + if(oConvertUtils.isEmpty(fileUrl)){ return Result.error("上传失败,请检查配置信息是否正确!"); } //保存文件信息 - OSSFile minioFile = new OSSFile(); + OssFile minioFile = new OssFile(); minioFile.setFileName(orgName); - minioFile.setUrl(file_url); + minioFile.setUrl(fileUrl); ossFileService.save(minioFile); - result.setMessage(file_url); + result.setMessage(fileUrl); result.setSuccess(true); return result; } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUserController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUserController.java index 1b2e2d3..9a5d5c8 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUserController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysUserController.java @@ -18,6 +18,7 @@ import org.apache.shiro.authz.annotation.RequiresRoles; import org.jeecg.common.api.vo.Result; import org.jeecg.common.aspect.annotation.PermissionData; import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.modules.base.service.BaseCommonService; import org.jeecg.common.system.query.QueryGenerator; @@ -159,7 +160,7 @@ public class SysUserController { } //@RequiresRoles({"admin"}) - //@RequiresPermissions("user:add") + //Permissions("system:user:add") @RequestMapping(value = "/add", method = RequestMethod.POST) public Result<SysUser> add(@RequestBody JSONObject jsonObject) { Result<SysUser> result = new Result<SysUser>(); @@ -174,6 +175,8 @@ public class SysUserController { user.setPassword(passwordEncode); user.setStatus(1); user.setDelFlag(CommonConstant.DEL_FLAG_0); + //用户表字段org_code不能在这里设置他的值 + user.setOrgCode(null); // 保存用户走一个service 保证事务 sysUserService.saveUser(user, selectedRoles, selectedDeparts); baseCommonService.addLog("添加用户,username: " +user.getUsername() ,CommonConstant.LOG_TYPE_2, 2); @@ -186,7 +189,7 @@ public class SysUserController { } //@RequiresRoles({"admin"}) - //@RequiresPermissions("user:edit") + //Permissions("system:user:edit") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result<SysUser> edit(@RequestBody JSONObject jsonObject) { Result<SysUser> result = new Result<SysUser>(); @@ -206,6 +209,8 @@ public class SysUserController { //vue3.0前端只传递了departIds departs=user.getDepartIds(); } + //用户表字段org_code不能在这里设置他的值 + user.setOrgCode(null); // 修改用户走一个service 保证事务 sysUserService.editUser(user, roles, departs); result.success("修改成功!"); @@ -439,8 +444,13 @@ public class SysUserController { @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, @RequestParam(name = "departId", required = false) String departId, @RequestParam(name="realname",required=false) String realname, - @RequestParam(name="username",required=false) String username) { - IPage<SysUser> pageList = sysUserDepartService.queryDepartUserPageList(departId, username, realname, pageSize, pageNo); + @RequestParam(name="username",required=false) String username, + @RequestParam(name="id",required = false) String id) { + //update-begin-author:taoyan date:2022-7-14 for: VUEN-1702【禁止问题】sql注入漏洞 + String[] arr = new String[]{departId, realname, username, id}; + SqlInjectionUtil.filterContent(arr, SymbolConstant.SINGLE_QUOTATION_MARK); + //update-end-author:taoyan date:2022-7-14 for: VUEN-1702【禁止问题】sql注入漏洞 + IPage<SysUser> pageList = sysUserDepartService.queryDepartUserPageList(departId, username, realname, pageSize, pageNo,id); return Result.OK(pageList); } @@ -450,6 +460,8 @@ public class SysUserController { * @param request * @param sysUser */ + //@RequiresRoles({"admin"}) + //@RequiresPermissions("system:user:export") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(SysUser sysUser,HttpServletRequest request) { // Step.1 组装查询条件 @@ -483,7 +495,7 @@ public class SysUserController { * @return */ //@RequiresRoles({"admin"}) - //@RequiresPermissions("user:import") + //Permissions("system:user:import") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response)throws IOException { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; @@ -1267,6 +1279,15 @@ public class SysUserController { sysUser.setPhone(phone); } if(StringUtils.isNotBlank(email)){ + //update-begin---author:wangshuai ---date:20220708 for:[VUEN-1528]积木官网邮箱重复,应该提示准确------------ + LambdaQueryWrapper<SysUser> emailQuery = new LambdaQueryWrapper<>(); + emailQuery.eq(SysUser::getEmail,email); + long count = sysUserService.count(emailQuery); + if (!email.equals(sysUser.getEmail()) && count!=0) { + result.error500("保存失败,邮箱已存在!"); + return result; + } + //update-end---author:wangshuai ---date:20220708 for:[VUEN-1528]积木官网邮箱重复,应该提示准确-------------- sysUser.setEmail(email); } if(null != birthday){ @@ -1277,7 +1298,7 @@ public class SysUserController { } } catch (Exception e) { log.error(e.getMessage(), e); - result.error500("操作失败!"); + result.error500("保存失败!"); } return result; } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java index 4c93b1e..2082875 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/ThirdAppController.java @@ -246,7 +246,7 @@ public class ThirdAppController { // 第三方app的类型 String app = params.getString("app"); // 消息id - String msg_task_id = params.getString("msg_task_id"); + String msgTaskId = params.getString("msg_task_id"); if (ThirdAppConfig.WECHAT_ENTERPRISE.equals(app)) { if (thirdAppConfig.isWechatEnterpriseEnabled()) { @@ -255,7 +255,7 @@ public class ThirdAppController { return Result.error("企业微信已被禁用"); } else if (ThirdAppConfig.DINGTALK.equals(app)) { if (thirdAppConfig.isDingtalkEnabled()) { - Response<JSONObject> response = dingtalkService.recallMessageResponse(msg_task_id); + Response<JSONObject> response = dingtalkService.recallMessageResponse(msgTaskId); if (response.isSuccess()) { return Result.OK("撤回成功", response); } else { diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java index d7e7c06..56686a4 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java @@ -332,7 +332,10 @@ public class ThirdLoginController { builder.append("&scope=openid"); // 跟随authCode原样返回。 builder.append("&state=").append(state); - url = builder.toString(); + //update-begin---author:wangshuai ---date:20220613 for:[issues/I5BOUF]oauth2 钉钉无法登录------------ + builder.append("&prompt=").append("consent"); + //update-end---author:wangshuai ---date:20220613 for:[issues/I5BOUF]oauth2 钉钉无法登录-------------- + url = builder.toString(); } else { return "不支持的source"; } @@ -377,9 +380,28 @@ public class ThirdLoginController { return "不支持的source"; } try { - String token = saveToken(loginUser); + + //update-begin-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面 + String redirect = ""; + if (state.indexOf("?") > 0) { + String[] arr = state.split("\\?"); + state = arr[0]; + if(arr.length>1){ + redirect = arr[1]; + } + } + + String token = saveToken(loginUser); state += "/oauth2-app/login?oauth2LoginToken=" + URLEncoder.encode(token, "UTF-8"); - state += "&thirdType=" + "wechat_enterprise"; + //update-begin---author:wangshuai ---date:20220613 for:[issues/I5BOUF]oauth2 钉钉无法登录------------ + state += "&thirdType=" + source; + //state += "&thirdType=" + "wechat_enterprise"; + if (redirect != null && redirect.length() > 0) { + state += "&" + redirect; + } + //update-end-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面 + + //update-end---author:wangshuai ---date:20220613 for:[issues/I5BOUF]oauth2 钉钉无法登录------------ log.info("OAuth2登录重定向地址: " + state); try { response.sendRedirect(state); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysRoleIndex.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysRoleIndex.java index 1c744bf..d270fc5 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysRoleIndex.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysRoleIndex.java @@ -40,6 +40,17 @@ public class SysRoleIndex { @Excel(name = "路由地址", width = 15) @ApiModelProperty(value = "路由地址") private java.lang.String url; + /**路由地址*/ + @Excel(name = "路由地址", width = 15) + @ApiModelProperty(value = "组件") + private java.lang.String component; + /** + * 是否路由菜单: 0:不是 1:是(默认值1) + */ + @Excel(name = "是否路由菜单", width = 15) + @ApiModelProperty(value = "是否路由菜单") + @TableField(value="is_route") + private boolean route; /**优先级*/ @Excel(name = "优先级", width = 15) @ApiModelProperty(value = "优先级") @@ -72,4 +83,12 @@ public class SysRoleIndex { @Excel(name = "所属部门", width = 15) @ApiModelProperty(value = "所属部门") private java.lang.String sysOrgCode; + + + public SysRoleIndex() { + + } + public SysRoleIndex(String componentUrl){ + this.component = componentUrl; + } } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysUser.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysUser.java index 74f7fc5..837852e 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysUser.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/entity/SysUser.java @@ -2,6 +2,7 @@ package org.jeecg.modules.system.entity; import java.util.Date; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableLogic; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; @@ -182,4 +183,10 @@ public class SysUser implements Serializable { /**设备id uniapp推送用*/ private String clientId; + + /** + * 登录首页地址 + */ + @TableField(exist = false) + private String homePath; } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java index 135b0bf..17c2cdd 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysDictMapper.java @@ -124,28 +124,28 @@ public interface SysDictMapper extends BaseMapper<SysDict> { @Deprecated public String queryTableDictTextByKey(@Param("table") String table,@Param("text") String text,@Param("code") String code,@Param("key") String key); - /** - * 通过查询指定table的 text code key 获取字典值,可批量查询 - * - * @param table - * @param text - * @param code - * @param keys - * @return - */ - @Deprecated - List<DictModel> queryTableDictTextByKeys(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keys") List<String> keys); +// /** +// * 通过查询指定table的 text code key 获取字典值,可批量查询 +// * +// * @param table +// * @param text +// * @param code +// * @param keys +// * @return +// */ +// @Deprecated +// List<DictModel> queryTableDictTextByKeys(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keys") List<String> keys); - /** - * 通过查询指定table的 text code key 获取字典值,包含value - * @param table - * @param text - * @param code - * @param keyArray - * @return List<DictModel> - */ - @Deprecated - public List<DictModel> queryTableDictByKeys(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyArray") String[] keyArray); +// D /** +//// * 通过查询指定table的 text code key 获取字典值,包含value +//// * @param table +//// * @param text +//// * @param code +//// * @param keyArray +//// * @return List<DictModel> +//// */ +//// @Deprecated +//// public List<DictModel> queryTableictByKeys(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyArray") String[] keyArray); /** * 查询所有部门 作为字典信息 id -->value,departName -->text @@ -159,28 +159,28 @@ public interface SysDictMapper extends BaseMapper<SysDict> { */ public List<DictModel> queryAllUserBackDictModel(); - /** - * 通过关键字查询出字典表 - * @param table - * @param text - * @param code - * @param keyword - * @return - */ - @Deprecated - public List<DictModel> queryTableDictItems(@Param("table") String table,@Param("text") String text,@Param("code") String code,@Param("keyword") String keyword); +// /** +// * 通过关键字查询出字典表 +// * @param table +// * @param text +// * @param code +// * @param keyword +// * @return +// */ +// @Deprecated +// public List<DictModel> queryTableDictItems(@Param("table") String table,@Param("text") String text,@Param("code") String code,@Param("keyword") String keyword); - /** - * 通过关键字查询出字典表 - * @param page - * @param table - * @param text - * @param code - * @param keyword - * @return - */ - IPage<DictModel> queryTableDictItems(Page<DictModel> page, @Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyword") String keyword); +// /** +// * 通过关键字查询出字典表 +// * @param page +// * @param table +// * @param text +// * @param code +// * @param keyword +// * @return +// */ +// //IPage<DictModel> queryTableDictItems(Page<DictModel> page, @Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyword") String keyword); /** * 根据表名、显示字段名、存储字段名 查询树 diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysRoleMapper.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysRoleMapper.java index 83d5a44..00c9607 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysRoleMapper.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/SysRoleMapper.java @@ -18,16 +18,17 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; public interface SysRoleMapper extends BaseMapper<SysRole> { /** - * @Description: 删除角色与用户关系 + * 删除角色与用户关系 * @Author scott * @Date 2019/12/13 16:12 + * @param roleId */ @Delete("delete from sys_user_role where role_id = #{roleId}") void deleteRoleUserRelation(@Param("roleId") String roleId); /** - * @Description: 删除角色与权限关系 + * 删除角色与权限关系 * @Author scott * @param roleId * @Date 2019/12/13 16:12 diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysCategoryMapper.xml b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysCategoryMapper.xml index 71a5e8b..741670c 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysCategoryMapper.xml +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysCategoryMapper.xml @@ -11,9 +11,25 @@ from sys_category where pid = #{pid} <if test="query!= null"> - <foreach collection="query.entrySet()" item="value" index="key" > - and ${key} = #{value} - </foreach> + <if test="query.code !=null and query.code != ''"> + and code = #{query.code} + </if> + + <if test="query.name !=null and query.name != ''"> + and name = #{query.name} + </if> + + <if test="query.id !=null and query.id != ''"> + and id = #{query.id} + </if> + + <if test="query.createBy !=null and query.createBy != ''"> + and create_by = #{query.createBy} + </if> + + <if test="query.sysOrgCode !=null and query.sysOrgCode != ''"> + and sys_org_code = #{query.sysOrgCode} + </if> </if> </select> diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml index 34f3ebe..24d49a2 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml @@ -80,22 +80,22 @@ select ${text} as "text" from ${table} where ${code}= #{key} </select> - <!--通过查询指定table的 text code key 获取字典值,可批量查询--> + <!--通过查询指定table的 text code key 获取字典值,可批量查询 <select id="queryTableDictTextByKeys" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel"> select ${text} as "text", ${code} as "value" from ${table} where ${code} IN ( <foreach item="key" collection="keys" separator=","> #{key} </foreach> ) - </select> + </select>--> - <!--通过查询指定table的 text code key 获取字典值,包含value--> + <!--通过查询指定table的 text code key 获取字典值,包含value <select id="queryTableDictByKeys" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel"> select ${text} as "text", ${code} as "value" from ${table} where ${code} in <foreach item="key" collection="keyArray" open="(" separator="," close=")"> #{key} </foreach> - </select> + </select>--> <!-- 重复校验 sql语句 --> <select id="duplicateCheckCountSql" resultType="Long" parameterType="org.jeecg.modules.system.model.DuplicateCheckVo"> @@ -117,10 +117,10 @@ select username as "value",realname as "text" from sys_user where del_flag = '0' </select> - <!--通过查询指定table的 text code 获取字典数据,且支持关键字查询 --> + <!--通过查询指定table的 text code 获取字典数据,且支持关键字查询 <select id="queryTableDictItems" parameterType="String" resultType="org.jeecg.common.system.vo.DictModel"> select ${text} as "text",${code} as "value" from ${table} where ${text} like #{keyword} - </select> + </select> --> <!-- 根据表名、显示字段名、存储字段名、父ID查询树 --> <select id="queryTreeList" parameterType="Object" resultType="org.jeecg.modules.system.model.TreeSelectModel"> @@ -150,6 +150,16 @@ <foreach collection="query.entrySet()" item="value" index="key" > and ${key} LIKE #{value} </foreach> + <!-- udapte-end-author:sunjianlei date:20220615 for: 【issues/3709】自定义树查询条件没有处理父ID,没有树状结构了 --> + <choose> + <when test="pid != null and pid != ''"> + and ${pidField} = #{pid} + </when> + <otherwise> + and (${pidField} = '' OR ${pidField} IS NULL) + </otherwise> + </choose> + <!-- udapte-end-author:sunjianlei date:20220615 for: 【issues/3709】自定义树查询条件没有处理父ID,没有树状结构了 --> </if> <!-- udapte-end-author:sunjianlei date:20220110 for: 【JTC-597】自定义树查询条件查不出数据 --> </select> diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/model/SysPermissionTree.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/model/SysPermissionTree.java index 3b6ee09..be9b16b 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/model/SysPermissionTree.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/model/SysPermissionTree.java @@ -52,6 +52,11 @@ public class SysPermissionTree implements Serializable { private String component; /** + * 组件名字 + */ + private String componentName; + + /** * 跳转网页链接 */ private String url; @@ -141,6 +146,7 @@ public class SysPermissionTree implements Serializable { this.perms = permission.getPerms(); this.permsType = permission.getPermsType(); this.component = permission.getComponent(); + this.componentName = permission.getComponentName(); this.createBy = permission.getCreateBy(); this.createTime = permission.getCreateTime(); this.delFlag = permission.getDelFlag(); @@ -266,6 +272,14 @@ public class SysPermissionTree implements Serializable { this.component = component; } + public String getComponentName() { + return componentName; + } + + public void setComponentName(String componentName) { + this.componentName = componentName; + } + public String getUrl() { return url; } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/security/DictQueryBlackListHandler.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/security/DictQueryBlackListHandler.java index 279c72a..53f2e7c 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/security/DictQueryBlackListHandler.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/security/DictQueryBlackListHandler.java @@ -1,5 +1,6 @@ package org.jeecg.modules.system.security; +import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.util.oConvertUtils; import org.jeecg.common.util.security.AbstractQueryBlackListHandler; @@ -32,8 +33,9 @@ public class DictQueryBlackListHandler extends AbstractQueryBlackListHandler { QueryTable table = new QueryTable(tableName, ""); // 无论什么场景 第二、三个元素一定是表的字段,直接add table.addField(arr[1].trim()); - if (oConvertUtils.isNotEmpty(arr[2].trim())) { - table.addField(arr[2].trim()); + String filed = arr[2].trim(); + if (oConvertUtils.isNotEmpty(filed)) { + table.addField(filed); } List<QueryTable> list = new ArrayList<>(); list.add(table); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysCategoryService.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysCategoryService.java index 908dfda..6c8b301 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysCategoryService.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysCategoryService.java @@ -20,6 +20,11 @@ public interface ISysCategoryService extends IService<SysCategory> { public static final String ROOT_PID_VALUE = "0"; /** + * 存在子节点 + */ + public static final String HAS_CHILD = "1"; + + /** * 添加分类字典 * @param sysCategory */ diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDataSourceService.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDataSourceService.java index c8f3e04..eab243c 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDataSourceService.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDataSourceService.java @@ -1,6 +1,7 @@ package org.jeecg.modules.system.service; import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.common.api.vo.Result; import org.jeecg.modules.system.entity.SysDataSource; /** @@ -11,4 +12,25 @@ import org.jeecg.modules.system.entity.SysDataSource; */ public interface ISysDataSourceService extends IService<SysDataSource> { + /** + * 添加数据源 + * @param sysDataSource + * @return + */ + Result saveDataSource(SysDataSource sysDataSource); + + /** + * 修改数据源 + * @param sysDataSource + * @return + */ + Result editDataSource(SysDataSource sysDataSource); + + + /** + * 删除数据源 + * @param id + * @return + */ + Result deleteDataSource(String id); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDepartService.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDepartService.java index 5e52ef2..7cff1ce 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDepartService.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDepartService.java @@ -127,9 +127,10 @@ public interface ISysDepartService extends IService<SysDepart>{ * 获取我的部门下级所有部门 * @param parentId 父id * @param ids 多个部门id + * @param primaryKey 主键字段(id或者orgCode) * @return */ - List<SysDepartTreeModel> queryTreeListByPid(String parentId,String ids); + List<SysDepartTreeModel> queryTreeListByPid(String parentId,String ids, String primaryKey); /** * 获取某个部门的所有父级部门的ID diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDictService.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDictService.java index b08a9d3..7f9bc9e 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDictService.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysDictService.java @@ -158,16 +158,16 @@ public interface ISysDictService extends IService<SysDict> { */ public List<DictModel> queryAllUserBackDictModel(); - /** - * 通过关键字查询字典表 - * @param table - * @param text - * @param code - * @param keyword - * @return - */ - @Deprecated - public List<DictModel> queryTableDictItems(String table, String text, String code,String keyword); +// /** +// * 通过关键字查询字典表 +// * @param table +// * @param text +// * @param code +// * @param keyword +// * @return +// */ +// @Deprecated +// public List<DictModel> queryTableDictItems(String table, String text, String code,String keyword); /** * 查询字典表数据 只查询前10条 @@ -179,6 +179,7 @@ public interface ISysDictService extends IService<SysDict> { * @param pageSize 每页条数 * @return */ + @Deprecated public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize); /** @@ -190,6 +191,7 @@ public interface ISysDictService extends IService<SysDict> { * @param keyword * @return */ + @Deprecated public List<DictModel> queryAllTableDictItems(String table, String text, String code, String condition, String keyword); /** * 根据表名、显示字段名、存储字段名 查询树 diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java index e368942..72eaaa5 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysUserDepartService.java @@ -49,8 +49,10 @@ public interface ISysUserDepartService extends IService<SysUserDepart> { * @param username * @param pageSize * @param pageNo + * @param realname + * @param id * @return */ - IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo); + IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo,String id); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysUserService.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysUserService.java index 70c880a..3ef056f 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysUserService.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/ISysUserService.java @@ -6,7 +6,9 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.system.vo.SysUserCacheInfo; +import org.jeecg.modules.system.entity.SysRoleIndex; import org.jeecg.modules.system.entity.SysUser; import org.jeecg.modules.system.model.SysUserSysDepartModel; import org.springframework.transaction.annotation.Transactional; @@ -87,12 +89,22 @@ public interface ISysUserService extends IService<SysUser> { * @return */ public List<String> getRole(String username); + + /** + * 获取根据登录用户的角色获取动态首页 + * + * @param username + * @param version 前端UI版本 + * @return + */ + public SysRoleIndex getDynamicIndexByUserRole(String username,String version); /** * 查询用户信息包括 部门信息 * @param username * @return */ + @Deprecated public SysUserCacheInfo getCacheUser(String username); /** @@ -175,6 +187,7 @@ public interface ISysUserService extends IService<SysUser> { /** * 根据手机号获取用户名和密码 * @param phone 手机号 + * @return SysUser */ public SysUser getUserByPhone(String phone); @@ -280,4 +293,12 @@ public interface ISysUserService extends IService<SysUser> { */ List<String> userIdToUsername(Collection<String> userIdList); + + /** + * 获取用户信息 字段信息是加密后的 【加密用户信息】 + * @param username + * @return + */ + LoginUser getEncodeUserInfo(String username); + } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java index 7e34096..9223a91 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysBaseApiImpl.java @@ -1,4 +1,5 @@ package org.jeecg.modules.system.service.impl; + import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -14,19 +15,22 @@ import org.apache.shiro.SecurityUtils; import org.jeecg.common.api.dto.OnlineAuthDTO; import org.jeecg.common.api.dto.message.*; import org.jeecg.common.aspect.UrlMatchEnum; -import org.jeecg.common.constant.CacheConstant; -import org.jeecg.common.constant.CommonConstant; -import org.jeecg.common.constant.DataBaseConstant; -import org.jeecg.common.constant.WebsocketConst; +import org.jeecg.common.constant.*; +import org.jeecg.common.constant.enums.MessageTypeEnum; +import org.jeecg.common.desensitization.util.SensitiveInfoUtil; import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.*; import org.jeecg.common.util.SysAnnmentTypeEnum; import org.jeecg.common.util.YouBianCodeUtil; +import org.jeecg.common.util.dynamic.db.FreemarkerParseFactory; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.message.entity.SysMessageTemplate; +import org.jeecg.modules.message.handle.impl.DdSendMsgHandle; import org.jeecg.modules.message.handle.impl.EmailSendMsgHandle; +import org.jeecg.modules.message.handle.impl.QywxSendMsgHandle; +import org.jeecg.modules.message.handle.impl.SystemSendMsgHandle; import org.jeecg.modules.message.service.ISysMessageTemplateService; import org.jeecg.modules.message.websocket.WebSocket; import org.jeecg.modules.system.entity.*; @@ -58,11 +62,10 @@ import java.util.*; public class SysBaseApiImpl implements ISysBaseAPI { /** 当前系统数据库类型 */ private static String DB_TYPE = ""; + @Autowired private ISysMessageTemplateService sysMessageTemplateService; @Resource - private SysLogMapper sysLogMapper; - @Resource private SysUserMapper userMapper; @Resource private SysUserRoleMapper sysUserRoleMapper; @@ -82,7 +85,6 @@ public class SysBaseApiImpl implements ISysBaseAPI { private SysDepartMapper departMapper; @Resource private SysCategoryMapper categoryMapper; - @Autowired private ISysDataSourceService dataSourceService; @Autowired @@ -91,28 +93,33 @@ public class SysBaseApiImpl implements ISysBaseAPI { private SysPermissionMapper sysPermissionMapper; @Autowired private ISysPermissionDataRuleService sysPermissionDataRuleService; - @Autowired private ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService; @Autowired private ThirdAppDingtalkServiceImpl dingtalkService; - @Autowired ISysCategoryService sysCategoryService; + @Autowired + private ISysUserService sysUserService; @Override - @Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username") + //@SensitiveDecode public LoginUser getUserByName(String username) { - if(oConvertUtils.isEmpty(username)) { + //update-begin-author:taoyan date:2022-6-6 for: VUEN-1276 【v3流程图】测试bug 1、通过我发起的流程或者流程实例,查看历史,流程图预览问题 + if (oConvertUtils.isEmpty(username)) { return null; } - LoginUser loginUser = new LoginUser(); - SysUser sysUser = userMapper.getUserByName(username); - if(sysUser==null) { - return null; + //update-end-author:taoyan date:2022-6-6 for: VUEN-1276 【v3流程图】测试bug 1、通过我发起的流程或者流程实例,查看历史,流程图预览问题 + LoginUser user = sysUserService.getEncodeUserInfo(username); + + //相同类中方法间调用时脱敏解密 Aop会失效,获取用户信息太重要,此处采用原生解密方法,不采用@SensitiveDecodeAble注解方式 + try { + SensitiveInfoUtil.handlerObject(user, false); + } catch (IllegalAccessException e) { + e.printStackTrace(); } - BeanUtils.copyProperties(sysUser, loginUser); - return loginUser; + + return user; } @Override @@ -204,6 +211,14 @@ public class SysBaseApiImpl implements ISysBaseAPI { SysUserCacheInfo info = new SysUserCacheInfo(); info.setOneDepart(true); LoginUser user = this.getUserByName(username); + +// try { +// //相同类中方法间调用时脱敏@SensitiveDecodeAble解密 Aop失效处理 +// SensitiveInfoUtil.handlerObject(user, false); +// } catch (IllegalAccessException e) { +// e.printStackTrace(); +// } + if(user!=null) { info.setSysUserCode(user.getUsername()); info.setSysUserName(user.getRealname()); @@ -290,7 +305,7 @@ public class SysBaseApiImpl implements ISysBaseAPI { @Override public List<DictModel> queryTableDictItemsByCode(String table, String text, String code) { //update-begin-author:taoyan date:20200820 for:【Online+系统】字典表加权限控制机制逻辑,想法不错 LOWCOD-799 - if(table.indexOf("#{")>=0){ + if(table.indexOf(SymbolConstant.SYS_VAR_PREFIX)>=0){ table = QueryGenerator.getSqlRuleValue(table); } //update-end-author:taoyan date:20200820 for:【Online+系统】字典表加权限控制机制逻辑,想法不错 LOWCOD-799 @@ -528,15 +543,15 @@ public class SysBaseApiImpl implements ISysBaseAPI { try { DatabaseMetaData md = connection.getMetaData(); String dbType = md.getDatabaseProductName().toLowerCase(); - if(dbType.indexOf("mysql")>=0) { + if(dbType.indexOf(DataBaseConstant.DB_TYPE_MYSQL.toLowerCase())>=0) { DB_TYPE = DataBaseConstant.DB_TYPE_MYSQL; - }else if(dbType.indexOf("oracle")>=0) { + }else if(dbType.indexOf(DataBaseConstant.DB_TYPE_ORACLE.toLowerCase())>=0) { DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE; - }else if(dbType.indexOf("sqlserver")>=0||dbType.indexOf("sql server")>=0) { + }else if(dbType.indexOf(DataBaseConstant.DB_TYPE_SQLSERVER.toLowerCase())>=0||dbType.indexOf(DataBaseConstant.DB_TYPE_SQL_SERVER_BLANK)>=0) { DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER; - }else if(dbType.indexOf("postgresql")>=0) { + }else if(dbType.indexOf(DataBaseConstant.DB_TYPE_POSTGRESQL.toLowerCase())>=0) { DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL; - }else if(dbType.indexOf("mariadb")>=0) { + }else if(dbType.indexOf(DataBaseConstant.DB_TYPE_MARIADB.toLowerCase())>=0) { DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB; }else { log.error("数据库类型:[" + dbType + "]不识别!"); @@ -777,6 +792,8 @@ public class SysBaseApiImpl implements ISysBaseAPI { if(userDepartList != null){ //查找所属公司 String orgCodes = ""; + StringBuilder orgCodesBuilder = new StringBuilder(); + orgCodesBuilder.append(orgCodes); for(SysUserDepart userDepart : userDepartList){ //查询所属公司编码 SysDepart depart = sysDepartService.getById(userDepart.getDepId()); @@ -785,10 +802,11 @@ public class SysBaseApiImpl implements ISysBaseAPI { if(depart != null && depart.getOrgCode() != null){ compyOrgCode = depart.getOrgCode().substring(0,length); if(orgCodes.indexOf(compyOrgCode) == -1){ - orgCodes = orgCodes + "," + compyOrgCode; + orgCodesBuilder.append(SymbolConstant.COMMA).append(compyOrgCode); } } } + orgCodes = orgCodesBuilder.toString(); if(oConvertUtils.isNotEmpty(orgCodes)){ orgCodes = orgCodes.substring(1); List<String> listIds = departMapper.getSubDepIdsByOrgCodes(orgCodes.split(",")); @@ -1037,7 +1055,7 @@ public class SysBaseApiImpl implements ISysBaseAPI { @Override public void sendEmailMsg(String email, String title, String content) { EmailSendMsgHandle emailHandle=new EmailSendMsgHandle(); - emailHandle.SendMsg(email, title, content); + emailHandle.sendMsg(email, title, content); } /** @@ -1154,4 +1172,54 @@ public class SysBaseApiImpl implements ISysBaseAPI { return sysDictService.queryTableDictTextByKeys(table, text, code, Arrays.asList(keys.split(","))); } + //-------------------------------------流程节点发送模板消息----------------------------------------------- + @Autowired + private QywxSendMsgHandle qywxSendMsgHandle; + + @Autowired + private SystemSendMsgHandle systemSendMsgHandle; + + @Autowired + private EmailSendMsgHandle emailSendMsgHandle; + + @Autowired + private DdSendMsgHandle ddSendMsgHandle; + + @Override + public void sendTemplateMessage(MessageDTO message) { + String messageType = message.getType(); + //update-begin-author:taoyan date:2022-7-9 for: 将模板解析代码移至消息发送, 而不是调用的地方 + String templateCode = message.getTemplateCode(); + if(oConvertUtils.isNotEmpty(templateCode)){ + String content = getTemplateContent(templateCode); + if(oConvertUtils.isNotEmpty(content) && null!=message.getData()){ + content = FreemarkerParseFactory.parseTemplateContent(content, message.getData()); + } + message.setContent(content); + } + if(oConvertUtils.isEmpty(message.getContent())){ + throw new JeecgBootException("发送消息失败,消息内容为空!"); + } + //update-end-author:taoyan date:2022-7-9 for: 将模板解析代码移至消息发送, 而不是调用的地方 + if(MessageTypeEnum.XT.getType().equals(messageType)){ + systemSendMsgHandle.sendMessage(message); + }else if(MessageTypeEnum.YJ.getType().equals(messageType)){ + emailSendMsgHandle.sendMessage(message); + }else if(MessageTypeEnum.DD.getType().equals(messageType)){ + ddSendMsgHandle.sendMessage(message); + }else if(MessageTypeEnum.QYWX.getType().equals(messageType)){ + qywxSendMsgHandle.sendMessage(message); + } + } + + @Override + public String getTemplateContent(String code) { + List<SysMessageTemplate> list = sysMessageTemplateService.selectByCode(code); + if(list==null || list.size()==0){ + return null; + } + return list.get(0).getTemplateContent(); + } + //-------------------------------------流程节点发送模板消息----------------------------------------------- + } \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysCategoryServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysCategoryServiceImpl.java index 1c0401c..437be4e 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysCategoryServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysCategoryServiceImpl.java @@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.FillRuleConstant; +import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.util.FillRuleUtil; import org.jeecg.common.util.oConvertUtils; @@ -43,8 +45,8 @@ public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCa if(!ISysCategoryService.ROOT_PID_VALUE.equals(categoryPid)){ SysCategory parent = baseMapper.selectById(categoryPid); parentCode = parent.getCode(); - if(parent!=null && !"1".equals(parent.getHasChild())){ - parent.setHasChild("1"); + if(parent!=null && !ISysCategoryService.HAS_CHILD.equals(parent.getHasChild())){ + parent.setHasChild(ISysCategoryService.HAS_CHILD); baseMapper.updateById(parent); } } @@ -66,8 +68,8 @@ public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCa }else{ //如果当前节点父ID不为空 则设置父节点的hasChild 为1 SysCategory parent = baseMapper.selectById(sysCategory.getPid()); - if(parent!=null && !"1".equals(parent.getHasChild())){ - parent.setHasChild("1"); + if(parent!=null && !ISysCategoryService.HAS_CHILD.equals(parent.getHasChild())){ + parent.setHasChild(ISysCategoryService.HAS_CHILD); baseMapper.updateById(parent); } } @@ -170,14 +172,15 @@ public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCa queryWrapper.eq(SysCategory::getPid,metaPid); queryWrapper.notIn(SysCategory::getId,Arrays.asList(idArr)); List<SysCategory> dataList = this.baseMapper.selectList(queryWrapper); - if((dataList == null || dataList.size()==0) && !Arrays.asList(idArr).contains(metaPid) - && !sb.toString().contains(metaPid)){ + boolean flag = (dataList == null || dataList.size()==0) && !Arrays.asList(idArr).contains(metaPid) + && !sb.toString().contains(metaPid); + if(flag){ //如果当前节点原本有子节点 现在木有了,更新状态 sb.append(metaPid).append(","); } } } - if(sb.toString().endsWith(",")){ + if(sb.toString().endsWith(SymbolConstant.COMMA)){ sb = sb.deleteCharAt(sb.length() - 1); } return sb.toString(); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDataSourceServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDataSourceServiceImpl.java index 048e63e..f3052ec 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDataSourceServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDataSourceServiceImpl.java @@ -1,11 +1,22 @@ package org.jeecg.modules.system.service.impl; +import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; +import com.baomidou.dynamic.datasource.creator.DruidDataSourceCreator; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.lang.StringUtils; +import org.jeecg.common.api.vo.Result; +import org.jeecg.common.util.dynamic.db.DataSourceCachePool; import org.jeecg.modules.system.entity.SysDataSource; import org.jeecg.modules.system.mapper.SysDataSourceMapper; import org.jeecg.modules.system.service.ISysDataSourceService; +import org.jeecg.modules.system.util.SecurityUtil; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import javax.sql.DataSource; + /** * @Description: 多数据源管理 * @Author: jeecg-boot @@ -15,4 +26,106 @@ import org.springframework.stereotype.Service; @Service public class SysDataSourceServiceImpl extends ServiceImpl<SysDataSourceMapper, SysDataSource> implements ISysDataSourceService { + @Autowired + private DruidDataSourceCreator dataSourceCreator; + + @Autowired + private DataSource dataSource; + + @Override + public Result saveDataSource(SysDataSource sysDataSource) { + try { + long count = checkDbCode(sysDataSource.getCode()); + if (count > 0) { + return Result.error("数据源编码已存在"); + } + String dbPassword = sysDataSource.getDbPassword(); + if (StringUtils.isNotBlank(dbPassword)) { + String encrypt = SecurityUtil.jiami(dbPassword); + sysDataSource.setDbPassword(encrypt); + } + boolean result = save(sysDataSource); + if (result) { + //动态创建数据源 + //addDynamicDataSource(sysDataSource, dbPassword); + } + } catch (Exception e) { + e.printStackTrace(); + } + return Result.OK("添加成功!"); + } + + @Override + public Result editDataSource(SysDataSource sysDataSource) { + try { + SysDataSource d = getById(sysDataSource.getId()); + DataSourceCachePool.removeCache(d.getCode()); + String dbPassword = sysDataSource.getDbPassword(); + if (StringUtils.isNotBlank(dbPassword)) { + String encrypt = SecurityUtil.jiami(dbPassword); + sysDataSource.setDbPassword(encrypt); + } + Boolean result=updateById(sysDataSource); + if(result){ + //先删除老的数据源 + // removeDynamicDataSource(d.getCode()); + //添加新的数据源 + //addDynamicDataSource(sysDataSource,dbPassword); + } + } catch (Exception e) { + e.printStackTrace(); + } + return Result.OK("编辑成功!"); + } + + @Override + public Result deleteDataSource(String id) { + SysDataSource sysDataSource = getById(id); + DataSourceCachePool.removeCache(sysDataSource.getCode()); + removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 动态添加数据源 【注册mybatis动态数据源】 + * + * @param sysDataSource 添加数据源数据对象 + * @param dbPassword 未加密的密码 + */ + private void addDynamicDataSource(SysDataSource sysDataSource, String dbPassword) { + DataSourceProperty dataSourceProperty = new DataSourceProperty(); + dataSourceProperty.setUrl(sysDataSource.getDbUrl()); + dataSourceProperty.setPassword(dbPassword); + dataSourceProperty.setDriverClassName(sysDataSource.getDbDriver()); + dataSourceProperty.setUsername(sysDataSource.getDbUsername()); + DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource; + DataSource dataSource = dataSourceCreator.createDataSource(dataSourceProperty); + try { + ds.addDataSource(sysDataSource.getCode(), dataSource); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除数据源 + * @param code + */ + private void removeDynamicDataSource(String code) { + DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource; + ds.removeDataSource(code); + } + + /** + * 检查数据源编码是否存在 + * + * @param dbCode + * @return + */ + private long checkDbCode(String dbCode) { + QueryWrapper<SysDataSource> qw = new QueryWrapper(); + qw.lambda().eq(true, SysDataSource::getCode, dbCode); + return count(qw); + } + } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java index 5de598d..3b3aa21 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDepartServiceImpl.java @@ -10,6 +10,7 @@ import org.apache.commons.lang.StringUtils; import org.jeecg.common.constant.CacheConstant; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.FillRuleConstant; +import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.util.FillRuleUtil; import org.jeecg.common.util.YouBianCodeUtil; import org.jeecg.common.util.oConvertUtils; @@ -469,14 +470,14 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart */ private String getMinLengthNode(String[] str){ int min =str[0].length(); - String orgCode = str[0]; + StringBuilder orgCodeBuilder = new StringBuilder(str[0]); for(int i =1;i<str.length;i++){ if(str[i].length()<=min){ min = str[i].length(); - orgCode = orgCode+","+str[i]; + orgCodeBuilder.append(SymbolConstant.COMMA).append(str[i]); } } - return orgCode; + return orgCodeBuilder.toString(); } /** * 获取部门树信息根据关键字 @@ -504,13 +505,18 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart * 根据parentId查询部门树 * @param parentId * @param ids 前端回显传递 + * @param primaryKey 主键字段(id或者orgCode) * @return */ @Override - public List<SysDepartTreeModel> queryTreeListByPid(String parentId,String ids) { + public List<SysDepartTreeModel> queryTreeListByPid(String parentId,String ids, String primaryKey) { Consumer<LambdaQueryWrapper<SysDepart>> square = i -> { if (oConvertUtils.isNotEmpty(ids)) { - i.in(SysDepart::getId, ids.split(",")); + if (CommonConstant.DEPART_KEY_ORG_CODE.equals(primaryKey)) { + i.in(SysDepart::getOrgCode, ids.split(SymbolConstant.COMMA)); + } else { + i.in(SysDepart::getId, ids.split(SymbolConstant.COMMA)); + } } else { if(oConvertUtils.isEmpty(parentId)){ i.and(q->q.isNull(true,SysDepart::getParentId).or().eq(true,SysDepart::getParentId,"")); @@ -519,10 +525,12 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart } } }; - LambdaQueryWrapper<SysDepart> lqw=new LambdaQueryWrapper(); + LambdaQueryWrapper<SysDepart> lqw=new LambdaQueryWrapper<>(); lqw.eq(true,SysDepart::getDelFlag,CommonConstant.DEL_FLAG_0.toString()); lqw.func(square); - lqw.orderByDesc(SysDepart::getDepartOrder); + //update-begin---author:wangshuai ---date:20220527 for:[VUEN-1143]排序不对,vue3和2应该都有问题,应该按照升序排------------ + lqw.orderByAsc(SysDepart::getDepartOrder); + //update-end---author:wangshuai ---date:20220527 for:[VUEN-1143]排序不对,vue3和2应该都有问题,应该按照升序排-------------- List<SysDepart> list = list(lqw); //update-begin---author:wangshuai ---date:20220316 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理 //设置用户id,让前台显示 @@ -549,7 +557,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart @Override public JSONObject queryAllParentIdByDepartId(String departId) { JSONObject result = new JSONObject(); - for (String id : departId.split(",")) { + for (String id : departId.split(SymbolConstant.COMMA)) { JSONObject all = this.queryAllParentId("id", id); result.put(id, all); } @@ -559,7 +567,7 @@ public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart @Override public JSONObject queryAllParentIdByOrgCode(String orgCode) { JSONObject result = new JSONObject(); - for (String code : orgCode.split(",")) { + for (String code : orgCode.split(SymbolConstant.COMMA)) { JSONObject all = this.queryAllParentId("org_code", code); result.put(code, all); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java index 6662166..c1fe226 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysDictServiceImpl.java @@ -7,8 +7,11 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.jeecg.common.constant.CacheConstant; import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.constant.DataBaseConstant; +import org.jeecg.common.constant.SymbolConstant; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.util.JwtUtil; +import org.jeecg.common.system.util.ResourceUtil; import org.jeecg.common.system.vo.DictModel; import org.jeecg.common.system.vo.DictModelMany; import org.jeecg.common.system.vo.DictQuery; @@ -25,10 +28,7 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -97,6 +97,10 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl }).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; } @@ -123,6 +127,10 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl List<DictModel> dictItemList = dictMap.computeIfAbsent(dict.getDictCode(), i -> new ArrayList<>()); dictItemList.add(new DictModel(dict.getValue(), dict.getText())); } + //update-begin-author:taoyan date:2022-7-8 for: 系统字典数据应该包括自定义的java类-枚举 + Map<String, List<DictModel>> enumRes = ResourceUtil.queryManyDictByKeys(dictCodeList, keys); + dictMap.putAll(enumRes); + //update-end-author:taoyan date:2022-7-8 for: 系统字典数据应该包括自定义的java类-枚举 return dictMap; } @@ -167,7 +175,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl public List<DictModel> queryTableDictTextByKeys(String table, String text, String code, List<String> keys) { //update-begin-author:taoyan date:20220113 for: @dict注解支持 dicttable 设置where条件 String filterSql = null; - if(table.toLowerCase().indexOf("where")>0){ + if(table.toLowerCase().indexOf(DataBaseConstant.SQL_WHERE)>0){ String[] arr = table.split(" (?i)where "); table = arr[0]; filterSql = arr[1]; @@ -200,7 +208,16 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl return null; } String[] keyArray = keys.split(","); - List<DictModel> dicts = sysDictMapper.queryTableDictByKeys(table, text, code, keyArray); + + //update-begin-author:taoyan date:2022-4-24 for: 下拉搜索组件,表单编辑页面回显下拉搜索的文本的时候,因为表名后配置了条件,导致sql执行失败, + String filterSql = null; + if(table.toLowerCase().indexOf("where")!=-1){ + String[] arr = table.split(" (?i)where "); + table = arr[0]; + filterSql = arr[1]; + } + List<DictModel> dicts = sysDictMapper.queryTableDictByKeysAndFilterSql(table, text, code, filterSql, Arrays.asList(keyArray)); + //update-end-author:taoyan date:2022-4-24 for: 下拉搜索组件,表单编辑页面回显下拉搜索的文本的时候,因为表名后配置了条件,导致sql执行失败, List<String> texts = new ArrayList<>(dicts.size()); // update-begin--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ---- @@ -261,15 +278,19 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl return baseMapper.queryAllUserBackDictModel(); } - @Override - public List<DictModel> queryTableDictItems(String table, String text, String code, String keyword) { - return baseMapper.queryTableDictItems(table, text, code, "%"+keyword+"%"); - } +// @Override +// public List<DictModel> queryTableDictItems(String table, String text, String code, String keyword) { +// return baseMapper.queryTableDictItems(table, text, code, "%"+keyword+"%"); +// } @Override public List<DictModel> queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize) { Page<DictModel> page = new Page<DictModel>(1, pageSize); page.setSearchCount(false); + + //【issues/3713】字典接口存在SQL注入风险 + SqlInjectionUtil.specialFilterContentForDictSql(code); + String filterSql = getFilterSql(table, text, code, condition, keyword); IPage<DictModel> pageList = baseMapper.queryTableDictWithFilter(page, table, text, code, filterSql); return pageList.getRecords(); @@ -284,15 +305,15 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl * @return */ private String getFilterSql(String table, String text, String code, String condition, String keyword){ - String keywordSql = null, filterSql = "", sql_where = " where "; + String keywordSql = null, filterSql = "", sqlWhere = " where "; // update-begin-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错 - if (table.toLowerCase().contains(" where ")) { - sql_where = " and "; + if (table.toLowerCase().contains(sqlWhere)) { + sqlWhere = " and "; } // update-end-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错 if(oConvertUtils.isNotEmpty(keyword)){ // 判断是否是多选 - if (keyword.contains(",")) { + if (keyword.contains(SymbolConstant.COMMA)) { //update-begin--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致 ---- String inKeywords = "'" + String.join("','", keyword.split(",")) + "'"; //update-end--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致---- @@ -302,11 +323,11 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl } } if(oConvertUtils.isNotEmpty(condition) && oConvertUtils.isNotEmpty(keywordSql)){ - filterSql+= sql_where + condition + " and " + keywordSql; + filterSql+= sqlWhere + condition + " and " + keywordSql; }else if(oConvertUtils.isNotEmpty(condition)){ - filterSql+= sql_where + condition; + filterSql+= sqlWhere + condition; }else if(oConvertUtils.isNotEmpty(keywordSql)){ - filterSql+= sql_where + keywordSql; + filterSql+= sqlWhere + keywordSql; } return filterSql; } @@ -319,13 +340,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl @Override public List<TreeSelectModel> queryTreeList(Map<String, String> query,String table, String text, String code, String pidField,String pid,String hasChildField) { - List<TreeSelectModel> result = baseMapper.queryTreeList(query, table, text, code, pidField, pid, hasChildField); - // udapte-begin-author:sunjianlei date:20220110 for: 【JTC-597】如果 query 有值,就不允许展开子节点 - if (query != null) { - result.forEach(r -> r.setLeaf(true)); - } - return result; - // udapte-end-author:sunjianlei date:20220110 for: 【JTC-597】如果 query 有值,就不允许展开子节点 + return baseMapper.queryTreeList(query, table, text, code, pidField, pid, hasChildField); } @Override @@ -354,7 +369,7 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl @Override public List<DictModel> getDictItems(String dictCode) { List<DictModel> ls; - if (dictCode.contains(",")) { + if (dictCode.contains(SymbolConstant.COMMA)) { //关联表字典(举例:sys_user,realname,id) String[] params = dictCode.split(","); if (params.length < 3) { @@ -362,11 +377,16 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl return null; } //SQL注入校验(只限制非法串改数据库) - final String[] sqlInjCheck = {params[0], params[1], params[2]}; + //update-begin-author:taoyan date:2022-7-4 for: issues/I5BNY9 指定带过滤条件的字典table在生成代码后失效 + // 表名后也有可能带条件and语句 不能走filterContent方法 + SqlInjectionUtil.specialFilterContentForDictSql(params[0]); + final String[] sqlInjCheck = {params[1], params[2]}; + //update-end-author:taoyan date:2022-7-4 for: issues/I5BNY9 指定带过滤条件的字典table在生成代码后失效 + //【issues/3713】字典接口存在SQL注入风险 SqlInjectionUtil.filterContent(sqlInjCheck); if (params.length == 4) { // SQL注入校验(查询条件SQL 特殊check,此方法仅供此处使用) - SqlInjectionUtil.specialFilterContent(params[3]); + SqlInjectionUtil.specialFilterContentForDictSql(params[3]); ls = this.queryTableDictItemsByCodeAndFilter(params[0], params[1], params[2], params[3]); } else if (params.length == 3) { ls = this.queryTableDictItemsByCode(params[0], params[1], params[2]); @@ -383,7 +403,10 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl @Override public List<DictModel> loadDict(String dictCode, String keyword, Integer pageSize) { - if (dictCode.contains(",")) { + //【issues/3713】字典接口存在SQL注入风险 + SqlInjectionUtil.specialFilterContentForDictSql(dictCode); + + if (dictCode.contains(SymbolConstant.COMMA)) { //update-begin-author:taoyan date:20210329 for: 下拉搜索不支持表名后加查询条件 String[] params = dictCode.split(","); String condition = null; @@ -393,11 +416,16 @@ public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> impl } else if (params.length == 4) { condition = params[3]; // update-begin-author:taoyan date:20220314 for: online表单下拉搜索框表字典配置#{sys_org_code}报错 #3500 - if(condition.indexOf("#{")>=0){ + if(condition.indexOf(SymbolConstant.SYS_VAR_PREFIX)>=0){ condition = QueryGenerator.getSqlRuleValue(condition); } // update-end-author:taoyan date:20220314 for: online表单下拉搜索框表字典配置#{sys_org_code}报错 #3500 } + + // 字典Code格式不正确 [表名为空] + if(oConvertUtils.isEmpty(params[0])){ + return null; + } List<DictModel> ls; if (pageSize != null) { ls = this.queryLittleTableDictItems(params[0], params[1], params[2], condition, keyword, pageSize); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysGatewayRouteServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysGatewayRouteServiceImpl.java index 18c3649..1853103 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysGatewayRouteServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysGatewayRouteServiceImpl.java @@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.jeecg.common.base.BaseMap; import org.jeecg.common.constant.CacheConstant; +import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.constant.GlobalConstants; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.system.entity.SysGatewayRoute; @@ -35,6 +36,7 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl<SysGatewayRouteMappe @Autowired private RedisTemplate<String, Object> redisTemplate; + private static final String STRING_STATUS = "status"; @Override public void addRoute2Redis(String key) { @@ -75,10 +77,10 @@ public class SysGatewayRouteServiceImpl extends ServiceImpl<SysGatewayRouteMappe } route.setFilters(filters); route.setUri(json.getString("uri")); - if (json.get("status") == null) { + if (json.get(STRING_STATUS) == null) { route.setStatus(1); } else { - route.setStatus(json.getInteger("status")); + route.setStatus(json.getInteger(STRING_STATUS)); } this.saveOrUpdate(route); resreshRouter(null); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysLogServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysLogServiceImpl.java index e9b561d..e226c3c 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysLogServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysLogServiceImpl.java @@ -31,8 +31,6 @@ public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> impleme @Resource private SysLogMapper sysLogMapper; - @Autowired - private SysBaseApiImpl sysBaseAPI; /** * @功能:清空所有日志记录 diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionDataRuleImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionDataRuleImpl.java index 69b7c12..be7c3f7 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionDataRuleImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionDataRuleImpl.java @@ -88,7 +88,8 @@ public class SysPermissionDataRuleImpl extends ServiceImpl<SysPermissionDataRule public void savePermissionDataRule(SysPermissionDataRule sysPermissionDataRule) { this.save(sysPermissionDataRule); SysPermission permission = sysPermissionMapper.selectById(sysPermissionDataRule.getPermissionId()); - if(permission!=null && (permission.getRuleFlag()==null || permission.getRuleFlag().equals(CommonConstant.RULE_FLAG_0))) { + boolean flag = permission != null && (permission.getRuleFlag() == null || permission.getRuleFlag().equals(CommonConstant.RULE_FLAG_0)); + if(flag) { permission.setRuleFlag(CommonConstant.RULE_FLAG_1); sysPermissionMapper.updateById(permission); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java index 88b93ff..f40c163 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysPermissionServiceImpl.java @@ -200,7 +200,8 @@ public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, S //如果当前菜单的父菜单变了,则需要修改新父菜单和老父菜单的,叶子节点状态 String pid = sysPermission.getParentId(); - if((oConvertUtils.isNotEmpty(pid) && !pid.equals(p.getParentId())) || oConvertUtils.isEmpty(pid)&&oConvertUtils.isNotEmpty(p.getParentId())) { + boolean flag = (oConvertUtils.isNotEmpty(pid) && !pid.equals(p.getParentId())) || oConvertUtils.isEmpty(pid)&&oConvertUtils.isNotEmpty(p.getParentId()); + if (flag) { //a.设置新的父菜单不为叶子节点 this.sysPermissionMapper.setMenuLeaf(pid, 0); //b.判断老的菜单下是否还有其他子菜单,没有的话则设置为叶子节点 diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java index 4089360..4749c2e 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysUserDepartServiceImpl.java @@ -44,13 +44,13 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S */ @Override public List<DepartIdModel> queryDepartIdsOfUser(String userId) { - LambdaQueryWrapper<SysUserDepart> queryUDep = new LambdaQueryWrapper<SysUserDepart>(); + LambdaQueryWrapper<SysUserDepart> queryUserDep = new LambdaQueryWrapper<SysUserDepart>(); LambdaQueryWrapper<SysDepart> queryDep = new LambdaQueryWrapper<SysDepart>(); try { - queryUDep.eq(SysUserDepart::getUserId, userId); + queryUserDep.eq(SysUserDepart::getUserId, userId); List<String> depIdList = new ArrayList<>(); List<DepartIdModel> depIdModelList = new ArrayList<>(); - List<SysUserDepart> userDepList = this.list(queryUDep); + List<SysUserDepart> userDepList = this.list(queryUserDep); if(userDepList != null && userDepList.size() > 0) { for(SysUserDepart userDepart : userDepList) { depIdList.add(userDepart.getDepId()); @@ -78,10 +78,10 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S */ @Override public List<SysUser> queryUserByDepId(String depId) { - LambdaQueryWrapper<SysUserDepart> queryUDep = new LambdaQueryWrapper<SysUserDepart>(); - queryUDep.eq(SysUserDepart::getDepId, depId); + LambdaQueryWrapper<SysUserDepart> queryUserDep = new LambdaQueryWrapper<SysUserDepart>(); + queryUserDep.eq(SysUserDepart::getDepId, depId); List<String> userIdList = new ArrayList<>(); - List<SysUserDepart> uDepList = this.list(queryUDep); + List<SysUserDepart> uDepList = this.list(queryUserDep); if(uDepList != null && uDepList.size() > 0) { for(SysUserDepart uDep : uDepList) { userIdList.add(uDep.getUserId()); @@ -121,7 +121,7 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S } @Override - public IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo) { + public IPage<SysUser> queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo,String id) { IPage<SysUser> pageList = null; // 部门ID不存在 直接查询用户表即可 Page<SysUser> page = new Page<SysUser>(pageNo, pageSize); @@ -133,6 +133,11 @@ public class SysUserDepartServiceImpl extends ServiceImpl<SysUserDepartMapper, S if(oConvertUtils.isNotEmpty(username)){ query.like(SysUser::getUsername, username); } + //update-begin---author:wangshuai ---date:20220608 for:[VUEN-1238]邮箱回复时,发送到显示的为用户id------------ + if(oConvertUtils.isNotEmpty(id)){ + query.eq(SysUser::getId, id); + } + //update-end---author:wangshuai ---date:20220608 for:[VUEN-1238]邮箱回复时,发送到显示的为用户id------------ pageList = sysUserMapper.selectPage(page, query); }else{ // 有部门ID 需要走自定义sql diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java index 3316a9f..71dea40 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java @@ -9,6 +9,9 @@ import lombok.extern.slf4j.Slf4j; import org.jeecg.common.api.vo.Result; import org.jeecg.common.constant.CacheConstant; import org.jeecg.common.constant.CommonConstant; +import org.jeecg.common.constant.enums.RoleIndexConfigEnum; +import org.jeecg.common.desensitization.annotation.SensitiveEncode; +import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.system.vo.SysUserCacheInfo; import org.jeecg.common.util.PasswordUtil; import org.jeecg.common.util.UUIDGenerator; @@ -19,6 +22,7 @@ import org.jeecg.modules.system.mapper.*; import org.jeecg.modules.system.model.SysUserSysDepartModel; import org.jeecg.modules.system.service.ISysUserService; import org.jeecg.modules.system.vo.SysUserDepVo; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; @@ -65,6 +69,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService; @Autowired ThirdAppDingtalkServiceImpl dingtalkService; + @Autowired + SysRoleIndexMapper sysRoleIndexMapper; @Override @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true) @@ -155,7 +161,40 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl public List<String> getRole(String username) { return sysUserRoleMapper.getRoleByUserName(username); } - + + /** + * 获取动态首页路由配置 + * @param username + * @param version + * @return + */ + @Override + public SysRoleIndex getDynamicIndexByUserRole(String username,String version) { + List<String> roles = sysUserRoleMapper.getRoleByUserName(username); + String componentUrl = RoleIndexConfigEnum.getIndexByRoles(roles); + SysRoleIndex roleIndex = new SysRoleIndex(componentUrl); + //只有 X-Version=v3 的时候,才读取sys_role_index表获取角色首页配置 + if (oConvertUtils.isNotEmpty(version) && roles!=null && roles.size()>0) { + LambdaQueryWrapper<SysRoleIndex> routeIndexQuery = new LambdaQueryWrapper(); + //用户所有角色 + routeIndexQuery.in(SysRoleIndex::getRoleCode, roles); + //角色首页状态0:未开启 1:开启 + routeIndexQuery.eq(SysRoleIndex::getStatus, CommonConstant.STATUS_1); + //优先级正序排序 + routeIndexQuery.orderByAsc(SysRoleIndex::getPriority); + List<SysRoleIndex> list = sysRoleIndexMapper.selectList(routeIndexQuery); + if (null != list && list.size() > 0) { + roleIndex = list.get(0); + } + } + + //如果componentUrl为空,则返回空 + if(oConvertUtils.isEmpty(roleIndex.getComponent())){ + return null; + } + return roleIndex; + } + /** * 通过用户名获取用户角色集合 * @param username 用户名 @@ -200,7 +239,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl * @return */ @Override - @Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username") public SysUserCacheInfo getCacheUser(String username) { SysUserCacheInfo info = new SysUserCacheInfo(); info.setOneDepart(true); @@ -558,4 +596,19 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl return userList.stream().map(SysUser::getUsername).collect(Collectors.toList()); } + @Override + @Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username") + @SensitiveEncode + public LoginUser getEncodeUserInfo(String username){ + if(oConvertUtils.isEmpty(username)) { + return null; + } + LoginUser loginUser = new LoginUser(); + SysUser sysUser = userMapper.getUserByName(username); + if(sysUser==null) { + return null; + } + BeanUtils.copyProperties(sysUser, loginUser); + return loginUser; + } } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java index 02a54b0..f7391a0 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/service/impl/ThirdAppWechatEnterpriseServiceImpl.java @@ -67,15 +67,20 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService { private SysAnnouncementSendMapper sysAnnouncementSendMapper; /** + * errcode + */ + private static final String ERR_CODE = "errcode"; + + /** * 第三方APP类型,当前固定为 wechat_enterprise */ public final String THIRD_TYPE = ThirdAppConfig.WECHAT_ENTERPRISE.toLowerCase(); @Override public String getAccessToken() { - String CORP_ID = thirdAppConfig.getWechatEnterprise().getClientId(); - String SECRET = thirdAppConfig.getWechatEnterprise().getClientSecret(); - AccessToken accessToken = JwAccessTokenAPI.getAccessToken(CORP_ID, SECRET); + String corpId = thirdAppConfig.getWechatEnterprise().getClientId(); + String secret = thirdAppConfig.getWechatEnterprise().getClientSecret(); + AccessToken accessToken = JwAccessTokenAPI.getAccessToken(corpId, secret); if (accessToken != null) { return accessToken.getAccesstoken(); } @@ -85,14 +90,14 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService { /** 获取APPToken,新版企业微信的秘钥是分开的 */ public String getAppAccessToken() { - String CORP_ID = thirdAppConfig.getWechatEnterprise().getClientId(); - String SECRET = thirdAppConfig.getWechatEnterprise().getAgentAppSecret(); + String corpId = thirdAppConfig.getWechatEnterprise().getClientId(); + String secret = thirdAppConfig.getWechatEnterprise().getAgentAppSecret(); // 如果没有配置APP秘钥,就说明是老企业,可以通用秘钥 - if (oConvertUtils.isEmpty(SECRET)) { - SECRET = thirdAppConfig.getWechatEnterprise().getClientSecret(); + if (oConvertUtils.isEmpty(secret)) { + secret = thirdAppConfig.getWechatEnterprise().getClientSecret(); } - AccessToken accessToken = JwAccessTokenAPI.getAccessToken(CORP_ID, SECRET); + AccessToken accessToken = JwAccessTokenAPI.getAccessToken(corpId, secret); if (accessToken != null) { return accessToken.getAccesstoken(); } @@ -464,6 +469,7 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService { case 60104: msg = "手机号码已存在"; break; + default: } String str = String.format("用户 %s(%s) 同步失败!错误码:%s——%s", sysUser.getUsername(), sysUser.getRealname(), errCode, msg); syncInfo.addFailInfo(str); @@ -567,7 +573,7 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService { // 企业微信规则:1表示启用成员,0表示禁用成员 // JEECG规则:1正常,2冻结 if (sysUser.getStatus() != null) { - if (sysUser.getStatus() == 1 || sysUser.getStatus() == 2) { + if (CommonConstant.USER_UNFREEZE.equals(sysUser.getStatus()) || CommonConstant.USER_FREEZE.equals(sysUser.getStatus())) { user.setEnable(sysUser.getStatus() == 1 ? 1 : 0); } else { user.setEnable(1); @@ -837,7 +843,7 @@ public class ThirdAppWechatEnterpriseServiceImpl implements IThirdAppService { JSONObject response = JwUserAPI.getUserInfoByCode(code, accessToken); if (response != null) { log.info("response: " + response.toJSONString()); - if (response.getIntValue("errcode") == 0) { + if (response.getIntValue(ERR_CODE) == 0) { return response.getString("UserId"); } } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/PermissionDataUtil.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/PermissionDataUtil.java index 2438fcc..211740a 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/PermissionDataUtil.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/PermissionDataUtil.java @@ -2,6 +2,8 @@ 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.oConvertUtils; import org.jeecg.modules.system.entity.SysPermission; @@ -11,6 +13,21 @@ import org.jeecg.modules.system.entity.SysPermission; */ public class PermissionDataUtil { + /** + * 路径:views/ + */ + private static final String PATH_VIEWS = "views/"; + + /** + * 路径:src/views/ + */ + private static final String PATH_SRC_VIEWS = "src/views/"; + + /** + * .vue后缀 + */ + private static final String VUE_SUFFIX = ".vue"; + /** * 智能处理错误数据,简化用户失误操作 * @@ -24,17 +41,17 @@ public class PermissionDataUtil { // 组件 if (oConvertUtils.isNotEmpty(permission.getComponent())) { String component = permission.getComponent(); - if (component.startsWith("/")) { + if (component.startsWith(SymbolConstant.SINGLE_SLASH)) { component = component.substring(1); } - if (component.startsWith("views/")) { - component = component.replaceFirst("views/", ""); + if (component.startsWith(PATH_VIEWS)) { + component = component.replaceFirst(PATH_VIEWS, ""); } - if (component.startsWith("src/views/")) { - component = component.replaceFirst("src/views/", ""); + if (component.startsWith(PATH_SRC_VIEWS)) { + component = component.replaceFirst(PATH_SRC_VIEWS, ""); } - if (component.endsWith(".vue")) { - component = component.replace(".vue", ""); + if (component.endsWith(VUE_SUFFIX)) { + component = component.replace(VUE_SUFFIX, ""); } permission.setComponent(component); } @@ -42,11 +59,11 @@ public class PermissionDataUtil { // 请求URL if (oConvertUtils.isNotEmpty(permission.getUrl())) { String url = permission.getUrl(); - if (url.endsWith(".vue")) { - url = url.replace(".vue", ""); + if (url.endsWith(VUE_SUFFIX)) { + url = url.replace(VUE_SUFFIX, ""); } - if (!url.startsWith("http") && !url.startsWith("/")&&!url.trim().startsWith("{{")) { - url = "/" + url; + if (!url.startsWith(CommonConstant.STR_HTTP) && !url.startsWith(SymbolConstant.SINGLE_SLASH)&&!url.trim().startsWith(SymbolConstant.DOUBLE_LEFT_CURLY_BRACKET)) { + url = SymbolConstant.SINGLE_SLASH + url; } permission.setUrl(url); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/RandImageUtil.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/RandImageUtil.java index d9e7fe4..3311d68 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/RandImageUtil.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/RandImageUtil.java @@ -15,26 +15,26 @@ import java.util.Random; */ public class RandImageUtil { - public static final String key = "JEECG_LOGIN_KEY"; + public static final String KEY = "JEECG_LOGIN_KEY"; /** * 定义图形大小 */ - private static final int width = 105; + private static final int WIDTH = 105; /** * 定义图形大小 */ - private static final int height = 35; + private static final int HEIGHT = 35; /** * 定义干扰线数量 */ - private static final int count = 200; + private static final int COUNT = 200; /** * 干扰线的长度=1.414*lineWidth */ - private static final int lineWidth = 2; + private static final int LINE_WIDTH = 2; /** * 图片格式 @@ -85,28 +85,28 @@ public class RandImageUtil { private static BufferedImage getImageBuffer(String resultCode){ // 在内存中创建图象 - final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + final BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); // 获取图形上下文 final Graphics2D graphics = (Graphics2D) image.getGraphics(); // 设定背景颜色 // ---1 graphics.setColor(Color.WHITE); - graphics.fillRect(0, 0, width, height); + graphics.fillRect(0, 0, WIDTH, HEIGHT); // 设定边框颜色 // graphics.setColor(getRandColor(100, 200)); // ---2 - graphics.drawRect(0, 0, width - 1, height - 1); + graphics.drawRect(0, 0, WIDTH - 1, HEIGHT - 1); final Random random = new Random(); // 随机产生干扰线,使图象中的认证码不易被其它程序探测到 - for (int i = 0; i < count; i++) { + for (int i = 0; i < COUNT; i++) { // ---3 graphics.setColor(getRandColor(150, 200)); // 保证画在边框之内 - final int x = random.nextInt(width - lineWidth - 1) + 1; - final int y = random.nextInt(height - lineWidth - 1) + 1; - final int xl = random.nextInt(lineWidth); - final int yl = random.nextInt(lineWidth); + final int x = random.nextInt(WIDTH - LINE_WIDTH - 1) + 1; + final int y = random.nextInt(HEIGHT - LINE_WIDTH - 1) + 1; + final int xl = random.nextInt(LINE_WIDTH); + final int yl = random.nextInt(LINE_WIDTH); graphics.drawLine(x, y, x + xl, y + yl); } // 取随机产生的认证码 @@ -129,11 +129,12 @@ public class RandImageUtil { private static Color getRandColor(int fc, int bc) { // 取得给定范围随机颜色 final Random random = new Random(); - if (fc > 255) { - fc = 255; + int length = 255; + if (fc > length) { + fc = length; } - if (bc > 255) { - bc = 255; + if (bc > length) { + bc = length; } final int r = fc + random.nextInt(bc - fc); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/XssUtils.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/XssUtils.java new file mode 100644 index 0000000..1fbb380 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/util/XssUtils.java @@ -0,0 +1,49 @@ +package org.jeecg.modules.system.util; + +import org.springframework.web.util.HtmlUtils; + +import java.util.regex.Pattern; + +/** + * @Description: 工具类XSSUtils,现在的做法是替换成空字符,CSDN的是进行转义,比如文字开头的"<"转成< + * @author: lsq + * @date: 2021年07月26日 19:13 + */ +public class XssUtils { + + private static Pattern[] patterns = new Pattern[]{ + //Script fragments + Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE), + //src='...' + Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL), + Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL), + //script tags + Pattern.compile("</script>", Pattern.CASE_INSENSITIVE), + Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL), + //eval(...) + Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL), + //expression(...) + Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL), + //javascript:... + Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE), + //vbscript:... + Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE), + //onload(...)=... + Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL), + }; + + public static String scriptXss(String value) { + if (value != null) { + value = value.replaceAll(" ", ""); + for(Pattern scriptPattern: patterns){ + value = scriptPattern.matcher(value).replaceAll(""); + } + } + return HtmlUtils.htmlEscape(value); + } + + public static void main(String[] args) { + String s = scriptXss("<img src=x onload=alert(111).*?><script></script>javascript:eval()\\\\."); + System.err.println("s======>" + s); + } +} diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/application-dev.yml b/jeecg-boot/jeecg-boot-module-system/src/main/resources/application-dev.yml index d8057f0..3c76532 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/application-dev.yml +++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/application-dev.yml @@ -184,7 +184,11 @@ jeecg: # 签名密钥串(前后端要一致,正式发布请自行修改) signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a # 本地:local\Minio:minio\阿里云:alioss - uploadType: local + uploadType: minio + # 前端访问地址 + domainUrl: + pc: http://localhost:3100 + app: http://localhost:8051 path: #文件上传根目录 设置 upload: /opt/upFiles @@ -328,4 +332,4 @@ third-app: client-id: ?? # appSecret client-secret: ?? - agent-id: ?? \ No newline at end of file + agent-id: ?? diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/application-prod.yml b/jeecg-boot/jeecg-boot-module-system/src/main/resources/application-prod.yml index 2db8fb0..773ad14 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/application-prod.yml +++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/application-prod.yml @@ -39,10 +39,10 @@ spring: quartz: job-store-type: jdbc initialize-schema: embedded - #延迟1秒启动定时任务 - startup-delay: 1s #定时任务启动开关,true-开 false-关 auto-startup: true + #延迟1秒启动定时任务 + startup-delay: 1s #启动时更新己存在的Job overwrite-existing-jobs: true properties: @@ -185,6 +185,10 @@ jeecg: signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a # 本地:local\Minio:minio\阿里云:alioss uploadType: alioss + # 前端访问地址 + domainUrl: + pc: http://localhost:3100 + app: http://localhost:8051 path: #文件上传根目录 设置 upload: /opt/jeecg-boot/upload diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/application-test.yml b/jeecg-boot/jeecg-boot-module-system/src/main/resources/application-test.yml index 671e559..1371d31 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/application-test.yml +++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/application-test.yml @@ -185,6 +185,10 @@ jeecg: signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a # 本地:local\Minio:minio\阿里云:alioss uploadType: local + # 前端访问地址 + domainUrl: + pc: http://localhost:3100 + app: http://localhost:8051 path: #文件上传根目录 设置 upload: D://opt//upFiles diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/banner.txt b/jeecg-boot/jeecg-boot-module-system/src/main/resources/banner.txt index 21783e0..14ea568 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/banner.txt +++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/banner.txt @@ -9,6 +9,6 @@ ${AnsiColor.BRIGHT_BLUE} ${AnsiColor.BRIGHT_GREEN} -Jeecg Boot Version: 3.2.0 +Jeecg Boot Version: 3.3.0 Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version} ${AnsiColor.BLACK} diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/sql/menu_insert.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/sql/menu_insert.ftl index ac35200..ced8333 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/sql/menu_insert.ftl +++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/sql/menu_insert.ftl @@ -1,5 +1,27 @@ -- 注意:该页面对应的前台目录为views/${entityPackage}文件夹下 -- 如果你想更改到其他目录,请修改sql中component字段对应的值 +<#assign id = '${.now?string["yyyyMMddhhmmSSsss"]}0'> + INSERT INTO sys_permission(id, parent_id, name, url, component, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_route, is_leaf, keep_alive, hidden, hide_tab, description, status, del_flag, rule_flag, create_by, create_time, update_by, update_time, internal_or_external) -VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}', NULL, '${tableVo.ftlDescription}', '/${entityPackage}/${entityName?uncap_first}List', '${entityPackage}/${entityName}List', NULL, NULL, 0, NULL, '1', 1.00, 0, NULL, 1, 1, 0, 0, 0, NULL, '1', 0, 0, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0); \ No newline at end of file +VALUES ('${id}', NULL, '${tableVo.ftlDescription}', '/${entityPackage}/${entityName?uncap_first}List', '${entityPackage}/${entityName}List', NULL, NULL, 0, NULL, '1', 1.00, 0, NULL, 1, 1, 0, 0, 0, NULL, '1', 0, 0, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0); + +-- 权限控制sql +-- 新增 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}1', '${id}', '添加${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${bussiPackage}:${tableName}:add', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0); +-- 编辑 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}2', '${id}', '编辑${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${bussiPackage}:${tableName}:edit', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0); +-- 删除 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}3', '${id}', '删除${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${bussiPackage}:${tableName}:delete', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0); +-- 批量删除 +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}4', '${id}', '批量删除${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${bussiPackage}:${tableName}:deleteBatch', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0); +-- 导出excel +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}5', '${id}', '导出excel_${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${bussiPackage}:${tableName}:exportXls', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0); +-- 导入excel +INSERT INTO sys_permission(id, parent_id, name, url, component, is_route, component_name, redirect, menu_type, perms, perms_type, sort_no, always_show, icon, is_leaf, keep_alive, hidden, hide_tab, description, create_by, create_time, update_by, update_time, del_flag, rule_flag, status, internal_or_external) +VALUES ('${.now?string["yyyyMMddhhmmSSsss"]}6', '${id}', '导入excel_${tableVo.ftlDescription}', NULL, NULL, 0, NULL, NULL, 2, '${bussiPackage}:${tableName}:importExcel', '1', NULL, 0, NULL, 1, 0, 0, 0, NULL, 'admin', '${.now?string["yyyy-MM-dd HH:mm:ss"]}', NULL, NULL, 0, 0, '1', 0); \ No newline at end of file diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/core.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/core.ftl index 2b43ff6..c3a2143 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/core.ftl +++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/core.ftl @@ -32,7 +32,7 @@ { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}, <#-- 邮政编码 --> <#elseif fieldValidType == 'p'> - { pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'}, + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}, <#-- 字母 --> <#elseif fieldValidType == 's'> { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}, diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3CoreNative.ftl b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3CoreNative.ftl index 45b269f..2c395d5 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3CoreNative.ftl +++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/common/validatorRulesTemplate/native/vue3CoreNative.ftl @@ -28,7 +28,7 @@ { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码!'}<#rt>, <#-- 邮政编码 --> <#elseif fieldValidType == 'p'> - { pattern: /^[1-9]\d{5}$/, message: '请输入正确的邮政编码!'}<#rt>, + { pattern: /^[0-9]\d{5}$/, message: '请输入正确的邮政编码!'}<#rt>, <#-- 字母 --> <#elseif fieldValidType == 's'> { pattern: /^[A-Z|a-z]+$/, message: '请输入字母!'}<#rt>, diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai index d7236b2..d12e75c 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai +++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/default/one/java/${bussiPackage}/${entityPackage}/controller/${entityName}Controller.javai @@ -86,6 +86,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-添加") @ApiOperation(value="${tableVo.ftlDescription}-添加", notes="${tableVo.ftlDescription}-添加") + //@RequiresPermissions("${bussiPackage}:${tableName}:add") @PostMapping(value = "/add") public Result<String> add(@RequestBody ${entityName} ${entityName?uncap_first}) { <#if bpm_flag> @@ -103,6 +104,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-编辑") @ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑") + //@RequiresPermissions("${bussiPackage}:${tableName}:edit") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result<String> edit(@RequestBody ${entityName} ${entityName?uncap_first}) { ${entityName?uncap_first}Service.updateById(${entityName?uncap_first}); @@ -117,6 +119,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-通过id删除") @ApiOperation(value="${tableVo.ftlDescription}-通过id删除", notes="${tableVo.ftlDescription}-通过id删除") + //@RequiresPermissions("${bussiPackage}:${tableName}:delete") @DeleteMapping(value = "/delete") public Result<String> delete(@RequestParam(name="id",required=true) String id) { ${entityName?uncap_first}Service.removeById(id); @@ -131,6 +134,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e */ @AutoLog(value = "${tableVo.ftlDescription}-批量删除") @ApiOperation(value="${tableVo.ftlDescription}-批量删除", notes="${tableVo.ftlDescription}-批量删除") + //@RequiresPermissions("${bussiPackage}:${tableName}:deleteBatch") @DeleteMapping(value = "/deleteBatch") public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) { this.${entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(","))); @@ -160,6 +164,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e * @param request * @param ${entityName?uncap_first} */ + //@RequiresPermissions("${bussiPackage}:${tableName}:exportXls") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(HttpServletRequest request, ${entityName} ${entityName?uncap_first}) { return super.exportXls(request, ${entityName?uncap_first}, ${entityName}.class, "${tableVo.ftlDescription}"); @@ -172,6 +177,7 @@ public class ${entityName}Controller extends JeecgController<${entityName}, I${e * @param response * @return */ + //@RequiresPermissions("${tableName}:importExcel") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) { return super.importExcel(request, response, ${entityName}.class); diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei index 2d379bd..5400008 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei +++ b/jeecg-boot/jeecg-boot-module-system/src/main/resources/jeecg/code-template-online/inner-table/onetomany/java/${bussiPackage}/${entityPackage}/vue/${entityName}List.vuei @@ -55,7 +55,7 @@ <template v-if="toggleSearchStatus"> </#if> <#-- update-begin-author:taoyan date:20220303 for: /issues/3420 内嵌风格,datetime控件样式异常 --> - <#if po.queryModel=='group' && po.classType=='datetime'> + <#if po.queryMode?default("")?trim=='group' && po.classType=='datetime'> ${indent}<a-col :xl="10" :lg="12" :md="12" :sm="24"> <#else> ${indent}<a-col :xl="6" :lg="7" :md="8" :sm="24"> diff --git a/jeecg-boot/jeecg-boot-module-system/src/test/java/org/jeecg/modules/system/test/SysUserTest.java b/jeecg-boot/jeecg-boot-module-system/src/test/java/org/jeecg/modules/system/test/SysUserTest.java index a02448a..5c1d38f 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/test/java/org/jeecg/modules/system/test/SysUserTest.java +++ b/jeecg-boot/jeecg-boot-module-system/src/test/java/org/jeecg/modules/system/test/SysUserTest.java @@ -1,5 +1,6 @@ package org.jeecg.modules.system.test; +import com.alibaba.fastjson.JSONObject; import org.jeecg.JeecgSystemApplication; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.system.util.JwtUtil; @@ -9,13 +10,11 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import com.alibaba.fastjson.JSONObject; import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; /** * 系统用户单元测试