新增企业微信扫描登录

This commit is contained in:
jinqiming 2021-06-06 13:59:02 +08:00
parent 174ae785f8
commit dbe6994d09
7 changed files with 118 additions and 66 deletions

View File

@ -8,20 +8,16 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.snow.common.constant.Constants; import com.snow.common.constant.Constants;
import com.snow.common.enums.DingTalkListenerType; import com.snow.common.enums.DingTalkListenerType;
import com.snow.dingtalk.common.EventNameEnum;
import com.snow.dingtalk.sync.ISyncSysInfo; import com.snow.dingtalk.sync.ISyncSysInfo;
import com.snow.dingtalk.sync.SyncSysInfoFactory; import com.snow.dingtalk.sync.SyncSysInfoFactory;
import com.snow.system.domain.DingtalkCallBack; import com.snow.system.domain.DingtalkCallBack;
import com.snow.system.service.impl.DingtalkCallBackServiceImpl; import com.snow.system.service.impl.DingtalkCallBackServiceImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -97,6 +93,8 @@ public class CallBackController {
} }
} }
/** /**
* 接收钉钉dingFlow机器人消息 * 接收钉钉dingFlow机器人消息
* @return * @return

View File

@ -1,36 +1,25 @@
package com.snow.web.controller.dingtalk; package com.snow.web.controller.dingtalk;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.response.OapiSnsGetuserinfoBycodeResponse;
import com.dingtalk.api.response.OapiUserGetbyunionidResponse;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.snow.common.core.controller.BaseController; import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult; import com.snow.common.core.domain.AjaxResult;
import com.snow.common.utils.AuthUtils;
import com.snow.common.utils.ServletUtils; import com.snow.common.utils.ServletUtils;
import com.snow.common.utils.StringUtils; import com.snow.common.utils.StringUtils;
import com.snow.dingtalk.service.UserService;
import com.snow.framework.shiro.auth.LoginType; import com.snow.framework.shiro.auth.LoginType;
import com.snow.framework.shiro.auth.UserToken; import com.snow.framework.shiro.auth.UserToken;
import com.snow.framework.util.ShiroUtils; import com.snow.framework.util.ShiroUtils;
import com.snow.system.domain.SysAuthUser; import com.snow.system.domain.SysAuthUser;
import com.snow.system.domain.SysSocialUser;
import com.snow.system.domain.SysUser; import com.snow.system.domain.SysUser;
import com.snow.system.mapper.SysUserMapper; import com.snow.system.mapper.SysUserMapper;
import com.snow.system.service.ISysConfigService; import com.snow.system.service.ISysConfigService;
import com.snow.system.service.impl.SysSocialUserServiceImpl;
import com.snow.system.service.impl.SysUserServiceImpl;
import me.zhyd.oauth.cache.AuthDefaultStateCache;
import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.model.AuthCallback; import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse; import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthDingTalkRequest; import me.zhyd.oauth.request.AuthDingTalkRequest;
import me.zhyd.oauth.request.AuthRequest; import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.request.AuthWeChatEnterpriseRequest;
import me.zhyd.oauth.utils.AuthStateUtils; import me.zhyd.oauth.utils.AuthStateUtils;
import org.apache.shiro.SecurityUtils; 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.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -40,8 +29,6 @@ import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/** /**
* @program: snow * @program: snow
@ -71,19 +58,34 @@ public class ThirdOauthController extends BaseController {
@ResponseBody @ResponseBody
public void renderAuth(@PathVariable("source") String source) throws IOException public void renderAuth(@PathVariable("source") String source) throws IOException
{ {
String appId= iSysConfigService.selectConfigByKey("ding.login.appid"); AuthRequest authRequest =null;
String appSecret= iSysConfigService.selectConfigByKey("ding.login.appSecret"); switch (source){
String redirectUri= iSysConfigService.selectConfigByKey("ding.login.redirectUri"); case "dingtalk":
authRequest= getDingTalkAuthRequest();
break;
case "weChart":
authRequest=getWeChatAuthRequest();
break;
}
AuthRequest authRequest = new AuthDingTalkRequest(AuthConfig.builder()
.clientId(appId)
.clientSecret(appSecret)
.redirectUri(redirectUri)
.build());
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState()); String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
ServletUtils.getResponse().sendRedirect(authorizeUrl); ServletUtils.getResponse().sendRedirect(authorizeUrl);
} }
/**
* 微信回调登录
* @param callback
* @param request
* @return
*/
@SuppressWarnings("unchecked")
@GetMapping("/weChartLogin")
public Object weChartLogin(AuthCallback callback, HttpServletRequest request)
{
return thirdLogin("weChart",getWeChatAuthRequest(),callback);
}
/** /**
* 钉钉回调 * 钉钉回调
*/ */
@ -91,16 +93,73 @@ public class ThirdOauthController extends BaseController {
@GetMapping("/dingTalkLogin") @GetMapping("/dingTalkLogin")
public Object callbackAuth(AuthCallback callback, HttpServletRequest request) public Object callbackAuth(AuthCallback callback, HttpServletRequest request)
{ {
return thirdLogin("dingtalk",getDingTalkAuthRequest(),callback);
}
String source="dingtalk";
/**
* 检查是否授权
*/
@PostMapping("/checkAuthUser")
@ResponseBody
public AjaxResult checkAuthUser(SysAuthUser authUser)
{
Long userId = ShiroUtils.getUserId();
String source = authUser.getSource();
if (userMapper.checkAuthUser(userId, source) > 0)
{
return error(source + "平台账号已经绑定");
}
return AjaxResult.success();
}
/**
* 取消授权
*/
@PostMapping("/unlock")
@ResponseBody
public AjaxResult unlockAuth(SysAuthUser authUser)
{
return toAjax(userMapper.deleteAuthUser(authUser.getAuthId()));
}
/**
* 构建钉钉AuthRequest
* @return
*/
private AuthRequest getDingTalkAuthRequest() {
String appId= iSysConfigService.selectConfigByKey("ding.login.appid"); String appId= iSysConfigService.selectConfigByKey("ding.login.appid");
String appSecret= iSysConfigService.selectConfigByKey("ding.login.appSecret"); String appSecret= iSysConfigService.selectConfigByKey("ding.login.appSecret");
String redirectUri= iSysConfigService.selectConfigByKey("ding.login.redirectUri"); String redirectUri= iSysConfigService.selectConfigByKey("ding.login.redirectUri");
AuthRequest authRequest = new AuthDingTalkRequest(AuthConfig.builder() return new AuthDingTalkRequest(AuthConfig.builder()
.clientId(appId) .clientId(appId)
.clientSecret(appSecret) .clientSecret(appSecret)
.redirectUri(redirectUri) .redirectUri(redirectUri)
.build()); .build());
}
/**
* 构建企业微信AuthRequest
* @return
*/
private AuthRequest getWeChatAuthRequest() {
return new AuthWeChatEnterpriseRequest(AuthConfig.builder()
.clientId("ww2354bcd694497bd8")
.clientSecret("EzODWvC9zdPJJS4KnCNVENB3UhSiYCbmr9UrFpOM9dQ")
.redirectUri("http://workflow.vaiwan.com/third/oauth/weChartLogin")
.agentId("1000002")
.build());
}
/**
* 构建登录
* @param source 来源
* @param authRequest 请求参数
* @param callback 请求参数
* @return
*/
private Object thirdLogin(String source, AuthRequest authRequest,AuthCallback callback){
AuthResponse<AuthUser> response = authRequest.login(callback); AuthResponse<AuthUser> response = authRequest.login(callback);
if (response.ok()) if (response.ok())
{ {
@ -139,30 +198,4 @@ public class ThirdOauthController extends BaseController {
return new ModelAndView("error/404"); return new ModelAndView("error/404");
} }
/**
* 检查是否授权
*/
@PostMapping("/checkAuthUser")
@ResponseBody
public AjaxResult checkAuthUser(SysAuthUser authUser)
{
Long userId = ShiroUtils.getUserId();
String source = authUser.getSource();
if (userMapper.checkAuthUser(userId, source) > 0)
{
return error(source + "平台账号已经绑定");
}
return AjaxResult.success();
}
/**
* 取消授权
*/
@PostMapping("/unlock")
@ResponseBody
public AjaxResult unlockAuth(SysAuthUser authUser)
{
return toAjax(userMapper.deleteAuthUser(authUser.getAuthId()));
}
} }

View File

@ -167,15 +167,15 @@ public class SysIndexController extends BaseController
sysNotice.setNoticeType("1"); sysNotice.setNoticeType("1");
List<SysNotice> sysNotices = sysNoticeService.selectNoticeList(sysNotice); List<SysNotice> sysNotices = sysNoticeService.selectNoticeList(sysNotice);
mmap.put("sysNotices",sysNotices); mmap.put("sysNotices",sysNotices);
if(CollectionUtil.isNotEmpty(sysNotices)&&sysNotices.size()>4){ if(CollectionUtil.isNotEmpty(sysNotices)&&sysNotices.size()>5){
mmap.put("sysNoticeList",sysNotices.subList(0,4)); mmap.put("sysNoticeList",sysNotices.subList(0,5));
}else { }else {
mmap.put("sysNoticeList",sysNotices); mmap.put("sysNoticeList",sysNotices);
} }
mmap.put("sysNoticeListSize",sysNotices.size()); mmap.put("sysNoticeListSize",sysNotices.size());
HistoricTaskInstanceDTO historicTaskInstanceDTO=new HistoricTaskInstanceDTO(); HistoricTaskInstanceDTO historicTaskInstanceDTO=new HistoricTaskInstanceDTO();
historicTaskInstanceDTO.setPageNum(1); historicTaskInstanceDTO.setPageNum(1);
historicTaskInstanceDTO.setPageSize(4); historicTaskInstanceDTO.setPageSize(5);
historicTaskInstanceDTO.setUserId(String.valueOf(sysUser.getUserId())); historicTaskInstanceDTO.setUserId(String.valueOf(sysUser.getUserId()));
PageModel<HistoricTaskInstanceVO> historicTaskInstance = flowableService.getHistoricTaskInstance(historicTaskInstanceDTO); PageModel<HistoricTaskInstanceVO> historicTaskInstance = flowableService.getHistoricTaskInstance(historicTaskInstanceDTO);
mmap.put("historicTaskInstanceList",historicTaskInstance.getPagedRecords()); mmap.put("historicTaskInstanceList",historicTaskInstance.getPagedRecords());

View File

@ -71,8 +71,8 @@
<img src="../static/img/dingtalk.png" th:src="@{/img/dingtalk.png}"/> <img src="../static/img/dingtalk.png" th:src="@{/img/dingtalk.png}"/>
</a> </a>
</div> </div>
<div class="item" title="功能开发中..."> <div class="item" title="使用 企业微信 账号授权登录">
<a href="#"> <a th:href="@{/third/oauth/toDingPage/weChart}">
<img src="../static/img/weixin.svg" th:src="@{/img/weixin.svg}"/> <img src="../static/img/weixin.svg" th:src="@{/img/weixin.svg}"/>
</a> </a>
</div> </div>

View File

@ -54,7 +54,7 @@
</h3> </h3>
</a> </a>
<br/> <br/>
<h2 class="m-xs text-center"> <span class="text-warning text-center" style="font-size:1em">待办数 - [[${flowGeneralSituation.todoTaskNum}]]</span></h2> <h2 class="m-xs text-center"> <span class="text-warning text-center" style="font-size:0.8em">待办数 - [[${flowGeneralSituation.todoTaskNum}]]</span></h2>
</div> </div>
</div> </div>
<div class="col-sm-3"> <div class="col-sm-3">
@ -65,7 +65,7 @@
</h3> </h3>
</a> </a>
<br/> <br/>
<h2 class="m-xs text-center"> <span class="text-primary text-center" style="font-size:1em">已办数 - [[${flowGeneralSituation.doneTaskNum}]]</span></h2> <h2 class="m-xs text-center"> <span class="text-primary text-center" style="font-size:0.8em">已办数 - [[${flowGeneralSituation.doneTaskNum}]]</span></h2>
</div> </div>
</div> </div>
<div class="col-sm-3"> <div class="col-sm-3">
@ -75,7 +75,7 @@
</h3> </h3>
<br/> <br/>
<h2 class="m-xs text-center"> <h2 class="m-xs text-center">
<span class="text-success text-center" style="font-size:1em">流程数 - [[${flowGeneralSituation.myStartProcessInstanceNum}]]</span> <span class="text-success text-center" style="font-size:0.8em">流程数 - [[${flowGeneralSituation.myStartProcessInstanceNum}]]</span>
</h2> </h2>
</div> </div>
</div> </div>
@ -86,7 +86,7 @@
</h3> </h3>
<br/> <br/>
<h2 class="m-xs text-center"> <h2 class="m-xs text-center">
<span class="text-danger text-center" style="font-size:1em"> 超时数 - [[${flowGeneralSituation.threeTodoTaskNum}]]</span> <span class="text-danger text-center" style="font-size:0.8em"> 超时数 - [[${flowGeneralSituation.threeTodoTaskNum}]]</span>
</h2> </h2>
</div> </div>
</div> </div>
@ -176,7 +176,11 @@
</div> </div>
</div> </div>
<button class="btn btn-primary btn-block m-t" th:if="${sysNoticeListSize} gt 2"><i class="fa fa-arrow-down"></i> 加载更多</button> <button class="btn btn-primary btn-block m-t" th:if="${sysNoticeListSize} gt 4">
<a onclick="openMoreNotice()">
<i class="fa fa-arrow-down"></i> 加载更多
</a>
</button>
</div> </div>
</div> </div>
</div> </div>
@ -197,7 +201,12 @@
</div> </div>
</div> </div>
<button class="btn btn-primary btn-block m-t" th:if="${historicTaskInstanceSize} gt 2"><i class="fa fa-arrow-down"></i> 加载更多</button> <button class="btn btn-primary btn-block m-t" th:if="${historicTaskInstanceSize} gt 4">
<a onclick="openMoreHistoricTask()">
<i class="fa fa-arrow-down"></i> 加载更多
</a>
</button>
</div> </div>
</div> </div>
</div> </div>
@ -353,6 +362,12 @@
var detailUrl="/system/notice/detail/"+id; var detailUrl="/system/notice/detail/"+id;
$.modal.openTab("公告详情", detailUrl); $.modal.openTab("公告详情", detailUrl);
} }
function openMoreNotice(){
$.modal.openTab("公告管理","/system/notice");
}
function openMoreHistoricTask(){
$.modal.openTab("我的已办","/flow/toMyTakePartInProcess");
}
function hisTaskDetail(detailUrl) { function hisTaskDetail(detailUrl) {
$.modal.openTab("我的已办", detailUrl); $.modal.openTab("我的已办", detailUrl);
} }

View File

@ -151,7 +151,7 @@
<a class="third-app" href="javascript:void(0)" th:onclick="authUrl('dingtalk');" title="使用 DingTalk 账号授权登录"> <a class="third-app" href="javascript:void(0)" th:onclick="authUrl('dingtalk');" title="使用 DingTalk 账号授权登录">
<div class="git-other-login-icon"><img th:src="@{/img/dingding.jpg}"></div> <div class="git-other-login-icon"><img th:src="@{/img/dingding.jpg}"></div>
<span class="app-name">DingTalk</span></a> <span class="app-name">DingTalk</span></a>
<a class="third-app" href="#" title="功能开发中..."> <a class="third-app" href="javascript:void(0)" th:onclick="authUrl('weChart');" title="使用 企业微信 账号授权登录">
<div class="git-other-login-icon"><img th:src="@{/img/weixin.svg}"></div> <div class="git-other-login-icon"><img th:src="@{/img/weixin.svg}"></div>
<span class="app-name">WeiXin</span></a> <span class="app-name">WeiXin</span></a>

View File

@ -157,6 +157,12 @@
<version>2.6</version> <version>2.6</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-cp</artifactId>
<version>4.1.0</version>
</dependency>
</dependencies> </dependencies>
</project> </project>