Java实现小程序基础开发

Java实现小程序基础开发

描述

继上篇Java整合公众号基本功能实现,现继续完善与公众号管理绑定的小程序功能开发
实现公众号与小程序配套使用
现实现小程序的注册,手机号授权登录,Jsapi授权、小程序与公众号关系

小程序配置类

@Configuration
@RequiredArgsConstructor
@ConditionalOnClass(WxMaService.class)
@EnableConfigurationProperties()
public class WxMaConfiguration {
    private final MiniappConfigMapper miniappConfigMapper;
    /**
     * 默认配置
     */
    private static Map<String, WxMaService> wxMaServices = new HashMap<>();
    /**
     * jsapi配置
     */
    private static Map<String, WxMaJsapiService> WxMaJsapiServices = new HashMap<>();
    /**
     * 用户配置(获取用户客户代码)
     */
    private static Map<String, Integer> MINI_USER_CONF = new HashMap<>();

    public static Map<String, WxMaService> getMpServices() {
        return wxMaServices;
    }

    public static Integer getCustomId(String appid) {
        return MINI_USER_CONF.get(appid);
    }

    public static Map<String, WxMaJsapiService> getWxMaJsapiServices() {
        return WxMaJsapiServices;
    }
    
    /**
     * 小程序多客户
     * @return
     */
    @Bean
    public Object mpServices() {
        List<MiniappConfig> blueWxConfigs = miniappConfigMapper.selectList(Wrappers.emptyWrapper());
        for (MiniappConfig a : blueWxConfigs) {
            WxMaDefaultConfigImpl configStorage = new WxMaDefaultConfigImpl();
            configStorage.setAppid(a.getAppid());
            configStorage.setSecret(a.getSecret());
            configStorage.setToken(a.getToken());
            configStorage.setAesKey(a.getAeskey());
            configStorage.setMsgDataFormat(a.getMsgDataFormat());
            WxMaService service = new WxMaServiceImpl();
            service.setWxMaConfig(configStorage);
            WxMaJsapiService wxMaJsapiService = new WxMaJsapiServiceImpl(service);
            wxMaServices.put(a.getCustomerCode() + ":" + a.getAppid(), service);
            WxMaJsapiServices.put(a.getCustomerCode() + ":" + a.getAppid(), wxMaJsapiService);
            MINI_USER_CONF.put(a.getAppid(), a.getCustomerId());
        }
        return Boolean.TRUE;
    }
}

Jsapi签名

/**
 * 微信小程序获取jsapi签名
 */
@Slf4j
@RestController
@RequestMapping(value = "/miniapp/jsapi",produces = MediaType.APPLICATION_JSON_VALUE)
public class MiniappJsApiController {

	/**
     * 消息处理
     */
    @GetMapping(value = "/{customCode}")
    public WxJsapiSignature authGet(@PathVariable("customCode") String customCode,
                          @RequestParam(name = "url") String url) {
         WxJsapiSignature jsapiSignature = null;
        try {
            log.info("接收到获取接口,customCode=[{}],url=[{}]", customCode, url);
            if (customCode == null || StringUtil.isAnyBlank(url)) {
                log.error("请求参数非法,请核实!");
                return jsapiSignature;
            }
            WxMaJsapiService wxMaJsapiService = WxMaConfiguration.getWxMaJsapiServices().get(customCode);
            if (wxMaJsapiService == null) {
                log.error("没有找到该客户的配置,customCode=[{}]", customCode);
                return jsapiSignature;
            }
            jsapiSignature = wxMaJsapiService.createJsapiSignature(url);
        } catch (Exception e) {
            log.error("WxJsApiController authGet 失败{}", ExceptionUtil.getStackTraceAsString(e));
        }
        return jsapiSignature ;
    }
}

小程序入口

/**
 * 小程序入口
 */
@Slf4j
@RestController
@RequestMapping(value = "/miniapp/portal",produces = MediaType.APPLICATION_JSON_VALUE)
public class MiniappPortalController {

	@GetMapping(value = "/{customCode}", produces = "text/plain;charset=utf-8")
    public String authGet(@PathVariable("customCode") String customCode,
                          @RequestParam(name = "signature", required = false) String signature,
                          @RequestParam(name = "timestamp", required = false) String timestamp,
                          @RequestParam(name = "nonce", required = false) String nonce,
                          @RequestParam(name = "echostr", required = false) String echostr) {
        log.info("\n接收到来自微信服务器的认证消息:signature = [{}], timestamp = [{}], nonce = [{}], echostr = [{}]",
                signature, timestamp, nonce, echostr);
                if (StringUtil.isAnyBlank(signature, timestamp, nonce, echostr)) {
            throw new IllegalArgumentException("请求参数非法,请核实!");
        }
        if (customCode == null) {
            customCode = "";
        }
        if (WxMaConfiguration.getMpServices().get(customCode).checkSignature(timestamp, nonce, signature)) {
            return echostr;
        }
        return "非法请求";
    }


	@PostMapping(value = "/{customCode}", produces = "application/xml; charset=UTF-8")
    public String post(@PathVariable("customCode") String customCode,
                       @RequestBody String requestBody,
                       @RequestParam("msg_signature") String msgSignature,
                       @RequestParam("encrypt_type") String encryptType,
                       @RequestParam("signature") String signature,
                       @RequestParam("timestamp") String timestamp,
                       @RequestParam("nonce") String nonce) {
        log.info("\n接收微信请求:[msg_signature=[{}], encrypt_type=[{}], signature=[{}]," +
                        " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
                msgSignature, encryptType, signature, timestamp, nonce, requestBody);
        if (customCode == null) {
            customCode = "";
        }
        final boolean isJson = Objects.equals(WxMaConfiguration.getMpServices().get(customCode).getWxMaConfig().getMsgDataFormat(),
                WxMaConstants.MsgDataFormat.JSON);
        if (StringUtil.isBlank(encryptType)) {
            // 明文传输的消息
            WxMaMessage inMessage;
            if (isJson) {
                inMessage = WxMaMessage.fromJson(requestBody);
            } else {//xml
                inMessage = WxMaMessage.fromXml(requestBody);
            }
            System.out.println(inMessage);
            return "success";
        }
        if ("aes".equals(encryptType)) {
        	WxMaMessage inMessage;
            if (isJson) {
                inMessage = WxMaMessage.fromEncryptedJson(requestBody, WxMaConfiguration.getMpServices().get(1).getWxMaConfig());
            } else {//xml
                inMessage = WxMaMessage.fromEncryptedXml(requestBody, WxMaConfiguration.getMpServices().get(1).getWxMaConfig(),
                        timestamp, nonce, msgSignature);
            }
            return "success";
        }
        throw new RuntimeException("不可识别的加密类型:" + encryptType);
    }
}

小程序登录

/**
 * 小程序登录入口
 **/
@RequiredArgsConstructor
@Slf4j
@RestController
@RequestMapping(value = "/miniapp/login", produces = MediaType.APPLICATION_JSON_VALUE)
public class MiniappLoginController {

    /**
     * code登录,只要先拿到微信的sessionKey
     *
     * @param code 微信code
     */
    @ClearAuth
    @GetMapping("/codeLogin")
    public OMiniappLoginVO codeLogin(@RequestParam("code") String code,
                                     @RequestParam(value = "appid", required = false) String appid) {
        OMiniappLoginVO oMiniappLoginVO = new OMiniappLoginVO();
        // 通过code调用微信个人信息接口
        WxMaJscode2SessionResult session = null;
        WxMaService wxMaService = WxMaConfiguration.getMpServices().get(MiniappConstant.PARENT_CODE + ":" + appid);
        session = wxMaService.getUserService().getSessionInfo(code);
        log.info("获取结果为:{}", JSONObject.toJSONString(session));
        String sessionKey = session.getSessionKey();
        //获取微信的openId
        String openId = session.getOpenid();
        //获取微信的unionId,这个和公众号的unionId是一样的,所以可以根据这个来获取公众号用户来确定绑定关系
        String unionId = session.getUnionid();
        Integer customId = WxMaConfiguration.getCustomId(appid);
        //查看是否绑定过
        MiniappUserParent bindUserParent = miniappUserParentMapper.selectOneByOpenId(openId, customId);
        //这个miniappId业务上自行处理,这个主要是记录使用小程序的记录用户,与业务平台的用户一个绑定关系,可以通过这个来关联处理
        Long miniappId = null;
        MpUserParent mpUserParent = mpUserParentMapper.selectOneByUnionId(unionId);
		if (bindUserParent == null) {
            MiniappUserParent miniappUserParent = getMiniappUserParent(unionId, appid);
            miniappUserParent.setOpenId(openId);
            miniappUserParentMapper.insert(miniappUserParent);
            miniappId = miniappUserParent.getMiniappId();
        } else {
            miniappId = bindUserParent.getMiniappId();
        }
        String sessionId = IdUtil.fastSimpleUUID();
		oMiniappLoginVO.setSessionId(sessionId);
        oMiniappLoginVO.setSessionKey(sessionKey);
        return oMiniappLoginVO;
    }


    /**
     * 手机号码授权登录(先调上面的接口,拿到sessionKey)
     *
     * @param iMiniappPhoneLoginVO 机密数据
     * * @param encryptedData  机密数据
     * * @param iv   iv数据
     * * @param appid  
     * @return
     */
    @PostMapping("/phoneLogin.json")
    public void phone(@Valid @RequestBody IPhoneLoginVO iPhoneLoginVO) {
        MiniappUserDTO userDTO = UserUtil.getUser();
        String sessionKey = userDTO.getSessionKey();
        Long miniappId = userDTO.getMiniappId();
        String sessionId = miniappUser.getSessionId();
        String thirdBindingId = iMiniappPhoneLoginVO.getThirdBindingId();
        String appKey = null;
        String encryptedData = iMiniappPhoneLoginVO.getEncryptedData();
        String iv = iMiniappPhoneLoginVO.getIv();
        log.info("encryptedData={},iv={},sessionKey={}", encryptedData, iv, sessionKey);
        String appid = iMiniappPhoneLoginVO.getAppid();
        //获取缓存的数据
        WxMaService wxMaService = WxMaConfiguration.getMpServices().get(MiniappConstant.PARENT_CODE + ":" + appid);
        //解密
        WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
        log.info("phoneNoInfo数据:{}", phoneNoInfo);
        //获取手机号
        String phone = phoneNoInfo.getPhoneNumber();
        /判断该手机号有没注册过,如果有直接进行一个绑定,没有新增
        AppUserDTO appUserDTO = appUserMapper.selectByPhone(phone);
        if (appUserDTO != null) {
        
        } else {
        
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值