
package com.tmerclub.cloud.flow.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.tmerclub.cloud.flow.bo.FlowSystemBO;
import com.tmerclub.cloud.flow.bo.FlowSystemUserBO;
import com.tmerclub.cloud.flow.constant.FlowDateTypeEnum;
import com.tmerclub.cloud.flow.constant.SystemTypeEnum;
import com.tmerclub.cloud.flow.service.SystemAnalyseMongoService;
import com.tmerclub.cloud.flow.util.FlowUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 流量分析—用户访问数据
 *
 * @author YXF
 * @date 2021-05-21 15:25:19
 */
@Service
public class SystemAnalyseMongoServiceImpl implements SystemAnalyseMongoService {

    private static final Logger LOG = LoggerFactory.getLogger(SystemAnalyseMongoServiceImpl.class);

    @Autowired
    private MongoTemplate mongoTemplate;

    private final static String[] SYSTEM_TYPE = {"全部", "PC", "H5", "微信小程序", "安卓", "IOS"};

    @Override
    public void statisticsAndSaveSystemOfDay(Date beginDate, Date endDate) {
        List<FlowSystemBO> systemAnalyseList = this.listRealTimeStatistics(beginDate, endDate, null);

        // 统计的数据批量保存到flow_system
        this.batchInsertFlowSystemBO(FlowDateTypeEnum.DAY.value(), beginDate, endDate, systemAnalyseList);
    }
    @Override
    public List<FlowSystemBO> listRealTimeStatistics(Date beginDate, Date endDate, Integer systemType) {
        // 没有传时间，默认为当天的开始和结束时间
        if (Objects.isNull(beginDate) || Objects.isNull(endDate)) {
            beginDate = DateUtil.beginOfDay(new Date());
            endDate = DateUtil.offsetDay(beginDate, 1);
        }
        List<FlowSystemBO> flowSystemList = new ArrayList<>();
        // 统计整个商城的数据
        if (Objects.isNull(systemType) || Objects.equals(SystemTypeEnum.ALL.value(), systemType)) {
            // flow_user_log中统计各个端的数据（6条）
            // 总数据使用flow_user_log和订单来统计
            FlowSystemBO flowSystemBO = this.getALLSystemAnalyseBO(beginDate, endDate);
            this.handleSystemOrder(flowSystemBO, beginDate, endDate);
            if (Objects.nonNull(flowSystemBO.getSystemType())) {
                flowSystemList.add(flowSystemBO);
            }
        }

        // 统计各个端或者指定端的数据
        if (Objects.isNull(systemType) || !Objects.equals(SystemTypeEnum.ALL.value(), systemType)) {
            // 指定端的数据则用flow_user_log统计
            List<FlowSystemBO> systemAnalyseList = this.listSystemAnalyse(beginDate, endDate, systemType);
            systemAnalyseList = this.handleSystemOrderList(systemAnalyseList, beginDate, endDate, systemType);

            if (CollUtil.isNotEmpty(systemAnalyseList)) {
                flowSystemList.addAll(systemAnalyseList);
            }
        }

        // 设置数据的时间
        for (FlowSystemBO flowSystemBO : flowSystemList) {
            flowSystemBO.setCreateTime(beginDate);
        }

        // 合并数据
       return flowSystemList;
    }

    @Override
    public void statisticsAndSaveSystemOfTime(int dateType, Date beginDate, Date endDate) {
        // flow_user_log中统计各个端的数据（6条）
        // 总数据使用flow_system和flow_system_user来统计

        List<FlowSystemBO> flowSystemBOList = this.statisticsSystemTypeListOfTime(beginDate, endDate, null);
        if (flowSystemBOList == null) {
            return;
        }
        this.batchInsertFlowSystemBO(dateType, beginDate, endDate, flowSystemBOList);
    }


    @Override
    public List<FlowSystemBO> statisticsSystemTypeListOfTime(Date beginDate, Date endDate, Integer systemType) {
        // 系统类型、浏览量、下单金额、支付金额
        Long beginId = FlowUtil.timeToId(beginDate, FlowSystemBO.ID_LENGTH);
        Long endId = FlowUtil.timeToId(endDate, FlowSystemBO.ID_LENGTH);
        Criteria criteria = Criteria.where("_id").gte(beginId).lt(endId)
                .and("dateType").is(FlowDateTypeEnum.DAY.value());

        if (systemType != null) {
            criteria.and("systemType").is(systemType);
        }

        MatchOperation matchOperation = Aggregation.match(criteria);

        String[] fields;
        if (Objects.isNull(systemType)) {
            fields = new String[]{"systemType"};
        } else {
            fields = new String[0];
        }

        GroupOperation groupOperation = Aggregation.group(fields)
                .first("systemType").as("systemType")
                .sum("visit").as("visit")
                .sum("placeOrderAmount").as("placeOrderAmount")
                .sum("payAmount").as("payAmount");

        TypedAggregation<FlowSystemBO> typedAggregation = Aggregation.newAggregation (
                FlowSystemBO.class,
                matchOperation,
                groupOperation
        );
        LOG.info("statisticsSystemTypeListOfTime:typedAggregation={}", typedAggregation);

        List<FlowSystemBO> flowSystemBOList = mongoTemplate
                .aggregate(typedAggregation, FlowSystemBO.class)
                .getMappedResults();

        if (CollUtil.isEmpty(flowSystemBOList)) {
            return new ArrayList<>();
        } else {
            flowSystemBOList = new ArrayList<>(flowSystemBOList);
        }

        for (FlowSystemBO flowSystemBO : flowSystemBOList) {
            flowSystemBO.setCreateTime(beginDate);
        }

        // 加购人数、访客数、新访客数、跳失人数、下单人数、支付人数
        return statisticsSystemUserListOfTime(beginDate, endDate, systemType, flowSystemBOList);
    }

    @Override
    public List<FlowSystemBO> listFlowSystemByDateTypeAndSystemType(Date startTime, Date endTiem, Integer dateType, Integer systemType) {
        Long startId = FlowUtil.timeToId(startTime, FlowSystemBO.ID_LENGTH);
        Long endId = FlowUtil.timeToId(endTiem, FlowSystemBO.ID_LENGTH);
        Criteria criteria = Criteria.where("dateType").is(dateType)
                .and("_id").gte(startId).lt(endId);

        if (Objects.nonNull(systemType)) {
            criteria.and("systemType").is(systemType);
        }

        Query query = new Query(criteria);

        LOG.info("构建listFlowSystemByDateTypeAndSystemType查询语句： {}", query);
        List<FlowSystemBO> flowSystemList = mongoTemplate.find(query, FlowSystemBO.class);

        if (CollUtil.isEmpty(flowSystemList)) {
            return new ArrayList<>();
        }
        return flowSystemList;
    }

    @Override
    public List<FlowSystemBO> listFlowSystem(Date startTime, Date endTime, Integer dateType) {
        Criteria criteria = Criteria.where("dateType").is(dateType)
                .and("_id")
                .gte(FlowUtil.timeToId(startTime, FlowSystemBO.ID_LENGTH))
                .lt(FlowUtil.timeToId(endTime, FlowSystemBO.ID_LENGTH));

        Query query = new Query(criteria);

        LOG.info("listFlowSystem query:{}", query);

        List<FlowSystemBO> flowSystemList = mongoTemplate.find(query, FlowSystemBO.class);
        return flowSystemList;
    }

    private void batchInsertFlowSystemBO(Integer dateType, Date beginDate, Date endDate, List<FlowSystemBO> flowSystemBOList) {
        if (CollUtil.isEmpty(flowSystemBOList)) {
            return;
        }

        String date = DateUtil.format(beginDate, "yyMMdd");
        Date currentDate = new Date();


        // 设置id为当前时间+时间类型+系统类型
        flowSystemBOList.forEach(systemAnalyse -> {
            systemAnalyse.setCreateTime(beginDate);
            systemAnalyse.setUpdateTime(currentDate);
            systemAnalyse.setDateType(dateType);
            systemAnalyse.setId(Integer.parseInt( date + dateType + systemAnalyse.getSystemType()));
        });

        // 先删除再更新
        mongoTemplate.remove(FlowUtil.getRemoveQuery(beginDate, endDate, FlowSystemBO.ID_LENGTH, dateType), FlowSystemBO.class);

        // 统计的数据批量保存到flow_system
        mongoTemplate.insertAll(flowSystemBOList);
    }


    private List<FlowSystemBO> statisticsSystemUserListOfTime(Date beginDate, Date endDate, Integer systemType, List<FlowSystemBO> flowSystemBOList) {
        // 加购人数、访客数、新访客数、跳失人数、下单人数、支付人数
        List<FlowSystemBO> systemUserAnalyseBOList = statisticsSystemUserAnalyseList(beginDate, endDate, systemType);

        flowSystemBOList = new ArrayList<>(flowSystemBOList);

        if (CollUtil.isEmpty(systemUserAnalyseBOList)) {
            return flowSystemBOList;
        }

        // systemTyep为空时，代表统计所有端的数据，因此需要补充一个总的数据
        if (Objects.isNull(systemType)) {
            List<FlowSystemBO> allSystemUserAnalyseBO = statisticsSystemUserAnalyseList(beginDate, endDate, SystemTypeEnum.ALL.value());
            allSystemUserAnalyseBO.get(0).setSystemType(SystemTypeEnum.ALL.value());
            systemUserAnalyseBOList.add(allSystemUserAnalyseBO.get(0));
        }
        Map<Integer, FlowSystemBO> map = flowSystemBOList.stream().collect(Collectors.toMap(FlowSystemBO::getSystemType, s -> s));
        for (FlowSystemBO flowSystemBO : systemUserAnalyseBOList) {
            if (!map.containsKey(flowSystemBO.getSystemType())) {
                flowSystemBOList.add(flowSystemBO);
                continue;
            }
            FlowSystemBO systemAnalyse = map.get(flowSystemBO.getSystemType());
            systemAnalyse.setPlusShopCartUser(flowSystemBO.getPlusShopCartUser());
            systemAnalyse.setVisitUser(flowSystemBO.getVisitUser());
            systemAnalyse.setNewVisitUser(flowSystemBO.getNewVisitUser());
            systemAnalyse.setLossUser(flowSystemBO.getLossUser());
            systemAnalyse.setPlaceOrderUser(flowSystemBO.getPlaceOrderUser());
            systemAnalyse.setPayUser(flowSystemBO.getPayUser());
        }
        return flowSystemBOList;
    }

    /**
     * flow_system_user中统计用户数量
     * @param beginDate
     * @param endDate
     * @return
     */
    private List<FlowSystemBO> statisticsSystemUserAnalyseList(
            Date beginDate, Date endDate,
            Integer systemType) {

        Criteria criteria = Criteria.where("_id")
                    .gte(FlowUtil.timeToId(beginDate, FlowSystemUserBO.ID_LENGTH))
                    .lt(FlowUtil.timeToId(endDate, FlowSystemUserBO.ID_LENGTH))
                .and("dateType").is(FlowDateTypeEnum.DAY.value());

        if (systemType != null && systemType != 0) {
            criteria.and("systemType").is(systemType);
        }
        List<AggregationOperation> aggregationOperationList = new ArrayList<>();

        aggregationOperationList.add(Aggregation.match(criteria));

        String[] userArray;
        if (Objects.isNull(systemType)) {
            userArray = new String[]{"systemType", "userId"};
        } else {
            userArray = new String[]{"userId"};
        }

        aggregationOperationList.add(Aggregation.group(userArray)
                .first("systemType").as("systemType")
                .max("plusShopCart").as("plusShopCart")
                .max("newVisitUser").as("newVisitUser")
                .max("loss").as("loss")
                .max("placeOrder").as("placeOrder")
                .max("pay").as("pay"));

        String[] systemTypeArray;
        if (Objects.isNull(systemType)) {
            systemTypeArray = new String[]{"systemType"};
        } else {
            systemTypeArray = new String[0];
        }

        aggregationOperationList.add(Aggregation.group(systemTypeArray)
                .first("systemType").as("systemType")
                .sum("plusShopCart").as("plusShopCartUser")
                .count().as("visitUser")
                .sum("newVisitUser").as("newVisitUser")
                .sum("loss").as("lossUser")
                .sum("placeOrder").as("placeOrderUser")
                .sum("pay").as("payUser"));

        TypedAggregation<FlowSystemBO> typedAggregation = Aggregation.newAggregation(
                FlowSystemBO.class,
                aggregationOperationList
        );

        List<FlowSystemBO> flowSystemBOList = mongoTemplate
                .aggregate(typedAggregation, "flow_system_user", FlowSystemBO.class)
                .getMappedResults();

        if (Objects.equals(systemType, SystemTypeEnum.ALL.value()) && CollUtil.isNotEmpty(flowSystemBOList)) {
            flowSystemBOList.get(0).setSystemType(systemType);
        }

        return new ArrayList<>(flowSystemBOList);
    }

    private List<FlowSystemBO> listSystemAnalyse(Date beginDate, Date endDate, Integer systemType) {
        Criteria criteria = Criteria.where("dt").gte(beginDate).lt(endDate);

        if (systemType != null) {
            criteria.and("st").is(systemType);
        }


        ProjectionOperation initProjectionOperation = Aggregation.project("oid", "uid", "s", "st")
                // 加购数量
                .and(ConditionalOperators.when(Criteria.where("ve").is(2)).then(1).otherwise(0)).as("plusShopCartNum");

        GroupOperation oidGroupOperation = Aggregation.group("oid", "st")
                .first("oid").as("oid")
                .first("st").as("st")
                .last("uid").as("uid")
                .max("s").as("step")
                .sum("plusShopCartNum").as("plusShopCartNum")
                .count().as("visit");

        ProjectionOperation projectionOperation = Aggregation.project("visit", "st")
                // 人数统计id处理
                .and(ConditionalOperators.when(Criteria.where("uid").gt(0)).then("$uid").otherwise("$oid" )).as("uid")
                // 新访客
                .and(ConditionalOperators.when(Criteria.where("uid").gt(0)).then(0).otherwise(1)).as("newUser")
                // 跳失人数
                .and(ConditionalOperators.when(Criteria.where("step").is(1)).then(1).otherwise(0)).as("lossUser")
                // 加购人数
                .and(ConditionalOperators.when(Criteria.where("plusShopCartNum").gt(0)).then(1).otherwise(0)).as("plusShopCartUser");

        // 跳失取最小的值：要全部的步数都是1步才能算跳失
        // 加购取最大值：只要用户在其中一个会话中加购了就算加购用户
        GroupOperation uidGroupOperation = Aggregation.group("uid", "st")
                .first("st").as("st")
                .sum("visit").as("visit")
                .max("newUser").as("newUser")
                .min("lossUser").as("lossUser")
                .max("plusShopCartUser").as("plusShopCartUser");

        GroupOperation groupOperation = Aggregation.group("st")
                .first("st").as("systemType")
                .sum("visit").as("visit")
                .sum("lossUser").as("lossUser")
                .sum("newUser").as("newVisitUser")
                .sum("plusShopCartUser").as("plusShopCartUser")
                .count().as("visitUser");

        TypedAggregation<FlowSystemBO> typedAggregation = Aggregation.newAggregation(
                FlowSystemBO.class,
                Aggregation.match(criteria),
                initProjectionOperation,
                oidGroupOperation,
                projectionOperation,
                uidGroupOperation,
                groupOperation
        );

        List<FlowSystemBO> systemAnalyseList = mongoTemplate.aggregate(typedAggregation, "flow_user_log", FlowSystemBO.class).getMappedResults();
        if (CollUtil.isEmpty(systemAnalyseList)) {
            systemAnalyseList = new ArrayList<>();
        }
        return new ArrayList<>(systemAnalyseList);
    }


    private List<FlowSystemBO> handleSystemOrderList(List<FlowSystemBO> systemAnalyseList, Date beginDate, Date endDate, Integer systemType) {
        // 过滤
        Criteria criteria = Criteria.where("dt").gte(beginDate).lt(endDate).and("ve").in(4, 5);
        if (Objects.nonNull(systemType)) {
            criteria.and("st").is(systemType);
        }
        MatchOperation matchOperation = Aggregation.match(criteria);

        GroupOperation initGroupOperation = Aggregation.group("bid", "ve", "st")
                .first("bid").as("bid")
                .first("ve").as("ve")
                .last("uid").as("uid");

        LookupOperation lookupOperation = Aggregation.lookup("order", "bid", "_id", "orders");

        ProjectionOperation orderProjectionOperation = Aggregation.project("uid")
                // 下单金额
                .and(ConditionalOperators.when(Criteria.where("ve").is(4)).then("$orders.actualTotal").otherwise(0)).as("placeOrderAmount")
                // 下单金额
                .and(ConditionalOperators.when(Criteria.where("ve").is(5)).then("$orders.actualTotal").otherwise(0)).as("payAmount")
                // 系统类型
                .and("_id.st").as("systemType");

        GroupOperation userGroupOperation = Aggregation.group("uid", "systemType")
                .sum("placeOrderAmount").as("placeOrderAmount")
                .sum("payAmount").as("payAmount")
                .first("systemType").as("systemType");

        ProjectionOperation projectionOperation = Aggregation.project("placeOrderAmount", "payAmount", "systemType")
                // 下单金额
                .and(ConditionalOperators.when(Criteria.where("placeOrderAmount").gt(0)).then(1).otherwise(0)).as("placeOrderUser")
                // 下单金额
                .and(ConditionalOperators.when(Criteria.where("payAmount").gt(0)).then(1).otherwise(0)).as("payUser");



        GroupOperation groupOperation = Aggregation.group("systemType")
                .sum("placeOrderUser").as("placeOrderUser")
                .sum("payUser").as("payUser")
                .sum("placeOrderAmount").as("placeOrderAmount")
                .sum("payAmount").as("payAmount")
                .first("systemType").as("systemType");

        TypedAggregation<FlowSystemBO> typedAggregation = Aggregation.newAggregation(
                FlowSystemBO.class,
                matchOperation,
                initGroupOperation,
                lookupOperation,
                Aggregation.unwind("orders"),
                orderProjectionOperation,
                userGroupOperation,
                projectionOperation,
                groupOperation
        );

        LOG.info("handleSystemOrderList:typedAggregation:{}", typedAggregation);

        List<FlowSystemBO> flowSystemBOList = mongoTemplate.aggregate(typedAggregation, "flow_user_log",  FlowSystemBO.class).getMappedResults();
        if (CollUtil.isEmpty(flowSystemBOList)) {
            return systemAnalyseList;
        }

        Map<Integer, FlowSystemBO> map = systemAnalyseList.stream().collect(Collectors.toMap(FlowSystemBO::getSystemType, s -> s));
        for (FlowSystemBO flowSystemBO : flowSystemBOList) {
            FlowSystemBO systemAnalyse = map.get(flowSystemBO.getSystemType());
            if (Objects.isNull(systemAnalyse)) {
                systemAnalyse = new FlowSystemBO();
                map.put(flowSystemBO.getSystemType(), systemAnalyse);
            }
            systemAnalyse.setPlaceOrderUser(flowSystemBO.getPlaceOrderUser());
            systemAnalyse.setPayUser(flowSystemBO.getPayUser());
            systemAnalyse.setPlaceOrderAmount(flowSystemBO.getPlaceOrderAmount());
            systemAnalyse.setPayAmount(flowSystemBO.getPayAmount());
        }
        return new ArrayList<>(map.values());
    }


    private FlowSystemBO getALLSystemAnalyseBO(Date beginDate, Date endDate) {
        ProjectionOperation projectionOperation = Aggregation.project("oid", "uid", "s")
                // 加购数量
                .and(ConditionalOperators.when(Criteria.where("ve").is(2)).then(1).otherwise(0)).as("plusShopCartNum");

        GroupOperation oidGroupOperation = Aggregation.group("oid")
                .last("uid").as("uid")
                .max("s").as("step")
                .sum("plusShopCartNum").as("plusShopCartNum")
                .count().as("visit");

        ProjectionOperation projectionOperation2 = Aggregation.project("visit")
                // 人数统计id处理
                .and(ConditionalOperators.when(Criteria.where("uid").gt(0)).then("$uid").otherwise("$_id" )).as("uid")
                // 新访客
                .and(ConditionalOperators.when(Criteria.where("uid").gt(0)).then(0).otherwise(1)).as("newUser")
                // 跳失人数
                .and(ConditionalOperators.when(Criteria.where("step").is(1)).then(1).otherwise(0)).as("lossUser")
                // 加购人数
                .and(ConditionalOperators.when(Criteria.where("plusShopCartNum").gt(0)).then(1).otherwise(0)).as("plusShopCartUser");

        // 跳失取最小的值：要全部的步数都是1步才能算跳失
        // 加购取最大值：只要用户在其中一个会话中加购了就算加购用户
        GroupOperation uidGroupOperation = Aggregation.group("uid")
                .sum("visit").as("visit")
                .max("newUser").as("newVisitUser")
                .min("lossUser").as("lossUser")
                .max("plusShopCartUser").as("plusShopCartUser");

        GroupOperation groupOperation = Aggregation.group()
                .sum("visit").as("visit")
                .sum("lossUser").as("lossUser")
                .sum("newVisitUser").as("newVisitUser")
                .sum("plusShopCartUser").as("plusShopCartUser")
                .count().as("visitUser");

        TypedAggregation<FlowSystemBO> typedAggregation = Aggregation.newAggregation(
                FlowSystemBO.class,
                Aggregation.match(Criteria.where("dt").gte(beginDate).lt(endDate)),
                projectionOperation,
                oidGroupOperation,
                projectionOperation2,
                uidGroupOperation,
                groupOperation
        );

        List<FlowSystemBO> mappedResults = mongoTemplate.aggregate(typedAggregation, "flow_user_log", FlowSystemBO.class).getMappedResults();

        FlowSystemBO flowSystemBO;
        if (CollUtil.isEmpty(mappedResults)) {
            flowSystemBO =  new FlowSystemBO();
        } else {
            flowSystemBO = mappedResults.get(0);
            flowSystemBO.setSystemType(SystemTypeEnum.ALL.value());
        }

        return flowSystemBO;
    }



    private void handleSystemOrder(FlowSystemBO flowSystemBO, Date beginDate, Date endDate) {

        MatchOperation matchOperation = Aggregation.match(Criteria.where("createTime").gte(beginDate).lt(endDate));

        ProjectionOperation userProjectionOperation = Aggregation.project("_id", "userId")
                .and("actualTotal").as("placeOrderAmount")
                .and(ConditionalOperators.when(Criteria.where("isPayed").is(1)).then("$actualTotal").otherwise(0)).as("payAmount");

        GroupOperation userGroupOperation = Aggregation.group("userId")
                .sum("placeOrderAmount").as("placeOrderAmount")
                .sum("payAmount").as("payAmount");

        ProjectionOperation projectionOperation = Aggregation.project("placeOrderAmount", "payAmount")
                .and(ConditionalOperators.when(Criteria.where("placeOrderAmount").gt(0)).then(1).otherwise(0)).as("placeOrderUser")
                .and(ConditionalOperators.when(Criteria.where("payAmount").gt(0)).then(1).otherwise(0)).as("payUser");


        GroupOperation groupOperation = Aggregation.group()
                .sum("placeOrderAmount").as("placeOrderAmount")
                .sum("payAmount").as("payAmount")
                .sum("placeOrderUser").as("placeOrderUser")
                .sum("payUser").as("payUser");

        TypedAggregation<FlowSystemBO> typedAggregation = Aggregation.newAggregation(
                FlowSystemBO.class,
                matchOperation,
                userProjectionOperation,
                userGroupOperation,
                projectionOperation,
                groupOperation
        );
        LOG.info("handleSystemOrder:typedAggregation:{}", typedAggregation);

        List<FlowSystemBO> flowSystemList = mongoTemplate
                .aggregate(typedAggregation, "order", FlowSystemBO.class)
                .getMappedResults();
        if (CollUtil.isEmpty(flowSystemList)) {
            return;
        }
        FlowSystemBO systemAnalyse = flowSystemList.get(0);
        flowSystemBO.setSystemType(0);
        flowSystemBO.setPayAmount(systemAnalyse.getPayAmount());
        flowSystemBO.setPlaceOrderAmount(systemAnalyse.getPlaceOrderAmount());
        flowSystemBO.setPayUser(systemAnalyse.getPayUser());
        flowSystemBO.setPlaceOrderUser(systemAnalyse.getPlaceOrderUser());
    }

}
