diff --git a/box-bps/src/main/java/com/ruoyi/bps/controller/ExpSubsPushApiController.java b/box-bps/src/main/java/com/ruoyi/bps/controller/ExpSubsPushApiController.java index 02e7cc63e..b33d9f2aa 100644 --- a/box-bps/src/main/java/com/ruoyi/bps/controller/ExpSubsPushApiController.java +++ b/box-bps/src/main/java/com/ruoyi/bps/controller/ExpSubsPushApiController.java @@ -3,16 +3,21 @@ package com.ruoyi.bps.controller; import com.kuaidi100.sdk.response.SubscribeResp; import com.ruoyi.bps.domain.ExpSubscribe; import com.ruoyi.bps.service.IExpSubsPushApiService; +import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.enums.BusinessType; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; /** * 接受快递推送信息的API接口Controller @@ -20,16 +25,16 @@ import javax.servlet.http.HttpServletRequest; * @author box * @date 2021-05-13 */ -@Api("快递信息订阅推送") +@Api(value = "快递信息订阅推送",tags = "快递订阅接口") @RestController -@RequestMapping("/anon") +/*@RequestMapping("/anon")*/ public class ExpSubsPushApiController extends BaseController { @Autowired IExpSubsPushApiService expSubsPushApiService; //推送 @CrossOrigin - @PostMapping("/subscribeCallBackUrl") + @PostMapping("anon/subscribeCallBackUrl") @ApiOperation("快递信息订阅推送接受") public SubscribeResp SubscribeCallBackUrl(HttpServletRequest request) { return expSubsPushApiService.ExpressSubscribeCallBackUrl(request); @@ -37,10 +42,25 @@ public class ExpSubsPushApiController extends BaseController { //订阅 @CrossOrigin - @PostMapping("/subscribe") + @PostMapping("anon/subscribe") public SubscribeResp Subscribe(ExpSubscribe expSubscribe){ return expSubsPushApiService.ExpressSubscribe(expSubscribe); } + //接受topgp订阅, + @Log(title = "快递订阅", businessType = BusinessType.OTHER) + @CrossOrigin + @ApiOperation(value="topgp订阅快递",notes = "request body格式: {\"deliveryNo\":\"S301-2108020001\",\"expressNo\":\"300444235610\",\"company\":\"annengwuliu\",\"phone\":\"13800138000\"}") + @ApiImplicitParams({ + @ApiImplicitParam(name = "token", value = "token", required = true, paramType = "header", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "requestJson", value = "请求json",required = true, paramType = "body", dataType = "String", dataTypeClass = String.class) + }) + + @PostMapping("api/express/topgpSubscribe") + public String topgpSubscribe(HttpServletRequest request, HttpServletResponse response) throws IOException { + return expSubsPushApiService.ExpressSubscribeWithTopgp(request); + } + + } diff --git a/box-bps/src/main/java/com/ruoyi/bps/controller/FrForCrTopgpController.java b/box-bps/src/main/java/com/ruoyi/bps/controller/FrForCrTopgpController.java index c0d8f02a3..ea61ca9ac 100644 --- a/box-bps/src/main/java/com/ruoyi/bps/controller/FrForCrTopgpController.java +++ b/box-bps/src/main/java/com/ruoyi/bps/controller/FrForCrTopgpController.java @@ -7,34 +7,39 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.DataSourceType; import com.ruoyi.common.utils.StringUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.List; import java.util.Map; +@Api(tags = "TOPGP使用帆软报表接口") @RestController public class FrForCrTopgpController { @Autowired private TopgpDdlService topgpDdlService; //访问 ../anon/bps/frforcr/topprod时,使用topprod + @ApiOperation("TOPPROD正式区访问") + @ApiImplicitParam(name = "jsonString", value = "Json字符串", paramType = "body", dataType = "String", dataTypeClass = String.class) @CrossOrigin @Log(title = "CSFR412_CR报表_TOPPROD", businessType = BusinessType.DROP) - @RequestMapping("/anon/bps/frforcr/topprod") + @PostMapping("/anon/bps/frforcr/topprod") @DataSource(value = DataSourceType.TOPPRODDSREPORT) public AjaxResult frforcrtopprod(@RequestBody Map map){ return frforcrtoppgp(map); } //访问../anon/bps/frforcr/topprod时,使用toptest实例 + @ApiOperation("TOPTEST正式区访问") + @ApiImplicitParam(name = "jsonString", value = "Json字符串", paramType = "body", dataType = "String", dataTypeClass = String.class) @CrossOrigin @Log(title = "CSFR412_CR报表_TOPTEST", businessType = BusinessType.DROP) - @RequestMapping("/anon/bps/frforcr/toptest") + @PostMapping("/anon/bps/frforcr/toptest") @DataSource(value = DataSourceType.TOPTESTDSREPORT) public AjaxResult frforcrtoptest(@RequestBody Map map){ return frforcrtoppgp(map); diff --git a/box-bps/src/main/java/com/ruoyi/bps/service/IExpSubsPushApiService.java b/box-bps/src/main/java/com/ruoyi/bps/service/IExpSubsPushApiService.java index 5867116de..f47f834de 100644 --- a/box-bps/src/main/java/com/ruoyi/bps/service/IExpSubsPushApiService.java +++ b/box-bps/src/main/java/com/ruoyi/bps/service/IExpSubsPushApiService.java @@ -4,8 +4,15 @@ import com.ruoyi.bps.domain.ExpSubscribe; import com.kuaidi100.sdk.response.SubscribeResp; import javax.servlet.http.HttpServletRequest; +import java.io.IOException; public interface IExpSubsPushApiService { + + /** + * 向快递100推送订阅请求 + * @param expSubscribe + * @return + */ public SubscribeResp ExpressSubscribe(ExpSubscribe expSubscribe); /** @@ -19,4 +26,11 @@ public interface IExpSubsPushApiService { * */ public SubscribeResp ExpressSubscribeCallBackUrl(HttpServletRequest request); + + /** + * 获取Topgp推送的快递信息,向快递100推送订阅请求 + * @param request + * @return + */ + public String ExpressSubscribeWithTopgp(HttpServletRequest request) throws IOException; } diff --git a/box-bps/src/main/java/com/ruoyi/bps/service/impl/ExpSubsPushApiServiceImpl.java b/box-bps/src/main/java/com/ruoyi/bps/service/impl/ExpSubsPushApiServiceImpl.java index 50b3ede50..ac794b775 100644 --- a/box-bps/src/main/java/com/ruoyi/bps/service/impl/ExpSubsPushApiServiceImpl.java +++ b/box-bps/src/main/java/com/ruoyi/bps/service/impl/ExpSubsPushApiServiceImpl.java @@ -1,5 +1,6 @@ package com.ruoyi.bps.service.impl; +import com.alibaba.fastjson.JSONObject; import com.google.gson.Gson; import com.kuaidi100.sdk.api.Subscribe; import com.kuaidi100.sdk.contant.ApiInfoConstant; @@ -12,7 +13,6 @@ import com.kuaidi100.sdk.response.SubscribePushData; import com.kuaidi100.sdk.response.SubscribePushParamResp; import com.kuaidi100.sdk.response.SubscribePushResult; import com.kuaidi100.sdk.response.SubscribeResp; -import com.kuaidi100.sdk.utils.PropertiesReader; import com.kuaidi100.sdk.utils.SignUtils; import com.ruoyi.bps.domain.ExpSubsPushResp; import com.ruoyi.bps.domain.ExpSubscribe; @@ -20,23 +20,30 @@ import com.ruoyi.bps.service.IExpSubsPushApiService; import com.ruoyi.bps.service.IExpSubsPushRespService; import com.ruoyi.bps.service.IExpSubscribeService; import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.HashMap; import java.util.List; +import java.util.Map; @Service public class ExpSubsPushApiServiceImpl implements IExpSubsPushApiService { - String key = PropertiesReader.get("key"); + /*String key = PropertiesReader.get("key"); String customer = PropertiesReader.get("customer"); String secret = PropertiesReader.get("secret"); String siid = PropertiesReader.get("siid"); String userid = PropertiesReader.get("userid"); String tid = PropertiesReader.get("tid"); String secret_key = PropertiesReader.get("secret_key"); - String secret_secret = PropertiesReader.get("secret_secret"); + String secret_secret = PropertiesReader.get("secret_secret"); */ + @Value("${express.key}") + private String key; @Autowired private IExpSubsPushRespService expSubsPushRespService; @@ -50,6 +57,10 @@ public class ExpSubsPushApiServiceImpl implements IExpSubsPushApiService { */ @Override public SubscribeResp ExpressSubscribe(ExpSubscribe expSubscribe) { + + String loginFrom= expSubscribe.getSalt(); + String subscribeFrom= StringUtils.isNotEmpty(loginFrom)?loginFrom.equals("topgp")?"topgp":"localhost":"localhost"; + SubscribeParameters subscribeParameters = new SubscribeParameters(); SubscribeResp subscribeResp = new SubscribeResp(); subscribeParameters.setCallbackurl("http://report.bpsemi.cn:8081/it_war/anon/subscribeCallBackUrl"); @@ -68,7 +79,7 @@ public class ExpSubsPushApiServiceImpl implements IExpSubsPushApiService { IBaseClient subscribe = new Subscribe(); try{ HttpResult httpResult= subscribe.execute(subscribeReq); - System.out.println(httpResult); + //System.out.println(httpResult); subscribeResp= new Gson().fromJson(httpResult.getBody(),SubscribeResp.class); }catch (Exception e) { @@ -85,13 +96,13 @@ public class ExpSubsPushApiServiceImpl implements IExpSubsPushApiService { newExpSubscribe.setCompany(expSubscribe.getCompany()); newExpSubscribe.setNumber(expSubscribe.getNumber()); newExpSubscribe.setPhone(expSubscribe.getPhone()); - newExpSubscribe.setSalt("bpsemi"); + newExpSubscribe.setSalt(subscribeFrom); //偷懒,把请求来源记录到salt栏位,不再增加exp_subscribe字段了。。以后找时间改吧 newExpSubscribe.setSubscribeTime(DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss")); newExpSubscribe.setResult((subscribeResp.isResult())?"true":"false"); newExpSubscribe.setReturnCode(subscribeResp.getReturnCode()); newExpSubscribe.setMessage(subscribeResp.getMessage()); - ExpSubscribe queryExpSubscribe = new ExpSubscribe(); + /*ExpSubscribe queryExpSubscribe = new ExpSubscribe(); queryExpSubscribe.setCompany(expSubscribe.getCompany()); queryExpSubscribe.setNumber(expSubscribe.getNumber()); queryExpSubscribe.setResult(expSubscribe.getResult()); @@ -107,7 +118,9 @@ public class ExpSubsPushApiServiceImpl implements IExpSubsPushApiService { }else { //如果数据库中没有快递单号+快递公司编码,则更插入新记录 expSubscribeService.insertExpSubscribe(newExpSubscribe); - } + }*/ + //20210802 无论系统里有没有记录,都会记录本次推送。 + expSubscribeService.insertExpSubscribe(newExpSubscribe); //返回订阅结果 return subscribeResp; @@ -247,11 +260,62 @@ public class ExpSubsPushApiServiceImpl implements IExpSubsPushApiService { str+="\r\n"; } } - System.out.println(str); + //System.out.println(str); return str; } + /** + * 获取Topgp推送的快递信息,向快递100推送订阅请求 + * + * @param request + * @return + */ + @Override + public String ExpressSubscribeWithTopgp(HttpServletRequest request) throws IOException { + //获取httpServletRequest传过来的Json字符串,并进行解析 + JSONObject contentJson= JSONObject.parseObject(ServletUtils.getRequestContent(request)); + String deliveryNo= contentJson.getString("deliveryNo"); + String expressNo = contentJson.getString("expressNo"); + String company = contentJson.getString("company"); + String phone = contentJson.getString("phone"); + //如果出货单号或者快递单号为空,则返回错误信息,并写入Logo + if(StringUtils.isEmpty(deliveryNo) || StringUtils.isEmpty(expressNo)){ + SubscribeResp subscribeResp=new SubscribeResp(); + subscribeResp.setMessage("快递单号或出货单号为空"); + subscribeResp.setResult(false); + subscribeResp.setReturnCode("700"); + + Map map=new HashMap<>(); + map.put("subscribeResp",subscribeResp); + map.put("deliveryNo",deliveryNo); + map.put("expressNo",expressNo); + //写入Logo + //todo + + //返回错误信息 + return JSONObject.toJSONString(map); + + } + //向快递100推送订阅请求 + ExpSubscribe expSubscribe=new ExpSubscribe(); + expSubscribe.setNumber(expressNo); + expSubscribe.setCompany(company); + expSubscribe.setPhone(phone); + expSubscribe.setSalt("topgp"); //偷懒,把请求来源记录到salt栏位,不再增加exp_subscribe字段了。。以后找时间改吧 + SubscribeResp subscribeResp= ExpressSubscribe(expSubscribe); + + /*Object object = JSONObject.toJSON(subscribeResp); + Map map=JSONObject.parseObject(object.toString(), Map.class);*/ + Map map= new HashMap<>(); + map.put("expSubscribe",subscribeResp); + map.put("deliveryNo",deliveryNo); + map.put("expressNo",expressNo); + return JSONObject.toJSONString(map); + } + + + } diff --git a/box-bps/src/main/java/com/ruoyi/bps/service/impl/ExpressInfoServiceImpl.java b/box-bps/src/main/java/com/ruoyi/bps/service/impl/ExpressInfoServiceImpl.java index 6e1f80630..e9f6093cf 100644 --- a/box-bps/src/main/java/com/ruoyi/bps/service/impl/ExpressInfoServiceImpl.java +++ b/box-bps/src/main/java/com/ruoyi/bps/service/impl/ExpressInfoServiceImpl.java @@ -21,6 +21,7 @@ import com.kuaidi100.sdk.response.QueryTrackResp; import com.kuaidi100.sdk.utils.PropertiesReader; import com.kuaidi100.sdk.utils.SignUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -37,13 +38,6 @@ import java.util.List; public class ExpressInfoServiceImpl implements IExpressInfoService { /* - String key = "Jydbrxsm2311"; - String customer = "2DD48B3469B82F2B7700569093AB792B"; - String secret = "8781ed9b35a7438499eb02fee915915a"; - String userid = "2a62da2192c24d17a943ff78ee64f8c6"; - - */ - String key = PropertiesReader.get("key"); String customer = PropertiesReader.get("customer"); String secret = PropertiesReader.get("secret"); @@ -52,6 +46,13 @@ public class ExpressInfoServiceImpl implements IExpressInfoService String tid = PropertiesReader.get("tid"); String secret_key = PropertiesReader.get("secret_key"); String secret_secret = PropertiesReader.get("secret_secret"); + */ + @Value("${express.key}") + private String key; + + @Value("${express.customer}") + private String customer; + @@ -132,7 +133,7 @@ public class ExpressInfoServiceImpl implements IExpressInfoService //如果没有输入快递公司编号,则查询快递公司编号 if(StringUtils.isEmpty(com)){ if(AutoGetExpressCom(nu)==null){ - callbackExpressInfo.setData("根据快递单号查询不到快递公司,请确认快递单号是否正确!"); + callbackExpressInfo.setData("请提供要查询的快递所属物流公司编号!"); return callbackExpressInfo; } com=AutoGetExpressCom(nu).getComCode(); diff --git a/box-bps/src/main/java/com/ruoyi/bps/service/impl/ExpressServiceImpl.java b/box-bps/src/main/java/com/ruoyi/bps/service/impl/ExpressServiceImpl.java index 7be4e0eb5..b71b0370a 100644 --- a/box-bps/src/main/java/com/ruoyi/bps/service/impl/ExpressServiceImpl.java +++ b/box-bps/src/main/java/com/ruoyi/bps/service/impl/ExpressServiceImpl.java @@ -14,6 +14,7 @@ import com.kuaidi100.sdk.utils.SignUtils; import com.ruoyi.bps.service.IExpressService; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -27,14 +28,21 @@ public class ExpressServiceImpl implements IExpressService { String secret = "8781ed9b35a7438499eb02fee915915a"; String userid = "2a62da2192c24d17a943ff78ee64f8c6"; */ - String key = PropertiesReader.get("key"); + /*String key = PropertiesReader.get("key"); String customer = PropertiesReader.get("customer"); String secret = PropertiesReader.get("secret"); String siid = PropertiesReader.get("siid"); String userid = PropertiesReader.get("userid"); String tid = PropertiesReader.get("tid"); String secret_key = PropertiesReader.get("secret_key"); - String secret_secret = PropertiesReader.get("secret_secret"); + String secret_secret = PropertiesReader.get("secret_secret");*/ + + @Value("${express.key}") + private String key; + + @Value("${express.customer}") + private String customer; + String msg=""; @Autowired IExpressService expressService; diff --git a/box-bps/src/main/resources/account.properties b/box-bps/src/main/resources/account.properties index c7f7dc6a0..eca321a27 100644 --- a/box-bps/src/main/resources/account.properties +++ b/box-bps/src/main/resources/account.properties @@ -1,9 +1,9 @@ #快递100的基础账号信息,可以在这里获取 # https://poll.kuaidi100.com/manager/page/myinfo/enterprise -key = Jydbrxsm2311 -customer = 2DD48B3469B82F2B7700569093AB792B -secret = 8781ed9b35a7438499eb02fee915915a -userid = 2a62da2192c24d17a943ff78ee64f8c6 +#key = kzuyKyAE3985 +#customer = 6774D6F41D773B17027EEBE5CC902C9E +#secret = 4fc7633a027c4fe1a68b68237c236d6e +#userid = bfc0389a986f45c4b36e27d9b18b7bd3 #电子面单快递公司账号信息(非必填) partnerId = @@ -20,6 +20,6 @@ secret_key = secret_secret = #是否记录快递100接口返回结果,建议记录日志或者入库,方便后期有问题双方排查(true:启用 false: 关闭 ) -log.return.record = true +#log.return.record = true #日志记录位置,建议根据自身情况配置 -logPath = logs \ No newline at end of file +#logPath = logs \ No newline at end of file diff --git a/box-test/src/main/java/com/ruoyi/test/conrtroller/GetEcologyInfoTestController.java b/box-test/src/main/java/com/ruoyi/test/conrtroller/GetEcologyInfoTestController.java index faf741d0d..0d52737dc 100644 --- a/box-test/src/main/java/com/ruoyi/test/conrtroller/GetEcologyInfoTestController.java +++ b/box-test/src/main/java/com/ruoyi/test/conrtroller/GetEcologyInfoTestController.java @@ -2,6 +2,7 @@ package com.ruoyi.test.conrtroller; import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.system.service.ISysDeptService; import com.ruoyi.system.service.ISysUserService; import org.springframework.beans.factory.annotation.Autowired; @@ -16,27 +17,20 @@ public class GetEcologyInfoTestController extends BaseController { private ISysUserService userService; @RequestMapping("/anon/getEcologyDept") - public String getEcologyDept() throws Exception { + public AjaxResult getEcologyDept() throws Exception { String url="http://192.168.2.85:90/api/hrm/resful/getHrmdepartmentWithPage"; String params="{\"params\":{\"pagesize\":999999}}"; //return sendPost(url,params); - int result = deptService.syncEcologyDept(url,params); - if(result==200){ - return "同步成功"; - } - return "同步失败"; + return deptService.syncEcologyDept(url,params); + } @RequestMapping("/anon/getEcologyUser") - public String getEcologyUser(){ + public AjaxResult getEcologyUser(){ String url="http://192.168.2.85:90/api/hrm/resful/getHrmUserInfoWithPage"; String params="{\"params\":{\"pagesize\":999999}}"; - int result = userService.syncEcologyUser(url,params); - if(result==200){ - return "同步成功"; - } - return "同步失败"; + return userService.syncEcologyUser(url,params); } /* *//*public Map sendPostWithRest(String url,String params){ diff --git a/box-test/src/main/java/com/ruoyi/test/conrtroller/WechatApiController.java b/box-test/src/main/java/com/ruoyi/test/conrtroller/WechatApiController.java new file mode 100644 index 000000000..ef71ebbee --- /dev/null +++ b/box-test/src/main/java/com/ruoyi/test/conrtroller/WechatApiController.java @@ -0,0 +1,85 @@ +package com.ruoyi.test.conrtroller; + +import com.alibaba.fastjson.JSON; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.system.service.IWechatApiService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Controller +public class WechatApiController extends BaseController { + @Autowired + IWechatApiService wechatApiService; + + @RequestMapping("anon/getAccessToken") + @ResponseBody + public String getAccessToken() { + return wechatApiService.GetAccessToken(); + } + + @GetMapping("anon/userInfo") + @ResponseBody + public Object getJSON(HttpServletRequest request, HttpServletResponse response) throws IOException { + + BufferedReader streamReader = new BufferedReader( new InputStreamReader(request.getInputStream(), "UTF-8")); + StringBuilder responseStrBuilder = new StringBuilder(); + String inputStr; + while ((inputStr = streamReader.readLine()) != null) { + responseStrBuilder.append(inputStr); + } + //return JSON.parseObject(responseStrBuilder.toString(), Map.class); + return JSON.parse(responseStrBuilder.toString()); + + } + + + @GetMapping("anon/SendTextMessageToWechatUser") + @ResponseBody + public Map SendTextMessageToWechatUser() { + List userIdList = new ArrayList<>(); + userIdList.add("2342343243");//错误userId示例 + userIdList.add("erqrqwe");//错误userId示例 + userIdList.add(""); //空UserId示例 + userIdList.add("359"); + if(! String.valueOf(ShiroUtils.getUserId()).equals("359")){ + userIdList.add(String.valueOf(ShiroUtils.getUserId())); + } + Map resultMap = wechatApiService.SendTextMessageToWechatUser(userIdList,"哈哈哈!"); + return resultMap; + } + + @GetMapping("anon/SendTextCardMessageToWechatUser") + @ResponseBody + public Map SendTextCardMessageToWechatUser() { + List userIdList = new ArrayList<>(); + userIdList.add("23456667"); //错误userId示例 + userIdList.add("355354354"); //错误userId示例 + userIdList.add(""); //空UserId示例 + userIdList.add("359"); + //userIdList.add("454"); + //userIdList.add("408"); + if(!String.valueOf(ShiroUtils.getUserId()).equals("359")){ + userIdList.add(String.valueOf(ShiroUtils.getUserId())); + } + String title="号外:特大优惠!限时抢购"; + String description="今年仅此一次,苹果手机1000元起!欢迎前来购买!走过路过,不要错过!"; + String dtailUrl="https://item.jd.com/100008348530.html"; + + Map resultMap = wechatApiService.SendTextCardMessageToWechatUser(userIdList,title,description,dtailUrl); + return resultMap; + } + +} diff --git a/box-test/src/main/java/com/ruoyi/test/conrtroller/XmlWebserviceController.java b/box-test/src/main/java/com/ruoyi/test/conrtroller/XmlWebserviceController.java new file mode 100644 index 000000000..831579088 --- /dev/null +++ b/box-test/src/main/java/com/ruoyi/test/conrtroller/XmlWebserviceController.java @@ -0,0 +1,26 @@ +package com.ruoyi.test.conrtroller; + +import com.ruoyi.common.utils.TopgpXmlUtils; +import com.ruoyi.common.utils.http.HttpUtils; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.HashMap; +import java.util.Map; + +@RestController + +public class XmlWebserviceController { + //private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); + + @PostMapping("/anon/sendXml") + public String SendXml() { + Map map = new HashMap<>(); + map.put("responseInfo", "此处为测试消息"); + String param = TopgpXmlUtils.GetTopgpRequestXml("express_testRequest", map); + String url = "http://192.168.2.81:85/web/ws/r/aws_ttsrv2_toptest"; + String returnXml = HttpUtils.sendXmlPost(url,param); + return TopgpXmlUtils.GetStatusFromTopgpResponse(returnXml).toString(); + + } +} diff --git a/box-test/src/main/resources/templates/test/index.html b/box-test/src/main/resources/templates/test/index.html index 4b05e873e..8579cdc2d 100644 --- a/box-test/src/main/resources/templates/test/index.html +++ b/box-test/src/main/resources/templates/test/index.html @@ -6,7 +6,13 @@

BPS后台管理系统-测试首页



-一、Mybaits配置DML测试-Oracle(第二数据源) + +一、集成企业微信测试 +
  • 推送文本消息到企业微信
  • +
  • 推送文本卡片消息到企业微信
  • +

    + +二、Mybaits配置DML测试-Oracle(第二数据源)
  • 查询所有用户
  • 新增ID为1000的用户
  • 根据ID查询用户,查询id=1000的用户
  • @@ -14,13 +20,13 @@
  • 删除ID为1000的用户
  • -二、Mybaits配置DDL测试-Oracle +三、Mybaits配置DDL测试-Oracle
  • 查询表中的记录数
  • 查询tc_user是否存在
  • Ajax发送获取Json配置测试

    -二、输入后验证测试 +四、输入后验证测试

  • 验证数据表中是否有记录
  • diff --git a/pom.xml b/pom.xml index e7480fd90..e5a734bfc 100644 --- a/pom.xml +++ b/pom.xml @@ -26,9 +26,9 @@ 2.1.4 1.3.1 1.2.76 - 5.7.5 + 5.8.0 5.8.0 - 2.10.0 + 2.11.0 1.4 3.17 1.7 diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java index e123bee99..f751e33b2 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java @@ -1,6 +1,8 @@ package com.ruoyi.web.controller.system; import java.util.List; + +import com.ruoyi.system.service.ISysConfigService; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @@ -37,6 +39,9 @@ public class SysDeptController extends BaseController @Autowired private ISysDeptService deptService; + @Autowired + ISysConfigService configService; + @RequiresPermissions("system:dept:view") @GetMapping() public String dept() @@ -157,7 +162,7 @@ public class SysDeptController extends BaseController /** * 选择部门树 - * + * * @param deptId 部门ID * @param excludeId 排除ID */ @@ -212,14 +217,9 @@ public class SysDeptController extends BaseController @RequiresPermissions("system:dept:sync") @PostMapping("/syncDept") @ResponseBody - public AjaxResult syncDept() - { - String url="http://192.168.2.85:90/api/hrm/resful/getHrmdepartmentWithPage"; - String params="{\"params\":{\"pagesize\":999999}}"; - int result = deptService.syncEcologyDept(url,params); - if(result==200){ - return AjaxResult.success("同步Ecology部门成功,返回状态码:"+result); - } - return AjaxResult.error("同步Ecology部门失败,返回状态码:"+result); + public AjaxResult syncDept() { + String url = "http://192.168.2.85:90/api/hrm/resful/getHrmdepartmentWithPage"; + String params = "{\"params\":{\"pagesize\":999999}}"; + return deptService.syncEcologyDept(url, params); } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java index 4ac9fb758..2cb8c985c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java @@ -4,6 +4,9 @@ import java.util.Date; import java.util.List; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; + +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.common.utils.http.HttpUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; @@ -126,6 +129,14 @@ public class SysIndexController extends BaseController @GetMapping("/system/main") public String main(ModelMap mmap) { + JSONObject wordsJson = JSONObject.parseObject(HttpUtils.sendGet("https://v1.jinrishici.com/all.json","")); + JSONObject oneWordJson = JSONObject.parseObject(HttpUtils.sendGet("https://api.xygeng.cn/one","")); + JSONObject oneWordDataJson = JSONObject.parseObject(oneWordJson.getString("data")); + mmap.put("wordsContent",wordsJson.get("content")); + mmap.put("wordsAuthor",wordsJson.get("author")); + mmap.put("wordsOrigin",wordsJson.getString("origin")); + mmap.put("oneWordOrigin",oneWordDataJson.get("origin")); + mmap.put("oneWordContent",oneWordDataJson.get("content")); mmap.put("version", RuoYiConfig.getVersion()); return "main"; } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java index 9d1abc8fe..5ee51536b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -1,22 +1,37 @@ package com.ruoyi.web.controller.system; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.utils.ServletUtils; -import com.ruoyi.common.utils.StringUtils; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.common.utils.http.HttpUtils; +import com.ruoyi.framework.jwt.service.IJwtTokenService; import com.ruoyi.framework.shiro.util.CustToken; import com.ruoyi.system.service.IWechatApiService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.jwt.utils.JwtUtils; +import com.ruoyi.framework.shiro.service.SysPasswordService; +import com.ruoyi.system.service.ISysUserService; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import java.util.Map; /** @@ -24,9 +39,13 @@ import java.util.Map; * * @author ruoyi */ +@Api(tags = "生成AccessToken接口") @Controller public class SysLoginController extends BaseController { + @Autowired + private IJwtTokenService jwtTokenService; + @Autowired private IWechatApiService wechatApiService; @@ -38,17 +57,15 @@ public class SysLoginController extends BaseController String code= request.getParameter("code"); //String state = request.getParameter("state"); String username=wechatApiService.GetLoginNameWithWechatCode(code); - //如果没有获取到用户名,说明验证失败,跳转登录页 + //如果没有获取到登录名,说明验证失败,跳转登录页 if(StringUtils.isEmpty(username)){ return "login"; } String password=""; - Boolean rememberMe=true; map.put("loginType","wechat"); map.put("username",username); map.put("password",password); - return "loginwechat"; @@ -85,6 +102,26 @@ public class SysLoginController extends BaseController } } + @ApiOperation("获取Json格式AccessToken") + @ApiImplicitParams({ + @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class), + }) + @PostMapping("/jwt/login") + @ResponseBody + public AjaxResult jwtLogin(String username, String password) + { + return jwtTokenService.AjaxResultJwtToken(username,password); + } + + @ApiOperation("获取String格式AccessToken") + @PostMapping("/jwt/topgplogin") + @ResponseBody + public String topgpJwtLogin(String username, String password) + { + return JSONObject.toJSONString(jwtTokenService.AjaxResultJwtToken(username,password)); + } + @GetMapping("/unauth") public String unauth() { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java index 1a6a487fc..cd51e33ff 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java @@ -2,6 +2,8 @@ package com.ruoyi.web.controller.system; import java.util.List; import java.util.stream.Collectors; + +import com.ruoyi.system.service.ISysConfigService; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @@ -52,6 +54,9 @@ public class SysUserController extends BaseController @Autowired private SysPasswordService passwordService; + @Autowired + private ISysConfigService configService; + @RequiresPermissions("system:user:view") @GetMapping() public String user() @@ -293,14 +298,10 @@ public class SysUserController extends BaseController @RequiresPermissions("system:user:sync") @PostMapping("/syncUser") @ResponseBody - public AjaxResult syncDept() - { - String url="http://192.168.2.85:90/api/hrm/resful/getHrmUserInfoWithPage"; - String params="{\"params\":{\"pagesize\":999999}}"; - int result = userService.syncEcologyUser(url,params); - if(result==200){ - return AjaxResult.success("Ecology人员同步成功,返回状态码:"+result); - } - return AjaxResult.error("Ecology人员同步失败,返回状态码:"+result); + public AjaxResult syncUser() { + String url = "http://192.168.2.85:90/api/hrm/resful/getHrmUserInfoWithPage"; + String params = "{\"params\":{\"pagesize\":999999}}"; + return userService.syncEcologyUser(url, params); } + } \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/WechatApiController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/WechatApiController.java deleted file mode 100644 index 5898a1cfa..000000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/WechatApiController.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.ruoyi.web.controller.system; - -import com.alibaba.fastjson.JSON; -import com.ruoyi.common.core.controller.BaseController; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.framework.shiro.util.CustToken; -import com.ruoyi.system.service.IWechatApiService; -import org.apache.shiro.SecurityUtils; -import org.apache.shiro.authc.AuthenticationException; -import org.apache.shiro.subject.Subject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Map; - -@Controller -public class WechatApiController extends BaseController { - @Autowired - IWechatApiService wechatApiService; - - @RequestMapping("anon/getAccessToken") - public String getAccessToken() { - return wechatApiService.GetAccessToken(); - } - - @GetMapping("anon/wechatLogin") - @ResponseBody - public AjaxResult WechatLogin(HttpServletRequest request) - { - String code= request.getParameter("code"); - String state = request.getParameter("state"); - String username=wechatApiService.GetLoginNameWithWechatCode(code); - String password=""; - Boolean rememberMe=true; - String loginType=request.getParameter("loginType"); - - //UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe); - CustToken token=new CustToken(username,password,rememberMe,loginType); - Subject subject = SecurityUtils.getSubject(); - try - { - subject.login(token); - return success(); - } - catch (AuthenticationException e) - { - String msg = "用户或密码错误"; - if (StringUtils.isNotEmpty(e.getMessage())) - { - msg = e.getMessage(); - } - return error(msg); - } - - } - - @GetMapping("anon/userInfo") - public Map getJSON(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - - BufferedReader streamReader = new BufferedReader( new InputStreamReader(request.getInputStream(), "UTF-8")); - StringBuilder responseStrBuilder = new StringBuilder(); - String inputStr; - while ((inputStr = streamReader.readLine()) != null) { - responseStrBuilder.append(inputStr); - } - Map params = JSON.parseObject(responseStrBuilder.toString(), Map.class); - return params; - } - - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java index 4588a7a53..b609defb0 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java @@ -47,7 +47,7 @@ public class TestController extends BaseController } @ApiOperation("获取用户详细") - @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path",dataTypeClass = Integer.class ) @GetMapping("/{userId}") public AjaxResult getUser(@PathVariable Integer userId) { @@ -63,10 +63,10 @@ public class TestController extends BaseController @ApiOperation("新增用户") @ApiImplicitParams({ - @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer"), - @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String"), - @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String"), - @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String") + @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class), + @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class) }) @PostMapping("/save") public AjaxResult save(UserEntity user) @@ -95,7 +95,7 @@ public class TestController extends BaseController } @ApiOperation("删除用户信息") - @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) @DeleteMapping("/{userId}") public AjaxResult delete(@PathVariable Integer userId) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java index 0cfbfbadb..0a3f38239 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java @@ -55,9 +55,9 @@ public class SwaggerConfig // 用ApiInfoBuilder进行定制 return new ApiInfoBuilder() // 设置标题 - .title("标题:若依管理系统_接口文档") + .title("BPS管理系统_接口文档") // 描述 - .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...") + .description("描述:用于管理系统的各类接口的文档说明。") // 作者信息 .contact(new Contact(RuoYiConfig.getName(), null, null)) // 版本 diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml index cdc620e0a..86ea6e820 100644 --- a/ruoyi-admin/src/main/resources/application-druid.yml +++ b/ruoyi-admin/src/main/resources/application-druid.yml @@ -16,7 +16,7 @@ spring: url: jdbc:oracle:thin:@192.168.2.91:1521/toptest username: ds7 password: ds7 - driverClassName: oracle.jdbc.driver.OracleDriver + driverClassName: oracle.jdbc.OracleDriver #SQlServer数据源 sqlsvr: # 从数据源开关/默认关闭 @@ -33,7 +33,7 @@ spring: url: jdbc:oracle:thin:@192.168.2.91:1521/topprod username: ds_report password: ds_report - driverClassName: oracle.jdbc.driver.OracleDriver + driverClassName: oracle.jdbc.OracleDriver # Toptest_ds_report toptestdsreport: @@ -42,7 +42,7 @@ spring: url: jdbc:oracle:thin:@192.168.2.91:1521/toptest username: ds_report password: ds_report - driverClassName: oracle.jdbc.driver.OracleDriver + driverClassName: oracle.jdbc.OracleDriver # 初始连接数 initialSize: 5 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 37267eb23..66d0b7258 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -104,7 +104,6 @@ mybatis: # PageHelper分页插件 pagehelper: helperDialect: mysql - reasonable: true supportMethodsArguments: true params: count=countSql @@ -161,7 +160,27 @@ swagger: #企业微信 wechat: corpId: ww4ed3771457e5f463 - agentId: 1000080 - secret: drtHKYabI9_EgjJQ8aqDPTQkY1WUYeWUTMkYw7D_z64 + agentId: 1000082 + secret: PqTYlveYQc54T13QS-cDyuAesDaGgyMSgpZLXBNJ-Uc token: 111 - aesKey: 111 \ No newline at end of file + aesKey: 111 + +#快递100 +express: + #快递100的基础账号信息,可以在这里获取 + # https://poll.kuaidi100.com/manager/page/myinfo/enterprise + key: kzuyKyAE3985 + customer: 6774D6F41D773B17027EEBE5CC902C9E + secret: 4fc7633a027c4fe1a68b68237c236d6e + userid: bfc0389a986f45c4b36e27d9b18b7bd3 + #电子面单快递公司账号信息(非必填) + partnerId: + partnerKey: + net: + siid: + #短信模板id(非必填) + tid: + #云平台相关(非必填) + #登录云平台 https://cloud.kuaidi100.com/buyer/user/info + secret_key: + secret_secret: \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/static/img/profile.jpg b/ruoyi-admin/src/main/resources/static/img/profile.jpg index b3a940b21..91e9a7a35 100644 Binary files a/ruoyi-admin/src/main/resources/static/img/profile.jpg and b/ruoyi-admin/src/main/resources/static/img/profile.jpg differ diff --git a/ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js b/ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js index 82759721b..2c38d8f24 100644 --- a/ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js +++ b/ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js @@ -10,12 +10,12 @@ var table = { options: {}, // 设置实例配置 set: function(id) { - if($.common.getLength(table.config) > 1) { + if($.common.getLength(table.config) > 1) { var tableId = $.common.isEmpty(id) ? $(event.currentTarget).parents(".bootstrap-table").find("table.table").attr("id") : id; if ($.common.isNotEmpty(tableId)) { table.options = table.get(tableId); } - } + } }, // 获取实例配置 get: function(id) { @@ -29,13 +29,13 @@ var table = { (function ($) { $.extend({ - _tree: {}, - bttTable: {}, - // 表格封装处理 - table: { + _tree: {}, + bttTable: {}, + // 表格封装处理 + table: { // 初始化表格参数 init: function(options) { - var defaults = { + var defaults = { id: "bootstrap-table", type: 0, // 0 代表bootstrapTable 1代表bootstrapTreeTable method: 'post', @@ -75,9 +75,9 @@ var table = { queryParams: $.table.queryParams, rowStyle: undefined, }; - var options = $.extend(defaults, options); - table.options = options; - table.config[options.id] = options; + var options = $.extend(defaults, options); + table.options = options; + table.config[options.id] = options; $.table.initEvent(); $('#' + options.id).bootstrapTable({ id: options.id, @@ -154,12 +154,12 @@ var table = { }, // 获取实例ID,如存在多个返回#id1,#id2 delimeter分隔符 getOptionsIds: function(separator) { - var _separator = $.common.isEmpty(separator) ? "," : separator; - var optionsIds = ""; - $.each(table.config, function(key, value){ + var _separator = $.common.isEmpty(separator) ? "," : separator; + var optionsIds = ""; + $.each(table.config, function(key, value){ optionsIds += "#" + key + _separator; - }); - return optionsIds.substring(0, optionsIds.length - 1); + }); + return optionsIds.substring(0, optionsIds.length - 1); }, // 查询条件 queryParams: function(params) { @@ -171,24 +171,24 @@ var table = { orderByColumn: params.sort, isAsc: params.order }; - var currentId = $.common.isEmpty(table.options.formId) ? $('form').attr('id') : table.options.formId; - return $.extend(curParams, $.common.formToJSON(currentId)); + var currentId = $.common.isEmpty(table.options.formId) ? $('form').attr('id') : table.options.formId; + return $.extend(curParams, $.common.formToJSON(currentId)); }, // 请求获取数据后处理回调函数 responseHandler: function(res) { - if (typeof table.get(this.id).responseHandler == "function") { + if (typeof table.get(this.id).responseHandler == "function") { table.get(this.id).responseHandler(res); } if (res.code == web_status.SUCCESS) { if ($.common.isNotEmpty(table.options.sidePagination) && table.options.sidePagination == 'client') { - return res.rows; + return res.rows; } else { - if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) { + if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) { var column = $.common.isEmpty(table.options.uniqueId) ? table.options.columns[1].field : table.options.uniqueId; $.each(res.rows, function(i, row) { row.state = $.inArray(row[column], table.rememberSelectedIds[table.options.id]) !== -1; }) - } + } return { rows: res.rows, total: res.total }; } } else { @@ -198,21 +198,21 @@ var table = { }, // 初始化事件 initEvent: function() { - // 实例ID信息 - var optionsIds = $.table.getOptionsIds(); - // 监听事件处理 - $(optionsIds).on(TABLE_EVENTS, function () { + // 实例ID信息 + var optionsIds = $.table.getOptionsIds(); + // 监听事件处理 + $(optionsIds).on(TABLE_EVENTS, function () { table.set($(this).attr("id")); - }); - // 在表格体渲染完成,并在 DOM 中可见后触发(事件) - $(optionsIds).on("post-body.bs.table", function (e, args) { + }); + // 在表格体渲染完成,并在 DOM 中可见后触发(事件) + $(optionsIds).on("post-body.bs.table", function (e, args) { // 浮动提示框特效 $(".table [data-toggle='tooltip']").tooltip(); // 气泡弹出框特效 $('.table [data-toggle="popover"]').popover(); - }); - // 选中、取消、全部选中、全部取消(事件) - $(optionsIds).on("check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table", function (e, rowsAfter, rowsBefore) { + }); + // 选中、取消、全部选中、全部取消(事件) + $(optionsIds).on("check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table", function (e, rowsAfter, rowsBefore) { // 复选框分页保留保存选中数组 var rows = $.common.equals("uncheck-all", e.type) ? rowsBefore : rowsAfter; var rowIds = $.table.affectedRowIds(rows); @@ -231,9 +231,9 @@ var table = { table.rememberSelecteds[table.options.id] = _[func]([], rows); } } - }); - // 加载成功、选中、取消、全部选中、全部取消(事件) - $(optionsIds).on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table load-success.bs.table", function () { + }); + // 加载成功、选中、取消、全部选中、全部取消(事件) + $(optionsIds).on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table load-success.bs.table", function () { var toolbar = table.options.toolbar; var uniqueId = table.options.uniqueId; // 工具栏按钮控制 @@ -242,9 +242,9 @@ var table = { $('#' + toolbar + ' .multiple').toggleClass('disabled', !rows.length); // 非单个禁用 $('#' + toolbar + ' .single').toggleClass('disabled', rows.length!=1); - }); - // 图片预览事件 - $(optionsIds).off("click").on("click", '.img-circle', function() { + }); + // 图片预览事件 + $(optionsIds).off("click").on("click", '.img-circle', function() { var src = $(this).attr('src'); var target = $(this).data('target'); if($.common.equals("self", target)) { @@ -262,8 +262,8 @@ var table = { window.open(src); } }); - // 单击tooltip事件 - $(optionsIds).on("click", '.tooltip-show', function() { + // 单击tooltip事件 + $(optionsIds).on("click", '.tooltip-show', function() { var target = $(this).data('target'); var input = $(this).prev(); if ($.common.equals("copy", target)) { @@ -277,20 +277,20 @@ var table = { btnclass: ['btn btn-primary'], }); } - }); + }); }, // 当所有数据被加载时触发 onLoadSuccess: function(data) { - if (typeof table.options.onLoadSuccess == "function") { + if (typeof table.options.onLoadSuccess == "function") { table.options.onLoadSuccess(data); - } + } }, // 表格销毁 destroy: function (tableId) { - var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; - $("#" + currentId).bootstrapTable('destroy'); - delete table.rememberSelectedIds[currentId]; - delete table.rememberSelecteds[currentId]; + var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; + $("#" + currentId).bootstrapTable('destroy'); + delete table.rememberSelectedIds[currentId]; + delete table.rememberSelecteds[currentId]; }, // 序列号生成 serialNumber: function (index, tableId) { @@ -353,10 +353,10 @@ var table = { table.options.formId = $.common.isEmpty(formId) ? $('form').attr('id') : formId; var params = $.common.isEmpty(tableId) ? $("#" + table.options.id).bootstrapTable('getOptions') : $("#" + tableId).bootstrapTable('getOptions'); if ($.common.isNotEmpty(pageNumber)) { - params.pageNumber = pageNumber; + params.pageNumber = pageNumber; } if ($.common.isNotEmpty(pageSize)) { - params.pageSize = pageSize; + params.pageSize = pageSize; } if($.common.isNotEmpty(tableId)){ $("#" + tableId).bootstrapTable('refresh', params); @@ -401,11 +401,11 @@ var table = { }, // 导入数据 importExcel: function(formId, width, height) { - table.set(); - var currentId = $.common.isEmpty(formId) ? 'importTpl' : formId; - var _width = $.common.isEmpty(width) ? "400" : width; + table.set(); + var currentId = $.common.isEmpty(formId) ? 'importTpl' : formId; + var _width = $.common.isEmpty(width) ? "400" : width; var _height = $.common.isEmpty(height) ? "230" : height; - layer.open({ + layer.open({ type: 1, area: [_width + 'px', _height + 'px'], fix: false, @@ -450,22 +450,22 @@ var table = { } }); } - }); + }); }, // 刷新表格 refresh: function(tableId, pageNumber, pageSize, url) { - var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; - var params = $("#" + currentId).bootstrapTable('getOptions'); - if ($.common.isEmpty(pageNumber)) { - pageNumber = params.pageNumber; - } - if ($.common.isEmpty(pageSize)) { - pageSize = params.pageSize; - } - if ($.common.isEmpty(url)) { - url = $.common.isEmpty(url) ? params.url : url; - } - $("#" + currentId).bootstrapTable('refresh', { + var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; + var params = $("#" + currentId).bootstrapTable('getOptions'); + if ($.common.isEmpty(pageNumber)) { + pageNumber = params.pageNumber; + } + if ($.common.isEmpty(pageSize)) { + pageSize = params.pageSize; + } + if ($.common.isEmpty(url)) { + url = $.common.isEmpty(url) ? params.url : url; + } + $("#" + currentId).bootstrapTable('refresh', { silent: true, url: url, pageNumber: pageNumber, @@ -477,59 +477,61 @@ var table = { var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; $("#" + currentId).bootstrapTable('refreshOptions', options); }, - // 查询表格指定列值 - selectColumns: function(column) { - var rows = $.map($("#" + table.options.id).bootstrapTable('getSelections'), function (row) { + // 查询表格指定列值 deDuplication( true去重、false不去重) + selectColumns: function(column, deDuplication) { + var distinct = $.common.isEmpty(deDuplication) ? true : deDuplication; + var rows = $.map($("#" + table.options.id).bootstrapTable('getSelections'), function (row) { return $.common.getItemField(row, column); - }); - if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) { - var selectedRows = table.rememberSelecteds[table.options.id]; - if($.common.isNotEmpty(selectedRows)) { - rows = $.map(table.rememberSelecteds[table.options.id], function (row) { - return $.common.getItemField(row, column); - }); - } - } - return $.common.uniqueFn(rows); + }); + if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) { + var selectedRows = table.rememberSelecteds[table.options.id]; + if($.common.isNotEmpty(selectedRows)) { + rows = $.map(table.rememberSelecteds[table.options.id], function (row) { + return $.common.getItemField(row, column); + }); + } + } + return distinct ? $.common.uniqueFn(rows) : rows; }, // 获取当前页选中或者取消的行ID affectedRowIds: function(rows) { - var column = $.common.isEmpty(table.options.uniqueId) ? table.options.columns[1].field : table.options.uniqueId; - var rowIds; - if ($.isArray(rows)) { - rowIds = $.map(rows, function(row) { - return $.common.getItemField(row, column); - }); - } else { - rowIds = [rows[column]]; - } - return rowIds; + var column = $.common.isEmpty(table.options.uniqueId) ? table.options.columns[1].field : table.options.uniqueId; + var rowIds; + if ($.isArray(rows)) { + rowIds = $.map(rows, function(row) { + return $.common.getItemField(row, column); + }); + } else { + rowIds = [rows[column]]; + } + return rowIds; }, - // 查询表格首列值 - selectFirstColumns: function() { - var rows = $.map($("#" + table.options.id).bootstrapTable('getSelections'), function (row) { + // 查询表格首列值deDuplication( true去重、false不去重) + selectFirstColumns: function(deDuplication) { + var distinct = $.common.isEmpty(deDuplication) ? true : deDuplication; + var rows = $.map($("#" + table.options.id).bootstrapTable('getSelections'), function (row) { return $.common.getItemField(row, table.options.columns[1].field); }); - if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) { + if ($.common.isNotEmpty(table.options.rememberSelected) && table.options.rememberSelected) { var selectedRows = table.rememberSelecteds[table.options.id]; if($.common.isNotEmpty(selectedRows)) { rows = $.map(selectedRows, function (row) { return $.common.getItemField(row, table.options.columns[1].field); }); } - } - return $.common.uniqueFn(rows); + } + return distinct ? $.common.uniqueFn(rows) : rows; }, // 回显数据字典 selectDictLabel: function(datas, value) { - if ($.common.isEmpty(datas) || $.common.isEmpty(value)) { - return ''; - } - var actions = []; + if ($.common.isEmpty(datas) || $.common.isEmpty(value)) { + return ''; + } + var actions = []; $.each(datas, function(index, dict) { if (dict.dictValue == ('' + value)) { - var listClass = $.common.equals("default", dict.listClass) || $.common.isEmpty(dict.listClass) ? "" : "badge badge-" + dict.listClass; - actions.push($.common.sprintf("%s", listClass, dict.dictLabel)); + var listClass = $.common.equals("default", dict.listClass) || $.common.isEmpty(dict.listClass) ? "" : "badge badge-" + dict.listClass; + actions.push($.common.sprintf("%s", listClass, dict.dictLabel)); return false; } }); @@ -537,11 +539,11 @@ var table = { }, // 回显数据字典(字符串数组) selectDictLabels: function(datas, value, separator) { - if ($.common.isEmpty(datas) || $.common.isEmpty(value)) { - return ''; - } - var currentSeparator = $.common.isEmpty(separator) ? "," : separator; - var actions = []; + if ($.common.isEmpty(datas) || $.common.isEmpty(value)) { + return ''; + } + var currentSeparator = $.common.isEmpty(separator) ? "," : separator; + var actions = []; $.each(value.split(currentSeparator), function(i, val) { $.each(datas, function(index, dict) { if (dict.dictValue == ('' + val)) { @@ -555,30 +557,30 @@ var table = { }, // 显示表格指定列 showColumn: function(column, tableId) { - var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; - $("#" + currentId).bootstrapTable('showColumn', column); + var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; + $("#" + currentId).bootstrapTable('showColumn', column); }, // 隐藏表格指定列 hideColumn: function(column, tableId) { - var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; - $("#" + currentId).bootstrapTable('hideColumn', column); + var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; + $("#" + currentId).bootstrapTable('hideColumn', column); }, // 显示所有表格列 showAllColumns: function(tableId) { - var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; - $("#" + currentId).bootstrapTable('showAllColumns'); + var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; + $("#" + currentId).bootstrapTable('showAllColumns'); }, // 隐藏所有表格列 hideAllColumns: function(tableId) { - var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; - $("#" + currentId).bootstrapTable('hideAllColumns'); + var currentId = $.common.isEmpty(tableId) ? table.options.id : tableId; + $("#" + currentId).bootstrapTable('hideAllColumns'); } }, // 表格树封装处理 treeTable: { // 初始化表格 init: function(options) { - var defaults = { + var defaults = { id: "bootstrap-tree-table", type: 1, // 0 代表bootstrapTable 1代表bootstrapTreeTable height: 0, @@ -593,10 +595,10 @@ var table = { expandAll: true, expandFirst: true }; - var options = $.extend(defaults, options); - table.options = options; - table.config[options.id] = options; - $.table.initEvent(); + var options = $.extend(defaults, options); + table.options = options; + table.config[options.id] = options; + $.table.initEvent(); $.bttTable = $('#' + options.id).bootstrapTreeTable({ code: options.code, // 用于设置父子关系 parentCode: options.parentCode, // 用于设置父子关系 @@ -622,27 +624,28 @@ var table = { }, // 条件查询 search: function(formId) { - var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId; - var params = $.common.formToJSON(currentId); + var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId; + var params = $.common.formToJSON(currentId); $.bttTable.bootstrapTreeTable('refresh', params); }, // 刷新 refresh: function() { - $.bttTable.bootstrapTreeTable('refresh'); + $.bttTable.bootstrapTreeTable('refresh'); }, - // 查询表格树指定列值 - selectColumns: function(column) { + // 查询表格树指定列值deDuplication( true去重、false不去重) + selectColumns: function(column, deDuplication) { + var distinct = $.common.isEmpty(deDuplication) ? true : deDuplication; var rows = $.map($.bttTable.bootstrapTreeTable('getSelections'), function (row) { return $.common.getItemField(row, column); }); - return $.common.uniqueFn(rows); + return distinct ? $.common.uniqueFn(rows) : rows; }, // 请求获取数据后处理回调函数,校验异常状态提醒 responseHandler: function(res) { - if (typeof table.options.responseHandler == "function") { + if (typeof table.options.responseHandler == "function") { table.options.responseHandler(res); } - if (res.code != undefined && res.code != web_status.SUCCESS) { + if (res.code != undefined && res.code != web_status.SUCCESS) { $.modal.alertWarning(res.msg); return []; } else { @@ -651,36 +654,36 @@ var table = { }, // 当所有数据被加载时触发 onLoadSuccess: function(data) { - if (typeof table.options.onLoadSuccess == "function") { + if (typeof table.options.onLoadSuccess == "function") { table.options.onLoadSuccess(data); - } - $(".table [data-toggle='tooltip']").tooltip(); + } + $(".table [data-toggle='tooltip']").tooltip(); }, }, // 表单封装处理 - form: { + form: { // 表单重置 reset: function(formId, tableId, pageNumber, pageSize) { table.set(tableId); - formId = $.common.isEmpty(formId) ? $('form').attr('id') : formId; - $("#" + formId)[0].reset(); - var tableId = $.common.isEmpty(tableId) ? table.options.id : tableId; - if (table.options.type == table_type.bootstrapTable) { - var params = $("#" + tableId).bootstrapTable('getOptions'); + formId = $.common.isEmpty(formId) ? $('form').attr('id') : formId; + $("#" + formId)[0].reset(); + var tableId = $.common.isEmpty(tableId) ? table.options.id : tableId; + if (table.options.type == table_type.bootstrapTable) { + var params = $("#" + tableId).bootstrapTable('getOptions'); if ($.common.isNotEmpty(pageNumber)) { - params.pageNumber = pageNumber; + params.pageNumber = pageNumber; } if ($.common.isNotEmpty(pageSize)) { - params.pageSize = pageSize; + params.pageSize = pageSize; } $("#" + tableId).bootstrapTable('refresh', params); - } else if (table.options.type == table_type.bootstrapTreeTable) { - $("#" + tableId).bootstrapTreeTable('refresh', []); - } + } else if (table.options.type == table_type.bootstrapTreeTable) { + $("#" + tableId).bootstrapTreeTable('refresh', []); + } }, // 获取选中复选框项 selectCheckeds: function(name) { - var checkeds = ""; + var checkeds = ""; $('input:checkbox[name="' + name + '"]:checked').each(function(i) { if (0 == i) { checkeds = $(this).val(); @@ -692,19 +695,19 @@ var table = { }, // 获取选中下拉框项 selectSelects: function(name) { - var selects = ""; - $('#' + name + ' option:selected').each(function (i) { - if (0 == i) { - selects = $(this).val(); - } else { - selects += ("," + $(this).val()); - } - }); - return selects; + var selects = ""; + $('#' + name + ' option:selected').each(function (i) { + if (0 == i) { + selects = $(this).val(); + } else { + selects += ("," + $(this).val()); + } + }); + return selects; } }, // 弹出层封装处理 - modal: { + modal: { // 显示图标 icon: function(type) { var icon = ""; @@ -721,7 +724,7 @@ var table = { }, // 消息提示 msg: function(content, type) { - if (type != undefined) { + if (type != undefined) { layer.msg(content, { icon: $.modal.icon(type), time: 1000, shift: 5 }); } else { layer.msg(content); @@ -729,15 +732,15 @@ var table = { }, // 错误消息 msgError: function(content) { - $.modal.msg(content, modal_status.FAIL); + $.modal.msg(content, modal_status.FAIL); }, // 成功消息 msgSuccess: function(content) { - $.modal.msg(content, modal_status.SUCCESS); + $.modal.msg(content, modal_status.SUCCESS); }, // 警告消息 msgWarning: function(content) { - $.modal.msg(content, modal_status.WARNING); + $.modal.msg(content, modal_status.WARNING); }, // 弹出提示 alert: function(content, type) { @@ -750,26 +753,26 @@ var table = { }, // 消息提示并刷新父窗体 msgReload: function(msg, type) { - layer.msg(msg, { - icon: $.modal.icon(type), - time: 500, - shade: [0.1, '#8F8F8F'] - }, - function() { - $.modal.reload(); - }); + layer.msg(msg, { + icon: $.modal.icon(type), + time: 500, + shade: [0.1, '#8F8F8F'] + }, + function() { + $.modal.reload(); + }); }, // 错误提示 alertError: function(content) { - $.modal.alert(content, modal_status.FAIL); + $.modal.alert(content, modal_status.FAIL); }, // 成功提示 alertSuccess: function(content) { - $.modal.alert(content, modal_status.SUCCESS); + $.modal.alert(content, modal_status.SUCCESS); }, // 警告提示 alertWarning: function(content) { - $.modal.alert(content, modal_status.WARNING); + $.modal.alert(content, modal_status.WARNING); }, // 关闭窗体 close: function (index) { @@ -797,22 +800,22 @@ var table = { }, // 弹出层指定宽度 open: function (title, url, width, height, callback) { - // 如果是移动端,就使用自适应大小弹窗 - if ($.common.isMobile()) { - width = 'auto'; - height = 'auto'; - } - if ($.common.isEmpty(title)) { + // 如果是移动端,就使用自适应大小弹窗 + if ($.common.isMobile()) { + width = 'auto'; + height = 'auto'; + } + if ($.common.isEmpty(title)) { title = false; } if ($.common.isEmpty(url)) { - url = "/404.html"; + url = "/404.html"; } if ($.common.isEmpty(width)) { - width = 800; + width = 800; } if ($.common.isEmpty(height)) { - height = ($(window).height() - 50); + height = ($(window).height() - 50); } if ($.common.isEmpty(callback)) { callback = function(index, layero) { @@ -820,36 +823,36 @@ var table = { iframeWin.contentWindow.submitHandler(index, layero); } } - layer.open({ - type: 2, - area: [width + 'px', height + 'px'], - fix: false, - //不固定 - maxmin: true, - shade: 0.3, - title: title, - content: url, - btn: ['确定', '关闭'], - // 弹层外区域关闭 - shadeClose: true, - yes: callback, - cancel: function(index) { - return true; - } - }); + layer.open({ + type: 2, + area: [width + 'px', height + 'px'], + fix: false, + //不固定 + maxmin: true, + shade: 0.3, + title: title, + content: url, + btn: ['确定', '关闭'], + // 弹层外区域关闭 + shadeClose: true, + yes: callback, + cancel: function(index) { + return true; + } + }); }, // 弹出层指定参数选项 openOptions: function (options) { - var _url = $.common.isEmpty(options.url) ? "/404.html" : options.url; - var _title = $.common.isEmpty(options.title) ? "系统窗口" : options.title; + var _url = $.common.isEmpty(options.url) ? "/404.html" : options.url; + var _title = $.common.isEmpty(options.title) ? "系统窗口" : options.title; var _width = $.common.isEmpty(options.width) ? "800" : options.width; var _height = $.common.isEmpty(options.height) ? ($(window).height() - 50) : options.height; var _btn = [' 确认', ' 关闭']; - // 如果是移动端,就使用自适应大小弹窗 - if ($.common.isMobile()) { - _width = 'auto'; - _height = 'auto'; - } + // 如果是移动端,就使用自适应大小弹窗 + if ($.common.isMobile()) { + _width = 'auto'; + _height = 'auto'; + } if ($.common.isEmpty(options.yes)) { options.yes = function(index, layero) { options.callBack(index, layero); @@ -886,22 +889,22 @@ var table = { }, // 弹出层全屏 openFull: function (title, url, width, height) { - // 如果是移动端,就使用自适应大小弹窗 - if ($.common.isMobile()) { - width = 'auto'; - height = 'auto'; - } - if ($.common.isEmpty(title)) { + // 如果是移动端,就使用自适应大小弹窗 + if ($.common.isMobile()) { + width = 'auto'; + height = 'auto'; + } + if ($.common.isEmpty(title)) { title = false; } if ($.common.isEmpty(url)) { url = "/404.html"; } if ($.common.isEmpty(width)) { - width = 800; + width = 800; } if ($.common.isEmpty(height)) { - height = ($(window).height() - 50); + height = ($(window).height() - 50); } var index = layer.open({ type: 2, @@ -922,46 +925,46 @@ var table = { cancel: function(index) { return true; } - }); + }); layer.full(index); }, // 选卡页方式打开 openTab: function (title, url, isRefresh) { - createMenuItem(url, title, isRefresh); + createMenuItem(url, title, isRefresh); }, // 选卡页同一页签打开 parentTab: function (title, url) { - var dataId = window.frameElement.getAttribute('data-id'); - createMenuItem(url, title); - closeItem(dataId); + var dataId = window.frameElement.getAttribute('data-id'); + createMenuItem(url, title); + closeItem(dataId); }, // 关闭选项卡 closeTab: function (dataId) { - closeItem(dataId); + closeItem(dataId); }, // 禁用按钮 disable: function() { - var doc = window.top == window.parent ? window.document : window.parent.document; - $("a[class*=layui-layer-btn]", doc).addClass("layer-disabled"); + var doc = window.top == window.parent ? window.document : window.parent.document; + $("a[class*=layui-layer-btn]", doc).addClass("layer-disabled"); }, // 启用按钮 enable: function() { - var doc = window.top == window.parent ? window.document : window.parent.document; - $("a[class*=layui-layer-btn]", doc).removeClass("layer-disabled"); + var doc = window.top == window.parent ? window.document : window.parent.document; + $("a[class*=layui-layer-btn]", doc).removeClass("layer-disabled"); }, // 打开遮罩层 loading: function (message) { - $.blockUI({ message: '

    ' + message + '
    ' }); + $.blockUI({ message: '
    ' + message + '
    ' }); }, // 关闭遮罩层 closeLoading: function () { - setTimeout(function(){ - $.unblockUI(); - }, 50); + setTimeout(function(){ + $.unblockUI(); + }, 50); }, // 重新加载 reload: function () { - parent.location.reload(); + parent.location.reload(); } }, // 操作封装处理 @@ -987,17 +990,17 @@ var table = { }, // post请求传输 post: function(url, data, callback) { - $.operate.submit(url, "post", "json", data, callback); + $.operate.submit(url, "post", "json", data, callback); }, // get请求传输 get: function(url, callback) { - $.operate.submit(url, "get", "json", "", callback); + $.operate.submit(url, "get", "json", "", callback); }, // 详细信息 detail: function(id, width, height) { - table.set(); - var _url = $.operate.detailUrl(id); - var options = { + table.set(); + var _url = $.operate.detailUrl(id); + var options = { title: table.options.modalName + "详细", width: width, height: height, @@ -1008,231 +1011,231 @@ var table = { layer.close(index); } }; - $.modal.openOptions(options); + $.modal.openOptions(options); }, // 详细信息,以tab页展现 detailTab: function(id) { - table.set(); - $.modal.openTab("详细" + table.options.modalName, $.operate.detailUrl(id)); + table.set(); + $.modal.openTab("详细" + table.options.modalName, $.operate.detailUrl(id)); }, // 详细访问地址 detailUrl: function(id) { - var url = "/404.html"; - if ($.common.isNotEmpty(id)) { - url = table.options.detailUrl.replace("{id}", id); - } else { - var id = $.common.isEmpty(table.options.uniqueId) ? $.table.selectFirstColumns() : $.table.selectColumns(table.options.uniqueId); - if (id.length == 0) { + var url = "/404.html"; + if ($.common.isNotEmpty(id)) { + url = table.options.detailUrl.replace("{id}", id); + } else { + var id = $.common.isEmpty(table.options.uniqueId) ? $.table.selectFirstColumns() : $.table.selectColumns(table.options.uniqueId); + if (id.length == 0) { $.modal.alertWarning("请至少选择一条记录"); return; - } - url = table.options.detailUrl.replace("{id}", id); - } + } + url = table.options.detailUrl.replace("{id}", id); + } return url; }, // 删除信息 remove: function(id) { - table.set(); - $.modal.confirm("确定删除该条" + table.options.modalName + "信息吗?", function() { + table.set(); + $.modal.confirm("确定删除该条" + table.options.modalName + "信息吗?", function() { var url = $.common.isEmpty(id) ? table.options.removeUrl : table.options.removeUrl.replace("{id}", id); if(table.options.type == table_type.bootstrapTreeTable) { - $.operate.get(url); + $.operate.get(url); } else { - var data = { "ids": id }; - $.operate.submit(url, "post", "json", data); + var data = { "ids": id }; + $.operate.submit(url, "post", "json", data); } - }); + }); }, // 批量删除信息 removeAll: function() { - table.set(); - var rows = $.common.isEmpty(table.options.uniqueId) ? $.table.selectFirstColumns() : $.table.selectColumns(table.options.uniqueId); - if (rows.length == 0) { - $.modal.alertWarning("请至少选择一条记录"); - return; - } - $.modal.confirm("确认要删除选中的" + rows.length + "条数据吗?", function() { - var url = table.options.removeUrl; - var data = { "ids": rows.join() }; - $.operate.submit(url, "post", "json", data); - }); + table.set(); + var rows = $.common.isEmpty(table.options.uniqueId) ? $.table.selectFirstColumns() : $.table.selectColumns(table.options.uniqueId); + if (rows.length == 0) { + $.modal.alertWarning("请至少选择一条记录"); + return; + } + $.modal.confirm("确认要删除选中的" + rows.length + "条数据吗?", function() { + var url = table.options.removeUrl; + var data = { "ids": rows.join() }; + $.operate.submit(url, "post", "json", data); + }); }, // 清空信息 clean: function() { - table.set(); - $.modal.confirm("确定清空所有" + table.options.modalName + "吗?", function() { - var url = table.options.cleanUrl; - $.operate.submit(url, "post", "json", ""); - }); + table.set(); + $.modal.confirm("确定清空所有" + table.options.modalName + "吗?", function() { + var url = table.options.cleanUrl; + $.operate.submit(url, "post", "json", ""); + }); }, // 添加信息 add: function(id) { - table.set(); - $.modal.open("添加" + table.options.modalName, $.operate.addUrl(id)); + table.set(); + $.modal.open("添加" + table.options.modalName, $.operate.addUrl(id)); }, // 添加信息,以tab页展现 addTab: function (id) { - table.set(); + table.set(); $.modal.openTab("添加" + table.options.modalName, $.operate.addUrl(id)); }, // 添加信息 全屏 addFull: function(id) { - table.set(); + table.set(); $.modal.openFull("添加" + table.options.modalName, $.operate.addUrl(id)); }, // 添加访问地址 addUrl: function(id) { - var url = $.common.isEmpty(id) ? table.options.createUrl.replace("{id}", "") : table.options.createUrl.replace("{id}", id); + var url = $.common.isEmpty(id) ? table.options.createUrl.replace("{id}", "") : table.options.createUrl.replace("{id}", id); return url; }, // 修改信息 edit: function(id) { - table.set(); - if($.common.isEmpty(id) && table.options.type == table_type.bootstrapTreeTable) { - var row = $("#" + table.options.id).bootstrapTreeTable('getSelections')[0]; - if ($.common.isEmpty(row)) { - $.modal.alertWarning("请至少选择一条记录"); - return; - } - var url = table.options.updateUrl.replace("{id}", row[table.options.uniqueId]); - $.modal.open("修改" + table.options.modalName, url); - } else { - $.modal.open("修改" + table.options.modalName, $.operate.editUrl(id)); - } + table.set(); + if($.common.isEmpty(id) && table.options.type == table_type.bootstrapTreeTable) { + var row = $("#" + table.options.id).bootstrapTreeTable('getSelections')[0]; + if ($.common.isEmpty(row)) { + $.modal.alertWarning("请至少选择一条记录"); + return; + } + var url = table.options.updateUrl.replace("{id}", row[table.options.uniqueId]); + $.modal.open("修改" + table.options.modalName, url); + } else { + $.modal.open("修改" + table.options.modalName, $.operate.editUrl(id)); + } }, // 修改信息,以tab页展现 editTab: function(id) { - table.set(); - $.modal.openTab("修改" + table.options.modalName, $.operate.editUrl(id)); + table.set(); + $.modal.openTab("修改" + table.options.modalName, $.operate.editUrl(id)); }, // 修改信息 全屏 editFull: function(id) { - table.set(); - var url = "/404.html"; - if ($.common.isNotEmpty(id)) { - url = table.options.updateUrl.replace("{id}", id); - } else { - if(table.options.type == table_type.bootstrapTreeTable) { - var row = $("#" + table.options.id).bootstrapTreeTable('getSelections')[0]; - if ($.common.isEmpty(row)) { - $.modal.alertWarning("请至少选择一条记录"); - return; - } - url = table.options.updateUrl.replace("{id}", row[table.options.uniqueId]); - } else { - var row = $.common.isEmpty(table.options.uniqueId) ? $.table.selectFirstColumns() : $.table.selectColumns(table.options.uniqueId); - url = table.options.updateUrl.replace("{id}", row); - } - } - $.modal.openFull("修改" + table.options.modalName, url); + table.set(); + var url = "/404.html"; + if ($.common.isNotEmpty(id)) { + url = table.options.updateUrl.replace("{id}", id); + } else { + if(table.options.type == table_type.bootstrapTreeTable) { + var row = $("#" + table.options.id).bootstrapTreeTable('getSelections')[0]; + if ($.common.isEmpty(row)) { + $.modal.alertWarning("请至少选择一条记录"); + return; + } + url = table.options.updateUrl.replace("{id}", row[table.options.uniqueId]); + } else { + var row = $.common.isEmpty(table.options.uniqueId) ? $.table.selectFirstColumns() : $.table.selectColumns(table.options.uniqueId); + url = table.options.updateUrl.replace("{id}", row); + } + } + $.modal.openFull("修改" + table.options.modalName, url); }, // 修改访问地址 editUrl: function(id) { - var url = "/404.html"; - if ($.common.isNotEmpty(id)) { - url = table.options.updateUrl.replace("{id}", id); - } else { - var id = $.common.isEmpty(table.options.uniqueId) ? $.table.selectFirstColumns() : $.table.selectColumns(table.options.uniqueId); - if (id.length == 0) { - $.modal.alertWarning("请至少选择一条记录"); - return; - } - url = table.options.updateUrl.replace("{id}", id); - } + var url = "/404.html"; + if ($.common.isNotEmpty(id)) { + url = table.options.updateUrl.replace("{id}", id); + } else { + var id = $.common.isEmpty(table.options.uniqueId) ? $.table.selectFirstColumns() : $.table.selectColumns(table.options.uniqueId); + if (id.length == 0) { + $.modal.alertWarning("请至少选择一条记录"); + return; + } + url = table.options.updateUrl.replace("{id}", id); + } return url; }, // 保存信息 刷新表格 save: function(url, data, callback) { - var config = { - url: url, - type: "post", - dataType: "json", - data: data, - beforeSend: function () { - $.modal.loading("正在处理中,请稍后..."); - $.modal.disable(); - }, - success: function(result) { - if (typeof callback == "function") { - callback(result); - } - $.operate.successCallback(result); - } - }; - $.ajax(config) + var config = { + url: url, + type: "post", + dataType: "json", + data: data, + beforeSend: function () { + $.modal.loading("正在处理中,请稍后..."); + $.modal.disable(); + }, + success: function(result) { + if (typeof callback == "function") { + callback(result); + } + $.operate.successCallback(result); + } + }; + $.ajax(config) }, // 保存信息 弹出提示框 saveModal: function(url, data, callback) { - var config = { - url: url, - type: "post", - dataType: "json", - data: data, - beforeSend: function () { - $.modal.loading("正在处理中,请稍后..."); - }, - success: function(result) { - if (typeof callback == "function") { - callback(result); - } - if (result.code == web_status.SUCCESS) { - $.modal.alertSuccess(result.msg) - } else if (result.code == web_status.WARNING) { - $.modal.alertWarning(result.msg) - } else { - $.modal.alertError(result.msg); - } - $.modal.closeLoading(); - } - }; - $.ajax(config) + var config = { + url: url, + type: "post", + dataType: "json", + data: data, + beforeSend: function () { + $.modal.loading("正在处理中,请稍后..."); + }, + success: function(result) { + if (typeof callback == "function") { + callback(result); + } + if (result.code == web_status.SUCCESS) { + $.modal.alertSuccess(result.msg) + } else if (result.code == web_status.WARNING) { + $.modal.alertWarning(result.msg) + } else { + $.modal.alertError(result.msg); + } + $.modal.closeLoading(); + } + }; + $.ajax(config) }, // 保存选项卡信息 saveTab: function(url, data, callback) { - var config = { - url: url, - type: "post", - dataType: "json", - data: data, - beforeSend: function () { - $.modal.loading("正在处理中,请稍后..."); - }, - success: function(result) { - if (typeof callback == "function") { - callback(result); - } - $.operate.successTabCallback(result); - } - }; - $.ajax(config) + var config = { + url: url, + type: "post", + dataType: "json", + data: data, + beforeSend: function () { + $.modal.loading("正在处理中,请稍后..."); + }, + success: function(result) { + if (typeof callback == "function") { + callback(result); + } + $.operate.successTabCallback(result); + } + }; + $.ajax(config) }, // 保存结果弹出msg刷新table表格 ajaxSuccess: function (result) { - if (result.code == web_status.SUCCESS && table.options.type == table_type.bootstrapTable) { - $.modal.msgSuccess(result.msg); - $.table.refresh(); + if (result.code == web_status.SUCCESS && table.options.type == table_type.bootstrapTable) { + $.modal.msgSuccess(result.msg); + $.table.refresh(); } else if (result.code == web_status.SUCCESS && table.options.type == table_type.bootstrapTreeTable) { - $.modal.msgSuccess(result.msg); - $.treeTable.refresh(); + $.modal.msgSuccess(result.msg); + $.treeTable.refresh(); } else if (result.code == web_status.SUCCESS && $.common.isEmpty(table.options.type)) { - $.modal.msgSuccess(result.msg) + $.modal.msgSuccess(result.msg) } else if (result.code == web_status.WARNING) { - $.modal.alertWarning(result.msg) + $.modal.alertWarning(result.msg) } else { - $.modal.alertError(result.msg); + $.modal.alertError(result.msg); } - $.modal.closeLoading(); + $.modal.closeLoading(); }, // 成功结果提示msg(父窗体全局更新) saveSuccess: function (result) { - if (result.code == web_status.SUCCESS) { - $.modal.msgReload("保存成功,正在刷新数据请稍后……", modal_status.SUCCESS); + if (result.code == web_status.SUCCESS) { + $.modal.msgReload("保存成功,正在刷新数据请稍后……", modal_status.SUCCESS); } else if (result.code == web_status.WARNING) { - $.modal.alertWarning(result.msg) + $.modal.alertWarning(result.msg) } else { - $.modal.alertError(result.msg); + $.modal.alertError(result.msg); } - $.modal.closeLoading(); + $.modal.closeLoading(); }, // 成功回调执行事件(父窗体静默更新) successCallback: function(result) { @@ -1260,18 +1263,18 @@ var table = { // 选项卡成功回调执行事件(父窗体静默更新) successTabCallback: function(result) { if (result.code == web_status.SUCCESS) { - var topWindow = $(window.parent.document); - var currentId = $('.page-tabs-content', topWindow).find('.active').attr('data-panel'); - var $contentWindow = $('.RuoYi_iframe[data-id="' + currentId + '"]', topWindow)[0].contentWindow; - $.modal.close(); - $contentWindow.$.modal.msgSuccess(result.msg); - $contentWindow.$(".layui-layer-padding").removeAttr("style"); - if ($contentWindow.table.options.type == table_type.bootstrapTable) { - $contentWindow.$.table.refresh(); - } else if ($contentWindow.table.options.type == table_type.bootstrapTreeTable) { - $contentWindow.$.treeTable.refresh(); - } - $.modal.closeTab(); + var topWindow = $(window.parent.document); + var currentId = $('.page-tabs-content', topWindow).find('.active').attr('data-panel'); + var $contentWindow = $('.RuoYi_iframe[data-id="' + currentId + '"]', topWindow)[0].contentWindow; + $.modal.close(); + $contentWindow.$.modal.msgSuccess(result.msg); + $contentWindow.$(".layui-layer-padding").removeAttr("style"); + if ($contentWindow.table.options.type == table_type.bootstrapTable) { + $contentWindow.$.table.refresh(); + } else if ($contentWindow.table.options.type == table_type.bootstrapTreeTable) { + $contentWindow.$.treeTable.refresh(); + } + $.modal.closeTab(); } else if (result.code == web_status.WARNING) { $.modal.alertWarning(result.msg) } else { @@ -1291,12 +1294,12 @@ var table = { }, // 表单验证 form: function (formId) { - var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId; + var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId; return $("#" + currentId).validate().form(); }, // 重置表单验证(清除提示信息) reset: function (formId) { - var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId; + var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId; return $("#" + currentId).validate().resetForm(); } }, @@ -1360,28 +1363,28 @@ var table = { }, // 搜索节点 searchNode: function() { - // 取得输入的关键字的值 - var value = $.common.trim($("#keyword").val()); - if ($.tree._lastValue == value) { - return; - } - // 保存最后一次搜索名称 - $.tree._lastValue = value; - var nodes = $._tree.getNodes(); - // 如果要查空字串,就退出不查了。 - if (value == "") { - $.tree.showAllNode(nodes); - return; - } - $.tree.hideAllNode(nodes); - // 根据搜索值模糊匹配 - $.tree.updateNodes($._tree.getNodesByParamFuzzy("name", value)); + // 取得输入的关键字的值 + var value = $.common.trim($("#keyword").val()); + if ($.tree._lastValue == value) { + return; + } + // 保存最后一次搜索名称 + $.tree._lastValue = value; + var nodes = $._tree.getNodes(); + // 如果要查空字串,就退出不查了。 + if (value == "") { + $.tree.showAllNode(nodes); + return; + } + $.tree.hideAllNode(nodes); + // 根据搜索值模糊匹配 + $.tree.updateNodes($._tree.getNodesByParamFuzzy("name", value)); }, // 根据Id和Name选中指定节点 selectByIdName: function(treeId, node) { - if ($.common.isNotEmpty(treeId) && node && treeId == node.id) { - $._tree.selectNode(node, true); - } + if ($.common.isNotEmpty(treeId) && node && treeId == node.id) { + $._tree.selectNode(node, true); + } }, // 显示所有节点 showAllNode: function(nodes) { @@ -1395,7 +1398,7 @@ var table = { $._tree.showNode(nodes[i]); $.tree.showAllNode(nodes[i].children); } - }, + }, // 隐藏所有节点 hideAllNode: function(nodes) { var tree = $.fn.zTree.getZTreeObj("tree"); @@ -1439,7 +1442,7 @@ var table = { return $.map(nodes, function (row) { return row[_column]; }).join(); - }, + }, // 不允许根父节点选择 notAllowParents: function(_tree) { var nodes = _tree.getSelectedNodes(); @@ -1487,8 +1490,8 @@ var table = { } }, // 通用方法封装处理 - common: { - // 判断字符串是否为空 + common: { + // 判断字符串是否为空 isEmpty: function (value) { if (value == null || this.trim(value) == "") { return true; @@ -1497,7 +1500,7 @@ var table = { }, // 判断一个字符串是否为非空串 isNotEmpty: function (value) { - return !$.common.isEmpty(value); + return !$.common.isEmpty(value); }, // 空对象转字符串 nullToStr: function(value) { @@ -1522,19 +1525,19 @@ var table = { }, // 比较两个字符串(大小写敏感) equals: function (str, that) { - return str == that; + return str == that; }, // 比较两个字符串(大小写不敏感) equalsIgnoreCase: function (str, that) { - return String(str).toUpperCase() === String(that).toUpperCase(); + return String(str).toUpperCase() === String(that).toUpperCase(); }, // 将字符串按指定字符分割 split: function (str, sep, maxLen) { - if ($.common.isEmpty(str)) { - return null; - } - var value = String(str).split(sep); - return maxLen ? value.slice(0, maxLen - 1) : value; + if ($.common.isEmpty(str)) { + return null; + } + var value = String(str).split(sep); + return maxLen ? value.slice(0, maxLen - 1) : value; }, // 字符串格式化(%s ) sprintf: function (str) { @@ -1622,31 +1625,31 @@ var table = { }, // 数组中的所有元素放入一个字符串 join: function(array, separator) { - if ($.common.isEmpty(array)) { - return null; - } + if ($.common.isEmpty(array)) { + return null; + } return array.join(separator); }, // 获取form下所有的字段并转换为json对象 formToJSON: function(formId) { - var json = {}; - $.each($("#" + formId).serializeArray(), function(i, field) { - if(json[field.name]) { - json[field.name] += ("," + field.value); - } else { - json[field.name] = field.value; - } - }); - return json; + var json = {}; + $.each($("#" + formId).serializeArray(), function(i, field) { + if(json[field.name]) { + json[field.name] += ("," + field.value); + } else { + json[field.name] = field.value; + } + }); + return json; }, // 数据字典转下拉框 dictToSelect: function(datas, value, name) { - var actions = []; - actions.push($.common.sprintf("", name)); $.each(datas, function(index, dict) { actions.push($.common.sprintf("", dict.dictLabel)); }); diff --git a/ruoyi-admin/src/main/resources/templates/login.html b/ruoyi-admin/src/main/resources/templates/login.html index 95188c7f1..807382248 100644 --- a/ruoyi-admin/src/main/resources/templates/login.html +++ b/ruoyi-admin/src/main/resources/templates/login.html @@ -3,7 +3,7 @@ - 登录BPS后台管理系统 + BPS后台管理系统 diff --git a/ruoyi-admin/src/main/resources/templates/loginwechat.html b/ruoyi-admin/src/main/resources/templates/loginwechat.html index ab13f59d5..9edc37af2 100644 --- a/ruoyi-admin/src/main/resources/templates/loginwechat.html +++ b/ruoyi-admin/src/main/resources/templates/loginwechat.html @@ -38,7 +38,6 @@

    登录中...

    -
    @@ -51,7 +50,7 @@ var loginType = [[${loginType}]]; var username = [[${username}]]; var password = [[${password}]]; - var rememberMe = "true"; + var rememberMe = true; $(function () { if (loginType == 'wechat') { diff --git a/ruoyi-admin/src/main/resources/templates/main.html b/ruoyi-admin/src/main/resources/templates/main.html index ef324c721..3b5096ee6 100644 --- a/ruoyi-admin/src/main/resources/templates/main.html +++ b/ruoyi-admin/src/main/resources/templates/main.html @@ -4,15 +4,46 @@ - BPS后台管理系统介绍 + BPS后台管理系统 + -
    +
    +
    +

    [[${wordsContent}]]

    +
    --  《[[${wordsOrigin}]]》 · [[${wordsAuthor}]]
    +

    +

    [[${oneWordContent}]]

    +
    --  《[[${oneWordOrigin}]]》
    +
    +
    + + diff --git a/ruoyi-admin/src/main/resources/templates/system/dept/dept.html b/ruoyi-admin/src/main/resources/templates/system/dept/dept.html index 566ba20a8..4cc4b0948 100644 --- a/ruoyi-admin/src/main/resources/templates/system/dept/dept.html +++ b/ruoyi-admin/src/main/resources/templates/system/dept/dept.html @@ -35,7 +35,7 @@ 新增 - + 修改 @@ -96,6 +96,7 @@ { title: '操作', align: 'left', + visible: showAction(), formatter: function(value, row, index) { if (row.parentId != 0) { var actions = []; @@ -112,30 +113,44 @@ $.treeTable.init(options); }); + function showAction(){ + if(deptSyncType == "1"){ + return false; + } + return true; + } + + function editDept(){ + if(deptSyncType =="0") { + $.operate.edit(); + }else { + alert("已启用同步Ecology部门信息,禁止手动修改部门!") + } + } function addDept(){ if(deptSyncType =="0") { $.operate.add(999999); }else { - alert("系统参数已启用同步Ecology部门信息,禁止手动新增部门!") + alert("已启用同步Ecology部门信息,禁止手动新增部门!") } } function syncDept() { - if(deptSyncType =="1") { + /*if(deptSyncType =="1") {*/ $.ajax({ type: 'POST', url: ctx + "system/dept/syncDept", - data: JSON.stringify(""), //beauty是字符串 + data: JSON.stringify(""), contentType: "application/json", dataType: "json", success: function (message) { alert(JSON.stringify(message)); //将JSON对象转换为字符串 } }); - }else { - alert("系统参数未启用同步Ecology部门!") - } + /*}else { + alert("系统未启用同步Ecology部门!"); + }*/ }; diff --git a/ruoyi-admin/src/main/resources/templates/system/notice/edit.html b/ruoyi-admin/src/main/resources/templates/system/notice/edit.html index 63a3f5e97..311d54bd6 100644 --- a/ruoyi-admin/src/main/resources/templates/system/notice/edit.html +++ b/ruoyi-admin/src/main/resources/templates/system/notice/edit.html @@ -51,6 +51,7 @@ height : 192, lang : 'zh-CN', followingToolbar: false, + dialogsInBody: true, callbacks: { onImageUpload: function (files) { sendFile(files[0], this); diff --git a/ruoyi-admin/src/main/resources/templates/system/user/edit.html b/ruoyi-admin/src/main/resources/templates/system/user/edit.html index 3d598dbd4..2dec17c30 100644 --- a/ruoyi-admin/src/main/resources/templates/system/user/edit.html +++ b/ruoyi-admin/src/main/resources/templates/system/user/edit.html @@ -15,7 +15,7 @@
    - +
    @@ -37,7 +37,7 @@
    - +
    @@ -48,7 +48,7 @@
    - +
    @@ -91,8 +91,8 @@
    - +
    @@ -133,6 +133,7 @@ diff --git a/ruoyi-admin/src/main/resources/templates/system/user/user.html b/ruoyi-admin/src/main/resources/templates/system/user/user.html index f7a58d70d..10ae93007 100644 --- a/ruoyi-admin/src/main/resources/templates/system/user/user.html +++ b/ruoyi-admin/src/main/resources/templates/system/user/user.html @@ -96,6 +96,7 @@ var editFlag = [[${@permission.hasPermi('system:user:edit')}]]; var removeFlag = [[${@permission.hasPermi('system:user:remove')}]]; var resetPwdFlag = [[${@permission.hasPermi('system:user:resetPwd')}]]; + var userSyncType = [[${#strings.defaultString(@config.getKey('sys.user.sync'), 0)}]]; var prefix = ctx + "system/user"; $(function() { @@ -191,7 +192,7 @@ }; $.table.init(options); } - + function queryDeptTree() { var url = ctx + "system/dept/treeData"; @@ -267,6 +268,7 @@ } function syncUser() { + /*if(userSyncType=="1") {*/ $.ajax({ type: 'POST', url: ctx + "system/user/syncUser", @@ -277,6 +279,9 @@ alert(JSON.stringify(message)); //将JSON对象转换为字符串 } }); + /*}else { + alert("系统未启用同步Ecology部门!"); + }*/ }; diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index edd31141d..bf5675cd1 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -101,6 +101,13 @@ javax.servlet-api + + org.json + json + 20160810 + compile + + \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index 869997cda..64664e06e 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -17,6 +17,16 @@ public class Constants */ public static final String GBK = "GBK"; + /** + * http请求 + */ + public static final String HTTP = "http://"; + + /** + * https请求 + */ + public static final String HTTPS = "https://"; + /** * 通用成功标识 */ diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java index a5a190cdd..f09cbadf9 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java @@ -1,13 +1,15 @@ package com.ruoyi.common.utils; -import java.io.IOException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import com.ruoyi.common.core.text.Convert; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; -import com.ruoyi.common.core.text.Convert; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.BufferedReader; +import java.io.IOException; /** * 客户端工具类 @@ -161,4 +163,22 @@ public class ServletUtils } return flag; } + + /** + * 从HttpServletRequest中获取post的json对象数据content-type=“text/plain” + * @param request + * @return content + * @throws IOException + */ + public static String getRequestContent(HttpServletRequest request) throws IOException { + BufferedReader reader = request.getReader(); + char[] buf = new char[request.getContentLength()]; + int len = 0; + StringBuffer contentBuffer = new StringBuffer(); + while ((len = reader.read(buf)) != -1) { + contentBuffer.append(buf, 0, len); + } + String content= contentBuffer.toString(); + return content; + } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java index 882e94a64..73a40cf07 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/StringUtils.java @@ -1,7 +1,13 @@ package com.ruoyi.common.utils; +import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; +import org.springframework.util.AntPathMatcher; +import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.text.StrFormatter; /** @@ -256,6 +262,91 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils return StrFormatter.format(template, params); } + /** + * 是否为http(s)://开头 + * + * @param link 链接 + * @return 结果 + */ + public static boolean ishttp(String link) + { + return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS); + } + + /** + * 字符串转set + * + * @param str 字符串 + * @param sep 分隔符 + * @return set集合 + */ + public static final Set str2Set(String str, String sep) + { + return new HashSet(str2List(str, sep, true, false)); + } + + /** + * 字符串转list + * + * @param str 字符串 + * @param sep 分隔符 + * @param filterBlank 过滤纯空白 + * @param trim 去掉首尾空白 + * @return list集合 + */ + public static final List str2List(String str, String sep, boolean filterBlank, boolean trim) + { + List list = new ArrayList(); + if (StringUtils.isEmpty(str)) + { + return list; + } + + // 过滤空白字符串 + if (filterBlank && StringUtils.isBlank(str)) + { + return list; + } + String[] split = str.split(sep); + for (String string : split) + { + if (filterBlank && StringUtils.isBlank(string)) + { + continue; + } + if (trim) + { + string = string.trim(); + } + list.add(string); + } + + return list; + } + + /** + * 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写 + * + * @param cs 指定字符串 + * @param searchCharSequences 需要检查的字符串数组 + * @return 是否包含任意一个字符串 + */ + public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) + { + if (isEmpty(cs) || isEmpty(searchCharSequences)) + { + return false; + } + for (CharSequence testStr : searchCharSequences) + { + if (containsIgnoreCase(cs, testStr)) + { + return true; + } + } + return false; + } + /** * 驼峰转下划线命名 */ @@ -301,6 +392,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils } sb.append(Character.toLowerCase(c)); } + return sb.toString(); } @@ -400,9 +492,48 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils return sb.toString(); } + /** + * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串 + * + * @param str 指定字符串 + * @param strs 需要检查的字符串数组 + * @return 是否匹配 + */ + public static boolean matches(String str, List strs) + { + if (isEmpty(str) || isEmpty(strs)) + { + return false; + } + for (String pattern : strs) + { + if (isMatch(pattern, str)) + { + return true; + } + } + return false; + } + + /** + * 判断url是否与规则配置: + * ? 表示单个字符; + * * 表示一层路径内的任意字符串,不可跨层级; + * ** 表示任意层路径; + * + * @param pattern 匹配规则 + * @param url 需要匹配的url + * @return + */ + public static boolean isMatch(String pattern, String url) + { + AntPathMatcher matcher = new AntPathMatcher(); + return matcher.match(pattern, url); + } + @SuppressWarnings("unchecked") public static T cast(Object obj) { return (T) obj; } -} +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/TopgpXmlUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/TopgpXmlUtils.java new file mode 100644 index 000000000..d5dc2ae38 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/TopgpXmlUtils.java @@ -0,0 +1,73 @@ +package com.ruoyi.common.utils; + +import com.ruoyi.common.utils.http.HttpUtils; +import org.json.JSONObject; +import org.json.XML; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; + +public class TopgpXmlUtils { + private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); + + /** + * 组合TOPGP所需的XML格式 + * @param tip 调用TOPGP的Webservice的方法名 如:express_testRequest + * @param mapInfo XML中Filed对应的键值对Map + * @return xml字符串 + */ + public static String GetTopgpRequestXml(String tip, Map mapInfo){ + log.info("=======生成xml======"); + StringBuffer stringBuffer = new StringBuffer(); + stringBuffer.append("\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " <Request>\n" + + " <Access>\n" + + " <Authentication user='topgui' password='' />\n" + + " <Connection application='bps' source='www.bpsemi.com' />\n" + + " <Organization name='SYSTEM' />\n" + + " <Locale language='zh_cn' />\n" + + " </Access>\n" + + " <RequestContent>\n" + + " <Parameter>\n" + + " <Record>\n" + + " <Field name="); + for(String key:mapInfo.keySet()){ + stringBuffer.append("'"+key+"' value='" +mapInfo.get(key).toString().replaceAll("&","&")+"' />\n"); + } + stringBuffer.append(" </Record>\n" + + " </Parameter>\n" + + " <Document/>\n" + + " </RequestContent>\n" + + " </Request>\n" + + " \n" + + " \n" + + " \n" + + ""); + log.info("=======生成xml结束======"); + return stringBuffer.toString(); + } + + /** + * 将TOPGP返回的XML转化为Json,并提出返回Status + * @param TopgpResonseXml 调用TOPGP的Webservice的方法名 如:express_testRequest + * @return Status JsonObject + */ + public static JSONObject GetStatusFromTopgpResponse(String TopgpResonseXml) { + JSONObject jsonObject = XML.toJSONObject(TopgpResonseXml); + + JSONObject envelope = jsonObject.getJSONObject("SOAP-ENV:Envelope"); + JSONObject body = envelope.getJSONObject("SOAP-ENV:Body"); + JSONObject express_testResponse = body.getJSONObject("fjs1:express_testResponse"); + JSONObject fjs1Response = express_testResponse.getJSONObject("fjs1:response"); + JSONObject response = fjs1Response.getJSONObject("Response"); + JSONObject execution = response.getJSONObject("Execution"); + return execution.getJSONObject("Status"); + } + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java index 8093b0a7f..dcaa8c5a2 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java @@ -1,10 +1,14 @@ package com.ruoyi.common.utils.http; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; +import com.ruoyi.common.constant.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import javax.net.ssl.*; +import java.io.*; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.URL; @@ -12,18 +16,6 @@ import java.net.URLConnection; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.Map; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import com.ruoyi.common.constant.Constants; -import org.springframework.http.ResponseEntity; -import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestTemplate; /** * 通用http发送方法 @@ -265,14 +257,76 @@ public class HttpUtils } } + /** + * 向指定 URL 发送xml POST方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + *Author yangbo + */ + public static String sendXmlPost(String url, String param) { + PrintWriter out = null; + BufferedReader in = null; + StringBuilder result = new StringBuilder(); + try { + String urlNameString = url; + log.info("sendPost - {}", urlNameString); + URL realUrl = new URL(urlNameString); + URLConnection conn = realUrl.openConnection(); + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + conn.setRequestProperty("Accept-Charset", "utf-8"); + conn.setRequestProperty("Content-Type", "text/xml; charset=UTF-8"); //发送xml需加上此请求头 + conn.addRequestProperty("SOAPAction", "\"\""); //向topgp发送xml必须加上该Name=“SOAPAction", Value="\"\"" ,否则会报415错误,不能识别XML. + conn.setDoOutput(true); + conn.setDoInput(true); + out = new PrintWriter(conn.getOutputStream()); + out.print(param); + out.flush(); + in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); + String line; + while ((line = in.readLine()) != null) { + result.append(line); + } + log.info("recv - {}", result); + } catch (ConnectException e) { + log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e); + } catch (SocketTimeoutException e) { + log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e); + } catch (IOException e) { + log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e); + } catch (Exception e) { + log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e); + } finally { + try { + if (out != null) { + out.close(); + } + if (in != null) { + in.close(); + } + } catch (IOException ex) { + log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); + } + } + return result.toString().replace("<","<").replace(">",">"); + } + + /** * 向指定 Restful接口 发送POST方法的请求 * * @param url 发送请求的 URL * @param params 请求参数,请求参数为json的形式。例:params="{\"params\":{\"pagesize\":1000}}" * @return 返回Map, Key="statusCode",接口访问返回状态, key="result":接口返回接果 + * + * author yangbo */ - public static Map sendPostWithRest(String url, String params){ + //public static Map sendPostWithRest(String url, String params){ + //如果参数为String类型,推送企业微信消息会乱码,因此改为Object类型,直接推送Map --yangbo 20210729 + public static Map sendPostWithRest(String url, Object params){ RestTemplate restTemplate=new RestTemplate(); ResponseEntity result=null; int statusCode=0; diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssFilter.java b/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssFilter.java index d307fbc9f..30fd69ce8 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssFilter.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/xss/XssFilter.java @@ -3,8 +3,6 @@ package com.ruoyi.common.xss; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -27,16 +25,10 @@ public class XssFilter implements Filter */ public List excludes = new ArrayList<>(); - /** - * xss过滤开关 - */ - public boolean enabled = false; - @Override public void init(FilterConfig filterConfig) throws ServletException { String tempExcludes = filterConfig.getInitParameter("excludes"); - String tempEnabled = filterConfig.getInitParameter("enabled"); if (StringUtils.isNotEmpty(tempExcludes)) { String[] url = tempExcludes.split(","); @@ -45,10 +37,6 @@ public class XssFilter implements Filter excludes.add(url[i]); } } - if (StringUtils.isNotEmpty(tempEnabled)) - { - enabled = Boolean.valueOf(tempEnabled); - } } @Override @@ -68,25 +56,14 @@ public class XssFilter implements Filter private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) { - if (!enabled) + String url = request.getServletPath(); + String method = request.getMethod(); + // GET DELETE 不过滤 + if (method == null || method.matches("GET") || method.matches("DELETE")) { return true; } - if (excludes == null || excludes.isEmpty()) - { - return false; - } - String url = request.getServletPath(); - for (String pattern : excludes) - { - Pattern p = Pattern.compile("^" + pattern); - Matcher m = p.matcher(url); - if (m.find()) - { - return true; - } - } - return false; + return StringUtils.matches(url, excludes); } @Override diff --git a/ruoyi-framework/pom.xml b/ruoyi-framework/pom.xml index 4541aa3b1..0a05c2a56 100644 --- a/ruoyi-framework/pom.xml +++ b/ruoyi-framework/pom.xml @@ -77,12 +77,19 @@ ruoyi-system - + org.springframework.boot spring-boot-starter-data-ldap + + + com.auth0 + java-jwt + 3.4.0 + + \ No newline at end of file diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java index 92d010e80..b7d10b8f9 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FilterConfig.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.Map; import javax.servlet.DispatcherType; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -16,11 +17,9 @@ import com.ruoyi.common.xss.XssFilter; * @author ruoyi */ @Configuration +@ConditionalOnProperty(value = "xss.enabled", havingValue = "true") public class FilterConfig { - @Value("${xss.enabled}") - private String enabled; - @Value("${xss.excludes}") private String excludes; @@ -36,10 +35,9 @@ public class FilterConfig registration.setFilter(new XssFilter()); registration.addUrlPatterns(StringUtils.split(urlPatterns, ",")); registration.setName("xssFilter"); - registration.setOrder(Integer.MAX_VALUE); + registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); Map initParameters = new HashMap(); initParameters.put("excludes", excludes); - initParameters.put("enabled", enabled); registration.setInitParameters(initParameters); return registration; } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java index 422654aa2..b2c10506f 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java @@ -25,6 +25,8 @@ import com.ruoyi.common.constant.Constants; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.security.CipherUtils; import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.framework.jwt.auth.AllowAllCredentialsMatcher; +import com.ruoyi.framework.jwt.filter.JwtFilter; import com.ruoyi.framework.shiro.realm.UserRealm; import com.ruoyi.framework.shiro.session.OnlineSessionDAO; import com.ruoyi.framework.shiro.session.OnlineSessionFactory; @@ -177,6 +179,7 @@ public class ShiroConfig UserRealm userRealm = new UserRealm(); userRealm.setAuthorizationCacheName(Constants.SYS_AUTH_CACHE); userRealm.setCacheManager(cacheManager); + userRealm.setCredentialsMatcher(new AllowAllCredentialsMatcher()); return userRealm; } @@ -287,6 +290,8 @@ public class ShiroConfig filterChainDefinitionMap.put("/logout", "logout"); // 不需要拦截的访问 filterChainDefinitionMap.put("/login", "anon,captchaValidate"); + filterChainDefinitionMap.put("/jwt/login", "anon"); + filterChainDefinitionMap.put("/jwt/topgplogin", "anon"); // 注册相关 filterChainDefinitionMap.put("/register", "anon,captchaValidate"); // 系统权限列表 @@ -297,10 +302,14 @@ public class ShiroConfig filters.put("syncOnlineSession", syncOnlineSessionFilter()); filters.put("captchaValidate", captchaValidateFilter()); filters.put("kickout", kickoutSessionFilter()); + filters.put("jwt", new JwtFilter()); // 注销成功,则跳转到指定页面 filters.put("logout", logoutFilter()); shiroFilterFactoryBean.setFilters(filters); + // jwt 请求单独验证 + filterChainDefinitionMap.put("/api/**", "jwt"); + // 所有请求需要认证 filterChainDefinitionMap.put("/**", "user,kickout,onlineSession,syncOnlineSession"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/auth/AllowAllCredentialsMatcher.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/auth/AllowAllCredentialsMatcher.java new file mode 100644 index 000000000..9131fdcfe --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/auth/AllowAllCredentialsMatcher.java @@ -0,0 +1,19 @@ +package com.ruoyi.framework.jwt.auth; + +import org.apache.shiro.authc.AuthenticationInfo; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.authc.credential.SimpleCredentialsMatcher; + +/** + * 无需验证密码 + * + * @author ruoyi + */ +public class AllowAllCredentialsMatcher extends SimpleCredentialsMatcher +{ + @Override + public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) + { + return true; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/auth/JwtToken.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/auth/JwtToken.java new file mode 100644 index 000000000..3dfc19eac --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/auth/JwtToken.java @@ -0,0 +1,45 @@ +package com.ruoyi.framework.jwt.auth; + +import org.apache.shiro.authc.UsernamePasswordToken; + +/** + * 自定义登录Token + * + * @author ruoyi + */ +public class JwtToken extends UsernamePasswordToken +{ + private static final long serialVersionUID = 1L; + + private String token; + + public JwtToken() + { + } + + public JwtToken(String username, String password, boolean rememberMe) + { + super(username, password, rememberMe); + } + + public JwtToken(String username, String password) + { + super(username, password, false); + } + + public JwtToken(String token) + { + super("", "", false); + this.token = token; + } + + public String getToken() + { + return token; + } + + public void setToken(String token) + { + this.token = token; + } +} \ No newline at end of file diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/filter/JwtFilter.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/filter/JwtFilter.java new file mode 100644 index 000000000..980a8ae4f --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/filter/JwtFilter.java @@ -0,0 +1,135 @@ +package com.ruoyi.framework.jwt.filter; + +import java.io.IOException; +import java.io.PrintWriter; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.web.filter.AccessControlFilter; +import org.apache.shiro.web.util.WebUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.RequestMethod; +import com.alibaba.fastjson.JSON; +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.exceptions.TokenExpiredException; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.jwt.auth.JwtToken; + +/** + * jwt 自定义拦截器 + * + * @author ruoyi + */ +public class JwtFilter extends AccessControlFilter +{ + private static final Logger LOGGER = LoggerFactory.getLogger(JwtFilter.class); + + private static final String AUTHZ_HEADER = "token"; + + private final ThreadLocal MSG_HOLDER = new ThreadLocal<>(); + + @Override + public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception + { + return super.onPreHandle(request, response, mappedValue); + } + + @Override + protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception + { + return this.executeLogin(request, response); + } + + /** + * 执行登录方法(UserRealm判断,异常返回false) + */ + protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception + { + String token = WebUtils.toHttp(request).getHeader(AUTHZ_HEADER); + if (StringUtils.isEmpty(token)) + { + MSG_HOLDER.set("消息头不正确,header需要携带token参数"); + return false; + } + try + { + // 断是否有权限 + JwtToken jwtToken = new JwtToken(token); + this.getSubject(request, response).login(jwtToken); + return true; + } + catch (AuthenticationException e) + { + if (e.getCause() instanceof TokenExpiredException) + { + MSG_HOLDER.set("token已过期"); + } + else if (e.getCause() instanceof JWTVerificationException) + { + MSG_HOLDER.set("用户密码错误"); + } + else + { + MSG_HOLDER.set("用户信息验证失败:" + e.getMessage()); + } + return false; + } + } + + /** + * 请求前处理,处理跨域 + */ + @Override + protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception + { + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin")); + httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE"); + httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers")); + // 跨域时,option请求直接返回正常状态 + if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) + { + httpServletResponse.setStatus(HttpStatus.OK.value()); + return false; + } + return super.preHandle(request, response); + } + + /** + * 异常处理 + */ + @Override + protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception + { + this.jwtFail(request, response, 401, "对不起,您无权限进行操作!"); + return false; + } + + /** + * 认证失败,异常返回 + */ + protected void jwtFail(ServletRequest request, ServletResponse response, int code, String message) + { + HttpServletResponse httpResponse = WebUtils.toHttp(response); + String contentType = "application/json;charset=UTF-8"; + httpResponse.setStatus(401); + httpResponse.setContentType(contentType); + try + { + String msg = StringUtils.isNotEmpty(MSG_HOLDER.get()) ? MSG_HOLDER.get() : message; + AjaxResult ajaxResult = new AjaxResult().put(AjaxResult.CODE_TAG, code).put(AjaxResult.MSG_TAG, msg); + PrintWriter printWriter = httpResponse.getWriter(); + printWriter.append(JSON.toJSONString(ajaxResult)); + } + catch (IOException e) + { + LOGGER.error("sendChallenge error,can not resolve httpServletResponse"); + } + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/service/IJwtTokenService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/service/IJwtTokenService.java new file mode 100644 index 000000000..79c383efa --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/service/IJwtTokenService.java @@ -0,0 +1,13 @@ +package com.ruoyi.framework.jwt.service; + +import com.ruoyi.common.core.domain.AjaxResult; + +public interface IJwtTokenService { + /** + * 获取AjaxResult格式的jwt token + * @param username 用户名 + * @param password 密码 + * @return jwtToken + */ + public AjaxResult AjaxResultJwtToken(String username, String password); +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/service/impl/JwtTokenServiceImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/service/impl/JwtTokenServiceImpl.java new file mode 100644 index 000000000..65e6649b6 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/service/impl/JwtTokenServiceImpl.java @@ -0,0 +1,59 @@ +package com.ruoyi.framework.jwt.service.impl; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.jwt.service.IJwtTokenService; +import com.ruoyi.framework.jwt.utils.JwtUtils; +import com.ruoyi.framework.shiro.service.SysPasswordService; +import com.ruoyi.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class JwtTokenServiceImpl implements IJwtTokenService { + @Autowired + private ISysUserService userService; + + @Autowired + private SysPasswordService passwordService; + /** + * 获取AjaxResult格式的jwt token + * + * @param username 用户名 + * @param password 密码 + * @return jwtToken + */ + @Override + public AjaxResult AjaxResultJwtToken(String username, String password) { + if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) + { + return AjaxResult.error("账号和密码不能为空!"); + } + + SysUser user = userService.selectUserByLoginName(username); + if (user == null) + { + return AjaxResult.error("用户不存在/密码错误!"); + } + + if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + return AjaxResult.error("对不起,您的账号已被删除!"); + } + + if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + return AjaxResult.error("用户已封禁,请联系管理员!"); + } + + if (!passwordService.matches(user, password)) + { + return AjaxResult.error("用户不存在/密码错误!"); + } + + String token = JwtUtils.createToken(username, user.getPassword()); + return AjaxResult.success("登录成功,请妥善保管您的token信息").put("token", token); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/utils/JwtUtils.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/utils/JwtUtils.java new file mode 100644 index 000000000..c0ce30121 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/jwt/utils/JwtUtils.java @@ -0,0 +1,66 @@ +package com.ruoyi.framework.jwt.utils; + +import java.util.Date; +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTDecodeException; +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.exceptions.TokenExpiredException; +import com.auth0.jwt.interfaces.DecodedJWT; + +/** + * jwt 工具类 + * + * @author ruoyi + */ +public class JwtUtils +{ + private static final long EXPIRE_TIME = 30 * 60 * 1000; + + private static final String CLAIM_NAME = "username"; + + public static String createToken(String username, String password) + { + return createToken(username, password, EXPIRE_TIME); + } + + public static String createToken(String username, String password, long expireTime) + { + Date date = new Date(System.currentTimeMillis() + expireTime); + // 加密处理密码 + Algorithm algorithm = Algorithm.HMAC256(password); + return JWT.create().withClaim(CLAIM_NAME, username).withExpiresAt(date).sign(algorithm); + } + + public static void verify(String username, String dbPwd, String token) + { + Algorithm algorithm = Algorithm.HMAC256(dbPwd); + JWTVerifier jwtVerifier = JWT.require(algorithm).withClaim(CLAIM_NAME, username).build(); + try + { + jwtVerifier.verify(token); + } + catch (TokenExpiredException e) + { + throw new TokenExpiredException("token已过期"); + } + catch (JWTVerificationException e) + { + throw new JWTVerificationException("token验证失败"); + } + } + + public static String getUserName(String token) + { + try + { + DecodedJWT jwt = JWT.decode(token); + return jwt.getClaim(CLAIM_NAME).asString(); + } + catch (JWTDecodeException e) + { + return null; + } + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/realm/UserRealm.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/realm/UserRealm.java index 88ad4d249..5723523a0 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/realm/UserRealm.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/realm/UserRealm.java @@ -4,6 +4,7 @@ import java.util.HashSet; import java.util.Set; import com.ruoyi.framework.shiro.util.CustToken; +import org.apache.shiro.authc.AccountException; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; @@ -23,16 +24,21 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.enums.UserStatus; import com.ruoyi.common.exception.user.CaptchaException; import com.ruoyi.common.exception.user.RoleBlockedException; import com.ruoyi.common.exception.user.UserBlockedException; +import com.ruoyi.common.exception.user.UserDeleteException; import com.ruoyi.common.exception.user.UserNotExistsException; import com.ruoyi.common.exception.user.UserPasswordNotMatchException; import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException; import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.framework.jwt.auth.JwtToken; +import com.ruoyi.framework.jwt.utils.JwtUtils; import com.ruoyi.framework.shiro.service.SysLoginService; import com.ruoyi.system.service.ISysMenuService; import com.ruoyi.system.service.ISysRoleService; +import com.ruoyi.system.service.ISysUserService; /** * 自定义Realm 处理登录 权限 @@ -52,6 +58,9 @@ public class UserRealm extends AuthorizingRealm @Autowired private SysLoginService loginService; + @Autowired + private ISysUserService userService; + /** * 授权 */ @@ -86,55 +95,96 @@ public class UserRealm extends AuthorizingRealm * 登录认证 */ @Override - protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) + throws AuthenticationException { - //UsernamePasswordToken upToken = (UsernamePasswordToken) token; - CustToken upToken= (CustToken) token; - String loginType = upToken.getLoginType(); - String username = upToken.getUsername(); - String password = ""; + if (authenticationToken instanceof JwtToken) + { + JwtToken jwtToken = (JwtToken) authenticationToken; + String token = jwtToken.getToken(); + String username = JwtUtils.getUserName(token); + if (username == null) + { + throw new AccountException("token 验证失败"); + } + SysUser user = userService.selectUserByLoginName(username); + if (user == null) + { + throw new AuthenticationException("用户数据不存在"); + } - if (upToken.getPassword() != null) - { - password = new String(upToken.getPassword()); - } + try + { + JwtUtils.verify(username, user.getPassword(), jwtToken.getToken()); - SysUser user = null; - try - { - user = loginService.login(username, password,loginType); + if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + throw new UserDeleteException(); + } + + if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + throw new UserBlockedException(); + } + } + catch (Exception e) + { + log.info("对用户[" + username + "]进行jwt登录验证..验证未通过{}", e.getMessage()); + throw new AuthenticationException(e.getMessage(), e); + } + + return new SimpleAuthenticationInfo(user, null, getName()); } - catch (CaptchaException e) + else { - throw new AuthenticationException(e.getMessage(), e); + //UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken; + CustToken upToken= (CustToken) authenticationToken; + String loginType = upToken.getLoginType(); + String username = upToken.getUsername(); + String password = ""; + + if (upToken.getPassword() != null) + { + password = new String(upToken.getPassword()); + } + + SysUser user = null; + try + { + user = loginService.login(username, password,loginType); + } + catch (CaptchaException e) + { + throw new AuthenticationException(e.getMessage(), e); + } + catch (UserNotExistsException e) + { + throw new UnknownAccountException(e.getMessage(), e); + } + catch (UserPasswordNotMatchException e) + { + throw new IncorrectCredentialsException(e.getMessage(), e); + } + catch (UserPasswordRetryLimitExceedException e) + { + throw new ExcessiveAttemptsException(e.getMessage(), e); + } + catch (UserBlockedException e) + { + throw new LockedAccountException(e.getMessage(), e); + } + catch (RoleBlockedException e) + { + throw new LockedAccountException(e.getMessage(), e); + } + catch (Exception e) + { + log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage()); + throw new AuthenticationException(e.getMessage(), e); + } + SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName()); + return info; } - catch (UserNotExistsException e) - { - throw new UnknownAccountException(e.getMessage(), e); - } - catch (UserPasswordNotMatchException e) - { - throw new IncorrectCredentialsException(e.getMessage(), e); - } - catch (UserPasswordRetryLimitExceedException e) - { - throw new ExcessiveAttemptsException(e.getMessage(), e); - } - catch (UserBlockedException e) - { - throw new LockedAccountException(e.getMessage(), e); - } - catch (RoleBlockedException e) - { - throw new LockedAccountException(e.getMessage(), e); - } - catch (Exception e) - { - log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage()); - throw new AuthenticationException(e.getMessage(), e); - } - SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName()); - return info; } /** diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java index d9812d8a4..21a9c876d 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java @@ -13,6 +13,7 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.exception.BusinessException; import com.ruoyi.common.exception.DemoModeException; import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.security.PermissionUtils; /** @@ -32,7 +33,7 @@ public class GlobalExceptionHandler public Object handleAuthorizationException(HttpServletRequest request, AuthorizationException e) { log.error(e.getMessage(), e); - if (ServletUtils.isAjaxRequest(request)) + if (ServletUtils.isAjaxRequest(request) || StringUtils.isNotEmpty(request.getHeader("token"))) { return AjaxResult.error(PermissionUtils.getMsg(e.getMessage())); } diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java index 78297d2be..55a31f275 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java @@ -303,7 +303,8 @@ public class VelocityUtils */ public static String getParentMenuId(JSONObject paramsObj) { - if (StringUtils.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID)) + if (StringUtils.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID) + && StringUtils.isNotEmpty(paramsObj.getString(GenConstants.PARENT_MENU_ID))) { return paramsObj.getString(GenConstants.PARENT_MENU_ID); } diff --git a/ruoyi-generator/src/main/resources/vm/html/add.html.vm b/ruoyi-generator/src/main/resources/vm/html/add.html.vm index 85fd47c48..b228b34ee 100644 --- a/ruoyi-generator/src/main/resources/vm/html/add.html.vm +++ b/ruoyi-generator/src/main/resources/vm/html/add.html.vm @@ -238,6 +238,7 @@ $(function() { $('.summernote').summernote({ lang: 'zh-CN', + dialogsInBody: true, callbacks: { onChange: function(contents, $edittable) { $("input[name='" + this.id + "']").val(contents); diff --git a/ruoyi-generator/src/main/resources/vm/html/edit.html.vm b/ruoyi-generator/src/main/resources/vm/html/edit.html.vm index 0d1f8b7cb..174cc0823 100644 --- a/ruoyi-generator/src/main/resources/vm/html/edit.html.vm +++ b/ruoyi-generator/src/main/resources/vm/html/edit.html.vm @@ -245,6 +245,7 @@ $('.summernote').each(function(i) { $('#' + this.id).summernote({ lang: 'zh-CN', + dialogsInBody: true, callbacks: { onChange: function(contents, $edittable) { $("input[name='" + this.id + "']").val(contents); diff --git a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm index aeb20b48e..c837ff8e5 100644 --- a/ruoyi-generator/src/main/resources/vm/java/controller.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/controller.java.vm @@ -105,7 +105,7 @@ public class ${ClassName}Controller extends BaseController { if (StringUtils.isNotNull(${pkColumn.javaField})) { - mmap.put("${className}", ${className}Service.select${ClassName}ById(${pkColumn.javaField})); + mmap.put("${className}", ${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField})); } return prefix + "/add"; } @@ -129,7 +129,7 @@ public class ${ClassName}Controller extends BaseController @GetMapping("/edit/{${pkColumn.javaField}}") public String edit(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}, ModelMap mmap) { - ${ClassName} ${className} = ${className}Service.select${ClassName}ById(${pkColumn.javaField}); + ${ClassName} ${className} = ${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); mmap.put("${className}", ${className}); return prefix + "/edit"; } @@ -156,7 +156,7 @@ public class ${ClassName}Controller extends BaseController @ResponseBody public AjaxResult remove(String ids) { - return toAjax(${className}Service.delete${ClassName}ByIds(ids)); + return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(ids)); } #elseif($table.tree) /** @@ -168,7 +168,7 @@ public class ${ClassName}Controller extends BaseController @ResponseBody public AjaxResult remove(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) { - return toAjax(${className}Service.delete${ClassName}ById(${pkColumn.javaField})); + return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField})); } #end #if($table.tree) @@ -182,7 +182,7 @@ public class ${ClassName}Controller extends BaseController { if (StringUtils.isNotNull(${pkColumn.javaField})) { - mmap.put("${className}", ${className}Service.select${ClassName}ById(${pkColumn.javaField})); + mmap.put("${className}", ${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField})); } return prefix + "/tree"; } diff --git a/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm b/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm index 0c903051b..05df192e5 100644 --- a/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm @@ -17,10 +17,10 @@ public interface ${ClassName}Mapper /** * 查询${functionName} * - * @param ${pkColumn.javaField} ${functionName}ID + * @param ${pkColumn.javaField} ${functionName}主键 * @return ${functionName} */ - public ${ClassName} select${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}); + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); /** * 查询${functionName}列表 @@ -49,27 +49,27 @@ public interface ${ClassName}Mapper /** * 删除${functionName} * - * @param ${pkColumn.javaField} ${functionName}ID + * @param ${pkColumn.javaField} ${functionName}主键 * @return 结果 */ - public int delete${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}); + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); /** * 批量删除${functionName} * - * @param ${pkColumn.javaField}s 需要删除的数据ID + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 * @return 结果 */ - public int delete${ClassName}ByIds(String[] ${pkColumn.javaField}s); + public int delete${ClassName}By${pkColumn.capJavaField}s(String[] ${pkColumn.javaField}s); #if($table.sub) /** * 批量删除${subTable.functionName} * - * @param customerIds 需要删除的数据ID + * @param ${pkColumn.javaField}s 需要删除的数据主键集合 * @return 结果 */ - public int delete${subClassName}By${subTableFkClassName}s(String[] ${pkColumn.javaField}s); + public int delete${subClassName}By${pkColumn.capJavaField}s(String[] ${pkColumn.javaField}s); /** * 批量新增${subTable.functionName} @@ -81,11 +81,11 @@ public interface ${ClassName}Mapper /** - * 通过${functionName}ID删除${subTable.functionName}信息 + * 通过${functionName}主键删除${subTable.functionName}信息 * * @param ${pkColumn.javaField} ${functionName}ID * @return 结果 */ - public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField}); + public int delete${subClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); #end } diff --git a/ruoyi-generator/src/main/resources/vm/java/service.java.vm b/ruoyi-generator/src/main/resources/vm/java/service.java.vm index e073cc82b..c30ec41ca 100644 --- a/ruoyi-generator/src/main/resources/vm/java/service.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/service.java.vm @@ -17,10 +17,10 @@ public interface I${ClassName}Service /** * 查询${functionName} * - * @param ${pkColumn.javaField} ${functionName}ID + * @param ${pkColumn.javaField} ${functionName}主键 * @return ${functionName} */ - public ${ClassName} select${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}); + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); /** * 查询${functionName}列表 @@ -49,18 +49,18 @@ public interface I${ClassName}Service /** * 批量删除${functionName} * - * @param ids 需要删除的数据ID + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合 * @return 结果 */ - public int delete${ClassName}ByIds(String ids); + public int delete${ClassName}By${pkColumn.capJavaField}s(String ${pkColumn.javaField}s); /** * 删除${functionName}信息 * - * @param ${pkColumn.javaField} ${functionName}ID + * @param ${pkColumn.javaField} ${functionName}主键 * @return 结果 */ - public int delete${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}); + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}); #if($table.tree) /** diff --git a/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm b/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm index bb3553319..c23c523a8 100644 --- a/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm @@ -39,13 +39,13 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service /** * 查询${functionName} * - * @param ${pkColumn.javaField} ${functionName}ID + * @param ${pkColumn.javaField} ${functionName}主键 * @return ${functionName} */ @Override - public ${ClassName} select${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}) + public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) { - return ${className}Mapper.select${ClassName}ById(${pkColumn.javaField}); + return ${className}Mapper.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); } /** @@ -111,36 +111,36 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service } /** - * 删除${functionName}对象 + * 批量删除${functionName} * - * @param ids 需要删除的数据ID + * @param ${pkColumn.javaField}s 需要删除的${functionName}主键 * @return 结果 */ #if($table.sub) @Transactional #end @Override - public int delete${ClassName}ByIds(String ids) + public int delete${ClassName}By${pkColumn.capJavaField}s(String ${pkColumn.javaField}s) { #if($table.sub) - ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(Convert.toStrArray(ids)); + ${className}Mapper.delete${subClassName}By${subTableFkClassName}s(Convert.toStrArray(${pkColumn.javaField}s)); #end - return ${className}Mapper.delete${ClassName}ByIds(Convert.toStrArray(ids)); + return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}s(Convert.toStrArray(${pkColumn.javaField}s)); } /** * 删除${functionName}信息 * - * @param ${pkColumn.javaField} ${functionName}ID + * @param ${pkColumn.javaField} ${functionName}主键 * @return 结果 */ @Override - public int delete${ClassName}ById(${pkColumn.javaType} ${pkColumn.javaField}) + public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField}) { #if($table.sub) ${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField}); #end - return ${className}Mapper.delete${ClassName}ById(${pkColumn.javaField}); + return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}); } #if($table.tree) @@ -179,7 +179,7 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service public void insert${subClassName}(${ClassName} ${className}) { List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List(); - Long ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}(); + ${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}(); if (StringUtils.isNotNull(${subclassName}List)) { List<${subClassName}> list = new ArrayList<${subClassName}>(); diff --git a/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm b/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm index c93aa0b0d..e1f086cff 100644 --- a/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm +++ b/ruoyi-generator/src/main/resources/vm/xml/mapper.xml.vm @@ -64,7 +64,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #end - #if($table.crud) where ${pkColumn.columnName} = #{${pkColumn.javaField}} @@ -113,11 +113,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where ${pkColumn.columnName} = #{${pkColumn.javaField}} - + delete from ${tableName} where ${pkColumn.columnName} = #{${pkColumn.javaField}} - + delete from ${tableName} where ${pkColumn.columnName} in #{${pkColumn.javaField}} @@ -132,7 +132,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + delete from ${subTableName} where ${subTableFkName} = #{${subTableFkclassName}} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java index 6803c96fa..84354e3f7 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/SysJobController.java @@ -133,11 +133,15 @@ public class SysJobController extends BaseController { if (!CronUtils.isValid(job.getCronExpression())) { - return AjaxResult.error("新增任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + return error("新增任务'" + job.getJobName() + "'失败,Cron表达式不正确"); } else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) { - return AjaxResult.error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi://'调用"); + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi://'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)//'调用"); } return toAjax(jobService.insertJob(job)); } @@ -163,11 +167,15 @@ public class SysJobController extends BaseController { if (!CronUtils.isValid(job.getCronExpression())) { - return AjaxResult.error("修改任务'" + job.getJobName() + "'失败,Cron表达式不正确"); + return error("修改任务'" + job.getJobName() + "'失败,Cron表达式不正确"); } else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) { - return AjaxResult.error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi://'调用"); + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi://'调用"); + } + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) + { + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)//'调用"); } return toAjax(jobService.updateJob(job)); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/WechatSendMessage.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/WechatSendMessage.java new file mode 100644 index 000000000..23d504c9c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/WechatSendMessage.java @@ -0,0 +1,111 @@ +package com.ruoyi.system.domain; + +public class WechatSendMessage { + public String touser; + public String toparty; + public String totag; + public String msgtype; + public Integer agentid; + public String text; + public Integer safe; + public Integer enable_id_trans; + public Integer enable_duplicate_check; + public Integer duplicate_check_interval; + + public String getTouser() { + return touser; + } + + public void setTouser(String touser) { + this.touser = touser; + } + + public String getToparty() { + return toparty; + } + + public void setToparty(String toparty) { + this.toparty = toparty; + } + + public String getTotag() { + return totag; + } + + public void setTotag(String totag) { + this.totag = totag; + } + + public Integer getAgentid() { + return agentid; + } + + public void setAgentid(Integer agentid) { + this.agentid = agentid; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public Integer getSafe() { + return safe; + } + + public void setSafe(Integer safe) { + this.safe = safe; + } + + public Integer getEnable_id_trans() { + return enable_id_trans; + } + + public void setEnable_id_trans(Integer enable_id_trans) { + this.enable_id_trans = enable_id_trans; + } + + public Integer getEnable_duplicate_check() { + return enable_duplicate_check; + } + + public void setEnable_duplicate_check(Integer enable_duplicate_check) { + this.enable_duplicate_check = enable_duplicate_check; + } + + public Integer getDuplicate_check_interval() { + return duplicate_check_interval; + } + + public void setDuplicate_check_interval(Integer duplicate_check_interval) { + this.duplicate_check_interval = duplicate_check_interval; + } + + public String getMsgtype() { + return msgtype; + } + + @Override + public String toString() { + return "WechatSendMessage{" + + "touser='" + touser + '\'' + + ", toparty='" + toparty + '\'' + + ", totag='" + totag + '\'' + + ", msgtype='" + msgtype + '\'' + + ", agentid=" + agentid + + ", text='" + text + '\'' + + ", safe=" + safe + + ", enable_id_trans=" + enable_id_trans + + ", enable_duplicate_check=" + enable_duplicate_check + + ", duplicate_check_interval=" + duplicate_check_interval + + '}'; + } + + public void setMsgtype(String msgtype) { + this.msgtype = msgtype; + } + +} \ No newline at end of file diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/WechatUserInfo.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/WechatUserInfo.java index b66f361d3..b29cdfdc5 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/WechatUserInfo.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/WechatUserInfo.java @@ -3,36 +3,36 @@ package com.ruoyi.system.domain; import java.util.List; public class WechatUserInfo { - String errocode; //返回码 + Integer errcode; //返回码 String errmsg; //返回码描述 String Userid; //成员UserID String name; //成员名称 - String depatrment; //成员所属部门id列表 - String order; //部门内的排序值 + Object department; //成员所属部门id列表 + Object order; //部门内的排序值 String position; //职务信息 String mobile; //手机号码 String gender; //性别,0:未定义,1:男,2:女 String email; //邮箱 - String is_leader_in_dept; //在所在的部门内是否为上级 + Object is_leader_in_dept; //在所在的部门内是否为上级 String avatar; //头像Url String thumb_avatar; //头像缩略图Url String telephone; //座机 String alias; //别名 String address; //地址 String open_userid; //全局唯一id - String main_department; //主部门 - String extattr; //扩展属性 - String Status; //激活状态: 1=已激活,2=已禁用,4=未激活,5=退出企业。 + Integer main_department; //主部门 + Object extattr; //扩展属性 + Integer Status; //激活状态: 1=已激活,2=已禁用,4=未激活,5=退出企业。 String qr_code; //员工个人二维码 String external_position; // 对外职务 - String external_profile; //成员对外属性 + Object external_profile; //成员对外属性 - public String getErrocode() { - return errocode; + public Integer getErrcode() { + return errcode; } - public void setErrocode(String errocode) { - this.errocode = errocode; + public void setErrcode(Integer errcode) { + this.errcode = errcode; } public String getErrmsg() { @@ -59,19 +59,19 @@ public class WechatUserInfo { this.name = name; } - public String getDepatrment() { - return depatrment; + public Object getdepartment() { + return department; } - public void setDepatrment(String depatrment) { - this.depatrment = depatrment; + public void setdepartment(Object department) { + this.department = department; } - public String getOrder() { + public Object getOrder() { return order; } - public void setOrder(String order) { + public void setOrder(Object order) { this.order = order; } @@ -107,11 +107,11 @@ public class WechatUserInfo { this.email = email; } - public String getIs_leader_in_dept() { + public Object getIs_leader_in_dept() { return is_leader_in_dept; } - public void setIs_leader_in_dept(String is_leader_in_dept) { + public void setIs_leader_in_dept(Object is_leader_in_dept) { this.is_leader_in_dept = is_leader_in_dept; } @@ -163,27 +163,27 @@ public class WechatUserInfo { this.open_userid = open_userid; } - public String getMain_department() { + public Integer getMain_department() { return main_department; } - public void setMain_department(String main_department) { + public void setMain_department(Integer main_department) { this.main_department = main_department; } - public String getExtattr() { + public Object getExtattr() { return extattr; } - public void setExtattr(String extattr) { + public void setExtattr(Object extattr) { this.extattr = extattr; } - public String getStatus() { + public Integer getStatus() { return Status; } - public void setStatus(String status) { + public void setStatus(Integer status) { Status = status; } @@ -203,13 +203,11 @@ public class WechatUserInfo { this.external_position = external_position; } - public String getExternal_profile() { + public Object getExternal_profile() { return external_profile; } - public void setExternal_profile(String external_profile) { + public void setExternal_profile(Object external_profile) { this.external_profile = external_profile; } - - } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java index 7deaf4055..258f75511 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDeptService.java @@ -1,6 +1,8 @@ package com.ruoyi.system.service; import java.util.List; + +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.Ztree; import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.entity.SysRole; @@ -111,5 +113,5 @@ public interface ISysDeptService /** * Ecology部门信息同步 */ - public int syncEcologyDept(String url,String params); + public AjaxResult syncEcologyDept(String url, String params); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java index 0492ec362..e4c214331 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java @@ -1,6 +1,8 @@ package com.ruoyi.system.service; import java.util.List; + +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.system.domain.SysUserRole; @@ -208,7 +210,7 @@ public interface ISysUserService /** * Ecology人员信息同步 */ - public int syncEcologyUser(String url,String params); + public AjaxResult syncEcologyUser(String url, String params); /** * 查询用户列表 diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IWechatApiService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IWechatApiService.java index d4968517f..604043ee9 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IWechatApiService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IWechatApiService.java @@ -1,9 +1,49 @@ package com.ruoyi.system.service; +import com.ruoyi.system.domain.WechatSendMessage; +import com.ruoyi.system.domain.WechatUserInfo; + +import java.util.List; +import java.util.Map; + public interface IWechatApiService { //获取Access Token public String GetAccessToken(); //根据企业微信登录身份获取本地LoginName public String GetLoginNameWithWechatCode(String code); + + /** + * 根据企业微信登录链接的code用户获取userid; + * @param code + * @return userid + */ + public String GetUseridByWechatLogin(String code); + + /** + * 根据企业微信userid获取用户详细信息 + * @param userId + * @return 用户详细信息 + */ + public WechatUserInfo GetWechatUserInfoDetailByUserId(String userId); + + /** + * 推送text消息到企业微信用户 + * @param toUserList 发送的用户列表 + * @param message 发送的消息内容 + * @return 消息发送结果 + */ + public Map SendTextMessageToWechatUser(List toUserList, String message); + + /** + * 推送文本卡片消息到企业微信用户 + * description参数说明:支持使用br标签或者空格来进行换行处理,也支持使用div标签来使用不同的字体颜色,目前内置了3种文字颜色:灰色(gray)、高亮(highlight)、默认黑色(normal),将其作为div标签的class属性即可 + * 示例:"description" : "
    2016年9月26日
    恭喜你抽中iPhone 7一台,领奖码:xxxx
    请于2016年10月10日前联系行政同事领取
    " + * @param toUserList 发送的用户列表 + * @param title 标题 + * @param description 内容描述 + * @param detailUrl 点击详情的Url地址 + * @return 消息发送结果 + */ + public Map SendTextCardMessageToWechatUser(List toUserList, String title, String description, String detailUrl); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java index d665df5df..1bcd2f9ff 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDeptServiceImpl.java @@ -4,16 +4,22 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.ruoyi.common.annotation.DataScope; import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.Ztree; import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.exception.BusinessException; +import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.system.domain.EcologyDept; import com.ruoyi.system.mapper.SysDeptMapper; +import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysDeptService; +import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.system.service.IWechatApiService; import org.apache.commons.lang3.ArrayUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -35,6 +41,15 @@ public class SysDeptServiceImpl implements ISysDeptService @Autowired private SysDeptMapper deptMapper; + @Autowired + private ISysConfigService sysconfig; + + @Autowired + private IWechatApiService wechatApiService; + + @Autowired + ISysUserService userService; + /** * 查询部门管理数据 * @@ -66,7 +81,7 @@ public class SysDeptServiceImpl implements ISysDeptService /** * 查询部门管理树(排除下级) * - * @param deptId 部门ID + * @param dept 部门 * @return 所有部门信息 */ @Override @@ -233,7 +248,8 @@ public class SysDeptServiceImpl implements ISysDeptService updateDeptChildren(dept.getDeptId(), newAncestors, oldAncestors); } int result = deptMapper.updateDept(dept); - if (UserConstants.DEPT_NORMAL.equals(dept.getStatus())) + if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors()) + && !StringUtils.equals("0", dept.getAncestors())) { // 如果该部门是启用状态,则启用该部门的所有上级部门 updateParentDeptStatusNormal(dept); @@ -319,9 +335,24 @@ public class SysDeptServiceImpl implements ISysDeptService * Ecology部门信息同步 */ @Override - public int syncEcologyDept(String url,String params) { - int result= deptSync(HttpUtils.sendPostWithRest(url,params)); - return result; + public AjaxResult syncEcologyDept(String url, String params) { + String msg="同步OA部门失败!"; + List userList=new ArrayList<>(); + userList.add(ShiroUtils.getLoginName().equals("admin")?"359":String.valueOf(ShiroUtils.getUserId())); + if( ! sysconfig.selectConfigByKey("sys.dept.sync").equals("1")){ + msg="OA部门同步失败!系统未开启OA部门同步!"; + wechatApiService.SendTextMessageToWechatUser(userList,msg); + return AjaxResult.success(msg,"false"); + } + int result =deptSync(HttpUtils.sendPostWithRest(url,params)); + if( result==200) + { + return AjaxResult.success("OA部门同步成功!",result); + } + + wechatApiService.SendTextMessageToWechatUser(userList,msg+"result:"+result); + return AjaxResult.error(msg,result); + } @SuppressWarnings("unchecked") diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java index eaf08e3ab..5045313b8 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java @@ -6,10 +6,12 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.ruoyi.common.annotation.DataScope; import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.exception.BusinessException; +import com.ruoyi.common.utils.ShiroUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.common.utils.security.Md5Utils; @@ -17,6 +19,7 @@ import com.ruoyi.system.domain.*; import com.ruoyi.system.mapper.*; import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.system.service.IWechatApiService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -56,6 +59,9 @@ public class SysUserServiceImpl implements ISysUserService @Autowired private ISysConfigService configService; + @Autowired + private IWechatApiService wechatApiService; + /** * 根据条件分页查询用户列表 * @@ -535,9 +541,24 @@ public class SysUserServiceImpl implements ISysUserService * @param params */ @Override - public int syncEcologyUser(String url, String params) { + public AjaxResult syncEcologyUser(String url, String params) { + String msg="OA人员同步失败!"; + List userList=new ArrayList<>(); + userList.add(ShiroUtils.getLoginName().equals("admin")?"359":String.valueOf(ShiroUtils.getUserId())); + if( ! configService.selectConfigByKey("sys.user.sync").equals("1")){ + msg="OA人员同步失败!系统未开启OA人员同步!"; + wechatApiService.SendTextMessageToWechatUser(userList,msg); + return AjaxResult.success(msg,"false"); + } int result= userSync(HttpUtils.sendPostWithRest(url,params)); - return result; + if( result==200) + { + return AjaxResult.success("OA人员同步成功!",result); + } + + wechatApiService.SendTextMessageToWechatUser(userList,msg+"result:"+result); + return AjaxResult.error(msg,result); + } /** @@ -569,10 +590,15 @@ public class SysUserServiceImpl implements ISysUserService List ecologyUserList= new Gson().fromJson(dataMap.get("dataList").toString(), new TypeToken>(){}.getType()); */ + //获取原同步的用户 + SysUser oldSysUser=new SysUser(); + oldSysUser.setUserType("02"); + List oldSysUserList=userMapper.selectUserLists(oldSysUser); + //删除从Ecology同步过来(用户类型为02)的用户 userMapper.deleteEcologySyncUser(); - //同步Ecology部门信息 + //同步Ecology人员信息 SysUser user = new SysUser(); for(EcologyUser ecologyUser:ecologyUserList){ if(ecologyUser.getSubcompanyid1().equals("1") && StringUtils.isNotEmpty(ecologyUser.getLoginid())) { //只取分部ID为“1”的员工 @@ -593,6 +619,17 @@ public class SysUserServiceImpl implements ISysUserService user.setPhonenumber(ecologyUser.getMobile()); user.setStatus(ecologyUser.getStatus().equals("5")?"1":"0"); //Ecology为离职状态5,则无效 user.setDelFlag("0"); + for(SysUser oldUser:oldSysUserList){ + if(String.valueOf(oldUser.getUserId()).equals(ecologyUser.getId())){ + user.setAvatar(oldUser.getAvatar()); + user.setPassword(oldUser.getPassword()); + user.setSalt(oldUser.getSalt()); + user.setLoginDate(oldUser.getLoginDate()); + user.setLoginIp(oldUser.getLoginIp()); + user.setPwdUpdateDate(oldUser.getPwdUpdateDate()); + user.setRemark(oldUser.getRemark()); + } + } userMapper.insertUser(user); } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatApiServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatApiServiceImpl.java index cc936330a..52bad6719 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatApiServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/WechatApiServiceImpl.java @@ -2,21 +2,25 @@ package com.ruoyi.system.service.impl; import com.alibaba.fastjson.JSONObject; import com.google.gson.Gson; -import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.CacheUtils; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.system.domain.WechatAccessToken; +import com.ruoyi.system.domain.WechatUserInfo; import com.ruoyi.system.mapper.WechatAccessTokenMapper; import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.IWechatApiService; +import org.apache.shiro.cache.Cache; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; @Service public class WechatApiServiceImpl implements IWechatApiService { @@ -43,6 +47,31 @@ public class WechatApiServiceImpl implements IWechatApiService { */ @Override public String GetAccessToken() { + String cacheName = "wechatToke:" + corpId + "," + agentId; + + //获取缓存中accessToken与缓存的时间信息 + Cache cache = CacheUtils.getCache(cacheName); + String accessToken = (String) cache.get("accessToken"); + Date getTokenTime = ObjectToDate(cache.get("getTokenTime")); + Integer expires_in = ObjectToInteger(cache.get("expires_in")); + //如果没有获取到cache或者accessToken为空或者cache即将过期,则重新获取并返回新的accessToken; + if (StringUtils.isEmpty(accessToken) || null == getTokenTime ? true : (differenceSecond(DateUtils.getNowDate(), getTokenTime) + 1000 > expires_in ? true : false)) { + //清空wechatAccessTokenCache + CacheUtils.removeAll(cacheName); + //从企业微信获取新的accessToken + WechatAccessToken wechatAccessToken = getAccessTokenFromWechat(corpId, secret, agentId); + //将Token写入缓存 + CacheUtils.put(cacheName, "accessToken", wechatAccessToken.getAccess_token()); + CacheUtils.put(cacheName, "expires_in", wechatAccessToken.getExpires_in()); + CacheUtils.put(cacheName, "getTokenTime", DateUtils.getNowDate()); + //返回token + return wechatAccessToken.getAccess_token(); + } + return accessToken; + } + + /* + public String GetAccessToken() { //获取本地数据库中的Token WechatAccessToken wat = new WechatAccessToken(); wat.setCorpId(corpId); @@ -53,6 +82,7 @@ public class WechatApiServiceImpl implements IWechatApiService { if(list.isEmpty() || list.size() <=0) { returnWat= getAccessTokenFromWechat(corpId,secret,agentId); + //将accessToken写入数据库 wechatAccessTokenMapper.insertWechatAccessToken(returnWat); return returnWat.getAccess_token(); } @@ -81,6 +111,34 @@ public class WechatApiServiceImpl implements IWechatApiService { //如果以上情况皆不是,则返回本地数据库的token return list.get(0).getAccess_token(); + }*/ + + //将对象转化为日期,如果无法转换则返回空值,避免抛出异常。 + private Date ObjectToDate(Object obj){ + try { + return (Date) obj; + }catch (Exception e){ + return null; + } + } + + //将对象转化为Integer,如果对象为空或无法转换返回0, + private Integer ObjectToInteger(Object obj){ + //如果为空返回零 + if(null==obj){ + return 0; + } + try{ + return Integer.parseInt(obj.toString()); + }catch (Exception e){ + //发生异常返回0 + return 0; + } + } + + //获取相两个日期相差秒数 + private int differenceSecond(Date minuendDate, Date subtractionDate ) { + return (int)((minuendDate.getTime() - subtractionDate.getTime()) / 1000); } //根据corpId与corpSecret获取Token @@ -95,12 +153,6 @@ public class WechatApiServiceImpl implements IWechatApiService { return wechatAccessToken; } - //获取相两个日期相差秒数 - private int differenceSecond(Date minuendDate, Date subtractionDate ) { - return (int)((minuendDate.getTime() - subtractionDate.getTime()) / 1000); - } - - /** * 根据企业微信登录身份获取本地LoginName * @@ -110,7 +162,47 @@ public class WechatApiServiceImpl implements IWechatApiService { @Override public String GetLoginNameWithWechatCode(String code) { + if(StringUtils.isEmpty(code)){ + return ""; + } //获取访问用户身份ID + String userId= GetUseridByWechatLogin(code); + if(StringUtils.isEmpty(userId)){ + return ""; + } + //获取用户邮箱与姓名 + WechatUserInfo wechatUserInfo = GetWechatUserInfoDetailByUserId(userId); + if (null==wechatUserInfo || null==wechatUserInfo.getName()){ + return ""; + } + //根据用户id+邮箱名+用户名匹配本地用户对应的userId+邮箱名与用户名 + SysUser sysUserWechat=new SysUser(); + sysUserWechat.setUserId(Long.parseLong(wechatUserInfo.getUserid())); + sysUserWechat.setUserName(wechatUserInfo.getName()); + sysUserWechat.setEmail(wechatUserInfo.getEmail()); + sysUserWechat.setUserType("02"); //只获取从OA同步的用户,保持与企业微信一致。 + + List userList= userService.selectUserLists(sysUserWechat); + int count= userList.size(); + if(count <= 0){ + return ""; //系统里没有用户,没有从OA同步? 处理逻辑待定 + } + if(count > 1){ + return ""; //本地数据库存在多个姓名与邮箱相同的记录,如何处理??--加上了sysUserWechat.setUserId(Long.parseLong(wechatUserInfo.getUserid()));,不存在这种情况了。 + } + String loginName= userList.get(0).getLoginName(); + return loginName; + + } + + /** + * 根据企业微信登录链接的code用户获取userid; + * + * @param code + * @return userid + */ + @Override + public String GetUseridByWechatLogin(String code) { String url="https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo"; String param = "access_token="+wechatApiService.GetAccessToken()+"&code="+code; String userInfo = HttpUtils.sendGet(url,param); //测试已能正常返回UserInfo Json,正式使用时打开 @@ -118,41 +210,102 @@ public class WechatApiServiceImpl implements IWechatApiService { JSONObject jsonObjectUserInfo = JSONObject.parseObject(userInfo); //如果返回码不为0,则输出错误信息,并返回空值 if ( Integer.parseInt(jsonObjectUserInfo.getString("errcode")) != 0){ - System.out.println(jsonObjectUserInfo.getString("errmsg")); - return ""; - } - String userId = jsonObjectUserInfo.getString("UserId"); - - //获取用户邮箱与姓名 - url="https://qyapi.weixin.qq.com/cgi-bin/user/get"; - param="access_token="+wechatApiService.GetAccessToken()+"&userid="+userId; - String userInfoDetail=HttpUtils.sendGet(url,param); //获取成员信息 - JSONObject jsonObjectUserInfoDetail=JSONObject.parseObject(userInfoDetail); - //如果返回码不为0,则返回错误信息 - if(Integer.parseInt(jsonObjectUserInfoDetail.getString("errcode")) != 0) - { System.out.println(jsonObjectUserInfo.getString("errmsg")); return ""; } - String userEmail= jsonObjectUserInfoDetail.getString("email"); - String userName= jsonObjectUserInfoDetail.getString("name"); + return jsonObjectUserInfo.getString("UserId"); + } - //根据邮箱名+用户名匹配本地用户对应的邮箱名与用户名 - SysUser sysUser=new SysUser(); - sysUser.setUserName(userName); - sysUser.setEmail(userEmail); - sysUser.setUserType("02"); //只获取从OA同步的用户,保持与企业微信一致。 - List userList= userService.selectUserLists(sysUser); - int count= userList.size(); - if(count <= 0){ - return ""; //系统里没有用户,没有从OA同步? 处理逻辑待定 + /** + * 根据企业微信userid获取用户详细信息 + * + * @param userId + * @return 用户详细信息 + */ + @Override + public WechatUserInfo GetWechatUserInfoDetailByUserId(String userId) { + String url="https://qyapi.weixin.qq.com/cgi-bin/user/get"; + String param="access_token="+wechatApiService.GetAccessToken()+"&userid="+userId; + String userInfoDetail=HttpUtils.sendGet(url,param); //获取成员信息 + WechatUserInfo wechatUserInfo = JSONObject.parseObject(userInfoDetail,WechatUserInfo.class); + //如果返回码不为0,则返回空,显示错误信息 + if (wechatUserInfo.getErrcode() !=0) + { + System.out.println(wechatUserInfo.getErrmsg()); + return null; } - if(count > 1){ - return ""; //本地数据库存在多个姓名与邮箱相同的记录,如何处理?? - } - String loginName= userList.get(0).getLoginName(); - return loginName; + return wechatUserInfo; + } + //将List转换为企业微信人员格式,例[359|358] + private String CovertListToWechatTouserFormat(List toUserList){ + StringBuilder toUser = new StringBuilder(); + for(String user:toUserList){ + toUser.append(user); + if(toUserList.indexOf(user) < toUserList.size()-1){ + toUser.append("|"); + } + } + return toUser.toString(); + } + + /** + * 推送text消息到企业微信用户 + * 其中text参数的content字段可以支持换行、以及A标签,即可打开自定义的网页 + * 示例:"content" : "你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看
    邮件中心视频实况,聪明避开排队。" + * @param toUserList 发送的用户列表 + * @param message 发送的消息内容 + * @return 消息发送结果 + */ + @Override + public Map SendTextMessageToWechatUser(List toUserList,String message) { + Map resultMap; + Map param = new HashMap<>(16); + param.put("touser", CovertListToWechatTouserFormat(toUserList)); + param.put("msgtype", "text"); + param.put("agentid", agentId); + + Map text = new HashMap<>(16); + text.put("content", message); + param.put("text", text); + + String url="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token="+wechatApiService.GetAccessToken(); + + //param参数需要直接使用对象,而不能转换成json字符串,否则推送到企业微信中文消息乱码。 + resultMap =HttpUtils.sendPostWithRest(url,param); + return resultMap; + } + + /** + * 推送文本卡片消息到企业微信用户 + * description参数说明:支持使用br标签或者空格来进行换行处理,也支持使用div标签来使用不同的字体颜色,目前内置了3种文字颜色:灰色(gray)、高亮(highlight)、默认黑色(normal),将其作为div标签的class属性即可 + * 示例:"description" : "
    2016年9月26日
    恭喜你抽中iPhone 7一台,领奖码:xxxx
    请于2016年10月10日前联系行政同事领取
    " + * + * @param toUserList 发送的用户列表 + * @param title 标题 + * @param description 内容描述 + * @param detailUrl 点击详情的Url地址 + * @return 消息发送结果 + */ + @Override + public Map SendTextCardMessageToWechatUser(List toUserList, String title, String description, String detailUrl) { + Map resultMap; + Map param = new HashMap<>(16); + param.put("touser", CovertListToWechatTouserFormat(toUserList)); + param.put("msgtype", "textcard"); + param.put("agentid", agentId); + + Map textcard=new HashMap<>(); + textcard.put("title",title); + textcard.put("description",description); + textcard.put("url",detailUrl); + param.put("textcard",textcard); + + String url="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token="+wechatApiService.GetAccessToken(); + + //param参数需要直接使用对象,而不能转换成json字符串,否则推送到企业微信中文消息乱码。 + resultMap =HttpUtils.sendPostWithRest(url,param); + return resultMap; } } diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index 827c417b5..f78713eac 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -231,6 +231,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"