1. 增加 XXL-Job starter
2. 迁移 pay 服务的 Job 逻辑
This commit is contained in:
@@ -1,53 +0,0 @@
|
||||
package cn.iocoder.mall.order.biz.dao.order;
|
||||
|
||||
import cn.iocoder.mall.order.biz.dataobject.OrderDO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 订单 mapper
|
||||
*
|
||||
* @author Sin
|
||||
* @time 2019-03-16 15:09
|
||||
*/
|
||||
@Repository
|
||||
public interface OrderMapper extends BaseMapper<OrderDO> {
|
||||
|
||||
// /**
|
||||
// * 更新 - 根据 id 更新
|
||||
// *
|
||||
// * @param orderDO
|
||||
// * @return
|
||||
// */
|
||||
// int updateById(OrderDO orderDO);
|
||||
//
|
||||
// int updateByIdAndStatus(@Param("id") Integer id,
|
||||
// @Param("status") Integer status,
|
||||
// @Param("updateObj") OrderDO updateObj);
|
||||
//
|
||||
// /**
|
||||
// * 查询 - 根据id 查询
|
||||
// *
|
||||
// * @param id
|
||||
// * @return
|
||||
// */
|
||||
// OrderDO selectById(
|
||||
// @Param("id") Integer id
|
||||
// );
|
||||
//
|
||||
// /**
|
||||
// * 查询 - 后台分页page
|
||||
// *
|
||||
// * @param orderQueryDTO
|
||||
// * @return
|
||||
// */
|
||||
// int selectPageCount(OrderQueryDTO orderQueryDTO);
|
||||
//
|
||||
// /**
|
||||
// * 查询 - 后台分页page
|
||||
// *
|
||||
// * @param orderQueryDTO
|
||||
// * @return
|
||||
// */
|
||||
// List<OrderDO> selectPage(OrderQueryDTO orderQueryDTO);
|
||||
}
|
||||
@@ -17,28 +17,6 @@ import java.util.List;
|
||||
@Repository
|
||||
public interface OrderMapper extends BaseMapper<OrderDO> {
|
||||
|
||||
/**
|
||||
* 更新 - 根据 id 更新
|
||||
*
|
||||
* @param orderDO
|
||||
* @return
|
||||
*/
|
||||
int updateById(OrderDO orderDO);
|
||||
|
||||
int updateByIdAndStatus(@Param("id") Integer id,
|
||||
@Param("status") Integer status,
|
||||
@Param("updateObj") OrderDO updateObj);
|
||||
|
||||
/**
|
||||
* 查询 - 根据id 查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
OrderDO selectById(
|
||||
@Param("id") Integer id
|
||||
);
|
||||
|
||||
/**
|
||||
* 查询 - 后台分页page
|
||||
*
|
||||
|
||||
@@ -326,31 +326,6 @@ public class OrderServiceImpl implements OrderService {
|
||||
return CommonResult.success(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String updatePaySuccess(String orderId, Integer payAmount) {
|
||||
OrderDO order = orderMapper.selectById(Integer.valueOf(orderId));
|
||||
if (order == null) { // 订单不存在
|
||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_NOT_EXISTENT.getCode()).getMessage();
|
||||
}
|
||||
if (!order.getStatus().equals(OrderStatusEnum.WAITING_PAYMENT.getValue())) { // 状态不处于等待支付
|
||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_STATUS_NOT_WAITING_PAYMENT.getCode()).getMessage();
|
||||
}
|
||||
if (!order.getPresentPrice().equals(payAmount)) { // 支付金额不正确
|
||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_PAY_AMOUNT_ERROR.getCode()).getMessage();
|
||||
}
|
||||
// 更新 OrderDO 状态为已支付,等待发货
|
||||
OrderDO updateOrderObj = new OrderDO()
|
||||
.setStatus(OrderStatusEnum.WAIT_SHIPMENT.getValue())
|
||||
.setPayAmount(payAmount)
|
||||
.setPaymentTime(new Date());
|
||||
int updateCount = orderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), updateOrderObj);
|
||||
if (updateCount <= 0) {
|
||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_STATUS_NOT_WAITING_PAYMENT.getCode()).getMessage();
|
||||
}
|
||||
// TODO FROM 芋艿 to 小范,把更新 OrderItem 给补全。
|
||||
return "success";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult listenerConfirmGoods() {
|
||||
return null;
|
||||
|
||||
@@ -2,100 +2,6 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.mall.order.biz.dao.order.OrderMapper">
|
||||
|
||||
<sql id="FIELDS">
|
||||
id, user_id, order_no, buy_price, discount_price, logistics_price, present_price, pay_amount,
|
||||
payment_time, delivery_time, receiver_time, closing_time,
|
||||
has_return_exchange,
|
||||
status, remark, create_time, update_time, `deleted`
|
||||
</sql>
|
||||
|
||||
<sql id="updateFieldSql" >
|
||||
<set>
|
||||
<if test="orderNo != null">
|
||||
, order_no = #{orderNo}
|
||||
</if>
|
||||
<if test="buyPrice != null">
|
||||
, buy_price = #{buyPrice}
|
||||
</if>
|
||||
<if test="discountPrice != null">
|
||||
, discount_price = #{discountPrice}
|
||||
</if>
|
||||
<if test="logisticsPrice != null">
|
||||
, logistics_price = #{logisticsPrice}
|
||||
</if>
|
||||
<if test="logisticsPrice != null">
|
||||
, logistics_price = #{logisticsPrice}
|
||||
</if>
|
||||
<if test="presentPrice != null">
|
||||
, present_price = #{presentPrice}
|
||||
</if>
|
||||
<if test="payAmount != null">
|
||||
, pay_amount = #{payAmount}
|
||||
</if>
|
||||
<if test="deliveryTime != null">
|
||||
, delivery_time = #{deliveryTime}
|
||||
</if>
|
||||
<if test="paymentTime != null">
|
||||
, payment_time = #{paymentTime}
|
||||
</if>
|
||||
<if test="receiverTime != null">
|
||||
, receiver_time = #{receiverTime}
|
||||
</if>
|
||||
<if test="closingTime != null">
|
||||
, closing_time = #{closingTime}
|
||||
</if>
|
||||
<if test="hasReturnExchange != null">
|
||||
, has_return_exchange = #{hasReturnExchange}
|
||||
</if>
|
||||
|
||||
<if test="status != null">
|
||||
, status = #{status}
|
||||
</if>
|
||||
<if test="remark != null">
|
||||
, remark = #{remark}
|
||||
</if>
|
||||
<if test="deleted != null">
|
||||
, `deleted` = #{deleted}
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
, create_time = #{createTime}
|
||||
</if>
|
||||
<if test="updateTime != null">
|
||||
, update_time = #{updateTime}
|
||||
</if>
|
||||
</set>
|
||||
</sql>
|
||||
|
||||
<update id="updateById" parameterType="OrderDO">
|
||||
UPDATE `orders`
|
||||
<include refid="updateFieldSql" />
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="updateByIdAndStatus">
|
||||
UPDATE `orders`
|
||||
<set>
|
||||
<if test="updateObj.payAmount != null">
|
||||
, pay_amount = #{updateObj.payAmount}
|
||||
</if>
|
||||
<if test="updateObj.paymentTime != null">
|
||||
, payment_time = #{updateObj.paymentTime}
|
||||
</if>
|
||||
<if test="updateObj.status != null">
|
||||
, status = #{updateObj.status}
|
||||
</if>
|
||||
</set>
|
||||
WHERE id = #{id}
|
||||
AND status = #{status}
|
||||
</update>
|
||||
|
||||
<select id="selectById" resultType="cn.iocoder.mall.order.biz.dataobject.OrderDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM `orders`
|
||||
WHERE id = #{id}
|
||||
</select>
|
||||
|
||||
<sql id="selectWhere">
|
||||
<if test="status != null">
|
||||
AND `status` = #{status}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package cn.iocoder.mall.pay.biz.config;
|
||||
|
||||
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
@Configuration
|
||||
@Profile("dev")
|
||||
public class XxlJobConfiguration {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(XxlJobConfiguration.class);
|
||||
|
||||
@Value("${xxl.job.admin.addresses}")
|
||||
private String adminAddresses;
|
||||
@Value("${xxl.job.executor.appname}")
|
||||
private String appName;
|
||||
@Value("${xxl.job.executor.ip}")
|
||||
private String ip;
|
||||
@Value("${xxl.job.executor.port}")
|
||||
private int port;
|
||||
@Value("${xxl.job.accessToken}")
|
||||
private String accessToken;
|
||||
@Value("${xxl.job.executor.logpath}")
|
||||
private String logPath;
|
||||
@Value("${xxl.job.executor.logretentiondays}")
|
||||
private int logRetentionDays;
|
||||
|
||||
@Bean(initMethod = "start", destroyMethod = "destroy")
|
||||
public XxlJobSpringExecutor xxlJobExecutor() {
|
||||
logger.info(">>>>>>>>>>> xxl-job config init.");
|
||||
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
|
||||
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
|
||||
xxlJobSpringExecutor.setAppName(appName);
|
||||
xxlJobSpringExecutor.setIp(ip);
|
||||
xxlJobSpringExecutor.setPort(port);
|
||||
xxlJobSpringExecutor.setAccessToken(accessToken);
|
||||
xxlJobSpringExecutor.setLogPath(logPath);
|
||||
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
|
||||
|
||||
return xxlJobSpringExecutor;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package cn.iocoder.mall.pay.biz.job;
|
||||
|
||||
import cn.iocoder.mall.pay.biz.dao.PayNotifyTaskMapper;
|
||||
import cn.iocoder.mall.pay.biz.dataobject.PayNotifyTaskDO;
|
||||
import cn.iocoder.mall.pay.biz.service.PayNotifyServiceImpl;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.handler.IJobHandler;
|
||||
import com.xxl.job.core.handler.annotation.JobHandler;
|
||||
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 支付通知重试 Job
|
||||
*/
|
||||
@Component
|
||||
@JobHandler(value = "payTransactionNotifyJob")
|
||||
public class PayNotifyJob extends IJobHandler {
|
||||
|
||||
@Autowired
|
||||
private PayNotifyTaskMapper payTransactionNotifyTaskMapper;
|
||||
|
||||
@Autowired
|
||||
private PayNotifyServiceImpl payNotifyService;
|
||||
|
||||
@Resource
|
||||
private RocketMQTemplate rocketMQTemplate;
|
||||
|
||||
@Override
|
||||
public ReturnT<String> execute(String param) {
|
||||
// 获得需要通知的任务
|
||||
List<PayNotifyTaskDO> notifyTasks = payTransactionNotifyTaskMapper.selectByNotify();
|
||||
// 循环任务,发送通知
|
||||
for (PayNotifyTaskDO notifyTask : notifyTasks) {
|
||||
// 发送 MQ
|
||||
payNotifyService.sendNotifyMessage(notifyTask);
|
||||
// 更新最后通知时间
|
||||
// 1. 这样操作,虽然可能会出现 MQ 消费快于下面 PayTransactionNotifyTaskDO 的更新语句。但是,因为更新字段不同,所以不会有问题。
|
||||
// 2. 换个视角,如果先更新 PayTransactionNotifyTaskDO ,再发送 MQ 消息。如果 MQ 消息发送失败,则 PayTransactionNotifyTaskDO 再也不会被轮询到了。
|
||||
// 3. 当然,最最最完美的话,就是做事务消息,不过这样又过于复杂~
|
||||
PayNotifyTaskDO updateNotifyTask = new PayNotifyTaskDO()
|
||||
.setId(notifyTask.getId()).setLastExecuteTime(new Date());
|
||||
payTransactionNotifyTaskMapper.update(updateNotifyTask);
|
||||
}
|
||||
return new ReturnT<>("执行通知数:" + notifyTasks.size());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -80,7 +80,4 @@ public class PayTransactionServiceImpl implements PayTransactionService {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# xxl-job
|
||||
xxl:
|
||||
job:
|
||||
admin:
|
||||
addresses: http://s1.iocoder.cn:18079/
|
||||
executor:
|
||||
appname: pay-job-executor
|
||||
ip:
|
||||
port: 0
|
||||
logpath: /Users/yunai/logs/xxl-job/
|
||||
logretentiondays: 1
|
||||
accessToken:
|
||||
@@ -1,32 +0,0 @@
|
||||
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;
|
||||
|
||||
public class DubboGenericInvokerTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
ApplicationConfig application = new ApplicationConfig();
|
||||
application.setName("api-generic-consumer");
|
||||
|
||||
RegistryConfig registry = new RegistryConfig();
|
||||
registry.setAddress("zookeeper://127.0.0.1:2181");
|
||||
|
||||
application.setRegistry(registry);
|
||||
|
||||
ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
|
||||
// 弱类型接口名
|
||||
reference.setInterface("cn.iocoder.mall.order.api.OrderService");
|
||||
// 声明为泛化接口
|
||||
reference.setGeneric(true);
|
||||
|
||||
reference.setApplication(application);
|
||||
|
||||
// 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
|
||||
GenericService genericService = reference.get();
|
||||
|
||||
String name = (String) genericService.$invoke("updatePaySuccess", new String[]{String.class.getName()}, new Object[]{"1"});
|
||||
System.out.println(name);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user