Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Y
yudao-cloud
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
hblj
yudao-cloud
Commits
3eca1823
提交
3eca1823
authored
4月 21, 2019
作者:
YunaiV
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
后端:增加支付成功后,回调支付模块
上级
914de3f2
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
147 行增加
和
39 行删除
+147
-39
OrderService.java
...src/main/java/cn/iocoder/mall/order/api/OrderService.java
+13
-0
OrderErrorCodeEnum.java
...n/iocoder/mall/order/api/constant/OrderErrorCodeEnum.java
+2
-0
OrderMapper.java
.../main/java/cn/iocoder/mall/order/biz/dao/OrderMapper.java
+4
-0
OrderServiceImpl.java
...a/cn/iocoder/mall/order/biz/service/OrderServiceImpl.java
+23
-0
OrderMapper.xml
...er-service-impl/src/main/resources/mapper/OrderMapper.xml
+37
-12
DubboGenericInvokerTest.java
...ay-application/src/test/java/DubboGenericInvokerTest.java
+2
-3
PayTransactionMapper.java
...ava/cn/iocoder/mall/pay/biz/dao/PayTransactionMapper.java
+2
-3
PayTransactionPaySuccessConsumer.java
...der/mall/pay/biz/mq/PayTransactionPaySuccessConsumer.java
+64
-21
没有找到文件。
order/order-service-api/src/main/java/cn/iocoder/mall/order/api/OrderService.java
浏览文件 @
3eca1823
...
...
@@ -138,8 +138,21 @@ public interface OrderService {
*
* mq 更新 payStatus
*/
@Deprecated
CommonResult
listenerPayment
();
/**
* 更新订单支付成功
*
* 如果成功,则返回 success
* 如果失败,则返回具体原因
*
* @param orderId 订单编号
* @param payAmount 支付的订单金额
* @return 支付结果
*/
String
updatePaySuccess
(
String
orderId
,
Integer
payAmount
);
/**
* 监听确认收货
*
...
...
order/order-service-api/src/main/java/cn/iocoder/mall/order/api/constant/OrderErrorCodeEnum.java
浏览文件 @
3eca1823
...
...
@@ -25,6 +25,8 @@ public enum OrderErrorCodeEnum {
ORDER_NOT_USER_ORDER
(
1008000011
,
"不是该用户的订单!"
),
ORDER_UNABLE_CONFIRM_ORDER
(
1008000012
,
"状态不对不能确认订单!"
),
ORDER_CREATE_CART_IS_EMPTY
(
1008000013
,
"购物车无选中的商品,无法创建订单"
),
ORDER_STATUS_NOT_WAITING_PAYMENT
(
1008000014
,
"订单不处于等待支付状态"
),
ORDER_PAY_AMOUNT_ERROR
(
1008000015
,
"订单金额不正确"
),
// order item
ORDER_ITEM_ONLY_ONE
(
1008000200
,
"订单Item只有一个!"
),
...
...
order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/dao/OrderMapper.java
浏览文件 @
3eca1823
...
...
@@ -31,6 +31,10 @@ public interface OrderMapper {
*/
int
updateById
(
OrderDO
orderDO
);
int
updateByIdAndStatus
(
@Param
(
"id"
)
Integer
id
,
@Param
(
"status"
)
Integer
status
,
@Param
(
"updateObj"
)
OrderDO
updateObj
);
/**
* 查询 - 根据id 查询
*
...
...
order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/OrderServiceImpl.java
浏览文件 @
3eca1823
...
...
@@ -598,6 +598,29 @@ public class OrderServiceImpl implements OrderService {
return
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
updateOrderObj
=
new
OrderDO
()
.
setStatus
(
OrderStatusEnum
.
ALREADY_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
();
}
return
"success"
;
}
@Override
public
CommonResult
listenerConfirmGoods
()
{
return
null
;
...
...
order/order-service-impl/src/main/resources/mapper/OrderMapper.xml
浏览文件 @
3eca1823
...
...
@@ -34,22 +34,30 @@
<if
test=
"orderNo != null"
>
, order_no = #{orderNo}
</if>
<!-- <if test="price != null">-->
<!-- TODO 后面要改下 -->
<!-- , price = #{price}-->
<!-- </if>-->
<!-- <if test="payAmount != null">-->
<!-- , pay_amount = #{payAmount}-->
<!-- </if>-->
<!-- <if test="logisticsPrice != null">-->
<!-- , logistics_price = #{logisticsPrice}-->
<!-- </if>-->
<if
test=
"paymentTime != null"
>
, payment_time = #{paymentTime}
<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>
...
...
@@ -87,6 +95,23 @@
WHERE id = #{id}
</update>
<update
id=
"updateByIdAndStatus"
>
UPDATE `order`
<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>
<!--
查询 - 根据id 查询
-->
...
...
pay/pay-application/src/test/java/DubboGenericInvokerTest.java
浏览文件 @
3eca1823
...
...
@@ -16,7 +16,7 @@ public class DubboGenericInvokerTest {
ReferenceConfig
<
GenericService
>
reference
=
new
ReferenceConfig
<>();
// 弱类型接口名
reference
.
setInterface
(
"cn.iocoder.mall.
pay.api.PayDemo
Service"
);
reference
.
setInterface
(
"cn.iocoder.mall.
order.api.Order
Service"
);
// 声明为泛化接口
reference
.
setGeneric
(
true
);
...
...
@@ -29,4 +29,4 @@ public class DubboGenericInvokerTest {
System
.
out
.
println
(
name
);
}
}
\ No newline at end of file
}
pay/pay-service-impl/src/main/java/cn/iocoder/mall/pay/biz/dao/PayTransactionMapper.java
浏览文件 @
3eca1823
...
...
@@ -15,6 +15,6 @@ public interface PayTransactionMapper {
PayTransactionDO
selectByAppIdAndOrderId
(
@Param
(
"appId"
)
String
appId
,
@Param
(
"orderId"
)
String
orderId
);
PayTransactionDO
selectById
(
@Param
(
"id"
)
Integer
appI
d
);
PayTransactionDO
selectById
(
@Param
(
"id"
)
Integer
i
d
);
}
\ No newline at end of file
}
pay/pay-service-impl/src/main/java/cn/iocoder/mall/pay/biz/mq/PayTransactionPaySuccessConsumer.java
浏览文件 @
3eca1823
...
...
@@ -14,11 +14,17 @@ import com.alibaba.dubbo.config.ApplicationConfig;
import
com.alibaba.dubbo.config.ReferenceConfig
;
import
com.alibaba.dubbo.config.RegistryConfig
;
import
com.alibaba.dubbo.rpc.service.GenericService
;
import
com.google.common.cache.CacheBuilder
;
import
com.google.common.cache.CacheLoader
;
import
com.google.common.cache.LoadingCache
;
import
lombok.Data
;
import
org.apache.rocketmq.spring.annotation.RocketMQMessageListener
;
import
org.apache.rocketmq.spring.core.RocketMQListener
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.util.Assert
;
import
java.util.Calendar
;
import
java.util.Date
;
...
...
@@ -30,6 +36,26 @@ import java.util.Date;
)
public
class
PayTransactionPaySuccessConsumer
implements
RocketMQListener
<
PayTransactionPaySuccessMessage
>
{
@Data
private
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
;
}
}
@Value
(
"${dubbo.registry.address}"
)
private
String
dubboRegistryAddress
;
@Value
(
"${dubbo.application.name}"
)
private
String
dubboApplicationName
;
@Autowired
private
PayTransactionNotifyTaskMapper
payTransactionNotifyTaskMapper
;
@Autowired
...
...
@@ -37,37 +63,55 @@ public class PayTransactionPaySuccessConsumer implements RocketMQListener<PayTra
@Autowired
private
PayTransactionMapper
payTransactionMapper
;
@Override
@Transactional
public
void
onMessage
(
PayTransactionPaySuccessMessage
message
)
{
// TODO 先简单写,后面重构
private
LoadingCache
<
String
,
ReferenceMeta
>
referenceMetaCache
=
CacheBuilder
.
newBuilder
()
.
build
(
new
CacheLoader
<
String
,
ReferenceMeta
>()
{
@Override
public
ReferenceMeta
load
(
String
notifyUrl
)
{
return
createGenericService
(
notifyUrl
);
}
});
private
ReferenceMeta
createGenericService
(
String
notifyUrl
)
{
String
[]
notifyUrlParts
=
notifyUrl
.
split
(
"#"
);
// 创建 ApplicationConfig 对象
ApplicationConfig
application
=
new
ApplicationConfig
();
application
.
setName
(
"api-generic-consumer"
);
application
.
setName
(
dubboApplicationName
);
// 创建 RegistryConfig 对象
RegistryConfig
registry
=
new
RegistryConfig
();
registry
.
setAddress
(
"zookeeper://127.0.0.1:2181"
);
//
registry.setAddress("zookeeper://127.0.0.1:2181");
registry
.
setAddress
(
dubboRegistryAddress
);
application
.
setRegistry
(
registry
);
// 创建 ReferenceConfig 对象
ReferenceConfig
<
GenericService
>
reference
=
new
ReferenceConfig
<>();
// 弱类型接口名
reference
.
setInterface
(
"cn.iocoder.mall.pay.api.PayDemoService"
);
// 声明为泛化接口
reference
.
setGeneric
(
true
);
reference
.
setInterface
(
notifyUrlParts
[
0
]);
// 弱类型接口名
reference
.
setGeneric
(
true
);
// 声明为泛化接口
reference
.
setApplication
(
application
);
// 获得 GenericService 对象
GenericService
genericService
=
reference
.
get
();
// 构建最终的 ReferenceMeta 对象
return
new
ReferenceMeta
(
reference
,
genericService
,
notifyUrlParts
[
1
]);
}
// 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
GenericService
genericService
=
reference
.
get
();
// TODO 芋艿,要缓存,不然重复引用
@Override
@Transactional
public
void
onMessage
(
PayTransactionPaySuccessMessage
message
)
{
// 获得 ReferenceMeta 对象
ReferenceMeta
referenceMeta
=
referenceMetaCache
.
getUnchecked
(
message
.
getNotifyUrl
());
Assert
.
notNull
(
referenceMeta
,
String
.
format
(
"notifyUrl(%s) 不存在对应的 ReferenceMeta 对象"
,
message
.
getNotifyUrl
()));
GenericService
genericService
=
referenceMeta
.
getService
();
String
methodName
=
referenceMeta
.
getMethodName
();
// 查询支付交易
PayTransactionDO
transaction
=
payTransactionMapper
.
selectById
(
message
.
getTransactionId
());
Assert
.
notNull
(
transaction
,
String
.
format
(
"回调消息(%s) 订单交易不能为空"
,
message
.
toString
()));
// 发起调用
String
response
=
null
;
// RPC / HTTP 调用的响应
PayTransactionNotifyTaskDO
updateTask
=
new
PayTransactionNotifyTaskDO
()
// 更新 PayTransactionNotifyTaskDO 对象
.
setId
(
message
.
getId
())
.
setLastExecuteTime
(
new
Date
())
.
setNotifyTimes
(
message
.
getNotifyTimes
()
+
1
);
try
{
response
=
(
String
)
genericService
.
$invoke
(
"updatePaySuccess"
,
new
String
[]{
String
.
class
.
getName
()},
new
Object
[]{
message
.
getOrderId
()});
response
=
(
String
)
genericService
.
$invoke
(
methodName
,
new
String
[]{
String
.
class
.
getName
(),
Integer
.
class
.
getName
()},
new
Object
[]{
message
.
getOrderId
(),
transaction
.
getPrice
()});
if
(
"success"
.
equals
(
response
))
{
// 情况一,请求成功且返回成功
// 更新通知成功
updateTask
.
setStatus
(
PayTransactionNotifyStatusEnum
.
SUCCESS
.
getValue
());
...
...
@@ -87,7 +131,7 @@ public class PayTransactionPaySuccessConsumer implements RocketMQListener<PayTra
handleFailure
(
updateTask
,
PayTransactionNotifyStatusEnum
.
REQUEST_FAILURE
.
getValue
());
payTransactionNotifyTaskMapper
.
update
(
updateTask
);
// 抛出异常,回滚事务
throw
e
;
throw
e
;
// TODO 芋艿,此处不能抛出异常。因为,会导致 MQ + 定时任务多重试。此处的目标是,事务回滚 + 吃掉事务。另外,最后的 finally 的日志,要插入成功。
}
finally
{
// 插入 PayTransactionNotifyLogDO 日志
PayTransactionNotifyLogDO
notifyLog
=
new
PayTransactionNotifyLogDO
().
setNotifyId
(
message
.
getId
())
...
...
@@ -105,4 +149,4 @@ public class PayTransactionPaySuccessConsumer implements RocketMQListener<PayTra
}
}
}
\ No newline at end of file
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论