企业商户交易流水记录功能v1

wxpay
LI-CCONG\李聪聪 7 months ago
parent 2853583521
commit 25a68e6347

@ -1,12 +1,15 @@
package cc.yunxi.domain.po;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
@ -18,77 +21,53 @@ import lombok.Setter;
* @author ccongli
* @since 2024-03-10 09:04:53
*/
@Getter
@Setter
@TableName("nx_enterprise")
@Data
@TableName("base_organize")
@ApiModel(value = "Enterprise对象", description = "企业(商户)信息")
public class Enterprise {
@ApiModelProperty("自然主键")
@TableId("id")
@TableId(value = "f_id", type = IdType.ASSIGN_ID)
private String id;
@ApiModelProperty("商户代码")
@TableField("enterprise_code")
@TableField("f_en_code")
private String enterpriseCode;
@ApiModelProperty("商户名称")
@TableField("enterprise_name")
@TableField("f_full_name")
private String enterpriseName;
@ApiModelProperty("商户简称")
@TableField("enterprise_short_name")
private String enterpriseShortName;
@ApiModelProperty("描述")
@TableField("f_description")
private String description;
@ApiModelProperty("有效标志(0-禁用1-启用)")
@TableField("f_enabled_mark")
private Integer status;
@ApiModelProperty("商户余额")
@TableField("fund")
private BigDecimal fund;
@ApiModelProperty("商户logo")
@TableField("enterprise_logo")
@TableField("pictures")
private String enterpriseLogo;
@ApiModelProperty("主体类型id国有企业私有企业集体")
@TableField("principal_type_id")
private String principalTypeId;
@ApiModelProperty("商户状态")
@TableField("enterprise_status")
private Integer enterpriseStatus;
@ApiModelProperty("合约状态")
@TableField("contract_status")
private Integer contractStatus;
@ApiModelProperty("所在城市")
@TableField("city")
private String city;
@ApiModelProperty("传真")
@TableField("fax")
private String fax;
@ApiModelProperty("联系电话")
@TableField("tele_phone")
private String telePhone;
@ApiModelProperty("详细地址")
@TableField("address")
private String address;
@ApiModelProperty("发票抬头")
@TableField("invoice_header")
private String invoiceHeader;
@ApiModelProperty("商户税号")
@TableField("tax_id")
private String taxId;
@ApiModelProperty("描述或说明")
@TableField("description")
private String description;
// @ApiModelProperty("注册人手持身份证照片")
// @TableField("registrant_pictures")
// private String registrantPictures;
//
// @ApiModelProperty("社会信用代码证照片")
// @TableField("society_pictures")
// private String societyPictures;
// @ApiModelProperty("拓展属性")
// @TableField("f_property_json")
// private String propertyJson;
@ApiModelProperty("创建时间")
@TableField("f_creator_time")
private Date fCreatorTime;
private LocalDateTime creatorTime;
@ApiModelProperty("修改时间")
@TableField("f_last_modify_time")

@ -0,0 +1,75 @@
package cc.yunxi.domain.po;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
*
* </p>
*
* @author ccongli
* @since 2024-03-14 06:39:30
*/
@Getter
@Setter
@TableName("nx_enterprise_account_bill")
@ApiModel(value = "EnterpriseAccountBill", description = "企业钱包流水")
public class EnterpriseAccountBill {
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
@ApiModelProperty("企业id")
@TableField("enterprise_id")
private String enterpriseId;
@ApiModelProperty("流水编号")
@TableField("bill_number")
private String billNumber;
@ApiModelProperty("订单编号")
@TableField("order_number")
private String orderNumber;
// @ApiModelProperty("订单类型id")
// @TableField("order_type_id")
// private String orderTypeId;
// @ApiModelProperty("单据状态id")
// @TableField("bill_status_id")
// private String billStatusId;
// @ApiModelProperty("收入(元)")
// @TableField("income_amount")
// private BigDecimal incomeAmount;
@ApiModelProperty("交易额")
@TableField("payout_amount")
private BigDecimal payoutAmount;
@ApiModelProperty("账户余额(元)")
@TableField("account_balance")
private BigDecimal accountBalance;
@ApiModelProperty("创建时间")
@TableField("creator_time")
private LocalDateTime creatorTime;
@ApiModelProperty("备注")
@TableField("remark")
private String remark;
}

@ -122,9 +122,9 @@ public class RecycleStation {
@TableField("accept_range")
private Integer acceptRange;
@ApiModelProperty("服务范围内小区")
@TableField("accept_housing_estate")
private String acceptHousingEstate;
// @ApiModelProperty("服务范围内小区")
// @TableField("accept_housing_estate")
// private String acceptHousingEstate;
@ApiModelProperty("创建时间")
@TableField("creator_time")

@ -33,9 +33,9 @@ public class ClientAddressReqVO {
@NotBlank(message = "联系人手机号不能为空", groups = AddAddressGroup.class)
private String receiveMobilePhone;
@ApiModelProperty(value = "城市",required = true)
@NotBlank(message = "城市不能为空", groups = AddAddressGroup.class)
private String receiveCity;
// @ApiModelProperty(value = "城市",required = true)
// @NotBlank(message = "城市不能为空", groups = AddAddressGroup.class)
// private String receiveCity;
@ApiModelProperty(value = "地址",required = true)
@NotBlank(message = "地址不能为空", groups = AddAddressGroup.class)

@ -12,7 +12,9 @@ import lombok.Getter;
@AllArgsConstructor
public enum BusinessCodeEnum implements BaseEnum {
ORDER("RO", "订单业务码");
ORDER("RO", "订单业务码"),
BILL("BL", "商户流水业务码");
private final String code;

@ -0,0 +1,18 @@
package cc.yunxi.mapper;
import cc.yunxi.domain.po.EnterpriseAccountBill;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper
* </p>
*
* @author ccongli
* @since 2024-03-14 06:39:30
*/
@Mapper
public interface EnterpriseAccountBillMapper extends BaseMapper<EnterpriseAccountBill> {
}

@ -3,6 +3,7 @@ package cc.yunxi.mapper;
import cc.yunxi.domain.po.Enterprise;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* <p>
@ -15,4 +16,11 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface EnterpriseMapper extends BaseMapper<Enterprise> {
// /**
// * 站点id获取商户信息
// * @param stationId
// * @return Enterprise
// */
// Enterprise getEnterpriseByStationId(@Param("stationId") String stationId);
}

@ -47,6 +47,13 @@ public interface IClientService extends IService<Client> {
*/
Client getClientByOpenid(String openid);
/**
* keyId
* @param keyId
* @return Client
*/
Client getClientByKeyId(String keyId);
/**
*
* @param phoneNumber

@ -13,4 +13,17 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface IEnterpriseService extends IService<Enterprise> {
/**
* id
* @param stationId
* @return Enterprise
*/
Enterprise getEnterpriseByStationId(String stationId);
/**
* id
* @param enterpriseId
* @return Enterprise
*/
Enterprise getEnterpriseById(String enterpriseId);
}

@ -4,21 +4,22 @@ import cc.yunxi.common.domain.LambdaQueryWrapperX;
import cc.yunxi.common.exception.BizIllegalException;
import cc.yunxi.common.exception.DbException;
import cc.yunxi.common.utils.BeanUtils;
import cc.yunxi.common.utils.CommonUtil;
import cc.yunxi.config.props.WxPayV3Properties;
import cc.yunxi.domain.dto.UserDTO;
import cc.yunxi.domain.po.Client;
import cc.yunxi.domain.po.ClientAccountDetail;
import cc.yunxi.domain.po.RecycleOrder;
import cc.yunxi.domain.po.Recycler;
import cc.yunxi.domain.po.*;
import cc.yunxi.domain.query.ClientAccountQuery;
import cc.yunxi.domain.query.ClientQuery;
import cc.yunxi.domain.query.RecyclerQuery;
import cc.yunxi.domain.vo.client.ClientUpdateVO;
import cc.yunxi.enums.BalanceChangeTypeEnum;
import cc.yunxi.enums.BusinessCodeEnum;
import cc.yunxi.mapper.ClientAccountDetailMapper;
import cc.yunxi.mapper.ClientMapper;
import cc.yunxi.mapper.EnterpriseAccountBillMapper;
import cc.yunxi.mapper.RecyclerMapper;
import cc.yunxi.service.IClientService;
import cc.yunxi.service.IEnterpriseService;
import cc.yunxi.utils.UserContext;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
@ -66,6 +67,12 @@ public class ClientServiceImpl extends ServiceImpl<ClientMapper, Client> impleme
@Autowired
private ClientAccountDetailMapper accountDetailMapper;
@Autowired
private EnterpriseAccountBillMapper accountBillMapper;
@Resource
private IEnterpriseService enterpriseService;
@Resource
private WxPayV3Properties wxPayV3Properties;
@ -98,6 +105,18 @@ public class ClientServiceImpl extends ServiceImpl<ClientMapper, Client> impleme
return lambdaQuery().eq(Client::getWxOpenid, openid).one();
}
@Override
public Client getClientByKeyId(String keyId) {
LambdaQueryWrapper<Client> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Client::getId, keyId).or().eq(Client::getWxOpenid, keyId);
wrapper.last("for update");
Client client = this.getOne(wrapper);
if (client == null) {
throw new BizIllegalException("散户不存在");
}
return client;
}
@Override
@Transactional
@ -137,8 +156,8 @@ public class ClientServiceImpl extends ServiceImpl<ClientMapper, Client> impleme
@Override
public void addBalance(String clientId, BigDecimal amount, String orderNo) {
this.changeBalance(clientId, amount, orderNo, BalanceChangeTypeEnum.INCOME);
public void addBalance(String clientId, BigDecimal amount, String orderNo, String stationId) {
this.changeBalance(clientId, amount, orderNo, stationId, BalanceChangeTypeEnum.INCOME);
}
@ -146,7 +165,7 @@ public class ClientServiceImpl extends ServiceImpl<ClientMapper, Client> impleme
@Transactional(rollbackFor = Exception.class)
public void cashBalance(String openId, Integer amount) throws Exception {
// 模拟提现成功
this.changeBalance(openId, new BigDecimal(amount), null, BalanceChangeTypeEnum.CASH_OUT);
this.changeBalance(openId, new BigDecimal(amount), null, null, BalanceChangeTypeEnum.CASH_OUT);
/* BatchTransferModel batchTransferModel = new BatchTransferModel()
.setAppid(wxPayV3Properties.getAppId())
.setOut_batch_no(PayKit.generateStr())
@ -222,30 +241,49 @@ public class ClientServiceImpl extends ServiceImpl<ClientMapper, Client> impleme
// 统一金额交易
private void changeBalance(String keyId, BigDecimal amount, String orderNo, BalanceChangeTypeEnum changeTypeEnum) {
LambdaQueryWrapper<Client> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Client::getId, keyId).or().eq(Client::getWxOpenid, keyId);
wrapper.last("for update");
Client client = this.getOne(wrapper);
private void changeBalance(String keyId, BigDecimal amount, String orderNo,
String stationId, BalanceChangeTypeEnum changeTypeEnum) {
Client client = this.getClientByKeyId(keyId);
BigDecimal balance = client.getBanlance();
String remark;
LocalDateTime now = LocalDateTime.now();
if (changeTypeEnum.equals(BalanceChangeTypeEnum.INCOME)) { // 收入
balance = balance.add(amount);
remark = "废品回收结算,收入" + amount + "元";
} else { // 支出/提现
} else { // 微信提现
if (balance.compareTo(amount) < 0) {
throw new BizIllegalException("余额不足");
}
balance = balance.subtract(amount);
remark = "微信提现" + amount + "元";
// 更新商户资金
Enterprise enterprise = enterpriseService.getEnterpriseByStationId(stationId);
BigDecimal fund = enterprise.getFund();
if (fund.compareTo(amount) < 0) {
throw new BizIllegalException("商户资金不足,请联系商户");
}
fund = fund.subtract(amount);
enterprise.setFund(fund);
enterpriseService.updateById(enterprise);
// 记录商户流水
EnterpriseAccountBill accountBill = new EnterpriseAccountBill();
accountBill.setEnterpriseId(enterprise.getId());
accountBill.setBillNumber(CommonUtil.getIdNumber(BusinessCodeEnum.BILL.getCode()));
accountBill.setAccountBalance(fund);
accountBill.setPayoutAmount(amount);
accountBill.setOrderNumber(orderNo);
accountBill.setRemark("支付给散户"+ amount + "元");
accountBill.setCreatorTime(now);
accountBillMapper.insert(accountBill);
}
// 更新余额
// 更新散户余额
client.setBanlance(balance);
client.setUpdateTime(now);
this.updateById(client);
// 添加流水记录
// 添加散户余额明细记录
ClientAccountDetail accountDetail = new ClientAccountDetail();
accountDetail.setClientId(client.getId());
accountDetail.setAmount(amount);

@ -1,11 +1,20 @@
package cc.yunxi.service.impl;
import cc.yunxi.common.exception.BizIllegalException;
import cc.yunxi.domain.po.Enterprise;
import cc.yunxi.domain.po.RecycleStation;
import cc.yunxi.enums.GlobalStatusEnum;
import cc.yunxi.mapper.EnterpriseMapper;
import cc.yunxi.service.IEnterpriseService;
import cc.yunxi.service.IRecycleStationService;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* <p>
* ()
@ -17,4 +26,32 @@ import org.springframework.stereotype.Service;
@Service
public class EnterpriseServiceImpl extends ServiceImpl<EnterpriseMapper, Enterprise> implements IEnterpriseService {
@Resource
private IRecycleStationService recycleStationService;
public Enterprise getEnterpriseByStationId(String stationId) {
RecycleStation station = recycleStationService.getStationById(stationId);
String enterpriseId = station.getEnterpriseId();
if (StrUtil.isEmpty(enterpriseId)) {
throw new BizIllegalException("回收站点未绑定商户");
}
return this.getEnterpriseById(enterpriseId);
}
@Override
public Enterprise getEnterpriseById(String enterpriseId) {
if (StrUtil.isEmpty(enterpriseId)) {
throw new BizIllegalException("参数缺失");
}
LambdaQueryWrapper<Enterprise> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Enterprise::getId, enterpriseId);
wrapper.eq(Enterprise::getStatus, GlobalStatusEnum.VALID.getCode());
wrapper.last("for update");
Enterprise enterprise = getOne(wrapper);
if (ObjectUtil.isEmpty(enterprise)) {
throw new BizIllegalException("商户不存在或已被禁用");
}
return enterprise;
}
}

@ -235,8 +235,11 @@ public class RecycleOrderServiceImpl extends ServiceImpl<RecycleOrderMapper, Rec
List<RecycleOrderProduct> recycleOrderProducts = BeanUtils.copyList(recycleOrderProductVOList, RecycleOrderProduct.class);
this.recycleOrderProductService.updateOrderProducts(recycleOrderProducts);
// 记录关键信息
String clientId = recycleOrder.getClientId();
String orderNumber = recycleOrder.getOrderNumber();
String recycleStationId = recycleOrder.getRecycleStationId();
recycleOrder = BeanUtils.copyBean(orderFinishVO, RecycleOrder.class);
recycleOrder.setOrderStatus(OrderStatusEnum.FINISHED);
recycleOrder.setCompleteTime(LocalDateTime.now());
@ -254,7 +257,7 @@ public class RecycleOrderServiceImpl extends ServiceImpl<RecycleOrderMapper, Rec
this.updateById(recycleOrder);
// 增加收入余额 异步? todo
clientService.addBalance(clientId, totalAmount, orderNumber);
clientService.addBalance(clientId, totalAmount, orderNumber, recycleStationId);
}

@ -0,0 +1,5 @@
<?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="cc.yunxi.mapper.EnterpriseAccountBillMapper">
</mapper>
Loading…
Cancel
Save