TRX 1 år sedan
förälder
incheckning
54ee26b3b0
20 ändrade filer med 604 tillägg och 57 borttagningar
  1. 5 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/ExpenseFlowCount.java
  2. 18 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/ExpenseFlowModel.java
  3. 40 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/ExpenseFlowSearch.java
  4. 4 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/ExpenseRefundParam.java
  5. 30 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/statistic/BusinessMainStatisticModel.java
  6. 24 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/statistic/StatisticItem.java
  7. 31 0
      FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/statistic/StatisticSearch.java
  8. 8 1
      FullCardClient/src/main/java/com/zhongshu/card/client/service/payment/ExpenseFlowService.java
  9. 20 0
      FullCardClient/src/main/java/com/zhongshu/card/client/utils/type/StatisticType.java
  10. 29 8
      FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/payment/ExpenseFlowController.java
  11. 12 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/BaseImpl.java
  12. 3 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/OrganizationUserDao.java
  13. 14 1
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/payment/extend/ExpenseFlowDaoExtend.java
  14. 109 28
      FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/payment/impl/ExpenseFlowDaoImpl.java
  15. 6 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/payment/ExpenseFlow.java
  16. 30 4
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/IndexService.java
  17. 79 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/OrganizationServiceImpl.java
  18. 95 11
      FullCardServer/src/main/java/com/zhongshu/card/server/core/service/payment/ExpenseFlowServiceImpl.java
  19. 3 0
      FullCardServer/src/main/java/com/zhongshu/card/server/core/test/Test.java
  20. 44 4
      FullCardServer/src/main/java/com/zhongshu/card/server/core/util/DateUtils.java

+ 5 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/ExpenseFlowCount.java

@@ -1,5 +1,6 @@
 package com.zhongshu.card.client.model.payment;
 
+import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -16,5 +17,9 @@ import java.math.BigDecimal;
 @AllArgsConstructor
 @NoArgsConstructor
 public class ExpenseFlowCount {
+    @Schema(description = "总数,单位:分")
     private BigDecimal payAmount = BigDecimal.ZERO;
+
+    @Schema(description = "订单数量")
+    private Long total = 0L;
 }

+ 18 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/ExpenseFlowModel.java

@@ -113,6 +113,24 @@ public class ExpenseFlowModel extends SuperModel {
     @Schema(description = "退款状态")
     private RefundState refundState;
 
+    private String refundStateStr;
+
+    public String getRefundStateStr() {
+        if (refundState != null) {
+            return refundState.getRemark();
+        }
+        return "";
+    }
+
+    @Schema(description = "退款金额")
+    private BigDecimal refundAMount;
+
+    @Schema(description = "操作退款用户userId")
+    private String refundUserId;
+
+    @Schema(description = "退款申请人")
+    private String applicant;
+
     @Schema(description = "申请退款时间")
     private Long refundTime;
 

+ 40 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/ExpenseFlowSearch.java

@@ -2,6 +2,9 @@ package com.zhongshu.card.client.model.payment;
 
 import cn.hutool.json.JSONObject;
 import com.zhongshu.card.client.model.base.SuperSearch;
+import com.zhongshu.card.client.utils.type.OrderType;
+import com.zhongshu.card.client.utils.type.RefundState;
+import com.zhongshu.card.client.utils.type.StatisticType;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.AllArgsConstructor;
 import lombok.Data;
@@ -9,6 +12,7 @@ import lombok.NoArgsConstructor;
 import org.apache.commons.lang3.StringUtils;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 /**
  * @author TRX
@@ -21,6 +25,18 @@ public class ExpenseFlowSearch extends SuperSearch {
     @Schema(description = "用户userId")
     private String userId;
 
+    @Schema(description = "订单状态")
+    private List<OrderType> orderTypes;
+
+    @Schema(description = "所属项目Oid")
+    private String projectOid;
+
+    @Schema(description = "订单所属的商户")
+    private String shopOid;
+
+    @Schema(description = "订单所属的学校")
+    private String schoolOid;
+
     @Schema(description = "消费类型,如:餐饮消费")
     private String payType;
 
@@ -30,6 +46,9 @@ public class ExpenseFlowSearch extends SuperSearch {
     @Schema(description = "月份,如06")
     private String month;
 
+    @Schema(description = "第几周")
+    private String week;
+
     public String getMonth() {
         if (StringUtils.isNotEmpty(month)) {
             if (month.length() == 2) {
@@ -64,4 +83,25 @@ public class ExpenseFlowSearch extends SuperSearch {
 
     @Schema(description = "是否消费成功")
     private Boolean isPaySuccess;
+
+    @Schema(description = "退款状态")
+    private RefundState refundState;
+
+    @Schema(description = "")
+    private Boolean verifyParamIsSuccess;
+
+    @Schema(description = "是否退款")
+    private Boolean isRefund;
+
+    // ------------------商户查询参数 start-----------------
+
+    @Schema(description = "是否查询所有的商户")
+    private Boolean isAllBusinessMain = Boolean.TRUE;
+
+    @Schema(description = "查询商户集合")
+    private List<String> shopOids;
+
+    @Schema(description = "统计类型,按年、月、周", hidden = true)
+    private StatisticType statisticType;
+
 }

+ 4 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/ExpenseRefundParam.java

@@ -1,5 +1,6 @@
 package com.zhongshu.card.client.model.payment;
 
+import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -12,6 +13,9 @@ import lombok.NoArgsConstructor;
 @AllArgsConstructor
 @NoArgsConstructor
 public class ExpenseRefundParam {
+    @Schema(description = "数据ID")
     private String id;
+
+    @Schema(description = "退款备注")
     private String remark;
 }

+ 30 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/statistic/BusinessMainStatisticModel.java

@@ -0,0 +1,30 @@
+package com.zhongshu.card.client.model.payment.statistic;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author TRX
+ * @date 2024/8/2
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class BusinessMainStatisticModel {
+
+    @Schema(description = "统计项")
+    private List<StatisticItem> items = new ArrayList<>();
+
+    @Schema(description = "当前金额金额,单位分")
+    private BigDecimal amount = BigDecimal.ZERO;
+
+    @Schema(description = "当前订单数量")
+    private String total;
+
+}

+ 24 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/statistic/StatisticItem.java

@@ -0,0 +1,24 @@
+package com.zhongshu.card.client.model.payment.statistic;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+/**
+ * @author TRX
+ * @date 2024/8/2
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class StatisticItem {
+
+    @Schema(description = "统计项")
+    private String name;
+
+    @Schema(description = "金额")
+    private BigDecimal amount;
+}

+ 31 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/statistic/StatisticSearch.java

@@ -0,0 +1,31 @@
+package com.zhongshu.card.client.model.payment.statistic;
+
+import com.zhongshu.card.client.utils.type.StatisticType;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * 商户首页统计
+ *
+ * @author TRX
+ * @date 2024/6/17
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class StatisticSearch {
+
+    @Schema(description = "是否查询所有的商户")
+    private Boolean isAllBusinessMain = Boolean.TRUE;
+
+    @Schema(description = "商户oid,当isAllBusinessMain=false,传入该值")
+    private String shopOid;
+
+    @Schema(description = "统计类型,按年、月、周", hidden = true)
+    private StatisticType statisticType = StatisticType.Month;
+
+}

+ 8 - 1
FullCardClient/src/main/java/com/zhongshu/card/client/service/payment/ExpenseFlowService.java

@@ -16,11 +16,18 @@ public interface ExpenseFlowService {
 
     ResultContent<Page<ExpenseFlowModel>> page(ExpenseFlowSearch param, Pageable pageable);
 
-    ResultContent<ExpenseFlowCount> countPayment(ExpenseFlowSearch param);
+    // 统计用户的消费金额
+    ResultContent<ExpenseFlowCount> countUserPayment(ExpenseFlowSearch param);
 
     ResultContent<ExpenseFlowModel> getDetail(String id);
 
+    // 商户的订单列表
+    ResultContent<Page<ExpenseFlowModel>> pageBusMainOrder(ExpenseFlowSearch param, Pageable pageable);
+
     // 商家直接消费订单退款
     ResultContent expenseShopRefund(ExpenseRefundParam param);
 
+    // 商户统计
+    ResultContent<ExpenseFlowCount> countBuinessMainPayment(ExpenseFlowSearch param);
+
 }

+ 20 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/utils/type/StatisticType.java

@@ -0,0 +1,20 @@
+package com.zhongshu.card.client.utils.type;
+
+import lombok.Getter;
+
+/**
+ * 统计类型
+ */
+public enum StatisticType {
+    Year("年"),
+    Month("月"),
+    Week("周"),
+    ;
+
+    @Getter
+    private String remark;
+
+    StatisticType(String remark) {
+        this.remark = remark;
+    }
+}

+ 29 - 8
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/payment/ExpenseFlowController.java

@@ -46,13 +46,6 @@ public class ExpenseFlowController {
     @Autowired
     AuthHelper authHelper;
 
-    @ResourceAuth(value = "user", type = AuthType.User)
-    @Operation(summary = "消费详情", description = "消费详情")
-    @RequestMapping(value = "getDetail", method = {RequestMethod.POST})
-    public ResultContent<ExpenseFlowModel> getDetail(@RequestBody IDParam param) {
-        return this.expenseFlowService.getDetail(param.getId());
-    }
-
     @ResourceAuth(value = "user", type = AuthType.User)
     @Operation(summary = "消费列表-分页查询(当前用户)", description = "消费列表-分页查询")
     @RequestMapping(value = {"page"}, method = {RequestMethod.POST})
@@ -64,13 +57,32 @@ public class ExpenseFlowController {
         return expenseFlowService.page(param, pageable);
     }
 
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @Operation(summary = "消费详情", description = "消费详情")
+    @RequestMapping(value = "getDetail", method = {RequestMethod.POST})
+    public ResultContent<ExpenseFlowModel> getDetail(@RequestBody IDParam param) {
+        return this.expenseFlowService.getDetail(param.getId());
+    }
+
     @ResourceAuth(value = "user", type = AuthType.User)
     @Operation(summary = "统计消费总数(当前用户)", description = "统计消费总数")
     @RequestMapping(value = {"countPayment"}, method = {RequestMethod.POST})
     public ResultContent<ExpenseFlowCount> countPayment(@RequestBody ExpenseFlowSearch param) {
         param.setIsPaySuccess(Boolean.TRUE);
         param.setUserId(authHelper.getCurrentUser().getUserId());
-        return expenseFlowService.countPayment(param);
+        return expenseFlowService.countUserPayment(param);
+    }
+
+
+    //------------------------商户订单相关功能 start--------------------------
+
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @Operation(summary = "商户订单查询", description = "商户订单查询询")
+    @RequestMapping(value = {"pageBusMainOrder"}, method = {RequestMethod.POST})
+    public ResultContent<Page<ExpenseFlowModel>> pageBusMainOrder(
+            @Parameter(hidden = true) @PageableDefault(page = 0, size = 10) Pageable pageable,
+            @Parameter(required = false) ExpenseFlowSearch param) {
+        return expenseFlowService.pageBusMainOrder(param, pageable);
     }
 
     @ResourceAuth(value = "user", type = AuthType.User)
@@ -80,4 +92,13 @@ public class ExpenseFlowController {
         return expenseFlowService.expenseShopRefund(param);
     }
 
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @Operation(summary = "统计商户收入总数", description = "统计商户收入总数")
+    @RequestMapping(value = {"countBusinessMainPayment"}, method = {RequestMethod.POST})
+    public ResultContent<ExpenseFlowCount> countBusinessMainPayment(@RequestBody ExpenseFlowSearch param) {
+        return expenseFlowService.countBuinessMainPayment(param);
+    }
+
+    //------------------------商户订单相关功能 end----------------------------
+
 }

+ 12 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/BaseImpl.java

@@ -27,6 +27,18 @@ public abstract class BaseImpl {
         return criteria;
     }
 
+    /**
+     * 通用搜索条件 不包含oid
+     *
+     * @param param
+     * @return
+     */
+    public Criteria buildCriteriaNotOid(SuperSearch param) {
+        Criteria criteria = new Criteria();
+        criteria.and("isDelete").is(Boolean.FALSE);
+        return criteria;
+    }
+
     /**
      * 排序
      *

+ 3 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/org/OrganizationUserDao.java

@@ -36,4 +36,7 @@ public interface OrganizationUserDao extends MongoDao<OrganizationUser>, Organiz
 
     // 查询用户所在机构
     List<OrganizationUser> findByUserAndAuthTypeAndState(UserAccount userAccount, AuthType authType, UserState state);
+
+    List<OrganizationUser> findByUserAndAuthType(UserAccount userAccount, AuthType authType);
+
 }

+ 14 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/payment/extend/ExpenseFlowDaoExtend.java

@@ -30,7 +30,20 @@ public interface ExpenseFlowDaoExtend {
      * @param param
      * @return
      */
-    ExpenseFlowCount countPayment(ExpenseFlowSearch param);
+    ExpenseFlowCount countUserPayment(ExpenseFlowSearch param);
+
+    /**
+     * 统计商户总的收入
+     *
+     * @param param
+     * @return
+     */
+    ExpenseFlowCount countBuinessMainPayment(ExpenseFlowSearch param);
+
+    // 统计数量
+    long countExpenseFlows(ExpenseFlowSearch param);
 
     ExpenseFlow init(String mqttDataId, String token);
+
+
 }

+ 109 - 28
FullCardServer/src/main/java/com/zhongshu/card/server/core/dao/payment/impl/ExpenseFlowDaoImpl.java

@@ -32,6 +32,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 /**
  * @Author TRX
@@ -47,22 +48,28 @@ public class ExpenseFlowDaoImpl extends BaseImpl implements ExpenseFlowDaoExtend
     @Autowired
     private DBHelper dbHelper;
 
-    @Override
-    public Page<ExpenseFlow> page(Pageable pageable, ExpenseFlowSearch param) {
-        Criteria criteria = buildCriteria(param);
+    private Criteria buildSearcCriteria(ExpenseFlowSearch param) {
+        Criteria criteria = buildCriteriaNotOid(param);
 
         if (StringUtils.isNotEmpty(param.getUserId())) {
             criteria.and("userId").is(param.getUserId());
         }
 
+        // 年
         if (StringUtils.isNotEmpty(param.getYear())) {
             criteria.and("year").is(param.getYear());
         }
-
+        // 月
         if (StringUtils.isNotEmpty(param.getMonth())) {
             criteria.and("month").is(CommonUtil.turnMonthSearch(param.getMonth()));
         }
 
+        // 周
+        if (StringUtils.isNotEmpty(param.getWeek())) {
+            criteria.and("week").is(param.getWeek());
+        }
+
+        // 是否支付成功
         if (param.getIsPaySuccess() != null) {
             criteria.and("isPaySuccess").is(param.getIsPaySuccess());
         }
@@ -71,6 +78,46 @@ public class ExpenseFlowDaoImpl extends BaseImpl implements ExpenseFlowDaoExtend
             criteria.and("createTime").gte(param.getStartTime()).and("createTime").lte(param.getEndTime());
         }
 
+        // 项目
+        if (StringUtils.isNotEmpty(param.getProjectOid())) {
+            criteria.and("projectOid").is(param.getProjectOid());
+        }
+
+        // 学校
+        if (StringUtils.isNotEmpty(param.getSchoolOid())) {
+            criteria.and("schoolOid").is(param.getSchoolOid());
+        }
+
+        // 商户
+        if (StringUtils.isNotEmpty(param.getShopOid())) {
+            criteria.and("shopOid").is(param.getShopOid());
+        }
+
+        // 商户集合
+        if (ObjectUtils.isNotEmpty(param.getShopOids())) {
+            criteria.and("shopOids").in(param.getShopOids());
+        }
+
+        // 是否支付成功
+        if (param.getIsPaySuccess() != null) {
+            criteria.and("isPaySuccess").is(param.getIsPaySuccess());
+        }
+
+        // 退款状态
+        if (param.getRefundState() != null) {
+            criteria.and("refundState").is(param.getRefundState());
+        }
+
+        // 是否退款
+        if (param.getIsRefund() != null) {
+            criteria.and("isRefund").is(param.getIsRefund());
+        }
+
+        // 订单状态
+        if (ObjectUtils.isNotEmpty(param.getOrderTypes())) {
+            criteria.and("orderTypes").in(param.getOrderTypes());
+        }
+
         // 模糊搜索
         List<Criteria> criterias = new ArrayList<>();
         if (StringUtils.isNotEmpty(param.getOrderNo())) {
@@ -85,71 +132,105 @@ public class ExpenseFlowDaoImpl extends BaseImpl implements ExpenseFlowDaoExtend
         if (!CollectionUtils.isEmpty(criterias)) {
             criteria.andOperator(criterias.toArray(new Criteria[]{}));
         }
+        return criteria;
+    }
 
+    /**
+     * 查询订单列表
+     *
+     * @param pageable
+     * @param param
+     * @return
+     */
+    @Override
+    public Page<ExpenseFlow> page(Pageable pageable, ExpenseFlowSearch param) {
+        Criteria criteria = buildSearcCriteria(param);
         Sort sort = buildSort(param);
         Query query = Query.query(criteria);
         query.with(sort);
         return dbHelper.pages(query, pageable, ExpenseFlow.class);
     }
 
+    @Override
+    public long countExpenseFlows(ExpenseFlowSearch param) {
+        Criteria criteria = buildSearcCriteria(param);
+        Query query = Query.query(criteria);
+        return mongoTemplate.count(query, ExpenseFlow.class);
+    }
+
     /**
-     * 统计
+     * 统计 用户的消费金额
      *
      * @param param
      * @return
      */
     @Override
-    public ExpenseFlowCount countPayment(ExpenseFlowSearch param) {
+    public ExpenseFlowCount countUserPayment(ExpenseFlowSearch param) {
         ExpenseFlowCount expenseFlowCount = new ExpenseFlowCount();
-        Criteria criteria = buildCriteria(param);
-
-        if (StringUtils.isNotEmpty(param.getUserId())) {
-            criteria.and("userId").is(param.getUserId());
-        }
+        Criteria criteria = buildSearcCriteria(param);
 
-        if (StringUtils.isNotEmpty(param.getYear())) {
-            criteria.and("year").is(param.getYear());
-        }
+        List<AggregationOperation> operations = new ArrayList<>(2);
+        AggregationOperation match = Aggregation.match(criteria);
+        operations.add(match);
 
-        if (StringUtils.isNotEmpty(param.getMonth())) {
-            criteria.and("month").is(param.getMonth());
-        }
+        AggregationOperation group = Aggregation.group("$userId").sum("$payAmount").as("count");
+        operations.add(group);
 
-        if (param.getIsPaySuccess() != null) {
-            criteria.and("isPaySuccess").is(param.getIsPaySuccess());
+        BigDecimal number = BigDecimal.ZERO;
+        Aggregation groupAggregation = Aggregation.newAggregation(operations);
+        List<Map> countObjs = mongoTemplate.aggregate(groupAggregation, ExpenseFlow.class, Map.class).getMappedResults();
+        if (countObjs.size() > 0) {
+            Map map = countObjs.get(0);
+            Object obj = map.get("count");
+            number = CommonUtil.getBigDecimalByObj(obj);
         }
+        expenseFlowCount.setPayAmount(number);
+        return expenseFlowCount;
+    }
 
-        if (!CommonUtil.longIsEmpty(param.getStartTime()) && !CommonUtil.longIsEmpty(param.getEndTime())) {
-            criteria.and("createTime").gte(param.getStartTime()).and("createTime").lte(param.getEndTime());
-        }
+    /**
+     * 商户收入总数
+     *
+     * @param param
+     * @return
+     */
+    @Override
+    public ExpenseFlowCount countBuinessMainPayment(ExpenseFlowSearch param) {
+        ExpenseFlowCount expenseFlowCount = new ExpenseFlowCount();
+        Criteria criteria = buildSearcCriteria(param);
 
         List<AggregationOperation> operations = new ArrayList<>(2);
         AggregationOperation match = Aggregation.match(criteria);
         operations.add(match);
 
-        AggregationOperation group = Aggregation.group("$userId").sum("$payAmount").as("count");
+        AggregationOperation group = Aggregation.group("$shopOid").sum("$payAmount").as("count");
         operations.add(group);
 
         BigDecimal number = BigDecimal.ZERO;
         Aggregation groupAggregation = Aggregation.newAggregation(operations);
         List<Map> countObjs = mongoTemplate.aggregate(groupAggregation, ExpenseFlow.class, Map.class).getMappedResults();
         if (countObjs.size() > 0) {
-            Map map = countObjs.get(0);
-            Object obj = map.get("count");
-            number = CommonUtil.getBigDecimalByObj(obj);
+            List<BigDecimal> numbers = countObjs.stream().map(it -> {
+                Object obj = it.get("count");
+                return CommonUtil.getBigDecimalByObj(obj);
+            }).collect(Collectors.toList());
+            number = numbers.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
         }
         expenseFlowCount.setPayAmount(number);
+        // 数据条数
+        expenseFlowCount.setTotal(countExpenseFlows(param));
+
         return expenseFlowCount;
     }
 
+
     public ExpenseFlow init(String mqttDataId, String token) {
         ExpenseFlow doc = null;
         try {
             Query query = Query.query(Criteria.where("mqttDataId").is(mqttDataId).and("token").isNull());
             Update update = new Update()
                     .set("token", token)
-                    .set("createTime", System.currentTimeMillis())
-                    ;
+                    .set("createTime", System.currentTimeMillis());
             FindAndModifyOptions options = new FindAndModifyOptions().upsert(true)
                     .returnNew(true);
             doc = mongoTemplate.findAndModify(query, update, options,

+ 6 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/domain/payment/ExpenseFlow.java

@@ -87,6 +87,9 @@ public class ExpenseFlow extends SuperMain {
     @Schema(description = "月份,如06")
     private String month;
 
+    @Schema(description = "第几周")
+    private String week;
+
     @Schema(description = "消费订单号")
     private String orderNo;
 
@@ -164,6 +167,9 @@ public class ExpenseFlow extends SuperMain {
     @Schema(description = "操作退款用户userId")
     private String refundUserId;
 
+    @Schema(description = "退款金额")
+    private BigDecimal refundAMount;
+
     @Schema(description = "退款状态")
     private RefundState refundState;
 

+ 30 - 4
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/IndexService.java

@@ -17,6 +17,7 @@ import com.zhongshu.card.client.model.org.OrganizationUserModel;
 import com.zhongshu.card.client.model.wechat.PhoneModel;
 import com.zhongshu.card.client.model.wechat.WechatPhoneNumber;
 import com.zhongshu.card.client.ret.ResultContent;
+import com.zhongshu.card.client.service.org.OrganizationService;
 import com.zhongshu.card.client.utils.type.LoginFromType;
 import com.zhongshu.card.client.utils.type.OrganizationState;
 import com.zhongshu.card.client.utils.type.UserState;
@@ -29,16 +30,14 @@ import jakarta.servlet.http.HttpServletRequest;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.kafka.common.protocol.types.Field;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
+import java.util.*;
 
 /**
  * @author TRX
@@ -89,9 +88,13 @@ public class IndexService {
 
     @Autowired
     UserAccountServiceImpl userAccountService;
+
     @Autowired
     private RoleServiceImpl roleServiceImpl;
 
+    @Autowired
+    OrganizationServiceImpl organizationService;
+
     /**
      * 登录 只验证 用户名 和密码
      *
@@ -100,9 +103,26 @@ public class IndexService {
      */
     public ResultContent login(LoginParam param) {
         String phone = param.getLoginValue();
+
+        LoginFromType loginFromType = param.getLoginFromType();
+        // 验证用户是否加入该类型机构
+        if (loginFromType != null) {
+            UserAccount userAccount = userCountDao.findTopByLoginName(phone);
+            String userId = userAccount.getUserId();
+            if (loginFromType == LoginFromType.Shop) {
+                // 登录商家端
+                List<Organization> shopOrgs = organizationService.getUserAllOrgs(userId, AuthType.BusinessMain);
+                if (ObjectUtils.isEmpty(shopOrgs)) {
+                    return ResultContent.buildFail("该用户未加入任何商户,登录失败");
+                }
+            }
+        }
+
+        // 验证用户名密码
         UserAuthLoginModel userAuthLoginModel = new UserAuthLoginModel();
         BeanUtils.copyProperties(param, userAuthLoginModel);
         ResultContent resultContent = commonLogin(userAuthLoginModel);
+
         if (resultContent.isFailed()) {
             return resultContent;
         }
@@ -212,6 +232,12 @@ public class IndexService {
         return ResultContent.buildSuccess(b);
     }
 
+    /**
+     * 通用登录 只验证用户名和密码
+     *
+     * @param userAuthLoginModel
+     * @return
+     */
     public ResultContent<LoginTokenModel> commonLogin(UserAuthLoginModel userAuthLoginModel) {
         String phone = userAuthLoginModel.getLoginValue();
         userAuthLoginModel.setDeviceIp(IPUtil.getRemoteIp(request));

+ 79 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/org/OrganizationServiceImpl.java

@@ -593,6 +593,79 @@ public class OrganizationServiceImpl extends SuperService implements Organizatio
         return ResultContent.buildSuccess(model);
     }
 
+    /**
+     * 根据oid查询机构entity信息
+     *
+     * @param oid
+     * @return
+     */
+    public Organization getOrgByOid(String oid) {
+        Organization organization = organizationDao.findTopByOid(oid);
+        return organization;
+    }
+
+    /**
+     * 判断oid是否是商户
+     *
+     * @param oid
+     * @return
+     */
+    public boolean oidIsBusinessMain(String oid) {
+        Organization organization = organizationDao.findTopByOid(oid);
+        if (ObjectUtils.isNotEmpty(organization) && organization.getAuthType() == AuthType.BusinessMain) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 判断oid是否是学校
+     *
+     * @param oid
+     * @return
+     */
+    public boolean oidIsSchool(String oid) {
+        Organization organization = organizationDao.findTopByOid(oid);
+        if (ObjectUtils.isNotEmpty(organization) && organization.getAuthType() == AuthType.School) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 判断oid是否是项目
+     *
+     * @param oid
+     * @return
+     */
+    public boolean oidIsProject(String oid) {
+        Organization organization = organizationDao.findTopByOid(oid);
+        if (ObjectUtils.isNotEmpty(organization) && organization.getAuthType() == AuthType.Project) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 查询用户所有机构的数据
+     *
+     * @param userId
+     * @return
+     */
+    public List<Organization> getUserAllOrgs(String userId, AuthType authType) {
+        List<Organization> orgs = new ArrayList<>();
+        UserAccount userAccount = userCountDao.findTopByUserId(userId);
+        if (ObjectUtils.isNotEmpty(userAccount)) {
+            List<OrganizationUser> _list = organizationUserDao.findByUserAndAuthType(userAccount, authType);
+            if (ObjectUtils.isNotEmpty(_list)) {
+                orgs = _list.stream().map(it -> {
+                    return it.getOrganization();
+                }).collect(Collectors.toList());
+            }
+        }
+        return orgs;
+    }
+
     /**
      * 分页数据
      *
@@ -862,6 +935,12 @@ public class OrganizationServiceImpl extends SuperService implements Organizatio
         return model;
     }
 
+    /**
+     * 根据code查询机构信息
+     *
+     * @param code
+     * @return
+     */
     public String getOrgNameByCode(String code) {
         if (StringUtils.isNotEmpty(code)) {
             Organization organization = organizationDao.findTopByCode(code);

+ 95 - 11
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/payment/ExpenseFlowServiceImpl.java

@@ -2,15 +2,15 @@ package com.zhongshu.card.server.core.service.payment;
 
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
+import com.github.microservice.auth.security.type.AuthType;
 import com.github.microservice.components.data.base.util.PageEntityUtil;
 import com.github.microservice.models.hxz.*;
 import com.github.microservice.models.type.OrderFromType;
 import com.github.microservice.models.type.PaymentDeviceType;
 import com.github.microservice.models.type.PaymentType;
-import com.zhongshu.card.client.model.payment.ExpenseFlowCount;
-import com.zhongshu.card.client.model.payment.ExpenseFlowModel;
-import com.zhongshu.card.client.model.payment.ExpenseFlowSearch;
-import com.zhongshu.card.client.model.payment.ExpenseRefundParam;
+import com.zhongshu.card.client.model.payment.*;
+import com.zhongshu.card.client.model.payment.statistic.BusinessMainStatisticModel;
+import com.zhongshu.card.client.model.payment.statistic.StatisticSearch;
 import com.zhongshu.card.client.ret.ResultContent;
 import com.zhongshu.card.client.ret.ResultMessage;
 import com.zhongshu.card.client.service.payment.ExpenseFlowService;
@@ -27,8 +27,6 @@ import com.zhongshu.card.server.core.domain.org.Organization;
 import com.zhongshu.card.server.core.domain.org.OrganizationRelation;
 import com.zhongshu.card.server.core.domain.org.UserAccount;
 import com.zhongshu.card.server.core.domain.payment.ExpenseFlow;
-import com.zhongshu.card.server.core.domain.payment.Wallet;
-import com.zhongshu.card.server.core.domain.payment.WalletRecharge;
 import com.zhongshu.card.server.core.domain.school.CardInfo;
 import com.zhongshu.card.server.core.domain.org.DeviceInfo;
 import com.zhongshu.card.server.core.domain.school.DeviceBind;
@@ -51,6 +49,9 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * @author TRX
@@ -114,6 +115,7 @@ public class ExpenseFlowServiceImpl extends SuperService implements ExpenseFlowS
 
         expenseFlow.setYear(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.patternyyyy));
         expenseFlow.setMonth(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.patternMM));
+        expenseFlow.setWeek(DateUtils.getCurrentWeekInYear() + "");
         expenseFlow.setPaymentTime(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.patternyyyySSS));
 
         // 消费订单号
@@ -457,8 +459,7 @@ public class ExpenseFlowServiceImpl extends SuperService implements ExpenseFlowS
                 result.setAmount(CommonUtil.turnMoney2Show(expenseFlow.getPayAmount()));
 
                 if (expenseFlow.getPaymentType() == PaymentType.UserWallet) {
-                    com.zhongshu.payment.client.ret.ResultContent<WalletModel> content = walletFeignService.getWallet(
-                            expenseFlow.getProjectOid(), WalletType.User, "", expenseFlow.getUserId());
+                    com.zhongshu.payment.client.ret.ResultContent<WalletModel> content = walletFeignService.getWallet(expenseFlow.getProjectOid(), WalletType.User, "", expenseFlow.getUserId());
                     if (content.isSuccess()) {
                         WalletModel walletModel = content.getContent();
                         if (ObjectUtils.isNotEmpty(walletModel)) {
@@ -489,6 +490,49 @@ public class ExpenseFlowServiceImpl extends SuperService implements ExpenseFlowS
         return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toModel));
     }
 
+    /**
+     * 商户订单查询
+     *
+     * @param param
+     * @param pageable
+     * @return
+     */
+    @Override
+    public ResultContent<Page<ExpenseFlowModel>> pageBusMainOrder(ExpenseFlowSearch param, Pageable pageable) {
+        // 查询支付成功的
+        param.setIsPaySuccess(Boolean.TRUE);
+        // 用户搜索的商户
+        List<String> shopOids = getSearchAllShopOid(param);
+        if (ObjectUtils.isEmpty(shopOids)) {
+            return ResultContent.buildFail("请选择查询商户或所有的");
+        }
+        param.setShopOids(shopOids);
+        Page<ExpenseFlow> page = expenseFlowDao.page(pageable, param);
+        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toModel));
+    }
+
+    /**
+     * 查询搜索条件
+     *
+     * @param param
+     * @return
+     */
+    public List<String> getSearchAllShopOid(ExpenseFlowSearch param) {
+        List<String> shopOids = new ArrayList<String>();
+        if (param.getIsAllBusinessMain() != null && param.getIsAllBusinessMain()) {
+            // 查询当前用户所有的商户信息
+            List<Organization> orgs = organizationService.getUserAllOrgs(getCurrentUserId(), AuthType.BusinessMain);
+            if (ObjectUtils.isNotEmpty(orgs)) {
+                shopOids = orgs.stream().map(it -> it.getOid()).collect(Collectors.toList());
+            }
+        } else {
+            if (StringUtils.isNotEmpty(param.getShopOid())) {
+                shopOids.add(param.getShopOid());
+            }
+        }
+        return shopOids;
+    }
+
     /**
      * 统计用户支出总数
      *
@@ -496,8 +540,8 @@ public class ExpenseFlowServiceImpl extends SuperService implements ExpenseFlowS
      * @return
      */
     @Override
-    public ResultContent<ExpenseFlowCount> countPayment(ExpenseFlowSearch param) {
-        return ResultContent.buildSuccess(expenseFlowDao.countPayment(param));
+    public ResultContent<ExpenseFlowCount> countUserPayment(ExpenseFlowSearch param) {
+        return ResultContent.buildSuccess(expenseFlowDao.countUserPayment(param));
     }
 
     /**
@@ -511,7 +555,46 @@ public class ExpenseFlowServiceImpl extends SuperService implements ExpenseFlowS
         param.setStartTime(DateUtils.getDayStartTime(System.currentTimeMillis()));
         param.setEndTime(DateUtils.getDayEndTime(System.currentTimeMillis()));
         param.setUserId(userId);
-        return ResultContent.buildSuccess(expenseFlowDao.countPayment(param));
+        param.setIsPaySuccess(Boolean.TRUE);
+        return ResultContent.buildSuccess(expenseFlowDao.countUserPayment(param));
+    }
+
+    /**
+     * 统计商户的数据
+     *
+     * @param param
+     * @return
+     */
+    public ResultContent<ExpenseFlowCount> countBuinessMainPayment(ExpenseFlowSearch param) {
+        // 查询支付成功的
+        param.setIsPaySuccess(Boolean.TRUE);
+        // 用户搜索的商户
+        List<String> shopOids = getSearchAllShopOid(param);
+        if (ObjectUtils.isEmpty(shopOids)) {
+            return ResultContent.buildFail("请选择查询商户或所有的");
+        }
+        param.setShopOids(shopOids);
+        ExpenseFlowCount flowCount = expenseFlowDao.countBuinessMainPayment(param);
+        return ResultContent.buildSuccess(flowCount);
+    }
+
+    /**
+     * 商户首页统计
+     *
+     * @param statisticSearch
+     * @return
+     */
+    public ResultContent businessMainPageStatistic(StatisticSearch statisticSearch) {
+        BusinessMainStatisticModel statisticModel = new BusinessMainStatisticModel();
+
+        ExpenseFlowSearch param = new ExpenseFlowSearch();
+        param.setIsPaySuccess(Boolean.TRUE);
+        BeanUtils.copyProperties(statisticSearch, param);
+        // 统计模型,按 月、周
+        StatisticType statisticType = param.getStatisticType();
+
+
+        return ResultContent.buildSuccess(statisticModel);
     }
 
     /**
@@ -562,6 +645,7 @@ public class ExpenseFlowServiceImpl extends SuperService implements ExpenseFlowS
             expenseFlow.setApplicant(getCurrentUserId());
             // 退款人
             expenseFlow.setRefundUserId(getCurrentUserId());
+            expenseFlow.setRefundAMount(expenseFlow.getPayAmount());
             expenseFlow.setOrderType(OrderType.REFUNDED);
             expenseFlow.setRefundState(RefundState.Refunded);
             expenseFlow.setRefuseRemark("退款成功");

+ 3 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/test/Test.java

@@ -4,6 +4,7 @@ import cn.hutool.core.lang.Snowflake;
 import cn.hutool.json.JSONUtil;
 import com.zhongshu.card.client.utils.type.DataState;
 import com.zhongshu.card.server.core.util.CommonUtil;
+import com.zhongshu.card.server.core.util.DateUtils;
 import com.zhongshu.card.server.core.util.ValidateResult;
 import com.zhongshu.card.server.core.util.ValidateUtils;
 import groovy.lang.GroovyShell;
@@ -38,6 +39,8 @@ public class Test {
         BigDecimal b2 = BigDecimal.valueOf(54.32);
         System.out.println("m= " + b1.divide(b2, 5, RoundingMode.HALF_UP));
 
+        System.out.println("weekDays: " + DateUtils.getCurrentYear());
+
         GroovyShell groovyShell = new GroovyShell();
         String res = " println 'Hello, Groovy!' ";
         Object result1 = groovyShell.evaluate(res);

+ 44 - 4
FullCardServer/src/main/java/com/zhongshu/card/server/core/util/DateUtils.java

@@ -7,10 +7,8 @@ import org.apache.commons.lang3.StringUtils;
 import java.sql.Timestamp;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.ZoneId;
+import java.time.*;
+import java.time.temporal.IsoFields;
 import java.time.temporal.WeekFields;
 import java.util.*;
 
@@ -181,6 +179,48 @@ public class DateUtils {
         return beginTime;
     }
 
+    /**
+     * 得到当前是本周第几天
+     *
+     * @return
+     */
+    public static int getCurrentWeekDay() {
+        Calendar c = Calendar.getInstance();
+        int weekday = c.get(Calendar.DAY_OF_WEEK);
+        return weekday - 1;
+    }
+
+    /**
+     * 当前是今年第几周
+     *
+     * @return
+     */
+    public static int getCurrentWeekInYear() {
+        LocalDate date = LocalDate.now(); // 获取当前日期
+        int weekOfYear = date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
+        return weekOfYear;
+    }
+
+    /**
+     * 得到当前是第几月份,如:8
+     *
+     * @return
+     */
+    public static int getCurrentMonthInYear() {
+        LocalDate date = LocalDate.now(); // 获取当前日期
+        return date.getMonthValue();
+    }
+
+    /**
+     * 得到当前年份,如:2024
+     *
+     * @return
+     */
+    public static int getCurrentYear() {
+        LocalDate date = LocalDate.now(); // 获取当前日期
+        return date.getYear();
+    }
+
     /**
      * 获得本小时的开始时间
      *