用户账单统计

package net.baiqu.shop.data.website.expose;

import com.alibaba.fastjson.JSONObject;
import com.baiqu.api.model.ApiResultResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.baiqu.shop.data.api.models.request.bill.UserBillByIdRequest;
import net.baiqu.shop.data.api.models.request.bill.UserBillByTimeRequest;
import net.baiqu.shop.data.api.models.response.bill.UserChangeResponse;
import net.baiqu.shop.data.api.models.response.bill.UserMaxAndRateResponse;
import net.baiqu.shop.data.api.models.response.bill.UserTotalResponse;
import net.baiqu.shop.data.api.models.response.bill.UserTradeResponse;
import net.baiqu.shop.data.core.service.UserBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

@RestController
@Slf4j
@RequestMapping("/user")
@Api(description = "统计用户账单接口")
public class UserBillExpose {

    @Autowired
    private UserBillService userBillService;

    @ApiOperation(value = "查询用户注册账单", notes = "查询用户注册账单")
    @PostMapping("/bill/register")
    public ApiResultResponse<UserChangeResponse> userBillRegister(@RequestBody @Valid UserBillByIdRequest request) {
        log.info("userBillRegister->request:{}", JSONObject.toJSONString(request));
        return userBillService.getUserBillRegister(request);
    }

    @ApiOperation(value = "查询用户升级账单", notes = "查询用户升级账单")
    @PostMapping("/bill/vip")
    public ApiResultResponse<UserChangeResponse> userBillVip(@RequestBody @Valid UserBillByIdRequest request) {
        log.info("userBillRegister->request:{}", JSONObject.toJSONString(request));
        return userBillService.getUserBillVip(request);
    }

    @ApiOperation(value = "查询用户交易账单", notes = "查询用户交易账单")
    @PostMapping("/bill/trade")
    public ApiResultResponse<UserTradeResponse> userBillTrade(@RequestBody @Valid UserBillByTimeRequest request) {
        log.info("userBillTrade->request:{}", JSONObject.toJSONString(request));
        return userBillService.getUserTrade(request);
    }

    @ApiOperation(value = "查询用户下单交易金额最大与交易产品比例账单", notes = "查询用户下单交易金额最大与交易产品比例账单")
    @PostMapping("/bill/rate")
    public ApiResultResponse<UserMaxAndRateResponse> userBillMaxAndRate(@RequestBody @Valid UserBillByTimeRequest request) {
        log.info("userBillMaxAndRate->request:{}", JSONObject.toJSONString(request));
        return userBillService.getUserBillMaxAndRate(request);
    }

    @ApiOperation(value = "查询用户账单总计", notes = "查询用户账单总计")
    @PostMapping("/bill/total")
    public ApiResultResponse<UserTotalResponse> userBillTotal(@RequestBody @Valid UserBillByTimeRequest request) {
        log.info("userBillTotal->request:{}", JSONObject.toJSONString(request));
        return userBillService.getUserBillTotal(request);
    }

}
package net.baiqu.shop.data.core.service;

import com.baiqu.api.model.ApiResultResponse;
import net.baiqu.shop.data.api.models.request.bill.UserBillByIdRequest;
import net.baiqu.shop.data.api.models.request.bill.UserBillByTimeRequest;
import net.baiqu.shop.data.api.models.response.bill.UserChangeResponse;
import net.baiqu.shop.data.api.models.response.bill.UserMaxAndRateResponse;
import net.baiqu.shop.data.api.models.response.bill.UserTotalResponse;
import net.baiqu.shop.data.api.models.response.bill.UserTradeResponse;

public interface UserBillService {

    ApiResultResponse<UserChangeResponse> getUserBillRegister(UserBillByIdRequest request);

    ApiResultResponse<UserChangeResponse> getUserBillVip(UserBillByIdRequest request);

    ApiResultResponse<UserTradeResponse> getUserTrade(UserBillByTimeRequest request);

    ApiResultResponse<UserTotalResponse> getUserBillTotal(UserBillByTimeRequest request);

    ApiResultResponse<UserMaxAndRateResponse> getUserBillMaxAndRate(UserBillByTimeRequest request);

}
package net.baiqu.shop.data.core.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baiqu.api.model.ApiResultResponse;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import lombok.extern.slf4j.Slf4j;
import net.baiqu.shop.data.api.AppResponseUtils;
import net.baiqu.shop.data.api.enums.ApiResponseCodeEnum;
import net.baiqu.shop.data.api.models.request.bill.UserBillByIdRequest;
import net.baiqu.shop.data.api.models.request.bill.UserBillByTimeRequest;
import net.baiqu.shop.data.api.models.response.bill.*;
import net.baiqu.shop.data.core.exception.AppException;
import net.baiqu.shop.data.core.service.UserBillService;
import net.baiqu.shop.data.core.util.DateUtils;
import net.baiqu.shop.data.dal.entity.document.MOrder;
import net.baiqu.shop.data.dal.entity.document.MUser;
import net.baiqu.shop.data.dal.entity.document.MVipRecord;
import net.baiqu.shop.data.dal.entity.model.Product;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.Decimal128;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;

@Service
@Slf4j
public class UserBillServiceImpl implements UserBillService {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 查询用户注册时间和第几位注册
     *
     * @param request
     * @return
     */
    @Override
    public ApiResultResponse<UserChangeResponse> getUserBillRegister(UserBillByIdRequest request) {
        UserChangeResponse response = new UserChangeResponse();
        Aggregation agg = Aggregation.newAggregation(
                match(Criteria.where("userId").is(request.getUserId())));
        AggregationResults<BasicDBObject> registerResult = mongoTemplate.aggregate(agg, MUser.class, BasicDBObject.class);
        log.info("getUserBillRegister->registerResult: {}", JSONObject.toJSONString(registerResult));
        if (CollectionUtils.isEmpty(registerResult.getMappedResults())) {
            return AppResponseUtils.buildErrorResponse(ApiResponseCodeEnum.USER_NOT_EXIST);
        }
        agg = Aggregation.newAggregation(
                match(Criteria.where("createTime").lt(registerResult.getMappedResults().get(0).getDate("createTime"))),
                project("userId"));
        AggregationResults<BasicDBObject> rankResult = mongoTemplate.aggregate(agg, MUser.class, BasicDBObject.class);
        int size = rankResult.getMappedResults().size();
        log.info("getUserBillRegister->rankResult的size=" + size);
        response.setDate(DateUtils.formatToString(registerResult.getMappedResults().get(0).getDate("createTime"), "yyyy-MM-dd hh:mm:ss"));
        response.setRank(size + 1);
        log.info("getUserBillRegister->response: {}", JSONObject.toJSONString(response));
        return AppResponseUtils.buildSuccessResponse(response);
    }

    /**
     * 查询用户升级时间和第几位升级
     *
     * @param request
     * @return
     */
    @Override
    public ApiResultResponse<UserChangeResponse> getUserBillVip(UserBillByIdRequest request) {
        UserChangeResponse response = new UserChangeResponse();
        Aggregation agg = Aggregation.newAggregation(
                match(
                        Criteria.where("userId").is(request.getUserId())
                                .and("afterUserType").in("FORMAL_VIP", "EXP_VIP")),
                sort(Sort.Direction.ASC, "startTime"),
                limit(1));
        AggregationResults<BasicDBObject> vipResult = mongoTemplate.aggregate(agg, MVipRecord.class, BasicDBObject.class);
        log.info("getUserBillVip->vipResult: {}", JSONObject.toJSONString(vipResult));
        if (CollectionUtils.isEmpty(vipResult.getMappedResults())) {
            return AppResponseUtils.buildErrorResponse(ApiResponseCodeEnum.VIP_NOT_EXIST);
        }
        agg = Aggregation.newAggregation(
                match(Criteria.where("startTime").lt(vipResult.getMappedResults().get(0).getDate("startTime"))),
                project("userId"));
        AggregationResults<BasicDBObject> rankResult = mongoTemplate.aggregate(agg, MVipRecord.class, BasicDBObject.class);
        response.setDate(DateUtils.formatToString(vipResult.getMappedResults().get(0).getDate("startTime"), "yyyy-MM-dd hh:mm:ss"));
        response.setRank(rankResult.getMappedResults().size() + 1);
        log.info("getUserBillVip->response: {}", JSONObject.toJSONString(response));
        return AppResponseUtils.buildSuccessResponse(response);
    }

    /**
     * 查询用户第一笔交易、最大3笔交易和最喜欢的店铺
     *
     * @param request
     * @return
     */
    @Override
    public ApiResultResponse<UserTradeResponse> getUserTrade(UserBillByTimeRequest request) {
        UserTradeResponse response = new UserTradeResponse();
        Date startTime;
        Date endTime;
        if (StringUtils.isNotBlank(request.getStartTime())) {
            startTime = DateUtils.fromString(request.getStartTime(), "yyyy-MM-dd HH:mm:ss");
        } else {
            startTime = DateUtils.fromString("2000-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss");
        }
        if (StringUtils.isNotBlank(request.getEndTime())) {
            endTime = DateUtils.fromString(request.getEndTime(), "yyyy-MM-dd HH:mm:ss");
        } else {
            endTime = new Date();
        }
        response.setUserFirstTrade(getUserFirstTrade(request.getUserId(), startTime, endTime));
        response.setBigThreeTrade(getBigThreeTrade(request.getUserId(), startTime, endTime));
        response.setFavoriteShop(getFavoriteShop(request.getUserId(), startTime, endTime));
        log.info("getUserTrade->response: {}", JSONObject.toJSONString(response));
        return AppResponseUtils.buildSuccessResponse(response);
    }

    /**
     * 获取用户第一笔交易
     *
     * @param userId
     * @param startTime
     * @param endTime
     * @return
     */
    private UserOrderResponse getUserFirstTrade(Long userId, Date startTime, Date endTime) {
        Aggregation aggregation = Aggregation.newAggregation(
                match(Criteria.where("userId").is(userId)
                        .and("createTime").gte(startTime).lte(endTime)),
                sort(Sort.Direction.ASC, "createTime"));
        AggregationResults<BasicDBObject> result = mongoTemplate.aggregate(aggregation, MOrder.class, BasicDBObject.class);
        if (CollectionUtils.isEmpty(result.getMappedResults())) {
            throw new AppException(ApiResponseCodeEnum.ORDER_NOT_EXIST);
        }
        BasicDBObject bd = result.getMappedResults().get(0);
        UserOrderResponse order = new UserOrderResponse();
        order.setOrderId(bd.getString("orderId"));
        order.setPayAmount(new BigDecimal(bd.get("payAmount").toString()));
        order.setProductList(getUserProductList(bd.get("productList").toString()));
        order.setCreateTime(DateUtils.formatToString(bd.getDate("createTime"), "yyyy-MM-dd HH:mm:ss"));
        log.info("getUserFirstTrade->order: {}", JSONObject.toJSONString(order));
        return order;
    }


    /**
     * 获取产品集合
     *
     * @return
     */
    private List<UserProductResponse> getUserProductList(String str) {
        List<UserProductResponse> productList = new ArrayList<>();
        JSONArray products = JSONArray.parseArray(str);
        for (int i = 0; i < products.size(); i++) {
            JSONObject jsonObject = products.getJSONObject(i);
            UserProductResponse productResponse = new UserProductResponse();
            productResponse.setProductId(jsonObject.getLong("productId"));
            productResponse.setProductName(jsonObject.getString("productName"));
            productResponse.setProductType(jsonObject.getString("productType"));
            productList.add(productResponse);
        }
        return productList;
    }

    /**
     * 获取用户最大的三笔交易
     *
     * @param userId
     * @param startTime
     * @param endTime
     * @return
     */
    private List<UserOrderResponse> getBigThreeTrade(Long userId, Date startTime, Date endTime) {
        List<UserOrderResponse> orderList = new ArrayList<>();
        Aggregation aggregation = Aggregation.newAggregation(
                match(Criteria.where("userId").is(userId)
                        .and("createTime").gte(startTime).lte(endTime)),
                sort(Sort.Direction.DESC, "payAmount"),
                limit(3));
        AggregationResults<BasicDBObject> result = mongoTemplate.aggregate(aggregation, MOrder.class, BasicDBObject.class);
        if (CollectionUtils.isEmpty(result.getMappedResults())) {
            throw new AppException(ApiResponseCodeEnum.ORDER_NOT_EXIST);
        }
        for (BasicDBObject bd : result.getMappedResults()) {
            UserOrderResponse order = new UserOrderResponse();
            order.setOrderId(bd.getString("orderId"));
            order.setPayAmount(new BigDecimal(bd.get("payAmount").toString()));
            order.setProductList(getUserProductList(bd.get("productList").toString()));
            order.setCreateTime(DateUtils.formatToString(bd.getDate("createTime"), "yyyy-MM-dd HH:mm:ss"));
            orderList.add(order);
        }
        log.info("getBigThreeTrade->orderList: {}", JSONObject.toJSONString(orderList));
        return orderList;
    }

    /**
     * 获取用户最喜欢的店铺
     *
     * @param userId
     * @param startTime
     * @param endTime
     * @return
     */
    private UserFavoriteShopResponse getFavoriteShop(Long userId, Date startTime, Date endTime) {
        UserFavoriteShopResponse response = new UserFavoriteShopResponse();
        Aggregation aggregation = Aggregation.newAggregation(
                match(Criteria.where("userId").is(userId)
                        .and("createTime").gte(startTime).lte(endTime)),
                group("shopId").count().as("count"),
                sort(Sort.Direction.DESC, "count"),
                limit(1),
                lookup("shop", "_id", "shopId", "shopInfo"));
        AggregationResults<BasicDBObject> result =
                mongoTemplate.aggregate(aggregation, MOrder.class, BasicDBObject.class);
        if (CollectionUtils.isEmpty(result.getMappedResults())) {
            throw new AppException(ApiResponseCodeEnum.SHOP_NOT_EXIST);
        }
        response.setShopId((long) result.getMappedResults().get(0).get("_id"));
        BasicDBList shopInfoList = (BasicDBList) result.getMappedResults().get(0).get("shopInfo");
        BasicDBObject shopInfo = (BasicDBObject) shopInfoList.get(0);
        response.setName(shopInfo.getString("name"));
        response.setAreaId(shopInfo.getLong("areaId"));
        response.setType(shopInfo.getString("type"));
        response.setTradeNum((int) result.getMappedResults().get(0).get("count"));
        log.info("getFavoriteShop->response: {}", JSONObject.toJSONString(response));
        return response;
    }

    /**
     * 查询:
     * 一共下了多少单
     * 下单总共原始价多少钱
     * 一共支付了多少钱
     * 一共节约了多少钱
     * 一共获取了多少食堂劵
     */
    @Override
    public ApiResultResponse<UserTotalResponse> getUserBillTotal(UserBillByTimeRequest request) {
        Long userId = request.getUserId();
        Date startTime;
        Date endTime;
        if (StringUtils.isNotBlank(request.getStartTime())) {
            startTime = DateUtils.fromString(request.getStartTime(), "yyyy-MM-dd HH:mm:ss");
        } else {
            startTime = DateUtils.fromString("2000-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss");
        }
        if (StringUtils.isNotBlank(request.getEndTime())) {
            endTime = DateUtils.fromString(request.getEndTime(), "yyyy-MM-dd HH:mm:ss");
        } else {
            endTime = new Date();
        }

        Integer orderTotal = this.getOrderTotal(userId, startTime, endTime);
        log.info("getUserBillTotal->orderTotal 总下单数: {}", JSONObject.toJSONString(orderTotal));
        BigDecimal orgAmountTotal = this.getAmountTotal(userId, startTime, endTime, "orgAmount");
        log.info("getUserBillTotal->orgAmountTotal 下单总原始价: {}", JSONObject.toJSONString(orgAmountTotal));
        BigDecimal payAmountTotal = this.getAmountTotal(userId, startTime, endTime, "payAmount");
        log.info("getUserBillTotal->payAmountTotal 支付总金额: {}", JSONObject.toJSONString(payAmountTotal));
        BigDecimal saveAmountTotal = this.getSaveAmountTotal(userId, startTime, endTime);
        log.info("getUserBillTotal->saveAmountTotal 节约总金额: {}", JSONObject.toJSONString(saveAmountTotal));
        BigDecimal ticketTotal = this.getTicketTotal(userId, startTime, endTime);
        log.info("getUserBillTotal->ticketTotal 获取食堂劵总数: {}", JSONObject.toJSONString(ticketTotal));

        UserTotalResponse response = new UserTotalResponse(orderTotal, orgAmountTotal, payAmountTotal, saveAmountTotal, ticketTotal);
        log.info("getUserBillTotal->response: {}", JSONObject.toJSONString(response));
        return AppResponseUtils.buildSuccessResponse(response);
    }

    /**
     * 查询:
     * 花费金额最多的那天和金额
     * 下单最多的那天和下单数量
     * 交易的产品比例
     */
    @Override
    public ApiResultResponse<UserMaxAndRateResponse> getUserBillMaxAndRate(UserBillByTimeRequest request) {
        Long userId = request.getUserId();
        Date startTime;
        Date endTime;
        if (StringUtils.isNotBlank(request.getStartTime())) {
            startTime = DateUtils.fromString(request.getStartTime(), "yyyy-MM-dd HH:mm:ss");
        } else {
            startTime = DateUtils.fromString("2000-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss");
        }
        if (StringUtils.isNotBlank(request.getEndTime())) {
            endTime = DateUtils.fromString(request.getEndTime(), "yyyy-MM-dd HH:mm:ss");
        } else {
            endTime = new Date();
        }

        // 查询花费金额最多的那天和金额
        UserAmountMaxResponse amountMax = this.getAmountMax(userId, startTime, endTime);
        log.info("getUserBillMaxAndRate->amountMax 用户花费金额最多的那天和金额: {}", JSONObject.toJSONString(amountMax));

        // 查询下单最多的那天和下单数量
        UserCountMaxResponse countMax = this.getCountMax(userId, startTime, endTime);
        log.info("getUserBillMaxAndRate->countMax 用户下单最多的那天和下单数量: {}", JSONObject.toJSONString(countMax));

        // 查询交易的产品比例
        List<UserRateResponse> rate = this.getRate(userId, startTime, endTime);
        log.info("getUserBillMaxAndRate->rate 用户交易的产品比例: {}", JSONObject.toJSONString(rate));

        UserMaxAndRateResponse response = new UserMaxAndRateResponse(amountMax, countMax, rate);
        log.info("getUserBillMaxAndRate->response: {}", JSONObject.toJSONString(response));
        return AppResponseUtils.buildSuccessResponse(response);
    }

    /**
     * 查询花费金额最多的那天和金额
     */
    private UserAmountMaxResponse getAmountMax(Long userId, Date startTime, Date endTime) {
        Aggregation aggregation = Aggregation.newAggregation(
                match(
                        Criteria.where("userId").is(userId)
                                .and("createTime").gte(startTime).lte(endTime)),
                project("payAmount").andExpression("{$dateToString:{format:'%Y-%m-%d',date: '$createTime'}}").as("createTime"),
                group("createTime").sum("payAmount").as("total"),
                sort(Sort.Direction.DESC, "total"));
        AggregationResults<BasicDBObject> result = mongoTemplate.aggregate(aggregation, MOrder.class, BasicDBObject.class);

        if (CollectionUtils.isEmpty(result.getMappedResults())) {
            throw new AppException(ApiResponseCodeEnum.ORDER_NOT_EXIST);
        }

        String day = result.getMappedResults().get(0).getString("_id");
        BigDecimal amount = ((Decimal128) result.getMappedResults().get(0).get("total")).bigDecimalValue();
        return new UserAmountMaxResponse(day, amount);
    }

    /**
     * 下单最多的那天和下单数量
     */
    private UserCountMaxResponse getCountMax(Long userId, Date startTime, Date endTime) {
        Aggregation aggregation = Aggregation.newAggregation(
                match(
                        Criteria.where("userId").is(userId)
                                .and("createTime").gte(startTime).lte(endTime)),
                project().andExpression("{$dateToString:{format:'%Y-%m-%d',date: '$createTime'}}").as("createTime"),
                group("createTime").count().as("count"),
                sort(Sort.Direction.DESC, "count"));
        AggregationResults<BasicDBObject> result = mongoTemplate.aggregate(aggregation, MOrder.class, BasicDBObject.class);

        if (CollectionUtils.isEmpty(result.getMappedResults())) {
            throw new AppException(ApiResponseCodeEnum.ORDER_NOT_EXIST);
        }

        String day = result.getMappedResults().get(0).getString("_id");
        int count = result.getMappedResults().get(0).getInt("count");
        return new UserCountMaxResponse(day, count);
    }

    /**
     * 查询交易的产品比例
     */
    private List<UserRateResponse> getRate(Long userId, Date startTime, Date endTime) {
        Aggregation aggregation = Aggregation.newAggregation(
                match(Criteria.where("userId").is(userId)
                        .and("createTime").gte(startTime).lte(endTime)));
        AggregationResults<BasicDBObject> result = mongoTemplate.aggregate(aggregation, MOrder.class, BasicDBObject.class);

        if (CollectionUtils.isEmpty(result.getMappedResults())) {
            throw new AppException(ApiResponseCodeEnum.ORDER_NOT_EXIST);
        }

        int sum = 0;
        for (Iterator<BasicDBObject> iterator = result.iterator(); iterator.hasNext(); ) {
            DBObject obj = iterator.next();
            List<Product> products = (List<Product>) obj.get("productList");
            sum += products.size();
        }

        aggregation = Aggregation.newAggregation(
                match(Criteria.where("userId").is(userId)),
                unwind("productList"),
                group("productList.productType").count().as("total"));
        result = mongoTemplate.aggregate(aggregation, MOrder.class, BasicDBObject.class);

        if (CollectionUtils.isEmpty(result.getMappedResults())) {
            throw new AppException(ApiResponseCodeEnum.ORDER_NOT_EXIST);
        }

        List<UserRateResponse> list = new ArrayList<>(6);
        int i = 0;
        BigDecimal other = new BigDecimal(0);
        int tempCount = 0;
        for (BasicDBObject obj : result.getMappedResults()) {
            UserRateResponse userRate = new UserRateResponse();
            if (i == 6) {
                userRate.setProductType(obj.getString("other"));
                userRate.setRate(new BigDecimal(1).subtract(other));
                userRate.setTradeCount(sum - tempCount);
                list.add(userRate);
                break;
            }
            BigDecimal rate = new BigDecimal(obj.getInt("total")).divide(new BigDecimal(sum), 4, BigDecimal.ROUND_HALF_UP);
            userRate.setProductType(obj.getString("_id"));
            userRate.setRate(rate);
            userRate.setTradeCount(obj.getInt("total"));
            list.add(userRate);
            other = other.add(rate);
            tempCount += obj.getInt("total");
            i++;
        }

        return list;
    }

    /**
     * 查询用户一共下了多少单
     */
    private Integer getOrderTotal(Long userId, Date startTime, Date endTime) {
        Aggregation aggregation = Aggregation.newAggregation(
                match(
                        Criteria.where("userId").is(userId)
                                .and("createTime").gte(startTime).lte(endTime)),
                group("userId").count().as("count"));
        AggregationResults<BasicDBObject> result = mongoTemplate.aggregate(aggregation, MOrder.class, BasicDBObject.class);

        if (CollectionUtils.isEmpty(result.getMappedResults())) {
            throw new AppException(ApiResponseCodeEnum.ORDER_NOT_EXIST);
        }

        return result.getMappedResults().get(0).getInt("count");
    }

    /**
     * 查询:
     * 用户下单总共原始价多少钱
     * 或
     * 用户一共支付了多少钱
     */
    private BigDecimal getAmountTotal(Long userId, Date startTime, Date endTime, String refer) {
        Aggregation aggregation = Aggregation.newAggregation(
                match(
                        Criteria.where("userId").is(userId)
                                .and("createTime").gte(startTime).lte(endTime)),
                group("userId").sum(refer).as("total"));
        AggregationResults<BasicDBObject> result = mongoTemplate.aggregate(aggregation, MOrder.class, BasicDBObject.class);

        if (CollectionUtils.isEmpty(result.getMappedResults())) {
            throw new AppException(ApiResponseCodeEnum.ORDER_NOT_EXIST);
        }

        return ((Decimal128) result.getMappedResults().get(0).get("total")).bigDecimalValue();
    }

    /**
     * 查询一共节约了多少钱
     */
    private BigDecimal getSaveAmountTotal(Long userId, Date startTime, Date endTime) {
        Aggregation aggregation = Aggregation.newAggregation(
                match(
                        Criteria.where("userId").is(userId)
                                .and("createTime").gte(startTime).lte(endTime)),
                group("userId")
                        .sum("orgAmount").as("orgAmount")
                        .sum("payAmount").as("payAmount"),
                project("orgAmount", "payAmount")
                        .and("orgAmount").minus("payAmount").as("saveAmount"));
        AggregationResults<BasicDBObject> result = mongoTemplate.aggregate(aggregation, MOrder.class, BasicDBObject.class);

        if (CollectionUtils.isEmpty(result.getMappedResults())) {
            throw new AppException(ApiResponseCodeEnum.ORDER_NOT_EXIST);
        }

        return ((Decimal128) result.getMappedResults().get(0).get("saveAmount")).bigDecimalValue();
    }

    /**
     * 查询一共获取了多少食堂劵
     */
    private BigDecimal getTicketTotal(Long userId, Date startTime, Date endTime) {
        Aggregation aggregation = Aggregation.newAggregation(
                match(
                        Criteria.where("userId").is(userId)
                                .and("createTime").gte(startTime).lte(endTime)),
                unwind("productList"),
                group("userId").sum("productList.ticket").as("total"));
        AggregationResults<BasicDBObject> result = mongoTemplate.aggregate(aggregation, MOrder.class, BasicDBObject.class);

        if (CollectionUtils.isEmpty(result.getMappedResults())) {
            throw new AppException(ApiResponseCodeEnum.ORDER_NOT_EXIST);
        }

        return ((Decimal128) result.getMappedResults().get(0).get("total")).bigDecimalValue();
    }

}

 

posted on 2018-09-03 17:49  动物管理猿  阅读(383)  评论(0)    收藏  举报

导航