Переглянути джерело

Merge branch 'master' of http://218.85.55.253:3000/miaxis/zzjs

小么熊🐻 4 роки тому
батько
коміт
c7ab7ce05e
25 змінених файлів з 831 додано та 177 видалено
  1. 98 57
      zzjs-admin/src/main/java/com/miaxis/app/controller/film/FilmController.java
  2. 65 27
      zzjs-admin/src/main/java/com/miaxis/app/controller/film/NotifyController.java
  3. 1 0
      zzjs-admin/src/main/resources/application-dev.yml
  4. 1 0
      zzjs-admin/src/main/resources/application-prod.yml
  5. 10 1
      zzjs-admin/src/test/java/com/miaxis/test/NormalTest.java
  6. 2 0
      zzjs-common/src/main/java/com/miaxis/common/config/WxpayConfig.java
  7. 1 1
      zzjs-framework/src/main/java/com/miaxis/framework/web/exception/GlobalExceptionHandler.java
  8. 117 0
      zzjs-service/src/main/java/com/miaxis/film/controller/RefundRecordController.java
  9. 31 87
      zzjs-service/src/main/java/com/miaxis/film/domain/FilmOrder.java
  10. 143 0
      zzjs-service/src/main/java/com/miaxis/film/domain/RefundRecord.java
  11. 27 0
      zzjs-service/src/main/java/com/miaxis/film/dto/CinemaData.java
  12. 10 0
      zzjs-service/src/main/java/com/miaxis/film/dto/FilmOrderCreateDTO.java
  13. 28 0
      zzjs-service/src/main/java/com/miaxis/film/dto/FilmOrderJsonData.java
  14. 19 0
      zzjs-service/src/main/java/com/miaxis/film/dto/FilmOrderListDTO.java
  15. 0 4
      zzjs-service/src/main/java/com/miaxis/film/dto/FilmOrderNotifyDTO.java
  16. 50 0
      zzjs-service/src/main/java/com/miaxis/film/dto/FilmWxpayRefundDTO.java
  17. 9 0
      zzjs-service/src/main/java/com/miaxis/film/dto/WxNotifyReturnDTO.java
  18. 3 0
      zzjs-service/src/main/java/com/miaxis/film/mapper/FilmOrderMapper.java
  19. 22 0
      zzjs-service/src/main/java/com/miaxis/film/mapper/RefundRecordMapper.java
  20. 5 0
      zzjs-service/src/main/java/com/miaxis/film/service/IFilmOrderService.java
  21. 26 0
      zzjs-service/src/main/java/com/miaxis/film/service/IRefundRecordService.java
  22. 9 0
      zzjs-service/src/main/java/com/miaxis/film/service/impl/FilmOrderServiceImpl.java
  23. 87 0
      zzjs-service/src/main/java/com/miaxis/film/service/impl/RefundRecordServiceImpl.java
  24. 10 0
      zzjs-service/src/main/resources/mapper/film/FilmOrderMapper.xml
  25. 57 0
      zzjs-service/src/main/resources/mapper/film/RefundRecordMapper.xml

+ 98 - 57
zzjs-admin/src/main/java/com/miaxis/app/controller/film/FilmController.java

@@ -9,17 +9,18 @@ import com.miaxis.common.constant.Constants;
 import com.miaxis.common.core.controller.BaseController;
 import com.miaxis.common.core.domain.Response;
 import com.miaxis.common.core.domain.entity.UserInfo;
+import com.miaxis.common.core.page.ResponsePageInfo;
 import com.miaxis.common.exception.CustomException;
 import com.miaxis.common.utils.SecurityUtils;
 import com.miaxis.common.utils.uuid.CommonUtils;
 import com.miaxis.feign.dto.FilmDTO;
 import com.miaxis.film.domain.FilmOrder;
-import com.miaxis.film.dto.FilmOrderCreateDTO;
+import com.miaxis.film.dto.*;
 import com.miaxis.film.service.IFilmOrderService;
+import com.miaxis.question.domain.QuestionInfo;
 import com.miaxis.system.service.ISysConfigService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
+import com.miaxis.system.service.ISysDictDataService;
+import io.swagger.annotations.*;
 import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -30,9 +31,11 @@ import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.util.EntityUtils;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.io.ClassPathResource;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
 import java.io.ByteArrayOutputStream;
@@ -73,6 +76,9 @@ public class FilmController extends BaseController {
     @Autowired
     private ISysConfigService configService;
 
+    @Autowired
+    private ISysDictDataService dictDataService;
+
     @Value("${app.appid}")
     private String appid;
     @Value("${film.appKey}")
@@ -84,6 +90,24 @@ public class FilmController extends BaseController {
 
 
 
+
+
+
+    @GetMapping("/order/list")
+    @ApiOperation("查询订单列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "pageNum",value = "当前页码" ,dataType = "int", paramType = "query", required = false),
+            @ApiImplicitParam(name = "pageSize",value = "每页数据量" , dataType = "int", paramType = "query", required = false),
+    })
+    public ResponsePageInfo<FilmOrder> list(@ModelAttribute FilmOrderListDTO filmOrderListDTO){
+
+        String openid = SecurityUtils.getLoginUser().getStudent().getOpenid();
+        startPage();
+        filmOrderListDTO.setOpenid(openid);
+        List<FilmOrder> list = filmOrderService.selectOrderList(filmOrderListDTO);
+        return toResponsePageInfo(list);
+    }
+
     /**
      * 微信支付获取预订单id
      */
@@ -96,21 +120,34 @@ public class FilmController extends BaseController {
 
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         ObjectMapper objectMapper = new ObjectMapper();
-
         UserInfo student = SecurityUtils.getLoginUser().getStudent();
 
-
-        //生成预订单
+        //1 本地创建订单
+        FilmOrder order = new FilmOrder();
         Long id = student.getId();
         String orderCode = getOrderCode(id);
+        order.setOutTradeNo(orderCode);
+        order.setOpenid(student.getOpenid());
+        String goodsName = dictDataService.selectDictLabel("goods_type", filmOrderCreateDTO.getGoodsType());
+        order.setGoodsType(goodsName);
+        order.setGoodsPictureUrl(filmOrderCreateDTO.getGoodsPictureUrl());
+        FilmOrderJsonData filmOrderJsonData = new FilmOrderJsonData();
+        filmOrderCreateDTO.setThirdOrderId(orderCode);
+        filmOrderJsonData.setFilmOrderCreateDTO(filmOrderCreateDTO);
         //通过影院api 获取单票价格
-        Integer price = getPrice(filmOrderCreateDTO.getCinemaId(),filmOrderCreateDTO.getShowId());
+        Integer price = getPrice(filmOrderCreateDTO.getCinemaId(),filmOrderCreateDTO.getShowId(),filmOrderJsonData);
         int number = filmOrderCreateDTO.getSeat().split(",").length;
+        order.setOrderDataJson(JSONObject.toJSONString(filmOrderJsonData));
+        order.setTotal(price*number);
+        filmOrderService.save(order);
+
 
+
+        // 2 调用微信接口生成预订单
         ObjectNode rootNode = objectMapper.createObjectNode();
         rootNode.put("mchid",wxpayConfig.getMerchantId())
                 .put("appid", appid)
-                .put("description", "电影票")
+                .put("description", filmOrderCreateDTO.getGoodsType())
                 .put("notify_url", notifyUrl)
                 .put("out_trade_no", orderCode);
         rootNode.putObject("amount")
@@ -126,19 +163,8 @@ public class FilmController extends BaseController {
             throw new CustomException(JSONObject.parseObject(bodyAsString).get("message").toString());
         }
 
-        //本地创建订单
-        FilmOrder order = new FilmOrder();
-        order.setShowId(filmOrderCreateDTO.getShowId());
-        order.setOutTradeNo(orderCode);
-        order.setSeat(filmOrderCreateDTO.getSeat());
-        order.setAcceptChangeSeat(filmOrderCreateDTO.getAcceptChangeSeat());
-        order.setSeatId(filmOrderCreateDTO.getSeatId());
-        order.setSeatNo(filmOrderCreateDTO.getSeatNo());
-        order.setReservedPhone(filmOrderCreateDTO.getReservedPhone());
-        order.setOpenid(student.getOpenid());
-        filmOrderService.save(order);
-
 
+        //3 生成前端小程序调用调起微信支付所需参数
         String  packageStr = "prepay_id="+JSONObject.parseObject(bodyAsString).get("prepay_id");
         JSONObject jsonObject = new JSONObject();
         jsonObject.put("package",packageStr);
@@ -169,35 +195,41 @@ public class FilmController extends BaseController {
 
     }
 
-    private Integer getPrice(String cinemaId, String showId) {
+
+
+    private Integer getPrice(String cinemaId, String showId, FilmOrderJsonData filmOrderJsonData) {
+
         FilmDTO filmDTO = new FilmDTO();
-        filmDTO.setUrl("get-schedule-list");
+        filmDTO.setUrl("movieapi/movie-info/get-schedule-list");
         StringBuffer paramData =  new StringBuffer();
         paramData.append("cinemaId="+cinemaId);
+        filmDTO.setParamData(paramData.toString());
         String result = filmOrderService.excuteFilmApi(filmDTO);
         JSONObject jsonObject = JSONObject.parseObject(result);
         JSONObject  data = jsonObject.getJSONObject("data");
         JSONObject  discountRule = data.getJSONObject("discountRule");
-        JSONArray list = jsonObject.getJSONArray("list");
+        JSONArray list = data.getJSONArray("list");
+        log.info(list.toJSONString());
         List<CinemaData> cinemaData = list.toJavaList(CinemaData.class);
         List<CinemaData> listdata = cinemaData.stream().filter(a -> showId.equals(a.getShowId())).collect(Collectors.toList());
-        Integer netPrice = listdata.get(0).getNetPrice();
+        CinemaData realCinemaData = listdata.get(0);
+        filmOrderJsonData.setCinemaData(realCinemaData);
+        Integer netPrice = realCinemaData.getNetPrice();
         Double upDiscountRate = discountRule.getDouble("upDiscountRate");
+        Double downDiscountRate = discountRule.getDouble("downDiscountRate");
         String film_discount = configService.selectConfigByKey("film_discount");
+        Double  chosenDiscount = netPrice >3900 ? upDiscountRate:downDiscountRate;
         Double aDouble = Double.valueOf(film_discount);
-        Double v = netPrice * upDiscountRate * aDouble;
+        Double v = netPrice * chosenDiscount * aDouble;
+
         return v.intValue();
 
 
     }
 
 
-    @Data
-    class CinemaData{
-        Integer netPrice;
-        String showId;
 
-    }
+
 
 
     /**
@@ -225,38 +257,47 @@ public class FilmController extends BaseController {
     /**
      * 获取电影订单详细信息
      */
-    @GetMapping(value = "/{id}")
+    @GetMapping(value = "/{outTradeNo}")
     @ApiOperation("获取电影订单详细信息")
     public Response<FilmOrder> getInfo(
-            @ApiParam(name = "id", value = "电影订单参数", required = true)
-            @PathVariable("id") Long id
+            @ApiParam(name = "outTradeNo", value = "电影订单参数", required = true)
+            @PathVariable("outTradeNo") String outTradeNo
     ){
-        return Response.success(filmOrderService.getById(id));
+        FilmOrder filmOrder = filmOrderService.getByOutTradeNo(outTradeNo);
+        if (!filmOrder.getOpenid().equals(SecurityUtils.getLoginUser().getStudent().getOpenid())){
+            throw new CustomException("该用户无访问此订单权限");
+        }
+        return Response.success(filmOrder);
     }
 
 
-    /**
-     * 微信支付查单接口
-     */
-    @GetMapping(value = "/wxorder/{outTradeNo}")
-    @ApiOperation("根据订单号查询订单状态")
-    public Response<String> getOrderInfo(
-            @ApiParam(name = "outTradeNo", value = "商户订单号", required = true)
-            @PathVariable("outTradeNo") String outTradeNo
-    ) throws IOException {
-        HttpGet get = new HttpGet("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/"
-                +outTradeNo+"?mchid="+wxpayConfig.getMerchantId());
-        get.addHeader("Accept", "application/json");
-        HttpResponse response = httpClient.execute(get);
-        String bodyAsString = EntityUtils.toString(response.getEntity());
-        JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
-        int statusCode = response.getStatusLine().getStatusCode();
-        if (statusCode == 200) {
-            return Response.success(jsonObject.getString("trade_state"));
-        } else {
-            throw new CustomException(EntityUtils.toString(response.getEntity()));
-        }
-    }
+
+
+
+
+
+//    /**
+//     * 微信支付查单接口
+//     */
+//    @GetMapping(value = "/wxorder/{outTradeNo}")
+//    @ApiOperation("根据订单号查询订单状态")
+//    public Response<String> getOrderInfo(
+//            @ApiParam(name = "outTradeNo", value = "商户订单号", required = true)
+//            @PathVariable("outTradeNo") String outTradeNo
+//    ) throws IOException {
+//        HttpGet get = new HttpGet("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/"
+//                +outTradeNo+"?mchid="+wxpayConfig.getMerchantId());
+//        get.addHeader("Accept", "application/json");
+//        HttpResponse response = httpClient.execute(get);
+//        String bodyAsString = EntityUtils.toString(response.getEntity());
+//        JSONObject jsonObject = JSONObject.parseObject(bodyAsString);
+//        int statusCode = response.getStatusLine().getStatusCode();
+//        if (statusCode == 200) {
+//            return Response.success(jsonObject.getString("trade_state"));
+//        } else {
+//            throw new CustomException(EntityUtils.toString(response.getEntity()));
+//        }
+//    }
 
 
 

+ 65 - 27
zzjs-admin/src/main/java/com/miaxis/app/controller/film/NotifyController.java

@@ -5,20 +5,24 @@ import com.alibaba.fastjson.JSONObject;
 import com.miaxis.common.config.WxpayConfig;
 import com.miaxis.common.constant.Constants;
 import com.miaxis.common.core.domain.Response;
+import com.miaxis.common.core.domain.entity.UserInfo;
 import com.miaxis.common.exception.CustomException;
 import com.miaxis.common.utils.AesUtil;
+import com.miaxis.common.utils.SecurityUtils;
 import com.miaxis.feign.dto.FilmDTO;
 import com.miaxis.film.domain.FilmOrder;
-import com.miaxis.film.dto.FilmOrderNotifyDTO;
-import com.miaxis.film.dto.FilmWxpayDTO;
+import com.miaxis.film.dto.*;
 import com.miaxis.film.service.IFilmOrderService;
+import com.miaxis.film.service.IRefundRecordService;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import lombok.Data;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.joda.time.DateTime;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@@ -33,6 +37,8 @@ import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.util.Locale;
 
+import static com.miaxis.common.utils.OrderCodeFactory.getOrderCode;
+
 @RestController
 @RequiredArgsConstructor
 @RequestMapping(Constants.OPEN_PREFIX+"/film/notify")
@@ -51,6 +57,10 @@ public class NotifyController {
     @Autowired
     private ThreadPoolTaskExecutor threadPoolTaskExecutor;
 
+    @Autowired
+    private  IRefundRecordService  refundRecordService;
+
+
     @Value("${film.notifyUrl}")
     private  String notifyUrl ;
 
@@ -59,7 +69,7 @@ public class NotifyController {
      */
     @PostMapping(value = "/wxpay")
     @ApiOperation("微信支付回调")
-    public WxNotifyReturnDTO wxpayNotify(@RequestBody FilmWxpayDTO filmWxpayDTO,HttpServletRequest request) throws GeneralSecurityException, IOException {
+    public WxNotifyReturnDTO wxpayNotify(@RequestBody FilmWxpayDTO filmWxpayDTO, HttpServletRequest request) throws GeneralSecurityException, IOException {
         AesUtil aesUtil = new AesUtil(wxpayConfig.getV3key().getBytes());
         FilmWxpayDTO.WxpaySource wxpaySource = filmWxpayDTO.getResource();
         String resourceString = aesUtil.decryptToString(wxpaySource.getAssociated_data().getBytes(), wxpaySource.getNonce().getBytes(), wxpaySource.getCiphertext());
@@ -76,29 +86,56 @@ public class NotifyController {
 
         return wxNotifyReturnDTO;
     }
-
     /**
      * 电影回调接口
      */
     @PostMapping(value = "/filmOrder")
     @ApiOperation("电影订单回调")
-    public FilmNotifyReturnDTO filmOrderNotify(FilmOrderNotifyDTO filmOrderNotifyDTO) {
+    public FilmNotifyReturnDTO filmOrderNotify(FilmOrderNotifyDTO filmOrderNotifyDTO ,String sign, String appKey) {
         FilmOrder filmOrder = filmOrderService.getByOutTradeNo(filmOrderNotifyDTO.getThirdOrderId());
        //todo 检查sign
-        filmOrder.setOrderState(filmOrderNotifyDTO.getEventName());
-        if (filmOrderNotifyDTO.getOrderPrice()!= null)
-        filmOrder.setOrderPrice(Integer.valueOf(filmOrderNotifyDTO.getOrderPrice()));
-        if (filmOrderNotifyDTO.getCloseCause()!= null)
-        filmOrder.setCloseCause(filmOrderNotifyDTO.getCloseCause());
-        if (filmOrderNotifyDTO.getRealSeat()!= null)
-        filmOrder.setRealSeat(filmOrderNotifyDTO.getRealSeat());
-        if (filmOrderNotifyDTO.getTicketCode()!= null)
-        filmOrder.setTicketCode(filmOrderNotifyDTO.getTicketCode());
-        if (filmOrderNotifyDTO.getTicketImage()!= null)
-        filmOrder.setTicketImage(filmOrderNotifyDTO.getTicketImage());
+        String orderDataJson = filmOrder.getOrderDataJson();
+        FilmOrderJsonData filmOrderJsonData = JSONObject.parseObject(orderDataJson, FilmOrderJsonData.class);
+        FilmOrderNotifyDTO dbFilmOrderNotifyDTO= filmOrderJsonData.getFilmOrderNotifyDTO();
+        if (dbFilmOrderNotifyDTO == null){
+            dbFilmOrderNotifyDTO = filmOrderNotifyDTO;
+        }else{
+            dbFilmOrderNotifyDTO.setEventName(filmOrderNotifyDTO.getEventName());
+            if (filmOrderNotifyDTO.getOrderPrice()!= null)
+                dbFilmOrderNotifyDTO.setOrderPrice(filmOrderNotifyDTO.getOrderPrice());
+            if (filmOrderNotifyDTO.getCloseCause()!= null)
+                dbFilmOrderNotifyDTO.setCloseCause(filmOrderNotifyDTO.getCloseCause());
+            if (filmOrderNotifyDTO.getRealSeat()!= null)
+                dbFilmOrderNotifyDTO.setRealSeat(filmOrderNotifyDTO.getRealSeat());
+            if (filmOrderNotifyDTO.getTicketCode()!= null)
+                dbFilmOrderNotifyDTO.setTicketCode(filmOrderNotifyDTO.getTicketCode());
+            if (filmOrderNotifyDTO.getTicketImage()!= null)
+                dbFilmOrderNotifyDTO.setTicketImage(filmOrderNotifyDTO.getTicketImage());
+        }
+        filmOrderJsonData.setFilmOrderNotifyDTO(dbFilmOrderNotifyDTO);
+        filmOrder.setOrderDataJson(JSONObject.toJSONString(filmOrderJsonData));
+        UserInfo student = SecurityUtils.getLoginUser().getStudent();
+        Long id = student.getId();
+        String refundCode = getOrderCode(id);
+        //如果回调回来的订单关闭,则调用退款
+        if ("ORDER_CLOSE".equals(filmOrderNotifyDTO.getEventName())){
+        threadPoolTaskExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    refundRecordService.refund(filmOrder,refundCode);
+                } catch (Exception e) {
+                    log.info(e.getMessage());
+                }
+            }
+        });
+
+        }
+        filmOrder.setOutRefundNo(refundCode);
         filmOrderService.updateById(filmOrder);
 
 
+
         FilmNotifyReturnDTO filmNotifyReturnDTO = new FilmNotifyReturnDTO();
         filmNotifyReturnDTO.setCode("200");
         filmNotifyReturnDTO.setMessage("请求成功");
@@ -114,16 +151,18 @@ public class NotifyController {
     @ApiOperation("电影订单下单测试")
     public Response<String> filmOrderNotifytest(String outTradeNo) throws GeneralSecurityException, IOException {
         String s = "";
-        FilmOrder filmOrder = filmOrderService.getByOutTradeNo(outTradeNo);
+        FilmOrder filmOrder1 = filmOrderService.getByOutTradeNo(outTradeNo);
         FilmDTO filmDTO = new FilmDTO();
         filmDTO.setUrl("api/order/create");
         StringBuffer paramData =  new StringBuffer();
+        FilmOrderJsonData filmOrderJsonData = JSONObject.parseObject(filmOrder1.getOrderDataJson(), FilmOrderJsonData.class);
+        FilmOrderCreateDTO filmOrder = filmOrderJsonData.getFilmOrderCreateDTO();
         paramData.append("showId="+filmOrder.getShowId()+"&");
         paramData.append("seat="+filmOrder.getSeat()+"&");
         if (filmOrder.getReservedPhone() != null){
             paramData.append("reservedPhone="+filmOrder.getReservedPhone()+"&");
         }
-        paramData.append("thirdOrderId="+filmOrder.getOutTradeNo()+"&");
+        paramData.append("thirdOrderId="+filmOrder.getThirdOrderId()+"&");
         paramData.append("notifyUrl="+notifyUrl+"&");
         if (filmOrder.getSeatId() != null){
             paramData.append("seatId="+filmOrder.getSeatId()+"&");
@@ -154,7 +193,7 @@ public class NotifyController {
         filmOrder.setTotal(amount.getInteger("total"));
         filmOrder.setCurrency(amount.getString("currency"));
         filmOrder.setPayerCurrency(amount.getString("payer_currency"));
-        filmOrder.setTradeState(jsonObject.getString("SUCCESS"));
+        filmOrder.setTradeState(jsonObject.getString("trade_state"));
         filmOrder.setBankType(jsonObject.getString("bank_type"));
         DateTime dateTime  = new DateTime(jsonObject.getString("success_time"));
         filmOrder.setSuccessTime(dateTime.toDate());
@@ -166,20 +205,22 @@ public class NotifyController {
             filmOrder.setDeviceId(sceneInfo.getString("device_id"));
         }
         //如果订单还未下过电影票订单,则异步调用电影下单api
-        String orderState = filmOrder.getOrderState();
-        if (orderState == null){
+        String  orderDataJson= filmOrder.getOrderDataJson();
+        FilmOrderJsonData filmOrderJsonData = JSONObject.parseObject(orderDataJson, FilmOrderJsonData.class);
+        if (filmOrderJsonData != null && filmOrderJsonData.getFilmOrderNotifyDTO() == null){
             threadPoolTaskExecutor.execute(new Runnable() {
                 @Override
                 public void run() {
                     FilmDTO filmDTO = new FilmDTO();
                     filmDTO.setUrl("api/order/create");
                     StringBuffer paramData =  new StringBuffer();
+                    FilmOrderCreateDTO filmOrder = filmOrderJsonData.getFilmOrderCreateDTO();
                     paramData.append("showId="+filmOrder.getShowId()+"&");
                     paramData.append("seat="+filmOrder.getSeat()+"&");
                     if (filmOrder.getReservedPhone() != null){
                         paramData.append("reservedPhone="+filmOrder.getReservedPhone()+"&");
                     }
-                    paramData.append("thirdOrderId="+filmOrder.getOutTradeNo()+"&");
+                    paramData.append("thirdOrderId="+filmOrder.getThirdOrderId()+"&");
                     paramData.append("notifyUrl="+notifyUrl+"&");
                     if (filmOrder.getSeatId() != null){
                         paramData.append("seatId="+filmOrder.getSeatId()+"&");
@@ -199,11 +240,8 @@ public class NotifyController {
 
         filmOrderService.updateById(filmOrder);
     }
-    @Data
-    public class WxNotifyReturnDTO {
-        String code;
-        String message;
-    }
+
+
 
     @Data
     public class FilmNotifyReturnDTO {

+ 1 - 0
zzjs-admin/src/main/resources/application-dev.yml

@@ -105,6 +105,7 @@ cos:
 # 微信支付
 wxpay:
     v3url: https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi
+    v3urlRefund: https://api.mch.weixin.qq.com/v3/refund/domestic/refunds
     merchantId: 1608699504
     serialNumber: 487159E168001CDBA0EFE2C988249A84023AD6CC
     v3key: qqwweerrttyyuuiioopp123456789000

+ 1 - 0
zzjs-admin/src/main/resources/application-prod.yml

@@ -105,6 +105,7 @@ cos:
 # 微信支付
 wxpay:
     v3url: https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi
+    v3urlRefund: https://api.mch.weixin.qq.com/v3/refund/domestic/refunds
     merchantId: 1608699504
     serialNumber: 487159E168001CDBA0EFE2C988249A84023AD6CC
     v3key: qqwweerrttyyuuiioopp123456789000

+ 10 - 1
zzjs-admin/src/test/java/com/miaxis/test/NormalTest.java

@@ -1,18 +1,27 @@
 package com.miaxis.test;
 
 import com.miaxis.ZzjsApplication;
+import com.miaxis.film.domain.FilmOrder;
+import com.miaxis.film.service.IFilmOrderService;
+import com.miaxis.film.service.IRefundRecordService;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
 @SpringBootTest(classes = ZzjsApplication.class)
 @RunWith(SpringRunner.class)
 public class NormalTest {
+    @Autowired
+    private IFilmOrderService filmOrderService;
 
+    @Autowired
+    private IRefundRecordService refundRecordService;
     @Test
     public void test1() throws Exception {
-
+        FilmOrder filmOrder = filmOrderService.getByOutTradeNo("12021051815555556348172644409486");
+        refundRecordService.refund(filmOrder,"12021051815333778448136985596487");
     }
 
 

+ 2 - 0
zzjs-common/src/main/java/com/miaxis/common/config/WxpayConfig.java

@@ -10,7 +10,9 @@ import org.springframework.stereotype.Component;
 public class WxpayConfig {
 
     private String v3url;
+    private String v3urlRefund;
     private String merchantId;
     private String serialNumber;
     private String v3key;
+
 }

+ 1 - 1
zzjs-framework/src/main/java/com/miaxis/framework/web/exception/GlobalExceptionHandler.java

@@ -107,7 +107,7 @@ public class GlobalExceptionHandler
     public Response handleException(Exception e)
     {
         log.error(e.getMessage(), e);
-        return Response.error().setMsg(toString());
+        return Response.error().setMsg(e.getMessage());
     }
 //    /**
 //     * 演示模式异常

+ 117 - 0
zzjs-service/src/main/java/com/miaxis/film/controller/RefundRecordController.java

@@ -0,0 +1,117 @@
+package com.miaxis.film.controller;
+
+import com.miaxis.common.constant.Constants;
+import java.util.List;
+import java.util.Arrays;
+import io.swagger.annotations.*;
+import com.miaxis.common.core.domain.Response;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import com.miaxis.common.annotation.Log;
+import com.miaxis.common.core.controller.BaseController;
+import com.miaxis.common.enums.BusinessTypeEnum;
+import com.miaxis.film.domain.RefundRecord;
+import com.miaxis.film.service.IRefundRecordService;
+import com.miaxis.common.utils.poi.ExcelUtil;
+import com.miaxis.common.core.page.ResponsePageInfo;
+
+/**
+ * 【微信退款记录】Controller
+ *
+ * @author miaxis
+ * @date 2021-05-18
+ */
+@RestController
+@RequestMapping("/film/record")
+@Api(tags={"【小程序-微信退款记录】"})
+public class RefundRecordController extends BaseController{
+    @Autowired
+    private IRefundRecordService refundRecordService;
+
+    /**
+     * 查询微信退款记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('film:record:list')")
+    @GetMapping("/list")
+    @ApiOperation("查询微信退款记录列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "pageNum",value = "当前页码" ,dataType = "int", paramType = "query", required = false),
+            @ApiImplicitParam(name = "pageSize",value = "每页数据量" , dataType = "int", paramType = "query", required = false),
+    })
+    public ResponsePageInfo<RefundRecord> list(@ModelAttribute RefundRecord refundRecord){
+        startPage();
+        List<RefundRecord> list = refundRecordService.selectRefundRecordList(refundRecord);
+        return toResponsePageInfo(list);
+    }
+
+    /**
+     * 导出微信退款记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('film:record:export')")
+    @Log(title = "微信退款记录", businessType = BusinessTypeEnum.EXPORT)
+    @GetMapping("/export")
+    @ApiOperation("导出微信退款记录列表Excel")
+    public Response<String> export(@ModelAttribute RefundRecord refundRecord){
+        List<RefundRecord> list = refundRecordService.selectRefundRecordList(refundRecord);
+        ExcelUtil<RefundRecord> util = new ExcelUtil<RefundRecord>(RefundRecord.class);
+        return util.exportExcel(list, "record");
+    }
+
+    /**
+     * 获取微信退款记录详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('film:record:query')")
+    @GetMapping(value = "/{id}")
+    @ApiOperation("获取微信退款记录详细信息")
+    public Response<RefundRecord> getInfo(
+            @ApiParam(name = "id", value = "微信退款记录参数", required = true)
+            @PathVariable("id") Long id
+    ){
+        return Response.success(refundRecordService.getById(id));
+    }
+
+    /**
+     * 新增微信退款记录
+     */
+    @PreAuthorize("@ss.hasPermi('film:record:add')")
+    @Log(title = "微信退款记录", businessType = BusinessTypeEnum.INSERT)
+    @PostMapping
+    @ApiOperation("新增微信退款记录")
+    public Response<Integer> add(@RequestBody RefundRecord refundRecord){
+        return toResponse(refundRecordService.save(refundRecord) ? 1 : 0);
+    }
+
+    /**
+     * 修改微信退款记录
+     */
+    @PreAuthorize("@ss.hasPermi('film:record:edit')")
+    @Log(title = "微信退款记录", businessType = BusinessTypeEnum.UPDATE)
+    @PutMapping
+    @ApiOperation("修改微信退款记录")
+    public Response<Integer> edit(@RequestBody RefundRecord refundRecord){
+        return toResponse(refundRecordService.updateById(refundRecord) ? 1 : 0);
+    }
+
+    /**
+     * 删除微信退款记录
+     */
+    @PreAuthorize("@ss.hasPermi('film:record:remove')")
+    @Log(title = "微信退款记录", businessType = BusinessTypeEnum.DELETE)
+	@DeleteMapping("/{ids}")
+    @ApiOperation("删除微信退款记录")
+    public  Response<Integer> remove(
+            @ApiParam(name = "ids", value = "微信退款记录ids参数", required = true)
+            @PathVariable Long[] ids
+    ){
+        return toResponse(refundRecordService.removeByIds(Arrays.asList(ids)) ? 1 : 0);
+    }
+}

+ 31 - 87
zzjs-service/src/main/java/com/miaxis/film/domain/FilmOrder.java

@@ -34,6 +34,12 @@ public class FilmOrder extends BaseBusinessEntity{
     @ApiModelProperty(value = "商户订单号")
     private String outTradeNo;
 
+    /** 退款单号 */
+    @Excel(name = "退款单号")
+    @TableField("out_refund_no")
+    @ApiModelProperty(value = "退款单号")
+    private String outRefundNo;
+
     /** 微信支付系统生成的订单号 */
     @Excel(name = "微信支付系统生成的订单号")
     @TableField("transaction_id")
@@ -47,14 +53,14 @@ public class FilmOrder extends BaseBusinessEntity{
     private String tradeType;
 
     /** 交易状态,枚举值:
-SUCCESS:支付成功
-REFUND:转入退款
-NOTPAY:未支付
-CLOSED:已关闭
-REVOKED:已撤销(付款码支付)
-USERPAYING:用户支付中(付款码支付)
-PAYERROR:支付失败(其他原因,如银行返回失败)
-ACCEPT:已接收,等待扣款 */
+        SUCCESS:支付成功
+        REFUND:转入退款
+        NOTPAY:未支付
+        CLOSED:已关闭
+        REVOKED:已撤销(付款码支付)
+        USERPAYING:用户支付中(付款码支付)
+        PAYERROR:支付失败(其他原因,如银行返回失败)
+        ACCEPT:已接收,等待扣款 */
     @TableField("trade_state")
     @ApiModelProperty(value = "交易状态,枚举值: SUCCESS:支付成功 REFUND:转入退款 NOTPAY:" +
             "未支付 CLOSED:已关闭 REVOKED:已撤销(付款码支付) " +
@@ -92,10 +98,16 @@ ACCEPT:已接收,等待扣款 */
     private String openid;
 
     /** 商品名称 */
-    @Excel(name = "商品名称")
-    @TableField("goods_name")
-    @ApiModelProperty(value = "商品名称")
-    private String goodsName;
+    @Excel(name = "商品类型")
+    @TableField("goods_type")
+    @ApiModelProperty(value = "商品类型,具体查看字典定义.")
+    private String goodsType;
+
+    /** 商品名称 */
+    @Excel(name = "商品图片地址")
+    @TableField("goods_picture_url")
+    @ApiModelProperty(value = "商品图片地址")
+    private String goodsPictureUrl;
 
     /** 订单总金额,单位为分。 */
     @Excel(name = "订单总金额,单位为分。")
@@ -127,82 +139,14 @@ ACCEPT:已接收,等待扣款 */
     @ApiModelProperty(value = "商户端设备号")
     private String deviceId;
 
+
     /** 商户端设备号 */
-    @Excel(name = "排期的showId,由影院接口得来")
-    @TableField("show_id")
-    @ApiModelProperty(value = "排期的showId,由影院接口得来")
-    private String showId;
-
-    /** 用户所选的座位,例:1排1座,1排2座 以英文的逗号 “ , “隔开。 如果座位是情侣座,请传入 : 1排1座(情侣座),1排2座(情侣座) */
-    @Excel(name = "用户所选的座位,例:1排1座,1排2座 以英文的逗号 “ , “隔开。 如果座位是情侣座,请传入 : 1排1座(情侣座),1排2座(情侣座)")
-    @TableField("seat")
-    @ApiModelProperty(value = "用户所选的座位,例:1排1座,1排2座 以英文的逗号 “ , “隔开。 如果座位是情侣座,请传入 : 1排1座(情侣座),1排2座(情侣座)")
-    private String seat;
-
-    /** 预留的手机号 */
-    @Excel(name = "预留的手机号")
-    @TableField("reserved_phone")
-    @ApiModelProperty(value = "预留的手机号")
-    private String reservedPhone;
-
-    /** 是否允许调座,1-允许,0-不允许 */
-    @Excel(name = "是否允许调座,1-允许,0-不允许")
-    @TableField("accept_change_seat")
-    @ApiModelProperty(value = "是否允许调座,1-允许,0-不允许")
-    private Integer acceptChangeSeat;
-
-    /** 座位接口的seatId字段, 如果有多个,则以竖线分割 */
-    @Excel(name = "座位接口的seatId字段, 如果有多个,则以竖线分割")
-    @TableField("seat_id")
-    @ApiModelProperty(value = "座位接口的seatId字段, 如果有多个,则以竖线分割")
-    private String seatId;
-
-    /** 座位接口的seatNo字段,如果有多个,则以竖线分割 */
-    @Excel(name = "座位接口的seatNo字段,如果有多个,则以竖线分割")
-    @TableField("seat_no")
-    @ApiModelProperty(value = "座位接口的seatNo字段,如果有多个,则以竖线分割")
-    private String seatNo;
-
-    /** 订单状态,枚举值:
-ORDER_CLOSE  关闭
-ORDER_FINISH  订单正常处理完毕
-WAIT_TICKET 订单竞价结束,正在等待出票
-TICKET_SUCCESS 订单出票成功
-TICKET_SYNC 取票码出现意外情况,需要修改时 */
-    @TableField("order_state")
-    @ApiModelProperty(value = "订单状态,枚举值: ORDER_CLOSE  关闭 ORDER_FINISH  订单正常处理完毕" +
-            " WAIT_TICKET 订单竞价结束,正在等待出票 TICKET_SUCCESS 订单出票成功 TICKET_SYNC 取票码出现意外情况,需要修改时")
-    private String orderState;
-
-    /** api下单成本价 */
-    @Excel(name = "api下单成本价")
-    @TableField("order_price")
-    @ApiModelProperty(value = "api下单成本价")
-    private Integer orderPrice;
-
-    /** 订单关闭原因 */
-    @Excel(name = "订单关闭原因")
-    @TableField("close_cause")
-    @ApiModelProperty(value = "订单关闭原因")
-    private String closeCause;
-
-    /** 实际出票位置 */
-    @Excel(name = "实际出票位置")
-    @TableField("real_seat")
-    @ApiModelProperty(value = "实际出票位置")
-    private String realSeat;
-
-    /** 取票字符串 */
-    @Excel(name = "取票字符串")
-    @TableField("ticket_code")
-    @ApiModelProperty(value = "取票字符串")
-    private String ticketCode;
-
-    /** 取票码原始截图 */
-    @Excel(name = "取票码原始截图")
-    @TableField("ticket_image")
-    @ApiModelProperty(value = "取票码原始截图")
-    private String ticketImage;
+    @Excel(name = "订单数据详情")
+    @TableField("order_data_json")
+    @ApiModelProperty(value = "订单数据详情")
+    private String orderDataJson;
+
+
 
 
 }

+ 143 - 0
zzjs-service/src/main/java/com/miaxis/film/domain/RefundRecord.java

@@ -0,0 +1,143 @@
+package com.miaxis.film.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.miaxis.common.annotation.Excel;
+import com.miaxis.common.core.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.miaxis.common.core.domain.BaseBusinessEntity;
+import lombok.Data;
+/**
+ * 微信退款记录对象 refund_record
+ *
+ * @author miaxis
+ * @date 2021-05-18
+ */
+@Data
+@TableName("refund_record")
+@ApiModel(value = "RefundRecord", description = "微信退款记录对象 refund_record")
+public class RefundRecord extends BaseBusinessEntity{
+    private static final long serialVersionUID = 1L;
+
+    /** 记录id */
+    @TableId(value = "id")
+    @ApiModelProperty(value = "记录id")
+    private Long id;
+
+    /** 微信支付退款号 */
+    @Excel(name = "微信支付退款号")
+    @TableField("refund_id")
+    @ApiModelProperty(value = "微信支付退款号")
+    private String refundId;
+
+    /** 退款单号 */
+    @Excel(name = "退款单号")
+    @TableField("out_refund_no")
+    @ApiModelProperty(value = "退款单号")
+    private String outRefundNo;
+
+    /** 微信支付订单号 */
+    @Excel(name = "微信支付订单号")
+    @TableField("transaction_id")
+    @ApiModelProperty(value = "微信支付订单号")
+    private String transactionId;
+
+    /** 商户订单号 */
+    @Excel(name = "商户订单号")
+    @TableField("out_trade_no")
+    @ApiModelProperty(value = "商户订单号")
+    private String outTradeNo;
+
+    /** 枚举值:
+ORIGINAL:原路退款
+BALANCE:退回到余额
+OTHER_BALANCE:原账户异常退到其他余额账户
+OTHER_BANKCARD:原银行卡异常退到其他银行卡
+示例值:ORIGINAL */
+    @Excel(name = "枚举值: ORIGINAL:原路退款 BALANCE:退回到余额 OTHER_BALANCE:原账户异常退到其他余额账户 OTHER_BANKCARD:原银行卡异常退到其他银行卡 示例值:ORIGINAL")
+    @TableField("channel")
+    @ApiModelProperty(value = "枚举值: ORIGINAL:原路退款 BALANCE:退回到余额 OTHER_BALANCE:原账户异常退到其他余额账户 OTHER_BANKCARD:原银行卡异常退到其他银行卡 示例值:ORIGINAL")
+    private String channel;
+
+    /** 退款入账账户 */
+    @Excel(name = "退款入账账户")
+    @TableField("user_received_account")
+    @ApiModelProperty(value = "退款入账账户")
+    private String userReceivedAccount;
+
+    /** 退款成功时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "退款成功时间", width = 30, dateFormat = "yyyy-MM-dd")
+    @TableField("success_time")
+    @ApiModelProperty(value = "退款成功时间")
+    private Date successTime;
+
+    /** 退款状态枚举值:SUCCESS:退款成功CLOSED:退款关闭PROCESSING:退款处理中ABNORMAL:退款异常 */
+    @Excel(name = "退款状态 枚举值: SUCCESS:退款成功 CLOSED:退款关闭 PROCESSING:退款处理中 ABNORMAL:退款异常")
+    @TableField("status")
+    @ApiModelProperty(value = "退款状态 枚举值: SUCCESS:退款成功 CLOSED:退款关闭 PROCESSING:退款处理中 ABNORMAL:退款异常")
+    private String status;
+
+    /** 资金账户 */
+    @Excel(name = "资金账户")
+    @TableField("funds_account")
+    @ApiModelProperty(value = "资金账户")
+    private String fundsAccount;
+
+    /** 订单总金额,单位为分。
+示例值:100 */
+    @Excel(name = "订单总金额,单位为分。 示例值:100")
+    @TableField("total")
+    @ApiModelProperty(value = "订单总金额,单位为分。 示例值:100")
+    private Long total;
+
+    /** 退款标价金额,单位为分 */
+    @Excel(name = "退款标价金额,单位为分")
+    @TableField("refund")
+    @ApiModelProperty(value = "退款标价金额,单位为分")
+    private Long refund;
+
+    /** 现金支付金额 */
+    @Excel(name = "现金支付金额")
+    @TableField("payer_total")
+    @ApiModelProperty(value = "现金支付金额")
+    private Long payerTotal;
+
+    /** 退款给用户的金额,不包含所有优惠券金额 */
+    @Excel(name = "退款给用户的金额,不包含所有优惠券金额")
+    @TableField("payer_refund")
+    @ApiModelProperty(value = "退款给用户的金额,不包含所有优惠券金额")
+    private Long payerRefund;
+
+    /** 去掉非充值代金券退款金额后的退款金额 */
+    @Excel(name = "去掉非充值代金券退款金额后的退款金额")
+    @TableField("settlement_refund")
+    @ApiModelProperty(value = "去掉非充值代金券退款金额后的退款金额")
+    private Long settlementRefund;
+
+    /** 应结订单金额=订单金额-免充值代金券金额 */
+    @Excel(name = "应结订单金额=订单金额-免充值代金券金额")
+    @TableField("settlement_total")
+    @ApiModelProperty(value = "应结订单金额=订单金额-免充值代金券金额")
+    private Long settlementTotal;
+
+    /** 优惠退款金额&lt;=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见 */
+    @Excel(name = "优惠退款金额&lt;=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见")
+    @TableField("discount_refund")
+    @ApiModelProperty(value = "优惠退款金额&lt;=退款金额,退款金额-代金券或立减优惠退款金额为现金,说明详见")
+    private Long discountRefund;
+
+    /** 符合ISO 4217标准的三位字母代码,目前只支持人民币:CNY。 */
+    @Excel(name = "符合ISO 4217标准的三位字母代码,目前只支持人民币:CNY。")
+    @TableField("currency")
+    @ApiModelProperty(value = "符合ISO 4217标准的三位字母代码,目前只支持人民币:CNY。")
+    private String currency;
+
+}

+ 27 - 0
zzjs-service/src/main/java/com/miaxis/film/dto/CinemaData.java

@@ -0,0 +1,27 @@
+package com.miaxis.film.dto;
+
+
+import lombok.Data;
+
+
+/**
+ * 排期数据
+ */
+@Data
+public class CinemaData {
+    Integer netPrice;
+    String planType;
+    String showTime;
+    String language;
+    Integer duration;
+    String showId;
+    String stopSellTime;
+    Integer cinemaId;
+    String cinemaName;
+    Integer filmId;
+    String scheduleArea;
+    String filmName;
+    String hallName;
+    String showVersionType;
+
+}

+ 10 - 0
zzjs-service/src/main/java/com/miaxis/film/dto/FilmOrderCreateDTO.java

@@ -15,12 +15,22 @@ public class FilmOrderCreateDTO {
     @ApiModelProperty(value = "排期的showId,由影院接口得来")
     private String showId;
 
+    /** 商品名称 */
+    @ApiModelProperty(value = "商品类型")
+    private String goodsType;
+
+    /** 商品名称 */
+    @ApiModelProperty(value = "商品图片地址")
+    private String goodsPictureUrl;
+
     @ApiModelProperty(value = "影院id")
     private String cinemaId;
 
     @ApiModelProperty(value = "用户所选的座位,例:1排1座,1排2座 以英文的逗号 “ , “隔开。 如果座位是情侣座,请传入 : 1排1座(情侣座),1排2座(情侣座)")
     private String seat;
 
+    @ApiModelProperty(value = "商家订单id")
+    private String thirdOrderId;
 
     @ApiModelProperty(value = "预留的手机号")
     private String reservedPhone;

+ 28 - 0
zzjs-service/src/main/java/com/miaxis/film/dto/FilmOrderJsonData.java

@@ -0,0 +1,28 @@
+package com.miaxis.film.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 微信支付回调 dto
+ */
+@Data
+public class FilmOrderJsonData {
+    private static final long serialVersionUID = 1L;
+
+    //下单字段
+    private  FilmOrderCreateDTO filmOrderCreateDTO;
+    //电影排场信息
+    private CinemaData cinemaData;
+    //电影订单回调信息
+    private FilmOrderNotifyDTO filmOrderNotifyDTO ;
+
+
+
+
+
+
+
+
+
+}

+ 19 - 0
zzjs-service/src/main/java/com/miaxis/film/dto/FilmOrderListDTO.java

@@ -0,0 +1,19 @@
+package com.miaxis.film.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class FilmOrderListDTO {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "近几天的天数")
+    private Integer days;
+
+
+    @ApiModelProperty(value = "openid",hidden = true)
+    private String  openid;
+
+
+
+}

+ 0 - 4
zzjs-service/src/main/java/com/miaxis/film/dto/FilmOrderNotifyDTO.java

@@ -10,11 +10,7 @@ import lombok.Data;
 public class FilmOrderNotifyDTO {
     private static final long serialVersionUID = 1L;
 
-    @ApiModelProperty(value = "签名,接入方需校验签名是否有效。签名规则与下单相同。")
-    private String sign;
 
-    @ApiModelProperty(value = "接入方key (推广位)")
-    private String appKey;
 
     @ApiModelProperty(value = "时间戳")
     private String time;

+ 50 - 0
zzjs-service/src/main/java/com/miaxis/film/dto/FilmWxpayRefundDTO.java

@@ -0,0 +1,50 @@
+package com.miaxis.film.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 微信支付退款 dto
+ */
+@Data
+public class FilmWxpayRefundDTO {
+    private static final long serialVersionUID = 1L;
+
+
+    @ApiModelProperty(value = "商户订单号")
+    private String out_trade_no;
+
+    @ApiModelProperty(value = "商户系统内部的退款单号")
+    private String out_refund_no;
+
+
+    @ApiModelProperty(value = "原因")
+    private String reason;
+
+
+    @ApiModelProperty(value = "是否允许调座,1-允许,0-不允许")
+    private WxpaySource resource;
+
+    @ApiModelProperty(value = "回调摘要")
+    private String summary;
+
+
+    @Data
+    public class WxpaySource{
+        @ApiModelProperty(value = "对开启结果数据进行加密的加密算法,目前只支持AEAD_AES_256_GCM")
+        private String algorithm;
+        @ApiModelProperty(value = "Base64编码后的开启/停用结果数据密文")
+        private String ciphertext;
+        @ApiModelProperty(value = "附加数据")
+        private String associated_data;
+        @ApiModelProperty(value = "原始回调类型,为transaction")
+        private String original_type;
+        @ApiModelProperty(value = "加密使用的随机串")
+        private String nonce;
+
+
+    }
+
+
+
+}

+ 9 - 0
zzjs-service/src/main/java/com/miaxis/film/dto/WxNotifyReturnDTO.java

@@ -0,0 +1,9 @@
+package com.miaxis.film.dto;
+
+import lombok.Data;
+
+@Data
+public class WxNotifyReturnDTO {
+    String code;
+    String message;
+}

+ 3 - 0
zzjs-service/src/main/java/com/miaxis/film/mapper/FilmOrderMapper.java

@@ -3,6 +3,7 @@ package com.miaxis.film.mapper;
 import java.util.List;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.miaxis.film.domain.FilmOrder;
+import com.miaxis.film.dto.FilmOrderListDTO;
 
 /**
  * 电影订单Mapper接口
@@ -20,4 +21,6 @@ public interface FilmOrderMapper extends BaseMapper<FilmOrder> {
     public List<FilmOrder> selectFilmOrderList(FilmOrder filmOrder);
 
     FilmOrder getByOutTradeNo(String outTradeNo);
+
+    List<FilmOrder> selectOrderList(FilmOrderListDTO filmOrderListDTO);
 }

+ 22 - 0
zzjs-service/src/main/java/com/miaxis/film/mapper/RefundRecordMapper.java

@@ -0,0 +1,22 @@
+package com.miaxis.film.mapper;
+
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.miaxis.film.domain.RefundRecord;
+
+/**
+ * 微信退款记录Mapper接口
+ *
+ * @author miaxis
+ * @date 2021-05-18
+ */
+public interface RefundRecordMapper extends BaseMapper<RefundRecord> {
+    /**
+     * 查询微信退款记录列表
+     *
+     * @param refundRecord 微信退款记录
+     * @return 微信退款记录集合
+     */
+    public List<RefundRecord> selectRefundRecordList(RefundRecord refundRecord);
+
+}

+ 5 - 0
zzjs-service/src/main/java/com/miaxis/film/service/IFilmOrderService.java

@@ -6,6 +6,7 @@ import java.util.List;
 import com.miaxis.feign.dto.FilmDTO;
 import com.miaxis.film.domain.FilmOrder;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.miaxis.film.dto.FilmOrderListDTO;
 
 /**
  * 电影订单Service接口
@@ -25,4 +26,8 @@ public interface IFilmOrderService extends IService<FilmOrder>{
     FilmOrder getByOutTradeNo(String outTradeNo);
 
     String excuteFilmApi(FilmDTO filmDTO) ;
+
+    List<FilmOrder> selectOrderList(FilmOrderListDTO filmOrderListDTO);
+
+
 }

+ 26 - 0
zzjs-service/src/main/java/com/miaxis/film/service/IRefundRecordService.java

@@ -0,0 +1,26 @@
+package com.miaxis.film.service;
+
+import java.util.List;
+
+import com.miaxis.film.domain.FilmOrder;
+import com.miaxis.film.domain.RefundRecord;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.miaxis.film.dto.WxNotifyReturnDTO;
+
+/**
+ * 微信退款记录Service接口
+ *
+ * @author miaxis
+ * @date 2021-05-18
+ */
+public interface IRefundRecordService extends IService<RefundRecord>{
+    /**
+     * 查询微信退款记录列表
+     *
+     * @param refundRecord 微信退款记录
+     * @return 微信退款记录集合
+     */
+    public List<RefundRecord> selectRefundRecordList(RefundRecord refundRecord);
+
+    WxNotifyReturnDTO refund(FilmOrder filmOrder, String refundCode) throws Exception;
+}

+ 9 - 0
zzjs-service/src/main/java/com/miaxis/film/service/impl/FilmOrderServiceImpl.java

@@ -13,8 +13,10 @@ import com.miaxis.common.sms.MD5Utils;
 import com.miaxis.common.utils.DateUtils;
 import com.miaxis.common.utils.StringUtils;
 import com.miaxis.feign.dto.FilmDTO;
+import com.miaxis.film.dto.FilmOrderListDTO;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
+import org.apache.http.client.HttpClient;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.impl.client.CloseableHttpClient;
@@ -54,6 +56,8 @@ public class FilmOrderServiceImpl extends ServiceImpl<FilmOrderMapper, FilmOrder
     private  String v2Url ;
 
 
+
+
     /**
      * 查询电影订单列表
      *
@@ -137,4 +141,9 @@ public class FilmOrderServiceImpl extends ServiceImpl<FilmOrderMapper, FilmOrder
         }
 
     }
+
+    @Override
+    public List<FilmOrder> selectOrderList(FilmOrderListDTO filmOrderListDTO) {
+        return filmOrderMapper.selectOrderList(filmOrderListDTO);
+    }
 }

+ 87 - 0
zzjs-service/src/main/java/com/miaxis/film/service/impl/RefundRecordServiceImpl.java

@@ -0,0 +1,87 @@
+package com.miaxis.film.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.miaxis.common.config.WxpayConfig;
+import com.miaxis.common.exception.CustomException;
+import com.miaxis.film.domain.FilmOrder;
+import com.miaxis.film.domain.RefundRecord;
+import com.miaxis.film.dto.WxNotifyReturnDTO;
+import com.miaxis.film.mapper.RefundRecordMapper;
+import com.miaxis.film.service.IRefundRecordService;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.util.EntityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.ByteArrayOutputStream;
+import java.util.List;
+
+/**
+ * 微信退款记录Service业务层处理
+ *
+ * @author miaxis
+ * @date 2021-05-18
+ */
+@Service
+public class RefundRecordServiceImpl extends ServiceImpl<RefundRecordMapper, RefundRecord> implements IRefundRecordService {
+    @Resource
+    private RefundRecordMapper refundRecordMapper;
+
+    @Autowired
+    private HttpClient httpClient;
+
+
+    @Autowired
+    private WxpayConfig wxpayConfig;
+    /**
+     * 查询微信退款记录列表
+     *
+     * @param refundRecord 微信退款记录
+     * @return 微信退款记录
+     */
+    @Override
+    public List<RefundRecord> selectRefundRecordList(RefundRecord refundRecord){
+        return refundRecordMapper.selectRefundRecordList(refundRecord);
+    }
+
+    @Override
+    public WxNotifyReturnDTO refund(FilmOrder filmOrder, String refundCode) throws Exception{
+        HttpPost httpPost = new HttpPost(wxpayConfig.getV3urlRefund());
+        httpPost.addHeader("Accept", "application/json");
+        httpPost.addHeader("Content-type","application/json; charset=utf-8");
+        ObjectMapper objectMapper = new ObjectMapper();
+        ObjectNode rootNode = objectMapper.createObjectNode();
+
+        rootNode.put("out_trade_no", filmOrder.getOutTradeNo())
+                .put("out_refund_no", refundCode)
+                .put("reason", "电影购票失败");
+        rootNode.putObject("amount")
+                .put("refund", filmOrder.getTotal())
+                .put("total", filmOrder.getTotal())
+                .put("currency", filmOrder.getCurrency());
+        System.out.println(rootNode.toString());
+//        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+//        objectMapper.writeValue(bos, rootNode);
+        httpPost.setEntity(new StringEntity(rootNode.toString()));
+        HttpResponse response = httpClient.execute(httpPost);
+        // 返回数据:
+        String bodyAsString = EntityUtils.toString(response.getEntity());
+        if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
+            //to-do  保存数据到数据库
+            WxNotifyReturnDTO wxNotifyReturnDTO = new WxNotifyReturnDTO();
+            wxNotifyReturnDTO.setCode("SUCCESS");
+            wxNotifyReturnDTO.setMessage("成功");
+            return wxNotifyReturnDTO;
+        }else{
+            throw new CustomException(bodyAsString);
+        }
+
+    }
+}

+ 10 - 0
zzjs-service/src/main/resources/mapper/film/FilmOrderMapper.xml

@@ -77,4 +77,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </where>
     </select>
 
+
+    <select id="selectOrderList" resultType="com.miaxis.film.domain.FilmOrder">
+        select * from film_order
+         where openid=#{openid} and trade_state ='SUCCESS'
+        <if test="days != null  and days != ''">
+            and  DATE_SUB(CURDATE(), INTERVAL #{days} DAY) &lt;= date(create_time)
+        </if>
+         order by create_time desc
+    </select>
+
 </mapper>

+ 57 - 0
zzjs-service/src/main/resources/mapper/film/RefundRecordMapper.xml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.miaxis.film.mapper.RefundRecordMapper">
+
+    <resultMap type="RefundRecord" id="RefundRecordResult">
+        <result property="id"    column="id"    />
+        <result property="refundId"    column="refund_id"    />
+        <result property="outRefundNo"    column="out_refund_no"    />
+        <result property="transactionId"    column="transaction_id"    />
+        <result property="outTradeNo"    column="out_trade_no"    />
+        <result property="channel"    column="channel"    />
+        <result property="userReceivedAccount"    column="user_received_account"    />
+        <result property="successTime"    column="success_time"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="status"    column="status"    />
+        <result property="fundsAccount"    column="funds_account"    />
+        <result property="total"    column="total"    />
+        <result property="refund"    column="refund"    />
+        <result property="payerTotal"    column="payer_total"    />
+        <result property="payerRefund"    column="payer_refund"    />
+        <result property="settlementRefund"    column="settlement_refund"    />
+        <result property="settlementTotal"    column="settlement_total"    />
+        <result property="discountRefund"    column="discount_refund"    />
+        <result property="currency"    column="currency"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectRefundRecordVo">
+        select * from refund_record
+    </sql>
+
+    <select id="selectRefundRecordList" parameterType="RefundRecord" resultMap="RefundRecordResult">
+        <include refid="selectRefundRecordVo"/>
+        <where>
+            <if test="refundId != null  and refundId != ''"> and refund_id = #{refundId}</if>
+            <if test="outRefundNo != null  and outRefundNo != ''"> and out_refund_no = #{outRefundNo}</if>
+            <if test="transactionId != null  and transactionId != ''"> and transaction_id = #{transactionId}</if>
+            <if test="outTradeNo != null  and outTradeNo != ''"> and out_trade_no = #{outTradeNo}</if>
+            <if test="channel != null  and channel != ''"> and channel = #{channel}</if>
+            <if test="userReceivedAccount != null  and userReceivedAccount != ''"> and user_received_account = #{userReceivedAccount}</if>
+            <if test="successTime != null "> and success_time = #{successTime}</if>
+            <if test="status != null  and status != ''"> and status = #{status}</if>
+            <if test="fundsAccount != null  and fundsAccount != ''"> and funds_account = #{fundsAccount}</if>
+            <if test="total != null "> and total = #{total}</if>
+            <if test="refund != null "> and refund = #{refund}</if>
+            <if test="payerTotal != null "> and payer_total = #{payerTotal}</if>
+            <if test="payerRefund != null "> and payer_refund = #{payerRefund}</if>
+            <if test="settlementRefund != null "> and settlement_refund = #{settlementRefund}</if>
+            <if test="settlementTotal != null "> and settlement_total = #{settlementTotal}</if>
+            <if test="discountRefund != null "> and discount_refund = #{discountRefund}</if>
+            <if test="currency != null  and currency != ''"> and currency = #{currency}</if>
+        </where>
+    </select>
+
+</mapper>