7.15 拼团锁单和小商场对接
This commit is contained in:
parent
fbaa6b06dc
commit
89d4b04e9c
@ -14,6 +14,7 @@ services:
|
|||||||
- "13306:3306"
|
- "13306:3306"
|
||||||
volumes:
|
volumes:
|
||||||
- ./mysql/sql:/docker-entrypoint-initdb.d
|
- ./mysql/sql:/docker-entrypoint-initdb.d
|
||||||
|
- ./mysql/my.cnf:/etc/mysql/conf.d/mysql.cnf:ro
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
|
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
|
||||||
interval: 5s
|
interval: 5s
|
||||||
|
@ -14,6 +14,7 @@ services:
|
|||||||
- "13306:3306"
|
- "13306:3306"
|
||||||
volumes:
|
volumes:
|
||||||
- ./mysql/sql:/docker-entrypoint-initdb.d
|
- ./mysql/sql:/docker-entrypoint-initdb.d
|
||||||
|
- ./mysql/my.cnf:/etc/mysql/conf.d/mysql.cnf:ro
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
|
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
|
||||||
interval: 5s
|
interval: 5s
|
||||||
|
24
docs/dev-ops/mysql/my.cnf
Normal file
24
docs/dev-ops/mysql/my.cnf
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
[client]
|
||||||
|
port = 3306
|
||||||
|
default-character-set = utf8mb4
|
||||||
|
|
||||||
|
[mysqld]
|
||||||
|
user = mysql
|
||||||
|
port = 3306
|
||||||
|
sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
|
||||||
|
|
||||||
|
default-storage-engine = InnoDB
|
||||||
|
default-authentication-plugin = mysql_native_password
|
||||||
|
character-set-server = utf8mb4
|
||||||
|
collation-server = utf8mb4_unicode_ci
|
||||||
|
init_connect = 'SET NAMES utf8mb4'
|
||||||
|
|
||||||
|
slow_query_log
|
||||||
|
#long_query_time = 3
|
||||||
|
slow-query-log-file = /var/log/mysql/mysql.slow.log
|
||||||
|
log-error = /var/log/mysql/mysql.error.log
|
||||||
|
|
||||||
|
default-time-zone = '+8:00'
|
||||||
|
|
||||||
|
[mysql]
|
||||||
|
default-character-set = utf8mb4
|
@ -11,7 +11,7 @@
|
|||||||
Target Server Version : 80042
|
Target Server Version : 80042
|
||||||
File Encoding : 65001
|
File Encoding : 65001
|
||||||
|
|
||||||
Date: 13/07/2025 14:21:55
|
Date: 15/07/2025 14:36:57
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SET NAMES utf8mb4;
|
SET NAMES utf8mb4;
|
||||||
@ -32,17 +32,19 @@ CREATE TABLE `pay_order` (
|
|||||||
`status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '订单状态;create-创建完成、pay_wait-等待支付、pay_success-支付成功、deal_done-交易完成、close-订单关单',
|
`status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '订单状态;create-创建完成、pay_wait-等待支付、pay_success-支付成功、deal_done-交易完成、close-订单关单',
|
||||||
`pay_url` varchar(2014) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '支付信息',
|
`pay_url` varchar(2014) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '支付信息',
|
||||||
`pay_time` datetime NULL DEFAULT NULL COMMENT '支付时间',
|
`pay_time` datetime NULL DEFAULT NULL COMMENT '支付时间',
|
||||||
|
`market_type` tinyint(1) NULL DEFAULT NULL COMMENT '营销类型;0无营销、1拼团营销',
|
||||||
|
`market_deduction_amount` decimal(8, 2) NULL DEFAULT NULL COMMENT '营销金额;优惠金额',
|
||||||
|
`pay_amount` decimal(8, 2) NOT NULL COMMENT '支付金额',
|
||||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
PRIMARY KEY (`id`) USING BTREE,
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
UNIQUE INDEX `uq_order_id`(`order_id` ASC) USING BTREE,
|
UNIQUE INDEX `uq_order_id`(`order_id` ASC) USING BTREE,
|
||||||
INDEX `idx_user_id_product_id`(`user_id` ASC, `product_id` ASC) USING BTREE
|
INDEX `idx_user_id_product_id`(`user_id` ASC, `product_id` ASC) USING BTREE
|
||||||
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
|
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
|
||||||
|
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of pay_order
|
-- Records of pay_order
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
INSERT INTO `pay_order` VALUES (5, 'smile01', '10001', '测试商品', '51403944017404', '2025-07-12 05:49:16', 1.68, 'PAY_WAIT', '<form name=\"punchout_form\" method=\"post\" action=\"https://openapi-sandbox.dl.alipaydev.com/gateway.do?charset=utf-8&method=alipay.trade.page.pay&sign=Af8UHbR23xcDThup0mv3NVZLlkMAcQ3tjmqGNBpwYqJ1Xn1ytqt42NWBsbDxKHT3rEo3h3dmd60wJ9N0LTmjElq%2B9HGFukp7KtxOiZRlbxip9x9yl4mCjQTUunf6l7iMsUAAtBUh%2FiVJOsI7Uy4Jy8Fg7fqjRAjc06fKcsynU5wb3xtOhr9f8uQIpe7ykxLg3Uc6YyR9GYdTcceVRu15BoSur6xz4S%2FMhRTOqc8XbWrqBGhvWMk%2BV6FHbx04AHYg7HHc0%2FTndoIHFSX9c1h7Jysxbyxp3q40GMfrnpX53VkqcPpQBbLA8f%2BWO8MnzbnxobeKcXAR11gxSbl4FcEWng%3D%3D&return_url=https%3A%2F%2Fblog.bitday.top¬ify_url=https%3A%2F%2Fpay.bitday.top%2Fapi%2Fv1%2Falipay%2Falipay_notify_url&version=1.0&app_id=9021000150645052&sign_type=RSA2×tamp=2025-07-13+14%3A21%3A33&alipay_sdk=alipay-sdk-java-4.38.157.ALL&format=json\">\n<input type=\"hidden\" name=\"biz_content\" value=\"{"out_trade_no":"51403944017404","total_amount":"1.68","subject":"测试商品","product_code":"FAST_INSTANT_TRADE_PAY"}\">\n<input type=\"submit\" value=\"立即支付\" style=\"display:none\" >\n</form>\n<script>document.forms[0].submit();</script>', NULL, '2025-07-12 13:49:15', '2025-07-13 14:21:33');
|
INSERT INTO `pay_order` VALUES (18, 'smile02', '9890001', 'MyBatisBook', '855240590150', '2025-07-15 06:35:57', 100.00, 'PAY_WAIT', '<form name=\"punchout_form\" method=\"post\" action=\"https://openapi-sandbox.dl.alipaydev.com/gateway.do?charset=utf-8&method=alipay.trade.page.pay&sign=qPjHpyXTrmdn%2BGc4H4tqQ0i8MakJ%2BmNNAASwHRwizg0KEQ0YksmQyub3q4IzVOUjkRGj1HuxUdIgKLfJg9h%2F%2B%2FRuVXRa4DNCMw1dUmFXhH2sThvzbRGPAUaR2Nb2B0TAr77X6aDu%2FzWxhLHCkRf2mTaAGoKhuhySf6gxZeJp7Izwu9kka4wlzD1M08KHPWzmrszyJbcH%2BwJsrPHe%2B82%2B9GkJw0pi10nVX9BBPp6ss17zlYgbk8Sg4EWAIEaNZ46RxUDPznPhHNM%2FXY2awBHfNTqbY17eY%2Bu8Tl9nVnKpNXIBiKgG3SlMA0FEi1%2FTjNMkiQPfYr9YcCGwzQWdPJwQxQ%3D%3D&return_url=https%3A%2F%2Fblog.bitday.top¬ify_url=https%3A%2F%2Fpay.bitday.top%2Fapi%2Fv1%2Falipay%2Falipay_notify_url&version=1.0&app_id=9021000150645052&sign_type=RSA2×tamp=2025-07-15+14%3A35%3A57&alipay_sdk=alipay-sdk-java-4.38.157.ALL&format=json\">\n<input type=\"hidden\" name=\"biz_content\" value=\"{"out_trade_no":"855240590150","total_amount":80.00,"subject":"MyBatisBook","product_code":"FAST_INSTANT_TRADE_PAY"}\">\n<input type=\"submit\" value=\"立即支付\" style=\"display:none\" >\n</form>\n<script>document.forms[0].submit();</script>', NULL, 1, 20.00, 80.00, '2025-07-15 14:35:56', '2025-07-15 14:35:57');
|
||||||
INSERT INTO `pay_order` VALUES (6, '10001', '10001', '测试商品', '66665553128265', '2025-07-13 06:19:11', 1.68, 'PAY_WAIT', '<form name=\"punchout_form\" method=\"post\" action=\"https://openapi-sandbox.dl.alipaydev.com/gateway.do?charset=utf-8&method=alipay.trade.page.pay&sign=lQ1WTro6vDXTQet%2Bd%2BJ7TWIIWXF%2B5SWg0r53joEBUesQL12UtgHrWa%2BafAwjkJWxH9zPqwAvFuXr1ZFfmMnqz1PTsRXo4ACTAJC0Se2uFSYAU1HK8Cyk4jHh9OwEjW1MQXdWT1l52KjLuZOBeJAlUvVPyAfxQnBx0HF2XKHEfFLFBgeRufAp%2BEzCM%2BoX8l0G%2FkQdskCRhICLMh2tFj2T4i4sgsSwuJQDV%2Fs0EOwpDpDKV3Z9xPEzkI2zZM6ZB8jCfTa734H8%2BC9IWZmKX2njnNj89g4h9RVuLd92l0veNn%2FJmrxTz296eCWJl6yU5PLSB0pX0IiSnUoHiySFnrswaA%3D%3D&return_url=https%3A%2F%2Fblog.bitday.top¬ify_url=https%3A%2F%2Fpay.bitday.top%2Fapi%2Fv1%2Falipay%2Falipay_notify_url&version=1.0&app_id=9021000150645052&sign_type=RSA2×tamp=2025-07-13+14%3A19%3A11&alipay_sdk=alipay-sdk-java-4.38.157.ALL&format=json\">\n<input type=\"hidden\" name=\"biz_content\" value=\"{"out_trade_no":"66665553128265","total_amount":"1.68","subject":"测试商品","product_code":"FAST_INSTANT_TRADE_PAY"}\">\n<input type=\"submit\" value=\"立即支付\" style=\"display:none\" >\n</form>\n<script>document.forms[0].submit();</script>', NULL, '2025-07-13 14:19:11', '2025-07-13 14:21:21');
|
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
@ -9,5 +9,11 @@ public class CreatePayRequestDTO {
|
|||||||
private String userId;
|
private String userId;
|
||||||
// 产品编号
|
// 产品编号
|
||||||
private String productId;
|
private String productId;
|
||||||
|
// 拼团队伍 - 队伍ID
|
||||||
|
private String teamId;
|
||||||
|
// 活动ID,来自于页面调用拼团试算后,获得的活动ID信息
|
||||||
|
private Long activityId;
|
||||||
|
// 营销类型 - 0无营销
|
||||||
|
private Integer marketType = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package edu.whut.config;
|
package edu.whut.config;
|
||||||
|
|
||||||
|
import edu.whut.infrastructure.gateway.IGroupBuyMarketService;
|
||||||
import edu.whut.infrastructure.gateway.IWeixinApiService;
|
import edu.whut.infrastructure.gateway.IWeixinApiService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import retrofit2.Retrofit;
|
import retrofit2.Retrofit;
|
||||||
@ -14,25 +16,29 @@ public class Retrofit2Config {
|
|||||||
// 微信开放平台的基础 URL,后续所有接口都会在这个前缀下拼接路径
|
// 微信开放平台的基础 URL,后续所有接口都会在这个前缀下拼接路径
|
||||||
private static final String BASE_URL = "https://api.weixin.qq.com/";
|
private static final String BASE_URL = "https://api.weixin.qq.com/";
|
||||||
|
|
||||||
/**
|
@Value("${app.config.group-buy-market.api-url}")
|
||||||
* 创建一个 Retrofit 对象,并注册为 Spring Bean
|
private String groupBuyMarketApiUrl;
|
||||||
* - baseUrl:设置所有请求的公共前缀
|
|
||||||
* - addConverterFactory:添加 Jackson 转换器,用于 JSON <-> Java 对象的自动映射
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public Retrofit retrofit() {
|
|
||||||
return new Retrofit.Builder()
|
|
||||||
.baseUrl(BASE_URL)
|
|
||||||
.addConverterFactory(JacksonConverterFactory.create()).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过 Retrofit 动态生成 IWeixinApiService 接口的实现,
|
* 通过 Retrofit 动态生成 IWeixinApiService 接口的实现,
|
||||||
* 并注册为 Spring 容器中的 Bean,方便业务层直接注入使用
|
* 并注册为 Spring 容器中的 Bean,方便业务层直接注入使用
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public IWeixinApiService weixinApiService(Retrofit retrofit) {
|
public IWeixinApiService weixinApiService() {
|
||||||
|
Retrofit retrofit = new Retrofit.Builder()
|
||||||
|
.baseUrl(BASE_URL)
|
||||||
|
.addConverterFactory(JacksonConverterFactory.create()).build();
|
||||||
return retrofit.create(IWeixinApiService.class);
|
return retrofit.create(IWeixinApiService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public IGroupBuyMarketService groupBuyMarketService() {
|
||||||
|
Retrofit retrofit = new Retrofit.Builder()
|
||||||
|
.baseUrl(groupBuyMarketApiUrl)
|
||||||
|
.addConverterFactory(JacksonConverterFactory.create()).build();
|
||||||
|
|
||||||
|
return retrofit.create(IGroupBuyMarketService.class);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,20 @@
|
|||||||
server:
|
server:
|
||||||
port: 8092
|
port: 8092
|
||||||
|
|
||||||
|
# 应用配置
|
||||||
|
app:
|
||||||
|
config:
|
||||||
|
# 版本,方便通过接口版本升级
|
||||||
|
api-version: v1
|
||||||
|
# 跨域,开发阶段可以设置为 * 不限制
|
||||||
|
cross-origin: '*'
|
||||||
|
# SC 渠道配置 - 拼团对接渠道值、回调通知
|
||||||
|
group-buy-market:
|
||||||
|
api-url: http://127.0.0.1:8091
|
||||||
|
notify-url: http://127.0.0.1:8091/api/v1/test/group_buy_notify
|
||||||
|
source: s01
|
||||||
|
chanel: c01
|
||||||
|
|
||||||
# 线程池配置
|
# 线程池配置
|
||||||
thread:
|
thread:
|
||||||
pool:
|
pool:
|
||||||
|
@ -13,15 +13,18 @@
|
|||||||
<result column="status" property="status"/>
|
<result column="status" property="status"/>
|
||||||
<result column="pay_url" property="payUrl"/>
|
<result column="pay_url" property="payUrl"/>
|
||||||
<result column="pay_time" property="payTime"/>
|
<result column="pay_time" property="payTime"/>
|
||||||
|
<result column="market_type" property="marketType"/>
|
||||||
|
<result column="market_deduction_amount" property="marketDeductionAmount"/>
|
||||||
|
<result column="pay_amount" property="payAmount"/>
|
||||||
<result column="create_time" property="createTime"/>
|
<result column="create_time" property="createTime"/>
|
||||||
<result column="update_time" property="updateTime"/>
|
<result column="update_time" property="updateTime"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<insert id="insert" parameterType="edu.whut.infrastructure.dao.po.PayOrder">
|
<insert id="insert" parameterType="edu.whut.infrastructure.dao.po.PayOrder">
|
||||||
insert into pay_order(user_id, product_id, product_name, order_id, order_time,
|
insert into pay_order(user_id, product_id, product_name, order_id, order_time,
|
||||||
total_amount, status, create_time, update_time)
|
total_amount, status, market_type, market_deduction_amount, pay_amount, create_time, update_time)
|
||||||
values(#{userId}, #{productId}, #{productName}, #{orderId}, #{orderTime},
|
values(#{userId}, #{productId}, #{productName}, #{orderId}, #{orderTime},
|
||||||
#{totalAmount}, #{status}, now(), now())
|
#{totalAmount}, #{status}, #{marketType}, #{marketDeductionAmount}, #{payAmount}, now(), now())
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
<select id="queryUnPayOrder" parameterType="edu.whut.infrastructure.dao.po.PayOrder" resultMap="dataMap">
|
<select id="queryUnPayOrder" parameterType="edu.whut.infrastructure.dao.po.PayOrder" resultMap="dataMap">
|
||||||
@ -33,7 +36,9 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<update id="updateOrderPayInfo" parameterType="edu.whut.infrastructure.dao.po.PayOrder">
|
<update id="updateOrderPayInfo" parameterType="edu.whut.infrastructure.dao.po.PayOrder">
|
||||||
update pay_order set pay_url = #{payUrl}, status = #{status}, update_time = now()
|
update pay_order set pay_url = #{payUrl}, status = #{status},
|
||||||
|
market_type = #{marketType}, market_deduction_amount = #{marketDeductionAmount}, pay_amount = #{payAmount},
|
||||||
|
update_time = now()
|
||||||
where order_id = #{orderId}
|
where order_id = #{orderId}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package edu.whut.test.domain;
|
|||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import edu.whut.domain.order.model.entity.PayOrderEntity;
|
import edu.whut.domain.order.model.entity.PayOrderEntity;
|
||||||
import edu.whut.domain.order.model.entity.ShopCartEntity;
|
import edu.whut.domain.order.model.entity.ShopCartEntity;
|
||||||
|
import edu.whut.domain.order.model.valobj.MarketTypeVO;
|
||||||
import edu.whut.domain.order.service.IOrderService;
|
import edu.whut.domain.order.service.IOrderService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -15,16 +16,20 @@ import javax.annotation.Resource;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class OrderServiceTest {
|
public class OrderServiceTest {
|
||||||
|
|
||||||
private final IOrderService orderService;
|
@Resource // 或者 @Autowired
|
||||||
|
private IOrderService orderService;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test_createOrder() throws Exception {
|
public void test_createOrder() throws Exception {
|
||||||
ShopCartEntity shopCartEntity = new ShopCartEntity();
|
ShopCartEntity shopCartEntity = new ShopCartEntity();
|
||||||
shopCartEntity.setUserId("smile01");
|
shopCartEntity.setUserId("smile02");
|
||||||
shopCartEntity.setProductId("10001");
|
shopCartEntity.setProductId("9890001");
|
||||||
|
shopCartEntity.setTeamId(null);
|
||||||
|
shopCartEntity.setActivityId(100123L);
|
||||||
|
shopCartEntity.setMarketTypeVO(MarketTypeVO.GROUP_BUY_MARKET);
|
||||||
|
|
||||||
PayOrderEntity payOrderEntity = orderService.createOrder(shopCartEntity);
|
PayOrderEntity payOrderEntity = orderService.createOrder(shopCartEntity);
|
||||||
log.info("请求参数:{}", JSON.toJSONString(shopCartEntity));
|
log.info("请求参数:{}", JSON.toJSONString(shopCartEntity));
|
||||||
log.info("测试结果:{}", JSON.toJSONString(payOrderEntity));
|
log.info("测试结果:{}", JSON.toJSONString(payOrderEntity));
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
package edu.whut.domain.order.adapter.port;
|
package edu.whut.domain.order.adapter.port;
|
||||||
|
|
||||||
|
|
||||||
|
import edu.whut.domain.order.model.entity.MarketPayDiscountEntity;
|
||||||
import edu.whut.domain.order.model.entity.ProductEntity;
|
import edu.whut.domain.order.model.entity.ProductEntity;
|
||||||
|
|
||||||
public interface IProductPort {
|
public interface IProductPort {
|
||||||
ProductEntity queryProductByProductId(String productId);
|
ProductEntity queryProductByProductId(String productId);
|
||||||
|
|
||||||
|
MarketPayDiscountEntity lockMarketPayOrder(String userId, String teamId, Long activityId, String productId, String orderId);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,14 @@ public class CreateOrderAggregate {
|
|||||||
|
|
||||||
private OrderEntity orderEntity;
|
private OrderEntity orderEntity;
|
||||||
|
|
||||||
public static OrderEntity buildOrderEntity(String productId, String productName){
|
public static OrderEntity buildOrderEntity(String productId, String productName, Integer marketType){
|
||||||
return OrderEntity.builder()
|
return OrderEntity.builder()
|
||||||
.productId(productId)
|
.productId(productId)
|
||||||
.productName(productName)
|
.productName(productName)
|
||||||
.orderId(RandomStringUtils.randomNumeric(14))
|
.orderId(RandomStringUtils.randomNumeric(12))
|
||||||
.orderTime(new Date())
|
.orderTime(new Date())
|
||||||
.orderStatusVO(OrderStatusVO.CREATE)
|
.orderStatusVO(OrderStatusVO.CREATE)
|
||||||
|
.marketType(marketType)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package edu.whut.domain.order.model.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 营销支付优惠
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class MarketPayDiscountEntity {
|
||||||
|
|
||||||
|
/** 原始价格 */
|
||||||
|
private BigDecimal originalPrice;
|
||||||
|
/** 折扣金额 */
|
||||||
|
private BigDecimal deductionPrice;
|
||||||
|
/** 支付金额 */
|
||||||
|
private BigDecimal payPrice;
|
||||||
|
|
||||||
|
}
|
@ -21,5 +21,11 @@ public class OrderEntity {
|
|||||||
private BigDecimal totalAmount;
|
private BigDecimal totalAmount;
|
||||||
private OrderStatusVO orderStatusVO;
|
private OrderStatusVO orderStatusVO;
|
||||||
private String payUrl;
|
private String payUrl;
|
||||||
|
// 营销类型;0无营销、1拼团营销
|
||||||
|
private Integer marketType;
|
||||||
|
// 营销金额;优惠金额
|
||||||
|
private BigDecimal marketDeductionAmount;
|
||||||
|
// 支付金额
|
||||||
|
private BigDecimal payAmount;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ import lombok.Builder;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@ -16,4 +18,11 @@ public class PayOrderEntity {
|
|||||||
private String payUrl;
|
private String payUrl;
|
||||||
private OrderStatusVO orderStatus;
|
private OrderStatusVO orderStatus;
|
||||||
|
|
||||||
|
// 营销类型;0无营销、1拼团营销
|
||||||
|
private Integer marketType;
|
||||||
|
// 营销金额;优惠金额
|
||||||
|
private BigDecimal marketDeductionAmount;
|
||||||
|
// 支付金额
|
||||||
|
private BigDecimal payAmount;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package edu.whut.domain.order.model.entity;
|
package edu.whut.domain.order.model.entity;
|
||||||
|
|
||||||
|
import edu.whut.domain.order.model.valobj.MarketTypeVO;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -11,8 +12,19 @@ import lombok.NoArgsConstructor;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class ShopCartEntity {
|
public class ShopCartEntity {
|
||||||
|
|
||||||
|
// 用户ID
|
||||||
private String userId;
|
private String userId;
|
||||||
|
|
||||||
|
// 商品ID
|
||||||
private String productId;
|
private String productId;
|
||||||
|
|
||||||
|
// 拼团组队ID,可为空,为空的时,则为用户首次创建拼团
|
||||||
|
private String teamId;
|
||||||
|
|
||||||
|
// 活动ID,来自于页面调用拼团试算后,获得的活动ID信息
|
||||||
|
private Long activityId;
|
||||||
|
|
||||||
|
// 营销类型,无营销,拼团营销
|
||||||
|
private MarketTypeVO marketTypeVO;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package edu.whut.domain.order.model.valobj;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 营销类型
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum MarketTypeVO {
|
||||||
|
|
||||||
|
|
||||||
|
NO_MARKET(0, "无营销"),
|
||||||
|
GROUP_BUY_MARKET(1, "拼团营销"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final Integer code;
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
|
||||||
|
public static MarketTypeVO valueOf(Integer code) {
|
||||||
|
switch (code) {
|
||||||
|
case 0:
|
||||||
|
return NO_MARKET;
|
||||||
|
case 1:
|
||||||
|
return GROUP_BUY_MARKET;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("err code not exist!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,10 +4,8 @@ import com.alipay.api.AlipayApiException;
|
|||||||
import edu.whut.domain.order.adapter.port.IProductPort;
|
import edu.whut.domain.order.adapter.port.IProductPort;
|
||||||
import edu.whut.domain.order.adapter.repository.IOrderRepository;
|
import edu.whut.domain.order.adapter.repository.IOrderRepository;
|
||||||
import edu.whut.domain.order.model.aggregate.CreateOrderAggregate;
|
import edu.whut.domain.order.model.aggregate.CreateOrderAggregate;
|
||||||
import edu.whut.domain.order.model.entity.OrderEntity;
|
import edu.whut.domain.order.model.entity.*;
|
||||||
import edu.whut.domain.order.model.entity.PayOrderEntity;
|
import edu.whut.domain.order.model.valobj.MarketTypeVO;
|
||||||
import edu.whut.domain.order.model.entity.ProductEntity;
|
|
||||||
import edu.whut.domain.order.model.entity.ShopCartEntity;
|
|
||||||
import edu.whut.domain.order.model.valobj.OrderStatusVO;
|
import edu.whut.domain.order.model.valobj.OrderStatusVO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@ -32,44 +30,86 @@ public abstract class AbstractOrderService implements IOrderService {
|
|||||||
// 1. 查询当前用户是否存在掉单和未支付订单
|
// 1. 查询当前用户是否存在掉单和未支付订单
|
||||||
OrderEntity unpaidOrderEntity = repository.queryUnPayOrder(shopCartEntity);
|
OrderEntity unpaidOrderEntity = repository.queryUnPayOrder(shopCartEntity);
|
||||||
|
|
||||||
// 如果已有订单正在等待支付,直接复用
|
// 如果已有未支付订单且状态为支付等待,则直接复用
|
||||||
if (null != unpaidOrderEntity && OrderStatusVO.PAY_WAIT.equals(unpaidOrderEntity.getOrderStatusVO())) {
|
if (unpaidOrderEntity != null && OrderStatusVO.PAY_WAIT.equals(unpaidOrderEntity.getOrderStatusVO())) {
|
||||||
log.info("创建订单-存在,已存在未支付订单。userId:{} productId:{} orderId:{}", shopCartEntity.getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getOrderId());
|
log.info("创建订单-存在,已存在未支付订单。userId:{} productId:{} orderId:{}",
|
||||||
|
shopCartEntity.getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getOrderId());
|
||||||
return PayOrderEntity.builder()
|
return PayOrderEntity.builder()
|
||||||
.orderId(unpaidOrderEntity.getOrderId())
|
.orderId(unpaidOrderEntity.getOrderId())
|
||||||
.payUrl(unpaidOrderEntity.getPayUrl())
|
.payUrl(unpaidOrderEntity.getPayUrl())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
} else if (null != unpaidOrderEntity && OrderStatusVO.CREATE.equals(unpaidOrderEntity.getOrderStatusVO())) {
|
// 如果已有订单仅创建了记录但未生成支付单,则生成支付单
|
||||||
log.info("创建订单-存在,存在未创建'支付单'订单,创建支付单开始 userId:{} productId:{} orderId:{}", shopCartEntity.getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getOrderId());
|
} else if (unpaidOrderEntity != null && OrderStatusVO.CREATE.equals(unpaidOrderEntity.getOrderStatusVO())) {
|
||||||
PayOrderEntity payOrderEntity = doPrepayOrder(shopCartEntity.getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getProductName(), unpaidOrderEntity.getOrderId(), unpaidOrderEntity.getTotalAmount());
|
log.info("创建订单-存在,存在未创建支付单订单,创建支付单开始 userId:{} productId:{} orderId:{}",
|
||||||
|
shopCartEntity.getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getOrderId());
|
||||||
|
Integer marketType = unpaidOrderEntity.getMarketType();
|
||||||
|
BigDecimal marketDeductionAmount = unpaidOrderEntity.getMarketDeductionAmount();
|
||||||
|
PayOrderEntity payOrderEntity;
|
||||||
|
|
||||||
|
if (MarketTypeVO.GROUP_BUY_MARKET.getCode().equals(marketType) && marketDeductionAmount == null) {
|
||||||
|
MarketPayDiscountEntity discount = lockMarketPayOrder(
|
||||||
|
shopCartEntity.getUserId(), shopCartEntity.getTeamId(),
|
||||||
|
shopCartEntity.getActivityId(), shopCartEntity.getProductId(),
|
||||||
|
unpaidOrderEntity.getOrderId());
|
||||||
|
payOrderEntity = doPrepayOrder(
|
||||||
|
shopCartEntity.getUserId(), shopCartEntity.getProductId(),
|
||||||
|
unpaidOrderEntity.getProductName(), unpaidOrderEntity.getOrderId(),
|
||||||
|
unpaidOrderEntity.getTotalAmount(), discount);
|
||||||
|
} else if (MarketTypeVO.GROUP_BUY_MARKET.getCode().equals(marketType)) {
|
||||||
|
payOrderEntity = doPrepayOrder(
|
||||||
|
shopCartEntity.getUserId(), shopCartEntity.getProductId(),
|
||||||
|
unpaidOrderEntity.getProductName(), unpaidOrderEntity.getOrderId(),
|
||||||
|
unpaidOrderEntity.getPayAmount());
|
||||||
|
} else {
|
||||||
|
payOrderEntity = doPrepayOrder(
|
||||||
|
shopCartEntity.getUserId(), shopCartEntity.getProductId(),
|
||||||
|
unpaidOrderEntity.getProductName(), unpaidOrderEntity.getOrderId(),
|
||||||
|
unpaidOrderEntity.getTotalAmount());
|
||||||
|
}
|
||||||
|
|
||||||
return PayOrderEntity.builder()
|
return PayOrderEntity.builder()
|
||||||
.orderId(payOrderEntity.getOrderId())
|
.orderId(payOrderEntity.getOrderId())
|
||||||
.payUrl(payOrderEntity.getPayUrl())
|
.payUrl(payOrderEntity.getPayUrl())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 调用产品服务,查询商品详细信息
|
// 2. 查询商品信息
|
||||||
ProductEntity productEntity = port.queryProductByProductId(shopCartEntity.getProductId());
|
ProductEntity productEntity = port.queryProductByProductId(shopCartEntity.getProductId());
|
||||||
|
|
||||||
// 3. 构建基础 OrderEntity(含 orderId、时间等)
|
// 3. 构建新的订单实体,并保存
|
||||||
OrderEntity orderEntity = CreateOrderAggregate.buildOrderEntity(productEntity.getProductId(), productEntity.getProductName());
|
OrderEntity orderEntity = CreateOrderAggregate.buildOrderEntity(
|
||||||
|
productEntity.getProductId(),
|
||||||
// 4. 组装聚合根:聚合中包含用户、商品和待持久化的订单实体
|
productEntity.getProductName(),
|
||||||
|
shopCartEntity.getMarketTypeVO().getCode());
|
||||||
CreateOrderAggregate orderAggregate = CreateOrderAggregate.builder()
|
CreateOrderAggregate orderAggregate = CreateOrderAggregate.builder()
|
||||||
.userId(shopCartEntity.getUserId())
|
.userId(shopCartEntity.getUserId())
|
||||||
.productEntity(productEntity)
|
.productEntity(productEntity)
|
||||||
.orderEntity(orderEntity)
|
.orderEntity(orderEntity)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// 5. 交由子类实现,保存订单聚合
|
|
||||||
this.doSaveOrder(orderAggregate);
|
this.doSaveOrder(orderAggregate);
|
||||||
|
|
||||||
PayOrderEntity payOrderEntity = doPrepayOrder(shopCartEntity.getUserId(), productEntity.getProductId(), productEntity.getProductName(), orderEntity.getOrderId(), productEntity.getPrice());
|
// 4. 如果是拼团,发起营销锁单
|
||||||
log.info("创建订单-完成,生成支付单。userId: {} orderId: {} payUrl: {}", shopCartEntity.getUserId(), orderEntity.getOrderId(), payOrderEntity.getPayUrl());
|
MarketPayDiscountEntity marketPayDiscountEntity = null;
|
||||||
|
if (MarketTypeVO.GROUP_BUY_MARKET.equals(shopCartEntity.getMarketTypeVO())) {
|
||||||
|
marketPayDiscountEntity = this.lockMarketPayOrder(
|
||||||
|
shopCartEntity.getUserId(), shopCartEntity.getTeamId(),
|
||||||
|
shopCartEntity.getActivityId(), shopCartEntity.getProductId(),
|
||||||
|
orderEntity.getOrderId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 创建支付订单
|
||||||
|
PayOrderEntity payOrderEntity = doPrepayOrder(
|
||||||
|
shopCartEntity.getUserId(),
|
||||||
|
productEntity.getProductId(),
|
||||||
|
productEntity.getProductName(),
|
||||||
|
orderEntity.getOrderId(),
|
||||||
|
productEntity.getPrice(),
|
||||||
|
marketPayDiscountEntity);
|
||||||
|
|
||||||
|
log.info("创建订单-完成,生成支付单。userId: {} orderId: {} payUrl: {}",
|
||||||
|
shopCartEntity.getUserId(), orderEntity.getOrderId(), payOrderEntity.getPayUrl());
|
||||||
|
|
||||||
// 6. 返回支付实体
|
|
||||||
return PayOrderEntity.builder()
|
return PayOrderEntity.builder()
|
||||||
.orderId(orderEntity.getOrderId())
|
.orderId(orderEntity.getOrderId())
|
||||||
.payUrl(payOrderEntity.getPayUrl())
|
.payUrl(payOrderEntity.getPayUrl())
|
||||||
@ -81,5 +121,10 @@ public abstract class AbstractOrderService implements IOrderService {
|
|||||||
*/
|
*/
|
||||||
protected abstract void doSaveOrder(CreateOrderAggregate orderAggregate);
|
protected abstract void doSaveOrder(CreateOrderAggregate orderAggregate);
|
||||||
|
|
||||||
|
protected abstract MarketPayDiscountEntity lockMarketPayOrder(String userId, String teamId, Long activityId, String productId, String orderId);
|
||||||
|
|
||||||
protected abstract PayOrderEntity doPrepayOrder(String userId, String productId, String productName, String orderId, BigDecimal totalAmount) throws AlipayApiException;
|
protected abstract PayOrderEntity doPrepayOrder(String userId, String productId, String productName, String orderId, BigDecimal totalAmount) throws AlipayApiException;
|
||||||
|
|
||||||
|
protected abstract PayOrderEntity doPrepayOrder(String userId, String productId, String productName, String orderId, BigDecimal totalAmount, MarketPayDiscountEntity marketPayDiscountEntity) throws AlipayApiException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,9 @@ import com.alipay.api.request.AlipayTradePagePayRequest;
|
|||||||
import edu.whut.domain.order.adapter.port.IProductPort;
|
import edu.whut.domain.order.adapter.port.IProductPort;
|
||||||
import edu.whut.domain.order.adapter.repository.IOrderRepository;
|
import edu.whut.domain.order.adapter.repository.IOrderRepository;
|
||||||
import edu.whut.domain.order.model.aggregate.CreateOrderAggregate;
|
import edu.whut.domain.order.model.aggregate.CreateOrderAggregate;
|
||||||
|
import edu.whut.domain.order.model.entity.MarketPayDiscountEntity;
|
||||||
import edu.whut.domain.order.model.entity.PayOrderEntity;
|
import edu.whut.domain.order.model.entity.PayOrderEntity;
|
||||||
|
import edu.whut.domain.order.model.valobj.MarketTypeVO;
|
||||||
import edu.whut.domain.order.model.valobj.OrderStatusVO;
|
import edu.whut.domain.order.model.valobj.OrderStatusVO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@ -37,18 +39,31 @@ public class OrderService extends AbstractOrderService{
|
|||||||
repository.doSaveOrder(orderAggregate);
|
repository.doSaveOrder(orderAggregate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MarketPayDiscountEntity lockMarketPayOrder(String userId, String teamId, Long activityId, String productId, String orderId) {
|
||||||
|
return port.lockMarketPayOrder(userId, teamId, activityId, productId, orderId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预支付订单
|
* 预支付订单
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected PayOrderEntity doPrepayOrder(String userId, String productId, String productName, String orderId, BigDecimal totalAmount) throws AlipayApiException {
|
protected PayOrderEntity doPrepayOrder(String userId, String productId, String productName, String orderId, BigDecimal totalAmount) throws AlipayApiException {
|
||||||
|
return doPrepayOrder(userId, productId, productName, orderId, totalAmount, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PayOrderEntity doPrepayOrder(String userId, String productId, String productName, String orderId, BigDecimal totalAmount, MarketPayDiscountEntity marketPayDiscountEntity) throws AlipayApiException {
|
||||||
|
// 支付金额
|
||||||
|
BigDecimal payAmount = null == marketPayDiscountEntity ? totalAmount : marketPayDiscountEntity.getPayPrice();
|
||||||
|
|
||||||
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
|
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
|
||||||
request.setNotifyUrl(notifyUrl);
|
request.setNotifyUrl(notifyUrl);
|
||||||
request.setReturnUrl(returnUrl);
|
request.setReturnUrl(returnUrl);
|
||||||
|
|
||||||
JSONObject bizContent = new JSONObject();
|
JSONObject bizContent = new JSONObject();
|
||||||
bizContent.put("out_trade_no", orderId);
|
bizContent.put("out_trade_no", orderId);
|
||||||
bizContent.put("total_amount", totalAmount.toString());
|
bizContent.put("total_amount", payAmount);
|
||||||
bizContent.put("subject", productName);
|
bizContent.put("subject", productName);
|
||||||
bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
|
bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
|
||||||
request.setBizContent(bizContent.toString());
|
request.setBizContent(bizContent.toString());
|
||||||
@ -58,9 +73,13 @@ public class OrderService extends AbstractOrderService{
|
|||||||
PayOrderEntity payOrderEntity = new PayOrderEntity();
|
PayOrderEntity payOrderEntity = new PayOrderEntity();
|
||||||
payOrderEntity.setOrderId(orderId);
|
payOrderEntity.setOrderId(orderId);
|
||||||
payOrderEntity.setPayUrl(form);
|
payOrderEntity.setPayUrl(form);
|
||||||
//等待支付
|
|
||||||
payOrderEntity.setOrderStatus(OrderStatusVO.PAY_WAIT);
|
payOrderEntity.setOrderStatus(OrderStatusVO.PAY_WAIT);
|
||||||
|
|
||||||
|
// 营销信息
|
||||||
|
payOrderEntity.setMarketType(null == marketPayDiscountEntity ? MarketTypeVO.NO_MARKET.getCode() : MarketTypeVO.GROUP_BUY_MARKET.getCode());
|
||||||
|
payOrderEntity.setMarketDeductionAmount(null == marketPayDiscountEntity ? BigDecimal.ZERO : marketPayDiscountEntity.getDeductionPrice());
|
||||||
|
payOrderEntity.setPayAmount(payAmount);
|
||||||
|
|
||||||
repository.updateOrderPayInfo(payOrderEntity);
|
repository.updateOrderPayInfo(payOrderEntity);
|
||||||
|
|
||||||
return payOrderEntity;
|
return payOrderEntity;
|
||||||
|
@ -30,6 +30,11 @@
|
|||||||
<groupId>com.squareup.retrofit2</groupId>
|
<groupId>com.squareup.retrofit2</groupId>
|
||||||
<artifactId>adapter-rxjava2</artifactId>
|
<artifactId>adapter-rxjava2</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>edu.whut</groupId>
|
||||||
|
<artifactId>group-buying-sys-api</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
<!-- 系统模块 -->
|
<!-- 系统模块 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>edu.whut</groupId>
|
<groupId>edu.whut</groupId>
|
||||||
|
@ -1,29 +1,97 @@
|
|||||||
package edu.whut.infrastructure.adapter.port;
|
package edu.whut.infrastructure.adapter.port;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import edu.whut.api.dto.LockMarketPayOrderRequestDTO;
|
||||||
|
import edu.whut.api.dto.LockMarketPayOrderResponseDTO;
|
||||||
|
import edu.whut.api.response.Response;
|
||||||
import edu.whut.domain.order.adapter.port.IProductPort;
|
import edu.whut.domain.order.adapter.port.IProductPort;
|
||||||
|
import edu.whut.domain.order.model.entity.MarketPayDiscountEntity;
|
||||||
import edu.whut.domain.order.model.entity.ProductEntity;
|
import edu.whut.domain.order.model.entity.ProductEntity;
|
||||||
|
import edu.whut.infrastructure.gateway.IGroupBuyMarketService;
|
||||||
import edu.whut.infrastructure.gateway.ProductRPC;
|
import edu.whut.infrastructure.gateway.ProductRPC;
|
||||||
import edu.whut.infrastructure.gateway.dto.ProductDTO;
|
import edu.whut.infrastructure.gateway.dto.ProductDTO;
|
||||||
|
import edu.whut.types.exception.AppException;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import retrofit2.Call;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
public class ProductPort implements IProductPort {
|
public class ProductPort implements IProductPort {
|
||||||
|
|
||||||
|
@Value("${app.config.group-buy-market.source}")
|
||||||
|
private String source;
|
||||||
|
@Value("${app.config.group-buy-market.chanel}")
|
||||||
|
private String chanel;
|
||||||
|
@Value("${app.config.group-buy-market.notify-url}")
|
||||||
|
private String notifyUrl;
|
||||||
|
|
||||||
|
private final IGroupBuyMarketService groupBuyMarketService;
|
||||||
|
|
||||||
private final ProductRPC productRPC;
|
private final ProductRPC productRPC;
|
||||||
|
|
||||||
public ProductPort(ProductRPC productRPC) {
|
|
||||||
this.productRPC = productRPC;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据产品ID查询基础商品信息
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ProductEntity queryProductByProductId(String productId) {
|
public ProductEntity queryProductByProductId(String productId) {
|
||||||
ProductDTO productDTO = productRPC.queryProductByProductId(productId);
|
// 调用远程产品服务获取 DTO
|
||||||
|
ProductDTO dto = productRPC.queryProductByProductId(productId);
|
||||||
|
// 转换为领域实体并返回
|
||||||
return ProductEntity.builder()
|
return ProductEntity.builder()
|
||||||
.productId(productDTO.getProductId())
|
.productId(dto.getProductId())
|
||||||
.productName(productDTO.getProductName())
|
.productName(dto.getProductName())
|
||||||
.productDesc(productDTO.getProductDesc())
|
.productDesc(dto.getProductDesc())
|
||||||
.price(productDTO.getPrice())
|
.price(dto.getPrice())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发起营销锁单请求,获取拼团优惠信息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public MarketPayDiscountEntity lockMarketPayOrder(String userId, String teamId, Long activityId, String productId, String orderId) {
|
||||||
|
// 请求参数
|
||||||
|
LockMarketPayOrderRequestDTO requestDTO = new LockMarketPayOrderRequestDTO();
|
||||||
|
requestDTO.setUserId(userId);
|
||||||
|
requestDTO.setTeamId(teamId);
|
||||||
|
requestDTO.setGoodsId(productId);
|
||||||
|
requestDTO.setActivityId(activityId);
|
||||||
|
requestDTO.setSource(source);
|
||||||
|
requestDTO.setChannel(chanel);
|
||||||
|
requestDTO.setOutTradeNo(orderId);
|
||||||
|
requestDTO.setNotifyUrl(notifyUrl);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 发起 HTTP 请求,执行营销锁单
|
||||||
|
Call<Response<LockMarketPayOrderResponseDTO>> call = groupBuyMarketService.lockMarketPayOrder(requestDTO);
|
||||||
|
|
||||||
|
// 获取结果
|
||||||
|
Response<LockMarketPayOrderResponseDTO> response = call.execute().body();
|
||||||
|
log.info("营销锁单{} requestDTO:{} responseDTO:{}", userId, JSON.toJSONString(requestDTO), JSON.toJSONString(response));
|
||||||
|
if (null == response) return null;
|
||||||
|
|
||||||
|
// 异常判断
|
||||||
|
if (!"0000".equals(response.getCode())){
|
||||||
|
throw new AppException(response.getCode(), response.getInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
LockMarketPayOrderResponseDTO responseDTO = response.getData();
|
||||||
|
|
||||||
|
// 获取拼团优惠
|
||||||
|
return MarketPayDiscountEntity.builder()
|
||||||
|
.originalPrice(responseDTO.getOriginalPrice())
|
||||||
|
.deductionPrice(responseDTO.getDeductionPrice())
|
||||||
|
.payPrice(responseDTO.getPayPrice())
|
||||||
|
.build();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("营销锁单失败{}", userId, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import edu.whut.domain.order.model.entity.OrderEntity;
|
|||||||
import edu.whut.domain.order.model.entity.PayOrderEntity;
|
import edu.whut.domain.order.model.entity.PayOrderEntity;
|
||||||
import edu.whut.domain.order.model.entity.ProductEntity;
|
import edu.whut.domain.order.model.entity.ProductEntity;
|
||||||
import edu.whut.domain.order.model.entity.ShopCartEntity;
|
import edu.whut.domain.order.model.entity.ShopCartEntity;
|
||||||
|
import edu.whut.domain.order.model.valobj.MarketTypeVO;
|
||||||
import edu.whut.domain.order.model.valobj.OrderStatusVO;
|
import edu.whut.domain.order.model.valobj.OrderStatusVO;
|
||||||
import edu.whut.infrastructure.dao.IOrderDao;
|
import edu.whut.infrastructure.dao.IOrderDao;
|
||||||
import edu.whut.infrastructure.dao.po.PayOrder;
|
import edu.whut.infrastructure.dao.po.PayOrder;
|
||||||
@ -16,6 +17,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
@ -46,6 +48,10 @@ public class OrderRepository implements IOrderRepository {
|
|||||||
order.setOrderTime(orderEntity.getOrderTime());
|
order.setOrderTime(orderEntity.getOrderTime());
|
||||||
order.setTotalAmount(productEntity.getPrice());
|
order.setTotalAmount(productEntity.getPrice());
|
||||||
order.setStatus(orderEntity.getOrderStatusVO().getCode());
|
order.setStatus(orderEntity.getOrderStatusVO().getCode());
|
||||||
|
order.setMarketType(MarketTypeVO.NO_MARKET.getCode());
|
||||||
|
order.setMarketDeductionAmount(BigDecimal.ZERO);
|
||||||
|
order.setPayAmount(productEntity.getPrice());
|
||||||
|
order.setMarketType(orderEntity.getMarketType());
|
||||||
|
|
||||||
// 插入数据库
|
// 插入数据库
|
||||||
orderDao.insert(order);
|
orderDao.insert(order);
|
||||||
@ -74,6 +80,9 @@ public class OrderRepository implements IOrderRepository {
|
|||||||
.orderTime(order.getOrderTime())
|
.orderTime(order.getOrderTime())
|
||||||
.totalAmount(order.getTotalAmount())
|
.totalAmount(order.getTotalAmount())
|
||||||
.payUrl(order.getPayUrl())
|
.payUrl(order.getPayUrl())
|
||||||
|
.marketType(order.getMarketType())
|
||||||
|
.marketDeductionAmount(order.getMarketDeductionAmount())
|
||||||
|
.payAmount(order.getPayAmount())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +97,9 @@ public class OrderRepository implements IOrderRepository {
|
|||||||
.orderId(payOrderEntity.getOrderId())
|
.orderId(payOrderEntity.getOrderId())
|
||||||
.status(payOrderEntity.getOrderStatus().getCode())
|
.status(payOrderEntity.getOrderStatus().getCode())
|
||||||
.payUrl(payOrderEntity.getPayUrl())
|
.payUrl(payOrderEntity.getPayUrl())
|
||||||
|
.marketType(payOrderEntity.getMarketType())
|
||||||
|
.marketDeductionAmount(payOrderEntity.getMarketDeductionAmount())
|
||||||
|
.payAmount(payOrderEntity.getPayAmount())
|
||||||
.build();
|
.build();
|
||||||
orderDao.updateOrderPayInfo(payOrderReq);
|
orderDao.updateOrderPayInfo(payOrderReq);
|
||||||
}
|
}
|
||||||
|
@ -14,17 +14,35 @@ import java.util.Date;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class PayOrder {
|
public class PayOrder {
|
||||||
|
|
||||||
|
// 自增ID
|
||||||
private Long id;
|
private Long id;
|
||||||
|
// 用户ID
|
||||||
private String userId;
|
private String userId;
|
||||||
|
// 商品ID
|
||||||
private String productId;
|
private String productId;
|
||||||
|
// 商品名称
|
||||||
private String productName;
|
private String productName;
|
||||||
|
// 订单ID
|
||||||
private String orderId;
|
private String orderId;
|
||||||
|
// 下单时间
|
||||||
private Date orderTime;
|
private Date orderTime;
|
||||||
|
// 订单金额
|
||||||
private BigDecimal totalAmount;
|
private BigDecimal totalAmount;
|
||||||
|
// 订单状态;create-创建完成、pay_wait-等待支付、pay_success-支付成功、deal_done-交易完成、close-订单关单
|
||||||
private String status;
|
private String status;
|
||||||
|
// 支付信息
|
||||||
private String payUrl;
|
private String payUrl;
|
||||||
|
// 支付时间
|
||||||
private Date payTime;
|
private Date payTime;
|
||||||
|
// 营销类型;0无营销、1拼团营销
|
||||||
|
private Integer marketType;
|
||||||
|
// 营销金额;优惠金额
|
||||||
|
private BigDecimal marketDeductionAmount;
|
||||||
|
// 支付金额
|
||||||
|
private BigDecimal payAmount;
|
||||||
|
// 创建时间
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
|
// 更新时间
|
||||||
private Date updateTime;
|
private Date updateTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package edu.whut.infrastructure.gateway;
|
||||||
|
|
||||||
|
import edu.whut.api.dto.LockMarketPayOrderRequestDTO;
|
||||||
|
import edu.whut.api.dto.LockMarketPayOrderResponseDTO;
|
||||||
|
import edu.whut.api.response.Response;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.http.Body;
|
||||||
|
import retrofit2.http.POST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拼团营销
|
||||||
|
*/
|
||||||
|
public interface IGroupBuyMarketService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 营销锁单
|
||||||
|
*
|
||||||
|
* @param requestDTO 锁单商品信息
|
||||||
|
* @return 锁单结果信息
|
||||||
|
*/
|
||||||
|
@POST("api/v1/gbm/trade/lock_market_pay_order")
|
||||||
|
Call<Response<LockMarketPayOrderResponseDTO>> lockMarketPayOrder(@Body LockMarketPayOrderRequestDTO requestDTO);
|
||||||
|
|
||||||
|
}
|
@ -14,9 +14,9 @@ public class ProductRPC {
|
|||||||
public ProductDTO queryProductByProductId(String productId){
|
public ProductDTO queryProductByProductId(String productId){
|
||||||
ProductDTO productVO = new ProductDTO();
|
ProductDTO productVO = new ProductDTO();
|
||||||
productVO.setProductId(productId);
|
productVO.setProductId(productId);
|
||||||
productVO.setProductName("测试商品");
|
productVO.setProductName("MyBatisBook");
|
||||||
productVO.setProductDesc("这是一个测试商品");
|
productVO.setProductDesc("MyBatisBook");
|
||||||
productVO.setPrice(new BigDecimal("1.68"));
|
productVO.setPrice(new BigDecimal("100.00"));
|
||||||
return productVO;
|
return productVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,14 +6,13 @@ import edu.whut.api.dto.CreatePayRequestDTO;
|
|||||||
import edu.whut.api.response.Response;
|
import edu.whut.api.response.Response;
|
||||||
import edu.whut.domain.order.model.entity.PayOrderEntity;
|
import edu.whut.domain.order.model.entity.PayOrderEntity;
|
||||||
import edu.whut.domain.order.model.entity.ShopCartEntity;
|
import edu.whut.domain.order.model.entity.ShopCartEntity;
|
||||||
|
import edu.whut.domain.order.model.valobj.MarketTypeVO;
|
||||||
import edu.whut.domain.order.service.IOrderService;
|
import edu.whut.domain.order.service.IOrderService;
|
||||||
import edu.whut.types.common.Constants;
|
import edu.whut.types.common.Constants;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -43,10 +42,14 @@ public class AliPayController implements IPayService {
|
|||||||
log.info("商品下单,根据商品ID创建支付单开始 userId:{} productId:{}", createPayRequestDTO.getUserId(), createPayRequestDTO.getUserId());
|
log.info("商品下单,根据商品ID创建支付单开始 userId:{} productId:{}", createPayRequestDTO.getUserId(), createPayRequestDTO.getUserId());
|
||||||
String userId = createPayRequestDTO.getUserId();
|
String userId = createPayRequestDTO.getUserId();
|
||||||
String productId = createPayRequestDTO.getProductId();
|
String productId = createPayRequestDTO.getProductId();
|
||||||
|
String teamId = createPayRequestDTO.getTeamId();
|
||||||
|
Integer marketType = createPayRequestDTO.getMarketType();
|
||||||
// 下单
|
// 下单
|
||||||
PayOrderEntity payOrderEntity = orderService.createOrder(ShopCartEntity.builder()
|
PayOrderEntity payOrderEntity = orderService.createOrder(ShopCartEntity.builder()
|
||||||
.userId(userId)
|
.userId(userId)
|
||||||
.productId(productId)
|
.productId(productId)
|
||||||
|
.teamId(teamId)
|
||||||
|
.marketTypeVO(MarketTypeVO.valueOf(marketType))
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
log.info("商品下单,根据商品ID创建支付单完成 userId:{} productId:{} orderId:{}", userId, productId, payOrderEntity.getOrderId());
|
log.info("商品下单,根据商品ID创建支付单完成 userId:{} productId:{} orderId:{}", userId, productId, payOrderEntity.getOrderId());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user