Просмотр исходного кода

fix cash out

release_toaliyun_real
xiaohanzi 5 лет назад
Родитель
Сommit
b92049ec5a
8 измененных файлов: 98 добавлений и 60 удалений
  1. +7
    -1
      mallinkAdmin/src/main/resources/db/migration/V202104130001__for_cash_out.sql
  2. +0
    -15
      mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java
  3. +2
    -1
      mallinkService/src/main/java/com/iformall/domain/po/WxMall.java
  4. +3
    -0
      mallinkService/src/main/java/com/iformall/domain/po/WxMerchant.java
  5. +2
    -0
      mallinkService/src/main/java/com/iformall/mapper/WxMerchantMapper.java
  6. +74
    -39
      mallinkService/src/main/java/com/iformall/service/impl/WxCashOutServiceImpl.java
  7. +2
    -1
      mallinkService/src/main/resources/mapper/WxMallMapper.xml
  8. +8
    -3
      mallinkService/src/main/resources/mapper/WxMerchantMapper.xml

+ 7
- 1
mallinkAdmin/src/main/resources/db/migration/V202104130001__for_cash_out.sql Просмотреть файл

@@ -3,7 +3,7 @@ ADD COLUMN `cash_out_support` INT(1) COMMENT '是否支持商户提现(不开启


UPDATE wx_mall SET cash_out_support = 0 ; UPDATE wx_mall SET cash_out_support = 0 ;


ALTER TABLE wx_merchant ADD COLUMN `cash_out_number` INT(11) COMMENT '商户待提现金额(分)' ;
ALTER TABLE wx_merchant ADD COLUMN `cash_out_number` INT(11) DEFAULT 0 COMMENT '商户待提现金额(分)' ;


###页面添加工作流,提现审批,22, 初始化里面也加上 ###页面添加工作流,提现审批,22, 初始化里面也加上


@@ -29,6 +29,12 @@ CREATE TABLE `wx_cash_out` (
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;


ALTER TABLE `wx_mall`
ADD COLUMN `cash_out_limit` INT(3) COMMENT '商户提现每日次数限制' AFTER `cash_out_support`;

UPDATE wx_mall SET cash_out_limit = 10 ;

ALTER TABLE wx_merchant ADD COLUMN `cash_out_count` INT(3) DEFAULT 0 COMMENT '当日提现次数' ;







+ 0
- 15
mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java Просмотреть файл

@@ -63,21 +63,6 @@ public class WxCashOutController extends BaseController {
@PostMapping("recashout") @PostMapping("recashout")
public ResultData recashout(@RequestBody WxCashOut wxCashOut) { public ResultData recashout(@RequestBody WxCashOut wxCashOut) {
WxMerchantBUser buser = getLoginBUser(); WxMerchantBUser buser = getLoginBUser();
//当前管理员的账户必须在c端授权了
WxCUser cuUser = new WxCUser();
cuUser.updateTenantInfo(buser);
cuUser.setPhone(buser.getPhone());
try {
WxCUser mUser = wxCUserService.getByObject(cuUser);
if (mUser == null) {
return new ResultData(Result.ERROR,"请用绑定["+buser.getPhone()+"]的微信在C端完成授权手机号操作。");
}
wxCashOut.setReciveOpenId(mUser.getOpenId());
wxCashOut.setReciveNickName(mUser.getNickName());
}catch(Exception e) {
return new ResultData(Result.ERROR,buser.getPhone()+"匹配C端用户失败,该情况可能是存在多个微信对应统一手机号,请联系管理员处理, 。");
}
return wxCashOutService.reCashout(buser, wxCashOut,EnumPayWay.PAY_WAY_WECHAT); return wxCashOutService.reCashout(buser, wxCashOut,EnumPayWay.PAY_WAY_WECHAT);
} }




+ 2
- 1
mallinkService/src/main/java/com/iformall/domain/po/WxMall.java Просмотреть файл

@@ -88,7 +88,8 @@ public class WxMall extends TenantEntity {
private Integer liveSupport; private Integer liveSupport;
@io.swagger.annotations.ApiModelProperty(value="是否支持商户提现(不开启分账才有效) 0-不支持 1-支持",name="cashOutSupport") @io.swagger.annotations.ApiModelProperty(value="是否支持商户提现(不开启分账才有效) 0-不支持 1-支持",name="cashOutSupport")
private Integer cashOutSupport; private Integer cashOutSupport;
@io.swagger.annotations.ApiModelProperty(value="商户提现每日次数限制",name="cashOutLimit")
private Integer cashOutLimit;


@TableField(exist = false) @TableField(exist = false)
protected List<WxMallBuilding> buildings; protected List<WxMallBuilding> buildings;


+ 3
- 0
mallinkService/src/main/java/com/iformall/domain/po/WxMerchant.java Просмотреть файл

@@ -265,6 +265,9 @@ public class WxMerchant extends TenantEntity {
@io.swagger.annotations.ApiModelProperty(value = "商户待提现金额(分)", name = "cashOutNumber") @io.swagger.annotations.ApiModelProperty(value = "商户待提现金额(分)", name = "cashOutNumber")
private Integer cashOutNumber; private Integer cashOutNumber;
@io.swagger.annotations.ApiModelProperty(value = "当日提现次数", name = "cashOutCount")
private Integer cashOutCount;


@TableField(exist = false) @TableField(exist = false)
@SortColumn(column = "couponSale") @SortColumn(column = "couponSale")


+ 2
- 0
mallinkService/src/main/java/com/iformall/mapper/WxMerchantMapper.java Просмотреть файл

@@ -45,4 +45,6 @@ public interface WxMerchantMapper extends CommonMapper<WxMerchant, Long> {
void increaseCash(WxMerchant record); void increaseCash(WxMerchant record);
void reduceCash(WxMerchant record); void reduceCash(WxMerchant record);
void increaseCashCount(WxMerchant record);
} }

+ 74
- 39
mallinkService/src/main/java/com/iformall/service/impl/WxCashOutServiceImpl.java Просмотреть файл

@@ -84,6 +84,13 @@ public class WxCashOutServiceImpl implements WxCashOutService {
wxCashOutMapper.insert(record); wxCashOutMapper.insert(record);
} }


private boolean hasCashCount(WxMall mall,WxMerchant merchant) {
if (mall.getCashOutLimit().intValue()<=merchant.getCashOutCount().intValue()) {
return false;
}
return true;
}
@Override @Override
@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class}) @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class})
public ResultData applyCashout(WxMerchantBUser buser, WxCashOut record,EnumPayWay payWay) { public ResultData applyCashout(WxMerchantBUser buser, WxCashOut record,EnumPayWay payWay) {
@@ -96,6 +103,11 @@ public class WxCashOutServiceImpl implements WxCashOutService {
if (!(buser.getPhone().equals(merchant.getLinkPhone()))) { if (!(buser.getPhone().equals(merchant.getLinkPhone()))) {
return new ResultData(Result.ERROR,"当前账号非商户管理员,不能进行此操作。"); return new ResultData(Result.ERROR,"当前账号非商户管理员,不能进行此操作。");
} }
if(!hasCashCount(mall,merchant)) {
return new ResultData(Result.ERROR,"当日提现次数已达限额。");
}
if (record.getTotalFee().intValue()<=0) { if (record.getTotalFee().intValue()<=0) {
return new ResultData(Result.ERROR,"提现金额非法。"); return new ResultData(Result.ERROR,"提现金额非法。");
} }
@@ -114,6 +126,7 @@ public class WxCashOutServiceImpl implements WxCashOutService {
if (cashsetlock) { if (cashsetlock) {
try { try {
merchant.setCashOutNumber(record.getTotalFee()); merchant.setCashOutNumber(record.getTotalFee());
//更新金额,并减小次数
wxMerchantMapper.reduceCash(merchant); wxMerchantMapper.reduceCash(merchant);
redisLock.unlock("merchantLockReduceCashSet_"+merchant.getId(), timeStr); redisLock.unlock("merchantLockReduceCashSet_"+merchant.getId(), timeStr);
}catch(Exception e) { }catch(Exception e) {
@@ -166,7 +179,6 @@ public class WxCashOutServiceImpl implements WxCashOutService {
sendCashOutMsg(merchant, cashout.getId(),payWay); sendCashOutMsg(merchant, cashout.getId(),payWay);
} }
return new ResultData("提现提交成功。"); return new ResultData("提现提交成功。");
} }
@@ -199,7 +211,7 @@ public class WxCashOutServiceImpl implements WxCashOutService {
WxMerchant merchant = wxMerchantMapper.selectById(record.getMerchantId()); WxMerchant merchant = wxMerchantMapper.selectById(record.getMerchantId());
//增加账户金额 //增加账户金额
//此处需要加锁,防止并发设置 //此处需要加锁,防止并发设置
long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
long time = System.currentTimeMillis() + RedisLock.LONG_TIMEOUT;
String timeStr = String.valueOf(time); String timeStr = String.valueOf(time);
boolean cashsetlock = redisLock.lock("merchantLockRejectCashSet_"+merchant.getId(), timeStr); boolean cashsetlock = redisLock.lock("merchantLockRejectCashSet_"+merchant.getId(), timeStr);
if (cashsetlock) { if (cashsetlock) {
@@ -243,44 +255,67 @@ public class WxCashOutServiceImpl implements WxCashOutService {


@Override @Override
public ResultData reCashout(WxMerchantBUser buser, WxCashOut record, EnumPayWay payWay) { public ResultData reCashout(WxMerchantBUser buser, WxCashOut record, EnumPayWay payWay) {
WxCashOut cashout = this.getById(record.getId(), buser.getTenantId());
if (null == cashout ) {
return new ResultData(Result.ERROR,"该提现记录不存在");
}
if( EnumCashOutStatus.FAIL.getCode().intValue() != record.getStatus().intValue()) {
return new ResultData(Result.ERROR,"提现失败状态才能重新提现。");
}
//只有商户管理员才能进行此操作
WxMerchant merchant = wxMerchantMapper.selectById(buser.getMerchantId());
if (!(buser.getPhone().equals(merchant.getLinkPhone()))) {
return new ResultData(Result.ERROR,"当前账号非商户管理员,不能进行此操作。");
}
WxAppinfo appInfo = wxAppinfoService.getCAppInfo(buser, payWay);
if (null == appInfo) {
return new ResultData(Result.ERROR,"当前账号非商户管理员,不能进行此操作。");
}
WxPayAccount payAccount = wxPayAccountService.getByTenantId(buser.getTenantId());
if (null == payAccount) {
return new ResultData(Result.ERROR,"当前账号非商户管理员,不能进行此操作。");
}
//查询是否已经真实的转过了
CashOutAdapterResult qresult = payServiceFactory.getCashOutAdapterService(payWay.getCode()).queryCashOut(appInfo, payAccount, cashout);
if (qresult.isSuccess()) {
cashout.setStatus(EnumCashOutStatus.SUCCESS.getCode());
wxCashOutMapper.updateStatus(cashout);
}else {
CashOutAdapterResult result = payServiceFactory.getCashOutAdapterService(payWay.getCode()).cashOut(appInfo, payAccount, cashout);
cashout.setUpdateDate(new Date());
if (result.isSuccess()) {
cashout.setStatus(EnumCashOutStatus.SUCCESS.getCode());
}else {
cashout.setStatus(EnumCashOutStatus.FAIL.getCode());
cashout.setFailRemark(result.getMsg());
}
wxCashOutMapper.updateById(cashout);
}
//不能重复提交操作
long time = System.currentTimeMillis() + RedisLock.LONG_TIMEOUT;
String timeStr = String.valueOf(time);
boolean cashsetlock = redisLock.lock("merchantLockReCashSet_"+record.getId(), timeStr);
if (cashsetlock) {
try {
WxCashOut cashout = this.getById(record.getId(), buser.getTenantId());
if (null == cashout ) {
return new ResultData(Result.ERROR,"该提现记录不存在");
}
if( EnumCashOutStatus.FAIL.getCode().intValue() != record.getStatus().intValue()) {
return new ResultData(Result.ERROR,"提现失败状态才能重新提现。");
}
//只有商户管理员才能进行此操作
WxMerchant merchant = wxMerchantMapper.selectById(buser.getMerchantId());
if (!(buser.getPhone().equals(merchant.getLinkPhone()))) {
return new ResultData(Result.ERROR,"当前账号非商户管理员,不能进行此操作。");
}
WxMall mall = wxMallMapper.getByTenantId(buser.getTenantId());
if(!hasCashCount(mall,merchant)) {
return new ResultData(Result.ERROR,"当日提现次数已达限额。");
}
WxAppinfo appInfo = wxAppinfoService.getCAppInfo(buser, payWay);
if (null == appInfo) {
return new ResultData(Result.ERROR,"系统错误,appInfo未查询到。");
}
WxPayAccount payAccount = wxPayAccountService.getByTenantId(buser.getTenantId());
if (null == payAccount) {
return new ResultData(Result.ERROR,"系统错误,payAccount未查询到。");
}
//查询是否已经真实的转过了
CashOutAdapterResult qresult = payServiceFactory.getCashOutAdapterService(payWay.getCode()).queryCashOut(appInfo, payAccount, cashout);
if (qresult.isSuccess()) {
cashout.setStatus(EnumCashOutStatus.SUCCESS.getCode());
wxCashOutMapper.updateStatus(cashout);
}else {
CashOutAdapterResult result = payServiceFactory.getCashOutAdapterService(payWay.getCode()).cashOut(appInfo, payAccount, cashout);
cashout.setUpdateDate(new Date());
if (result.isSuccess()) {
cashout.setStatus(EnumCashOutStatus.SUCCESS.getCode());
}else {
cashout.setStatus(EnumCashOutStatus.FAIL.getCode());
cashout.setFailRemark(result.getMsg());
}
wxCashOutMapper.updateById(cashout);
}
//更新次数
wxMerchantMapper.increaseCashCount(merchant);
redisLock.unlock("merchantLockReCashSet_"+record.getId(), timeStr);
}catch(Exception e) {
redisLock.unlock("merchantLockReCashSet_"+record.getId(), timeStr);
logger.error("update cashout fail.",e);
}finally {
redisLock.unlock("merchantLockReCashSet_"+record.getId(), timeStr);
}
}
return new ResultData(); return new ResultData();
} }
} }

+ 2
- 1
mallinkService/src/main/resources/mapper/WxMallMapper.xml Просмотреть файл

@@ -37,6 +37,7 @@
<result column="longitude" jdbcType="DECIMAL" property="longitude"/> <result column="longitude" jdbcType="DECIMAL" property="longitude"/>
<result column="live_support" jdbcType="INTEGER" property="liveSupport"/> <result column="live_support" jdbcType="INTEGER" property="liveSupport"/>
<result column="cash_out_support" jdbcType="INTEGER" property="cashOutSupport"/> <result column="cash_out_support" jdbcType="INTEGER" property="cashOutSupport"/>
<result column="cash_out_limit" jdbcType="INTEGER" property="cashOutLimit"/>
</resultMap> </resultMap>


<sql id="allColumns"> <sql id="allColumns">
@@ -45,7 +46,7 @@
`img_url`,`img_url_h`, `weap_note`, `img_qrcode_weapp`, `img_qrcode_wemp`, `img_url`,`img_url_h`, `weap_note`, `img_qrcode_weapp`, `img_qrcode_wemp`,
`weapp_share_title`,`weapp_share_cover_img`, `pos_qrcode_rule`, `weapp_share_title`,`weapp_share_cover_img`, `pos_qrcode_rule`,
`sale_type`, `valid_start`, `valid_end`,`business_hours`,`introduction`,`img`, `sale_type`, `valid_start`, `valid_end`,`business_hours`,`introduction`,`img`,
`group_support`,`latitude`,`longitude`,`live_support`,`cash_out_support`
`group_support`,`latitude`,`longitude`,`live_support`,`cash_out_support`,`cash_out_limit`
</sql> </sql>


<sql id="dynamicWhereConditions"> <sql id="dynamicWhereConditions">


+ 8
- 3
mallinkService/src/main/resources/mapper/WxMerchantMapper.xml Просмотреть файл

@@ -36,18 +36,19 @@
<result column="rental_end_date" property="rentalEndDate"/> <result column="rental_end_date" property="rentalEndDate"/>
<result column="credit_locked" property="creditLocked"/> <result column="credit_locked" property="creditLocked"/>
<result column="cash_out_number" jdbcType="INTEGER" property="cashOutNumber"/> <result column="cash_out_number" jdbcType="INTEGER" property="cashOutNumber"/>
<result column="cash_out_count" jdbcType="INTEGER" property="cashOutCount"/>
</resultMap> </resultMap>
<sql id="allColumns"> <sql id="allColumns">
`id`,`tenant_id`,`parent_tenant_id`,`img_url`,`name`,`link_phone`,`create_date`,`update_date`,`car_vendor_type`,`car_params`,`status`,`link_person`, `id`,`tenant_id`,`parent_tenant_id`,`img_url`,`name`,`link_phone`,`create_date`,`update_date`,`car_vendor_type`,`car_params`,`status`,`link_person`,
`business_id`,`sub_business_id`,`shop_type`,`brand`,`type`,`is_public`,email,`title`,`cover_picture`,`is_admin`,`bill_setting`,`qr_code`, `business_id`,`sub_business_id`,`shop_type`,`brand`,`type`,`is_public`,email,`title`,`cover_picture`,`is_admin`,`bill_setting`,`qr_code`,
`introduction`,`action_desc`,`is_del`,`talk_user_main`,`talk_user_aux`,link_line_phone,credit_locked,cash_out_number
`introduction`,`action_desc`,`is_del`,`talk_user_main`,`talk_user_aux`,link_line_phone,credit_locked,cash_out_number,cash_out_count
</sql> </sql>
<sql id="allColumnsVo"> <sql id="allColumnsVo">
m.`id`,m.`tenant_id`,m.`parent_tenant_id`,m.`img_url`,m.`name`,m.`link_phone`,m.`create_date`,m.`update_date`,m.`car_vendor_type`,m.`car_params`,m.`status`,m.`link_person`, m.`id`,m.`tenant_id`,m.`parent_tenant_id`,m.`img_url`,m.`name`,m.`link_phone`,m.`create_date`,m.`update_date`,m.`car_vendor_type`,m.`car_params`,m.`status`,m.`link_person`,
m.`business_id`,m.`sub_business_id`,m.`shop_type`,m.`brand`,m.`type`,m.`is_public`,m.email,m.`title`,m.`cover_picture`,m.`is_admin`,m.`bill_setting`,m.`qr_code`, m.`business_id`,m.`sub_business_id`,m.`shop_type`,m.`brand`,m.`type`,m.`is_public`,m.email,m.`title`,m.`cover_picture`,m.`is_admin`,m.`bill_setting`,m.`qr_code`,
m.`introduction`,m.`action_desc`,m.`is_del`,m.`talk_user_main`,m.`talk_user_aux`,m.link_line_phone,r.rental_start_date,r.rental_end_date,cash_out_number
m.`introduction`,m.`action_desc`,m.`is_del`,m.`talk_user_main`,m.`talk_user_aux`,m.link_line_phone,r.rental_start_date,r.rental_end_date,cash_out_number,cash_out_count
</sql> </sql>
<sql id="dynamicWhereConditions"> <sql id="dynamicWhereConditions">
@@ -615,7 +616,11 @@
</update> </update>
<update id="reduceCash" parameterType="com.iformall.domain.po.WxMerchant"> <update id="reduceCash" parameterType="com.iformall.domain.po.WxMerchant">
update wx_merchant set cash_out_number = cash_out_number-#{cashOutNumber} where id = #{id}
update wx_merchant set cash_out_number = cash_out_number-#{cashOutNumber}, cash_out_count = cash_out_count+1 where id = #{id}
</update>
<update id="increaseCashCount" parameterType="com.iformall.domain.po.WxMerchant">
update wx_merchant set cash_out_count = cash_out_count+1 where id = #{id}
</update> </update>


</mapper> </mapper>

Загрузка…
Отмена
Сохранить