소스 검색

Merge remote-tracking branch 'origin/master'

小么熊🐻 4 년 전
부모
커밋
8c5fb986a7

+ 93 - 33
zzjs-admin/src/main/java/com/miaxis/app/controller/film/FilmController.java

@@ -10,6 +10,7 @@ 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.sms.MD5Utils;
 import com.miaxis.common.utils.SecurityUtils;
 import com.miaxis.common.utils.StringUtils;
@@ -18,17 +19,19 @@ import com.miaxis.customer.dto.AppletCustomerInfoDto;
 import com.miaxis.customer.service.ICustomerInfoService;
 import com.miaxis.customer.vo.ExhibitionCustomerInfoVo;
 import com.miaxis.feign.dto.FilmDTO;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
-import io.swagger.annotations.ApiOperation;
+import com.miaxis.film.domain.FilmOrder;
+import com.miaxis.film.dto.FilmOrderCreateDTO;
+import com.miaxis.film.service.IFilmOrderService;
+import io.swagger.annotations.*;
 import lombok.Data;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.RandomStringUtils;
 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.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.CloseableHttpClient;
@@ -38,14 +41,18 @@ import org.apache.http.util.EntityUtils;
 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;
 import java.io.File;
+import java.io.IOException;
 import java.security.PrivateKey;
 import java.security.Signature;
 import java.util.*;
 
+import static com.miaxis.common.utils.OrderCodeFactory.getOrderCode;
+
 /**
  * 【小程序-客户信息】Controller
  *
@@ -56,6 +63,7 @@ import java.util.*;
 @RequiredArgsConstructor
 @RequestMapping(Constants.STUDENT_PREFIX+"/film/wxpay")
 @Api(tags = {"【小程序-电影】"})
+@Slf4j
 public class FilmController extends BaseController {
 
     @Autowired
@@ -64,21 +72,26 @@ public class FilmController extends BaseController {
     @Autowired
     private WxpayConfig wxpayConfig;
 
+    @Autowired
+    private IFilmOrderService filmOrderService;
+
     @Value("${app.appid}")
     private String appid;
-
-    private static String appKey = "10000000000";
-
-    private static String appSecret = "25f9e794323b453885f5181f1b624d0b";
+    @Value("${film.appKey}")
+    private  String appKey ;
+    @Value("${film.appSecret}")
+    private  String appSecret ;
+    @Value("${film.notifyUrl}")
+    private  String notifyUrl ;
 
 
 
     /**
      * 微信支付获取预订单id
      */
-    @GetMapping(value = "/prepareOrder")
+    @PostMapping(value = "/prepareOrder")
     @ApiOperation("微信支付获取预订单id")
-    public Response<JSONObject> getPrepareOrderId() throws Exception{
+    public Response<JSONObject> getPrepareOrderId(@RequestBody FilmOrderCreateDTO filmOrderCreateDTO) throws Exception{
         HttpPost httpPost = new HttpPost(wxpayConfig.getV3url());
         httpPost.addHeader("Accept", "application/json");
         httpPost.addHeader("Content-type","application/json; charset=utf-8");
@@ -86,20 +99,45 @@ public class FilmController extends BaseController {
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         ObjectMapper objectMapper = new ObjectMapper();
 
+        //生成订单id
+        UserInfo student = SecurityUtils.getLoginUser().getStudent();
+        Long id = student.getId();
+        String orderCode = getOrderCode(id);
+        log.info(appid);
+        log.info(notifyUrl);
+
+        //生成预订单
         ObjectNode rootNode = objectMapper.createObjectNode();
-        rootNode.put("mchid","1608699504")
-                .put("appid", "wx8f43db501343feab")
-                .put("description", "Image形象店-深圳腾大-QQ公仔")
-                .put("notify_url", "https://www.weixin.qq.com/wxpay/pay.php")
-                .put("out_trade_no", "1217752501201407033233368044");
+        rootNode.put("mchid",wxpayConfig.getMerchantId())
+                .put("appid", appid)
+                .put("description", "电影票")
+                .put("notify_url", notifyUrl)
+                .put("out_trade_no", orderCode);
         rootNode.putObject("amount")
-                .put("total", 1);
+                .put("total", filmOrderCreateDTO.getTotal());
         rootNode.putObject("payer")
-                .put("openid", "oO7PJ5FlradAM7tqw3TM2zvEj4O4");
+                .put("openid", student.getOpenid());
         objectMapper.writeValue(bos, rootNode);
         httpPost.setEntity(new StringEntity(bos.toString("UTF-8")));
         HttpResponse response = httpClient.execute(httpPost);
         String bodyAsString = EntityUtils.toString(response.getEntity());
+        System.out.println(bodyAsString);
+        if (JSONObject.parseObject(bodyAsString).get("prepay_id") == null){
+            throw new CustomException(JSONObject.parseObject(bodyAsString).get("message").toString());
+        }
+
+        //本地创建订单
+        FilmOrder order = new FilmOrder();
+        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);
+
+
         String  packageStr = "prepay_id="+JSONObject.parseObject(bodyAsString).get("prepay_id");
         JSONObject jsonObject = new JSONObject();
         jsonObject.put("package",packageStr);
@@ -125,6 +163,7 @@ public class FilmController extends BaseController {
         byte[] signedData = signature.sign();
         String base64Str =  Base64.getEncoder().encodeToString(signedData);
         jsonObject.put("paySign",base64Str);
+        jsonObject.put("outTradeNo",orderCode);
         return Response.success(jsonObject);
 
     }
@@ -147,7 +186,6 @@ public class FilmController extends BaseController {
             post.setHeader("Content-Type","application/x-www-form-urlencoded");
             Map<String, Object> sortMap = new TreeMap<String, Object>();
             String time = String.valueOf(System.currentTimeMillis()/1000);
-            Map<String,Object> param = new HashMap<String,Object>();
             sortMap.put("appKey",appKey);
             sortMap.put("time",time);
             //1 将数据拆分成 treemap存储
@@ -165,8 +203,9 @@ public class FilmController extends BaseController {
                 Object v = s.getValue();
                 builder.append(k).append("=").append(v).append("&");
             }
+            builder.append("appSecret="+appSecret);
             //3 将最后拼接出来的sign传 md5加密
-            String sign = MD5Utils.MD5Encode(builder.append("appSecret="+appSecret).toString());
+            String sign = MD5Utils.MD5Encode(builder.toString());
             List<BasicNameValuePair> pairList = new ArrayList<BasicNameValuePair>();
             // 迭代Map-->取出key,value放到BasicNameValuePair对象中-->添加到list中
             for (Map.Entry entry : sortMap.entrySet()) {
@@ -194,22 +233,40 @@ public class FilmController extends BaseController {
         return Response.success(JSONObject.parseObject(resultData));
     }
 
+    /**
+     * 获取电影订单详细信息
+     */
+    @GetMapping(value = "/{id}")
+    @ApiOperation("获取电影订单详细信息")
+    public Response<FilmOrder> getInfo(
+            @ApiParam(name = "id", value = "电影订单参数", required = true)
+            @PathVariable("id") Long id
+    ){
+        return Response.success(filmOrderService.getById(id));
+    }
 
-    public static String getSign(Map<String, Object> params,String appSecretStr) {
-        Map<String, Object> sortMap = new TreeMap<String, Object>();
-        sortMap.putAll(params);
-        // 以k1=v1&k2=v2...方式拼接参数
-        StringBuilder builder = new StringBuilder();
-        for (Map.Entry<String, Object> s : sortMap.entrySet()) {
-            String k = s.getKey();
-            Object v = s.getValue();
-            builder.append(k).append("=").append(v).append("&");
-        }
-        if (!sortMap.isEmpty()) {
-            builder.deleteCharAt(builder.length() - 1);
+
+    /**
+     * 微信支付查单接口
+     */
+    @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()));
         }
-        builder.append(appSecretStr);
-        return builder.toString();
     }
 
 
@@ -223,4 +280,7 @@ public class FilmController extends BaseController {
 
 
 
+
+
+
 }

+ 97 - 0
zzjs-admin/src/main/java/com/miaxis/app/controller/film/NotifyController.java

@@ -0,0 +1,97 @@
+package com.miaxis.app.controller.film;
+
+
+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.exception.CustomException;
+import com.miaxis.common.utils.AesUtil;
+import com.miaxis.film.domain.FilmOrder;
+import com.miaxis.film.dto.FilmWxpayDTO;
+import com.miaxis.film.service.IFilmOrderService;
+import io.swagger.annotations.Api;
+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.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.sql.Date;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.Locale;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping(Constants.OPEN_PREFIX+"/film/notify")
+@Api(tags = {"【小程序-回调】"})
+@Slf4j
+public class NotifyController {
+
+
+    @Autowired
+    private WxpayConfig wxpayConfig;
+
+
+    @Autowired
+    private IFilmOrderService filmOrderService;
+
+    /**
+     * 微信支付回调接口
+     */
+    @PostMapping(value = "/wxpay")
+    @ApiOperation("微信支付回调")
+    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());
+        log.info(resourceString);
+        JSONObject jsonObject = JSONObject.parseObject(resourceString);
+        //将回调数据写入数据库
+        writeNotifyDataToDb(jsonObject);
+        WxNotifyReturnDTO wxNotifyReturnDTO = new WxNotifyReturnDTO();
+        wxNotifyReturnDTO.setCode("SUCCESS");
+        wxNotifyReturnDTO.setMessage("成功");
+        return wxNotifyReturnDTO;
+    }
+
+    private void writeNotifyDataToDb(JSONObject jsonObject) {
+        String outTradeNo = jsonObject.getString("out_trade_no");
+        FilmOrder filmOrder = filmOrderService.getByOutTradeNo(outTradeNo);
+        if (filmOrder == null) {
+            throw new CustomException("该订单不存在");
+        }
+        filmOrder.setTransactionId(jsonObject.getString("transaction_id"));
+        JSONObject amount = jsonObject.getJSONObject("amount");
+        filmOrder.setPayerTotal(amount.getInteger("payer_total"));
+        filmOrder.setTotal(amount.getInteger("total"));
+        filmOrder.setCurrency(amount.getString("currency"));
+        filmOrder.setPayerCurrency(amount.getString("payer_currency"));
+        filmOrder.setTradeState(jsonObject.getString("SUCCESS"));
+        filmOrder.setBankType(jsonObject.getString("bank_type"));
+        DateTime dateTime  = new DateTime(jsonObject.getString("success_time"));
+        filmOrder.setSuccessTime(dateTime.toDate());
+        filmOrder.setTradeStateDesc(jsonObject.getString("trade_state_desc"));
+        filmOrder.setTradeType(jsonObject.getString("trade_type"));
+        filmOrder.setAttach(jsonObject.getString("attach"));
+        JSONObject sceneInfo = jsonObject.getJSONObject("scene_info");
+        if (sceneInfo != null){
+            filmOrder.setDeviceId(sceneInfo.getString("device_id"));
+        }
+        filmOrderService.updateById(filmOrder);
+
+    }
+    @Data
+    public class WxNotifyReturnDTO {
+        String code;
+        String message;
+    }
+
+}

+ 1 - 1
zzjs-admin/src/main/java/com/miaxis/system/controller/system/SysLoginController.java

@@ -133,7 +133,7 @@ public class SysLoginController
     public Response<TokenDTO> getInfoTest(String jscode){
         TokenDTO tokenDTO = new TokenDTO();
             // 生成令牌
-        String token = loginService.login("ofFva6gzQEiXeKUCFdkwn2jrKGBE",null, StudentLoginTypeEnum.OPENID_LOGIN.getCode());
+        String token = loginService.login("oO7PJ5CPQJo62kZWA3uiUX2KG2s4",null, StudentLoginTypeEnum.OPENID_LOGIN.getCode());
         tokenDTO.setToken(token);
         return Response.success(tokenDTO) ;
 

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

@@ -233,6 +233,12 @@ wxpay:
   v3key: qqwweerrttyyuuiioopp123456789000
 
 
+# 电影
+film:
+  appKey: 10000000000
+  appSecret: 25f9e794323b453885f5181f1b624d0b
+#  notifyUrl: http://218.85.55.253:65535/zzjs-admin/
+  notifyUrl: http://218.85.55.253:65535/zzjs-admin/open-api/film/notify/wxpay
 
 
 

+ 44 - 0
zzjs-common/src/main/java/com/miaxis/common/utils/AesUtil.java

@@ -0,0 +1,44 @@
+package com.miaxis.common.utils;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+public class AesUtil {
+
+    static final int KEY_LENGTH_BYTE = 32;
+    static final int TAG_LENGTH_BIT = 128;
+    private final byte[] aesKey;
+
+    public AesUtil(byte[] key) {
+        if (key.length != KEY_LENGTH_BYTE) {
+            throw new IllegalArgumentException("无效的ApiV3Key,长度必须为32个字节");
+        }
+        this.aesKey = key;
+    }
+
+    public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext)
+            throws GeneralSecurityException, IOException {
+        try {
+            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+
+            SecretKeySpec key = new SecretKeySpec(aesKey, "AES");
+            GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);
+
+            cipher.init(Cipher.DECRYPT_MODE, key, spec);
+            cipher.updateAAD(associatedData);
+
+            return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");
+        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
+            throw new IllegalStateException(e);
+        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+}

+ 124 - 0
zzjs-common/src/main/java/com/miaxis/common/utils/OrderCodeFactory.java

@@ -0,0 +1,124 @@
+package com.miaxis.common.utils;
+
+
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Random;
+
+
+/**
+ *
+
+ * 订单编码码生成器,生成32位数字编码,
+ * @生成规则 1位单号类型+17位时间戳+14位(用户id加密&随机数)
+ */
+public class OrderCodeFactory {
+    /**
+     * 订单类别头
+     */
+    private static final String ORDER_CODE = "1";
+    /**
+     * 退货类别头
+     */
+    private static final String RETURN_ORDER = "2";
+    /**
+     * 退款类别头
+     */
+    private static final String REFUND_ORDER = "3";
+    /**
+     * 未付款重新支付别头
+     */
+    private static final String AGAIN_ORDER = "4";
+    /**
+     * 随即编码
+     */
+    private static final int[] r = new int[]{7, 9, 6, 2, 8, 1, 3, 0, 5, 4};
+    /**
+     * 用户id和随机数总长度
+     */
+    private static final int maxLength = 14;
+
+    /**
+     * 根据id进行加密+加随机数组成固定长度编码
+     */
+    private static String toCode(Long id) {
+        String idStr = id.toString();
+        StringBuilder idsbs = new StringBuilder();
+        for (int i = idStr.length() - 1; i >= 0; i--) {
+            idsbs.append(r[idStr.charAt(i) - '0']);
+        }
+        return idsbs.append(getRandom(maxLength - idStr.length())).toString();
+    }
+
+    /**
+     * 生成时间戳
+     */
+    private static String getDateTime() {
+        DateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+        return sdf.format(new Date());
+    }
+
+    /**
+     * 生成固定长度随机码
+     *
+     * @param n 长度
+     */
+    private static long getRandom(long n) {
+        long min = 1, max = 9;
+        for (int i = 1; i < n; i++) {
+            min *= 10;
+            max *= 10;
+        }
+        long rangeLong = (((long) (new Random().nextDouble() * (max - min)))) + min;
+        return rangeLong;
+    }
+
+    /**
+     * 生成不带类别标头的编码
+     *
+     * @param userId
+     */
+    private static synchronized String getCode(Long userId) {
+        userId = userId == null ? 10000 : userId;
+        return getDateTime() + toCode(userId);
+    }
+
+    /**
+     * 生成订单单号编码
+     *
+     * @param userId
+     */
+    public static String getOrderCode(Long userId) {
+        return ORDER_CODE + getCode(userId);
+    }
+
+    /**
+     * 生成退货单号编码
+     *
+     * @param userId
+     */
+    public static String getReturnCode(long userId) {
+        return RETURN_ORDER + getCode(userId);
+    }
+
+    /**
+     * 生成退款单号编码
+     *
+     * @param userId
+     */
+    public static String getRefundCode(long userId) {
+        return REFUND_ORDER + getCode(userId);
+    }
+
+    /**
+     * 未付款重新支付
+     *
+     * @param userId
+     */
+    public static String getAgainCode(long userId) {
+        return AGAIN_ORDER + getCode(userId);
+
+    }
+}

+ 60 - 0
zzjs-framework/src/main/java/com/miaxis/framework/aspectj/LogFileAspect.java

@@ -0,0 +1,60 @@
+package com.miaxis.framework.aspectj;
+
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
+import com.miaxis.common.utils.ServletUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.*;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Arrays;
+
+@Aspect
+@Component
+@Slf4j
+public class LogFileAspect {
+
+
+    @Pointcut("execution(* com.miaxis.*.controller..*(..))")
+//@Pointcut("@annotation(com.miaxis.common.annotation.Log)")
+    public void logPoint() {
+
+    }
+
+    @Before("logPoint()")
+    public void doBefore(JoinPoint joinPoint) throws Throwable {
+        // 接收到请求,记录请求内容
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = attributes.getRequest();
+
+
+        // 记录下请求内容
+        log.info("HTTP METHOD : " + request.getMethod());
+        log.info("请求地址 : " + request.getRequestURL().toString());
+        log.info("IP : " + request.getRemoteAddr());
+        //log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
+       // log.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
+        log.info("ARGS_JSON : " + JSONUtil.toJsonStr(joinPoint.getArgs()));
+    }
+
+    @AfterReturning(returning = "ret", pointcut = "logPoint()")// returning的值和doAfterReturning的参数名一致
+    public void doAfterReturning(Object ret) throws Throwable {
+        // 处理完请求,返回内容
+        log.info("返回值 : " + JSON.toJSONString(ret));
+    }
+
+    @Around("logPoint()")
+    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
+        long startTime = System.currentTimeMillis();
+        Object ob = pjp.proceed();// ob 为方法的返回值
+        log.info("耗时 : " + (System.currentTimeMillis() - startTime) + "ms");
+        return ob;
+    }
+
+}
+

+ 202 - 0
zzjs-service/src/main/java/com/miaxis/film/domain/FilmOrder.java

@@ -0,0 +1,202 @@
+package com.miaxis.film.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.miaxis.common.annotation.Excel;
+import com.miaxis.common.core.domain.BaseBusinessEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+/**
+ * 电影订单对象 film_order
+ *
+ * @author miaxis
+ * @date 2021-05-07
+ */
+@Data
+@TableName("film_order")
+@ApiModel(value = "FilmOrder", description = "电影订单对象 film_order")
+public class FilmOrder extends BaseBusinessEntity{
+    private static final long serialVersionUID = 1L;
+
+    /** id */
+    @TableId(value = "id")
+    @ApiModelProperty(value = "id")
+    private Long id;
+
+    /** 商户订单号 */
+    @Excel(name = "商户订单号")
+    @TableField("out_trade_no")
+    @ApiModelProperty(value = "商户订单号")
+    private String outTradeNo;
+
+    /** 微信支付系统生成的订单号 */
+    @Excel(name = "微信支付系统生成的订单号")
+    @TableField("transaction_id")
+    @ApiModelProperty(value = "微信支付系统生成的订单号")
+    private String transactionId;
+
+    /** 交易类型,枚举值 */
+    @Excel(name = "交易类型,枚举值")
+    @TableField("trade_type")
+    @ApiModelProperty(value = "交易类型,枚举值")
+    private String tradeType;
+
+    /** 交易状态,枚举值:
+SUCCESS:支付成功
+REFUND:转入退款
+NOTPAY:未支付
+CLOSED:已关闭
+REVOKED:已撤销(付款码支付)
+USERPAYING:用户支付中(付款码支付)
+PAYERROR:支付失败(其他原因,如银行返回失败)
+ACCEPT:已接收,等待扣款 */
+    @TableField("trade_state")
+    @ApiModelProperty(value = "交易状态,枚举值: SUCCESS:支付成功 REFUND:转入退款 NOTPAY:" +
+            "未支付 CLOSED:已关闭 REVOKED:已撤销(付款码支付) " +
+            "USERPAYING:用户支付中(付款码支付) PAYERROR:支付失败(其他原因,如银行返回失败) ACCEPT:已接收,等待扣款")
+    private String tradeState;
+    /** 交易状态描述 */
+    @Excel(name = "交易状态描述")
+    @TableField("trade_state_desc")
+    @ApiModelProperty(value = "交易状态描述")
+    private String tradeStateDesc;
+
+    /** 银行类型 */
+    @Excel(name = "银行类型")
+    @TableField("bank_type")
+    @ApiModelProperty(value = "银行类型")
+    private String bankType;
+
+    /** 附加数据 */
+    @Excel(name = "附加数据")
+    @TableField("attach")
+    @ApiModelProperty(value = "附加数据")
+    private String attach;
+
+    /** 支付完成时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "支付完成时间", width = 30, dateFormat = "yyyy-MM-dd")
+    @TableField("success_time")
+    @ApiModelProperty(value = "支付完成时间")
+    private Date successTime;
+
+    /** 用户在直连商户appid下的唯一标识 */
+    @Excel(name = "用户在直连商户appid下的唯一标识")
+    @TableField("openid")
+    @ApiModelProperty(value = "用户在直连商户appid下的唯一标识")
+    private String openid;
+
+    /** 商品名称 */
+    @Excel(name = "商品名称")
+    @TableField("goods_name")
+    @ApiModelProperty(value = "商品名称")
+    private String goodsName;
+
+    /** 订单总金额,单位为分。 */
+    @Excel(name = "订单总金额,单位为分。")
+    @TableField("total")
+    @ApiModelProperty(value = "订单总金额,单位为分。")
+    private Integer total;
+
+    /** 用户支付金额,单位为分。 */
+    @Excel(name = "用户支付金额,单位为分。")
+    @TableField("payer_total")
+    @ApiModelProperty(value = "用户支付金额,单位为分。")
+    private Integer payerTotal;
+
+    /** CNY:人民币,境内商户号仅支持人民币。 */
+    @Excel(name = "CNY:人民币,境内商户号仅支持人民币。")
+    @TableField("currency")
+    @ApiModelProperty(value = "CNY:人民币,境内商户号仅支持人民币。")
+    private String currency;
+
+    /** 用户支付币种 */
+    @Excel(name = "用户支付币种")
+    @TableField("payer_currency")
+    @ApiModelProperty(value = "用户支付币种")
+    private String payerCurrency;
+
+    /** 商户端设备号 */
+    @Excel(name = "商户端设备号")
+    @TableField("device_id")
+    @ApiModelProperty(value = "商户端设备号")
+    private String deviceId;
+
+    /** 用户所选的座位,例: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("seatNo")
+    @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;
+
+
+}

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

@@ -0,0 +1,52 @@
+package com.miaxis.film.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.miaxis.common.annotation.Excel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class FilmOrderCreateDTO {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "总金额, 单位分")
+    private int total;
+
+    @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("seatNo")
+    @ApiModelProperty(value = "座位接口的seatNo字段,如果有多个,则以竖线分割")
+    private String seatno;
+
+
+
+
+}

+ 54 - 0
zzjs-service/src/main/java/com/miaxis/film/dto/FilmWxpayDTO.java

@@ -0,0 +1,54 @@
+package com.miaxis.film.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.miaxis.common.annotation.Excel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 微信支付回调 dto
+ */
+@Data
+public class FilmWxpayDTO {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "通知的唯一ID")
+    private String id;
+
+    @ApiModelProperty(value = "创建的时间,rfc3339标准格式")
+    private String create_time;
+
+    @ApiModelProperty(value = "通知的类型,支付成功通知的类型为TRANSACTION.SUCCESS")
+    private String event_type;
+
+
+    @ApiModelProperty(value = "通知的资源数据类型")
+    private String resource_type;
+
+
+    @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;
+
+
+    }
+
+
+
+}

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

@@ -0,0 +1,23 @@
+package com.miaxis.film.mapper;
+
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.miaxis.film.domain.FilmOrder;
+
+/**
+ * 电影订单Mapper接口
+ *
+ * @author miaxis
+ * @date 2021-05-07
+ */
+public interface FilmOrderMapper extends BaseMapper<FilmOrder> {
+    /**
+     * 查询电影订单列表
+     *
+     * @param filmOrder 电影订单
+     * @return 电影订单集合
+     */
+    public List<FilmOrder> selectFilmOrderList(FilmOrder filmOrder);
+
+    FilmOrder getByOutTradeNo(String outTradeNo);
+}

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

@@ -0,0 +1,23 @@
+package com.miaxis.film.service;
+
+import java.util.List;
+import com.miaxis.film.domain.FilmOrder;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * 电影订单Service接口
+ *
+ * @author miaxis
+ * @date 2021-05-07
+ */
+public interface IFilmOrderService extends IService<FilmOrder>{
+    /**
+     * 查询电影订单列表
+     *
+     * @param filmOrder 电影订单
+     * @return 电影订单集合
+     */
+    public List<FilmOrder> selectFilmOrderList(FilmOrder filmOrder);
+
+    FilmOrder getByOutTradeNo(String outTradeNo);
+}

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

@@ -0,0 +1,41 @@
+package com.miaxis.film.service.impl;
+
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.miaxis.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.apache.commons.lang3.StringUtils;
+import com.miaxis.film.mapper.FilmOrderMapper;
+import com.miaxis.film.domain.FilmOrder;
+import com.miaxis.film.service.IFilmOrderService;
+
+/**
+ * 电影订单Service业务层处理
+ *
+ * @author miaxis
+ * @date 2021-05-07
+ */
+@Service
+public class FilmOrderServiceImpl extends ServiceImpl<FilmOrderMapper, FilmOrder> implements IFilmOrderService {
+    @Autowired
+    private FilmOrderMapper filmOrderMapper;
+
+    /**
+     * 查询电影订单列表
+     *
+     * @param filmOrder 电影订单
+     * @return 电影订单
+     */
+    @Override
+    public List<FilmOrder> selectFilmOrderList(FilmOrder filmOrder){
+        return filmOrderMapper.selectFilmOrderList(filmOrder);
+    }
+
+    @Override
+    public FilmOrder getByOutTradeNo(String outTradeNo) {
+        return filmOrderMapper.getByOutTradeNo(outTradeNo);
+    }
+}

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

@@ -0,0 +1,80 @@
+<?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.FilmOrderMapper">
+
+    <resultMap type="FilmOrder" id="FilmOrderResult">
+        <result property="id"    column="id"    />
+        <result property="outTradeNo"    column="out_trade_no"    />
+        <result property="transactionId"    column="transaction_id"    />
+        <result property="tradeType"    column="trade_type"    />
+        <result property="tradeState"    column="trade_state"    />
+        <result property="tradeStateDesc"    column="trade_state_desc"    />
+        <result property="bankType"    column="bank_type"    />
+        <result property="attach"    column="attach"    />
+        <result property="successTime"    column="success_time"    />
+        <result property="openid"    column="openid"    />
+        <result property="goodsName"    column="goods_name"    />
+        <result property="total"    column="total"    />
+        <result property="payerTotal"    column="payer_total"    />
+        <result property="currency"    column="currency"    />
+        <result property="payerCurrency"    column="payer_currency"    />
+        <result property="deviceId"    column="device_id"    />
+        <result property="seat"    column="seat"    />
+        <result property="reservedPhone"    column="reserved_phone"    />
+        <result property="acceptChangeSeat"    column="accept_change_seat"    />
+        <result property="seatId"    column="seat_id"    />
+        <result property="seatno"    column="seatNo"    />
+        <result property="orderState"    column="order_state"    />
+        <result property="orderPrice"    column="order_price"    />
+        <result property="closeCause"    column="close_cause"    />
+        <result property="realSeat"    column="real_seat"    />
+        <result property="ticketCode"    column="ticket_code"    />
+        <result property="ticketImage"    column="ticket_image"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectFilmOrderVo">
+        select * from film_order
+    </sql>
+
+    <select id="getByOutTradeNo" parameterType="string" resultType="com.miaxis.film.domain.FilmOrder">
+         select * from film_order where out_trade_no =#{outTradeNo}
+    </select>
+
+
+    <select id="selectFilmOrderList" parameterType="FilmOrder" resultMap="FilmOrderResult">
+        <include refid="selectFilmOrderVo"/>
+        <where>
+            <if test="outTradeNo != null "> and out_trade_no = #{outTradeNo}</if>
+            <if test="transactionId != null  and transactionId != ''"> and transaction_id = #{transactionId}</if>
+            <if test="tradeType != null  and tradeType != ''"> and trade_type = #{tradeType}</if>
+            <if test="tradeState != null  and tradeState != ''"> and trade_state = #{tradeState}</if>
+            <if test="tradeStateDesc != null  and tradeStateDesc != ''"> and trade_state_desc = #{tradeStateDesc}</if>
+            <if test="bankType != null  and bankType != ''"> and bank_type = #{bankType}</if>
+            <if test="attach != null  and attach != ''"> and attach = #{attach}</if>
+            <if test="successTime != null "> and success_time = #{successTime}</if>
+            <if test="openid != null  and openid != ''"> and openid = #{openid}</if>
+            <if test="goodsName != null  and goodsName != ''"> and goods_name like concat('%', #{goodsName}, '%')</if>
+            <if test="total != null "> and total = #{total}</if>
+            <if test="payerTotal != null "> and payer_total = #{payerTotal}</if>
+            <if test="currency != null  and currency != ''"> and currency = #{currency}</if>
+            <if test="payerCurrency != null  and payerCurrency != ''"> and payer_currency = #{payerCurrency}</if>
+            <if test="deviceId != null  and deviceId != ''"> and device_id = #{deviceId}</if>
+            <if test="seat != null  and seat != ''"> and seat = #{seat}</if>
+            <if test="reservedPhone != null  and reservedPhone != ''"> and reserved_phone = #{reservedPhone}</if>
+            <if test="acceptChangeSeat != null "> and accept_change_seat = #{acceptChangeSeat}</if>
+            <if test="seatId != null  and seatId != ''"> and seat_id = #{seatId}</if>
+            <if test="seatno != null  and seatno != ''"> and seatNo = #{seatno}</if>
+            <if test="orderState != null  and orderState != ''"> and order_state = #{orderState}</if>
+            <if test="orderPrice != null "> and order_price = #{orderPrice}</if>
+            <if test="closeCause != null  and closeCause != ''"> and close_cause = #{closeCause}</if>
+            <if test="realSeat != null  and realSeat != ''"> and real_seat = #{realSeat}</if>
+            <if test="ticketCode != null  and ticketCode != ''"> and ticket_code = #{ticketCode}</if>
+            <if test="ticketImage != null  and ticketImage != ''"> and ticket_image = #{ticketImage}</if>
+        </where>
+    </select>
+
+</mapper>

+ 1 - 0
zzjs-service/src/main/resources/mapper/product/ProductTypeInfoMapper.xml

@@ -74,6 +74,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         py.status
         from product_type_info py
         LEFT JOIN file_info f on f.file_id = py.product_icon
+        where py.status = 0
         ORDER BY weight DESC
     </select>