院后微信小程序登录和个人信息接口开发完成
This commit is contained in:
parent
f098cd7d26
commit
07a2b6177b
@ -103,7 +103,7 @@ token:
|
||||
# 令牌有效期(默认30分钟)
|
||||
expireTime: 30
|
||||
# 请求拦截白名单
|
||||
ant-matchers: /postDischarge/**,/testMobile/**
|
||||
ant-matchers: /postDischarge/**,/testMobile/**,/postDischargeApplet/**
|
||||
|
||||
## MyBatis-Plus配置
|
||||
mybatis-plus:
|
||||
|
||||
@ -283,4 +283,34 @@ public class Constants {
|
||||
* 成功
|
||||
*/
|
||||
public static final int SUCCESS_ERROR_CODE = 0;
|
||||
|
||||
/**
|
||||
* 院后微信小程序登录接口地址
|
||||
*/
|
||||
public static final String APPLET_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";
|
||||
|
||||
/**
|
||||
* 微信小程序ACCESS_TOKEN前缀
|
||||
*/
|
||||
public static final String POST_DISCHARGE_APPLET_ACCESS_TOKEN = "POST_Discharge_APPLET_ACCESS_TOKEN_";
|
||||
|
||||
/**
|
||||
* 返回成功状态码
|
||||
*/
|
||||
public static final int SUCCESS_CODE = 0;
|
||||
|
||||
/**
|
||||
* 院后微信小程序获取用户手机号接口地址
|
||||
*/
|
||||
public static final String PHONE_NUMBER_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";
|
||||
|
||||
/**
|
||||
* 获取微信小程序access_token错误码
|
||||
*/
|
||||
public static final int ERROR_ACCESS_CODE = 40001;
|
||||
|
||||
/**
|
||||
* 返回成功状态码
|
||||
*/
|
||||
public static final String OK = "ok";
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package com.xinelu.manage.mapper.residentinfo;
|
||||
|
||||
import com.xinelu.manage.domain.residentinfo.ResidentInfo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@ -17,7 +19,7 @@ public interface ResidentInfoMapper {
|
||||
* @param id 居民信息主键
|
||||
* @return 居民信息
|
||||
*/
|
||||
public ResidentInfo selectResidentInfoById(Long id);
|
||||
ResidentInfo selectResidentInfoById(Long id);
|
||||
|
||||
/**
|
||||
* 查询居民信息列表
|
||||
@ -58,4 +60,13 @@ public interface ResidentInfoMapper {
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteResidentInfoByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 根据电话号码和微信小程序openid查询居民基本信息
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @param openId 微信小程序openId
|
||||
* @return 被护理人基本信息
|
||||
*/
|
||||
ResidentInfo getResidentInfoByPhoneAndOpenId(@Param("phone") String phone, @Param("openId") String openId);
|
||||
}
|
||||
|
||||
@ -183,4 +183,18 @@
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="getResidentInfoByPhoneAndOpenId" parameterType="string"
|
||||
resultType="com.xinelu.manage.domain.residentinfo.ResidentInfo">
|
||||
<include refid="selectResidentInfoVo" />
|
||||
<where>
|
||||
del_flag = 0
|
||||
<if test="phone != null and phone != ''">
|
||||
and patient_phone = #{phone}
|
||||
</if>
|
||||
<if test="openId != null and openId != ''">
|
||||
and open_id = #{openId}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
||||
@ -0,0 +1,54 @@
|
||||
package com.xinelu.mobile.controller.appletpersoncenter;
|
||||
|
||||
import com.xinelu.common.core.domain.AjaxResult;
|
||||
import com.xinelu.mobile.service.appletpersoncenter.AppletPersonCenterService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
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 javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @Description 院后小程序个人中心控制器
|
||||
* @Author 纪寒
|
||||
* @Date 2024-04-16 10:49:14
|
||||
* @Version 1.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/postDischargeApplet")
|
||||
public class AppletPersonCenterController {
|
||||
|
||||
@Resource
|
||||
private AppletPersonCenterService appletPersonCenterService;
|
||||
|
||||
/**
|
||||
* 院后微信小程序一键登录接口
|
||||
*
|
||||
* @param loginCode 登录凭证
|
||||
* @param phoneCode 获取手机号登录凭证
|
||||
* @return 微信小程序用户登录信息
|
||||
*/
|
||||
@GetMapping("/appletLogin")
|
||||
public AjaxResult appletLogin(@RequestParam("loginCode") String loginCode, @RequestParam("phoneCode") String phoneCode) {
|
||||
if (StringUtils.isBlank(loginCode)) {
|
||||
return AjaxResult.error("登录凭证编码不能为空!");
|
||||
}
|
||||
if (StringUtils.isBlank(phoneCode)) {
|
||||
return AjaxResult.error("用户手机号凭证不存在");
|
||||
}
|
||||
return appletPersonCenterService.appletLogin(loginCode, phoneCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据居民表id查询患者个人信息
|
||||
*
|
||||
* @param residentId 居民表id
|
||||
* @return 个人信息
|
||||
*/
|
||||
@GetMapping("/getResidentInfoById")
|
||||
public AjaxResult getResidentInfoById(Long residentId) {
|
||||
return appletPersonCenterService.getResidentInfoById(residentId);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.xinelu.mobile.service.appletpersoncenter;
|
||||
|
||||
import com.xinelu.common.core.domain.AjaxResult;
|
||||
|
||||
/**
|
||||
* @Description 院后小程序个人中心业务层
|
||||
* @Author 纪寒
|
||||
* @Date 2024-04-16 10:51:28
|
||||
* @Version 1.0
|
||||
*/
|
||||
public interface AppletPersonCenterService {
|
||||
|
||||
/**
|
||||
* 院后微信小程序一键登录接口
|
||||
*
|
||||
* @param loginCode 登录凭证
|
||||
* @param phoneCode 获取手机号登录凭证
|
||||
* @return 微信小程序用户登录信息
|
||||
*/
|
||||
AjaxResult appletLogin(String loginCode, String phoneCode);
|
||||
|
||||
/**
|
||||
* 根据居民表id查询患者个人信息
|
||||
*
|
||||
* @param residentId 居民表id
|
||||
* @return 个人信息
|
||||
*/
|
||||
AjaxResult getResidentInfoById(Long residentId);
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
package com.xinelu.mobile.service.appletpersoncenter.Impl;
|
||||
|
||||
import com.xinelu.common.config.WeChatAppletChatConfig;
|
||||
import com.xinelu.common.constant.Constants;
|
||||
import com.xinelu.common.core.domain.AjaxResult;
|
||||
import com.xinelu.manage.domain.residentinfo.ResidentInfo;
|
||||
import com.xinelu.manage.mapper.residentinfo.ResidentInfoMapper;
|
||||
import com.xinelu.mobile.service.appletpersoncenter.AppletPersonCenterService;
|
||||
import com.xinelu.mobile.utils.WeChatAppletUtils;
|
||||
import com.xinelu.mobile.vo.appletpersoncenter.PostDischargeAppletPhoneVO;
|
||||
import com.xinelu.mobile.vo.appletpersoncenter.PostDischargeAppletVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Description 院后小程序个人中心业务层实现类
|
||||
* @Author 纪寒
|
||||
* @Date 2024-04-16 10:52:09
|
||||
* @Version 1.0
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class AppletPersonCenterServiceImpl implements AppletPersonCenterService {
|
||||
|
||||
@Resource
|
||||
private WeChatAppletUtils weChatAppletUtils;
|
||||
@Resource
|
||||
private WeChatAppletChatConfig weChatAppletChatConfig;
|
||||
@Resource
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
@Resource
|
||||
private ResidentInfoMapper residentInfoMapper;
|
||||
|
||||
/**
|
||||
* 院后微信小程序一键登录接口
|
||||
*
|
||||
* @param loginCode 登录凭证
|
||||
* @param phoneCode 获取手机号登录凭证
|
||||
* @return 微信小程序用户登录信息
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult appletLogin(String loginCode, String phoneCode) {
|
||||
//根据code获取用户的微信unionId以及openId等信息
|
||||
PostDischargeAppletVO appletLoginInfo = weChatAppletUtils.getPostDischargeAppletLogin(weChatAppletChatConfig.getAppletId(), weChatAppletChatConfig.getSecret(), loginCode, weChatAppletChatConfig.getGrantType());
|
||||
if (Objects.isNull(appletLoginInfo)) {
|
||||
return AjaxResult.error("获取院后微信小程序用户信息失败");
|
||||
}
|
||||
if (Objects.nonNull(appletLoginInfo.getErrcode()) && appletLoginInfo.getErrcode() != Constants.SUCCESS_CODE) {
|
||||
return AjaxResult.error("获取院后微信小程序用户信息失败,失败信息为:" + appletLoginInfo.getErrmsg());
|
||||
}
|
||||
//获取微信accessToken
|
||||
String accessToken;
|
||||
String accessTokenKey = Constants.POST_DISCHARGE_APPLET_ACCESS_TOKEN + "accessToken";
|
||||
//从Redis中取出accessToken
|
||||
Object object = redisTemplate.opsForValue().get(accessTokenKey);
|
||||
if (Objects.isNull(object)) {
|
||||
accessToken = weChatAppletUtils.getWeChatAppletAccessToken();
|
||||
} else {
|
||||
accessToken = (String) object;
|
||||
}
|
||||
//获取用户手机号
|
||||
PostDischargeAppletPhoneVO appletPhoneInfo = weChatAppletUtils.getPostDischargeAppletPhone(phoneCode, accessToken);
|
||||
if (Objects.isNull(appletPhoneInfo)) {
|
||||
return AjaxResult.error("获取用户手机号失败");
|
||||
}
|
||||
if (Objects.nonNull(appletPhoneInfo.getErrcode()) && appletPhoneInfo.getErrcode() == Constants.ERROR_ACCESS_CODE) {
|
||||
//当前Redis缓存中的access_token无效直接删除
|
||||
if (Objects.nonNull(object)) {
|
||||
redisTemplate.delete(accessTokenKey);
|
||||
//删除之后重新获取获取accessToken
|
||||
accessToken = weChatAppletUtils.getWeChatAppletAccessToken();
|
||||
appletPhoneInfo = weChatAppletUtils.getPostDischargeAppletPhone(phoneCode, accessToken);
|
||||
if (Objects.isNull(appletPhoneInfo)) {
|
||||
return AjaxResult.error("获取用户手机号失败");
|
||||
}
|
||||
if (Objects.nonNull(appletPhoneInfo.getErrcode()) && appletPhoneInfo.getErrcode() == Constants.ERROR_ACCESS_CODE) {
|
||||
return AjaxResult.error("登录失败!");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(appletPhoneInfo.getErrmsg()) && !Constants.OK.equals(appletPhoneInfo.getErrmsg())) {
|
||||
return AjaxResult.error("获取用户手机号失败,失败信息为:" + appletPhoneInfo.getErrmsg());
|
||||
}
|
||||
//根据手机号和微信小程序openid判断当前用户是否存在
|
||||
String phone = StringUtils.isBlank(appletPhoneInfo.getPhoneInfo().getPhoneNumber()) ? "" : appletPhoneInfo.getPhoneInfo().getPhoneNumber();
|
||||
String openId = StringUtils.isBlank(appletLoginInfo.getOpenid()) ? "" : appletLoginInfo.getOpenid();
|
||||
ResidentInfo residentInfoByPhone = residentInfoMapper.getResidentInfoByPhoneAndOpenId(null, openId);
|
||||
ResidentInfo residentInfo = new ResidentInfo();
|
||||
//居民信息为空新增个人信息
|
||||
if (Objects.isNull(residentInfoByPhone)) {
|
||||
residentInfo.setOpenId(openId);
|
||||
residentInfo.setPatientPhone(phone);
|
||||
residentInfo.setCreateTime(LocalDateTime.now());
|
||||
residentInfoMapper.insertResidentInfo(residentInfo);
|
||||
residentInfo.setId(residentInfo.getId());
|
||||
return AjaxResult.success(residentInfo);
|
||||
}
|
||||
//更新居民信息的openid等微信标识信息
|
||||
residentInfo.setId(residentInfoByPhone.getId());
|
||||
residentInfo.setOpenId(openId);
|
||||
residentInfo.setPatientPhone(StringUtils.isBlank(residentInfoByPhone.getPatientPhone()) ? "" : residentInfoByPhone.getPatientPhone());
|
||||
residentInfo.setUpdateTime(LocalDateTime.now());
|
||||
residentInfoMapper.updateResidentInfo(residentInfo);
|
||||
return AjaxResult.success(residentInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据居民表id查询患者个人信息
|
||||
*
|
||||
* @param residentId 居民表id
|
||||
* @return 个人信息
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult getResidentInfoById(Long residentId) {
|
||||
return AjaxResult.success(residentInfoMapper.selectResidentInfoById(residentId));
|
||||
}
|
||||
}
|
||||
@ -6,11 +6,15 @@ import com.xinelu.common.constant.Constants;
|
||||
import com.xinelu.common.entity.AccessToken;
|
||||
import com.xinelu.common.exception.ServiceException;
|
||||
import com.xinelu.common.utils.http.HttpUtils;
|
||||
import com.xinelu.mobile.vo.appletpersoncenter.PostDischargeAppletPhoneVO;
|
||||
import com.xinelu.mobile.vo.appletpersoncenter.PostDischargeAppletVO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -68,4 +72,50 @@ public class WeChatAppletUtils {
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据登录编码获取微信小程序用户信息
|
||||
*
|
||||
* @param appletId 小程序id
|
||||
* @param secret 小程序秘钥
|
||||
* @param code 登录凭证码
|
||||
* @param grantType 授权类型
|
||||
* @return 登录信息
|
||||
*/
|
||||
public PostDischargeAppletVO getPostDischargeAppletLogin(String appletId, String secret, String code, String grantType) {
|
||||
//请求地址
|
||||
String appletLoginUrl = Constants.APPLET_LOGIN_URL
|
||||
+ "?appid=" + appletId
|
||||
+ "&secret=" + secret
|
||||
+ "&js_code=" + code
|
||||
+ "&grant_type=" + grantType;
|
||||
//发送请求
|
||||
String result = HttpUtils.sendGet(appletLoginUrl);
|
||||
if (StringUtils.isBlank(result)) {
|
||||
throw new ServiceException("获取院后微信小程序用户信息失败", 201);
|
||||
}
|
||||
return JSON.parseObject(result, PostDischargeAppletVO.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取院后微信小程序的手机号码
|
||||
*
|
||||
* @param code 登录凭证
|
||||
* @param accessToken 小程序accessToken
|
||||
* @return 手机信息
|
||||
*/
|
||||
public PostDischargeAppletPhoneVO getPostDischargeAppletPhone(String code, String accessToken) {
|
||||
//请求地址
|
||||
String phoneUrl = Constants.PHONE_NUMBER_URL + accessToken;
|
||||
//请求参数
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
paramMap.put("code", code);
|
||||
String param = JSON.toJSONString(paramMap);
|
||||
//发送POST请求
|
||||
String result = HttpUtils.sendPostJson(phoneUrl, param);
|
||||
if (StringUtils.isBlank(result)) {
|
||||
throw new ServiceException("获取院后微信小程序手机号失败", 201);
|
||||
}
|
||||
return JSON.parseObject(result, PostDischargeAppletPhoneVO.class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
package com.xinelu.mobile.vo.appletpersoncenter;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @Description 获取小程序用户手机号实体类
|
||||
* @Author 纪寒
|
||||
* @Date 2024-04-16 11:15:53
|
||||
* @Version 1.0
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class PostDischargeAppletPhoneVO implements Serializable {
|
||||
private static final long serialVersionUID = 7053513139462975391L;
|
||||
/**
|
||||
* 错误编码,
|
||||
* 0:成功
|
||||
* -1:系统繁忙,此时请开发者稍候再试
|
||||
* 40029:不合法的code(code不存在、已过期或者使用过)
|
||||
*/
|
||||
@JsonProperty("errcode")
|
||||
private Integer errcode;
|
||||
|
||||
/**
|
||||
* 返回提示信息,ok:成功
|
||||
*/
|
||||
@JsonProperty("errmsg")
|
||||
private String errmsg;
|
||||
|
||||
/**
|
||||
* 电话信息实体类
|
||||
*/
|
||||
@JsonProperty("phone_info")
|
||||
private PhoneInfoDTO phoneInfo;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class PhoneInfoDTO {
|
||||
|
||||
/**
|
||||
* 用户绑定的手机号(国外手机号会有区号)
|
||||
*/
|
||||
@JsonProperty("phoneNumber")
|
||||
private String phoneNumber;
|
||||
|
||||
/**
|
||||
* 没有区号的手机号
|
||||
*/
|
||||
@JsonProperty("purePhoneNumber")
|
||||
private String purePhoneNumber;
|
||||
|
||||
/**
|
||||
* 区号
|
||||
*/
|
||||
@JsonProperty("countryCode")
|
||||
private Integer countryCode;
|
||||
|
||||
/**
|
||||
* 数据水印
|
||||
*/
|
||||
@JsonProperty("watermark")
|
||||
private WatermarkDTO watermark;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class WatermarkDTO {
|
||||
|
||||
/**
|
||||
* 用户获取手机号操作的时间戳
|
||||
*/
|
||||
@JsonProperty("timestamp")
|
||||
private Integer timestamp;
|
||||
|
||||
/**
|
||||
* 小程序appid
|
||||
*/
|
||||
@JsonProperty("appid")
|
||||
private String appid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.xinelu.mobile.vo.appletpersoncenter;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @Description 院后微信小程序用户信息实体类
|
||||
* @Author 纪寒
|
||||
* @Date 2024-04-16 10:56:22
|
||||
* @Version 1.0
|
||||
*/
|
||||
@Data
|
||||
public class PostDischargeAppletVO implements Serializable {
|
||||
private static final long serialVersionUID = 9163624256938346478L;
|
||||
/**
|
||||
* 小程序unionid
|
||||
*/
|
||||
private String unionid;
|
||||
|
||||
/**
|
||||
* 小程序openid
|
||||
*/
|
||||
private String openid;
|
||||
|
||||
/**
|
||||
* 错误状态码,40029:js_code无效,45011:API 调用太频繁,请稍候再试
|
||||
* 40226:高风险等级用户,小程序登录拦截 ,-1:系统繁忙,此时请开发者稍候再试
|
||||
*/
|
||||
private Integer errcode;
|
||||
|
||||
/**
|
||||
* 状态信息,取值有,40029:code 无效,
|
||||
* 45011:api minute-quota reach limit mustslower retry next minute
|
||||
* 40226:code blocked
|
||||
* -1:system error
|
||||
*/
|
||||
private String errmsg;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user