puhanshu
2022-08-16 43f0578e80af82ecae6c61b51bd0539c6b960603
springcloud_k8s_panzhihuazhihuishequ/applets/src/main/java/com/panzhihua/applets/api/WxOfficialApi.java
@@ -1,130 +1,231 @@
//package com.panzhihua.applets.api;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import com.panzhihua.common.model.vos.R;
//import com.panzhihua.common.utlis.StringUtils;
//import io.swagger.annotations.ApiOperation;
//import lombok.extern.slf4j.Slf4j;
//import org.checkerframework.checker.units.qual.A;
//import org.springframework.web.bind.annotation.*;
//
//import java.io.*;
//import java.net.HttpURLConnection;
//import java.net.MalformedURLException;
//import java.net.ProtocolException;
//import java.net.URL;
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
//@Slf4j
//@RestController
//@RequestMapping("/official")
//public class WxOfficialApi {
//
//    //公众号appid
//    private List<String> appidList = new ArrayList<String>(){{this.add("wx7c733ebbf6c55ecf");this.add("wxc94f0cddf13577d5");}};
//    //公众号secret
//    private List<String> secretList = new ArrayList<String>(){{this.add("500290552cbfdd1c1c18131c5807b6ae");this.add("3418127405845701497a09f65678953f");}};
//
//    /**
//     * 获取token
//     * @param appid     公众号appid
//     * @param secret    公众号secret
//     * @return  token
//     */
//    private String getToken(String appid,String secret) throws MalformedURLException, IOException, ProtocolException {
//        // 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));
//        }
//
////        System.out.println(sb.toString());
//        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<String, Object> 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));
//        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));
//        }
//
//        in.close();
//        return sb.toString();
//    }
//
//
//    @ApiOperation(value = "拉取公众号列表")
//    @GetMapping("/list/noToken")
//    public R pageDiscuss() throws Exception{
//        WxOfficialApi officialApi = new WxOfficialApi();
//
//        List<String> tokenList = new ArrayList<>();
//        if(!appidList.isEmpty()){
//            for (int i = 0; i < appidList.size(); i++) {
//                String token = officialApi.getToken(appidList.get(i),secretList.get(i));
//                log.info("通过appid:"+appidList.get(i)+"获取token返回参数:" + token);
//                JSONObject tokenJson = JSON.parseObject(token);
//                if(StringUtils.isNotEmpty(tokenJson)){
//                    tokenList.add(tokenJson.getString("access_token"));
//                }
//            }
//        }
//
//        List<JSONObject> resultList = new ArrayList<>();
//        if(!tokenList.isEmpty()){
//            tokenList.forEach(token -> {
//                try {
//                    String result = officialApi.getContentList(token);
//                    log.info("通过token获取文章列表成功,返回结果:" + result);
//                    resultList.add(JSON.parseObject(result));
//                }catch (Exception e){
//                    log.error("通过token获取文章列表失败,错误原因:" + e.getMessage());
//                }
//            });
//        }
//        return R.ok(resultList);
//    }
//
//}
package com.panzhihua.applets.api;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import com.panzhihua.common.api.LcApiConstants;
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 com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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;
@Slf4j
@RestController
@RequestMapping("/official")
public class WxOfficialApi {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    // 公众号appid
    private List<String> appidList = new ArrayList<String>() {
        {
            this.add("wx7c733ebbf6c55ecf");
            this.add("wxc94f0cddf13577d5");
        }
    };
    // 公众号secret
    private List<String> secretList = new ArrayList<String>() {
        {
            this.add("500290552cbfdd1c1c18131c5807b6ae");
            this.add("3418127405845701497a09f65678953f");
        }
    };
    /**
     * 微信公众号请求头设置
     */
    public static Map<String, String> getWxHeaderMap() {
        Map<String, String> 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<String, Object> 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));
        }
        // System.out.println(sb.toString());
        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<String, Object> 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<String, String> valueOperations = stringRedisTemplate.opsForValue();
        List<String> tokenList = new ArrayList<>();
        if (!appidList.isEmpty()) {
            for (int i = 0; i < appidList.size(); i++) {
                String token = officialApi.getToken(appidList.get(i), secretList.get(i));
                log.info("通过appid:" + appidList.get(i) + "获取token返回参数:" + token);
                JSONObject tokenJson = JSON.parseObject(token);
                if (StringUtils.isNotEmpty(tokenJson)) {
                    tokenList.add(tokenJson.getString("access_token"));
                }
            }
        }
        List<JSONObject> 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<JSONObject> 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<JSONObject> 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<String, String> valueOperations = stringRedisTemplate.opsForValue();
        String url = valueOperations.get(key);
        return R.ok(url);
    }
}