package com.chuanghai.smartschool.tuitionpayment.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chuanghai.smartschool.tuitionpayment.common.exception.BizCodeEnume;
import com.chuanghai.smartschool.tuitionpayment.common.exception.RRException;
import com.chuanghai.smartschool.tuitionpayment.common.utils.CommonResult;
import com.chuanghai.smartschool.tuitionpayment.config.WechatConfig;
import com.chuanghai.smartschool.tuitionpayment.config.WeixiaoConfig;
import com.chuanghai.smartschool.tuitionpayment.entity.*;
import com.chuanghai.smartschool.tuitionpayment.service.*;
import com.chuanghai.smartschool.tuitionpayment.vo.PayableInfoStudentResultVO;
import com.chuanghai.smartschool.tuitionpayment.vo.WeixiaoVO;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* 微信相关接口
*
* @author codingliang
* @email codingliang@gmail.com
* @date 2021-08-12 16:04
*/
@Controller
@RequestMapping("tuitionpayment/wechat")
public class WechatController {
@Autowired
private WechatConfig wechatConfig;
@Autowired
private WeixiaoConfig weixiaoConfig;
@Autowired
private PayableInfoService payableInfoService;
@Autowired
private PayableInfoWaterService payableInfoWaterService;
@Autowired
private PayOrderService payOrderService;
@Autowired
private FeedbackMsgController feedbackMsgController;
@Autowired
private PayItemService payItemService;
@Autowired
private SchoolUserService schoolUserService;
/**
* 用于记录用户的access_token
*/
private String accessTokenPublic = "";
/**
* 用于记录催缴的次数 计时器
*/
private Integer askCount = 0;
/**
* 微校中的学校组织代码
*/
private String schoolOrgId;
/**
* 用于记录当前获取微校用户的页码信息
*/
private static Integer userPage = 1;
/**
* 微信授权回调地址
*
* @param code 微信code
* @apiNote 用户跳转到微信授权链接上,微信服务器接收用户授权后会携带code回调到该接口上,该接口使用code获取到用户的openId信息。
* 如果openId获取成功,该接口会以 【fontendUrl + 路由地址 + ?openId=wx123456】 的形式跳回到前端应用页面;
* 如果openId获取失败,该接口会以 【fontendUrl + /error/?errorMsg=获取用户openId失败】 的形式跳回到前端应用页面。
* 注意:
* fontendUrl + 路由地址:前端项目地址+页面路由地址,用于前端页面接收用户的信息或错误信息,该地址需要前端人员与后台开发人员协调好。
*/
@GetMapping("pub/auth")
public String pubAuth(String code, String state) {
// code换取access_token
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
"appid=" + wechatConfig.getAppid() +
"&secret=" + wechatConfig.getSecret() +
"&code=" + code +
"&grant_type=authorization_code";
try {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); // 解决回参中文乱码
String response = restTemplate.getForObject(url, String.class);
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(response);
String openid = jsonNode.get("openid").asText();
return "redirect:" + wechatConfig.getFontendUrl() + "/#/" + state + "/?openId=" + openid;
} catch (Exception e) {
return "redirect:" + wechatConfig.getFontendUrl() + "/error/?errorMsg=获取用户openId失败";
}
}
/**
* 微校授权回调地址
*
* @param wxcode 微校code
* @param state 透传数据
* @return
* @apiNote 用户跳转到微校授权链接上,微校服务器接收用户授权后会携带wxcode回调到该接口上,该接口使用wxcode获取到用户的信息。
* 如果用户信息获取成功,该接口会以 【fontendUrl + /?cardNumber=wx123456&name=测试用户】 的形式跳回到前端应用页面;
* 如果用户信息获取失败,该接口会以 【fontendUrl + /error/?errorMsg=获取用户信息失败】 的形式跳回到前端应用页面。
* 注意:
* fontendUrl + 路由地址:前端项目地址+页面路由地址,用于前端页面接收用户的信息或错误信息,该地址需要前端人员与后台开发人员协调好。
*
*/
@GetMapping("weixiao/auth")
public String weixiaoAuth(String wxcode, String state) {
String tokenUrl = "https://open.wecard.qq.com/connect/oauth2/token";
Map tokenParams = new HashMap<>();
tokenParams.put("wxcode", wxcode);
tokenParams.put("app_key", weixiaoConfig.getAppKey());
tokenParams.put("app_secret", weixiaoConfig.getAppSecret());
tokenParams.put("grant_type", "authorization_code");
tokenParams.put("redirect_uri", state); // 该地址需要与发起授权地址保持一直
try {
// wecode换取token
RestTemplate client = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity