提交 0b72b385 authored 作者: liupengfei's avatar liupengfei

--no commit message

上级 9b0b93e4
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.zrqx</groupId>
<artifactId>app</artifactId>
<version>5.0.0</version>
</parent>
<artifactId>order</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<!-- redis 集成 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- cloud zipkin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!-- eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--表示为web工程 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 用于健康监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--熔断器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<!-- <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId>
</dependency> -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--分布式事务 -->
<!-- <dependency> <groupId>com.codingapi</groupId> <artifactId>transaction-springcloud</artifactId>
<exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>*</artifactId>
</exclusion> </exclusions> </dependency> <dependency> <groupId>com.codingapi</groupId>
<artifactId>tx-plugins-db</artifactId> <exclusions> <exclusion> <groupId>org.slf4j</groupId>
<artifactId>*</artifactId> </exclusion> </exclusions> </dependency> -->
<!--swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!--用于测试的 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- fastJson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.zrqx.order;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import com.alibaba.druid.pool.DruidDataSource;
import tk.mybatis.spring.annotation.MapperScan;
@EnableFeignClients
@EnableDiscoveryClient
@EnableHystrix
@EnableHystrixDashboard
@EnableScheduling
@SpringBootApplication // 系统会去入口类的同级包以及下级包中去扫描实体类,因此我们建议入口类的位置在groupId+arctifactID组合的包名下。
@MapperScan(basePackages = {"com.zrqx.order.*.mapper.*"})
public class Application {
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
private final static Logger logger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
logger.info("order服务已启动.....");
}
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setUsername(username);// 用户名
dataSource.setPassword(password);// 密码
dataSource.setInitialSize(10);
dataSource.setMaxActive(200);
dataSource.setMaxWait(60000);
dataSource.setValidationQuery("SELECT 1");
dataSource.setTestOnBorrow(false);
dataSource.setTestWhileIdle(true);
dataSource.setPoolPreparedStatements(false);
return dataSource;
}
}
package com.zrqx.order.bg.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.zrqx.core.vo.third.pay.refundquery.BaseRefundQueryReturnVo;
@FeignClient(name = "third", fallback = ThirdClientHystrix.class)
public interface ThirdClient {
@GetMapping("/pay/test")
BaseRefundQueryReturnVo test(@RequestParam("payType") String payType);
}
package com.zrqx.order.bg.client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.zrqx.core.vo.third.pay.refundquery.BaseRefundQueryReturnVo;
@Component
public class ThirdClientHystrix implements ThirdClient {
private static final Logger logger = LoggerFactory.getLogger(ThirdClientHystrix.class);
@Override
public BaseRefundQueryReturnVo test(String payType) {
logger.info("调用三方服务失败");
return null;
}
}
package com.zrqx.order.bg.controller;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.zrqx.core.constant.order.OrderRequestPath;
import com.zrqx.core.form.order.bg.InvoiceForm;
import com.zrqx.core.model.order.Invoice;
import com.zrqx.core.util.page.PageInfo;
import com.zrqx.core.util.page.PageParam;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.order.bg.service.InvoiceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;
@RestController
@RequestMapping(OrderRequestPath.BG+OrderRequestPath.INVOICE)
@Api(description = "后台发票管理")
public class InvoiceController {
@Autowired
private InvoiceService invoiceService;
@ApiOperation("发票列表")
@GetMapping(OrderRequestPath.PAGE)
public CallBack<PageInfo<Invoice>> page(PageParam pageParam, InvoiceForm form){
if (StringUtils.isBlank(pageParam.getOrderBy())) {
pageParam.setOrderBy("createTime desc");
}
Example example = invoiceService.createExample();
Criteria cr = example.createCriteria();
if(StringUtils.isNotBlank(form.getId())) {
cr.orEqualTo("invoiceCode", form.getId()).
orEqualTo("invoiceTitle", form.getId()).
orEqualTo("code", form.getId());
}
if(StringUtils.isNotBlank(form.getInvoiceCode())) {
cr.orEqualTo("invoiceCode", form.getInvoiceCode());
}
if(StringUtils.isNotBlank(form.getInvoiceTitle())) {
cr.orEqualTo("invoiceTitle", form.getInvoiceTitle());
}
if(StringUtils.isNotBlank(form.getCode())) {
cr.orEqualTo("orderCode", form.getCode());
}
if(StringUtils.isNotBlank(form.getCreaterName())) {
cr.orEqualTo("createrName", form.getCreaterName());
}
if (StringUtils.isNotBlank(form.getStartTime())) {
cr.andGreaterThanOrEqualTo("createTime", form.getStartTime());
}
if (StringUtils.isNotBlank(form.getEndTime())) {
cr.andLessThanOrEqualTo("createTime", form.getEndTime());
}
return CallBack.success(invoiceService.queryExample(pageParam, example));
}
}
package com.zrqx.order.bg.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.zrqx.core.constant.order.OrderRequestPath;
import com.zrqx.core.enums.order.OrderStatusListEnum;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.form.order.bg.OrderForm;
import com.zrqx.core.form.order.bg.OrderRemarkHistoryForm;
import com.zrqx.core.form.order.bg.UpdateOrderInvoiceForm;
import com.zrqx.core.model.order.OrderRemarkLog;
import com.zrqx.core.model.order.OrderStatusLog;
import com.zrqx.core.util.page.PageInfo;
import com.zrqx.core.util.page.PageParam;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.core.vo.order.bg.IndexOrderSummaryVo;
import com.zrqx.core.vo.order.bg.OrderListVO;
import com.zrqx.core.vo.order.bg.OrderVO;
import com.zrqx.order.bg.client.ThirdClient;
import com.zrqx.order.bg.service.OrderService;
@RestController
@RequestMapping(OrderRequestPath.BG + OrderRequestPath.ORDER)
@Api(description = "后台订单管理")
public class OrderController {
@Autowired
private OrderService orderService;
@Autowired
private ThirdClient thirdClient;
/**
* 查询订单列表
*
* @param form
* @param pageParam
* @return
* @author xjg
* @date 2019年1月7日 下午5:19:52
*/
@ApiOperation("查询订单列表")
@GetMapping(OrderRequestPath.PAGE)
public CallBack<PageInfo<OrderListVO>> page(OrderForm form,
PageParam pageParam) {
return CallBack.success(orderService.page(form, pageParam));
}
@ApiOperation("根据订单id查找订单详情")
@GetMapping(OrderRequestPath.OID)
public CallBack<OrderVO> echo(@PathVariable Integer oid) {
return CallBack.success(orderService.selectById(oid));
}
@ApiOperation("给订单增加或者修改发票信息")
@PostMapping(OrderRequestPath.UPDATE_ORDER_INVOICE)
public CallBack<Integer> updateOrderInvoice(@RequestBody UpdateOrderInvoiceForm form){
return CallBack.success(orderService.updateOrderInvoice(form));
}
@ApiOperation("订单添加备注历史")
@PostMapping(OrderRequestPath.SAVE_REMARK_HISTORY)
public CallBack<Boolean> saveRemarkHistory(@RequestBody OrderRemarkHistoryForm orderRemarkHistoryForm){
if(orderRemarkHistoryForm.getOrderId() == null){
throw new BaseException("订单id为空,不能添加备注信息");
}
if(orderRemarkHistoryForm.getRemark() == null || StringUtils.isEmpty(orderRemarkHistoryForm.getRemark())){
throw new BaseException("备注信息为空,添加备注历史信息失败");
}
return CallBack.success(orderService.saveRemarkHistory(orderRemarkHistoryForm));
}
@ApiOperation("根据订单id查询备注历史列表")
@GetMapping(OrderRequestPath.PAGE_REMARK_HISTORY)
public CallBack<PageInfo<OrderRemarkLog>> pageOrderRemarkLog(Integer orderId, PageParam pageParam){
return CallBack.success(orderService.pageOrderRemarkLog(orderId,pageParam));
}
@ApiOperation("根据订单id查询状态改变历史列表")
@GetMapping(OrderRequestPath.PAGE_STATUS_HISTORY)
public CallBack<PageInfo<OrderStatusLog>> pageOrderStatusLog(Integer orderId, PageParam pageParam){
return CallBack.success(orderService.pageOrderStatusLog(orderId,pageParam));
}
@ApiOperation("根据订单id取消订单")
@PostMapping(OrderRequestPath.CANCEL_ORDER)
public CallBack<Boolean> cancelOrder(Integer orderId){
return CallBack.success(orderService.cancelOrder(orderId));
}
@ApiOperation("订单所有状态列表,key:状态码,value:中文状态")
@PostMapping(OrderRequestPath.LIST_STATUS)
public CallBack<Map<String,String>> listStatus(){
Map<String, String> map = OrderStatusListEnum.getAllEnumMap();
return CallBack.success(map);
}
@ApiOperation("订单总数")
@GetMapping(OrderRequestPath.INDEX_COUNT)
public CallBack<Integer> count(){
// TODO
// 查询订单总数量
return null;
}
@ApiOperation("首页-订单统计信息")
@GetMapping(OrderRequestPath.INDEX_SUMMARY)
public CallBack<IndexOrderSummaryVo> indexSummary(){
// TODO
// 首页订单统计信息
// 成交是否意味 着 已支付 和已完成的订单
return null;
}
@ApiOperation("根据资源id和类型删除相关订单信息")
@PostMapping(OrderRequestPath.DELETE + OrderRequestPath.ORDER)
public CallBack<Boolean> deleteOrder(@RequestBody List<String> ids){
return CallBack.success(orderService.deleteOrder(ids));
}
}
package com.zrqx.order.bg.manage;
import org.apache.ibatis.annotations.Mapper;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.order.Invoice;
@Mapper
public interface InvoiceMapper extends BaseMapper<Invoice> {
}
package com.zrqx.order.bg.manage;
public class OrderManage {
}
package com.zrqx.order.bg.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.zrqx.core.form.order.bg.OrderForm;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.vo.order.bg.OrderListVO;
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
/**
* 查询订单列表
* @param orderFormQuery
* @return
* @author xjg
* @date 2019年1月7日 下午5:19:10
*/
@Select("<script>"
+ " select a.id,a.code,a.createrName,a.payment,a.status,a.createTime,a.needInvoice,a.invoiceStatus,a.orderSource,a.payType "
+ " from ord_order a "
+ " where 1 = 1 and a.orderType != 4 "
// 订单号
+ "<if test='"+ NOTBLANK +"(form.code)'>"
+ " and a.code like concat('%', #{form.code}, '%') "
+ "</if>"
//订单号
+ "<if test='"+ LIST_NOT_EMPTY +"(form.codes)'>"
+ " and a.code in "
+ "<foreach item='item' index='index' collection= 'form.codes' open='(' separator=',' close=')'>"
+ "#{item}"
+ "</foreach>"
+ "</if>"
// 支付方式:请选择、支付宝、微信、网银
+ "<if test='form.payType!=null'>"
+ " and a.payType = #{form.payType} "
+ "</if>"
// 开票状态:请选择、已开票、未开票
+ "<if test='form.invoiceStatus!=null'>"
+ " and a.invoiceStatus = #{form.invoiceStatus} "
+ "</if>"
// 订单状态:待支付、已支付、已确认、待发货、配货中、已发货、已完成、已缺货、已取消、请选择
+ "<if test='form.status!=null'>"
+ " and a.status=#{form.status} "
+ "</if>"
// 下单时间-开始时间
+ "<if test='form.startTime!=null'>"
+ " and a.createTime <![CDATA[ >= ]]> #{form.startTime} "
+ "</if>"
// 下单时间-结束时间
+ "<if test='form.endTime!=null'>"
+ " and date(a.createTime) <![CDATA[ <= ]]> #{form.endTime} "
+ "</if>"
// 下单会员
+ "<if test='"+ NOTBLANK +"(form.createrName)'>"
+ " and a.createrName like concat('%', #{form.createrName}, '%') "
+ "</if>"
+ " group by a.id "
+ " order by a.createTime desc "
+ "</script>")
List<OrderListVO>page(@Param("form")OrderForm form);
}
package com.zrqx.order.bg.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.order.OrderRemarkLog;
@Mapper
public interface OrderRemarkLogMapper extends BaseMapper<OrderRemarkLog>{
/**
* 根据订单id查询备注历史
* @param orderid
* @return
* @author ydm
* @date: 2018年7月16日 上午10:42:11
*/
@Select("<script>"
+ "select a.operationContent,a.createTime,a.createrName "
+ " from ord_order_remark_log a where 1=1 "
// 订单id
+ "<if test='orderid!=null'>"
+ " and a.orderId = #{orderid} "
+ "</if>"
+ " order by a.createTime desc "
+ "</script>")
List<OrderRemarkLog> pageOrderRemarkLog(@Param("orderid")Integer orderid);
}
package com.zrqx.order.bg.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.order.OrderStatusLog;
@Mapper
public interface OrderStatusLogMapper extends BaseMapper<OrderStatusLog>{
/**
* 根据订单id查询备注历史
* @param orderid
* @return
* @author ydm
* @date: 2018年7月16日 上午10:42:11
*/
@Select("<script>"
+ "select a.operationContent,a.createTime,a.createrName "
+ " from ord_order_status_log a where 1=1 "
// 订单id
+ "<if test='orderid!=null'>"
+ " and a.orderId = #{orderid} "
+ "</if>"
+ " order by a.createTime desc "
+ "</script>")
List<OrderStatusLog> pageOrderStatusLog(@Param("orderid")Integer orderid);
}
package com.zrqx.order.bg.mapper;
import org.apache.ibatis.annotations.Mapper;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.order.OrderInfo;
@Mapper
public interface OrderinfoMapper extends BaseMapper<OrderInfo>{
}
package com.zrqx.order.bg.service;
import com.zrqx.core.model.order.Invoice;
import com.zrqx.core.service.BaseService;
public interface InvoiceService extends BaseService<Invoice, Integer>{
}
package com.zrqx.order.bg.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.order.Invoice;
import com.zrqx.core.service.BaseServiceImpl;
import com.zrqx.order.bg.manage.InvoiceMapper;
@Service
public class InvoiceServiceImpl extends BaseServiceImpl<Invoice, Integer> implements InvoiceService{
private static final Logger logger = LoggerFactory.getLogger(InvoiceServiceImpl.class);
@Autowired
private InvoiceMapper invoiceMapper;
@Override
public BaseMapper<Invoice> getMapper() {
return invoiceMapper;
}
}
package com.zrqx.order.bg.service;
import java.util.List;
import com.zrqx.core.form.order.bg.OrderForm;
import com.zrqx.core.form.order.bg.OrderRemarkHistoryForm;
import com.zrqx.core.form.order.bg.UpdateOrderInvoiceForm;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.model.order.OrderRemarkLog;
import com.zrqx.core.model.order.OrderStatusLog;
import com.zrqx.core.service.BaseService;
import com.zrqx.core.util.page.PageInfo;
import com.zrqx.core.util.page.PageParam;
import com.zrqx.core.vo.order.bg.OrderListVO;
import com.zrqx.core.vo.order.bg.OrderVO;
public interface OrderService extends BaseService<Order, Integer> {
/**
* 查询订单列表
* @param orderFormQuery
* @return
* @author xjg
* @date 2019年1月7日 下午5:18:00
*/
public PageInfo<OrderListVO> page(OrderForm form, PageParam pageParam);
/**
* 根据订单id查找订单详情
* @param oid
* @return
* @author xjg
* @date 2019年1月8日 上午10:40:49
*/
public OrderVO selectById(Integer oid);
/**
* 更新订单中的发票信息
* @param form
* @return
* @author ycw
* @date: 2019年3月28日 下午5:54:14
*/
Integer updateOrderInvoice(UpdateOrderInvoiceForm form);
/**
* 添加订单历史备注信息
* @param orderRemarkHistoryForm
* @return
* @author ycw
* @date: 2019年3月28日 下午3:39:21
*/
boolean saveRemarkHistory(OrderRemarkHistoryForm orderRemarkHistoryForm);
/**
* 根据订单id查询备注历史列表
* @param orderId
* @param pageParam
* @return
* @author xjg
* @date 2019年1月8日 下午4:25:26
*/
PageInfo<OrderRemarkLog> pageOrderRemarkLog(Integer orderId, PageParam pageParam);
/**
* 根据订单id查询状态变更记录
* @param orderId
* @param pageParam
* @return
* @author xjg
* @date 2019年1月8日 下午4:25:49
*/
PageInfo<OrderStatusLog> pageOrderStatusLog(Integer orderId, PageParam pageParam);
/**
* 根据订单id取消订单
* @param orderId
* @return
* @author xjg
* @date 2019年1月9日 下午2:18:19
*/
public Boolean cancelOrder(Integer orderId);
/**
* 根据资源ids删除订单相关信息
* @param goodsForm
* @return
*/
public boolean deleteOrder(List<String> ids);
}
package com.zrqx.order.bg.service;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import com.zrqx.core.enums.BooleanStatusEnum;
import com.zrqx.core.enums.GoodsTypeEnum;
import com.zrqx.core.enums.member.LevelEnum;
import com.zrqx.core.enums.order.OrderSourceEnum;
import com.zrqx.core.enums.order.OrderStatusEnum;
import com.zrqx.core.enums.third.pay.PayTypeEnum;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.exception.BusinessValidateException;
import com.zrqx.core.exception.LoginValidateException;
import com.zrqx.core.form.order.bg.OrderForm;
import com.zrqx.core.form.order.bg.OrderRemarkHistoryForm;
import com.zrqx.core.form.order.bg.UpdateOrderInvoiceForm;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.model.order.OrderInfo;
import com.zrqx.core.model.order.OrderRemarkLog;
import com.zrqx.core.model.order.OrderStatusLog;
import com.zrqx.core.model.sysuser.user.User;
import com.zrqx.core.service.BaseServiceImpl;
import com.zrqx.core.util.datatype.StringUtil;
import com.zrqx.core.util.page.PageInfo;
import com.zrqx.core.util.page.PageParam;
import com.zrqx.core.vo.order.bg.OrderListVO;
import com.zrqx.core.vo.order.bg.OrderVO;
import com.zrqx.order.bg.mapper.OrderMapper;
import com.zrqx.order.bg.mapper.OrderRemarkLogMapper;
import com.zrqx.order.bg.mapper.OrderStatusLogMapper;
import com.zrqx.order.bg.mapper.OrderinfoMapper;
import com.zrqx.order.commons.redis.RedisManage;
@Service
public class OrderServiceImpl extends BaseServiceImpl<Order, Integer> implements
OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private OrderinfoMapper orderinfoMapper;
@Autowired
private OrderRemarkLogMapper orderRemarkLogMapper;
@Autowired
private OrderStatusLogMapper orderStatusLogMapper;
@Autowired
private RedisManage redisManage;
@Override
public BaseMapper<Order> getMapper() {
return orderMapper;
}
/**
* 查询订单列表
* @param form
* @param pageParam
* @return
* @author xjg
* @date 2019年1月9日 下午2:29:26
*/
@Override
public PageInfo<OrderListVO> page(OrderForm form, PageParam pageParam) {
//this.fmtForm(form);
// 开启分页
startPage(pageParam);
List<OrderListVO> list = orderMapper.page(form);
list.parallelStream()
.forEach(vo -> {
// 存在null
vo.setInvoiceStatus(BooleanStatusEnum.YES.getCode().equals(vo
.getInvoiceStatus()) ? "已开票" : "未开票");
vo.setStatusZh(OrderStatusEnum.getName(vo.getStatus()));
vo.setOrderSourceZh(OrderSourceEnum.getName(vo
.getOrderSource()));
vo.setPayType(PayTypeEnum.getName(vo.getPayType()));
});
return new PageInfo<OrderListVO>(list);
}
/**
* 构造查询参数
* @param form
* @author lpf
* @date: 2019年1月29日 下午4:06:37
*/
private void fmtForm(OrderForm form){
form.setCodes(form.getCode() == null ? null : StringUtil.split(form.getCode()));
}
/**
* 根据订单id查询订单详情
* @param oid
* @return
* @author xjg
* @date 2019年1月9日 下午2:29:58
*/
@Override
public OrderVO selectById(Integer oid) {
OrderVO orderVO = new OrderVO();
Order order = orderMapper.selectByPrimaryKey(oid);
BeanUtils.copyProperties(order, orderVO);
orderVO.setLevel_zh(LevelEnum.getName(orderVO.getLevel()));
orderVO.setStatusZh(OrderStatusEnum.getName(orderVO.getStatus()));
orderVO.setOrderSource(OrderSourceEnum.getName(orderVO.getOrderSource()));
orderVO.setPayTypeZh(PayTypeEnum.getName(orderVO.getPayType()));
OrderInfo orderInfo = new OrderInfo();
orderInfo.setOrderid(order.getId());
List<OrderInfo> list = orderinfoMapper.select(orderInfo);
list.parallelStream()
.forEach(vo -> {
// 存在null
vo.setType(GoodsTypeEnum.getName(vo.getType()));
if(vo.getNum() != null){
BigDecimal num=new BigDecimal(vo.getNum());
vo.setTotalPrice(vo.getSalePrice().multiply(num));
}
});
orderVO.setOrderinfoList(list);
return orderVO;
}
/**
* 更新订单中的发票信息
* @see com.zrqx.order.bg.service.OrderService#updateOrderInvoice(com.zrqx.core.form.order.bg.UpdateOrderInvoiceForm)
* @param form
* @return
* @author ycw
* @date: 2019年3月28日 下午5:54:40
*/
@Override
public Integer updateOrderInvoice(UpdateOrderInvoiceForm form) {
Integer orderId = form.getOrderId();
if (orderId == null) {
throw new BusinessValidateException("订单id为空");
}
Order o = selectByPrimaryKey(orderId);
if (o == null) {
throw new BusinessValidateException("未找到该订单");
}
o.setNeedInvoice(form.getNeedInvoice());
//o.setInvoiceStatus(form.getInvoiceStatus());
o.setInvoiceEmail(form.getInvoiceEmail());
o.setInvoiceAddress(form.getInvoiceAddress());
o.setInvoiceType(form.getInvoiceType());
o.setInvoiceTitle(form.getInvoiceTitle());
o.setTaxpayerIdentificationNumber(form.getTaxpayerIdentificationNumber());
o.setInvoiceContext(form.getInvoiceContext());
User user = redisManage.get(User.class);
if (user == null) {
throw new LoginValidateException();
}
o.setUpdater(user.getUserId());
o.setUpdaterName(user.getUserName());
o.setUpdateTime(new Date());
Integer result = orderMapper.updateByPrimaryKeySelective(o);
return result;
}
/**
* 添加订单历史备注信息
* @see com.zrqx.order.bg.service.OrderService#saveRemarkHistory(com.zrqx.core.form.order.bg.OrderRemarkHistoryForm)
* @param orderRemarkHistoryForm
* @return
* @author ycw
* @date: 2019年3月28日 下午3:51:27
*/
@Override
public boolean saveRemarkHistory(
OrderRemarkHistoryForm orderRemarkHistoryForm) {
Order o = selectByPrimaryKey(orderRemarkHistoryForm.getOrderId());
if (o == null) {
throw new BaseException("未找到订单,请检查后重试");
}
OrderRemarkLog orl = new OrderRemarkLog();
orl.setOrderId(orderRemarkHistoryForm.getOrderId());
orl.setCreateTime(new Date());
User user = redisManage.get(User.class);
if (user != null) {
orl.setCreater(user.getUserId());
orl.setCreaterName(user.getName());
orl.setCreaterType(user.getIsAdmin());
}
orl.setOperationContent(orderRemarkHistoryForm.getRemark());
if (1 == orderRemarkLogMapper.insert(orl)) {
return true;
}
return false;
}
/**
* 根据订单id查询日志列表
* @param orderId
* @param pageParam
* @return
* @author xjg
* @date 2019年1月9日 下午2:30:55
*/
@Override
public PageInfo<OrderRemarkLog> pageOrderRemarkLog(Integer orderId,
PageParam pageParam) {
// 开启分页
startPage(pageParam);
List<OrderRemarkLog> list = orderRemarkLogMapper
.pageOrderRemarkLog(orderId);
return new PageInfo<OrderRemarkLog>(list);
}
/**
* 根据订单id查询订单变更列表
* @param orderId
* @param pageParam
* @return
* @author xjg
* @date 2019年1月9日 下午2:31:52
*/
@Override
public PageInfo<OrderStatusLog> pageOrderStatusLog(Integer orderId,
PageParam pageParam) {
// 开启分页
startPage(pageParam);
List<OrderStatusLog> list = orderStatusLogMapper
.pageOrderStatusLog(orderId);
return new PageInfo<OrderStatusLog>(list);
}
/**
* 根据订单id取消订单
* @param orderId
* @return
* @author xjg
* @date 2019年1月9日 下午2:32:51
*/
@Override
public Boolean cancelOrder(Integer orderId) {
boolean result=false;
Order order = new Order();
order.setStatus("9");
result = orderMapper.updateByPrimaryKeySelective(order) > 0;
return result;
}
/**
* 根据资源ids删除订单信息
* @param ids
* @return
* @author xjg
* @date 2019年1月9日 下午2:32:51
*/
@Override
public boolean deleteOrder(List<String> ids) {
Example example = new Example(OrderInfo.class);
example.createCriteria().andIn("goodsid", ids);
List<OrderInfo>orderInfoList = orderinfoMapper.selectByExample(example);
List<Integer> orderId = orderInfoList.stream().map(OrderInfo :: getOrderid).distinct().collect(Collectors.toList());
orderinfoMapper.deleteByExample(example);
example = new Example(Order.class);
example.createCriteria().andIn("id", orderId);
orderMapper.deleteByExample(example);
return true;
}
}
package com.zrqx.order.commons.aspect;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;
/**
*
* @author lpf
* @date 2018年12月26日下午5:25:20
*/
@Aspect
@Configuration
public class TxAdviceInterceptor {
private static final int TX_METHOD_TIMEOUT = 120;
private static final int TX_METHOD_TIMEOUT_PUSH_BAISHI = 3600;
public static final String AOP_POINTCUT_EXPRESSION = "(execution(* com.zrqx..service..*Impl.*(..)))";
@Autowired
private PlatformTransactionManager transactionManager;
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public TransactionInterceptor txAdvice() {
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
/*只读事务,不做更新操作*/
RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
readOnlyTx.setReadOnly(true);
readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED );
/*当前存在事务就使用当前事务,当前不存在事务就创建一个新的事务*/
RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
requiredTx.setRollbackRules(
Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
requiredTx.setTimeout(TX_METHOD_TIMEOUT);
RuleBasedTransactionAttribute requiredTx_pushBaiShi = new RuleBasedTransactionAttribute();
requiredTx_pushBaiShi.setRollbackRules(
Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
requiredTx_pushBaiShi.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
requiredTx_pushBaiShi.setTimeout(TX_METHOD_TIMEOUT_PUSH_BAISHI);
Map<String, TransactionAttribute> txMap = new HashMap<>();
txMap.put("updatePushToForeign*", requiredTx_pushBaiShi);
txMap.put("add*", requiredTx);
txMap.put("create*", requiredTx);
txMap.put("toPay*", requiredTx);
txMap.put("save*", requiredTx);
txMap.put("insert*", requiredTx);
txMap.put("update*", requiredTx);
txMap.put("batch*", requiredTx);
txMap.put("delete*", requiredTx);
txMap.put("get*", readOnlyTx);
txMap.put("query*", readOnlyTx);
source.setNameMap( txMap );
TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager, source);
return txAdvice;
}
@Bean
public Advisor txAdviceAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
return new DefaultPointcutAdvisor(pointcut, txAdvice());
//return new DefaultPointcutAdvisor(pointcut, txAdvice);
}
}
\ No newline at end of file
package com.zrqx.order.commons.aspect;
import org.springframework.core.Ordered;
//@Aspect
public class TxTransactionAspect implements Ordered {
@Override
public int getOrder() {
return HIGHEST_PRECEDENCE;
}
/* @Autowired
private TxManagerInterceptor txManagerInterceptor;
@Around(TxAdviceInterceptor.AOP_POINTCUT_EXPRESSION)
public Object around(ProceedingJoinPoint point)throws Throwable{
return txManagerInterceptor.around(point);
}*/
}
package com.zrqx.order.commons.config;
import java.lang.reflect.Method;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* redis 配置类
* @author pc
*
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
/*@SuppressWarnings("rawtypes")
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
// 设置缓存过期时间
// rcm.setDefaultExpiration(60);//秒
return rcm;
}*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
//.entryTtl(Duration.ofHours(1)) // 设置缓存有效期一小时
;
return RedisCacheManager
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
.cacheDefaults(redisCacheConfiguration).build();
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
// key序列化方式,但是如果方法上有Long等非String类型的话,会报类型转换错误
// 所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer
RedisSerializer<String> redisSerializer = new StringRedisSerializer();// Long类型不可以会出现异常信息;
redisTemplate.setKeySerializer(redisSerializer);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
\ No newline at end of file
package com.zrqx.order.commons.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.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* 访问地址
* http://ip:port/swagger-ui.html
最常用的5个注解
@Api:修饰整个类,描述Controller的作用
@ApiOperation:描述一个类的一个方法,或者说一个接口
@ApiParam:单个参数描述
@ApiModel:用对象来接收参数
@ApiModelProperty:用对象接收参数时,描述对象的一个字段
其它若干
@ApiResponse:HTTP响应其中1个描述
@ApiResponses:HTTP响应整体描述
@ApiIgnore:使用该注解忽略这个API
@ApiClass
@ApiError
@ApiErrors
@ApiParamImplicit
@ApiParamsImplicit
*/
@EnableSwagger2
@Configuration
public class Swagger2Config {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//为当前包路径
.apis(RequestHandlerSelectors.basePackage("com.zrqx"))
.paths(PathSelectors.any())
.build();
}
//构建 api文档的详细信息函数
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
//页面标题
.title("order 测试使用 Swagger2 构建RESTful API")
//描述
.description("order服务 API 描述")
//创建人
.contact(new Contact("刘鹏飞", "www.baidu.com", "liupengfei_it@163.com"))
//版本号
.version("3.0")
.build();
}
}
\ No newline at end of file
package com.zrqx.order.commons.convert;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
/**
* 字符串转换为Date
* @author lpf
* @date 2018年7月10日下午4:02:01
*/
public class StringToDateConverter implements Converter<String, Date> {
private static final List<String> formarts = new ArrayList<String>(4);
static{
formarts.add("yyyy-MM");
formarts.add("yyyy-MM-dd");
formarts.add("yyyy-MM-dd hh:mm");
formarts.add("yyyy-MM-dd HH:mm:ss");
}
public Date convert(String source) {
String value = source.trim();
if ("".equals(value)) {
return null;
}
if(source.matches("^\\d{4}-\\d{1,2}$")){
return parseDate(source, formarts.get(0));
}else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")){
return parseDate(source, formarts.get(1));
}else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")){
return parseDate(source, formarts.get(2));
}else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
return parseDate(source, formarts.get(3));
}else {
throw new IllegalArgumentException("Invalid boolean value '" + source + "'");
}
}
public Date parseDate(String dateStr, String format) {
Date date=null;
try {
DateFormat dateFormat = new SimpleDateFormat(format);
date = (Date) dateFormat.parse(dateStr);
} catch (Exception e) {
}
return date;
}
}
package com.zrqx.order.commons.enums;
import com.zrqx.core.enums.interfaces.EnumsInterface;
/**
* 购买方式枚举
* @author lpf
* @date 2018年12月28日下午12:45:22
*/
public enum BuyTypeEnum implements EnumsInterface<String> {
/** 立即购买 */
NOW("1", "立即购买"),
/** 再次购买 */
AGAIN("2", "再次购买"),
/** 购物车 */
SHOPPING_CART("3", "购物车"),
/** 组合购买 */
GROUP("4", "组合购买");
private final String code;
private final String name;
private BuyTypeEnum(String code, String name) {
this.code = code;
this.name = name;
}
/**
* 判断名称是否有效
* @param name
* @return
* @author lpf
* @date: 2018年6月11日 下午6:30:16
*/
public static boolean isExist(String code) {
BuyTypeEnum[] enums = BuyTypeEnum.values();
for (BuyTypeEnum BuyTypeEnum : enums) {
if (BuyTypeEnum.code.equals(code)) {
return true;
}
}
return false;
}
/**
* 根据code 获取名字
* @param code
* @return
* @author lpf
* @date: 2018年12月28日 下午12:52:14
*/
public static String getName(String code) {
BuyTypeEnum[] enums = BuyTypeEnum.values();
for (BuyTypeEnum BuyTypeEnum : enums) {
if (BuyTypeEnum.code.equals(code)) {
return BuyTypeEnum.name;
}
}
return null;
}
/**
* 根据code 获取名字
* @param name
* @return
* @author lpf
* @date: 2018年12月28日 下午12:52:35
*/
public static String getCode(String name) {
BuyTypeEnum[] enums = BuyTypeEnum.values();
for (BuyTypeEnum BuyTypeEnum : enums) {
if (BuyTypeEnum.name.equals(name)) {
return BuyTypeEnum.code;
}
}
return null;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
}
package com.zrqx.order.commons.enums.interfaces.buytype;
import java.util.List;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.form.order.fg.FgOrderForm;
/**
* 购买方式默认逻辑
* @author lpf
* @date 2019年1月11日下午4:31:08
*/
public abstract class BuyTypeAdapter implements BuyTypeInterface{
@Override
public List<CreateOrderInfoForm> getGoodsList(FgOrderForm form) {
return form.getGoodsList();
}
}
package com.zrqx.order.commons.enums.interfaces.buytype;
import java.util.List;
import com.zrqx.core.enums.interfaces.EnumsBindBean;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.form.order.fg.FgOrderForm;
import com.zrqx.order.commons.enums.BuyTypeEnum;
/**
* 购买方式绑定操作接口
* @author lpf
* @date 2019年1月4日上午10:28:16
*/
public interface BuyTypeInterface extends EnumsBindBean<BuyTypeEnum>{
/**
* 查询订单详情表单
* @param form
* @return
* @author lpf
* @date: 2019年1月11日 下午5:18:00
*/
List<CreateOrderInfoForm> getGoodsList(FgOrderForm form);
}
package com.zrqx.order.commons.enums.interfaces.buytype.impl;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.form.order.fg.FgOrderForm;
import com.zrqx.order.commons.enums.BuyTypeEnum;
import com.zrqx.order.commons.enums.interfaces.buytype.BuyTypeAdapter;
import com.zrqx.order.commons.enums.interfaces.buytype.BuyTypeInterface;
import com.zrqx.order.fg.mapper.FgOrderInfoMapper;
/**
* 订单再次购买
* @author lpf
* @date 2019年1月7日下午4:49:42
*/
@Component
public class AgainImpl extends BuyTypeAdapter{
@Autowired
private FgOrderInfoMapper fgOrderInfoMapper;
@Override
public List<BuyTypeEnum> getEnums() {
return Arrays.asList(BuyTypeEnum.AGAIN);
}
@Override
public List<CreateOrderInfoForm> getGoodsList(FgOrderForm form) {
Integer id = form.getOrderId();
return fgOrderInfoMapper.getGoodsList(id);
}
}
package com.zrqx.order.commons.enums.interfaces.buytype.impl;
import java.util.Arrays;
import java.util.List;
import org.springframework.stereotype.Component;
import com.zrqx.order.commons.enums.BuyTypeEnum;
import com.zrqx.order.commons.enums.interfaces.buytype.BuyTypeAdapter;
import com.zrqx.order.commons.enums.interfaces.buytype.BuyTypeInterface;
/**
* 默认购买方式逻辑
* @author lpf
* @date 2019年1月7日下午4:48:54
*/
@Component
public class DefaultBuyTypeImpl extends BuyTypeAdapter{
/**
* 操作绑定的枚举
* @see com.zrqx.core.enums.interfaces.EnumsBindBean#getEnums()
* @return
* @author lpf
* @date: 2019年1月7日 下午4:53:14
*/
@Override
public List<BuyTypeEnum> getEnums() {
return Arrays.asList(BuyTypeEnum.NOW, BuyTypeEnum.GROUP);
}
}
package com.zrqx.order.commons.enums.interfaces.buytype.impl;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.form.order.fg.FgOrderForm;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.order.commons.enums.BuyTypeEnum;
import com.zrqx.order.commons.enums.interfaces.buytype.BuyTypeAdapter;
import com.zrqx.order.fg.client.FgShopcartClient;
/**
* 购物车购买
* @author lpf
* @date 2019年1月7日下午4:48:44
*/
@Component
public class ShoppingCartImpl extends BuyTypeAdapter{
@Autowired
private FgShopcartClient fgShopcartClient;
/**
* 操作绑定的枚举
* @see com.zrqx.core.enums.interfaces.EnumsBindBean#getEnums()
* @return
* @author lpf
* @date: 2019年1月7日 下午4:58:14
*/
@Override
public List<BuyTypeEnum> getEnums() {
return Arrays.asList(BuyTypeEnum.SHOPPING_CART);
}
@Override
public List<CreateOrderInfoForm> getGoodsList(FgOrderForm form) {
Integer[] ids = form.getShoppingCartIds();
CallBack<List<CreateOrderInfoForm>> call = fgShopcartClient.queryByIds(ids);
if (call.hasEntity()) {
return call.getData();
}
throw new BaseException("查询购物车信息失败,form:" + form);
}
}
package com.zrqx.order.commons.enums.interfaces.ordertype;
import java.math.BigDecimal;
import java.util.List;
import com.zrqx.core.enums.interfaces.EnumsBindBean;
import com.zrqx.core.enums.order.OrderTypeEnum;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.form.third.pay.PayResultForm;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.model.order.OrderInfo;
import com.zrqx.core.model.resource.shoppingaddress.ShoppingAddress;
import com.zrqx.core.vo.third.pay.payquery.PayQueryReturnVo;
/**
* 订单类型绑定操作
* @author lpf
* @date 2019年1月8日上午10:09:32
*/
public interface OrderTypeInterface extends EnumsBindBean<OrderTypeEnum>{
/**
* 获取收货地址
* @param id
* @return
* @author lpf
* @date: 2019年1月10日 下午3:58:33
*/
ShoppingAddress getShoppingAddress(Integer id);
/**
* 验证库存
* @param list 实体商品
* @author lpf
* @date: 2019年1月11日 下午5:47:51
*/
void validateSotck(List<CreateOrderInfoForm> list);
/**
* 计算实际邮费
* @param context
* @return
* @author lpf
* @param province
* @date: 2019年1月10日 下午5:45:25
*/
BigDecimal calculateCarriage(List<OrderInfo> infoList, String province);
/**
* 计算用户邮费
* @param infoList
* @param province
* @return
* @author lpf
* @param string
* @date: 2019年1月10日 下午5:46:25
*/
BigDecimal calculateReaderCarriage(List<OrderInfo> infoList, String province);
/**
* 支付回调,订单处理逻辑
* @param order 订单
* @param form 支付回调表单
* @return
* @author lpf
* @date: 2019年2月21日 上午10:58:18
*/
boolean receivePayCall(Order order, PayResultForm form);
/**
* 支付回调,验证成功后,订单处理逻辑
* @param order
* @param payQueryReturnVo
* @return
* @author lpf
* @date: 2019年2月25日 上午11:55:53
*/
boolean paySuccess(Order order, PayQueryReturnVo payQueryReturnVo);
}
package com.zrqx.order.commons.enums.interfaces.ordertype.impl;
import java.math.BigDecimal;
import java.util.List;
import com.zrqx.core.constant.BaseConstant;
import com.zrqx.core.enums.order.OrderStatusEnum;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.model.order.OrderInfo;
import com.zrqx.core.model.resource.shoppingaddress.ShoppingAddress;
import com.zrqx.core.vo.third.pay.payquery.PayQueryReturnVo;
/**
* 电子订单公用逻辑
* @author lpf
* @date 2019年1月24日上午11:12:49
*/
public abstract class ElectronicOrderTypeAdapter extends OrderTypeAdapter{
/**
* 电子订单支付成功处理逻辑
* @param order
* @param payQueryReturnVo
* @return
* @author lpf
* @date: 2019年2月21日 上午11:57:14
*/
@Override
protected boolean paySuccessProcess(Order order, PayQueryReturnVo payQueryReturnVo) {
// 订单状态修改为已支付
boolean flag = super.fgOrderManage.updateOrderStatusAndLogs(order,
OrderStatusEnum.HAVE_PAID, "订单支付", BaseConstant.SYSTEM_NAME);
// 订单状态修改为已完成
boolean flag1 = super.fgOrderManage.updateOrderStatusAndLogs(order,
OrderStatusEnum.SIGNED_IN, "订单已完成", BaseConstant.SYSTEM_NAME);
return flag && flag1;
}
@Override
public ShoppingAddress getShoppingAddress(Integer id) {
// 电子订单不需要收货地址
return null;
}
@Override
public void validateSotck(List<CreateOrderInfoForm> list) {
}
@Override
public BigDecimal calculateCarriage(List<OrderInfo> infoList, String province) {
return new BigDecimal(0);
}
@Override
public BigDecimal calculateReaderCarriage(List<OrderInfo> infoList, String province) {
return new BigDecimal(0);
}
}
package com.zrqx.order.commons.enums.interfaces.ordertype.impl;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.zrqx.core.enums.order.OrderTypeEnum;
/**
* 电子订单逻辑
* @author lpf
* @date 2019年1月10日下午4:48:26
*/
@Component
public class ElectronicOrderTypeImpl extends ElectronicOrderTypeAdapter{
private static final Logger logger = LoggerFactory.getLogger(ElectronicOrderTypeImpl.class);
@Override
public List<OrderTypeEnum> getEnums() {
return Arrays.asList(OrderTypeEnum.ELECTRONIC);
}
@Override
public Logger getLog() {
return logger;
}
}
package com.zrqx.order.commons.enums.interfaces.ordertype.impl;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.zrqx.core.constant.BaseConstant;
import com.zrqx.core.enums.order.OrderStatusEnum;
import com.zrqx.core.enums.order.OrderTypeEnum;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.form.order.fg.FgExpressCalculateForm;
import com.zrqx.core.form.order.fg.FgExpressCalculateFormQuery;
import com.zrqx.core.model.member.Member;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.model.order.OrderInfo;
import com.zrqx.core.model.resource.shoppingaddress.ShoppingAddress;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.core.vo.third.pay.payquery.PayQueryReturnVo;
import com.zrqx.order.commons.redis.FgRedisManage;
import com.zrqx.order.fg.client.FgShippingAddressClient;
/**
* 实体订单或混合订单逻辑
* @author lpf
* @date 2019年1月10日下午4:48:36
*/
@Component
public class EntityOrderTypeImpl extends OrderTypeAdapter{
private static final Logger logger = LoggerFactory.getLogger(EntityOrderTypeImpl.class);
@Autowired
private FgShippingAddressClient fgShippingAddressClient;
@Autowired
private FgRedisManage fgRedisManage;
@Override
public List<OrderTypeEnum> getEnums() {
return Arrays.asList(OrderTypeEnum.ENTITY, OrderTypeEnum.MIXED);
}
@Override
public Logger getLog() {
return logger;
}
@Override
public ShoppingAddress getShoppingAddress(Integer id) {
Member m = fgRedisManage.getMember();
Integer memberId = m.getId();
CallBack<ShoppingAddress> call = fgShippingAddressClient.getShippingAddress(id);
if (call.hasEntity()) {
return call.getData();
}
logger.error("EntityOrderTypeImpl#getShippingAddress("+ id +" , "+ memberId +") 实体订单获取收货地址失败" );
throw new BaseException("获取收货地址失败");
}
@Override
public void validateSotck(List<CreateOrderInfoForm> list) {
// TODO 库存调用 修改或验证库存锁定数
}
@Override
public BigDecimal calculateCarriage(List<OrderInfo> infoList, String province) {
FgExpressCalculateFormQuery form = this.getFgExpressCalculateFormQuery(infoList, province);
BigDecimal result = new BigDecimal(0);
// TODO 计算结算邮费
return result;
}
@Override
public BigDecimal calculateReaderCarriage(List<OrderInfo> infoList, String province) {
FgExpressCalculateFormQuery form = this.getFgExpressCalculateFormQuery(infoList, province);
BigDecimal result = new BigDecimal(0);
// TODO 计算用户邮费
return result;
}
private FgExpressCalculateFormQuery getFgExpressCalculateFormQuery(List<OrderInfo> infoList, String province) {
FgExpressCalculateFormQuery form = new FgExpressCalculateFormQuery();
form.setProvince(province);
logger.info("EntityOrderTypeImpl#getFgExpressCalculateFormQuery 生成邮费计算对象 form:" + form );
List<FgExpressCalculateForm> list = infoList.stream().map(v -> {
FgExpressCalculateForm f = new FgExpressCalculateForm();
f.setGoodsId(v.getGoodsid());
f.setGoodsType(v.getType());
f.setNum(v.getNum());
f.setSalePrice(v.getSalePrice());
return f;
}).collect(Collectors.toList());
form.setInfo(list);
return form;
}
/**
* 实体订单支付成功处理逻辑
* @param order
* @param payQueryReturnVo
* @return
* @author lpf
* @date: 2019年2月21日 上午11:57:14
*/
@Override
protected boolean paySuccessProcess(Order order, PayQueryReturnVo payQueryReturnVo) {
// 订单状态修改为已支付
return super.fgOrderManage.updateOrderStatusAndLogs(order,
OrderStatusEnum.HAVE_PAID, "订单支付", BaseConstant.SYSTEM_NAME);
}
}
package com.zrqx.order.commons.enums.interfaces.ordertype.impl;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import com.zrqx.core.enums.interfaces.LoggerFactory;
import com.zrqx.core.enums.order.OrderStatusEnum;
import com.zrqx.core.enums.order.OrderTypeEnum;
import com.zrqx.core.form.third.pay.PayResultForm;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.core.vo.third.pay.payquery.PayQueryReturnVo;
import com.zrqx.order.commons.enums.interfaces.ordertype.OrderTypeInterface;
import com.zrqx.order.fg.client.pay.FgPayClient;
import com.zrqx.order.fg.manage.FgOrderManage;
/**
* 订单公用逻辑
* @author lpf
* @date 2019年2月21日上午11:01:16
*/
public abstract class OrderTypeAdapter implements OrderTypeInterface, LoggerFactory{
/** 子类log */
protected Logger log;
@Autowired
protected FgPayClient fgPayClient;
@Autowired
protected FgOrderManage fgOrderManage;
public OrderTypeAdapter(){
this.log = getLog();
}
@Override
public boolean receivePayCall(Order order, PayResultForm form) {
CallBack<PayQueryReturnVo> result = fgPayClient.query(form.getOut_trade_no(), form.getPayType());
log.info("OrderTypeAdapter#receivePayCall查询第三方结果:" + result);
// 验证
if(result.hasEntity()){
PayQueryReturnVo payQueryReturnVo = result.getData();
if (payQueryReturnVo.getPaySuccess()) {
// 支付成功
String payMent = order.getPayment().doubleValue() + "";
if (!payQueryReturnVo.getPayment().equals(payMent)){
// TODO 支付金额和订单金额不一致 处理流程
log.warn("OrderTypeAdapter#receivePayCall 订单金额与支付金额不一致; order:"+ order + "; payQueryReturnVo : " + payQueryReturnVo);
}
// 判断订单状态 能否被修改
if (OrderStatusEnum.isCanPay(order.getStatus())) {
// 订单支付回调成功处理逻辑
return this.paySuccess(order, payQueryReturnVo);
}
log.warn("OrderTypeAdapter#receivePayCall 订单状态不能执行支付成功回调处理逻辑; order:" + order );
return false;
}
// 支付失败
log.warn("OrderTypeAdapter#receivePayCall支付回调,支付失败,payQueryReturnVo:" + payQueryReturnVo);
return false;
}
log.warn("OrderTypeAdapter#receivePayCall查询第三方失败,CallBack:" + result + ";form:" + form);
return false;
}
/**
* 订单支付成功处理逻辑
* @param order
* @param payQueryReturnVo
* @return
* @author lpf
* @date: 2019年2月25日 上午11:54:14
*/
public boolean paySuccess(Order order, PayQueryReturnVo payQueryReturnVo){
order.setPayType(payQueryReturnVo.getPayType());
order.setPayTime(payQueryReturnVo.getPayTime());
order.setPayCode(payQueryReturnVo.getPayCode());
return this.paySuccessProcess(order, payQueryReturnVo);
}
/**
* 订单支付成功处理逻辑
* @param order
* @param payQueryReturnVo
* @return
* @author lpf
* @date: 2019年2月21日 上午11:57:14
*/
protected abstract boolean paySuccessProcess(Order order, PayQueryReturnVo payQueryReturnVo);
}
package com.zrqx.order.commons.enums.interfaces.ordertype.impl;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.zrqx.core.enums.order.OrderTypeEnum;
/**
* 充值订单 逻辑
* @author lpf
* @date 2019年1月24日上午11:11:13
*/
@Component
public class TopUpOrderTypeImpl extends ElectronicOrderTypeAdapter{
private static final Logger logger = LoggerFactory.getLogger(TopUpOrderTypeImpl.class);
@Override
public List<OrderTypeEnum> getEnums() {
return Arrays.asList(OrderTypeEnum.TOPUP);
}
@Override
public Logger getLog() {
return logger;
}
}
package com.zrqx.order.commons.interceptor;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.zrqx.core.enums.ResponseCodeEnum;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.util.response.CallBack;
/**
*controller 异常处理
* @ClassName: CustomExceptionHandler
* @author 杨振广
* @date 2016-7-14 上午9:45:40
*
*/
@ControllerAdvice
public class CustomExceptionHandler {
private static Logger logger = LoggerFactory.getLogger(CustomExceptionHandler.class);
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public Object handlerException(HttpServletRequest request,HttpServletResponse response,Exception e){
e.printStackTrace();
StackTraceElement[] s = e.getStackTrace();
StringBuffer stes = new StringBuffer(s.length*2);
for (StackTraceElement stackTraceElement : s) {
stes.append(stackTraceElement.toString());
stes.append("<br/>");
}
String info = "异常时间:"+new Date().toLocaleString()+"\n请求地址:"+request.getRequestURI()+"\n参数:"+request.getQueryString()+"\n"+e.getMessage();
logger.error(info+"\n"+stes.toString());
request.setAttribute("error",info);
request.setAttribute("errorInfo",e.getStackTrace());
return CallBack.fail(e.getMessage());
}
/**
* 参数验证异常处理
* @Title: handlerException
* @Description:
* @param request
* @param response
* @param e BindException
* @return
* @author lpf
* @date: 2018年5月9日 下午5:01:58
*/
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public Object handlerException(HttpServletRequest request,HttpServletResponse response,BindException e) {
List<ObjectError> errors = e.getAllErrors();
StringBuffer msg = new StringBuffer();
for (ObjectError objectError : errors) {
msg.append(objectError.getDefaultMessage());
msg.append(",");
}
msg.deleteCharAt(msg.length()-1);
return CallBack.fail(msg.toString());
}
/**
* 执行异常处理
* @Description:
* @param e BaseException
* @return
* @date: 2018年5月9日 下午5:01:58
*
*/
@ExceptionHandler(BaseException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public Object myException(BaseException e) {
return CallBack.fail(ResponseCodeEnum.EXCEPTION, e.getMessage());
}
@ExceptionHandler(SQLException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public Object handlerException(SQLException e){
logger.error("数据库异常:"+e.getMessage());
return CallBack.fail();
}
}
\ No newline at end of file
package com.zrqx.order.commons.interceptor;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.RequestInterceptor;
import feign.RequestTemplate;
@Component
public class CustomRequestInterceptor implements RequestInterceptor {
@Autowired
private ObjectMapper objectMapper;
@Override
public void apply(RequestTemplate template) {
// feign 不支持 GET 方法传 POJO, json body转query
if (template.method().equals("GET") && template.body() != null) {
try {
JsonNode jsonNode = objectMapper.readTree(template.body());
template.body(null);
Map<String, Collection<String>> queries = new HashMap<>();
buildQuery(jsonNode, "", queries);
template.queries(queries);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void buildQuery(JsonNode jsonNode, String path, Map<String, Collection<String>> queries) {
if (!jsonNode.isContainerNode()) { // 叶子节点
if (jsonNode.isNull()) {
return;
}
Collection<String> values = queries.get(path);
if (null == values) {
values = new ArrayList<>();
queries.put(path, values);
}
values.add(jsonNode.asText());
return;
}
if (jsonNode.isArray()) { // 数组节点
Iterator<JsonNode> it = jsonNode.elements();
while (it.hasNext()) {
buildQuery(it.next(), path, queries);
}
} else {
Iterator<Map.Entry<String, JsonNode>> it = jsonNode.fields();
while (it.hasNext()) {
Map.Entry<String, JsonNode> entry = it.next();
if (StringUtils.hasText(path)) {
buildQuery(entry.getValue(), path + "." + entry.getKey(), queries);
} else { // 根节点
buildQuery(entry.getValue(), entry.getKey(), queries);
}
}
}
}
}
package com.zrqx.order.commons.interceptor;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* Feign配置
* 使用FeignClient进行服务间调用,传递headers信息
* @author lw
* @date 2018年10月17日下午2:48:44
*/
@Component
@Configuration
public class FeignHeaderInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
// 前台token
if(request.getHeader("Y-Token") != null){
requestTemplate.header("Y-Token", request.getHeader("Y-Token"));
}
// 后台token
if(request.getHeader("X-Token") != null){
requestTemplate.header("X-Token", request.getHeader("X-Token"));
}
}
}
}
package com.zrqx.order.commons.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class InterceptorConfig implements HandlerInterceptor{
private static final Logger logger = LoggerFactory.getLogger(InterceptorConfig.class);
/**
* 进入controller层之前拦截请求
* @param httpServletRequest
* @param httpServletResponse
* @param o
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
HttpSession session = httpServletRequest.getSession();
if(session.getAttribute("user") != null){
return true;
}
else{
return true;
}
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
logger.info("--------------处理请求完成后视图渲染之前的处理操作---------------");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
logger.info("---------------视图渲染之后的操作--------------------------");
}
}
\ No newline at end of file
package com.zrqx.order.commons.lcn;
/**
* create by lorne on 2017/11/18
*/
//@Service
public class TxManagerHttpRequestServiceImpl {/*implements TxManagerHttpRequestService{
@Override
public String httpGet(String url) {
String res = HttpUtils.get(url);
return res;
}
@Override
public String httpPost(String url, String params) {
String res = HttpUtils.post(url,params);
return res;
}*/
}
package com.zrqx.order.commons.lcn;
/**
* create by lorne on 2017/11/18
*/
//@Service
public class TxManagerTxUrlServiceImpl{ /*implements TxManagerTxUrlService{
@Value("${tm.manager.url}")
private String url;
@Override
public String getTxUrl() {
return url;
}*/
}
package com.zrqx.order.commons.quartz;
import java.util.List;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.zrqx.core.constant.BaseConstant;
import com.zrqx.core.enums.order.OrderStatusEnum;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.model.order.Order;
import com.zrqx.order.fg.service.FgOrderService;
@Component
public class OrderCheckPay {
private static final Logger log = Logger.getLogger(OrderCheckPay.class);
@Autowired
FgOrderService orderService;
@Value("${order-quartz}")
private Boolean offon;
/**
* 检查订单是不是已经支付了
*
* @author ydm
* @date: 2018年10月17日 下午3:56:56
*/
@Scheduled(cron="0 0/5 * * * ? ")
public void task01(){
if(offon){
log.info("定时任务1:检查订单是不是已经支付了");
List<Order> list = orderService.queryAllWaitPay();
log.info("定时任务1:检查订单是不是已经支付了:待支付订单列表:"+JSON.toJSONString(list));
for(Order o : list){
try {
orderService.checkIsPaid(o.getId());
} catch (BaseException e) {
log.warn(e.getMessage(), e);
}
}
}
}
/**
* 将所有未支付的并且已经超时的订单修改状态为已取消
*
* @author ydm
* @date: 2018年10月17日 下午3:57:13
*/
@Scheduled(cron="0 0 0/1 * * ? ")
public void task02(){
if(offon){
log.info("定时任务2:将所有未支付的并且已经超时的订单修改状态为已取消");
List<Order> list = orderService.queryAllWaitPayAndTimeout();
log.info("定时任务2:将所有未支付的并且已经超时的订单修改状态为已取消:当日未支付且超时的订单列表:"+JSON.toJSONString(list));
for(Order o : list){
orderService.updateStatus(o, OrderStatusEnum.CANCELLED, "用户取消订单", BaseConstant.SYSTEM_NAME);
}
}
}
}
\ No newline at end of file
package com.zrqx.order.commons.redis;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.zrqx.core.enums.ResponseCodeEnum;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.model.member.Member;
@Component
public class FgRedisManage extends RedisAdapter{
private static final Logger logger = LoggerFactory.getLogger(FgRedisManage.class);
@Override
public String getOpName() {
Member m = this.getMember();
return m.getAccount();
}
@Override
public String getOpId() {
Member m = this.getMember();
return m.getId() + "";
}
@Override
public String tokenKey() {
return "y-token";
}
public Member getMember(){
try {
return super.get(Member.class);
} catch (Exception e) {
/*Member m = new Member();
m.setId(1);
m.setAccount("admin");
return m;*/
throw new BaseException(ResponseCodeEnum.NO_LOGIN);
}
}
}
package com.zrqx.order.commons.redis;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson.JSON;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.exception.BusinessValidateException;
public abstract class RedisAdapter implements RedisInterface{
@Autowired
StringRedisTemplate stringRedisTemplate;
@Override
public StringRedisTemplate getRedisTemplate() {
return stringRedisTemplate;
}
@Override
public <T> T get(Class<T> clazz) {
String token = getToken();
if(token != null){
return get(token, clazz);
}
throw new BusinessValidateException("RedisAdapter#get请登录后进行此操作");
}
@Override
public <T> T get(String key, Class<T> clazz) {
try {
String userInfo = stringRedisTemplate.opsForValue().get(key);
return JSON.parseObject(userInfo, clazz);
} catch (Exception e) {
throw new BaseException(e.getMessage());
}
}
@Override
public String getToken() {
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String key = (String) headerNames.nextElement();
if(key.toLowerCase().equals(tokenKey())){
String token=request.getHeader(key);
return token;
}
}
return null;
}
}
package com.zrqx.order.commons.redis;
import org.springframework.data.redis.core.StringRedisTemplate;
/**
* reids接口
* @author lpf
* @date 2019年1月14日上午10:49:43
*/
public interface RedisInterface {
/**
* 获取reids模板
* @return
* @author lpf
* @date: 2019年1月14日 上午10:59:59
*/
StringRedisTemplate getRedisTemplate();
/**
* 获取操作人名称
* @return
* @author lpf
* @date: 2019年1月14日 上午11:00:11
*/
String getOpName();
/**
* 获取操作人id
* @return
* @author lpf
* @date: 2019年1月14日 上午11:00:45
*/
String getOpId();
/**
* 获取token
* @return
* @author lpf
* @date: 2019年1月14日 上午11:01:47
*/
String getToken();
/**
* token的 key
* @return
* @author lpf
* @date: 2019年1月14日 上午11:02:25
*/
String tokenKey();
/**
* 根据key获取 T对象
* @param key
* @param clazz
* @return
* @author lpf
* @date: 2019年1月14日 上午11:04:12
*/
<T> T get(String key, Class<T> clazz);
/**
* 根据token获取指定类
* @param clazz
* @return
* @author lpf
* @date: 2019年1月14日 上午11:07:38
*/
<T> T get(Class<T> clazz);
}
package com.zrqx.order.commons.redis;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.zrqx.core.model.sysuser.user.User;
@Component
public class RedisManage extends RedisAdapter {
private static final Logger logger = LoggerFactory.getLogger(RedisManage.class);
@Override
public String getOpName() {
User u = get(User.class);
return u.getName();
}
@Override
public String getOpId() {
User u = get(User.class);
return u.getUserId();
}
@Override
public String tokenKey() {
return "x-token";
}
}
package com.zrqx.order.commons.utils;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.function.Consumer;
import com.zrqx.core.util.datatype.StringUtil;
/**
* 单号生成工具类
* @author lpf
* @date 2019年1月11日下午2:30:19
*/
public class CodeUtils {
/** 是否为测试环境,spring加载完成后进行装载 */
public static boolean TEST_ENVIRONMENT = true;
/**
* 订单生成规则
* @return
* @author lpf
* @date: 2019年1月11日 下午2:42:35
*/
public static String createOrderCode(){
return initRandomOrderCode(b -> b.append("O"), b -> {});
}
/**
* 充值订单生成规则
* @return
* @author lpf
* @date: 2019年2月20日 下午5:21:48
*/
public static String createTopupOrderCode(){
return initRandomOrderCode(b -> b.append("O"), b -> b.append("C"));
}
/**
* 基础生成编码规则
* 测试环境: ZRQX + 2随机字母 + yyyyMMddHHmmssSSSS
* 生产环境: 2随机字母 + yyyyMMddHHmmssSSSS
* @return
* @author ydm
* @date: 2018年8月13日 下午2:31:44
*/
public static String initRandomOrderCode(Consumer<StringBuffer> before, Consumer<StringBuffer> after) {
StringBuffer result = new StringBuffer();
if (TEST_ENVIRONMENT) {
result.append("ZRQX");
}
before.accept(result);
result.append(StringUtil.getRandomEnSign(1,2,0));
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSSS");
result.append(sdf.format(new Date()));
after.accept(result);
return result.toString();
}
}
package com.zrqx.order.commons.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.zrqx.core.util.spring.BaseSpringContextUtils;
@Component
public class SpringContextUtils extends BaseSpringContextUtils {
private static final Logger logger = LoggerFactory.getLogger(SpringContextUtils.class);
@Value("${test-environment}")
private Boolean testEnvironment;
/**
* 初始化操作
* @author lpf
* @date: 2019年1月3日 上午9:17:01
*/
public void init(){
// 单号生成采用的环境
CodeUtils.TEST_ENVIRONMENT = testEnvironment;
}
@Override
public Logger getLog() {
return SpringContextUtils.logger;
}
}
package com.zrqx.order.fg.client;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import com.zrqx.core.constant.sysuser.SysUserRequestPath;
import com.zrqx.core.form.order.fg.FgSaveOrderInfoCommentForm;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.order.fg.client.hystric.FgCommentClientHystric;
@FeignClient(name = "sysuser", fallback = FgCommentClientHystric.class)
public interface FgCommentClient {
/**
* 批量保存商品 评论
* @param form
* @return
* @author lpf
* @date: 2019年1月28日 下午5:13:59
*/
@PostMapping(SysUserRequestPath.FG + SysUserRequestPath.COMMENT + SysUserRequestPath.BATCH_SAVE)
CallBack<?> saveComments(List<FgSaveOrderInfoCommentForm> form);
}
package com.zrqx.order.fg.client;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import com.zrqx.core.constant.BaseRequestPath;
import com.zrqx.core.constant.resource.ResourceRequestPath;
import com.zrqx.core.model.order.OrderInfo;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.core.vo.order.fg.GoodsBuyVo;
import com.zrqx.order.fg.client.hystric.FgGoodsClientHystric;
@FeignClient(name = "resource", fallback = FgGoodsClientHystric.class , path = ResourceRequestPath.FG + ResourceRequestPath.RESOURCE)
public interface FgGoodsClient {
/**
* 根据商品id和商品类型 获取OrderInfo对象
* @param id
* @param goodsType
* @return
* @author lpf
* @date: 2019年1月10日 下午3:03:07
*/
@GetMapping(ResourceRequestPath.GET + ResourceRequestPath.INFO)
CallBack<OrderInfo> queryOrderInfo(@RequestParam(BaseRequestPath.IDSTRING)String id, @RequestParam("goodsType")String goodsType);
/**
* 根据购买信息 增加商品销量
* @param list
* @return
* @author lpf
* @date: 2019年1月14日 上午10:23:13
*/
@PostMapping(ResourceRequestPath.ADD_SALES)
CallBack<Integer> updateGoodsSales(@RequestBody List<OrderInfo> list);
/**
* 根据商品id和商品类型获取商品详细信息vo
* @param id
* @param goodsType
* @return
* @author lpf
* @date: 2019年2月13日 下午4:18:35
*/
@GetMapping(ResourceRequestPath.GET + ResourceRequestPath.BUY)
CallBack<GoodsBuyVo> queryGoodsBuyVo(@RequestParam(BaseRequestPath.IDSTRING)String id, @RequestParam("goodsType")String goodsType);
}
package com.zrqx.order.fg.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import com.zrqx.core.constant.resource.ResourceRequestPath;
import com.zrqx.core.model.resource.shoppingaddress.ShoppingAddress;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.order.fg.client.hystric.FgShippingAddressClientHystric;
@FeignClient(name = "resource", fallback = FgShippingAddressClientHystric.class)
public interface FgShippingAddressClient {
/**
* 根据收货地址id
* @param id 收货地址id
* @return
* @author lpf
* @date: 2019年1月10日 下午4:56:10
*/
// TODO 未实现
@GetMapping(ResourceRequestPath.FG + ResourceRequestPath.SHOPPING_ADDRESS + ResourceRequestPath.GET_OID)
CallBack<ShoppingAddress> getShippingAddress(@PathVariable(ResourceRequestPath.OBJECTID)Integer oid);
}
package com.zrqx.order.fg.client;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import com.zrqx.core.constant.resource.ResourceRequestPath;
import com.zrqx.core.constant.sysuser.SysUserRequestPath;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.order.fg.client.hystric.FgShopcartClientHystric;
@FeignClient(name="resource",fallback=FgShopcartClientHystric.class)
public interface FgShopcartClient {
/**
* 根据ids删除购物车
* @param ids
* @return
* @author lpf
* @date: 2019年1月14日 下午12:00:22
*/
@PostMapping(ResourceRequestPath.FG + ResourceRequestPath.SHOPPING_CART + ResourceRequestPath.BATCH_DELETE)
CallBack<?> deleteByIds(@RequestBody Integer[] ids);
/**
* 根据ids 查询CreateOrderInfoForm 对象
* @param ids
* @return
* @author lpf
* @date: 2019年1月14日 下午3:07:42
*/
@PostMapping(ResourceRequestPath.FG + ResourceRequestPath.SHOPPING_CART + ResourceRequestPath.LIST_ORDER_INFO_FORM)
CallBack<List<CreateOrderInfoForm>> queryByIds(@RequestBody Integer[] ids);
}
package com.zrqx.order.fg.client.hystric;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.zrqx.core.form.order.fg.FgSaveOrderInfoCommentForm;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.order.fg.client.FgCommentClient;
@Component
public class FgCommentClientHystric implements FgCommentClient{
private static final Logger logger = LoggerFactory.getLogger(FgCommentClientHystric.class);
@Override
public CallBack<?> saveComments(List<FgSaveOrderInfoCommentForm> form) {
logger.error("批量保存商品评论失败,form:" + form);
return CallBack.fail();
}
}
package com.zrqx.order.fg.client.hystric;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.zrqx.core.model.order.OrderInfo;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.core.vo.order.fg.GoodsBuyVo;
import com.zrqx.order.fg.client.FgGoodsClient;
@Component
public class FgGoodsClientHystric implements FgGoodsClient{
private static final Logger logger = LoggerFactory.getLogger(FgGoodsClientHystric.class);
@Override
public CallBack<OrderInfo> queryOrderInfo(String id, String goodsType) {
logger.warn("FgGoodsClientHystric#queryOrderInfo fail");
return CallBack.fail();
}
@Override
public CallBack<Integer> updateGoodsSales(List<OrderInfo> list) {
logger.warn("FgGoodsClientHystric#updateGoodsSales fail");
return CallBack.fail();
}
@Override
public CallBack<GoodsBuyVo> queryGoodsBuyVo(String id, String goodsType) {
logger.warn("FgGoodsClientHystric#queryGoodsBuyVo fail");
return CallBack.fail();
}
}
package com.zrqx.order.fg.client.hystric;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.zrqx.core.model.resource.shoppingaddress.ShoppingAddress;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.order.fg.client.FgShippingAddressClient;
@Component
public class FgShippingAddressClientHystric implements FgShippingAddressClient{
private static final Logger logger = LoggerFactory.getLogger(FgShippingAddressClientHystric.class);
@Override
public CallBack<ShoppingAddress> getShippingAddress(Integer id) {
logger.warn("FgShippingAddressClientHystric#getShippingAddress 用户id:"+ ",收货地址id:"+id + ";获取收货地失败");
return CallBack.fail();
}
}
package com.zrqx.order.fg.client.hystric;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.order.fg.client.FgShopcartClient;
@Component
public class FgShopcartClientHystric implements FgShopcartClient{
private static final Logger logger = LoggerFactory.getLogger(FgShopcartClientHystric.class);
@Override
public CallBack<?> deleteByIds(Integer[] ids) {
logger.info("删除购物车失败");
return CallBack.fail();
}
@Override
public CallBack<List<CreateOrderInfoForm>> queryByIds(Integer [] ids) {
logger.warn("查询购物车失败ids:"+ids);
return CallBack.fail();
}
}
package com.zrqx.order.fg.client.pay;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.zrqx.core.constant.pay.PayRequestPath;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.core.vo.pay.PayInfoVo;
import com.zrqx.core.vo.third.pay.payquery.PayQueryReturnVo;
@FeignClient(name = "pay", fallback = FgPayClientHystrix.class)
public interface FgPayClient {
/**
* 支付(获取支付页面或二维码url)
* @param orderCode 订单编号
* @param payType 支付类型
* @return
* @author lw
* @date: 2019年2月20日 下午5:29:08
*/
@GetMapping(PayRequestPath.FG + PayRequestPath.PAY + PayRequestPath.PAY)
public CallBack<PayInfoVo> pay(@RequestParam("orderCode") String orderCode,
@RequestParam("payType") String payType);
/**
* 支付查询
* @param out_trade_no 店铺订单号
* @param payType 支付类型
* @return
* @author lw
* @date: 2019年1月22日 上午10:57:49
*/
@GetMapping(PayRequestPath.FG + PayRequestPath.PAY + PayRequestPath.QUERY_PAY_INFO)
CallBack<PayQueryReturnVo> query(@RequestParam("orderCode") String orderCode,@RequestParam("payType") String payType);
}
package com.zrqx.order.fg.client.pay;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.core.vo.pay.PayInfoVo;
import com.zrqx.core.vo.third.pay.payquery.PayQueryReturnVo;
@Component
public class FgPayClientHystrix implements FgPayClient {
private static final Logger logger = LoggerFactory.getLogger(FgPayClientHystrix.class);
@Override
public CallBack<PayQueryReturnVo> query(String out_trade_no, String payType) {
logger.info("FgPayClientHystrix#query调用聚合支付服务支付查询失败");
return null;
}
@Override
public CallBack<PayInfoVo> pay(String orderCode, String payType) {
logger.info("FgPayClientHystrix#getPayUrl调用聚合支付服务获取支付url失败");
return CallBack.fail();
}
}
package com.zrqx.order.fg.client.third;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import com.zrqx.core.constant.third.ThirdRequestPath;
import com.zrqx.core.form.third.baiwang.BaiwangDownloadForm;
import com.zrqx.core.form.third.baiwang.BaiwangForm;
import com.zrqx.core.form.third.pay.ToPayForm;
import com.zrqx.core.model.third.baiwang.BaiwangDownloadReturn;
import com.zrqx.core.model.third.baiwang.BaiwangPayReturn;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.core.vo.third.pay.payquery.PayQueryReturnVo;
@FeignClient(name = "third", fallback = FgThirdClientHystrix.class)
public interface FgThirdClient {
/**
* 支付查询
* @param out_trade_no 店铺订单号
* @param payType 支付类型
* @return
* @author lw
* @date: 2019年1月22日 上午10:57:49
*/
@GetMapping("/third/pay/query")
CallBack<PayQueryReturnVo> query(@RequestParam("out_trade_no") String out_trade_no,@RequestParam("payType") String payType);
/**
* 去支付(获取支付页面或二维码url)
* @param toPayForm
* @return
* @author lw
* @date: 2019年1月22日 上午11:00:46
*/
@PostMapping("/third/pay/to_pay")
public CallBack<String> getPayUrl(ToPayForm toPayForm);
@ApiOperation(value = "开发票和对冲发票", notes = "开发票和对冲发票")
@PostMapping(ThirdRequestPath.BAIWANG+ThirdRequestPath.PAY)
public CallBack<BaiwangPayReturn> pay(@RequestBody BaiwangForm baiwang);
@ApiOperation(value = "下载发票", notes = "下载发票")
@GetMapping(ThirdRequestPath.BAIWANG+ThirdRequestPath.DOWNLOAD)
public CallBack<BaiwangDownloadReturn> download(BaiwangDownloadForm baiwangDownloadForm);
}
package com.zrqx.order.fg.client.third;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.zrqx.core.form.third.baiwang.BaiwangDownloadForm;
import com.zrqx.core.form.third.baiwang.BaiwangForm;
import com.zrqx.core.form.third.pay.ToPayForm;
import com.zrqx.core.model.third.baiwang.BaiwangDownloadReturn;
import com.zrqx.core.model.third.baiwang.BaiwangPayReturn;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.core.vo.third.pay.payquery.PayQueryReturnVo;
@Component
public class FgThirdClientHystrix implements FgThirdClient{
private static final Logger logger = LoggerFactory.getLogger(FgThirdClientHystrix.class);
@Override
public CallBack<PayQueryReturnVo> query(String out_trade_no, String payType) {
logger.info("调用三方服务支付查询失败");
return null;
}
@Override
public CallBack<String> getPayUrl(ToPayForm toPayForm) {
logger.info("调用三方服务获取支付url失败");
return null;
}
@Override
public CallBack<BaiwangPayReturn> pay(BaiwangForm baiwang) {
logger.info("FgThirdClientHystrix#pay开发票失败");
return CallBack.fail();
}
@Override
public CallBack<BaiwangDownloadReturn> download(BaiwangDownloadForm baiwangDownloadForm) {
logger.info("FgThirdClientHystrix#download下载发票失败");
return CallBack.fail();
}
}
package com.zrqx.order.fg.controller;
import java.util.List;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.github.pagehelper.PageHelper;
import com.zrqx.core.constant.order.OrderRequestPath;
import com.zrqx.core.enums.order.OrderInvoiceStatusEnum;
import com.zrqx.core.exception.BusinessValidateException;
import com.zrqx.core.form.order.fg.FgSaveOrderInvoiceForm;
import com.zrqx.core.model.order.Invoice;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.util.bean.BeanUtils;
import com.zrqx.core.util.datatype.DateUtils;
import com.zrqx.core.util.page.PageInfo;
import com.zrqx.core.util.page.PageParam;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.core.vo.order.fg.FgInvoiceOrderPageVo;
import com.zrqx.core.vo.order.fg.FgInvoiceVo;
import com.zrqx.order.commons.redis.FgRedisManage;
import com.zrqx.order.fg.service.FgInvoiceService;
import com.zrqx.order.fg.service.FgOrderService;
@RestController
@RequestMapping(OrderRequestPath.FG+OrderRequestPath.INVOICE)
@Api(description = "前台发票管理")
public class FgInvoiceController {
@Autowired
private FgOrderService fgOrderService;
@Autowired
private FgInvoiceService fgInvoiceService;
@Autowired
private FgRedisManage fgRedisManage;
@ApiOperation("个人中心-我的发票-发票列表")
@GetMapping(OrderRequestPath.PAGE)
public CallBack<PageInfo<FgInvoiceOrderPageVo>> page(PageParam pageParam){
// 查询可以开票的订单
// 订单状态 : 已支付 已完成 当前登录用户
// 排序方式 : 订单创建时间倒序
// 需求: 用户下单未开发票时可通过我的发票功能进行补开发票,增值税普通发票订单完成后1年内可补开发票,
if (StringUtils.isBlank(pageParam.getOrderBy())) {
pageParam.setOrderBy("createTime desc");
}
return CallBack.success(fgOrderService.pageInvoiceOrder(pageParam));
}
@ApiOperation("发票详情")
@GetMapping(OrderRequestPath.OID)
public CallBack<List<FgInvoiceVo>> get(@ApiParam(value = "订单id", required = true)@PathVariable Integer oid){
//TODO 待调试
// 获取订单的发票详情
// 1. 已开票的 订单
// 2. 开票记录中的 发票代码和发票号码
if (oid == null) {
throw new BusinessValidateException("订单id不能为空");
}
Order o = fgOrderService.notNull(oid);
if (OrderInvoiceStatusEnum.SUCCESS.getCode().equals(o.getInvoiceStatus())) {
Invoice record = new Invoice();
record.setOrderId(oid);
List<Invoice> list = fgInvoiceService.select(record);
List<FgInvoiceVo> result = BeanUtils.copyList(list, FgInvoiceVo.class);
return CallBack.success(result);
}
throw new BusinessValidateException(o.getCode() + "订单未完成开票");
}
@ApiOperation("申请开票-回显")
@GetMapping(OrderRequestPath.INFO)
public CallBack<FgInvoiceVo> info(@ApiParam(value = "订单id", required = true) @RequestParam(name = "id") Integer id){
// 获取订单的发票详情
// 1. 已开票的 订单
if (id == null) {
throw new BusinessValidateException("订单id不能为空");
}
Order o = fgOrderService.notNull(id);
FgInvoiceVo vo = new FgInvoiceVo();
BeanUtils.copyProperties(o, vo);
vo.setOrderId(o.getId());
vo.setOrderCode(o.getCode());
return CallBack.success(vo);
}
@ApiOperation("申请开票-保存发票信息并开票")
@PostMapping(OrderRequestPath.SAVE_OPEN)
public CallBack<FgInvoiceVo> saveAndOpen(@RequestBody FgSaveOrderInvoiceForm form){
// TODO 待调试
// 0. 验证订单是否在一年内 未开票
// 1. 根据当前登录用户和订单id 修改订单发票信息,更新修改时间
// 2. 对接第三方开具发票 ,保存开票记录
// 3. (TODO 未实现)第三方开票失败 则保存错误原因,(已实现)第三方开票成功 则 修改订单为已开票
// 4. 返回开票的信息
// TODO 需要确认的问题,1. 保存并开票 是否直接提供给用户下载? 2. 开票的地方还有其他接口吗(订单完成时是否需要开票?)
Order o = fgOrderService.notNull(form.getId());
boolean bl = DateUtils.isWithin(o.getCreateTime(), 12);
if (!bl) {
throw new BusinessValidateException("订单id:"+ form.getId() + ",不在一年内,无法开票");
}
if (!OrderInvoiceStatusEnum.isCanMake(o.getInvoiceStatus())) {
throw new BusinessValidateException("订单id:"+ form.getId() + ",开票状态:" + o.getInvoiceStatus() + ";不符合开票状态");
}
// 根据当前登录用户和订单id 修改订单发票信息,更新修改时间
fgOrderService.saveInvoice(form);
return CallBack.success(fgInvoiceService.saveAndOpen(form.getId()));
}
@ApiOperation(value = "上次开票信息")
@PostMapping(OrderRequestPath.LAST_INVOICE)
public CallBack<FgInvoiceVo> lastInvoice(){
// 查询最近一次成功开票的发票信息
Invoice invoice = new Invoice();
invoice.setOrderCreater(fgRedisManage.getMember().getId());
PageHelper.orderBy("createTime desc");
Invoice one = fgInvoiceService.selectOne(invoice);
FgInvoiceVo vo = new FgInvoiceVo();
if(one != null){
vo = BeanUtils.copy(one, FgInvoiceVo.class);
}
return CallBack.success(vo);
}
}
package com.zrqx.order.fg.manage;
import java.util.List;
import com.zrqx.core.form.GoodsForm;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.model.order.OrderInfo;
import com.zrqx.core.vo.order.fg.FgOrderInfoPageVo;
public interface FgOrderInfoManage {
/**
* 保存订单详情
* @param infoList 订单详情列表
* @param o 订单
* @return
* @author lpf
* @date: 2019年1月11日 下午4:10:49
*/
boolean save(List<OrderInfo> infoList, Order o);
/**
* 根据订单id查询订单详情列表
* @param id
* @return
* @author lpf
* @date: 2019年1月28日 下午3:23:47
*/
List<OrderInfo> selectByOrderId(Integer id);
/**
* 根据订单id查询订单详情vo列表
* @param id
* @return
* @author lpf
* @date: 2019年1月28日 下午3:59:46
*/
List<FgOrderInfoPageVo> listByOrderId(Integer id);
/**
* 根据订单详情id 查询商品对象的联合主键
* @param id
* @return
* @author lpf
* @date: 2019年1月28日 下午5:05:29
*/
GoodsForm get(Integer id);
/**
* 根据订单详情id查询不为空的订单详情对象
* @param id
* @return
* @author lpf
* @date: 2019年1月28日 下午5:06:38
*/
OrderInfo notNull(Integer id);
}
package com.zrqx.order.fg.manage;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.zrqx.core.exception.BusinessValidateException;
import com.zrqx.core.form.GoodsForm;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.model.order.OrderInfo;
import com.zrqx.core.util.bean.BeanUtils;
import com.zrqx.core.vo.order.fg.FgOrderInfoPageVo;
import com.zrqx.order.fg.mapper.FgOrderInfoMapper;
@Component
public class FgOrderInfoManageImpl implements FgOrderInfoManage{
private static final Logger logger = LoggerFactory.getLogger(FgOrderInfoManageImpl.class);
@Autowired
private FgOrderInfoMapper fgOrderInfoMapper;
@Override
public boolean save(List<OrderInfo> infoList, Order o) {
infoList.forEach(info -> {
info.setOrderid(o.getId());
info.setOrderCode(o.getCode());
});
logger.debug("保存订单详情,infoList:" + infoList);
return fgOrderInfoMapper.insertList(infoList) == infoList.size();
}
@Override
public List<OrderInfo> selectByOrderId(Integer id) {
OrderInfo example = new OrderInfo();
example.setOrderid(id);
List<OrderInfo> infoList = fgOrderInfoMapper.select(example);
return infoList;
}
@Override
public List<FgOrderInfoPageVo> listByOrderId(Integer id) {
List<OrderInfo> infoList = this.selectByOrderId(id);
List<FgOrderInfoPageVo> infoVoList = BeanUtils.copyList(infoList, FgOrderInfoPageVo.class);
return infoVoList;
}
@Override
public GoodsForm get(Integer id) {
OrderInfo info = this.notNull(id);
GoodsForm goodsForm = new GoodsForm();
goodsForm.setId(info.getGoodsid());
goodsForm.setType(info.getType());
return goodsForm;
}
@Override
public OrderInfo notNull(Integer id) {
OrderInfo info = fgOrderInfoMapper.selectByPrimaryKey(id);
if (info == null) {
throw new BusinessValidateException("id:"+ id +",找不到订单详情对象");
}
return info;
}
}
package com.zrqx.order.fg.manage;
import com.zrqx.core.enums.order.OrderStatusEnum;
import com.zrqx.core.model.order.Order;
/**
* 订单manage
* @author lpf
* @date 2019年1月11日下午2:48:50
*/
public interface FgOrderManage {
/**
* 前台保存订单方法
* @param order
* @return
* @author lpf
* @date: 2019年1月11日 下午2:49:10
*/
boolean save(Order order);
/**
* 前台修改订单方法
* @param order 要保存的订单信息
* @param log 订单日志
* @return
* @author lpf
* @date: 2019年2月19日 下午12:01:31
*/
boolean update(Order order, String log);
/**
* 修改订单状态
* @param order 订单
* @param enu 要修改为的状态
* @return
* @author lw
* @date: 2019年1月21日 下午2:58:22
*/
boolean updateOrderStatus(Order order, OrderStatusEnum enu);
/**
* 修改订单状态并保存修改记录
* @param order 订单
* @param enu 要修改为的状态
* @param content 内容/为空将取默认(订单状态变更为:)不为空将加入在默认前
* @param operator 不为空时将默认为系统操作,为空时去redis用户
* @return
* @author lw
* @date: 2019年1月21日 下午3:32:01
*/
boolean updateOrderStatusAndLogs(Order order, OrderStatusEnum enu, String content, String operator);
/**
* 根据订单id查找订单
* @param id 订单id
* @return
* @author lpf
* @date: 2019年2月19日 下午2:39:59
*/
Order notNull(Integer id);
}
package com.zrqx.order.fg.manage;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.zrqx.core.enums.order.OrderStatusEnum;
import com.zrqx.core.exception.BusinessValidateException;
import com.zrqx.core.model.order.Order;
import com.zrqx.order.commons.redis.FgRedisManage;
import com.zrqx.order.fg.mapper.FgOrderMapper;
@Component
public class FgOrderManageImpl implements FgOrderManage{
private static final Logger logger = LoggerFactory.getLogger(FgOrderManageImpl.class);
@Autowired
private FgOrderMapper fgOrderMapper;
@Autowired
private FgOrderStatusLogManage fgOrderStatusLogManage;
@Autowired
private FgRedisManage fgRedisManage;
/**
* 1. 保存订单
* 2. 保存订单操作日志
* @see com.zrqx.order.fg.manage.FgOrderManage#save(com.zrqx.core.model.order.Order)
* @param order
* @return
* @author lpf
* @date: 2019年1月11日 下午2:51:25
*/
@Override
public boolean save(Order order) {
logger.info("保存订单Order:" + order);
boolean orderFlag = fgOrderMapper.insertSelective(order) > 0;
fgOrderStatusLogManage.save(order.getId(), OrderStatusEnum.WAIT_PAY, "创建订单",null);
return orderFlag;
}
/**
* 修改订单状态
* @see com.zrqx.order.fg.manage.FgOrderManage#updateOrderStatus(com.zrqx.core.enums.order.OrderStatusEnum)
* @param enu 要修改为的状态
* @param enu
* @return
* @author lw
* @date: 2019年1月21日 下午2:56:34
*/
@Override
public boolean updateOrderStatus(Order order, OrderStatusEnum enu) {
order.setStatus(enu.getCode());
try {
order.setUpdater(fgRedisManage.getOpId());
order.setUpdaterName(fgRedisManage.getOpName());
} catch (Exception e) {
order.setUpdater("1");
order.setUpdaterName("system-quartz");
}
order.setUpdateTime(new Date());
boolean isUpdate = fgOrderMapper.updateByPrimaryKeySelective(order) > 0;
return isUpdate;
}
/**
* 修改订单状态并保存修改记录
* @see com.zrqx.order.fg.manage.FgOrderManage#updateOrderStatusAndLogs(com.zrqx.core.enums.order.OrderStatusEnum)
* @param order 订单
* @param enu 要修改为的状态
* @param content 内容/为空将取默认(订单状态变更为:)不为空将加入在默认前
* @param operator 不为空时将默认为系统操作,为空时去redis用户
* @return
* @author lw
* @date: 2019年1月21日 下午2:56:37
*/
@Override
public boolean updateOrderStatusAndLogs(Order order, OrderStatusEnum enu, String content, String operator) {
boolean isUpdate = this.updateOrderStatus(order, enu);
// 写入订单操作日志表
boolean isInsert = fgOrderStatusLogManage.save(order.getId(), enu, content, operator);
return isUpdate && isInsert;
}
/**
* 前台修改订单方法
* @param order 要保存的订单信息
* @param log 订单日志
* @return
* @author lpf
* @date: 2019年2月19日 下午12:01:31
*/
@Override
public boolean update(Order order, String log) {
order.setUpdateTime(new Date());
order.setUpdater(fgRedisManage.getOpId());
order.setUpdaterName(fgRedisManage.getOpName());
boolean isUpdate = fgOrderMapper.updateByPrimaryKeySelective(order) > 0;
boolean isInsert = fgOrderStatusLogManage.save(order.getId(), log, null);
return isUpdate && isInsert;
}
/**
* 根据订单id查找订单
* @param id 订单id
* @return
* @author lpf
* @date: 2019年2月19日 下午2:39:59
*/
@Override
public Order notNull(Integer id) {
Order o = fgOrderMapper.selectByPrimaryKey(id);
if (o == null) {
throw new BusinessValidateException("id:"+ id + ",订单不存在");
}
return o;
}
}
package com.zrqx.order.fg.manage;
import com.zrqx.core.enums.order.OrderStatusEnum;
/**
* 订单状态日志manage
* @author lpf
* @date 2019年1月11日下午3:33:52
*/
public interface FgOrderStatusLogManage {
/**
* 保存订单状态变更日志
* @param oid 订单id
* @param enu 修改为的状态
* @param content 内容/为空将取默认(订单状态变更为:)不为空将加入在默认前
* @param operator 不为空时将默认为系统操作,为空时去redis用户
* @return
* @author lw
* @date: 2019年1月21日 下午3:14:35
*/
boolean save(Integer oid, OrderStatusEnum enu,String content, String operator);
/**
* 保存订单状态变更日志
* @param oid 订单id
* @param content 记录内容
* @param operator 不为空时将默认为系统操作,为空时去redis用户
* @return
* @author lpf
* @date: 2019年1月28日 下午3:48:46
*/
boolean save(Integer oid, String content, String operator);
}
package com.zrqx.order.fg.manage;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.zrqx.core.constant.BaseConstant;
import com.zrqx.core.enums.order.OrderStatusEnum;
import com.zrqx.core.model.order.OrderStatusLog;
import com.zrqx.order.commons.redis.FgRedisManage;
import com.zrqx.order.fg.mapper.FgOrderStatusLogMapper;
@Component
public class FgOrderStatusLogManageImpl implements FgOrderStatusLogManage {
private static final Logger logger = LoggerFactory.getLogger(FgOrderStatusLogManageImpl.class);
@Autowired
private FgOrderStatusLogMapper fgOrderStatusLogMapper;
@Autowired
private FgRedisManage fgRedisManage;
/**
* 保存订单状态变更日志
* @see com.zrqx.order.fg.manage.FgOrderStatusLogManage#save(java.lang.Integer, com.zrqx.core.enums.order.OrderStatusEnum, java.lang.String, java.lang.String)
* @param oid 订单id
* @param enu 修改为的状态
* @param content 内容/为空将取默认(订单状态变更为:)不为空将加入在默认前
* @param operator 不为空时将默认为系统操作,为空时去redis用户
* @return
* @author lw
* @date: 2019年1月21日 下午3:19:50
*/
@Override
public boolean save(Integer oid, OrderStatusEnum enu, String content, String operator) {
logger.info(content + "订单状态修改:" + "oid:" + oid + "、status:" + enu.getName());
OrderStatusLog osl = this.create(oid, content, operator);
osl.setOperationContent((content == null ? "" : content + ",") + "订单状态变更为" + enu.getName());
return fgOrderStatusLogMapper.insertSelective(osl) > 0;
}
/**
* 保存订单状态变更日志
* @param oid 订单id
* @param content 记录内容
* @param operator 不为空时将默认为系统操作,为空时去redis用户
* @return
* @author lpf
* @date: 2019年1月28日 下午3:48:46
*/
@Override
public boolean save(Integer oid, String content, String operator) {
logger.info(content + "订单修改:" + "oid:" + oid + "、context:" + content);
OrderStatusLog osl = this.create(oid, content, operator);
return fgOrderStatusLogMapper.insertSelective(osl) > 0;
}
private OrderStatusLog create(Integer oid, String content, String operator){
OrderStatusLog osl = new OrderStatusLog();
osl.setOrderId(oid);
osl.setOperationContent(content == null ? "" : content);
osl.setCreateTime(new Date());
if (operator == null) {
osl.setCreaterName(fgRedisManage.getOpName());
osl.setCreater(fgRedisManage.getOpId());
osl.setCreaterType(0);
} else if (BaseConstant.SYSTEM_NAME.equals(operator)) {
osl.setCreaterName(operator);
osl.setCreater(operator);
osl.setCreaterType(2);
} else {
logger.warn("FgOrderStatusLogManageImpl#create 操作人未知 osl:" + osl + "; operator" + operator);
}
return osl;
}
}
package com.zrqx.order.fg.mapper;
import org.apache.ibatis.annotations.Mapper;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.order.Invoice;
@Mapper
public interface FgInvoiceMapper extends BaseMapper<Invoice> {
}
package com.zrqx.order.fg.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.order.OrderInfo;
@Mapper
public interface FgOrderInfoMapper extends BaseMapper<OrderInfo>{
/**
* 根据订单id 查询订单详情
* @param id
* @return
* @author lpf
* @date: 2019年1月14日 下午3:31:40
*/
@Select(" select goodsid as goodsId,type as goodsType, salePrice as salePrice , num as num from ord_orderinfo where orderid = #{id} ")
List<CreateOrderInfoForm> getGoodsList(@Param("id")Integer id);
}
package com.zrqx.order.fg.mapper;
import org.apache.ibatis.annotations.Mapper;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.order.OrderStatusLog;
@Mapper
public interface FgOrderStatusLogMapper extends BaseMapper<OrderStatusLog>{
}
package com.zrqx.order.fg.service;
import com.zrqx.core.form.third.baiwang.BaiwangForm;
import com.zrqx.core.model.order.Invoice;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.model.third.baiwang.BaiwangPayReturn;
import com.zrqx.core.service.BaseService;
import com.zrqx.core.vo.order.fg.FgInvoiceVo;
public interface FgInvoiceService extends BaseService<Invoice, Integer>{
/**
* 开具发票
* 对接第三方开具发票 ,保存开票记录
* 第三方开票失败 则保存错误原因,第三方开票成功 则 修改订单为已开票
* 返回开票的信息
* @param id 订单id
* @return
* @author lpf
* @date: 2019年2月19日 下午2:13:59
*/
FgInvoiceVo saveAndOpen(Integer id);
/**
* 生成发票记录信息
* @param o 订单
* @param r 百望云返回信息
* @param serialNo 发票流水
* @return
* @author lpf
* @date: 2019年2月19日16:43:23
*/
Invoice saveInvoice(Order o, BaiwangPayReturn r, BaiwangForm form);
}
package com.zrqx.order.fg.service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.zrqx.core.enums.GoodsTypeEnum;
import com.zrqx.core.enums.order.InvoiceContextEnum;
import com.zrqx.core.enums.order.InvoiceTypeEnum;
import com.zrqx.core.enums.order.OrderInvoiceStatusEnum;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.exception.BusinessValidateException;
import com.zrqx.core.form.third.baiwang.BaiwangDetailForm;
import com.zrqx.core.form.third.baiwang.BaiwangDownloadForm;
import com.zrqx.core.form.third.baiwang.BaiwangForm;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.order.Invoice;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.model.order.OrderInfo;
import com.zrqx.core.model.third.baiwang.BaiwangDownloadReturn;
import com.zrqx.core.model.third.baiwang.BaiwangPayReturn;
import com.zrqx.core.service.BaseServiceImpl;
import com.zrqx.core.util.bean.BeanUtils;
import com.zrqx.core.util.datatype.StringUtil;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.core.vo.order.fg.FgInvoiceVo;
import com.zrqx.order.fg.client.third.FgThirdClient;
import com.zrqx.order.fg.manage.FgOrderInfoManage;
import com.zrqx.order.fg.manage.FgOrderManage;
import com.zrqx.order.fg.mapper.FgInvoiceMapper;
@Service
public class FgInvoiceServiceImpl extends BaseServiceImpl<Invoice, Integer> implements FgInvoiceService{
private static final Logger logger = LoggerFactory.getLogger(FgInvoiceServiceImpl.class);
@Autowired
private FgInvoiceMapper fgInvoiceMapper;
@Autowired
private FgOrderManage fgOrderManage;
@Autowired
private FgOrderInfoManage fgOrderInfoManage;
@Autowired
private FgThirdClient fgThirdClient;
@Override
public BaseMapper<Invoice> getMapper() {
return fgInvoiceMapper;
}
/**
* 开具发票
* 对接第三方开具发票 ,保存开票记录
* 第三方开票失败 则保存错误原因,第三方开票成功 则 修改订单为已开票
* 返回开票的信息
* @param id 订单id
* @return
* @author lpf
* @date: 2019年2月19日 下午2:13:59
*/
@Override
public FgInvoiceVo saveAndOpen(Integer id) {
Order o = fgOrderManage.notNull(id);
if(StringUtils.isEmpty(o.getInvoiceEmail()) && StringUtils.isEmpty(o.getInvoiceTel())){
throw new BusinessValidateException("订单的邮箱和手机号不能同时为空");
}
BaiwangForm form = this.createBaiwangForm(o);
logger.info("推送发票信息");
logger.info("发票信息为:"+JSON.toJSONString(form));
// 推送发票
CallBack<BaiwangPayReturn> call = fgThirdClient.pay(form);
if (call.isStatus()) {
BaiwangPayReturn r = call.getData();
if (r != null) {
// 生成开票记录
Invoice i = this.saveInvoice(o, r, form);
//获取发票图片地址
getInvoiceImgUrl(r,i,o);
o.setInvoiceStatus(OrderInvoiceStatusEnum.SUCCESS.getCode());
fgOrderManage.update(o, "发票开具成功,发票号码:" + i.getInvoiceNumber());
return BeanUtils.copy(i, FgInvoiceVo.class);
} else {
throw new BaseException("开发票返回成功,但无开票成功信息,开票失败");
}
} else {
// TODO 获取发票错误原因
throw new BaseException("开发票失败");
}
}
/**
* 生成发票记录信息
* @param o 订单
* @param r 百望云返回信息
* @param serialNo 发票流水
* @return
* @author lpf
* @date: 2019年2月19日16:43:08
*/
@Override
public Invoice saveInvoice(Order o, BaiwangPayReturn r, BaiwangForm form) {
Invoice i = new Invoice();
i.setOrderId(o.getId());
i.setOrderCode(o.getCode());
i.setCreateTime(new Date());
i.setOrderCreater(o.getCreater());
i.setInvoiceType(o.getInvoiceType());
i.setInvoiceContext(o.getInvoiceContext());
i.setInvoiceTitle(o.getInvoiceTitle());
i.setTaxpayerIdentificationNumber(o.getTaxpayerIdentificationNumber());
i.setInvoiceTel(o.getInvoiceTel());
i.setInvoiceEmail(o.getInvoiceEmail());
i.setInvoiceCode(r.getInvoiceCode());
i.setInvoiceNumber(r.getInvoiceNo());
i.setType(form.getInvoiceType());
i.setSerialNo(form.getSerialNo());
fgInvoiceMapper.insert(i);
return i;
}
/**
* 保存发票图片地址
* @param r
* @param i
* @author ydm
* @param o
* @date: 2018年9月13日 下午1:42:52
*/
private void getInvoiceImgUrl(BaiwangPayReturn r, Invoice i, Order o) {
BaiwangDownloadForm form = new BaiwangDownloadForm();
form.setInvoiceCode(r.getInvoiceCode());
form.setInvoiceNo(r.getInvoiceNo());
form.setBuyerEmail(o.getInvoiceEmail());
form.setBuyerPhone(o.getPhone());
CallBack<BaiwangDownloadReturn> callback = fgThirdClient.download(form);
if(callback.isStatus()){
BaiwangDownloadReturn data = callback.getData();
if(data.getMessage() != null){
i.setInvoiceUrl(data.getMessage());
this.updateByPrimaryKeySelective(i);
}
}
}
/**
* 生成百旺云平台开具发票参数
* @param o 订单
* @return
* @author lpf
* @date: 2019年2月19日 下午2:26:28
*/
private BaiwangForm createBaiwangForm(Order o) {
BaiwangForm form = new BaiwangForm();
o.setInvoiceAddress(StringUtil.ifelse(o.getInvoiceAddress()));
o.setInvoiceTel(StringUtil.ifelse(o.getInvoiceTel()));
o.setInvoiceOpenBank(StringUtil.ifelse(o.getInvoiceOpenBank()));
o.setInvoiceBankAccount(StringUtil.ifelse(o.getInvoiceBankAccount()));
String serialNo = StringUtil.getUUIDAndDate();
// 发票流水号
form.setSerialNo(serialNo);
form.setInvoiceType(InvoiceTypeEnum.BLUE.getCode());
form.setBuyerName(o.getInvoiceTitle());
form.setBuyerTaxNo(o.getTaxpayerIdentificationNumber());
// 购方地址及电话,专票必填
form.setBuyerAddressPhone(o.getInvoiceAddress() + o.getInvoiceTel());
// 购方开户行及账号,专票必填
form.setBuyerBankAccount(o.getInvoiceOpenBank() + o.getInvoiceBankAccount());
// 合计金额
form.setInvoiceTotalPrice(o.getPayment().doubleValue()+"");
// 合计税额
// TODO 需要看出版社的收税 税率
form.setInvoiceTotalTax("0.0");
// 价税合计
form.setInvoiceTotalPriceTax(o.getPayment().doubleValue()+"");
List<BaiwangDetailForm> list = this.createBaiwangDetailFormList(o);
form.setInvoiceDetailsList(list);
// 清单标志: 0:无清单 1:带清单 (发票明细大于等于8行必须带清单),必填
if (list.size() >= 8) {
form.setInvoiceListMark("1");
} else {
form.setInvoiceListMark("0");
}
return form;
}
/**
* 生成发票详细
* @param o
* @return
* @author lpf
* @date: 2019年2月19日 下午3:10:34
*/
private List<BaiwangDetailForm> createBaiwangDetailFormList(Order o){
List<BaiwangDetailForm> resultList = new ArrayList<>();
List<OrderInfo> list = fgOrderInfoManage.selectByOrderId(o.getId());
// TODO 详情未拆分套餐
if (InvoiceContextEnum.INFO.equals(o.getInvoiceContext())) {
int line = 1;
// 发票内容 明细
for (OrderInfo orderInfo : list) {
BaiwangDetailForm form = this.createBaiwangDetailForm(orderInfo);
form.setGoodsLineNo(line+"");
resultList.add(form);
line ++;
}
} else if (InvoiceContextEnum.DATA.equals(o.getInvoiceContext())) {
// 发票内容 资料
// TODO 发票 描述
BaiwangDetailForm form = this.createBaiwangDetailForm(o, list, "资料", "个");
resultList.add(form);
} else {
// 发票内容 图书
// TODO 发票 描述
BaiwangDetailForm form = this.createBaiwangDetailForm(o, list, "图书", "册");
resultList.add(form);
}
return resultList;
}
/**
* 生成发票汇总详细
* @param list
* @return
* @author lpf
* @date: 2019年2月19日 下午3:32:40
*/
private BaiwangDetailForm createBaiwangDetailForm(Order order, List<OrderInfo> list, String name, String unit) {
BaiwangDetailForm form = this.createBaiwangDetailForm();
form.setGoodsLineNo("1");
// 商品名
form.setGoodsName(name);
// 单位
form.setGoodsUnit(unit);
// 售价
form.setGoodsTotalPrice(order.getPayment().doubleValue() + "");
int num = list.size();
form.setGoodsQuantity(num + "");
// 单价
form.setGoodsPrice(Double.parseDouble(form.getGoodsTotalPrice())/Integer.parseInt(form.getGoodsQuantity()));
return form;
}
/**
* 生成单个发票详细
* @param info
* @return
* @author lpf
* @date: 2019年2月19日 下午3:20:42
*/
private BaiwangDetailForm createBaiwangDetailForm(OrderInfo info) {
BaiwangDetailForm form = this.createBaiwangDetailForm();
form.setGoodsName(info.getName());
form.setGoodsTotalPrice(info.getSalePrice()
.multiply(new BigDecimal(info.getNum())).doubleValue() + "");
form.setGoodsTaxItem(GoodsTypeEnum.getName(info.getType()));
form.setGoodsQuantity(info.getNum()+"");
form.setGoodsPrice(info.getSalePrice().doubleValue());
return form;
}
private BaiwangDetailForm createBaiwangDetailForm(){
BaiwangDetailForm form = new BaiwangDetailForm();
// TODO 发票行性质,0:正常行 1:折扣行 2:被折扣行,必填
form.setGoodsLineNature("0");
// TODO 商品编码
form.setGoodsCode("106020101990000000001");
// TODO 商品单元需要定义
form.setGoodsUnit("册");
return form;
}
}
package com.zrqx.order.fg.service;
import java.math.BigInteger;
import java.util.List;
import com.zrqx.core.model.order.OrderInfo;
import com.zrqx.core.service.BaseService;
import com.zrqx.core.vo.order.fg.FgOrderInfoPageVo;
public interface FgOrderInfoService extends BaseService<OrderInfo, Integer>{
/**
* 根据订单id查询订单详情vo列表
* @param id
* @return
* @author lpf
* @date: 2019年1月28日 下午3:59:46
*/
List<FgOrderInfoPageVo> listByOrderId(Integer id);
}
package com.zrqx.order.fg.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zrqx.core.mapper.BaseMapper;
import com.zrqx.core.model.order.OrderInfo;
import com.zrqx.core.service.BaseServiceImpl;
import com.zrqx.core.vo.order.fg.FgOrderInfoPageVo;
import com.zrqx.order.fg.manage.FgOrderInfoManage;
import com.zrqx.order.fg.mapper.FgOrderInfoMapper;
@Service
public class FgOrderInfoServiceImpl extends BaseServiceImpl<OrderInfo, Integer> implements FgOrderInfoService{
@Autowired
private FgOrderInfoManage fgOrderInfoManage;
@Autowired
private FgOrderInfoMapper fgOrderInfoMapper;
@Override
public BaseMapper<OrderInfo> getMapper() {
return this.fgOrderInfoMapper;
}
/**
* 根据订单id查询订单详情vo列表
* @param id
* @return
* @author lpf
* @date: 2019年1月28日 下午3:59:46
*/
@Override
public List<FgOrderInfoPageVo> listByOrderId(Integer id) {
return fgOrderInfoManage.listByOrderId(id);
}
}
package com.zrqx.order.fg.service;
import java.math.BigDecimal;
import java.util.List;
import com.zrqx.core.enums.order.OrderStatusEnum;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.form.GoodsForm;
import com.zrqx.core.form.order.fg.FgOrderForm;
import com.zrqx.core.form.order.fg.FgQueryOrderInfoBuyForm;
import com.zrqx.core.form.order.fg.FgQueryOrderPageForm;
import com.zrqx.core.form.order.fg.FgQueryRecentlyForm;
import com.zrqx.core.form.order.fg.FgSaveOrderInvoiceForm;
import com.zrqx.core.form.order.fg.SaveOrderCommentForm;
import com.zrqx.core.form.third.pay.PayResultForm;
import com.zrqx.core.model.order.Order;
import com.zrqx.core.service.BaseService;
import com.zrqx.core.util.page.PageInfo;
import com.zrqx.core.util.page.PageParam;
import com.zrqx.core.vo.order.fg.FgBuyOrderInfoPageVo;
import com.zrqx.core.vo.order.fg.FgInvoiceOrderPageVo;
import com.zrqx.core.vo.order.fg.FgOrderPageVo;
import com.zrqx.core.vo.order.fg.FgOrderVO;
import com.zrqx.core.vo.order.fg.FgRecentlyOrderVo;
import com.zrqx.core.vo.order.fg.OrderPayVo;
import com.zrqx.core.vo.order.fg.TopUpVo;
import com.zrqx.core.vo.order.fg.TradingRecordVo;
import com.zrqx.core.vo.pay.PayInfoVo;
public interface FgOrderService extends BaseService<Order, Integer>{
/**
* 创建订单
* @param form
* @return
* @throws BaseException
* @author lpf
* @date: 2018年12月28日 下午12:40:36
*/
Integer createOrder(FgOrderForm form) throws BaseException;
/**
* 创建充值订单
* @param price 充值金额
* @return
* @author lpf
* @date: 2019年1月24日 下午2:37:23
*/
Integer createOrder(BigDecimal price);
/**
* 接收三方调用----拿到支付回调修改订单状态
* @param form 支付结果
* @author lw
* @date: 2019年1月21日 上午9:09:50
*/
boolean receivePayCall(PayResultForm form);
/**
* 统一调用三方----去支付(获取页面或二维码url)
* @param code 订单id
* @param payType 支付类型
* @return
* @author lw
* @date: 2019年1月21日 下午5:17:16
*/
PayInfoVo pay(String orderId, String payType);
/**
* 获取订单支付验证信息
* @param code 订单号
* @return
* @author lpf
* @date: 2019年1月23日 上午9:44:37
*/
OrderPayVo getOrderPayVo(String code);
/**
* 获取近n个月的m条最新订单,按照创建时间倒序
* @param form
* @return
* @author lpf
* @date: 2019年1月23日 下午2:38:12
*/
List<FgRecentlyOrderVo> listRecently(FgQueryRecentlyForm form);
/**
* 查询当前登录用户订单数量
* @param form
* @return
* @author lpf
* @date: 2019年1月28日 上午9:24:36
*/
Integer count(FgQueryOrderPageForm form);
/**
* 个人中心-我的订单 查询订单列表
* @param pageParam
* @param form
* @return
* @author lpf
* @date: 2019年1月28日 上午11:43:45
*/
PageInfo<FgOrderPageVo> page(PageParam pageParam, FgQueryOrderPageForm form);
/**
* 根据订单id查询订单vo
* @param oid
* @return
* @author lpf
* @date: 2019年1月28日 下午3:17:07
*/
FgOrderVO get(Integer oid);
/**
* 批量修改订单 display字段 并添加日志
* @param ids
* @return
* @author lpf
* @date: 2019年1月28日 下午3:39:32
*/
Boolean delete(List<Integer> ids);
/**
* 订单发表评论
* @param form
* @return
* @author lpf
* @date: 2019年1月28日 下午4:44:15
*/
Boolean saveComment(SaveOrderCommentForm form);
/**
* 已购买的商品分页列表
* @param pageParam
* @param form
* @return
* @author lpf
* @date: 2019年2月13日 下午3:26:31
*/
PageInfo<FgBuyOrderInfoPageVo> pageBuy(PageParam pageParam, FgQueryOrderInfoBuyForm form);
/**
* 根据 商品id 商品类型 当前用户 订单状态(支付后) 计数 返回 result > 0
* @param form
* @return
* @author lpf
* @date: 2019年2月14日 下午5:05:29
*/
Boolean isExistBuyGoods(GoodsForm form);
/**
* 查询可以开票的订单
* 订单状态 : 已支付 已完成 当前登录用户
* 排序方式 : 订单创建时间倒序
* @return
* @author lpf
* @date: 2019年2月15日 下午3:55:46
*/
PageInfo<FgInvoiceOrderPageVo> pageInvoiceOrder(PageParam pageParam);
/**
* 查询已购买的商品信息
* @return
* @author lpf
* @date: 2019年2月18日 下午1:42:55
*/
List<GoodsForm> listBuy();
/**
* 根据登录人查询不为空的订单
* @param id
* @return
* @author lpf
* @date: 2019年2月18日 下午2:40:42
*/
Order notNull(Integer id);
/**
* 根据当前登录用户和订单id 修改订单发票信息,更新修改时间
* @param form
* @return
* @author lpf
* @date: 2019年2月19日 上午11:49:11
*/
boolean saveInvoice(FgSaveOrderInvoiceForm form);
/**
* 修改订单状态
* @param o
* @param statusEnum
* @param log
* @return
* @author lpf
* @date: 2019年3月11日 上午9:17:38
*/
boolean updateStatus(Order o, OrderStatusEnum statusEnum, String log);
/**
* 修改订单状态
* @param o
* @param statusEnum
* @param log
* @param operator
* @return
* @author ycw
* @date: 2019年4月4日 上午9:14:00
*/
boolean updateStatus(Order o, OrderStatusEnum statusEnum, String log, String operator);
/**
* 登录用户的交易记录
* 查询指定用户 使用账户余额支付方式的 订单信息
* @param pageParam
* @return
* @author lpf
* @date: 2019年3月12日 上午11:37:48
*/
PageInfo<TradingRecordVo> pageTradingRecord(PageParam pageParam);
/**
* 查询充值订单
* @param pageParam
* @return
* @author lpf
* @date: 2019年3月12日 下午2:35:38
*/
PageInfo<TopUpVo> pageTopUp(PageParam pageParam);
/**
* 查询所有未支付订单
* @return
* @author ydm
* @date: 2018年8月27日 下午6:02:17
*/
List<Order> queryAllWaitPay();
/**
* 订单id查询订单是否被支付 0未支付 1已支付
* @param oid
* @return
* @author ycw
* @date: 2019年4月1日 上午11:38:21
*/
String checkIsPaid(Integer oid);
/**
* 查询所有未支付并且已超时的订单
* @return
* @author ydm
* @date: 2018年10月17日 下午4:02:37
*/
List<Order> queryAllWaitPayAndTimeout();
}
package com.zrqx.order.fg.service.order;
import java.math.BigDecimal;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.model.order.OrderInfo;
/**
* 订单详情抽象工厂
* @author lpf
* @date 2019年1月2日上午11:04:31
*/
public interface OrderInfoFactory{
/**
* 创建订单详情对象
* @param form 商品form
* @return
* @author lpf
* @date: 2019年1月2日 上午11:10:10
*/
OrderInfo create(CreateOrderInfoForm form);
/**
* 创建充值订单详情对象
* @param price
* @return
* @author lpf
* @date: 2019年1月24日 下午2:50:01
*/
OrderInfo create(BigDecimal price);
}
package com.zrqx.order.fg.service.order;
import java.math.BigDecimal;
import com.zrqx.core.enums.BooleanStatusEnum;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.exception.BusinessValidateException;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.model.order.OrderInfo;
/**
* 生成订单详情公用方法
* @author lpf
* @date 2019年1月10日上午10:45:49
*/
public abstract class OrderInfoFactoryAdapter implements OrderInfoFactory{
/**
* 生成订单详情后处理方法
* @param form
* @param info
* @author lpf
* @date: 2019年1月10日 下午3:09:59
*/
protected void after(CreateOrderInfoForm form, OrderInfo info){
validatePrice(form, info);
build(form, info);
}
/**
* 计算订单详情信息
* @param form
* @param info
* @author lpf
* @date: 2019年1月10日 下午3:24:15
*/
protected void build(CreateOrderInfoForm form, OrderInfo info){
info.setNum(form.getNum());
info.setTotalPrice(info.getSalePrice().multiply(new BigDecimal(info.getNum())));
info.setHasComment(BooleanStatusEnum.NO.getCode());
}
/**
* 验证价格是否一致
* @param form
* @param info
* @author lpf
* @date: 2019年1月10日 下午3:11:30
*/
protected void validatePrice(CreateOrderInfoForm form, OrderInfo info){
if (info.getSalePrice() == null) {
throw new BusinessValidateException("商品价格不存在,不能下单;" + info );
}
if (form.getSalePrice() == null) {
return ;
}
if (info == null || info.getSalePrice() == null || form.getSalePrice().doubleValue() != info.getSalePrice().doubleValue()) {
throw new BusinessValidateException("商品价格已经变化,请重新购买");
}
}
}
package com.zrqx.order.fg.service.order.impl;
import java.math.BigDecimal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.zrqx.core.enums.BooleanStatusEnum;
import com.zrqx.core.enums.GoodsTypeEnum;
import com.zrqx.core.exception.BaseException;
import com.zrqx.core.form.order.fg.CreateOrderInfoForm;
import com.zrqx.core.model.order.OrderInfo;
import com.zrqx.core.util.response.CallBack;
import com.zrqx.order.fg.client.FgGoodsClient;
import com.zrqx.order.fg.service.order.OrderInfoFactoryAdapter;
/**
* 默认创建订单详情逻辑
* @author lpf
* @date 2019年1月10日上午9:52:26
*/
@Component
public class DefaultOrderInfoFactoryImpl extends OrderInfoFactoryAdapter{
@Autowired
private FgGoodsClient fgGoodsClient;
/**
* 创建订单详情对象
* @see com.zrqx.order.fg.service.order.OrderInfoFactory#create(com.zrqx.core.form.order.fg.CreateOrderInfoForm)
* @param form
* @return
* @author lpf
* @date: 2019年1月10日 上午9:53:49
*/
@Override
public OrderInfo create(CreateOrderInfoForm form) {
CallBack<OrderInfo> call = fgGoodsClient.queryOrderInfo(form.getGoodsId(), form.getGoodsType());
if (call.hasEntity()) {
OrderInfo info = call.getData();
this.after(form, info);
return info;
}
throw new BaseException("生成订单详情失败");
}
/**
* 创建充值订单详情对象
* @param price
* @return
* @author lpf
* @date: 2019年1月24日 下午2:50:01
*/
@Override
public OrderInfo create(BigDecimal price) {
OrderInfo info = new OrderInfo();
info.setGoodsid("-1");
info.setType(GoodsTypeEnum.TOPUP.getCode());
info.setName(GoodsTypeEnum.TOPUP.getName());
info.setWeight(new BigDecimal(0));
info.setPrice(price);
info.setDiscount(new BigDecimal(1));
info.setSalePrice(price);
info.setTotalPrice(price);
info.setNum(1);
info.setHasComment(BooleanStatusEnum.NO.getCode());
//info.setCover(cover);
return info;
}
}
test-environment=true
order-quartz=true
# 小时
order-lose-hour=24
img-root-path=http://122.14.50.6:8097/file/?isOnLine=true&fileName=
\ No newline at end of file
logging:
level:
com.zrqx.order: DEBUG
mybatis:
type-aliases-package: com.zrqx.core.model
mapper:
mappers:
- com.zrqx.core.mapper.BaseMapper
not-empty: false
i-d-e-n-t-i-t-y: MYSQL
style: normal
b-e-f-o-r-e: true
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
spring:
main:
allow-bean-definition-overriding: true #2.1.0 多个接口上的@FeignClient(“相同服务名”)会报错 ,允许覆盖
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
http:
multipart:
maxFileSize: 20Mb
maxRequestSize: 20Mb
feign:
hystrix:
enabled: true
ribbon:
ConnectTimeout: 360000
ReadTimeout: 360000
hystrix:
command:
default:
execution:
isolation:
strategy: SEMAPHORE
thread:
timeoutInMilliseconds: 1440000
semaphore:
maxConcurrentRequests: 200
\ No newline at end of file
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论