Browse Source

订单/统计

licailing 5 years ago
parent
commit
dcb99dba41

+ 3 - 4
src/main/java/com/izouma/jiashanxia/domain/GoodsInfo.java

@@ -1,6 +1,5 @@
 package com.izouma.jiashanxia.domain;
 package com.izouma.jiashanxia.domain;
 
 
-import com.izouma.jiashanxia.enums.ItemType;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
@@ -35,9 +34,9 @@ public class GoodsInfo extends BaseEntity {
     @ApiModelProperty(value = "景区id")
     @ApiModelProperty(value = "景区id")
     private Long attractionsId;
     private Long attractionsId;
 
 
-    @ApiModelProperty(value = "类型")
-    @Enumerated(EnumType.STRING)
-    private ItemType type;
+//    @ApiModelProperty(value = "类型")
+//    @Enumerated(EnumType.STRING)
+//    private ItemType type;
 
 
 //    @Builder.Default
 //    @Builder.Default
 //    @Column(nullable = false)
 //    @Column(nullable = false)

+ 2 - 0
src/main/java/com/izouma/jiashanxia/domain/Package.java

@@ -8,6 +8,7 @@ import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Data;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.NoArgsConstructor;
+import org.hibernate.annotations.Where;
 
 
 import javax.persistence.*;
 import javax.persistence.*;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
@@ -19,6 +20,7 @@ import java.util.List;
 @AllArgsConstructor
 @AllArgsConstructor
 @NoArgsConstructor
 @NoArgsConstructor
 @ApiModel(value = "套餐信息")
 @ApiModel(value = "套餐信息")
+@Where(clause = "del = 0")
 public class Package extends BaseEntity {
 public class Package extends BaseEntity {
     @ApiModelProperty(value = "景区id")
     @ApiModelProperty(value = "景区id")
     private Long attractionsId;
     private Long attractionsId;

+ 7 - 1
src/main/java/com/izouma/jiashanxia/domain/WxFee.java

@@ -1,5 +1,6 @@
 package com.izouma.jiashanxia.domain;
 package com.izouma.jiashanxia.domain;
 
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Data;
 import lombok.Data;
@@ -17,7 +18,12 @@ public class WxFee extends BaseEntity {
     private Long       userId;
     private Long       userId;
     private Long       orderId;
     private Long       orderId;
     private String     transactionId;
     private String     transactionId;
-    private Boolean    isRefund;
+//    private Boolean    isRefund;
+    @ApiModelProperty(value = "操作")
+    /*
+    0 收入 1 退款 2 提现
+     */
+    private int        action;
     private BigDecimal amount;
     private BigDecimal amount;
     private String     remark;
     private String     remark;
     private String     type;
     private String     type;

+ 1 - 0
src/main/java/com/izouma/jiashanxia/dto/StatisticDTO.java

@@ -16,5 +16,6 @@ public class StatisticDTO {
     private Long       dayOrder;
     private Long       dayOrder;
     private BigDecimal dayFee;
     private BigDecimal dayFee;
     private BigDecimal dayWithdraw;
     private BigDecimal dayWithdraw;
+    private BigDecimal dayRefund;
     private LocalDate  date;
     private LocalDate  date;
 }
 }

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

@@ -7,6 +7,7 @@ import org.springframework.data.jpa.repository.Query;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.List;
+import java.util.Optional;
 
 
 public interface WxFeeRepo extends JpaRepository<WxFee, String> {
 public interface WxFeeRepo extends JpaRepository<WxFee, String> {
 
 
@@ -14,4 +15,6 @@ public interface WxFeeRepo extends JpaRepository<WxFee, String> {
     BigDecimal sumByAmount();
     BigDecimal sumByAmount();
 
 
     List<WxFee> findAllByCreatedAtBetween(LocalDateTime createdAt, LocalDateTime createdAt2);
     List<WxFee> findAllByCreatedAtBetween(LocalDateTime createdAt, LocalDateTime createdAt2);
+
+    Optional<WxFee> findByTransactionId(String transactionId);
 }
 }

+ 12 - 8
src/main/java/com/izouma/jiashanxia/service/ConsumptionService.java

@@ -89,14 +89,18 @@ public class ConsumptionService {
         BigDecimal amount = BigDecimal.valueOf(notifyResult.getTotalFee() * 0.01);
         BigDecimal amount = BigDecimal.valueOf(notifyResult.getTotalFee() * 0.01);
         String transactionId = notifyResult.getTransactionId();
         String transactionId = notifyResult.getTransactionId();
 
 
-        wxFeeRepo.save(WxFee.builder()
-                .amount(amount)
-                .isRefund(false)
-                .transactionId(transactionId)
-                .type(type)
-                .userId(userId)
-                .orderId(orderId)
-                .build());
+        if (!wxFeeRepo.findByTransactionId(transactionId).isPresent()) {
+            wxFeeRepo.save(WxFee.builder()
+                    .amount(amount)
+//                    .isRefund(false)
+                    .action(0)
+                    .transactionId(transactionId)
+                    .type(type)
+                    .userId(userId)
+                    .orderId(orderId)
+                    .build());
+        }
+
 //        orderInfoService.completed(orderId, transactionId);
 //        orderInfoService.completed(orderId, transactionId);
         orderInfoService.completed1(orderId, transactionId);
         orderInfoService.completed1(orderId, transactionId);
     }
     }

+ 22 - 0
src/main/java/com/izouma/jiashanxia/service/OrderInfoService.java

@@ -42,6 +42,7 @@ public class OrderInfoService {
     private final CompanyRepo          companyRepo;
     private final CompanyRepo          companyRepo;
     private final WithdrawService      withdrawService;
     private final WithdrawService      withdrawService;
     private final UserPackageFlowRepo  userPackageFlowRepo;
     private final UserPackageFlowRepo  userPackageFlowRepo;
+    private final UserService          userService;
 
 
     public Page<OrderInfo> all(PageQuery pageQuery) {
     public Page<OrderInfo> all(PageQuery pageQuery) {
         pageQuery.setSort("createdAt,desc");
         pageQuery.setSort("createdAt,desc");
@@ -446,4 +447,25 @@ public class OrderInfoService {
         }
         }
     }
     }
 
 
+    /*
+    员工的下级
+    */
+    public Page<OrderInfo> children(PageQuery pageQuery) {
+        pageQuery.setSort("createdAt,desc");
+        Map<String, Object> query = pageQuery.getQuery();
+        String parent = (String) query.get("userId");
+        query.remove("userId");
+        List<Long> childrenId = userService.childrenId(Long.valueOf(parent));
+
+        return orderInfoRepo.findAll(((root, criteriaQuery, criteriaBuilder) -> {
+            List<Predicate> and = JpaUtils.toPredicates(pageQuery, OrderInfo.class, root, criteriaQuery, criteriaBuilder);
+            if (StrUtil.isNotEmpty(pageQuery.getSearch())) {
+                withdrawService.getNickname(pageQuery.getSearch(), and, root, criteriaBuilder);
+            }
+            and.add(criteriaBuilder.equal(root.get("status"), OrderInfoStatus.PAID));
+            and.add(root.get("userId").in(childrenId));
+            return criteriaBuilder.and(and.toArray(new Predicate[0]));
+        }), JpaUtils.toPageRequest(pageQuery));
+    }
+
 }
 }

+ 18 - 10
src/main/java/com/izouma/jiashanxia/service/OrderRefundService.java

@@ -1,6 +1,8 @@
 package com.izouma.jiashanxia.service;
 package com.izouma.jiashanxia.service;
 
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ObjectUtil;
+import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
+import com.github.binarywang.wxpay.bean.entpay.EntPayResult;
 import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
 import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
 import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
 import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.exception.WxPayException;
@@ -17,6 +19,7 @@ import com.izouma.jiashanxia.utils.JpaUtils;
 import com.izouma.jiashanxia.utils.SnowflakeIdWorker;
 import com.izouma.jiashanxia.utils.SnowflakeIdWorker;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.RandomStringUtils;
 import org.springframework.core.env.Environment;
 import org.springframework.core.env.Environment;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Page;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
@@ -183,22 +186,26 @@ public class OrderRefundService {
         OrderInfo orderInfo = orderInfoRepo.findByTransactionId(notifyResult.getReqInfo().getTransactionId());
         OrderInfo orderInfo = orderInfoRepo.findByTransactionId(notifyResult.getReqInfo().getTransactionId());
 
 
         // 微信退款流水
         // 微信退款流水
-        WxFee wxFee = WxFee.builder()
-                .amount(BigDecimal.valueOf(notifyResult.getReqInfo().getRefundFee() / 100.0))
-                .isRefund(true)
-                .orderId(orderInfo.getId())
-                .type("refund")
-                .transactionId(notifyResult.getReqInfo().getRefundId())
-                .userId(orderInfo.getUserId())
-                .build();
-        wxFeeRepo.save(wxFee);
+        String refundId = notifyResult.getReqInfo().getRefundId();
+        if (!wxFeeRepo.findByTransactionId(refundId).isPresent()) {
+            WxFee wxFee = WxFee.builder()
+                    .amount(BigDecimal.valueOf(notifyResult.getReqInfo().getRefundFee() / 100.0))
+//                    .isRefund(true)
+                    .action(1)
+                    .orderId(orderInfo.getId())
+                    .type("refund")
+                    .transactionId(refundId)
+                    .userId(orderInfo.getUserId())
+                    .build();
+            wxFeeRepo.save(wxFee);
+        }
 
 
         // 订单状态
         // 订单状态
         orderInfo.setStatus(OrderInfoStatus.REFUNDED);
         orderInfo.setStatus(OrderInfoStatus.REFUNDED);
         orderInfoRepo.save(orderInfo);
         orderInfoRepo.save(orderInfo);
 
 
         // 退款状态
         // 退款状态
-        OrderRefund refund = orderRefundRepo.findByRefundId(notifyResult.getReqInfo().getRefundId());
+        OrderRefund refund = orderRefundRepo.findByRefundId(refundId);
         refund.setStatus(RefundStatus.SUCCESS);
         refund.setStatus(RefundStatus.SUCCESS);
         refund.setAuditTime(LocalDateTime.now());
         refund.setAuditTime(LocalDateTime.now());
         orderRefundRepo.save(refund);
         orderRefundRepo.save(refund);
@@ -249,4 +256,5 @@ public class OrderRefundService {
             userPackageRepo.save(userPackage);
             userPackageRepo.save(userPackage);
         });
         });
     }
     }
+
 }
 }

+ 42 - 6
src/main/java/com/izouma/jiashanxia/service/StatisticService.java

@@ -1,5 +1,6 @@
 package com.izouma.jiashanxia.service;
 package com.izouma.jiashanxia.service;
 
 
+import cn.hutool.core.collection.CollUtil;
 import com.izouma.jiashanxia.domain.OrderInfo;
 import com.izouma.jiashanxia.domain.OrderInfo;
 import com.izouma.jiashanxia.domain.Withdraw;
 import com.izouma.jiashanxia.domain.Withdraw;
 import com.izouma.jiashanxia.domain.WxFee;
 import com.izouma.jiashanxia.domain.WxFee;
@@ -17,6 +18,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 
 @Service
 @Service
 @AllArgsConstructor
 @AllArgsConstructor
@@ -51,20 +53,32 @@ public class StatisticService {
         List<StatisticDTO> dtos = new ArrayList<>();
         List<StatisticDTO> dtos = new ArrayList<>();
         LocalDateTime now = LocalDateTime.now();
         LocalDateTime now = LocalDateTime.now();
         LocalDateTime start = LocalDateTime.of(now.toLocalDate().minusDays(day - 1), LocalTime.MIN);
         LocalDateTime start = LocalDateTime.of(now.toLocalDate().minusDays(day - 1), LocalTime.MIN);
-        List<OrderInfo> orderInfos = orderInfoRepo.findAllByPaidAtBetweenAndStatus(start, now, OrderInfoStatus.PAID);
-        List<WxFee> wxFees = wxFeeRepo.findAllByCreatedAtBetween(start, now);
+//        List<OrderInfo> orderInfos = orderInfoRepo.findAllByPaidAtBetweenAndStatus(start, now, OrderInfoStatus.PAID);
+        Map<Integer, List<WxFee>> collect = wxFeeRepo.findAllByCreatedAtBetween(start, now)
+                .stream()
+                .collect(Collectors.groupingBy(WxFee::getAction));
+        List<WxFee> wxFees = collect.get(0);
+        List<WxFee> refunds = new ArrayList<>();
+        List<WxFee> wxFees1 = collect.get(1);
+        if (CollUtil.isNotEmpty(wxFees1)) {
+            refunds = wxFees1;
+        }
         List<Withdraw> withdraws = withdrawRepo.findAllByStatus(WithdrawStatus.SUCCESS);
         List<Withdraw> withdraws = withdrawRepo.findAllByStatus(WithdrawStatus.SUCCESS);
 
 
         while (day > 0) {
         while (day > 0) {
             LocalDateTime end = start.plusDays(1);
             LocalDateTime end = start.plusDays(1);
             LocalDateTime finalStart = start;
             LocalDateTime finalStart = start;
-            long order = orderInfos.stream()
-                    .filter(orderInfo -> !finalStart.isAfter(orderInfo.getPaidAt()) && end.isAfter(orderInfo.getPaidAt()))
-                    .count();
+//            long order = orderInfos.stream()
+//                    .filter(orderInfo -> !finalStart.isAfter(orderInfo.getPaidAt()) && end.isAfter(orderInfo.getPaidAt()))
+//                    .count();
             BigDecimal fee = wxFees.stream()
             BigDecimal fee = wxFees.stream()
                     .filter(wxFee -> !finalStart.isAfter(wxFee.getCreatedAt()) && end.isAfter(wxFee.getCreatedAt()))
                     .filter(wxFee -> !finalStart.isAfter(wxFee.getCreatedAt()) && end.isAfter(wxFee.getCreatedAt()))
                     .map(WxFee::getAmount)
                     .map(WxFee::getAmount)
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
+            BigDecimal refund = refunds.stream()
+                    .filter(wxFee -> !finalStart.isAfter(wxFee.getCreatedAt()) && end.isAfter(wxFee.getCreatedAt()))
+                    .map(WxFee::getAmount)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
             BigDecimal withdraw = withdraws.stream()
             BigDecimal withdraw = withdraws.stream()
                     .filter(wxFee -> !finalStart.isAfter(wxFee.getAuditTime()) && end.isAfter(wxFee.getAuditTime()))
                     .filter(wxFee -> !finalStart.isAfter(wxFee.getAuditTime()) && end.isAfter(wxFee.getAuditTime()))
                     .map(Withdraw::getAmount)
                     .map(Withdraw::getAmount)
@@ -72,9 +86,31 @@ public class StatisticService {
 
 
             dtos.add(StatisticDTO.builder()
             dtos.add(StatisticDTO.builder()
                     .date(finalStart.toLocalDate())
                     .date(finalStart.toLocalDate())
-                    .dayOrder(order)
+//                    .dayOrder(order)
                     .dayFee(fee)
                     .dayFee(fee)
                     .dayWithdraw(withdraw)
                     .dayWithdraw(withdraw)
+                    .dayRefund(refund)
+                    .build());
+            day--;
+            start = end;
+        }
+        return dtos;
+    }
+
+    public List<StatisticDTO> dayData2(Integer day) {
+        List<StatisticDTO> dtos = new ArrayList<>();
+        LocalDateTime now = LocalDateTime.now();
+        LocalDateTime start = LocalDateTime.of(now.toLocalDate().minusDays(day - 1), LocalTime.MIN);
+        List<OrderInfo> orderInfos = orderInfoRepo.findAllByPaidAtBetweenAndStatus(start, now, OrderInfoStatus.PAID);
+        while (day > 0) {
+            LocalDateTime end = start.plusDays(1);
+            LocalDateTime finalStart = start;
+            long order = orderInfos.stream()
+                    .filter(orderInfo -> !finalStart.isAfter(orderInfo.getPaidAt()) && end.isAfter(orderInfo.getPaidAt()))
+                    .count();
+            dtos.add(StatisticDTO.builder()
+                    .date(finalStart.toLocalDate())
+                    .dayOrder(order)
                     .build());
                     .build());
             day--;
             day--;
             start = end;
             start = end;

+ 13 - 1
src/main/java/com/izouma/jiashanxia/service/UserService.java

@@ -428,6 +428,19 @@ public class UserService {
         return userRepo.save(user);
         return userRepo.save(user);
     }
     }
 
 
+    /*
+    捞所有下级id
+     */
+    public List<Long> childrenId(Long userId) {
+        List<Long> users = userRepo.findIdByParentAndDelFalse(userId);
+        List<Long> children = new ArrayList<>(users);
+        while (CollUtil.isNotEmpty(users)) {
+            users = userRepo.findIdByParentInAndDelFalse(users);
+            children.addAll(users);
+        }
+        return children;
+    }
+
     /*
     /*
     下级
     下级
      */
      */
@@ -441,7 +454,6 @@ public class UserService {
             users = userRepo.findIdByParentInAndDelFalse(users);
             users = userRepo.findIdByParentInAndDelFalse(users);
             children.addAll(users);
             children.addAll(users);
         }
         }
-//        return children;
 
 
         query.remove("parent");
         query.remove("parent");
         return userRepo.findAll(((root, criteriaQuery, criteriaBuilder) -> {
         return userRepo.findAll(((root, criteriaQuery, criteriaBuilder) -> {

+ 53 - 4
src/main/java/com/izouma/jiashanxia/service/WithdrawService.java

@@ -1,10 +1,15 @@
 package com.izouma.jiashanxia.service;
 package com.izouma.jiashanxia.service;
 
 
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
+import com.github.binarywang.wxpay.bean.entpay.EntPayResult;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
 import com.izouma.jiashanxia.domain.CommissionRecord;
 import com.izouma.jiashanxia.domain.CommissionRecord;
-import com.izouma.jiashanxia.domain.OrderInfo;
 import com.izouma.jiashanxia.domain.User;
 import com.izouma.jiashanxia.domain.User;
 import com.izouma.jiashanxia.domain.Withdraw;
 import com.izouma.jiashanxia.domain.Withdraw;
+import com.izouma.jiashanxia.domain.WxFee;
 import com.izouma.jiashanxia.dto.PageQuery;
 import com.izouma.jiashanxia.dto.PageQuery;
 import com.izouma.jiashanxia.enums.PayMethod;
 import com.izouma.jiashanxia.enums.PayMethod;
 import com.izouma.jiashanxia.enums.TransactionType;
 import com.izouma.jiashanxia.enums.TransactionType;
@@ -13,8 +18,11 @@ import com.izouma.jiashanxia.exception.BusinessException;
 import com.izouma.jiashanxia.repo.CommissionRecordRepo;
 import com.izouma.jiashanxia.repo.CommissionRecordRepo;
 import com.izouma.jiashanxia.repo.UserRepo;
 import com.izouma.jiashanxia.repo.UserRepo;
 import com.izouma.jiashanxia.repo.WithdrawRepo;
 import com.izouma.jiashanxia.repo.WithdrawRepo;
+import com.izouma.jiashanxia.repo.WxFeeRepo;
 import com.izouma.jiashanxia.utils.JpaUtils;
 import com.izouma.jiashanxia.utils.JpaUtils;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.RandomStringUtils;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Page;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
@@ -28,11 +36,14 @@ import java.util.List;
 
 
 @Service
 @Service
 @AllArgsConstructor
 @AllArgsConstructor
+@Slf4j
 public class WithdrawService {
 public class WithdrawService {
 
 
-    private WithdrawRepo         withdrawRepo;
-    private UserRepo             userRepo;
-    private CommissionRecordRepo commissionRecordRepo;
+    private final WithdrawRepo         withdrawRepo;
+    private final UserRepo             userRepo;
+    private final CommissionRecordRepo commissionRecordRepo;
+    private final WxPayService         wxPayService;
+    private final WxFeeRepo            wxFeeRepo;
 
 
     public Page<Withdraw> all(PageQuery pageQuery) {
     public Page<Withdraw> all(PageQuery pageQuery) {
         pageQuery.setSort("createdAt,desc");
         pageQuery.setSort("createdAt,desc");
@@ -125,4 +136,42 @@ public class WithdrawService {
         withdrawRepo.save(withdraw);
         withdrawRepo.save(withdraw);
     }
     }
 
 
+    /*
+    企业支付
+    */
+    public void pay(Withdraw withdraw) {
+        User user1 = withdraw.getUser();
+        if (user1 == null) {
+            user1 = userRepo.findById(withdraw.getUserId()).orElseThrow(new BusinessException("无用户"));
+        }
+        try {
+            String description = String.format("天游佳处余额提现%s元", withdraw.getAmount());
+            EntPayRequest request = new EntPayRequest();
+            request.setPartnerTradeNo(RandomStringUtils.randomAlphabetic(32));
+            request.setAmount(withdraw.getAmount().multiply(BigDecimal.valueOf(100)).intValue());
+            request.setOpenid(user1.getOpenId());
+            request.setCheckName("NO_CHECK");
+            request.setDescription(description);
+            request.setSpbillCreateIp("192.168.31.12");
+            EntPayResult result = wxPayService.getEntPayService().entPay(request);
+            result.checkResult(wxPayService, "MD5", true);
+            // 保存微信流水
+            if ("SUCCESS".equals(result.getReturnCode())) {
+                if (!wxFeeRepo.findByTransactionId(result.getPartnerTradeNo()).isPresent()) {
+                    wxFeeRepo.save(WxFee.builder()
+                            .userId(withdraw.getUserId())
+                            .action(2)
+                            .type("withdraw")
+                            .orderId(withdraw.getId())
+                            .transactionId(result.getPartnerTradeNo())
+                            .amount(withdraw.getAmount())
+                            .build());
+                }
+            }
+        } catch (WxPayException e) {
+            log.error("余额提现", e);
+            throw new BusinessException("余额提现失败,请联系公众号客服");
+        }
+
+    }
 }
 }

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

@@ -91,5 +91,10 @@ public class OrderInfoController extends BaseController {
     public long count() {
     public long count() {
         return orderInfoRepo.countByUserId(SecurityUtils.getAuthenticatedUser().getId());
         return orderInfoRepo.countByUserId(SecurityUtils.getAuthenticatedUser().getId());
     }
     }
+
+    @PostMapping("/children")
+    public Page<OrderInfo> children(@RequestBody PageQuery pageQuery) {
+        return orderInfoService.children(pageQuery);
+    }
 }
 }
 
 

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

@@ -28,4 +28,10 @@ public class StatisticController {
     public List<StatisticDTO> dayAdd(Integer day) {
     public List<StatisticDTO> dayAdd(Integer day) {
         return statisticService.dayData(day);
         return statisticService.dayData(day);
     }
     }
+
+    @ApiOperation("日销售额")
+    @GetMapping("/dayAdd2")
+    public List<StatisticDTO> dayAdd2(Integer day) {
+        return statisticService.dayData2(day);
+    }
 }
 }

+ 10 - 1
src/main/vue/src/router.js

@@ -82,7 +82,7 @@ const router = new Router({
                 {
                 {
                     path: '/employeeList',
                     path: '/employeeList',
                     name: 'employeeList',
                     name: 'employeeList',
-                    component: () => import(/* webpackChunkName: "userEdit" */ '@/views/EmployeeList.vue'),
+                    component: () => import(/* webpackChunkName: "userEdit" */ '@/views/employee/EmployeeList.vue'),
                     meta: {
                     meta: {
                         title: '员工列表'
                         title: '员工列表'
                     }
                     }
@@ -95,6 +95,15 @@ const router = new Router({
                         title: '下级列表'
                         title: '下级列表'
                     }
                     }
                 },
                 },
+                {
+                    path: '/employeeOrderList',
+                    name: 'employeeOrderList',
+                    component: () =>
+                        import(/* webpackChunkName: "userEdit" */ '@/views/employee/EmployeeOrderList.vue'),
+                    meta: {
+                        title: '下级列表'
+                    }
+                },
                 {
                 {
                     path: '/userPackageFlowList1',
                     path: '/userPackageFlowList1',
                     name: 'UserPackageFlowList1',
                     name: 'UserPackageFlowList1',

+ 3 - 1
src/main/vue/src/views/OrderInfoList.vue

@@ -105,7 +105,9 @@ export default {
                 { label: '未支付', value: 'UNPAID' },
                 { label: '未支付', value: 'UNPAID' },
                 { label: '已支付', value: 'PAID' },
                 { label: '已支付', value: 'PAID' },
                 { label: '已取消', value: 'CANCELLED' },
                 { label: '已取消', value: 'CANCELLED' },
-                { label: '线下支付', value: 'OFFLINE_PAID' }
+                { label: '线下支付', value: 'OFFLINE_PAID' },
+                { label: '已退款', value: 'REFUNDED' },
+                { label: '申请退款中', value: 'REQUEST_REFUND' }
             ],
             ],
             status: [],
             status: [],
             packageId: '',
             packageId: '',

+ 9 - 0
src/main/vue/src/views/EmployeeList.vue → src/main/vue/src/views/employee/EmployeeList.vue

@@ -46,6 +46,7 @@
                 <template slot-scope="{ row }">
                 <template slot-scope="{ row }">
                     <el-button size="mini" @click="handleCommand2(row.id)">收益</el-button>
                     <el-button size="mini" @click="handleCommand2(row.id)">收益</el-button>
                     <el-button size="mini" @click="handleCommand1(row.id)">下级</el-button>
                     <el-button size="mini" @click="handleCommand1(row.id)">下级</el-button>
+                    <el-button size="mini" @click="handleCommand3(row.id)">销售</el-button>
                     <!-- <el-button
                     <!-- <el-button
                         @click="remove(row)"
                         @click="remove(row)"
                         type="warning"
                         type="warning"
@@ -206,6 +207,14 @@ export default {
                     id: id
                     id: id
                 }
                 }
             });
             });
+        },
+        handleCommand3(id) {
+            this.$router.push({
+                path: '/employeeOrderList',
+                query: {
+                    id: id
+                }
+            });
         }
         }
     }
     }
 };
 };

+ 221 - 0
src/main/vue/src/views/employee/EmployeeOrderList.vue

@@ -0,0 +1,221 @@
+<template>
+    <div class="list-view">
+        <div class="filters-container">
+            <el-input placeholder="输入关键字" v-model="search" clearable class="filter-item"></el-input>
+            <el-button @click="getData" type="primary" icon="el-icon-search" class="filter-item">搜索 </el-button>
+            <!-- <el-button @click="addRow" type="primary" icon="el-icon-plus" class="filter-item">添加 </el-button> -->
+            <!-- <el-button
+                @click="download"
+                type="primary"
+                icon="el-icon-download"
+                :loading="downloading"
+                class="filter-item"
+                >导出EXCEL
+            </el-button> -->
+            <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="packageId" class="filter-item" clearable @change="getData" placeholder="请选择套餐">
+                <el-option v-for="item in packages" :label="item.name" :value="item.id" :key="item.id"></el-option>
+            </el-select>
+        </div>
+        <el-table
+            :data="tableData"
+            row-key="id"
+            ref="table"
+            header-row-class-name="table-header-row"
+            header-cell-class-name="table-header-cell"
+            row-class-name="table-row"
+            cell-class-name="table-cell"
+            :height="tableHeight"
+        >
+            <el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
+            <!--<el-table-column prop="id" label="ID" width="100"> </el-table-column>-->
+            <el-table-column prop="orderNumber" label="订单号" show-overflow-tooltip> </el-table-column>
+            <el-table-column prop="user.nickname" label="昵称"> </el-table-column>
+            <el-table-column prop="payMethod" label="支付方式" :formatter="payMethodFormatter"> </el-table-column>
+            <el-table-column prop="status" label="订单状态">
+                <template slot-scope="{ row }">
+                    <el-tag type="warning" v-if="row.status == 'UNPAID'">未支付</el-tag>
+                    <el-tag type="success" v-else-if="row.status == 'PAID'">已支付</el-tag>
+                    <el-tag type="info" v-else-if="row.status == 'CANCELLED'">已取消</el-tag>
+                    <el-tag v-else>线下支付</el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column prop="name" label="名称" show-overflow-tooltip> </el-table-column>
+            <el-table-column prop="paidAt" label="支付时间" show-overflow-tooltip> </el-table-column>
+            <!-- <el-table-column label="操作" align="center" fixed="right" min-width="150"> -->
+            <!-- <template slot-scope="{ row }"> -->
+            <!-- <el-button @click="editRow(row)" type="primary" size="mini" plain>编辑</el-button> -->
+            <!-- <el-button @click="deleteRow(row)" type="danger" size="mini" plain>删除</el-button> -->
+            <!-- </template> -->
+            <!-- </el-table-column> -->
+        </el-table>
+        <div class="pagination-wrapper">
+            <!-- <div class="multiple-mode-wrapper">
+                <el-button v-if="!multipleMode" @click="toggleMultipleMode(true)">批量编辑</el-button>
+                <el-button-group v-else>
+                    <el-button @click="operation1">批量操作1</el-button>
+                    <el-button @click="operation2">批量操作2</el-button>
+                    <el-button @click="toggleMultipleMode(false)">取消</el-button>
+                </el-button-group>
+            </div> -->
+            <el-pagination
+                background
+                @size-change="onSizeChange"
+                @current-change="onCurrentChange"
+                :current-page="page"
+                :page-sizes="[10, 20, 30, 40, 50]"
+                :page-size="pageSize"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="totalElements"
+            >
+            </el-pagination>
+        </div>
+    </div>
+</template>
+<script>
+import { mapState } from 'vuex';
+import pageableTable from '@/mixins/pageableTable';
+
+export default {
+    name: 'EmployeeOrderList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/orderInfo/children',
+            downloading: false,
+            payMethodOptions: [
+                { label: '微信', value: 'WEIXIN' },
+                { label: '余额', value: 'YUE' },
+                { label: '线下', value: 'OFFLINE' }
+            ],
+            statusOptions: [
+                { label: '未支付', value: 'UNPAID' },
+                { label: '已支付', value: 'PAID' },
+                { label: '已取消', value: 'CANCELLED' },
+                { label: '线下支付', value: 'OFFLINE_PAID' }
+            ],
+            status: [],
+            packageId: '',
+            packages: []
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    mounted() {
+        this.$http
+            .get('/package/allList')
+            .then(res => {
+                this.packages = 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);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            return {
+                search: this.search,
+                query: {
+                    status: this.status,
+                    packageId: this.packageId,
+                    userId: this.$route.query.id
+                }
+            };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/orderInfoEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/orderInfoEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/orderInfo/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000 }
+                })
+                .then(res => {
+                    console.log(res);
+                    this.downloading = false;
+                    const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                    const link = document.createElement('a');
+                    link.href = downloadUrl;
+                    link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
+                    document.body.appendChild(link);
+                    link.click();
+                    link.remove();
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.downloading = false;
+                    this.$message.error(e.error);
+                });
+        },
+        operation1() {
+            this.$notify({
+                title: '提示',
+                message: this.selection
+            });
+        },
+        operation2() {
+            this.$message('操作2');
+        },
+        deleteRow(row) {
+            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/orderInfo/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
+};
+</script>
+<style lang="less" scoped></style>

+ 1 - 1
src/main/vue/src/widgets/RecentOrder.vue

@@ -33,7 +33,7 @@ export default {
         getData() {
         getData() {
             this.loading = true;
             this.loading = true;
             this.$http
             this.$http
-                .get('/statistic/dayAdd', {
+                .get('/statistic/dayAdd2', {
                     day: this.recentDays
                     day: this.recentDays
                 })
                 })
                 .then(res => {
                 .then(res => {

+ 7 - 0
src/main/vue/src/widgets/RecentSales.vue

@@ -55,6 +55,13 @@ export default {
                                 backgroundColor: ['rgba(230, 162, 60, 0.2)'],
                                 backgroundColor: ['rgba(230, 162, 60, 0.2)'],
                                 borderColor: ['rgba(230, 162, 60, 1)'],
                                 borderColor: ['rgba(230, 162, 60, 1)'],
                                 borderWidth: 1
                                 borderWidth: 1
+                            },
+                            {
+                                label: '退款额',
+                                data: res.map(i => i.dayRefund),
+                                backgroundColor: ['rgba(245, 108, 108, 0.2)'],
+                                borderColor: ['rgba(245, 108, 108, 1)'],
+                                borderWidth: 1
                             }
                             }
                         ]
                         ]
                     };
                     };

+ 5 - 0
src/test/java/com/izouma/jiashanxia/service/UserServiceTest.java

@@ -66,4 +66,9 @@ public class UserServiceTest {
         Page<User> children = userService.children(pageQuery);
         Page<User> children = userService.children(pageQuery);
         children.getContent().forEach(System.out::println);
         children.getContent().forEach(System.out::println);
     }
     }
+
+    @Test
+    public void test4() {
+        System.out.println(userService.childrenId(928L));
+    }
 }
 }