diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/auth/ali/AliConfig.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/auth/ali/AliConfig.java index 7718736d..ce317d6b 100644 --- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/auth/ali/AliConfig.java +++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/auth/ali/AliConfig.java @@ -25,14 +25,6 @@ public class AliConfig { @Value("${ali.privateKey}") private String privateKey; -// // 应用公钥 -// @Value("${ali.publicKey}") -// private String publicKey; -// -// // 支付宝公钥 -// @Value("${ali.alipayPublicKey}") -// private String alipayPublicKey; - @Value("${ali.aesPrivateKey}") private String aesPrivateKey; @@ -51,18 +43,6 @@ public class AliConfig { @Value("${ali.alipayRootCertPath}") private String alipayRootCertPath; -// private AlipayConfig getAlipayConfig() { -// AlipayConfig alipayConfig = new AlipayConfig(); -// alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do"); -// alipayConfig.setAppId(appId); -// alipayConfig.setPrivateKey(privateKey); -// alipayConfig.setAlipayPublicKey(alipayPublicKey); -// alipayConfig.setFormat("json"); -// alipayConfig.setCharset("UTF-8"); -// alipayConfig.setSignType("RSA2"); -// return alipayConfig; -// } - // 证书模式 @Bean public AlipayClient alipayClient() { diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/auth/wx/AccessTokenUtil.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/auth/wx/AccessTokenUtil.java index 248d2eaf..64ff11a9 100644 --- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/auth/wx/AccessTokenUtil.java +++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/auth/wx/AccessTokenUtil.java @@ -3,6 +3,7 @@ package com.ruoyi.common.auth.wx; import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; +import com.ruoyi.common.config.WxConfig; import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.StringUtils; @@ -13,23 +14,26 @@ import java.util.concurrent.TimeUnit; public class AccessTokenUtil { - public static final String APPID = SpringUtils.getRequiredProperty("wx.appid"); - public static final String APP_SECRET = SpringUtils.getRequiredProperty("wx.appSecret"); - @SneakyThrows - public static String getToken() { + public static String getToken(WxConfig wxConfig) { + if (wxConfig == null) { + return null; + } + RedisCache redisCache = SpringUtils.getBean(RedisCache.class); - String token = redisCache.getCacheObject(CacheConstants.WX_ACCESS_TOKEN); + + String cacheKey = CacheConstants.WX_ACCESS_TOKEN + wxConfig.getAppId(); + String token = redisCache.getCacheObject(cacheKey); if (StringUtils.isBlank(token)) { WxMaService wxMaService = new WxMaServiceImpl(); WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl(); - config.setAppid(APPID); - config.setSecret(APP_SECRET); + config.setAppid(wxConfig.getAppId()); + config.setSecret(wxConfig.getAppSecret()); wxMaService.setWxMaConfig(config); token = wxMaService.getAccessToken(); - redisCache.setCacheObject(CacheConstants.WX_ACCESS_TOKEN, token, 5400, TimeUnit.SECONDS); + redisCache.setCacheObject(cacheKey, token, 5400, TimeUnit.SECONDS); } return token; } diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/auth/wx/WxAuthService.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/auth/wx/WxAuthService.java index a9189582..9e577d9a 100644 --- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/auth/wx/WxAuthService.java +++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/auth/wx/WxAuthService.java @@ -21,25 +21,27 @@ public class WxAuthService { @Autowired - private WxConfig wxConfig; + private WxConfig defaultWxConfig; /** * 使用登录码获取微信用户信息 + * * @param jsCode 登录码,通过wx.login获得 + * @param config */ - public WxMaJscode2SessionResult wxJsCode2Session(String jsCode) { + public WxMaJscode2SessionResult wxJsCode2Session(String jsCode, WxConfig config) { String grantType = "authorization_code"; - String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=%s", wxConfig.getAppId(), wxConfig.getAppSecret(), jsCode, grantType); + String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=%s", config.getAppId(), config.getAppSecret(), jsCode, grantType); String body = HttpUtils.sendGet(url); return JSON.parseObject(body, WxMaJscode2SessionResult.class); } - public String getOpenId(String loginCode) { + public String getOpenId(String loginCode, WxConfig config) { if (loginCode == null) { return null; } // 通过登录授权码获取到用户信息 - WxMaJscode2SessionResult wxMaJscode2SessionResult = this.wxJsCode2Session(loginCode); + WxMaJscode2SessionResult wxMaJscode2SessionResult = this.wxJsCode2Session(loginCode, config); if (wxMaJscode2SessionResult == null) { return null; } @@ -48,14 +50,16 @@ public class WxAuthService { /** * 通过微信手机号授权码获取微信手机号 + * * @param mobileCode 微信手机号授权码 + * @param config * @return */ - public String getWxPhoneNumber(String mobileCode) { + public String getWxPhoneNumber(String mobileCode, WxConfig config) { String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="; // 根据手机号获取到用户名 - String token = AccessTokenUtil.getToken(); + String token = AccessTokenUtil.getToken(config); url = url + token; JSONObject jsonObject = new JSONObject(); jsonObject.put("code", mobileCode); diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java index 96357610..056b9981 100644 --- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java +++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java @@ -64,7 +64,7 @@ public class CacheConstants /** * 微信access_token */ - public static final String WX_ACCESS_TOKEN = "wx_access_token"; + public static final String WX_ACCESS_TOKEN = "wx_access_token:"; /** * 设备在线状态 diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/core/domain/entity/SmUser.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/core/domain/entity/SmUser.java index a5175609..cce6d692 100644 --- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/core/domain/entity/SmUser.java +++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/core/domain/entity/SmUser.java @@ -20,6 +20,7 @@ import javax.validation.constraints.Size; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Date; +import java.util.List; /** * 普通用户信息对象 sm_user @@ -248,4 +249,12 @@ public class SmUser extends BaseEntity @ApiModelProperty("支付宝openId") private String aliOpenId; + + @Excel(name = "自定义渠道ID列表") + @ApiModelProperty("自定义渠道ID列表") + private List channelIds; + + @Excel(name = "所属应用ID") + @ApiModelProperty("所属应用ID") + private Long appId; } diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/core/domain/model/WxLoginBody.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/core/domain/model/WxLoginBody.java index 57f061c7..878b9c4c 100644 --- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/core/domain/model/WxLoginBody.java +++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/core/domain/model/WxLoginBody.java @@ -22,4 +22,7 @@ public class WxLoginBody { @NotBlank(message = "登录授权码不允许为空") @ApiModelProperty("wx.login获取的登录授权码,用于获取openId,必填") private String loginCode; + + @NotNull(message = "应用ID不允许为空") + private Long appId; } diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/xy/service/XyWxPayService.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/xy/service/XyWxPayService.java index a6952c70..b6746d96 100644 --- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/xy/service/XyWxPayService.java +++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/xy/service/XyWxPayService.java @@ -131,11 +131,7 @@ public class XyWxPayService implements PayApi { try { String response = HttpUtil.postData(url, params); ServiceUtil.assertion(response == null, "响应结果为空"); - JSONObject json = JSONObject.parseObject(response); - String code = json.getString("code"); - ServiceUtil.assertion(!Objects.equals("000000", code), json.getString("msg")); - - return json.getJSONObject("data"); + return JSONObject.parseObject(response); } catch (Exception e) { throw new ServiceException("查询支付单失败:" + e.getMessage()); } @@ -157,7 +153,6 @@ public class XyWxPayService implements PayApi { params.put("oldTOrderNo", refundAble.refundOutTradeNo()); params.put("refundAmount", refundAble.refundAmountFen()); params.put("tag", XyPayConstants.TAG_WX); - params.put("remark", refundAble.refundReason()); params.put("timeStamp", DateUtils.format(LocalDateTime.now(), "yyyyMMddHHmmss")); params.put("version", "1.0.0"); @@ -187,7 +182,11 @@ public class XyWxPayService implements PayApi { @Override public boolean isPaySuccess(Object result) { - return result != null; + if (result == null) { + return false; + } + JSONObject json = (JSONObject) result; + return Objects.equals("000000", json.getString("code")) ; } @Override @@ -196,7 +195,11 @@ public class XyWxPayService implements PayApi { return null; } JSONObject json = (JSONObject) result; - return DateUtils.toLocalDateTime(json.getDate("orderTime")); + JSONObject data = json.getJSONObject("data"); + if (data == null) { + return null; + } + return DateUtils.toLocalDateTime(data.getString("orderTime"), "yyyyMMddHHmmss"); } /** diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/DateUtils.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/DateUtils.java index 839cf452..fb24371d 100644 --- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/DateUtils.java +++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/DateUtils.java @@ -172,6 +172,9 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils */ public static Date toDate(LocalDateTime temporalAccessor) { + if (temporalAccessor == null) { + return null; + } ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); return Date.from(zdt.toInstant()); } diff --git a/smart-switch-ruoyi/smart-switch-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/smart-switch-ruoyi/smart-switch-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index 99630c3d..d1b246bf 100644 --- a/smart-switch-ruoyi/smart-switch-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/smart-switch-ruoyi/smart-switch-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -1,58 +1,47 @@ package com.ruoyi.framework.web.service; -import javax.annotation.Resource; - -import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; -import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; -import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.auth.ali.AliAuthService; -import com.ruoyi.common.core.domain.entity.SmUser; -import com.ruoyi.common.core.domain.model.AliLoginBody; -import com.ruoyi.common.core.domain.model.WxLoginBody; -import com.ruoyi.common.enums.UserStatus; -import com.ruoyi.common.enums.UserType; -import com.ruoyi.common.utils.ServiceUtil; -import com.ruoyi.common.utils.http.HttpUtils; -import com.ruoyi.common.auth.wx.AccessTokenUtil; import com.ruoyi.common.auth.wx.WxAuthService; -import com.ruoyi.ss.account.domain.Account; +import com.ruoyi.common.config.WxConfig; +import com.ruoyi.common.constant.CacheConstants; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.AliLoginBody; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.core.domain.model.WxLoginBody; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.exception.user.*; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.MessageUtils; +import com.ruoyi.common.utils.ServiceUtil; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.framework.manager.AsyncManager; +import com.ruoyi.framework.manager.factory.AsyncFactory; +import com.ruoyi.framework.security.context.AuthenticationContextHolder; +import com.ruoyi.ss.account.service.AccountService; +import com.ruoyi.ss.app.domain.AppVO; +import com.ruoyi.ss.app.domain.enums.AppType; +import com.ruoyi.ss.app.service.AppConverter; +import com.ruoyi.ss.app.service.AppService; import com.ruoyi.ss.store.service.StoreService; import com.ruoyi.ss.user.domain.SmUserVO; import com.ruoyi.ss.user.service.ISmUserService; -import com.ruoyi.ss.account.service.AccountService; -import com.ruoyi.ss.account.domain.enums.AccountType; -import com.ruoyi.system.domain.SysConfig; import com.ruoyi.system.domain.enums.config.ConfigKey; -import com.ruoyi.system.service.*; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysUserService; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.ObjectUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Component; -import com.ruoyi.common.constant.CacheConstants; -import com.ruoyi.common.constant.Constants; -import com.ruoyi.common.constant.UserConstants; -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.core.redis.RedisCache; -import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.exception.user.BlackListException; -import com.ruoyi.common.exception.user.CaptchaException; -import com.ruoyi.common.exception.user.CaptchaExpireException; -import com.ruoyi.common.exception.user.UserNotExistsException; -import com.ruoyi.common.exception.user.UserPasswordNotMatchException; -import com.ruoyi.common.utils.DateUtils; -import com.ruoyi.common.utils.MessageUtils; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.ip.IpUtils; -import com.ruoyi.framework.manager.AsyncManager; -import com.ruoyi.framework.manager.factory.AsyncFactory; -import com.ruoyi.framework.security.context.AuthenticationContextHolder; -import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; import java.util.Objects; /** @@ -97,6 +86,12 @@ public class SysLoginService @Autowired private AliAuthService aliAuthService; + @Autowired + private AppService appService; + + @Autowired + private AppConverter appConverter; + /** * 登录验证 * @@ -267,9 +262,17 @@ public class SysLoginService * 微信登录 */ public String wxLogin(WxLoginBody body) { + // 查询APP信息 + AppVO app = appService.selectAppById(body.getAppId()); + ServiceUtil.assertion(app == null, "ID为%s的APP信息不存在,请联系管理员", body.getAppId()); + ServiceUtil.assertion(!AppType.WX.getType().equals(app.getType()), "ID为%s的APP不是微信小程序", body.getAppId()); + + // 转换为微信配置信息 + WxConfig wxConfig = appConverter.toWxConfig(app); + ServiceUtil.assertion(wxConfig == null, "微信配置信息不存在,请联系管理员"); // 通过openId查询用户 - String openId = wxAuthService.getOpenId(body.getLoginCode()); + String openId = wxAuthService.getOpenId(body.getLoginCode(), wxConfig); ServiceUtil.assertion(openId == null, "获取微信openId失败"); SmUserVO user = smUserService.selectSmUserByWxOpenId(openId); @@ -279,10 +282,10 @@ public class SysLoginService boolean loginWithPhone = sysConfigService.getBoolean(ConfigKey.ARRIVAL_DELAY); String mobile = null; if (loginWithPhone && StringUtils.hasText(body.getMobileCode())) { - mobile = wxAuthService.getWxPhoneNumber(body.getMobileCode()); + mobile = wxAuthService.getWxPhoneNumber(body.getMobileCode(), wxConfig); } // 用户注册 - user = smUserService.registerWx(openId, mobile); + user = smUserService.registerWx(openId, mobile, app); } ServiceUtil.assertion(user == null, "用户不存在"); diff --git a/smart-switch-ruoyi/smart-switch-system/src/main/java/com/ruoyi/system/mapper/typehandler/LongSplitListTypeHandler.java b/smart-switch-ruoyi/smart-switch-system/src/main/java/com/ruoyi/system/mapper/typehandler/LongSplitListTypeHandler.java new file mode 100644 index 00000000..b527fb89 --- /dev/null +++ b/smart-switch-ruoyi/smart-switch-system/src/main/java/com/ruoyi/system/mapper/typehandler/LongSplitListTypeHandler.java @@ -0,0 +1,30 @@ +package com.ruoyi.system.mapper.typehandler; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author wjh + * 2025/1/9 + */ +public class LongSplitListTypeHandler extends AbstractSplitListTypeHandler{ + /** + * 转换为列表 + * + * @param data + * @param delimiter + */ + @Override + public List parseToList(String data, String delimiter) { + + if (StringUtils.isBlank(data)) { + return new ArrayList<>(); + } + String[] split = data.split(delimiter); + return Arrays.stream(split).map(Long::valueOf).collect(Collectors.toList()); + } +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/common/constants/DictTypeConstants.java b/smart-switch-service/src/main/java/com/ruoyi/common/constants/DictTypeConstants.java index 86384407..bc290be7 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/common/constants/DictTypeConstants.java +++ b/smart-switch-service/src/main/java/com/ruoyi/common/constants/DictTypeConstants.java @@ -21,5 +21,6 @@ public class DictTypeConstants { public static final String SUIT_FEE_TYPE = "suit_fee_type"; // 客服类型 public static final String CUSTOMER_SERVICE_TYPE = "customer_service_type"; - + // 充值渠道类型 + public static final String RECHARGE_CHANNEL_TYPE = "recharge_channel_type"; } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/app/domain/App.java b/smart-switch-service/src/main/java/com/ruoyi/ss/app/domain/App.java index 25ac8601..e8c918e7 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/app/domain/App.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/app/domain/App.java @@ -1,10 +1,15 @@ package com.ruoyi.ss.app.domain; import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Sensitive; import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.core.domain.ValidGroup; +import com.ruoyi.common.enums.DesensitizedType; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import javax.validation.constraints.NotBlank; + /** * APP信息对象 ss_app * @@ -20,18 +25,23 @@ public class App extends BaseEntity @Excel(name = "应用名称") @ApiModelProperty("应用名称") + @NotBlank(message = "应用名称不能为空", groups = {ValidGroup.Create.class}) private String name; @Excel(name = "应用类型", readConverterExp = "1=微信小程序,2=支付宝小程序") @ApiModelProperty("应用类型") + @NotBlank(message = "应用类型不能为空", groups = {ValidGroup.Create.class}) private String type; @Excel(name = "应用ID") @ApiModelProperty("应用ID") + @NotBlank(message = "应用ID不能为空", groups = {ValidGroup.Create.class}) private String appId; @Excel(name = "应用秘钥") @ApiModelProperty("应用秘钥") + @Sensitive(desensitizedType = DesensitizedType.PASSWORD) + @NotBlank(message = "应用秘钥不能为空", groups = {ValidGroup.Create.class}) private String appSecret; } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/app/domain/enums/AppType.java b/smart-switch-service/src/main/java/com/ruoyi/ss/app/domain/enums/AppType.java new file mode 100644 index 00000000..22751033 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/app/domain/enums/AppType.java @@ -0,0 +1,20 @@ +package com.ruoyi.ss.app.domain.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author wjh + * 2025/1/9 + */ +@Getter +@AllArgsConstructor +public enum AppType { + + WX("1", "微信小程序"), + ALI("2", "支付宝小程序"); + + private final String type; + private final String msg; + +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/app/service/AppConverter.java b/smart-switch-service/src/main/java/com/ruoyi/ss/app/service/AppConverter.java new file mode 100644 index 00000000..90b28911 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/app/service/AppConverter.java @@ -0,0 +1,14 @@ +package com.ruoyi.ss.app.service; + +import com.ruoyi.common.config.WxConfig; +import com.ruoyi.ss.app.domain.AppVO; + +/** + * @author wjh + * 2025/1/9 + */ +public interface AppConverter { + + WxConfig toWxConfig(AppVO app); + +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/app/service/impl/AppConverterImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/app/service/impl/AppConverterImpl.java new file mode 100644 index 00000000..eacdd01c --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/app/service/impl/AppConverterImpl.java @@ -0,0 +1,26 @@ +package com.ruoyi.ss.app.service.impl; + +import com.ruoyi.common.config.WxConfig; +import com.ruoyi.ss.app.domain.AppVO; +import com.ruoyi.ss.app.domain.enums.AppType; +import com.ruoyi.ss.app.service.AppConverter; +import org.springframework.stereotype.Service; + +/** + * @author wjh + * 2025/1/9 + */ +@Service +public class AppConverterImpl implements AppConverter { + @Override + public WxConfig toWxConfig(AppVO app) { + if (app == null || !AppType.WX.getType().equals(app.getType())) { + return null; + } + + WxConfig config = new WxConfig(); + config.setAppId(app.getAppId()); + config.setAppSecret(app.getAppSecret()); + return config; + } +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/domain/Bonus.java b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/domain/Bonus.java index 8600f62b..1816a42b 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/domain/Bonus.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/domain/Bonus.java @@ -97,4 +97,8 @@ public class Bonus extends BaseEntity @ApiModelProperty("待分成金额") private BigDecimal waitAmount; + @Excel(name = "是否需要加入到余额中") + @ApiModelProperty("是否需要加入到余额中") + private Boolean toBalance; + } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.java b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.java index 0c38bf41..cd5df50b 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.java @@ -81,7 +81,7 @@ public interface BonusMapper /** * 批量更新分成金额 */ - int batchUpdateAmount(@Param("list") List list); + int batchUpdateAmount(@Param("list") List list); /** * 根据到账方统计 diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.xml b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.xml index f27821bc..0b51e458 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.xml +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/mapper/BonusMapper.xml @@ -24,7 +24,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" sb.dept_id, sb.pre_pay_time, sb.payed_amount, - sb.wait_amount + sb.wait_amount, + sb.to_balance @@ -49,6 +50,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and sb.pay_time <= #{query.payTimeEnd} and sb.pre_pay_time >= #{query.prePayTimeStart} and sb.pre_pay_time <= #{query.prePayTimeEnd} + and sb.to_balance = #{query.toBalance} and sb.bill_id in @@ -235,6 +237,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" pre_pay_time, payed_amount, wait_amount, + to_balance, #{billId}, @@ -253,6 +256,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{prePayTime}, #{payedAmount}, #{waitAmount}, + #{toBalance}, @@ -421,6 +425,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" pre_pay_time = #{data.prePayTime}, payed_amount = #{data.payedAmount}, wait_amount = #{data.waitAmount}, + to_balance = #{data.toBalance}, diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/BonusService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/BonusService.java index 3a26ea4a..e2ccb094 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/BonusService.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/BonusService.java @@ -11,6 +11,7 @@ import com.ruoyi.ss.bonus.domain.BonusVO; import com.ruoyi.ss.bonus.domain.vo.BonusDailyAmountVO; import com.ruoyi.ss.bonus.domain.vo.BonusMonthAmountVO; import com.ruoyi.ss.bonus.domain.vo.ProvideBonusVO; +import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -77,14 +78,6 @@ public interface BonusService */ int batchInsert(List bonusList); - /** - * 处理分成支付 - * - * @param bonusList 分成列表 - * @return 处理数量 - */ - int payBonus(List bonusList); - /** * 支付分成 * @param bonus @@ -93,10 +86,11 @@ public interface BonusService /** * 处理分成,按照比例分出金额 + * * @param bonusList 分成列表 - * @param money 总金额 + * @param money 总金额 */ - int partBonus(List bonusList, BigDecimal money); + void partBonus(List bonusList, BigDecimal money); /** * 根据到账方统计 @@ -169,4 +163,11 @@ public interface BonusService * 查询已分成金额总和 */ BigDecimal selectSumOfPayedAmount(BonusQuery query); + + /** + * 根据平台收款构建分成列表 + */ + List buildBonusListByPlatform(List bonusList, TransactionBillVO bill); + + List buildBonusListByCustom(TransactionBillVO bill); } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/impl/BonusServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/impl/BonusServiceImpl.java index 6b55e3cb..4a6ed74c 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/impl/BonusServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/bonus/service/impl/BonusServiceImpl.java @@ -23,6 +23,7 @@ import com.ruoyi.ss.bonus.mapper.BonusMapper; import com.ruoyi.ss.bonus.service.BonusService; import com.ruoyi.ss.recordBalance.domain.enums.RecordBalanceBstType; import com.ruoyi.ss.store.service.StoreService; +import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO; import com.ruoyi.ss.user.domain.SmUserVO; import com.ruoyi.ss.user.service.ISmUserService; import com.ruoyi.ss.user.service.UserAssembler; @@ -37,10 +38,10 @@ import org.springframework.transaction.support.TransactionTemplate; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** @@ -166,21 +167,6 @@ public class BonusServiceImpl implements BonusService return bonusMapper.batchInsert(bonusList); } - - - @Override - public int payBonus(List bonusList) { - int total = 0; - - // 循环遍历,添加金额到账户上 - for (BonusVO bonus : bonusList) { - int pay = this.payBonus(bonus); - total += pay; - } - - return total; - } - @Override public int payBonus(BonusVO bonus) { if (bonus == null) { @@ -191,12 +177,14 @@ public class BonusServiceImpl implements BonusService int pay = bonusMapper.pay(bonus.getId(), bonus.getWaitAmount(), LocalDateTime.now()); ServiceUtil.assertion(pay != 1, "分成打款失败,待分金额不足或状态已改变"); - // 根据类型,添加金额 - if (BonusArrivalType.userList().contains(bonus.getArrivalType())) { - int add = userService.addBalance(bonus.getArrivalId(), bonus.getWaitAmount(), String.format("订单分成:%s", bonus.getBillNo()), RecordBalanceBstType.RECHARGE, bonus.getBillId()); - ServiceUtil.assertion(add != 1, "增加账户金额失败"); - } else if (BonusArrivalType.deptList().contains(bonus.getArrivalType())) { + // 若需要打款到余额,根据类型,添加金额 + if (bonus.getToBalance() != null && bonus.getToBalance()) { + if (BonusArrivalType.userList().contains(bonus.getArrivalType())) { + int add = userService.addBalance(bonus.getArrivalId(), bonus.getWaitAmount(), String.format("订单分成:%s", bonus.getBillNo()), RecordBalanceBstType.RECHARGE, bonus.getBillId()); + ServiceUtil.assertion(add != 1, "增加账户金额失败"); + } else if (BonusArrivalType.deptList().contains(bonus.getArrivalType())) { // add = deptService.addBalance(bonus.getArrivalId(), bonus.getAmount(), String.format("订单分成:%s", bonus.getBillNo()), RecordBalanceBstType.RECHARGE, bonus.getBillId()); + } } return pay; @@ -206,9 +194,9 @@ public class BonusServiceImpl implements BonusService } @Override - public int partBonus(List bonusList, BigDecimal money) { + public void partBonus(List bonusList, BigDecimal money) { if (CollectionUtils.isEmptyElement(bonusList) || money == null) { - return 0; + return; } BigDecimal decimal100 = new BigDecimal(100); @@ -217,7 +205,7 @@ public class BonusServiceImpl implements BonusService // 获取用户列表 List userList = userService.selectByUserIds(bonusList.stream() .filter(item -> BonusArrivalType.userList().contains(item.getArrivalType())) - .map(BonusVO::getArrivalId) + .map(Bonus::getArrivalId) .collect(Collectors.toList()) ); // 拼接用户实际到账延迟 @@ -226,7 +214,7 @@ public class BonusServiceImpl implements BonusService LocalDateTime now = LocalDateTime.now(); // 获取平台的分成 - BonusVO platform = bonusList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())).findFirst().orElse(null); + Bonus platform = bonusList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())).findFirst().orElse(null); ServiceUtil.assertion(platform == null, "平台不存在"); BigDecimal platformAmount = money.multiply(platform.getPoint()).divide(decimal100, 2, RoundingMode.HALF_UP); // 平台预计分成金额 @@ -246,7 +234,7 @@ public class BonusServiceImpl implements BonusService // 计算其他分成方分成金额 BigDecimal remain = money.subtract(platform.getAmount()); // 剩余可分成金额 BigDecimal remainPoint = decimal100.subtract(platform.getPoint()); // 剩余总百分比 - for (BonusVO bonus : bonusList) { + for (Bonus bonus : bonusList) { if (bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())) { continue; } @@ -261,7 +249,7 @@ public class BonusServiceImpl implements BonusService // 其余情况,正常收取费用 else { // 循环遍历,构造分成金额 - for (BonusVO bonus : bonusList) { + for (Bonus bonus : bonusList) { BigDecimal amount = money.multiply(bonus.getPoint()).divide(decimal100, 2, RoundingMode.HALF_UP); this.setAmount(bonus, amount); // 增加已分成金额 @@ -276,7 +264,7 @@ public class BonusServiceImpl implements BonusService } // 设置预计分成时间等数据 - for (BonusVO bonus : bonusList) { + for (Bonus bonus : bonusList) { bonus.setStatus(BonusStatus.WAIT_DIVIDE.getStatus()); bonus.setWaitAmount(bonus.getAmount()); // 设置预计分成时间 @@ -291,23 +279,18 @@ public class BonusServiceImpl implements BonusService } } - Integer result = transactionTemplate.execute(status -> { - // 批量更新分成金额 - int updateAmount = this.batchUpdateAmount(bonusList); - ServiceUtil.assertion(updateAmount != bonusList.size(), "更新分成金额失败"); - - return updateAmount; - }); - - // 立即执行一次分成 - scheduledExecutorService.schedule(() -> { - this.payBonusBeforeTime(LocalDateTime.now()); - }, 3, TimeUnit.SECONDS); - - return result == null ? 0 : result; + // 操作数据库:批量更新分成金额 +// Integer result = transactionTemplate.execute(status -> { +// int updateAmount = this.batchUpdateAmount(bonusList); +// ServiceUtil.assertion(updateAmount != bonusList.size(), "更新分成金额失败"); +// +// return updateAmount; +// }); +// +// return result == null ? 0 : result; } - private void setAmount(BonusVO bonus, BigDecimal amount) { + private void setAmount(Bonus bonus, BigDecimal amount) { ServiceUtil.assertion(amount.compareTo(BigDecimal.ZERO) < 0, "分成金额不允许小于0"); bonus.setAmount(amount); } @@ -433,7 +416,46 @@ public class BonusServiceImpl implements BonusService return bonusMapper.selectSumOfPayedAmount(query); } - private int batchUpdateAmount(List list) { + @Override + public List buildBonusListByPlatform(List bonusList, TransactionBillVO bill) { + // 设置分成基础数据 + for (Bonus bonus : bonusList) { + bonus.setBillId(bill.getBillId()); + bonus.setBillNo(bill.getBillNo()); + bonus.setToBalance(true); + } + // 计算分成金额 + this.partBonus(bonusList, bill.getMoney()); + + return bonusList; + } + + @Override + public List buildBonusListByCustom(TransactionBillVO bill) { + List bonusList = new ArrayList<>(); + Bonus bonus = new BonusVO(); + bonus.setBillId(bill.getBillId()); + bonus.setBillNo(bill.getBillNo()); + bonus.setStatus(BonusStatus.DIVIDEND.getStatus()); + bonus.setArrivalId(bill.getMchId()); + bonus.setArrivalName(bill.getMchName()); + bonus.setArrivalType(BonusArrivalType.MCH.getType()); + bonus.setPoint(BigDecimal.valueOf(100)); + bonus.setAmount(bill.getMoney()); + bonus.setRefundAmount(BigDecimal.ZERO); + bonus.setAncestors(String.valueOf(bill.getMchId())); + bonus.setDeptId(null); + bonus.setPayTime(LocalDateTime.now()); + bonus.setPrePayTime(LocalDateTime.now()); + bonus.setPayedAmount(bill.getMoney()); + bonus.setWaitAmount(BigDecimal.ZERO); + bonus.setToBalance(false); + bonusList.add(bonus); + + return bonusList; + } + + private int batchUpdateAmount(List list) { if (CollectionUtils.isEmptyElement(list)) { return 0; } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/channel/domain/Channel.java b/smart-switch-service/src/main/java/com/ruoyi/ss/channel/domain/Channel.java index 4bf2427e..f229ec71 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/channel/domain/Channel.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/channel/domain/Channel.java @@ -2,13 +2,16 @@ package com.ruoyi.ss.channel.domain; import com.fasterxml.jackson.annotation.JsonView; import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.constants.DictTypeConstants; import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.JsonViewProfile; import com.ruoyi.common.core.domain.ValidGroup; +import com.ruoyi.system.valid.DictValid; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; import java.math.BigDecimal; /** @@ -55,14 +58,18 @@ public class Channel extends BaseEntity @Excel(name = "适用平台(1微信 2支付宝)") @ApiModelProperty("适用平台(1微信 2支付宝)") + @NotBlank(message = "适用平台不能为空", groups = {ValidGroup.Create.class}) private String platform; @Excel(name = "渠道API类型", readConverterExp = "1=微信支付,2=支付宝,3=银行卡,4=通联微信,5=太米微信") @ApiModelProperty("渠道API类型") + @NotBlank(message = "渠道API类型不能为空", groups = {ValidGroup.Create.class}) private String apiType; - @Excel(name = "渠道类型", readConverterExp = "1=官方渠道,2=自定义渠道") + @Excel(name = "渠道类型", dictType = DictTypeConstants.RECHARGE_CHANNEL_TYPE) @ApiModelProperty("渠道类型") + @NotBlank(message = "渠道类型不能为空", groups = {ValidGroup.Create.class}) + @DictValid(type = DictTypeConstants.RECHARGE_CHANNEL_TYPE, message = "非法的渠道类型") private String type; @Excel(name = "渠道配置") diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/channel/domain/enums/ChannelType.java b/smart-switch-service/src/main/java/com/ruoyi/ss/channel/domain/enums/ChannelType.java index d68faee6..501f5b17 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/channel/domain/enums/ChannelType.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/channel/domain/enums/ChannelType.java @@ -11,8 +11,8 @@ import lombok.Getter; @AllArgsConstructor public enum ChannelType { - SYSTEM("1", "系统预设"), - CUSTOM("2", "自定义"); + PLATFORM("1", "平台收款"), + CUSTOM("2", "用户收款"); private final String type; private final String msg; diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/channel/service/impl/ChannelServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/channel/service/impl/ChannelServiceImpl.java index ad7c32f5..fe84fe4f 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/channel/service/impl/ChannelServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/channel/service/impl/ChannelServiceImpl.java @@ -9,7 +9,6 @@ import com.ruoyi.ss.channel.domain.Channel; import com.ruoyi.ss.channel.domain.ChannelQuery; import com.ruoyi.ss.channel.domain.ChannelVO; import com.ruoyi.ss.channel.domain.enums.ChannelApiType; -import com.ruoyi.ss.channel.domain.enums.ChannelType; import com.ruoyi.ss.channel.mapper.ChannelMapper; import com.ruoyi.ss.channel.service.ChannelConverter; import com.ruoyi.ss.channel.service.ChannelService; @@ -183,9 +182,9 @@ public class ChannelServiceImpl implements ChannelService } // 校验 - for (ChannelVO channel : channelList) { - ServiceUtil.assertion(ChannelType.SYSTEM.getType().equals(channel.getType()), "不允许删除系统预设渠道 \"%s\"}", channel.getName()); - } +// for (ChannelVO channel : channelList) { +// ServiceUtil.assertion(ChannelType.SYSTEM.getType().equals(channel.getType()), "不允许删除系统预设渠道 \"%s\"}", channel.getName()); +// } return channelMapper.logicDel(ids); } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/payBill/service/impl/PayBillServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/payBill/service/impl/PayBillServiceImpl.java index 5298eb1e..fef56074 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/payBill/service/impl/PayBillServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/payBill/service/impl/PayBillServiceImpl.java @@ -365,11 +365,9 @@ public class PayBillServiceImpl implements PayBillService return 0; } for (PayBillVO bill : payList) { - if (PayBillStatus.PAYING.getStatus().equals(bill.getStatus()) || PayBillStatus.WAIT_PAY.getStatus().equals(bill.getStatus()) ) { - PayResultVO payResult = getPayResult(bill); - if (payResult.getSuccess()) { - this.handleSuccess(bill, payResult.getPayTime()); - } + PayResultVO payResult = getPayResult(bill); + if (payResult.getSuccess()) { + this.handleSuccess(bill, payResult.getPayTime()); } } return payList.size(); diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBill.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBill.java index 7225f93e..dcf96727 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBill.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBill.java @@ -329,4 +329,7 @@ public class TransactionBill extends BaseEntity @ApiModelProperty("商户展示手机号缴费状态") private String mchShowMobileStatus; + @Excel(name = "渠道类型", dictType = DictTypeConstants.RECHARGE_CHANNEL_TYPE) + @ApiModelProperty("渠道类型") + private String channelType; } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/bo/PaySuccessBO.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/bo/PaySuccessBO.java index 25ddd281..227ed49e 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/bo/PaySuccessBO.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/bo/PaySuccessBO.java @@ -1,8 +1,8 @@ package com.ruoyi.ss.transactionBill.domain.bo; +import com.ruoyi.ss.channel.domain.ChannelVO; import com.ruoyi.ss.device.domain.vo.DeviceVO; import com.ruoyi.ss.payBill.domain.PayBillVO; -import com.ruoyi.ss.transactionBill.domain.TransactionBill; import com.ruoyi.ss.transactionBill.domain.vo.TransactionBillVO; import lombok.Data; @@ -23,4 +23,7 @@ public class PaySuccessBO { // 充值订单 private TransactionBillVO order; + // 充值渠道 + private ChannelVO channel; + } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.xml b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.xml index d8d6e14f..acc1f07e 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.xml +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.xml @@ -82,6 +82,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" stb.mch_show_mobile, stb.mch_show_mobile_price, stb.mch_show_mobile_status, + stb.channel_type, @@ -96,7 +97,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" sd.total_electri_quantity as device_total_ele, sd.expire_time as device_expire_time, sd.expire_ele as decvice_expire_ele, - su.phonenumber as user_mobile + su.phonenumber as user_mobile, + sc.name as channel_name from @@ -106,6 +108,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" left join sm_user su1 on su1.user_id = stb.mch_id left join sm_device sd on sd.device_id = stb.device_id left join sm_suit ss on ss.suit_id = stb.suit_id + left join sm_channel sc on sc.channel_id = stb.channel_id @@ -210,6 +213,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and stb.suit_void_result = #{query.suitVoidResult} and stb.open_msg like concat('%', #{query.openMsg}, '%') and stb.mch_show_mobile_status = #{query.mchShowMobileStatus} + and channel_type = #{query.channelType} and stb.suit_end_time is @@ -564,6 +568,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" mch_show_mobile, mch_show_mobile_price, mch_show_mobile_status, + channel_type, #{billNo}, @@ -634,6 +639,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{mchShowMobile}, #{mchShowMobilePrice}, #{mchShowMobileStatus}, + #{channelType}, @@ -720,6 +726,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" stb.mch_show_mobile = #{data.mchShowMobile}, stb.mch_show_mobile_price = #{data.mchShowMobilePrice}, stb.mch_show_mobile_status = #{data.mchShowMobileStatus}, + stb.channel_type = #{data.channelType}, diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/RechargePayHandler.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/RechargePayHandler.java index 0ff7dfd0..b5825ffd 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/RechargePayHandler.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/RechargePayHandler.java @@ -2,14 +2,17 @@ package com.ruoyi.ss.transactionBill.service.impl; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.ServiceUtil; -import com.ruoyi.ss.bonus.domain.BonusVO; +import com.ruoyi.ss.bonus.domain.Bonus; import com.ruoyi.ss.bonus.domain.enums.BonusArrivalType; import com.ruoyi.ss.bonus.service.BonusService; +import com.ruoyi.ss.channel.domain.ChannelVO; +import com.ruoyi.ss.channel.domain.enums.ChannelType; +import com.ruoyi.ss.channel.service.ChannelService; import com.ruoyi.ss.device.domain.vo.DeviceVO; +import com.ruoyi.ss.device.service.DeviceAssembler; import com.ruoyi.ss.device.service.DeviceService; import com.ruoyi.ss.payBill.domain.PayBillVO; import com.ruoyi.ss.payBill.domain.bo.RefundSuccessBO; -import com.ruoyi.ss.payBill.domain.dto.PayBillRefundDTO; import com.ruoyi.ss.payBill.interfaces.AfterPay; import com.ruoyi.ss.payBill.interfaces.AfterRefund; import com.ruoyi.ss.payBill.service.PayBillService; @@ -67,6 +70,12 @@ public class RechargePayHandler implements AfterPay, AfterRefund { @Autowired private DeviceService deviceService; + @Autowired + private ChannelService channelService; + + @Autowired + private DeviceAssembler deviceAssembler; + @Override public int onPaySuccess(PayBillVO payBill) { TransactionBillVO bill = transactionBillService.selectSmTransactionBillByBillId(payBill.getBstId()); @@ -77,9 +86,8 @@ public class RechargePayHandler implements AfterPay, AfterRefund { PaySuccessBO bo = new PaySuccessBO(); bo.setOrder(bill); bo.setPayBill(payBill); - bo.setDevice(deviceService.selectById(bill.getDeviceId())); - // 拼接分成列表 - transactionAssembler.assembleBonusList(bill); + bo.setDevice( deviceService.selectById(bill.getDeviceId())); + bo.setChannel(channelService.selectSmChannelByChannelId(payBill.getChannelId())); return this.handleSinglePaySuccess(bo); } @@ -97,20 +105,40 @@ public class RechargePayHandler implements AfterPay, AfterRefund { DeviceVO device = bo.getDevice(); deviceService.pullDeviceInfo(device, null); - List bonusList = bill.getBonusList(); + // 渠道信息 + ChannelVO channel = bo.getChannel(); + ServiceUtil.assertion(channel == null, "支付渠道不存在"); + // 构造分成数据 + List bonusList; + // 只有通过平台渠道支付的才需要分成给余额 + if (ChannelType.PLATFORM.getType().equals(channel.getType())) { + // 获取设备分成数据 + deviceAssembler.assembleBonusList(device); + // 构造分成列表 + bonusList = bonusService.buildBonusListByPlatform(device.getBonusList(), bill); + } + // 其他只需要记录分成数据即可 + else { + bonusList = bonusService.buildBonusListByCustom(bill); + } + + // 操作数据库 Integer result = transactionTemplate.execute(status -> { + // 创建分成 + int bonusInsert = bonusService.batchInsert(bonusList); + ServiceUtil.assertion(bonusInsert != bonusList.size(), "创建分成失败"); // 处理分成,将金额分好 - bonusService.partBonus(bonusList, bill.getMoney()); - BonusVO platform = bonusList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())).findFirst().orElse(null); - BonusVO mch = bonusList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.MCH.getType())).findFirst().orElse(null); + Bonus platform = bonusList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())).findFirst().orElse(null); + Bonus mch = bonusList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.MCH.getType())).findFirst().orElse(null); // 修改订单的数据 TransactionBill data = new TransactionBill(); data.setStatus(TransactionBillStatus.SUCCESS.getStatus()); data.setPayTime(DateUtils.toDate(pay.getPayTime())); - data.setChannelId(pay.getChannelId()); + data.setChannelId(channel.getChannelId()); data.setChannelCost(pay.getChannelCost()); + data.setChannelType(channel.getType()); data.setPayId(pay.getPayId()); // 平台信息 if (platform != null) { @@ -137,7 +165,6 @@ public class RechargePayHandler implements AfterPay, AfterRefund { BigDecimal endEle = startEle.add(bill.getRechargeEle()); data.setSuitEndEle(endEle); } - // 修改的条件 TransactionBillQuery query = new TransactionBillQuery(); query.setBillId(bill.getBillId()); @@ -164,6 +191,11 @@ public class RechargePayHandler implements AfterPay, AfterRefund { // 操作成功 if (result != null && result == 1) { + // 立即执行一次分成 + scheduledExecutorService.schedule(() -> { + bonusService.payBonusBeforeTime(LocalDateTime.now()); + }, 3, TimeUnit.SECONDS); + // 充值设备 transactionBillService.rechargeDevice(bill.getBillId()); @@ -179,51 +211,51 @@ public class RechargePayHandler implements AfterPay, AfterRefund { /** * 处理分时段订单支付成功 */ - private int handleTimingPaySuccess(PaySuccessBO bo) { - if (bo == null) { - return 0; - } - - TransactionBillVO order = bo.getOrder(); - PayBillVO pay = bo.getPayBill(); - - ServiceUtil.assertion(order == null, "充值订单不存在"); - ServiceUtil.assertion(!TransactionBillStatus.UNPAID.getStatus().equals(order.getStatus()), "当前订单状态非待支付状态"); - - Integer result = transactionTemplate.execute(status -> { - // 修改订单状态 - TransactionBill data = new TransactionBill(); - data.setPayTime(DateUtils.toDate(pay.getPayTime())); - data.setPayId(pay.getPayId()); - data.setChannelCost(pay.getChannelCost()); - data.setChannelId(pay.getChannelId()); - data.setStatus(TransactionBillStatus.SUCCESS.getStatus()); - TransactionBillQuery query = new TransactionBillQuery(); - query.setBillId(order.getBillId()); - query.setStatus(TransactionBillStatus.UNPAID.getStatus()); - int update = transactionBillService.updateByQuery(data, query); - ServiceUtil.assertion(update != 1, "修改订单状态失败"); - - // 处理分成 - bonusService.partBonus(order.getBonusList(), order.getMoney()); - - // 如果有押金,则申请押金退款 - if (order.getSuitDeposit() != null && order.getSuitDeposit().compareTo(BigDecimal.ZERO) > 0 && order.getDepositPayId() != null) { - // 押金退款 - PayBillRefundDTO refundDto = new PayBillRefundDTO(); - refundDto.setPayId(order.getDepositPayId()); - refundDto.setRefundAmount(order.getSuitDeposit()); - refundDto.setRefundReason(String.format("充值订单%s押金退款", order.getBillNo())); - int refund = payBillService.refund(refundDto); - ServiceUtil.assertion(refund != 1, "申请退款失败"); - } - - return update; - }); - - return result == null ? 0 : result; - - } +// private int handleTimingPaySuccess(PaySuccessBO bo) { +// if (bo == null) { +// return 0; +// } +// +// TransactionBillVO order = bo.getOrder(); +// PayBillVO pay = bo.getPayBill(); +// +// ServiceUtil.assertion(order == null, "充值订单不存在"); +// ServiceUtil.assertion(!TransactionBillStatus.UNPAID.getStatus().equals(order.getStatus()), "当前订单状态非待支付状态"); +// +// Integer result = transactionTemplate.execute(status -> { +// // 修改订单状态 +// TransactionBill data = new TransactionBill(); +// data.setPayTime(DateUtils.toDate(pay.getPayTime())); +// data.setPayId(pay.getPayId()); +// data.setChannelCost(pay.getChannelCost()); +// data.setChannelId(pay.getChannelId()); +// data.setStatus(TransactionBillStatus.SUCCESS.getStatus()); +// TransactionBillQuery query = new TransactionBillQuery(); +// query.setBillId(order.getBillId()); +// query.setStatus(TransactionBillStatus.UNPAID.getStatus()); +// int update = transactionBillService.updateByQuery(data, query); +// ServiceUtil.assertion(update != 1, "修改订单状态失败"); +// +// // 处理分成 +// bonusService.partBonus(order.getBonusList(), order.getMoney()); +// +// // 如果有押金,则申请押金退款 +// if (order.getSuitDeposit() != null && order.getSuitDeposit().compareTo(BigDecimal.ZERO) > 0 && order.getDepositPayId() != null) { +// // 押金退款 +// PayBillRefundDTO refundDto = new PayBillRefundDTO(); +// refundDto.setPayId(order.getDepositPayId()); +// refundDto.setRefundAmount(order.getSuitDeposit()); +// refundDto.setRefundReason(String.format("充值订单%s押金退款", order.getBillNo())); +// int refund = payBillService.refund(refundDto); +// ServiceUtil.assertion(refund != 1, "申请退款失败"); +// } +// +// return update; +// }); +// +// return result == null ? 0 : result; +// +// } @Override public int onRefundSuccess(RefundSuccessBO bo) { diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java index 04304e62..0798fab1 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java @@ -29,6 +29,7 @@ import com.ruoyi.ss.bonus.domain.enums.BonusArrivalType; import com.ruoyi.ss.bonus.domain.enums.BonusStatus; import com.ruoyi.ss.bonus.service.BonusConverter; import com.ruoyi.ss.bonus.service.BonusService; +import com.ruoyi.ss.channel.domain.ChannelVO; import com.ruoyi.ss.channelWithdraw.domain.ChannelWithdrawVO; import com.ruoyi.ss.channelWithdraw.service.ChannelWithdrawService; import com.ruoyi.ss.device.domain.enums.DevicePowerStatus; @@ -279,11 +280,10 @@ public class TransactionBillServiceImpl implements TransactionBillService, After ServiceUtil.assertion(!redisLock.lock(RedisLockKey.ADD_RECHARGE_ORDER, deviceId), "当前使用该设备人数较多,请稍后再试"); try { // 拉取设备信息 - deviceService.pullDeviceInfo(bo.getDevice().getDeviceId(), null); + deviceService.pullDeviceInfo(bo.getDevice(), null); // 生成订单 TransactionBill order = parseToOrder(bo); - List bonusList = bo.getDevice().getBonusList(); transactionTemplate.execute(status -> { // 收取月费 @@ -294,14 +294,6 @@ public class TransactionBillServiceImpl implements TransactionBillService, After int insert = this.insertSmTransactionBill(order); ServiceUtil.assertion(insert != 1, "下单失败"); - // 插入分成列表 - for (Bonus bonus : bonusList) { - bonus.setBillId(order.getBillId()); - bonus.setBillNo(order.getBillNo()); - } - int bonusInsert = bonusService.batchInsert(bonusList); - ServiceUtil.assertion(bonusInsert != bonusList.size(), "创建分成失败"); - return insert; }); @@ -1463,8 +1455,8 @@ public class TransactionBillServiceImpl implements TransactionBillService, After ServiceUtil.assertion(!allowCancel.contains(bill.getStatus()), "当前订单状态不允许取消"); // 若是未支付的分时订单,则不允许取消 - ServiceUtil.assertion(TransactionBillStatus.UNPAID.getStatus().equals(bill.getStatus()) - && SuitFeeType.timingList().contains(bill.getSuitFeeType()), "未支付的分时段订单不允许取消"); +// ServiceUtil.assertion(TransactionBillStatus.UNPAID.getStatus().equals(bill.getStatus()) +// && SuitFeeType.timingList().contains(bill.getSuitFeeType()), "未支付的分时段订单不允许取消"); Integer result = transactionTemplate.execute(s -> { // 执行取消订单 @@ -1622,18 +1614,6 @@ public class TransactionBillServiceImpl implements TransactionBillService, After ServiceUtil.assertion(CollectionUtils.isEmptyElement(bonusList), "订单编号为%s的订单没有收益信息,无法退款", bill.getBillNo()); Integer result = transactionTemplate.execute(status -> { - // 修改订单状态 -// TransactionBill data = new TransactionBill(); -// data.setStatus(TransactionBillStatus.REFUNDING.getStatus()); -// TransactionBillQuery billQuery = new TransactionBillQuery(); -// billQuery.setBillId(dto.getBillId()); -// billQuery.setStatusList(TransactionBillStatus.canRefund()); -// if (dto.getCheckFinish() != null && dto.getCheckFinish()) { -// billQuery.setIsFinished(true); -// } -// int updateBill = this.updateByQuery(data, billQuery); -// ServiceUtil.assertion(updateBill != 1, "退款时修改订单状态失败,订单状态已发生改变,请刷新后重试"); - // 分成方余额按照比例扣减 // 按比例计算退款金额 BigDecimal refundAmount = dto.getRefundAmount(); // 总退款金额 @@ -1687,10 +1667,11 @@ public class TransactionBillServiceImpl implements TransactionBillService, After dividedAmount = dividedAmount.add(bonusRefundAmount); } - // 平台吃掉误差 - Bonus platform = refundList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())).findFirst().orElse(null); - ServiceUtil.assertion(platform == null, "平台不存在"); + // 若存在误差,则平台吃掉误差 if (dividedAmount.compareTo(refundAmount) != 0) { + Bonus platform = refundList.stream().filter(bonus -> bonus.getArrivalType().equals(BonusArrivalType.PLATFORM.getType())).findFirst().orElse(null); + ServiceUtil.assertion(platform == null, "平台不存在"); + BigDecimal subtract = refundAmount.subtract(dividedAmount); // 误差值 platform.setRefundAmount(platform.getRefundAmount().add(subtract)); } @@ -1717,10 +1698,12 @@ public class TransactionBillServiceImpl implements TransactionBillService, After ServiceUtil.assertion(refund != 1, "可退款金额不足"); // 扣减分成方余额 - if (BonusArrivalType.userList().contains(bonus.getArrivalType())) { - userService.subtractBalance(bonus.getArrivalId(), bonus.getRefundAmount(), String.format("订单退款:%s", bonus.getBillNo()), RecordBalanceBstType.RECHARGE, bonus.getBillId()); - } else if (BonusArrivalType.deptList().contains(bonus.getArrivalType())) { + if (bonus.getToBalance() != null && bonus.getToBalance()) { + if (BonusArrivalType.userList().contains(bonus.getArrivalType())) { + userService.subtractBalance(bonus.getArrivalId(), bonus.getRefundAmount(), String.format("订单退款:%s", bonus.getBillNo()), RecordBalanceBstType.RECHARGE, bonus.getBillId()); + } else if (BonusArrivalType.deptList().contains(bonus.getArrivalType())) { // deptService.subtractBalance(bonus.getArrivalId(), bonus.getRefundAmount(), String.format("订单退款:%s", bonus.getBillNo()), RecordBalanceBstType.RECHARGE, bonus.getBillId()); + } } } @@ -1904,6 +1887,9 @@ public class TransactionBillServiceImpl implements TransactionBillService, After Long lockKey = order.getBillId(); ServiceUtil.assertion(!redisLock.lock(RedisLockKey.PREPAY, lockKey), "当前订单正在支付,请稍后重试"); try { + // 分成明细 + List bonusList = bo.getDevice().getBonusList(); + ChannelVO channel = bo.getChannel(); return transactionTemplate.execute(status -> { // 修改订单信息 diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/user/domain/SmUserVO.java b/smart-switch-service/src/main/java/com/ruoyi/ss/user/domain/SmUserVO.java index d61c46fb..78451db0 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/user/domain/SmUserVO.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/user/domain/SmUserVO.java @@ -61,4 +61,7 @@ public class SmUserVO extends SmUser { @JsonView(JsonViewProfile.App.class) private Boolean isStaff; + @ApiModelProperty("所属应用名称") + private String appName; + } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/user/mapper/SmUserMapper.xml b/smart-switch-service/src/main/java/com/ruoyi/ss/user/mapper/SmUserMapper.xml index e87279c9..a66c13a7 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/user/mapper/SmUserMapper.xml +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/user/mapper/SmUserMapper.xml @@ -9,6 +9,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -61,11 +62,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" su.agent_device_service, su.agent_allow_mch_switch, su.ali_open_id, + su.channel_ids, + su.app_id, 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, - (select sum(sb.payed_amount) from ss_bonus sb where sb.arrival_id = su.user_id and sb.arrival_type in ('2', '3')) as total_income + sa.name as app_name from sm_user su + left join ss_app sa on sa.app_id = su.app_id @@ -97,6 +99,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and su.agent_allow_mch_switch != #{agentAllowMchSwitch} and if(su.is_real, su.real_name, su.user_name) like concat('%', #{realOrUserName}, '%') and su.real_id_card = #{eqRealIdCard} + and app_id = #{appId} and su.user_id in ( select sdt.tenant_id @@ -206,6 +209,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" agent_device_service, agent_allow_mch_switch, ali_open_id, + channel_ids, + app_id, #{userName}, @@ -255,6 +260,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{agentDeviceService}, #{agentAllowMchSwitch}, #{aliOpenId}, + #{channelIds,typeHandler=com.ruoyi.system.mapper.typehandler.StringSplitListTypeHandler}, + #{appId}, @@ -320,6 +327,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" agent_device_service = #{agentDeviceService}, agent_allow_mch_switch = #{agentAllowMchSwitch}, ali_open_id = #{aliOpenId}, + channel_ids = #{channelIds,typeHandler=com.ruoyi.system.mapper.typehandler.StringSplitListTypeHandler}, + app_id = #{appId}, where user_id = #{userId} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/ISmUserService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/ISmUserService.java index 1ded6b03..ee16b2c1 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/ISmUserService.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/ISmUserService.java @@ -2,6 +2,7 @@ package com.ruoyi.ss.user.service; import com.ruoyi.common.core.domain.entity.SmUser; import com.ruoyi.common.enums.UserType; +import com.ruoyi.ss.app.domain.AppVO; import com.ruoyi.ss.recordBalance.domain.enums.RecordBalanceBstType; import com.ruoyi.ss.riskInfo.domain.RiskInfoVO; import com.ruoyi.ss.user.domain.SmUserQuery; @@ -276,11 +277,13 @@ public interface ISmUserService /** * 注册微信账号 + * * @param openId * @param mobile + * @param app * @return */ - SmUserVO registerWx(String openId, String mobile); + SmUserVO registerWx(String openId, String mobile, AppVO app); /** * 绑定支付宝手机号 diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/UserConverter.java b/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/UserConverter.java index 29cee47e..e44c9059 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/UserConverter.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/UserConverter.java @@ -12,4 +12,8 @@ public interface UserConverter { */ SmUser toUserSettingByApp(SmUser data); + /** + * 新增、编辑时,转为PO + */ + SmUser toPo(SmUser data); } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/impl/SmUserServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/impl/SmUserServiceImpl.java index 6a1ef259..31827d65 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/impl/SmUserServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/impl/SmUserServiceImpl.java @@ -25,6 +25,9 @@ import com.ruoyi.common.valid.liveness.LivenessResponseQueryData; import com.ruoyi.common.valid.liveness.LivenessResponseTokenData; import com.ruoyi.common.valid.liveness.LivenessUtils; import com.ruoyi.common.valid.liveness.enums.LivenessQueryResult; +import com.ruoyi.ss.app.domain.AppVO; +import com.ruoyi.ss.app.service.AppConverter; +import com.ruoyi.ss.app.service.AppService; import com.ruoyi.ss.device.domain.DeviceQuery; import com.ruoyi.ss.device.domain.vo.DeviceVO; import com.ruoyi.ss.device.service.DeviceService; @@ -129,6 +132,12 @@ public class SmUserServiceImpl implements ISmUserService @Autowired private AliAuthService aliAuthService; + @Autowired + private AppService appService; + + @Autowired + private AppConverter appConverter; + /** * 查询普通用户信息 * @@ -137,6 +146,9 @@ public class SmUserServiceImpl implements ISmUserService */ @Override public SmUserVO selectSmUserByUserId(Long userId) { + if (userId == null) { + return null; + } return smUserMapper.selectSmUserByUserId(userId); } @@ -585,7 +597,16 @@ public class SmUserServiceImpl implements ISmUserService log.warn("微信手机号临时授权码为空"); return 0; } - String mobile = wxAuthService.getWxPhoneNumber(mobileCode); + // 获取用户信息 + SmUserVO user = selectSmUserByUserId(userId); + ServiceUtil.assertion(user == null, "用户不存在"); + + // 获取小程序信息 + AppVO app = appService.selectAppById(userId); + ServiceUtil.assertion(app == null, "小程序信息不存在"); + + // 获取手机号 + String mobile = wxAuthService.getWxPhoneNumber(mobileCode, appConverter.toWxConfig(app)); ServiceUtil.assertion(StringUtils.isBlank(mobile), "获取微信手机号失败"); return this.bindMobile(userId, mobile); } @@ -673,7 +694,7 @@ public class SmUserServiceImpl implements ISmUserService } @Override - public SmUserVO registerWx(String openId, String mobile) { + public SmUserVO registerWx(String openId, String mobile, AppVO app) { if (StringUtils.isBlank(openId)) { return null; } @@ -686,6 +707,7 @@ public class SmUserServiceImpl implements ISmUserService data.setWxOpenId(openId); data.setPhonenumber(mobile); data.setType(UserType.USER.getType()); + data.setAppId(app.getId()); int insert = this.insertSmUser(data); ServiceUtil.assertion(insert != 1, "注册微信用户失败"); diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/impl/UserConverterImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/impl/UserConverterImpl.java index 27483cd9..e380fe79 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/impl/UserConverterImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/impl/UserConverterImpl.java @@ -20,4 +20,42 @@ public class UserConverterImpl implements UserConverter { po.setAgentDeviceService(data.getAgentDeviceService()); return po; } + + @Override + public SmUser toPo(SmUser data) { + if (data == null) { + return null; + } + + SmUser po = new SmUser(); + po.setUserId(data.getUserId()); + po.setUserName(data.getUserName()); + po.setNickName(data.getNickName()); + po.setEmail(data.getEmail()); + po.setPhonenumber(data.getPhonenumber()); + po.setAvatar(data.getAvatar()); + po.setPassword(data.getPassword()); + po.setServiceRate(data.getServiceRate()); + po.setDeviceAdmin(data.getDeviceAdmin()); + po.setServiceType(data.getServiceType()); + po.setWithdrawServiceType(data.getWithdrawServiceType()); + po.setWithdrawServiceRate(data.getWithdrawServiceRate()); + po.setLimitWithdraw(data.getLimitWithdraw()); + po.setLimitWithdrawReason(data.getLimitWithdrawReason()); + po.setLimitRefund(data.getLimitRefund()); + po.setLimitRefundReason(data.getLimitRefundReason()); + po.setLimitWithdrawTime(data.getLimitWithdrawTime()); + po.setType(data.getType()); + po.setAgentServiceRate(data.getAgentServiceRate()); + po.setArrivalDelay(data.getArrivalDelay()); + po.setLimitRefundTime(data.getLimitRefundTime()); + po.setShowBillMobile(data.getShowBillMobile()); + po.setShowBillMobilePrice(data.getShowBillMobilePrice()); + po.setAgentDeviceService(data.getAgentDeviceService()); + po.setAgentAllowMchSwitch(data.getAgentAllowMchSwitch()); + po.setChannelIds(data.getChannelIds()); + po.setRemark(data.getRemark()); + + return po; + } } diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppAccountController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppAccountController.java index 1b82ebfb..d919aaeb 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppAccountController.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppAccountController.java @@ -1,19 +1,24 @@ package com.ruoyi.web.controller.app; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; +import com.ruoyi.common.auth.wx.WxAuthService; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.ValidGroup; import com.ruoyi.common.utils.ServiceUtil; import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.auth.wx.WxAuthService; import com.ruoyi.ss.account.domain.Account; import com.ruoyi.ss.account.domain.AccountQuery; import com.ruoyi.ss.account.domain.AccountVO; import com.ruoyi.ss.account.domain.enums.AccountType; import com.ruoyi.ss.account.service.AccountService; import com.ruoyi.ss.account.service.AccountValidator; -import com.ruoyi.ss.channelWithdraw.service.ChannelWithdrawService; +import com.ruoyi.ss.app.domain.AppVO; +import com.ruoyi.ss.app.domain.enums.AppType; +import com.ruoyi.ss.app.service.AppConverter; +import com.ruoyi.ss.app.service.AppService; +import com.ruoyi.ss.user.domain.SmUserVO; +import com.ruoyi.ss.user.service.ISmUserService; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; @@ -38,27 +43,53 @@ public class AppAccountController extends BaseController { @Autowired private WxAuthService wxAuthService; + @Autowired + private ISmUserService userService; + + @Autowired + private AppService appService; + + @Autowired + private AppConverter appConverter; + @ApiOperation("添加收款账户") @PostMapping public AjaxResult addAccount(@RequestBody @Validated({ValidGroup.FrontCreate.class}) Account data) { + // 获取用户信息 + SmUserVO user = userService.selectSmUserByUserId(getUserId()); + ServiceUtil.assertion(user == null, "用户不存在"); + + // 获取应用信息 + AppVO app = appService.selectAppById(user.getAppId()); + ServiceUtil.assertion(app == null, "应用信息不存在"); + ServiceUtil.assertion(!AppType.WX.getType().equals(app.getType()), "当前应用不是微信小程序"); + // 微信,获取微信openId并替换数据 if (AccountType.WECHAT.getType().equals(data.getAccountType())) { - WxMaJscode2SessionResult result = wxAuthService.wxJsCode2Session(data.getAccountNo()); + WxMaJscode2SessionResult result = wxAuthService.wxJsCode2Session(data.getAccountNo(), appConverter.toWxConfig(app)); ServiceUtil.assertion(result == null, "获取微信信息失败"); data.setAccountNo(result.getOpenid()); } - data.setUserId(getUserId()); + data.setUserId(user.getUserId()); return success(accountService.insertSmAccount(data)); } @ApiOperation("修改收款账户") @PutMapping public AjaxResult updateAccount(@RequestBody @Validated({ValidGroup.FrontUpdate.class}) Account data) { + // 获取用户信息 + SmUserVO user = userService.selectSmUserByUserId(getUserId()); + ServiceUtil.assertion(user == null, "用户不存在"); + + // 获取应用信息 + AppVO app = appService.selectAppById(user.getAppId()); + ServiceUtil.assertion(app == null, "应用信息不存在"); + ServiceUtil.assertion(!AppType.WX.getType().equals(app.getType()), "当前应用不是微信小程序"); // 微信,获取微信openId并替换数据 if (AccountType.WECHAT.getType().equals(data.getAccountType()) && StringUtils.hasText(data.getAccountNo())) { - WxMaJscode2SessionResult result = wxAuthService.wxJsCode2Session(data.getAccountNo()); + WxMaJscode2SessionResult result = wxAuthService.wxJsCode2Session(data.getAccountNo(), appConverter.toWxConfig(app)); ServiceUtil.assertion(result == null, "获取微信信息失败"); data.setAccountNo(result.getOpenid()); } diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppChannelController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppChannelController.java index aabe3d92..6151372e 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppChannelController.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppChannelController.java @@ -4,8 +4,13 @@ import com.fasterxml.jackson.annotation.JsonView; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.JsonViewProfile; +import com.ruoyi.common.utils.collection.CollectionUtils; import com.ruoyi.ss.channel.domain.ChannelQuery; +import com.ruoyi.ss.channel.domain.ChannelVO; +import com.ruoyi.ss.channel.domain.enums.ChannelType; import com.ruoyi.ss.channel.service.ChannelService; +import com.ruoyi.ss.user.domain.SmUserVO; +import com.ruoyi.ss.user.service.ISmUserService; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -13,6 +18,9 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.util.ArrayList; +import java.util.List; + /** * @author wjh * 2024/4/15 @@ -24,13 +32,35 @@ public class AppChannelController extends BaseController { @Autowired private ChannelService channelService; + @Autowired + private ISmUserService userService; + @ApiOperation("获取充值渠道列表") @JsonView(JsonViewProfile.App.class) @GetMapping("/enabledList") - public AjaxResult getRechargeEnabledList(@RequestParam(required = false, defaultValue = "1") String platform) { + public AjaxResult getRechargeEnabledList(@RequestParam(required = false, defaultValue = "1") String platform, + @RequestParam(required = false) Long mchId) { + + List channelList = new ArrayList<>(); + + // 查询商户专属渠道 + SmUserVO mch = userService.selectSmUserByUserId(mchId); + if (mch != null && CollectionUtils.isNotEmptyElement(mch.getChannelIds())) { + ChannelQuery mchQuery = new ChannelQuery(); + mchQuery.setPlatform(platform); + mchQuery.setChannelIds(mch.getChannelIds()); + List mchChannelList = channelService.selectEnabledRechargeList(mchQuery); + channelList.addAll(mchChannelList); + } + + // 查询平台收款的渠道 ChannelQuery query = new ChannelQuery(); query.setPlatform(platform); - return success(channelService.selectEnabledRechargeList(query)); + query.setType(ChannelType.PLATFORM.getType()); + List platformChannelList = channelService.selectEnabledRechargeList(query); + channelList.addAll(platformChannelList); + + return success(channelList); } } diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/AppController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/AppController.java index 025ddabe..1445ec7e 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/AppController.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/AppController.java @@ -3,6 +3,7 @@ package com.ruoyi.web.controller.ss; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.ValidGroup; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.poi.ExcelUtil; @@ -12,6 +13,7 @@ import com.ruoyi.ss.app.domain.AppVO; import com.ruoyi.ss.app.service.AppService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; @@ -72,7 +74,7 @@ public class AppController extends BaseController @PreAuthorize("@ss.hasPermi('ss:app:add')") @Log(title = "APP信息", businessType = BusinessType.INSERT) @PostMapping - public AjaxResult add(@RequestBody App app) + public AjaxResult add(@RequestBody @Validated(ValidGroup.Create.class) App app) { return toAjax(appService.insertApp(app)); } @@ -83,7 +85,7 @@ public class AppController extends BaseController @PreAuthorize("@ss.hasPermi('ss:app:edit')") @Log(title = "APP信息", businessType = BusinessType.UPDATE) @PutMapping - public AjaxResult edit(@RequestBody App app) + public AjaxResult edit(@RequestBody @Validated(ValidGroup.Create.class) App app) { return toAjax(appService.updateApp(app)); } diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/PayBillController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/PayBillController.java index 976ff402..880ce44b 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/PayBillController.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/PayBillController.java @@ -1,29 +1,20 @@ package com.ruoyi.web.controller.ss; -import java.util.List; -import javax.servlet.http.HttpServletResponse; - -import com.ruoyi.ss.payBill.domain.dto.PayBillRefundDTO; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.ss.payBill.domain.PayBill; -import com.ruoyi.ss.payBill.domain.PayBillVO; -import com.ruoyi.ss.payBill.domain.PayBillQuery; -import com.ruoyi.ss.payBill.service.PayBillService; -import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.ss.payBill.domain.PayBillQuery; +import com.ruoyi.ss.payBill.domain.PayBillVO; +import com.ruoyi.ss.payBill.service.PayBillService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; /** * 支付订单Controller @@ -110,13 +101,13 @@ public class PayBillController extends BaseController /** * 退款 */ - @PreAuthorize("@ss.hasPermi('ss:payBill:refund')") - @Log(title = "支付订单退款", businessType = BusinessType.OTHER) - @PutMapping("/refund") - public AjaxResult refund(@RequestBody PayBillRefundDTO dto) - { - return toAjax(payBillService.refund(dto)); - } +// @PreAuthorize("@ss.hasPermi('ss:payBill:refund')") +// @Log(title = "支付订单退款", businessType = BusinessType.OTHER) +// @PutMapping("/refund") +// public AjaxResult refund(@RequestBody PayBillRefundDTO dto) +// { +// return toAjax(payBillService.refund(dto)); +// } } diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmChannelController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmChannelController.java index 9e9d50bf..aad23ab4 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmChannelController.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmChannelController.java @@ -10,7 +10,6 @@ import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.ss.channel.domain.Channel; import com.ruoyi.ss.channel.domain.ChannelQuery; import com.ruoyi.ss.channel.domain.ChannelVO; -import com.ruoyi.ss.channel.domain.enums.ChannelType; import com.ruoyi.ss.channel.service.ChannelService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; @@ -45,6 +44,17 @@ public class SmChannelController extends BaseController return getDataTable(list); } + /** + * 查询充值渠道列表 + */ + @PreAuthorize("@ss.hasPermi('system:channel:listByIds')") + @PostMapping("/listByIds") + public AjaxResult listByIds(@RequestBody List ids) + { + List list = smChannelService.selectByIds(ids); + return success(list); + } + /** * 导出充值渠道列表 */ @@ -78,6 +88,7 @@ public class SmChannelController extends BaseController { Channel channel = new Channel(); channel.setName(form.getName()); + channel.setType(form.getType()); channel.setChannelId(form.getChannelId()); channel.setEnabled(form.getEnabled()); channel.setCostRate(form.getCostRate()); @@ -99,7 +110,7 @@ public class SmChannelController extends BaseController { Channel channel = new Channel(); channel.setName(form.getName()); - channel.setType(ChannelType.CUSTOM.getType()); + channel.setType(form.getType()); channel.setEnabled(form.getEnabled()); channel.setCostRate(form.getCostRate()); channel.setServiceType(form.getServiceType()); diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmUserController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmUserController.java index 6f735f41..6812a21f 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmUserController.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmUserController.java @@ -1,34 +1,28 @@ package com.ruoyi.web.controller.ss; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import javax.servlet.http.HttpServletResponse; - -import com.ruoyi.common.core.domain.ValidGroup; -import com.ruoyi.ss.user.domain.SmUserQuery; -import com.ruoyi.ss.user.domain.SmUserVO; -import com.ruoyi.ss.user.service.UserAssembler; -import io.swagger.annotations.ApiOperation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.core.domain.ValidGroup; import com.ruoyi.common.core.domain.entity.SmUser; -import com.ruoyi.ss.user.service.ISmUserService; -import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.ss.user.domain.SmUserQuery; +import com.ruoyi.ss.user.domain.SmUserVO; +import com.ruoyi.ss.user.service.ISmUserService; +import com.ruoyi.ss.user.service.UserAssembler; +import com.ruoyi.ss.user.service.UserConverter; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * 普通用户信息Controller @@ -46,6 +40,9 @@ public class SmUserController extends BaseController @Autowired private UserAssembler userAssembler; + @Autowired + private UserConverter userConverter; + /** * 查询普通用户信息列表 */ @@ -113,7 +110,8 @@ public class SmUserController extends BaseController @PostMapping public AjaxResult add(@RequestBody @Validated(ValidGroup.Create.class) SmUser smUser) { - return toAjax(smUserService.insertSmUser(smUser)); + SmUser po = userConverter.toPo(smUser); + return toAjax(smUserService.insertSmUser(po)); } /** @@ -124,7 +122,8 @@ public class SmUserController extends BaseController @PutMapping public AjaxResult edit(@RequestBody @Validated(ValidGroup.Update.class) SmUser smUser) { - return toAjax(smUserService.updateSmUser(smUser)); + SmUser po = userConverter.toPo(smUser); + return toAjax(smUserService.updateSmUser(po)); } @ApiOperation("重置用户服务费")