|
@@ -1,7 +1,11 @@
|
|
|
package com.jpsoft.picc.modules.admin.controller;
|
|
|
|
|
|
+import com.jpsoft.picc.modules.base.entity.CompanyUser;
|
|
|
+import com.jpsoft.picc.modules.common.config.WeixinConfig;
|
|
|
+import com.jpsoft.picc.modules.common.constant.WeixinEvent;
|
|
|
import com.jpsoft.picc.modules.common.dto.MessageResult;
|
|
|
import com.jpsoft.picc.modules.common.utils.DES3;
|
|
|
+import com.jpsoft.picc.modules.common.utils.WeixinUtil;
|
|
|
import com.jpsoft.picc.modules.sys.entity.User;
|
|
|
import com.jpsoft.picc.modules.sys.service.UserService;
|
|
|
import io.jsonwebtoken.Jwts;
|
|
@@ -10,19 +14,23 @@ import io.swagger.annotations.Api;
|
|
|
import io.swagger.annotations.ApiImplicitParam;
|
|
|
import io.swagger.annotations.ApiImplicitParams;
|
|
|
import io.swagger.annotations.ApiOperation;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
-import org.springframework.web.bind.annotation.GetMapping;
|
|
|
-import org.springframework.web.bind.annotation.PostMapping;
|
|
|
-import org.springframework.web.bind.annotation.RequestAttribute;
|
|
|
-import org.springframework.web.bind.annotation.RestController;
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
+import org.springframework.data.redis.core.ValueOperations;
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
import springfox.documentation.annotations.ApiIgnore;
|
|
|
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpSession;
|
|
|
import java.security.Key;
|
|
|
import java.util.Base64;
|
|
|
import java.util.Date;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
+@Slf4j
|
|
|
@RestController
|
|
|
@Api(description = "用户登录、登出")
|
|
|
public class JwtsUserController {
|
|
@@ -32,11 +40,20 @@ public class JwtsUserController {
|
|
|
@Autowired
|
|
|
private UserService userService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private WeixinConfig weixinConfig;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ValueOperations<String,Object> valueOperations;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private RedisTemplate redisTemplate;
|
|
|
+
|
|
|
@PostMapping("/login")
|
|
|
@ApiOperation(value="登录获取token,在swagger ui中获取token时将写入session,调用其它接口时不用再设置header")
|
|
|
@ApiImplicitParams({
|
|
|
- @ApiImplicitParam(name="userName", paramType="query", required=true, value="用户名"),
|
|
|
- @ApiImplicitParam(name="password", paramType="query", required=true, value="密码")
|
|
|
+ @ApiImplicitParam(name="userName", paramType="form", required=true, value="用户名"),
|
|
|
+ @ApiImplicitParam(name="password", paramType="form", required=true, value="密码")
|
|
|
})
|
|
|
public MessageResult<String> login(String userName, String password, @ApiIgnore HttpSession session){
|
|
|
MessageResult<String> messageResult = new MessageResult<>();
|
|
@@ -101,4 +118,207 @@ public class JwtsUserController {
|
|
|
|
|
|
return messageResult;
|
|
|
}
|
|
|
+
|
|
|
+ @ApiOperation(value = "获取微信绑定二维码")
|
|
|
+ @GetMapping(value="/qrcode/binding/create")
|
|
|
+ @ResponseBody
|
|
|
+ public MessageResult<String> createBindingQrcode(@RequestAttribute String subject) {
|
|
|
+ MessageResult<String> msgResult = new MessageResult<>();
|
|
|
+
|
|
|
+ try{
|
|
|
+ String url = WeixinUtil.createQrcode(weixinConfig,
|
|
|
+ WeixinEvent.PICC_ADMIN_SCAN_QRCODE_BINDING + "," + subject, 3000);
|
|
|
+
|
|
|
+ if(StringUtils.isNotEmpty(url)){
|
|
|
+ msgResult.setData(url);
|
|
|
+ msgResult.setResult(true);
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ throw new Exception("生成二维码失败!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex){
|
|
|
+ msgResult.setMessage(ex.getMessage());
|
|
|
+ msgResult.setResult(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ return msgResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 接收微信绑定回调
|
|
|
+ * @param eventKey
|
|
|
+ * @param openId
|
|
|
+ * @return 返回值会在微信中显示
|
|
|
+ */
|
|
|
+ @ApiOperation(value = "接收微信绑定回调")
|
|
|
+ @PostMapping(value="/pub/qrcode/binding/scan")
|
|
|
+ @ResponseBody
|
|
|
+ public String scanQrcodeBinding(String eventKey,String openId) {
|
|
|
+ String result = "";
|
|
|
+
|
|
|
+ try {
|
|
|
+ String[] arr = eventKey.split(",");
|
|
|
+
|
|
|
+ User user = userService.get(arr[1]);
|
|
|
+
|
|
|
+ user.setOpenId(openId);
|
|
|
+ user.setUpdateBy("weixin");
|
|
|
+ user.setUpdateTime(new Date());
|
|
|
+
|
|
|
+ userService.update(user);
|
|
|
+
|
|
|
+ result= "微信绑定成功!";
|
|
|
+ }
|
|
|
+ catch (Exception ex){
|
|
|
+ log.error(ex.getMessage(),ex);
|
|
|
+
|
|
|
+ result = "微信绑定失败!" + ex.getMessage();
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @ResponseBody
|
|
|
+ @ApiOperation(value = "创建扫码登录二维码")
|
|
|
+ @GetMapping(value="/pub/qrcode/login/create")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name = "loginCode",value = "6位随机数", required = true, paramType = "query")
|
|
|
+ })
|
|
|
+ public MessageResult<String> createQrcodeLogin(@RequestParam(value = "loginCode") String loginCode){
|
|
|
+ MessageResult<String> msgResult = new MessageResult<>();
|
|
|
+
|
|
|
+ log.warn("收到登录请求码:" + loginCode);
|
|
|
+
|
|
|
+ try {
|
|
|
+ if (loginCode.length()>10){
|
|
|
+ throw new Exception("登录请求码长度不能大于10!");
|
|
|
+ }
|
|
|
+
|
|
|
+ long expireSeconds = 3000; //5分钟
|
|
|
+ String url = WeixinUtil.createQrcode(weixinConfig, WeixinEvent.PICC_ADMIN_SCAN_QRCODE_LOGIN + "," + loginCode, expireSeconds);
|
|
|
+
|
|
|
+ if(StringUtils.isNotEmpty(url)){
|
|
|
+ valueOperations.set(WeixinConfig.SCAN_QRCODE_LOGIN_PREFIX + loginCode,"0",expireSeconds, TimeUnit.SECONDS);
|
|
|
+
|
|
|
+ msgResult.setData(url);
|
|
|
+ msgResult.setResult(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex){
|
|
|
+ msgResult.setMessage(ex.getMessage());
|
|
|
+ msgResult.setResult(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ return msgResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 接收扫码登录回调
|
|
|
+ * @param eventKey
|
|
|
+ * @param openId
|
|
|
+ * @return 返回值会在微信中显示
|
|
|
+ */
|
|
|
+ @ApiOperation(value = "接收扫码登录回调")
|
|
|
+ @PostMapping(value="/pub/qrcode/login/scan")
|
|
|
+ @ResponseBody
|
|
|
+ public String scanQrcodeLoginCallback(String eventKey,String openId){
|
|
|
+ log.warn(openId + "请求登录!");
|
|
|
+ String result;
|
|
|
+
|
|
|
+ User user = userService.findByOpenId(openId);
|
|
|
+
|
|
|
+ if(user!=null) {
|
|
|
+ String[] arr = eventKey.split(",");
|
|
|
+ String randNum = arr[1];
|
|
|
+
|
|
|
+ long expireSeconds = 3000; //5分钟
|
|
|
+
|
|
|
+ valueOperations.set(WeixinConfig.SCAN_QRCODE_LOGIN_PREFIX + randNum, openId, expireSeconds, TimeUnit.SECONDS);
|
|
|
+ result = "扫码登录成功!";
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ result = "当前用户未绑定微信!";
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation(value = "扫码登录轮询")
|
|
|
+ @GetMapping(value="/pub/qrcode/login/loop")
|
|
|
+ @ResponseBody
|
|
|
+ public MessageResult<String> scanQrcodeLoginLoop(String loginCode){
|
|
|
+ MessageResult<String> msgResult = new MessageResult<>();
|
|
|
+
|
|
|
+ String openId = (String) valueOperations.get(WeixinConfig.SCAN_QRCODE_LOGIN_PREFIX + loginCode);
|
|
|
+
|
|
|
+ if(StringUtils.isNotEmpty(openId) && openId.length()>1) {
|
|
|
+ //n秒内可以用该openId登录
|
|
|
+ valueOperations.set("LOGIN_" + openId, "1", 120,TimeUnit.SECONDS);
|
|
|
+
|
|
|
+ msgResult.setData(openId);
|
|
|
+ msgResult.setResult(true);
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ //由于前端将result=false的message全部弹出显示,故这里改成设置data=""
|
|
|
+ msgResult.setResult(false);
|
|
|
+ msgResult.setMessage("未收到登录请求!");
|
|
|
+ }
|
|
|
+
|
|
|
+ return msgResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping("/pub/qrcode/login")
|
|
|
+ @ApiOperation(value="登录获取token,在swagger ui中获取token时将写入session,调用其它接口时不用再设置header")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name="openId", paramType="form", required=true, value="用户名")
|
|
|
+ })
|
|
|
+ public MessageResult<String> scanQrcodeLogin(String openId, @ApiIgnore HttpSession session){
|
|
|
+ MessageResult<String> messageResult = new MessageResult<>();
|
|
|
+
|
|
|
+ try {
|
|
|
+ //redisTemplate.hasKey("LOGIN_" + openId) 为false
|
|
|
+ if(StringUtils.isEmpty(openId)
|
|
|
+ || valueOperations.get("LOGIN_" + openId)==null){
|
|
|
+ throw new Exception("扫码登录失败!");
|
|
|
+ }
|
|
|
+
|
|
|
+ User user = userService.findByOpenId(openId);
|
|
|
+
|
|
|
+ if(user!=null){
|
|
|
+ //生成token
|
|
|
+ Date now = new Date();
|
|
|
+ long expiration = now.getTime() + 3600 * 6000; //6个小时后,该客户端的token过期
|
|
|
+
|
|
|
+ byte[] privateKey = Base64.getDecoder().decode(jwtSecret);
|
|
|
+
|
|
|
+ Key key = Keys.hmacShaKeyFor(privateKey);
|
|
|
+
|
|
|
+ String token = Jwts.builder()
|
|
|
+ .setSubject(user.getId())
|
|
|
+ //设置自定义claims后,setSubject值将失效
|
|
|
+// .setClaims(extraInfo)
|
|
|
+ .signWith(key)
|
|
|
+ .setExpiration(new Date(expiration))
|
|
|
+ .compact();
|
|
|
+
|
|
|
+ session.setAttribute("token","Bearer " + token);
|
|
|
+
|
|
|
+ messageResult.setResult(true);
|
|
|
+ messageResult.setData("Bearer " + token);
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ messageResult.setResult(false);
|
|
|
+ messageResult.setMessage("用户未绑定微信!");
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ catch(Exception ex){
|
|
|
+ messageResult.setResult(false);
|
|
|
+ messageResult.setMessage(ex.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ return messageResult;
|
|
|
+ }
|
|
|
}
|