文章目录
1.后端代码
代码如下(示例):
java
package com.ulinkle.base.controller.wx;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import com.ulinkle.base.api.BaseStaffService;
import com.ulinkle.base.api.LoginService;
import com.ulinkle.common.core.exception.CheckedException;
import com.ulinkle.common.core.utils.ArgumentAssert;
import com.ulinkle.common.core.web.page.DataResponse;
import com.ulinkle.domain.base.ao.BaseWxGetPhoneAo;
import com.ulinkle.domain.base.entity.BaseStaff;
import com.ulinkle.domain.base.vo.WxLoginVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Optional;
@RestController
@RequestMapping("/wx/agent")
@Api(tags = "小程序登录相关: 提货点")
@AllArgsConstructor
@Slf4j
@Validated
public class LoginWxAgentController {
private final WxMaService wxMaService;
private final BaseStaffService baseStaffService;
private final LoginService loginService;
/**
* 登陆接口
*/
@GetMapping("/login")
@ApiOperation(value = "小程序登录:如果用户已经绑定了手机号和openId,则返回值中包含token,否则返回空的token")
public DataResponse<WxLoginVo> login(@ApiParam(name = "appid", value = "微信appid", required = true)
@RequestParam("appid") @NotBlank(message = "appid不能为空") String appid,
@ApiParam(name = "code", value = "微信用户code", required = true)
@RequestParam("code") @NotBlank(message = "code不能为空") String code) {
if (StringUtils.isBlank(code)) {
return DataResponse.builderFailed("empty jscode");
}
if (!wxMaService.switchover(appid)) {
throw new CheckedException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
}
try {
WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
WxLoginVo vo = WxLoginVo.builder()
.openid(session.getOpenid())
.sessionKey(session.getSessionKey())
.unionid(session.getUnionid()).build();
Optional<BaseStaff> staffOptional = baseStaffService.getByOpenId(session.getOpenid());
BaseStaff baseStaff = staffOptional.orElse(null);
if (baseStaff != null && StringUtils.isNotEmpty(baseStaff.getTelephone())) {
String token = loginService.createToken(baseStaff);
vo.setToken(token);
log.info("用户小程序登录成功,token:{},用户ID:{},用户名称:", token, baseStaff.getId(), baseStaff.getUserName());
}
return DataResponse.builderSuccess(vo);
} catch (WxErrorException e) {
log.error(e.getMessage(), e);
return DataResponse.builderFailed(e.getMessage());
} finally {
WxMaConfigHolder.remove();//清理ThreadLocal
}
}
/**
* <pre>
* 更具手机号匹配用户openId,并绑定
* </pre>
*/
@PostMapping("/phone")
@ApiOperation(value = "小程序绑定手机号和openId,用户必须先在系统等级并填写手机号,然后通过本接口绑定手机号和openId")
public DataResponse<String> phone(@ApiParam(name = "ao", value = "参数不能为空", required = true)
@RequestBody @NotNull BaseWxGetPhoneAo ao) {
if (!wxMaService.switchover(ao.getAppid())) {
throw new CheckedException(String.format("未找到对应appid=[%s]的配置,请核实!", ao.getAppid()));
}
try {
WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(ao.getCode());
ArgumentAssert.notNull(phoneNoInfo, "获取手机号信息失败,code:{},openId:{}", ao.getCode(), ao.getOpenid());
BaseStaff staff = baseStaffService.getStaffByTelephone(phoneNoInfo.getPurePhoneNumber());
ArgumentAssert.isTrue(staff != null, "用户尚未录入,手机号:{}", phoneNoInfo.getPurePhoneNumber());
ArgumentAssert.isTrue(StringUtils.isBlank(staff.getOpenId()), "手机号已绑定其他微信账号");
//更新openId
BaseStaff updateStaff = new BaseStaff();
updateStaff.setId(staff.getId());
updateStaff.setOpenId(ao.getOpenid());
baseStaffService.updateById(updateStaff);
String token = loginService.createToken(staff);
log.info("用户小程序登录成功,token:{},用户ID:{},用户名称:{}", token, staff.getId(), staff.getUserName());
return DataResponse.builderSuccess("登录成功", token);
} catch (WxErrorException e) {
throw new CheckedException(e);
} finally {
WxMaConfigHolder.remove();//清理ThreadLocal
}
}
}
java
/**
* 创建令牌
*
* @author : zhang
* @date : 2023-01-11 9:42
*/
public String createToken(BaseStaff baseStaff) {
BaseOrg org = orgService.getById(baseStaff.getOrgId());
LoginStaffVo loginStaff = BeanPlusUtil.toBean(baseStaff, LoginStaffVo.class);
loginStaff.setOrgName(org.getOrgName());
String jsonStaff = JSON.toJSONString(loginStaff);
String encry = AESHelper.encry(jsonStaff, AESHelper.KEY);
//生成token 用户ID+年月日
String encryPre = AESHelper.encry(baseStaff.getId() + DateTimeUtils.parseDateToStr(DateTimeUtils.YYYY_MM_DD_HH_MM_SS, new Date()), AESHelper.KEY);
String token = (encryPre + ".@lasttToken").replace("@lasttToken", encry);
//设置过期时间 刷新令牌
redisTemplate.opsForValue().set(SystemConstants.getTokenKey(1,baseStaff.getUserName()), "Bearer " + token, Constants.SYS_TOKEN_EXPIRE_HOUR, TimeUnit.HOURS);
return token;
}
java
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class WxLoginVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("sessionKey")
private String sessionKey;
@ApiModelProperty("openid")
private String openid;
@ApiModelProperty("unionid")
private String unionid;
@ApiModelProperty("token:不存在需要获取手机号码")
private String token;
}
java
import
io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BaseWxGetPhoneAo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("微信appid")
@NotEmpty(message = "appid不能为空")
private String appid;
@ApiModelProperty("openid")
@NotEmpty(message = "openid不能为空")
private String openid;
@ApiModelProperty("unionid")
@NotEmpty(message = "unionid不能为空")
private String unionid;
@ApiModelProperty("获取手机号的动态code")
@NotEmpty(message = "code不能为空")
private String code;
}
xml
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>4.6.0</version>
</dependency>
2.前端代码
ai待生成