Sfoglia il codice sorgente

Merge branch 'release_real_202103' of https://git.malls.iformall.com/server/formallProject into release_real_202103

release_toaliyun_real
xhxu 5 anni fa
parent
commit
5d9c5f1d2f
31 ha cambiato i file con 1381 aggiunte e 19 eliminazioni
  1. +40
    -0
      mallinkAdmin/src/main/resources/db/migration/V202104130001__for_cash_out.sql
  2. +69
    -0
      mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java
  3. +8
    -0
      mallinkMQConsumer/src/main/java/com/iformall/mq/MqBaseConsumer.java
  4. +6
    -1
      mallinkService/src/main/java/com/iformall/config/BaseMyBatisConfiguration.java
  5. +51
    -0
      mallinkService/src/main/java/com/iformall/domain/po/WxCashOut.java
  6. +4
    -0
      mallinkService/src/main/java/com/iformall/domain/po/WxMall.java
  7. +6
    -0
      mallinkService/src/main/java/com/iformall/domain/po/WxMerchant.java
  8. +23
    -0
      mallinkService/src/main/java/com/iformall/domain/po/msg/FmInsideCashOutMsg.java
  9. +36
    -0
      mallinkService/src/main/java/com/iformall/enums/EnumCashOut.java
  10. +40
    -0
      mallinkService/src/main/java/com/iformall/enums/EnumCashOutStatus.java
  11. +2
    -0
      mallinkService/src/main/java/com/iformall/enums/EnumFlowKey.java
  12. +1
    -0
      mallinkService/src/main/java/com/iformall/enums/EnumMsgRecordType.java
  13. +18
    -0
      mallinkService/src/main/java/com/iformall/mapper/WxCashOutMapper.java
  14. +6
    -0
      mallinkService/src/main/java/com/iformall/mapper/WxMerchantMapper.java
  15. +37
    -0
      mallinkService/src/main/java/com/iformall/pay/WxCashOutP.java
  16. +27
    -0
      mallinkService/src/main/java/com/iformall/pay/WxCashOutQueryP.java
  17. +2
    -2
      mallinkService/src/main/java/com/iformall/pay/WxPay.java
  18. +51
    -0
      mallinkService/src/main/java/com/iformall/service/WxCashOutService.java
  19. +321
    -0
      mallinkService/src/main/java/com/iformall/service/impl/WxCashOutServiceImpl.java
  20. +38
    -8
      mallinkService/src/main/java/com/iformall/service/impl/WxCouponOrderServiceImpl.java
  21. +30
    -0
      mallinkService/src/main/java/com/iformall/service/impl/WxFlowServiceImpl.java
  22. +29
    -0
      mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideCashOutMsgServiceImpl.java
  23. +1
    -1
      mallinkService/src/main/java/com/iformall/service/park/impl/cyf/CYFParkService.java
  24. +24
    -1
      mallinkService/src/main/java/com/iformall/service/pay/PayServiceFactory.java
  25. +48
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/cashout/CashOutAdapterService.java
  26. +51
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/cashout/entity/CashOutAdapterResult.java
  27. +314
    -0
      mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java
  28. +79
    -0
      mallinkService/src/main/resources/mapper/WxCashOutMapper.xml
  29. +1
    -1
      mallinkService/src/main/resources/mapper/WxCouponOrderMapper.xml
  30. +3
    -2
      mallinkService/src/main/resources/mapper/WxMallMapper.xml
  31. +15
    -3
      mallinkService/src/main/resources/mapper/WxMerchantMapper.xml

+ 40
- 0
mallinkAdmin/src/main/resources/db/migration/V202104130001__for_cash_out.sql Vedi File

@@ -0,0 +1,40 @@
ALTER TABLE `wx_mall`
ADD COLUMN `cash_out_support` INT(1) COMMENT '是否支持商户提现(不开启分账才有效) 0-不支持 1-支持' AFTER `live_support`;

UPDATE wx_mall SET cash_out_support = 0 ;

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

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

CREATE TABLE `wx_cash_out` (
`id` bigint(20) NOT NULL,
`total_fee` int(11) NOT NULL COMMENT '总金额(分)',
`status` tinyint(1) NOT NULL COMMENT '状态 0-提现中,1-提现成功,2-提现失败,3-提现拒绝',
`create_date` datetime DEFAULT NULL COMMENT '创建时间',
`update_date` datetime DEFAULT NULL COMMENT '更新时间',
`audio_remark` varchar(1000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '审核备注',
`tenant_id` varchar(5) COLLATE utf8mb4_unicode_ci NOT NULL,
`parent_tenant_id` varchar(5) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`b_user_id` bigint(20) NOT NULL COMMENT 'merchant_b_user编号',
`wx_b_open_id` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'b端微信openId',
`audio_date` datetime DEFAULT NULL COMMENT '审批时间',
`merchant_id` bigint(20) NOT NULL COMMENT '提现商户',
`merchant_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '商户名称',
`recive_open_id` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '接收的openId',
`recive_nick_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '昵称',
`wx_pay_no` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '支付渠道支付编号',
`wx_pay_time` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '支付渠道支付时间',
`fail_remark` varchar(1000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '失败原因',
PRIMARY KEY (`id`)
) 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 '当日提现次数' ;




+ 69
- 0
mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java Vedi File

@@ -0,0 +1,69 @@
package com.iformall.controller;

import com.github.pagehelper.PageInfo;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.*;
import com.iformall.enums.EnumPayWay;
import com.iformall.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/cashout")
@Api(description = "提现相关接口")
public class WxCashOutController extends BaseController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
private WxCashOutService wxCashOutService;
@Autowired
WxCUserService wxCUserService;
@ApiOperation("分页列表接口")
@GetMapping("list")
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
@ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
public ResultData list(@ModelAttribute WxCashOut wxCashOut, Integer pageNum, Integer pageSize) {
if (null == wxCashOut) wxCashOut = new WxCashOut();
final PageInfo<WxCashOut> page = wxCashOutService.listAsPage(wxCashOut, pageNum, pageSize);
return new ResultData(page);
}

@ApiOperation("微信B端提现")
@PostMapping("cashout")
public ResultData cashout(@RequestBody WxCashOut wxCashOut) {
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.applyCashout(buser, wxCashOut,EnumPayWay.PAY_WAY_WECHAT);
}
@ApiOperation("微信B端重新提现")
@PostMapping("recashout")
public ResultData recashout(@RequestBody WxCashOut wxCashOut) {
WxMerchantBUser buser = getLoginBUser();
return wxCashOutService.reCashout(buser, wxCashOut,EnumPayWay.PAY_WAY_WECHAT);
}

}

+ 8
- 0
mallinkMQConsumer/src/main/java/com/iformall/mq/MqBaseConsumer.java Vedi File

@@ -46,6 +46,9 @@ public class MqBaseConsumer {
//@Autowired
//UpdateCouponStockMsgServiceImpl updateCouponStockMsgService;
@Autowired
private FmInsideCashOutMsgServiceImpl fmInsideCashOutMsgService;


public void doMessage(String message) {
@@ -103,6 +106,11 @@ public class MqBaseConsumer {
FmInsideNotifyRefundSuccessMsg msg = (FmInsideNotifyRefundSuccessMsg)JsonUtil.readValue(message,FmInsideNotifyRefundSuccessMsg.class);
fmInsideNotifyRefundSuccessMsgService.send(msg);
}
else if(EnumMsgRecordType.CASH_OUT.getCode().equals(baseMsg.getMsgType())) {
// 内部消息 - 商户提现通知
FmInsideCashOutMsg msg = (FmInsideCashOutMsg)JsonUtil.readValue(message,FmInsideCashOutMsg.class);
fmInsideCashOutMsgService.send(msg);
}
//else if (EnumMsgRecordType.COUPON_STOCK.getCode().equals(baseMsg.getMsgType())) {
// UpdateCouponStockMsg msg = (UpdateCouponStockMsg)JsonUtil.readValue(message,UpdateCouponStockMsg.class);
// updateCouponStockMsgService.send(msg);


+ 6
- 1
mallinkService/src/main/java/com/iformall/config/BaseMyBatisConfiguration.java Vedi File

@@ -212,7 +212,12 @@ public class BaseMyBatisConfiguration {
wxCarJSOrderSharding.setRule(EnumShardingRule.HASH.getCode());
shardingList.add(wxCarJSOrderSharding);
ShardingSphere wxCashOutSharding = new ShardingSphere();
wxCashOutSharding.setColumn("tenant_id");
wxCashOutSharding.setTableName("wx_cash_out");
wxCashOutSharding.setCount(100);
wxCashOutSharding.setRule(EnumShardingRule.HASH.getCode());
shardingList.add(wxCashOutSharding);
//初始化
shardingSpherePlugin.setShardingSpheres(shardingList);


+ 51
- 0
mallinkService/src/main/java/com/iformall/domain/po/WxCashOut.java Vedi File

@@ -0,0 +1,51 @@
package com.iformall.domain.po;

import com.baomidou.mybatisplus.annotation.TableName;
import com.iformall.domain.po.base.TenantEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.util.Date;

@TableName(value = "wx_cash_out")
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class WxCashOut extends TenantEntity {

protected Long id;

@io.swagger.annotations.ApiModelProperty(value = "总金额(分)", name = "totalFee")
private Integer totalFee;
@io.swagger.annotations.ApiModelProperty(value = "状态 0-提现中,1-提现成功,2-提现失败,3-提现拒绝", name = "status")
private Integer status;
@io.swagger.annotations.ApiModelProperty(value = "创建时间", name = "createDate")
private Date createDate;
@io.swagger.annotations.ApiModelProperty(value = "更新时间", name = "updateDate")
private Date updateDate;
@io.swagger.annotations.ApiModelProperty(value = "审核备注", name = "audioRemark")
private String audioRemark;
@io.swagger.annotations.ApiModelProperty(value = "merchant_b_user编号", name = "bUserId")
private Long bUserId;
@io.swagger.annotations.ApiModelProperty(value = "b端微信用户Id", name = "wxBOpenId")
private String wxBOpenId;
@io.swagger.annotations.ApiModelProperty(value = "审批时间", name = "audioDate")
private Date audioDate;
@io.swagger.annotations.ApiModelProperty(value = "提现商户", name = "merchantId")
private Long merchantId;
@io.swagger.annotations.ApiModelProperty(value = "商户名称", name = "merchantName")
private String merchantName;
@io.swagger.annotations.ApiModelProperty(value = "接收的openId", name = "reciveOpenId")
private String reciveOpenId;
@io.swagger.annotations.ApiModelProperty(value = "昵称", name = "reciveNickName")
private String reciveNickName;
@io.swagger.annotations.ApiModelProperty(value = "支付渠道支付编号", name = "wxPayNo")
private String wxPayNo;
@io.swagger.annotations.ApiModelProperty(value = "支付渠道支付时间", name = "wxPayTime")
private String wxPayTime;
@io.swagger.annotations.ApiModelProperty(value = "失败原因", name = "failRemark")
private String failRemark;
}

+ 4
- 0
mallinkService/src/main/java/com/iformall/domain/po/WxMall.java Vedi File

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

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


+ 6
- 0
mallinkService/src/main/java/com/iformall/domain/po/WxMerchant.java Vedi File

@@ -262,6 +262,12 @@ public class WxMerchant extends TenantEntity {

@io.swagger.annotations.ApiModelProperty(value = "积分锁定0正常1锁定", name = "creditLocked")
private Integer creditLocked;
@io.swagger.annotations.ApiModelProperty(value = "商户待提现金额(分)", name = "cashOutNumber")
private Integer cashOutNumber;
@io.swagger.annotations.ApiModelProperty(value = "当日提现次数", name = "cashOutCount")
private Integer cashOutCount;

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


+ 23
- 0
mallinkService/src/main/java/com/iformall/domain/po/msg/FmInsideCashOutMsg.java Vedi File

@@ -0,0 +1,23 @@
package com.iformall.domain.po.msg;

import com.iformall.enums.EnumPayWay;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class FmInsideCashOutMsg extends BaseMsg{
private static final long serialVersionUID = 1L;

@io.swagger.annotations.ApiModelProperty(value = "租户ID", name = "tenantId")
private String tenantId;
@io.swagger.annotations.ApiModelProperty(value="父租户id",name="parentTenantId")
private String parentTenantId;
@io.swagger.annotations.ApiModelProperty(value = "提现ID", name = "cashOutId")
private Long cashOutId;
@io.swagger.annotations.ApiModelProperty(value = "支付方式", name = "payWay")
private EnumPayWay payWay;
}

+ 36
- 0
mallinkService/src/main/java/com/iformall/enums/EnumCashOut.java Vedi File

@@ -0,0 +1,36 @@
package com.iformall.enums;

/**
* Created by Stormeye on 2018/08/09.
*/
public enum EnumCashOut {

NO(0, "不持支商户提现"),
YES(1, "支持商户提现")
;

public static EnumCashOut getEnum(Integer code) {
for (EnumCashOut value : values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}

private Integer code;
private String message;

EnumCashOut(Integer code, String message) {
this.code = code;
this.message = message;
}

public Integer getCode() {
return code;
}

public String getMessage() {
return message;
}
}

+ 40
- 0
mallinkService/src/main/java/com/iformall/enums/EnumCashOutStatus.java Vedi File

@@ -0,0 +1,40 @@
package com.iformall.enums;

/**
* Created by Stormeye on 2018/08/09.
*/
public enum EnumCashOutStatus {
//状态 0-提现中,1-提现成功,2-提现失败,3-提现拒绝
DOING(0, "提现中"),
SUCCESS(1, "提现成功"),
FAIL(2, "提现失败"),
REJECT(3, "提现拒绝"),
AUDIOING(4, "审批中"),
WAITING(5, "待到账")
;

public static EnumCashOutStatus getEnum(Integer code) {
for (EnumCashOutStatus value : values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}

private Integer code;
private String message;

EnumCashOutStatus(Integer code, String message) {
this.code = code;
this.message = message;
}

public Integer getCode() {
return code;
}

public String getMessage() {
return message;
}
}

+ 2
- 0
mallinkService/src/main/java/com/iformall/enums/EnumFlowKey.java Vedi File

@@ -34,6 +34,8 @@ public enum EnumFlowKey {
NEW_RENT_POINT_CONTRACT_END(20, "多经点位商铺租金+物业合同终止"),

SETTLE(21,"结算单审批"),
CASH_OUT(23,"商户提现审批")
;

public static EnumFlowKey getEnum(Integer code) {


+ 1
- 0
mallinkService/src/main/java/com/iformall/enums/EnumMsgRecordType.java Vedi File

@@ -19,6 +19,7 @@ public enum EnumMsgRecordType {
//INSIDE_NOTIFY_PAY_SUCCESS(103, "微信支付回调"),
INSIDE_NOTIFY_REFUND_SUCCESS(104, "微信退款回调"),
COUPON_STOCK(105, "券库存更新"),
CASH_OUT(106,"商户提现")
;

public static EnumMsgRecordType getEnum(Integer code) {


+ 18
- 0
mallinkService/src/main/java/com/iformall/mapper/WxCashOutMapper.java Vedi File

@@ -0,0 +1,18 @@
package com.iformall.mapper;

import com.iformall.common.CommonMapper;
import com.iformall.domain.po.WxCashOut;

import java.util.List;

import org.apache.ibatis.annotations.Param;

public interface WxCashOutMapper extends CommonMapper<WxCashOut, Long> {

WxCashOut selectById(@Param("id")Long id,@Param("tenantId")String tenantId);
List<WxCashOut> findList(WxCashOut wxCashOut);

int updateStatus(WxCashOut wxCashOut);

}

+ 6
- 0
mallinkService/src/main/java/com/iformall/mapper/WxMerchantMapper.java Vedi File

@@ -41,4 +41,10 @@ public interface WxMerchantMapper extends CommonMapper<WxMerchant, Long> {
List<WxMerchant> findListVo2(WxMerchant record);

List<WxMerchant> getMerchantList(WxMerchant wxMerchant);
void increaseCash(WxMerchant record);
void reduceCash(WxMerchant record);
void increaseCashCount(WxMerchant record);
}

+ 37
- 0
mallinkService/src/main/java/com/iformall/pay/WxCashOutP.java Vedi File

@@ -0,0 +1,37 @@
package com.iformall.pay;

import lombok.Data;

/**
* Created by Stormeye on 2018/8/10.
*/
@Data
public class WxCashOutP {
private String mch_appid; // 申请商户号的appid或商户号绑定的appid
private String mchid; // 商户号
private String nonce_str; // 随机字符串
private String sign; // 签名
private String partner_trade_no; // 商户订单号,需保持唯一性 (只能是字母或者数字,不能包含有其它字符)
private String openid; // 商户appid下,某用户的openid
private String check_name; // NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名
private String re_user_name; // 收款用户真实姓名。 如果check_name设置为FORCE_CHECK,则必填用户真实姓名 如需电子回单,需要传入收款用户姓名
private Integer amount; // 企业付款金额,单位为分
private String desc; // 企业付款备注,必填

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("WxCashOutP{");
sb.append("mch_appid='").append(mch_appid).append('\'');
sb.append(", mch_id='").append(mchid).append('\'');
sb.append(", nonce_str='").append(nonce_str).append('\'');
sb.append(", sign='").append(sign).append('\'');
sb.append(", partner_trade_no='").append(partner_trade_no).append('\'');
sb.append(", openid='").append(openid).append('\'');
sb.append(", check_name=").append(check_name).append('\'');
sb.append(", re_user_name=").append(re_user_name).append('\'');
sb.append(", amount=").append(amount).append('\'');
sb.append(", desc=").append(desc).append('\'');
sb.append('}');
return sb.toString();
}
}

+ 27
- 0
mallinkService/src/main/java/com/iformall/pay/WxCashOutQueryP.java Vedi File

@@ -0,0 +1,27 @@
package com.iformall.pay;

import lombok.Data;

/**
* Created by Stormeye on 2018/8/10.
*/
@Data
public class WxCashOutQueryP {
private String appid; // 申请商户号的appid或商户号绑定的appid
private String mch_id; // 商户号
private String nonce_str; // 随机字符串
private String sign; // 签名
private String partner_trade_no; // 商户订单号,需保持唯一性 (只能是字母或者数字,不能包含有其它字符)

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("WxCashOutQueryP{");
sb.append("appid='").append(appid).append('\'');
sb.append(", mch_id='").append(mch_id).append('\'');
sb.append(", nonce_str='").append(nonce_str).append('\'');
sb.append(", sign='").append(sign).append('\'');
sb.append(", partner_trade_no='").append(partner_trade_no).append('\'');
sb.append('}');
return sb.toString();
}
}

+ 2
- 2
mallinkService/src/main/java/com/iformall/pay/WxPay.java Vedi File

@@ -212,7 +212,7 @@ public class WxPay {

/**
* 企业付款
*
* https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
* @param params
* 请求参数
* @param certPath
@@ -227,7 +227,7 @@ public class WxPay {

/**
* 查询企业付款
*
* https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3
* @param params
* 请求参数
* @param certPath


+ 51
- 0
mallinkService/src/main/java/com/iformall/service/WxCashOutService.java Vedi File

@@ -0,0 +1,51 @@
package com.iformall.service;

import com.github.pagehelper.PageInfo;
import com.iformall.common.ResultData;
import com.iformall.domain.po.*;
import com.iformall.domain.po.base.TenantEntity;
import com.iformall.enums.EnumPayWay;

public interface WxCashOutService {

/**
* 根据实体查询分页列表
*
* @param record
* @param pageIndex
* @param pageSize
* @return
*/
PageInfo<WxCashOut> listAsPage(WxCashOut record, Integer pageIndex, Integer pageSize);
/**
* 根据Id获得实体
*
* @param id
* @return
*/
WxCashOut getById(Long id,String tenantId);
/**
*更新状态
*
* @param record
*/
void updateStatus(WxCashOut record);
void createCashOut(WxCashOut record);
ResultData applyCashout(WxMerchantBUser buser,WxCashOut record,EnumPayWay payWay);
public void sendCashOutMsg(TenantEntity tenantEntity, Long cashOutId,EnumPayWay payWay);
void rejectCashOut(WxCashOut record);
void cashOutToWx(EnumPayWay payWay,TenantEntity tenantEntity, Long cashOutId);
/**
* 失败的情况下,可以重复发起
*/
ResultData reCashout(WxMerchantBUser buser,WxCashOut record,EnumPayWay payWay);
}

+ 321
- 0
mallinkService/src/main/java/com/iformall/service/impl/WxCashOutServiceImpl.java Vedi File

@@ -0,0 +1,321 @@
package com.iformall.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iformall.common.ErrorCode;
import com.iformall.common.IdWorker;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.*;
import com.iformall.domain.po.base.TenantEntity;
import com.iformall.domain.po.msg.FmInsideCashOutMsg;
import com.iformall.domain.po.msg.FmInsideCouponVerifyMsg;
import com.iformall.enums.EnumCashOut;
import com.iformall.enums.EnumCashOutStatus;
import com.iformall.enums.EnumFlowKey;
import com.iformall.enums.EnumMsgMqKey;
import com.iformall.enums.EnumMsgMqTag;
import com.iformall.enums.EnumMsgMqTopic;
import com.iformall.enums.EnumMsgRecordType;
import com.iformall.enums.EnumPayWay;
import com.iformall.mapper.*;
import com.iformall.mq.MqBaseProducer;
import com.iformall.service.*;
import com.iformall.service.pay.PayServiceFactory;
import com.iformall.service.pay.service.cashout.entity.CashOutAdapterResult;
import com.iformall.utils.RedisLock;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class WxCashOutServiceImpl implements WxCashOutService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
WxCashOutMapper wxCashOutMapper;
@Autowired
WxMerchantMapper wxMerchantMapper;
@Autowired
WxMallMapper wxMallMapper;
@Autowired
RedisLock redisLock;
@Autowired
MqBaseProducer mqBaseProducer;
@Autowired
private WxFlowService wxFlowService;
@Autowired
PayServiceFactory payServiceFactory;
@Autowired
WxAppinfoService wxAppinfoService;
@Autowired
WxPayAccountService wxPayAccountService;

@Override
public PageInfo<WxCashOut> listAsPage(WxCashOut record, Integer pageIndex, Integer pageSize) {
return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCashOutMapper.findList(record));
}

@Override
public WxCashOut getById(Long id,String tenantId) {
return wxCashOutMapper.selectById(id,tenantId);
}

@Override
public void updateStatus(WxCashOut record) {
wxCashOutMapper.updateStatus(record);
}

@Override
public void createCashOut(WxCashOut record) {
final IdWorker idWorker = IdWorker.get();
record.setId(idWorker.nextId());
wxCashOutMapper.insert(record);
}

private boolean hasCashCount(WxMall mall,WxMerchant merchant) {
if (mall.getCashOutLimit().intValue()<=merchant.getCashOutCount().intValue()) {
return false;
}
return true;
}
@Override
@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class})
public ResultData applyCashout(WxMerchantBUser buser, WxCashOut record,EnumPayWay payWay) {
WxMall mall = wxMallMapper.getByTenantId(buser.getTenantId());
if (EnumCashOut.NO.getCode().intValue() == mall.getCashOutSupport().intValue()) {
return new ResultData(Result.ERROR,"当前租户不支持商户提现。");
}
//只有商户管理员才能进行此操作
WxMerchant merchant = wxMerchantMapper.selectById(buser.getMerchantId());
if (!(buser.getPhone().equals(merchant.getLinkPhone()))) {
return new ResultData(Result.ERROR,"当前账号非商户管理员,不能进行此操作。");
}
if(!hasCashCount(mall,merchant)) {
return new ResultData(Result.ERROR,"当日提现次数已达限额。");
}
if (record.getTotalFee().intValue()<=0) {
return new ResultData(Result.ERROR,"提现金额非法。");
}
if (record.getTotalFee().intValue()> merchant.getCashOutNumber().intValue()) {
return new ResultData(Result.ERROR,"提现金额超出商户余额。");
}
if (StringUtils.isBlank(record.getReciveOpenId())) {
return new ResultData(Result.ERROR,"收取人第三方openId不能为空。");
}
//扣掉账户金额
//此处需要加锁,防止并发设置
long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
String timeStr = String.valueOf(time);
boolean cashsetlock = redisLock.lock("merchantLockReduceCashSet_"+merchant.getId(), timeStr);
if (cashsetlock) {
try {
merchant.setCashOutNumber(record.getTotalFee());
//更新金额,并减小次数
wxMerchantMapper.reduceCash(merchant);
redisLock.unlock("merchantLockReduceCashSet_"+merchant.getId(), timeStr);
}catch(Exception e) {
redisLock.unlock("merchantLockReduceCashSet_"+merchant.getId(), timeStr);
logger.error("update cashout fail.",e);
}finally {
redisLock.unlock("merchantLockReduceCashSet_"+merchant.getId(), timeStr);
}
}
//记录提现记录
WxCashOut cashout = new WxCashOut();
final IdWorker idWorker = IdWorker.get();
cashout.setId(idWorker.nextId());
cashout.setTotalFee(record.getTotalFee());
cashout.setStatus(EnumCashOutStatus.DOING.getCode());
cashout.setCreateDate(new Date());
cashout.setBUserId(buser.getId());
cashout.setWxBOpenId(String.valueOf(buser.getBuserId()));
cashout.setMerchantId(merchant.getId());
cashout.setMerchantName(merchant.getName());
cashout.setReciveOpenId(record.getReciveOpenId());
cashout.setReciveNickName(record.getReciveNickName());
cashout.updateTenantInfo(buser);
wxCashOutMapper.insert(cashout);
//TODO有没有审批
boolean hasAudit = hasWorkFlow(buser);
if (hasAudit) {
//提交审批
Map<String, Object> map = new HashMap<String, Object>();
map.put("businessId", String.valueOf(cashout.getId()));
map.put("businessType", EnumFlowKey.CASH_OUT.getCode());
map.put("phone", buser.getPhone());
List<Map> variablesList = new ArrayList<Map>();
Map tenantIdMap = new HashMap<String,Object>();
tenantIdMap.put("key","cashTenantId");
tenantIdMap.put("value",String.valueOf(buser.getTenantId()));
variablesList.add(tenantIdMap);
Map payWayMap = new HashMap<String,Object>();
payWayMap.put("key","cashPayWay");
payWayMap.put("value",String.valueOf(payWay.getCode()));
variablesList.add(payWayMap);
map.put("variables", variablesList);
wxFlowService.start(map, buser.getId(), buser.getName(), buser);
return new ResultData(Result.SUCCESS,"提现提交审批成功");
}else {
//没有审批则发送消息
sendCashOutMsg(merchant, cashout.getId(),payWay);
}
return new ResultData("提现提交成功。");
}
protected boolean hasWorkFlow(TenantEntity tenantEntity) {
WxFlowModel wxFlowModel = new WxFlowModel();
wxFlowModel.setFlowType(EnumFlowKey.CASH_OUT.getCode());
wxFlowModel.updateTenantInfo(tenantEntity);
List<WxFlowModel> flows = wxFlowService.getModelBybusiness(wxFlowModel);
if (null != flows && flows.size() > 0) {
return true;
}
return false;
}
@Override
public void sendCashOutMsg(TenantEntity tenantEntity, Long cashOutId,EnumPayWay payWay) {
FmInsideCashOutMsg verifyMsg = new FmInsideCashOutMsg();
verifyMsg.setMsgType(EnumMsgRecordType.CASH_OUT.getCode());
verifyMsg.updateTenantInfo(tenantEntity);
verifyMsg.setCashOutId(cashOutId);
verifyMsg.setPayWay(payWay);
mqBaseProducer.sendMessage(verifyMsg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());
}

@Override
@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class})
public void rejectCashOut(WxCashOut record) {
//更新状态,并且把钱数退回账户
wxCashOutMapper.updateStatus(record);
WxMerchant merchant = wxMerchantMapper.selectById(record.getMerchantId());
//增加账户金额
//此处需要加锁,防止并发设置
long time = System.currentTimeMillis() + RedisLock.LONG_TIMEOUT;
String timeStr = String.valueOf(time);
boolean cashsetlock = redisLock.lock("merchantLockRejectCashSet_"+merchant.getId(), timeStr);
if (cashsetlock) {
try {
merchant.setCashOutNumber(record.getTotalFee());
wxMerchantMapper.increaseCash(merchant);
redisLock.unlock("merchantLockRejectCashSet_"+merchant.getId(), timeStr);
}catch(Exception e) {
redisLock.unlock("merchantLockRejectCashSet_"+merchant.getId(), timeStr);
logger.error("update cashout fail.",e);
}finally {
redisLock.unlock("merchantLockRejectCashSet_"+merchant.getId(), timeStr);
}
}
}

@Override
public void cashOutToWx(EnumPayWay payWay,TenantEntity tenantEntity, Long cashOutId) {
WxCashOut cashout = this.getById(cashOutId, tenantEntity.getTenantId());
if (null == cashout ) {
return;
}
WxAppinfo appInfo = wxAppinfoService.getCAppInfo(tenantEntity, payWay);
if (null == appInfo) {
return;
}
WxPayAccount payAccount = wxPayAccountService.getByTenantId(tenantEntity.getTenantId());
if (null == payAccount) {
return;
}
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);
}

@Override
public ResultData reCashout(WxMerchantBUser buser, WxCashOut record, EnumPayWay payWay) {
//不能重复提交操作
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();
}
}

+ 38
- 8
mallinkService/src/main/java/com/iformall/service/impl/WxCouponOrderServiceImpl.java Vedi File

@@ -29,6 +29,8 @@ import com.iformall.service.pay.PayServiceFactory;
import com.iformall.utils.Constant;
import com.iformall.utils.DateUtils;
import com.iformall.utils.PayUtils;
import com.iformall.utils.RedisLock;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -144,6 +146,9 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService {
@Autowired
@Qualifier("couponDetailRedisTemplate")
RedisTemplate<String, WxCouponCVo> cdRedisTemplate;
@Autowired
RedisLock redisLock;

private final SimpleDateFormat mydateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

@@ -524,18 +529,42 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService {
try {
// 核销记账
if (couponOrder.getCouponPrice() > 0) {
recordAfterVerified(couponOrder, bUser.getMerchantId());
WxMerchantSubsidy subsidy = recordAfterVerified(couponOrder, bUser.getMerchantId());
//是否开通了商户提现,开通了商户提现往商户账户里面加金额
WxMall mall = wxMallMapper.getByTenantId(couponOrder.getTenantId());
if (null != mall && mall.getCashOutSupport().intValue() == EnumCashOut.YES.getCode().intValue()) {
WxMerchant merchant = wxMerchantMapper.selectById(bUser.getMerchantId());
if (null != merchant) {
//此处需要加锁,防止并发设置
long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
String timeStr = String.valueOf(time);
boolean cashsetlock = redisLock.lock("merchantLockCashSet_"+merchant.getId(), timeStr);
if (cashsetlock) {
try {
merchant.setCashOutNumber(couponOrder.getCouponPrice());
wxMerchantMapper.increaseCash(merchant);
logger.info("wxcoupon update cashout success.wxCouponOrderId:["+couponOrder.getId()+"] subsidyId:["+subsidy.getId()+"].");
redisLock.unlock("merchantLockCashSet_"+merchant.getId(), timeStr);
}catch(Exception e) {
redisLock.unlock("merchantLockCashSet_"+merchant.getId(), timeStr);
logger.error("update cashout fail.wxCouponOrderId:["+couponOrder.getId()+"] subsidyId:["+subsidy.getId()+"].",e);
}finally {
redisLock.unlock("merchantLockCashSet_"+merchant.getId(), timeStr);
}
}
}
}
}
} catch (Exception e) {
logger.info("核销记账失败");
logger.error(e.getMessage());
logger.error("核销记账失败"+e.getMessage(),e);
}
} else {
try {
// 核销分账
shareAfterVerify(couponOrder, bUser.getMerchantId(),couponOrder.getPayVendor());
} catch (Exception e) {
logger.error(e.getMessage());
logger.error("核销记账失败"+e.getMessage(),e);
}
}

@@ -543,7 +572,7 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService {
// 核销补贴
subsidyAfterVerify(couponOrder, bUser.getMerchantId());
} catch (Exception e) {
logger.error(e.getMessage());
logger.error("核销记账失败"+e.getMessage(),e);
}

boolean bSentCoupon = false;
@@ -552,18 +581,18 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService {
try {
bSentCoupon = sendCouponAfterVerify(couponOrder, bUser);
} catch (Exception e) {
logger.error(e.getMessage());
logger.error("核销记账失败"+e.getMessage(),e);
}

// 核销发模板消息
try {
sendVerifyMsg(couponOrder, bUser, bSentCoupon);
} catch (Exception e) {
logger.error("核销发送消息发生错误:" + e.getMessage());
logger.error("核销发送消息发生错误:" + e.getMessage(),e);
}
}

public void recordAfterVerified(WxCouponOrder couponOrder, Long merchantId) {
public WxMerchantSubsidy recordAfterVerified(WxCouponOrder couponOrder, Long merchantId) {
WxCoupon wxCoupon = wxCouponMapper.selectById(couponOrder.getCouponId(),couponOrder.getTenantId());
WxMerchantSubsidy merchantSubsidy = new WxMerchantSubsidy();
if (couponOrder.getCouponType().equals(EnumCouponType.COUPON_PRESS.getCode())
@@ -597,6 +626,7 @@ public class WxCouponOrderServiceImpl implements WxCouponOrderService {
merchantSubsidy.setUpdateDate(curDate);
merchantSubsidy.setStatus(EnumMerchantSubsidyStatus.NOT_SUBSIDY.getCode());
wxMerchantSubsidyMapper.insert(merchantSubsidy);
return merchantSubsidy;
}

@Override


+ 30
- 0
mallinkService/src/main/java/com/iformall/service/impl/WxFlowServiceImpl.java Vedi File

@@ -99,6 +99,8 @@ public class WxFlowServiceImpl implements WxFlowService {
@Autowired
@Qualifier("couponChannelRedisTemplate")
RedisTemplate<String, PageInfo<WxCouponChannelVo>> cdRedisTemplate;
@Autowired
private WxCashOutService wxCashOutService;

@Override
public void wxFlowConfigInit(String tenantId) {
@@ -434,6 +436,34 @@ public class WxFlowServiceImpl implements WxFlowService {
wxBillSettleService.updateFreezeOrStatus(settle.getPayBillIds(),EnumFreezeType.DEF.getCode(),null);
}
wxBillSettleMapper.updateById(wxBillSettle);
}else if (EnumFlowKey.CASH_OUT.getCode().equals(flowType)) {
String tenantId = (String)getVariableByKey(variables,"cashTenantId");
WxCashOut cashout = wxCashOutService.getById(Long.parseLong(businessId), tenantId);
//如果是提交审批
if (EnumRentContractAppStatus.APPLYING.getCode().intValue() == applyStatus.intValue()) {
cashout.setStatus(EnumCashOutStatus.AUDIOING.getCode());
cashout.setUpdateDate(new Date());
wxCashOutService.updateStatus(cashout);
// 审批完成
}else if (EnumRentContractAppStatus.FINISH.getCode().intValue() == applyStatus.intValue()) {
cashout.setStatus(EnumCashOutStatus.WAITING.getCode());
cashout.setUpdateDate(new Date());
wxCashOutService.updateStatus(cashout);
//发送零钱提现通知
String cashPayWay = (String)getVariableByKey(variables,"cashPayWay");
wxCashOutService.sendCashOutMsg(cashout, cashout.getId(),EnumPayWay.getEnum(Integer.parseInt(cashPayWay)));
logger.info("cashout msg:"+cashout.getId());
//如果是审批撤回,或者驳回,改回草稿状态
}else if (EnumRentContractAppStatus.SETBACK.getCode().intValue() == applyStatus.intValue()
|| EnumRentContractAppStatus.REJECT.getCode().intValue() == applyStatus.intValue()) {
cashout.setStatus(EnumCashOutStatus.REJECT.getCode());
String remark = (String)mapInfo.get("remark");
cashout.setAudioRemark(remark);
cashout.setAudioDate(new Date());
cashout.setUpdateDate(new Date());
wxCashOutService.rejectCashOut(cashout);
}
}
}



+ 29
- 0
mallinkService/src/main/java/com/iformall/service/msg/impl/FmInsideCashOutMsgServiceImpl.java Vedi File

@@ -0,0 +1,29 @@
package com.iformall.service.msg.impl;

import com.iformall.domain.po.base.TenantEntity;
import com.iformall.domain.po.msg.BaseMsg;
import com.iformall.domain.po.msg.FmInsideCashOutMsg;
import com.iformall.service.WxCashOutService;
import com.iformall.service.msg.MsgSendService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class FmInsideCashOutMsgServiceImpl implements MsgSendService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
private WxCashOutService wxCashOutService;

@Override
public void send(BaseMsg baseMsg) throws Exception {
FmInsideCashOutMsg msg = (FmInsideCashOutMsg)baseMsg;
TenantEntity tenantEntity = new TenantEntity();
tenantEntity.setTenantId(msg.getTenantId());
tenantEntity.setParentTenantId(msg.getParentTenantId());
wxCashOutService.cashOutToWx(msg.getPayWay(),tenantEntity, msg.getCashOutId());
}
}

+ 1
- 1
mallinkService/src/main/java/com/iformall/service/park/impl/cyf/CYFParkService.java Vedi File

@@ -134,7 +134,7 @@ public class CYFParkService extends BaseParkService implements ParkAdapterServic
Integer endTime = retObj.getInteger("endTime");//离场时间
String msg = retObj.getString("warmPrompt");
String appId = "";
String payPath = "";
String payPath = "http://wechat.cheyifu2016.com/fm-pay/#/transit?encodeURIComponent('orderNo=123&couponFee=2&actualFee=20')";
return new ResultData(new ParkStopFee(retObj.getString("orderId"), cyf.utcToLocal(String.valueOf(createTime)),
cyf.utcToLocal(String.valueOf(endTime)), String.valueOf(retObj.getDouble("fee")),appId,payPath,null,msg));
}else {


+ 24
- 1
mallinkService/src/main/java/com/iformall/service/pay/PayServiceFactory.java Vedi File

@@ -8,6 +8,8 @@ import org.springframework.stereotype.Service;
import com.iformall.common.ErrorCode;
import com.iformall.enums.EnumPayWay;
import com.iformall.exception.MallinkException;
import com.iformall.service.pay.service.cashout.CashOutAdapterService;
import com.iformall.service.pay.service.cashout.wx.WxCashOutAdapterService;
import com.iformall.service.pay.service.pay.CDrivingPayService;
import com.iformall.service.pay.service.pay.CPassivePayService;
import com.iformall.service.pay.service.pay.PayAdapterService;
@@ -29,6 +31,7 @@ public class PayServiceFactory {
private Map<Integer,PayAdapterService> serviceMap = null;
private Map<Integer,PayShareAdapterService> shareMap = null;
private Map<Integer,RefundPayAdapterService> refundMap = null;
private Map<Integer,CashOutAdapterService> cashoutMap = null;
@Autowired
WxMiniAppPayAdapterService wxMiniAppPayService;
@@ -45,6 +48,9 @@ public class PayServiceFactory {
@Autowired
WxRefundAdapterService wxRefundService;
@Autowired
WxCashOutAdapterService WxCashOutService;

private Map<Integer,PayAdapterService> getServiceMap() {
@@ -83,7 +89,16 @@ public class PayServiceFactory {
refundMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode(), wxRefundService);
}
return refundMap;
}
}
private Map<Integer,CashOutAdapterService> getCashOutMap() {
if (null == cashoutMap ) {
cashoutMap = new ConcurrentHashMap<Integer, CashOutAdapterService>();
cashoutMap.put(EnumPayWay.PAY_WAY_WECHAT.getCode(), WxCashOutService);
cashoutMap.put(EnumPayWay.PAY_WAY_WECHAT_MA.getCode(), WxCashOutService);
}
return cashoutMap;
}
public PayAdapterService getPayAdapterService(Integer type) throws MallinkException{
PayAdapterService service = getServiceMap().get(type);
@@ -132,4 +147,12 @@ public class PayServiceFactory {
}
return refundService;
}
public CashOutAdapterService getCashOutAdapterService(Integer type)throws MallinkException {
CashOutAdapterService cashOutService = getCashOutMap().get(type);
if (null == cashOutService) {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+type+"] 零钱service未找到");
}
return cashOutService;
}
}

+ 48
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/cashout/CashOutAdapterService.java Vedi File

@@ -0,0 +1,48 @@
package com.iformall.service.pay.service.cashout;

import java.util.Map;

import com.alibaba.fastjson.JSONArray;
import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.po.WxCashOut;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxProfitSharingOrder;
import com.iformall.domain.po.WxProfitSharingReceiver;
import com.iformall.enums.EnumPayWay;
import com.iformall.enums.EnumProfitSharingOrderType;
import com.iformall.enums.EnumProfitSharingReceiverType;
import com.iformall.exception.MallinkException;
import com.iformall.service.pay.service.share.entity.ShareAccountResult;
import com.iformall.service.pay.service.cashout.entity.CashOutAdapterResult;
import com.iformall.service.pay.service.share.entity.PayShareQueryResult;
import com.iformall.service.pay.service.share.entity.PayShareResult;
import com.iformall.service.pay.service.share.entity.ShareNotifyAdapterResult;

/**
* 零钱接口
* @author alascor
*/
public interface CashOutAdapterService {

/**
* 付款到零钱
* @param appInfo
* @param payAccount
* @param record
* @param transcationId
* @param amount 分账金额
* @return
*/
public CashOutAdapterResult cashOut(WxAppinfo appInfo,WxPayAccount payAccount,WxCashOut cashOut);
/**
* 付款到零钱
* @param appInfo
* @param payAccount
* @param record
* @param transcationId
* @param amount 分账金额
* @return
*/
public CashOutAdapterResult queryCashOut(WxAppinfo appInfo,WxPayAccount payAccount,WxCashOut cashOut);
}

+ 51
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/cashout/entity/CashOutAdapterResult.java Vedi File

@@ -0,0 +1,51 @@
package com.iformall.service.pay.service.cashout.entity;

import java.io.Serializable;

public class CashOutAdapterResult implements Serializable{
private static final long serialVersionUID = -6647306162758854293L;
private boolean isSuccess;
private Integer code;
private String msg;
private Object data;
public CashOutAdapterResult() {
}
public CashOutAdapterResult(boolean isSuccess,Integer code,String msg,Object data) {
this.isSuccess = isSuccess;
this.code = code;
this.msg = msg;
this.data = data;
}
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}

public Integer getCode() {
return code;
}

public void setCode(Integer code) {
this.code = code;
}

}

+ 314
- 0
mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java Vedi File

@@ -0,0 +1,314 @@
package com.iformall.service.pay.service.cashout.wx;

import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.po.WxCashOut;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.domain.po.WxRefundOrder;
import com.iformall.enums.EnumCashOutStatus;
import com.iformall.enums.EnumPayMode;
import com.iformall.enums.EnumPayType;
import com.iformall.enums.EnumPayWay;
import com.iformall.enums.EnumRefundStatus;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.WxAppinfoMapper;
import com.iformall.mapper.WxPayAccountMapper;
import com.iformall.mapper.WxPayOrderMapper;
import com.iformall.mapper.WxRefundOrderMapper;
import com.iformall.pay.WxCashOutP;
import com.iformall.pay.WxCashOutQueryP;
import com.iformall.pay.WxPay;
import com.iformall.pay.WxPayment;
import com.iformall.pay.WxRefundOrderP;
import com.iformall.pay.WxRefundOrderSP;
import com.iformall.service.pay.service.cashout.CashOutAdapterService;
import com.iformall.service.pay.service.cashout.entity.CashOutAdapterResult;
import com.iformall.service.pay.service.refund.RefundPayAdapterService;
import com.iformall.service.pay.service.refund.entity.RefundAdapterResult;
import com.iformall.service.pay.service.refund.entity.RefundNotifyAdapterResult;
import com.iformall.utils.BeanUtils;
import com.iformall.utils.CipherUtil;
import com.iformall.utils.Utility;
import com.iformall.utils.XmlUtil;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class WxCashOutAdapterService implements CashOutAdapterService{

JSONObject errorRefundReqMap = JSON.parseObject("{\n" +
" \"NO_AUTH\": {\n" +
" \"detail\": \"没有该接口权限\",\n" +
" \"reason\": \"1. 用户账号被冻结,无法付款;2. 产品权限没有开通或者被风控冻结;3. 此IP地址不允许调用接口,如有需要请登录微信支付商户平台更改配置\",\n" +
" \"resolution\": \"请根据具体的错误返回描述做对应处理,如返回描述不够明确,请参考此处的错误原因做排查。\"\n" +
" },\n" +
" \"AMOUNT_LIMIT\": {\n" +
" \"detail\": \"金额超限\",\n" +
" \"reason\": \"1. 被微信风控拦截,最低单笔付款限额调整为5元。2. 低于最低单笔付款限额或者高于最高单笔付款限额\",\n" +
" \"resolution\": \"目前最低付款金额为1元,最高10万元,请确认是否付款金额超限。\"\n" +
" },\n" +
" \"PARAM_ERROR\": {\n" +
" \"detail\": \"参数错误\",\n" +
" \"reason\": \"1. 请求参数校验错误 2. 字符中包含非utf8字符 3. 商户号和appid没有绑定关系\\t\",\n" +
" \"resolution\": \"请参照原因检查您的请求参数是否正确\"\n" +
" },\n" +
" \"OPENID_ERROR\": {\n" +
" \"detail\": \"Openid错误\",\n" +
" \"reason\": \"Openid格式错误或者不属于商家公众账号\",\n" +
" \"resolution\": \"Openid与appid是有一一映射关系的,请确保正确使用。\"\n" +
" },\n" +
" \"SEND_FAILED\": {\n" +
" \"detail\": \"付款错误\",\n" +
" \"reason\": \"付款错误,请查单确认付款结果\",\n" +
" \"resolution\": \"请查单确认付款结果,以查单结果为准。\"\n" +
" },\n" +
" \"NOTENOUGH\": {\n" +
" \"detail\": \"余额不足\",\n" +
" \"reason\": \"您的付款帐号余额不足或资金未到账\\t\",\n" +
" \"resolution\": \"如果要继续付款必须使用原商户订单号重试\"\n" +
" },\n" +
" \"SYSTEMERROR\": {\n" +
" \"detail\": \"系统繁忙,请稍后再试\",\n" +
" \"reason\": \"微信内部接口调用发生错误\",\n" +
" \"resolution\": \"请先调用查询接口,查看此次付款结果,如结果为不明确状态(如订单号不存在),请务必使用原商户订单号进行重试。\"\n" +
" },\n" +
" \"NAME_MISMATCH\": {\n" +
" \"detail\": \"姓名校验出错\",\n" +
" \"reason\": \"收款人身份校验不通过\",\n" +
" \"resolution\": \"如果要继续付款必须使用原商户订单号重试\"\n" +
" },\n" +
" \"SIGN_ERROR\": {\n" +
" \"detail\": \"签名错误\",\n" +
" \"reason\": \"校验签名错误\",\n" +
" \"resolution\": \"请检查您的请求参数和签名密钥KEY是否正确,如果要继续付款必须使用原商户订单号重试\"\n" +
" },\n" +
" \"XML_ERROR\": {\n" +
" \"detail\": \"Post内容出错\",\n" +
" \"reason\": \"Post请求数据不是合法的xml格式内容\",\n" +
" \"resolution\": \"格式问题,请检查请求格式是否正确。\"\n" +
" },\n" +
" \"FATAL_ERROR\": {\n" +
" \"detail\": \"两次请求参数不一致\",\n" +
" \"reason\": \"两次请求商户单号一样,但是参数不一致\",\n" +
" \"resolution\": \"重入必须保证所有参数值都不变\"\n" +
" },\n" +
" \"FREQ_LIMIT\": {\n" +
" \"detail\": \"超过频率限制,请稍后再试\",\n" +
" \"reason\": \"接口请求频率超时接口限制\",\n" +
" \"resolution\": \"调用接口过于频繁,请稍后再试,如果要继续付款必须使用原商户订单号重试\"\n" +
" },\n" +
" \"MONEY_LIMIT\": {\n" +
" \"detail\": \"已经达到今日付款总额上限/已达到付款给此用户额度上限\",\n" +
" \"reason\": \"请关注接口的付款限额条件\",\n" +
" \"resolution\": \"付款额度已经超限,请参考接口使用条件,如果要继续付款必须使用原商户订单号重试\"\n" +
" },\n" +
" \"CA_ERROR\": {\n" +
" \"detail\": \"商户API证书校验出错\",\n" +
" \"reason\": \"请求没带商户API证书或者带上了错误的商户API证书\",\n" +
" \"resolution\": \"您使用的调用证书有误,请确认是否使用了正确的证书,可以前往商户平台重新下载,证书需与商户号对应,如果要继续付款必须使用原商户订单号重试\"\n" +
" },\n" +
" \"V2_ACCOUNT_SIMPLE_BAN\": {\n" +
" \"detail\": \"无法给未实名用户付款\",\n" +
" \"reason\": \"用户微信支付账户未实名,无法付款\",\n" +
" \"resolution\": \"不支持给未实名用户付款,如果要继续付款必须使用原商户订单号重试\"\n" +
" },\n" +
" \"PARAM_IS_NOT_UTF8\": {\n" +
" \"detail\": \"请求参数中包含非utf8编码字符\",\n" +
" \"reason\": \"接口规范要求所有请求参数都必须为utf8编码\",\n" +
" \"resolution\": \"微信接口使用编码是UTF-8,请确认,如果要继续付款必须使用原商户订单号重试\"\n" +
" },\n" +
" \"SENDNUM_LIMIT\": {\n" +
" \"detail\": \"该用户今日付款次数超过限制,如有需要请进入【微信支付商户平台-产品中心-企业付款到零钱-产品设置】进行修改\",\n" +
" \"reason\": \"该用户今日付款次数超过限制,如有需要请进入【微信支付商户平台-产品中心-企业付款到零钱-产品设置】进行修改\",\n" +
" \"resolution\": \"向用户付款的次数超限了,请参考接口使用条件,如果要继续付款必须使用原商户订单号重试\"\n" +
" },\n" +
" \"RECV_ACCOUNT_NOT_ALLOWED\": {\n" +
" \"detail\": \"收款账户不在收款账户列表\",\n" +
" \"reason\": \"收款账户不在收款账户列表\",\n" +
" \"resolution\": \"请登陆商户平台,查看产品中心企业付款到零钱的产品配置\"\n" +
" },\n" +
" \"PAY_CHANNEL_NOT_ALLOWED\": {\n" +
" \"detail\": \"本商户号未配置API发起能力\",\n" +
" \"reason\": \"本商户号未配置API发起能力\",\n" +
" \"resolution\": \"请登陆商户平台,查看产品中心企业付款到零钱的产品配置\"\n" +
" }\n" +
"}");
JSONObject errorQueryReqMap = JSON.parseObject("{\n" +
" \"CA_ERROR\": {\n" +
" \"detail\": \"请求未携带证书,或请求携带的证书出错\",\n" +
" \"reason\": \"请求未携带证书,或请求携带的证书出错\",\n" +
" \"resolution\": \"到商户平台下载证书,请求带上证书后重试。\"\n" +
" },\n" +
" \"SIGN_ERROR\": {\n" +
" \"detail\": \"商户签名错误\",\n" +
" \"reason\": \"商户签名错误\",\n" +
" \"resolution\": \"按文档要求重新生成签名后再重试。\"\n" +
" },\n" +
" \"FREQ_LIMIT\": {\n" +
" \"detail\": \"受频率限制\",\n" +
" \"reason\": \"受频率限制\\t\",\n" +
" \"resolution\": \"请对请求做频率控制\"\n" +
" },\n" +
" \"XML_ERROR\": {\n" +
" \"detail\": \"请求的xml格式错误,或者post的数据为空\",\n" +
" \"reason\": \"请求的xml格式错误,或者post的数据为空\",\n" +
" \"resolution\": \"检查请求串,确认无误后重试。\"\n" +
" },\n" +
" \"PARAM_ERROR\": {\n" +
" \"detail\": \"参数错误\",\n" +
" \"reason\": \"参数错误\",\n" +
" \"resolution\": \"请查看err_code_des,修改设置错误的参数。\"\n" +
" },\n" +
" \"SYSTEMERROR\": {\n" +
" \"detail\": \"系统繁忙,请再试\",\n" +
" \"reason\": \"系统繁忙,请再试\\t\",\n" +
" \"resolution\": \"系统繁忙\"\n" +
" },\n" +
" \"NOT_FOUND\": {\n" +
" \"detail\": \"1、指定单号数据不存在 2、指定单号数据不存在,单据查询超过有效期\",\n" +
" \"reason\": \"1、指定单号数据不存在 2、指定单号数据不存在,单据查询超过有效期\",\n" +
" \"resolution\": \"1、查询单号对应的数据不存在,请使用正确的商户订单号查询2、如需查询超过有效期的单据,请登录到商户平台进行查询。\"\n" +
" }\n" +
"}");
@Override
public CashOutAdapterResult cashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) {
WxCashOutP wxCashOutP = generateWxCashOutP(payAccount, appInfo, cashOut);
Map signMap = null;
try {
signMap = BeanUtils.toStringMap(wxCashOutP);
} catch (Exception e) {
log.error("零钱支付命令生辰: " + e.getMessage(),e);
throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "零钱支付签名异常");
}

String signAgent = WxPayment.createSign(signMap, payAccount.getApiKey());
signMap.put("sign", signAgent);
String response = null;
try {
response = WxPay.transfers(signMap, payAccount.getCertPath(), payAccount.getMchId());
} catch (Exception e) {
log.error("零钱支付异常: " + e.getMessage(),e);
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "零钱支付异常");
}
log.info("微信零钱支付:" + wxCashOutP.toString() + ", response: " + response.toString());
return getReusltFromp(response,cashOut);
// if (payAccount.getType() == EnumPayMode.MCH.getCode()) {
// 普通商户模式
// }
}
private WxCashOutP generateWxCashOutP(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) {
String noncestr = Utility.generate32UUID();
WxCashOutP wxCashOutP = new WxCashOutP();
wxCashOutP.setMch_appid(appInfo.getAppId());
wxCashOutP.setMchid(payAccount.getSubMchId());
wxCashOutP.setNonce_str(noncestr);
wxCashOutP.setAmount(cashOut.getTotalFee());
wxCashOutP.setCheck_name("NO_CHECK");
wxCashOutP.setDesc("客户结算");
wxCashOutP.setOpenid(cashOut.getReciveOpenId());
wxCashOutP.setPartner_trade_no(String.valueOf(cashOut.getId()));
return wxCashOutP;
}
private CashOutAdapterResult getReusltFromp(String response,WxCashOut cashOut) throws MallinkException{
Map<String, String> returnMap = WxPayment.xmlToMap(response);
String result_no = returnMap.get("result_code");
if ("SUCCESS".equals(result_no)) {
log.info("微信零钱支付申请成功: " + returnMap.toString());
String wxPayNo = returnMap.get("payment_no");
String payTime = returnMap.get("payment_time");
cashOut.setWxPayNo(wxPayNo);
cashOut.setWxPayTime(payTime);
return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"微信零钱支付申请成功",returnMap);
} else {
log.error("微信零钱支付申请失败: " + response);
String errMsg = "";
JSONObject errObj = errorRefundReqMap.getJSONObject(result_no);
if (errObj != null) {
errMsg = errObj.toJSONString();
} else {
errMsg = returnMap.get("err_code_des");
}
return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), errMsg, returnMap);
}
}

@Override
public CashOutAdapterResult queryCashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) {
WxCashOutQueryP wxCashOutP = generateQueryWxCashOutP(payAccount, appInfo, cashOut);
Map signMap = null;
try {
signMap = BeanUtils.toStringMap(wxCashOutP);
} catch (Exception e) {
log.error("零钱支付命令生辰: " + e.getMessage(),e);
throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "零钱支付签名异常");
}

String signAgent = WxPayment.createSign(signMap, payAccount.getApiKey());
signMap.put("sign", signAgent);
String response = null;
try {
response = WxPay.getTransferInfo(signMap, payAccount.getCertPath(), payAccount.getMchId());
} catch (Exception e) {
log.error("零钱支付异常: " + e.getMessage(),e);
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "零钱支付异常");
}
log.info("微信零钱支付:" + wxCashOutP.toString() + ", response: " + response.toString());
return getReusltFromQueryp(response);
}
private WxCashOutQueryP generateQueryWxCashOutP(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) {
String noncestr = Utility.generate32UUID();
WxCashOutQueryP wxCashOutQueryP = new WxCashOutQueryP();
wxCashOutQueryP.setAppid(appInfo.getAppId());
wxCashOutQueryP.setMch_id(payAccount.getSubMchId());
wxCashOutQueryP.setNonce_str(noncestr);
wxCashOutQueryP.setPartner_trade_no(String.valueOf(cashOut.getId()));
return wxCashOutQueryP;
}
private CashOutAdapterResult getReusltFromQueryp(String response) throws MallinkException{
Map<String, String> returnMap = WxPayment.xmlToMap(response);
String result_no = returnMap.get("result_code");
if ("SUCCESS".equals(result_no)) {
String realStatus = returnMap.get("status");
if ("SUCCESS".equals(realStatus)) {
return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"微信零钱支付申请成功",returnMap);
}else {
String msg = returnMap.get("reason");
return new CashOutAdapterResult(false,EnumCashOutStatus.SUCCESS.getCode(),msg,returnMap);
}
} else {
log.error("微信零钱支付查询失败: " + response);
String errMsg = "";
JSONObject errObj = errorQueryReqMap.getJSONObject(result_no);
if (errObj != null) {
errMsg = errObj.toJSONString();
} else {
errMsg = returnMap.get("err_code_des");
}
return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), errMsg, returnMap);
}
}
}

+ 79
- 0
mallinkService/src/main/resources/mapper/WxCashOutMapper.xml Vedi File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.iformall.mapper.WxCashOutMapper">
<resultMap id="BaseResultMap" type="com.iformall.domain.po.WxCashOut">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="tenant_id" jdbcType="VARCHAR" property="tenantId" />
<result column="parent_tenant_id" jdbcType="VARCHAR" property="parentTenantId" />
<result column="total_fee" jdbcType="INTEGER" property="totalFee" />
<result column="status" jdbcType="INTEGER" property="status" />
<result column="audio_remark" jdbcType="VARCHAR" property="audioRemark" />
<result column="create_date" jdbcType="TIMESTAMP" property="createDate" />
<result column="update_date" jdbcType="TIMESTAMP" property="updateDate" />
<result column="b_user_id" jdbcType="BIGINT" property="updateDate" />
<result column="wx_b_open_id" jdbcType="VARCHAR" property="updateDate" />
<result column="audio_date" jdbcType="TIMESTAMP" property="updateDate" />
<result column="merchant_id" jdbcType="VARCHAR" property="merchantId" />
<result column="merchant_name" jdbcType="VARCHAR" property="merchantName" />
<result column="recive_open_id" jdbcType="VARCHAR" property="reciveOpenId" />
<result column="recive_nick_name" jdbcType="VARCHAR" property="reciveNickName" />
<result column="wx_pay_no" jdbcType="VARCHAR" property="wxPayNo" />
<result column="wx_pay_time" jdbcType="VARCHAR" property="wxPayTime" />
<result column="fail_remark" jdbcType="VARCHAR" property="failRemark" />
</resultMap>

<sql id="allColumns">
`id`,`tenant_id`,`parent_tenant_id`,`total_fee`,`status`,`audio_remark`,`create_date`,`update_date`,`b_user_id`,`wx_b_open_id`,`audio_date`,
`merchant_id`,`merchant_name`,`recive_open_id`,`reciveNickName`,`wx_pay_no`,`wx_pay_time`,`fail_remark`
</sql>

<sql id="dynamicWhereConditions">
where 1 = 1

<if test=" null != id ">
and `id` = #{id}
</if>

<if test=" null != tenantId and '' != tenantId">
and `tenant_id` = #{tenantId}
</if>
<if test=" null != parentTenantId and '' != parentTenantId">
and `parent_tenant_id` = #{parentTenantId}
</if>

<if test=" null != status ">
and `status` = #{status}
</if>

<if test=" null != ids ">
and id in
<foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")">
#{idItem}
</foreach>
</if>
<if test=" null != sortColumns"> order by ${sortColumns} </if>
</sql>

<select id="selectById" parameterType="java.util.HashMap" resultMap="BaseResultMap">
select <include refid="allColumns" /> from wx_cash_out where id = #{id} and tenant_id=#{tenantId}
</select>

<select id="findList" parameterType="com.iformall.domain.po.WxCashOut" resultMap="BaseResultMap">
select <include refid="allColumns" /> from wx_cash_out
<include refid="dynamicWhereConditions" />
</select>

<update id="updateStatus" parameterType="com.iformall.domain.po.WxCashOut">
update wx_cash_out
set `status` = #{status},
`update_date` = #{updateDate}
where id=#{id}
<if test=" null != tenantId and '' != tenantId">
and `tenant_id` = #{tenantId}
</if>
<if test=" null != parentTenantId and '' != parentTenantId">
and `parent_tenant_id` = #{parentTenantId}
</if>
</update>

</mapper>

+ 1
- 1
mallinkService/src/main/resources/mapper/WxCouponOrderMapper.xml Vedi File

@@ -3,7 +3,7 @@
<mapper namespace="com.iformall.mapper.WxCouponOrderMapper">
<resultMap id="BaseResultMap" type="com.iformall.domain.po.WxCouponOrder">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="tenant_id" jdbcType="BIGINT" property="tenantId" />
<result column="tenant_id" jdbcType="VARCHAR" property="tenantId" />
<result column="parent_tenant_id" jdbcType="VARCHAR" property="parentTenantId" />
<result column="coupon_id" jdbcType="BIGINT" property="couponId" />
<result column="coupon_type" jdbcType="INTEGER" property="couponType" />


+ 3
- 2
mallinkService/src/main/resources/mapper/WxMallMapper.xml Vedi File

@@ -36,7 +36,8 @@
<result column="latitude" jdbcType="DECIMAL" property="latitude"/>
<result column="longitude" jdbcType="DECIMAL" property="longitude"/>
<result column="live_support" jdbcType="INTEGER" property="liveSupport"/>

<result column="cash_out_support" jdbcType="INTEGER" property="cashOutSupport"/>
<result column="cash_out_limit" jdbcType="INTEGER" property="cashOutLimit"/>
</resultMap>

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

<sql id="dynamicWhereConditions">


+ 15
- 3
mallinkService/src/main/resources/mapper/WxMerchantMapper.xml Vedi File

@@ -35,19 +35,20 @@
<result column="rental_start_date" property="rentalStartDate"/>
<result column="rental_end_date" property="rentalEndDate"/>
<result column="credit_locked" property="creditLocked"/>

<result column="cash_out_number" jdbcType="INTEGER" property="cashOutNumber"/>
<result column="cash_out_count" jdbcType="INTEGER" property="cashOutCount"/>
</resultMap>
<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`,
`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
`introduction`,`action_desc`,`is_del`,`talk_user_main`,`talk_user_aux`,link_line_phone,credit_locked,cash_out_number,cash_out_count
</sql>
<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.`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
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 id="dynamicWhereConditions">
@@ -610,5 +611,16 @@
order by create_date desc
</select>

<update id="updateCash" parameterType="com.iformall.domain.po.WxMerchant">
update wx_merchant set cash_out_number = cash_out_number+#{cashOutNumber} where id = #{id}
</update>
<update id="reduceCash" parameterType="com.iformall.domain.po.WxMerchant">
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>

</mapper>

Caricamento…
Annulla
Salva