licailing 5 years ago
parent
commit
a20c6cc2ac

+ 24 - 0
src/main/java/com/izouma/jiashanxia/domain/WxFee.java

@@ -0,0 +1,24 @@
+package com.izouma.jiashanxia.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+import java.math.BigDecimal;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@Entity
+public class WxFee extends BaseEntity {
+    private Long       userId;
+    private Long       orderId;
+    private String     transactionId;
+    private Boolean    isRefund;
+    private BigDecimal amount;
+    private String     remark;
+    private String     type;
+}

+ 1 - 0
src/main/java/com/izouma/jiashanxia/enums/OrderInfoStatus.java

@@ -4,6 +4,7 @@ public enum OrderInfoStatus {
     UNPAID("未支付"),
     PAID("已支付"),
     CANCELLED("已取消"),
+    OFFLINE_PAID("线下已付"),
 
     ;
 

+ 2 - 1
src/main/java/com/izouma/jiashanxia/enums/PayMethod.java

@@ -3,7 +3,8 @@ package com.izouma.jiashanxia.enums;
 public enum PayMethod {
     WEIXIN("微信"),
     ALI("支付宝"),
-    YUE("余额");
+    YUE("余额"),
+    OFFLINE("线下");
     private final String description;
 
     PayMethod(String description) {

+ 7 - 0
src/main/java/com/izouma/jiashanxia/repo/WxFeeRepo.java

@@ -0,0 +1,7 @@
+package com.izouma.jiashanxia.repo;
+
+import com.izouma.jiashanxia.domain.WxFee;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface WxFeeRepo extends JpaRepository<WxFee, String> {
+}

+ 36 - 16
src/main/java/com/izouma/jiashanxia/service/ConsumptionService.java

@@ -1,5 +1,7 @@
 package com.izouma.jiashanxia.service;
 
+import com.alibaba.fastjson.JSONObject;
+import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
 import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
 import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
 import com.github.binarywang.wxpay.constant.WxPayConstants;
@@ -7,14 +9,15 @@ import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.izouma.jiashanxia.domain.OrderInfo;
 import com.izouma.jiashanxia.domain.User;
+import com.izouma.jiashanxia.domain.WxFee;
 import com.izouma.jiashanxia.exception.BusinessException;
 import com.izouma.jiashanxia.repo.OrderInfoRepo;
 import com.izouma.jiashanxia.repo.UserRepo;
+import com.izouma.jiashanxia.repo.WxFeeRepo;
 import com.izouma.jiashanxia.utils.JsonUtils;
 import com.izouma.jiashanxia.utils.SnowflakeIdWorker;
+import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Service;
 
@@ -23,18 +26,14 @@ import java.util.Arrays;
 
 @Service
 @Slf4j
+@AllArgsConstructor
 public class ConsumptionService {
-    @Autowired
-    private UserRepo      userRepo;
-    @Autowired
-    private OrderInfoRepo orderInfoRepo;
-    @Value("${wx.pay.notifyUrl}")
-    private String        wxNotifyUrl;
-    @Autowired
-    private Environment   environment;
-    @Autowired
-    private WxPayService  wxPayService;
-
+    private UserRepo         userRepo;
+    private OrderInfoRepo    orderInfoRepo;
+    private Environment      environment;
+    private WxPayService     wxPayService;
+    private WxFeeRepo        wxFeeRepo;
+    private OrderInfoService orderInfoService;
 
     /*
     微信支付
@@ -54,17 +53,16 @@ public class ConsumptionService {
             request.setTotalFee(1);
         }
         request.setOpenid(user.getOpenId());
-        request.setNotifyUrl(wxNotifyUrl);
+        request.setNotifyUrl(environment.getProperty("wx.pay.notifyUrl"));
         request.setSpbillCreateIp("180.102.110.170");
         request.setTradeType(WxPayConstants.TradeType.JSAPI);
         request.setSignType("MD5");
         request.setAttach(new JsonUtils.Builder()
-                .add("type", "member")
+                .add("type", "consumption")
                 .add("orderId", orderId)
                 .add("userId", userId)
                 .add("amount", orders.getPrice())
                 .build());
-
         try {
             return wxPayService.createOrder(request);
         } catch (WxPayException e) {
@@ -73,5 +71,27 @@ public class ConsumptionService {
         }
     }
 
+    /*
+    回调
+     */
+    public void handleConsumptionNotify(WxPayOrderNotifyResult notifyResult) {
+        JSONObject attach = JSONObject.parseObject(notifyResult.getAttach());
+        Long orderId = attach.getLong("orderId");
+        Long userId = attach.getLong("userId");
+        String type = attach.getString("type");
+        BigDecimal amount = attach.getBigDecimal("amount");
+        String transactionId = notifyResult.getTransactionId();
+
+        wxFeeRepo.save(WxFee.builder()
+                .amount(amount)
+                .isRefund(false)
+                .transactionId(transactionId)
+                .type(type)
+                .userId(userId)
+                .orderId(orderId)
+                .build());
+        orderInfoService.completed(orderId, transactionId);
+    }
+
 
 }

+ 19 - 8
src/main/java/com/izouma/jiashanxia/service/SetMealService.java

@@ -1,18 +1,14 @@
 package com.izouma.jiashanxia.service;
 
 import cn.hutool.core.util.ObjectUtil;
-import com.izouma.jiashanxia.domain.Company;
-import com.izouma.jiashanxia.domain.SetGoods;
-import com.izouma.jiashanxia.domain.SetMeal;
-import com.izouma.jiashanxia.domain.User;
+import com.izouma.jiashanxia.domain.*;
 import com.izouma.jiashanxia.dto.PageQuery;
 import com.izouma.jiashanxia.enums.AuthorityName;
+import com.izouma.jiashanxia.enums.OrderInfoStatus;
+import com.izouma.jiashanxia.enums.PayMethod;
 import com.izouma.jiashanxia.enums.SetType;
 import com.izouma.jiashanxia.exception.BusinessException;
-import com.izouma.jiashanxia.repo.CompanyRepo;
-import com.izouma.jiashanxia.repo.SetGoodsRepo;
-import com.izouma.jiashanxia.repo.SetMealRepo;
-import com.izouma.jiashanxia.repo.UserRepo;
+import com.izouma.jiashanxia.repo.*;
 import com.izouma.jiashanxia.security.Authority;
 import com.izouma.jiashanxia.utils.JpaUtils;
 import lombok.AllArgsConstructor;
@@ -20,6 +16,8 @@ import org.springframework.data.domain.Page;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.List;
 import java.util.Set;
 
@@ -33,6 +31,7 @@ public class SetMealService {
     private UserSetService userSetService;
     private CompanyRepo    companyRepo;
     private UserRepo       userRepo;
+    private OrderInfoRepo  orderInfoRepo;
 
     public Page<SetMeal> all(PageQuery pageQuery) {
         return setMealRepo.findAll(JpaUtils.toSpecification(pageQuery, SetMeal.class), JpaUtils.toPageRequest(pageQuery));
@@ -47,6 +46,18 @@ public class SetMealService {
         if (!SetType.TEAM.equals(set.getType())) {
             throw new BusinessException("不是团队套餐");
         }
+        // 新建订单
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+        String localTime = df.format(LocalDateTime.now());
+        String num = String.format("%05d", orderInfoRepo.orderNum() + 1);
+        orderInfoRepo.save(OrderInfo.builder()
+                .setMealId(setMealId)
+                .userId(userId)
+                .payMethod(PayMethod.OFFLINE)
+                .name(set.getName())
+                .orderNumber(localTime + num)
+                .status(OrderInfoStatus.OFFLINE_PAID)
+                .build());
 
         // 加入套餐商品
         List<SetGoods> setGoodsList = setGoodsRepo.findAllBySetMealId(setMealId);

+ 24 - 0
src/main/java/com/izouma/jiashanxia/web/ConsumptionController.java

@@ -0,0 +1,24 @@
+package com.izouma.jiashanxia.web;
+
+import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
+import com.izouma.jiashanxia.service.ConsumptionService;
+import com.izouma.jiashanxia.utils.SecurityUtils;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@AllArgsConstructor
+@RestController
+@RequestMapping("/pay")
+public class ConsumptionController {
+    private ConsumptionService consumptionService;
+
+    @ApiOperation("支付")
+    @GetMapping("/wx")
+    public WxPayMpOrderResult wx(Long orderId) {
+        return consumptionService.payOrder(SecurityUtils.getAuthenticatedUser().getId(), orderId);
+    }
+
+}

+ 5 - 0
src/main/java/com/izouma/jiashanxia/web/SetMealController.java

@@ -70,5 +70,10 @@ public class SetMealController extends BaseController {
     public void openTeamSet(Long userId, Long setMealId) {
         setMealService.openTeamSet(userId, setMealId);
     }
+
+    @GetMapping("/allList")
+    public List<SetMeal> allList() {
+        return setMealRepo.findAll();
+    }
 }
 

+ 28 - 0
src/main/java/com/izouma/jiashanxia/web/StatisticController.java

@@ -0,0 +1,28 @@
+package com.izouma.jiashanxia.web;
+
+import com.izouma.jiashanxia.repo.CompanyRepo;
+import com.izouma.jiashanxia.repo.OrderInfoRepo;
+import com.izouma.jiashanxia.repo.UserRepo;
+import com.izouma.jiashanxia.repo.WxFeeRepo;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+@AllArgsConstructor
+@RestController
+@RequestMapping("/statistic")
+public class StatisticController {
+    private UserRepo      userRepo;
+    private CompanyRepo   companyRepo;
+    private OrderInfoRepo orderInfoRepo;
+    private WxFeeRepo     wxFeeRepo;
+
+    @ApiOperation("数据总浏")
+    public Map<String, Object> dataOverview() {
+
+        return null;
+    }
+}

+ 7 - 3
src/main/java/com/izouma/jiashanxia/web/WxController.java

@@ -10,6 +10,7 @@ import com.github.binarywang.wxpay.constant.WxPayConstants;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.izouma.jiashanxia.exception.BusinessException;
+import com.izouma.jiashanxia.service.ConsumptionService;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -32,9 +33,10 @@ import java.io.IOException;
 @RestController
 @RequestMapping("/wx")
 public class WxController {
-    private WxMpService  wxMpService;
-    private WxPayService wxPayService;
-    private Environment  env;
+    private WxMpService        wxMpService;
+    private WxPayService       wxPayService;
+    private Environment        env;
+    private ConsumptionService consumptionService;
 
     @RequestMapping("/testMp")
     public ModelAndView testPay(@RequestParam(required = false) String code, HttpServletRequest request,
@@ -109,6 +111,8 @@ public class WxController {
         JSONObject attach = JSONObject.parseObject(notifyResult.getAttach());
         String type = attach.getString("type");
         switch (type) {
+            case "consumption":
+                consumptionService.handleConsumptionNotify(notifyResult);
         }
         return WxPayNotifyResponse.success("OK");
     }

BIN
src/main/resources/cert/apiclient_cert.p12


+ 24 - 0
src/main/resources/cert/apiclient_cert.pem

@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID9jCCAt6gAwIBAgIUP9MvML164b5s/yPg1wkePkD5igYwDQYJKoZIhvcNAQEL
+BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
+FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
+Q0EwHhcNMjAxMTI3MDczNjE1WhcNMjUxMTI2MDczNjE1WjCBhzETMBEGA1UEAwwK
+MTYwNDQ4NzQyNDEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTMwMQYDVQQL
+DCrlj6XlrrnluILnlLLlsbHkuIvppJDppa7nrqHnkIbmnInpmZDlhazlj7gxCzAJ
+BgNVBAYMAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBALQciCMgqu25CK4cLcN1+fHA6fwxDz9kT/2sXC1YDyXjGkPz
+EvKzE5PbOBUBqOCSM18Myt7XSZxmlg30AE9tDp5P8NxHPfNh8eBUHueHeCNRn4x4
+Nzcm1wBEmProtOfliv7TXzczLbkQPJ4+B8kelrTUlBbvGZqVhkl8Fo94mLYuyUF0
+1fCrkevM7f0mlKRst4mHaSrSF5wBLVgmqg7V/3Nmry2dRR/qU2zmjB4TKNCX9xiL
+vOzBPchWZyGuh2amyypnQ7k8qCCZZNHhsc1d3bEu+ZRlcLZ9At5ByJPA3TJ4lWJf
+jf/OLujokTCRNxW2tmop80ppolyw84EILnV3/qMCAwEAAaOBgTB/MAkGA1UdEwQC
+MAAwCwYDVR0PBAQDAgTwMGUGA1UdHwReMFwwWqBYoFaGVGh0dHA6Ly9ldmNhLml0
+cnVzLmNvbS5jbi9wdWJsaWMvaXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2
+QUQzOTc1NDk4NDZDMDFDM0U4RUJEMjANBgkqhkiG9w0BAQsFAAOCAQEAC29mf3Jm
+lTEWUsuqFdGwJJ8QDUj0JM/Z9vvTmyR2BTbura37RTLfqqR031mWJuG2aizRbAT9
+hOKLN4mj0t5cYmmSTdI7ErbM7qN+zBk5oXFrijIhJqbE8vBlSW4fQ+mttj/9YarC
+1Z+3OImb0vmHhc0uYXH5lYmr8w7qPpopbyhrNfk6JjMnQ5JU/wNHB6oXQWnptObe
+hSOZn9N7DX16oWIXxH6mk1q+3S19CSaPUwGckXvcn1eGnJU3LeDYmjQMT4Etg8CK
+wPiUjYdRsUjH1zDdY2/Da0/jW/lD2LQ4q6tMDxg9ocoJ32SEVDe5b5Rb0XjCN+Ft
+Z+JcT0ie2GPjpg==
+-----END CERTIFICATE-----

+ 28 - 0
src/main/resources/cert/apiclient_key.pem

@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC0HIgjIKrtuQiu
+HC3DdfnxwOn8MQ8/ZE/9rFwtWA8l4xpD8xLysxOT2zgVAajgkjNfDMre10mcZpYN
+9ABPbQ6eT/DcRz3zYfHgVB7nh3gjUZ+MeDc3JtcARJj66LTn5Yr+0183My25EDye
+PgfJHpa01JQW7xmalYZJfBaPeJi2LslBdNXwq5HrzO39JpSkbLeJh2kq0hecAS1Y
+JqoO1f9zZq8tnUUf6lNs5oweEyjQl/cYi7zswT3IVmchrodmpssqZ0O5PKggmWTR
+4bHNXd2xLvmUZXC2fQLeQciTwN0yeJViX43/zi7o6JEwkTcVtrZqKfNKaaJcsPOB
+CC51d/6jAgMBAAECggEBAJ3CkAwUxSNMe6nlzL/0SmXTECBx6GUiPF555pNhGoOZ
+FJyIAQTMjk1oKwtbVMy/wndzAQ+Hi1aPFMhL/SmU4MUSSGrpi/3uwKo5hIhQRI7L
+I/EqK1MHljMJ4uWDh1HH4aOrCS+UiGwdKLuCodcsD918hepArDCW3/Tl1+z7OOf5
+QdjT36919RNwosvzXmpHSJtZAI5e7euEtW/ZnYdF1FUDIYYg6ygKlqOMPCxlxUHi
+WVvZ7stmIjtZKMg34FF0XfrHmFSGp5LKNBIDNOwRYvCiV7RDXfElGzxJP8gbHL23
+IQqRyFG282rAJdlljB7L8pJzUuH1V+IVpO0M8X292MECgYEA55XmynW1o4rYujhL
+MAS7bx7ZzPaudLNwGDduV4OzhHaF/bXWKI30x609rI9DpAGH2jTYWw/xHkKEZJKR
+cqedcuvk4PyAgvo0Ac++fDKMrbwW8lZDKOqONdyXmeCo1IacMqQEYnO7/xRMvhLb
+5ry287vToBWNzcwL6pwAzKZFu4sCgYEAxxlupZcDZZZIiFatSbK8hq3Zx1cEBnjQ
+lVAIKUwGZ4f8C9Bsk1owNGbmgac9nEkrSMMmDdZegKobRaS2iwb53QmhCUJHP8bB
+i6AnbIztspjvP35f2Vs3OSw+OUEBACifr9oL9FJLo7gxpbpi5LDfAL+K+m++Fds9
+BeLBSInBDEkCgYABbI+NwSmLxufMRVpZAj5w0Xy/YOjzuMLAs16PVTT+ZIgwZjTZ
+7P2LWMpfTEY7NPMz6U1HShLOf9Q2lhwk21kBgufWZlcX9xfoxvFB7EGnM9fkR5mE
+H+Ud+axI+vOu0uEVAqMwQ8vtJp/OL2mAwrpRR19mxZson8+W8ryihYc6PwKBgEW4
+rDyko3XhqMjFwa07QDXRj5/04t35VOHUwubjTqLWxfbFKCB5xsOy/SmODU87eELk
+w+C4nyNjbmV3Bs2sxbcX9iKt6RF2YrSoguXKfDq8v5t2f8432SDWU3vtPZJ2p2UH
+cIRAhWhxykEFAjifj5hNeze0BdbVjYsQGytxwf6xAoGBALnQkK4XJNZdtp/jERoQ
+Tv9OqV5j/BUj8PGhJDK7f2tEUd9LKsQUbISeehAmBPqQzkUwgb7E0q67J4g3TpDH
+oyibxYZm0EpOl4O4Cs3Sn5wv6vEnkgSagZFRdHDopqag5sb9jVTq8qcsRvUqYyqz
+IA++NUsvxvfS49ock4vCN6wO
+-----END PRIVATE KEY-----

+ 29 - 4
src/main/vue/src/views/OrderInfoList.vue

@@ -12,10 +12,20 @@
                 class="filter-item"
                 >导出EXCEL
             </el-button>
-            <el-select v-model="status" multiple clearable @change="getData" placeholder="请选择订单状态">
+            <el-select
+                v-model="status"
+                multiple
+                clearable
+                @change="getData"
+                placeholder="请选择订单状态"
+                class="filter-item"
+            >
                 <el-option v-for="item in statusOptions" :key="item.value" :value="item.value" :label="item.label">
                 </el-option>
             </el-select>
+            <el-select v-model="setMealId" class="filter-item" clearable @change="getData" placeholder="请选择套餐">
+                <el-option v-for="item in setMeals" :label="item.name" :value="item.id" :key="item.id"></el-option>
+            </el-select>
         </div>
         <el-table
             :data="tableData"
@@ -81,14 +91,17 @@ export default {
             downloading: false,
             payMethodOptions: [
                 { label: '微信', value: 'WEIXIN' },
-                { label: '余额', value: 'YUE' }
+                { label: '余额', value: 'YUE' },
+                { label: '线下', value: 'OFFLINE' }
             ],
             statusOptions: [
                 { label: '未支付', value: 'UNPAID' },
                 { label: '已支付', value: 'PAID' },
                 { label: '已取消', value: 'CANCELLED' }
             ],
-            status: []
+            status: [],
+            setMealId: '',
+            setMeals: []
         };
     },
     computed: {
@@ -96,6 +109,17 @@ export default {
             return this.$refs.table.selection.map(i => i.id);
         }
     },
+    mounted() {
+        this.$http
+            .get('/setMeal/allList')
+            .then(res => {
+                this.setMeals = res;
+            })
+            .catch(e => {
+                console.log(e);
+                this.$message.error(e.error);
+            });
+    },
     methods: {
         payMethodFormatter(row, column, cellValue, index) {
             let selectedOption = this.payMethodOptions.find(i => i.value === cellValue);
@@ -115,7 +139,8 @@ export default {
             return {
                 search: this.search,
                 query: {
-                    status: this.status
+                    status: this.status,
+                    setMealId: this.setMealId
                 }
             };
         },