소스 검색

2023年1月6 18:17

wangzhuo 3 년 전
부모
커밋
71d23ebad2
19개의 변경된 파일746개의 추가작업 그리고 100개의 파일을 삭제
  1. 6 0
      blade-auth/pom.xml
  2. 9 0
      blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailsServiceImpl.java
  3. 2 0
      blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java
  4. 36 0
      blade-service-api/blade-client-api/src/main/java/org/springblade/client/entity/WxUnionIdOpenId.java
  5. 45 0
      blade-service-api/blade-client-api/src/main/java/org/springblade/client/feign/IWxUnionIdOpenIdClient.java
  6. 5 0
      blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/entity/User.java
  7. 102 0
      blade-service/blade-client/src/main/java/org/springblade/client/wechat/Util/WXPayXmlUtil.java
  8. 97 0
      blade-service/blade-client/src/main/java/org/springblade/client/wechat/Util/WxUtil.java
  9. 2 1
      blade-service/blade-client/src/main/java/org/springblade/client/wechat/controller/WechatController.java
  10. 83 0
      blade-service/blade-client/src/main/java/org/springblade/client/wechat/controller/WxUnionIdOpenIdController.java
  11. 4 91
      blade-service/blade-client/src/main/java/org/springblade/client/wechat/feign/WechatClient.java
  12. 36 0
      blade-service/blade-client/src/main/java/org/springblade/client/wechat/feign/WxUnionIdOpenIdClient.java
  13. 14 0
      blade-service/blade-client/src/main/java/org/springblade/client/wechat/mapper/WxUnionIdOpenIdMapper.java
  14. 12 0
      blade-service/blade-client/src/main/java/org/springblade/client/wechat/mapper/WxUnionIdOpenIdMapper.xml
  15. 28 0
      blade-service/blade-client/src/main/java/org/springblade/client/wechat/service/IWxUnionIdOpenIdService.java
  16. 31 0
      blade-service/blade-client/src/main/java/org/springblade/client/wechat/service/impl/WxUnionIdOpenIdServiceImpl.java
  17. 2 8
      blade-service/blade-purchase-sales/src/main/java/org/springblade/purchase/sales/service/impl/BidingServiceImpl.java
  18. 204 0
      blade-service/blade-school/src/main/java/org/springblade/school/controller/WxTest.java
  19. 28 0
      blade-service/blade-school/src/main/java/org/springblade/school/util/WXPayXmlUtil.java

+ 6 - 0
blade-auth/pom.xml

@@ -85,6 +85,12 @@
             <groupId>com.github.whvcse</groupId>
             <artifactId>easy-captcha</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-client-api</artifactId>
+            <version>2.8.2.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
         <!-- 链路追踪、服务监控 -->
         <!--<dependency>
             <groupId>org.springblade</groupId>

+ 9 - 0
blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailsServiceImpl.java

@@ -22,6 +22,8 @@ import lombok.SneakyThrows;
 import org.apache.commons.lang.StringUtils;
 import org.springblade.auth.constant.AuthConstant;
 import org.springblade.auth.utils.TokenUtil;
+import org.springblade.client.entity.WxUnionIdOpenId;
+import org.springblade.client.feign.IWxUnionIdOpenIdClient;
 import org.springblade.common.cache.CacheNames;
 import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.tool.api.R;
@@ -57,6 +59,7 @@ public class BladeUserDetailsServiceImpl implements UserDetailsService {
 	private final ISysClient sysClient;
 
 	private final BladeRedis bladeRedis;
+	private final IWxUnionIdOpenIdClient wxUnionIdOpenIdClient;
 
 	@Override
 	@SneakyThrows
@@ -99,6 +102,12 @@ public class BladeUserDetailsServiceImpl implements UserDetailsService {
 				}
 				tenant = sysClient.getTenant(user.getTenantId());
 			}
+
+			//根据unionId查询微信信息表是否存在该unionId
+			WxUnionIdOpenId wxUnionIdOpenId = wxUnionIdOpenIdClient.getWxUnionId(unionId);
+			if (ObjectUtil.isNotEmpty(wxUnionIdOpenId)){//存在 更新公众号openid
+				user.setOaOpenId(wxUnionIdOpenId.getOpenId());
+			}
 			user.setOpenId(openId);
 			user.setUnionId(unionId);
 			userClient.updateOpenId(user);

+ 2 - 0
blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java

@@ -55,6 +55,8 @@ public class AuthProvider {
 		DEFAULT_SKIP_URL.add("/manager/check-upload");
 		DEFAULT_SKIP_URL.add("/error/**");
 		DEFAULT_SKIP_URL.add("/assets/**");
+		DEFAULT_SKIP_URL.add("/wechatTest/**");
+		DEFAULT_SKIP_URL.add("/wxOfficial/**");
 	}
 
 	/**

+ 36 - 0
blade-service-api/blade-client-api/src/main/java/org/springblade/client/entity/WxUnionIdOpenId.java

@@ -0,0 +1,36 @@
+package org.springblade.client.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 公众号信息表实体类
+ *
+ * @author BladeX
+ */
+@Data
+@TableName("wx_unionid_openid")
+@ApiModel(value = "WxUnionIdOpenId对象", description = "公众号信息表")
+public class WxUnionIdOpenId {
+
+	/**
+	 * 主键
+	 */
+	@ApiModelProperty(value = "主键")
+	private Long id;
+
+	/**
+	 * 公众号openId
+	 */
+	@ApiModelProperty(value = "公众号openId")
+	private String openId;
+
+	/**
+	 * unionId唯一标识
+	 */
+	@ApiModelProperty(value = "unionId")
+	private String unionId;
+
+}

+ 45 - 0
blade-service-api/blade-client-api/src/main/java/org/springblade/client/feign/IWxUnionIdOpenIdClient.java

@@ -0,0 +1,45 @@
+package org.springblade.client.feign;
+
+import org.springblade.client.entity.WxUnionIdOpenId;
+import org.springblade.common.constant.LauncherConstant;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+@FeignClient(
+	value = LauncherConstant.APPLICATION_CLIENT_NAME
+)
+/**
+ * 公众号信息对外访问API
+ */
+public interface IWxUnionIdOpenIdClient {
+
+	String API_PREFIX = "/client";
+	String GET_WX_UNION_ID = "/getWxUnionId";
+	String INSERT_WX_UO = "/insertWxUO";
+	String UPDATE_WX_UO = "/updateWxUO";
+
+	/**
+	 * 根据unionId查询
+	 *
+	 * @param unionId
+	 */
+	@GetMapping(GET_WX_UNION_ID)
+	WxUnionIdOpenId getWxUnionId(@RequestParam(value = "unionId") String unionId);
+
+	/**
+	 * 新增
+	 *
+	 * @param wxUnionIdOpenId
+	 */
+	@PostMapping(INSERT_WX_UO)
+	int insertWxUO(@RequestBody WxUnionIdOpenId wxUnionIdOpenId);
+
+	/**
+	 * 更新
+	 *
+	 * @param wxUnionIdOpenId
+	 */
+	@PostMapping(UPDATE_WX_UO)
+	boolean updateWxUO(@RequestBody WxUnionIdOpenId wxUnionIdOpenId);
+
+}

+ 5 - 0
blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/entity/User.java

@@ -122,4 +122,9 @@ public class User extends TenantEntity {
 	 * 发送次数
 	 */
 	private Integer timesSending;
+
+	/**
+	 * 公众号openid
+	 */
+	private String oaOpenId;
 }

+ 102 - 0
blade-service/blade-client/src/main/java/org/springblade/client/wechat/Util/WXPayXmlUtil.java

@@ -0,0 +1,102 @@
+package org.springblade.client.wechat.Util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+public class WXPayXmlUtil {
+
+	public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
+		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+		documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+		documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+		documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+		documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+		documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+		documentBuilderFactory.setXIncludeAware(false);
+		documentBuilderFactory.setExpandEntityReferences(false);
+
+		return documentBuilderFactory.newDocumentBuilder();
+	}
+
+	public static Document newDocument() throws ParserConfigurationException {
+		return newDocumentBuilder().newDocument();
+	}
+
+	public static Map<String, String> analysis(HttpServletRequest request) {
+		try {
+			BufferedReader reader = null;
+			String line = "";
+			String xmlString = null;
+			reader = request.getReader();
+			StringBuffer inputString = new StringBuffer();
+
+			while ((line = reader.readLine()) != null) {
+				inputString.append(line);
+			}
+			xmlString = inputString.toString();
+			Map<String, String> dataMap = xmlToMap(xmlString);
+			return dataMap;
+		} catch (Exception e) {
+			return null;
+		}
+
+	}
+
+	/**
+	 * XML格式字符串转换为Map
+	 *
+	 * @param strXML XML字符串
+	 * @return XML数据转换后的Map
+	 * @throws Exception
+	 */
+	public static Map<String, String> xmlToMap(String strXML) throws Exception {
+		try {
+			Map<String, String> data = new HashMap<String, String>();
+			DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder();
+			InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
+			org.w3c.dom.Document doc = documentBuilder.parse(stream);
+			doc.getDocumentElement().normalize();
+			NodeList nodeList = doc.getDocumentElement().getChildNodes();
+			for (int idx = 0; idx < nodeList.getLength(); ++idx) {
+				Node node = nodeList.item(idx);
+				if (node.getNodeType() == Node.ELEMENT_NODE) {
+					org.w3c.dom.Element element = (org.w3c.dom.Element) node;
+					data.put(element.getNodeName(), element.getTextContent());
+				}
+			}
+			try {
+				stream.close();
+			} catch (Exception ex) {
+				// do nothing
+			}
+			return data;
+		} catch (Exception ex) {
+			getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
+			throw ex;
+		}
+
+	}
+
+	/**
+	 * 日志
+	 * @return
+	 */
+	public static Logger getLogger() {
+		Logger logger = LoggerFactory.getLogger("wxpay java sdk");
+		return logger;
+	}
+}

+ 97 - 0
blade-service/blade-client/src/main/java/org/springblade/client/wechat/Util/WxUtil.java

@@ -0,0 +1,97 @@
+package org.springblade.client.wechat.Util;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.core.tool.utils.ObjectUtil;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+public class WxUtil {
+
+	/**
+	 * 获得公众号token
+	 */
+	public static Map<String, String> getToken(String appId, String appSecret) {
+
+		Map<String,String> tokenMap = new HashMap<>();
+		String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;
+		try {
+			String response = HttpUtil.get(requestUrl);
+			JSONObject jsonObject = JSONObject.parseObject(response);
+			if (ObjectUtil.isEmpty(jsonObject.get("errcode"))){
+				String accessToken = String.valueOf(jsonObject.get("access_token"));
+				if (ObjectUtil.isEmpty(accessToken)){
+					throw new RuntimeException("获取token出现异常");
+				}else {
+					tokenMap.put("accessToken", accessToken);
+				}
+			}else if (jsonObject.getString("errcode").equals("-1")) {
+				throw new RuntimeException("系统繁忙,此时请开发者稍候再试");
+			} else {
+				throw new RuntimeException("不合法的telCode(telCode不存在、已过期或者使用过)");
+			}
+
+		} catch (Exception e) {
+			log.info("获取token出现异常");
+			e.printStackTrace();
+		}
+
+		return tokenMap;
+	}
+
+	/**
+	 * 获得用户列表
+	 */
+	public static Map<String, Object> getUserOpenId(String accessToken){
+		Map<String, Object> openIdMap = new HashMap<>();
+		String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/get?access_token="+accessToken;
+		try {
+			String response = HttpUtil.get(requestUrl);
+			JSONObject jsonObject = JSONObject.parseObject(response);
+			if (ObjectUtil.isEmpty(jsonObject.get("errcode"))){
+				JSONObject data = jsonObject.getJSONObject("data");
+				if (ObjectUtil.isNotEmpty(data.get("openid"))){
+					openIdMap.put("openIds",data.getJSONArray("openid"));
+				}
+			}else {
+				throw new RuntimeException("用户获取失败"+jsonObject.get("errmsg"));
+			}
+
+		} catch (Exception e) {
+			log.info("获取用户openid出现异常");
+			e.printStackTrace();
+		}
+		return openIdMap;
+	}
+
+	/**
+	 * 获得用户信息
+	 */
+	public static Map<String, String > getUserInfo(String accessToken, String openId){
+		Map<String,String> userMap = new HashMap<>();
+		String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+accessToken+"&openid="+openId+"&lang=zh_CN";
+		try {
+			String response = HttpUtil.get(requestUrl);
+			JSONObject jsonObject = JSONObject.parseObject(response);
+			if (ObjectUtil.isEmpty(jsonObject.get("errcode"))){
+				String unionid = String.valueOf(jsonObject.get("unionid"));
+				if (ObjectUtil.isEmpty(unionid)){
+					throw new RuntimeException("获取unionid出现异常");
+				}else {
+					userMap.put("openid", openId);
+					userMap.put("unionid", unionid);
+				}
+			}else {
+				throw new RuntimeException("用户获取失败"+jsonObject.get("errmsg"));
+			}
+
+		} catch (Exception e) {
+			log.info("获取unionid出现异常");
+			e.printStackTrace();
+		}
+
+		return userMap;
+	}
+}

+ 2 - 1
blade-service/blade-client/src/main/java/org/springblade/client/wechat/controller/WechatController.java

@@ -39,7 +39,7 @@ public class WechatController {
 
 	// 登录凭证校验地址
 	public final static String GetPageAccessTokenUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=CODE&grant_type=authorization_code";
-	// 小程序的appId以及appSecret
+	// 诺晶小程序的appId以及appSecret
 	private static final String appId = "wx0a0feca24b695636";
 	private static final String appSecret = "b3efb530f9ef97626e2ec31fc7a3af56";
 //	private static final String appSecret = "d78d26f94e756c89f2623cc2e3050237";
@@ -181,4 +181,5 @@ public class WechatController {
 
 		return R.data(map);
 	}
+
 }

+ 83 - 0
blade-service/blade-client/src/main/java/org/springblade/client/wechat/controller/WxUnionIdOpenIdController.java

@@ -0,0 +1,83 @@
+package org.springblade.client.wechat.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springblade.client.entity.WxUnionIdOpenId;
+import org.springblade.client.wechat.Util.HttpUtil;
+import org.springblade.client.wechat.Util.WXPayXmlUtil;
+import org.springblade.client.wechat.Util.WxUtil;
+import org.springblade.client.wechat.service.IWxUnionIdOpenIdService;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.DocumentBuilder;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 与微信公众号产生交换的控制器
+ *
+ * @author BladeX
+ */
+@Slf4j
+@RestController
+@RequestMapping("/wxOfficial")
+@AllArgsConstructor
+public class WxUnionIdOpenIdController {
+
+	private final IWxUnionIdOpenIdService wxUnionIdOpenIdService;
+
+	//公众号的appId以及secret
+	private static final String appId = "wxf077390a6ec17f23";
+	private static final String appSecret = "50e84930675a0c06057d45a6d64ec548";
+
+	@PostMapping("/scanCodeCallback")
+	public void scanCodeCallback(HttpServletRequest request, HttpServletResponse response){
+		log.info("======关注回调======");
+
+		Map<String, String> dataMap = WXPayXmlUtil.analysis(request);
+		log.info("返回数据======》" + dataMap.toString());
+		String openId = dataMap.get("FromUserName");//openId
+		String Event = dataMap.get("Event");//关注或取消关注
+
+		if ("subscribe".equals(Event)) {//关注
+
+			//获得公众号token
+			Map<String,String> tokenMap = WxUtil.getToken(appId, appSecret);
+			log.info("token======>"+tokenMap.get("accessToken"));
+
+			//根据公众号openid获得unionId
+			Map<String, String > userMap = WxUtil.getUserInfo(tokenMap.get("accessToken"),openId);
+			String unionId = userMap.get("unionid");
+			log.info("unionId======>"+userMap.get("unionid"));
+
+			if (ObjectUtil.isNotEmpty(unionId)){
+				//根据unionId查询数据库是否存在
+				WxUnionIdOpenId wxUnionIdOpenId = wxUnionIdOpenIdService.getWxUnionId(userMap.get("unionid"));
+				if (ObjectUtil.isEmpty(wxUnionIdOpenId)){//不存在 新增
+					wxUnionIdOpenId.setOpenId(openId);
+					wxUnionIdOpenId.setUnionId(unionId);
+					wxUnionIdOpenIdService.insert(wxUnionIdOpenId);
+				}else {//存在 则更新
+					wxUnionIdOpenId.setOpenId(openId);
+					wxUnionIdOpenIdService.updateById(wxUnionIdOpenId);
+				}
+			}
+
+		}
+
+	}
+
+}

+ 4 - 91
blade-service/blade-client/src/main/java/org/springblade/client/wechat/feign/WechatClient.java

@@ -1,6 +1,5 @@
 package org.springblade.client.wechat.feign;
 
-import com.alibaba.fastjson.JSONObject;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
@@ -9,9 +8,8 @@ import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
 import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
 import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
 import org.springblade.client.feign.IWechatClient;
-import org.springblade.client.wechat.Util.HttpUtil;
+import org.springblade.client.wechat.Util.WxUtil;
 import org.springblade.core.tenant.annotation.NonDS;
-import org.springblade.core.tool.utils.ObjectUtil;
 import org.springframework.web.bind.annotation.RestController;
 import springfox.documentation.annotations.ApiIgnore;
 
@@ -40,16 +38,16 @@ public class WechatClient implements IWechatClient {
 	@Override
 	public List<Map<String, String>> getAllUnionIds() {
 		//获得token
-		Map<String,String> tokenMap = this.getToken();
+		Map<String,String> tokenMap = WxUtil.getToken(appId, appSecret);
 		//获得用户列表
-		Map<String, Object> openIdMap = this.getUserOpenId(tokenMap.get("accessToken"));
+		Map<String, Object> openIdMap = WxUtil.getUserOpenId(tokenMap.get("accessToken"));
 		List<String> openIdsList = (List<String>) openIdMap.get("openIds");
 		List<Map<String, String>> unionIdMapList = new ArrayList<>();
 		//获得用户unionId
 		for (int i = 0; i < openIdsList.size(); i++ ){
 			String openid = openIdsList.get(i);
 			//获得unionId
-			Map<String, String > userMap = this.getUserInfo(tokenMap.get("accessToken"),openid);
+			Map<String, String > userMap = WxUtil.getUserInfo(tokenMap.get("accessToken"),openid);
 			unionIdMapList.add(userMap);
 		}
 		return unionIdMapList;
@@ -139,89 +137,4 @@ public class WechatClient implements IWechatClient {
 		return null;
 	}
 
-	/**
-	 * 获得公众号token
-	 */
-	public Map<String, String> getToken() {
-
-		Map<String,String> tokenMap = new HashMap<>();
-		String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;
-		try {
-			String response = HttpUtil.get(requestUrl);
-			JSONObject jsonObject = JSONObject.parseObject(response);
-			if (ObjectUtil.isEmpty(jsonObject.get("errcode"))){
-				String accessToken = String.valueOf(jsonObject.get("access_token"));
-				if (ObjectUtil.isEmpty(accessToken)){
-					throw new RuntimeException("获取token出现异常");
-				}else {
-					tokenMap.put("accessToken", accessToken);
-				}
-			}else if (jsonObject.getString("errcode").equals("-1")) {
-				throw new RuntimeException("系统繁忙,此时请开发者稍候再试");
-			} else {
-				throw new RuntimeException("不合法的telCode(telCode不存在、已过期或者使用过)");
-			}
-
-		} catch (Exception e) {
-			log.info("获取token出现异常");
-			e.printStackTrace();
-		}
-
-		return tokenMap;
-	}
-
-	/**
-	 * 获得用户列表
-	 */
-	public Map<String, Object> getUserOpenId(String accessToken){
-		Map<String, Object> openIdMap = new HashMap<>();
-		String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/get?access_token="+accessToken;
-		try {
-			String response = HttpUtil.get(requestUrl);
-			JSONObject jsonObject = JSONObject.parseObject(response);
-			if (ObjectUtil.isEmpty(jsonObject.get("errcode"))){
-				JSONObject data = jsonObject.getJSONObject("data");
-				if (ObjectUtil.isNotEmpty(data.get("openid"))){
-					openIdMap.put("openIds",data.getJSONArray("openid"));
-				}
-			}else {
-				throw new RuntimeException("用户获取失败"+jsonObject.get("errmsg"));
-			}
-
-		} catch (Exception e) {
-			log.info("获取用户openid出现异常");
-			e.printStackTrace();
-		}
-		return openIdMap;
-	}
-
-	/**
-	 * 获得用户信息
-	 */
-	public Map<String, String > getUserInfo(String accessToken,String openId){
-		Map<String,String> userMap = new HashMap<>();
-		String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+accessToken+"&openid="+openId+"&lang=zh_CN";
-		try {
-			String response = HttpUtil.get(requestUrl);
-			JSONObject jsonObject = JSONObject.parseObject(response);
-			if (ObjectUtil.isEmpty(jsonObject.get("errcode"))){
-				String unionid = String.valueOf(jsonObject.get("unionid"));
-				if (ObjectUtil.isEmpty(unionid)){
-					throw new RuntimeException("获取unionid出现异常");
-				}else {
-					userMap.put("openid", openId);
-					userMap.put("unionid", unionid);
-				}
-			}else {
-				throw new RuntimeException("用户获取失败"+jsonObject.get("errmsg"));
-			}
-
-		} catch (Exception e) {
-			log.info("获取unionid出现异常");
-			e.printStackTrace();
-		}
-
-		return userMap;
-	}
-
 }

+ 36 - 0
blade-service/blade-client/src/main/java/org/springblade/client/wechat/feign/WxUnionIdOpenIdClient.java

@@ -0,0 +1,36 @@
+package org.springblade.client.wechat.feign;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.client.entity.WxUnionIdOpenId;
+import org.springblade.client.feign.IWxUnionIdOpenIdClient;
+import org.springblade.client.wechat.service.IWxUnionIdOpenIdService;
+import org.springblade.core.tenant.annotation.NonDS;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+@NonDS
+@ApiIgnore()
+@RestController
+@AllArgsConstructor
+@Slf4j
+public class WxUnionIdOpenIdClient implements IWxUnionIdOpenIdClient {
+
+	private final IWxUnionIdOpenIdService wxUnionIdOpenIdService;
+
+	@Override
+	public WxUnionIdOpenId getWxUnionId(String unionId) {
+		return wxUnionIdOpenIdService.getOne(new QueryWrapper<WxUnionIdOpenId>().eq("unionId", unionId));
+	}
+
+	@Override
+	public int insertWxUO(WxUnionIdOpenId wxUnionIdOpenId) {
+		return wxUnionIdOpenIdService.insert(wxUnionIdOpenId);
+	}
+
+	@Override
+	public boolean updateWxUO(WxUnionIdOpenId wxUnionIdOpenId) {
+		return wxUnionIdOpenIdService.updateById(wxUnionIdOpenId);
+	}
+}

+ 14 - 0
blade-service/blade-client/src/main/java/org/springblade/client/wechat/mapper/WxUnionIdOpenIdMapper.java

@@ -0,0 +1,14 @@
+package org.springblade.client.wechat.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.client.entity.WxUnionIdOpenId;
+
+/**
+ * 微信公众号信息表 Mapper 接口
+ *
+ * @author BladeX
+ */
+public interface WxUnionIdOpenIdMapper extends BaseMapper<WxUnionIdOpenId> {
+
+
+}

+ 12 - 0
blade-service/blade-client/src/main/java/org/springblade/client/wechat/mapper/WxUnionIdOpenIdMapper.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.client.wechat.mapper.WxUnionIdOpenIdMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="bidingItemsResultMap" type="org.springblade.client.entity.WxUnionIdOpenId">
+        <id column="id" property="id"/>
+        <result column="open_id" property="openId"/>
+        <result column="union_id" property="unionId"/>
+    </resultMap>
+
+</mapper>

+ 28 - 0
blade-service/blade-client/src/main/java/org/springblade/client/wechat/service/IWxUnionIdOpenIdService.java

@@ -0,0 +1,28 @@
+package org.springblade.client.wechat.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.client.entity.WxUnionIdOpenId;
+
+/**
+ * 微信信息 服务类
+ *
+ * @author BladeX
+ * @since 2023-09-07
+ */
+
+public interface IWxUnionIdOpenIdService extends IService<WxUnionIdOpenId> {
+
+	/**
+	 * 根据unionId查询
+	 *
+	 * @param unionId
+	 */
+	WxUnionIdOpenId getWxUnionId(String unionId);
+
+	/**
+	 * 添加信息
+	 * @param wxUnionIdOpenId
+	 * @return
+	 */
+	int insert(WxUnionIdOpenId wxUnionIdOpenId);
+}

+ 31 - 0
blade-service/blade-client/src/main/java/org/springblade/client/wechat/service/impl/WxUnionIdOpenIdServiceImpl.java

@@ -0,0 +1,31 @@
+package org.springblade.client.wechat.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.AllArgsConstructor;
+import org.springblade.client.entity.WxUnionIdOpenId;
+import org.springblade.client.wechat.mapper.WxUnionIdOpenIdMapper;
+import org.springblade.client.wechat.service.IWxUnionIdOpenIdService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 微信信息表 服务实现类
+ *
+ * @author BladeX
+ * @since 2023-01-06
+ */
+@Service
+@AllArgsConstructor
+public class WxUnionIdOpenIdServiceImpl extends ServiceImpl<WxUnionIdOpenIdMapper, WxUnionIdOpenId> implements IWxUnionIdOpenIdService {
+
+
+	@Override
+	public WxUnionIdOpenId getWxUnionId(String unionId) {
+		return baseMapper.selectOne(new QueryWrapper<WxUnionIdOpenId>().eq("unionId", unionId));
+	}
+
+	@Override
+	public int insert(WxUnionIdOpenId wxUnionIdOpenId) {
+		return baseMapper.insert(wxUnionIdOpenId);
+	}
+}

+ 2 - 8
blade-service/blade-purchase-sales/src/main/java/org/springblade/purchase/sales/service/impl/BidingServiceImpl.java

@@ -312,8 +312,6 @@ public class BidingServiceImpl extends ServiceImpl<BidingMapper, Biding> impleme
 		//箱型箱量
 		String boxTypeQuantity = salesBiding.getBoxTypeQuantity();
 
-		//获得所有关注用户
-		List<Map<String, String >> unionIdMapList = wechatClient.getAllUnionIds();
 		//根据代理客户的客户联系人进行消息推送
 		//获得所有代理客户
 		List<BidingAgent> agentList = bidingAgentService.getBidingAgent(salesBiding);;
@@ -328,12 +326,8 @@ public class BidingServiceImpl extends ServiceImpl<BidingMapper, Biding> impleme
 						//获得用户信息
 						R<User> user = userClient.userInfoById(corpsAttn.getUserId());
 						if (ObjectUtil.isNotEmpty(user.getData())){
-							if (ObjectUtil.isNotEmpty(user.getData().getUnionId())){
-								unionIdMapList.forEach(union -> {
-									if (union.get("unionid").equals(user.getData().getUnionId())){
-										wechatClient.newsPush(union.get("openid"),salesBiding.getContractNo(), departureHarbor, objectiveHarbor, boxTypeQuantity, loadingTime);
-									}
-								});
+							if (ObjectUtil.isNotEmpty(user.getData().getOaOpenId())){
+								wechatClient.newsPush(user.getData().getOaOpenId(),salesBiding.getContractNo(), departureHarbor, objectiveHarbor, boxTypeQuantity, loadingTime);
 							}
 						}
 					});

+ 204 - 0
blade-service/blade-school/src/main/java/org/springblade/school/controller/WxTest.java

@@ -0,0 +1,204 @@
+package org.springblade.school.controller;
+
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springblade.client.entity.WxUnionIdOpenId;
+import org.springblade.client.feign.IWxUnionIdOpenIdClient;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.school.util.WXPayXmlUtil;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.DocumentBuilder;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.*;
+
+/**
+ * 与微信产生交换的控制器
+ *
+ * @author BladeX
+ */
+@Slf4j
+@RestController
+@RequestMapping("/wechatTest")
+@AllArgsConstructor
+public class WxTest {
+
+	private final IWxUnionIdOpenIdClient wxUnionIdOpenIdClient;
+
+	//公众号的appId以及secret
+	private static final String appId = "wxf077390a6ec17f23";
+	private static final String appSecret = "50e84930675a0c06057d45a6d64ec548";
+
+	@PostMapping("/scanCodeCallback")
+	public void scanCodeCallback(HttpServletRequest request, HttpServletResponse response){
+		log.info("======关注回调======");
+
+		Map<String, String> dataMap = analysis(request);
+		log.info("返回数据======》" + dataMap);
+		log.info("返回数据======》" + dataMap.toString());
+		String openId = dataMap.get("FromUserName");//openId
+		String Event = dataMap.get("Event");//关注或取消关注
+
+		if ("subscribe".equals(Event)) {//关注
+			//获得公众号token
+			Map<String,String> tokenMap = this.getToken();
+			log.info("token======>"+tokenMap.get("accessToken"));
+			//根据公众号openid获得unionId
+			Map<String, String > userMap = this.getUserInfo(tokenMap.get("accessToken"),openId);
+			String unionId = userMap.get("unionid");
+			log.info("unionId======>"+userMap.get("unionid"));
+
+			if (ObjectUtil.isNotEmpty(unionId)){
+				//根据unionId查询数据库是否存在
+				WxUnionIdOpenId wxUnionIdOpenId = wxUnionIdOpenIdClient.getWxUnionId(userMap.get("unionid"));
+				if (ObjectUtil.isEmpty(wxUnionIdOpenId)){//不存在 新增
+					wxUnionIdOpenId.setOpenId(openId);
+					wxUnionIdOpenId.setUnionId(unionId);
+					wxUnionIdOpenIdClient.insertWxUO(wxUnionIdOpenId);
+				}else {//存在 则更新
+					wxUnionIdOpenId.setOpenId(openId);
+					wxUnionIdOpenIdClient.updateWxUO(wxUnionIdOpenId);
+				}
+			}
+
+		}
+
+	}
+
+	/**
+	 * 获得公众号token
+	 */
+	public Map<String, String> getToken() {
+
+		Map<String,String> tokenMap = new HashMap<>();
+		String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;
+		try {
+			String response = HttpUtil.get(requestUrl);
+			JSONObject jsonObject = JSONObject.parseObject(response);
+			if (ObjectUtil.isEmpty(jsonObject.get("errcode"))){
+				String accessToken = String.valueOf(jsonObject.get("access_token"));
+				if (ObjectUtil.isEmpty(accessToken)){
+					throw new RuntimeException("获取token出现异常");
+				}else {
+					tokenMap.put("accessToken", accessToken);
+				}
+			}else if (jsonObject.getString("errcode").equals("-1")) {
+				throw new RuntimeException("系统繁忙,此时请开发者稍候再试");
+			} else {
+				throw new RuntimeException("不合法的telCode(telCode不存在、已过期或者使用过)");
+			}
+
+		} catch (Exception e) {
+			log.info("获取token出现异常");
+			e.printStackTrace();
+		}
+
+		return tokenMap;
+	}
+
+	/**
+	 * 获得用户信息
+	 */
+	public Map<String, String > getUserInfo(String accessToken,String openId){
+		Map<String,String> userMap = new HashMap<>();
+		String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+accessToken+"&openid="+openId+"&lang=zh_CN";
+		try {
+			String response = HttpUtil.get(requestUrl);
+			JSONObject jsonObject = JSONObject.parseObject(response);
+			if (ObjectUtil.isEmpty(jsonObject.get("errcode"))){
+				String unionid = String.valueOf(jsonObject.get("unionid"));
+				if (ObjectUtil.isEmpty(unionid)){
+					throw new RuntimeException("获取unionid出现异常");
+				}else {
+					userMap.put("openid", openId);
+					userMap.put("unionid", unionid);
+				}
+			}else {
+				throw new RuntimeException("用户获取失败"+jsonObject.get("errmsg"));
+			}
+
+		} catch (Exception e) {
+			log.info("获取unionid出现异常");
+			e.printStackTrace();
+		}
+
+		return userMap;
+	}
+
+	public Map<String, String> analysis(HttpServletRequest request) {
+		try {
+			BufferedReader reader = null;
+			String line = "";
+			String xmlString = null;
+			reader = request.getReader();
+			StringBuffer inputString = new StringBuffer();
+
+			while ((line = reader.readLine()) != null) {
+				inputString.append(line);
+			}
+			xmlString = inputString.toString();
+			Map<String, String> dataMap = xmlToMap(xmlString);
+			return dataMap;
+		} catch (Exception e) {
+			return null;
+		}
+
+	}
+
+	/**
+	 * XML格式字符串转换为Map
+	 *
+	 * @param strXML XML字符串
+	 * @return XML数据转换后的Map
+	 * @throws Exception
+	 */
+	public static Map<String, String> xmlToMap(String strXML) throws Exception {
+		try {
+			Map<String, String> data = new HashMap<String, String>();
+			DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder();
+			InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
+			org.w3c.dom.Document doc = documentBuilder.parse(stream);
+			doc.getDocumentElement().normalize();
+			NodeList nodeList = doc.getDocumentElement().getChildNodes();
+			for (int idx = 0; idx < nodeList.getLength(); ++idx) {
+				Node node = nodeList.item(idx);
+				if (node.getNodeType() == Node.ELEMENT_NODE) {
+					org.w3c.dom.Element element = (org.w3c.dom.Element) node;
+					data.put(element.getNodeName(), element.getTextContent());
+				}
+			}
+			try {
+				stream.close();
+			} catch (Exception ex) {
+				// do nothing
+			}
+			return data;
+		} catch (Exception ex) {
+			getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
+			throw ex;
+		}
+
+	}
+
+	/**
+	 * 日志
+	 * @return
+	 */
+	public static Logger getLogger() {
+		Logger logger = LoggerFactory.getLogger("wxpay java sdk");
+		return logger;
+	}
+
+}

+ 28 - 0
blade-service/blade-school/src/main/java/org/springblade/school/util/WXPayXmlUtil.java

@@ -0,0 +1,28 @@
+package org.springblade.school.util;
+
+import org.w3c.dom.Document;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+public class WXPayXmlUtil {
+
+	public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
+		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+		documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+		documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
+		documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+		documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+		documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+		documentBuilderFactory.setXIncludeAware(false);
+		documentBuilderFactory.setExpandEntityReferences(false);
+
+		return documentBuilderFactory.newDocumentBuilder();
+	}
+
+	public static Document newDocument() throws ParserConfigurationException {
+		return newDocumentBuilder().newDocument();
+	}
+}