package com.zteits.pay.biz.wx; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.clouds.common.constants.CodeValKindEnum; import com.clouds.common.constants.CodeValueEnum; import com.clouds.common.constants.RedisKeyEnum; import com.clouds.common.oss.base.OssClientService; import com.clouds.common.oss.fastdfs.FastDFSOssClientWrapper; import com.clouds.common.utils.HttpClientUtils; import com.clouds.common.utils.ResultUtils; import com.clouds.common.utils.WxConfigUtil; import com.clouds.common.utils.image.ImageBase64Util; import com.clouds.common.utils.wx.AccessToken; import com.clouds.common.utils.wx.AccessTokenUtil; import com.zteits.clouds.api.apibase.bean.BizResult; import com.zteits.clouds.api.apibase.constants.BasicEnum; import com.zteits.clouds.api.apibase.constants.ErrorType; import com.zteits.clouds.api.apibase.constants.PayTypeEnum; import com.zteits.clouds.api.apibase.exception.BizException; import com.zteits.clouds.api.dto.pay.TdCAcctNoSecretDTO; import com.zteits.clouds.api.dto.pay.param.GetWxUnlimitedQrCodeRequest; import com.zteits.clouds.api.dto.sys.DataDicKindDetailDTO; import com.zteits.clouds.api.dto.sys.SysOrgAppIdDTO; import com.zteits.clouds.api.dto.sys.param.DataDicKindDetailRequest; import com.zteits.clouds.api.dto.sys.param.SysOrgAppIdQueryRequest; import com.zteits.clouds.api.service.pay.wx.WeChatMiniProgramRemoteService; import com.zteits.clouds.api.service.sys.DataDictionaryService; import com.zteits.clouds.api.service.sys.SysOrgAppIdService; import com.zteits.pay.biz.AccountRechargeServiceImpl; import com.zteits.pay.dao.TdBWxConfigDao; import com.zteits.pay.domain.TdBWxConfig; import com.zteits.pay.util.FastDFSClientWrapper; import groovy.util.logging.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import java.net.URLEncoder; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * @Author: Tom * @Date: 2022/8/30 14:26 * @Description: */ @Service public class WeChatMiniProgramRemoteServiceImpl implements WeChatMiniProgramRemoteService { private static final Logger logger = LoggerFactory.getLogger(WeChatMiniProgramRemoteServiceImpl.class); /** * 获取小程序码,适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制。URL */ private final String GETUNLIMITED = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?"; @Autowired private FastDFSClientWrapper fastDFSClientWrapper; @Autowired private TdBWxConfigDao tdBWxConfigDao; @Autowired private SysOrgAppIdService sysOrgAppIdService; @Autowired private DataDictionaryService dataDictionaryService; @Override public BizResult getUnlimitedQrCodeUrl(GetWxUnlimitedQrCodeRequest request) { if (request == null || request.getOrgId() == null || StringUtils.isBlank(request.getScene())){ return new BizResult<>(ErrorType.PARAMM_NULL, "参数为空"); } SysOrgAppIdQueryRequest sysRequest = new SysOrgAppIdQueryRequest(); sysRequest.setOrgId(request.getOrgId()); sysRequest.setPayType(PayTypeEnum.WXAPPLETS.getValue()); sysRequest.setSysCode(BasicEnum.SYS_CODE.getValue()); BizResult appIdDTOBizResult = sysOrgAppIdService.querySysOrgAppIdByOrgIdAndPayType(sysRequest); SysOrgAppIdDTO sysOrgAppIdDTO = appIdDTOBizResult.getData(); TdBWxConfig tdBWxConfig = tdBWxConfigDao.queryWxConfigByAppId(sysOrgAppIdDTO.getPayAppId()); //微信小程序appId String wxAppId = tdBWxConfig.getAppid(); //微信小程序appsecret String wxAppSecret = tdBWxConfig.getAppSecret(); byte[] body = this.getUnlimitedForBytes(wxAppId,wxAppSecret, request.getScene()); if (body == null || body.length == 0) { logger.info("获取二维码失败,失效accessToken,重新调用"); AccessTokenUtil.deleteAccessToken(wxAppId); body = this.getUnlimitedForBytes(wxAppId,wxAppSecret, request.getScene()); if (body == null || body.length == 0) { logger.info("新的accessToken获取二维码依旧失效,抛异常"); } } //上传图片到OSS String url = ""; try { url = fastDFSClientWrapper.uploadBase64Pic(ImageBase64Util.encode(body), ".jpg",request.getOrgId(),"wx"); } catch (Exception e) { logger.error("图片上传阿里云失败", e); } logger.info("图片完整地址:{}", url); return new BizResult<>(url); } /** * 调用微信生成二维码,获取bytes * * @return */ private byte[] getUnlimitedForBytes(String wxAppId, String wxAppSecret, String scene) { DataDicKindDetailRequest dataDicKindDetailRequest = new DataDicKindDetailRequest(); dataDicKindDetailRequest.setCodeKind(CodeValKindEnum.WX_MINI_CONFIG.name()); dataDicKindDetailRequest.setSysCode(BasicEnum.SYS_CODE.getValue()); BizResult> bizResult = dataDictionaryService.getDataDictionaryKindDetails(dataDicKindDetailRequest); List dataDicKindDetailDTOS = ResultUtils.getBizResultData(bizResult); if (CollectionUtils.isEmpty(dataDicKindDetailDTOS)) { throw new BizException(ErrorType.SYS_CODE_NOT_CONFIG, "字典表未配置" + CodeValKindEnum.WX_MINI_CONFIG.name(), false); } Map map = dataDicKindDetailDTOS.stream().collect(Collectors.toMap(DataDicKindDetailDTO::getCodeValue, DataDicKindDetailDTO::getCodeValueName)); //要打开的小程序版本。正式版为 release(默认值),体验版为 trial,开发版为 develop String envVersion = map.get(CodeValueEnum.WX_MINI_ENV_VERSION.name()); //page String page = map.get(CodeValueEnum.WX_MINI_CHARGE_PAGE.name()); //获取accessToken wxAppSecret = WxConfigUtil.decode(wxAppSecret); AccessToken token = AccessTokenUtil.getToken(wxAppId, wxAppSecret); String accessToken = token.getAccessToken(); //生成二维码 String url = GETUNLIMITED + "access_token=" + accessToken; JSONObject params = new JSONObject(); params.put("scene", scene); if (StringUtils.isNotEmpty(envVersion)) { //不传递,默认release params.put("env_version", envVersion); } if (StringUtils.isNotEmpty(page)) { params.put("page", page); } params.put("check_path", false); HttpClientUtils client = new HttpClientUtils(); byte[] body = client.post(url, params.toJSONString()); return body; } }