将支付成功、退款成功的 MQ 消费逻辑进行迁移
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
package cn.iocoder.mall.pay.api.constant;
|
||||
|
||||
/**
|
||||
* 支付退款状态枚举
|
||||
*/
|
||||
public enum PayRefundStatus {
|
||||
|
||||
WAITING(1, "处理中"),
|
||||
SUCCESS(2, "成功"),
|
||||
FAILURE(3, "失败"), // 例如说,支付单超时
|
||||
;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer value;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
private String name;
|
||||
|
||||
PayRefundStatus(Integer value, String name) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public PayRefundStatus setValue(Integer value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public PayRefundStatus setName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package cn.iocoder.mall.pay.biz.component;
|
||||
|
||||
import cn.iocoder.common.framework.util.StringUtil;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import lombok.Data;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class DubboReferencePool {
|
||||
|
||||
@Data
|
||||
public class ReferenceMeta {
|
||||
|
||||
private final ReferenceConfig config; // TODO 芋艿,后续需要做销毁
|
||||
private final GenericService service;
|
||||
private final String methodName;
|
||||
|
||||
private ReferenceMeta(ReferenceConfig config, GenericService service, String methodName) {
|
||||
this.config = config;
|
||||
this.service = service;
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private LoadingCache<String, ReferenceMeta> referenceMetaCache = CacheBuilder.newBuilder()
|
||||
.build(new CacheLoader<String, ReferenceMeta>() {
|
||||
@Override
|
||||
public ReferenceMeta load(String notifyUrl) {
|
||||
return createGenericService(notifyUrl);
|
||||
}
|
||||
});
|
||||
|
||||
@Value("${dubbo.registry.address}")
|
||||
private String dubboRegistryAddress;
|
||||
@Value("${dubbo.application.name}")
|
||||
private String dubboApplicationName;
|
||||
|
||||
private ReferenceMeta createGenericService(String notifyUrl) {
|
||||
// 使用 # 号分隔,格式为 服务名#方法名#版本号
|
||||
List<String> notifyUrlParts = StringUtil.split(notifyUrl, "#");
|
||||
// 创建 ApplicationConfig 对象
|
||||
ApplicationConfig application = new ApplicationConfig();
|
||||
application.setName(dubboApplicationName);
|
||||
// 创建 RegistryConfig 对象
|
||||
RegistryConfig registry = new RegistryConfig();
|
||||
// registry.setAddress("zookeeper://127.0.0.1:2181");
|
||||
registry.setAddress(dubboRegistryAddress);
|
||||
application.setRegistry(registry);
|
||||
// 创建 ReferenceConfig 对象
|
||||
ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
|
||||
reference.setInterface(notifyUrlParts.get(0)); // 弱类型接口名
|
||||
reference.setGeneric(true); // 声明为泛化接口
|
||||
reference.setApplication(application);
|
||||
reference.setVersion(notifyUrlParts.size() > 2 ? notifyUrlParts.get(2) : "1.0.0"); // 如果未配置服务的版本号,则默认使用 1.0.0
|
||||
// 获得 GenericService 对象
|
||||
GenericService genericService = reference.get();
|
||||
// 构建最终的 ReferenceMeta 对象
|
||||
return new ReferenceMeta(reference, genericService, notifyUrlParts.get(1));
|
||||
}
|
||||
|
||||
public ReferenceMeta getReferenceMeta(String notifyUrl) {
|
||||
DubboReferencePool.ReferenceMeta referenceMeta = referenceMetaCache.getUnchecked(notifyUrl);
|
||||
Assert.notNull(referenceMeta, String.format("notifyUrl(%s) 不存在对应的 ReferenceMeta 对象", notifyUrl));
|
||||
return referenceMeta;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package cn.iocoder.mall.pay.biz.dao;
|
||||
|
||||
import cn.iocoder.mall.pay.biz.dataobject.PayRefundDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface PayRefundMapper {
|
||||
|
||||
void insert(PayRefundDO entity);
|
||||
|
||||
int update(@Param("entity") PayRefundDO entity,
|
||||
@Param("whereStatus") Integer whereStatus);
|
||||
|
||||
PayRefundDO selectById(@Param("id") Integer id);
|
||||
|
||||
PayRefundDO selectByRefundCode(@Param("refundCode") String refundCode);
|
||||
|
||||
List<PayRefundDO> selectListByPage(@Param("createBeginTime") Date createBeginTime,
|
||||
@Param("createEndTime") Date createEndTime,
|
||||
@Param("finishBeginTime") Date finishBeginTime,
|
||||
@Param("finishEndTime") Date finishEndTime,
|
||||
@Param("status") Integer status,
|
||||
@Param("payChannel") Integer payChannel,
|
||||
@Param("offset") Integer offset,
|
||||
@Param("limit") Integer limit);
|
||||
|
||||
Integer selectCountByPage(@Param("createBeginTime") Date createBeginTime,
|
||||
@Param("createEndTime") Date createEndTime,
|
||||
@Param("finishBeginTime") Date finishBeginTime,
|
||||
@Param("finishEndTime") Date finishEndTime,
|
||||
@Param("status") Integer status,
|
||||
@Param("payChannel") Integer payChannel);
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package cn.iocoder.mall.pay.biz.dao;
|
||||
|
||||
import cn.iocoder.mall.pay.biz.dataobject.PayTransactionDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface PayTransactionMapper {
|
||||
|
||||
int updateForRefundTotal(@Param("id") Integer id,
|
||||
@Param("refundTotalIncr") Integer refundTotalIncr);
|
||||
|
||||
|
||||
List<PayTransactionDO> selectListByPage(@Param("createBeginTime") Date createBeginTime,
|
||||
@Param("createEndTime") Date createEndTime,
|
||||
@Param("paymentBeginTime") Date paymentBeginTime,
|
||||
@Param("paymentEndTime") Date paymentEndTime,
|
||||
@Param("status") Integer status,
|
||||
@Param("hasRefund") Boolean hasRefund,
|
||||
@Param("payChannel") Integer payChannel,
|
||||
@Param("orderSubject") String orderSubject,
|
||||
@Param("offset") Integer offset,
|
||||
@Param("limit") Integer limit);
|
||||
|
||||
Integer selectCountByPage(@Param("createBeginTime") Date createBeginTime,
|
||||
@Param("createEndTime") Date createEndTime,
|
||||
@Param("paymentBeginTime") Date paymentBeginTime,
|
||||
@Param("paymentEndTime") Date paymentEndTime,
|
||||
@Param("status") Integer status,
|
||||
@Param("hasRefund") Boolean hasRefund,
|
||||
@Param("payChannel") Integer payChannel,
|
||||
@Param("orderSubject") String orderSubject);
|
||||
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package cn.iocoder.mall.pay.biz.mq;
|
||||
|
||||
import cn.iocoder.common.framework.util.DateUtil;
|
||||
import cn.iocoder.common.framework.util.ExceptionUtil;
|
||||
import cn.iocoder.mall.pay.api.constant.PayTransactionNotifyStatusEnum;
|
||||
import cn.iocoder.mall.pay.api.message.AbstractPayNotifySuccessMessage;
|
||||
import cn.iocoder.mall.pay.biz.component.DubboReferencePool;
|
||||
import cn.iocoder.mall.pay.biz.dao.PayNotifyLogMapper;
|
||||
import cn.iocoder.mall.pay.biz.dao.PayNotifyTaskMapper;
|
||||
import cn.iocoder.mall.pay.biz.dataobject.PayNotifyLogDO;
|
||||
import cn.iocoder.mall.pay.biz.dataobject.PayNotifyTaskDO;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public abstract class AbstractPayNotifySuccessConsumer<T extends AbstractPayNotifySuccessMessage> implements RocketMQListener<T> {
|
||||
|
||||
@Autowired
|
||||
private DubboReferencePool dubboReferencePool;
|
||||
|
||||
@Autowired
|
||||
private PayNotifyTaskMapper payTransactionNotifyTaskMapper;
|
||||
@Autowired
|
||||
private PayNotifyLogMapper payTransactionNotifyLogMapper;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void onMessage(T message) {
|
||||
// 获得 ReferenceMeta 对象
|
||||
DubboReferencePool.ReferenceMeta referenceMeta = dubboReferencePool.getReferenceMeta(message.getNotifyUrl());
|
||||
// 发起调用
|
||||
String response = null; // RPC / HTTP 调用的响应
|
||||
PayNotifyTaskDO updateTask = new PayNotifyTaskDO() // 更新 PayTransactionNotifyTaskDO 对象
|
||||
.setId(message.getId())
|
||||
.setLastExecuteTime(new Date())
|
||||
.setNotifyTimes(message.getNotifyTimes() + 1);
|
||||
try {
|
||||
response = invoke(message, referenceMeta);
|
||||
if ("success".equals(response)) { // 情况一,请求成功且返回成功
|
||||
// 更新通知成功
|
||||
updateTask.setStatus(PayTransactionNotifyStatusEnum.SUCCESS.getValue());
|
||||
payTransactionNotifyTaskMapper.update(updateTask);
|
||||
// 需要更新支付交易单通知应用成功
|
||||
afterInvokeSuccess(message);
|
||||
} else { // 情况二,请求成功且返回失败
|
||||
// 更新通知请求成功,但是结果失败
|
||||
handleFailure(updateTask, PayTransactionNotifyStatusEnum.REQUEST_SUCCESS.getValue());
|
||||
payTransactionNotifyTaskMapper.update(updateTask);
|
||||
}
|
||||
} catch (Throwable e) { // 请求失败
|
||||
// 更新通知请求失败
|
||||
response = ExceptionUtil.getRootCauseMessage(e);
|
||||
handleFailure(updateTask, PayTransactionNotifyStatusEnum.REQUEST_FAILURE.getValue());
|
||||
payTransactionNotifyTaskMapper.update(updateTask);
|
||||
// 抛出异常,回滚事务
|
||||
throw e; // TODO 芋艿,此处不能抛出异常。因为,会导致 MQ + 定时任务多重试。此处的目标是,事务回滚 + 吃掉事务。另外,最后的 finally 的日志,要插入成功。
|
||||
} finally {
|
||||
// 插入 PayTransactionNotifyLogDO 日志
|
||||
PayNotifyLogDO notifyLog = new PayNotifyLogDO().setNotifyId(message.getId())
|
||||
.setRequest(JSON.toJSONString(message)).setResponse(response).setStatus(updateTask.getStatus());
|
||||
payTransactionNotifyLogMapper.insert(notifyLog);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleFailure(PayNotifyTaskDO updateTask, Integer defaultStatus) {
|
||||
if (updateTask.getNotifyTimes() >= PayNotifyTaskDO.NOTIFY_FREQUENCY.length) {
|
||||
updateTask.setStatus(PayTransactionNotifyStatusEnum.FAILURE.getValue());
|
||||
} else {
|
||||
updateTask.setNextNotifyTime(DateUtil.addDate(Calendar.SECOND, PayNotifyTaskDO.NOTIFY_FREQUENCY[updateTask.getNotifyTimes()]));
|
||||
updateTask.setStatus(defaultStatus);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract String invoke(T message, DubboReferencePool.ReferenceMeta referenceMeta);
|
||||
|
||||
protected abstract void afterInvokeSuccess(T message);
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package cn.iocoder.mall.pay.biz.mq;
|
||||
|
||||
import cn.iocoder.mall.pay.api.message.PayRefundSuccessMessage;
|
||||
import cn.iocoder.mall.pay.biz.component.DubboReferencePool;
|
||||
import cn.iocoder.mall.pay.biz.dao.PayRefundMapper;
|
||||
import cn.iocoder.mall.pay.biz.dataobject.PayRefundDO;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Service
|
||||
@RocketMQMessageListener(
|
||||
topic = PayRefundSuccessMessage.TOPIC,
|
||||
consumerGroup = "pay-consumer-group-" + PayRefundSuccessMessage.TOPIC
|
||||
)
|
||||
@Deprecated // 艿艿:突然发现,业务方实际无需回调。参考了 https://help.youzan.com/displaylist/detail_4_998 的文章。业务方,只要记录下退款单号,进行关联即可。
|
||||
public class PayRefundSuccessConsumer extends AbstractPayNotifySuccessConsumer<PayRefundSuccessMessage>
|
||||
implements RocketMQListener<PayRefundSuccessMessage> {
|
||||
|
||||
@Autowired
|
||||
private PayRefundMapper payRefundMapper;
|
||||
|
||||
@Override
|
||||
protected String invoke(PayRefundSuccessMessage message, DubboReferencePool.ReferenceMeta referenceMeta) {
|
||||
// 查询支付交易
|
||||
PayRefundDO refund = payRefundMapper.selectById(message.getRefundId());
|
||||
Assert.notNull(refund, String.format("回调消息(%s) 退款单不能为空", message.toString()));
|
||||
// 执行调用
|
||||
GenericService genericService = referenceMeta.getService();
|
||||
String methodName = referenceMeta.getMethodName();
|
||||
return (String) genericService.$invoke(methodName, new String[]{String.class.getName(), Integer.class.getName()},
|
||||
new Object[]{message.getOrderId(), refund.getPrice()});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterInvokeSuccess(PayRefundSuccessMessage message) {
|
||||
PayRefundDO updateRefund = new PayRefundDO().setId(message.getRefundId()).setFinishTime(new Date());
|
||||
payRefundMapper.update(updateRefund, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package cn.iocoder.mall.pay.biz.mq;
|
||||
|
||||
import cn.iocoder.mall.pay.api.message.PayTransactionSuccessMessage;
|
||||
import cn.iocoder.mall.pay.biz.component.DubboReferencePool;
|
||||
import cn.iocoder.mall.pay.biz.dao.PayTransactionMapper;
|
||||
import cn.iocoder.mall.pay.biz.dataobject.PayTransactionDO;
|
||||
import org.apache.dubbo.rpc.service.GenericService;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Service
|
||||
@RocketMQMessageListener(
|
||||
topic = PayTransactionSuccessMessage.TOPIC,
|
||||
consumerGroup = "pay-consumer-group-" + PayTransactionSuccessMessage.TOPIC
|
||||
)
|
||||
public class PayTransactionSuccessConsumer extends AbstractPayNotifySuccessConsumer<PayTransactionSuccessMessage>
|
||||
implements RocketMQListener<PayTransactionSuccessMessage> {
|
||||
|
||||
@Autowired
|
||||
private PayTransactionMapper payTransactionMapper;
|
||||
|
||||
@Override
|
||||
protected String invoke(PayTransactionSuccessMessage message, DubboReferencePool.ReferenceMeta referenceMeta) {
|
||||
// 查询支付交易
|
||||
PayTransactionDO transaction = payTransactionMapper.selectById(message.getTransactionId());
|
||||
Assert.notNull(transaction, String.format("回调消息(%s) 订单交易不能为空", message.toString()));
|
||||
// 执行调用
|
||||
GenericService genericService = referenceMeta.getService();
|
||||
String methodName = referenceMeta.getMethodName();
|
||||
return (String) genericService.$invoke(methodName, new String[]{String.class.getName(), Integer.class.getName()},
|
||||
new Object[]{message.getOrderId(), transaction.getPrice()});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterInvokeSuccess(PayTransactionSuccessMessage message) {
|
||||
PayTransactionDO updateTransaction = new PayTransactionDO().setId(message.getTransactionId()).setFinishTime(new Date());
|
||||
payTransactionMapper.update(updateTransaction, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
<?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="cn.iocoder.mall.pay.biz.dao.PayRefundMapper">
|
||||
|
||||
<sql id="FIELDS">
|
||||
id, transaction_id, refund_code, app_id, create_ip, order_id,
|
||||
order_description, price, status,
|
||||
finish_time, notify_url, extension_data, refund_channel, refund_time, notify_time,
|
||||
trade_no, create_time
|
||||
</sql>
|
||||
|
||||
<insert id="insert" parameterType="PayRefundDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
|
||||
INSERT INTO refund (
|
||||
transaction_id, refund_code, app_id, create_ip, order_id,
|
||||
order_description, price, status,
|
||||
finish_time, notify_url, extension_data, refund_channel, refund_time, notify_time,
|
||||
trade_no, create_time
|
||||
) VALUES (
|
||||
#{transactionId}, #{refundCode}, #{appId}, #{createIp}, #{orderId},
|
||||
#{orderDescription}, #{price}, #{status},
|
||||
#{finishTime}, #{notifyUrl}, #{extensionData}, #{refundChannel}, #{refundTime}, #{notifyTime},
|
||||
#{tradeNo}, #{createTime}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="update">
|
||||
UPDATE refund
|
||||
<set>
|
||||
<if test="entity.status != null">
|
||||
, status = #{entity.status}
|
||||
</if>
|
||||
<if test="entity.finishTime != null">
|
||||
, finish_time = #{entity.finishTime}
|
||||
</if>
|
||||
<if test="entity.extensionData != null">
|
||||
, extension_data = #{entity.extensionData}
|
||||
</if>
|
||||
<if test="entity.refundTime != null">
|
||||
, refund_time = #{entity.refundTime}
|
||||
</if>
|
||||
<if test="entity.notifyTime != null">
|
||||
, notify_time = #{entity.notifyTime}
|
||||
</if>
|
||||
<if test="entity.tradeNo != null">
|
||||
, trade_no = #{entity.tradeNo}
|
||||
</if>
|
||||
</set>
|
||||
WHERE id = #{entity.id}
|
||||
<if test="whereStatus != null">
|
||||
AND status = #{whereStatus}
|
||||
</if>
|
||||
</update>
|
||||
|
||||
<select id="selectByRefundCode" parameterType="String" resultType="PayRefundDO">
|
||||
SELECT
|
||||
<include refid="FIELDS"/>
|
||||
FROM refund
|
||||
WHERE refund_code = #{refundCode}
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectById" parameterType="Integer" resultType="PayRefundDO">
|
||||
SELECT
|
||||
<include refid="FIELDS"/>
|
||||
FROM refund
|
||||
WHERE id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectListByPage" resultType="PayRefundDO">
|
||||
SELECT
|
||||
<include refid="FIELDS"/>
|
||||
FROM refund
|
||||
<where>
|
||||
<if test="createBeginTime != null">
|
||||
AND create_time >= #{createBeginTime}
|
||||
</if>
|
||||
<if test="createEndTime != null">
|
||||
AND #{createEndTime} >= create_time
|
||||
</if>
|
||||
<if test="finishBeginTime != null">
|
||||
AND finish_time >= #{finishBeginTime}
|
||||
</if>
|
||||
<if test="finishEndTime != null">
|
||||
AND #{finishEndTime} >= finish_time
|
||||
</if>
|
||||
<if test="status != null">
|
||||
AND status = #{status}
|
||||
</if>
|
||||
<if test="payChannel != null">
|
||||
AND pay_channel = #{payChannel}
|
||||
</if>
|
||||
</where>
|
||||
LIMIT #{offset}, #{limit}
|
||||
</select>
|
||||
|
||||
<select id="selectCountByPage" resultType="Integer">
|
||||
SELECT
|
||||
COUNT(1)
|
||||
FROM refund
|
||||
<where>
|
||||
<if test="createBeginTime != null">
|
||||
AND create_time >= #{createBeginTime}
|
||||
</if>
|
||||
<if test="createEndTime != null">
|
||||
AND #{createEndTime} >= create_time
|
||||
</if>
|
||||
<if test="finishBeginTime != null">
|
||||
AND finish_time >= #{finishBeginTime}
|
||||
</if>
|
||||
<if test="finishEndTime != null">
|
||||
AND #{finishEndTime} >= finish_time
|
||||
</if>
|
||||
<if test="status != null">
|
||||
AND status = #{status}
|
||||
</if>
|
||||
<if test="payChannel != null">
|
||||
AND pay_channel = #{payChannel}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -1,25 +0,0 @@
|
||||
<?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="cn.iocoder.mall.pay.biz.dao.PayTransactionExtensionMapper">
|
||||
|
||||
<sql id="FIELDS">
|
||||
id, transaction_id, pay_channel, transaction_code, extension_data,
|
||||
create_ip, status, create_time
|
||||
</sql>
|
||||
|
||||
<select id="selectByTransactionCode" parameterType="String" resultType="PayTransactionExtensionDO">
|
||||
SELECT
|
||||
<include refid="FIELDS"/>
|
||||
FROM transaction_extension
|
||||
WHERE transaction_code = #{transactionCode}
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="selectById" parameterType="Integer" resultType="PayTransactionExtensionDO">
|
||||
SELECT
|
||||
<include refid="FIELDS"/>
|
||||
FROM transaction_extension
|
||||
WHERE id = #{id}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -1,128 +0,0 @@
|
||||
<?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="cn.iocoder.mall.pay.biz.dao.PayTransactionMapper">
|
||||
|
||||
<sql id="FIELDS">
|
||||
id, app_id, create_ip, order_id, order_subject,
|
||||
order_description, order_memo, price, status, expire_time,
|
||||
finish_time, notify_url, extension_id, pay_channel, payment_time,
|
||||
notify_time, trade_no, refund_total, create_time
|
||||
</sql>
|
||||
|
||||
<update id="update">
|
||||
UPDATE transaction
|
||||
<set>
|
||||
<if test="entity.status != null">
|
||||
, status = #{entity.status}
|
||||
</if>
|
||||
<if test="entity.extensionId != null">
|
||||
, extension_id = #{entity.extensionId}
|
||||
</if>
|
||||
<if test="entity.payChannel != null">
|
||||
, pay_channel = #{entity.payChannel}
|
||||
</if>
|
||||
<if test="entity.paymentTime != null">
|
||||
, payment_time = #{entity.paymentTime}
|
||||
</if>
|
||||
<if test="entity.finishTime != null">
|
||||
, finish_time = #{entity.finishTime}
|
||||
</if>
|
||||
<if test="entity.notifyTime != null">
|
||||
, notify_time = #{entity.notifyTime}
|
||||
</if>
|
||||
<if test="entity.tradeNo != null">
|
||||
, trade_no = #{entity.tradeNo}
|
||||
</if>
|
||||
</set>
|
||||
WHERE id = #{entity.id}
|
||||
<if test="whereStatus != null">
|
||||
AND status = #{whereStatus}
|
||||
</if>
|
||||
</update>
|
||||
|
||||
<update id="updateForRefundTotal">
|
||||
UPDATE `transaction`
|
||||
SET refund_total = refund_total + ${refundTotalIncr}
|
||||
WHERE price >= refund_total + ${refundTotalIncr}
|
||||
</update>
|
||||
|
||||
<select id="selectByAppIdAndOrderId" resultType="PayTransactionDO">
|
||||
SELECT
|
||||
<include refid="FIELDS"/>
|
||||
FROM transaction
|
||||
WHERE app_id = #{appId}
|
||||
AND order_id = #{orderId}
|
||||
</select>
|
||||
|
||||
<select id="selectListByPage" resultType="PayTransactionDO">
|
||||
SELECT
|
||||
<include refid="FIELDS"/>
|
||||
FROM transaction
|
||||
<where>
|
||||
<if test="createBeginTime != null">
|
||||
AND create_time >= #{createBeginTime}
|
||||
</if>
|
||||
<if test="createEndTime != null">
|
||||
AND #{createEndTime} >= create_time
|
||||
</if>
|
||||
<if test="paymentBeginTime != null">
|
||||
AND payment_time >= #{paymentBeginTime}
|
||||
</if>
|
||||
<if test="paymentEndTime != null">
|
||||
AND #{paymentEndTime} >= payment_time
|
||||
</if>
|
||||
<if test="status != null">
|
||||
AND status = #{status}
|
||||
</if>
|
||||
<if test="hasRefund == true">
|
||||
AND refund_total > 0
|
||||
</if>
|
||||
<if test="hasRefund == false">
|
||||
AND refund_total = 0
|
||||
</if>
|
||||
<if test="payChannel != null">
|
||||
AND pay_channel = #{payChannel}
|
||||
</if>
|
||||
<if test="orderSubject != null">
|
||||
order_subject LIKE "%"#{orderSubject}"%"
|
||||
</if>
|
||||
</where>
|
||||
LIMIT #{offset}, #{limit}
|
||||
</select>
|
||||
|
||||
<select id="selectCountByPage" resultType="Integer">
|
||||
SELECT
|
||||
COUNT(1)
|
||||
FROM transaction
|
||||
<where>
|
||||
<if test="createBeginTime != null">
|
||||
AND create_time >= #{createBeginTime}
|
||||
</if>
|
||||
<if test="createEndTime != null">
|
||||
AND #{createEndTime} >= create_time
|
||||
</if>
|
||||
<if test="paymentBeginTime != null">
|
||||
AND payment_time >= #{paymentBeginTime}
|
||||
</if>
|
||||
<if test="paymentEndTime != null">
|
||||
AND #{paymentEndTime} >= payment_time
|
||||
</if>
|
||||
<if test="status != null">
|
||||
AND status = #{status}
|
||||
</if>
|
||||
<if test="hasRefund == true">
|
||||
AND refund_total > 0
|
||||
</if>
|
||||
<if test="hasRefund == false">
|
||||
AND refund_total = 0
|
||||
</if>
|
||||
<if test="payChannel != null">
|
||||
AND pay_channel = #{payChannel}
|
||||
</if>
|
||||
<if test="orderSubject != null">
|
||||
order_subject LIKE "%"#{orderSubject}"%"
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user