Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop

This commit is contained in:
Chopper711 2023-03-10 09:37:34 +08:00
commit 79ccab6869
40 changed files with 704 additions and 477 deletions

View File

@ -47,7 +47,7 @@ public class ConnectBuyerWebController {
@GetMapping("/login/web/{type}") @GetMapping("/login/web/{type}")
@ApiOperation(value = "WEB信任登录授权") @ApiOperation(value = "WEB信任登录授权,包含PC、WAP")
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "type", value = "登录方式:QQ,微信,微信_PC", @ApiImplicitParam(name = "type", value = "登录方式:QQ,微信,微信_PC",
allowableValues = "QQ,WECHAT,WECHAT_PC", paramType = "path") allowableValues = "QQ,WECHAT,WECHAT_PC", paramType = "path")
@ -75,25 +75,13 @@ public class ConnectBuyerWebController {
return connectUtil.getResult(state); return connectUtil.getResult(state);
} }
@GetMapping("/register/auto") @ApiOperation(value = "APP-unionID登录")
@ApiOperation(value = "WEB信任登录授权")
public ResultMessage<Token> webAuthorize() {
Token token = memberService.autoRegister();
return ResultUtil.data(token);
}
@ApiOperation(value = "unionID登录")
@ApiImplicitParams({
@ApiImplicitParam(name = "openId", value = "openid", required = true, paramType = "query"),
@ApiImplicitParam(name = "type", value = "联合类型", required = true,
allowableValues = "WECHAT,QQ,ALIPAY,WEIBO,APPLE", paramType = "query"),
@ApiImplicitParam(name = "uniAccessToken", value = "联合登陆返回的accessToken", required = true, paramType = "query")
})
@GetMapping("/app/login") @GetMapping("/app/login")
public ResultMessage<Token> unionLogin(ConnectAuthUser authUser, @RequestHeader("uuid") String uuid) { public ResultMessage<Token> unionLogin(ConnectAuthUser authUser, @RequestHeader("uuid") String uuid) {
try { try {
return ResultUtil.data(connectService.appLoginCallback(authUser, uuid)); return ResultUtil.data(connectService.unionLoginCallback(authUser, uuid));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
log.error("unionID登录错误", e); log.error("unionID登录错误", e);
} }
return null; return null;

View File

@ -9,12 +9,18 @@ import cn.lili.common.security.context.UserContext;
import cn.lili.common.vo.ResultMessage; import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.service.MemberService; import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.WithdrawalSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.entity.vo.WithdrawalSettingVO;
import cn.lili.modules.system.service.SettingService;
import cn.lili.modules.verification.entity.enums.VerificationEnums; import cn.lili.modules.verification.entity.enums.VerificationEnums;
import cn.lili.modules.verification.service.VerificationService; import cn.lili.modules.verification.service.VerificationService;
import cn.lili.modules.wallet.entity.dos.MemberWallet; import cn.lili.modules.wallet.entity.dos.MemberWallet;
import cn.lili.modules.wallet.entity.vo.MemberWalletVO; import cn.lili.modules.wallet.entity.vo.MemberWalletVO;
import cn.lili.modules.wallet.service.MemberWalletService; import cn.lili.modules.wallet.service.MemberWalletService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiImplicitParams;
@ -25,7 +31,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.Max; import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.Pattern; import javax.validation.constraints.Pattern;
/** /**
@ -56,6 +61,9 @@ public class MemberWalletBuyerController {
@Autowired @Autowired
private VerificationService verificationService; private VerificationService verificationService;
@Autowired
private SettingService settingService;
@GetMapping @GetMapping
@ApiOperation(value = "查询会员预存款余额") @ApiOperation(value = "查询会员预存款余额")
public ResultMessage<MemberWalletVO> get() { public ResultMessage<MemberWalletVO> get() {
@ -66,6 +74,31 @@ public class MemberWalletBuyerController {
throw new ServiceException(ResultCode.USER_NOT_LOGIN); throw new ServiceException(ResultCode.USER_NOT_LOGIN);
} }
@GetMapping(value = "/withdrawalSettingVO")
@ApiOperation(value = "获取提现设置VO")
public ResultMessage<Object> minPrice() {
Setting setting = settingService.get(SettingEnum.WITHDRAWAL_SETTING.name());
WithdrawalSetting withdrawalSetting = new Gson().fromJson(setting.getSettingValue(), WithdrawalSetting.class);
WithdrawalSettingVO withdrawalSettingVO = new WithdrawalSettingVO();
withdrawalSettingVO.setMinPrice(withdrawalSetting.getMinPrice());
withdrawalSettingVO.setFee(withdrawalSetting.getFee());
withdrawalSettingVO.setType(withdrawalSetting.getType());
return ResultUtil.data(withdrawalSettingVO);
}
@PreventDuplicateSubmissions
@PostMapping(value = "/withdrawal")
@ApiOperation(value = "会员中心余额提现")
@ApiImplicitParams({
@ApiImplicitParam(name = "price", value = "提现金额", required = true, dataType = "double", paramType = "query"),
@ApiImplicitParam(name = "realName", value = "真实姓名", required = true, dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "connectNumber", value = "第三方登录账号", required = true, dataType = "String", paramType = "query")
})
public ResultMessage<Boolean> withdrawal(@Max(value = 9999, message = "充值金额单次最多允许提现9999元") Double price, @RequestParam String realName, @RequestParam String connectNumber) {
return ResultUtil.data(memberWalletService.applyWithdrawal(price, realName, connectNumber));
}
@PostMapping(value = "/set-password") @PostMapping(value = "/set-password")
@ApiOperation(value = "设置支付密码") @ApiOperation(value = "设置支付密码")
@ApiImplicitParams({ @ApiImplicitParams({
@ -122,18 +155,4 @@ public class MemberWalletBuyerController {
return memberWalletService.checkPassword(); return memberWalletService.checkPassword();
} }
@PreventDuplicateSubmissions
@PostMapping(value = "/withdrawal")
@ApiOperation(value = "会员中心余额提现")
@ApiImplicitParams({
@ApiImplicitParam(name = "price", value = "提现金额", required = true, dataType = "double", paramType = "query")
})
public ResultMessage<Boolean> withdrawal(
@Max(value = 9999, message = "提现金额单次最多允许提现9999元")
@Min(value = 1, message = "提现金额单次最少提现金额为1元")
Double price) {
return ResultUtil.data(memberWalletService.applyWithdrawal(price));
}
} }

View File

@ -24,13 +24,13 @@ spring:
boot: boot:
admin: admin:
client: client:
url: http://192.168.0.116:8000 url: http://192.168.0.108:8000
cache: cache:
type: redis type: redis
# Redis # Redis
redis: redis:
host: 127.0.0.1 host: 192.168.0.108
port: 6379 port: 30379
password: lilishop password: lilishop
lettuce: lettuce:
pool: pool:
@ -60,7 +60,7 @@ spring:
default-datasource: default-datasource:
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/lilishop?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai url: jdbc:mysql://192.168.0.108:30306/kuaidi100?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: root username: root
password: lilishop password: lilishop
maxActive: 50 maxActive: 50
@ -241,16 +241,16 @@ lili:
sk: zhNKVrJK6UPOhqIjn8AQvG37b9sz6 sk: zhNKVrJK6UPOhqIjn8AQvG37b9sz6
#域名 #域名
domain: domain:
pc: http://192.168.0.116:8888 pc: http://192.168.0.108:8888
wap: http://192.168.0.116:8888 wap: http://192.168.0.108:8888
seller: http://192.168.0.116:8888 seller: http://192.168.0.108:8888
admin: http://192.168.0.116:8888 admin: http://192.168.0.108:8888
#api地址 #api地址
api: api:
buyer: https://z171l91606.51mypc.cn buyer: https://z171l91606.51mypc.cn
base: http://192.168.0.116:8888 base: http://192.168.0.108:8888
manager: http://192.168.0.116:8888 manager: http://192.168.0.108:8888
seller: http://192.168.0.116:8888 seller: http://192.168.0.108:8888
# jwt 细节设定 # jwt 细节设定
jwt-setting: jwt-setting:
@ -269,7 +269,7 @@ lili:
data: data:
elasticsearch: elasticsearch:
cluster-name: elasticsearch cluster-name: elasticsearch
cluster-nodes: 127.0.0.1:9200 cluster-nodes: 192.168.0.108:30920
index: index:
number-of-replicas: 0 number-of-replicas: 0
number-of-shards: 3 number-of-shards: 3
@ -301,7 +301,7 @@ lili:
after-sale-topic: lili_after_sale_topic after-sale-topic: lili_after_sale_topic
after-sale-group: lili_after_sale_group after-sale-group: lili_after_sale_group
rocketmq: rocketmq:
name-server: 127.0.0.1:9876 name-server: 192.168.0.108:30876
isVIPChannel: false isVIPChannel: false
producer: producer:
group: lili_group group: lili_group
@ -310,7 +310,7 @@ rocketmq:
xxl: xxl:
job: job:
admin: admin:
addresses: http://127.0.0.1:9001/xxl-job-admin addresses: http://192.168.0.108:9001/xxl-job-admin
executor: executor:
appname: xxl-job-executor-lilishop appname: xxl-job-executor-lilishop
address: address:

View File

@ -0,0 +1,21 @@
package cn.lili.event;
import cn.lili.modules.connect.entity.dto.ConnectAuthUser;
import cn.lili.modules.member.entity.dos.Member;
/**
* 会员联合登录消息
*
* @author Chopper
* @since 2020/11/17 7:13 下午
*/
public interface MemberConnectLoginEvent {
/**
* 会员联合登录
*
* @param member 会员
* @param authUser 第三方登录
*/
void memberConnectLogin(Member member, ConnectAuthUser authUser);
}

View File

@ -1,25 +1,58 @@
package cn.lili.event.impl; package cn.lili.event.impl;
import cn.hutool.core.util.StrUtil;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.event.MemberConnectLoginEvent;
import cn.lili.event.MemberLoginEvent; import cn.lili.event.MemberLoginEvent;
import cn.lili.modules.connect.entity.dto.ConnectAuthUser;
import cn.lili.modules.connect.entity.enums.ConnectEnum;
import cn.lili.modules.connect.entity.enums.SourceEnum;
import cn.lili.modules.connect.service.ConnectService;
import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.service.MemberService; import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.system.service.SettingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/** /**
* 会员自身业务 * 会员自身业务
* 会员登录会员第三方登录
* *
* @author Chopper * @author Chopper
* @version v1.0 * @version v1.0
* 2022-01-11 11:08 * 2022-01-11 11:08
*/ */
@Slf4j
@Service @Service
public class MemberExecute implements MemberLoginEvent { public class MemberExecute implements MemberLoginEvent, MemberConnectLoginEvent {
@Autowired @Autowired
private MemberService memberService; private MemberService memberService;
@Autowired
private ConnectService connectService;
@Autowired
private SettingService settingService;
@Override @Override
public void memberLogin(Member member) { public void memberLogin(Member member) {
memberService.updateMemberLoginTime(member.getId()); memberService.updateMemberLoginTime(member.getId());
} }
@Override
public void memberConnectLogin(Member member, ConnectAuthUser authUser) {
log.info("unionid:"+authUser.getToken().getUnionId());
log.info("openid:"+authUser.getUuid());
//保存UnionID
if (StrUtil.isNotBlank(authUser.getToken().getUnionId())) {
connectService.loginBindUser(member.getId(), authUser.getToken().getUnionId(), authUser.getSource());
}
//保存OpenID
if (StrUtil.isNotBlank(authUser.getUuid())) {
log.info("authUser.getSource():"+authUser.getSource());
log.info("authUser.getType():"+authUser.getType());
SourceEnum sourceEnum = SourceEnum.getSourceEnum(ConnectEnum.valueOf(authUser.getSource()), ClientTypeEnum.valueOf(authUser.getType()));
connectService.loginBindUser(member.getId(), authUser.getUuid(), sourceEnum.name());
}
}
} }

View File

@ -1,8 +1,11 @@
package cn.lili.event.impl; package cn.lili.event.impl;
import cn.lili.event.MemberRegisterEvent; import cn.lili.event.MemberWithdrawalEvent;
import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.wallet.entity.dto.MemberWalletUpdateDTO;
import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage;
import cn.lili.modules.wallet.entity.enums.DepositServiceTypeEnum;
import cn.lili.modules.wallet.entity.enums.WithdrawStatusEnum;
import cn.lili.modules.wallet.service.MemberWalletService; import cn.lili.modules.wallet.service.MemberWalletService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -14,14 +17,31 @@ import org.springframework.stereotype.Service;
* @since 2020-07-03 11:20 * @since 2020-07-03 11:20
*/ */
@Service @Service
public class MemberWalletExecute implements MemberRegisterEvent { public class MemberWalletExecute implements MemberWithdrawalEvent {
@Autowired @Autowired
private MemberWalletService memberWalletService; private MemberWalletService memberWalletService;
@Override @Override
public void memberRegister(Member member) { public void memberWithdrawal(MemberWithdrawalMessage memberWithdrawalMessage) {
// 有些情况下会同时创建一个member_id的两条数据 switch (WithdrawStatusEnum.valueOf(memberWithdrawalMessage.getStatus())) {
// memberWalletService.save(member.getId(),member.getUsername()); case VIA_AUDITING:
memberWalletService.withdrawal(memberWithdrawalMessage.getMemberWithdrawApplyId());
break;
case SUCCESS:
//提现成功扣减冻结金额
memberWalletService.reduceFrozen(
new MemberWalletUpdateDTO(memberWithdrawalMessage.getPrice(), memberWithdrawalMessage.getMemberId(), "提现成功,余额提现", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
break;
case ERROR:
//需要从冻结金额扣减到余额
memberWalletService.increaseWithdrawal(new MemberWalletUpdateDTO(memberWithdrawalMessage.getPrice(), memberWithdrawalMessage.getMemberId(), "提现失败,提现金额解冻到余额", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
break;
case FAIL_AUDITING:
//需要从冻结金额扣减到余额
memberWalletService.increaseWithdrawal(new MemberWalletUpdateDTO(memberWithdrawalMessage.getPrice(), memberWithdrawalMessage.getMemberId(), "审核拒绝,提现金额解冻到余额", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
default:
break;
}
} }
} }

View File

@ -16,7 +16,6 @@ import cn.lili.modules.order.order.service.OrderService;
import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum; import cn.lili.modules.order.trade.entity.enums.AfterSaleStatusEnum;
import cn.lili.modules.order.trade.entity.enums.AfterSaleTypeEnum; import cn.lili.modules.order.trade.entity.enums.AfterSaleTypeEnum;
import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage; import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage;
import cn.lili.modules.wallet.entity.enums.MemberWithdrawalDestinationEnum;
import cn.lili.modules.wallet.entity.enums.WithdrawStatusEnum; import cn.lili.modules.wallet.entity.enums.WithdrawStatusEnum;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -179,60 +178,30 @@ public class NoticeMessageExecute implements TradeEvent, OrderStatusChangeEvent,
public void memberWithdrawal(MemberWithdrawalMessage memberWithdrawalMessage) { public void memberWithdrawal(MemberWithdrawalMessage memberWithdrawalMessage) {
NoticeMessageDTO noticeMessageDTO = new NoticeMessageDTO(); NoticeMessageDTO noticeMessageDTO = new NoticeMessageDTO();
noticeMessageDTO.setMemberId(memberWithdrawalMessage.getMemberId()); noticeMessageDTO.setMemberId(memberWithdrawalMessage.getMemberId());
//如果提现状态为申请则发送申请提现站内消息 Map<String, String> params = new HashMap<>(2);
if (memberWithdrawalMessage.getStatus().equals(WithdrawStatusEnum.APPLY.name())) { switch (WithdrawStatusEnum.valueOf(memberWithdrawalMessage.getStatus())) {
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_CREATE); case APPLY:
Map<String, String> params = new HashMap<>(2); //如果提现状态为申请则发送申请提现站内消息
params.put("price", memberWithdrawalMessage.getPrice().toString()); noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_CREATE);
noticeMessageDTO.setParameter(params); break;
//发送提现申请成功消息 case FAIL_AUDITING:
noticeMessageService.noticeMessage(noticeMessageDTO); noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_AUDIT_ERROR);
} break;
//如果提现状态为通过则发送审核通过站内消息 case SUCCESS:
if (memberWithdrawalMessage.getStatus().equals(WithdrawStatusEnum.VIA_AUDITING.name())) {
//如果提现到余额
if (memberWithdrawalMessage.getDestination().equals(MemberWithdrawalDestinationEnum.WALLET.name())) {
//组织参数
Map<String, String> params = new HashMap<>(2);
params.put("income", memberWithdrawalMessage.getPrice().toString());
noticeMessageDTO.setParameter(params);
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_SUCCESS); noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_SUCCESS);
//发送提现成功消息 break;
noticeMessageService.noticeMessage(noticeMessageDTO); case ERROR:
params.put("income", memberWithdrawalMessage.getPrice().toString()); noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_ERROR);
params.put("expenditure", "0"); break;
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_CHANGE); case VIA_AUDITING:
noticeMessageDTO.setParameter(params); noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_AUDIT_SUCCESS);
//发送余额变动消息 default:
noticeMessageService.noticeMessage(noticeMessageDTO); break;
}
//如果提现到微信
if (memberWithdrawalMessage.getDestination().equals(MemberWithdrawalDestinationEnum.WECHAT.name())) {
Map<String, String> params = new HashMap<>(2);
params.put("income", memberWithdrawalMessage.getPrice().toString());
noticeMessageDTO.setParameter(params);
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_WEICHAT_SUCCESS);
//发送提现成功消息
noticeMessageService.noticeMessage(noticeMessageDTO);
params.put("income", "0");
params.put("expenditure", memberWithdrawalMessage.getPrice().toString());
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_CHANGE);
noticeMessageDTO.setParameter(params);
//发送余额变动消息
noticeMessageService.noticeMessage(noticeMessageDTO);
}
}
//如果提现状态为拒绝则发送审核拒绝站内消息
if (memberWithdrawalMessage.getStatus().equals(WithdrawStatusEnum.FAIL_AUDITING.name())) {
noticeMessageDTO.setNoticeMessageNodeEnum(NoticeMessageNodeEnum.WALLET_WITHDRAWAL_ERROR);
Map<String, String> params = new HashMap<>(2);
params.put("price", memberWithdrawalMessage.getPrice().toString());
noticeMessageDTO.setParameter(params);
//发送提现申请成功消息
noticeMessageService.noticeMessage(noticeMessageDTO);
} }
params.put("price", memberWithdrawalMessage.getPrice().toString());
noticeMessageDTO.setParameter(params);
//发送提现申请消息
noticeMessageService.noticeMessage(noticeMessageDTO);
} }
} }

View File

@ -3,6 +3,7 @@ package cn.lili.listener;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import cn.lili.event.*; import cn.lili.event.*;
import cn.lili.event.impl.ImTalkExecute; import cn.lili.event.impl.ImTalkExecute;
import cn.lili.modules.connect.entity.dto.MemberConnectLoginMessage;
import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.entity.dos.MemberSign; import cn.lili.modules.member.entity.dos.MemberSign;
import cn.lili.modules.member.entity.dto.MemberPointMessage; import cn.lili.modules.member.entity.dto.MemberPointMessage;
@ -55,10 +56,10 @@ public class MemberMessageListener implements RocketMQListener<MessageExt> {
*/ */
@Autowired @Autowired
private List<MemberLoginEvent> memberLoginEvents; private List<MemberLoginEvent> memberLoginEvents;
@Autowired @Autowired
private List<MemberInfoChangeEvent> memberInfoChangeEvents; private List<MemberInfoChangeEvent> memberInfoChangeEvents;
@Autowired
private List<MemberConnectLoginEvent> memberConnectLoginEvents;
@Override @Override
public void onMessage(MessageExt messageExt) { public void onMessage(MessageExt messageExt) {
@ -77,7 +78,7 @@ public class MemberMessageListener implements RocketMQListener<MessageExt> {
} }
} }
break; break;
//用户登录
case MEMBER_LOGIN: case MEMBER_LOGIN:
for (MemberLoginEvent memberLoginEvent : memberLoginEvents) { for (MemberLoginEvent memberLoginEvent : memberLoginEvents) {
@ -139,6 +140,20 @@ public class MemberMessageListener implements RocketMQListener<MessageExt> {
} }
} }
break; break;
//用户第三方登录
case MEMBER_CONNECT_LOGIN:
for (MemberConnectLoginEvent memberConnectLoginEvent : memberConnectLoginEvents) {
try {
MemberConnectLoginMessage memberConnectLoginMessage = JSONUtil.toBean(new String(messageExt.getBody()), MemberConnectLoginMessage.class);
memberConnectLoginEvent.memberConnectLogin(memberConnectLoginMessage.getMember(), memberConnectLoginMessage.getConnectAuthUser());
} catch (Exception e) {
log.error("会员{},在{}业务中,状态修改事件执行异常",
new String(messageExt.getBody()),
memberConnectLoginEvent.getClass().getName(),
e);
}
}
break;
default: default:
break; break;
} }

View File

@ -31,7 +31,7 @@ public enum ClientTypeEnum {
*/ */
UNKNOWN("未知"); UNKNOWN("未知");
private final String clientName; private String clientName;
ClientTypeEnum(String des) { ClientTypeEnum(String des) {
this.clientName = des; this.clientName = des;

View File

@ -257,9 +257,10 @@ public enum ResultCode {
WALLET_WITHDRAWAL_FROZEN_AMOUNT_INSUFFICIENT(34006, "冻结金额不足,无法处理提现申请请求!"), WALLET_WITHDRAWAL_FROZEN_AMOUNT_INSUFFICIENT(34006, "冻结金额不足,无法处理提现申请请求!"),
WALLET_ERROR_INSUFFICIENT(34003, "零钱提现失败!"), WALLET_ERROR_INSUFFICIENT(34003, "零钱提现失败!"),
WALLET_REMARK_ERROR(34004, "请填写审核备注!"), WALLET_REMARK_ERROR(34004, "请填写审核备注!"),
WALLET_EXIT_ERROR(34000, "钱包已存在,无法重复创建"), WALLET_EXIT_ERROR(34005, "钱包已存在,无法重复创建"),
WALLET_APPLY_ERROR(34005, "提现申请异常!"), WALLET_APPLY_ERROR(34006, "提现申请异常!"),
WALLET_WITHDRAWAL_AMOUNT_ERROR(34006, "申请提现金额异常!"), WALLET_APPLY_MIN_PRICE_ERROR(34007, "提现最低提现金额错误!"),
WALLET_WITHDRAWAL_AMOUNT_ERROR(34008, "申请提现金额异常!"),
/** /**
* 评价 * 评价
*/ */

View File

@ -11,7 +11,7 @@ package cn.lili.modules.connect.config;
public enum ConnectAuthEnum implements ConnectAuth { public enum ConnectAuthEnum implements ConnectAuth {
/** /**
* 微信开放平台 * 微信公众号登录
*/ */
WECHAT { WECHAT {
@Override @Override
@ -32,6 +32,7 @@ public enum ConnectAuthEnum implements ConnectAuth {
/** /**
* 微信开放平台 * 微信开放平台
* 微信PC登录
*/ */
WECHAT_PC { WECHAT_PC {
@Override @Override

View File

@ -67,6 +67,12 @@ public class ConnectAuthUser implements Serializable {
* 用户来源 * 用户来源
*/ */
private String source; private String source;
/**
* 类型
* 例如PCWAP小程序
*/
private String type;
/** /**
* 用户授权的token信息 * 用户授权的token信息
*/ */
@ -81,4 +87,9 @@ public class ConnectAuthUser implements Serializable {
*/ */
private ConnectAuthEnum connectEnum; private ConnectAuthEnum connectEnum;
/**
* 手机号
*/
private String phone;
} }

View File

@ -0,0 +1,14 @@
package cn.lili.modules.connect.entity.dto;
import cn.lili.modules.member.entity.dos.Member;
import lombok.Data;
/**
* 会员联合登录消息
*/
@Data
public class MemberConnectLoginMessage {
private Member member;
private ConnectAuthUser connectAuthUser;
}

View File

@ -15,8 +15,6 @@ public enum ConnectEnum {
WEIBO("微博联合登录"), WEIBO("微博联合登录"),
//只存放unionid //只存放unionid
WECHAT("微信联合登录"), WECHAT("微信联合登录"),
WECHAT_OPEN_ID("微信openid登录"),
WECHAT_MP_OPEN_ID("微信openid登录"),
ALIPAY("支付宝登录"), ALIPAY("支付宝登录"),
APPLE("苹果登录"); APPLE("苹果登录");

View File

@ -0,0 +1,62 @@
package cn.lili.modules.connect.entity.enums;
import cn.lili.common.enums.ClientTypeEnum;
/**
* 联合登陆-渠道枚举
*
* @author Chopper
* @version v4.0
* @since 2020/11/25 18:20
*/
public enum SourceEnum {
WECHAT_PC_OPEN_ID("微信PC应用 openid登录"),
WECHAT_OFFIACCOUNT_OPEN_ID("微信公众号 openid登录"),
WECHAT_MP_OPEN_ID("微信小程序 openid登录"),
WECHAT_APP_OPEN_ID("微信APP openid登录"),
QQ_APP_OPEN_ID("QQ APP openid登录"),
QQ_PC_OPEN_ID("QQ PC应用 openid登录"),
QQ_H5_OPEN_ID("QQ H5应用 openid登录"),
APPLE_OPEN_ID("苹果 openid登录"),
;
private final String description;
SourceEnum(String description) {
this.description = description;
}
public static SourceEnum getSourceEnum(ConnectEnum source, ClientTypeEnum type) {
switch (source) {
case WECHAT:
switch (type) {
case APP:
return WECHAT_APP_OPEN_ID;
case WECHAT_MP:
return WECHAT_MP_OPEN_ID;
case PC:
return WECHAT_PC_OPEN_ID;
case H5:
return WECHAT_OFFIACCOUNT_OPEN_ID;
}
break;
case QQ:
switch (type) {
case APP:
return QQ_APP_OPEN_ID;
case PC:
return QQ_PC_OPEN_ID;
case H5:
return QQ_H5_OPEN_ID;
}
break;
case APPLE:
return APPLE_OPEN_ID;
}
return null;
}
}

View File

@ -2,6 +2,8 @@ package cn.lili.modules.connect.request;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.lili.cache.Cache; import cn.lili.cache.Cache;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.common.utils.HttpUtils;
import cn.lili.common.utils.StringUtils; import cn.lili.common.utils.StringUtils;
import cn.lili.common.utils.UrlBuilder; import cn.lili.common.utils.UrlBuilder;
import cn.lili.modules.connect.config.AuthConfig; import cn.lili.modules.connect.config.AuthConfig;
@ -12,9 +14,9 @@ import cn.lili.modules.connect.entity.dto.AuthToken;
import cn.lili.modules.connect.entity.dto.ConnectAuthUser; import cn.lili.modules.connect.entity.dto.ConnectAuthUser;
import cn.lili.modules.connect.entity.enums.AuthResponseStatus; import cn.lili.modules.connect.entity.enums.AuthResponseStatus;
import cn.lili.modules.connect.entity.enums.AuthUserGender; import cn.lili.modules.connect.entity.enums.AuthUserGender;
import cn.lili.modules.connect.entity.enums.ConnectEnum;
import cn.lili.modules.connect.exception.AuthException; import cn.lili.modules.connect.exception.AuthException;
import cn.lili.modules.connect.util.GlobalAuthUtils; import cn.lili.modules.connect.util.GlobalAuthUtils;
import cn.lili.common.utils.HttpUtils;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import java.util.Map; import java.util.Map;
@ -67,7 +69,8 @@ public class BaseAuthQQRequest extends BaseAuthRequest {
.uuid(openId) .uuid(openId)
.gender(AuthUserGender.getRealGender(object.getString("gender"))) .gender(AuthUserGender.getRealGender(object.getString("gender")))
.token(authToken) .token(authToken)
.source(source.toString()) .source(ConnectEnum.QQ.name())
.type(ClientTypeEnum.PC.name())
.build(); .build();
} }

View File

@ -1,6 +1,8 @@
package cn.lili.modules.connect.request; package cn.lili.modules.connect.request;
import cn.lili.cache.Cache; import cn.lili.cache.Cache;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.common.utils.HttpUtils;
import cn.lili.common.utils.UrlBuilder; import cn.lili.common.utils.UrlBuilder;
import cn.lili.modules.connect.config.AuthConfig; import cn.lili.modules.connect.config.AuthConfig;
import cn.lili.modules.connect.config.ConnectAuthEnum; import cn.lili.modules.connect.config.ConnectAuthEnum;
@ -10,8 +12,9 @@ import cn.lili.modules.connect.entity.dto.AuthToken;
import cn.lili.modules.connect.entity.dto.ConnectAuthUser; import cn.lili.modules.connect.entity.dto.ConnectAuthUser;
import cn.lili.modules.connect.entity.enums.AuthResponseStatus; import cn.lili.modules.connect.entity.enums.AuthResponseStatus;
import cn.lili.modules.connect.entity.enums.AuthUserGender; import cn.lili.modules.connect.entity.enums.AuthUserGender;
import cn.lili.modules.connect.entity.enums.ConnectEnum;
import cn.lili.modules.connect.entity.enums.SourceEnum;
import cn.lili.modules.connect.exception.AuthException; import cn.lili.modules.connect.exception.AuthException;
import cn.lili.common.utils.HttpUtils;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
/** /**
@ -56,10 +59,11 @@ public class BaseAuthWeChatPCRequest extends BaseAuthRequest {
.nickname(object.getString("nickname")) .nickname(object.getString("nickname"))
.avatar(object.getString("headimgurl")) .avatar(object.getString("headimgurl"))
.location(location) .location(location)
.uuid(authToken.getUnionId()) .uuid(authToken.getOpenId())
.gender(AuthUserGender.getWechatRealGender(object.getString("sex"))) .gender(AuthUserGender.getWechatRealGender(object.getString("sex")))
.token(authToken) .token(authToken)
.source(source.toString()) .source(ConnectEnum.WECHAT.name())
.type(ClientTypeEnum.PC.name())
.build(); .build();
} }
@ -112,6 +116,7 @@ public class BaseAuthWeChatPCRequest extends BaseAuthRequest {
*/ */
@Override @Override
public String authorize(String state) { public String authorize(String state) {
return UrlBuilder.fromBaseUrl(source.authorize()) return UrlBuilder.fromBaseUrl(source.authorize())
.queryParam("response_type", "code") .queryParam("response_type", "code")
.queryParam("appid", config.getClientId()) .queryParam("appid", config.getClientId())

View File

@ -1,6 +1,8 @@
package cn.lili.modules.connect.request; package cn.lili.modules.connect.request;
import cn.lili.cache.Cache; import cn.lili.cache.Cache;
import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.common.utils.HttpUtils;
import cn.lili.common.utils.UrlBuilder; import cn.lili.common.utils.UrlBuilder;
import cn.lili.modules.connect.config.AuthConfig; import cn.lili.modules.connect.config.AuthConfig;
import cn.lili.modules.connect.config.ConnectAuthEnum; import cn.lili.modules.connect.config.ConnectAuthEnum;
@ -10,9 +12,10 @@ import cn.lili.modules.connect.entity.dto.AuthToken;
import cn.lili.modules.connect.entity.dto.ConnectAuthUser; import cn.lili.modules.connect.entity.dto.ConnectAuthUser;
import cn.lili.modules.connect.entity.enums.AuthResponseStatus; import cn.lili.modules.connect.entity.enums.AuthResponseStatus;
import cn.lili.modules.connect.entity.enums.AuthUserGender; import cn.lili.modules.connect.entity.enums.AuthUserGender;
import cn.lili.modules.connect.entity.enums.ConnectEnum;
import cn.lili.modules.connect.entity.enums.SourceEnum;
import cn.lili.modules.connect.exception.AuthException; import cn.lili.modules.connect.exception.AuthException;
import cn.lili.modules.connect.util.GlobalAuthUtils; import cn.lili.modules.connect.util.GlobalAuthUtils;
import cn.lili.common.utils.HttpUtils;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
/** /**
@ -61,7 +64,8 @@ public class BaseAuthWeChatRequest extends BaseAuthRequest {
.uuid(openId) .uuid(openId)
.gender(AuthUserGender.getWechatRealGender(object.getString("sex"))) .gender(AuthUserGender.getWechatRealGender(object.getString("sex")))
.token(authToken) .token(authToken)
.source(source.toString()) .source(ConnectEnum.WECHAT.name())
.type(ClientTypeEnum.H5.name())
.build(); .build();
} }

View File

@ -28,27 +28,14 @@ public interface ConnectService extends IService<Connect> {
*/ */
String CONNECT_TYPE = "CONNECT_TYPE"; String CONNECT_TYPE = "CONNECT_TYPE";
/**
* 联合登陆
*
* @param type 类型
* @param unionid unionid
* @param longTerm 是否长时间有效
* @param uuid UUID
* @return token
* @throws NoPermissionException 不允许操作
*/
Token unionLoginCallback(String type, String unionid, String uuid, boolean longTerm) throws NoPermissionException;
/** /**
* 联合登陆对象直接登录 * 联合登陆对象直接登录
* *
* @param type 第三方登录类型
* @param authUser 第三方登录返回封装类 * @param authUser 第三方登录返回封装类
* @param uuid 用户uuid * @param uuid 用户uuid
* @return token * @return token
*/ */
Token unionLoginCallback(String type, ConnectAuthUser authUser, String uuid); Token unionLoginCallback(ConnectAuthUser authUser, String uuid);
/** /**
* 绑定 * 绑定
@ -86,15 +73,6 @@ public interface ConnectService extends IService<Connect> {
return CachePrefix.CONNECT_AUTH.getPrefix() + type + uuid; return CachePrefix.CONNECT_AUTH.getPrefix() + type + uuid;
} }
/**
* app联合登录 回调
*
* @param authUser 登录对象
* @param uuid uuid
* @return token
*/
Token appLoginCallback(ConnectAuthUser authUser, String uuid);
/** /**
* 微信一键登录 * 微信一键登录
@ -119,4 +97,12 @@ public interface ConnectService extends IService<Connect> {
* @param userId 会员id * @param userId 会员id
*/ */
void deleteByMemberId(String userId); void deleteByMemberId(String userId);
/**
* 绑定第三方平台用户
* @param userId 用户ID
* @param unionId 第三方平台用户ID
* @param type 平台类型
*/
void loginBindUser(String userId, String unionId, String type);
} }

View File

@ -1,25 +1,26 @@
package cn.lili.modules.connect.serviceimpl; package cn.lili.modules.connect.serviceimpl;
import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache; import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix; import cn.lili.cache.CachePrefix;
import cn.lili.common.context.ThreadContextHolder;
import cn.lili.common.enums.ClientTypeEnum; import cn.lili.common.enums.ClientTypeEnum;
import cn.lili.common.enums.ResultCode; import cn.lili.common.enums.ResultCode;
import cn.lili.common.event.TransactionCommitSendMQEvent;
import cn.lili.common.exception.ServiceException; import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.RocketmqCustomProperties; import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.security.AuthUser; import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext; import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.token.Token; import cn.lili.common.security.token.Token;
import cn.lili.common.utils.CookieUtil;
import cn.lili.common.utils.HttpUtils; import cn.lili.common.utils.HttpUtils;
import cn.lili.modules.connect.entity.Connect; import cn.lili.modules.connect.entity.Connect;
import cn.lili.modules.connect.entity.dto.AuthToken;
import cn.lili.modules.connect.entity.dto.ConnectAuthUser; import cn.lili.modules.connect.entity.dto.ConnectAuthUser;
import cn.lili.modules.connect.entity.dto.MemberConnectLoginMessage;
import cn.lili.modules.connect.entity.dto.WechatMPLoginParams; import cn.lili.modules.connect.entity.dto.WechatMPLoginParams;
import cn.lili.modules.connect.entity.enums.ConnectEnum; import cn.lili.modules.connect.entity.enums.ConnectEnum;
import cn.lili.modules.connect.entity.enums.SourceEnum;
import cn.lili.modules.connect.mapper.ConnectMapper; import cn.lili.modules.connect.mapper.ConnectMapper;
import cn.lili.modules.connect.service.ConnectService; import cn.lili.modules.connect.service.ConnectService;
import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.member.entity.dos.Member;
@ -31,13 +32,14 @@ import cn.lili.modules.system.entity.dto.connect.WechatConnectSetting;
import cn.lili.modules.system.entity.dto.connect.dto.WechatConnectSettingItem; import cn.lili.modules.system.entity.dto.connect.dto.WechatConnectSettingItem;
import cn.lili.modules.system.entity.enums.SettingEnum; import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService; import cn.lili.modules.system.service.SettingService;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.MemberTagsEnum; import cn.lili.rocketmq.tags.MemberTagsEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -49,7 +51,6 @@ import java.nio.charset.StandardCharsets;
import java.security.AlgorithmParameters; import java.security.AlgorithmParameters;
import java.security.Security; import java.security.Security;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
/** /**
* 联合登陆接口实现 * 联合登陆接口实现
@ -71,65 +72,20 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
@Autowired @Autowired
private Cache cache; private Cache cache;
/** /**
* RocketMQ 配置 * RocketMQ
*/
@Autowired
private RocketMQTemplate rocketMQTemplate;
/**
* RocketMQ配置
*/ */
@Autowired @Autowired
private RocketmqCustomProperties rocketmqCustomProperties; private RocketmqCustomProperties rocketmqCustomProperties;
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Token unionLoginCallback(String type, String unionid, String uuid, boolean longTerm) throws NoPermissionException { public Token unionLoginCallback(ConnectAuthUser authUser, String uuid) {
return this.unionLoginCallback(authUser, false);
try {
LambdaQueryWrapper<Connect> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Connect::getUnionId, unionid);
queryWrapper.eq(Connect::getUnionType, type);
//查询绑定关系
Connect connect = this.getOne(queryWrapper);
if (connect == null) {
throw new NoPermissionException("未绑定用户");
}
//查询会员
Member member = memberService.getById(connect.getUserId());
//如果未绑定会员则把刚才查询到的联合登录表数据删除
if (member == null) {
this.remove(queryWrapper);
throw new NoPermissionException("未绑定用户");
}
return memberTokenGenerate.createToken(member, longTerm);
} catch (NoPermissionException e) {
log.error("联合登陆失败:", e);
throw e;
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public Token unionLoginCallback(String type, ConnectAuthUser authUser, String uuid) {
Token token;
try {
token = this.unionLoginCallback(type, authUser.getUuid(), uuid, false);
} catch (NoPermissionException e) {
if (AUTO_REGION) {
token = memberService.autoRegister(authUser);
return token;
} else {
//写入cookie
CookieUtil.addCookie(CONNECT_COOKIE, uuid, 1800, ThreadContextHolder.getHttpResponse());
CookieUtil.addCookie(CONNECT_TYPE, type, 1800, ThreadContextHolder.getHttpResponse());
//自动登录失败则把信息缓存起来
cache.put(ConnectService.cacheKey(type, uuid), authUser, 30L, TimeUnit.MINUTES);
throw new ServiceException(ResultCode.USER_NOT_BINDING);
}
} catch (Exception e) {
log.error("联合登陆异常:", e);
throw new ServiceException(ResultCode.ERROR);
}
return token;
} }
@Override @Override
@ -137,6 +93,8 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
AuthUser authUser = Objects.requireNonNull(UserContext.getCurrentUser()); AuthUser authUser = Objects.requireNonNull(UserContext.getCurrentUser());
Connect connect = new Connect(authUser.getId(), unionId, type); Connect connect = new Connect(authUser.getId(), unionId, type);
this.save(connect); this.save(connect);
} }
@Override @Override
@ -161,16 +119,6 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
return keys; return keys;
} }
@Override
@Transactional(rollbackFor = Exception.class)
public Token appLoginCallback(ConnectAuthUser authUser, String uuid) {
try {
return this.unionLoginCallback(authUser.getSource(), authUser.getUuid(), uuid, true);
} catch (NoPermissionException e) {
return memberService.autoRegister(authUser);
}
}
@Override @Override
@Transactional @Transactional
@ -226,40 +174,30 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Token phoneMpBindAndLogin(String sessionKey, WechatMPLoginParams params, String openId, String unionId) { public Token phoneMpBindAndLogin(String sessionKey, WechatMPLoginParams params, String openId, String unionId) {
String encryptedData = params.getEncryptedData(); try {
String iv = params.getIv(); String encryptedData = params.getEncryptedData();
JSONObject userInfo = this.getUserInfo(encryptedData, sessionKey, iv); String iv = params.getIv();
log.info("联合登陆返回:{}", userInfo.toString()); JSONObject userInfo = this.getUserInfo(encryptedData, sessionKey, iv);
String phone = (String) userInfo.get("purePhoneNumber"); log.info("联合登陆返回:{}", userInfo.toString());
String phone = (String) userInfo.get("purePhoneNumber");
//手机号登录 ConnectAuthUser connectAuthUser = new ConnectAuthUser();
LambdaQueryWrapper<Member> lambdaQueryWrapper = new LambdaQueryWrapper<>(); connectAuthUser.setUuid(openId);
lambdaQueryWrapper.eq(Member::getMobile, phone); connectAuthUser.setNickname(params.getNickName());
Member member = memberService.getOne(lambdaQueryWrapper); connectAuthUser.setAvatar(params.getImage());
//如果不存在会员则进行绑定微信openid unionid并且登录 connectAuthUser.setUsername("m" + phone);
if (member != null) { connectAuthUser.setPhone(phone);
bindMpMember(openId, unionId, member); connectAuthUser.setSource(ConnectEnum.WECHAT.name());
return memberTokenGenerate.createToken(member, true); connectAuthUser.setType(ClientTypeEnum.WECHAT_MP.name());
AuthToken authToken = new AuthToken();
authToken.setUnionId(unionId);
connectAuthUser.setToken(authToken);
return this.unionLoginCallback(connectAuthUser, true);
} catch (Exception e) {
e.printStackTrace();
} }
return null;
//如果没有会员则根据手机号注册会员
Member newMember = new Member("m" + phone, "111111", phone, params.getNickName(), params.getImage());
memberService.save(newMember);
newMember = memberService.findByUsername(newMember.getUsername());
//判定有没有邀请人并且写入
UserContext.settingInviter(newMember.getId(), cache);
bindMpMember(openId, unionId, newMember);
//判定有没有邀请人并且写入
UserContext.settingInviter(newMember.getId(), cache);
// 发送会员注册信息
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("new member register", rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_REGISTER.name(), newMember));
return memberTokenGenerate.createToken(newMember, true);
} }
@Override @Override
@ -280,47 +218,86 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
} }
/** /**
* 会员绑定 绑定微信小程序 * 成功登录则检测cookie中的信息进行会员绑定
* <p>
* 如果openid 已经绑定其他账号则这里不作处理如果未绑定则绑定最新的会员
* 这样微信小程序注册之后其他app 公众号页面都可以实现绑定自动登录功能
* </p>
* *
* @param openId 微信openid * @param userId 用户ID
* @param unionId 微信unionid * @param unionId 第三方用户ID
* @param member 会员 * @param type 类型
*/ */
private void bindMpMember(String openId, String unionId, Member member) { @Override
public void loginBindUser(String userId, String unionId, String type) {
Connect connect = this.queryConnect(
//如果unionid 不为空 则为账号绑定unionid ConnectQueryDTO.builder().unionId(unionId).unionType(type).build()
if (CharSequenceUtil.isNotEmpty(unionId)) { );
LambdaQueryWrapper<Connect> lambdaQueryWrapper = new LambdaQueryWrapper(); //如果未绑定则直接绑定
lambdaQueryWrapper.eq(Connect::getUnionId, unionId); if (connect == null) {
lambdaQueryWrapper.eq(Connect::getUnionType, ConnectEnum.WECHAT.name()); connect = new Connect(userId, unionId, type);
List<Connect> connects = this.list(lambdaQueryWrapper); this.save(connect);
if (connects.isEmpty()) { //如果已绑定不是当前用户信息则删除绑定信息重新绑定
Connect connect = new Connect(); } else if (!connect.getUserId().equals(userId)) {
connect.setUnionId(unionId); this.removeById(connect.getId());
connect.setUserId(member.getId()); this.loginBindUser(userId, unionId, type);
connect.setUnionType(ConnectEnum.WECHAT.name());
this.save(connect);
}
}//如果openid 不为空 则为账号绑定openid
if (CharSequenceUtil.isNotEmpty(openId)) {
LambdaQueryWrapper<Connect> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(Connect::getUnionId, openId);
lambdaQueryWrapper.eq(Connect::getUnionType, ConnectEnum.WECHAT_MP_OPEN_ID.name());
List<Connect> connects = this.list(lambdaQueryWrapper);
if (connects.isEmpty()) {
Connect connect = new Connect();
connect.setUnionId(openId);
connect.setUserId(member.getId());
connect.setUnionType(ConnectEnum.WECHAT_MP_OPEN_ID.name());
this.save(connect);
}
} }
}
/**
* 第三方联合登陆
* 1.判断是否使用开放平台
* 1.1如果使用开放平台则使用UnionId进行登录
* 1.2如果不适用开放平台则使用OpenId进行登录
* <p>
* 2.用户登录后判断绑定OpenId
*
* @param authUser 第三方登录封装类
* @param longTerm 是否长时间有效
* @return token
* @throws NoPermissionException 不允许操作
*/
private Token unionLoginCallback(ConnectAuthUser authUser, boolean longTerm) {
try {
LambdaQueryWrapper<Connect> queryWrapper = new LambdaQueryWrapper<Connect>();
//使用UnionId登录
if (StrUtil.isNotBlank(authUser.getToken().getUnionId())) {
queryWrapper.eq(Connect::getUnionId, authUser.getToken().getUnionId())
.eq(Connect::getUnionType, authUser.getSource());
} else {
//使用OpenID登录
SourceEnum sourceEnum = SourceEnum.getSourceEnum(ConnectEnum.valueOf(authUser.getType()), ClientTypeEnum.valueOf(authUser.getSource()));
queryWrapper.eq(Connect::getUnionId, authUser.getToken().getUnionId())
.eq(Connect::getUnionType, sourceEnum.name());
}
//查询绑定关系
Connect connect = this.getOne(queryWrapper);
Member member = new Member();
if (connect == null) {
member = memberService.autoRegister(authUser);
} else {
//查询会员
member = memberService.getById(connect.getUserId());
//如果未绑定会员则把刚才查询到的联合登录表数据删除
if (member == null) {
this.remove(queryWrapper);
member = memberService.autoRegister(authUser);
}
}
//发送用户第三方登录消息
MemberConnectLoginMessage memberConnectLoginMessage = new MemberConnectLoginMessage();
memberConnectLoginMessage.setMember(member);
memberConnectLoginMessage.setConnectAuthUser(authUser);
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_CONNECT_LOGIN.name();
//发送用户第三方登录消息
rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(memberConnectLoginMessage), RocketmqSendCallbackBuilder.commonCallback());
return memberTokenGenerate.createToken(member, longTerm);
} catch (Exception e) {
log.error("联合登陆失败:", e);
throw e;
}
} }
/** /**
@ -392,4 +369,6 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> impl
} }
throw new ServiceException(ResultCode.USER_CONNECT_ERROR); throw new ServiceException(ResultCode.USER_CONNECT_ERROR);
} }
} }

View File

@ -66,6 +66,7 @@ public class ConnectUtil {
/** /**
* 回调地址获取 * 回调地址获取
*
* @param connectAuthEnum 用户枚举 * @param connectAuthEnum 用户枚举
* @return 回调地址 * @return 回调地址
*/ */
@ -75,9 +76,11 @@ public class ConnectUtil {
/** /**
* 登录回调 * 登录回调
* 此方法处理第三方登录回调
* 场景PCWAP(微信公众号)
* *
* @param type * @param type 类型
* @param callback * @param callback 回调参数
* @param httpServletResponse * @param httpServletResponse
* @param httpServletRequest * @param httpServletRequest
* @throws IOException * @throws IOException
@ -89,9 +92,8 @@ public class ConnectUtil {
//联合登陆处理如果响应正常则录入响应结果到redis //联合登陆处理如果响应正常则录入响应结果到redis
if (response.ok()) { if (response.ok()) {
ConnectAuthUser authUser = response.getData(); ConnectAuthUser authUser = response.getData();
Token token;
try { try {
token = connectService.unionLoginCallback(type, authUser, callback.getState()); Token token = connectService.unionLoginCallback(authUser, callback.getState());
resultMessage = ResultUtil.data(token); resultMessage = ResultUtil.data(token);
} catch (ServiceException e) { } catch (ServiceException e) {
throw new ServiceException(ResultCode.ERROR, e.getMessage()); throw new ServiceException(ResultCode.ERROR, e.getMessage());
@ -112,7 +114,7 @@ public class ConnectUtil {
try { try {
httpServletResponse.sendRedirect(url); httpServletResponse.sendRedirect(url);
} catch (Exception e) { } catch (Exception e) {
log.error("登录回调错误",e); log.error("登录回调错误", e);
} }
} }
@ -165,6 +167,7 @@ public class ConnectUtil {
//寻找配置 //寻找配置
Setting setting = settingService.get(SettingEnum.WECHAT_CONNECT.name()); Setting setting = settingService.get(SettingEnum.WECHAT_CONNECT.name());
WechatConnectSetting wechatConnectSetting = JSONUtil.toBean(setting.getSettingValue(), WechatConnectSetting.class); WechatConnectSetting wechatConnectSetting = JSONUtil.toBean(setting.getSettingValue(), WechatConnectSetting.class);
for (WechatConnectSettingItem wechatConnectSettingItem : wechatConnectSetting.getWechatConnectSettingItems()) { for (WechatConnectSettingItem wechatConnectSettingItem : wechatConnectSetting.getWechatConnectSettingItems()) {
if (wechatConnectSettingItem.getClientType().equals(ClientTypeEnum.PC.name())) { if (wechatConnectSettingItem.getClientType().equals(ClientTypeEnum.PC.name())) {
authRequest = new BaseAuthWeChatPCRequest(AuthConfig.builder() authRequest = new BaseAuthWeChatPCRequest(AuthConfig.builder()
@ -178,10 +181,10 @@ public class ConnectUtil {
break; break;
} }
case QQ: case QQ:
//寻找配置 //寻找配置
Setting setting = settingService.get(SettingEnum.QQ_CONNECT.name()); Setting setting = settingService.get(SettingEnum.QQ_CONNECT.name());
QQConnectSetting qqConnectSetting = JSONUtil.toBean(setting.getSettingValue(), QQConnectSetting.class); QQConnectSetting qqConnectSetting = JSONUtil.toBean(setting.getSettingValue(), QQConnectSetting.class);
for (QQConnectSettingItem qqConnectSettingItem : qqConnectSetting.getQqConnectSettingItemList()) { for (QQConnectSettingItem qqConnectSettingItem : qqConnectSetting.getQqConnectSettingItemList()) {
if (qqConnectSettingItem.getClientType().equals(ClientTypeEnum.PC.name())) { if (qqConnectSettingItem.getClientType().equals(ClientTypeEnum.PC.name())) {
authRequest = new BaseAuthQQRequest(AuthConfig.builder() authRequest = new BaseAuthQQRequest(AuthConfig.builder()

View File

@ -83,7 +83,6 @@ public class DistributionCashServiceImpl extends ServiceImpl<DistributionCashMap
MemberWithdrawalMessage memberWithdrawalMessage = new MemberWithdrawalMessage(); MemberWithdrawalMessage memberWithdrawalMessage = new MemberWithdrawalMessage();
memberWithdrawalMessage.setMemberId(distribution.getMemberId()); memberWithdrawalMessage.setMemberId(distribution.getMemberId());
memberWithdrawalMessage.setPrice(applyMoney); memberWithdrawalMessage.setPrice(applyMoney);
memberWithdrawalMessage.setDestination(MemberWithdrawalDestinationEnum.WALLET.name());
memberWithdrawalMessage.setStatus(WithdrawStatusEnum.APPLY.name()); memberWithdrawalMessage.setStatus(WithdrawStatusEnum.APPLY.name());
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_WITHDRAWAL.name(); String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_WITHDRAWAL.name();
rocketMQTemplate.asyncSend(destination, memberWithdrawalMessage, RocketmqSendCallbackBuilder.commonCallback()); rocketMQTemplate.asyncSend(destination, memberWithdrawalMessage, RocketmqSendCallbackBuilder.commonCallback());
@ -147,7 +146,6 @@ public class DistributionCashServiceImpl extends ServiceImpl<DistributionCashMap
//组织会员提现审核消息 //组织会员提现审核消息
memberWithdrawalMessage.setMemberId(distribution.getMemberId()); memberWithdrawalMessage.setMemberId(distribution.getMemberId());
memberWithdrawalMessage.setPrice(distributorCash.getPrice()); memberWithdrawalMessage.setPrice(distributorCash.getPrice());
memberWithdrawalMessage.setDestination(MemberWithdrawalDestinationEnum.WALLET.name());
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_WITHDRAWAL.name(); String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_WITHDRAWAL.name();
rocketMQTemplate.asyncSend(destination, memberWithdrawalMessage, RocketmqSendCallbackBuilder.commonCallback()); rocketMQTemplate.asyncSend(destination, memberWithdrawalMessage, RocketmqSendCallbackBuilder.commonCallback());
} }

View File

@ -15,6 +15,7 @@ import cn.lili.modules.member.entity.vo.QRLoginResultVo;
import cn.lili.modules.member.entity.vo.QRCodeLoginSessionVo; import cn.lili.modules.member.entity.vo.QRCodeLoginSessionVo;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.elasticsearch.monitor.os.OsStats;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -183,12 +184,12 @@ public interface MemberService extends IService<Member> {
IPage<MemberVO> getMemberPage(MemberSearchVO memberSearchVO, PageVO page); IPage<MemberVO> getMemberPage(MemberSearchVO memberSearchVO, PageVO page);
/** // /**
* 一键注册会员 // * 一键注册会员
* // *
* @return // * @return
*/ // */
Token autoRegister(); // Token autoRegister();
/** /**
* 一键注册会员 * 一键注册会员
@ -196,7 +197,7 @@ public interface MemberService extends IService<Member> {
* @param authUser 联合登录用户 * @param authUser 联合登录用户
* @return Token * @return Token
*/ */
Token autoRegister(ConnectAuthUser authUser); Member autoRegister(ConnectAuthUser authUser);
/** /**
* 刷新token * 刷新token

View File

@ -239,7 +239,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
@Override @Override
@Transactional @Transactional
public Token autoRegister(ConnectAuthUser authUser) { public Member autoRegister(ConnectAuthUser authUser) {
if (CharSequenceUtil.isEmpty(authUser.getNickname())) { if (CharSequenceUtil.isEmpty(authUser.getNickname())) {
authUser.setNickname("临时昵称"); authUser.setNickname("临时昵称");
@ -251,11 +251,11 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
String username = UuidUtils.getUUID(); String username = UuidUtils.getUUID();
Member member = new Member(username, UuidUtils.getUUID(), authUser.getAvatar(), authUser.getNickname(), Member member = new Member(username, UuidUtils.getUUID(), authUser.getAvatar(), authUser.getNickname(),
authUser.getGender() != null ? Convert.toInt(authUser.getGender().getCode()) : 0); authUser.getGender() != null ? Convert.toInt(authUser.getGender().getCode()) : 0);
registerHandler(member);
member.setPassword(DEFAULT_PASSWORD); member.setPassword(DEFAULT_PASSWORD);
//绑定登录方式 // 发送会员注册信息
loginBindUser(member, authUser.getUuid(), authUser.getSource()); registerHandler(member);
return memberTokenGenerate.createToken(member, false);
return member;
} catch (ServiceException e) { } catch (ServiceException e) {
log.error("自动注册服务抛出异常:", e); log.error("自动注册服务抛出异常:", e);
throw e; throw e;
@ -265,12 +265,12 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
} }
} }
@Override // @Override
@Transactional // @Transactional
public Token autoRegister() { // public Token autoRegister() {
ConnectAuthUser connectAuthUser = this.checkConnectUser(); // ConnectAuthUser connectAuthUser = this.checkConnectUser();
return this.autoRegister(connectAuthUser); // return this.autoRegister(connectAuthUser);
} // }
@Override @Override
public Token refreshToken(String refreshToken) { public Token refreshToken(String refreshToken) {
@ -308,7 +308,6 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
//保存会员 //保存会员
this.save(member); this.save(member);
// 发送会员注册信息 // 发送会员注册信息
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("new member register", rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_REGISTER.name(), member)); applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("new member register", rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_REGISTER.name(), member));
} }
@ -572,23 +571,6 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
return null; return null;
} }
/**
* 成功登录则检测cookie中的信息进行会员绑定
*
* @param member 会员
* @param unionId unionId
* @param type 状态
*/
private void loginBindUser(Member member, String unionId, String type) {
Connect connect = connectService.queryConnect(
ConnectQueryDTO.builder().unionId(unionId).unionType(type).build()
);
if (connect == null) {
connect = new Connect(member.getId(), unionId, type);
connectService.save(connect);
}
}
/** /**
* 成功登录则检测cookie中的信息进行会员绑定 * 成功登录则检测cookie中的信息进行会员绑定
* *
@ -627,42 +609,42 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
} }
/** // /**
* 检测是否可以绑定第三方联合登陆 // * 检测是否可以绑定第三方联合登陆
* 返回null原因 // * 返回null原因
* 包含原因1redis中已经没有联合登陆信息 2已绑定其他账号 // * 包含原因1redis中已经没有联合登陆信息 2已绑定其他账号
* // *
* @return 返回对象则代表可以进行绑定第三方会员返回null则表示联合登陆无法继续 // * @return 返回对象则代表可以进行绑定第三方会员返回null则表示联合登陆无法继续
*/ // */
private ConnectAuthUser checkConnectUser() { // private ConnectAuthUser checkConnectUser() {
//获取cookie存储的信息 // //获取cookie存储的信息
String uuid = CookieUtil.getCookie(ConnectService.CONNECT_COOKIE, ThreadContextHolder.getHttpRequest()); // String uuid = CookieUtil.getCookie(ConnectService.CONNECT_COOKIE, ThreadContextHolder.getHttpRequest());
String connectType = CookieUtil.getCookie(ConnectService.CONNECT_TYPE, ThreadContextHolder.getHttpRequest()); // String connectType = CookieUtil.getCookie(ConnectService.CONNECT_TYPE, ThreadContextHolder.getHttpRequest());
//
//如果联合登陆存储了信息 // //如果联合登陆存储了信息
if (CharSequenceUtil.isNotEmpty(uuid) && CharSequenceUtil.isNotEmpty(connectType)) { // if (CharSequenceUtil.isNotEmpty(uuid) && CharSequenceUtil.isNotEmpty(connectType)) {
//枚举 联合登陆类型获取 // //枚举 联合登陆类型获取
ConnectAuthEnum authInterface = ConnectAuthEnum.valueOf(connectType); // ConnectAuthEnum authInterface = ConnectAuthEnum.valueOf(connectType);
//
ConnectAuthUser connectAuthUser = getConnectAuthUser(uuid, connectType); // ConnectAuthUser connectAuthUser = getConnectAuthUser(uuid, connectType);
if (connectAuthUser == null) { // if (connectAuthUser == null) {
throw new ServiceException(ResultCode.USER_OVERDUE_CONNECT_ERROR); // throw new ServiceException(ResultCode.USER_OVERDUE_CONNECT_ERROR);
} // }
//检测是否已经绑定过用户 // //检测是否已经绑定过用户
Connect connect = connectService.queryConnect( // Connect connect = connectService.queryConnect(
ConnectQueryDTO.builder().unionType(connectType).unionId(connectAuthUser.getUuid()).build() // ConnectQueryDTO.builder().unionType(connectType).unionId(connectAuthUser.getUuid()).build()
); // );
//没有关联则返回true表示可以继续绑定 // //没有关联则返回true表示可以继续绑定
if (connect == null) { // if (connect == null) {
connectAuthUser.setConnectEnum(authInterface); // connectAuthUser.setConnectEnum(authInterface);
return connectAuthUser; // return connectAuthUser;
} else { // } else {
throw new ServiceException(ResultCode.USER_CONNECT_BANDING_ERROR); // throw new ServiceException(ResultCode.USER_CONNECT_BANDING_ERROR);
} // }
} else { // } else {
throw new ServiceException(ResultCode.USER_CONNECT_NOT_EXIST_ERROR); // throw new ServiceException(ResultCode.USER_CONNECT_NOT_EXIST_ERROR);
} // }
} // }
@Override @Override
public long getMemberNum(MemberSearchVO memberSearchVO) { public long getMemberNum(MemberSearchVO memberSearchVO) {

View File

@ -48,10 +48,11 @@ public enum NoticeMessageNodeEnum {
* 用户余额 * 用户余额
*/ */
WALLET_CHANGE("余额账户变更通知"), WALLET_CHANGE("余额账户变更通知"),
WALLET_WITHDRAWAL_CREATE("提现申请提交成功通知"), WALLET_WITHDRAWAL_CREATE("余额提现申请提交成功通知"),
WALLET_WITHDRAWAL_SUCCESS("余额提现成功通知"), WALLET_WITHDRAWAL_SUCCESS("余额提现成功通知"),
WALLET_WITHDRAWAL_WEICHAT_SUCCESS("微信提现成功通知"), WALLET_WITHDRAWAL_ERROR("余额提现申请失败通知"),
WALLET_WITHDRAWAL_ERROR("提现申请驳回通知"); WALLET_WITHDRAWAL_AUDIT_ERROR("余额提现申请驳回通知"),
WALLET_WITHDRAWAL_AUDIT_SUCCESS("余额提现申请通过通知");
private final String description; private final String description;

View File

@ -54,7 +54,7 @@ public class NoticeMessageServiceImpl extends ServiceImpl<NoticeMessageTemplateM
NoticeMessage noticeMessage = this.getOne( NoticeMessage noticeMessage = this.getOne(
new LambdaQueryWrapper<NoticeMessage>() new LambdaQueryWrapper<NoticeMessage>()
.eq(NoticeMessage::getNoticeNode .eq(NoticeMessage::getNoticeNode
, noticeMessageDTO.getNoticeMessageNodeEnum().getDescription().trim())); , noticeMessageDTO.getNoticeMessageNodeEnum().getDescription().trim()),false);
//如果通知类站内信开启的情况下 //如果通知类站内信开启的情况下
if (noticeMessage != null && noticeMessage.getNoticeStatus().equals(SwitchEnum.OPEN.name())) { if (noticeMessage != null && noticeMessage.getNoticeStatus().equals(SwitchEnum.OPEN.name())) {
MemberMessage memberMessage = new MemberMessage(); MemberMessage memberMessage = new MemberMessage();

View File

@ -145,13 +145,15 @@ public class CashierSupport {
/** /**
* 用户提现 * 用户提现
* @param paymentMethodEnum 支付渠道 *
* @param paymentMethodEnum 支付渠道
* @param memberWithdrawApply 用户提现申请 * @param memberWithdrawApply 用户提现申请
*/ */
public void transfer(PaymentMethodEnum paymentMethodEnum, MemberWithdrawApply memberWithdrawApply){ public boolean transfer(PaymentMethodEnum paymentMethodEnum, MemberWithdrawApply memberWithdrawApply) {
Payment payment = (Payment) SpringContextUtil.getBean(paymentMethodEnum.getPlugin()); Payment payment = (Payment) SpringContextUtil.getBean(paymentMethodEnum.getPlugin());
payment.transfer(memberWithdrawApply); return payment.transfer(memberWithdrawApply);
} }
/** /**
* 获取收银台参数 * 获取收银台参数
* *

View File

@ -114,7 +114,7 @@ public interface Payment {
/** /**
* 提现 * 提现
*/ */
default void transfer(MemberWithdrawApply memberWithdrawApply) { default boolean transfer(MemberWithdrawApply memberWithdrawApply) {
throw new ServiceException(ResultCode.PAY_ERROR); throw new ServiceException(ResultCode.PAY_ERROR);
} }

View File

@ -31,7 +31,6 @@ import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.*; import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipaySignature; import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.response.AlipayFundTransUniTransferResponse; import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.alipay.api.response.AlipayTradeRefundResponse; import com.alipay.api.response.AlipayTradeRefundResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -238,7 +237,7 @@ public class AliPayPlugin implements Payment {
* @param memberWithdrawApply 会员提现申请 * @param memberWithdrawApply 会员提现申请
*/ */
@Override @Override
public void transfer(MemberWithdrawApply memberWithdrawApply) { public boolean transfer(MemberWithdrawApply memberWithdrawApply) {
AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel(); AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
model.setOutBizNo(SnowFlake.createStr("T")); model.setOutBizNo(SnowFlake.createStr("T"));
model.setRemark("用户提现"); model.setRemark("用户提现");
@ -255,10 +254,10 @@ public class AliPayPlugin implements Payment {
model.setOrderTitle("用户提现"); model.setOrderTitle("用户提现");
//交互退款 //交互退款
try { try {
AlipayFundTransUniTransferResponse alipayFundTransUniTransferResponse = AliPayApi.uniTransferToResponse(model,null); AlipayFundTransUniTransferResponse alipayFundTransUniTransferResponse = AliPayApi.uniTransferToResponse(model, null);
log.error("支付宝退款,参数:{},支付宝响应:{}", JSONUtil.toJsonStr(model), JSONUtil.toJsonStr(alipayFundTransUniTransferResponse)); log.error("支付宝退款,参数:{},支付宝响应:{}", JSONUtil.toJsonStr(model), JSONUtil.toJsonStr(alipayFundTransUniTransferResponse));
if (alipayFundTransUniTransferResponse.isSuccess()) { if (alipayFundTransUniTransferResponse.isSuccess()) {
return true;
} else { } else {
log.error(alipayFundTransUniTransferResponse.getSubMsg()); log.error(alipayFundTransUniTransferResponse.getSubMsg());
} }
@ -266,6 +265,7 @@ public class AliPayPlugin implements Payment {
log.error("用户提现异常:", e); log.error("用户提现异常:", e);
throw new ServiceException(ResultCode.PAY_ERROR); throw new ServiceException(ResultCode.PAY_ERROR);
} }
return false;
} }
/** /**

View File

@ -18,6 +18,7 @@ import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.ResultMessage; import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.connect.entity.Connect; import cn.lili.modules.connect.entity.Connect;
import cn.lili.modules.connect.entity.enums.ConnectEnum; import cn.lili.modules.connect.entity.enums.ConnectEnum;
import cn.lili.modules.connect.entity.enums.SourceEnum;
import cn.lili.modules.connect.service.ConnectService; import cn.lili.modules.connect.service.ConnectService;
import cn.lili.modules.member.entity.dto.ConnectQueryDTO; import cn.lili.modules.member.entity.dto.ConnectQueryDTO;
import cn.lili.modules.order.order.service.OrderService; import cn.lili.modules.order.order.service.OrderService;
@ -39,12 +40,17 @@ import cn.lili.modules.payment.kit.plugin.wechat.model.*;
import cn.lili.modules.payment.service.PaymentService; import cn.lili.modules.payment.service.PaymentService;
import cn.lili.modules.payment.service.RefundLogService; import cn.lili.modules.payment.service.RefundLogService;
import cn.lili.modules.system.entity.dos.Setting; import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.WithdrawalSetting;
import cn.lili.modules.system.entity.dto.connect.WechatConnectSetting;
import cn.lili.modules.system.entity.dto.connect.dto.WechatConnectSettingItem;
import cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting; import cn.lili.modules.system.entity.dto.payment.WechatPaymentSetting;
import cn.lili.modules.system.entity.enums.SettingEnum; import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.modules.system.service.SettingService; import cn.lili.modules.system.service.SettingService;
import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply; import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.atp.Switch;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -378,7 +384,7 @@ public class WechatPlugin implements Payment {
try { try {
Connect connect = connectService.queryConnect( Connect connect = connectService.queryConnect(
ConnectQueryDTO.builder().userId(UserContext.getCurrentUser().getId()).unionType(ConnectEnum.WECHAT_MP_OPEN_ID.name()).build() ConnectQueryDTO.builder().userId(UserContext.getCurrentUser().getId()).unionType(SourceEnum.WECHAT_MP_OPEN_ID.name()).build()
); );
if (connect == null) { if (connect == null) {
return null; return null;
@ -475,17 +481,43 @@ public class WechatPlugin implements Payment {
* @param memberWithdrawApply 会员提现申请 * @param memberWithdrawApply 会员提现申请
*/ */
@Override @Override
public void transfer(MemberWithdrawApply memberWithdrawApply) { public boolean transfer(MemberWithdrawApply memberWithdrawApply) {
try { try {
WechatPaymentSetting setting = wechatPaymentSetting(); //获取提现设置
WithdrawalSetting withdrawalSetting = new Gson().fromJson(settingService.get(SettingEnum.WITHDRAWAL_SETTING.name()).getSettingValue(), WithdrawalSetting.class);
//获取用户OPENID
WechatConnectSetting wechatConnectSetting = new Gson().fromJson(settingService.get(SettingEnum.WECHAT_CONNECT.name()).getSettingValue(), WechatConnectSetting.class);
String source = "";
for (WechatConnectSettingItem wechatConnectSettingItem : wechatConnectSetting.getWechatConnectSettingItems()) {
if (wechatConnectSettingItem.getAppId().equals(withdrawalSetting.getWechatAppId())) {
switch (wechatConnectSettingItem.getClientType()) {
case "PC":
source = SourceEnum.WECHAT_PC_OPEN_ID.name();
break;
case "H5":
source = SourceEnum.WECHAT_OFFIACCOUNT_OPEN_ID.name();
break;
case "MP":
source = SourceEnum.WECHAT_MP_OPEN_ID.name();
break;
case "APP":
source = SourceEnum.WECHAT_APP_OPEN_ID.name();
break;
}
}
}
//获取微信设置
WechatPaymentSetting wechatPaymentSetting = wechatPaymentSetting();
//获取用户openId
Connect connect = connectService.queryConnect( Connect connect = connectService.queryConnect(
ConnectQueryDTO.builder().userId(UserContext.getCurrentUser().getId()) ConnectQueryDTO.builder().userId(memberWithdrawApply.getMemberId())
.unionType(ConnectEnum.WECHAT_OPEN_ID.name()).build() .unionType(source).build()
); );
//根据自身情况设置AppId,此处我存放的是服务号的APPID下方的openID需要对应此处的APPID配置 //构建提现发起申请
TransferModel transferModel = new TransferModel() TransferModel transferModel = new TransferModel()
.setAppid(setting.getServiceAppId()) .setAppid(withdrawalSetting.getWechatAppId())
.setOut_batch_no(SnowFlake.createStr("T")) .setOut_batch_no(SnowFlake.createStr("T"))
.setBatch_name("用户提现") .setBatch_name("用户提现")
.setBatch_remark("用户提现") .setBatch_remark("用户提现")
@ -499,10 +531,6 @@ public class WechatPlugin implements Payment {
transferDetailInput.setTransfer_amount(CurrencyUtil.fen(memberWithdrawApply.getApplyMoney())); transferDetailInput.setTransfer_amount(CurrencyUtil.fen(memberWithdrawApply.getApplyMoney()));
transferDetailInput.setTransfer_remark("用户提现"); transferDetailInput.setTransfer_remark("用户提现");
transferDetailInput.setOpenid(connect.getUnionId()); transferDetailInput.setOpenid(connect.getUnionId());
// transferDetailInput.setUserName(
// "757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45");
// transferDetailInput.setUserIdCard(
// "8609cb22e1774a50a930e414cc71eca06121bcd266335cda230d24a7886a8d9f");
transferDetailListList.add(transferDetailInput); transferDetailListList.add(transferDetailInput);
} }
transferModel.setTransfer_detail_list(transferDetailListList); transferModel.setTransfer_detail_list(transferDetailListList);
@ -511,17 +539,21 @@ public class WechatPlugin implements Payment {
RequestMethodEnums.POST, RequestMethodEnums.POST,
WechatDomain.CHINA.toString(), WechatDomain.CHINA.toString(),
WechatApiEnum.TRANSFER_BATCHES.toString(), WechatApiEnum.TRANSFER_BATCHES.toString(),
setting.getMchId(), wechatPaymentSetting.getMchId(),
setting.getSerialNumber(), wechatPaymentSetting.getSerialNumber(),
null, null,
setting.getApiclient_key(), wechatPaymentSetting.getApiclient_key(),
JSONUtil.toJsonStr(transferModel) JSONUtil.toJsonStr(transferModel)
); );
log.info("微信提现响应 {}", response); log.info("微信提现响应 {}", response);
String body = response.getBody();
JSONObject jsonObject = JSONUtil.parseObj(body);
return jsonObject.getStr("batch_id") != null ? true : false;
//根据自身业务进行接下来的任务处理 //根据自身业务进行接下来的任务处理
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return false;
} }

View File

@ -15,7 +15,28 @@ public class WithdrawalSetting implements Serializable {
private static final long serialVersionUID = -3872782530832122976L; private static final long serialVersionUID = -3872782530832122976L;
/** /**
* 提现是否需要申请 * 提现最低金额
*/
private Double minPrice;
/**
* 提现手续费
*/
private Double fee;
/**
* 提现类型 WECHAT\ALI
*/
private String type;
/**
* 提现是否需要审核
*/ */
private Boolean apply; private Boolean apply;
/**
* 微信提现-渠道使用的APPID
*/
private String wechatAppId;
/**
* 微信APPID渠道
*/
private String wechatAppIdSource;
} }

View File

@ -0,0 +1,31 @@
package cn.lili.modules.system.entity.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 用户提现设置VO
*
* @author Bulbasaur
* @since 2023/3/1
*/
@Data
public class WithdrawalSettingVO {
/**
* 提现最低金额
*/
@ApiModelProperty(value = "minPrice")
private Double minPrice;
/**
* 提现手续费
*/
@ApiModelProperty(value = "提现手续费")
private Double fee;
/**
* 提现类型 WECHAT\ALI
*/
@ApiModelProperty(value = "提现类型 WECHAT、ALI")
private String type;
}

View File

@ -56,8 +56,14 @@ public class MemberWithdrawApply extends BaseEntity {
@ApiModelProperty(value = "sn") @ApiModelProperty(value = "sn")
private String sn; private String sn;
/**
* 支付宝提现时必填
*/
@ApiModelProperty(value = "真实姓名") @ApiModelProperty(value = "真实姓名")
private String realName; private String realName;
/**
* 支付宝登录账号
*/
@ApiModelProperty(value = "第三方平台账号") @ApiModelProperty(value = "第三方平台账号")
private String connectNumber; private String connectNumber;

View File

@ -1,6 +1,5 @@
package cn.lili.modules.wallet.entity.dto; package cn.lili.modules.wallet.entity.dto;
import cn.lili.modules.wallet.entity.enums.MemberWithdrawalDestinationEnum;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -13,6 +12,9 @@ import lombok.Data;
@Data @Data
public class MemberWithdrawalMessage { public class MemberWithdrawalMessage {
@ApiModelProperty(value = "提现申请ID")
private String memberWithdrawApplyId;
@ApiModelProperty(value = "金额") @ApiModelProperty(value = "金额")
private Double price; private Double price;
@ -22,9 +24,4 @@ public class MemberWithdrawalMessage {
@ApiModelProperty(value = "提现状态") @ApiModelProperty(value = "提现状态")
private String status; private String status;
/**
* @see MemberWithdrawalDestinationEnum
*/
@ApiModelProperty(value = "提现到哪里")
private String destination;
} }

View File

@ -18,7 +18,15 @@ public enum WithdrawStatusEnum {
/** /**
* 审核未通过 * 审核未通过
*/ */
FAIL_AUDITING("审核未通过"); FAIL_AUDITING("审核未通过"),
/**
* 提现成功
*/
SUCCESS("提现成功"),
/**
* 提现失败
*/
ERROR("提现失败");
private String description; private String description;

View File

@ -3,10 +3,10 @@ package cn.lili.modules.wallet.service;
import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.wallet.entity.dos.MemberWallet; import cn.lili.modules.wallet.entity.dos.MemberWallet;
import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply;
import cn.lili.modules.wallet.entity.dto.MemberWalletUpdateDTO; import cn.lili.modules.wallet.entity.dto.MemberWalletUpdateDTO;
import cn.lili.modules.wallet.entity.vo.MemberWalletVO; import cn.lili.modules.wallet.entity.vo.MemberWalletVO;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.web.bind.annotation.RequestParam;
/** /**
* 会员预存款业务层 * 会员预存款业务层
@ -80,7 +80,7 @@ public interface MemberWalletService extends IService<MemberWallet> {
Boolean checkPassword(); Boolean checkPassword();
/** /**
* 会员注册添加会员预存款 * 会员注册添加会员余额钱包
* *
* @param memberId 会员id * @param memberId 会员id
* @param memberName 会员名称 * @param memberName 会员名称
@ -92,16 +92,18 @@ public interface MemberWalletService extends IService<MemberWallet> {
* 用户提现 * 用户提现
* *
* @param price 提现金额 * @param price 提现金额
* @param realName 真实姓名
* @param connectNumber 第三方账号
* @return 是否提现成功 * @return 是否提现成功
*/ */
Boolean applyWithdrawal(Double price); Boolean applyWithdrawal(Double price, String realName, String connectNumber);
/** /**
* 提现公共方法此方法供前端用户提现和后端提现使用 * 提现公共方法
* *
* @param memberWithdrawApply 会员零钱提现申请 * @param withdrawApplyId 会员零钱提现Id
* @return 操作状态 * @return 操作状态
*/ */
Boolean withdrawal(MemberWithdrawApply memberWithdrawApply); Boolean withdrawal(String withdrawApplyId);
} }

View File

@ -23,7 +23,6 @@ import cn.lili.modules.wallet.entity.dos.WalletLog;
import cn.lili.modules.wallet.entity.dto.MemberWalletUpdateDTO; import cn.lili.modules.wallet.entity.dto.MemberWalletUpdateDTO;
import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage; import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage;
import cn.lili.modules.wallet.entity.enums.DepositServiceTypeEnum; import cn.lili.modules.wallet.entity.enums.DepositServiceTypeEnum;
import cn.lili.modules.wallet.entity.enums.MemberWithdrawalDestinationEnum;
import cn.lili.modules.wallet.entity.enums.WithdrawStatusEnum; import cn.lili.modules.wallet.entity.enums.WithdrawStatusEnum;
import cn.lili.modules.wallet.entity.vo.MemberWalletVO; import cn.lili.modules.wallet.entity.vo.MemberWalletVO;
import cn.lili.modules.wallet.mapper.MemberWalletMapper; import cn.lili.modules.wallet.mapper.MemberWalletMapper;
@ -248,76 +247,107 @@ public class MemberWalletServiceImpl extends ServiceImpl<MemberWalletMapper, Mem
/** /**
* 提现方法 * 提现方法
* 1先执行平台逻辑平台逻辑成功后扣减第三方余额顺序问题为了防止第三方提现成功平台逻辑失败导致第三方零钱已提现而我们商城余额未扣减 * 1提现申请冻结用户的余额
* 2如果余额扣减失败 则抛出异常事务回滚 * 2判断是否需要平台审核不需要审核则直接调用第三方提现需要审核则审核通过后调用第三方提现
* *
* @param price 提现金额 * @param price 提现金额
* @return * @return
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Boolean applyWithdrawal(Double price) { public Boolean applyWithdrawal(Double price, String realName, String connectNumber) {
if (price == null || price <= 0 || price > 1000000) { if (price == null || price <= 0 || price > 1000000) {
throw new ServiceException(ResultCode.WALLET_WITHDRAWAL_AMOUNT_ERROR); throw new ServiceException(ResultCode.WALLET_WITHDRAWAL_AMOUNT_ERROR);
} }
MemberWithdrawalMessage memberWithdrawalMessage = new MemberWithdrawalMessage();
AuthUser authUser = UserContext.getCurrentUser(); AuthUser authUser = UserContext.getCurrentUser();
//校验金额是否满足提现因为是从余额扣减所以校验的是余额
MemberWalletVO memberWalletVO = this.getMemberWallet(authUser.getId());
if (memberWalletVO.getMemberWallet() < price) {
throw new ServiceException(ResultCode.WALLET_WITHDRAWAL_INSUFFICIENT);
}
//获取提现设置
Setting setting = settingService.get(SettingEnum.WITHDRAWAL_SETTING.name());
WithdrawalSetting withdrawalSetting = new Gson().fromJson(setting.getSettingValue(), WithdrawalSetting.class);
//判断金额是否小于最低提现金额
if (price < withdrawalSetting.getMinPrice()) {
throw new ServiceException(ResultCode.WALLET_APPLY_MIN_PRICE_ERROR.message());
}
//构建审核参数 //构建审核参数
MemberWithdrawApply memberWithdrawApply = new MemberWithdrawApply(); MemberWithdrawApply memberWithdrawApply = new MemberWithdrawApply();
memberWithdrawApply.setMemberId(authUser.getId()); memberWithdrawApply.setMemberId(authUser.getId());
memberWithdrawApply.setMemberName(authUser.getNickName()); memberWithdrawApply.setMemberName(authUser.getNickName());
memberWithdrawApply.setApplyMoney(price); memberWithdrawApply.setApplyMoney(price);
memberWithdrawApply.setApplyStatus(WithdrawStatusEnum.APPLY.name()); memberWithdrawApply.setRealName(realName);
memberWithdrawApply.setSn("W" + SnowFlake.getId()); memberWithdrawApply.setConnectNumber(connectNumber);
//校验该次提现是否需要审核,如果未进行配置 默认是需要审核
Setting setting = settingService.get(SettingEnum.WITHDRAWAL_SETTING.name());
if (setting != null) {
//如果不需要审核则审核自动通过
WithdrawalSetting withdrawalSetting = new Gson().fromJson(setting.getSettingValue(), WithdrawalSetting.class);
if (Boolean.FALSE.equals(withdrawalSetting.getApply())) {
memberWithdrawApply.setApplyStatus(WithdrawStatusEnum.VIA_AUDITING.name());
memberWithdrawApply.setInspectRemark("系统自动审核通过");
//校验金额是否满足提现因为是从余额扣减所以校验的是余额
MemberWalletVO memberWalletVO = this.getMemberWallet(memberWithdrawApply.getMemberId());
if (memberWalletVO.getMemberWallet() < price) {
throw new ServiceException(ResultCode.WALLET_WITHDRAWAL_INSUFFICIENT);
}
memberWithdrawalMessage.setStatus(WithdrawStatusEnum.VIA_AUDITING.name());
//微信零钱提现
Boolean result = withdrawal(memberWithdrawApply);
if (Boolean.TRUE.equals(result)) {
this.reduce(new MemberWalletUpdateDTO(price, authUser.getId(), "余额提现成功", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
}
} else {
memberWithdrawalMessage.setStatus(WithdrawStatusEnum.APPLY.name());
//扣减余额到冻结金额
this.reduceWithdrawal(new MemberWalletUpdateDTO(price, authUser.getId(), "提现金额已冻结,审核成功后到账", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
}
//发送余额提现申请消息
memberWithdrawalMessage.setMemberId(authUser.getId()); //判断提现是否需要审核
memberWithdrawalMessage.setPrice(price); if (withdrawalSetting.getApply()) {
memberWithdrawalMessage.setDestination(MemberWithdrawalDestinationEnum.WECHAT.name()); memberWithdrawApply.setApplyStatus(WithdrawStatusEnum.APPLY.name());
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_WITHDRAWAL.name(); } else {
rocketMQTemplate.asyncSend(destination, memberWithdrawalMessage, RocketmqSendCallbackBuilder.commonCallback()); memberWithdrawApply.setApplyStatus(WithdrawStatusEnum.VIA_AUDITING.name());
} }
return memberWithdrawApplyService.save(memberWithdrawApply);
memberWithdrawApply.setSn("W" + SnowFlake.getId());
//添加提现申请记录
memberWithdrawApplyService.save(memberWithdrawApply);
//扣减余额到冻结金额
this.reduceWithdrawal(new MemberWalletUpdateDTO(price, authUser.getId(), "提现金额已冻结", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
//发送余额提现申请消息
MemberWithdrawalMessage memberWithdrawalMessage = new MemberWithdrawalMessage();
memberWithdrawalMessage.setMemberWithdrawApplyId(memberWithdrawApply.getId());
memberWithdrawalMessage.setStatus(memberWithdrawApply.getApplyStatus());
memberWithdrawalMessage.setMemberId(authUser.getId());
memberWithdrawalMessage.setPrice(price);
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_WITHDRAWAL.name();
rocketMQTemplate.asyncSend(destination, memberWithdrawalMessage, RocketmqSendCallbackBuilder.commonCallback());
return true;
} }
@Override @Override
public Boolean withdrawal(MemberWithdrawApply memberWithdrawApply) { public Boolean withdrawal(String withdrawApplyId) {
MemberWithdrawApply memberWithdrawApply = memberWithdrawApplyService.getById(withdrawApplyId);
memberWithdrawApply.setInspectTime(new Date()); memberWithdrawApply.setInspectTime(new Date());
//保存或者修改零钱提现 //获取提现设置
this.memberWithdrawApplyService.saveOrUpdate(memberWithdrawApply); Setting setting = settingService.get(SettingEnum.WITHDRAWAL_SETTING.name());
//TODO 做成配置项目 WithdrawalSetting withdrawalSetting = new Gson().fromJson(setting.getSettingValue(), WithdrawalSetting.class);
cashierSupport.transfer(PaymentMethodEnum.WECHAT, memberWithdrawApply);
//调用提现方法
boolean result = true; boolean result = true;
//如果微信提现失败 则抛出异常 回滚数据 if ("WECHAT".equals(withdrawalSetting.getType())) {
if (!result) { result = cashierSupport.transfer(PaymentMethodEnum.WECHAT, memberWithdrawApply);
throw new ServiceException(ResultCode.WALLET_ERROR_INSUFFICIENT); } else if ("ALI".equals(withdrawalSetting.getType())) {
result = cashierSupport.transfer(PaymentMethodEnum.ALIPAY, memberWithdrawApply);
} }
//成功则扣减冻结金额
//失败则恢复冻结金额
if (result) {
memberWithdrawApply.setApplyStatus(WithdrawStatusEnum.SUCCESS.name());
} else {
memberWithdrawApply.setApplyStatus(WithdrawStatusEnum.ERROR.name());
}
//修改提现申请
this.memberWithdrawApplyService.updateById(memberWithdrawApply);
//发送余额提现申请消息
MemberWithdrawalMessage memberWithdrawalMessage = new MemberWithdrawalMessage();
memberWithdrawalMessage.setMemberWithdrawApplyId(memberWithdrawApply.getId());
memberWithdrawalMessage.setStatus(memberWithdrawApply.getApplyStatus());
memberWithdrawalMessage.setMemberId(memberWithdrawApply.getMemberId());
memberWithdrawalMessage.setPrice(memberWithdrawApply.getApplyMoney());
memberWithdrawalMessage.setStatus(memberWithdrawApply.getApplyStatus());
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_WITHDRAWAL.name();
rocketMQTemplate.asyncSend(destination, memberWithdrawalMessage, RocketmqSendCallbackBuilder.commonCallback());
return result; return result;
} }

View File

@ -7,10 +7,7 @@ import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.utils.StringUtils; import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO; import cn.lili.common.vo.PageVO;
import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply; import cn.lili.modules.wallet.entity.dos.MemberWithdrawApply;
import cn.lili.modules.wallet.entity.dto.MemberWalletUpdateDTO;
import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage; import cn.lili.modules.wallet.entity.dto.MemberWithdrawalMessage;
import cn.lili.modules.wallet.entity.enums.DepositServiceTypeEnum;
import cn.lili.modules.wallet.entity.enums.MemberWithdrawalDestinationEnum;
import cn.lili.modules.wallet.entity.enums.WithdrawStatusEnum; import cn.lili.modules.wallet.entity.enums.WithdrawStatusEnum;
import cn.lili.modules.wallet.entity.vo.MemberWalletVO; import cn.lili.modules.wallet.entity.vo.MemberWalletVO;
import cn.lili.modules.wallet.entity.vo.MemberWithdrawApplyQueryVO; import cn.lili.modules.wallet.entity.vo.MemberWithdrawApplyQueryVO;
@ -69,36 +66,18 @@ public class MemberWithdrawApplyServiceImpl extends ServiceImpl<MemberWithdrawAp
//如果审核通过 则微信直接提现反之则记录审核状态 //如果审核通过 则微信直接提现反之则记录审核状态
if (Boolean.TRUE.equals(result)) { if (Boolean.TRUE.equals(result)) {
memberWithdrawApply.setApplyStatus(WithdrawStatusEnum.VIA_AUDITING.name()); memberWithdrawApply.setApplyStatus(WithdrawStatusEnum.VIA_AUDITING.name());
//提现微信提现成功后扣减冻结金额
Boolean bool = memberWalletService.withdrawal(memberWithdrawApply);
if (Boolean.TRUE.equals(bool)) {
memberWithdrawalMessage.setStatus(WithdrawStatusEnum.VIA_AUDITING.name());
//保存修改审核记录
this.updateById(memberWithdrawApply);
//记录日志
memberWalletService.reduceFrozen(
new MemberWalletUpdateDTO(memberWithdrawApply.getApplyMoney(), memberWithdrawApply.getMemberId(), "审核通过,余额提现", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()))
;
} else {
//如果提现失败则无法审核
throw new ServiceException(ResultCode.WALLET_APPLY_ERROR);
}
} else { } else {
memberWithdrawalMessage.setStatus(WithdrawStatusEnum.FAIL_AUDITING.name());
//如果审核拒绝 审核备注必填
if (StringUtils.isEmpty(remark)) {
throw new ServiceException(ResultCode.WALLET_REMARK_ERROR);
}
memberWithdrawApply.setApplyStatus(WithdrawStatusEnum.FAIL_AUDITING.name()); memberWithdrawApply.setApplyStatus(WithdrawStatusEnum.FAIL_AUDITING.name());
//保存修改审核记录 //保存修改审核记录
this.updateById(memberWithdrawApply); this.updateById(memberWithdrawApply);
//需要从冻结金额扣减到余额
memberWalletService.increaseWithdrawal(new MemberWalletUpdateDTO(memberWithdrawApply.getApplyMoney(), memberWithdrawApply.getMemberId(), "审核拒绝,提现金额解冻到余额", DepositServiceTypeEnum.WALLET_WITHDRAWAL.name()));
} }
//发送审核消息 //发送审核消息
memberWithdrawalMessage.setStatus(memberWithdrawApply.getApplyStatus());
memberWithdrawalMessage.setMemberWithdrawApplyId(memberWithdrawApply.getId());
memberWithdrawalMessage.setMemberId(memberWithdrawApply.getMemberId()); memberWithdrawalMessage.setMemberId(memberWithdrawApply.getMemberId());
memberWithdrawalMessage.setPrice(memberWithdrawApply.getApplyMoney()); memberWithdrawalMessage.setPrice(memberWithdrawApply.getApplyMoney());
memberWithdrawalMessage.setDestination(MemberWithdrawalDestinationEnum.WECHAT.name());
String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_WITHDRAWAL.name(); String destination = rocketmqCustomProperties.getMemberTopic() + ":" + MemberTagsEnum.MEMBER_WITHDRAWAL.name();
rocketMQTemplate.asyncSend(destination, memberWithdrawalMessage, RocketmqSendCallbackBuilder.commonCallback()); rocketMQTemplate.asyncSend(destination, memberWithdrawalMessage, RocketmqSendCallbackBuilder.commonCallback());

View File

@ -10,6 +10,7 @@ import cn.lili.common.utils.DateUtil;
import cn.lili.common.utils.StringUtils; import cn.lili.common.utils.StringUtils;
import cn.lili.modules.connect.entity.Connect; import cn.lili.modules.connect.entity.Connect;
import cn.lili.modules.connect.entity.enums.ConnectEnum; import cn.lili.modules.connect.entity.enums.ConnectEnum;
import cn.lili.modules.connect.entity.enums.SourceEnum;
import cn.lili.modules.connect.service.ConnectService; import cn.lili.modules.connect.service.ConnectService;
import cn.lili.modules.member.entity.dto.ConnectQueryDTO; import cn.lili.modules.member.entity.dto.ConnectQueryDTO;
import cn.lili.modules.order.order.entity.dos.Order; import cn.lili.modules.order.order.entity.dos.Order;
@ -144,7 +145,7 @@ public class WechatMessageUtil {
} }
Connect connect = connectService.queryConnect( Connect connect = connectService.queryConnect(
ConnectQueryDTO.builder().userId(order.getMemberId()).unionType(ConnectEnum.WECHAT_MP_OPEN_ID.name()).build() ConnectQueryDTO.builder().userId(order.getMemberId()).unionType(SourceEnum.WECHAT_MP_OPEN_ID.name()).build()
); );
if (connect == null) { if (connect == null) {
return; return;

View File

@ -30,7 +30,11 @@ public enum MemberTagsEnum {
/** /**
* 会员积分变动 * 会员积分变动
*/ */
MEMBER_POINT_CHANGE("会员积分变动"); MEMBER_POINT_CHANGE("会员积分变动"),
/**
* 会员使用联合登录
*/
MEMBER_CONNECT_LOGIN("会员使用联合登录");
private final String description; private final String description;