package com.panzhihua.applets.api; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.panzhihua.applets.config.WxMaConfiguration; import com.panzhihua.common.constants.UserConstants; import com.panzhihua.common.model.vos.R; import com.panzhihua.common.utlis.HttpClientUtil; import com.panzhihua.common.utlis.StringUtils; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.TimeUnit; @Slf4j @RestController @RequestMapping("/official") public class WxOfficialApi { @Resource private StringRedisTemplate stringRedisTemplate; // 公众号appid private List appidList = new ArrayList() { { this.add("wx7c733ebbf6c55ecf"); this.add("wxc94f0cddf13577d5"); } }; // 公众号secret private List secretList = new ArrayList() { { this.add("500290552cbfdd1c1c18131c5807b6ae"); this.add("3418127405845701497a09f65678953f"); } }; /** * 微信公众号请求头设置 */ public static Map getWxHeaderMap() { Map map = new HashMap<>(new LinkedHashMap()); map.put("Accept", "text/html, application/xhtml+xml, image/jxr, */*"); map.put("Accept-Encoding", "gzip, deflate"); map.put("Accept-Language", "zh-Hans-CN, zh-Hans; q=0.8, en-US; q=0.5, en; q=0.3"); map.put("Host", "mp.weixin.qq.com"); map.put("If-Modified-Since", "Sat, 04 Jan 2020 12:23:43 GMT"); map.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"); return map; } /** * 根据文章链接抓取文章内容 * * @param url 文章链接 * @return 文章内容 */ public static String getActicle(String url) { // post发送的参数 Map map = new HashMap<>(); map.put("type", "news"); // news表示图文类型的素材,具体看API文档 map.put("offset", 0); map.put("count", 5); // 将map转换成json字符串 String paramBody = JSON.toJSONString(map); return HttpClientUtil.get(url, getWxHeaderMap(), paramBody); } /** * 获取token * * @param appid 公众号appid * @param secret 公众号secret * @return token */ private String getToken(String appid, String secret) throws IOException { // access_token接口https请求方式: GET // https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET String path = " https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential"; URL url = new URL(path + "&appid=" + appid + "&secret=" + secret); HttpURLConnection connection = (HttpURLConnection)url.openConnection(); connection.setRequestMethod("GET"); connection.connect(); InputStream in = connection.getInputStream(); byte[] b = new byte[100]; int len = -1; StringBuffer sb = new StringBuffer(); while ((len = in.read(b)) != -1) { sb.append(new String(b, 0, len)); } in.close(); return sb.toString(); } /** * 通过token获取公众号文章 * * @param token token * @return 获取的文章列表结果 */ private String getContentList(String token) throws IOException { String path = " https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=" + token; URL url = new URL(path); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); connection.setRequestProperty("content-type", "application/json;charset=utf-8"); connection.connect(); // post发送的参数 Map map = new HashMap<>(); map.put("type", "news"); // news表示图文类型的素材,具体看API文档 map.put("offset", 0); map.put("count", 5); // 将map转换成json字符串 String paramBody = JSON.toJSONString(map); // 这里用了Alibaba的fastjson OutputStream out = connection.getOutputStream(); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)); bw.write(paramBody); // 向流中写入参数字符串 bw.flush(); InputStream in = connection.getInputStream(); byte[] b = new byte[100]; int len = -1; StringBuffer sb = new StringBuffer(); while ((len = in.read(b)) != -1) { sb.append(new String(b, 0, len, StandardCharsets.UTF_8)); } in.close(); return sb.toString(); } @ApiOperation(value = "拉取公众号列表") @GetMapping(value = "/list/noToken", produces = "application/json;charset=utf-8") public R pageDiscuss() throws Exception { WxOfficialApi officialApi = new WxOfficialApi(); ValueOperations valueOperations = stringRedisTemplate.opsForValue(); List tokenList = new ArrayList<>(); if (!appidList.isEmpty()) { for (int i = 0; i < appidList.size(); i++) { String token = officialApi.getToken(appidList.get(i), secretList.get(i)); JSONObject tokenJson = JSON.parseObject(token); if (StringUtils.isNotEmpty(tokenJson)) { tokenList.add(tokenJson.getString("access_token")); if (StringUtils.isNotEmpty(token)) { tokenList.add(token); } } } } List resultList = new ArrayList<>(); Boolean newsListKey = stringRedisTemplate.hasKey(UserConstants.NEWS_LIST); if (newsListKey != null && newsListKey) { String json = valueOperations.get(UserConstants.NEWS_LIST); resultList = JSON.parseArray(json, JSONObject.class); return R.ok(resultList); } if (!tokenList.isEmpty()) { for (String token : tokenList) { try { String url = "https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=" + token; String result = getActicle(url); // log.info("通过token获取文章列表成功,返回结果:" + result); JSONObject resultJson = JSON.parseObject(result); if (resultJson != null) { List itemList = JSON.parseArray(resultJson.getString("item"), JSONObject.class); if (!itemList.isEmpty()) { for (JSONObject object : itemList) { String newsId = object.getString("media_id"); JSONObject contentJson = JSON.parseObject(object.getString("content")); List newsItemList = JSON.parseArray(contentJson.getString("news_item"), JSONObject.class); String newsUrl = newsItemList.get(0).getString("url"); newsItemList.get(0).put("news_id", newsId); contentJson.put("news_item", newsItemList); object.put("content", contentJson); valueOperations.set(UserConstants.NEWS_ID + newsId, newsUrl + "", 2, TimeUnit.DAYS); } } resultJson.put("item", itemList); } resultList.add(resultJson); } catch (Exception e) { log.error("通过token获取文章列表失败,错误原因:" + e.getMessage()); } valueOperations.set(UserConstants.NEWS_LIST, resultList.toString(), 12, TimeUnit.HOURS); } } return R.ok(resultList); } @ApiOperation(value = "获取公众号文章链接") @GetMapping(value = "/get/noToken") public R getDiscuss(@RequestParam("mediaId") String mediaId) { String key = UserConstants.NEWS_ID + mediaId; Boolean hasKey = stringRedisTemplate.hasKey(key); if (!hasKey) { return R.fail("未找到该文章的链接地址"); } ValueOperations valueOperations = stringRedisTemplate.opsForValue(); String url = valueOperations.get(key); return R.ok(url); } }