|
|
@@ -0,0 +1,199 @@
|
|
|
+package org.springblade.modules.member.service.impl;
|
|
|
+
|
|
|
+import cn.binarywang.wx.miniapp.api.WxMaService;
|
|
|
+import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import me.chanjar.weixin.common.error.WxErrorException;
|
|
|
+import org.springblade.core.launch.constant.TokenConstant;
|
|
|
+import org.springblade.core.log.exception.ServiceException;
|
|
|
+import org.springblade.core.mp.base.BaseServiceImpl;
|
|
|
+import org.springblade.core.secure.provider.IClientDetails;
|
|
|
+import org.springblade.core.secure.provider.IClientDetailsService;
|
|
|
+import org.springblade.core.tool.support.Kv;
|
|
|
+import org.springblade.core.tool.utils.DateUtil;
|
|
|
+import org.springblade.core.tool.utils.Func;
|
|
|
+import org.springblade.modules.member.entity.MemberAccountEntity;
|
|
|
+import org.springblade.modules.member.entity.MemberEntity;
|
|
|
+import org.springblade.modules.member.enums.AccountTypeEnum;
|
|
|
+import org.springblade.modules.member.mapper.MemberAccountMapper;
|
|
|
+import org.springblade.modules.member.service.IMemberAccountService;
|
|
|
+import org.springblade.modules.member.service.IMemberInfoService;
|
|
|
+import org.springblade.modules.member.util.WXTokenUtil;
|
|
|
+import org.springblade.modules.member.vo.MemberVO;
|
|
|
+import org.springblade.modules.member.wx.config.WxMaConfiguration;
|
|
|
+import org.springblade.modules.member.wx.dto.LoginTokenDTO;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.util.Date;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 服务实现类
|
|
|
+ *
|
|
|
+ * @author Chill
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@AllArgsConstructor
|
|
|
+public class MemberAccountServiceImpl extends BaseServiceImpl<MemberAccountMapper, MemberAccountEntity> implements IMemberAccountService {
|
|
|
+
|
|
|
+ private IMemberInfoService memberInfoService;
|
|
|
+
|
|
|
+ private IClientDetailsService clientDetailsService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Kv doWxMiniappRegister(String clientCode, String code) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(
|
|
|
+ rollbackFor = {Exception.class}
|
|
|
+ )
|
|
|
+ public Kv doWxMiniappLogin(String clientCode, String code, String tenantId) {
|
|
|
+
|
|
|
+ WxMaJscode2SessionResult session = this.getWxSession(clientCode, code);
|
|
|
+
|
|
|
+ Kv ret = this.SignIn(AccountTypeEnum.WX_MINI_APP.getCode(), clientCode, session.getOpenid(), session.getUnionid(), tenantId);
|
|
|
+ if (Func.isNull(ret)) {
|
|
|
+ ret = this.signUp(AccountTypeEnum.WX_MINI_APP.getCode(), clientCode, session.getOpenid(), session.getUnionid(), tenantId);
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ //登录
|
|
|
+ private Kv SignIn(String accountType, String clientCode, String account, String appendAccount, String tenantId) {
|
|
|
+ MemberAccountEntity accountEntity = this.getMemberAccount(accountType, account, appendAccount, tenantId);
|
|
|
+
|
|
|
+ //新用户,由注册流程返回信息
|
|
|
+ if (Func.isEmpty(accountEntity)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ Long memberId = accountEntity.getMemberId();
|
|
|
+ String effective = "";
|
|
|
+
|
|
|
+ MemberEntity member = memberInfoService.getById(memberId);
|
|
|
+
|
|
|
+ LoginTokenDTO loginToken = this.getLoginToken(member, accountEntity.getAccount());
|
|
|
+
|
|
|
+
|
|
|
+ return this.getAuthInfo(loginToken, effective);
|
|
|
+ }
|
|
|
+
|
|
|
+ //注册
|
|
|
+ private Kv signUp(String accountType, String clientCode, String account, String appendAccount, String tenantId) {
|
|
|
+ //1. 写member表
|
|
|
+ MemberEntity member = memberInfoService.addMember(clientCode, tenantId);
|
|
|
+
|
|
|
+ //2. 写member_account表
|
|
|
+ MemberAccountEntity accountEntity = this.addAccount(member.getId(), accountType, account, appendAccount, tenantId);
|
|
|
+
|
|
|
+
|
|
|
+ Long memberId = accountEntity.getMemberId();
|
|
|
+ String effective = "";
|
|
|
+
|
|
|
+ LoginTokenDTO loginToken = this.getLoginToken(member, accountEntity.getAccount());
|
|
|
+
|
|
|
+ return this.getAuthInfo(loginToken, effective);
|
|
|
+ }
|
|
|
+
|
|
|
+ //TODO chenjs 改造返回前端的内容,看看是否有必要返回account
|
|
|
+ private LoginTokenDTO getLoginToken(MemberEntity member, String account) {
|
|
|
+ LoginTokenDTO loginToken = new LoginTokenDTO();
|
|
|
+
|
|
|
+ MemberVO memberVO = Func.copyProperties(member, MemberVO.class);
|
|
|
+
|
|
|
+ loginToken.setId(member.getId());
|
|
|
+ loginToken.setAccount(account);
|
|
|
+ loginToken.setAvator(member.getAvator());
|
|
|
+ loginToken.setRealname(member.getRealName());
|
|
|
+ loginToken.setNickName(member.getNickName());
|
|
|
+ loginToken.setStatus(member.getStatus());
|
|
|
+ loginToken.setMemberInfo(memberVO);
|
|
|
+ loginToken.setTenantId(memberVO.getTenantId());
|
|
|
+
|
|
|
+ return loginToken;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取微信会话
|
|
|
+ private WxMaJscode2SessionResult getWxSession(String clientCode, String code) {
|
|
|
+ try {
|
|
|
+ IClientDetails clientDetail = clientDetailsService.loadClientByClientId(clientCode);
|
|
|
+ if(Func.isEmpty(clientDetail)) {
|
|
|
+ throw new ServiceException("应用id不存在");
|
|
|
+ }
|
|
|
+ final WxMaService wxService = WxMaConfiguration.getMaService(clientDetail.getClientId());
|
|
|
+ return wxService.getUserService().getSessionInfo(code);
|
|
|
+ } catch (WxErrorException e) {
|
|
|
+ throw new ServiceException("微信登录失败" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //找到现有的会员账号
|
|
|
+ private MemberAccountEntity getMemberAccount(String accountType, String account, String appendAccount, String tenantId) {
|
|
|
+ //先用unionId找账号
|
|
|
+ MemberAccountEntity accountEntity = this.getOne(Wrappers.<MemberAccountEntity>lambdaQuery()
|
|
|
+ .eq(MemberAccountEntity::getTenantId, tenantId)
|
|
|
+ .eq(MemberAccountEntity::getAccountType, accountType)
|
|
|
+ .eq(MemberAccountEntity::getAppendAccount, appendAccount)
|
|
|
+ .last("limit 1"));
|
|
|
+
|
|
|
+ if (Func.isNotEmpty(accountEntity)) {
|
|
|
+ return accountEntity;
|
|
|
+ }
|
|
|
+
|
|
|
+ //用unionId找不到账号之后再用openId找,因为第一版的用户只有openId
|
|
|
+ //TODO chenjs 目前还有22个2018年5月份进入小程序的用户没有重新登录新版本,下次检查一下,如果全部已经重新登录了就改造这个方法
|
|
|
+ accountEntity = this.getOne(Wrappers.<MemberAccountEntity>lambdaQuery()
|
|
|
+ .eq(MemberAccountEntity::getAccountType, accountType)
|
|
|
+ .eq(MemberAccountEntity::getAccount, account)
|
|
|
+ .last("limit 1"));
|
|
|
+
|
|
|
+ //如果找到了账号就将unionId写进去,下一次不再通过openId找
|
|
|
+ if (Func.isNotEmpty(accountEntity)) {
|
|
|
+ accountEntity.setAppendAccount(appendAccount);
|
|
|
+ this.updateById(accountEntity);
|
|
|
+ }
|
|
|
+
|
|
|
+ return accountEntity;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private MemberAccountEntity addAccount(Long memberId, String accountType, String account, String appendAccount, String tenantId) {
|
|
|
+
|
|
|
+ MemberAccountEntity accountEntity = new MemberAccountEntity();
|
|
|
+ accountEntity.setAccount(account);
|
|
|
+ accountEntity.setAppendAccount(appendAccount);
|
|
|
+ accountEntity.setAccountType(accountType);
|
|
|
+ accountEntity.setIsEnabled(Boolean.TRUE);
|
|
|
+ accountEntity.setMemberId(memberId);
|
|
|
+ accountEntity.setTenantId(tenantId);
|
|
|
+ this.save(accountEntity);
|
|
|
+
|
|
|
+ return accountEntity;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Date getEffectiveDate(Date oldDate, Integer effectiveDays) {
|
|
|
+ Date newDate = DateUtil.now();
|
|
|
+ if (Func.isEmpty(oldDate)) {
|
|
|
+ oldDate = DateUtil.now();
|
|
|
+ }
|
|
|
+ if (newDate.after(oldDate)) {
|
|
|
+ return DateUtil.plusDays(newDate, effectiveDays);
|
|
|
+ } else {
|
|
|
+ return DateUtil.plusDays(oldDate, effectiveDays);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private Kv getAuthInfo(LoginTokenDTO loginToken, String effective) {
|
|
|
+ Kv kv = WXTokenUtil.createAuthInfo(loginToken);
|
|
|
+
|
|
|
+ kv.set("tokenExpire", DateUtil.plusSeconds(DateUtil.now(), kv.getLong(TokenConstant.EXPIRES_IN)));
|
|
|
+ kv.set("equityEffective", effective);
|
|
|
+
|
|
|
+ return kv;
|
|
|
+ }
|
|
|
+}
|