初始化提交

This commit is contained in:
USER-20221017CE\Administrator
2022-11-01 12:14:54 +08:00
commit d31fad2aa9
1733 changed files with 370203 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
package com.tuling.tulingmall;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.ApplicationContext;
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class})
@EnableFeignClients
public class TulingmallOrderCurrApplication {
private static ApplicationContext applicationContext;
public static void main(String[] args) {
applicationContext = SpringApplication.run(TulingmallOrderCurrApplication.class, args);
}
public static <T> T getBean(String beanName) {
return applicationContext != null ? (T) applicationContext.getBean(beanName) : null;
}
}

View File

@@ -0,0 +1,104 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.tuling.tulingmall.ordercurr;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.apache.shardingsphere.transaction.core.TransactionTypeHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.transaction.annotation.Transactional;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* Order service.
*/
//@Service
public class SeataATOrderService {
private final JdbcTemplate jdbcTemplate;
@Autowired
public SeataATOrderService(final JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
* Init.
*/
public void init() {
jdbcTemplate.execute("DROP TABLE IF EXISTS t_order");
jdbcTemplate.execute("CREATE TABLE t_order (order_id BIGINT AUTO_INCREMENT, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_id))");
}
/**
* Clean up.
*/
public void cleanup() {
jdbcTemplate.execute("DROP TABLE IF EXISTS t_order");
}
/**
* Execute XA.
*
* @param count insert record count
* @return transaction type
*/
@Transactional
@ShardingTransactionType(TransactionType.BASE)
public TransactionType insert(final int count) {
return jdbcTemplate.execute("INSERT INTO t_order (user_id, status) VALUES (?, ?)", (PreparedStatementCallback<TransactionType>) preparedStatement -> {
doInsert(count, preparedStatement);
return TransactionTypeHolder.get();
});
}
/**
* Execute XA with exception.
*
* @param count insert record count
*/
@Transactional
@ShardingTransactionType(TransactionType.BASE)
public void insertFailed(final int count) {
jdbcTemplate.execute("INSERT INTO t_order (user_id, status) VALUES (?, ?)", (PreparedStatementCallback<TransactionType>) preparedStatement -> {
doInsert(count, preparedStatement);
throw new SQLException("mock transaction failed");
});
}
private void doInsert(final int count, final PreparedStatement preparedStatement) throws SQLException {
for (int i = 0; i < count; i++) {
preparedStatement.setObject(1, i);
preparedStatement.setObject(2, "init");
preparedStatement.executeUpdate();
}
}
/**
* Select all.
*
* @return record count
*/
public int selectAll() {
return jdbcTemplate.queryForObject("SELECT COUNT(1) AS count FROM t_order", Integer.class);
}
}

View File

@@ -0,0 +1,58 @@
package com.tuling.tulingmall.ordercurr.aop;/*
package com.tuling.tulingmall.aop;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.apache.shardingsphere.transaction.core.TransactionTypeHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.annotation.Annotation;
import java.util.Arrays;
*/
/**
* ,;,,;
* ,;;'( 社
* __ ,;;' ' \ 会
* /' '\'~~'~' \ /'\.) 主
* ,;( ) / |. 义
* ,;' \ /-.,,( ) \ 码
* ) / ) / )| 农
* || || \)
* (_\ (_\
*
* @author :图灵学院
* @date Created in 2020/5/7
* @version: V1.0
* @slogan: 天下风云出我辈,一入代码岁月催
* @description:
**//*
@Aspect
@Component
@Order(-1)
public class ShardingTxTypeAspj {
@Pointcut(value = "execution(* com.tuling.tulingmall.service.impl.Transaction2PcServiceImpl.insertOrder(..))")
public void pointCut(){
}
@Before(value = "pointCut()")
public void methodBefore(JoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String methodName = methodSignature.getName();
System.out.println("执行目标方法【"+methodName+"】的<前置通知>,入参"+ Arrays.asList(joinPoint.getArgs()));
Annotation[] declaredAnnotations = methodSignature.getMethod().getDeclaredAnnotations();
ShardingTransactionType declaredAnnotation = methodSignature.getMethod().getDeclaredAnnotation(ShardingTransactionType.class);
System.out.println(declaredAnnotation.value());
TransactionTypeHolder.set(declaredAnnotation.value());
}
}
*/

View File

@@ -0,0 +1,46 @@
package com.tuling.tulingmall.ordercurr.component;//package com.tuling.tulingmall.component;
//
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.tuling.tulingmall.domain.MqCancelOrder;
//import com.tuling.tulingmall.service.OmsPortalOrderService;
//import org.apache.rocketmq.common.message.Message;
//import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
//import org.apache.rocketmq.spring.core.RocketMQListener;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import java.io.IOException;
//
///**
// * 取消订单消息的处理者
// */
//@Component
//@RocketMQMessageListener(topic = "mall.order.cancel.ttl",consumerGroup = "mall-order-cancel" )
//public class CancelOrderReceiver implements RocketMQListener<MqCancelOrder> {
// private static Logger LOGGER =LoggerFactory.getLogger(CancelOrderReceiver.class);
// @Autowired
// private OmsPortalOrderService portalOrderService;
//
//// @RabbitListener(queues = "mall.order.cancel")
//// @RabbitHandler
//// public void handle(Message message) throws IOException {
////
//// ObjectMapper objectMapper = new ObjectMapper();
//// MqCancelOrder mqCancelOrder = objectMapper.readValue(message.getBody(), MqCancelOrder.class);
////
////
////
//// LOGGER.info("取消订单对象:{}",mqCancelOrder);
//// portalOrderService.cancelOrder(mqCancelOrder.getOrderId(),mqCancelOrder.getMemberId());
//// LOGGER.info("process orderId:{}",mqCancelOrder.getOrderId());
//// }
//
// @Override
// public void onMessage(MqCancelOrder mqCancelOrder) {
// LOGGER.info("取消订单对象:{}",mqCancelOrder);
// portalOrderService.cancelOrder(mqCancelOrder.getOrderId(),mqCancelOrder.getMemberId());
// LOGGER.info("process orderId:{}",mqCancelOrder.getOrderId());
// }
//}

View File

@@ -0,0 +1,37 @@
package com.tuling.tulingmall.ordercurr.component;
import com.tuling.tulingmall.ordercurr.domain.MqCancelOrder;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
/**
* 取消订单消息的发出者
*/
@Slf4j
@Component
public class CancelOrderSender implements InitializingBean {
// @Autowired
// private RabbitTemplate rabbitTemplate;
@Autowired
private RocketMQTemplate rocketMQTemplate;
public void sendMessage(MqCancelOrder mqCancelOrder, final long delayTimes){
//给延迟队列发送消息
// messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
rocketMQTemplate.syncSend("mall.order.cancel.ttl",
MessageBuilder.withPayload(mqCancelOrder).build(),5000,16);
log.info("send orderId:{}",mqCancelOrder.getOrderId());
}
@Override
public void afterPropertiesSet() throws Exception {
//设置消息转换器
// Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
// rabbitTemplate.setMessageConverter(jackson2JsonMessageConverter);
}
}

View File

@@ -0,0 +1,49 @@
package com.tuling.tulingmall.ordercurr.component;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;
/**
* @description: 缓存管理工具采用LRU淘汰策略
**/
@Slf4j
@Component
public class LocalCache<T> {
private Cache<String,T> localCache = null;
@PostConstruct
private void init(){
localCache = CacheBuilder.newBuilder()
//设置本地缓存容器的初始容量
.initialCapacity(10)
//设置本地缓存的最大容量
.maximumSize(500)
//设置写缓存后多少秒过期
.expireAfterWrite(60, TimeUnit.SECONDS).build();
}
public void setLocalCache(String key,T object){
localCache.put(key,object);
}
/***
* 返回值 如果不存在返回null
* @param key
* @param <T>
* @return
*/
public <T> T getCache(String key){
return (T) localCache.getIfPresent(key);
}
public void remove(String key){
localCache.invalidate(key);
}
}

View File

@@ -0,0 +1,29 @@
package com.tuling.tulingmall.ordercurr.component;
import com.tuling.tulingmall.common.api.CommonResult;
import com.tuling.tulingmall.ordercurr.service.OmsPortalOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 订单超时取消并解锁库存的定时器
*/
@Component
public class OrderTimeOutCancelTask {
private Logger LOGGER =LoggerFactory.getLogger(OrderTimeOutCancelTask.class);
@Autowired
private OmsPortalOrderService portalOrderService;
/**
* cron表达式Seconds Minutes Hours DayofMonth Month DayofWeek [Year]
* 每10分钟扫描一次扫描设定超时时间之前下的订单如果没支付则取消该订单
*/
@Scheduled(cron = "0 0/10 * ? * ?")
private void cancelTimeOutOrder(){
CommonResult result = portalOrderService.cancelTimeOutOrder();
LOGGER.info("取消订单并根据sku编号释放锁定库存:{}",result);
}
}

View File

@@ -0,0 +1,41 @@
package com.tuling.tulingmall.ordercurr.component;//package com.tuling.tulingmall.component;
//
//import com.tuling.tulingmall.common.constant.RedisKeyPrefixConst;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.data.redis.connection.Message;
//import org.springframework.data.redis.connection.MessageListener;
//import org.springframework.lang.Nullable;
//
//import java.nio.charset.StandardCharsets;
//
///**
// * ,;,,;
// * ,;;'( 社
// * __ ,;;' ' \ 会
// * /' '\'~~'~' \ /'\.) 主
// * ,;( ) / |. 义
// *,;' \ /-.,,( ) \ 码
// * ) / ) / )| 农
// * || || \)
// * (_\ (_\
// * @author :图灵学院
// * @date Created in 2020/4/17 19:20
// * @version: V1.0
// * @slogan: 天下风云出我辈,一入代码岁月催
// * @description:
// **/
//@Slf4j
//public class RedisChannelListener implements MessageListener {
//
// @Autowired
// private LocalCache localCache;
//
// @Override
// public void onMessage(Message message, @Nullable byte[] pattern) {
// log.info("sub message :) channel[cleanNoStockCache] !");
// String productId = new String(message.getBody(), StandardCharsets.UTF_8);
// localCache.remove(RedisKeyPrefixConst.MIAOSHA_STOCK_CACHE_PREFIX + productId);//TODO 处理
// }
//
//}

View File

@@ -0,0 +1,47 @@
package com.tuling.tulingmall.ordercurr.component;//package com.tuling.tulingmall.component;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* ,;,,;
* ,;;'( 社
* __ ,;;' ' \ 会
* /' '\'~~'~' \ /'\.) 主
* ,;( ) / |. 义
*,;' \ /-.,,( ) \ 码
* ) / ) / )| 农
* || || \)
* (_\ (_\
* @author :图灵学院
* @date Created in 2020/1/12 21:59
* @version: V1.0
* @slogan: 天下风云出我辈,一入代码岁月催
* @description: 支付宝二维码存储与访问路径设置
**/
@Component
@ConfigurationProperties(prefix = "trade.zhifu.qrcode")
@Data
public class TradePayProp {
/**
* 支付宝qrcode存储路径
*/
private String aliPayPath;
/**
* 微信支付qrcode存储路径
*/
private String weChatPath;
/**
* qrcode存储文件路径设置
*/
private String storePath;
/**
* http访问路径设置
*/
private String httpBasePath;
/**
* 支付成功回调页面
*/
private String paySuccessCallBack;
}

View File

@@ -0,0 +1,98 @@
package com.tuling.tulingmall.ordercurr.component.rocketmq;//package com.tuling.tulingmall.component.rocketmq;
//
//import com.tuling.tulingmall.common.constant.RedisKeyPrefixConst;
//import com.tuling.tulingmall.component.LocalCache;
//import com.tuling.tulingmall.domain.OrderMessage;
//import com.tuling.tulingmall.service.SecKillOrderService;
//import com.tuling.tulingmall.util.RedisOpsUtil;
//import lombok.extern.slf4j.Slf4j;
//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.Component;
//
//import java.util.Date;
//import java.util.concurrent.TimeUnit;
//
///**
// * ,;,,;
// * ,;;'( 社
// * __ ,;;' ' \ 会
// * /' '\'~~'~' \ /'\.) 主
// * ,;( ) / |. 义
// *,;' \ /-.,,( ) \ 码
// * ) / ) / )| 农
// * || || \)
// * (_\ (_\
// * @description: 消费监听rocketmq-接受订单消息
// **/
//@Slf4j
//@Component
//@RocketMQMessageListener(topic = "${rocketmq.tulingmall.asyncOrderTopic}",consumerGroup = "${rocketmq.tulingmall.asyncOrderGroup}")
//public class AscynCreateOrderReciever implements RocketMQListener<OrderMessage> {
//
// @Autowired
// private SecKillOrderService secKillOrderService;
//
// @Autowired
// private RedisOpsUtil redisOpsUtil;
//
// @Autowired
// private LocalCache<Object> cache;
//
// /**
// * 异步下单消费消息
// * @param orderMessage
// */
// @Override
// public void onMessage(OrderMessage orderMessage) {
// log.info("listen the rocketmq message");
// Long memberId = orderMessage.getOrder().getMemberId();
// Long productId = orderMessage.getOrderItem().getProductId();
// //订单编号,分库分表不用该编号做订单结果标记
// String orderSn = orderMessage.getOrder().getOrderSn();
// Integer limit = orderMessage.getFlashPromotionLimit();
// Date endDate = orderMessage.getFlashPromotionEndDate();
//
// try {
// Long orderId = secKillOrderService.asyncCreateOrder(orderMessage.getOrder(),orderMessage.getOrderItem(),orderMessage.getFlashPromotionRelationId());
//
// //更改排队标记状态,代表已经下单成功,ID设置为snowflake后,用ID作为状态标记
// redisOpsUtil.set(RedisKeyPrefixConst.MIAOSHA_ASYNC_WAITING_PREFIX + memberId
// + ":" + productId,orderId.toString(),60L, TimeUnit.SECONDS);
//
// /*
// * 设置用户购买次数,(不限制购买次数了,需要可自行放开此处,
// * 并在secKillOrderService.checkConfirm中加入验证)
// */
// /*Integer rebuy = redisOpsUtil.get(RedisKeyPrefixConst.MEMBER_BUYED_MIAOSHA_PREFIX + memberId + ":" + productId,Integer.class);
//
// if(rebuy != null){
// redisOpsUtil.decr(RedisKeyPrefixConst.MEMBER_BUYED_MIAOSHA_PREFIX + memberId + ":" + productId);
// }else{
// //剩余时间
// Date now = new Date();
// Long expired = endDate.getTime()-now.getTime();
// //打上购买次数标记
// redisOpsUtil.set(RedisKeyPrefixConst.MEMBER_BUYED_MIAOSHA_PREFIX + memberId + ":" + productId,limit-1
// ,expired,TimeUnit.MILLISECONDS);
// }*/
// } catch (Exception e) {
// log.error(e.getMessage(),e.getCause());
// /*
// * 下单失败
// */
// redisOpsUtil.set(RedisKeyPrefixConst.MIAOSHA_ASYNC_WAITING_PREFIX + memberId
// + ":" + productId,Integer.toString(-1),60L, TimeUnit.SECONDS);
// //还原预减库存
// secKillOrderService.incrRedisStock(productId);
// //清除掉本地guava-cache已经售完的标记
// cache.remove(RedisKeyPrefixConst.MIAOSHA_STOCK_CACHE_PREFIX + productId);
// //通知服务群,清除本地售罄标记缓存
// if(secKillOrderService.shouldPublishCleanMsg(productId)) {
// redisOpsUtil.publish("cleanNoStockCache", productId);
// }
// }
// }
//
//}

View File

@@ -0,0 +1,87 @@
package com.tuling.tulingmall.ordercurr.component.rocketmq;//package com.tuling.tulingmall.component.rocketmq;
import com.tuling.tulingmall.ordercurr.domain.OrderParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class OrderMessageSender {
@Value("${rocketmq.tulingmall.scheduleTopic}")
private String scheduleTopic;
@Value("${rocketmq.tulingmall.transGroup}")
private String transGroup;
@Value("${rocketmq.tulingmall.transTopic}")
private String transTopic;
@Value("${rocketmq.tulingmall.asyncOrderTopic}")
private String asyncOrderTopic;
private String TAG = "cancelOrder";
private String TXTAG = "trans";
private String ORDERTAG = "create-order";
@Autowired
private RocketMQTemplate rocketMQTemplate;
// /**
// * 发送延时订单
// * @param cancelId
// * 秒杀订单ID orderId:promotionId 秒杀活动ID
// * @return
// */
// public boolean sendTimeOutOrderMessage(String cancelId){
// Message message = MessageBuilder.withPayload(cancelId)
// .setHeader(RocketMQHeaders.KEYS, cancelId)
// .build();
// SendResult result = rocketMQTemplate.syncSend(scheduleTopic+":"+TAG,message,5000,15);
// return SendStatus.SEND_OK == result.getSendStatus();
// }
//
// /**
// * 事务消息,弱关联分布式系统柔性事务解决方案
// */
// public LocalTransactionState send2CartTransMessage(){
// Message message = MessageBuilder.withPayload("").setHeader(RocketMQHeaders.KEYS, "").build();
// TransactionSendResult transactionSendResult = rocketMQTemplate.sendMessageInTransaction(transGroup, transTopic + ":" + TXTAG, message, null);
// log.info("事务消息-本地事务执行状态:{}" + transactionSendResult.toString()
// ,transactionSendResult.getLocalTransactionState().name());
// return transactionSendResult.getLocalTransactionState();
// }
/**
* 使用事务消息机制发送订单
* @return
*/
public boolean sendCreateOrderMsg(Long orderId, Long memberId){
// SendResult result = rocketMQTemplate.syncSend(asyncOrderTopic+":"+ORDERTAG,message);
String destination = asyncOrderTopic+":"+ORDERTAG;
Message<String> message = MessageBuilder.withPayload(orderId+":"+memberId)
.build();
TransactionSendResult sendResult = rocketMQTemplate.sendMessageInTransaction(destination,message,orderId);
return SendStatus.SEND_OK == sendResult.getSendStatus();
}
// /**
// * 发送延时同步库存消息60s后同步库存
// * @param productId
// * @param promotionId
// * @return
// */
// public boolean sendStockSyncMessage(Long productId,Long promotionId){
// Message message = MessageBuilder.withPayload(productId+":"+promotionId).build();
// SendResult result = rocketMQTemplate.syncSend("stock-sync",message,5000,5);
// return SendStatus.SEND_OK == result.getSendStatus();
// }
}

View File

@@ -0,0 +1,46 @@
package com.tuling.tulingmall.ordercurr.component.rocketmq;//package com.tuling.tulingmall.component.rocketmq;
import com.tuling.tulingmall.ordercurr.service.OmsPortalOrderService;
import lombok.extern.slf4j.Slf4j;
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.Component;
import org.springframework.util.StringUtils;
/**
* 消费监听rocketmq-订单超时消息
* @author yangguo
*/
@Slf4j
@Component
@RocketMQMessageListener(consumerGroup = "CancelOrderGroup", topic = "${rocketmq.tulingmall.asyncOrderTopic}")
public class RocketMqCancelOrderReciever implements RocketMQListener<String> {
@Autowired
private OmsPortalOrderService omsPortalOrderService;
/**
* 延时消息,取消超时订单
* @param message orderId:memberId
*/
@Override
public void onMessage(String message) {
log.info("监控到订单支付超时事件取消超时订单message = "+message);
if(StringUtils.isEmpty(message)){
return;
}
Long orderId = Long.parseLong(message.split(":")[0]);
Long memberId = Long.parseLong(message.split(":")[1]);
try {
//取消的订单,释放锁定的库存
omsPortalOrderService.cancelOrder(orderId,memberId);
//取消的订单-还原缓存库存
// secKillOrderService.incrRedisStock(productId);
//这一步取消。订单超时不再更新Redis中的库存。未支付的订单就不再重新参与秒杀了。等待返场活动处理。
} catch (Exception e) {
log.error("订单取消异常 : 还原库存失败please check:{}",e.getMessage(),e.getCause());
throw new RuntimeException();//抛异常出去,rocketmq会重新投递
}
}
}

View File

@@ -0,0 +1,70 @@
package com.tuling.tulingmall.ordercurr.component.rocketmq;//package com.tuling.tulingmall.component.rocketmq;
//
//import com.tuling.tulingmall.common.api.CommonResult;
//import com.tuling.tulingmall.common.constant.RedisKeyPrefixConst;
//import com.tuling.tulingmall.feignapi.pms.PmsProductFeignApi;
//import com.tuling.tulingmall.util.RedisOpsUtil;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang.StringUtils;
//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.Component;
//
//import java.util.concurrent.TimeUnit;
//
///**
// * ,;,,;
// * ,;;'( 社
// * __ ,;;' ' \ 会
// * /' '\'~~'~' \ /'\.) 主
// * ,;( ) / |. 义
// *,;' \ /-.,,( ) \ 码
// * ) / ) / )| 农
// * || || \)
// * (_\ (_\
// * @author :图灵学院
// * @date Created in 2020/3/9 14:21
// * @version: V1.0
// * @slogan: 天下风云出我辈,一入代码岁月催
// * @description: 解决数据库和redis库存不一致的问题
// **/
//@Slf4j
//@Component
//@RocketMQMessageListener(topic = "stock-sync",consumerGroup = "stock-sync-worker")
//public class StockSyncReciever implements RocketMQListener<String> {
//
// @Autowired
// private RedisOpsUtil redisOpsUtil;
//
// @Autowired
// private PmsProductFeignApi stockManageFeignApi;
//
// @Override
// public void onMessage(String message) {
// String[] param = message.split(":");
// if(param.length <= 1){
// log.error("库存同步,消费消息参数不完整!");
// return;
// }
// Long productID = Long.parseLong(param[0]);
// Long promotionId = Long.parseLong(param[1]);
// /*
// * 有此标记,代表还没有做同步,需要同步DB到redis,如果标记被删除说明肯定不久前
// * 刚刚同步过。同步过就没有必要多次去同步,多条同步延时消息来源于高并发下发送
// * 库存同步消息。这里任然没有办法绝对避免多次查询DB但是可以大大减少查询次数.
// */
// if(redisOpsUtil.hasKey(RedisKeyPrefixConst.STOCK_REFRESHED_MESSAGE_PREFIX + promotionId)){
// log.info("start sync mysql stock to redis");
// //todo 同步一下库存到缓存当中
// Integer stock = stockManageFeignApi.selectStock(productID,promotionId).getData();
// if(stock > 0){
// //重置库存
// redisOpsUtil.set(RedisKeyPrefixConst.MIAOSHA_STOCK_CACHE_PREFIX + productID,stock);
// //删除同步标记
// redisOpsUtil.delete(RedisKeyPrefixConst.STOCK_REFRESHED_MESSAGE_PREFIX + promotionId);
// }
// }
// }
//
//}

View File

@@ -0,0 +1,133 @@
package com.tuling.tulingmall.ordercurr.component.rocketmq;//package com.tuling.tulingmall.component.rocketmq;
import com.tuling.tulingmall.common.api.CommonResult;
import com.tuling.tulingmall.common.api.ResultCode;
import com.tuling.tulingmall.ordercurr.mapper.OmsOrderMapper;
import com.tuling.tulingmall.ordercurr.mapper.OmsOrderSettingMapper;
import com.tuling.tulingmall.ordercurr.model.OmsOrder;
import com.tuling.tulingmall.ordercurr.model.OmsOrderSetting;
import com.tuling.tulingmall.ordercurr.service.TradeService;
import com.tuling.tulingmall.ordercurr.service.impl.OrderConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import java.util.Date;
/**
* 订单事务消息监听器
* 通过事务消息机制完成订单生成。注意:这个消息只是用来发给下游服务进行订单取消用。
*/
@Slf4j
@RocketMQTransactionListener()
public class TransactionListenerImpl implements RocketMQLocalTransactionListener {
//由于要做微服务负载均衡,检查次数就不能在本地记录了。
// private ConcurrentHashMap<String, Integer> localTrans = new ConcurrentHashMap<>();
//回查次数可以根据订单超时事件定制。普通订单超时时间来自于oms_order_settings表的normal_order_overtime表。
//这里用5次做模拟。
private static int maxTryMums = 5;
@Autowired
private TradeService tradeService;
@Autowired
private OmsOrderMapper orderMapper;
@Autowired
private RedisTemplate redisTemplate;
/**
* 下单事务消息的本地事务:
* 1、Redis中记录回查次数
* 2、返回UNKNOWN状态等待事务回查
* @param msg orderId:memberId
* @param arg orderParam
* @return
*/
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
try{
String transId = (String)msg.getHeaders().get(RocketMQHeaders.PREFIX + RocketMQHeaders.TRANSACTION_ID);
log.info("------------RocketMQ执行本地订单创建 transId: "+transId+"-------------");
/**
* 订单已提前生成,这里就不用记录本地订单了。
* */
String orderId = String.valueOf(arg);
redisTemplate.opsForHash().put(OrderConstant.REDIS_CREATE_ORDER,orderId,0);
return RocketMQLocalTransactionState.UNKNOWN;
}catch (Exception e){
log.warn("-----创建RocketMQ下单事务消息失败, ---",e);
return RocketMQLocalTransactionState.ROLLBACK;
}
}
/**
* 下单事务回查事务状态回查最大次数transactionCheckMax 默认15次每次回查的间隔时间transactionTimeOut 默认6秒。检查10次模拟一分钟支付时间
* 1、查询支付宝中的订单支付状态。--本地需要检查的状态: paytype 支付方式: 0-未支付1-支付宝支付。 status : 订单状态0->待付款1->待发货2->已发货3->已完成4->已关闭5->无效订单
* 2、如果订单已支付则返回ROLLBACK丢弃消息 -- 支付宝订单支付后的回调接口中会修改paytype和status并完成订单扣减等业务逻辑。
* 3、如果订单未支付且超过回查次数则修改status为5,无效订单并返回COMMIT推送消息 -- 下游消费者主要释放下单时锁定的库存。
* @param msg orderId:memberId
* @return
*/
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
try{
String transId = (String)msg.getHeaders().get(RocketMQHeaders.PREFIX + RocketMQHeaders.TRANSACTION_ID);
log.info("------------RocketMQ回查订单状态 transId: "+transId+"-------------");
String message = new String((byte[]) msg.getPayload());
if(StringUtils.isNotEmpty(message) && message.contains(":") ){
String[] split = message.split(":");
String orderId = split[0];
// Long memberId = Long.parseLong(split[1]);
Object redisRecord = redisTemplate.opsForHash().get(OrderConstant.REDIS_CREATE_ORDER, orderId);
if(null == redisRecord){
log.warn("-----RocketMQ订单事务回查失败, 没有Redis记录");
return RocketMQLocalTransactionState.ROLLBACK;
}
int retryTimes = (int)redisRecord;
//1、超过最大检查次数表示订单超时未支付关闭订单
if(retryTimes >= maxTryMums){
OmsOrder order = new OmsOrder();
order.setId(Long.parseLong(orderId));
order.setStatus(5); //订单状态修改为关闭
// order.setPayType(0); //支付状态修改为未支付
order.setPaymentTime(new Date());
orderMapper.updateByPrimaryKeySelective(order);
redisTemplate.opsForHash().delete(OrderConstant.REDIS_CREATE_ORDER,orderId);
log.info("--- 订单下单事务消息 transID: "+transId+"支付超时,发送消息,释放锁定的库存");
return RocketMQLocalTransactionState.COMMIT;
}else{
//2、查询支付宝订单支付状态
//2.1 如果支付宝支付成功这个方法中会更新订单paytype和status,并完成扣减库存
CommonResult commonResult = tradeService.tradeStatusQuery(Long.parseLong(orderId), 1);
if(ResultCode.SUCCESS.getCode() == commonResult.getCode()){
msg.getHeaders().remove("CHECK_TIME");
// localTrans.remove(transId);
log.info("--- 订单下单事务消息 transID: "+transId+";订单号:"+orderId+"已经完成支付,回滚消息");
return RocketMQLocalTransactionState.ROLLBACK;
}else{
log.info("--- 订单下单事务消息 transID: "+transId+";订单号:"+orderId+"未支付,已回查"+retryTimes+"次,等待下次回查");
//2.2 如果支付宝未支付,记录回查次数,等待下次回查。
redisTemplate.opsForHash().increment(OrderConstant.REDIS_CREATE_ORDER,orderId,1);
//消息的header不可修改。可以思考下为什么
// msg.getHeaders().put("CHECK_TIME",retryTimes+1);
return RocketMQLocalTransactionState.UNKNOWN;
}
}
}else{
log.info("----RocketMQ订单消息格式不对丢弃消息。");
return RocketMQLocalTransactionState.ROLLBACK;
}
}catch (Exception e){
log.warn("-----RcoketMQ下单事务消息状态回查失败, ---",e);
return RocketMQLocalTransactionState.ROLLBACK;
}
}
}

View File

@@ -0,0 +1,242 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.config;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Created by liuyangkly
*/
public class Configs {
private static Log log = LogFactory.getLog(Configs.class);
private static Configuration configs;
private static String openApiDomain; // 支付宝openapi域名
private static String mcloudApiDomain; // 支付宝mcloudmonitor域名
private static String pid; // 商户partner id
private static String appid; // 商户应用id
private static String privateKey; // RSA私钥用于对商户请求报文加签
private static String publicKey; // RSA公钥仅用于验证开发者网关
private static String alipayPublicKey; // 支付宝RSA公钥用于验签支付宝应答
private static String signType; // 签名类型
private static int maxQueryRetry; // 最大查询次数
private static long queryDuration; // 查询间隔(毫秒)
private static int maxCancelRetry; // 最大撤销次数
private static long cancelDuration; // 撤销间隔(毫秒)
private static long heartbeatDelay ; // 交易保障线程第一次调度延迟(秒)
private static long heartbeatDuration ; // 交易保障线程调度间隔(秒)
private Configs() {
// No Constructor
}
// 根据文件名读取配置文件,文件后缀名必须为.properties
public synchronized static void init(String filePath) {
if (configs != null) {
return;
}
try {
configs = new PropertiesConfiguration(filePath);
} catch (ConfigurationException e) {
e.printStackTrace();
}
if (configs == null) {
throw new IllegalStateException("can`t find file by path:" + filePath);
}
openApiDomain = configs.getString("open_api_domain");
mcloudApiDomain = configs.getString("mcloud_api_domain");
pid = configs.getString("pid");
appid = configs.getString("appid");
// RSA
privateKey = configs.getString("private_key");
publicKey = configs.getString("public_key");
alipayPublicKey = configs.getString("alipay_public_key");
signType = configs.getString("sign_type");
// 查询参数
maxQueryRetry = configs.getInt("max_query_retry");
queryDuration = configs.getLong("query_duration");
maxCancelRetry = configs.getInt("max_cancel_retry");
cancelDuration = configs.getLong("cancel_duration");
// 交易保障调度线程
heartbeatDelay = configs.getLong("heartbeat_delay");
heartbeatDuration = configs.getLong("heartbeat_duration");
log.info("配置文件名: " + filePath);
log.info(description());
}
public static String description() {
StringBuilder sb = new StringBuilder("Configs{");
sb.append("支付宝openapi网关: ").append(openApiDomain).append("\n");
if (StringUtils.isNotEmpty(mcloudApiDomain)) {
sb.append(", 支付宝mcloudapi网关域名: ").append(mcloudApiDomain).append("\n");
}
if (StringUtils.isNotEmpty(pid)) {
sb.append(", pid: ").append(pid).append("\n");
}
sb.append(", appid: ").append(appid).append("\n");
sb.append(", 商户RSA私钥: ").append(getKeyDescription(privateKey)).append("\n");
sb.append(", 商户RSA公钥: ").append(getKeyDescription(publicKey)).append("\n");
sb.append(", 支付宝RSA公钥: ").append(getKeyDescription(alipayPublicKey)).append("\n");
sb.append(", 签名类型: ").append(signType).append("\n");
sb.append(", 查询重试次数: ").append(maxQueryRetry).append("\n");
sb.append(", 查询间隔(毫秒): ").append(queryDuration).append("\n");
sb.append(", 撤销尝试次数: ").append(maxCancelRetry).append("\n");
sb.append(", 撤销重试间隔(毫秒): ").append(cancelDuration).append("\n");
sb.append(", 交易保障调度延迟(秒): ").append(heartbeatDelay).append("\n");
sb.append(", 交易保障调度间隔(秒): ").append(heartbeatDuration).append("\n");
sb.append("}");
return sb.toString();
}
private static String getKeyDescription(String key) {
int showLength = 6;
if (StringUtils.isNotEmpty(key) &&
key.length() > showLength) {
return new StringBuilder(key.substring(0, showLength))
.append("******")
.append(key.substring(key.length() - showLength))
.toString();
}
return null;
}
public static Configuration getConfigs() {
return configs;
}
public static String getOpenApiDomain() {
return openApiDomain;
}
public static String getMcloudApiDomain() {
return mcloudApiDomain;
}
public static void setMcloudApiDomain(String mcloudApiDomain) {
Configs.mcloudApiDomain = mcloudApiDomain;
}
public static String getPid() {
return pid;
}
public static String getAppid() {
return appid;
}
public static String getPrivateKey() {
return privateKey;
}
public static String getPublicKey() {
return publicKey;
}
public static String getAlipayPublicKey() {
return alipayPublicKey;
}
public static String getSignType() {
return signType;
}
public static int getMaxQueryRetry() {
return maxQueryRetry;
}
public static long getQueryDuration() {
return queryDuration;
}
public static int getMaxCancelRetry() {
return maxCancelRetry;
}
public static long getCancelDuration() {
return cancelDuration;
}
public static void setConfigs(Configuration configs) {
Configs.configs = configs;
}
public static void setOpenApiDomain(String openApiDomain) {
Configs.openApiDomain = openApiDomain;
}
public static void setPid(String pid) {
Configs.pid = pid;
}
public static void setAppid(String appid) {
Configs.appid = appid;
}
public static void setPrivateKey(String privateKey) {
Configs.privateKey = privateKey;
}
public static void setPublicKey(String publicKey) {
Configs.publicKey = publicKey;
}
public static void setAlipayPublicKey(String alipayPublicKey) {
Configs.alipayPublicKey = alipayPublicKey;
}
public static void setSignType(String signType) {
Configs.signType = signType;
}
public static void setMaxQueryRetry(int maxQueryRetry) {
Configs.maxQueryRetry = maxQueryRetry;
}
public static void setQueryDuration(long queryDuration) {
Configs.queryDuration = queryDuration;
}
public static void setMaxCancelRetry(int maxCancelRetry) {
Configs.maxCancelRetry = maxCancelRetry;
}
public static void setCancelDuration(long cancelDuration) {
Configs.cancelDuration = cancelDuration;
}
public static long getHeartbeatDelay() {
return heartbeatDelay;
}
public static void setHeartbeatDelay(long heartbeatDelay) {
Configs.heartbeatDelay = heartbeatDelay;
}
public static long getHeartbeatDuration() {
return heartbeatDuration;
}
public static void setHeartbeatDuration(long heartbeatDuration) {
Configs.heartbeatDuration = heartbeatDuration;
}
}

View File

@@ -0,0 +1,16 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.config;
/**
* Created by liuyangkly on 15/7/29.
*/
public class Constants {
private Constants() {
// No Constructor.
}
public static final String SUCCESS = "10000"; // 成功
public static final String PAYING = "10003"; // 用户支付中
public static final String FAILED = "40004"; // 失败
public static final String ERROR = "20000"; // 系统异常
}

View File

@@ -0,0 +1,30 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model;
import com.google.gson.annotations.SerializedName;
/**
* Created by liuyangkly on 15/6/26.
* 扩展信息
*/
public class ExtendParams {
// 系统商编号
@SerializedName("sys_service_provider_id")
private String sysServiceProviderId;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("ExtendParams{");
sb.append("sysServiceProviderId='").append(sysServiceProviderId).append('\'');
sb.append('}');
return sb.toString();
}
public String getSysServiceProviderId() {
return sysServiceProviderId;
}
public ExtendParams setSysServiceProviderId(String sysServiceProviderId) {
this.sysServiceProviderId = sysServiceProviderId;
return this;
}
}

View File

@@ -0,0 +1,122 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model;
import com.google.gson.annotations.SerializedName;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.utils.Utils;
/**
* Created by liuyangkly on 15/6/26.
* 商品明细
*/
public class GoodsDetail {
// 商品编号(国标)
@SerializedName("goods_id")
private String goodsId;
@SerializedName("alipay_goods_id")
private String alipayGoodsId;
// 商品名称
@SerializedName("goods_name")
private String goodsName;
// 商品数量
private int quantity;
// 商品价格此处单位为元精确到小数点后2位
private String price;
// 商品类别
@SerializedName("goods_category")
private String goodsCategory;
// 商品详情
private String body;
// 创建一个商品信息参数含义分别为商品id使用国标、商品名称、商品价格单位为分、商品数量
public static GoodsDetail newInstance(String goodsId, String goodsName, long price, int quantity) {
GoodsDetail info = new GoodsDetail();
info.setGoodsId(goodsId);
info.setGoodsName(goodsName);
info.setPrice(price);
info.setQuantity(quantity);
return info;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("GoodsDetail{");
sb.append("goodsId='").append(goodsId).append('\'');
sb.append(", alipayGoodsId='").append(alipayGoodsId).append('\'');
sb.append(", goodsName='").append(goodsName).append('\'');
sb.append(", quantity=").append(quantity);
sb.append(", price='").append(price).append('\'');
sb.append(", goodsCategory='").append(goodsCategory).append('\'');
sb.append(", body='").append(body).append('\'');
sb.append('}');
return sb.toString();
}
public String getGoodsId() {
return goodsId;
}
public GoodsDetail setGoodsId(String goodsId) {
this.goodsId = goodsId;
return this;
}
public String getAlipayGoodsId() {
return alipayGoodsId;
}
public GoodsDetail setAlipayGoodsId(String alipayGoodsId) {
this.alipayGoodsId = alipayGoodsId;
return this;
}
public String getGoodsName() {
return goodsName;
}
public GoodsDetail setGoodsName(String goodsName) {
this.goodsName = goodsName;
return this;
}
public int getQuantity() {
return quantity;
}
public GoodsDetail setQuantity(int quantity) {
this.quantity = quantity;
return this;
}
public String getPrice() {
return price;
}
public GoodsDetail setPrice(long price) {
this.price = Utils.toAmount(price);
return this;
}
public String getGoodsCategory() {
return goodsCategory;
}
public GoodsDetail setGoodsCategory(String goodsCategory) {
this.goodsCategory = goodsCategory;
return this;
}
public String getBody() {
return body;
}
public GoodsDetail setBody(String body) {
this.body = body;
return this;
}
}

View File

@@ -0,0 +1,12 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model;
/**
* Created by liuyangkly on 15/8/29.
*/
public enum TradeStatus {
SUCCESS // 业务交易明确成功,比如支付成功、退货成功
,FAILED // 业务交易明确失败,比如支付明确失败、退货明确失败
,UNKNOWN // 业务交易状态未知,此时不清楚该业务是否成功或者失败,需要商户自行确认
}

View File

@@ -0,0 +1,334 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder;
import com.google.gson.annotations.SerializedName;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb.*;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.utils.Utils;
import org.apache.commons.lang.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by liuyangkly on 16/3/2.
*/
public class AlipayHeartbeatSynRequestBuilder extends RequestBuilder {
private BizContent bizContent = new BizContent();
@Override
public BizContent getBizContent() {
return bizContent;
}
@Override
public boolean validate() {
if (bizContent.product == null) {
throw new NullPointerException("product should not be NULL!");
}
if (bizContent.type == null) {
throw new NullPointerException("type should not be NULL!");
}
if (StringUtils.isEmpty(bizContent.equipmentId)) {
throw new NullPointerException("equipment_id should not be NULL!");
}
if (bizContent.equipmentStatus == null) {
throw new NullPointerException("equipment_status should not be NULL!");
}
if (StringUtils.isEmpty(bizContent.time)) {
throw new NullPointerException("time should not be NULL!");
}
return true;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("AlipayHeartbeatSynRequestBuilder{");
sb.append("bizContent=").append(bizContent);
sb.append(", super=").append(super.toString());
sb.append('}');
return sb.toString();
}
@Override
public AlipayHeartbeatSynRequestBuilder setAppAuthToken(String appAuthToken) {
return (AlipayHeartbeatSynRequestBuilder) super.setAppAuthToken(appAuthToken);
}
@Override
public AlipayHeartbeatSynRequestBuilder setNotifyUrl(String notifyUrl) {
return (AlipayHeartbeatSynRequestBuilder) super.setNotifyUrl(notifyUrl);
}
public String getMac() {
return bizContent.mac;
}
public AlipayHeartbeatSynRequestBuilder setMac(String mac) {
bizContent.mac = mac;
return this;
}
public String getNetworkType() {
return bizContent.networkType;
}
public AlipayHeartbeatSynRequestBuilder setNetworkType(String networkType) {
bizContent.networkType = networkType;
return this;
}
public String getBattery() {
return bizContent.battery;
}
public AlipayHeartbeatSynRequestBuilder setBattery(String battery) {
bizContent.battery = battery;
return this;
}
public String getWifiMac() {
return bizContent.wifiMac;
}
public AlipayHeartbeatSynRequestBuilder setWifiMac(String wifiMac) {
bizContent.wifiMac = wifiMac;
return this;
}
public String getWifiName() {
return bizContent.wifiName;
}
public AlipayHeartbeatSynRequestBuilder setWifiName(String wifiName) {
bizContent.wifiName = wifiName;
return this;
}
public String getNetworkStatus() {
return bizContent.networkStatus;
}
public AlipayHeartbeatSynRequestBuilder setNetworkStatus(String networkStatus) {
bizContent.networkStatus = networkStatus;
return this;
}
public String getBbsPosition() {
return bizContent.bbsPosition;
}
public AlipayHeartbeatSynRequestBuilder setBbsPosition(String bbsPosition) {
bizContent.bbsPosition = bbsPosition;
return this;
}
public String getManufacturerPid() {
return bizContent.manufacturerPid;
}
public AlipayHeartbeatSynRequestBuilder setManufacturerPid(String manufacturerPid) {
bizContent.manufacturerPid = manufacturerPid;
return this;
}
public String getProviderId() {
return bizContent.providerId;
}
public AlipayHeartbeatSynRequestBuilder setProviderId(String providerId) {
bizContent.providerId = providerId;
return this;
}
public String getEquipmentId() {
return bizContent.equipmentId;
}
public AlipayHeartbeatSynRequestBuilder setEquipmentId(String equipmentId) {
bizContent.equipmentId = equipmentId;
return this;
}
public String getEquipmentPosition() {
return bizContent.equipmentPosition;
}
public AlipayHeartbeatSynRequestBuilder setEquipmentPosition(String equipmentPosition) {
bizContent.equipmentPosition = equipmentPosition;
return this;
}
public EquipStatus getEquipmentStatus() {
return bizContent.equipmentStatus;
}
public AlipayHeartbeatSynRequestBuilder setEquipmentStatus(EquipStatus equipmentStatus) {
bizContent.equipmentStatus = equipmentStatus;
return this;
}
public List<ExceptionInfo> getExceptionInfoList() {
return bizContent.exceptionInfoList;
}
public AlipayHeartbeatSynRequestBuilder setExceptionInfoList(List<ExceptionInfo> exceptionInfoList) {
bizContent.exceptionInfoList = exceptionInfoList;
return this;
}
public Map<String, Object> getExtendInfo() {
return bizContent.extendInfo;
}
public AlipayHeartbeatSynRequestBuilder setExtendInfo(Map<String, Object> extendInfo) {
bizContent.extendInfo = extendInfo;
return this;
}
public String getIp() {
return bizContent.ip;
}
public AlipayHeartbeatSynRequestBuilder setIp(String ip) {
bizContent.ip = ip;
return this;
}
public Product getProduct() {
return bizContent.product;
}
public AlipayHeartbeatSynRequestBuilder setProduct(Product product) {
bizContent.product = product;
return this;
}
public String getStoreId() {
return bizContent.storeId;
}
public AlipayHeartbeatSynRequestBuilder setStoreId(String storeId) {
bizContent.storeId = storeId;
return this;
}
public String getTime() {
return bizContent.time;
}
public AlipayHeartbeatSynRequestBuilder setTime(String time) {
bizContent.time = time;
return this;
}
public List<TradeInfo> getTradeInfoList() {
return bizContent.tradeInfoList;
}
public AlipayHeartbeatSynRequestBuilder setSysTradeInfoList(List<SysTradeInfo> sysTradeInfoList) {
if (Utils.isListNotEmpty(sysTradeInfoList)) {
bizContent.tradeInfoList = new ArrayList<TradeInfo>(sysTradeInfoList);
}
return this;
}
public AlipayHeartbeatSynRequestBuilder setPosTradeInfoList(List<PosTradeInfo> posTradeInfoList) {
if (Utils.isListNotEmpty(posTradeInfoList)) {
bizContent.tradeInfoList = new ArrayList<TradeInfo>(posTradeInfoList);
}
return this;
}
public Type getType() {
return bizContent.type;
}
public AlipayHeartbeatSynRequestBuilder setType(Type type) {
bizContent.type = type;
return this;
}
public static class BizContent {
private Product product;
private Type type;
@SerializedName("equipment_id")
private String equipmentId;
@SerializedName("equipment_status")
private EquipStatus equipmentStatus;
private String time;
@SerializedName("manufacturer_app_id")
private String manufacturerPid;
@SerializedName("sys_service_provider_id")
private String providerId;
@SerializedName("store_id")
private String storeId;
@SerializedName("equipment_position")
private String equipmentPosition;
@SerializedName("bbs_position")
private String bbsPosition;
@SerializedName("network_status")
private String networkStatus;
@SerializedName("network_type")
private String networkType;
private String battery;
@SerializedName("wifi_mac")
private String wifiMac;
@SerializedName("wifi_name")
private String wifiName;
private String ip;
private String mac;
@SerializedName("trade_info")
private List<TradeInfo> tradeInfoList;
@SerializedName("exception_info")
private List<ExceptionInfo> exceptionInfoList;
@SerializedName("extend_info")
private Map<String, Object> extendInfo;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("BizContent{");
sb.append("product=").append(product);
sb.append(", type=").append(type);
sb.append(", equipmentId='").append(equipmentId).append('\'');
sb.append(", equipmentStatus=").append(equipmentStatus);
sb.append(", time='").append(time).append('\'');
sb.append(", manufacturerPid='").append(manufacturerPid).append('\'');
sb.append(", providerId='").append(providerId).append('\'');
sb.append(", storeId='").append(storeId).append('\'');
sb.append(", equipmentPosition='").append(equipmentPosition).append('\'');
sb.append(", bbsPosition='").append(bbsPosition).append('\'');
sb.append(", networkStatus='").append(networkStatus).append('\'');
sb.append(", networkType='").append(networkType).append('\'');
sb.append(", battery='").append(battery).append('\'');
sb.append(", wifiMac='").append(wifiMac).append('\'');
sb.append(", wifiName='").append(wifiName).append('\'');
sb.append(", ip='").append(ip).append('\'');
sb.append(", mac='").append(mac).append('\'');
sb.append(", tradeInfoList=").append(tradeInfoList);
sb.append(", exceptionInfoList=").append(exceptionInfoList);
sb.append(", extendInfo=").append(extendInfo);
sb.append('}');
return sb.toString();
}
}
}

View File

@@ -0,0 +1,67 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder;
import com.google.gson.annotations.SerializedName;
import org.apache.commons.lang.StringUtils;
/**
* Created by liuyangkly on 16/3/3.
*/
public class AlipayTradeCancelRequestBuilder extends RequestBuilder {
private BizContent bizContent = new BizContent();
@Override
public BizContent getBizContent() {
return bizContent;
}
@Override
public boolean validate() {
if (StringUtils.isEmpty(bizContent.outTradeNo)) {
throw new NullPointerException("out_trade_no should not be NULL!");
}
return true;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("AlipayTradeCancelRequestBuilder{");
sb.append("bizContent=").append(bizContent);
sb.append(", super=").append(super.toString());
sb.append('}');
return sb.toString();
}
@Override
public AlipayTradeCancelRequestBuilder setAppAuthToken(String appAuthToken) {
return (AlipayTradeCancelRequestBuilder) super.setAppAuthToken(appAuthToken);
}
@Override
public AlipayTradeCancelRequestBuilder setNotifyUrl(String notifyUrl) {
return (AlipayTradeCancelRequestBuilder) super.setNotifyUrl(notifyUrl);
}
public String getOutTradeNo() {
return bizContent.outTradeNo;
}
public AlipayTradeCancelRequestBuilder setOutTradeNo(String outTradeNo) {
bizContent.outTradeNo = outTradeNo;
return this;
}
public static class BizContent {
// 商户订单号,通过此商户订单号撤销当面付的交易状态
@SerializedName("out_trade_no")
private String outTradeNo;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("BizContent{");
sb.append("outTradeNo='").append(outTradeNo).append('\'');
sb.append('}');
return sb.toString();
}
}
}

View File

@@ -0,0 +1,309 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder;
import com.google.gson.annotations.SerializedName;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.ExtendParams;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.GoodsDetail;
import org.apache.commons.lang.StringUtils;
import java.util.List;
import java.util.regex.Pattern;
/**
* Created by liuyangkly on 16/3/3.
*/
public class AlipayTradePayRequestBuilder extends RequestBuilder {
private BizContent bizContent = new BizContent();
@Override
public BizContent getBizContent() {
return bizContent;
}
@Override
public boolean validate() {
if (StringUtils.isEmpty(bizContent.scene)) {
throw new NullPointerException("scene should not be NULL!");
}
if (StringUtils.isEmpty(bizContent.authCode)) {
throw new NullPointerException("auth_code should not be NULL!");
}
if (!Pattern.matches("^\\d{10,}$", bizContent.authCode)) {
throw new IllegalStateException("invalid auth_code!");
}
if (StringUtils.isEmpty(bizContent.outTradeNo)) {
throw new NullPointerException("out_trade_no should not be NULL!");
}
if (StringUtils.isEmpty(bizContent.totalAmount)) {
throw new NullPointerException("total_amount should not be NULL!");
}
if (StringUtils.isEmpty(bizContent.subject)) {
throw new NullPointerException("subject should not be NULL!");
}
if (StringUtils.isEmpty(bizContent.storeId)) {
throw new NullPointerException("store_id should not be NULL!");
}
return true;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("AlipayTradePayRequestBuilder{");
sb.append("bizContent=").append(bizContent);
sb.append(", super=").append(super.toString());
sb.append('}');
return sb.toString();
}
public AlipayTradePayRequestBuilder() {
// 条码支付场景为bar_code
bizContent.scene = "bar_code";
}
@Override
public AlipayTradePayRequestBuilder setAppAuthToken(String appAuthToken) {
return (AlipayTradePayRequestBuilder) super.setAppAuthToken(appAuthToken);
}
@Override
public AlipayTradePayRequestBuilder setNotifyUrl(String notifyUrl) {
return (AlipayTradePayRequestBuilder) super.setNotifyUrl(notifyUrl);
}
public String getScene() {
return bizContent.scene;
}
public AlipayTradePayRequestBuilder setScene(String scene) {
bizContent.scene = scene;
return this;
}
public String getAuthCode() {
return bizContent.authCode;
}
public AlipayTradePayRequestBuilder setAuthCode(String authCode) {
bizContent.authCode = authCode;
return this;
}
public String getOutTradeNo() {
return bizContent.outTradeNo;
}
public AlipayTradePayRequestBuilder setOutTradeNo(String outTradeNo) {
bizContent.outTradeNo = outTradeNo;
return this;
}
public String getSellerId() {
return bizContent.sellerId;
}
public AlipayTradePayRequestBuilder setSellerId(String sellerId) {
bizContent.sellerId = sellerId;
return this;
}
public String getTotalAmount() {
return bizContent.totalAmount;
}
public AlipayTradePayRequestBuilder setTotalAmount(String totalAmount) {
bizContent.totalAmount = totalAmount;
return this;
}
public String getDiscountableAmount() {
return bizContent.discountableAmount;
}
public AlipayTradePayRequestBuilder setDiscountableAmount(String discountableAmount) {
bizContent.discountableAmount = discountableAmount;
return this;
}
public String getUndiscountableAmount() {
return bizContent.undiscountableAmount;
}
public AlipayTradePayRequestBuilder setUndiscountableAmount(String undiscountableAmount) {
bizContent.undiscountableAmount = undiscountableAmount;
return this;
}
public String getSubject() {
return bizContent.subject;
}
public AlipayTradePayRequestBuilder setSubject(String subject) {
bizContent.subject = subject;
return this;
}
public String getBody() {
return bizContent.body;
}
public AlipayTradePayRequestBuilder setBody(String body) {
bizContent.body = body;
return this;
}
public List<GoodsDetail> getGoodsDetailList() {
return bizContent.goodsDetailList;
}
public AlipayTradePayRequestBuilder setGoodsDetailList(List<GoodsDetail> goodsDetailList) {
bizContent.goodsDetailList = goodsDetailList;
return this;
}
public String getOperatorId() {
return bizContent.operatorId;
}
public AlipayTradePayRequestBuilder setOperatorId(String operatorId) {
bizContent.operatorId = operatorId;
return this;
}
public String getStoreId() {
return bizContent.storeId;
}
public AlipayTradePayRequestBuilder setStoreId(String storeId) {
bizContent.storeId = storeId;
return this;
}
public String getAlipayStoreId() {
return bizContent.alipayStoreId;
}
public AlipayTradePayRequestBuilder setAlipayStoreId(String alipayStoreId) {
bizContent.alipayStoreId = alipayStoreId;
return this;
}
public String getTerminalId() {
return bizContent.terminalId;
}
public AlipayTradePayRequestBuilder setTerminalId(String terminalId) {
bizContent.terminalId = terminalId;
return this;
}
public ExtendParams getExtendParams() {
return bizContent.extendParams;
}
public AlipayTradePayRequestBuilder setExtendParams(ExtendParams extendParams) {
bizContent.extendParams = extendParams;
return this;
}
public String getTimeoutExpress() {
return bizContent.timeoutExpress;
}
public AlipayTradePayRequestBuilder setTimeoutExpress(String timeoutExpress) {
bizContent.timeoutExpress = timeoutExpress;
return this;
}
public static class BizContent {
// 支付场景条码支付场景为bar_code
private String scene;
// 付款条码用户支付宝钱包手机app点击“付款”产生的付款条码
@SerializedName("auth_code")
private String authCode;
// 商户网站订单系统中唯一订单号64个字符以内只能包含字母、数字、下划线
// 需保证商户系统端不能重复建议通过数据库sequence生成
@SerializedName("out_trade_no")
private String outTradeNo;
// 卖家支付宝账号ID用于支持一个签约账号下支持打款到不同的收款账号(打款到sellerId对应的支付宝账号)
// 如果该字段为空则默认为与支付宝签约的商户的PID也就是appid对应的PID
@SerializedName("seller_id")
private String sellerId;
// 订单总金额整形此处单位为元精确到小数点后2位不能超过1亿元
// 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
@SerializedName("total_amount")
private String totalAmount;
// 订单可打折金额此处单位为元精确到小数点后2位
// 可以配合商家平台配置折扣活动,如果订单部分商品参与打折,可以将部分商品总价填写至此字段,默认全部商品可打折
// 如果该值未传入,但传入了【订单总金额】,【不可打折金额】 则该值默认为【订单总金额】- 【不可打折金额】
@SerializedName("discountable_amount")
private String discountableAmount;
// 订单不可打折金额此处单位为元精确到小数点后2位可以配合商家平台配置折扣活动如果酒水不参与打折则将对应金额填写至此字段
// 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
@SerializedName("undiscountable_amount")
private String undiscountableAmount;
// 订单标题,粗略描述用户的支付目的。如“喜士多(浦东店)消费”
private String subject;
// 订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品2件共15.00元"
private String body;
// 商品明细列表,需填写购买商品详细信息,
@SerializedName("goods_detail")
private List<GoodsDetail> goodsDetailList;
// 商户操作员编号,添加此参数可以为商户操作员做销售统计
@SerializedName("operator_id")
private String operatorId;
// 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支持
@SerializedName("store_id")
private String storeId;
// 支付宝商家平台中配置的商户门店号,详询支付宝技术支持
@SerializedName("alipay_store_id")
private String alipayStoreId;
// 商户机具终端编号,当以机具方式接入支付宝时必传,详询支付宝技术支持
@SerializedName("terminal_id")
private String terminalId;
// 业务扩展参数,目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法),详情请咨询支付宝技术支持
@SerializedName("extend_params")
private ExtendParams extendParams;
// (推荐使用,相对时间) 支付超时时间5m 5分钟
@SerializedName("timeout_express")
private String timeoutExpress;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("BizContent{");
sb.append("scene='").append(scene).append('\'');
sb.append(", authCode='").append(authCode).append('\'');
sb.append(", outTradeNo='").append(outTradeNo).append('\'');
sb.append(", sellerId='").append(sellerId).append('\'');
sb.append(", totalAmount='").append(totalAmount).append('\'');
sb.append(", discountableAmount='").append(discountableAmount).append('\'');
sb.append(", undiscountableAmount='").append(undiscountableAmount).append('\'');
sb.append(", subject='").append(subject).append('\'');
sb.append(", body='").append(body).append('\'');
sb.append(", goodsDetailList=").append(goodsDetailList);
sb.append(", operatorId='").append(operatorId).append('\'');
sb.append(", storeId='").append(storeId).append('\'');
sb.append(", alipayStoreId='").append(alipayStoreId).append('\'');
sb.append(", terminalId='").append(terminalId).append('\'');
sb.append(", extendParams=").append(extendParams);
sb.append(", timeoutExpress='").append(timeoutExpress).append('\'');
sb.append('}');
return sb.toString();
}
}
}

View File

@@ -0,0 +1,266 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder;
import com.google.gson.annotations.SerializedName;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.ExtendParams;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.GoodsDetail;
import org.apache.commons.lang.StringUtils;
import java.util.List;
/**
* Created by liuyangkly on 16/3/3.
*/
public class AlipayTradePrecreateRequestBuilder extends RequestBuilder {
private BizContent bizContent = new BizContent();
@Override
public BizContent getBizContent() {
return bizContent;
}
@Override
public boolean validate() {
if (StringUtils.isEmpty(bizContent.outTradeNo)) {
throw new NullPointerException("out_trade_no should not be NULL!");
}
if (StringUtils.isEmpty(bizContent.totalAmount)) {
throw new NullPointerException("total_amount should not be NULL!");
}
if (StringUtils.isEmpty(bizContent.subject)) {
throw new NullPointerException("subject should not be NULL!");
}
if (StringUtils.isEmpty(bizContent.storeId)) {
throw new NullPointerException("store_id should not be NULL!");
}
return true;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("AlipayTradePrecreateRequestBuilder{");
sb.append("bizContent=").append(bizContent);
sb.append(", super=").append(super.toString());
sb.append('}');
return sb.toString();
}
@Override
public AlipayTradePrecreateRequestBuilder setAppAuthToken(String appAuthToken) {
return (AlipayTradePrecreateRequestBuilder) super.setAppAuthToken(appAuthToken);
}
@Override
public AlipayTradePrecreateRequestBuilder setNotifyUrl(String notifyUrl) {
return (AlipayTradePrecreateRequestBuilder) super.setNotifyUrl(notifyUrl);
}
public String getOutTradeNo() {
return bizContent.outTradeNo;
}
public AlipayTradePrecreateRequestBuilder setOutTradeNo(String outTradeNo) {
bizContent.outTradeNo = outTradeNo;
return this;
}
public String getSellerId() {
return bizContent.sellerId;
}
public AlipayTradePrecreateRequestBuilder setSellerId(String sellerId) {
bizContent.sellerId = sellerId;
return this;
}
public String getTotalAmount() {
return bizContent.totalAmount;
}
public AlipayTradePrecreateRequestBuilder setTotalAmount(String totalAmount) {
bizContent.totalAmount = totalAmount;
return this;
}
public String getDiscountableAmount() {
return bizContent.discountableAmount;
}
public AlipayTradePrecreateRequestBuilder setDiscountableAmount(String discountableAmount) {
bizContent.discountableAmount = discountableAmount;
return this;
}
public String getUndiscountableAmount() {
return bizContent.undiscountableAmount;
}
public AlipayTradePrecreateRequestBuilder setUndiscountableAmount(String undiscountableAmount) {
bizContent.undiscountableAmount = undiscountableAmount;
return this;
}
public String getSubject() {
return bizContent.subject;
}
public AlipayTradePrecreateRequestBuilder setSubject(String subject) {
bizContent.subject = subject;
return this;
}
public String getBody() {
return bizContent.body;
}
public AlipayTradePrecreateRequestBuilder setBody(String body) {
bizContent.body = body;
return this;
}
public List<GoodsDetail> getGoodsDetailList() {
return bizContent.goodsDetailList;
}
public AlipayTradePrecreateRequestBuilder setGoodsDetailList(List<GoodsDetail> goodsDetailList) {
bizContent.goodsDetailList = goodsDetailList;
return this;
}
public String getOperatorId() {
return bizContent.operatorId;
}
public AlipayTradePrecreateRequestBuilder setOperatorId(String operatorId) {
bizContent.operatorId = operatorId;
return this;
}
public String getStoreId() {
return bizContent.storeId;
}
public AlipayTradePrecreateRequestBuilder setStoreId(String storeId) {
bizContent.storeId = storeId;
return this;
}
public String getAlipayStoreId() {
return bizContent.alipayStoreId;
}
public AlipayTradePrecreateRequestBuilder setAlipayStoreId(String alipayStoreId) {
bizContent.alipayStoreId = alipayStoreId;
return this;
}
public String getTerminalId() {
return bizContent.terminalId;
}
public AlipayTradePrecreateRequestBuilder setTerminalId(String terminalId) {
bizContent.terminalId = terminalId;
return this;
}
public ExtendParams getExtendParams() {
return bizContent.extendParams;
}
public AlipayTradePrecreateRequestBuilder setExtendParams(ExtendParams extendParams) {
bizContent.extendParams = extendParams;
return this;
}
public String getTimeoutExpress() {
return bizContent.timeoutExpress;
}
public AlipayTradePrecreateRequestBuilder setTimeoutExpress(String timeoutExpress) {
bizContent.timeoutExpress = timeoutExpress;
return this;
}
public static class BizContent {
// 商户网站订单系统中唯一订单号64个字符以内只能包含字母、数字、下划线
// 需保证商户系统端不能重复建议通过数据库sequence生成
@SerializedName("out_trade_no")
private String outTradeNo;
// 卖家支付宝账号ID用于支持一个签约账号下支持打款到不同的收款账号(打款到sellerId对应的支付宝账号)
// 如果该字段为空则默认为与支付宝签约的商户的PID也就是appid对应的PID
@SerializedName("seller_id")
private String sellerId;
// 订单总金额整形此处单位为元精确到小数点后2位不能超过1亿元
// 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
@SerializedName("total_amount")
private String totalAmount;
// 订单可打折金额此处单位为元精确到小数点后2位
// 可以配合商家平台配置折扣活动,如果订单部分商品参与打折,可以将部分商品总价填写至此字段,默认全部商品可打折
// 如果该值未传入,但传入了【订单总金额】,【不可打折金额】 则该值默认为【订单总金额】- 【不可打折金额】
@SerializedName("discountable_amount")
private String discountableAmount;
// 订单不可打折金额此处单位为元精确到小数点后2位可以配合商家平台配置折扣活动如果酒水不参与打折则将对应金额填写至此字段
// 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
@SerializedName("undiscountable_amount")
private String undiscountableAmount;
// 订单标题,粗略描述用户的支付目的。如“喜士多(浦东店)消费”
private String subject;
// 订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品2件共15.00元"
private String body;
// 商品明细列表,需填写购买商品详细信息,
@SerializedName("goods_detail")
private List<GoodsDetail> goodsDetailList;
// 商户操作员编号,添加此参数可以为商户操作员做销售统计
@SerializedName("operator_id")
private String operatorId;
// 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支持
@SerializedName("store_id")
private String storeId;
// 支付宝商家平台中配置的商户门店号,详询支付宝技术支持
@SerializedName("alipay_store_id")
private String alipayStoreId;
// 商户机具终端编号,当以机具方式接入支付宝时必传,详询支付宝技术支持
@SerializedName("terminal_id")
private String terminalId;
// 业务扩展参数,目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法),详情请咨询支付宝技术支持
@SerializedName("extend_params")
private ExtendParams extendParams;
// (推荐使用,相对时间) 支付超时时间5m 5分钟
@SerializedName("timeout_express")
private String timeoutExpress;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("BizContent{");
sb.append("outTradeNo='").append(outTradeNo).append('\'');
sb.append(", sellerId='").append(sellerId).append('\'');
sb.append(", totalAmount='").append(totalAmount).append('\'');
sb.append(", discountableAmount='").append(discountableAmount).append('\'');
sb.append(", undiscountableAmount='").append(undiscountableAmount).append('\'');
sb.append(", subject='").append(subject).append('\'');
sb.append(", body='").append(body).append('\'');
sb.append(", goodsDetailList=").append(goodsDetailList);
sb.append(", operatorId='").append(operatorId).append('\'');
sb.append(", storeId='").append(storeId).append('\'');
sb.append(", alipayStoreId='").append(alipayStoreId).append('\'');
sb.append(", terminalId='").append(terminalId).append('\'');
sb.append(", extendParams=").append(extendParams);
sb.append(", timeoutExpress='").append(timeoutExpress).append('\'');
sb.append('}');
return sb.toString();
}
}
}

View File

@@ -0,0 +1,82 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder;
import com.google.gson.annotations.SerializedName;
import org.apache.commons.lang.StringUtils;
/**
* Created by liuyangkly on 16/3/3.
*/
public class AlipayTradeQueryRequestBuilder extends RequestBuilder {
private BizContent bizContent = new BizContent();
@Override
public BizContent getBizContent() {
return bizContent;
}
@Override
public boolean validate() {
if (StringUtils.isEmpty(bizContent.tradeNo) &&
StringUtils.isEmpty(bizContent.outTradeNo)) {
throw new IllegalStateException("tradeNo and outTradeNo can not both be NULL!");
}
return true;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("AlipayTradeQueryRequestBuilder{");
sb.append("bizContent=").append(bizContent);
sb.append(", super=").append(super.toString());
sb.append('}');
return sb.toString();
}
@Override
public AlipayTradeQueryRequestBuilder setAppAuthToken(String appAuthToken) {
return (AlipayTradeQueryRequestBuilder) super.setAppAuthToken(appAuthToken);
}
@Override
public AlipayTradeQueryRequestBuilder setNotifyUrl(String notifyUrl) {
return (AlipayTradeQueryRequestBuilder) super.setNotifyUrl(notifyUrl);
}
public String getTradeNo() {
return bizContent.tradeNo;
}
public AlipayTradeQueryRequestBuilder setTradeNo(String tradeNo) {
bizContent.tradeNo = tradeNo;
return this;
}
public String getOutTradeNo() {
return bizContent.outTradeNo;
}
public AlipayTradeQueryRequestBuilder setOutTradeNo(String outTradeNo) {
bizContent.outTradeNo = outTradeNo;
return this;
}
public static class BizContent {
// 支付宝交易号,和商户订单号不能同时为空, 如果同时存在则通过tradeNo查询支付宝交易
@SerializedName("trade_no")
private String tradeNo;
// 商户订单号,通过此商户订单号查询当面付的交易状态
@SerializedName("out_trade_no")
private String outTradeNo;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("BizContent{");
sb.append("tradeNo='").append(tradeNo).append('\'');
sb.append(", outTradeNo='").append(outTradeNo).append('\'');
sb.append('}');
return sb.toString();
}
}
}

View File

@@ -0,0 +1,172 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder;
import com.google.gson.annotations.SerializedName;
import org.apache.commons.lang.StringUtils;
/**
* Created by liuyangkly on 16/3/3.
*/
public class AlipayTradeRefundRequestBuilder extends RequestBuilder {
private BizContent bizContent = new BizContent();
@Override
public BizContent getBizContent() {
return bizContent;
}
@Override
public boolean validate() {
if (StringUtils.isEmpty(bizContent.outTradeNo) &&
StringUtils.isEmpty(bizContent.tradeNo)) {
throw new NullPointerException("out_trade_no and trade_no should not both be NULL!");
}
if (StringUtils.isEmpty(bizContent.refundAmount)) {
throw new NullPointerException("refund_amount should not be NULL!");
}
if (StringUtils.isEmpty(bizContent.refundReason)) {
throw new NullPointerException("refund_reson should not be NULL!");
}
return true;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("AlipayTradeRefundRequestBuilder{");
sb.append("bizContent=").append(bizContent);
sb.append(", super=").append(super.toString());
sb.append('}');
return sb.toString();
}
@Override
public AlipayTradeRefundRequestBuilder setAppAuthToken(String appAuthToken) {
return (AlipayTradeRefundRequestBuilder) super.setAppAuthToken(appAuthToken);
}
@Override
public AlipayTradeRefundRequestBuilder setNotifyUrl(String notifyUrl) {
return (AlipayTradeRefundRequestBuilder) super.setNotifyUrl(notifyUrl);
}
public String getOutTradeNo() {
return bizContent.outTradeNo;
}
public AlipayTradeRefundRequestBuilder setOutTradeNo(String outTradeNo) {
bizContent.outTradeNo = outTradeNo;
return this;
}
public AlipayTradeRefundRequestBuilder setTradeNo(String tradeNo) {
bizContent.tradeNo = tradeNo;
return this;
}
public AlipayTradeRefundRequestBuilder setRefundAmount(String refundAmount) {
bizContent.refundAmount = refundAmount;
return this;
}
public AlipayTradeRefundRequestBuilder setOutRequestNo(String outRequestNo) {
bizContent.outRequestNo = outRequestNo;
return this;
}
public AlipayTradeRefundRequestBuilder setRefundReason(String refundReason) {
bizContent.refundReason = refundReason;
return this;
}
public AlipayTradeRefundRequestBuilder setStoreId(String storeId) {
bizContent.storeId = storeId;
return this;
}
public AlipayTradeRefundRequestBuilder setAlipayStoreId(String alipayStoreId) {
bizContent.alipayStoreId = alipayStoreId;
return this;
}
public AlipayTradeRefundRequestBuilder setTerminalId(String terminalId) {
bizContent.terminalId = terminalId;
return this;
}
public String getTradeNo() {
return bizContent.tradeNo;
}
public String getRefundAmount() {
return bizContent.refundAmount;
}
public String getOutRequestNo() {
return bizContent.outRequestNo;
}
public String getRefundReason() {
return bizContent.refundReason;
}
public String getStoreId() {
return bizContent.storeId;
}
public String getAlipayStoreId() {
return bizContent.alipayStoreId;
}
public String getTerminalId() {
return bizContent.terminalId;
}
public static class BizContent {
// 支付宝交易号,当面付支付成功后支付宝会返回给商户系统。通过此支付宝交易号进行交易退款
@SerializedName("trade_no")
private String tradeNo;
// (推荐) 外部订单号,可通过外部订单号申请退款,推荐使用
@SerializedName("out_trade_no")
private String outTradeNo;
// 退款金额该金额必须小于等于订单的支付金额此处单位为元精确到小数点后2位
@SerializedName("refund_amount")
private String refundAmount;
// (可选,需要支持重复退货时必填) 商户退款请求号,相同支付宝交易号下的不同退款请求号对应同一笔交易的不同退款申请,
// 对于相同支付宝交易号下多笔相同商户退款请求号的退款交易,支付宝只会进行一次退款
@SerializedName("out_request_no")
private String outRequestNo;
// (必填) 退款原因,可以说明用户退款原因,方便为商家后台提供统计
@SerializedName("refund_reason")
private String refundReason;
// (必填) 商户门店编号,退款情况下可以为商家后台提供退款权限判定和统计等作用,详询支付宝技术支持
@SerializedName("store_id")
private String storeId;
// 支付宝商家平台中配置的商户门店号,详询支付宝技术支持
@SerializedName("alipay_store_id")
private String alipayStoreId;
// 商户机具终端编号,当以机具方式接入支付宝时必传,详询支付宝技术支持
@SerializedName("terminal_id")
private String terminalId;
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("BizContent{");
sb.append("tradeNo='").append(tradeNo).append('\'');
sb.append(", outTradeNo='").append(outTradeNo).append('\'');
sb.append(", refundAmount='").append(refundAmount).append('\'');
sb.append(", outRequestNo='").append(outRequestNo).append('\'');
sb.append(", refundReason='").append(refundReason).append('\'');
sb.append(", storeId='").append(storeId).append('\'');
sb.append(", alipayStoreId='").append(alipayStoreId).append('\'');
sb.append(", terminalId='").append(terminalId).append('\'');
sb.append('}');
return sb.toString();
}
}
}

View File

@@ -0,0 +1,69 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.utils.GsonFactory;
/**
* Created by liuyangkly on 15/7/31.
*/
public abstract class RequestBuilder {
private String appAuthToken;
private String notifyUrl;
// 验证请求对象
public abstract boolean validate();
// 获取bizContent对象用于下一步转换为json字符串
public abstract Object getBizContent();
// 将bizContent对象转换为json字符串
public String toJsonString() {
// 使用gson将对象转换为json字符串
/**
* See https://sites.google.com/site/gson/gson-user-guide#TOC-Using-Gson
* Object Examples
class BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
BagOfPrimitives() {
// no-args constructor
}
}
(Serialization)
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);
==> json is {"value1":1,"value2":"abc"}
*/
return GsonFactory.getGson().toJson(this.getBizContent());
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("RequestBuilder{");
sb.append("appAuthToken='").append(appAuthToken).append('\'');
sb.append(", notifyUrl='").append(notifyUrl).append('\'');
sb.append('}');
return sb.toString();
}
public String getAppAuthToken() {
return appAuthToken;
}
public RequestBuilder setAppAuthToken(String appAuthToken) {
this.appAuthToken = appAuthToken;
return this;
}
public String getNotifyUrl() {
return notifyUrl;
}
public RequestBuilder setNotifyUrl(String notifyUrl) {
this.notifyUrl = notifyUrl;
return this;
}
}

View File

@@ -0,0 +1,26 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb;
/**
* Created by liuyangkly on 15/8/27.
*/
public enum EquipStatus {
ON("10") // 开机
,OFF("20") // 关机
,NORMAL("30") // 正常
,SLEEP("40") // 进入休眠
,AWAKE("41"); // 唤醒
private String value;
EquipStatus(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}

View File

@@ -0,0 +1,18 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
/**
* Created by liuyangkly on 15/8/27.
*/
public class EquipStatusAdapter implements JsonSerializer<EquipStatus> {
@Override
public JsonElement serialize(EquipStatus equipStatus, Type type, JsonSerializationContext jsonSerializationContext) {
return new JsonPrimitive(equipStatus.getValue());
}
}

View File

@@ -0,0 +1,12 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb;
/**
* Created by liuyangkly on 15/8/27.
*/
public enum ExceptionInfo {
HE_PRINTER // 打印机异常;
,HE_SCANER // 扫描枪异常;
,HE_OTHER // 其他硬件异常
}

View File

@@ -0,0 +1,25 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.utils.Utils;
import org.apache.commons.lang.StringUtils;
import java.lang.reflect.Type;
import java.util.List;
/**
* Created by liuyangkly on 15/8/27.
*/
public class ExceptionInfoAdapter implements JsonSerializer<List<ExceptionInfo>> {
@Override
public JsonElement serialize(List<ExceptionInfo> exceptionInfos, Type type, JsonSerializationContext jsonSerializationContext) {
if (Utils.isListEmpty(exceptionInfos)) {
return null;
}
return new JsonPrimitive(StringUtils.join(exceptionInfos, "|"));
}
}

View File

@@ -0,0 +1,22 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb;
/**
* Created by liuyangkly on 15/8/27.
*/
public enum HbStatus {
S // 交易成功(包括支付宝返回“处理中”)
,I // 支付宝返回处理中
,F // 支付宝返回失败
,P // POSP返回失败或商户系统失败
,X // 建立连接异常
,Y // 报文上送异常
,Z // 报文接收异常
,C // 收银员取消
}

View File

@@ -0,0 +1,59 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb;
/**
* Created by liuyangkly on 15/9/28.
*/
public class PosTradeInfo implements TradeInfo {
private HbStatus status;
private String time;
private int timeConsume;
private PosTradeInfo() {
// no public constructor.
}
public static PosTradeInfo newInstance(HbStatus status, String time, int timeConsume) {
PosTradeInfo info = new PosTradeInfo();
if (timeConsume > 99 || timeConsume < 0) {
timeConsume = 99;
}
info.setTimeConsume(timeConsume);
info.setStatus(status);
info.setTime(time);
return info;
}
@Override
public String toString() {
return new StringBuilder(status.name())
.append(time)
.append(String.format("%02d", timeConsume))
.toString();
}
@Override
public HbStatus getStatus() {
return status;
}
public void setStatus(HbStatus status) {
this.status = status;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
@Override
public double getTimeConsume() {
return (double) timeConsume;
}
public void setTimeConsume(int timeConsume) {
this.timeConsume = timeConsume;
}
}

View File

@@ -0,0 +1,10 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb;
/**
* Created by liuyangkly on 15/8/27.
*/
public enum Product {
FP // 当面付产品
,MP // 医疗产品
}

View File

@@ -0,0 +1,58 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb;
import com.google.gson.annotations.SerializedName;
/**
* Created by liuyangkly on 15/8/27.
*/
public class SysTradeInfo implements TradeInfo {
@SerializedName("OTN")
private String outTradeNo;
@SerializedName("TC")
private double timeConsume;
@SerializedName("STAT")
private HbStatus status;
private SysTradeInfo() {
// no public constructor.
}
public static SysTradeInfo newInstance(String outTradeNo, double timeConsume, HbStatus status) {
SysTradeInfo info = new SysTradeInfo();
info.setOutTradeNo(outTradeNo);
if (timeConsume > 99 || timeConsume < 0) {
timeConsume = 99;
}
info.setTimeConsume(timeConsume);
info.setStatus(status);
return info;
}
public String getOutTradeNo() {
return outTradeNo;
}
public void setOutTradeNo(String outTradeNo) {
this.outTradeNo = outTradeNo;
}
@Override
public HbStatus getStatus() {
return status;
}
public void setStatus(HbStatus status) {
this.status = status;
}
@Override
public double getTimeConsume() {
return timeConsume;
}
public void setTimeConsume(double timeConsume) {
this.timeConsume = timeConsume;
}
}

View File

@@ -0,0 +1,12 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb;
/**
* Created by liuyangkly on 15/9/28.
*/
public interface TradeInfo {
// 获取交易状态
public HbStatus getStatus();
// 获取交易时间
public double getTimeConsume();
}

View File

@@ -0,0 +1,30 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.utils.Utils;
import org.apache.commons.lang.StringUtils;
import java.lang.reflect.Type;
import java.util.List;
/**
* Created by liuyangkly on 15/9/28.
*/
public class TradeInfoAdapter implements JsonSerializer<List<TradeInfo>> {
@Override
public JsonElement serialize(List<TradeInfo> tradeInfoList, Type type, JsonSerializationContext jsonSerializationContext) {
if (Utils.isListEmpty(tradeInfoList)) {
return null;
}
TradeInfo tradeInfo = tradeInfoList.get(0);
if (tradeInfo instanceof PosTradeInfo) {
return new JsonPrimitive(StringUtils.join(tradeInfoList, ""));
}
return jsonSerializationContext.serialize(tradeInfoList);
}
}

View File

@@ -0,0 +1,20 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb;
/**
* Created by liuyangkly on 15/8/27.
*/
public enum Type {
CR // 收银机
,STORE // 门店
,VM // 售卖机
,MD // 医疗设备
,SOFT_POS // 软POS
,POS // POS终端
,ALI_POS // 支付宝POS
}

View File

@@ -0,0 +1,38 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result;
import com.alipay.api.response.AlipayTradePayResponse;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.TradeStatus;
/**
* Created by liuyangkly on 15/8/26.
*/
public class AlipayF2FPayResult implements Result {
private TradeStatus tradeStatus;
private AlipayTradePayResponse response;
public AlipayF2FPayResult(AlipayTradePayResponse response) {
this.response = response;
}
public void setTradeStatus(TradeStatus tradeStatus) {
this.tradeStatus = tradeStatus;
}
public void setResponse(AlipayTradePayResponse response) {
this.response = response;
}
public TradeStatus getTradeStatus() {
return tradeStatus;
}
public AlipayTradePayResponse getResponse() {
return response;
}
@Override
public boolean isTradeSuccess() {
return response != null &&
TradeStatus.SUCCESS.equals(tradeStatus);
}
}

View File

@@ -0,0 +1,38 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.TradeStatus;
/**
* Created by liuyangkly on 15/8/27.
*/
public class AlipayF2FPrecreateResult implements Result {
private TradeStatus tradeStatus;
private AlipayTradePrecreateResponse response;
public AlipayF2FPrecreateResult(AlipayTradePrecreateResponse response) {
this.response = response;
}
public void setTradeStatus(TradeStatus tradeStatus) {
this.tradeStatus = tradeStatus;
}
public void setResponse(AlipayTradePrecreateResponse response) {
this.response = response;
}
public TradeStatus getTradeStatus() {
return tradeStatus;
}
public AlipayTradePrecreateResponse getResponse() {
return response;
}
@Override
public boolean isTradeSuccess() {
return response != null &&
TradeStatus.SUCCESS.equals(tradeStatus);
}
}

View File

@@ -0,0 +1,38 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.TradeStatus;
/**
* Created by liuyangkly on 15/8/27.
*/
public class AlipayF2FQueryResult implements Result {
private TradeStatus tradeStatus;
private AlipayTradeQueryResponse response;
public AlipayF2FQueryResult(AlipayTradeQueryResponse response) {
this.response = response;
}
public void setTradeStatus(TradeStatus tradeStatus) {
this.tradeStatus = tradeStatus;
}
public void setResponse(AlipayTradeQueryResponse response) {
this.response = response;
}
public TradeStatus getTradeStatus() {
return tradeStatus;
}
public AlipayTradeQueryResponse getResponse() {
return response;
}
@Override
public boolean isTradeSuccess() {
return response != null &&
TradeStatus.SUCCESS.equals(tradeStatus);
}
}

View File

@@ -0,0 +1,38 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.TradeStatus;
/**
* Created by liuyangkly on 15/8/27.
*/
public class AlipayF2FRefundResult implements Result {
private TradeStatus tradeStatus;
private AlipayTradeRefundResponse response;
public AlipayF2FRefundResult(AlipayTradeRefundResponse response) {
this.response = response;
}
public void setTradeStatus(TradeStatus tradeStatus) {
this.tradeStatus = tradeStatus;
}
public void setResponse(AlipayTradeRefundResponse response) {
this.response = response;
}
public TradeStatus getTradeStatus() {
return tradeStatus;
}
public AlipayTradeRefundResponse getResponse() {
return response;
}
@Override
public boolean isTradeSuccess() {
return response != null &&
TradeStatus.SUCCESS.equals(tradeStatus);
}
}

View File

@@ -0,0 +1,10 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result;
/**
* Created by liuyangkly on 15/8/27.
*/
public interface Result {
// 判断交易是否在业务上成功, 返回true说明一定成功但是返回false并不代表业务不成功因为还有unknown的状态可能业务已经成功了
public boolean isTradeSuccess();
}

View File

@@ -0,0 +1,15 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.service;
import com.alipay.api.response.MonitorHeartbeatSynResponse;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayHeartbeatSynRequestBuilder;
/**
* Created by liuyangkly on 15/10/22.
*/
public interface AlipayMonitorService {
// 交易保障接口 https://openhome.alipay.com/platform/document.htm#mobileApp-barcodePay-API-heartBeat
// 可以提供给系统商/pos厂商使用
public MonitorHeartbeatSynResponse heartbeatSyn(AlipayHeartbeatSynRequestBuilder builder);
}

View File

@@ -0,0 +1,29 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.service;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayTradePayRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayTradePrecreateRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayTradeQueryRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayTradeRefundRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result.AlipayF2FPayResult;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result.AlipayF2FPrecreateResult;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result.AlipayF2FQueryResult;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result.AlipayF2FRefundResult;
/**
* Created by liuyangkly on 15/7/29.
*/
public interface AlipayTradeService {
// 当面付2.0流程支付
public AlipayF2FPayResult tradePay(AlipayTradePayRequestBuilder builder);
// 当面付2.0消费查询
public AlipayF2FQueryResult queryTradeResult(AlipayTradeQueryRequestBuilder builder);
// 当面付2.0消费退款
public AlipayF2FRefundResult tradeRefund(AlipayTradeRefundRequestBuilder builder);
// 当面付2.0预下单(生成二维码)
public AlipayF2FPrecreateResult tradePrecreate(AlipayTradePrecreateRequestBuilder builder);
}

View File

@@ -0,0 +1,43 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.service.impl;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayRequest;
import com.alipay.api.AlipayResponse;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.RequestBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Created by liuyangkly on 15/10/22.
*/
abstract class AbsAlipayService {
protected Log log = LogFactory.getLog(getClass());
// 验证bizContent对象
protected void validateBuilder(RequestBuilder builder) {
if (builder == null) {
throw new NullPointerException("builder should not be NULL!");
}
if (!builder.validate()) {
throw new IllegalStateException("builder validate failed! " + builder.toString());
}
}
// 调用AlipayClient的execute方法进行远程调用
@SuppressWarnings({ "rawtypes", "unchecked" })
protected AlipayResponse getResponse(AlipayClient client, AlipayRequest request) {
try {
AlipayResponse response = client.execute(request);
if (response != null) {
log.info(response.getBody());
}
return response;
} catch (AlipayApiException e) {
e.printStackTrace();
return null;
}
}
}

View File

@@ -0,0 +1,276 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.service.impl;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayResponse;
import com.alipay.api.request.AlipayTradeCancelRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.*;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.config.Configs;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.config.Constants;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.TradeStatus;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayTradeCancelRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayTradePrecreateRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayTradeQueryRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayTradeRefundRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result.AlipayF2FPayResult;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result.AlipayF2FPrecreateResult;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result.AlipayF2FQueryResult;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result.AlipayF2FRefundResult;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.service.AlipayTradeService;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.utils.Utils;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by liuyangkly on 15/10/28.
*/
abstract class AbsAlipayTradeService extends AbsAlipayService implements AlipayTradeService {
protected static ExecutorService executorService = Executors.newCachedThreadPool();
protected AlipayClient client;
@Override
public AlipayF2FQueryResult queryTradeResult(AlipayTradeQueryRequestBuilder builder) {
AlipayTradeQueryResponse response = tradeQuery(builder);
AlipayF2FQueryResult result = new AlipayF2FQueryResult(response);
if (querySuccess(response)) {
// 查询返回该订单交易支付成功
result.setTradeStatus(TradeStatus.SUCCESS);
} else if (tradeError(response)) {
// 查询发生异常,交易状态未知
result.setTradeStatus(TradeStatus.UNKNOWN);
} else {
// 其他情况均表明该订单号交易失败
result.setTradeStatus(TradeStatus.FAILED);
}
return result;
}
protected AlipayTradeQueryResponse tradeQuery(AlipayTradeQueryRequestBuilder builder) {
validateBuilder(builder);
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
request.putOtherTextParam("app_auth_token", builder.getAppAuthToken());
request.setBizContent(builder.toJsonString());
log.info("trade.query bizContent:" + request.getBizContent());
return (AlipayTradeQueryResponse) getResponse(client, request);
}
@Override
public AlipayF2FRefundResult tradeRefund(AlipayTradeRefundRequestBuilder builder) {
validateBuilder(builder);
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
request.setNotifyUrl(builder.getNotifyUrl());
request.putOtherTextParam("app_auth_token", builder.getAppAuthToken());
request.setBizContent(builder.toJsonString());
log.info("trade.refund bizContent:" + request.getBizContent());
AlipayTradeRefundResponse response = (AlipayTradeRefundResponse) getResponse(client, request);
AlipayF2FRefundResult result = new AlipayF2FRefundResult(response);
if (response != null && Constants.SUCCESS.equals(response.getCode())) {
// 退货交易成功
result.setTradeStatus(TradeStatus.SUCCESS);
} else if (tradeError(response)) {
// 退货发生异常,退货状态未知
result.setTradeStatus(TradeStatus.UNKNOWN);
} else {
// 其他情况表明该订单退货明确失败
result.setTradeStatus(TradeStatus.FAILED);
}
return result;
}
@Override
public AlipayF2FPrecreateResult tradePrecreate(AlipayTradePrecreateRequestBuilder builder) {
validateBuilder(builder);
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.setNotifyUrl(builder.getNotifyUrl());
request.putOtherTextParam("app_auth_token", builder.getAppAuthToken());
request.setBizContent(builder.toJsonString());
log.info("trade.precreate bizContent:" + request.getBizContent());
AlipayTradePrecreateResponse response = (AlipayTradePrecreateResponse) getResponse(client, request);
AlipayF2FPrecreateResult result = new AlipayF2FPrecreateResult(response);
if (response != null && Constants.SUCCESS.equals(response.getCode())) {
// 预下单交易成功
result.setTradeStatus(TradeStatus.SUCCESS);
} else if (tradeError(response)) {
// 预下单发生异常,状态未知
result.setTradeStatus(TradeStatus.UNKNOWN);
} else {
// 其他情况表明该预下单明确失败
result.setTradeStatus(TradeStatus.FAILED);
}
return result;
}
// 根据查询结果queryResponse判断交易是否支付成功如果支付成功则更新result并返回如果不成功则调用撤销
protected AlipayF2FPayResult checkQueryAndCancel(String outTradeNo, String appAuthToken, AlipayF2FPayResult result,
AlipayTradeQueryResponse queryResponse) {
if (querySuccess(queryResponse)) {
// 如果查询返回支付成功,则返回相应结果
result.setTradeStatus(TradeStatus.SUCCESS);
result.setResponse(toPayResponse(queryResponse));
return result;
}
// 如果查询结果不为成功,则调用撤销
AlipayTradeCancelRequestBuilder builder = new AlipayTradeCancelRequestBuilder().setOutTradeNo(outTradeNo);
builder.setAppAuthToken(appAuthToken);
AlipayTradeCancelResponse cancelResponse = cancelPayResult(builder);
if (tradeError(cancelResponse)) {
// 如果第一次同步撤销返回异常,则标记支付交易为未知状态
result.setTradeStatus(TradeStatus.UNKNOWN);
} else {
// 标记支付为失败,如果撤销未能成功,产生的单边帐由人工处理
result.setTradeStatus(TradeStatus.FAILED);
}
return result;
}
// 根据外部订单号outTradeNo撤销订单
protected AlipayTradeCancelResponse tradeCancel(AlipayTradeCancelRequestBuilder builder) {
validateBuilder(builder);
AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
request.putOtherTextParam("app_auth_token", builder.getAppAuthToken());
request.setBizContent(builder.toJsonString());
log.info("trade.cancel bizContent:" + request.getBizContent());
return (AlipayTradeCancelResponse) getResponse(client, request);
}
// 轮询查询订单支付结果
protected AlipayTradeQueryResponse loopQueryResult(AlipayTradeQueryRequestBuilder builder) {
AlipayTradeQueryResponse queryResult = null;
for (int i = 0; i < Configs.getMaxQueryRetry(); i++) {
Utils.sleep(Configs.getQueryDuration());
AlipayTradeQueryResponse response = tradeQuery(builder);
if (response != null) {
if (stopQuery(response)) {
return response;
}
queryResult = response;
}
}
return queryResult;
}
// 判断是否停止查询
protected boolean stopQuery(AlipayTradeQueryResponse response) {
if (Constants.SUCCESS.equals(response.getCode())) {
if ("TRADE_FINISHED".equals(response.getTradeStatus()) ||
"TRADE_SUCCESS".equals(response.getTradeStatus()) ||
"TRADE_CLOSED".equals(response.getTradeStatus())) {
// 如果查询到交易成功、交易结束、交易关闭,则返回对应结果
return true;
}
}
return false;
}
// 根据外部订单号outTradeNo撤销订单
protected AlipayTradeCancelResponse cancelPayResult(AlipayTradeCancelRequestBuilder builder) {
AlipayTradeCancelResponse response = tradeCancel(builder);
if (cancelSuccess(response)) {
// 如果撤销成功,则返回撤销结果
return response;
}
// 撤销失败
if (needRetry(response)) {
// 如果需要重试,首先记录日志,然后调用异步撤销
log.warn("begin async cancel request:" + builder);
asyncCancel(builder);
}
return response;
}
// 异步撤销
protected void asyncCancel(final AlipayTradeCancelRequestBuilder builder) {
executorService.submit(new Runnable() {
@Override
public void run() {
for (int i = 0; i < Configs.getMaxCancelRetry(); i++) {
Utils.sleep(Configs.getCancelDuration());
AlipayTradeCancelResponse response = tradeCancel(builder);
if (cancelSuccess(response) ||
!needRetry(response)) {
// 如果撤销成功或者应答告知不需要重试撤销,则返回撤销结果(无论撤销是成功失败,失败人工处理)
return ;
}
}
}
});
}
// 将查询应答转换为支付应答
protected AlipayTradePayResponse toPayResponse(AlipayTradeQueryResponse response) {
AlipayTradePayResponse payResponse = new AlipayTradePayResponse();
// 只有查询明确返回成功才能将返回码设置为10000否则均为失败
payResponse.setCode(querySuccess(response) ? Constants.SUCCESS : Constants.FAILED);
// 补充交易状态信息
StringBuilder msg = new StringBuilder(response.getMsg())
.append(" tradeStatus:")
.append(response.getTradeStatus());
payResponse.setMsg(msg.toString());
payResponse.setSubCode(response.getSubCode());
payResponse.setSubMsg(response.getSubMsg());
payResponse.setBody(response.getBody());
payResponse.setParams(response.getParams());
// payResponse应该是交易支付时间但是response里是本次交易打款给卖家的时间,是否有问题
// payResponse.setGmtPayment(response.getSendPayDate());
payResponse.setBuyerLogonId(response.getBuyerLogonId());
payResponse.setFundBillList(response.getFundBillList());
payResponse.setOpenId(response.getOpenId());
payResponse.setOutTradeNo(response.getOutTradeNo());
payResponse.setReceiptAmount(response.getReceiptAmount());
payResponse.setTotalAmount(response.getTotalAmount());
payResponse.setTradeNo(response.getTradeNo());
return payResponse;
}
// 撤销需要重试
protected boolean needRetry(AlipayTradeCancelResponse response) {
return response == null ||
"Y".equals(response.getRetryFlag());
}
// 查询返回“支付成功”
protected boolean querySuccess(AlipayTradeQueryResponse response) {
return response != null &&
Constants.SUCCESS.equals(response.getCode()) &&
("TRADE_SUCCESS".equals(response.getTradeStatus()) ||
"TRADE_FINISHED".equals(response.getTradeStatus())
);
}
// 撤销返回“撤销成功”
protected boolean cancelSuccess(AlipayTradeCancelResponse response) {
return response != null &&
Constants.SUCCESS.equals(response.getCode());
}
// 交易异常,或发生系统错误
protected boolean tradeError(AlipayResponse response) {
return response == null ||
Constants.ERROR.equals(response.getCode());
}
}

View File

@@ -0,0 +1,140 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.service.impl;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.MonitorHeartbeatSynRequest;
import com.alipay.api.response.MonitorHeartbeatSynResponse;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.config.Configs;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayHeartbeatSynRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.service.AlipayMonitorService;
import org.apache.commons.lang.StringUtils;
/**
* Created by liuyangkly on 15/10/22.
*/
public class AlipayMonitorServiceImpl extends AbsAlipayService implements AlipayMonitorService {
private AlipayClient client;
public static class ClientBuilder {
private String gatewayUrl;
private String appid;
private String privateKey;
private String format;
private String charset;
private String signType;
public AlipayMonitorServiceImpl build() {
if (StringUtils.isEmpty(gatewayUrl)) {
gatewayUrl = Configs.getMcloudApiDomain(); // 与openapi网关地址不同
}
if (StringUtils.isEmpty(appid)) {
appid = Configs.getAppid();
}
if (StringUtils.isEmpty(privateKey)) {
privateKey = Configs.getPrivateKey();
}
if (StringUtils.isEmpty(format)) {
format = "json";
}
if (StringUtils.isEmpty(charset)) {
charset = "utf-8";
}
if (StringUtils.isEmpty(signType)) {
signType = Configs.getSignType();
}
return new AlipayMonitorServiceImpl(this);
}
public ClientBuilder setAppid(String appid) {
this.appid = appid;
return this;
}
public ClientBuilder setCharset(String charset) {
this.charset = charset;
return this;
}
public ClientBuilder setFormat(String format) {
this.format = format;
return this;
}
public ClientBuilder setGatewayUrl(String gatewayUrl) {
this.gatewayUrl = gatewayUrl;
return this;
}
public ClientBuilder setPrivateKey(String privateKey) {
this.privateKey = privateKey;
return this;
}
public ClientBuilder setSignType(String signType) {
this.signType = signType;
return this;
}
public String getAppid() {
return appid;
}
public String getCharset() {
return charset;
}
public String getFormat() {
return format;
}
public String getGatewayUrl() {
return gatewayUrl;
}
public String getPrivateKey() {
return privateKey;
}
public String getSignType() {
return signType;
}
}
public AlipayMonitorServiceImpl(ClientBuilder builder) {
if (StringUtils.isEmpty(builder.getGatewayUrl())) {
throw new NullPointerException("gatewayUrl should not be NULL!");
}
if (StringUtils.isEmpty(builder.getAppid())) {
throw new NullPointerException("appid should not be NULL!");
}
if (StringUtils.isEmpty(builder.getPrivateKey())) {
throw new NullPointerException("privateKey should not be NULL!");
}
if (StringUtils.isEmpty(builder.getFormat())) {
throw new NullPointerException("format should not be NULL!");
}
if (StringUtils.isEmpty(builder.getCharset())) {
throw new NullPointerException("charset should not be NULL!");
}
if (StringUtils.isEmpty(builder.getSignType())) {
throw new NullPointerException("signType should not be NULL!");
}
// 此处不需要使用alipay public key因为金融云不产生签名
client = new DefaultAlipayClient(builder.getGatewayUrl(), builder.getAppid(), builder.getPrivateKey(),
builder.getFormat(), builder.getCharset(), builder.getSignType());
}
@Override
public MonitorHeartbeatSynResponse heartbeatSyn(AlipayHeartbeatSynRequestBuilder builder) {
validateBuilder(builder);
MonitorHeartbeatSynRequest request = new MonitorHeartbeatSynRequest();
request.putOtherTextParam("app_auth_token", builder.getAppAuthToken());
request.setBizContent(builder.toJsonString());
log.info("heartbeat.sync bizContent:" + request.getBizContent());
return (MonitorHeartbeatSynResponse) getResponse(client, request);
}
}

View File

@@ -0,0 +1,199 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.service.impl;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.config.Configs;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.config.Constants;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.TradeStatus;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayTradePayRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayTradeQueryRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result.AlipayF2FPayResult;
import org.apache.commons.lang.StringUtils;
/**
* Created by liuyangkly on 15/7/29.
*
* 一定要在创建AlipayTradeService之前调用Configs.init("xxxxxx");设置参数
*
*/
public class AlipayTradeServiceImpl extends AbsAlipayTradeService {
public static class ClientBuilder {
private String gatewayUrl;
private String appid;
private String privateKey;
private String format;
private String charset;
private String alipayPublicKey;
private String signType;
public AlipayTradeServiceImpl build() {
if (StringUtils.isEmpty(gatewayUrl)) {
gatewayUrl = Configs.getOpenApiDomain(); // 与mcloudmonitor网关地址不同
}
if (StringUtils.isEmpty(appid)) {
appid = Configs.getAppid();
}
if (StringUtils.isEmpty(privateKey)) {
privateKey = Configs.getPrivateKey();
}
if (StringUtils.isEmpty(format)) {
format = "json";
}
if (StringUtils.isEmpty(charset)) {
charset = "utf-8";
}
if (StringUtils.isEmpty(alipayPublicKey)) {
alipayPublicKey = Configs.getAlipayPublicKey();
}
if (StringUtils.isEmpty(signType)) {
signType = Configs.getSignType();
}
return new AlipayTradeServiceImpl(this);
}
public ClientBuilder setAlipayPublicKey(String alipayPublicKey) {
this.alipayPublicKey = alipayPublicKey;
return this;
}
public ClientBuilder setAppid(String appid) {
this.appid = appid;
return this;
}
public ClientBuilder setCharset(String charset) {
this.charset = charset;
return this;
}
public ClientBuilder setFormat(String format) {
this.format = format;
return this;
}
public ClientBuilder setGatewayUrl(String gatewayUrl) {
this.gatewayUrl = gatewayUrl;
return this;
}
public ClientBuilder setPrivateKey(String privateKey) {
this.privateKey = privateKey;
return this;
}
public ClientBuilder setSignType(String signType) {
this.signType = signType;
return this;
}
public String getAlipayPublicKey() {
return alipayPublicKey;
}
public String getSignType() {
return signType;
}
public String getAppid() {
return appid;
}
public String getCharset() {
return charset;
}
public String getFormat() {
return format;
}
public String getGatewayUrl() {
return gatewayUrl;
}
public String getPrivateKey() {
return privateKey;
}
}
public AlipayTradeServiceImpl(ClientBuilder builder) {
if (StringUtils.isEmpty(builder.getGatewayUrl())) {
throw new NullPointerException("gatewayUrl should not be NULL!");
}
if (StringUtils.isEmpty(builder.getAppid())) {
throw new NullPointerException("appid should not be NULL!");
}
if (StringUtils.isEmpty(builder.getPrivateKey())) {
throw new NullPointerException("privateKey should not be NULL!");
}
if (StringUtils.isEmpty(builder.getFormat())) {
throw new NullPointerException("format should not be NULL!");
}
if (StringUtils.isEmpty(builder.getCharset())) {
throw new NullPointerException("charset should not be NULL!");
}
if (StringUtils.isEmpty(builder.getAlipayPublicKey())) {
throw new NullPointerException("alipayPublicKey should not be NULL!");
}
if (StringUtils.isEmpty(builder.getSignType())) {
throw new NullPointerException("signType should not be NULL!");
}
client = new DefaultAlipayClient(builder.getGatewayUrl(), builder.getAppid(), builder.getPrivateKey(),
builder.getFormat(), builder.getCharset(), builder.getAlipayPublicKey(), builder.getSignType());
}
// 商户可以直接使用的pay方法
@Override
public AlipayF2FPayResult tradePay(AlipayTradePayRequestBuilder builder) {
validateBuilder(builder);
final String outTradeNo = builder.getOutTradeNo();
AlipayTradePayRequest request = new AlipayTradePayRequest();
// 设置平台参数
request.setNotifyUrl(builder.getNotifyUrl());
String appAuthToken = builder.getAppAuthToken();
// todo 等支付宝sdk升级公共参数后使用如下方法
// request.setAppAuthToken(appAuthToken);
request.putOtherTextParam("app_auth_token", builder.getAppAuthToken());
// 设置业务参数
request.setBizContent(builder.toJsonString());
log.info("trade.pay bizContent:" + request.getBizContent());
// 首先调用支付api
AlipayTradePayResponse response = (AlipayTradePayResponse) getResponse(client, request);
AlipayF2FPayResult result = new AlipayF2FPayResult(response);
if (response != null && Constants.SUCCESS.equals(response.getCode())) {
// 支付交易明确成功
result.setTradeStatus(TradeStatus.SUCCESS);
} else if (response != null && Constants.PAYING.equals(response.getCode())) {
// 返回用户处理中,则轮询查询交易是否成功,如果查询超时,则调用撤销
AlipayTradeQueryRequestBuilder queryBuiler = new AlipayTradeQueryRequestBuilder()
.setAppAuthToken(appAuthToken)
.setOutTradeNo(outTradeNo);
AlipayTradeQueryResponse loopQueryResponse = loopQueryResult(queryBuiler);
return checkQueryAndCancel(outTradeNo, appAuthToken, result, loopQueryResponse);
} else if (tradeError(response)) {
// 系统错误,则查询一次交易,如果交易没有支付成功,则调用撤销
AlipayTradeQueryRequestBuilder queryBuiler = new AlipayTradeQueryRequestBuilder()
.setAppAuthToken(appAuthToken)
.setOutTradeNo(outTradeNo);
AlipayTradeQueryResponse queryResponse = tradeQuery(queryBuiler);
return checkQueryAndCancel(outTradeNo, appAuthToken, result, queryResponse);
} else {
// 其他情况表明该订单支付明确失败
result.setTradeStatus(TradeStatus.FAILED);
}
return result;
}
}

View File

@@ -0,0 +1,303 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.service.impl;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.config.Configs;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.config.Constants;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.TradeStatus;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayTradePayRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayTradeQueryRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.result.AlipayF2FPayResult;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.service.impl.hb.HbListener;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.service.impl.hb.TradeListener;
import org.apache.commons.lang.StringUtils;
import java.net.ConnectException;
import java.net.NoRouteToHostException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
/**
* Created by liuyangkly on 15/7/29.
*
* 一定要在创建AlipayTradeService之前调用Configs.init("alipayrisk10");设置参数
*
*/
public class AlipayTradeWithHBServiceImpl extends AbsAlipayTradeService {
private TradeListener listener;
public static class ClientBuilder {
private String gatewayUrl;
private String appid;
private String privateKey;
private String format;
private String charset;
private String alipayPublicKey;
private String signType;
private TradeListener listener;
public AlipayTradeWithHBServiceImpl build() {
if (StringUtils.isEmpty(gatewayUrl)) {
gatewayUrl = Configs.getOpenApiDomain(); // 与mcloudmonitor网关地址不同
}
if (StringUtils.isEmpty(appid)) {
appid = Configs.getAppid();
}
if (StringUtils.isEmpty(privateKey)) {
privateKey = Configs.getPrivateKey();
}
if (StringUtils.isEmpty(format)) {
format = "json";
}
if (StringUtils.isEmpty(charset)) {
charset = "utf-8";
}
if (StringUtils.isEmpty(alipayPublicKey)) {
alipayPublicKey = Configs.getAlipayPublicKey();
}
if (StringUtils.isEmpty(signType)) {
signType = Configs.getSignType();
}
if (listener == null) {
listener = new HbListener(); // 默认监听器
}
return new AlipayTradeWithHBServiceImpl(this);
}
public TradeListener getListener() {
return listener;
}
public ClientBuilder setListener(TradeListener listener) {
this.listener = listener;
return this;
}
public ClientBuilder setAlipayPublicKey(String alipayPublicKey) {
this.alipayPublicKey = alipayPublicKey;
return this;
}
public ClientBuilder setAppid(String appid) {
this.appid = appid;
return this;
}
public ClientBuilder setCharset(String charset) {
this.charset = charset;
return this;
}
public ClientBuilder setFormat(String format) {
this.format = format;
return this;
}
public ClientBuilder setGatewayUrl(String gatewayUrl) {
this.gatewayUrl = gatewayUrl;
return this;
}
public ClientBuilder setPrivateKey(String privateKey) {
this.privateKey = privateKey;
return this;
}
public ClientBuilder setSignType(String signType) {
this.signType = signType;
return this;
}
public String getAlipayPublicKey() {
return alipayPublicKey;
}
public String getSignType() {
return signType;
}
public String getAppid() {
return appid;
}
public String getCharset() {
return charset;
}
public String getFormat() {
return format;
}
public String getGatewayUrl() {
return gatewayUrl;
}
public String getPrivateKey() {
return privateKey;
}
}
public AlipayTradeWithHBServiceImpl(ClientBuilder builder) {
if (StringUtils.isEmpty(builder.getGatewayUrl())) {
throw new NullPointerException("gatewayUrl should not be NULL!");
}
if (StringUtils.isEmpty(builder.getAppid())) {
throw new NullPointerException("appid should not be NULL!");
}
if (StringUtils.isEmpty(builder.getPrivateKey())) {
throw new NullPointerException("privateKey should not be NULL!");
}
if (StringUtils.isEmpty(builder.getFormat())) {
throw new NullPointerException("format should not be NULL!");
}
if (StringUtils.isEmpty(builder.getCharset())) {
throw new NullPointerException("charset should not be NULL!");
}
if (StringUtils.isEmpty(builder.getAlipayPublicKey())) {
throw new NullPointerException("alipayPublicKey should not be NULL!");
}
if (StringUtils.isEmpty(builder.getSignType())) {
throw new NullPointerException("signType should not be NULL!");
}
if (builder.getListener() == null) {
throw new NullPointerException("listener should not be NULL!");
}
listener = builder.getListener();
client = new DefaultAlipayClient(builder.getGatewayUrl(), builder.getAppid(), builder.getPrivateKey(),
builder.getFormat(), builder.getCharset(), builder.getAlipayPublicKey(), builder.getSignType());
}
private AlipayTradePayResponse getResponse(AlipayClient client, AlipayTradePayRequest request,
final String outTradeNo, final long beforeCall) {
try {
AlipayTradePayResponse response = client.execute(request);
if (response != null) {
log.info(response.getBody());
}
return response;
} catch (AlipayApiException e) {
// 获取异常真实原因
Throwable cause = e.getCause();
if (cause instanceof ConnectException ||
cause instanceof NoRouteToHostException) {
// 建立连接异常
executorService.submit(new Runnable() {
@Override
public void run() {
listener.onConnectException(outTradeNo, beforeCall);
}
});
} else if (cause instanceof SocketException) {
// 报文上送异常
executorService.submit(new Runnable() {
@Override
public void run() {
listener.onSendException(outTradeNo, beforeCall);
}
});
} else if (cause instanceof SocketTimeoutException) {
// 报文接收异常
executorService.submit(new Runnable() {
@Override
public void run() {
listener.onReceiveException(outTradeNo, beforeCall);
}
});
}
e.printStackTrace();
return null;
}
}
// 商户可以直接使用的pay方法并且集成了监控代码
@Override
public AlipayF2FPayResult tradePay(AlipayTradePayRequestBuilder builder) {
validateBuilder(builder);
final String outTradeNo = builder.getOutTradeNo();
AlipayTradePayRequest request = new AlipayTradePayRequest();
// 设置平台参数
String appAuthToken = builder.getAppAuthToken();
request.setNotifyUrl(builder.getNotifyUrl());
request.putOtherTextParam("app_auth_token", appAuthToken);
// 设置业务参数
request.setBizContent(builder.toJsonString());
log.info("trade.pay bizContent:" + request.getBizContent());
// 首先调用支付api
final long beforeCall = System.currentTimeMillis();
AlipayTradePayResponse response = getResponse(client, request, outTradeNo, beforeCall);
AlipayF2FPayResult result = new AlipayF2FPayResult(response);
if (response != null && Constants.SUCCESS.equals(response.getCode())) {
// 支付交易明确成功
result.setTradeStatus(TradeStatus.SUCCESS);
executorService.submit(new Runnable() {
@Override
public void run() {
listener.onPayTradeSuccess(outTradeNo, beforeCall);
}
});
} else if (response != null && Constants.PAYING.equals(response.getCode())) {
// 返回支付中,同步交易耗时
executorService.submit(new Runnable() {
@Override
public void run() {
listener.onPayInProgress(outTradeNo, beforeCall);
}
});
// 返回用户处理中,则轮询查询交易是否成功,如果查询超时,则调用撤销
AlipayTradeQueryRequestBuilder queryBuiler = new AlipayTradeQueryRequestBuilder()
.setAppAuthToken(appAuthToken)
.setOutTradeNo(outTradeNo);
AlipayTradeQueryResponse loopQueryResponse = loopQueryResult(queryBuiler);
return checkQueryAndCancel(outTradeNo, appAuthToken, result, loopQueryResponse);
} else if (tradeError(response)) {
// 系统错误,同步交易耗时
executorService.submit(new Runnable() {
@Override
public void run() {
listener.onPayFailed(outTradeNo, beforeCall);
}
});
// 系统错误,则查询一次交易,如果交易没有支付成功,则调用撤销
AlipayTradeQueryRequestBuilder queryBuiler = new AlipayTradeQueryRequestBuilder()
.setAppAuthToken(appAuthToken)
.setOutTradeNo(outTradeNo);
AlipayTradeQueryResponse queryResponse = tradeQuery(queryBuiler);
return checkQueryAndCancel(outTradeNo, appAuthToken, result, queryResponse);
} else {
// 其他情况表明该订单支付明确失败
result.setTradeStatus(TradeStatus.FAILED);
executorService.submit(new Runnable() {
@Override
public void run() {
listener.onPayFailed(outTradeNo, beforeCall);
}
});
}
return result;
}
}

View File

@@ -0,0 +1,85 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.service.impl.hb;
import com.alipay.api.response.MonitorHeartbeatSynResponse;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.config.Configs;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.builder.AlipayHeartbeatSynRequestBuilder;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.service.AlipayMonitorService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* Created by liuyangkly on 15/10/23.
*/
public abstract class AbsHbRunner implements Runnable {
protected Log log = LogFactory.getLog(getClass());
// 获取交易保障所需的信息
public abstract AlipayHeartbeatSynRequestBuilder getBuilder();
// 获取商户授权令牌,系统商通过此令牌帮助商户发起请求,完成业务
public abstract String getAppAuthToken();
private ScheduledExecutorService scheduledService = Executors.newSingleThreadScheduledExecutor();
private AlipayMonitorService monitorService;
private long delay = 0;
private long duration = 0;
public AbsHbRunner(AlipayMonitorService monitorService) {
this.monitorService = monitorService;
}
@Override
public void run() {
AlipayHeartbeatSynRequestBuilder builder = getBuilder();
builder.setAppAuthToken(getAppAuthToken());
MonitorHeartbeatSynResponse response = monitorService.heartbeatSyn(builder);
StringBuilder sb = new StringBuilder(response.getCode())
.append(":")
.append(response.getMsg());
if (StringUtils.isNotEmpty(response.getSubCode())) {
sb.append(", ")
.append(response.getSubCode())
.append(":")
.append(response.getSubMsg());
}
log.info(sb.toString());
}
public void schedule() {
if (delay == 0) {
delay = Configs.getHeartbeatDelay();
}
if (duration == 0) {
duration = Configs.getCancelDuration();
}
scheduledService.scheduleAtFixedRate(this, delay, duration, TimeUnit.SECONDS);
}
public void shutdown() {
scheduledService.shutdown();
}
public long getDelay() {
return delay;
}
public void setDelay(long delay) {
this.delay = delay;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
}

View File

@@ -0,0 +1,56 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.service.impl.hb;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb.HbStatus;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb.SysTradeInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Created by liuyangkly on 15/10/28.
*/
public class HbListener implements TradeListener {
private static Log log = LogFactory.getLog(HbListener.class);
private void offerTradeInfo(String outTradeNo, long beforeCall, HbStatus status) {
// 获取当前毫秒数
long afterCall = System.currentTimeMillis();
// 通过交易请求发生时毫秒数计算得到交易耗时
double timeConsume = ((double) (afterCall - beforeCall)) / 1000.0;
log.debug(outTradeNo + " offer " + status + ": " + timeConsume);
// 创建系统商trade_info结构添加进队列
HbQueue.offer(SysTradeInfo.newInstance(outTradeNo, timeConsume, status));
}
@Override
public void onPayTradeSuccess(String outTradeNo, long beforeCall) {
offerTradeInfo(outTradeNo, beforeCall, HbStatus.S);
}
@Override
public void onPayInProgress(String outTradeNo, long beforeCall) {
offerTradeInfo(outTradeNo, beforeCall, HbStatus.I);
}
@Override
public void onPayFailed(String outTradeNo, long beforeCall) {
offerTradeInfo(outTradeNo, beforeCall, HbStatus.F);
}
@Override
public void onConnectException(String outTradeNo, long beforeCall) {
offerTradeInfo(outTradeNo, beforeCall, HbStatus.X);
}
@Override
public void onSendException(String outTradeNo, long beforeCall) {
offerTradeInfo(outTradeNo, beforeCall, HbStatus.Y);
}
@Override
public void onReceiveException(String outTradeNo, long beforeCall) {
offerTradeInfo(outTradeNo, beforeCall, HbStatus.Z);
}
}

View File

@@ -0,0 +1,53 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.service.impl.hb;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb.SysTradeInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* Created by liuyangkly on 15/10/23.
private List<BlockingQueue<E>> concurrentQueueList = Collections.synchronizedList(queueList);
*/
public class HbQueue {
private static Log log = LogFactory.getLog(HbQueue.class);
public static final int QUEUE_SIZE = 300; // 最多同时保存300条交易记录
private static final BlockingQueue<SysTradeInfo> queue = new ArrayBlockingQueue<SysTradeInfo>(QUEUE_SIZE);
public synchronized static void offer(SysTradeInfo info) {
// blockingQueue不需要考虑队列满的情况生产者会被阻塞直到队列被消耗
if (info != null) {
try {
// 使用阻塞put
queue.put(info);
} catch (InterruptedException e) {
log.warn("interrupted for tradeInfo:" + info);
e.printStackTrace();
}
}
}
public synchronized static List<SysTradeInfo> poll() {
if (queue.isEmpty()) {
// 如果队列为空,则直接返回
return null;
}
int size = 30;
List<SysTradeInfo> tradeInfoList = new ArrayList<SysTradeInfo>(size);
for (int i = 0; i < size; i++) {
// 使用非阻塞poll
SysTradeInfo info = queue.poll();
if (info == null) {
break;
}
tradeInfoList.add(info);
}
return tradeInfoList;
}
}

View File

@@ -0,0 +1,25 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.service.impl.hb;
/**
* Created by liuyangkly on 15/10/27.
*/
public interface TradeListener {
// 支付成功
public void onPayTradeSuccess(String outTradeNo, long beforeCall);
// 支付处理中
public void onPayInProgress(String outTradeNo, long beforeCall);
// 支付失败
public void onPayFailed(String outTradeNo, long beforeCall);
// 建立连接异常
public void onConnectException(String outTradeNo, long beforeCall);
// 报文上送异常
public void onSendException(String outTradeNo, long beforeCall);
// 报文接收异常
public void onReceiveException(String outTradeNo, long beforeCall);
}

View File

@@ -0,0 +1,31 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.utils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.model.hb.*;
import java.lang.reflect.Type;
import java.util.List;
/**
* Created by liuyangkly on 15/6/26.
* 使用google gson作为json序列化反序列化工具
*/
public class GsonFactory {
private static class GsonHolder {
private static Type exceptionListType = new TypeToken<List<ExceptionInfo>>(){}.getType();
private static Type tradeInfoListType = new TypeToken<List<TradeInfo>>(){}.getType();
private static Gson gson = new GsonBuilder()
.registerTypeAdapter(exceptionListType, new ExceptionInfoAdapter())
.registerTypeAdapter(tradeInfoListType, new TradeInfoAdapter())
.registerTypeAdapter(EquipStatus.class, new EquipStatusAdapter())
.create();
}
public static Gson getGson() {
return GsonHolder.gson;
}
}

View File

@@ -0,0 +1,54 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.utils;
import org.apache.commons.lang.StringUtils;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* Created by liuyangkly on 15/6/27.
* 杂物工具类
*/
public class Utils {
private Utils() {
// No instances.
}
public static String toAmount(long amount) {
return new BigDecimal(amount).divide(new BigDecimal(100)).toString();
}
public static String toDate(Date date) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
}
public static boolean isEmpty(Object object) {
if (object instanceof String) {
return StringUtils.isEmpty((String) object);
}
return object == null;
}
public static boolean isNotEmpty(Object object) {
return !isEmpty(object);
}
public static <T> boolean isListNotEmpty(List<T> list) {
return list != null && list.size() > 0;
}
public static <T> boolean isListEmpty(List<T> list) {
return !isListNotEmpty(list);
}
public static void sleep(long time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,73 @@
package com.tuling.tulingmall.ordercurr.component.trade.alipay.utils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;
/**
* Created by liuyangkly on 15/6/27.
* 使用了google zxing作为二维码生成工具
*/
public class ZxingUtils {
private static Log log = LogFactory.getLog(ZxingUtils.class);
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
private static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
}
}
return image;
}
private static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
BufferedImage image = toBufferedImage(matrix);
if (!ImageIO.write(image, format, file)) {
throw new IOException("Could not write an image of format " + format + " to " + file);
}
}
/** 将内容contents生成长宽均为width的图片图片路径由imgPath指定
*/
public static File getQRCodeImge(String contents, int width, String imgPath) {
return getQRCodeImge(contents, width, width, imgPath);
}
/** 将内容contents生成长为width宽为width的图片图片路径由imgPath指定
*/
public static File getQRCodeImge(String contents, int width, int height, String imgPath) {
try {
Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
hints.put(EncodeHintType.CHARACTER_SET, "UTF8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
File imageFile = new File(imgPath);
writeToFile(bitMatrix, "png", imageFile);
return imageFile;
} catch (Exception e) {
log.error("create QR code error!", e);
return null;
}
}
}

View File

@@ -0,0 +1,43 @@
package com.tuling.tulingmall.ordercurr.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
/**
* MyBatis配置类
*/
@Configuration
@MapperScan({"com.tuling.tulingmall.ordercurr.mapper","com.tuling.tulingmall.ordercurr.dao"})
public class MyBatisConfig {
/*@Autowired
private MybatisProperties mybatisProperties;
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations(mybatisProperties));
sqlSessionFactoryBean.setDataSource(new DataSourceProxy(dataSource));
return sqlSessionFactoryBean;
}
public Resource[] resolveMapperLocations(MybatisProperties mybatisProperties) {
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
List<Resource> resources = new ArrayList<Resource>();
if (this.mybatisProperties.getMapperLocations() != null) {
for (String mapperLocation : mybatisProperties.getMapperLocations()) {
try {
Resource[] mappers = resourceResolver.getResources(mapperLocation);
resources.addAll(Arrays.asList(mappers));
} catch (IOException e) {
// ignore
}
}
}
return resources.toArray(new Resource[resources.size()]);
}*/
}

View File

@@ -0,0 +1,44 @@
package com.tuling.tulingmall.ordercurr.config;//package com.tuling.tulingmall.config;
import com.tuling.tulingmall.ordercurr.component.TradePayProp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* ,;,,;
* ,;;'( 社
* __ ,;;' ' \ 会
* /' '\'~~'~' \ /'\.) 主
* ,;( ) / |. 义
*,;' \ /-.,,( ) \ 码
* ) / ) / )| 农
* || || \)
* (_\ (_\
* @author :图灵学院
* @date Created in 2020/1/12 22:12
* @version: V1.0
* @slogan: 天下风云出我辈,一入代码岁月催
* @description: 资源访问路径配置
**/
@Configuration
public class ResourceConfig implements WebMvcConfigurer {
@Autowired
private TradePayProp tradePayProp;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// String os = System.getProperty("os.name");
// if(os.toLowerCase().startsWith("win")){ //windows系统
/** QrCode图片存储路径 */
registry.addResourceHandler(tradePayProp.getHttpBasePath()
+"/**")
.addResourceLocations("file:" + tradePayProp.getStorePath() + "/");
// }else{ //linux或者mac
// }
}
}

View File

@@ -0,0 +1,80 @@
package com.tuling.tulingmall.ordercurr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
/**
* Swagger2API文档的配置
*/
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.tuling.tulingmall.ordercurr.controller"))
.paths(PathSelectors.any())
.build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("tuling-mall订单系统")
.description("tuling-mall订单系统")
.contact("tuling")
.version("1.0")
.build();
}
private List<ApiKey> securitySchemes() {
//设置请求头信息
List<ApiKey> result = new ArrayList<>();
ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
result.add(apiKey);
return result;
}
private List<SecurityContext> securityContexts() {
//设置需要登录认证的路径
List<SecurityContext> result = new ArrayList<>();
result.add(getContextByPath("/member/.*"));
result.add(getContextByPath("/cart/.*"));
result.add(getContextByPath("/order/.*"));
result.add(getContextByPath("/returnApply/.*"));
return result;
}
private SecurityContext getContextByPath(String pathRegex) {
return SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex(pathRegex))
.build();
}
private List<SecurityReference> defaultAuth() {
List<SecurityReference> result = new ArrayList<>();
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
result.add(new SecurityReference("Authorization", authorizationScopes));
return result;
}
}

View File

@@ -0,0 +1,28 @@
package com.tuling.tulingmall.ordercurr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
/**
* @author :楼兰
* @description: 分布式事务配置
**/
@Configuration
@EnableTransactionManagement
public class TransactionConfig {
@Bean
public PlatformTransactionManager txManager(final DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
@Bean
public JdbcTemplate jdbcTemplate(final DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}

View File

@@ -0,0 +1,119 @@
package com.tuling.tulingmall.ordercurr.controller;
import com.tuling.tulingmall.common.api.CommonPage;
import com.tuling.tulingmall.common.api.CommonResult;
import com.tuling.tulingmall.ordercurr.domain.OmsOrderDetail;
import com.tuling.tulingmall.ordercurr.dto.OmsMoneyInfoParam;
import com.tuling.tulingmall.ordercurr.dto.OmsOrderDeliveryParam;
import com.tuling.tulingmall.ordercurr.dto.OmsOrderQueryParam;
import com.tuling.tulingmall.ordercurr.dto.OmsReceiverInfoParam;
import com.tuling.tulingmall.ordercurr.model.OmsOrder;
import com.tuling.tulingmall.ordercurr.service.OmsOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author roy
* @desc
*/
@Slf4j
@Controller
@Api(tags = "OmsAdminOrderController")
@RequestMapping("/orderadmin")
public class OmsAdminOrderController {
@Autowired
private OmsOrderService orderService;
@ApiOperation("查询订单")
@RequestMapping(value = "/list", method = {RequestMethod.GET,RequestMethod.POST})
@ResponseBody
public CommonResult<CommonPage<OmsOrder>> list(OmsOrderQueryParam queryParam,
@RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) {
List<OmsOrder> orderList = orderService.list(queryParam, pageSize, pageNum);
return CommonResult.success(CommonPage.restPage(orderList));
}
@ApiOperation("批量发货")
@RequestMapping(value = "/update/delivery", method = RequestMethod.POST)
@ResponseBody
public CommonResult delivery(@RequestBody List<OmsOrderDeliveryParam> deliveryParamList) {
int count = orderService.delivery(deliveryParamList);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
@ApiOperation("批量关闭订单")
@RequestMapping(value = "/update/close", method = RequestMethod.POST)
@ResponseBody
public CommonResult close(@RequestParam("ids") List<Long> ids, @RequestParam("note") String note) {
int count = orderService.close(ids, note);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
@ApiOperation("批量删除订单")
@RequestMapping(value = "/delete", method = RequestMethod.POST)
@ResponseBody
public CommonResult delete(@RequestParam("ids") List<Long> ids) {
int count = orderService.delete(ids);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
@ApiOperation("获取订单详情:订单信息、商品信息、操作记录")
@RequestMapping(value = "/{id}", method = {RequestMethod.GET,RequestMethod.POST})
@ResponseBody
public CommonResult<OmsOrderDetail> detail(@PathVariable Long id) {
OmsOrderDetail orderDetailResult = orderService.detail(id);
return CommonResult.success(orderDetailResult);
}
@ApiOperation("修改收货人信息")
@RequestMapping(value = "/update/receiverInfo", method = RequestMethod.POST)
@ResponseBody
public CommonResult updateReceiverInfo(@RequestBody OmsReceiverInfoParam receiverInfoParam) {
int count = orderService.updateReceiverInfo(receiverInfoParam);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
@ApiOperation("修改订单费用信息")
@RequestMapping(value = "/update/moneyInfo", method = RequestMethod.POST)
@ResponseBody
public CommonResult updatMoneyInfo(@RequestBody OmsMoneyInfoParam moneyInfoParam) {
int count = orderService.updateMoneyInfo(moneyInfoParam);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
@ApiOperation("备注订单")
@RequestMapping(value = "/update/note", method = RequestMethod.POST)
@ResponseBody
public CommonResult updateNote(@RequestParam("id") Long id,
@RequestParam("note") String note,
@RequestParam("status") Integer status) {
int count = orderService.updateNote(id, note, status);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
}

View File

@@ -0,0 +1,69 @@
package com.tuling.tulingmall.ordercurr.controller;
import com.tuling.tulingmall.common.api.CommonPage;
import com.tuling.tulingmall.common.api.CommonResult;
import com.tuling.tulingmall.ordercurr.dto.OmsOrderReturnApplyResult;
import com.tuling.tulingmall.ordercurr.dto.OmsReturnApplyQueryParam;
import com.tuling.tulingmall.ordercurr.dto.OmsUpdateStatusParam;
import com.tuling.tulingmall.ordercurr.model.OmsOrderReturnApply;
import com.tuling.tulingmall.ordercurr.service.OmsOrderReturnApplyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 订单退货申请管理
* Created on 2018/10/18.
*/
@Controller
@Api(tags = "OmsOrderReturnApplyController", description = "订单退货申请管理")
@RequestMapping("/returnApply")
public class OmsAdminOrderReturnApplyController {
@Autowired
private OmsOrderReturnApplyService returnApplyService;
@ApiOperation("分页查询退货申请")
@RequestMapping(value = "/list", method = {RequestMethod.GET,RequestMethod.POST})
@ResponseBody
public CommonResult<CommonPage<OmsOrderReturnApply>> list(OmsReturnApplyQueryParam queryParam,
@RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) {
List<OmsOrderReturnApply> returnApplyList = returnApplyService.list(queryParam, pageSize, pageNum);
return CommonResult.success(CommonPage.restPage(returnApplyList));
}
@ApiOperation("批量删除申请")
@RequestMapping(value = "/delete", method = RequestMethod.POST)
@ResponseBody
public CommonResult delete(@RequestParam("ids") List<Long> ids) {
int count = returnApplyService.delete(ids);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
@ApiOperation("获取退货申请详情")
@RequestMapping(value = "/{id}", method = {RequestMethod.GET,RequestMethod.POST})
@ResponseBody
public CommonResult getItem(@PathVariable Long id) {
OmsOrderReturnApplyResult result = returnApplyService.getItem(id);
return CommonResult.success(result);
}
@ApiOperation("修改申请状态")
@RequestMapping(value = "/update/status/{id}", method = RequestMethod.POST)
@ResponseBody
public CommonResult updateStatus(@PathVariable Long id, @RequestBody OmsUpdateStatusParam statusParam) {
int count = returnApplyService.updateStatus(id, statusParam);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
}

View File

@@ -0,0 +1,110 @@
package com.tuling.tulingmall.ordercurr.controller;//package com.tuling.tulingmall.controller;
//
//import com.tuling.tulingmall.common.api.CommonResult;
//import com.tuling.tulingmall.model.OmsCartItem;
//import com.tuling.tulingmall.domain.CartProduct;
//import com.tuling.tulingmall.domain.CartPromotionItem;
//import com.tuling.tulingmall.service.OmsCartItemService;
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Controller;
//import org.springframework.web.bind.annotation.*;
//
//import java.util.List;
//
///**
// * 购物车管理Controller
// * Created by macro on 2018/8/2.
// */
//@Controller
//@Api(tags = "OmsCartItemController", description = "购物车管理")
//@RequestMapping("/cart")
//public class OmsCartItemController {
// @Autowired
// private OmsCartItemService cartItemService;
//
//
// @ApiOperation(value = "添加商品到购物车", notes = "修改购物逻辑,数据不必全都从前台传")
// @RequestMapping(value = "/add")
// @ResponseBody
// public CommonResult add(@RequestBody OmsCartItem cartItem, @RequestHeader("memberId") Long memberId, @RequestHeader("nickName") String nickName) {
// int count = cartItemService.add(cartItem, memberId, nickName);
// if (count > 0) {
// return CommonResult.success(count);
// }
// return CommonResult.failed();
// }
//
// @ApiOperation("获取某个会员的购物车列表")
// @RequestMapping(value = "/list", method = RequestMethod.GET)
// @ResponseBody
// public CommonResult<List<OmsCartItem>> list(@RequestHeader("memberId") Long memberId) {
// List<OmsCartItem> cartItemList = cartItemService.list(memberId);
// return CommonResult.success(cartItemList);
// }
//
// @ApiOperation("获取某个会员的购物车列表,包括促销信息")
// @RequestMapping(value = "/list/promotion", method = RequestMethod.GET)
// @ResponseBody
// public CommonResult<List<CartPromotionItem>> listPromotion(@RequestHeader("memberId") Long memberId) {
// List<CartPromotionItem> cartPromotionItemList = cartItemService.listPromotion(memberId);
// return CommonResult.success(cartPromotionItemList);
// }
//
// @ApiOperation("修改购物车中某个商品的数量")
// @RequestMapping(value = "/update/quantity", method = RequestMethod.POST)
// @ResponseBody
// public CommonResult updateQuantity(@RequestParam Long id,
// @RequestParam Integer quantity,
// @RequestHeader("memberId") Long memberId) {
// int count = cartItemService.updateQuantity(id, memberId, quantity);
// if (count > 0) {
// return CommonResult.success(count);
// }
// return CommonResult.failed();
// }
//
// @ApiOperation("获取购物车中某个商品的规格,用于重选规格")
// @RequestMapping(value = "/getProduct/{productId}", method = RequestMethod.GET)
// @ResponseBody
// public CommonResult<CartProduct> getCartProduct(@PathVariable Long productId) {
// CartProduct cartProduct = cartItemService.getCartProduct(productId);
// return CommonResult.success(cartProduct);
// }
//
// @ApiOperation("修改购物车中商品的规格")
// @RequestMapping(value = "/update/attr", method = RequestMethod.POST)
// @ResponseBody
// public CommonResult updateAttr(@RequestBody OmsCartItem cartItem,
// @RequestHeader("memberId") Long memberId,
// @RequestHeader("nickName") String nickName) {
// int count = cartItemService.updateAttr(cartItem, memberId, nickName);
// if (count > 0) {
// return CommonResult.success(count);
// }
// return CommonResult.failed();
// }
//
// @ApiOperation("删除购物车中的某个商品")
// @RequestMapping(value = "/delete", method = RequestMethod.POST)
// @ResponseBody
// public CommonResult delete(@RequestParam("ids") List<Long> ids, @RequestHeader("memberId") Long memberId) {
// int count = cartItemService.delete(memberId, ids);
// if (count > 0) {
// return CommonResult.success(count);
// }
// return CommonResult.failed();
// }
//
// @ApiOperation("清空购物车")
// @RequestMapping(value = "/clear", method = RequestMethod.POST)
// @ResponseBody
// public CommonResult clear(@RequestHeader("memberId") Long memberId) {
// int count = cartItemService.clear(memberId);
// if (count > 0) {
// return CommonResult.success(count);
// }
// return CommonResult.failed();
// }
//}

View File

@@ -0,0 +1,87 @@
package com.tuling.tulingmall.ordercurr.controller;
import com.tuling.tulingmall.common.api.CommonPage;
import com.tuling.tulingmall.common.api.CommonResult;
import com.tuling.tulingmall.ordercurr.model.OmsOrderReturnReason;
import com.tuling.tulingmall.ordercurr.service.OmsOrderReturnReasonService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 退货原因管理Controller
* Created on 2018/10/17.
*/
@Controller
@Api(tags = "OmsOrderReturnReasonController", description = "退货原因管理")
@RequestMapping("/returnReason")
public class OmsOrderReturnReasonController {
@Autowired
private OmsOrderReturnReasonService orderReturnReasonService;
@ApiOperation("添加退货原因")
@RequestMapping(value = "/create", method = RequestMethod.POST)
@ResponseBody
public CommonResult create(@RequestBody OmsOrderReturnReason returnReason) {
int count = orderReturnReasonService.create(returnReason);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
@ApiOperation("修改退货原因")
@RequestMapping(value = "/update/{id}", method = RequestMethod.POST)
@ResponseBody
public CommonResult update(@PathVariable Long id, @RequestBody OmsOrderReturnReason returnReason) {
int count = orderReturnReasonService.update(id, returnReason);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
@ApiOperation("批量删除退货原因")
@RequestMapping(value = "/delete", method = RequestMethod.POST)
@ResponseBody
public CommonResult delete(@RequestParam("ids") List<Long> ids) {
int count = orderReturnReasonService.delete(ids);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
@ApiOperation("分页查询全部退货原因")
@RequestMapping(value = "/list", method = {RequestMethod.GET,RequestMethod.POST})
@ResponseBody
public CommonResult<CommonPage<OmsOrderReturnReason>> list(@RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) {
List<OmsOrderReturnReason> reasonList = orderReturnReasonService.list(pageSize, pageNum);
return CommonResult.success(CommonPage.restPage(reasonList));
}
@ApiOperation("获取单个退货原因详情信息")
@RequestMapping(value = "/{id}", method = {RequestMethod.GET,RequestMethod.POST})
@ResponseBody
public CommonResult<OmsOrderReturnReason> getItem(@PathVariable Long id) {
OmsOrderReturnReason reason = orderReturnReasonService.getItem(id);
return CommonResult.success(reason);
}
@ApiOperation("修改退货原因启用状态")
@RequestMapping(value = "/update/status", method = RequestMethod.POST)
@ResponseBody
public CommonResult updateStatus(@RequestParam(value = "status") Integer status,
@RequestParam("ids") List<Long> ids) {
int count = orderReturnReasonService.updateStatus(ids, status);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
}

View File

@@ -0,0 +1,41 @@
package com.tuling.tulingmall.ordercurr.controller;
import com.tuling.tulingmall.common.api.CommonResult;
import com.tuling.tulingmall.ordercurr.model.OmsOrderSetting;
import com.tuling.tulingmall.ordercurr.service.OmsOrderSettingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
/**
* 订单设置Controller
* Created on 2018/10/16.
*/
@Controller
@Api(tags = "OmsOrderSettingController", description = "订单设置管理")
@RequestMapping("/orderSetting")
public class OmsOrderSettingController {
@Autowired
private OmsOrderSettingService orderSettingService;
@ApiOperation("获取指定订单设置")
@RequestMapping(value = "/{id}", method = {RequestMethod.GET,RequestMethod.POST})
@ResponseBody
public CommonResult<OmsOrderSetting> getItem(@PathVariable Long id) {
OmsOrderSetting orderSetting = orderSettingService.getItem(id);
return CommonResult.success(orderSetting);
}
@ApiOperation("修改指定订单设置")
@RequestMapping(value = "/update/{id}", method = RequestMethod.POST)
@ResponseBody
public CommonResult update(@PathVariable Long id, @RequestBody OmsOrderSetting orderSetting) {
int count = orderSettingService.update(id,orderSetting);
if(count>0){
return CommonResult.success(count);
}
return CommonResult.failed();
}
}

View File

@@ -0,0 +1,261 @@
package com.tuling.tulingmall.ordercurr.controller;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.google.common.collect.Maps;
import com.tuling.tulingmall.common.api.CommonResult;
import com.tuling.tulingmall.common.exception.BusinessException;
import com.tuling.tulingmall.ordercurr.component.rocketmq.OrderMessageSender;
import com.tuling.tulingmall.ordercurr.component.trade.alipay.config.Configs;
import com.tuling.tulingmall.ordercurr.domain.MqCancelOrder;
import com.tuling.tulingmall.ordercurr.domain.OmsOrderDetail;
import com.tuling.tulingmall.ordercurr.domain.OrderParam;
import com.tuling.tulingmall.ordercurr.service.OmsPortalOrderService;
import com.tuling.tulingmall.ordercurr.service.TradeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 订单管理Controller
*/
@Slf4j
@Controller
@Api(tags = "OmsPortalOrderController",description = "订单管理")
@RequestMapping("/order")
public class OmsPortalOrderController {
@Autowired
private OmsPortalOrderService portalOrderService;
@Autowired
private TradeService tradeService;
@Autowired
private OrderMessageSender orderMessageSender;
@ApiOperation("根据购物车信息生成订单")
@RequestMapping(value = "/generateOrder",method = RequestMethod.POST)
@ResponseBody
public CommonResult generateOrder(@RequestBody OrderParam orderParam,
@RequestHeader("memberId") Long memberId) throws BusinessException {
return portalOrderService.generateOrder(orderParam,memberId);
}
// @ApiOperation("根据购物车信息生成订单")
// @RequestMapping(value = "/generateOrder",method = RequestMethod.POST)
// @ResponseBody
// public CommonResult generateOrder(@RequestBody OrderParam orderParam,
// @RequestHeader("memberId") Long memberId) throws BusinessException {
// Long orderId = portalOrderService.generateOrderId(memberId);
// orderParam.setOrderId(orderId);
// orderMessageSender.sendCreateOrderMsg(orderParam,memberId);
//// return portalOrderService.generateOrder(orderParam,memberId);
// Map<String,Object> res = new HashMap<>();
// res.put("orderId",orderId);
// return CommonResult.success(res);
// }
@ApiOperation("获取orderId可避免重复下单")
@GetMapping(value = "/generateOrderId")
@ResponseBody
public CommonResult generateOrderId(@RequestHeader("memberId") Long memberId) throws BusinessException {
Long orderId = portalOrderService.generateOrderId(memberId);
return CommonResult.success(orderId);
}
@ApiOperation("获取指定订单详情")
@RequestMapping(value = {"/specificOrderDetail","/orderDetail"},method = {RequestMethod.POST,RequestMethod.GET})
@ResponseBody
public CommonResult specificOrderDetail(@RequestParam Long orderId){
return portalOrderService.getDetailOrder(orderId);
}
@ApiOperation("获取指定业务编号订单详情")
@RequestMapping(value = "/specificOrderSnDetail",method = {RequestMethod.POST,RequestMethod.GET})
@ResponseBody
public CommonResult specificOrderSnDetail(@RequestParam String orderSn){
/*在我们的实现中业务订单orderSn和订单内部编号orderId是同一个
所以这里可以简单处理,实际工作中如果两者不一样,
保证根据一定的规则可以从orderSn获得orderId即可*/
return portalOrderService.getDetailOrder(Long.valueOf(orderSn));
}
// @ApiOperation("支付成功修改订单状态")
// @ApiImplicitParams({@ApiImplicitParam(name = "payType", value = "支付方式:0->未支付,1->支付宝支付,2->微信支付",
// allowableValues = "1,2", paramType = "query", dataType = "integer")})
// @RequestMapping(value = "/paySuccess/{orderId}",method = RequestMethod.POST)
// @ResponseBody
// public void paySuccess(@PathVariable Long orderId,Integer payType) {
// if(payType > 2 || payType < 0){
// throw new IllegalArgumentException("支付类型不正确,平台目前仅支持支付宝与微信支付");
// }
// portalOrderService.paySuccess(orderId,payType);
// }
@ApiOperation("批量检查超时订单并取消")
@RequestMapping(value = "/cancelTimeOutOrders",method = RequestMethod.POST)
@ResponseBody
public CommonResult cancelTimeOutOrders(){
return portalOrderService.cancelTimeOutOrder();
}
@ApiOperation("取消单个超时订单")
@RequestMapping(value = "/cancelOrder",method = RequestMethod.POST)
@ResponseBody
public CommonResult cancelOrder(Long orderId,@RequestHeader("memberId") Long memberId){
//todo
MqCancelOrder mqCancelOrder = new MqCancelOrder();
mqCancelOrder.setMemberId(memberId);
mqCancelOrder.setOrderId(orderId);
portalOrderService.sendDelayMessageCancelOrder(mqCancelOrder);
return CommonResult.success(null);
}
/**
* 删除订单[逻辑删除],只能status为3->已完成4->已关闭5->无效订单,才可以删除
* ,否则只能先取消订单然后删除。
* @param orderId
* @return
*/
@ApiOperation(value = "逻辑删除指定订单",notes = "status为3->已完成4->已关闭5->无效订单,才可以删除,否则只能先取消订单然后删除")
@RequestMapping(value = "/deleteOrder",method = RequestMethod.POST)
@ResponseBody
public CommonResult deleteOrder(Long orderId){
int total = portalOrderService.deleteOrder(orderId);
if(total > 0){
return CommonResult.success("有:"+total+":条订单被删除");
}else{
return CommonResult.failed("订单已经被删除或者没有符合条件的订单");
}
}
/**
* 订单服务由会员服务调用会员服务传来会员ID
* @param memberId
* @param status
* null查询所有
* 订单状态0->待付款1->待发货2->已发货3->已完成;4->已关闭;
* @return
*/
@ApiOperation("用户订单查询")
@ApiImplicitParams({
@ApiImplicitParam(name = "memberId", value = "用户ID", required = true, paramType = "query", dataType = "integer"),
@ApiImplicitParam(name = "status", value = "订单状态:0->待付款1->待发货2->已发货3->已完成4->已关闭",
allowableValues = "0,1,2,3,4", paramType = "query", dataType = "integer")})
@RequestMapping(value = "/list/userOrder",method = RequestMethod.POST)
@ResponseBody
public CommonResult<List<OmsOrderDetail>> findMemberOrderList(
@RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
@RequestParam(value = "memberId") Long memberId,
@RequestParam(value = "status",required = false) Integer status){
if(memberId == null || (status!=null && status > 4)){
return CommonResult.validateFailed();
}
return portalOrderService.findMemberOrderList(pageSize,pageNum,memberId,status);
}
/**
* 订单支付逻辑支付支持两种方式alipay,wechat
* @param orderId
* @param payType
* @return
*/
@ApiOperation("订单支付#实现支付宝支付{微信支付暂未实现}")
@ApiImplicitParams({@ApiImplicitParam(name = "payType", value = "支付方式:0->未支付,1->支付宝支付,2->微信支付",
allowableValues = "1,2", paramType = "query", dataType = "integer")})
@RequestMapping(value = "/tradeQrCode",method = RequestMethod.POST)
@ResponseBody
public CommonResult tradeQrCode(@RequestParam(value = "orderId") Long orderId,
@RequestHeader("memberId") Long memberId,
@RequestParam(value = "payType") Integer payType){
if(payType > 2 || payType < 0){
throw new IllegalArgumentException("支付类型不正确,平台目前仅支持支付宝与微信支付");
}
orderMessageSender.sendCreateOrderMsg(orderId,memberId);
return tradeService.tradeQrCode(orderId,payType,memberId);
}
@ApiOperation("订单支付状态查询,手动查询#实现支付宝查询")
@ApiImplicitParams({@ApiImplicitParam(name = "payType", value = "支付方式:0->未支付,1->支付宝支付,2->微信支付",
allowableValues = "1,2", paramType = "query", dataType = "integer")})
@RequestMapping(value = "/tradeStatusQuery",method = RequestMethod.POST)
@ResponseBody
public CommonResult tradeStatusQuery(@RequestParam(value = "orderId") Long orderId,
@RequestParam(value = "payType") Integer payType){
if(payType > 2 || payType < 0){
throw new IllegalArgumentException("支付类型不正确,平台目前仅支持支付宝与微信支付");
}
return tradeService.tradeStatusQuery(orderId,payType);
}
@ApiOperation("支付成功的回调")
@ApiImplicitParams({@ApiImplicitParam(name = "payType", value = "支付方式:0->未支付,1->支付宝支付,2->微信支付",
allowableValues = "1,2", paramType = "query", dataType = "integer")})
@RequestMapping(value = "/paySuccess/{payType}",method = RequestMethod.POST)
@ResponseBody
public void paySuccess(@PathVariable Integer payType,
HttpServletRequest request,
HttpServletResponse response) throws AlipayApiException {
if(payType > 2 || payType < 0){
throw new IllegalArgumentException("支付类型不正确,平台目前仅支持支付宝与微信支付");
}
if(payType == 1){//支付宝支付
//1、获取request里所有与alipay相关的参数封装成一个map
Map<String,String> param = Maps.newHashMap();
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()){
String parameterName = parameterNames.nextElement();
log.info("alipay callback parameters:-->"
+parameterName+":->" +request.getParameter(parameterName));
if(!parameterName.toLowerCase().equals("sign_type")){
param.put(parameterName,request.getParameter(parameterName));
}
}
// 2、验证请求是否是alipay返回的请求内容【验证请求合法性】
// 很重要
boolean isPassed = AlipaySignature.rsaCheckV2(param, Configs.getAlipayPublicKey(),"utf-8",Configs.getSignType());
PrintWriter out = null;
try {
out = response.getWriter();
} catch (IOException e) {
e.printStackTrace();
}
if(isPassed){
Long orderId = Long.parseLong(param.get("out_trade_no"));
int count = portalOrderService.paySuccess(orderId,payType);
if(count > 0){
log.info("支付成功,订单完成支付");
out.print("success");
}else{
log.info("支付失败,订单未能完成支付");
out.print("unSuccess");
}
}else{
log.info("支付失败,订单未能完成支付");
out.print("unSuccess");
}
}else if(payType == 2){//微信支付
}
}
}

View File

@@ -0,0 +1,423 @@
package com.tuling.tulingmall.ordercurr.controller;//package com.tuling.tulingmall.controller;
//
//import com.alipay.api.AlipayApiException;
//import com.alipay.api.internal.util.AlipaySignature;
//import com.google.common.collect.Maps;
//import com.tuling.tulingmall.common.api.CommonResult;
//import com.tuling.tulingmall.common.constant.RedisKeyPrefixConst;
//import com.tuling.tulingmall.common.exception.BusinessException;
//import com.tuling.tulingmall.component.trade.alipay.config.Configs;
//import com.tuling.tulingmall.domain.ConfirmOrderResult;
//import com.tuling.tulingmall.domain.MqCancelOrder;
//import com.tuling.tulingmall.domain.OmsOrderDetail;
//import com.tuling.tulingmall.domain.OrderParam;
//import com.tuling.tulingmall.service.OmsPortalOrderService;
//import com.tuling.tulingmall.service.SecKillOrderService;
//import com.tuling.tulingmall.service.TradeService;
//import com.tuling.tulingmall.util.MD5;
//import com.tuling.tulingmall.util.RedisOpsUtil;
//import com.tuling.tulingmall.util.VerifyCodeImgUtil;
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiImplicitParam;
//import io.swagger.annotations.ApiImplicitParams;
//import io.swagger.annotations.ApiOperation;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Controller;
//import org.springframework.util.ObjectUtils;
//import org.springframework.util.StringUtils;
//import org.springframework.web.bind.annotation.*;
//
//import javax.imageio.ImageIO;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//import java.io.OutputStream;
//import java.io.PrintWriter;
//import java.util.Enumeration;
//import java.util.List;
//import java.util.Map;
//import java.util.UUID;
//import java.util.concurrent.TimeUnit;
//
///**
// * 订单管理Controller
// * 2018/8/30.
// */
//@Slf4j
//@Controller
//@Api(tags = "OmsPortalOrderController",description = "订单管理")
//@RequestMapping("/order")
//public class OmsPortalOrderControllerV4 {
//
// @Autowired
// private OmsPortalOrderService portalOrderService;
//
// @Autowired
// private TradeService tradeService;
//
// @Autowired
// private RedisOpsUtil redisOpsUtil;
//
// @Autowired
// private SecKillOrderService secKillOrderService;
//
// @ApiOperation("根据购物车信息生成确认单信息")
// @ApiImplicitParam(name = "itemId",value = "购物车选择购买的选项ID",allowMultiple = true,paramType = "query",dataType = "long")
// @RequestMapping(value = "/generateConfirmOrder",method = RequestMethod.POST)
// @ResponseBody
// public CommonResult<ConfirmOrderResult> generateConfirmOrder(@RequestParam(value = "itemIds") List<Long> itemIds,
// @RequestHeader("memberId") Long memberId) throws BusinessException {
// ConfirmOrderResult confirmOrderResult = portalOrderService.generateConfirmOrder(itemIds,memberId);
// return CommonResult.success(confirmOrderResult);
// }
//
// @ApiOperation("根据购物车信息生成订单")
// @RequestMapping(value = "/generateOrder",method = RequestMethod.POST)
// @ResponseBody
// public CommonResult generateOrder(@RequestBody OrderParam orderParam,
// @RequestHeader("memberId") Long memberId) throws BusinessException {
// return portalOrderService.generateOrder(orderParam,memberId);
// }
//
// /**
// * 秒杀订单确认页
// * @param productId
// * @param memberId
// * @return
// * @throws BusinessException
// */
// @RequestMapping(value = "/miaosha/generateConfirmOrder",method = RequestMethod.POST)
// @ResponseBody
// public CommonResult generateMiaoShaConfirmOrder(@RequestParam("productId") Long productId,
// String token,
// @RequestHeader("memberId") Long memberId) throws BusinessException {
// return secKillOrderService.generateConfirmMiaoShaOrder(productId,memberId,token);
// }
//
// @RequestMapping(value = "/miaosha/generateOrder",method = RequestMethod.POST)
// @ResponseBody
// public CommonResult generateMiaoShaOrder(@RequestBody OrderParam orderParam,
// String token,
// @RequestHeader("memberId") Long memberId) throws BusinessException {
// return secKillOrderService.generateSecKillOrder(orderParam,memberId,token);
// }
//
// /**
// * 秒杀结果页面
// * @param memberId
// * @return
// */
// @ApiOperation("根据购物车信息生成订单")
// @GetMapping("/miaosha/result")
// @ResponseBody
// public CommonResult miaoShaResult(@RequestParam("productId") Long productId,@RequestHeader("memberId") Long memberId){
// String status = redisOpsUtil.get(RedisKeyPrefixConst.MIAOSHA_ASYNC_WAITING_PREFIX + memberId
// + ":" + productId);
//
// if(ObjectUtils.isEmpty(status)){
// return CommonResult.success(null,"无正在秒杀中的订单!");
// }
//
// if(status.equals("-1")){
// return CommonResult.success(status,"秒杀失败!");
// }
//
// if(status.equals("1")){
// return CommonResult.success(status,"正在排队中,请耐心等待!");
// }
// //如果Status>1则秒杀成功,返回订单编号
// return CommonResult.success(status);
// }
//
// @ApiOperation("查看订单详情#杨过添加")
// @RequestMapping(value = "/orderDetail",method = {RequestMethod.POST,RequestMethod.GET})
// @ResponseBody
// public CommonResult orderDetail(@RequestParam Long orderId){
// return portalOrderService.getDetailOrder(orderId);
// }
//
// @ApiOperation("支付成功的回调")
// @ApiImplicitParams({@ApiImplicitParam(name = "payType", value = "支付方式:0->未支付,1->支付宝支付,2->微信支付",
// allowableValues = "1,2", paramType = "query", dataType = "integer")})
// @RequestMapping(value = "/paySuccess/{payType}",method = RequestMethod.POST)
// @ResponseBody
// public void paySuccess(@PathVariable Integer payType,
// HttpServletRequest request,
// HttpServletResponse response) throws AlipayApiException {
// if(payType > 2 || payType < 0){
// throw new IllegalArgumentException("支付类型不正确,平台目前仅支持支付宝与微信支付");
// }
// if(payType == 1){//支付宝支付
// //1、获取request里所有与alipay相关的参数封装成一个map
// Map<String,String> param = Maps.newHashMap();
// Enumeration<String> parameterNames = request.getParameterNames();
// while (parameterNames.hasMoreElements()){
// String parameterName = parameterNames.nextElement();
// log.info("alipay callback parameters:-->"
// +parameterName+":->" +request.getParameter(parameterName));
// if(!parameterName.toLowerCase().equals("sign_type")){
// param.put(parameterName,request.getParameter(parameterName));
// }
// }
// // 2、验证请求是否是alipay返回的请求内容【验证请求合法性】
// // 很重要
// boolean isPassed = AlipaySignature.rsaCheckV2(param, Configs.getAlipayPublicKey(),"utf-8",Configs.getSignType());
// PrintWriter out = null;
// try {
// out = response.getWriter();
// } catch (IOException e) {
// e.printStackTrace();
// }
// if(isPassed){
// Long orderId = Long.parseLong(param.get("out_trade_no"));
// int count = portalOrderService.paySuccess(orderId,payType);
// if(count > 0){
// log.info("支付成功,订单完成支付");
// out.print("success");
// }else{
// log.info("支付失败,订单未能完成支付");
// out.print("unSuccess");
// }
// }else{
// log.info("支付失败,订单未能完成支付");
// out.print("unSuccess");
// }
// }else if(payType == 2){//微信支付
//
// }
// }
//
// @ApiOperation("自动取消超时订单")
// @RequestMapping(value = "/cancelTimeOutOrder",method = RequestMethod.POST)
// @ResponseBody
// public CommonResult cancelTimeOutOrder(){
// return portalOrderService.cancelTimeOutOrder();
// }
//
// @ApiOperation("取消单个超时订单")
// @RequestMapping(value = "/cancelOrder",method = RequestMethod.POST)
// @ResponseBody
// public CommonResult cancelOrder(Long orderId,@RequestHeader("memberId") Long memberId){
// //todo
// MqCancelOrder mqCancelOrder = new MqCancelOrder();
// mqCancelOrder.setMemberId(memberId);
// mqCancelOrder.setOrderId(orderId);
//
// portalOrderService.sendDelayMessageCancelOrder(mqCancelOrder);
// return CommonResult.success(null);
// }
//
// /**
// * 删除订单[逻辑删除],只能status为3->已完成4->已关闭5->无效订单,才可以删除
// * ,否则只能先取消订单然后删除。
// * @param orderId
// * @return
// */
// @ApiOperation(value = "删除会员订单#杨过添加",notes = "status为3->已完成4->已关闭5->无效订单,才可以删除,否则只能先取消订单然后删除")
// @RequestMapping(value = "/deleteOrder",method = RequestMethod.POST)
// @ResponseBody
// public CommonResult deleteOrder(Long orderId){
// int total = portalOrderService.deleteOrder(orderId);
// if(total > 0){
// return CommonResult.success("有:"+total+":条订单被删除");
// }else{
// return CommonResult.failed("订单已经被删除或者没有符合条件的订单");
// }
// }
// /**
// * 订单服务由会员服务调用会员服务传来会员ID
// * @param memberId
// * @param status
// * null查询所有
// * 订单状态0->待付款1->待发货2->已发货3->已完成;4->已关闭;
// * @return
// */
// @ApiOperation("会员订单查询#杨过添加")
// @ApiImplicitParams({
// @ApiImplicitParam(name = "memberId", value = "会员ID", required = true, paramType = "query", dataType = "integer"),
// @ApiImplicitParam(name = "status", value = "订单状态:0->待付款1->待发货2->已发货3->已完成4->已关闭",
// allowableValues = "0,1,2,3,4", paramType = "query", dataType = "integer")})
// @RequestMapping(value = "/list/userOrder",method = RequestMethod.POST)
// @ResponseBody
// public CommonResult<List<OmsOrderDetail>> findMemberOrderList(
// @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
// @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
// @RequestParam(value = "memberId") Long memberId,
// @RequestParam(value = "status",required = false) Integer status){
//
// if(memberId == null || (status!=null && status > 4)){
// return CommonResult.validateFailed();
// }
// return portalOrderService.findMemberOrderList(pageSize,pageNum,memberId,status);
// }
//
// /**
// * 订单支付逻辑支付支持两种方式alipay,wechat
// * @param orderId
// * @param payType
// * @return
// */
// @ApiOperation("订单支付#实现支付宝支付{微信支付暂未实现}")
// @ApiImplicitParams({@ApiImplicitParam(name = "payType", value = "支付方式:0->未支付,1->支付宝支付,2->微信支付",
// allowableValues = "1,2", paramType = "query", dataType = "integer")})
// @RequestMapping(value = "/tradeQrCode",method = RequestMethod.POST)
// @ResponseBody
// public CommonResult tradeQrCode(@RequestParam(value = "orderId") Long orderId,
// @RequestHeader("memberId") Long memberId,
// @RequestParam(value = "payType") Integer payType){
// if(payType > 2 || payType < 0){
// throw new IllegalArgumentException("支付类型不正确,平台目前仅支持支付宝与微信支付");
// }
// return tradeService.tradeQrCode(orderId,payType,memberId);
// }
//
//
// @ApiOperation("订单支付状态查询,手动查询#实现支付宝查询")
// @ApiImplicitParams({@ApiImplicitParam(name = "payType", value = "支付方式:0->未支付,1->支付宝支付,2->微信支付",
// allowableValues = "1,2", paramType = "query", dataType = "integer")})
// @RequestMapping(value = "/tradeStatusQuery",method = RequestMethod.POST)
// @ResponseBody
// public CommonResult tradeStatusQuery(@RequestParam(value = "orderId") Long orderId,
// @RequestParam(value = "payType") Integer payType){
//
// if(payType > 2 || payType < 0){
// throw new IllegalArgumentException("支付类型不正确,平台目前仅支持支付宝与微信支付");
// }
// return tradeService.tradeStatusQuery(orderId,payType);
// }
//
// /*--------------------------------限流防刷部分---------------------------------------*/
// @RequestMapping(value="/token", method=RequestMethod.GET)
// @ResponseBody
// public CommonResult getMiaoshaToken(HttpServletRequest request
// , @RequestParam("productId") Long productId
// , @RequestHeader("memberId") Long memberId
// , @RequestParam Integer verifyCode) {
// /*
// * 用redis限流限制接口1分钟最多访问10000次
// */
// String requestURI = request.getRequestURI().toString();
// Long requestNum = redisOpsUtil.incr(requestURI);
// if (requestNum == 1) {
// redisOpsUtil.expire(requestURI,60, TimeUnit.SECONDS);
// } else if (requestNum > 10000) {
// return CommonResult.failed("访问超载,请稍后再试");
// }
//
// String verifyCodeKey = RedisKeyPrefixConst.MIAOSHA_VERIFY_CODE_PREFIX + memberId + ":" + productId;
// /*
// * 校验验证码,防止接口被刷
// */
// Integer redisCode = redisOpsUtil.get(verifyCodeKey,Integer.class);
//
// if(StringUtils.isEmpty(redisCode) || !redisCode.equals(verifyCode)) {
// return CommonResult.failed("验证码错误");
// }
// //验证成功,删除该验证码
// redisOpsUtil.delete(verifyCodeKey);
//
// //创建一个token代表该用户有购买商品的权限。
// String token = MD5.md5(UUID.randomUUID().toString());
//
// log.info("miaosha token:{}",token);
//
// redisOpsUtil.set(RedisKeyPrefixConst.MIAOSHA_TOKEN_PREFIX + memberId + ":" + productId
// ,token
// ,300
// ,TimeUnit.SECONDS);
// System.out.println("token:::::::::::"+token);
// return CommonResult.success(token);
// }
//
// @RequestMapping(value="/verifyCode", method=RequestMethod.GET)
// @ResponseBody
// public CommonResult getVerifyCode(HttpServletRequest request,
// HttpServletResponse response,
// @RequestParam("productId") Long productId,
// @RequestHeader("memberId") Long memberId){
// try {
// //===============自定义验证码===========
// VerifyCodeImgUtil.VerifyCodeInfo imageInfo = VerifyCodeImgUtil.createVerifyCode();
// log.info("验证码答案:{}",imageInfo.getResult());
// //验证码答案写入到redis
// redisOpsUtil.set(RedisKeyPrefixConst.MIAOSHA_VERIFY_CODE_PREFIX + memberId + ":" + productId
// ,imageInfo.getResult()
// ,300
// ,TimeUnit.SECONDS);
// response.setHeader("Content-Type", "image/jpeg");
// OutputStream out = response.getOutputStream();
// ImageIO.write(imageInfo.getBufferedImage(), "JPEG", out);
// out.flush();
// out.close();
//
// redisOpsUtil.set(RedisKeyPrefixConst.MIAOSHA_VERIFY_CODE_PREFIX + memberId + ":" + productId
// ,imageInfo.getResult()
// ,300
// ,TimeUnit.SECONDS);
// /**
// * 返回图片的base64编码,js解码成图片
// */
// /*ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
// ImageIO.write(imageInfo.getBufferedImage(), "png", baos);//写入流中
// byte[] bytes = baos.toByteArray();//转换成字节
// BASE64Encoder encoder = new BASE64Encoder();
// String png_base64 = encoder.encodeBuffer(bytes).trim();//转换成base64串
// png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
// return CommonResult.success(png_base64);*/
// //===============自定义验证码结束===========
// //====== HappyCaptcha验证码 =======
// //这个步骤就会完成生成图片并且往response发送的步骤。
//// HappyCaptcha.require(request,response).style(CaptchaStyle.ANIM)
//// .type(CaptchaType.ARITHMETIC_ZH)
//// .build().finish();
//// //HappyCaptcha生成的验证码是String类型
//// Object captcha = request.getSession().getAttribute("happy-captcha");
//// int code = Integer.parseInt(captcha.toString());
//// log.info("验证码答案:{}",captcha);
////
//// redisOpsUtil.set(RedisKeyPrefixConst.MIAOSHA_VERIFY_CODE_PREFIX + memberId + ":" + productId
//// ,code
//// ,300
//// ,TimeUnit.SECONDS);
// //====== HappyCaptcha验证码结束 =======
// return null;
// }catch(Exception e) {
// e.printStackTrace();
// return CommonResult.failed("秒杀失败");
// }
// }
//
//
//
//
// /*--------------------------------测试用---------------------------------------*/
// @RequestMapping(value="/token2", method=RequestMethod.GET)
// @ResponseBody
// public CommonResult getToken(HttpServletRequest request
// , @RequestParam("productId") Long productId
// , @RequestParam("memberId") Long memberId) {
// /*
// * 用redis限流限制接口1分钟最多访问10000次
// */
// String requestURI = request.getRequestURI().toString();
// Long requestNum = redisOpsUtil.incr(requestURI);
// if (requestNum == 1) {
// redisOpsUtil.expire(requestURI,60, TimeUnit.SECONDS);
// } else if (requestNum > 10000) {
// return CommonResult.failed("访问超载,请稍后再试");
// }
// //todo 创建token
// String token = MD5.md5(UUID.randomUUID().toString());
//
// log.info("miaosha token:{}",token);
//
// redisOpsUtil.set(RedisKeyPrefixConst.MIAOSHA_TOKEN_PREFIX + memberId + ":" + productId
// ,token
// ,300
// ,TimeUnit.SECONDS);
// System.out.println("token:::::::::::"+token);
// return CommonResult.success(token);
// }
//
//}

View File

@@ -0,0 +1,35 @@
package com.tuling.tulingmall.ordercurr.controller;
import com.tuling.tulingmall.common.api.CommonResult;
import com.tuling.tulingmall.ordercurr.domain.OmsOrderReturnApplyParam;
import com.tuling.tulingmall.ordercurr.service.OmsPortalOrderReturnApplyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 申请退货管理Controller
*/
@Controller
@Api(tags = "OmsPortalOrderReturnApplyController", description = "申请退货管理")
@RequestMapping("/returnApply")
public class OmsPortalOrderReturnApplyController {
@Autowired
private OmsPortalOrderReturnApplyService returnApplyService;
@ApiOperation("申请退货")
@RequestMapping(value = "/create", method = RequestMethod.POST)
@ResponseBody
public CommonResult create(@RequestBody OmsOrderReturnApplyParam returnApply) {
int count = returnApplyService.create(returnApply);
if (count > 0) {
return CommonResult.success(count);
}
return CommonResult.failed();
}
}

View File

@@ -0,0 +1,38 @@
package com.tuling.tulingmall.ordercurr.controller;/*
package com.tuling.tulingmall.controller;
import com.tuling.tulingmall.common.api.CommonResult;
import com.tuling.tulingmall.service.impl.Transaction2PcServiceImpl;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.apache.shardingsphere.transaction.core.TransactionTypeHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
*/
/**
* @author :图灵学院
* @date Created in 2020/3/19
* @version: V1.0
* @slogan: 天下风云出我辈,一入代码岁月催
* @description:
**//*
@RestController
public class Transaction2PcController {
@Autowired
private Transaction2PcServiceImpl service;
@GetMapping("/sharding/2pc_transaction")
public CommonResult insertIn2Pc(){
//TransactionTypeHolder.set(TransactionType.XA);
return service.insertOrder();
}
@GetMapping("/sharding/select")
public CommonResult select(@RequestHeader("memberId") Long memberId){
return service.selectOrder(memberId);
}
}
*/

View File

@@ -0,0 +1,49 @@
package com.tuling.tulingmall.ordercurr.dao;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @author :图灵学院
* @date Created in 2020/2/25
* @version: V1.0
* @slogan: 天下风云出我辈,一入代码岁月催
* @description: 秒杀库存服务
**/
@Mapper
public interface MiaoShaStockDao {
//减库存
Integer descStock(@Param("id") Long id, @Param("stock") Integer stock);
/**
* 秒杀产品乐观锁减库存
* @param id
* 秒杀活动库存记录ID
* @return
*/
Integer descStockInVersion(@Param("id") Long id, @Param("oldStock") Integer oldStock, @Param("newStock") Integer newStock);
/**
* 查询当前的缓存库存
* @param id
* @return
*/
Integer selectMiaoShaStock(@Param("id") Long id);
/*-------------------------悲观锁实现--------------------------*/
/**
* 查询加锁
* @param id
* @return
*/
Integer selectMiaoShaStockInLock(@Param("id") Long id);
/**
*
* @param id
* @param stock
* @return
*/
Integer descStockInLock(@Param("id") Long id, @Param("stock") Integer stock);
}

View File

@@ -0,0 +1,55 @@
package com.tuling.tulingmall.ordercurr.dao;
import com.tuling.tulingmall.ordercurr.domain.OmsOrderDetail;
import com.tuling.tulingmall.ordercurr.model.OmsOrderItem;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 前台订单自定义Dao
*/
@Mapper
public interface PortalOrderDao {
/**
* 获取订单及下单商品详情
*/
OmsOrderDetail getDetail(@Param("orderId") Long orderId);
/**
* 获取超时订单
* @param minute 超时时间(分)
*/
List<OmsOrderDetail> getTimeOutOrders(@Param("minute") Integer minute);
/**
* 批量修改订单状态
*/
int updateOrderStatus(@Param("ids") List<Long> ids, @Param("status") Integer status);
/**
* 删除订单[逻辑删除],只能status为3->已完成4->已关闭5->无效订单,才可以删除
* ,否则只能先取消订单然后删除。
* @param orderId
* @return
* 受影响的行
*/
int deleteOrder(@Param("orderId") Long orderId);
/**
* 查询会员的订单
* @param memberId
* 会员ID
* @param status
* 订单状态
* @return
*/
List<OmsOrderDetail> findMemberOrderList(@Param("memberId") Long memberId, @Param("status") Integer status);
/**
* 修改 pms_sku_stock表的锁定库存及真实库存
*/
int updateSkuStock(@Param("itemList") List<OmsOrderItem> orderItemList);
}

View File

@@ -0,0 +1,16 @@
package com.tuling.tulingmall.ordercurr.dao;
import com.tuling.tulingmall.ordercurr.model.OmsOrderItem;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 订单商品信息自定义Dao
* Created by macro on 2018/9/3.
*/
@Mapper
public interface PortalOrderItemDao {
int insertList(@Param("list") List<OmsOrderItem> list);
}

View File

@@ -0,0 +1,32 @@
package com.tuling.tulingmall.ordercurr.domain;//package com.tuling.tulingmall.domain;
//
//import com.tuling.tulingmall.model.PmsProduct;
//import com.tuling.tulingmall.model.PmsProductAttribute;
//import com.tuling.tulingmall.model.PmsSkuStock;
//
//import java.util.List;
//
///**
// * 购物车中选择规格的商品信息
// * Created by macro on 2018/8/2.
// */
//public class CartProduct extends PmsProduct {
// private List<PmsProductAttribute> productAttributeList;
// private List<PmsSkuStock> skuStockList;
//
// public List<PmsProductAttribute> getProductAttributeList() {
// return productAttributeList;
// }
//
// public void setProductAttributeList(List<PmsProductAttribute> productAttributeList) {
// this.productAttributeList = productAttributeList;
// }
//
// public List<PmsSkuStock> getSkuStockList() {
// return skuStockList;
// }
//
// public void setSkuStockList(List<PmsSkuStock> skuStockList) {
// this.skuStockList = skuStockList;
// }
//}

View File

@@ -0,0 +1,73 @@
package com.tuling.tulingmall.ordercurr.domain;
import com.tuling.tulingmall.ordercurr.model.OmsCartItem;
import java.math.BigDecimal;
/**
* 购物车中促销信息的封装
*/
public class CartPromotionItem extends OmsCartItem{
//促销活动信息
private String promotionMessage;
//促销活动减去的金额,针对每个商品
private BigDecimal reduceAmount;
//商品的真实库存(剩余库存-锁定库存)
private Integer realStock;
//购买商品赠送积分
private Integer integration;
//购买商品赠送成长值
private Integer growth;
public CartPromotionItem(String promotionMessage, BigDecimal reduceAmount, Integer realStock,
Integer integration, Integer growth) {
this.promotionMessage = promotionMessage;
this.reduceAmount = reduceAmount;
this.realStock = realStock;
this.integration = integration;
this.growth = growth;
}
public CartPromotionItem() {
}
public String getPromotionMessage() {
return promotionMessage;
}
public void setPromotionMessage(String promotionMessage) {
this.promotionMessage = promotionMessage;
}
public BigDecimal getReduceAmount() {
return reduceAmount;
}
public void setReduceAmount(BigDecimal reduceAmount) {
this.reduceAmount = reduceAmount;
}
public Integer getRealStock() {
return realStock;
}
public void setRealStock(Integer realStock) {
this.realStock = realStock;
}
public Integer getIntegration() {
return integration;
}
public void setIntegration(Integer integration) {
this.integration = integration;
}
public Integer getGrowth() {
return growth;
}
public void setGrowth(Integer growth) {
this.growth = growth;
}
}

View File

@@ -0,0 +1,115 @@
package com.tuling.tulingmall.ordercurr.domain;
import com.tuling.tulingmall.ordercurr.model.UmsMemberReceiveAddress;
import java.math.BigDecimal;
import java.util.List;
/**
* 确认单信息封装
*/
public class ConfirmOrderResult {
//包含优惠信息的购物车信息
private List<CartPromotionItem> cartPromotionItemList;
//用户收货地址列表
private List<UmsMemberReceiveAddress> memberReceiveAddressList;
// //用户可用优惠券列表
// private List<SmsCouponHistoryDetail> couponHistoryDetailList;
// //积分使用规则
// private UmsIntegrationConsumeSetting integrationConsumeSetting;
//会员持有的积分
private Integer memberIntegration;
//计算的金额
private CalcAmount calcAmount;
public List<CartPromotionItem> getCartPromotionItemList() {
return cartPromotionItemList;
}
public void setCartPromotionItemList(List<CartPromotionItem> cartPromotionItemList) {
this.cartPromotionItemList = cartPromotionItemList;
}
public List<UmsMemberReceiveAddress> getMemberReceiveAddressList() {
return memberReceiveAddressList;
}
public void setMemberReceiveAddressList(List<UmsMemberReceiveAddress> memberReceiveAddressList) {
this.memberReceiveAddressList = memberReceiveAddressList;
}
// public List<SmsCouponHistoryDetail> getCouponHistoryDetailList() {
// return couponHistoryDetailList;
// }
//
// public void setCouponHistoryDetailList(List<SmsCouponHistoryDetail> couponHistoryDetailList) {
// this.couponHistoryDetailList = couponHistoryDetailList;
// }
//
// public UmsIntegrationConsumeSetting getIntegrationConsumeSetting() {
// return integrationConsumeSetting;
// }
//
// public void setIntegrationConsumeSetting(UmsIntegrationConsumeSetting integrationConsumeSetting) {
// this.integrationConsumeSetting = integrationConsumeSetting;
// }
public Integer getMemberIntegration() {
return memberIntegration;
}
public void setMemberIntegration(Integer memberIntegration) {
this.memberIntegration = memberIntegration;
}
public CalcAmount getCalcAmount() {
return calcAmount;
}
public void setCalcAmount(CalcAmount calcAmount) {
this.calcAmount = calcAmount;
}
public static class CalcAmount{
//订单商品总金额
private BigDecimal totalAmount;
//运费
private BigDecimal freightAmount;
//活动优惠
private BigDecimal promotionAmount;
//应付金额
private BigDecimal payAmount;
public BigDecimal getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(BigDecimal totalAmount) {
this.totalAmount = totalAmount;
}
public BigDecimal getFreightAmount() {
return freightAmount;
}
public void setFreightAmount(BigDecimal freightAmount) {
this.freightAmount = freightAmount;
}
public BigDecimal getPromotionAmount() {
return promotionAmount;
}
public void setPromotionAmount(BigDecimal promotionAmount) {
this.promotionAmount = promotionAmount;
}
public BigDecimal getPayAmount() {
return payAmount;
}
public void setPayAmount(BigDecimal payAmount) {
this.payAmount = payAmount;
}
}
}

View File

@@ -0,0 +1,14 @@
package com.tuling.tulingmall.ordercurr.domain;
import lombok.Data;
/**
* @desc: 类的描述:mq取消订单封装对象
*/
@Data
public class MqCancelOrder {
private Long orderId;
private Long memberId;
}

View File

@@ -0,0 +1,23 @@
package com.tuling.tulingmall.ordercurr.domain;
import com.tuling.tulingmall.ordercurr.model.OmsOrder;
import com.tuling.tulingmall.ordercurr.model.OmsOrderItem;
import java.util.List;
/**
* 包含订单商品信息的订单详情
* Created by macro on 2018/9/4.
*/
public class OmsOrderDetail extends OmsOrder {
private List<OmsOrderItem> orderItemList;
public List<OmsOrderItem> getOrderItemList() {
return orderItemList;
}
public void setOrderItemList(List<OmsOrderItem> orderItemList) {
this.orderItemList = orderItemList;
}
}

View File

@@ -0,0 +1,49 @@
package com.tuling.tulingmall.ordercurr.domain;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
/**
* 申请退货参数
* Created by macro on 2018/10/17.
*/
@Getter
@Setter
public class OmsOrderReturnApplyParam {
@ApiModelProperty("订单id")
private Long orderId;
@ApiModelProperty("退货商品id")
private Long productId;
@ApiModelProperty("订单编号")
private String orderSn;
@ApiModelProperty("会员用户名")
private String memberUsername;
@ApiModelProperty("退货人姓名")
private String returnName;
@ApiModelProperty("退货人电话")
private String returnPhone;
@ApiModelProperty("商品图片")
private String productPic;
@ApiModelProperty("商品名称")
private String productName;
@ApiModelProperty("商品品牌")
private String productBrand;
@ApiModelProperty("商品销售属性颜色红色尺码xl;")
private String productAttr;
@ApiModelProperty("退货数量")
private Integer productCount;
@ApiModelProperty("商品单价")
private BigDecimal productPrice;
@ApiModelProperty("商品实际支付单价")
private BigDecimal productRealPrice;
@ApiModelProperty("原因")
private String reason;
@ApiModelProperty("描述")
private String description;
@ApiModelProperty("凭证图片,以逗号隔开")
private String proofPics;
}

View File

@@ -0,0 +1,32 @@
package com.tuling.tulingmall.ordercurr.domain;
import com.tuling.tulingmall.ordercurr.model.OmsOrder;
import com.tuling.tulingmall.ordercurr.model.OmsOrderItem;
import lombok.Data;
import java.util.Date;
/**
* @author :图灵学院
* @date Created in 2020/2/25
* @version: V1.0
* @slogan: 天下风云出我辈,一入代码岁月催
* @description:
**/
@Data
public class OrderMessage {
private OmsOrder order;
private OmsOrderItem orderItem;
//秒杀活动记录ID
private Long flashPromotionRelationId;
//限购数量
private Integer flashPromotionLimit;
/*
* 秒杀活动结束日期
*/
private Date flashPromotionEndDate;
}

View File

@@ -0,0 +1,83 @@
package com.tuling.tulingmall.ordercurr.domain;
import java.util.List;
/**
* 生成订单时传入的参数
* Created by macro on 2018/8/30.
*/
public class OrderParam {
/*可用于避免重复生成订单*/
private Long orderId;
//收货地址id
private Long memberReceiveAddressId;
//优惠券id
private Long couponId;
//使用的积分数
private Integer useIntegration;
//支付方式
private Integer payType;
//选择购买的购物车商品
private List<Long> itemIds;
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public List<Long> getItemIds() {
return itemIds;
}
public void setItemIds(List<Long> itemIds) {
this.itemIds = itemIds;
}
public Long getMemberReceiveAddressId() {
return memberReceiveAddressId;
}
public void setMemberReceiveAddressId(Long memberReceiveAddressId) {
this.memberReceiveAddressId = memberReceiveAddressId;
}
public Long getCouponId() {
return couponId;
}
public void setCouponId(Long couponId) {
this.couponId = couponId;
}
public Integer getPayType() {
return payType;
}
public void setPayType(Integer payType) {
this.payType = payType;
}
public Integer getUseIntegration() {
return useIntegration;
}
public void setUseIntegration(Integer useIntegration) {
this.useIntegration = useIntegration;
}
@Override
public String toString() {
return "OrderParam{" +
"orderId=" + orderId +
", memberReceiveAddressId=" + memberReceiveAddressId +
", couponId=" + couponId +
", useIntegration=" + useIntegration +
", payType=" + payType +
", itemIds=" + itemIds +
'}';
}
}

View File

@@ -0,0 +1,151 @@
package com.tuling.tulingmall.ordercurr.domain;//package com.tuling.tulingmall.domain;
//
//import com.tuling.tulingmall.model.*;
//import io.swagger.annotations.ApiModelProperty;
//
//import java.math.BigDecimal;
//import java.util.Date;
//import java.util.List;
//
///**
// * 创建和修改商品时使用的参数
// * Created by tuling on 2018/4/26.
// */
//public class PmsProductParam extends PmsProduct {
// @ApiModelProperty("商品阶梯价格设置")
// private List<PmsProductLadder> productLadderList;
// @ApiModelProperty("商品满减价格设置")
// private List<PmsProductFullReduction> productFullReductionList;
// @ApiModelProperty("商品会员价格设置")
// private List<PmsMemberPrice> memberPriceList;
// @ApiModelProperty("商品的sku库存信息")
// private List<PmsSkuStock> skuStockList;
// @ApiModelProperty("商品参数及自定义规格属性")
// private List<PmsProductAttributeValue> productAttributeValueList;
// //秒杀活动信息
// /**
// * 秒杀活动价格
// */
// private BigDecimal flashPromotionPrice;
// /**
// * 活动商品库存数
// */
// private Integer flashPromotionCount;
// /**
// * 活动限购数量
// */
// private Integer flashPromotionLimit;
// /**
// * 秒杀活动状态
// * 0->关闭1->开启
// */
// private Integer flashPromotionStatus;
// /**
// * 秒杀活动开始日期
// */
// private Date flashPromotionStartDate;
// /**
// * 秒杀活动结束日期
// */
// private Date flashPromotionEndDate;
// /**
// * 秒杀活动记录-对应记录存有库存,限购数量,秒杀价格信息
// */
// private Long flashPromotionRelationId;
//
// public Long getFlashPromotionRelationId() {
// return flashPromotionRelationId;
// }
//
// public void setFlashPromotionRelationId(Long flashPromotionRelationId) {
// this.flashPromotionRelationId = flashPromotionRelationId;
// }
//
// public BigDecimal getFlashPromotionPrice() {
// return flashPromotionPrice;
// }
//
// public void setFlashPromotionPrice(BigDecimal flashPromotionPrice) {
// this.flashPromotionPrice = flashPromotionPrice;
// }
//
// public Integer getFlashPromotionCount() {
// return flashPromotionCount;
// }
//
// public void setFlashPromotionCount(Integer flashPromotionCount) {
// this.flashPromotionCount = flashPromotionCount;
// }
//
// public Integer getFlashPromotionLimit() {
// return flashPromotionLimit;
// }
//
// public void setFlashPromotionLimit(Integer flashPromotionLimit) {
// this.flashPromotionLimit = flashPromotionLimit;
// }
//
// public Integer getFlashPromotionStatus() {
// return flashPromotionStatus;
// }
//
// public void setFlashPromotionStatus(Integer flashPromotionStatus) {
// this.flashPromotionStatus = flashPromotionStatus;
// }
//
// public Date getFlashPromotionStartDate() {
// return flashPromotionStartDate;
// }
//
// public void setFlashPromotionStartDate(Date flashPromotionStartDate) {
// this.flashPromotionStartDate = flashPromotionStartDate;
// }
//
// public Date getFlashPromotionEndDate() {
// return flashPromotionEndDate;
// }
//
// public void setFlashPromotionEndDate(Date flashPromotionEndDate) {
// this.flashPromotionEndDate = flashPromotionEndDate;
// }
//
// public List<PmsProductLadder> getProductLadderList() {
// return productLadderList;
// }
//
// public void setProductLadderList(List<PmsProductLadder> productLadderList) {
// this.productLadderList = productLadderList;
// }
//
// public List<PmsProductFullReduction> getProductFullReductionList() {
// return productFullReductionList;
// }
//
// public void setProductFullReductionList(List<PmsProductFullReduction> productFullReductionList) {
// this.productFullReductionList = productFullReductionList;
// }
//
// public List<PmsMemberPrice> getMemberPriceList() {
// return memberPriceList;
// }
//
// public void setMemberPriceList(List<PmsMemberPrice> memberPriceList) {
// this.memberPriceList = memberPriceList;
// }
//
// public List<PmsSkuStock> getSkuStockList() {
// return skuStockList;
// }
//
// public void setSkuStockList(List<PmsSkuStock> skuStockList) {
// this.skuStockList = skuStockList;
// }
//
// public List<PmsProductAttributeValue> getProductAttributeValueList() {
// return productAttributeValueList;
// }
//
// public void setProductAttributeValueList(List<PmsProductAttributeValue> productAttributeValueList) {
// this.productAttributeValueList = productAttributeValueList;
// }
//}

View File

@@ -0,0 +1,13 @@
package com.tuling.tulingmall.ordercurr.domain;
/**
* @author :图灵学院
* @date Created in 2020/1/6 21:12
* @version: V1.0
* @slogan: 天下风云出我辈,一入代码岁月催
* @description:
**/
//@Data
//public class PortalMemberInfo extends UmsMember {
// private UmsMemberLevel umsMemberLevel;
//}

View File

@@ -0,0 +1,45 @@
package com.tuling.tulingmall.ordercurr.domain;//package com.tuling.tulingmall.domain;
//
//import com.tuling.tulingmall.model.PmsProduct;
//import com.tuling.tulingmall.model.PmsProductFullReduction;
//import com.tuling.tulingmall.model.PmsProductLadder;
//import com.tuling.tulingmall.model.PmsSkuStock;
//
//import java.util.List;
//
///**
// * Created by macro on 2018/8/27.
// * 商品的促销信息包括sku、打折优惠、满减优惠
// */
//public class PromotionProduct extends PmsProduct {
// //商品库存信息
// private List<PmsSkuStock> skuStockList;
// //商品打折信息
// private List<PmsProductLadder> productLadderList;
// //商品满减信息
// private List<PmsProductFullReduction> productFullReductionList;
//
// public List<PmsSkuStock> getSkuStockList() {
// return skuStockList;
// }
//
// public void setSkuStockList(List<PmsSkuStock> skuStockList) {
// this.skuStockList = skuStockList;
// }
//
// public List<PmsProductLadder> getProductLadderList() {
// return productLadderList;
// }
//
// public void setProductLadderList(List<PmsProductLadder> productLadderList) {
// this.productLadderList = productLadderList;
// }
//
// public List<PmsProductFullReduction> getProductFullReductionList() {
// return productFullReductionList;
// }
//
// public void setProductFullReductionList(List<PmsProductFullReduction> productFullReductionList) {
// this.productFullReductionList = productFullReductionList;
// }
//}

View File

@@ -0,0 +1,38 @@
package com.tuling.tulingmall.ordercurr.domain;
import lombok.Getter;
/**
* 消息队列枚举配置
* Created by macro on 2018/9/14.
*/
@Getter
public enum QueueEnum {
/**
* 消息通知队列
*/
QUEUE_ORDER_CANCEL("mall.order.direct", "mall.order.cancel", "mall.order.cancel"),
/**
* 消息通知ttl队列
*/
QUEUE_TTL_ORDER_CANCEL("mall.order.direct.ttl", "mall.order.cancel.ttl", "mall.order.cancel.ttl");
/**
* 交换名称
*/
private String exchange;
/**
* 队列名称
*/
private String name;
/**
* 路由键
*/
private String routeKey;
QueueEnum(String exchange, String name, String routeKey) {
this.exchange = exchange;
this.name = name;
this.routeKey = routeKey;
}
}

View File

@@ -0,0 +1,234 @@
package com.tuling.tulingmall.ordercurr.domain;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
public class SmsCoupon implements Serializable {
private Long id;
@ApiModelProperty(value = "优惠卷类型0->全场赠券1->会员赠券2->购物赠券3->注册赠券")
private Integer type;
private String name;
@ApiModelProperty(value = "使用平台0->全部1->移动2->PC")
private Integer platform;
@ApiModelProperty(value = "数量")
private Integer count;
@ApiModelProperty(value = "金额")
private BigDecimal amount;
@ApiModelProperty(value = "每人限领张数")
private Integer perLimit;
@ApiModelProperty(value = "使用门槛0表示无门槛")
private BigDecimal minPoint;
private Date startTime;
private Date endTime;
@ApiModelProperty(value = "使用类型0->全场通用1->指定分类2->指定商品")
private Integer useType;
@ApiModelProperty(value = "备注")
private String note;
@ApiModelProperty(value = "发行数量")
private Integer publishCount;
@ApiModelProperty(value = "已使用数量")
private Integer useCount;
@ApiModelProperty(value = "领取数量")
private Integer receiveCount;
@ApiModelProperty(value = "可以领取的日期")
private Date enableTime;
@ApiModelProperty(value = "优惠码")
private String code;
@ApiModelProperty(value = "可领取的会员类型0->无限时")
private Integer memberLevel;
private static final long serialVersionUID = 1L;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getPlatform() {
return platform;
}
public void setPlatform(Integer platform) {
this.platform = platform;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public Integer getPerLimit() {
return perLimit;
}
public void setPerLimit(Integer perLimit) {
this.perLimit = perLimit;
}
public BigDecimal getMinPoint() {
return minPoint;
}
public void setMinPoint(BigDecimal minPoint) {
this.minPoint = minPoint;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public Integer getUseType() {
return useType;
}
public void setUseType(Integer useType) {
this.useType = useType;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public Integer getPublishCount() {
return publishCount;
}
public void setPublishCount(Integer publishCount) {
this.publishCount = publishCount;
}
public Integer getUseCount() {
return useCount;
}
public void setUseCount(Integer useCount) {
this.useCount = useCount;
}
public Integer getReceiveCount() {
return receiveCount;
}
public void setReceiveCount(Integer receiveCount) {
this.receiveCount = receiveCount;
}
public Date getEnableTime() {
return enableTime;
}
public void setEnableTime(Date enableTime) {
this.enableTime = enableTime;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Integer getMemberLevel() {
return memberLevel;
}
public void setMemberLevel(Integer memberLevel) {
this.memberLevel = memberLevel;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", type=").append(type);
sb.append(", name=").append(name);
sb.append(", platform=").append(platform);
sb.append(", count=").append(count);
sb.append(", amount=").append(amount);
sb.append(", perLimit=").append(perLimit);
sb.append(", minPoint=").append(minPoint);
sb.append(", startTime=").append(startTime);
sb.append(", endTime=").append(endTime);
sb.append(", useType=").append(useType);
sb.append(", note=").append(note);
sb.append(", publishCount=").append(publishCount);
sb.append(", useCount=").append(useCount);
sb.append(", receiveCount=").append(receiveCount);
sb.append(", enableTime=").append(enableTime);
sb.append(", code=").append(code);
sb.append(", memberLevel=").append(memberLevel);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
}

View File

@@ -0,0 +1,148 @@
package com.tuling.tulingmall.ordercurr.domain;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.Date;
public class SmsCouponHistory implements Serializable {
private Long id;
private Long couponId;
private Long memberId;
private String couponCode;
@ApiModelProperty(value = "领取人昵称")
private String memberNickname;
@ApiModelProperty(value = "获取类型0->后台赠送1->主动获取")
private Integer getType;
private Date createTime;
@ApiModelProperty(value = "使用状态0->未使用1->已使用2->已过期")
private Integer useStatus;
@ApiModelProperty(value = "使用时间")
private Date useTime;
@ApiModelProperty(value = "订单编号")
private Long orderId;
@ApiModelProperty(value = "订单号码")
private String orderSn;
private static final long serialVersionUID = 1L;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getCouponId() {
return couponId;
}
public void setCouponId(Long couponId) {
this.couponId = couponId;
}
public Long getMemberId() {
return memberId;
}
public void setMemberId(Long memberId) {
this.memberId = memberId;
}
public String getCouponCode() {
return couponCode;
}
public void setCouponCode(String couponCode) {
this.couponCode = couponCode;
}
public String getMemberNickname() {
return memberNickname;
}
public void setMemberNickname(String memberNickname) {
this.memberNickname = memberNickname;
}
public Integer getGetType() {
return getType;
}
public void setGetType(Integer getType) {
this.getType = getType;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getUseStatus() {
return useStatus;
}
public void setUseStatus(Integer useStatus) {
this.useStatus = useStatus;
}
public Date getUseTime() {
return useTime;
}
public void setUseTime(Date useTime) {
this.useTime = useTime;
}
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public String getOrderSn() {
return orderSn;
}
public void setOrderSn(String orderSn) {
this.orderSn = orderSn;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", couponId=").append(couponId);
sb.append(", memberId=").append(memberId);
sb.append(", couponCode=").append(couponCode);
sb.append(", memberNickname=").append(memberNickname);
sb.append(", getType=").append(getType);
sb.append(", createTime=").append(createTime);
sb.append(", useStatus=").append(useStatus);
sb.append(", useTime=").append(useTime);
sb.append(", orderId=").append(orderId);
sb.append(", orderSn=").append(orderSn);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
}

View File

@@ -0,0 +1,40 @@
package com.tuling.tulingmall.ordercurr.domain;//package com.tuling.tulingmall.domain;
import java.util.List;
/**
* 优惠券领取历史详情封装
* Created by macro on 2018/8/29.
*/
public class SmsCouponHistoryDetail extends SmsCouponHistory {
//相关优惠券信息
private SmsCoupon coupon;
//优惠券关联商品
private List<SmsCouponProductRelation> productRelationList;
//优惠券关联商品分类
private List<SmsCouponProductCategoryRelation> categoryRelationList;
public SmsCoupon getCoupon() {
return coupon;
}
public void setCoupon(SmsCoupon coupon) {
this.coupon = coupon;
}
public List<SmsCouponProductRelation> getProductRelationList() {
return productRelationList;
}
public void setProductRelationList(List<SmsCouponProductRelation> productRelationList) {
this.productRelationList = productRelationList;
}
public List<SmsCouponProductCategoryRelation> getCategoryRelationList() {
return categoryRelationList;
}
public void setCategoryRelationList(List<SmsCouponProductCategoryRelation> categoryRelationList) {
this.categoryRelationList = categoryRelationList;
}
}

View File

@@ -0,0 +1,77 @@
package com.tuling.tulingmall.ordercurr.domain;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
public class SmsCouponProductCategoryRelation implements Serializable {
private Long id;
private Long couponId;
private Long productCategoryId;
@ApiModelProperty(value = "产品分类名称")
private String productCategoryName;
@ApiModelProperty(value = "父分类名称")
private String parentCategoryName;
private static final long serialVersionUID = 1L;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getCouponId() {
return couponId;
}
public void setCouponId(Long couponId) {
this.couponId = couponId;
}
public Long getProductCategoryId() {
return productCategoryId;
}
public void setProductCategoryId(Long productCategoryId) {
this.productCategoryId = productCategoryId;
}
public String getProductCategoryName() {
return productCategoryName;
}
public void setProductCategoryName(String productCategoryName) {
this.productCategoryName = productCategoryName;
}
public String getParentCategoryName() {
return parentCategoryName;
}
public void setParentCategoryName(String parentCategoryName) {
this.parentCategoryName = parentCategoryName;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", couponId=").append(couponId);
sb.append(", productCategoryId=").append(productCategoryId);
sb.append(", productCategoryName=").append(productCategoryName);
sb.append(", parentCategoryName=").append(parentCategoryName);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
}

View File

@@ -0,0 +1,77 @@
package com.tuling.tulingmall.ordercurr.domain;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
public class SmsCouponProductRelation implements Serializable {
private Long id;
private Long couponId;
private Long productId;
@ApiModelProperty(value = "商品名称")
private String productName;
@ApiModelProperty(value = "商品编码")
private String productSn;
private static final long serialVersionUID = 1L;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getCouponId() {
return couponId;
}
public void setCouponId(Long couponId) {
this.couponId = couponId;
}
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductSn() {
return productSn;
}
public void setProductSn(String productSn) {
this.productSn = productSn;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", couponId=").append(couponId);
sb.append(", productId=").append(productId);
sb.append(", productName=").append(productName);
sb.append(", productSn=").append(productSn);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
}

View File

@@ -0,0 +1,31 @@
package com.tuling.tulingmall.ordercurr.domain;
public class StockChanges {
private Long productSkuId;
private Integer changesCount;
public Long getProductSkuId() {
return productSkuId;
}
public void setProductSkuId(Long productSkuId) {
this.productSkuId = productSkuId;
}
public Integer getChangesCount() {
return changesCount;
}
public void setChangesCount(Integer changesCount) {
this.changesCount = changesCount;
}
public StockChanges(){}
public StockChanges(Long productSkuId, Integer changesCount) {
this.productSkuId = productSkuId;
this.changesCount = changesCount;
}
}

View File

@@ -0,0 +1,19 @@
package com.tuling.tulingmall.ordercurr.dto;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
/**
* 修改订单费用信息参数
* Created on 2018/10/29.
*/
@Getter
@Setter
public class OmsMoneyInfoParam {
private Long orderId;
private BigDecimal freightAmount;
private BigDecimal discountAmount;
private Integer status;
}

View File

@@ -0,0 +1,20 @@
package com.tuling.tulingmall.ordercurr.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 订单发货参数
* Created on 2018/10/12.
*/
@Getter
@Setter
public class OmsOrderDeliveryParam {
@ApiModelProperty("订单id")
private Long orderId;
@ApiModelProperty("物流公司")
private String deliveryCompany;
@ApiModelProperty("物流单号")
private String deliverySn;
}

View File

@@ -0,0 +1,28 @@
package com.tuling.tulingmall.ordercurr.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 订单查询参数
* Created on 2018/10/11.
*/
@Getter
@Setter
public class OmsOrderQueryParam {
@ApiModelProperty(value = "订单编号")
private String orderSn;
@ApiModelProperty(value = "客户ID")
private String memberId;
@ApiModelProperty(value = "收货人姓名/号码")
private String receiverKeyword;
@ApiModelProperty(value = "订单状态0->待付款1->待发货2->已发货3->已完成4->已关闭5->无效订单")
private Integer status;
@ApiModelProperty(value = "订单类型0->正常订单1->秒杀订单")
private Integer orderType;
@ApiModelProperty(value = "订单来源0->PC订单1->app订单")
private Integer sourceType;
@ApiModelProperty(value = "订单提交时间")
private String createTime;
}

View File

@@ -0,0 +1,16 @@
package com.tuling.tulingmall.ordercurr.dto;
import com.tuling.tulingmall.ordercurr.model.OmsCompanyAddress;
import com.tuling.tulingmall.ordercurr.model.OmsOrderReturnApply;
import lombok.Getter;
import lombok.Setter;
/**
* 申请信息封装
* Created on 2018/10/18.
*/
public class OmsOrderReturnApplyResult extends OmsOrderReturnApply {
@Getter
@Setter
private OmsCompanyAddress companyAddress;
}

View File

@@ -0,0 +1,22 @@
package com.tuling.tulingmall.ordercurr.dto;
import lombok.Getter;
import lombok.Setter;
/**
* 订单修改收货人信息参数
* Created on 2018/10/29.
*/
@Getter
@Setter
public class OmsReceiverInfoParam {
private Long orderId;
private String receiverName;
private String receiverPhone;
private String receiverPostCode;
private String receiverDetailAddress;
private String receiverProvince;
private String receiverCity;
private String receiverRegion;
private Integer status;
}

View File

@@ -0,0 +1,26 @@
package com.tuling.tulingmall.ordercurr.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* 订单退货申请查询参数
* Created on 2018/10/18.
*/
@Getter
@Setter
public class OmsReturnApplyQueryParam {
@ApiModelProperty("服务单号")
private Long id;
@ApiModelProperty(value = "收货人姓名/号码")
private String receiverKeyword;
@ApiModelProperty(value = "申请状态0->待处理1->退货中2->已完成3->已拒绝")
private Integer status;
@ApiModelProperty(value = "申请时间")
private String createTime;
@ApiModelProperty(value = "处理人员")
private String handleMan;
@ApiModelProperty(value = "处理时间")
private String handleTime;
}

View File

@@ -0,0 +1,32 @@
package com.tuling.tulingmall.ordercurr.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
/**
* 确认收货提交参数
* Created on 2018/10/18.
*/
@Getter
@Setter
public class OmsUpdateStatusParam {
@ApiModelProperty("服务单号")
private Long id;
@ApiModelProperty("收货地址关联id")
private Long companyAddressId;
@ApiModelProperty("确认退款金额")
private BigDecimal returnAmount;
@ApiModelProperty("处理备注")
private String handleNote;
@ApiModelProperty("处理人")
private String handleMan;
@ApiModelProperty("收货备注")
private String receiveNote;
@ApiModelProperty("收货人")
private String receiveMan;
@ApiModelProperty("申请状态1->退货中2->已完成3->已拒绝")
private Integer status;
}

View File

@@ -0,0 +1,23 @@
package com.tuling.tulingmall.ordercurr.feignapi.cart;
import com.tuling.tulingmall.ordercurr.domain.CartPromotionItem;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @desc: 调用购物车服务
*/
@FeignClient(name = "tulingmall-cart",path = "/cart")
public interface CartFeignApi {
// public String getSegmentId(@PathVariable("key") String key) ;
// @RequestMapping(value = "/api/segment/get/{key}")
// public List<CartPromotionItem> listSelectedPromotion(List<Long> itemIds,Long memberId);
@RequestMapping(value = "/list/selectedpromotion", method = RequestMethod.POST)
public List<CartPromotionItem> listSelectedPromotion(@RequestBody List<Long> itemIds);
}

View File

@@ -0,0 +1,26 @@
package com.tuling.tulingmall.ordercurr.feignapi.interceptor;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* @desc: 类的描述:Feign调用添加请求头
*/
@Slf4j
public class HeaderInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(attributes != null){
HttpServletRequest request = attributes.getRequest();
log.info("从Request中解析请求头:{}",request.getHeader("memberId"));
template.header("memberId",request.getHeader("memberId"));
}
}
}

View File

@@ -0,0 +1,41 @@
package com.tuling.tulingmall.ordercurr.feignapi.pms;//package com.tuling.tulingmall.feignapi.pms;
//
//import com.tuling.tulingmall.common.api.CommonResult;
//import com.tuling.tulingmall.domain.CartProduct;
//import com.tuling.tulingmall.domain.CartPromotionItem;
//import com.tuling.tulingmall.domain.PmsProductParam;
//import com.tuling.tulingmall.domain.PromotionProduct;
//import org.springframework.cloud.openfeign.FeignClient;
//import org.springframework.web.bind.annotation.*;
//
//import java.util.List;
//
///**
//* @vlog: 高于生活,源于生活
//* @desc: 类的描述:调用商品服务接口
//* @author: smlz
//* @createDate: 2020/1/23 17:42
//* @version: 1.0
//*/
//@FeignClient(name = "tulingmall-product")
//public interface PmsProductFeignApi {
//
// @RequestMapping(value = "/pms/cartProduct/{productId}", method = RequestMethod.GET)
// @ResponseBody
// CommonResult<CartProduct> getCartProduct(@PathVariable("productId") Long productId);
//
// @RequestMapping(value = "/pms/getPromotionProductList", method = RequestMethod.GET)
// CommonResult<List<PromotionProduct>> getPromotionProductList(@RequestParam("productIds") List<Long> ids);
//
// @RequestMapping("/stock/lockStock")
// CommonResult lockStock(@RequestBody List<CartPromotionItem> cartPromotionItemList);
//
// @RequestMapping(value = "/pms/productInfo/{id}", method = RequestMethod.GET)
// @ResponseBody
// CommonResult<PmsProductParam> getProductInfo(@PathVariable("id") Long id);
//
// @RequestMapping(value = "/stock/selectStock", method = RequestMethod.GET)
// @ResponseBody
// CommonResult<Integer> selectStock(@RequestParam("productId") Long productId,
// @RequestParam(value = "flashPromotionRelationId") Long flashPromotionRelationId);
//}

Some files were not shown because too many files have changed in this diff Show More