Explorar el Código

Merge remote-tracking branch 'origin/master'

TRX hace 1 año
padre
commit
df120f28ca

+ 27 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/ExpenseFlowUnionParam.java

@@ -0,0 +1,27 @@
+package com.zhongshu.card.client.model.payment;
+
+import com.zhongshu.card.client.type.payment.OrderType;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+public class ExpenseFlowUnionParam {
+
+    @Schema(description = "项目oid")
+    private String projectOid;
+
+    @Schema(description = "机构oid")
+    private String oid;
+
+    @Schema(description = "开始时间")
+    private Long startTime;
+
+    @Schema(description = "结束时间")
+    private Long endTime;
+
+    @Schema(description = "订单类型")
+    private OrderType orderType;
+
+    @Schema(description = "订单编号")
+    private String orderNo;
+}

+ 67 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/model/payment/OrderUnionWithModel.java

@@ -0,0 +1,67 @@
+package com.zhongshu.card.client.model.payment;
+
+import com.github.microservice.models.type.DeviceType;
+import com.github.microservice.types.OrderState;
+import com.github.microservice.types.payment.PaymentType;
+import com.zhongshu.card.client.model.org.UserCountModel;
+import com.zhongshu.card.client.model.school.AreaSimpleModel;
+import com.zhongshu.card.client.type.RefundState;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class OrderUnionWithModel {
+
+    private String id;
+
+    private Long createTime;
+
+    private Long updateTime;
+
+    @Schema(description = "所属机构ID")
+    private String oid;
+
+    @Schema(description = "所属项目oid")
+    private String projectOid;
+
+    @Schema(description = "数据主题的oid")
+    private String aboutOid;
+
+    @Schema(description = "订单的总体状态")
+    private OrderState orderState;
+
+    @Schema(description = "支付方式")
+    private PaymentType paymentType;
+
+    @Schema(description = "消费金额(单位:分)")
+    private BigDecimal payAmount;
+
+    @Schema(description = "用户信息")
+    private UserCountModel userAccount;
+
+    @Schema(description = "消费机设备ID")
+    private String deviceId;
+
+    @Schema(description = "设备类型")
+    private DeviceType deviceType;
+
+    @Schema(description = "设备所属区域信息")
+    private AreaSimpleModel area;
+
+    @Schema(description = "是否退款")
+    private Boolean isRefund;
+
+    @Schema(description = "操作退款用户userId")
+    private String refundUserId;
+
+    @Schema(description = "退款金额")
+    private BigDecimal refundAMount;
+
+    @Schema(description = "退款状态")
+    private RefundState refundState;
+
+    @Schema(description = "申请退款时间")
+    private Long refundTime;
+}

+ 16 - 0
FullCardClient/src/main/java/com/zhongshu/card/client/type/payment/OrderType.java

@@ -0,0 +1,16 @@
+package com.zhongshu.card.client.type.payment;
+
+import lombok.Getter;
+
+public enum OrderType {
+    Recharge("充值"),
+    Consume("消费"),
+    ;
+
+    @Getter
+    private String remark;
+
+    OrderType(String remark) {
+        this.remark = remark;
+    }
+}

+ 8 - 1
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/attendance/LeaveController.java

@@ -1,5 +1,7 @@
 package com.zhongshu.card.server.core.controller.attendance;
 
+import com.github.microservice.auth.security.annotations.ResourceAuth;
+import com.github.microservice.auth.security.type.AuthType;
 import com.github.microservice.net.ResultContent;
 import com.zhongshu.card.client.model.attendance.ApplyLeaveParam;
 import com.zhongshu.card.client.model.attendance.ApprovalLeaveParam;
@@ -26,30 +28,35 @@ public class LeaveController {
 
     @Operation(summary = "请假应用场景配置", description = "数据详情")
     @RequestMapping(value = "setting", method = {RequestMethod.POST})
+    @ResourceAuth(value = "user", type = AuthType.User)
     public ResultContent setting(@RequestBody @Valid LeaveSettingParam param){
         return leaveService.setting(param);
     }
 
     @Operation(summary = "获取请假应用场景配置", description = "数据详情")
     @RequestMapping(value = "getSetting", method = {RequestMethod.GET})
+    @ResourceAuth(value = "user", type = AuthType.User)
     public ResultContent getSetting(@RequestParam("sceneId") String sceneId){
         return leaveService.getSetting(sceneId);
     }
 
     @Operation(summary = "发起请假申请", description = "发起请假申请")
     @RequestMapping(value = "apply", method = {RequestMethod.POST})
+    @ResourceAuth(value = "user", type = AuthType.User)
     public ResultContent apply(@RequestBody @Valid ApplyLeaveParam param){
         return leaveService.apply(param);
     }
 
-    @Operation(summary = "请假审批", description = "发起请假申请")
+    @Operation(summary = "请假审批", description = "审批请假申请")
     @RequestMapping(value = "approval", method = {RequestMethod.POST})
+    @ResourceAuth(value = "user", type = AuthType.User)
     public ResultContent approval(@RequestBody @Valid ApprovalLeaveParam param){
         return leaveService.approval(param);
     }
 
     @Operation(summary = "请假申请列表(分页)", description = "请假申请列表(分页)")
     @RequestMapping(value = "page", method = {RequestMethod.POST})
+    @ResourceAuth(value = "user", type = AuthType.User)
     public ResultContent page(@Parameter(hidden = true) @PageableDefault(page = 0, size = 10)Pageable pageable,
                               @Parameter(required = false) LeaveQueryParam param){
         return leaveService.page(pageable,param);

+ 10 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/dictionary/DictionaryController.java

@@ -1,5 +1,7 @@
 package com.zhongshu.card.server.core.controller.dictionary;
 
+import com.github.microservice.auth.security.annotations.ResourceAuth;
+import com.github.microservice.auth.security.type.AuthType;
 import com.github.microservice.net.ResultContent;
 import com.zhongshu.card.client.model.dictionary.*;
 import com.zhongshu.card.client.model.pay.PeriodQueryModel;
@@ -26,18 +28,21 @@ public class DictionaryController {
 
     @Operation(summary = "添加字典", description = "添加字典")
     @RequestMapping(value = "addDictionary", method = RequestMethod.POST)
+    @ResourceAuth(value = "user", type = AuthType.User)
     public Object addDictionary(@Valid @RequestBody AddDictionaryParam param){
         return dictionaryService.addDictionary(param);
     }
 
     @Operation(summary = "修改字典", description = "修改字典")
     @RequestMapping(value = "updateDictionary", method = RequestMethod.POST)
+    @ResourceAuth(value = "user", type = AuthType.User)
     public ResultContent updateDictionary(@Valid @RequestBody UpdateDictionaryParam param){
         return dictionaryService.updateDictionary(param);
     }
 
     @Operation(summary = "删除字典", description = "修改字典")
     @RequestMapping(value = "deleteDictionary", method = RequestMethod.GET)
+    @ResourceAuth(value = "user", type = AuthType.User)
     public ResultContent deleteDictionary(@RequestParam("id") String id){
         return dictionaryService.deleteDictionary(id);
     }
@@ -51,18 +56,21 @@ public class DictionaryController {
 
     @Operation(summary = "添加项", description = "添加项")
     @RequestMapping(value = "addItem", method = RequestMethod.POST)
+    @ResourceAuth(value = "user", type = AuthType.User)
     public ResultContent addItem(@RequestBody AddDictionaryItemParam param){
         return dictionaryService.addItem(param);
     }
 
     @Operation(summary = "修改项", description = "修改项")
     @RequestMapping(value = "updateItem", method = RequestMethod.POST)
+    @ResourceAuth(value = "user", type = AuthType.User)
     public ResultContent updateItem(@RequestBody AddDictionaryItemParam param){
         return dictionaryService.updateItem(param);
     }
 
     @Operation(summary = "删除项", description = "删除项")
     @RequestMapping(value = "deleteItem", method = RequestMethod.GET)
+    @ResourceAuth(value = "user", type = AuthType.User)
     public ResultContent deleteItem(@RequestParam("id") String id){
         return dictionaryService.deleteItem(id);
     }
@@ -94,12 +102,14 @@ public class DictionaryController {
 
     @Operation(summary = "检查更新", description = "检查更新")
     @RequestMapping(value = "updateCheck", method = RequestMethod.GET)
+    @ResourceAuth(value = "user", type = AuthType.User)
     public ResultContent<DictionaryUpdateStatus> updateCheck(@RequestParam("projectId") String projectId){
         return dictionaryService.updateCheck(projectId);
     }
 
     @Operation(summary = "更新标签字典初始化数据", description = "更新标签字典初始化数据")
     @RequestMapping(value = "updateInit", method = RequestMethod.GET)
+    @ResourceAuth(value = "user", type = AuthType.User)
     public ResultContent updateInit(@RequestParam("projectId") String projectId,
                                     @RequestParam("coverName") boolean coverName,
                                     @RequestParam("coverCustomize") boolean coverCustomize){

+ 74 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/controller/openAPI/TransactionLogOpenApiController.java

@@ -0,0 +1,74 @@
+package com.zhongshu.card.server.core.controller.openAPI;
+
+import com.github.microservice.auth.security.annotations.ResourceAuth;
+import com.github.microservice.auth.security.type.AuthType;
+import com.github.microservice.pay.client.model.ledger.TransactionLogModel;
+import com.github.microservice.pay.client.model.ledger.transaction.TransactionLogPeriodAggregateRetModel;
+import com.github.microservice.pay.client.model.ledger.transaction.TransactionLogRealTimeAggregateRetModel;
+import com.github.microservice.pay.client.model.ledger.transaction.TransactionLogSettleAggregateRetModel;
+import com.github.microservice.pay.client.ret.ResultContent;
+import com.zhongshu.card.client.model.pay.PeriodDetailQueryModel;
+import com.zhongshu.card.client.model.pay.PeriodQueryModel;
+import com.zhongshu.card.client.model.pay.SettleDetailQueryModel;
+import com.zhongshu.card.server.core.service.pay.OrgOverviewService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.web.PageableDefault;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/openAPI/v1/transactionLog")
+@Tag(name = "openAPI-账单")
+public class TransactionLogOpenApiController {
+
+    @Autowired
+    OrgOverviewService orgOverviewService;
+
+    @Operation(summary = "查询收入账单", description = "查询收入账单-年月日汇总")
+    @RequestMapping(value = "queryCreditBill", method = RequestMethod.POST)
+    public ResultContent<Page<TransactionLogPeriodAggregateRetModel>> queryCreditBill(@Parameter(hidden = true) @PageableDefault(page = 0, size = 10) Pageable pageable,
+                                                                                      @Parameter(required = true) PeriodQueryModel param){
+        return orgOverviewService.queryCreditBill(pageable, param);
+    }
+
+    @Operation(summary = "查询收入账单详情", description = "查询收入账单详情")
+    @RequestMapping(value = "queryCreditBillDetail", method = RequestMethod.POST)
+    public ResultContent<Page<TransactionLogModel>> queryCreditBillDetail(@Parameter(hidden = true) @PageableDefault(page = 0, size = 10) Pageable pageable,
+                                                                          @Parameter(required = true) PeriodDetailQueryModel periodDetailQueryModel){
+        return orgOverviewService.queryCreditBillDetail(pageable, periodDetailQueryModel);
+    }
+
+    @Operation(summary = "查询结算账单", description = "查询结算账单")
+    @RequestMapping(value = "querySettleBill", method = RequestMethod.POST)
+    public ResultContent<Page<TransactionLogSettleAggregateRetModel>> querySettleBill(@Parameter(hidden = true) @PageableDefault(page = 0, size = 10) Pageable pageable,
+                                                                                      @Parameter(required = false) PeriodQueryModel param){
+        return orgOverviewService.querySettleBill(pageable, param);
+    }
+
+    @Operation(summary = "查询结算账单详情", description = "查询结算账单详情")
+    @RequestMapping(value = "querySettleBillDetail", method = RequestMethod.POST)
+    public ResultContent<Page<TransactionLogModel>> querySettleBillDetail(@Parameter(hidden = true) @PageableDefault(page = 0, size = 10) Pageable pageable,
+                                                                          @Parameter(required = false) SettleDetailQueryModel settleDetailQueryModel){
+        return orgOverviewService.querySettleBillDetail(pageable, settleDetailQueryModel);
+    }
+
+    @Operation(summary = "查询提现账单", description = "查询提现账单")
+    @RequestMapping(value = "queryWithdrawBill", method = RequestMethod.POST)
+    public ResultContent<Page<TransactionLogRealTimeAggregateRetModel>> queryWithdrawBill(@Parameter(hidden = true) @PageableDefault(page = 0, size = 10) Pageable pageable,
+                                                                                          @Parameter(required = false) PeriodQueryModel param){
+        return orgOverviewService.queryWithdrawBill(pageable, param);
+    }
+
+    @Operation(summary = "查询提现账单详情", description = "查询提现账单详情")
+    @RequestMapping(value = "queryWithdrawBillDetail", method = RequestMethod.POST)
+    public ResultContent<Page<TransactionLogModel>> queryWithdrawBillDetail(@Parameter(hidden = true) @PageableDefault(page = 0, size = 10) Pageable pageable,
+                                                                            @Parameter(required = false) SettleDetailQueryModel settleDetailQueryModel){
+        return orgOverviewService.queryWithdrawBillDetail(pageable, settleDetailQueryModel);
+    }
+}

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

@@ -2,10 +2,12 @@ package com.zhongshu.card.server.core.dao.payment.extend;
 
 import com.zhongshu.card.client.model.payment.ExpenseFlowCount;
 import com.zhongshu.card.client.model.payment.ExpenseFlowSearch;
+import com.zhongshu.card.client.model.payment.ExpenseFlowUnionParam;
 import com.zhongshu.card.client.model.payment.statistic.StatisticItem;
 import com.zhongshu.card.client.model.school.BookInfoSearch;
 import com.zhongshu.card.server.core.domain.payment.ExpenseFlow;
 import com.zhongshu.card.server.core.domain.school.BookInfo;
+import com.zhongshu.card.server.core.model.payment.ExpenseFlowUnionWithModel;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 
@@ -53,4 +55,6 @@ public interface ExpenseFlowDaoExtend {
     // 分组统计
     Map<String, BigDecimal> statisticItems(ExpenseFlowSearch param);
 
+    //聚合查询消费订单及充值订单
+    Page<ExpenseFlowUnionWithModel> unionWithRecharge(Pageable pageable, ExpenseFlowUnionParam param);
 }

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

@@ -1,17 +1,24 @@
 package com.zhongshu.card.server.core.dao.payment.impl;
 
 import com.github.microservice.components.data.mongo.mongo.helper.DBHelper;
+import com.mongodb.client.MongoCollection;
 import com.zhongshu.card.client.model.payment.ExpenseFlowCount;
 import com.zhongshu.card.client.model.payment.ExpenseFlowSearch;
+import com.zhongshu.card.client.model.payment.ExpenseFlowUnionParam;
+import com.zhongshu.card.client.type.payment.OrderType;
 import com.zhongshu.card.server.core.dao.BaseImpl;
 import com.zhongshu.card.server.core.dao.payment.extend.ExpenseFlowDaoExtend;
 import com.zhongshu.card.server.core.domain.payment.ExpenseFlow;
+import com.zhongshu.card.server.core.model.payment.ExpenseFlowUnionWithModel;
 import com.zhongshu.card.server.core.util.CommonUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.bson.Document;
+import org.bson.types.Decimal128;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.mongodb.core.FindAndModifyOptions;
@@ -25,10 +32,8 @@ import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
@@ -267,6 +272,99 @@ public class ExpenseFlowDaoImpl extends BaseImpl implements ExpenseFlowDaoExtend
         return map;
     }
 
+    @Override
+    public Page<ExpenseFlowUnionWithModel> unionWithRecharge(Pageable pageable, ExpenseFlowUnionParam param) {
+        List<Document> createTimePipeline = new ArrayList<>();
+
+        // 开始时间过滤
+        Optional.ofNullable(param.getStartTime()).ifPresent((it) -> {
+            createTimePipeline.add(new Document()
+                    .append("$match", new Document()
+                            .append("createTime", new Document()
+                                    .append("$gte", it)
+                            )
+                    ));
+        });
+
+        // 结束时间过滤
+        Optional.ofNullable(param.getEndTime()).ifPresent((it) -> {
+            createTimePipeline.add(new Document()
+                    .append("$match", new Document()
+                            .append("createTime", new Document()
+                                    .append("$lte", it)
+                            )
+                    ));
+        });
+
+        List<Document> unionWithPipeline = new ArrayList<>();
+
+        unionWithPipeline.add( new Document()
+                .append("$unionWith", new Document()
+                        .append("coll", "balanceRechargeOrder")
+                        .append("pipeline", Arrays.asList(
+                                        createTimePipeline,
+                                        new Document()
+                                                .append("$addFields", new Document()
+                                                        .append("type", OrderType.Recharge.name())
+                                                )
+                                )
+                        )
+                ));
+
+        List<Document> searchPipeline = new ArrayList<>();
+
+        Optional.ofNullable(param.getOrderType()).ifPresent((it) -> {
+            searchPipeline.add(new Document()
+                    .append("$match", new Document()
+                            .append("type", param.getOrderType().name())
+                    ));
+        });
+
+        Optional.ofNullable(param.getOrderNo()).ifPresent((it) -> {
+            searchPipeline.add(new Document()
+                    .append("$match", new Document()
+                            .append("orderNo", param.getOrderNo())
+                    ));
+        });
+
+
+        List<Document> pipeline = new ArrayList<>(){{
+            addAll(createTimePipeline);
+            add(new Document()
+                    .append("$addFields", new Document()
+                            .append("type", OrderType.Consume.name())
+                    ));
+            addAll(unionWithPipeline);
+            addAll(searchPipeline);
+        }};
+        // 取出查询对象
+        final MongoCollection<Document> collection = this.mongoTemplate.getCollection(this.mongoTemplate.getCollectionName(ExpenseFlow.class));
+
+        // 查询总记录数, 用于分页
+        AtomicReference<Long> count = new AtomicReference<>(0L);
+        collection.aggregate(new ArrayList<>() {{
+                    addAll(pipeline);
+                    add(new Document().append("$count", "count"));
+                }})
+                // 如果内存不够在启用磁盘
+                .allowDiskUse(false).forEach((it) -> {
+                    count.set(Long.valueOf(String.valueOf(it.get("count"))));
+                });
+
+        List<ExpenseFlowUnionWithModel> ret = new ArrayList<>();
+        collection.aggregate(new ArrayList<>() {{
+                    addAll(pipeline);
+                    add(new Document().append("$skip", pageable.getOffset()));
+                    add(new Document().append("$limit", pageable.getPageSize()));
+                }})  // 如果内存不够在启用磁盘
+                .allowDiskUse(false).forEach((document) -> {
+                    Optional.ofNullable(document).ifPresent((it) -> {
+                        ret.add(this.mongoTemplate.getConverter().read(ExpenseFlowUnionWithModel.class, it));
+                    });
+                });
+        return new PageImpl<>(ret, pageable, count.get());
+    }
+
     /**
      * 商户收入总数
      *

+ 386 - 0
FullCardServer/src/main/java/com/zhongshu/card/server/core/model/payment/ExpenseFlowUnionWithModel.java

@@ -0,0 +1,386 @@
+package com.zhongshu.card.server.core.model.payment;
+
+import cn.hutool.json.JSONObject;
+import com.github.microservice.auth.security.type.AuthType;
+import com.github.microservice.models.type.DeviceType;
+import com.github.microservice.models.type.OrderFromType;
+import com.github.microservice.pay.client.model.ledger.TransactionLogModel;
+import com.github.microservice.types.OrderModeType;
+import com.github.microservice.types.OrderState;
+import com.github.microservice.types.payment.ChargeableType;
+import com.github.microservice.types.payment.PaymentDeviceType;
+import com.github.microservice.types.payment.PaymentType;
+import com.zhongshu.card.client.model.school.AreaSimpleModel;
+import com.zhongshu.card.client.type.RefundState;
+import com.zhongshu.card.client.type.payAccount.RechargeOrderStatus;
+import com.zhongshu.card.client.type.payment.OrderType;
+import com.zhongshu.card.client.type.payment.SettlementState;
+import com.zhongshu.card.client.utils.DateUtils;
+import com.zhongshu.card.server.core.domain.org.UserAccount;
+import com.zhongshu.card.server.core.domain.payment.RefundRecord;
+import com.zhongshu.card.server.core.domain.school.CardInfo;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import org.springframework.data.mongodb.core.index.Indexed;
+import org.springframework.data.mongodb.core.mapping.DBRef;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class ExpenseFlowUnionWithModel {
+
+    private String id;
+
+    private OrderType type;
+
+    private Long createTime;
+
+    private Long updateTime;
+
+    @Schema(description = "所属机构ID")
+    private String oid;
+
+    @Schema(description = "所属项目oid")
+    private String projectOid;
+
+    @Schema(description = "数据主题的oid")
+    private String aboutOid;
+
+    @Schema(description = "数据主题管理的oid机构类型")
+    private AuthType aboutAuthType;
+
+    @Schema(description = "排序")
+    private Long sort = 1l;
+
+    @Schema(description = "备注")
+    private String remark;
+
+    @Schema(description = "是否删除")
+    private Boolean isDelete = Boolean.FALSE;
+
+    @Schema(description = "创建用户ID")
+    private String createUserId;
+
+    @Schema(description = "添加用户名称")
+    private String createUserName;
+
+    @Schema(description = "添加用户电话", hidden = true)
+    private String createPhone;
+
+    @Schema(description = "创建用户ID")
+    private String updateUserId;
+
+    @Schema(description = "添加用户名称")
+    private String updateUserName;
+
+    @Schema(description = "添加用户电话", hidden = true)
+    private String updatePhone;
+
+    //-----------------------------订单信息 start---------------------
+    @Indexed(unique = true, sparse = true)
+    @Schema(description = "mqtt推送生成的业务数据ID")
+    private String mqttDataId;
+
+    @Schema(description = "")
+    private String token;
+
+    @Schema(description = "订单的总体状态")
+    private OrderState orderState;
+
+    @Schema(description = "订单创建类型, 是消费还是查询余额")
+    private OrderModeType orderModeType;
+
+    @Schema(description = "消费类型,如:餐饮消费、水费、电费 等等")
+    private String payType;
+
+    @Schema(description = "订单计费方式")
+    private ChargeableType chargeableType = ChargeableType.Specified;
+
+    @Schema(description = "是否指定支付渠道")
+    private Boolean appointPaymentType = Boolean.FALSE;
+
+    @Schema(description = "支付方式")
+    private PaymentType paymentType;
+
+    @Schema(description = "支付来源:刷卡 二维码 刷脸")
+    private OrderFromType orderFromType;
+
+    @Schema(description = "订单生效时间")
+    private Long startTime;
+
+    @Schema(description = "订单支付失效时间, (不会为空,有默认值)")
+    private Long expirationTime;
+
+    @Schema(description = "消费金额(单位:分)")
+    private BigDecimal payAmount;
+
+    @Schema(description = "服务id、商品id")
+    private String productProvideId;
+
+    @Schema(description = "是否允许匿名下单")
+    private Boolean isAnonymous = Boolean.FALSE;
+
+    //----------------------------消费关联的用户信息 start ----------------------
+    @Schema(description = "消费的用户userId")
+    private String userId;
+
+    @Schema(description = "用户名称")
+    private String userName;
+
+    @Schema(description = "用户信息")
+    private UserAccount userAccount;
+
+    //-----------------------修复关联的设备信息 start--------------------
+
+    @Schema(description = "是否是设备订单")
+    private Boolean isDeviceOrder = Boolean.TRUE;
+
+    @Schema(description = "消费机设备ID")
+    private String deviceId;
+
+    @Schema(description = "设备类型")
+    private DeviceType deviceType;
+
+    @Schema(description = "设备所属区域信息")
+    private AreaSimpleModel area;
+
+    @Schema(description = "所属项目的code")
+    private String projectCode;
+
+    @Schema(description = "订单所属的商户")
+    private String shopOid;
+
+    //------------------------------消费关联的卡片信息 ---------------------
+
+    @Schema(description = "支付设备和方式")
+    private PaymentDeviceType paymentDeviceType;
+
+    @Schema(description = "卡片的编号,也是终端刷卡的 卡号")
+    private String cardNo = "";
+
+    @Schema(description = "卡片信息")
+    private CardInfo cardInfo;
+
+    @Schema(description = "消费订单号")
+    private String orderNo;
+
+    @Indexed
+    @Schema(description = "支付订单号")
+    private String paymentNo;
+
+    @Schema(description = "付款码内容")
+    private String qr;
+
+    @Schema(description = "关联信息")
+    @Indexed
+    private Object param;
+
+    //-----------------------订单创建-支付信息 start----------------------
+
+    @Schema(description = "订单是否创建成功")
+    private Boolean isCreateSuccess = Boolean.TRUE;
+
+    @Schema(description = "验证参数是否符合要求,可以发起支付")
+    private Boolean verifyParamIsSuccess = Boolean.TRUE;
+
+    @Schema(description = "验证参数的提示")
+    private String verifyParamMsg;
+
+    /**
+     * 设置参数验证错误
+     *
+     * @param error
+     */
+    public void setVerifyError(String error) {
+        verifyParamIsSuccess = Boolean.FALSE;
+        verifyParamMsg = error;
+        orderState = OrderState.PARAM_ERROR;
+    }
+
+    @Schema(description = "是否必须支付,当是离线的时候,是先在边缘计算,再后面付款,则这个订单用户必须支付")
+    private Boolean isMustPay = Boolean.FALSE;
+
+    //------------------支付结果 start-------------------------
+
+    @Schema(description = "失败时的重复次数")
+    private Integer repeatTime = 0;
+
+    @Schema(description = "支付订单状态")
+    private String paymentStatus;
+
+    @Schema(description = "支付是否成功,为空就是未支付过")
+    private Boolean isPaySuccess;
+
+    @Schema(description = "调用支付的 支付结果,保存支付结果返回的以后要使用的参数")
+    private JSONObject payResult = new JSONObject();
+
+    @Schema(description = "是否已支付")
+    private Boolean isPaid = Boolean.FALSE;
+
+    @Schema(description = "支付结果备注,返回给设备展示")
+    private String payRemark;
+
+    @Schema(description = "支付开始时间")
+    private Long payStartTime;
+
+    @Schema(description = "支付结束时间")
+    private Long payEndTime;
+
+    @Schema(description = "支付耗用的时间")
+    private Long payMillis = 0L;
+
+    @Schema(description = "支付账单流水ID集合")
+    private List<TransactionLogModel> transactionIds = new ArrayList<TransactionLogModel>();
+
+    //-----------------------退款 start--------------------------
+
+    @Schema(description = "是否退款")
+    private Boolean isRefund;
+
+    @Schema(description = "退款申请人")
+    private String applicant;
+
+    @Schema(description = "操作退款用户userId")
+    private String refundUserId;
+
+    @Schema(description = "退款金额")
+    private BigDecimal refundAMount;
+
+    @Schema(description = "退款状态")
+    private RefundState refundState;
+
+    @Schema(description = "申请退款时间")
+    private Long refundTime;
+
+    @Schema(description = "申请退款备注")
+    private String refundRemark;
+
+    @Schema(description = "退款处理备注")
+    private String refuseRemark;
+
+    @Schema(description = "退款订单号")
+    private String refundNo;
+
+    @Schema(description = "退款后调用账单是否成功")
+    private Boolean refundTransactionIsSuccess = Boolean.FALSE;
+
+    @Schema(description = "退款账单流量")
+    private List<TransactionLogModel> refundTransactionIds = new ArrayList<TransactionLogModel>();
+
+    @Schema(description = "最新关联的退款数据")
+    @DBRef(lazy = true)
+    private RefundRecord refundRecord;
+
+
+    //-------------------------结算信息 start ----------------
+
+    @Schema(description = "结算状态")
+    private SettlementState settlementState = SettlementState.Unsettled;
+
+    @Schema(description = "结算时间")
+    private Long settlementTime;
+
+    /**
+     * 设置支付失败
+     *
+     * @param msg
+     */
+    public void setPayFailed(String msg) {
+        this.paymentStatus = "支付失败";
+        this.isPaySuccess = Boolean.FALSE;
+        this.payRemark = msg;
+        this.orderState = OrderState.PAID_ERROR;
+        this.isPaid = Boolean.TRUE;
+    }
+
+    //------------------------------时间信息 start--------------------
+    @Schema(description = "年份,如:2024")
+    private Integer year;
+
+    @Schema(description = "月份,如:6")
+    private Integer month;
+
+    @Schema(description = "当前月的第几天")
+    private Integer dayOfMonth;
+
+    @Schema(description = "今年第几周,如:32")
+    private Integer week;
+
+    @Schema(description = "当前年的第几天")
+    private Integer dayOfYear;
+
+    @Schema(description = "当前的第几小时")
+    private Integer hourOfDay;
+
+    @Schema(description = "消费创建时间 yyyy-MM-dd HH:mm:ss SSS")
+    private String paymentTime;
+
+    public void setTimes() {
+        this.year = DateUtils.getCurrentYear();
+        this.month = DateUtils.getCurrentMonthInYear();
+        this.dayOfMonth = DateUtils.getCurrentDayInMonth();
+        this.hourOfDay = DateUtils.getCurrentHourOfDay();
+
+        this.dayOfYear = DateUtils.getCurrentDayInYear();
+        this.week = DateUtils.getCurrentWeekInYear();
+        this.paymentTime = DateUtils.paresTime(System.currentTimeMillis(), DateUtils.patternyyyySSS);
+    }
+    //------------------------------时间信息 end----------------------
+
+    @Schema(description = "扩展字段")
+    private Map<String, Object> metaInfo = new HashMap<>();
+
+    public void addMetaInfo(String key, Object value) {
+        if (metaInfo == null) {
+            metaInfo = new HashMap<>();
+        }
+        metaInfo.put(key, value);
+    }
+
+    public Object getMetaInfo(String key) {
+        if (metaInfo != null && metaInfo.containsKey(key)) {
+            return metaInfo.get(key);
+        }
+        return null;
+    }
+
+    //*****************************************充值订单字段**************************************************//
+
+//    @Schema(description = "项目oid")
+//    private String projectOid;
+//
+//    @Schema(description = "机构oid")
+//    private String oid;
+//
+//    @Schema(description = "用户id")
+//    private String userId;
+//
+//    @Schema(description = "支付方式")
+//    private PaymentType paymentType;
+
+    @Schema(description = "支付账户")
+    private String payAccount;
+
+    @Schema(description = "订单状态")
+    private RechargeOrderStatus status;
+
+    @Schema(description = "状态说明")
+    private String statusDesc;
+
+    @Schema(description = "金额")
+    private BigDecimal total = BigDecimal.ZERO;
+
+//    @Schema(description = "订单号")
+//    private String orderNo;
+
+    @Schema(description = "描述")
+    private String description;
+
+    /********************************渠道所属参数*********************************/
+    @Schema(description = "预支付单号(用于前端调起支付的参数)")
+    private Object prepay;
+}

+ 17 - 5
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/pay/ChinaumsSenselessPayService.java

@@ -47,9 +47,8 @@ import org.springframework.util.StopWatch;
 
 import java.math.BigDecimal;
 import java.math.MathContext;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
+import java.math.RoundingMode;
+import java.util.*;
 
 @Slf4j
 @Service
@@ -339,8 +338,10 @@ public class ChinaumsSenselessPayService extends SuperService {
     }
 
     private List<SatInfo> buildSatInfo(String projectOid, BigDecimal total, String orderNo, String sysSourceNo, List<SatInfoModel> satInfoModels) {
+        //按比例降序排序
+        satInfoModels.sort((a, b)-> b.getRatio().compareTo(a.getRatio()));
 
-        return satInfoModels.stream().map(model -> {
+        List<SatInfo> satInfos = satInfoModels.stream().map(model -> {
             if (BigDecimal.ZERO.compareTo(model.getRatio()) >= 0) {
                 return null;
             }
@@ -357,7 +358,9 @@ public class ChinaumsSenselessPayService extends SuperService {
             SatInfo satInfo = new SatInfo();
             satInfo.setMerId(orgConf.getMchId());
             satInfo.setFeeBear("Y");
-            BigDecimal ratioTotal = total.multiply(model.getRatio().movePointLeft(2));
+            //TODO 分账计算方式 :按比例计算 保留整数,然后随机一个机构+1
+            BigDecimal ratioTotal = total.multiply(model.getRatio().movePointLeft(2)).setScale(0, RoundingMode.HALF_UP);
+
             satInfo.setSatAmt(ratioTotal.toBigInteger().toString());
             satInfo.setMerOrderId(shareOrderNo);
 
@@ -373,6 +376,14 @@ public class ChinaumsSenselessPayService extends SuperService {
             shareOrderDao.save(shareOrder);
             return satInfo;
         }).toList();
+
+        if (satInfos.size()>1){
+            SatInfo satInfo = satInfos.get(0);
+            BigDecimal upSatAmt = new BigDecimal(satInfo.getSatAmt()).add(new BigDecimal("1"));
+            satInfo.setSatAmt(upSatAmt.toBigInteger().toString());
+            satInfos.set(0, satInfo);
+        }
+        return satInfos;
     }
 
     private String buildShareOrderNo(String sysSourceNo){
@@ -419,6 +430,7 @@ public class ChinaumsSenselessPayService extends SuperService {
 
             SatInfo satInfo = new SatInfo();
             satInfo.setMerId(orgConf.getMchId());
+            //TODO 处理分账的退款
             BigDecimal multiplyTotal = total.multiply(shareOrder.getRatio(), new MathContext(4));
             satInfo.setRefundAmt(multiplyTotal.toBigInteger().toString());
             satInfo.setRefundOrderId(shareOrderNo);

+ 16 - 15
FullCardServer/src/main/java/com/zhongshu/card/server/core/service/pay/OrgOverviewService.java

@@ -32,6 +32,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.bson.Document;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
@@ -234,7 +235,7 @@ public class OrgOverviewService extends SuperService {
     }
 
 
-    public Object queryCreditBill(Pageable pageable, PeriodQueryModel param){
+    public ResultContent<Page<TransactionLogPeriodAggregateRetModel>> queryCreditBill(Pageable pageable, PeriodQueryModel param){
         String projectOid = param.getProjectOid();
         if (StringUtils.isBlank(param.getProjectOid())){
             projectOid = getCurrentProjectOid();
@@ -246,7 +247,7 @@ public class OrgOverviewService extends SuperService {
 
         List<String> oidList = organizationUserService.getUserOrgListOids(getCurrentUserId(), projectOid);
         if (oidList==null || oidList.isEmpty()){
-            return com.github.microservice.net.ResultContent.buildFail("未加入机构");
+            return ResultContent.buildFail("未加入机构");
         }
 
         PayAccount payAccount = payAccountService.getOrgChildren(projectOid, oidList.get(0), PaymentChannelType.WaitSettle);
@@ -264,10 +265,10 @@ public class OrgOverviewService extends SuperService {
         }else if (param.getPeriodType().equals(PeriodType.year)){
             return transactionLogService.periodYearAggregate(queryModel);
         }
-        return com.github.microservice.net.ResultContent.buildFail("周期类型不存在");
+        return ResultContent.buildFail("周期类型不存在");
     }
 
-    public Object queryCreditBillDetail(Pageable pageable, PeriodDetailQueryModel periodDetailQueryModel){
+    public ResultContent<Page<TransactionLogModel>> queryCreditBillDetail(Pageable pageable, PeriodDetailQueryModel periodDetailQueryModel){
         String projectOid = periodDetailQueryModel.getProjectOid();
         if (StringUtils.isBlank(projectOid)) {
             projectOid = getCurrentProjectOid();
@@ -275,7 +276,7 @@ public class OrgOverviewService extends SuperService {
 
         List<String> oidList = organizationUserService.getUserOrgListOids(getCurrentUserId(), projectOid);
         if (oidList==null || oidList.isEmpty()){
-            return com.github.microservice.net.ResultContent.buildFail("未加入机构");
+            return ResultContent.buildFail("未加入机构");
         }
 
         PayAccount payAccount = payAccountService.getOrgChildren(projectOid, oidList.get(0), PaymentChannelType.WaitSettle);
@@ -385,7 +386,7 @@ public class OrgOverviewService extends SuperService {
         ExcelUtils.commonExecuteExcel(request, response, execlParam);
     }
 
-    public Object querySettleBill(Pageable pageable, PeriodQueryModel param){
+    public ResultContent<Page<TransactionLogSettleAggregateRetModel>> querySettleBill(Pageable pageable, PeriodQueryModel param){
         String projectOid = param.getProjectOid();
         if (StringUtils.isBlank(param.getProjectOid())){
             projectOid = getCurrentProjectOid();
@@ -397,7 +398,7 @@ public class OrgOverviewService extends SuperService {
 
         List<String> oidList = organizationUserService.getUserOrgListOids(getCurrentUserId(), projectOid);
         if (oidList==null || oidList.isEmpty()){
-            return com.github.microservice.net.ResultContent.buildFail("未加入机构");
+            return ResultContent.buildFail("未加入机构");
         }
 
         //获取已结算账本
@@ -414,7 +415,7 @@ public class OrgOverviewService extends SuperService {
         return transactionLogService.settleAggregate(queryModel);
     }
 
-    public Object querySettleBillDetail(Pageable pageable, SettleDetailQueryModel settleDetailQueryModel){
+    public ResultContent<Page<TransactionLogModel>> querySettleBillDetail(Pageable pageable, SettleDetailQueryModel settleDetailQueryModel){
         String projectOid = settleDetailQueryModel.getProjectOid();
         if (StringUtils.isBlank(projectOid)) {
             projectOid = getCurrentProjectOid();
@@ -422,7 +423,7 @@ public class OrgOverviewService extends SuperService {
 
         List<String> oidList = organizationUserService.getUserOrgListOids(getCurrentUserId(), projectOid);
         if (oidList==null || oidList.isEmpty()){
-            return com.github.microservice.net.ResultContent.buildFail("未加入机构");
+            return ResultContent.buildFail("未加入机构");
         }
 
         PayAccount payAccount = payAccountService.getOrgChildren(projectOid, oidList.get(0), PaymentChannelType.WaitSettle);
@@ -457,7 +458,7 @@ public class OrgOverviewService extends SuperService {
 
         String createDate = settleDetailQueryModel.getCreateDate();
         if (StringUtils.isBlank(createDate)){
-            return com.github.microservice.net.ResultContent.buildFail("createDate不能为空");
+            return ResultContent.buildFail("createDate不能为空");
         }
 
         String formatCreateTime = DateUtils.paresTime(DateUtils.timeToLong(createDate, DateUtils.pattern), DateUtils.pattern);
@@ -504,7 +505,7 @@ public class OrgOverviewService extends SuperService {
     }
 
 
-    public Object queryWithdrawBill(Pageable pageable, PeriodQueryModel param){
+    public ResultContent<Page<TransactionLogRealTimeAggregateRetModel>> queryWithdrawBill(Pageable pageable, PeriodQueryModel param){
         String projectOid = param.getProjectOid();
         if (StringUtils.isBlank(param.getProjectOid())){
             projectOid = getCurrentProjectOid();
@@ -516,7 +517,7 @@ public class OrgOverviewService extends SuperService {
 
         List<String> oidList = organizationUserService.getUserOrgListOids(getCurrentUserId(), projectOid);
         if (oidList==null || oidList.isEmpty()){
-            return com.github.microservice.net.ResultContent.buildFail("未加入机构");
+            return ResultContent.buildFail("未加入机构");
         }
 
         //获取已结算账本
@@ -533,7 +534,7 @@ public class OrgOverviewService extends SuperService {
         return transactionLogService.withdrawAggregate(queryModel);
     }
 
-    public Object queryWithdrawBillDetail(Pageable pageable, SettleDetailQueryModel settleDetailQueryModel){
+    public ResultContent<Page<TransactionLogModel>> queryWithdrawBillDetail(Pageable pageable, SettleDetailQueryModel settleDetailQueryModel){
         String projectOid = settleDetailQueryModel.getProjectOid();
         if (StringUtils.isBlank(projectOid)) {
             projectOid = getCurrentProjectOid();
@@ -541,7 +542,7 @@ public class OrgOverviewService extends SuperService {
 
         List<String> oidList = organizationUserService.getUserOrgListOids(getCurrentUserId(), projectOid);
         if (oidList==null || oidList.isEmpty()){
-            return com.github.microservice.net.ResultContent.buildFail("未加入机构");
+            return ResultContent.buildFail("未加入机构");
         }
 
         PayAccount payAccount = payAccountService.getOrgChildren(projectOid, oidList.get(0), PaymentChannelType.Settle);
@@ -576,7 +577,7 @@ public class OrgOverviewService extends SuperService {
 
         String createDate = settleDetailQueryModel.getCreateDate();
         if (StringUtils.isBlank(createDate)){
-            return com.github.microservice.net.ResultContent.buildFail("createDate不能为空");
+            return ResultContent.buildFail("createDate不能为空");
         }
 
         Long startTime = DateUtils.timeToLong(createDate, DateUtils.pattern);

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

@@ -36,6 +36,7 @@ import com.zhongshu.card.client.type.RefundState;
 import com.zhongshu.card.client.type.StatisticType;
 import com.zhongshu.card.client.type.UserState;
 import com.zhongshu.card.client.type.payAccount.RechargeOrderStatus;
+import com.zhongshu.card.client.type.payment.OrderType;
 import com.zhongshu.card.client.type.payment.SettlementState;
 import com.zhongshu.card.client.type.school.CardState;
 import com.zhongshu.card.client.utils.DateUtils;
@@ -51,6 +52,7 @@ 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.school.CardInfo;
 import com.zhongshu.card.server.core.httpRequest.ApiRequestService;
+import com.zhongshu.card.server.core.model.payment.ExpenseFlowUnionWithModel;
 import com.zhongshu.card.server.core.service.base.CommonService;
 import com.zhongshu.card.server.core.service.base.SuperService;
 import com.zhongshu.card.server.core.service.devices.DeviceInfoServiceImpl;
@@ -987,6 +989,23 @@ public class ExpenseFlowServiceImpl extends SuperService implements ExpenseFlowS
         return ResultContent.buildSuccess();
     }
 
+    //TODO toModel
+    public ResultContent pageUnionWith(Pageable pageable, ExpenseFlowUnionParam param){
+        Page<ExpenseFlowUnionWithModel> page = expenseFlowDao.unionWithRecharge(pageable, param);
+        return null;
+    }
+
+//    private OrderUnionWithModel toOrderUnionModel(ExpenseFlowUnionWithModel expenseFlowUnionWith){
+//        OrderUnionWithModel model = new OrderUnionWithModel();
+//        if (expenseFlowUnionWith != null) {
+//            if (expenseFlowUnionWith.getType().equals(OrderType.Consume)){
+//                BeanUtils.copyProperties(expenseFlowUnionWith, model, "userAccount");
+//            }else if (expenseFlowUnionWith.getType().equals(OrderType.Recharge)){
+//
+//            }
+//        }
+//    }
+
     /**
      * 得到订单支付显示信息
      *