Sfoglia il codice sorgente

1.增加微信登录及微信绑定。

tomatozq 5 anni fa
parent
commit
3c18d1db09

+ 121 - 0
picc-admin-server/src/main/java/com/jpsoft/picc/config/RedisConfig.java

@@ -0,0 +1,121 @@
+package com.jpsoft.picc.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.*;
+import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import java.lang.reflect.Method;
+
+@Configuration
+@EnableCaching
+public class RedisConfig extends CachingConfigurerSupport {
+    /**
+     * 注入 RedisConnectionFactory,注意maven中要有redis.clients.jedis
+     */
+    @Autowired
+    RedisConnectionFactory redisConnectionFactory;
+
+    /**
+     * 实例化 RedisTemplate 对象
+     * @return
+     */
+    @Bean
+    public RedisTemplate<String, Object> getRedisTemplate() {
+        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+        initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
+        return redisTemplate;
+    }
+
+    /**
+     * 设置数据存入 redis 的序列化方式
+     *
+     * @param redisTemplate
+     * @param factory
+     */
+    private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
+        redisTemplate.setKeySerializer(new StringRedisSerializer());
+        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
+        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
+        redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
+        redisTemplate.setConnectionFactory(factory);
+    }
+
+    @Bean
+    public KeyGenerator keyGenerator() {
+        return new KeyGenerator() {
+            @Override
+            public Object generate(Object target, Method method, Object... params) {
+                StringBuilder sb = new StringBuilder();
+                sb.append(target.getClass().getName());
+                sb.append(method.getName());
+                for (Object obj : params) {
+                    sb.append(obj.toString());
+                }
+
+                return sb.toString();
+            }
+        };
+    }
+
+    /**
+     * 实例化 HashOperations 对象,可以使用 Hash 类型操作
+     *
+     * @param redisTemplate
+     * @return
+     */
+    @Bean
+    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
+        return redisTemplate.opsForHash();
+    }
+
+    /**
+     * 实例化 ValueOperations 对象,可以使用 String 操作
+     *
+     * @param redisTemplate
+     * @return
+     */
+    @Bean
+    public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
+        return redisTemplate.opsForValue();
+    }
+
+    /**
+     * 实例化 ListOperations 对象,可以使用 List 操作
+     *
+     * @param redisTemplate
+     * @return
+     */
+    @Bean
+    public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
+        return redisTemplate.opsForList();
+    }
+
+    /**
+     * 实例化 SetOperations 对象,可以使用 Set 操作
+     *
+     * @param redisTemplate
+     * @return
+     */
+    @Bean
+    public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
+        return redisTemplate.opsForSet();
+    }
+
+    /**
+     * 实例化 ZSetOperations 对象,可以使用 ZSet 操作
+     *
+     * @param redisTemplate
+     * @return
+     */
+    @Bean
+    public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
+        return redisTemplate.opsForZSet();
+    }
+}

+ 2 - 1
picc-admin-server/src/main/java/com/jpsoft/picc/config/WebMvcConfig.java

@@ -49,6 +49,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
 				"/webjars/**",
 				"/swagger-ui.html",
 				"/v2/**",
-				"/pub/**");
+				"/pub/**"	//下载附件、扫码回调
+				);
 	}
 }

+ 226 - 6
picc-admin-server/src/main/java/com/jpsoft/picc/modules/admin/controller/JwtsUserController.java

@@ -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;
+    }
 }

+ 1 - 1
picc-admin-server/src/main/java/com/jpsoft/picc/modules/sys/controller/MenuController.java

@@ -191,7 +191,7 @@ public class MenuController {
     public MessageResult<List> query(
             String keywords,
             String excludeId,
-            @RequestParam(value = "length", defaultValue = "20") int limit,
+            @RequestParam(value = "limit", defaultValue = "20") int limit,
             @RequestAttribute String subject) {
         MessageResult<List> msgResult = new MessageResult<>();
 

+ 7 - 1
picc-admin-server/src/main/resources/application-dev.yml

@@ -13,4 +13,10 @@ logger:
   dir: D:\\Logs\\picc\\picc-admin-server\\
 
 pdf:
-  logoUrl: C:\\picc\\logo.png
+  logoUrl: C:\\picc\\logo.png
+
+weixin:
+  appId: wxc0ddd6a415c535d9
+  appSecret: 042fe6c9c970c1d9fe585dccfca89221
+  tokenUrl: "http://localhost:8086/weixin-middleware/token"
+  createQrCodeUrl: "http://localhost:8086/weixin-middleware/qrcode/create"

+ 9 - 0
picc-admin-server/src/main/resources/application-test.yml

@@ -16,3 +16,12 @@ springfox:
     swagger:
       v2:
         host: gyxm.jing-zhou.gov.cn
+
+pdf:
+  logoUrl: C:\\picc\\logo.png
+
+weixin:
+  appId: wxc0ddd6a415c535d9
+  appSecret: 042fe6c9c970c1d9fe585dccfca89221
+  tokenUrl: "http://localhost:8086/weixin-middleware/token"
+  createQrCodeUrl: "http://localhost:8086/weixin-middleware/qrcode/create"

+ 1 - 1
picc-admin-server/src/main/resources/application.yml

@@ -61,7 +61,7 @@ spring:
     # Redis数据库索引(默认为0)
     database: 1
     # Redis服务器地址
-    host: 192.168.33.21
+    host: 127.0.0.1
     # Redis服务器连接端口
     port: 6379
     # Redis服务器连接密码(默认为空)

+ 10 - 0
picc-common/src/main/java/com/jpsoft/picc/modules/common/constant/WeixinEvent.java

@@ -10,4 +10,14 @@ public class WeixinEvent {
      * PICC微信扫码绑定
      */
     public final static int PICC_ENT_SCAN_QRCODE_BINDING = 5001;
+
+    /**
+     * PICC微信扫码绑定
+     */
+    public final static int PICC_ADMIN_SCAN_QRCODE_LOGIN = 6000;
+
+    /**
+     * PICC微信扫码绑定
+     */
+    public final static int PICC_ADMIN_SCAN_QRCODE_BINDING = 6001;
 }

+ 1 - 0
picc-common/src/main/java/com/jpsoft/picc/modules/sys/dao/UserDAO.java

@@ -18,4 +18,5 @@ public interface UserDAO {
 	List<User> list();
 	List<User> search(Map<String,Object> searchParams,List<Sort> sortList);
 	User findByUserName(@Param("userName") String userName);
+	User findByOpenId(@Param("openId") String openId);
 }

+ 9 - 0
picc-common/src/main/java/com/jpsoft/picc/modules/sys/entity/User.java

@@ -22,6 +22,7 @@ public class User {
 	private Boolean delFlag;
 	private String createBy;
 	private String updateBy;
+	private String openId;
 	private List<String> roles;
 	/**
 	 *获取用户编号
@@ -157,4 +158,12 @@ public class User {
 	public void setRoles(List<String> roles) {
 		this.roles = roles;
 	}
+
+	public String getOpenId() {
+		return openId;
+	}
+
+	public void setOpenId(String openId) {
+		this.openId = openId;
+	}
 }

+ 1 - 0
picc-common/src/main/java/com/jpsoft/picc/modules/sys/service/UserService.java

@@ -15,4 +15,5 @@ public interface UserService {
 	List<User> list();
 	Page<User> pageSearch(Map<String, Object> searchParams,int pageNum,int pageSize,List<Sort> sortList);
 	User findByUserName(String userName);
+	User findByOpenId(String openId);
 }

+ 5 - 0
picc-common/src/main/java/com/jpsoft/picc/modules/sys/service/impl/UserServiceImpl.java

@@ -71,4 +71,9 @@ public class UserServiceImpl implements UserService {
 	public User findByUserName(String userName) {
 		return userDAO.findByUserName(userName);
 	}
+
+	@Override
+	public User findByOpenId(String openId) {
+		return userDAO.findByOpenId(openId);
+	}
 }

+ 10 - 3
picc-common/src/main/resources/mapper/sys/User.xml

@@ -13,6 +13,7 @@
         <result property="delFlag" column="del_flag"/>
         <result property="createBy" column="create_by"/>
         <result property="updateBy" column="update_by"/>
+        <result property="openId" column="open_id"/>
     </resultMap>
     <insert id="insert" parameterType="com.jpsoft.picc.modules.sys.entity.User">
         <!--
@@ -22,7 +23,7 @@
         -->
         <![CDATA[
 		insert into sys_user
-	    (id_,user_name,password_,real_name,create_time,update_time,del_flag,create_by,update_by)
+	    (id_,user_name,password_,real_name,create_time,update_time,del_flag,create_by,update_by,open_id)
 		values
 		(
             #{id,jdbcType=VARCHAR}
@@ -34,6 +35,7 @@
             ,#{delFlag,jdbcType= NUMERIC }
             ,#{createBy,jdbcType=VARCHAR}
             ,#{updateBy,jdbcType=VARCHAR}
+            ,#{openId,jdbcType=VARCHAR}
 		)
 	]]>
     </insert>
@@ -67,12 +69,14 @@
             <if test="updateBy!=null">
                 update_by=#{updateBy,jdbcType=VARCHAR},
             </if>
+            <if test="openId!=null">
+                open_id=#{openId,jdbcType=VARCHAR},
+            </if>
         </set>
         where id_=#{id}
     </update>
     <select id="get" parameterType="string" resultMap="UserMap">
-        select
-        id_,user_name,password_,real_name,create_time,update_time,del_flag,create_by,update_by from sys_user where
+        select * from sys_user where
         id_=#{0}
     </select>
     <select id="exist" parameterType="string" resultType="int">
@@ -84,6 +88,9 @@
     <select id="findByUserName" parameterType="string" resultMap="UserMap">
         select * from sys_user where user_name=#{userName} and del_flag=0 limit 1
     </select>
+    <select id="findByOpenId" parameterType="string" resultMap="UserMap">
+        select * from sys_user where open_id=#{openId} and del_flag=0 limit 1
+    </select>
     <select id="search" parameterType="hashmap" resultMap="UserMap">
         <![CDATA[
 			select * from sys_user

+ 32 - 11
picc-enterprise-server/src/main/java/com/jpsoft/picc/modules/pub/controller/UserController.java

@@ -54,19 +54,25 @@ public class UserController {
 
     @ResponseBody
     @ApiOperation(value = "创建扫码登录二维码")
-    @GetMapping(value="/create/qrcode/login")
+    @GetMapping(value="/qrcode/login/create")
     @ApiImplicitParams({
-            @ApiImplicitParam(name = "randNum",value = "6位随机数", required = true, paramType = "query")
+            @ApiImplicitParam(name = "loginCode",value = "6位随机数", required = true, paramType = "query")
     })
-    public MessageResult<String> createQrcodeLogin(String randNum){
+    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_ENT_SCAN_QRCODE_LOGIN + "," + randNum, expireSeconds);
+            String url = WeixinUtil.createQrcode(weixinConfig, WeixinEvent.PICC_ENT_SCAN_QRCODE_LOGIN + "," + loginCode, expireSeconds);
 
             if(StringUtils.isNotEmpty(url)){
-                valueOperations.set(WeixinConfig.SCAN_QRCODE_LOGIN_PREFIX + randNum,"0",expireSeconds, TimeUnit.SECONDS);
+                valueOperations.set(WeixinConfig.SCAN_QRCODE_LOGIN_PREFIX + loginCode,"0",expireSeconds, TimeUnit.SECONDS);
 
                 msgResult.setData(url);
                 msgResult.setResult(true);
@@ -80,8 +86,14 @@ public class UserController {
         return msgResult;
     }
 
+    /**
+     * 接收扫码登录回调
+     * @param eventKey
+     * @param openId
+     * @return 返回值会在微信中显示
+     */
     @ApiOperation(value = "接收扫码登录回调")
-    @PostMapping(value="/scan/qrcode/login")
+    @PostMapping(value="/qrcode/login/scan")
     @ResponseBody
     public String scanQrcodeLogin(String eventKey,String openId){
         log.warn(openId + "请求登录!");
@@ -106,12 +118,12 @@ public class UserController {
     }
 
     @ApiOperation(value = "扫码登录轮询")
-    @GetMapping(value="/scan/qrcode/loginLoop")
+    @GetMapping(value="/qrcode/login/loop")
     @ResponseBody
-    public MessageResult<String> scanQrcodeLoginLoop(String randNum){
+    public MessageResult<String> scanQrcodeLoginLoop(String loginCode){
         MessageResult<String> msgResult = new MessageResult<>();
 
-        String openId = (String) valueOperations.get(WeixinConfig.SCAN_QRCODE_LOGIN_PREFIX + randNum);
+        String openId = (String) valueOperations.get(WeixinConfig.SCAN_QRCODE_LOGIN_PREFIX + loginCode);
 
         if(StringUtils.isNotEmpty(openId) && openId.length()>1) {
             //n秒内可以用该openId登录
@@ -131,7 +143,7 @@ public class UserController {
     }
 
     @ApiOperation(value = "获取微信绑定二维码")
-    @PostMapping(value="/auth/binding/qrcode")
+    @GetMapping(value="/auth/qrcode/binding/create")
     @ResponseBody
     public MessageResult<String> createBindingQrcode(HttpServletRequest request){
         MessageResult<String> msgResult = new MessageResult<>();
@@ -148,6 +160,9 @@ public class UserController {
                 msgResult.setData(url);
                 msgResult.setResult(true);
             }
+            else{
+                throw new Exception("生成二维码失败!");
+            }
         }
         catch (Exception ex){
             msgResult.setMessage(ex.getMessage());
@@ -157,8 +172,14 @@ public class UserController {
         return msgResult;
     }
 
+    /**
+     * 接收微信绑定回调
+     * @param eventKey
+     * @param openId
+     * @return 返回值会在微信中显示
+     */
     @ApiOperation(value = "接收微信绑定回调")
-    @PostMapping(value="/scan/qrcode/binding")
+    @PostMapping(value="/qrcode/binding/scan")
     @ResponseBody
     public String scanQrcodeBinding(String eventKey,String openId){
         String result = "";

+ 15 - 0
weixin-middleware/src/main/java/com/jpsoft/weixin/config/PICCAdminScanConfig.java

@@ -0,0 +1,15 @@
+package com.jpsoft.weixin.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "qrcode.picc.admin.scan")
+@Data
+public class PICCAdminScanConfig {
+    private String loginCode;
+    private String loginCallbackUrl;
+    private String bindingCode;
+    private String bindingCallbackUrl;
+}

+ 6 - 0
weixin-middleware/src/main/java/com/jpsoft/weixin/controller/WeixinController.java

@@ -3,6 +3,7 @@ package com.jpsoft.weixin.controller;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.json.JSONObject;
 import com.jpsoft.weixin.callback.EventCallback;
+import com.jpsoft.weixin.config.PICCAdminScanConfig;
 import com.jpsoft.weixin.config.PICCEntScanConfig;
 import com.jpsoft.weixin.config.WeixinConfig;
 import com.jpsoft.weixin.util.WeixinUtil;
@@ -45,6 +46,9 @@ public class WeixinController {
     @Autowired
     private PICCEntScanConfig piccEntScanConfig;
 
+    @Autowired
+    private PICCAdminScanConfig piccAdminScanConfig;
+
     @Autowired
     private ValueOperations<String,Object> valueOperations;
 
@@ -171,6 +175,8 @@ public class WeixinController {
 
         list.add(new EventCallback(piccEntScanConfig.getLoginCode(),piccEntScanConfig.getLoginCallbackUrl()));
         list.add(new EventCallback(piccEntScanConfig.getBindingCode(),piccEntScanConfig.getBindingCallbackUrl()));
+        list.add(new EventCallback(piccAdminScanConfig.getLoginCode(),piccAdminScanConfig.getLoginCallbackUrl()));
+        list.add(new EventCallback(piccAdminScanConfig.getBindingCode(),piccAdminScanConfig.getBindingCallbackUrl()));
 
         return list;
     }

+ 8 - 2
weixin-middleware/src/main/resources/application-dev.yml

@@ -40,6 +40,12 @@ qrcode:
     enterprise:
       scan:
         loginCode: "5000"
-        loginCallbackUrl: "http://localhost:7070/picc-enterprise-server/scan/qrcode/login"
+        loginCallbackUrl: "http://localhost:7070/picc-enterprise-server/qrcode/login/scan"
         bindingCode: "5001"
-        bindingCallbackUrl: "http://localhost:7070/picc-enterprise-server/scan/qrcode/binding"
+        bindingCallbackUrl: "http://localhost:7070/picc-enterprise-server/qrcode/binding/scan"
+    admin:
+      scan:
+        loginCode: "6000"
+        loginCallbackUrl: "http://localhost:8081/picc-admin-server/pub/qrcode/login/scan"
+        bindingCode: "6001"
+        bindingCallbackUrl: "http://localhost:8081/picc-admin-server/pub/qrcode/binding/scan"