Quellcode durchsuchen

Merge remote-tracking branch 'origin/master'

yanliming vor 5 Jahren
Ursprung
Commit
75654b106c
33 geänderte Dateien mit 899 neuen und 197 gelöschten Zeilen
  1. 121 0
      picc-admin-server/src/main/java/com/jpsoft/picc/config/RedisConfig.java
  2. 2 1
      picc-admin-server/src/main/java/com/jpsoft/picc/config/WebMvcConfig.java
  3. 228 6
      picc-admin-server/src/main/java/com/jpsoft/picc/modules/admin/controller/JwtsUserController.java
  4. 168 98
      picc-admin-server/src/main/java/com/jpsoft/picc/modules/business/controller/InsurancePolicyController.java
  5. 1 1
      picc-admin-server/src/main/java/com/jpsoft/picc/modules/sys/controller/MenuController.java
  6. 9 1
      picc-admin-server/src/main/resources/application-dev.yml
  7. 11 0
      picc-admin-server/src/main/resources/application-test.yml
  8. 1 1
      picc-admin-server/src/main/resources/application.yml
  9. 2 0
      picc-common/src/main/java/com/jpsoft/picc/modules/common/config/WeixinConfig.java
  10. 10 0
      picc-common/src/main/java/com/jpsoft/picc/modules/common/constant/WeixinEvent.java
  11. 51 0
      picc-common/src/main/java/com/jpsoft/picc/modules/common/utils/WeixinUtil.java
  12. 1 0
      picc-common/src/main/java/com/jpsoft/picc/modules/sys/dao/UserDAO.java
  13. 9 0
      picc-common/src/main/java/com/jpsoft/picc/modules/sys/entity/User.java
  14. 1 0
      picc-common/src/main/java/com/jpsoft/picc/modules/sys/service/UserService.java
  15. 5 0
      picc-common/src/main/java/com/jpsoft/picc/modules/sys/service/impl/UserServiceImpl.java
  16. 10 3
      picc-common/src/main/resources/mapper/sys/User.xml
  17. 2 2
      picc-enterprise-server/pom.xml
  18. 0 29
      picc-enterprise-server/src/main/java/com/jpsoft/picc/config/WebSocketConfig.java
  19. 16 2
      picc-enterprise-server/src/main/java/com/jpsoft/picc/modules/auth/controller/CompanyController.java
  20. 49 14
      picc-enterprise-server/src/main/java/com/jpsoft/picc/modules/pub/controller/UserController.java
  21. 3 1
      picc-enterprise-server/src/main/resources/application-dev.yml
  22. 8 0
      picc-enterprise-server/src/main/resources/application-remote.yml
  23. 9 1
      picc-enterprise-server/src/main/resources/application-test.yml
  24. 1 2
      weixin-middleware/pom.xml
  25. 2 2
      weixin-middleware/src/main/java/com/jpsoft/weixin/callback/EventCallback.java
  26. 15 0
      weixin-middleware/src/main/java/com/jpsoft/weixin/config/PICCAdminScanConfig.java
  27. 1 0
      weixin-middleware/src/main/java/com/jpsoft/weixin/config/WeixinConfig.java
  28. 42 8
      weixin-middleware/src/main/java/com/jpsoft/weixin/controller/WeixinController.java
  29. 35 0
      weixin-middleware/src/main/java/com/jpsoft/weixin/util/WeixinUtil.java
  30. 9 23
      weixin-middleware/src/main/resources/application-dev.yml
  31. 32 0
      weixin-middleware/src/main/resources/application-production.yml
  32. 24 1
      weixin-middleware/src/main/resources/application-test.yml
  33. 21 1
      weixin-middleware/src/main/resources/application.yml

+ 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/**"	//下载附件、扫码回调
+				);
 	}
 }

+ 228 - 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,209 @@ 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){
+            log.error(ex.getMessage(),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){
+            log.error(ex.getMessage(),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;
+    }
 }

+ 168 - 98
picc-admin-server/src/main/java/com/jpsoft/picc/modules/business/controller/InsurancePolicyController.java

@@ -1,19 +1,27 @@
 package com.jpsoft.picc.modules.business.controller;
 
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.json.JSON;
+import cn.hutool.json.JSONObject;
 import com.github.pagehelper.Page;
+import com.jpsoft.picc.modules.base.entity.Company;
+import com.jpsoft.picc.modules.base.entity.CompanyUser;
 import com.jpsoft.picc.modules.base.entity.InsuranceAgent;
 import com.jpsoft.picc.modules.base.entity.InsuranceDefinitionLimit;
+import com.jpsoft.picc.modules.base.service.CompanyService;
+import com.jpsoft.picc.modules.base.service.CompanyUserService;
 import com.jpsoft.picc.modules.base.service.InsuranceAgentService;
 import com.jpsoft.picc.modules.base.service.InsuranceDefinitionLimitService;
 import com.jpsoft.picc.modules.business.entity.*;
 import com.jpsoft.picc.modules.business.service.*;
 import com.jpsoft.picc.modules.common.config.PdfConfig;
+import com.jpsoft.picc.modules.common.config.WeixinConfig;
 import com.jpsoft.picc.modules.common.constant.PolicyStatus;
 import com.jpsoft.picc.modules.common.dto.MessageResult;
 import com.jpsoft.picc.modules.common.dto.Sort;
 import com.jpsoft.picc.modules.common.utils.ItextPDFUtil;
 import com.jpsoft.picc.modules.common.utils.PojoUtils;
+import com.jpsoft.picc.modules.common.utils.WeixinUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
@@ -31,7 +39,9 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
 import java.io.File;
+import java.security.Policy;
 import java.util.*;
+import java.util.concurrent.Executor;
 
 @RestController
 @RequestMapping("/insurancePolicy")
@@ -60,6 +70,15 @@ public class InsurancePolicyController {
     @Autowired
     private InsuranceDefinitionLimitService insuranceDefinitionLimitService;
 
+    @Autowired
+    private CompanyService companyService;
+
+    @Autowired
+    private CompanyUserService companyUserService;
+
+    @Autowired
+    private WeixinConfig weixinConfig;
+
     @ApiOperation(value="创建空记录")
     @GetMapping("create")
     public MessageResult<InsurancePolicy> create(){
@@ -336,36 +355,67 @@ public class InsurancePolicyController {
             @ApiImplicitParam(name="opinion",value = "意见",required = true,paramType = "query")
     })
     public MessageResult<Integer> firstApproval(String applicationId,String policyId,String processStatus,String opinion, @RequestAttribute String subject){
-
         //当前用户ID
         System.out.println(subject);
 
         MessageResult<Integer> msgResult = new MessageResult<>();
 
-        String status ="";
+        try {
+            PolicyStatus policyStatus;
 
-        if(processStatus.equals("正常")){
-            //30
-            status = String.valueOf(PolicyStatus.PendingRetrial.getValue());
-        }
-        else{
-            //15
-            status = String.valueOf(PolicyStatus.Back.getValue());
-        }
+            if (processStatus.equals("正常")) {
+                //30
+                policyStatus = PolicyStatus.PendingRetrial;
+            } else {
+                //15
+                policyStatus = PolicyStatus.Back;
+            }
 
-        int affectCount = approval(applicationId,policyId,processStatus,opinion,status ,subject);
+            int affectCount = approval(applicationId, policyId, processStatus, opinion, policyStatus.getValue() + "", subject);
 
-        if(affectCount > 0){
-            //修改花名册人员状态为初审
-            check(policyId,"1",subject);
-        }
+            if (affectCount > 0) {
+                //修改花名册人员状态为初审
+                check(policyId, "1", subject);
+            }
 
-        msgResult.setResult(true);
-        msgResult.setData(affectCount);
+            //发送微信通知
+            sendWeixinMessage(applicationId, policyStatus);
+
+            msgResult.setResult(true);
+            msgResult.setData(affectCount);
+        }
+        catch (Exception ex){
+            logger.error(ex.getMessage(),ex);
+            msgResult.setMessage(ex.getMessage());
+        }
 
         return msgResult;
     }
 
+    private void sendWeixinMessage(String applicationId, PolicyStatus policyStatus) {
+        InsuranceApplication insuranceApplication = insuranceApplicationService.get(applicationId);
+        Company company = companyService.get(insuranceApplication.getCompanyId());
+        CompanyUser companyUser = companyUserService.findByCompanyId(company.getId());
+
+        if (companyUser!=null && StringUtils.isNotEmpty(companyUser.getOpenId())){
+            JSONObject jsonObject = new JSONObject();
+
+            JSONObject userNameObj = new JSONObject();
+            userNameObj.put("value",companyUser.getUserName());
+
+            jsonObject.put("userName",userNameObj);
+
+            JSONObject statusObj = new JSONObject();
+            statusObj.put("value",policyStatus.getText());
+
+            jsonObject.put("status",statusObj);
+
+            new Thread(()->WeixinUtil.sendTemplateMessage(weixinConfig,
+                    companyUser.getOpenId(),
+                    weixinConfig.getSendTmplId1(), jsonObject)
+            ).start();
+        }
+    }
 
     @ApiOperation(value="PICC复审")
     @RequestMapping(value = "secondApproval",method = RequestMethod.POST)
@@ -382,38 +432,48 @@ public class InsurancePolicyController {
 
         MessageResult<Integer> msgResult = new MessageResult<>();
 
-        String status ="";
-
-        if(processStatus.equals("正常")){
-            //40
-            InsurancePolicy insurancePolicy = insurancePolicyService.get(policyId);
-            if(insurancePolicy != null){
-                int no = insurancePolicy.getNo();
-                if(no > 1){
-                    //待制单
-                    status = String.valueOf(PolicyStatus.PendingMakePolicy.getValue());
-                }else{
-                    //待缴费
-                    status = String.valueOf(PolicyStatus.PendingPay.getValue());
+        try {
+            PolicyStatus policyStatus;
+
+            if (processStatus.equals("正常")) {
+                //40
+                InsurancePolicy insurancePolicy = insurancePolicyService.get(policyId);
+
+                if (insurancePolicy != null) {
+                    int no = insurancePolicy.getNo();
+                    if (no > 1) {
+                        //待制单
+                        policyStatus = PolicyStatus.PendingMakePolicy;
+                    } else {
+                        //待缴费
+                        policyStatus = PolicyStatus.PendingPay;
+                    }
+                } else {
+                    throw new Exception("下月投保单不存在");
                 }
+            } else {
+                //20
+                policyStatus = PolicyStatus.PendingTrial;
             }
 
-            //status = String.valueOf(PolicyStatus.PendingPay.getValue());
-        }
-        else{
-            //20
-            status = String.valueOf(PolicyStatus.PendingTrial.getValue());
-        }
+            int affectCount = approval(applicationId, policyId, processStatus, opinion, policyStatus.getValue() + "", subject);
 
-        int affectCount = approval(applicationId,policyId,processStatus,opinion,status ,subject);
+            if (affectCount > 0) {
+                //修改花名册人员状态为初审
+                check(policyId, "2", subject);
+            }
 
-        if(affectCount > 0){
-            //修改花名册人员状态为初审
-            check(policyId,"2",subject);
-        }
+            //发送微信通知
+            sendWeixinMessage(applicationId, policyStatus);
 
-        msgResult.setResult(true);
-        msgResult.setData(affectCount);
+            msgResult.setResult(true);
+            msgResult.setData(affectCount);
+        }
+        catch (Exception ex){
+            logger.error(ex.getMessage(),ex);
+            msgResult.setMessage(ex.getMessage());
+            msgResult.setResult(false);
+        }
 
         return msgResult;
     }
@@ -432,54 +492,55 @@ public class InsurancePolicyController {
 
         //当前用户ID
         System.out.println(subject);
-
         MessageResult<Integer> msgResult = new MessageResult<>();
 
-        String status ="";
-
-        if(processStatus.equals("正常")){
-            //70
-            status = String.valueOf(PolicyStatus.SendOutPolicy.getValue());
-        }
-        else{
-            //50
-            status = String.valueOf(PolicyStatus.PendingMakePolicy.getValue());
-        }
+        try {
+//        String status ="";
+            PolicyStatus policyStatus;
 
-        if(StringUtils.isNotEmpty(insurancePolicyFile)){
+            if (processStatus.equals("正常")) {
+                //70
+                policyStatus = PolicyStatus.SendOutPolicy;
+            } else {
+                //50
+                policyStatus = PolicyStatus.PendingMakePolicy;
+            }
 
-            InsurancePolicy insurancePolicy = insurancePolicyService.get(policyId);
+            if (StringUtils.isNotEmpty(insurancePolicyFile)) {
+                InsurancePolicy insurancePolicy = insurancePolicyService.get(policyId);
 
-            insurancePolicy.setInsurancePolicyFile(insurancePolicyFile);
+                insurancePolicy.setInsurancePolicyFile(insurancePolicyFile);
 
-            insurancePolicyService.update(insurancePolicy);
-        }
+                insurancePolicyService.update(insurancePolicy);
+            }
 
-        int affectCount = approval(applicationId,policyId,processStatus,opinion,status ,subject);
+            int affectCount = approval(applicationId, policyId, processStatus, opinion, policyStatus.getValue() + "", subject);
 
-        boolean flag = false;
-        String msg = "";
+            boolean flag = false;
+            String msg = "";
 
-        if(affectCount > 0 ){
-            if(processStatus.equals("正常")) {
-                //生成下月投保单
-                try {
+            if (affectCount > 0) {
+                if (processStatus.equals("正常")) {
+                    //生成下月投保单
                     generatePolicyInTrans(applicationId, policyId, subject);
+
+                    //发送微信通知
+                    sendWeixinMessage(applicationId, policyStatus);
+                } else {
                     flag = true;
-                } catch (Exception ex) {
-                    flag = false;
-                    msg = ex.getMessage();
                 }
             }
-            else{
-                flag = true;
-            }
-        }
 
+            msgResult.setResult(flag);
+            msgResult.setData(affectCount);
+            msgResult.setMessage(msg);
+        }
+        catch (Exception ex) {
+            logger.error(ex.getMessage(),ex);
 
-        msgResult.setResult(flag);
-        msgResult.setData(affectCount);
-        msgResult.setMessage(msg);
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
 
         return msgResult;
     }
@@ -543,35 +604,44 @@ public class InsurancePolicyController {
 
         MessageResult<Integer> msgResult = new MessageResult<>();
 
-        String status ="";
+        try {
+//        String status ="";
+            PolicyStatus policyStatus;
 
-        if(processStatus.equals("正常")){
-            //60
-            status = String.valueOf(PolicyStatus.PendingOutPolicy.getValue());
-        }
-        else{
-            //40
-            status = String.valueOf(PolicyStatus.PendingPay.getValue());
-        }
+            if (processStatus.equals("正常")) {
+                //60
+                policyStatus = PolicyStatus.PendingOutPolicy;
+            } else {
+                //40
+                policyStatus = PolicyStatus.PendingPay;
+            }
 
-        InsurancePolicy item = insurancePolicyService.get(policyId);
+            InsurancePolicy item = insurancePolicyService.get(policyId);
 
-        item.setAccountBank(accountBank);
-        item.setIssuingBank(issuingBank);
-        item.setSinglNumber(singlNumber);
-        item.setTransferTime(new Date());
-        item.setAgentId(agentId);
+            item.setAccountBank(accountBank);
+            item.setIssuingBank(issuingBank);
+            item.setSinglNumber(singlNumber);
+            item.setTransferTime(new Date());
+            item.setAgentId(agentId);
 
-        int affectCount = insurancePolicyService.update(item);
+            int affectCount = insurancePolicyService.update(item);
 
-        int affectCount1 = 0;
+            int affectCount1 = 0;
 
-        if(affectCount>0){
-            affectCount1 = approval(applicationId,policyId,processStatus,opinion,status ,subject);
-        }
+            if (affectCount > 0) {
+                affectCount1 = approval(applicationId, policyId, processStatus, opinion, policyStatus.getValue() + "", subject);
+            }
 
-        msgResult.setResult(true);
-        msgResult.setData(affectCount1);
+            //发送微信通知
+            sendWeixinMessage(applicationId, policyStatus);
+
+            msgResult.setResult(true);
+            msgResult.setData(affectCount1);
+        }
+        catch (Exception ex){
+            msgResult.setResult(false);
+            msgResult.setMessage(ex.getMessage());
+        }
 
         return msgResult;
     }

+ 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<>();
 

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

@@ -13,4 +13,12 @@ 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"
+  sendTmplMsgUrl: "https://api.weixin.qq.com/cgi-bin/message/template/send"
+  sendTmplId1: "oc6Kh7_ZkANmsUnl2keg-X2nUKRBkAwjnGI3z1gTodo"

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

@@ -16,3 +16,14 @@ springfox:
     swagger:
       v2:
         host: gyxm.jing-zhou.gov.cn
+
+pdf:
+  logoUrl: C:\\picc\\logo.png
+
+weixin:
+  appId: wxc0ddd6a415c535d9
+  appSecret: 042fe6c9c970c1d9fe585dccfca89221
+  tokenUrl: "http://www.jzrccs.com/weixin-middleware/token"
+  createQrCodeUrl: "http://www.jzrccs.com/weixin-middleware/qrcode/create"
+  sendTmplMsgUrl: "https://api.weixin.qq.com/cgi-bin/message/template/send"
+  sendTmplId1: "oc6Kh7_ZkANmsUnl2keg-X2nUKRBkAwjnGI3z1gTodo"

+ 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服务器连接密码(默认为空)

+ 2 - 0
picc-common/src/main/java/com/jpsoft/picc/modules/common/config/WeixinConfig.java

@@ -12,6 +12,8 @@ public class WeixinConfig {
     private String appSecret;
     private String tokenUrl;
     private String createQrCodeUrl;
+    private String sendTmplMsgUrl;
+    private String sendTmplId1;
 
     public final static String SCAN_QRCODE_LOGIN_PREFIX = "SCAN_QRCODE_LOGIN_";
 }

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

+ 51 - 0
picc-common/src/main/java/com/jpsoft/picc/modules/common/utils/WeixinUtil.java

@@ -98,4 +98,55 @@ public class WeixinUtil {
 
         return qrcodeUrl;
     }
+
+    public static boolean sendTemplateMessage(WeixinConfig config,String toUserOpenId,String templateId,JSONObject data){
+        boolean result = false;
+
+        try {
+            String accessToken = getAccessToken(config);
+
+            if (StringUtils.isEmpty(accessToken)) {
+                throw new Exception("获取基础token失败!");
+            }
+
+            StringBuilder urlBuilder = new StringBuilder();
+
+            urlBuilder.append(config.getSendTmplMsgUrl())
+                    .append("?access_token=")
+                    .append(URLEncoder.encode(accessToken, "UTF-8"));
+
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("touser", toUserOpenId);
+            jsonObject.put("template_id", templateId);
+            jsonObject.put("data", data);
+
+            StringEntity entity = new StringEntity(jsonObject.toString(), "utf-8");
+
+            entity.setContentType("application/json");//发送json数据需要设置contentType
+
+            HttpPost httpPost = new HttpPost(urlBuilder.toString());
+            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+
+            httpPost.setEntity(entity);
+
+            HttpResponse res = httpClient.execute(httpPost);
+
+            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+                String content = EntityUtils.toString(res.getEntity());
+                JSONObject ret = new JSONObject(content);
+
+                if (ret.getInt("errcode") == 0) {
+                    result = true;
+                } else {
+                    log.error(content);
+                }
+            }
+        }
+        catch (Exception ex){
+            log.error(ex.getMessage(),ex);
+            result = false;
+        }
+
+        return result;
+    }
 }

+ 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

+ 2 - 2
picc-enterprise-server/pom.xml

@@ -114,10 +114,10 @@
             <version>1.9.2</version>
         </dependency>
         <!--websocket start-->
-        <dependency>
+<!--        <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-websocket</artifactId>
-        </dependency>
+        </dependency>-->
         <!--websocket end-->
     </dependencies>
 

+ 0 - 29
picc-enterprise-server/src/main/java/com/jpsoft/picc/config/WebSocketConfig.java

@@ -1,29 +0,0 @@
-package com.jpsoft.picc.config;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.messaging.simp.config.MessageBrokerRegistry;
-import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
-import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
-import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
-import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
-
-@Configuration
-public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
-    @Override
-    public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
-        stompEndpointRegistry.addEndpoint("/stomp")
-                .setAllowedOrigins("*")
-                .withSockJS();
-    }
-
-    @Override
-    public void configureMessageBroker(MessageBrokerRegistry registry) {
-    	// TODO Auto-generated method stub
-
-    	//这句话表示在topic和user这两个域上可以向客户端发消息
-        registry.enableSimpleBroker("/user");
-
-        //这句话表示给指定用户发送一对一的主题前缀是"/user"
-        registry.setUserDestinationPrefix("/user");
-    }
-}

+ 16 - 2
picc-enterprise-server/src/main/java/com/jpsoft/picc/modules/auth/controller/CompanyController.java

@@ -1,13 +1,15 @@
 package com.jpsoft.picc.modules.auth.controller;
 
-import com.alibaba.druid.util.StringUtils;
 import com.jpsoft.picc.modules.base.entity.Company;
+import com.jpsoft.picc.modules.base.entity.CompanyUser;
 import com.jpsoft.picc.modules.base.service.CompanyService;
+import com.jpsoft.picc.modules.base.service.CompanyUserService;
 import com.jpsoft.picc.modules.common.dto.MessageResult;
 import com.jpsoft.picc.modules.common.utils.PojoUtils;
 import com.jpsoft.picc.modules.pub.dto.CompanyInfoDTO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
 import org.jasig.cas.client.authentication.AttributePrincipal;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -24,6 +26,9 @@ public class CompanyController {
     @Autowired
     private CompanyService companyService;
 
+    @Autowired
+    private CompanyUserService companyUserService;
+
     @GetMapping(value="detail")
     @ApiOperation(value = "获取企业信息")
     public MessageResult<CompanyInfoDTO> detail(HttpServletRequest request){
@@ -34,8 +39,12 @@ public class CompanyController {
 
             //todo
             AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
+            CompanyUser companyUser = companyUserService.findByUserName(principal.getName());
+            Company company = null;
 
-            Company company = companyService.findByCreateBy(principal.getName());
+            if (companyUser!=null && StringUtils.isNotEmpty(companyUser.getCompanyId())) {
+                company = companyService.get(companyUser.getCompanyId());
+            }
 
             if(company!=null) {
                 PojoUtils.map(company, companyInfoDTO);
@@ -93,6 +102,11 @@ public class CompanyController {
                 messageResult.setData(company.getId());
             }
 
+            CompanyUser companyUser = companyUserService.findByUserName(principal.getName());
+            companyUser.setCompanyId(company.getId());
+            companyUser.setUpdateTime(new Date());
+            companyUserService.update(companyUser);
+
             messageResult.setResult(true);
         }
         catch (Exception ex){

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

@@ -1,7 +1,9 @@
 package com.jpsoft.picc.modules.pub.controller;
 
 import com.jpsoft.picc.config.CasConfig;
+import com.jpsoft.picc.modules.base.entity.Company;
 import com.jpsoft.picc.modules.base.entity.CompanyUser;
+import com.jpsoft.picc.modules.base.service.CompanyService;
 import com.jpsoft.picc.modules.base.service.CompanyUserService;
 import com.jpsoft.picc.modules.common.config.WeixinConfig;
 import com.jpsoft.picc.modules.common.constant.WeixinEvent;
@@ -20,9 +22,7 @@ import org.jasig.cas.client.authentication.AttributePrincipal;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.ValueOperations;
-import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
 import javax.servlet.http.HttpServletRequest;
@@ -49,30 +49,40 @@ public class UserController {
     @Autowired
     private CompanyUserService companyUserService;
 
+    @Autowired
+    private CompanyService companyService;
+
     @Autowired
     private ValueOperations<String,Object> valueOperations;
 
     @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);
             }
         }
         catch (Exception ex){
+            log.error(ex.getMessage(),ex);
             msgResult.setMessage(ex.getMessage());
             msgResult.setResult(false);
         }
@@ -80,8 +90,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 +122,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 +147,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,8 +164,12 @@ public class UserController {
                 msgResult.setData(url);
                 msgResult.setResult(true);
             }
+            else{
+                throw new Exception("生成二维码失败!");
+            }
         }
         catch (Exception ex){
+            log.error(ex.getMessage(),ex);
             msgResult.setMessage(ex.getMessage());
             msgResult.setResult(false);
         }
@@ -157,8 +177,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 = "";
@@ -243,12 +269,13 @@ public class UserController {
                     e.printStackTrace();
                 }
 
+                //将成功调用云平台登录接口的用户信息更新
                 CompanyUser companyUser = companyUserService.findByUserName(userName);
 
                 if(companyUser!=null) {
                     companyUser.setPassword(des3.encrypt(DES3.DEFAULT_KEY, password));
                     companyUser.setUpdateTime(new Date());
-                    companyUser.setUpdateBy(companyUser.getId());
+                    companyUser.setUpdateBy(userName);
 
                     companyUserService.update(companyUser);
                 }
@@ -257,9 +284,17 @@ public class UserController {
                     companyUser.setId(UUID.randomUUID().toString());
                     companyUser.setUserName(userName);
                     companyUser.setPassword(des3.encrypt(DES3.DEFAULT_KEY, password));
+
                     companyUser.setDelFlag(false);
                     companyUser.setCreateTime(new Date());
 
+                    //修复历史数据
+                    Company company = companyService.findByCreateBy(userName);
+
+                    if (company!=null){
+                        companyUser.setCompanyId(company.getId());
+                    }
+
                     companyUserService.insert(companyUser);
                 }
 

+ 3 - 1
picc-enterprise-server/src/main/resources/application-dev.yml

@@ -30,4 +30,6 @@ weixin:
   appId: wxc0ddd6a415c535d9
   appSecret: 042fe6c9c970c1d9fe585dccfca89221
   tokenUrl: "http://localhost:8086/weixin-middleware/token"
-  createQrCodeUrl: "http://localhost:8086/weixin-middleware/qrcode/create"
+  createQrCodeUrl: "http://localhost:8086/weixin-middleware/qrcode/create"
+  sendTmplMsgUrl: "https://api.weixin.qq.com/cgi-bin/message/template/send"
+  sendTmplId: "6CMGIpbgZLtqdr9xOdyEAlrCWXh8nJ260jRdktnv7vE"

+ 8 - 0
picc-enterprise-server/src/main/resources/application-remote.yml

@@ -28,6 +28,14 @@ jpcloud:
   sellerSerialNumber: '000001000020'
   platformCode: '0008'
 
+weixin:
+  appId: wxc0ddd6a415c535d9
+  appSecret: 042fe6c9c970c1d9fe585dccfca89221
+  tokenUrl: "http://gyxm.jing-zhou.gov.cn/weixin-middleware/token"
+  createQrCodeUrl: "http://gyxm.jing-zhou.gov.cn/weixin-middleware/qrcode/create"
+  sendTmplMsgUrl: "https://api.weixin.qq.com/cgi-bin/message/template/send"
+  sendTmplId: "6CMGIpbgZLtqdr9xOdyEAlrCWXh8nJ260jRdktnv7vE"
+
 springfox:
   documentation:
     swagger:

+ 9 - 1
picc-enterprise-server/src/main/resources/application-test.yml

@@ -9,7 +9,7 @@ spring:
 
 logger:
   level: WARN
-  dir: C:\\picc\\logs\\picc-enterprise-server\\
+  dir: C:\\picc\\logs\\picc-enterprise-test\\
 
 nginx:
   port: 7070
@@ -28,6 +28,14 @@ jpcloud:
   sellerSerialNumber: '000001000020'
   platformCode: '0008'
 
+weixin:
+  appId: wxc0ddd6a415c535d9
+  appSecret: 042fe6c9c970c1d9fe585dccfca89221
+  tokenUrl: "http://www.jzrccs.com/weixin-middleware/token"
+  createQrCodeUrl: "http://www.jzrccs.com/weixin-middleware/qrcode/create"
+  sendTmplMsgUrl: "https://api.weixin.qq.com/cgi-bin/message/template/send"
+  sendTmplId: "6CMGIpbgZLtqdr9xOdyEAlrCWXh8nJ260jRdktnv7vE"
+
 springfox:
   documentation:
     swagger:

+ 1 - 2
weixin-middleware/pom.xml

@@ -9,7 +9,7 @@
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>weixin-middleware</artifactId>
-    <packaging>war</packaging>
+    <packaging>jar</packaging>
 
     <properties>
         <swagger2.version>2.7.0</swagger2.version>
@@ -122,7 +122,6 @@
                 <dependency>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-starter-tomcat</artifactId>
-                    <scope>provided</scope>
                 </dependency>
             </dependencies>
             <properties>

+ 2 - 2
weixin-middleware/src/main/java/com/jpsoft/weixin/callback/EventCallback.java

@@ -32,7 +32,7 @@ public class EventCallback {
 //        this.message = message;
     }
 
-    public boolean process(String fromUserName,String toUserName,String eventKey){
+    public boolean process(String openId,String eventKey){
         boolean result = false;
 
         try {
@@ -46,7 +46,7 @@ public class EventCallback {
 
             List<NameValuePair> list = new ArrayList<NameValuePair>();
             list.add(new BasicNameValuePair("eventKey", eventKey));
-            list.add(new BasicNameValuePair("openId", toUserName));
+            list.add(new BasicNameValuePair("openId", openId));
 
             UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
             httpPost.setEntity(entity);

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

+ 1 - 0
weixin-middleware/src/main/java/com/jpsoft/weixin/config/WeixinConfig.java

@@ -12,4 +12,5 @@ public class WeixinConfig {
     private String tokenUrl;
     private String createQrCodeUrl;
     private String showQrCodeUrl;
+    private String contentType;
 }

+ 42 - 8
weixin-middleware/src/main/java/com/jpsoft/weixin/controller/WeixinController.java

@@ -2,7 +2,10 @@ package com.jpsoft.weixin.controller;
 
 import cn.hutool.core.date.DateTime;
 import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.itextpdf.text.io.StreamUtil;
 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;
@@ -26,14 +29,18 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.ValueOperations;
 import org.springframework.stereotype.Controller;
+import org.springframework.util.StreamUtils;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.net.URLEncoder;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 @Api(description = "微信中控")
 @Controller
@@ -45,6 +52,9 @@ public class WeixinController {
     @Autowired
     private PICCEntScanConfig piccEntScanConfig;
 
+    @Autowired
+    private PICCAdminScanConfig piccAdminScanConfig;
+
     @Autowired
     private ValueOperations<String,Object> valueOperations;
 
@@ -67,7 +77,7 @@ public class WeixinController {
             return echostr;
         }
         else{
-            return null;
+            return "index";
         }
     }
 
@@ -128,18 +138,30 @@ public class WeixinController {
     @PostMapping("/")
     public void processEvent(HttpServletRequest request, HttpServletResponse response){
         try{
-            Map<String,Object> dataMap = WeixinUtil.xmlToMap(request.getInputStream());
+            log.warn("收到post请求");
+
+            JSONObject requestJson = null;
+
+            if("json".equals(weixinConfig.getContentType())){
+                String jsonStr = new BufferedReader(new InputStreamReader(request.getInputStream()))
+                        .lines().parallel().collect(Collectors.joining(System.lineSeparator()));
+
+                requestJson = new JSONObject(jsonStr);
+            }
+            else {
+                requestJson = WeixinUtil.xmlToJson(request.getInputStream());
+            }
 
             //{Ticket=gQEH8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyckZDekV1RHg5SFAxczNwYjF1MWIAAgTX10teAwQsAQAA, CreateTime=1582028776, EventKey=1457, Event=SCAN, ToUserName=gh_b6e865f48dea, FromUserName=op6Frsy4xuXYGqjaJ12Xv5Q-9NtU, MsgType=event}
-            log.warn(dataMap.toString());
+            log.warn(requestJson.toString());
 
             response.setContentType("UTF-8");
             response.setContentType("text/html; charset=UTF-8");
             response.setCharacterEncoding("UTF-8");
 
-            String eventKey = (String)dataMap.get("EventKey");
-            String toUserName = (String)dataMap.get("ToUserName");
-            String fromUserName = (String)dataMap.get("FromUserName");
+            String eventKey = requestJson.getStr("EventKey");
+            String toUserName = requestJson.getStr("ToUserName");
+            String fromUserName = requestJson.getStr("FromUserName");
 
             List<EventCallback> callbackList = registerCallbackList();
 
@@ -147,8 +169,12 @@ public class WeixinController {
 
             //开发者在5秒内未回复任何内容
             for (EventCallback callback: callbackList) {
-                if (eventKey.startsWith(callback.getCode())){
-                    callback.process(fromUserName,toUserName,eventKey);
+                if (StringUtils.isNotEmpty(eventKey) && eventKey.startsWith(callback.getCode())){
+                    //fromUserName 接收方帐号(收到的OpenID)
+                    //toUserName 开发者微信号
+                    callback.process(fromUserName,eventKey);
+
+                    //回复消息时,将两则颠倒
                     WeixinUtil.replyTextMessage(response,toUserName,fromUserName,callback.getMessage());
 
                     processed = true;
@@ -163,6 +189,12 @@ public class WeixinController {
         }
         catch (Exception ex){
             log.error(ex.getMessage(),ex);
+
+            try {
+                response.getWriter().print("fail");
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
         }
     }
 
@@ -171,6 +203,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;
     }

+ 35 - 0
weixin-middleware/src/main/java/com/jpsoft/weixin/util/WeixinUtil.java

@@ -1,10 +1,12 @@
 package com.jpsoft.weixin.util;
 
 import cn.hutool.core.date.DateTime;
+import cn.hutool.json.JSONObject;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
+import javax.servlet.ServletInputStream;
 import javax.servlet.http.HttpServletResponse;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
@@ -106,4 +108,37 @@ public class WeixinUtil {
             e.printStackTrace();
         }
     }
+
+    public static JSONObject xmlToJson(ServletInputStream inputStream) throws Exception {
+        JSONObject jsonObject = new JSONObject();
+
+        // 创建sax解析工厂
+        SAXParserFactory factory = SAXParserFactory.newInstance();
+        // 创建sax转换工具
+        SAXParser saxParser = factory.newSAXParser();
+
+        saxParser.parse(inputStream,new DefaultHandler(){
+            private String tagName;
+
+            @Override
+            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+                tagName = qName;
+            }
+
+            @Override
+            public void endElement(String uri, String localName, String qName) throws SAXException {
+                tagName = null;
+            }
+
+            @Override
+            public void characters(char[] ch, int start, int length) throws SAXException {
+                if(tagName!=null){
+                    String content = new String(ch,start,length);
+                    jsonObject.put(tagName,content);
+                }
+            }
+        });
+
+        return jsonObject;
+    }
 }

+ 9 - 23
weixin-middleware/src/main/resources/application-dev.yml

@@ -3,27 +3,6 @@ spring:
     add-properties: false
     restart:
       enabled: true
-  redis:
-    # Redis数据库索引(默认为0)
-    database: 1
-    # Redis服务器地址
-    host: 127.0.0.1
-    # Redis服务器连接端口
-    port: 6379
-    # Redis服务器连接密码(默认为空)
-    password:
-    # 连接池最大连接数(使用负值表示没有限制)
-    pool:
-      max-active: 8
-      # 连接池最大阻塞等待时间(使用负值表示没有限制)
-      max-wait: -1
-      # 连接池中的最大空闲连接
-      max-idle: 8
-      # 连接池中的最小空闲连接
-      min-idle: 0
-      # 连接超时时间(毫秒)
-      timeout: 0
-
 logger:
   level: WARN
   dir: D:\\Logs\\picc\\weixin-middleware\\
@@ -34,12 +13,19 @@ weixin:
   refreshOAuth2TokenUrl: "https://api.weixin.qq.com/sns/oauth2/refresh_token"
   createQrCodeUrl: "https://api.weixin.qq.com/cgi-bin/qrcode/create"
   showQrCodeUrl: "https://mp.weixin.qq.com/cgi-bin/showqrcode"
+  contentType: xml
 
 qrcode:
   picc:
     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"

+ 32 - 0
weixin-middleware/src/main/resources/application-production.yml

@@ -0,0 +1,32 @@
+spring:
+  devtools:
+    add-properties: false
+    restart:
+      enabled: true
+
+logger:
+  level: WARN
+  dir: /opt/logs/weixin-middleware/
+
+
+weixin:
+  token: weixin
+  tokenUrl: "https://api.weixin.qq.com/cgi-bin/token"
+  refreshOAuth2TokenUrl: "https://api.weixin.qq.com/sns/oauth2/refresh_token"
+  createQrCodeUrl: "https://api.weixin.qq.com/cgi-bin/qrcode/create"
+  showQrCodeUrl: "https://mp.weixin.qq.com/cgi-bin/showqrcode"
+
+qrcode:
+  picc:
+    enterprise:
+      scan:
+        loginCode: "5000"
+        loginCallbackUrl: "http://gyxm.jing-zhou.gov.cn/picc-enterprise-test/qrcode/login/scan"
+        bindingCode: "5001"
+        bindingCallbackUrl: "http://gyxm.jing-zhou.gov.cn/picc-enterprise-test/qrcode/binding/scan"
+    admin:
+      scan:
+        loginCode: "6000"
+        loginCallbackUrl: "http://gyxm.jing-zhou.gov.cn/picc-admin-server/pub/qrcode/login/scan"
+        bindingCode: "6001"
+        bindingCallbackUrl: "http://gyxm.jing-zhou.gov.cn/picc-admin-server/pub/qrcode/binding/scan"

+ 24 - 1
weixin-middleware/src/main/resources/application-test.yml

@@ -6,4 +6,27 @@ spring:
 
 logger:
   level: WARN
-  dir: C:\\Logs\\picc\\weixin-middleware\\
+  dir: C:\\picc\\logs\\weixin-middleware\\
+  contentType: xml
+
+weixin:
+  token: weixin
+  tokenUrl: "https://api.weixin.qq.com/cgi-bin/token"
+  refreshOAuth2TokenUrl: "https://api.weixin.qq.com/sns/oauth2/refresh_token"
+  createQrCodeUrl: "https://api.weixin.qq.com/cgi-bin/qrcode/create"
+  showQrCodeUrl: "https://mp.weixin.qq.com/cgi-bin/showqrcode"
+
+qrcode:
+  picc:
+    enterprise:
+      scan:
+        loginCode: "5000"
+        loginCallbackUrl: "http://gyxm.jing-zhou.gov.cn/picc-enterprise-test/qrcode/login/scan"
+        bindingCode: "5001"
+        bindingCallbackUrl: "http://gyxm.jing-zhou.gov.cn/picc-enterprise-test/qrcode/binding/scan"
+    admin:
+      scan:
+        loginCode: "6000"
+        loginCallbackUrl: "http://gyxm.jing-zhou.gov.cn/picc-admin-server/pub/qrcode/login/scan"
+        bindingCode: "6001"
+        bindingCallbackUrl: "http://gyxm.jing-zhou.gov.cn/picc-admin-server/pub/qrcode/binding/scan"

+ 21 - 1
weixin-middleware/src/main/resources/application.yml

@@ -12,4 +12,24 @@ spring:
     restart:
       enabled: true
   profiles:
-    active: @active.profile@
+    active: @active.profile@
+  redis:
+    # Redis数据库索引(默认为0)
+    database: 1
+    # Redis服务器地址
+    host: 127.0.0.1
+    # Redis服务器连接端口
+    port: 6379
+    # Redis服务器连接密码(默认为空)
+    password:
+    # 连接池最大连接数(使用负值表示没有限制)
+    pool:
+      max-active: 8
+      # 连接池最大阻塞等待时间(使用负值表示没有限制)
+      max-wait: -1
+      # 连接池中的最大空闲连接
+      max-idle: 8
+      # 连接池中的最小空闲连接
+      min-idle: 0
+      # 连接超时时间(毫秒)
+      timeout: 0