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.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();
}
}