This commit is contained in:
磷叶 2025-01-09 18:09:16 +08:00
parent f0f493ac98
commit b4aa567ad4
41 changed files with 633 additions and 313 deletions

View File

@ -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() {

View File

@ -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;
}

View File

@ -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);

View File

@ -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:";
/**
* 设备在线状态

View File

@ -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<Long> channelIds;
@Excel(name = "所属应用ID")
@ApiModelProperty("所属应用ID")
private Long appId;
}

View File

@ -22,4 +22,7 @@ public class WxLoginBody {
@NotBlank(message = "登录授权码不允许为空")
@ApiModelProperty("wx.login获取的登录授权码用于获取openId必填")
private String loginCode;
@NotNull(message = "应用ID不允许为空")
private Long appId;
}

View File

@ -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");
}
/**

View File

@ -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());
}

View File

@ -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, "用户不存在");

View File

@ -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<Long>{
/**
* 转换为列表
*
* @param data
* @param delimiter
*/
@Override
public List<Long> 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());
}
}

View File

@ -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";
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -97,4 +97,8 @@ public class Bonus extends BaseEntity
@ApiModelProperty("待分成金额")
private BigDecimal waitAmount;
@Excel(name = "是否需要加入到余额中")
@ApiModelProperty("是否需要加入到余额中")
private Boolean toBalance;
}

View File

@ -81,7 +81,7 @@ public interface BonusMapper
/**
* 批量更新分成金额
*/
int batchUpdateAmount(@Param("list") List<BonusVO> list);
int batchUpdateAmount(@Param("list") List<Bonus> list);
/**
* 根据到账方统计

View File

@ -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
<include refid="searchTables"/>
</sql>
@ -49,6 +50,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.payTimeEnd != null "> and sb.pay_time &lt;= #{query.payTimeEnd}</if>
<if test="query.prePayTimeStart != null "> and sb.pre_pay_time >= #{query.prePayTimeStart}</if>
<if test="query.prePayTimeEnd != null "> and sb.pre_pay_time &lt;= #{query.prePayTimeEnd}</if>
<if test="query.toBalance != null "> and sb.to_balance = #{query.toBalance}</if>
<if test="query.billIds != null and query.billIds.size() > 0 ">
and sb.bill_id in
<foreach collection="query.billIds" item="item" open="(" close=")" separator=",">
@ -235,6 +237,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="prePayTime != null">pre_pay_time,</if>
<if test="payedAmount != null">payed_amount,</if>
<if test="waitAmount != null">wait_amount,</if>
<if test="toBalance != null">to_balance,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="billId != null">#{billId},</if>
@ -253,6 +256,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="prePayTime != null">#{prePayTime},</if>
<if test="payedAmount != null">#{payedAmount},</if>
<if test="waitAmount != null">#{waitAmount},</if>
<if test="toBalance != null">#{toBalance},</if>
</trim>
</insert>
@ -421,6 +425,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="data.prePayTime != null">pre_pay_time = #{data.prePayTime},</if>
<if test="data.payedAmount != null">payed_amount = #{data.payedAmount},</if>
<if test="data.waitAmount != null">wait_amount = #{data.waitAmount},</if>
<if test="data.toBalance != null">to_balance = #{data.toBalance},</if>
</sql>
<delete id="deleteBonusById" parameterType="Long">

View File

@ -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<Bonus> bonusList);
/**
* 处理分成支付
*
* @param bonusList 分成列表
* @return 处理数量
*/
int payBonus(List<BonusVO> bonusList);
/**
* 支付分成
* @param bonus
@ -93,10 +86,11 @@ public interface BonusService
/**
* 处理分成按照比例分出金额
*
* @param bonusList 分成列表
* @param money 总金额
* @param money 总金额
*/
int partBonus(List<BonusVO> bonusList, BigDecimal money);
void partBonus(List<Bonus> bonusList, BigDecimal money);
/**
* 根据到账方统计
@ -169,4 +163,11 @@ public interface BonusService
* 查询已分成金额总和
*/
BigDecimal selectSumOfPayedAmount(BonusQuery query);
/**
* 根据平台收款构建分成列表
*/
List<Bonus> buildBonusListByPlatform(List<Bonus> bonusList, TransactionBillVO bill);
List<Bonus> buildBonusListByCustom(TransactionBillVO bill);
}

View File

@ -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<BonusVO> 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<BonusVO> bonusList, BigDecimal money) {
public void partBonus(List<Bonus> 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<SmUserVO> 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<BonusVO> list) {
@Override
public List<Bonus> buildBonusListByPlatform(List<Bonus> 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<Bonus> buildBonusListByCustom(TransactionBillVO bill) {
List<Bonus> 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<Bonus> list) {
if (CollectionUtils.isEmptyElement(list)) {
return 0;
}

View File

@ -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 = "渠道配置")

View File

@ -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;

View File

@ -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);
}

View File

@ -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();

View File

@ -329,4 +329,7 @@ public class TransactionBill extends BaseEntity
@ApiModelProperty("商户展示手机号缴费状态")
private String mchShowMobileStatus;
@Excel(name = "渠道类型", dictType = DictTypeConstants.RECHARGE_CHANNEL_TYPE)
@ApiModelProperty("渠道类型")
private String channelType;
}

View File

@ -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;
}

View File

@ -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,
</sql>
<sql id="selectSmTransactionBillVo">
@ -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 <include refid="rechargeTables"/>
</sql>
@ -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
</sql>
<!--查询提现VO-->
@ -210,6 +213,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<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.channelType != null and query.channelType != ''"> and channel_type = #{query.channelType}</if>
<if test="query.isNullSuitEndTime != null">
and stb.suit_end_time is
<if test="!query.isNullSuitEndTime">
@ -564,6 +568,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<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>
<if test="channelType != null and channelType != ''">channel_type,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="billNo != null">#{billNo},</if>
@ -634,6 +639,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="mchShowMobile != null">#{mchShowMobile},</if>
<if test="mchShowMobilePrice != null">#{mchShowMobilePrice},</if>
<if test="mchShowMobileStatus != null and mchShowMobileStatus != ''">#{mchShowMobileStatus},</if>
<if test="channelType != null and channelType != ''">#{channelType},</if>
</trim>
</insert>
@ -720,6 +726,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<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>
<if test="data.channelType != null and data.channelType != ''">stb.channel_type = #{data.channelType},</if>
</sql>
<update id="updateByQuery">

View File

@ -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<BonusVO> bonusList = bill.getBonusList();
// 渠道信息
ChannelVO channel = bo.getChannel();
ServiceUtil.assertion(channel == null, "支付渠道不存在");
// 构造分成数据
List<Bonus> 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) {

View File

@ -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<Bonus> 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<Bonus> bonusList = bo.getDevice().getBonusList();
ChannelVO channel = bo.getChannel();
return transactionTemplate.execute(status -> {
// 修改订单信息

View File

@ -61,4 +61,7 @@ public class SmUserVO extends SmUser {
@JsonView(JsonViewProfile.App.class)
private Boolean isStaff;
@ApiModelProperty("所属应用名称")
private String appName;
}

View File

@ -9,6 +9,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="rechargeAmount" column="recharge_amount" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="withDrawlAmount" column="with_drawl_amount" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="totalIncome" column="total_income" typeHandler="com.ruoyi.system.mapper.typehandler.NonNullDecimalTypeHandler" />
<result property="channelIds" column="channel_ids" typeHandler="com.ruoyi.system.mapper.typehandler.StringSplitListTypeHandler"/>
</resultMap>
<sql id="selectSmUserVo">
@ -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
</sql>
<sql id="searchCondition">
@ -97,6 +99,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="agentAllowMchSwitch != null">and su.agent_allow_mch_switch != #{agentAllowMchSwitch}</if>
<if test="realOrUserName != null and realOrUserName != ''">and if(su.is_real, su.real_name, su.user_name) like concat('%', #{realOrUserName}, '%')</if>
<if test="eqRealIdCard != null and eqRealIdCard != ''">and su.real_id_card = #{eqRealIdCard}</if>
<if test="appId != null "> and app_id = #{appId}</if>
<if test="tenantDeviceId != null">
and su.user_id in (
select sdt.tenant_id
@ -206,6 +209,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="agentDeviceService != null">agent_device_service,</if>
<if test="agentAllowMchSwitch != null">agent_allow_mch_switch,</if>
<if test="aliOpenId != null">ali_open_id,</if>
<if test="channelIds != null">channel_ids,</if>
<if test="appId != null">app_id,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userName != null and userName != ''">#{userName},</if>
@ -255,6 +260,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="agentDeviceService != null">#{agentDeviceService},</if>
<if test="agentAllowMchSwitch != null">#{agentAllowMchSwitch},</if>
<if test="aliOpenId != null">#{aliOpenId},</if>
<if test="channelIds != null">#{channelIds,typeHandler=com.ruoyi.system.mapper.typehandler.StringSplitListTypeHandler},</if>
<if test="appId != null">#{appId},</if>
</trim>
</insert>
@ -320,6 +327,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="agentDeviceService != null">agent_device_service = #{agentDeviceService},</if>
<if test="agentAllowMchSwitch != null">agent_allow_mch_switch = #{agentAllowMchSwitch},</if>
<if test="aliOpenId != null">ali_open_id = #{aliOpenId},</if>
<if test="channelIds != null">channel_ids = #{channelIds,typeHandler=com.ruoyi.system.mapper.typehandler.StringSplitListTypeHandler},</if>
<if test="appId != null">app_id = #{appId},</if>
</trim>
where user_id = #{userId}
</update>

View File

@ -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);
/**
* 绑定支付宝手机号

View File

@ -12,4 +12,8 @@ public interface UserConverter {
*/
SmUser toUserSettingByApp(SmUser data);
/**
* 新增编辑时转为PO
*/
SmUser toPo(SmUser data);
}

View File

@ -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, "注册微信用户失败");

View File

@ -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;
}
}

View File

@ -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());
}

View File

@ -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<ChannelVO> 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<ChannelVO> 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<ChannelVO> platformChannelList = channelService.selectEnabledRechargeList(query);
channelList.addAll(platformChannelList);
return success(channelList);
}
}

View File

@ -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));
}

View File

@ -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));
// }
}

View File

@ -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<Long> ids)
{
List<ChannelVO> 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());

View File

@ -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("重置用户服务费")