商户查看用户手机号

This commit is contained in:
墨大叔 2024-10-14 18:03:16 +08:00
parent b994a52f13
commit beaa110dad
27 changed files with 323 additions and 61 deletions

View File

@ -1,8 +1,11 @@
package com.ruoyi.common.auth.wx;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.config.WxConfig;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.http.HttpUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -29,4 +32,38 @@ public class WxAuthService {
return JSON.parseObject(body, WxMaJscode2SessionResult.class);
}
/**
* 通过微信手机号授权码获取微信手机号
* @param mobileCode 微信手机号授权码
* @return
*/
public String getWxPhoneNumber(String mobileCode) {
String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";
// 根据手机号获取到用户名
String token = AccessTokenUtil.getToken();
url = url + token;
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", mobileCode);
String post = HttpUtils.sendPost(url, jsonObject.toString());
// 获取微信用户手机号
JSONObject body = JSONObject.parseObject(post);
if (body == null) {
return null;
}
Integer errcode = body.getInteger("errcode");
if (errcode == null || !errcode.equals(0)) {
throw new ServiceException("获取手机号失败:" + body.getString("errmsg"));
}
String phoneInfo = body.getString("phone_info");
WxMaPhoneNumberInfo wxMaPhoneNumberInfo = JSONObject.parseObject(phoneInfo, WxMaPhoneNumberInfo.class);
if (wxMaPhoneNumberInfo == null) {
return null;
}
return wxMaPhoneNumberInfo.getPhoneNumber();
}
}

View File

@ -217,4 +217,14 @@ public class SmUser extends BaseEntity
@Excel(name = "限制退款时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty("限制退款时间")
private LocalDateTime limitRefundTime;
@Excel(name = "订单是否查看用户手机号")
@ApiModelProperty("订单是否查看用户手机号")
@JsonView(JsonViewProfile.App.class)
private Boolean showBillMobile;
@Excel(name = "订单查看用户手机号所需的金额", readConverterExp = "元=/单")
@ApiModelProperty("订单查看用户手机号所需的金额")
private BigDecimal showBillMobilePrice;
}

View File

@ -274,7 +274,7 @@ public class SysLoginService
boolean loginWithPhone = sysConfigService.getBoolean(ConfigKey.ARRIVAL_DELAY);
String mobile = null;
if (loginWithPhone && StringUtils.hasText(body.getMobileCode())) {
mobile = this.getWxPhoneNumber(body.getMobileCode());
mobile = wxAuthService.getWxPhoneNumber(body.getMobileCode());
}
// 用户注册
user = registerWx(openId, mobile);
@ -333,41 +333,6 @@ public class SysLoginService
return newUser;
}
/**
* 通过授权码获取微信用户手机号
* @param mobileCode
* @return
*/
private String getWxPhoneNumber(String mobileCode) {
String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";
// 根据手机号获取到用户名
String token = AccessTokenUtil.getToken();
url = url + token;
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", mobileCode);
String post = HttpUtils.sendPost(url, jsonObject.toString());
log.info("获取手机号body:{}", post);
// 获取微信用户手机号
JSONObject body = JSONObject.parseObject(post);
if (body == null) {
return null;
}
Integer errcode = body.getInteger("errcode");
if (errcode == null || !errcode.equals(0)) {
throw new ServiceException("获取手机号失败:" + body.getString("errmsg"));
}
String phoneInfo = body.getString("phone_info");
WxMaPhoneNumberInfo wxMaPhoneNumberInfo = JSONObject.parseObject(phoneInfo, WxMaPhoneNumberInfo.class);
if (wxMaPhoneNumberInfo == null) {
return null;
}
return wxMaPhoneNumberInfo.getPhoneNumber();
}
public String userLogin(String username, String password, String code, String uuid) {
// 验证码校验
validateCaptcha(username, code, uuid);

View File

@ -90,6 +90,10 @@ public class DeviceVO extends Device implements IotDevice {
@ApiModelProperty("代理商手机号")
private String agentMobile;
@ApiModelProperty("商户是否需要用户手机号")
@JsonView(DeviceView.SuitList.class)
private Boolean mchShowBillMobile;
@Override
public String iotMac1() {
return getMac();

View File

@ -162,6 +162,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
su.phonenumber as user_mobile,
su.user_name as user_name,
su.service_rate as user_service_rate,
su.show_bill_mobile as mch_show_bill_mobile,
sua.user_name as agent_name,
sua.phonenumber as agent_mobile,
sua.agent_service_rate as agent_user_service_rate

View File

@ -144,12 +144,6 @@ public class MchApplyServiceImpl implements IMchApplyService
int i = mchApplyMapper.updateWithCondition(apply, condition);
ServiceUtil.assertion(i != 1, "当前申请状态已发生变更,请刷新后重试");
// 如果成功则将用户修改为商家
if (pass) {
int i1 = userService.setMch(dbApply.getUserId());
ServiceUtil.assertion(i1 != 1, "将用户修改为商家失败,请刷新后重试");
}
return Boolean.TRUE;
});

View File

@ -12,7 +12,8 @@ import lombok.Getter;
public enum ReceiveBillType {
MONTH("1", "月费"),
OTHER("2", "其他");
OTHER("2", "其他"),
MOBILE("3", "商户获取用户手机号");
private final String type;

View File

@ -315,6 +315,23 @@ public class TransactionBill extends BaseEntity implements Payable
@ApiModelProperty("设备开启状态描述")
private String openMsg;
@Excel(name = "用户手机号")
@ApiModelProperty("用户手机号")
@JsonView(JsonViewProfile.AppMch.class)
private String userMobile;
@Excel(name = "商户是否展示用户手机号")
@ApiModelProperty("商户是否展示用户手机号")
private Boolean mchShowMobile;
@Excel(name = "商户展示手机号价格")
@ApiModelProperty("商户展示手机号价格")
private BigDecimal mchShowMobilePrice;
@Excel(name = "商户展示手机号缴费状态", readConverterExp = "1=-待缴费2-已缴费")
@ApiModelProperty("商户展示手机号缴费状态")
private String mchShowMobileStatus;
/**
* 获取价格
*/

View File

@ -0,0 +1,22 @@
package com.ruoyi.ss.transactionBill.domain.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 充值商户获取用户手机号缴费状态
* @author wjh
* 2024/10/14
*/
@Getter
@AllArgsConstructor
public enum RechargeBillShowMobileStatus {
UNPAID("1", "待缴费"),
PAID("2", "已缴费"),
;
private final String status;
private final String msg;
}

View File

@ -40,10 +40,6 @@ public class TransactionBillVO extends TransactionBill implements IotDevice {
@JsonView(JsonViewProfile.AppMch.class)
private String mchMobile;
@ApiModelProperty("用户手机号")
@JsonView(JsonViewProfile.App.class)
private String userMobile;
@ApiModelProperty("设备总用电量")
@JsonView(JsonViewProfile.App.class)
private BigDecimal deviceTotalEle;

View File

@ -78,6 +78,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
stb.suit_void_msg,
stb.suit_deposit,
stb.open_msg,
stb.user_mobile,
stb.mch_show_mobile,
stb.mch_show_mobile_price,
stb.mch_show_mobile_status,
</sql>
<sql id="selectSmTransactionBillVo">
@ -187,7 +191,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.withdrawType != null"> and stb.withdraw_type = #{query.withdrawType}</if>
<if test="query.money != null"> and stb.money = #{query.money}</if>
<if test="query.deviceNo != null and query.deviceNo != ''"> and sd.device_no like concat('%', #{query.deviceNo}, '%')</if>
<if test="query.userMobile != null and query.userMobile != ''"> and su.phonenumber like concat('%', #{query.userMobile}, '%')</if>
<if test="query.userMobile != null and query.userMobile != ''"> and stb.user_mobile like concat('%', #{query.userMobile}, '%')</if>
<if test="query.suitFeeMode != null and query.suitFeeMode != ''"> and stb.suit_fee_mode = #{query.suitFeeMode}</if>
<if test="query.suitFeeType != null and query.suitFeeType != ''"> and stb.suit_fee_type = #{query.suitFeeType}</if>
<if test="query.suitEnableLowPowerClose != null "> and stb.suit_enable_low_power_close = #{query.suitEnableLowPowerClose}</if>
@ -201,6 +205,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.suitEnabledVoid != null "> and stb.suit_enabled_void = #{query.suitEnabledVoid}</if>
<if test="query.suitVoidResult != null and query.suitVoidResult != ''"> and stb.suit_void_result = #{query.suitVoidResult}</if>
<if test="query.openMsg != null and query.openMsg != ''"> and stb.open_msg like concat('%', #{query.openMsg}, '%')</if>
<if test="query.mchShowMobileStatus != null and query.mchShowMobileStatus != ''"> and stb.mch_show_mobile_status = #{query.mchShowMobileStatus}</if>
<if test="query.isUsing != null">
<if test="query.isUsing">
and <include refid="isUsing"/>
@ -485,6 +490,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="suitVoidMsg != null">suit_void_msg,</if>
<if test="suitDeposit != null">suit_deposit,</if>
<if test="openMsg != null">open_msg,</if>
<if test="userMobile != null">user_mobile,</if>
<if test="mchShowMobile != null">mch_show_mobile,</if>
<if test="mchShowMobilePrice != null">mch_show_mobile_price,</if>
<if test="mchShowMobileStatus != null and mchShowMobileStatus != ''">mch_show_mobile_status,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="billNo != null">#{billNo},</if>
@ -551,6 +560,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="suitVoidMsg != null">#{suitVoidMsg},</if>
<if test="suitDeposit != null">#{suitDeposit},</if>
<if test="openMsg != null">#{openMsg},</if>
<if test="userMobile != null">#{userMobile},</if>
<if test="mchShowMobile != null">#{mchShowMobile},</if>
<if test="mchShowMobilePrice != null">#{mchShowMobilePrice},</if>
<if test="mchShowMobileStatus != null and mchShowMobileStatus != ''">#{mchShowMobileStatus},</if>
</trim>
</insert>
@ -635,6 +648,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="data.suitVoidMsg != null">stb.suit_void_msg = #{data.suitVoidMsg},</if>
<if test="data.suitDeposit != null">stb.suit_deposit = #{data.suitDeposit},</if>
<if test="data.openMsg != null">stb.open_msg = #{data.openMsg},</if>
<if test="data.userMobile != null">stb.user_mobile = #{data.userMobile},</if>
<if test="data.mchShowMobile != null">stb.mch_show_mobile = #{data.mchShowMobile},</if>
<if test="data.mchShowMobilePrice != null">stb.mch_show_mobile_price = #{data.mchShowMobilePrice},</if>
<if test="data.mchShowMobileStatus != null and data.mchShowMobileStatus != ''">stb.mch_show_mobile_status = #{data.mchShowMobileStatus},</if>
</sql>
<update id="updateByQuery">

View File

@ -37,4 +37,11 @@ public interface TransactionAssembler {
* @param list
*/
void assembleTotalUse(List<TransactionBillVO> list);
/**
* 处理用户的手机号
* @param list
*/
void handleMchUserMobile(List<TransactionBillVO> list);
}

View File

@ -322,4 +322,10 @@ public interface TransactionBillService
*/
int fixAll();
/**
* 收取商户查看用户手机号的价格
* @param bill
* @return
*/
int receiveMchShowMobileAmount(TransactionBillVO bill);
}

View File

@ -67,6 +67,10 @@ public class RechargeDepositAfterPay implements AfterPay {
int update = transactionBillService.updateByQuery(data, query);
ServiceUtil.assertion(update != 1, "修改订单信息失败,状态已经发生改变:%s", bill.getBillNo());
// 处理商户获取手机号扣款
int received = transactionBillService.receiveMchShowMobileAmount(bill);
ServiceUtil.assertion(received != 1, "商户获取用户手机号扣款失败");
this.openDevice(bill.getBillId(), device);
return update;

View File

@ -115,6 +115,10 @@ public class RechargePayHandler implements AfterPay, AfterRefund {
int updateCount = transactionBillService.updateByQuery(data, query);
ServiceUtil.assertion(updateCount != 1, "订单状态已发生变化,请刷新后重试");
// 处理商户获取手机号扣款
int received = transactionBillService.receiveMchShowMobileAmount(bill);
ServiceUtil.assertion(received != 1, "商户获取用户手机号扣款失败");
return updateCount;
});

View File

@ -12,6 +12,7 @@ import com.ruoyi.ss.channel.service.ChannelService;
import com.ruoyi.ss.channelWithdraw.service.ChannelWithdrawService;
import com.ruoyi.ss.suit.domain.enums.SuitFeeMode;
import com.ruoyi.ss.suit.domain.enums.SuitFeeType;
import com.ruoyi.ss.transactionBill.domain.enums.RechargeBillShowMobileStatus;
import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO;
import com.ruoyi.ss.transactionBill.service.TransactionAssembler;
import org.springframework.beans.factory.annotation.Autowired;
@ -141,4 +142,21 @@ public class TransactionAssemblerImpl implements TransactionAssembler {
}
}
@Override
public void handleMchUserMobile(List<TransactionBillVO> list) {
if (CollectionUtils.isNotEmptyElement(list)) {
return;
}
for (TransactionBillVO bill : list) {
if (bill == null) {
continue;
}
boolean payed = RechargeBillShowMobileStatus.PAID.getStatus().equals(bill.getMchShowMobileStatus()); // 是否已经缴费
if (bill.getMchShowMobile() == null || !bill.getMchShowMobile() || !payed) {
bill.setUserMobile(null);
}
}
}
}

View File

@ -31,6 +31,9 @@ import com.ruoyi.ss.payBill.domain.enums.PayBillBstType;
import com.ruoyi.ss.payBill.domain.vo.DoPayVO;
import com.ruoyi.ss.payBill.service.PayBillConverter;
import com.ruoyi.ss.payBill.service.PayBillService;
import com.ruoyi.ss.receiveBill.domain.ReceiveBill;
import com.ruoyi.ss.receiveBill.domain.enums.ReceiveBillStatus;
import com.ruoyi.ss.receiveBill.domain.enums.ReceiveBillType;
import com.ruoyi.ss.receiveBill.service.ReceiveBillService;
import com.ruoyi.ss.record.time.domain.enums.RecordTimeType;
import com.ruoyi.ss.record.time.service.IRecordTimeService;
@ -374,6 +377,53 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
return 1;
}
@Override
public int receiveMchShowMobileAmount(TransactionBillVO bill) {
ServiceUtil.assertion(bill == null, "订单不存在");
// 若未开启该功能则跳过
if (bill.getMchShowMobile() == null || !bill.getMchShowMobile()) {
return 1;
}
Integer result = transactionTemplate.execute(status -> {
// 创建应收账
ReceiveBill receive = new ReceiveBill();
receive.setUserId(bill.getMchId());
receive.setDeviceId(bill.getDeviceId());
receive.setType(ReceiveBillType.MOBILE.getType());
receive.setStatus(ReceiveBillStatus.PAID.getStatus());
receive.setBillTime(LocalDateTime.now());
receive.setAmount(bill.getMchShowMobilePrice());
receive.setDescription("商户获取用户手机号订单:" + bill.getBillNo());
receive.setReceivedAmount(bill.getMchShowMobilePrice());
int insert = receiveBillService.insertReceiveBill(receive);
ServiceUtil.assertion(insert != 1, "创建收款失败");
// 收款
userService.subtractBalance(
receive.getUserId(),
receive.getAmount(),
false,
receive.getDescription(),
RecordBalanceBstType.RECEIVABLE,
receive.getBillId()
);
// 修改订单缴费状态
TransactionBill data = new TransactionBill();
data.setMchShowMobileStatus(RechargeBillShowMobileStatus.PAID.getStatus());
TransactionBillQuery query = new TransactionBillQuery();
query.setBillId(bill.getBillId());
query.setMchShowMobileStatus(RechargeBillShowMobileStatus.UNPAID.getStatus());
int update = this.updateByQuery(data, query);
ServiceUtil.assertion(update != 1, "修改订单缴费状态失败,请刷新后重试");
return update;
});
return result == null ? 0 :result;
}
private int fix(TransactionBillVO bill) {
if (bill == null || bill.getBillId() == null) {
log.warn("修复订单数据失败订单不存在或订单ID为空");
@ -445,6 +495,13 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
// 用户信息
order.setUserId(user.getUserId());
order.setUserMobile(user.getPhonenumber());
// 商户信息
order.setMchId(mch.getUserId());
order.setMchShowMobile(mch.getShowBillMobile());
order.setMchShowMobilePrice(mch.getShowBillMobilePrice());
order.setMchShowMobileStatus(RechargeBillShowMobileStatus.UNPAID.getStatus());
// 套餐信息
order.setSuitId(suit.getSuitId());
@ -462,9 +519,8 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
order.setSuitVoidMinute(suit.getVoiceMinutes());
// 设备信息
order.setDeviceNo(dto.getDeviceNo());
order.setDeviceNo(device.getDeviceNo());
order.setDeviceId(device.getDeviceId());
order.setMchId(mch.getUserId());
order.setDeviceName(device.getDeviceName());
order.setDeviceMac(device.getMac());
order.setDeviceMac2(device.getMac2());
@ -1389,7 +1445,8 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
BigDecimal total = BigDecimal.ZERO;
// 计算每小时平均用电量
Duration betweenAvg = Duration.between(order.getSuitStartTime(), endTime);
LocalDateTime startTime = order.getSuitStartTime() == null ? LocalDateTime.now() : order.getSuitStartTime();
Duration betweenAvg = Duration.between(startTime, endTime);
long hours = betweenAvg.toHours();
if (hours == 0) {
hours = 1;
@ -1399,7 +1456,6 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
BigDecimal avgEle = usedEle.divide(BigDecimal.valueOf(hours), 2, RoundingMode.HALF_UP); // 平均每小时的用电量
// 初始时间
LocalDateTime startTime = order.getSuitStartTime();
List<BigDecimal> suitGearAmount = order.getSuitGearAmount();
List<Integer> suitGearTime = order.getSuitGearTime();
int hour = startTime.getHour() ;
@ -1417,7 +1473,7 @@ public class TransactionBillServiceImpl implements TransactionBillService, After
// 计算分时段计时金额
private BigDecimal calcTimingTimeAmount(TransactionBillVO order, LocalDateTime endTime) {
LocalDateTime startTime = order.getSuitStartTime();
LocalDateTime startTime = order.getSuitStartTime() == null ? LocalDateTime.now() : order.getSuitStartTime();
List<BigDecimal> suitGearAmount = order.getSuitGearAmount();
List<Integer> suitGearTime = order.getSuitGearTime();

View File

@ -76,12 +76,10 @@ public class TransactionBillValidatorImpl extends BaseValidator implements Trans
// 用户
SmUserVo user = bo.getUser();
// 检查用户是否有未支付的智能分时段订单
if (this.hasUnpaidSmartTimingOrder(user.getUserId())) {
return error("您有未支付的订单,请先支付后继续");
}
// 检查用户是否有正在使用中的智能订单
if (this.hasUsingSmartOrder(user.getUserId())) {
return error("您有正在使用中的智能订单,请结束后继续");
@ -108,9 +106,14 @@ public class TransactionBillValidatorImpl extends BaseValidator implements Trans
}
// 商户检查
SmUserVo mch = bo.getMch();
if (!userValidator.isUsage(device.getUserId())) {
return error("当前设备商户不存在或不可用,无法充值,请确认商户账号是否正常");
}
// 若商户开启了获取用户手机号则判断用户是否有手机号
if (mch.getShowBillMobile() != null && mch.getShowBillMobile() && StringUtils.isBlank(user.getPhonenumber())) {
return error("当前用户未绑定手机号,无法下单");
}
// 套餐检查
SuitVO suit = bo.getSuit();

View File

@ -29,4 +29,7 @@ public class SmUserQuery extends SmUser {
@ApiModelProperty("租户设备id")
private Long tenantDeviceId;
@ApiModelProperty("用户手机号精准匹配")
private String eqPhonenumber;
}

View File

@ -122,4 +122,9 @@ public interface SmUserMapper
* 根据用户手机号查询数量
*/
int selectCountByPhone(@Param("phonenumber") String phone);
/**
* 绑定手机号
*/
int bindMobile(@Param("userId") Long userId, @Param("mobile") String mobile);
}

View File

@ -56,6 +56,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
su.arrival_delay,
su.type,
su.limit_refund_time,
su.show_bill_mobile,
su.show_bill_mobile_price,
if(su.is_real, su.real_name, su.user_name) as real_or_user_name,
(select sum(stb.money) from sm_transaction_bill stb where stb.user_id = su.user_id and stb.type = '1' and stb.status = '2') as recharge_amount,
(select sum(stb.arrival_amount) from sm_transaction_bill stb where stb.user_id = su.user_id and stb.type = '2' and stb.status = '14') as with_drawl_amount,
@ -67,6 +69,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="userName != null and userName != ''"> and su.user_name like concat('%', #{userName}, '%')</if>
<if test="nickName != null and nickName != ''"> and su.nick_name like concat('%', #{nickName}, '%')</if>
<if test="phonenumber != null and phonenumber != ''"> and su.phonenumber like concat('%', #{phonenumber}, '%')</if>
<if test="eqPhonenumber != null and eqPhonenumber != ''"> and su.phonenumber = #{eqPhonenumber}</if>
<if test="sex != null and sex != ''"> and su.sex = #{sex}</if>
<if test="type != null and type != ''"> and su.type = #{type}</if>
<if test="status != null and status != ''"> and su.status = #{status}</if>
@ -82,6 +85,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="limitWithdraw != null "> and limit_withdraw = #{limitWithdraw}</if>
<if test="limitRefund != null "> and limit_refund = #{limitRefund}</if>
<if test="readMchLicence != null "> and read_mch_licence = #{readMchLicence}</if>
<if test="showBillMobile != null "> and show_bill_mobile = #{showBillMobile}</if>
<if test="tenantDeviceId != null">
and su.user_id in (
select sdt.tenant_id
@ -186,6 +190,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="agentServiceRate != null">agent_service_rate,</if>
<if test="type != null">`type`,</if>
<if test="limitRefundTime != null">limit_refund_time,</if>
<if test="showBillMobile != null">show_bill_mobile,</if>
<if test="showBillMobilePrice != null">show_bill_mobile_price,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userName != null and userName != ''">#{userName},</if>
@ -230,6 +236,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="agentServiceRate != null">#{agentServiceRate},</if>
<if test="type != null">#{type},</if>
<if test="limitRefundTime != null">#{limitRefundTime},</if>
<if test="showBillMobile != null">#{showBillMobile},</if>
<if test="showBillMobilePrice != null">#{showBillMobilePrice},</if>
</trim>
</insert>
@ -290,6 +298,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="agentServiceRate != null">agent_service_rate = #{agentServiceRate},</if>
<if test="type != null">`type` = #{type},</if>
<if test="limitRefundTime != null">limit_refund_time = #{limitRefundTime},</if>
<if test="showBillMobile != null">show_bill_mobile = #{showBillMobile},</if>
<if test="showBillMobilePrice != null">show_bill_mobile_price = #{showBillMobilePrice},</if>
</trim>
where user_id = #{userId}
</update>
@ -323,6 +333,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where user_id = #{userId} and del_flag = '0'
</update>
<update id="bindMobile">
update sm_user
set phonenumber = #{mobile}
where user_id = #{userId} and (phonenumber is null or phonenumber = '')
</update>
<delete id="deleteSmUserByUserId" parameterType="Long">
delete from sm_user where user_id = #{userId}
</delete>

View File

@ -254,4 +254,12 @@ public interface ISmUserService
* 更新手机号
*/
int updateMobile(Long userId, String mobile);
/**
* 绑定微信手机号
*
* @param userId
* @param mobileCode 微信手机号临时授权码
*/
int bindWxMobile(Long userId, String mobileCode);
}

View File

@ -1,6 +1,7 @@
package com.ruoyi.ss.user.service;
import com.ruoyi.common.core.domain.ValidateResult;
import com.ruoyi.ss.user.domain.SmUserVo;
import java.util.List;
@ -32,4 +33,10 @@ public interface UserValidator {
* 逻辑删除前校验
*/
ValidateResult preLogicDel(List<Long> userIds);
/**
* 校验手机号
* @param vo
*/
void checkMobile(SmUserVo vo);
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.ss.user.service.impl;
import com.ruoyi.common.auth.wx.WxAuthService;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.entity.SmUser;
import com.ruoyi.common.core.redis.RedisCache;
@ -38,6 +39,7 @@ import com.ruoyi.ss.user.domain.dto.UserRealNameDTO;
import com.ruoyi.ss.user.domain.vo.UserRealNameVO;
import com.ruoyi.ss.user.mapper.SmUserMapper;
import com.ruoyi.ss.user.service.ISmUserService;
import com.ruoyi.ss.user.service.UserValidator;
import com.ruoyi.system.domain.enums.config.ConfigKey;
import com.ruoyi.system.domain.enums.verificationCode.CodeBusinessType;
import com.ruoyi.system.service.ISysConfigService;
@ -94,9 +96,15 @@ public class SmUserServiceImpl implements ISmUserService
@Autowired
private IVerificationCodeService verificationCodeService;
@Autowired
private UserValidator userValidator;
// 活体检测返回地址
public static final String LIVENESS_RETURN_URL = SpringUtils.getRequiredProperty("liveness.returnUrl");
@Autowired
private WxAuthService wxAuthService;
/**
* 查询普通用户信息
*
@ -499,6 +507,30 @@ public class SmUserServiceImpl implements ISmUserService
return result == null ? 0 : result;
}
@Override
public int bindWxMobile(Long userId, String mobileCode) {
if (StringUtils.isBlank(mobileCode)) {
log.warn("微信手机号临时授权码为空");
return 0;
}
String mobile = wxAuthService.getWxPhoneNumber(mobileCode);
ServiceUtil.assertion(StringUtils.isBlank(mobile), "获取微信手机号失败");
Integer result = transactionTemplate.execute(status -> {
// 更新
int update = smUserMapper.bindMobile(userId, mobile);
ServiceUtil.assertion(update != 1, "绑定手机号失败,请刷新后重试");
// 后校验
SmUserVo vo = this.selectSmUserByUserId(userId);
userValidator.checkMobile(vo);
return update;
});
return result == null ? 0 : result;
}
private int selectCountByPhone(String phone) {
return smUserMapper.selectCountByPhone(phone);
}
@ -578,8 +610,10 @@ public class SmUserServiceImpl implements ISmUserService
}
// 判断手机号是否重复
SmUserVo repeatPhone = selectUserByPhone(data.getPhonenumber());
ServiceUtil.assertion(repeatPhone != null && !Objects.equals(repeatPhone.getUserId(), data.getUserId()), "用户手机号重复");
if (StringUtils.hasText(data.getPhonenumber())) {
SmUserVo repeatPhone = selectUserByPhone(data.getPhonenumber());
ServiceUtil.assertion(repeatPhone != null && !Objects.equals(repeatPhone.getUserId(), data.getUserId()), "用户手机号重复");
}
// 判断微信openId是否重复
SmUserVo repeatWxOpenId = selectUserByWxOpenId(data.getWxOpenId());

View File

@ -3,6 +3,8 @@ package com.ruoyi.ss.user.service.impl;
import com.ruoyi.common.core.domain.BaseValidator;
import com.ruoyi.common.core.domain.ValidateResult;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.ss.user.domain.SmUserQuery;
import com.ruoyi.ss.user.domain.SmUserVo;
import com.ruoyi.ss.user.service.ISmUserService;
@ -87,4 +89,19 @@ public class UserValidatorImpl extends BaseValidator implements UserValidator {
}
return success();
}
@Override
public void checkMobile(SmUserVo vo) {
if (vo == null) {
return;
}
// 校验手机是否重复
if (StringUtils.hasText(vo.getPhonenumber())) {
SmUserQuery query = new SmUserQuery();
query.setEqPhonenumber(vo.getPhonenumber());
Integer repeatCount = userService.selectCount(query);
ServiceUtil.assertion(repeatCount > 1, "用户手机号重复");
}
}
}

View File

@ -125,6 +125,7 @@ public class AppTransactionBillController extends BaseController
query.setType(TransactionBillType.RECHARGE.getType());
List<TransactionBillVO> list = transactionBillService.selectSmTransactionBillList(query);
transactionAssembler.assembleChannelName(list);
transactionAssembler.handleMchUserMobile(list);
return getDataTable(list);
}
@ -134,7 +135,9 @@ public class AppTransactionBillController extends BaseController
public AjaxResult detail(@PathVariable Long billId) {
ServiceUtil.assertion(transactionBillValidator.preGetDetailByApp(billId, getUserId()));
TransactionBillVO bill = transactionBillService.selectSmTransactionBillByBillId(billId);
List<TransactionBillVO> list = Collections.singletonList(bill);
transactionAssembler.assembleChannelName(Collections.singletonList(bill));
transactionAssembler.handleMchUserMobile(list);
return AjaxResult.success(bill);
}
@ -199,7 +202,6 @@ public class AppTransactionBillController extends BaseController
return AjaxResult.success(transactionBillService.cancelRecharge(billNo, TransactionBillStatus.CANCELED));
}
// @MchRequired
@ApiOperation("提现申请")
@PostMapping("/withdraw")
public AjaxResult withdraw(@RequestBody @Validated WithdrawDTO dto) {
@ -224,7 +226,10 @@ public class AppTransactionBillController extends BaseController
query.setType(TransactionBillType.RECHARGE.getType());
query.setStatus(TransactionBillStatus.SUCCESS.getStatus());
startPage();
return getDataTable(transactionBillService.selectSmTransactionBillList(query));
List<TransactionBillVO> list = transactionBillService.selectSmTransactionBillList(query);
// 处理手机号
transactionAssembler.handleMchUserMobile(list);
return getDataTable(list);
}
@ApiOperation("蓝牙充值成功回调")

View File

@ -20,8 +20,8 @@ import com.ruoyi.ss.user.service.UserAssembler;
import com.ruoyi.system.domain.enums.verificationCode.CodeBusinessType;
import com.ruoyi.system.service.IVerificationCodeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -124,7 +124,7 @@ public class AppUserController extends BaseController {
return success(verificationCodeService.sendMobileCode(mobile, CodeBusinessType.CHANGE_MOBILE_NEW));
}
@ApiOperation("修改手机号")
@ApiOperation("通过验证码修改手机号")
@PutMapping("/changeMobile")
public AjaxResult changeMobile(@RequestBody UserChangeMobileDTO dto) {
SmUserVo user = userService.selectSmUserByUserId(getUserId());
@ -142,4 +142,9 @@ public class AppUserController extends BaseController {
return success(userService.updateMobile(getUserId(), dto.getNewMobile()));
}
@ApiOperation("绑定微信手机号")
@PutMapping("/bindWxMobile")
public AjaxResult bindWxMobile(@ApiParam("微信手机号临时授权码") String mobileCode) {
return toAjax(userService.bindWxMobile(getUserId(), mobileCode));
}
}