小程序登录

This commit is contained in:
wxp01309236
2023-06-14 21:06:06 +08:00
parent f0f54a929e
commit 3e6801f522
31 changed files with 756 additions and 78 deletions

View File

@@ -57,6 +57,10 @@ public enum ErrorCodeEnum {
ZONE_NOT_EXIST(500004, "战区不存在!", null),
INTERVIEW_ENTER_FAIL(1021101, "进入面试间失败", null),
SIGN_FAIL(600000, "验签失败", null),
GET_ACCESSTOKEN_ERROR(600001, "获取小程序TOKEN错误", null),
NEW_MOBILE_HAS_EXIST(600002,"加盟商用户信息已存在",null),
;

View File

@@ -0,0 +1,43 @@
package com.cool.store.enums;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author wxp
* @FileName: UserPlatformTypeEnum
* @Description: 用户平台类型
* @date 2023-06-13 17:12
*/
public enum UserPlatformTypeEnum {
WECHAT("wechat", "微信"),
DOUYIN("douyin", "抖音"),
WEIBO("weibo", "微博");
private String code;
private String msg;
protected static final Map<String, UserPlatformTypeEnum> map = Arrays.stream(values()).collect(
Collectors.toMap(UserPlatformTypeEnum::getCode, Function.identity()));
UserPlatformTypeEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
public static UserPlatformTypeEnum getByCode(String code) {
return map.get(code);
}
}

View File

@@ -0,0 +1,80 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cool.store.utils;
import com.cool.store.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* The type Md5 utils.
*/
public class Md5Utils {
/**
* logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(Md5Utils.class);
/**
* Md 5 string.
*
* @param src the src
* @param charset the charset
*
* @return the string
*/
private static String md5(final String src, final String charset) {
MessageDigest md5;
StringBuilder hexValue = new StringBuilder(32);
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new ServiceException(e.getMessage());
}
byte[] byteArray = new byte[0];
try {
byteArray = src.getBytes(charset);
} catch (UnsupportedEncodingException e) {
LOG.error(e.getMessage(), e);
}
byte[] md5Bytes = md5.digest(byteArray);
for (byte md5Byte : md5Bytes) {
int val = ((int) md5Byte) & 0xff;
if (val < 16) {
hexValue.append("0");
}
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString();
}
/**
* Md 5 string.
*
* @param src the src
* @return the string
*/
public static String md5(final String src) {
return md5(src, StandardCharsets.UTF_8.name());
}
}

View File

@@ -0,0 +1,22 @@
package com.cool.store.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Sha1Utils {
public static String getSha1(byte[] input) {
try {
MessageDigest mDigest = MessageDigest.getInstance("SHA1");
byte[] result = mDigest.digest(input);
StringBuffer sb = new StringBuffer();
for (byte b : result) {
sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return "";
}
}
}

View File

@@ -5,7 +5,6 @@ import com.cool.store.mapper.HyPartnerUserInfoMapper;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
@@ -41,6 +40,18 @@ public class HyPartnerUserInfoDAO {
return hyPartnerUserInfoMapper.selectByPartnerId(partnerId);
}
/**
* 根据mobile查询用户
* @param mobile
* @return
*/
public HyPartnerUserInfoDO selectByMobile(String mobile){
if (StringUtils.isEmpty(mobile)){
return null;
}
return hyPartnerUserInfoMapper.selectByMobile(mobile);
}
/**
* 根据PartnerIds批量查询用户
* @param partnerIds
@@ -53,4 +64,9 @@ public class HyPartnerUserInfoDAO {
return hyPartnerUserInfoMapper.selectByPartnerIds(partnerIds);
}
public int insertSelective( HyPartnerUserInfoDO record){
return hyPartnerUserInfoMapper.insertSelective(record);
}
}

View File

@@ -0,0 +1,43 @@
package com.cool.store.dao;
import com.cool.store.entity.HyPartnerUserPlatformBindDO;
import com.cool.store.mapper.HyPartnerUserPlatformBindMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
/**
* @Author wxp
* @Date 2023/6/13 19:41
* @Version 1.0
*/
@Repository
public class HyPartnerUserPlatformBindDAO {
@Resource
HyPartnerUserPlatformBindMapper hyPartnerUserPlatformBindMapper;
public int insertSelective( HyPartnerUserPlatformBindDO record){
return hyPartnerUserPlatformBindMapper.insertSelective(record);
}
public int updateByPrimaryKeySelective(HyPartnerUserPlatformBindDO record){
return hyPartnerUserPlatformBindMapper.updateByPrimaryKeySelective(record);
}
public HyPartnerUserPlatformBindDO getByPlatformTypeAndUserId(String platformType, String platformUserId){
if(StringUtils.isAnyBlank(platformType, platformUserId)){
return null;
}
return hyPartnerUserPlatformBindMapper.getByPlatformTypeAndUserId(platformType, platformUserId);
}
public HyPartnerUserPlatformBindDO getByPartnerId(String partnerId){
if (StringUtils.isEmpty(partnerId)){
return null;
}
return hyPartnerUserPlatformBindMapper.getByPartnerId(partnerId);
}
}

View File

@@ -32,6 +32,8 @@ public interface HyPartnerUserInfoMapper {
*/
HyPartnerUserInfoDO selectByPartnerId(@Param("partnerId") String partnerId);
HyPartnerUserInfoDO selectByMobile(@Param("mobile") String mobile);
/**
* 根据partnerIDs批量查询用户信息
* @param partnerIdList

View File

@@ -1,5 +1,6 @@
package com.cool.store.mapper;
import com.cool.store.entity.HyPartnerUserInfoDO;
import com.cool.store.entity.HyPartnerUserPlatformBindDO;
import org.apache.ibatis.annotations.Param;
@@ -22,4 +23,9 @@ public interface HyPartnerUserPlatformBindMapper {
* dateTime:2023-05-29 03:53
*/
int updateByPrimaryKeySelective(@Param("record") HyPartnerUserPlatformBindDO record);
HyPartnerUserPlatformBindDO getByPlatformTypeAndUserId(@Param("platformType") String platformType, @Param("platformUserId") String platformUserId);
HyPartnerUserPlatformBindDO getByPartnerId(@Param("partnerId") String partnerId);
}

View File

@@ -25,6 +25,13 @@
where partner_id = #{partnerId}
</select>
<select id="selectByMobile" resultMap="BaseResultMap" >
select
<include refid="Base_Column_List"></include>
from hy_partner_user_info
where mobile = #{mobile}
</select>
<select id="selectByPartnerIds" resultMap="BaseResultMap" >
select

View File

@@ -80,4 +80,20 @@
</set>
where id = #{record.id}
</update>
<select id="getByPlatformTypeAndUserId" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"></include>
from
hy_partner_user_platform_bind
where platform_type = #{platformType} and platform_user_id = #{platformUserId}
</select>
<select id="getByPartnerId" resultMap="BaseResultMap" >
select
<include refid="Base_Column_List"></include>
from hy_partner_user_platform_bind
where partner_id = #{partnerId}
</select>
</mapper>

View File

@@ -13,12 +13,12 @@ import javax.validation.constraints.NotBlank;
@Data
public class MiniProgramLoginDTO {
@NotBlank(message = "appid不能为空")
private String appid;
@NotBlank(message = "jsCode不能为空")
private String jsCode;
@NotBlank(message = "手机号code不能为空")
private String mobileCode;
@NotBlank(message = "用户encryptedData不能为空")
private String encryptedData;

View File

@@ -0,0 +1,36 @@
package com.cool.store.dto.wx;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
/**
* @author wxp
* @FileName: PhoneInfoDTO
* @Description:
* @date 2023-06-14 14:28
*/
@Data
public class PhoneInfoDTO extends WXBaseResultDTO{
@JSONField(name = "phone_info")
private PhoneInfo phoneInfo;
@Data
public static class PhoneInfo{
/**
* 用户绑定的手机号(国外手机号会有区号)
*/
private String phoneNumber;
/**
* 没有区号的手机号
*/
private String purePhoneNumber;
/**
* 区号
*/
private String countryCode;
}
}

View File

@@ -0,0 +1,23 @@
package com.cool.store.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @Author wxp
* @Date 2023/5/31 11:01
* @Version 1.0
*/
@Data
@ApiModel
public class MobileUpdateRequest {
@NotBlank(message = "手机号code不能为空")
@ApiModelProperty("手机号code")
private String mobileCode;
}

View File

@@ -3,6 +3,9 @@ package com.cool.store.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import java.util.Objects;
/**
* @Author suzhuhong
@@ -16,6 +19,9 @@ public class PartnerUserInfoVO {
@ApiModelProperty("ID")
private Long id;
@ApiModelProperty("hy_partner_user_info.partner_id")
private String partnerId;
@ApiModelProperty("手机号")
private String mobile;
@@ -37,4 +43,22 @@ public class PartnerUserInfoVO {
@ApiModelProperty("邀请码")
private String inviteCode;
@ApiModelProperty("openid")
private String openid;
@ApiModelProperty("unionid")
private String unionId;
@ApiModelProperty("是否需要提交意向信息")
private Boolean isNeedSubmitWantInfo;
public Boolean getNeedSubmitWantInfo() {
if(StringUtils.isBlank(username)
|| StringUtils.isBlank(mobile)
|| StringUtils.isBlank(liveArea)
|| StringUtils.isBlank(wantShopArea)){
return true;
}
return false;
}
}

View File

@@ -1,5 +1,6 @@
package com.cool.store.vo.wx;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -15,4 +16,8 @@ public class CodeSessionVO {
private String openid;
private String unionId;
private String partnerId;
private String mobile;
}

View File

@@ -0,0 +1,34 @@
package com.cool.store.context;
import com.alibaba.fastjson.JSON;
import com.cool.store.vo.PartnerUserInfoVO;
import org.apache.commons.lang3.StringUtils;
/**
* C端登录用户信息
*/
public class PartnerUserHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
public static PartnerUserInfoVO getUser() {
String userStr = contextHolder.get();
if (StringUtils.isNotBlank(userStr)) {
return JSON.parseObject(userStr, PartnerUserInfoVO.class);
}
return new PartnerUserInfoVO();
}
public static void setUser(String user) {
contextHolder.set(user);
}
public static void removeUser(){
contextHolder.remove();
}
}

View File

@@ -1,16 +1,20 @@
package com.cool.store.http;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.dto.response.ResultDTO;
import com.cool.store.dto.wx.CodeSessionDTO;
import com.cool.store.dto.wx.PhoneInfoDTO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.utils.RestTemplateUtil;
import com.cool.store.mq.util.HttpRestTemplateService;
import com.cool.store.utils.RedisUtilPool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
@@ -23,24 +27,81 @@ import java.util.Objects;
@Service
public class WechatRest {
@Resource
private RedisUtilPool redisUtilPool;
@Resource
private HttpRestTemplateService httpRestTemplateService;
/**
* 小程序Token 地址
*/
String ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
/**
* 获取手机号码 地址
*/
String GET_USERPHONENUMBER = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s";
public CodeSessionDTO miniProgramJsCodeSession(String appId, String secret, String jsCode){
String url = "https://api.weixin.qq.com/sns/jscode2session";
Map requestMap = new HashMap<String, String>();
requestMap.put("appId", appId);
HashMap requestMap = new HashMap();
requestMap.put("appid", appId);
requestMap.put("secret", secret);
requestMap.put("jsCode", jsCode);
ResponseEntity<CodeSessionDTO> responseEntity = null;
requestMap.put("js_code", jsCode);
requestMap.put("grant_type","authorization_code");
ResultDTO responseEntity = null;
try {
responseEntity = RestTemplateUtil.get(url, CodeSessionDTO.class);
log.info("url:{}, response:{}", url, JSONObject.toJSONString(responseEntity));
if(Objects.nonNull(responseEntity.getBody()) && responseEntity.getBody().isSuccess()){
return responseEntity.getBody();
responseEntity = httpRestTemplateService.getForObject(url, ResultDTO.class, requestMap);
log.info("WechatRest#miniProgramJsCodeSession, url:{}, response:{}", url, JSONObject.toJSONString(responseEntity));
if(Objects.nonNull(responseEntity.getData()) && responseEntity.isSuccess()){
return JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getData()), CodeSessionDTO.class);
}
} catch (Exception e) {
log.info("调用微信服务异常{}", e);
throw new ServiceException(ErrorCodeEnum.WX_SERVICE_ERROR);
log.error("调用微信服务异常", e);
}
return null;
}
public String getAccessToken(String appId, String secret) {
String cacheAccessToken = "mini_" + appId;
String accessToken = redisUtilPool.getString(cacheAccessToken);
if (StringUtils.isNotBlank(accessToken)) {
return accessToken;
}
String reqUrl = String.format(ACCESS_TOKEN, appId, secret);
ResultDTO responseEntity = null;
try {
responseEntity = httpRestTemplateService.getForObject(reqUrl, ResultDTO.class, null);
log.info("WechatRest#getAccessToken, reqUrl:{}, response:{}", reqUrl, JSONObject.toJSONString(responseEntity));
if(Objects.nonNull(responseEntity.getData()) && responseEntity.isSuccess()){
JSONObject jsonObject = JSON.parseObject(JSONObject.toJSONString(responseEntity.getData()));
String token = jsonObject.getString("access_token");
if (StringUtils.isBlank(token)) {
throw new ServiceException(ErrorCodeEnum.GET_ACCESSTOKEN_ERROR);
}
redisUtilPool.setString(cacheAccessToken, token, 7000);
accessToken = token;
}
} catch (Exception e) {
log.error("获取微信小程序token异常", e);
}
return accessToken;
}
public PhoneInfoDTO getUserPhoneNumber(String code, String accessToken){
String reqUrl = String.format(GET_USERPHONENUMBER, accessToken);
HashMap requestMap = new HashMap();
requestMap.put("code", code);
PhoneInfoDTO phoneInfoDTO = null;
try {
phoneInfoDTO = httpRestTemplateService.postForObject(reqUrl, requestMap, PhoneInfoDTO.class);
log.info("WechatRest#getUserPhoneNumber, reqUrl:{}, response:{}", reqUrl, JSONObject.toJSONString(phoneInfoDTO));
} catch (Exception e) {
log.error("获取手机号异常", e);
}
return phoneInfoDTO;
}
}

View File

@@ -0,0 +1,5 @@
package com.cool.store.service;
public interface PartnerUserInfoService {
}

View File

@@ -1,10 +1,8 @@
package com.cool.store.service;
import com.cool.store.dto.wx.MiniProgramLoginDTO;
import com.cool.store.dto.wx.MiniProgramMsgDTO;
import com.cool.store.vo.wx.CodeSessionVO;
import com.cool.store.vo.wx.MiniProgramUserVO;
import com.cool.store.request.MobileUpdateRequest;
import com.cool.store.vo.PartnerUserInfoVO;
/**
* @author zhangchenbiao
* @FileName: WechatMiniAppService
@@ -14,9 +12,9 @@ import com.cool.store.vo.wx.MiniProgramUserVO;
public interface WechatMiniAppService {
CodeSessionVO miniProgramLogin(MiniProgramLoginDTO param);
PartnerUserInfoVO miniProgramLogin(MiniProgramLoginDTO param);
CodeSessionVO getUserPhoneNumber(MiniProgramLoginDTO param);
Boolean updateUserPhoneNumber(MobileUpdateRequest request, PartnerUserInfoVO userInfoVO);
CodeSessionVO queryMiniProgramUser(MiniProgramMsgDTO param);
PartnerUserInfoVO getUserInfo(String mobile, String openId);
}

View File

@@ -0,0 +1,14 @@
package com.cool.store.service.impl;
import com.cool.store.dao.HyPartnerUserInfoDAO;
import com.cool.store.service.PartnerUserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PartnerUserInfoServiceImpl implements PartnerUserInfoService {
@Autowired
private HyPartnerUserInfoDAO hyPartnerUserInfoDAO;
}

View File

@@ -1,24 +1,36 @@
package com.cool.store.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils;
import com.cool.store.constants.CommonConstants;
import com.cool.store.dao.HyPartnerLineInfoDAO;
import com.cool.store.dao.HyPartnerUserInfoDAO;
import com.cool.store.dao.HyPartnerUserPlatformBindDAO;
import com.cool.store.dto.wx.CodeSessionDTO;
import com.cool.store.dto.wx.MiniProgramLoginDTO;
import com.cool.store.dto.wx.MiniProgramMsgDTO;
import com.cool.store.dto.wx.PhoneInfoDTO;
import com.cool.store.entity.HyPartnerLineInfoDO;
import com.cool.store.entity.HyPartnerUserInfoDO;
import com.cool.store.entity.HyPartnerUserPlatformBindDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.UserPlatformTypeEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.http.WechatRest;
import com.cool.store.request.MobileUpdateRequest;
import com.cool.store.service.WechatMiniAppService;
import com.cool.store.utils.AesUtil;
import com.cool.store.utils.RedisUtilPool;
import com.cool.store.vo.wx.CodeSessionVO;
import com.cool.store.utils.UUIDUtils;
import com.cool.store.vo.PartnerUserInfoVO;
import com.cool.store.vo.wx.MiniProgramUserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.Date;
import java.util.Objects;
/**
@@ -35,49 +47,105 @@ public class WechatMiniAppServiceImpl implements WechatMiniAppService {
private RedisUtilPool redisUtilPool;
@Resource
private WechatRest wechatRest;
@Resource
private HyPartnerUserInfoDAO hyPartnerUserInfoDAO;
@Resource
private HyPartnerUserPlatformBindDAO hyPartnerUserPlatformBindDAO;
@Resource
private HyPartnerLineInfoDAO hyPartnerLineInfoDAO;
@Value("${weixin.appId}")
private String wxAppId;
@Value("${weixin.appSecret}")
private String wxAppSecret;
@Override
public CodeSessionVO miniProgramLogin(MiniProgramLoginDTO param) {
public PartnerUserInfoVO miniProgramLogin(MiniProgramLoginDTO param) {
PartnerUserInfoVO userInfoVO = new PartnerUserInfoVO();
String jsCode = param.getJsCode();
String lockKey = "codeSession:" + param.getAppid() + CommonConstants.MOSAICS + jsCode;
String lockKey = "codeSession:" + wxAppId + CommonConstants.MOSAICS + jsCode;
boolean lock = redisUtilPool.lock(lockKey);
if (!lock) {
throw new ServiceException(ErrorCodeEnum.OPERATION_OVER_TIME);
}
String appid = param.getAppid();
String secret = redisUtilPool.getString(MessageFormat.format(CommonConstants.WX_APP_SECRET_KEY, appid));
if(StringUtils.isBlank(secret)){
throw new ServiceException(ErrorCodeEnum.GET_APP_SECRET_ERROR);
}
CodeSessionDTO codeSession = wechatRest.miniProgramJsCodeSession(appid, secret, jsCode);
CodeSessionDTO codeSession = wechatRest.miniProgramJsCodeSession(wxAppId, wxAppSecret, jsCode);
String openid = codeSession.getOpenid();
String sessionCacheKey = MessageFormat.format(CommonConstants.MINI_PROGRAM_SESSION_KEY, appid, openid);
String sessionCacheKey = MessageFormat.format(CommonConstants.MINI_PROGRAM_SESSION_KEY, wxAppId, openid);
redisUtilPool.setString(sessionCacheKey, codeSession.getSessionKey(), CommonConstants.THREE_DAY_SECONDS);
String unionId = codeSession.getUnionId();
log.info("小程序登录:{}", unionId);
//todo 保存授权信息 判断是否第一次授权
return CodeSessionVO.builder().openid(openid).unionId(unionId).build();
}
@Override
public CodeSessionVO getUserPhoneNumber(MiniProgramLoginDTO param) {
return null;
}
@Override
public CodeSessionVO queryMiniProgramUser(MiniProgramMsgDTO param) {
String sessionCacheKey = MessageFormat.format(CommonConstants.MINI_PROGRAM_SESSION_KEY, param.getAppid(), param.getOpenid());
String sessionKey = redisUtilPool.getString(sessionCacheKey);
if (StringUtils.isBlank(sessionKey)) {
throw new ServiceException(ErrorCodeEnum.SESSION_KEY_ERROR);
}
log.info("sessionKey {}", sessionKey);
String decryptUser = AesUtil.decryptWechat(sessionKey, param.getEncryptedData(), param.getIvStr());
log.info("sessionKey {}", codeSession.getSessionKey());
String decryptUser = AesUtil.decryptWechat(codeSession.getSessionKey(), param.getEncryptedData(), param.getIvStr());
log.info("解密用户信息:{}", decryptUser);
MiniProgramUserVO miniProgramUser = JSON.parseObject(decryptUser, MiniProgramUserVO.class);
if (Objects.isNull(miniProgramUser)) {
throw new ServiceException(ErrorCodeEnum.GET_WECHAT_USER_INFO_FAIL);
}
return new CodeSessionVO();
// 获取小程序token
String accessToken = wechatRest.getAccessToken(wxAppId, wxAppSecret);
// 获取手机号码
PhoneInfoDTO phoneInfoDTO = wechatRest.getUserPhoneNumber(param.getMobileCode(), accessToken);
if(phoneInfoDTO != null && phoneInfoDTO.getPhoneInfo() != null && StringUtils.isNotBlank(phoneInfoDTO.getPhoneInfo().getPhoneNumber())){
HyPartnerUserInfoDO hyPartnerUserInfoDO = hyPartnerUserInfoDAO.selectByMobile(phoneInfoDTO.getPhoneInfo().getPhoneNumber());
if(hyPartnerUserInfoDO == null){
hyPartnerUserInfoDO = new HyPartnerUserInfoDO();
hyPartnerUserInfoDO.setMobile(phoneInfoDTO.getPhoneInfo().getPhoneNumber());
hyPartnerUserInfoDO.setUsername(miniProgramUser.getNickName());
hyPartnerUserInfoDO.setPartnerId(UUIDUtils.get32UUID());
hyPartnerUserInfoDAO.insertSelective(hyPartnerUserInfoDO);
// 生成一条线索
HyPartnerLineInfoDO hyPartnerLineInfoDO = new HyPartnerLineInfoDO();
hyPartnerLineInfoDO.setPartnerId(hyPartnerUserInfoDO.getPartnerId());
hyPartnerLineInfoDAO.insertSelective(hyPartnerLineInfoDO);
}
HyPartnerUserPlatformBindDO hyPartnerUserPlatformBindDO = hyPartnerUserPlatformBindDAO.getByPlatformTypeAndUserId(UserPlatformTypeEnum.WECHAT.getCode(), openid);
if(hyPartnerUserPlatformBindDO == null){
hyPartnerUserPlatformBindDO = new HyPartnerUserPlatformBindDO();
hyPartnerUserPlatformBindDO.setPlatformType(UserPlatformTypeEnum.WECHAT.getCode());
hyPartnerUserPlatformBindDO.setPlatformUserId(openid);
hyPartnerUserPlatformBindDO.setBindTime(new Date());
hyPartnerUserPlatformBindDO.setPartnerId(hyPartnerUserInfoDO.getPartnerId());
hyPartnerUserPlatformBindDAO.insertSelective(hyPartnerUserPlatformBindDO);
}
userInfoVO.setPartnerId(hyPartnerUserInfoDO.getPartnerId());
userInfoVO.setMobile(hyPartnerUserInfoDO.getMobile());
userInfoVO.setUsername(hyPartnerUserInfoDO.getUsername());
}
userInfoVO.setOpenid(openid);
userInfoVO.setUnionId(unionId);
return userInfoVO;
}
@Override
public Boolean updateUserPhoneNumber(MobileUpdateRequest request, PartnerUserInfoVO userInfoVO) {
HyPartnerUserInfoDO oldUserInfo = hyPartnerUserInfoDAO.selectByMobile(userInfoVO.getMobile());
if (oldUserInfo == null) {
throw new ServiceException(ErrorCodeEnum.PARTNER_USER_NOT_EXIST);
}
// 获取小程序token
String accessToken = wechatRest.getAccessToken(wxAppId, wxAppSecret);
// 获取手机号码
PhoneInfoDTO phoneInfoDTO = wechatRest.getUserPhoneNumber(request.getMobileCode(), accessToken);
if(phoneInfoDTO != null && phoneInfoDTO.getPhoneInfo() != null && StringUtils.isNotBlank(phoneInfoDTO.getPhoneInfo().getPhoneNumber())){
HyPartnerUserInfoDO newUserInfo = hyPartnerUserInfoDAO.selectByMobile(phoneInfoDTO.getPhoneInfo().getPhoneNumber());
if (newUserInfo != null) {
throw new ServiceException(ErrorCodeEnum.NEW_MOBILE_HAS_EXIST);
}
oldUserInfo.setMobile(phoneInfoDTO.getPhoneInfo().getPhoneNumber());
hyPartnerUserInfoDAO.updateByPrimaryKeySelective(oldUserInfo);
}
return true;
}
@Override
public PartnerUserInfoVO getUserInfo(String mobile, String openId) {
PartnerUserInfoVO userInfoVO = new PartnerUserInfoVO();
HyPartnerUserInfoDO hyPartnerUserInfoDO = hyPartnerUserInfoDAO.selectByMobile(mobile);
BeanUtil.copyProperties(hyPartnerUserInfoDO, userInfoVO);
HyPartnerUserPlatformBindDO hyPartnerUserPlatformBindDO = hyPartnerUserPlatformBindDAO.getByPartnerId(hyPartnerUserInfoDO.getPartnerId());
userInfoVO.setOpenid(hyPartnerUserPlatformBindDO.getPlatformUserId());
return userInfoVO;
}
}

View File

@@ -0,0 +1,128 @@
package com.cool.store.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.context.PartnerUserHolder;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.response.ResponseResult;
import com.cool.store.service.WechatMiniAppService;
import com.cool.store.utils.AesUtil;
import com.cool.store.utils.Md5Utils;
import com.cool.store.utils.Sha1Utils;
import com.cool.store.vo.PartnerUserInfoVO;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* @author ydw
* @Description 权限校验
* @date 2020/1/15
*/
@Component
@Order(3)
@Slf4j
public class SignValidateFilter implements Filter {
@Resource
private WechatMiniAppService wechatMiniAppService;
@Value("${signKey}")
private String signKey;
private static AntPathMatcher matcher = new AntPathMatcher();
private static List<String> patternList =
Lists.newArrayList("/web/check/ok","/check/ok",
"/partner/pc/doc.html","/partner/pc/v2/api-docs","/**/test/**","/partner/pc/feiShuLogin","/partner/pc/oss/getUploadFileConfig",
"/**/swagger*/**", "/**/webjars/**");
/**
* @param uri
* @return boolean
* @throws
* @Title excludePath
* @Description 是否是放行的请求
*/
private boolean excludePath(String uri) {
for (String pattern : patternList) {
if (matcher.match(pattern, uri)) {
return true;
}
}
return false;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
String uri = request.getRequestURI();
String method = request.getMethod();
String userStr = "";
boolean isInWhiteList = excludePath(uri);
Map<String, String[]> parameterMap = request.getParameterMap();
String jsonStr = JSONObject.toJSONString(parameterMap);
JSONObject obj = JSONObject.parseObject(jsonStr);
log.info("params:{}", obj.toJSONString());
String params = obj.toJSONString();
String sign = request.getHeader("SIGN");
String nonce = request.getHeader("NONCE");
String timestamp = request.getHeader("TIMESTAMP");
String aesPhone = request.getHeader("PHONE");
String openid = request.getHeader("OPENID");
String phone = AesUtil.decrypt(aesPhone, signKey);
String md5Value = phone + Md5Utils.md5(Md5Utils.md5(openid));
log.info("sign:{}, nonce:{}, timestamp:{},aesPhone:{}, openid:{}, 解密后的手机号:{}, md5Value:{}",
sign, nonce, timestamp, aesPhone, openid, phone, md5Value);
String signStr = timestamp + nonce + params + signKey + md5Value;
String newSign = Sha1Utils.getSha1(signStr.getBytes());
log.info("newSign: {}", newSign);
log.info("url:{}", uri);
if ( !isInWhiteList && !method.equals("OPTIONS")) {
// 前后端验签不等
if (!newSign.equals(sign)) {
response.setStatus(HttpStatus.OK.value());
response.getWriter().write(JSON.toJSONString(
ResponseResult.fail(ErrorCodeEnum.SIGN_FAIL)));
return;
}
PartnerUserInfoVO partnerUserInfoVO = wechatMiniAppService.getUserInfo(phone, openid);
if(partnerUserInfoVO != null){
userStr = JSONObject.toJSONString(partnerUserInfoVO);
log.info("url:{}, userStr:{}", uri, userStr);
}
}
try {
PartnerUserHolder.setUser(userStr);
filterChain.doFilter(servletRequest, servletResponse);
} finally {
PartnerUserHolder.removeUser();
}
}
@Override
public void destroy() {
}
}

View File

@@ -1,11 +1,12 @@
package com.cool.store.controller;
import com.cool.store.context.PartnerUserHolder;
import com.cool.store.dto.wx.MiniProgramLoginDTO;
import com.cool.store.dto.wx.MiniProgramMsgDTO;
import com.cool.store.request.MobileUpdateRequest;
import com.cool.store.response.ResponseResult;
import com.cool.store.service.WechatMiniAppService;
import com.cool.store.vo.wx.CodeSessionVO;
import com.cool.store.vo.PartnerUserInfoVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
@@ -29,23 +30,24 @@ public class MiniProgramAppController {
private WechatMiniAppService wechatMiniAppService;
@ApiOperation("小程序登录")
@PostMapping("/code/login")
public ResponseResult<CodeSessionVO> login(@RequestBody @Valid MiniProgramLoginDTO param) {
CodeSessionVO codeSessionVO = wechatMiniAppService.miniProgramLogin(param);
return ResponseResult.success(codeSessionVO);
@PostMapping("/login")
public ResponseResult<PartnerUserInfoVO> login(@RequestBody @Valid MiniProgramLoginDTO param) {
PartnerUserInfoVO userInfoVO = wechatMiniAppService.miniProgramLogin(param);
return ResponseResult.success(userInfoVO);
}
@ApiOperation("获取手机号")
@PostMapping("/code/getUserPhoneNumber")
public ResponseResult<CodeSessionVO> getUserPhoneNumber(@RequestBody @Valid MiniProgramLoginDTO param) {
CodeSessionVO codeSessionVO = wechatMiniAppService.getUserPhoneNumber(param);
return ResponseResult.success(codeSessionVO);
@ApiOperation("更新手机号")
@PostMapping("/updateUserPhoneNumber")
public ResponseResult<Boolean> updateUserPhoneNumber(@RequestBody @Valid MobileUpdateRequest request) {
PartnerUserInfoVO userInfoVO = PartnerUserHolder.getUser();
return ResponseResult.success(wechatMiniAppService.updateUserPhoneNumber(request, userInfoVO));
}
@ApiOperation("获取小程序用户信息")
@PostMapping("/user")
public ResponseResult<CodeSessionVO> queryMiniProgramUser(@RequestBody @Valid MiniProgramMsgDTO param) {
CodeSessionVO codeSessionVO = wechatMiniAppService.queryMiniProgramUser(param);
return ResponseResult.success(codeSessionVO);
@ApiOperation("根据mobile和openId获取用户信息")
@PostMapping("/getUserInfo")
public ResponseResult<PartnerUserInfoVO> getUserInfo(@RequestParam(value = "mobile",required = false) String mobile,
@RequestParam(value = "openId",required = false) String openId){
PartnerUserInfoVO userInfoVO = wechatMiniAppService.getUserInfo(mobile, openId);
return ResponseResult.success(userInfoVO);
}
}

View File

@@ -5,6 +5,8 @@ import com.cool.store.request.PartnerBaseInfoRequest;
import com.cool.store.request.PartnerClerkInfoRequest;
import com.cool.store.request.PartnerIntentInfoRequest;
import com.cool.store.response.ResponseResult;
import com.cool.store.service.HyPartnerIntentInfoService;
import com.cool.store.service.PartnerUserInfoService;
import com.cool.store.vo.*;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
@@ -14,6 +16,7 @@ import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
@@ -27,13 +30,16 @@ import java.util.List;
@Api(tags = "加盟商信息")
public class PartnerController {
@Resource
private PartnerUserInfoService partnerUserInfoService;
@Resource
HyPartnerIntentInfoService hyPartnerIntentInfoService;
@PostMapping(path = "/applyBaseInfo")
@ApiOperation("提交基本信息")
public ResponseResult<Boolean> applyBaseInfo(@RequestBody BaseUserInfoRequest baseUserInfoRequest){
return ResponseResult.success();
return ResponseResult.success(hyPartnerIntentInfoService.updatePartnerIntentInfo(baseUserInfoRequest));
}

View File

@@ -54,4 +54,9 @@ cdn.url=https://testhsaypic.coolstore.cn
#TRTC
trtc.sdkAppId=1400811820
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
weixin.appId=wx6f984e535e571818
weixin.appSecret=245a483747e6e9f8762d3e8539cf0318
signKey=77fea013c3a6459685b83c21a2fc3411

View File

@@ -51,4 +51,9 @@ corp.id = 171cddee76471740
#TRTC
trtc.sdkAppId=1400811820
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
weixin.appId=wx6f984e535e571818
weixin.appSecret=245a483747e6e9f8762d3e8539cf0318
signKey=77fea013c3a6459685b83c21a2fc3411

View File

@@ -49,4 +49,9 @@ corp.id = 171cddee76471740
#TRTC
trtc.sdkAppId=1400811820
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
weixin.appId=wx6f984e535e571818
weixin.appSecret=245a483747e6e9f8762d3e8539cf0318
signKey=d851f2a9ac90474abecdc2fbb148d4d7

View File

@@ -59,3 +59,8 @@ cdn.url=https://testhsaypic.coolstore.cn
#TRTC
trtc.sdkAppId=1400811820
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
weixin.appId=wx6f984e535e571818
weixin.appSecret=245a483747e6e9f8762d3e8539cf0318
signKey=77fea013c3a6459685b83c21a2fc3411

View File

@@ -49,4 +49,9 @@ corp.id = 171cddee76471740
#TRTC
trtc.sdkAppId=1400811820
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
weixin.appId=wx6f984e535e571818
weixin.appSecret=245a483747e6e9f8762d3e8539cf0318
signKey=d851f2a9ac90474abecdc2fbb148d4d7

View File

@@ -49,4 +49,9 @@ corp.id = 171cddee76471740
#TRTC
trtc.sdkAppId=1400811820
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
weixin.appId=wx6f984e535e571818
weixin.appSecret=245a483747e6e9f8762d3e8539cf0318
signKey=d851f2a9ac90474abecdc2fbb148d4d7

View File

@@ -49,4 +49,9 @@ corp.id = 171cddee76471740
#TRTC
trtc.sdkAppId=1400811820
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
trtc.secretKey=4854bab106c2ca2a2fda16a8c966933e28a078a34e458999d6227e8cd8ab8219
weixin.appId=wx6f984e535e571818
weixin.appSecret=245a483747e6e9f8762d3e8539cf0318
signKey=77fea013c3a6459685b83c21a2fc3411