package com.ruoyi.app.order;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.ruoyi.app.order.dto.OrderPositionInfo;
import com.ruoyi.app.order.dto.OrderPushBodyDto;
import com.ruoyi.app.order.dto.PositionDto;
import com.ruoyi.app.order.dto.QsDto;
import com.ruoyi.app.pay.PayController;
import com.ruoyi.app.service.UserService;
import com.ruoyi.app.service.WalletService;
import com.ruoyi.app.user.dto.StoreOutput;
import com.ruoyi.app.utils.DateUtil;
import com.ruoyi.app.utils.OperatingUtil;
import com.ruoyi.app.utils.PayPush;
import com.ruoyi.app.utils.event.PushEventService;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.OrderDTO;
import com.ruoyi.system.mapper.PosFoodMapper;
import com.ruoyi.system.mapper.PosOrderMapper;
import com.ruoyi.system.mapper.RiderPositionMapper;
import com.ruoyi.system.mapper.UserBillingMapper;
import com.ruoyi.system.service.*;
import com.ruoyi.system.utils.Auth;
import com.ruoyi.system.utils.GetArea;
import com.ruoyi.system.utils.JwtUtil;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletResponse;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * posorderController
 *
 * @author ruoyi
 * @date 2023-05-23
 */
@RestController
@RequestMapping("/system/order")
public class PosOrderController extends BaseController {
    @Autowired
    private IPosOrderService posOrderService;
    @Autowired
    private IInfoUserService infoUserService;
    @Autowired
    private IPosStoreService posStoreService;
    @Autowired
    private IInfoAddressService infoAddressService;
    @Autowired
    private IUserFootprintService userFootprintService;
    @Autowired
    private PosOrderMapper posOrderMapper;
    @Autowired
    private IRiderPositionService riderPositionService;
    @Autowired
    private IUserBillingService userBillingService;
    @Autowired
    private UserBillingMapper userBillingMapper;
    @Autowired
    private IPosMarginService posMarginService;
    @Autowired
    private ISalesPromotionService salesPromotionService;
    @Autowired
    private IPosAppealService posAppealService;
    @Autowired  //商品
    private IPosFoodService posFoodService;
    @Autowired  //经营时间
    private IOperatingHoursService operatingHoursService;
    @Autowired
    private IVipUserQuanyiService userQuanyiService;
    @Autowired
    private ISysPointControlService pointControlService;
    @Autowired
    private IUserWalletService userWalletService;
    @Autowired
    private RiderPositionMapper riderPositionMapper;
    @Autowired
    private IPointsTransactionService pointsTransactionService;
    @Autowired
    private PayController payController;
    @Autowired
    private PushEventService pushEventService;
    @Autowired
    private IPosOrderRatingService posOrderRatingService;
    @Autowired
    private IFoodStatisticsService foodStatisticsService;
    @Autowired
    private IOrderParentService orderParentService;
    @Autowired
    private WalletService walletService;
    @Autowired
    private PosFoodMapper posFoodMapper;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private UserService userService;


    //查询用户足迹
    @Anonymous
    @Auth
    @GetMapping("/getuserfootlist")
    public AjaxResult getuserfootlist(@RequestHeader String token, @RequestParam Integer page, @RequestParam Integer size) {
        JwtUtil jwtUtil = new JwtUtil();
        String id = jwtUtil.getusid(token);
        IPage<UserFootprint> palist = new Page<>(page, size);
        QueryWrapper<UserFootprint> queryWrapper = new QueryWrapper<>();
        queryWrapper.select().orderByDesc("cretim");
        queryWrapper.eq("user_id", id);
        IPage<UserFootprint> list = userFootprintService.page(palist, queryWrapper);
        List<UserFootprint> footprints = list.getRecords();
        // 收集所有门店ID（Integer类型）
        List<Long> storeIds = footprints.stream()
                .map(UserFootprint::getMdId)
                .toList();

        // 使用MyBatis Plus一次性查询所有门店的商品（避免N+1查询问题）
        Map<Integer, List<PosFood>> foodMap = new java.util.HashMap<>();
        if (!storeIds.isEmpty()) {
            // 将Integer类型的门店ID转换为Long类型用于查询（因为mdid是Long类型）
            List<Long> storeIdsLong = storeIds.stream()
                    .map(x -> x)
                    .collect(Collectors.toList());

            // 使用MyBatis Plus的Mapper方法，在数据库查询时就限制每个门店只返回6条商品
            List<PosFood> allFoods = posFoodMapper.selectFoodsByStoreIdsWithLimit(storeIdsLong, "3", 6);

            // 按门店ID分组（查询结果已经限制为每个门店最多6条）
            foodMap = allFoods.stream()
                    .collect(Collectors.groupingBy(food -> food.getMdid().intValue()));
        }

        // 转换为StoreOutput并设置每个门店的商品列表（每个门店最多6条）
        List<StoreOutput> storeOutputList = new ArrayList<>();
        for (UserFootprint collect : footprints) {
            PosStore store = posStoreService.getById(collect.getMdId());
            if (store != null) {
                StoreOutput storeOutput = new StoreOutput();
                // 复制PosStore的所有属性
                BeanUtils.copyProperties(store, storeOutput);
                // 从分组结果中获取该门店的商品列表（已限制为最多6条）
                List<PosFood> foodList = foodMap.getOrDefault(store.getId(), new ArrayList<>());
                storeOutput.setFoodList(foodList);
                storeOutputList.add(storeOutput);
            }
        }
        Page<StoreOutput> result = new Page<>(page, 10);
        result.setTotal(list.getTotal());
        result.setRecords(storeOutputList);
        return success(result);
    }


    //修改订单
    @Anonymous
    @Auth
    @RepeatSubmit(interval = 1000, message = "请求过于频繁")
    @PostMapping("/setorderuzt")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult setorderuzt(@RequestHeader String token, @RequestBody PosOrder posOrder) {
        JwtUtil jwtUtil = new JwtUtil();
        PayPush push = new PayPush();
        String id = jwtUtil.getusid(token);
        if (posOrder.getState() != null) {
            //状态为送达，设置送达时间
            if (posOrder.getState() == 12) {
                posOrder.setSdTime(new Date());
            }
            System.out.println("修改订单状态信息：" + JSON.toJSONString(posOrder));
            //设置支付类型为货到付款
            if (posOrder.getState() == 0 && "1".equals(posOrder.getCollectPayment())) {
                System.out.println("进入设置paytype等于1");
                posOrder.setPayType("1");
            }
            //取餐时设置预计送达时间
            setYjsdTime(posOrder);
            if (posOrder.getState() == 5) {
                return setOrderState5(posOrder);
            } else if (posOrder.getState() == 2) {
                return setOrderState2(posOrder, id);
            } else if (posOrder.getState() == 3 || posOrder.getState() == 4 || posOrder.getState() == 12) {
                return setOrderQsState(posOrder, id, push);
            } else if (posOrder.getState() == 7) {
                return setOrderState7(posOrder);
            } else {

                boolean org = posOrderService.saveOrUpdate(posOrder);
                PosOrder order = posOrderService.getById(posOrder.getId());
                if (order.getState() == 0 && order.getCollectPayment().equals("1")) {
                    sendHdfkMessage(order, push);
                }
                //作废退回积分
                if (posOrder.getState() == 10 && order.getPoints() != null && order.getPoints() > 0) {
                    returnPoints(order.getUserId(), Long.valueOf(order.getDdId()), Long.valueOf(order.getPoints()));
                }
                if (org) {
                    return success(MessageUtils.message("no.modify.success"), posOrder.getId());
                } else {
                    return error();
                }
            }
        } else {
            return setOrderNoState(posOrder, id);
        }
    }

    //骑手接单、取餐、送达
    private AjaxResult setOrderQsState(PosOrder posOrder, String qsId, PayPush push) {
        String lockKey = "order:qs:lock:" + posOrder.getId();
        RLock lock = redissonClient.getLock(lockKey);
        try {
            var local = LocaleContextHolder.getLocale();
            logger.info("骑手接单local信息：" + local.getLanguage());
            logger.info(JSON.toJSONString(local));
            // 尝试获取锁
            if (lock.tryLock(20L, 10L, TimeUnit.SECONDS)) {
                boolean releaseInfinally = true;
                try {
                    userService.checkUserStatus(Long.valueOf(qsId));
                    PosOrder orst = posOrderService.getById(posOrder.getId());
                    if (orst.getState() == 3 && posOrder.getState() == 3) {
                        throw new ServiceException(MessageUtils.message("no.order.snatched"));
                    }
                    if (posOrder.getState() == 3) {
                        QueryWrapper<PosOrder> wrapper = new QueryWrapper<>();
                        wrapper.eq("qs_id", qsId);
                        wrapper.in("state", 3, 4);
                        List<PosOrder> orsts = posOrderService.list(wrapper);
                        if (orsts.size() > 0) {
                            throw new ServiceException(MessageUtils.message("no.exist.undelivered.order"));
                        }
                    }
                    String userMessage = MessageUtils.message("no.message.push.delivery.personnel.receiving.order");
                    if (posOrder.getState() == 4) {
                        userMessage = MessageUtils.message("no.message.push.delivery.personnel.qspsz.order");
                    } else if (posOrder.getState() == 12) {
                        userMessage = MessageUtils.message("no.message.push.delivery.personnel.qsysd.order");
                    }

                    boolean org = posOrderService.saveOrUpdate(posOrder);
                    if (org) {
                        //到付订单,设置用户账单为完成
                        if (posOrder.getState() == 3 && "1".equals(orst.getCollectPayment())) {
                            updateUserBill(orst.getDdId(), orst.getUserId(), orst.getQsId());
                        }
                        InfoUser user = infoUserService.getById(orst.getUserId());
                        InfoUser shu = infoUserService.getById(orst.getShId());
                        String finalUserMessage = userMessage;
                        releaseInfinally = false;
                        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                            @Override
                            public void afterCommit() {
                                if (lock.isHeldByCurrentThread()) {
                                    lock.unlock();
                                }
                                // 给用户推送（骑手已接单/配送中/已送达）
                                if (!StringUtils.isEmpty(user.getCid())) {
                                    String userTitle = "no.message.push.message";
                                    String userContent = "no.message.push.delivery.personnel.receiving.order";
                                    if (posOrder.getState() == 4) {
                                        userContent = "no.message.push.delivery.personnel.qspsz.order";
                                    } else if (posOrder.getState() == 12) {
                                        userContent = "no.message.push.delivery.personnel.qsysd.order";
                                    }
                                    final String finalUserContent = userContent;
                                    String userBody = OrderPushBodyDto.getJson(String.valueOf(orst.getDdId()), String.valueOf(posOrder.getState()));
                                    Long userUserId = user.getUserId();
                                    String userCid = user.getCid();
                                    String userCidType = "";
                                    String userDdId = String.valueOf(orst.getDdId());
                                    AsyncManager.me().execute(new TimerTask() {
                                        @Override
                                        public void run() {
                                            PayPush.userPushHandleLocal(push, pushEventService, userUserId, userCid, userTitle, finalUserContent, userBody, userCidType, userDdId);
                                        }
                                    });
                                }
                                // 给商家推送（骑手已接单时）
                                if (!StringUtils.isEmpty(shu.getCid()) && posOrder.getState() == 3) {
                                    String shTitle = "no.message.push.message";
                                    String shContent = "no.message.push.delivery.personnel.receiving.order";
                                    String shBody = OrderPushBodyDto.getJson(String.valueOf(orst.getDdId()), String.valueOf(posOrder.getState()));
                                    Long shUserId = shu.getUserId();
                                    String shCid = shu.getCid();
                                    String shCidType = "";
                                    String shDdId = String.valueOf(orst.getDdId());
                                    AsyncManager.me().execute(new TimerTask() {
                                        @Override
                                        public void run() {
                                            PayPush.shPushHandleLocal(push, pushEventService, shUserId, shCid, shTitle, shContent, shBody, shCidType, shDdId);
                                        }
                                    });
                                }
                            }
                        });
                        return success(MessageUtils.message("no.modify.success"), posOrder.getId());
                    } else {
                        return error();
                    }
                } finally {
                    if (releaseInfinally && lock.isHeldByCurrentThread()) {
                        lock.unlock();
                    }
                }
            } else {
                throw new ServiceException(MessageUtils.message("no.system.busy.try.again"));
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new ServiceException(MessageUtils.message("no.operation.interrupted.try.again"));
        }
    }

    /**
     * 更新用户用户账单
     *
     * @param ddId
     * @param userId
     * @param qsId
     */
    private void updateUserBill(String ddId, Long userId, Long qsId) {
        QueryWrapper<UserBilling> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dd_id", ddId);
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("type", "3");
        UserBilling userBill = userBillingService.getOne(queryWrapper);
        if (userBill != null) {
            userBill.setState("0");
            userBill.setIllustrate("Rider Payment Order");
            userBill.setBalancePay("1");
            userBill.setPaymentId(String.valueOf(qsId));
            userBillingService.saveOrUpdate(userBill);
        }
    }


    //商家接单
    private AjaxResult setOrderState2(PosOrder posOrder, String id) {
        int zsou = userBillingMapper.gettypesum(Long.valueOf(id), 1L);
        int zcz = userBillingMapper.gettypesum(Long.valueOf(id), 2L);
        int xiaof = userBillingMapper.gettypesum(Long.valueOf(id), 3L);
        int yure = zsou - zcz - xiaof;
        PosMargin posMargin = posMarginService.getById(1);
        InfoUser user = infoUserService.getById(id);
        if (user.getUserType().equals("1")) {
            boolean org = posOrderService.saveOrUpdate(posOrder);
            if (org) {
                PosOrder order = posOrderService.getById(posOrder.getId());
                return success(MessageUtils.message("no.modify.success"), posOrder.getId());
            } else {
                return error();
            }
        } else {
            if (yure <= (int) Math.round(posMargin.getAmount())) {
                return error(MessageUtils.message("no.insufficient.user.security.deposit"));
            } else {
                boolean org = posOrderService.saveOrUpdate(posOrder);
                if (org) {
                    PosOrder order = posOrderService.getById(posOrder.getId());
                    return success(MessageUtils.message("no.modify.success"), posOrder.getId());
                } else {
                    return error();
                }
            }
        }
    }

    //订单完成
    private AjaxResult setOrderState5(PosOrder posOrder) {
        boolean org = posOrderService.saveOrUpdate(posOrder);
        if (org) {
            PosOrder order = posOrderService.getById(posOrder.getId());
            QueryWrapper<UserBilling> wrapper = new QueryWrapper<>();
            wrapper.eq("dd_id", order.getDdId());

            UserBilling billing = userBillingService.getOne(wrapper);
            if (billing == null) {
                setSanghuBilling(order);
                setQishouBilling(order);
            }
            return success(MessageUtils.message("no.modify.success"), posOrder.getId());
        } else {
            return error();
        }
    }

    //同意退款
    private AjaxResult setOrderState7(PosOrder posOrder) {
        boolean org = posOrderService.saveOrUpdate(posOrder);
        PosOrder order = posOrderService.getById(posOrder.getId());
        if (order.getPoints() != null && order.getPoints() > 0) {
            returnPoints(order.getUserId(), Long.valueOf(order.getDdId()), Long.valueOf(order.getPoints()));
        }
        if (org) {
            QueryWrapper<UserBilling> wrapper = new QueryWrapper<>();
            wrapper.eq("dd_id", posOrder.getId());
            List<UserBilling> billing = userBillingService.list(wrapper);
            if (billing.size() == 0) {
                return success(MessageUtils.message("no.modify.success"), posOrder.getId());
            } else {
                for (int i = 0; i < billing.size(); i++) {
                    UserBilling user = new UserBilling();
                    user.setId(billing.get(i).getId());
                    user.setState("1");
                    userBillingService.saveOrUpdate(user);
                }
                return success(MessageUtils.message("no.modify.success"), posOrder.getId());
            }
        } else {
            return error();
        }
    }

    //更改订单没传订单状态
    private AjaxResult setOrderNoState(PosOrder posOrder, String id) {
        PosOrder ordera = posOrderService.getById(posOrder.getId());
        //订单金额限制100万改为200万
        if (posOrder.getCollectPayment().equals("1") && ordera.getAmount() > 2000000) {
            return error(MessageUtils.message("no.cash_on_delivery_amount.exceed.limit_amount"));
        }

        QueryWrapper<PosOrder> query = new QueryWrapper<>();
        query.eq("user_id", id);
        query.eq("collect_payment", "1");
        query.notIn("state", 5, 10, 11);
        List<PosOrder> posOrders = posOrderService.list(query);
        //到付能存在2单未完成，第3单弹出提示;修改做判断的前提是当前订单不是为到付
        if (posOrders.size() >= 2 && posOrder.getCollectPayment().equals("1") && !"1".equals(ordera.getCollectPayment())) {
            return error(MessageUtils.message("no.exist.cash_on_delivery_order.incomplete"));
        }
        boolean org = posOrderService.saveOrUpdate(posOrder);
        if (org) {
            chuCan(ordera, posOrder);
            PosOrder order = posOrderService.getById(posOrder.getId());

            return success(MessageUtils.message("no.modify.success"), posOrder.getId());
        } else {
            return error();
        }
    }

    /**
     * 商家出餐推送：给用户和骑手推送通知
     */
    private void chuCan(PosOrder oldOrder, PosOrder posOrder) {
        if (oldOrder.getDiningStatus() != null && oldOrder.getDiningStatus() == 0
                && posOrder.getDiningStatus() != null && posOrder.getDiningStatus().equals(1L)) {
            List<Long> ids = new ArrayList<>();
            ids.add(oldOrder.getUserId());
            if (oldOrder.getQsId() != null) {
                ids.add(oldOrder.getQsId());
            }
            List<InfoUser> users = infoUserService.list(new LambdaQueryWrapper<InfoUser>().in(InfoUser::getUserId, ids));
            Optional<InfoUser> user = users.stream().filter(x -> "0".equals(x.getUserType())).findFirst();
            Optional<InfoUser> qsUser = users.stream().filter(x -> "2".equals(x.getUserType())).findFirst();

            String title = "no.message.push.message";
            String content = "no.message.push.merchant.ready.content";
            Long stateVal = posOrder.getState() != null ? posOrder.getState() : oldOrder.getState();
            String stateStr = stateVal != null ? String.valueOf(stateVal) : "2";
            String body = OrderPushBodyDto.getJson(String.valueOf(oldOrder.getDdId()), stateStr);
            String ddId = String.valueOf(oldOrder.getDdId());

            // 给用户推送
            if (user.isPresent()) {
                InfoUser u = user.get();
                PayPush push = new PayPush();
                Long uUserId = u.getUserId();
                String uCid = u.getCid();
                AsyncManager.me().execute(new TimerTask() {
                    @Override
                    public void run() {
                        PayPush.userPushHandleLocal(push, pushEventService, uUserId, uCid, title, content, body, "", ddId);
                    }
                });
            }
            // 给骑手推送
            if (qsUser.isPresent()) {
                InfoUser qs = qsUser.get();
                if (!StringUtils.isEmpty(qs.getCid())) {
                    PayPush push = new PayPush();
                    Long qsUserId = qs.getUserId();
                    String qsCid = qs.getCid();
                    AsyncManager.me().execute(new TimerTask() {
                        @Override
                        public void run() {
                            PayPush.qsPushHandleLocal(push, pushEventService, qsUserId, qsCid, title, content, body, "", ddId);
                        }
                    });
                }
            }
        }
    }

    /**
     * 获取预计送达时间
     *
     * @param posOrder
     * @return
     */
    private String setYjsdTime(PosOrder posOrder) {
        try {
            if (posOrder.getState() == 4) {
                GetArea getArea = new GetArea();
                PosOrder order = posOrderService.getById(posOrder.getId());
                String mdlat = order.getLongitude() + "," + order.getLatitude();
                InfoAddress shDz = infoAddressService.getById(order.getShdzId());

                String shlat = shDz.getLongitude() + "," + shDz.getLatitude();
                double time = getArea.getMotorbikeDuration(mdlat, shlat);
                DateUtil dateUtil = new DateUtil();
                String start = dateUtil.getHourAndMinute((long) time);
                double endTime = time + 600; //加上10分钟
                String end = dateUtil.getHourAndMinute((long) endTime);
                posOrder.setYjsdTime(start + "-" + end);
                return start + "-" + end;
            }
            return "";
        } catch (Exception e) {
            logger.error("获取预计送达时间异常,id:" + posOrder.getId() + "异常信息：", e);
            return "";
        }
    }

    //修改订单
    @Anonymous
    @PostMapping("/testYjsdTime")
    public String testYjsdTime(@RequestBody PosOrder order) {
        return setYjsdTime(order);

    }


    //执行商户分成
    public void setSanghuBilling(@NotNull PosOrder posOrder) {
        long count = userBillingService.count(new LambdaQueryWrapper<UserBilling>().eq(UserBilling::getUserId, posOrder.getShId()).eq(UserBilling::getType, "0").eq(UserBilling::getDdId, posOrder.getDdId()));
        if (count <= 0) {
            UserBilling billing = new UserBilling();
            DecimalFormat df = new DecimalFormat("#.00");

            // 判断是否为摊位订单
            PosStore store = posStoreService.getById(posOrder.getMdId());
            boolean isStall = store != null && store.getIsStall() != null && store.getIsStall() == 1 && store.getNightMarketId() != null;

            InfoUser user;
            if (isStall) {
                // 摊位订单：使用夜市用户的分成比例
                user = infoUserService.getById(store.getNightMarketId());
            } else {
                // 普通订单：使用商家用户的分成比例
                user = infoUserService.getById(posOrder.getShId());
            }
            Double fcbili = user.getCommission() == null ? 0.00 : user.getCommission();
            fcbili = getShCommissionRate(fcbili, user.getUserId());
            JSONArray list = JSONArray.parseArray(posOrder.getFood());
            int fenc = 0;
            for (int i = 0; i < list.size(); i++) {
                JSONObject foods = list.getJSONObject(i);
                //20250612修改，商品金额等于价格乘以数量；未修改前金额直接为商品价格
                int price = foods.getInteger("price");
                int otherPrice = foods.getInteger("otherPrice"); //规格价格
                int num = foods.getInteger("number");
                int age = (price + otherPrice) * num; //价格=商品价格+规格价格
                fenc += age;
            }
            String remark = "";
            //商家分成总金额，减去商家优惠金额，减去商家活动金额(type=1 为平台指定商家优惠券，由平台承担)
            if (posOrder.getMdYhId() != null && posOrder.getMdDiscountAmount() != null) {
                VipUserQuanyi userQuanyi = userQuanyiService.getById(posOrder.getMdYhId());
                if (userQuanyi != null && "1".equals(userQuanyi.getType())) {
                    fenc = fenc - posOrder.getMdDiscountAmount();
                    String yhmcMessage = MessageUtils.message("no.posorder.md.yh.mc.messag");
                    yhmcMessage = StrUtil.format(yhmcMessage, posOrder.getMdYhName());
                    remark += yhmcMessage;
                    String yhAmount = MessageUtils.message("no.posorder.md.yh.jiner.messag");
                    yhAmount = StrUtil.format(yhAmount, posOrder.getMdDiscountAmount());
                    remark += yhAmount;
                }

            }
            if (posOrder.getMdSalesName() != null && posOrder.getMdSalesReduction() != null) {
                fenc = fenc - posOrder.getMdSalesReduction();
                String cxNameMessage = MessageUtils.message("no.posorder.md.cx.mc.messag");
                cxNameMessage = StrUtil.format(cxNameMessage, posOrder.getMdSalesName());
                remark += cxNameMessage;
                String cxAmount = MessageUtils.message("no.posorder.md.cx.jiner.messag");
                cxAmount = StrUtil.format(cxAmount, posOrder.getMdSalesReduction());
                remark += cxAmount;
            }
            billing.setIllustrate(remark);
            Double chouc = fenc * fcbili;
            Double shfc = fenc - chouc;
            billing.setUserId(posOrder.getShId());
            billing.setDdId(String.valueOf(posOrder.getDdId()));
            billing.setType("0");
            billing.setAmount(Double.valueOf(df.format(shfc)));
            billing.setDivvy(Double.valueOf(df.format(chouc)));
            billing.setState("0");
            billing.setMdId(posOrder.getMdId());
            billing.setUserType("1");
            billing.setDivvyRate(fcbili);
            if (isStall) {
                // 摊位订单：更新摊位钱包
                billing.setStoreId(Long.valueOf(store.getId()));
                walletService.addStallBalance(Long.valueOf(store.getId()), BigDecimal.valueOf(billing.getAmount()), billing);
            } else {
                // 普通订单：更新用户钱包
                walletService.addBalance(billing.getUserId(), BigDecimal.valueOf(billing.getAmount()), billing);
            }
//            int reg = userBillingService.insertUserBilling(billing);
//            if (reg == 1) {
//
//                System.out.println("商户分成成功，订单号：" + posOrder.getDdId() + ",分成金额：" + shfc + ",抽成：" + chouc);
//
//            } else {
//                System.out.println("订单：" + posOrder.getDdId() + "分成失败");
//            }
        }
    }

    /**
     * 获取商家分成比例
     * 委托给 Service 层处理
     *
     * @param rate     默认分成比例
     * @param shUserId 商家用户ID
     * @return 分成比例
     */
    public Double getShCommissionRate(Double rate, Long shUserId) {
        return rate;
        // 委托给 Service 层处理
//        return commissionRatesService.getShCommissionRate(rate, shUserId);
    }

    //执行骑手分成
    public void setQishouBilling(@NotNull PosOrder posOrder) {
        long count = userBillingService.count(new LambdaQueryWrapper<UserBilling>().eq(UserBilling::getUserId, posOrder.getQsId()).eq(UserBilling::getType, "0").eq(UserBilling::getDdId, posOrder.getDdId()));
        if (count <= 0) {
            UserBilling billing = new UserBilling();
            DecimalFormat df = new DecimalFormat("#.00");
            InfoUser user = infoUserService.getById(posOrder.getQsId());
            if (user == null) {
                System.out.println("订单无骑手");
            } else {
                Double fcbili = user.getCommission() == null ? 0.00 : user.getCommission();
                Double fenc = posOrder.getFreight();
                Double chouc = fenc * fcbili;
                Double shfc = fenc - chouc;
                List<SysDictData> taxBl = DictUtils.getDictCache("sys_qs_freight_bl");
                if (taxBl != null && taxBl.get(0) != null) {
                    Double tax = shfc * Double.parseDouble(taxBl.get(0).getDictValue());
                    billing.setTax(BigDecimal.valueOf(tax));
                    billing.setTaxRate(taxBl.get(0).getDictValue());
                    shfc = shfc - tax;
                }
                billing.setUserId(posOrder.getQsId());
                billing.setDdId(String.valueOf(posOrder.getDdId()));
                billing.setType("0");
                billing.setAmount(Double.valueOf(df.format(shfc)));
                billing.setDivvy(Double.valueOf(df.format(chouc)));
                billing.setState("0");
                billing.setMdId(posOrder.getMdId());
                billing.setUserType("2");
                billing.setDivvyRate(user.getCommission());
                //货到付款设置代收金额
                if ("1".equals(posOrder.getCollectPayment())) {
                    billing.setBehalfAmount(Double.valueOf(posOrder.getAmount()));
                }
                walletService.addBalance(billing.getUserId(), BigDecimal.valueOf(billing.getAmount()), billing);
//                int reg = userBillingService.insertUserBilling(billing);
//                if (reg == 1) {
//                    System.out.println("骑手分成成功，订单号：" + posOrder.getDdId() + ",分成金额：" + shfc + ",抽成：" + chouc);
//                } else {
//                    System.out.println("订单：" + posOrder.getDdId() + "分成失败");
//                }
            }
        }

    }


    //后台查询详情
    @GetMapping("/getorderhout")
    public AjaxResult getorderhout(@RequestParam String id) {
        PosOrder orlist = posOrderService.getById(id);
        JSONObject org = new JSONObject();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        org.put("id", orlist.getId());
        org.put("ddId", orlist.getDdId());
        org.put("shanghu", infoUserService.getById(orlist.getShId()));
        org.put("store", posStoreService.getById(orlist.getMdId()));
        org.put("cretim", sdf.format(orlist.getCretim()));
        org.put("shdzId", orlist.getShdzId());
        org.put("shaddress", orlist.getShAddress() == null ? infoAddressService.getById(orlist.getShdzId()) : JSONObject.parseObject(orlist.getShAddress()));
        org.put("user", infoUserService.getById(orlist.getUserId()));
        org.put("amount", orlist.getAmount());
        org.put("kefuState", orlist.getKefuState());
        org.put("kefuContent", orlist.getKefuContent());
        org.put("kefuRepeat", orlist.getKefuRepeat());
        org.put("repeatDdId", orlist.getRepeatDdId());
        org.put("remarks", orlist.getRemarks());
        org.put("state", orlist.getState());
        org.put("type", orlist.getType());
        org.put("jvli", orlist.getJvli());
        org.put("freight", orlist.getFreight());
        org.put("delryTime", orlist.getDelryTime());
        org.put("longitude", orlist.getLongitude());
        org.put("latitude", orlist.getLatitude());
        org.put("qsuser", infoUserService.getById(orlist.getQsId()));
        org.put("payUrl", orlist.getPayUrl());
        QueryWrapper<RiderPosition> query = new QueryWrapper<>();
        query.eq("rider_id", orlist.getQsId());
        org.put("RiderPosition", orlist.getQsId() == null ? null : riderPositionService.getOne(query));
        org.put("diningStatus", orlist.getDiningStatus());
        org.put("collectPayment", orlist.getCollectPayment());
        org.put("food", JSONArray.parseArray(orlist.getFood()));
//        org.put("activity",salesPromotionService.getById(orlist.getActivity()));
        org.put("activity", orlist.getActivity());
        org.put("mdActivity", orlist.getMdActivity());
        org.put("salesReduction", orlist.getSalesReduction());
        org.put("mdSalesReduction", orlist.getMdSalesReduction());
        org.put("salesName", orlist.getSalesName());
        org.put("mdSalesName", orlist.getMdSalesName());
        org.put("mdDiscountAmount", orlist.getMdDiscountAmount());
        org.put("discountAmount", orlist.getDiscountAmount());
        org.put("mdYhId", orlist.getMdYhId());
        org.put("mdYhName", orlist.getMdYhName());
        org.put("yhId", orlist.getYhId());
        org.put("yhName", orlist.getYhName());
        org.put("points", orlist.getPoints());
        org.put("pointsReduction", orlist.getPointsReduction());
        org.put("sdTime", orlist.getSdTime());
        org.put("payType", orlist.getPayType());
        return success(org);
    }

    /**
     * 通过订单号查询订单详情
     *
     * @param ddid
     * @return
     */
    //查询订单详情
    @Anonymous
    @Auth
    @GetMapping("/getorderxq")
    public AjaxResult getorderxq(@RequestParam String ddid) {
        QueryWrapper<PosOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dd_id", ddid);
        PosOrder orlist = posOrderService.getOne(queryWrapper);
        JSONObject org = new JSONObject();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        org.put("id", orlist.getId());
        org.put("ddId", orlist.getDdId());
        org.put("shanghu", infoUserService.getById(orlist.getShId()));
        org.put("store", posStoreService.getById(orlist.getMdId()));
        org.put("cretim", sdf.format(orlist.getCretim()));
        org.put("shdzId", orlist.getShdzId());
        org.put("shaddress", orlist.getShAddress() == null ? infoAddressService.getById(orlist.getShdzId()) : JSONObject.parseObject(orlist.getShAddress()));
        org.put("user", infoUserService.getById(orlist.getUserId()));
        org.put("amount", orlist.getAmount());
        org.put("kefuState", orlist.getKefuState());
        org.put("kefuContent", orlist.getKefuContent());
        org.put("kefuRepeat", orlist.getKefuRepeat());
        org.put("repeatDdId", orlist.getRepeatDdId());
        org.put("remarks", orlist.getRemarks());
        org.put("state", orlist.getState());
        org.put("type", orlist.getType());
        org.put("jvli", orlist.getJvli());
        org.put("freight", orlist.getFreight());
        org.put("delryTime", orlist.getDelryTime());
        org.put("longitude", orlist.getLongitude());
        org.put("latitude", orlist.getLatitude());
        org.put("qsId", orlist.getQsId());
        org.put("sqImg", orlist.getQsImg());
        org.put("discountAmount", orlist.getDiscountAmount());
        InfoUser qsUser = infoUserService.getById(orlist.getQsId());
        setQsStar(qsUser);
        org.put("qsuser", orlist.getQsId() == null ? null : qsUser);
        org.put("payUrl", orlist.getPayUrl());
        QueryWrapper<RiderPosition> query = new QueryWrapper<>();
        query.eq("rider_id", orlist.getQsId());
        org.put("RiderPosition", orlist.getQsId() == null ? null : riderPositionService.getOne(query));
        org.put("diningStatus", orlist.getDiningStatus());
        org.put("collectPayment", orlist.getCollectPayment());
        org.put("food", JSONArray.parseArray(orlist.getFood()));
//        org.put("activity",salesPromotionService.getById(orlist.getActivity()));

        org.put("activity", orlist.getActivity());
        org.put("mdActivity", orlist.getMdActivity());
        org.put("salesReduction", orlist.getSalesReduction());
        org.put("mdSalesReduction", orlist.getMdSalesReduction());
        org.put("salesName", orlist.getSalesName());
        org.put("mdSalesName", orlist.getMdSalesName());
        org.put("mdDiscountAmount", orlist.getMdDiscountAmount());
        org.put("discountAmount", orlist.getDiscountAmount());
        org.put("mdYhId", orlist.getMdYhId());
        org.put("mdYhName", orlist.getMdYhName());
        org.put("yhId", orlist.getYhId());
        org.put("yhName", orlist.getYhName());
        org.put("points", orlist.getPoints());
        org.put("pointsReduction", orlist.getPointsReduction());
        org.put("sdTime", orlist.getSdTime());
        org.put("payType", orlist.getPayType());
        Long count = posOrderRatingService.getBaseMapper().selectCount(new QueryWrapper<PosOrderRating>().eq("dd_id", ddid));
        //是否已经评论
        org.put("isCommented", count > 0);
        return success(org);
    }

    /**
     * 设置骑手星级
     *
     * @param infoUser
     */

    private void setQsStar(InfoUser infoUser) {
        if (infoUser != null) {
            QueryWrapper<PosOrderRating> wrapper = new QueryWrapper<>();
            wrapper.eq("qs_id", infoUser.getUserId()).isNotNull("qs_stars").isNotNull("qs_stars").select("ROUND(AVG(qs_stars), 1) as qs_stars");
            List<Map<String, Object>> map = posOrderRatingService.getBaseMapper().selectMaps(wrapper);
            if (!map.isEmpty() && map.get(0) != null) {
                Object rating = map.get(0).get("qs_stars");
                // 关键：显式检查null值
                if (rating != null) {
                    infoUser.setStar(Double.parseDouble(rating.toString()));
                }

            } else {
                infoUser.setStar(4.5);
            }

        }
    }

    //查询所有的订单
    @Anonymous
    @GetMapping("/getqishouorderlist")
    public AjaxResult getqishouorderlist(@RequestParam Integer page, @RequestParam BigDecimal longitude, @RequestParam BigDecimal latitude, @RequestParam Integer juli, @RequestParam(defaultValue = "") String state) {

        JSONArray arr = new JSONArray();
        List<PosOrder> orlist;
        if (!"".equals(state)) {
            if (state.equals("z02")) {
                orlist = posOrderMapper.getz02(longitude, latitude, (page - 1) * 20, juli);
            } else if (state.equals("z234")) {
                orlist = posOrderMapper.getz234(longitude, latitude, (page - 1) * 20, juli, 2, 4);
            } else if (state.equals("z23")) {
                orlist = posOrderMapper.getz234(longitude, latitude, (page - 1) * 20, juli, 2, 3);
            } else if (state.equals("z34")) {
                orlist = posOrderMapper.getz234(longitude, latitude, (page - 1) * 20, juli, 3, 4);
            } else if (state.equals("z6789")) {
                orlist = posOrderMapper.getz234(longitude, latitude, (page - 1) * 20, juli, 6, 9);
            } else {
                orlist = posOrderMapper.getstate(longitude, latitude, (page - 1) * 20, juli, state);
            }
        } else {
            orlist = posOrderMapper.getqisjvli(longitude, latitude, (page - 1) * 20, juli);
        }
        for (int i = 0; i < orlist.size(); i++) {
            JSONObject org = new JSONObject();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            org.put("id", orlist.get(i).getId());
            org.put("ddId", orlist.get(i).getDdId());
            org.put("shanghu", infoUserService.getById(orlist.get(i).getShId()));
            org.put("store", posStoreService.getById(orlist.get(i).getMdId()));
            org.put("cretim", sdf.format(orlist.get(i).getCretim()));
            org.put("shdzId", orlist.get(i).getShdzId());
            org.put("shaddress", orlist.get(i).getShAddress() == null ? infoAddressService.getById(orlist.get(i).getShdzId()) : JSONObject.parseObject(orlist.get(i).getShAddress()));
            org.put("user", infoUserService.getById(orlist.get(i).getUserId()));
            org.put("amount", orlist.get(i).getAmount());
            org.put("kefuState", orlist.get(i).getKefuState());
            org.put("kefuContent", orlist.get(i).getKefuContent());
            org.put("kefuRepeat", orlist.get(i).getKefuRepeat());
            org.put("repeatDdId", orlist.get(i).getRepeatDdId());
            org.put("remarks", orlist.get(i).getRemarks());
            org.put("state", orlist.get(i).getState());
            org.put("type", orlist.get(i).getType());
            DecimalFormat jl = new DecimalFormat("#.0");
            org.put("jvli", jl.format(orlist.get(i).getJvli()));
            org.put("qsjvli", jl.format(orlist.get(i).getJuli()));
            org.put("freight", orlist.get(i).getFreight());
            org.put("delryTime", orlist.get(i).getDelryTime());
            org.put("qsId", orlist.get(i).getQsId());
            org.put("payUrl", orlist.get(i).getPayUrl());
            org.put("diningStatus", orlist.get(i).getDiningStatus());
            org.put("food", JSONArray.parseArray(orlist.get(i).getFood()));
            org.put("collectPayment", orlist.get(i).getCollectPayment());
//            org.put("activity",salesPromotionService.getById(orlist.get(i).getActivity()));

            org.put("activity", orlist.get(i).getActivity());
            org.put("mdActivity", orlist.get(i).getMdActivity());
            org.put("salesReduction", orlist.get(i).getSalesReduction());
            org.put("mdSalesReduction", orlist.get(i).getMdSalesReduction());
            org.put("salesName", orlist.get(i).getSalesName());
            org.put("mdSalesName", orlist.get(i).getMdSalesName());
            org.put("mdDiscountAmount", orlist.get(i).getMdDiscountAmount());
            org.put("discountAmount", orlist.get(i).getDiscountAmount());
            org.put("mdYhId", orlist.get(i).getMdYhId());
            org.put("mdYhName", orlist.get(i).getMdYhName());
            org.put("yhId", orlist.get(i).getYhId());
            org.put("yhName", orlist.get(i).getYhName());
            org.put("points", orlist.get(i).getPoints());
            org.put("pointsReduction", orlist.get(i).getPointsReduction());
            org.put("sdTime", orlist.get(i).getSdTime());
            org.put("payType", orlist.get(i).getPayType());
            arr.add(org);
        }
        return success(arr);
    }

    //查询骑手的订单
    @Anonymous
    @Auth
    @GetMapping("/getqsorderlist")
    public AjaxResult getqsorderlist(@RequestHeader String token, @RequestParam Integer page, @RequestParam Integer size, @RequestParam(defaultValue = "") String state, @RequestParam(defaultValue = "0") BigDecimal longitude, @RequestParam(defaultValue = "0") BigDecimal latitude) {
        logger.info("骑手token:" + token);
        JwtUtil jwtUtil = new JwtUtil();
        String id = jwtUtil.getusid(token);
        List<PosOrder> orlist = posOrderMapper.getQsOrderList(id, longitude, latitude, (page - 1) * size, size, state);
        JSONArray arr = new JSONArray();
        for (int i = 0; i < orlist.size(); i++) {
            JSONObject org = new JSONObject();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            org.put("id", orlist.get(i).getId());
            org.put("ddId", orlist.get(i).getDdId());
            org.put("shanghu", infoUserService.getById(orlist.get(i).getShId()));
            org.put("store", posStoreService.getById(orlist.get(i).getMdId()));
            org.put("cretim", sdf.format(orlist.get(i).getCretim()));
            org.put("shdzId", orlist.get(i).getShdzId());
            org.put("shaddress", orlist.get(i).getShAddress() == null ? infoAddressService.getById(orlist.get(i).getShdzId()) : JSONObject.parseObject(orlist.get(i).getShAddress()));
            org.put("user", infoUserService.getById(orlist.get(i).getUserId()));
            org.put("qishou", infoUserService.getById(orlist.get(i).getQsId()));
            org.put("amount", orlist.get(i).getAmount());
            org.put("kefuState", orlist.get(i).getKefuState());
            org.put("kefuContent", orlist.get(i).getKefuContent());
            org.put("kefuRepeat", orlist.get(i).getKefuRepeat());
            org.put("repeatDdId", orlist.get(i).getRepeatDdId());
            org.put("remarks", orlist.get(i).getRemarks());
            org.put("state", orlist.get(i).getState());
            org.put("type", orlist.get(i).getType());
            DecimalFormat jl = new DecimalFormat("#.0");
            org.put("jvli", jl.format(orlist.get(i).getJvli()));
            org.put("qsjvli", jl.format(orlist.get(i).getJuli()));
            org.put("freight", orlist.get(i).getFreight());
            org.put("delryTime", orlist.get(i).getDelryTime());
            org.put("diningStatus", orlist.get(i).getDiningStatus());
            org.put("food", JSONArray.parseArray(orlist.get(i).getFood()));
            org.put("collectPayment", orlist.get(i).getCollectPayment());
//            org.put("activity",salesPromotionService.getById(orlist.get(i).getActivity()));
            org.put("sqImg", orlist.get(i).getQsImg());
//            org.put("discountAmount",orlist.get(i).getDiscountAmount());

            org.put("activity", orlist.get(i).getActivity());
            org.put("mdActivity", orlist.get(i).getMdActivity());
            org.put("salesReduction", orlist.get(i).getSalesReduction());
            org.put("mdSalesReduction", orlist.get(i).getMdSalesReduction());
            org.put("salesName", orlist.get(i).getSalesName());
            org.put("mdSalesName", orlist.get(i).getMdSalesName());
            org.put("mdDiscountAmount", orlist.get(i).getMdDiscountAmount());
            org.put("discountAmount", orlist.get(i).getDiscountAmount());
            org.put("mdYhId", orlist.get(i).getMdYhId());
            org.put("mdYhName", orlist.get(i).getMdYhName());
            org.put("yhId", orlist.get(i).getYhId());
            org.put("yhName", orlist.get(i).getYhName());
            org.put("points", orlist.get(i).getPoints());
            org.put("pointsReduction", orlist.get(i).getPointsReduction());
            org.put("sdTime", orlist.get(i).getSdTime());
            org.put("payType", orlist.get(i).getPayType());
            arr.add(org);
        }
        return success(arr);
    }

    //查询商家的订单
    @Anonymous
    @Auth
    @GetMapping("/getstoreorderlist")
    public AjaxResult getstoreorderlist(@RequestHeader String token, @RequestParam Integer page, @RequestParam Integer size, @RequestParam String mdId, @RequestParam(defaultValue = "") String state, @RequestParam(defaultValue = "") String diningStatus) {
        JwtUtil jwtUtil = new JwtUtil();
        String id = jwtUtil.getusid(token);
        IPage<PosOrder> palist = new Page<>(page, size);
        QueryWrapper<PosOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select().orderByDesc("cretim");
        queryWrapper.eq("sh_id", id);
        System.out.println("商户id:" + id);
        queryWrapper.eq("md_id", mdId).eq("is_display", true);
        if (!"".equals(state)) {
            if (state.equals("z01")) {
                queryWrapper.apply(" ((state = 0 AND (collect_payment = 1 OR type = 1)) OR (state = 1))");
            } else if (state.equals("z234")) {
                queryWrapper.in("state", 2, 3, 4);
            } else if (state.equals("z23")) {
                queryWrapper.in("state", 2, 3);
            } else if (state.equals("z34")) {
                queryWrapper.in("state", 3, 4);
            } else if (state.equals("z678911")) {
                queryWrapper.in("state", 6, 7, 8, 9, 11);
            } else {
                queryWrapper.eq("state", state);
            }
        }
        if (!"".equals(diningStatus)) {
            queryWrapper.eq("dining_status", diningStatus);
        }
        IPage<PosOrder> list = posOrderService.page(palist, queryWrapper);
        List<PosOrder> orlist = list.getRecords();
        JSONArray arr = new JSONArray();
        for (int i = 0; i < orlist.size(); i++) {
            JSONObject org = new JSONObject();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            org.put("id", orlist.get(i).getId());
            org.put("ddId", orlist.get(i).getDdId());
            org.put("shanghu", infoUserService.getById(orlist.get(i).getShId()));
            org.put("store", posStoreService.getById(orlist.get(i).getMdId()));
            org.put("cretim", sdf.format(orlist.get(i).getCretim()));
            org.put("shdzId", orlist.get(i).getShdzId());
            org.put("shaddress", orlist.get(i).getShAddress() == null ? infoAddressService.getById(orlist.get(i).getShdzId()) : JSONObject.parseObject(orlist.get(i).getShAddress()));
            org.put("user", infoUserService.getById(orlist.get(i).getUserId()));
            org.put("amount", orlist.get(i).getAmount());
            org.put("kefuState", orlist.get(i).getKefuState());
            org.put("kefuContent", orlist.get(i).getKefuContent());
            org.put("kefuRepeat", orlist.get(i).getKefuRepeat());
            org.put("repeatDdId", orlist.get(i).getRepeatDdId());
            org.put("remarks", orlist.get(i).getRemarks());
            org.put("state", orlist.get(i).getState());
            org.put("type", orlist.get(i).getType());
            org.put("jvli", orlist.get(i).getJvli());
            org.put("freight", orlist.get(i).getFreight());
            org.put("delryTime", orlist.get(i).getDelryTime());
            org.put("diningStatus", orlist.get(i).getDiningStatus());
            org.put("collectPayment", orlist.get(i).getCollectPayment());
            org.put("discountAmount", orlist.get(i).getDiscountAmount());
            org.put("food", JSONArray.parseArray(orlist.get(i).getFood()));
            org.put("activity", orlist.get(i).getActivity());
            org.put("mdActivity", orlist.get(i).getMdActivity());
            org.put("salesReduction", orlist.get(i).getSalesReduction());
            org.put("mdSalesReduction", orlist.get(i).getMdSalesReduction());
            org.put("salesName", orlist.get(i).getSalesName());
            org.put("mdSalesName", orlist.get(i).getMdSalesName());
            org.put("mdDiscountAmount", orlist.get(i).getMdDiscountAmount());
            org.put("discountAmount", orlist.get(i).getDiscountAmount());
            org.put("mdYhId", orlist.get(i).getMdYhId());
            org.put("mdYhName", orlist.get(i).getMdYhName());
            org.put("yhId", orlist.get(i).getYhId());
            org.put("yhName", orlist.get(i).getYhName());
            org.put("points", orlist.get(i).getPoints());
            org.put("pointsReduction", orlist.get(i).getPointsReduction());
            org.put("sdTime", orlist.get(i).getSdTime());
            org.put("payType", orlist.get(i).getPayType());
            arr.add(org);
        }
        return success(arr);
    }

    //查询用户的订单
    @Anonymous
    @Auth
    @GetMapping("/getorderlist")
    public AjaxResult getorderlist(@RequestHeader String token, @RequestParam Integer page, @RequestParam Integer size, @RequestParam(defaultValue = "") String state) {
        JwtUtil jwtUtil = new JwtUtil();
        String id = jwtUtil.getusid(token);
        IPage<PosOrder> palist = new Page<>(page, size);
        QueryWrapper<PosOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select().orderByDesc("cretim");
        queryWrapper.eq("user_id", id);
        if (!"".equals(state)) {
            if (state.equals("z23412")) {
                queryWrapper.in("state", 2, 3, 4, 12);
            } else if (state.equals("z23")) {
                queryWrapper.in("state", 2, 3);
            } else if (state.equals("z34")) {
                queryWrapper.in("state", 3, 4);
            } else if (state.equals("z678911")) {
                queryWrapper.in("state", 6, 7, 8, 9, 11);
            } else {
                queryWrapper.eq("state", state);
            }
        }
        // 添加排除条件：state=0且collect_payment=0的数据
        queryWrapper.apply("NOT (state = 0 AND collect_payment = 0)");
        IPage<PosOrder> list = posOrderService.page(palist, queryWrapper);
        List<PosOrder> orlist = list.getRecords();
        List<String> parentDdIds = orlist.stream().map(PosOrder::getParentDdId).collect(Collectors.toList());
        List<OrderParent> orderParents = new ArrayList<>();
        if (!parentDdIds.isEmpty()) {
            orderParents = orderParentService.list(new LambdaQueryWrapper<>(OrderParent.class).in(OrderParent::getDdId, parentDdIds));
        }
        JSONArray arr = new JSONArray();
        for (int i = 0; i < orlist.size(); i++) {
            JSONObject org = new JSONObject();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            org.put("id", orlist.get(i).getId());
            org.put("ddId", orlist.get(i).getDdId().toString());
            org.put("shanghu", infoUserService.getById(orlist.get(i).getShId()));
            org.put("store", posStoreService.getById(orlist.get(i).getMdId()));
            org.put("cretim", sdf.format(orlist.get(i).getCretim()));
            org.put("shdzId", orlist.get(i).getShdzId());
            org.put("shaddress", orlist.get(i).getShAddress() == null ? infoAddressService.getById(orlist.get(i).getShdzId()) : JSONObject.parseObject(orlist.get(i).getShAddress()));
            org.put("user", infoUserService.getById(orlist.get(i).getUserId()));
            org.put("amount", orlist.get(i).getAmount());
            org.put("kefuState", orlist.get(i).getKefuState());
            org.put("kefuContent", orlist.get(i).getKefuContent());
            org.put("kefuRepeat", orlist.get(i).getKefuRepeat());
            org.put("repeatDdId", orlist.get(i).getRepeatDdId());
            org.put("remarks", orlist.get(i).getRemarks());
            org.put("state", orlist.get(i).getState());
            org.put("type", orlist.get(i).getType());
            org.put("jvli", orlist.get(i).getJvli());
            org.put("freight", orlist.get(i).getFreight());
            org.put("delryTime", orlist.get(i).getDelryTime());
            org.put("payUrl", orlist.get(i).getPayUrl());
            org.put("collectPayment", orlist.get(i).getCollectPayment());
            org.put("food", JSONArray.parseArray(orlist.get(i).getFood()));
//            org.put("activity",salesPromotionService.getById(orlist.get(i).getActivity()));
            org.put("activity", orlist.get(i).getActivity());
            org.put("mdActivity", orlist.get(i).getMdActivity());
            org.put("salesReduction", orlist.get(i).getSalesReduction());
            org.put("mdSalesReduction", orlist.get(i).getMdSalesReduction());
            org.put("salesName", orlist.get(i).getSalesName());
            org.put("mdSalesName", orlist.get(i).getMdSalesName());
            org.put("mdDiscountAmount", orlist.get(i).getMdDiscountAmount());
            org.put("discountAmount", orlist.get(i).getDiscountAmount());
            org.put("mdYhId", orlist.get(i).getMdYhId());
            org.put("mdYhName", orlist.get(i).getMdYhName());
            org.put("yhId", orlist.get(i).getYhId());
            org.put("yhName", orlist.get(i).getYhName());
            org.put("points", orlist.get(i).getPoints());
            org.put("pointsReduction", orlist.get(i).getPointsReduction());
            org.put("sdTime", orlist.get(i).getSdTime());
            org.put("payType", orlist.get(i).getPayType());
            int finalI = i;
            org.put("parentRemarks", "");
            if (StringUtils.isNotEmpty(orlist.get(i).getParentDdId())) {
                orderParents.stream().filter(item -> item.getDdId().equals(orlist.get(finalI).getParentDdId())).findFirst().ifPresent(a -> org.put("parentRemarks", a.getRemarks()));
            }
            arr.add(org);
        }
        return success(arr);
    }

    //    @Anonymous
//    @GetMapping("/sssaaaa")
//    public AjaxResult sssaaaa(@RequestParam String aa,@RequestParam String bb){
//        DateUtil dateUtil = new DateUtil();
//        Boolean sbsj = dateUtil.isLegalTime(aa,bb);
//        return success(sbsj);
//    }
    //添加新订单
    @SneakyThrows
    @Anonymous
    @Auth
    @RepeatSubmit(interval = 1000, message = "请求过于频繁")
    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    @PostMapping("/addorder")
    public AjaxResult addorder(@RequestHeader String token, @RequestBody OrderDTO orderDTO) {
        long methodStart = System.currentTimeMillis(); // 记录方法开始时间
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        Integer xiadanjiaoyan = orderDTO.getXiadanjiaoyan();
        if (xiadanjiaoyan == null || !xiadanjiaoyan.equals(2)) {
            return error(MessageUtils.message("no.xiadanyz.message"));
        }

        System.out.println("========== 接收到的orderDTO ==========");
        System.out.println(mapper.writeValueAsString(orderDTO));
        JwtUtil jwtUtil = new JwtUtil();
        PayPush push = new PayPush();
        DateUtil dateUtil = new DateUtil();
        String id = jwtUtil.getusid(token);
        QueryWrapper<OperatingHours> wrapper = new QueryWrapper<>();
        wrapper.eq("md_id", orderDTO.getMdId());
        List<OperatingHours> hourslist = operatingHoursService.list(wrapper);
        PosStore store = posStoreService.getById(orderDTO.getMdId());

        JSONObject usdizhi = new JSONObject();
        if (orderDTO.getType() != null && orderDTO.getType().equals(0L)) {
            InfoAddress usadd = infoAddressService.getById(orderDTO.getShdzId());
            if (usadd == null) {
                return error(MessageUtils.message("no.address.not.exist"));
            } else {
                usdizhi.put("name", usadd.getName());
                usdizhi.put("phone", usadd.getPhone());
                usdizhi.put("address", usadd.getAddress());
                usdizhi.put("country", usadd.getCountry());
                usdizhi.put("province", usadd.getProvince());
                usdizhi.put("city", usadd.getCity());
                usdizhi.put("area", usadd.getArea());
                usdizhi.put("longitude", String.valueOf(usadd.getLongitude()));
                usdizhi.put("latitude", String.valueOf(usadd.getLatitude()));
            }
        }
        if (hourslist.size() == 0) {
            return error(MessageUtils.message("no.mendian.not.set.business.hours"));
        }
        if (store.getState() == 1) {
            return error(MessageUtils.message("no.mendian.is.closed"));
        }
        //是否在上班时间内（按星期几和是否营业过滤）
        boolean isOperating = OperatingUtil.storeIsOperatingOfDay(hourslist);
        if (!isOperating) {
            return error(MessageUtils.message("no.mendian.is.closed"));
        }
        //订单金额限制100万改为200万
        if (orderDTO.getCollectPayment().equals("1") && orderDTO.getAmount() > 2000000) {
            return error(MessageUtils.message("no.cash_on_delivery_amount.exceed.limit_amount"));
        }
        QueryWrapper<PosOrder> query = new QueryWrapper<>();
        query.eq("user_id", id);
        query.eq("collect_payment", "1");
        query.notIn("state", 5, 10, 11);
        List<PosOrder> posOrders = posOrderService.list(query);
        System.out.println("到付信息：user_id=" + id + " ,到付数量:" + posOrders.size());
        //到付能存在2单未完成，第3单弹出提示
        if (posOrders.size() >= 2 && orderDTO.getCollectPayment().equals("1")) {
            return error(MessageUtils.message("no.exist.cash_on_delivery_order.incomplete"));
        }
        JSONArray jsonArray = orderDTO.getFoodlist();
        Map<Long, Long> map = new HashMap<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            Long foodid = jsonArray.getJSONObject(i).getLong("id");
            PosFood food = posFoodService.getById(foodid);
            if (food == null) {
                return error(jsonArray.getJSONObject(i).getString("name") + MessageUtils.message("no.goods.not.exist"));
            } else {
                if (food.getStackingUp().equals("1")) {
                    return error(food.getName() + MessageUtils.message("no.goods.is.off.shelf"));
                }
            }
            Long num = jsonArray.getJSONObject(i).getLong("number");
            map.put(foodid, num);
        }
        VipUserQuanyi yh = null;
        VipUserQuanyi mdYh = null;
        if (ObjectUtil.isNotNull(orderDTO.getYhId()) && ObjectUtil.notEqual(orderDTO.getYhId(), 0L)) {
            LambdaQueryWrapper<VipUserQuanyi> yhQuery = new LambdaQueryWrapper<>();
            yhQuery.eq(VipUserQuanyi::getId, orderDTO.getYhId());
            yh = userQuanyiService.getOne(yhQuery);
            if (yh == null) {
                throw new ServiceException("no.userquanyi.not.exist");
            }
            if (yh.getState().equals("1")) {
                throw new ServiceException("userquanyi.isUsed");
            }
        }
        if (ObjectUtil.isNotNull(orderDTO.getMdYhId()) && ObjectUtil.notEqual(orderDTO.getMdYhId(), 0L)) {
            LambdaQueryWrapper<VipUserQuanyi> mdYhquery = new LambdaQueryWrapper<>();
            mdYhquery.eq(VipUserQuanyi::getId, orderDTO.getMdYhId());
            mdYh = userQuanyiService.getOne(mdYhquery);
            if (mdYh == null) {
                throw new ServiceException("no.userquanyi.not.exist");
            }
            if (mdYh.getState().equals("1")) {
                throw new ServiceException("userquanyi.isUsed");
            }
        }
        SalesPromotion activity = null;
        SalesPromotion mdActivity = null;
        if (ObjectUtil.isNotNull(orderDTO.getActivity()) && ObjectUtil.notEqual(orderDTO.getActivity(), 0L)) {
            LambdaQueryWrapper<SalesPromotion> saleQuery = new LambdaQueryWrapper<>();
            saleQuery.eq(SalesPromotion::getId, orderDTO.getActivity());
            activity = salesPromotionService.getOne(saleQuery);
            if (activity == null) {
                throw new ServiceException("no.activity.not.exist");
            }
//            if (yh.getState().equals("1")) {
//                throw new ServiceException("userquanyi.isUsed");
//            }
        }
        if (ObjectUtil.isNotNull(orderDTO.getMdActivity()) && ObjectUtil.notEqual(orderDTO.getMdActivity(), 0L)) {
            LambdaQueryWrapper<SalesPromotion> saleQuery = new LambdaQueryWrapper<>();
            saleQuery.eq(SalesPromotion::getId, orderDTO.getMdActivity());
            mdActivity = salesPromotionService.getOne(saleQuery);

            if (mdActivity == null) {
                throw new ServiceException("no.activity.not.exist");
            }

        }
        PosOrder posOrder = new PosOrder();
        AjaxResult posOrderResult = redeePoints(orderDTO, Long.valueOf(id));
        if (!posOrderResult.get("code").equals(200)) {
            return posOrderResult;
        } else {
            posOrder.setPoints(orderDTO.getPoints());
            posOrder.setPointsReduction(orderDTO.getPointsReduction());
        }
        posOrder.setDdId(orderDTO.getDdId());
        posOrder.setShId(orderDTO.getShId());
        posOrder.setMdId(orderDTO.getMdId());
        posOrder.setShdzId(orderDTO.getShdzId());
        posOrder.setShAddress(JSON.toJSONString(usdizhi));
        posOrder.setUserId(Long.valueOf(id));
        posOrder.setAmount(orderDTO.getAmount());
        posOrder.setRemarks(orderDTO.getRemarks());
        posOrder.setType(orderDTO.getType());
        posOrder.setDelryTime(orderDTO.getDelryTime());
        posOrder.setFood(jsonArray.toString());
        posOrder.setState(0L);

        posOrder.setJvli(orderDTO.getJvli());
        posOrder.setFreight(orderDTO.getFreight());
        posOrder.setLongitude(orderDTO.getLongitude());
        posOrder.setLatitude(orderDTO.getLatitude());
        posOrder.setDiningStatus(orderDTO.getDiningStatus());
        posOrder.setQsId(orderDTO.getQsId());
        posOrder.setJuli(orderDTO.getJuli());
        posOrder.setPayUrl(orderDTO.getPayUrl());
        posOrder.setCollectPayment(orderDTO.getCollectPayment());

        // posOrder.setCretim(dateUtil.getDatetim(orderDTO.getCretim()));
        //创建时间改成后端生成
        posOrder.setCretim(new Date());

        if (yh != null) {
            posOrder.setYhName(yh.getName());
            posOrder.setYhId(orderDTO.getYhId());
            posOrder.setDiscountAmount(orderDTO.getDiscountAmount());
        }

        if (mdYh != null) {
            posOrder.setMdYhId(orderDTO.getMdYhId());
            posOrder.setMdYhName(mdYh.getName());
            posOrder.setMdDiscountAmount(orderDTO.getMdDiscountAmount());
        }

        if (mdActivity != null) {
            posOrder.setMdActivity(orderDTO.getMdActivity());
            posOrder.setMdSalesName(mdActivity.getSalesName());
            posOrder.setMdSalesReduction(orderDTO.getMdSalesReduction());
        }
        if (activity != null) {
            posOrder.setActivity(orderDTO.getActivity());
            posOrder.setSalesName(activity.getSalesName());
            posOrder.setSalesReduction(orderDTO.getSalesReduction());
        }
        //设置支付类型为货到付款
        if ("1".equals(posOrder.getCollectPayment())) {
            posOrder.setPayType("1");
        }
        Boolean org = posOrderService.saveOrUpdate(posOrder);
        foodStatistics(map);
        if (org) {
            QueryWrapper<UserBilling> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", id);
            queryWrapper.eq("dd_id", posOrder.getDdId());
            UserBilling billing = userBillingService.getOne(queryWrapper);
            if (billing == null) {
                UserBilling usb = new UserBilling();
                usb.setUserId(Long.valueOf(id));
                usb.setDdId(String.valueOf(posOrder.getDdId()));
                usb.setMdId(posOrder.getMdId());
                usb.setState("3");
                usb.setType("3");
                userBillingService.saveOrUpdate(usb);
            }
            QueryWrapper<UserFootprint> Wrapper = new QueryWrapper<>();
            Wrapper.eq("user_id", id);
            Wrapper.eq("md_id", posOrder.getMdId());
            UserFootprint foot = userFootprintService.getOne(Wrapper);
            DateUtil dateString = new DateUtil();
            if (foot == null) {
                UserFootprint usf = new UserFootprint();
                usf.setUserId(Long.valueOf(id));
                usf.setMdId(posOrder.getMdId());
                usf.setCretim(dateString.GetDate());
                userFootprintService.saveOrUpdate(usf);
            } else {
                foot.setCretim(dateString.GetDate());
                userFootprintService.saveOrUpdate(foot);
            }
            QueryWrapper<PosOrder> querywra = new QueryWrapper<>();
            querywra.eq("dd_id", posOrder.getDdId());
            PosOrder order = posOrderService.getOne(querywra);
            //货到付款、类型外卖，推送给骑手有新订单了
            if (order.getCollectPayment().equals("1") && order.getType() == 0) {
                sendHdfkMessage(order, push);
            }

            //存在使用优惠券的话，核销优惠券
            redeemCoupons(yh, mdYh, order.getDdId());
            System.out.println("========== 输出的order ==========");
            System.out.println(mapper.writeValueAsString(order));
            long methodEnd = System.currentTimeMillis(); // 方法结束时间
            System.out.println("addorder 方法总执行耗时: " + (methodEnd - methodStart) + " ms");
            return success(MessageUtils.message("no.order.submit.success"), order);
        } else {
            long methodEnd = System.currentTimeMillis(); // 方法结束时间
            System.out.println("addorder 方法总执行耗时: " + (methodEnd - methodStart) + " ms");
            return error();
        }
    }

    //统计美食销售量
    private void foodStatistics(Map<Long, Long> map) {
        for (Map.Entry<Long, Long> entry : map.entrySet()) {
            Long key = entry.getKey();
            Long value = entry.getValue();
            // 使用数据库原子UPSERT，避免并发下的竞态问题
            foodStatisticsService.increaseNumber(key, value);
        }
    }

    /**
     * 货到付款发送推送
     *
     * @param order
     * @param push
     */
    private void sendHdfkMessage(PosOrder order, PayPush push) {
        InfoUser sh = infoUserService.getById(order.getShId());
        push.shpush(sh.getCid(), MessageUtils.message("no.message.push.message"), MessageUtils.message("no.message.push.new.order"), OrderPushBodyDto.getJson(String.valueOf(order.getDdId()), String.valueOf(order.getState()), 0));
        pushEventService.PublisherEvent(sh.getUserId(), MessageUtils.message("no.message.push.message"), MessageUtils.message("no.message.push.new.order"), OrderPushBodyDto.getJson(String.valueOf(order.getDdId()), String.valueOf(order.getState()), 0));
        long sendQsPushStart = System.currentTimeMillis(); // sendQsPush 开始时间
        if (order.getType() == 0) {
            sendQsPush(order, push);
        }
        long sendQsPushEnd = System.currentTimeMillis(); // sendQsPush 结束时间
        System.out.println("sendQsPush 执行耗时: " + (sendQsPushEnd - sendQsPushStart) + " ms");
    }

    /**
     * 推送可接单骑手
     *
     * @param order
     * @param push
     */
    protected void sendQsPush(PosOrder order, PayPush push) {
        payController.sendAcceptRiderPush(order, push, riderPositionMapper, OrderPushBodyDto.getJson(String.valueOf(order.getDdId()), String.valueOf(order.getState()), 0));
    }

    //核销积分
    private AjaxResult redeePoints(OrderDTO orderDTO, Long userId) {
        if (ObjectUtil.isNotNull(orderDTO.getPoints()) && ObjectUtil.notEqual(orderDTO.getPoints(), 0) && ObjectUtil.isNotNull(orderDTO.getPointsReduction()) && ObjectUtil.notEqual(orderDTO.getPointsReduction(), 0)) {
            SysPointControl control = pointControlService.getById(1L);
            if (!control.getOrderUseEnable().equals(1L)) {
                throw new ServiceException(MessageUtils.message("no.points.use.enable"));
            }
            LambdaQueryWrapper<UserWallet> walletQuery = new LambdaQueryWrapper<>();
            walletQuery.eq(UserWallet::getUserId, userId);
            walletQuery.isNull(UserWallet::getStoreId);
            UserWallet userWallet = userWalletService.getOne(walletQuery);
            if (ObjectUtil.isNotNull(userWallet)) {
                if (userWallet.getPointsWallet().compareTo(Long.valueOf(orderDTO.getPoints())) >= 0) {
                    walletQuery.eq(UserWallet::getVersion, userWallet.getVersion());
                    userWallet.setPointsWallet(userWallet.getPointsWallet() - orderDTO.getPoints());
                    userWallet.setVersion(userWallet.getVersion() + 1);
                    boolean update = userWalletService.update(userWallet, walletQuery);
                    createPointTransaction(userId, Long.valueOf(orderDTO.getPoints()), userWallet.getPointsWallet(), orderDTO.getDdId().toString(), "1");
                    if (!update) {
                        throw new ServiceException(MessageUtils.message("no.points.update.fail"));
                    }
                } else {
                    throw new ServiceException(MessageUtils.message("no.points.insufficient"));
                }
            } else {
                throw new ServiceException(MessageUtils.message("no.points.not.exist"));
            }
        }
        return success();
    }

    /**
     * 创建积分流水
     */
    private void createPointTransaction(Long userid, Long pointsChange, Long currentPoints, String ddId, String type) {
        PointsTransaction pointsTransaction = new PointsTransaction();
        pointsTransaction.setUserId(userid);
        if (type.equals("1")) {
            pointsTransaction.setPointsChange("-" + pointsChange);
            pointsTransaction.setType("1");
        }
        if (type.equals("2")) {
            pointsTransaction.setPointsChange("+" + pointsChange);
            pointsTransaction.setType("2");
        }
        pointsTransaction.setCurrentPoints(currentPoints.toString());
        pointsTransaction.setDdId(ddId);
        pointsTransaction.setCreateTime(new Date());
        pointsTransactionService.save(pointsTransaction);
    }


    /**
     * 核销优惠券
     *
     * @param orderId
     */
    private void redeemCoupons(VipUserQuanyi yh, VipUserQuanyi mdYh, Long orderId) {
        if (ObjectUtil.isNotNull(yh)) {
            yh.setState("1");
            yh.setOrderId(String.valueOf(orderId));
            yh.setUpdateTime(new Date());
            userQuanyiService.saveOrUpdate(yh);
        }
        if (ObjectUtil.isNotNull(mdYh)) {
            mdYh.setState("1");
            mdYh.setOrderId(String.valueOf(orderId));
            mdYh.setUpdateTime(new Date());
            userQuanyiService.saveOrUpdate(mdYh);
        }
    }


    /**
     * 核销优惠券
     *
     * @param orderId
     */
    private void redeemCoupons(VipUserQuanyi yh, VipUserQuanyi mdYh, String orderId) {
        if (ObjectUtil.isNotNull(yh)) {
            yh.setState("1");
            yh.setOrderId(orderId);
            yh.setUpdateTime(new Date());
            userQuanyiService.saveOrUpdate(yh);
        }
        if (ObjectUtil.isNotNull(mdYh)) {
            mdYh.setState("1");
            mdYh.setOrderId(orderId);
            mdYh.setUpdateTime(new Date());
            userQuanyiService.saveOrUpdate(mdYh);
        }
    }

    /**
     * 查询posorder列表
     */
    @PreAuthorize("@ss.hasPermi('system:order:list')")
    @GetMapping("/list")
    public TableDataInfo list(PosOrder posOrder) {
        startPage();
        String[] dr = posOrder.getDateRange();
        if (dr != null && dr.length == 2) {
            posOrder.setCretimStart(dr[0]);
            posOrder.setCretimEnd(dr[1]);
        }
        List<PosOrder> list = posOrderService.selectPosOrderList(posOrder);
        if (list != null && list.size() > 0) {
            for (PosOrder od : list) {
                JSONArray foodArr = JSONArray.parseArray(od.getFood());
                long priceAll = 0L;
                for (int i = 0; i < foodArr.size(); i++) {
                    JSONObject obj = foodArr.getJSONObject(i);
                    BigDecimal price = obj.getBigDecimal("price");
                    if (price == null) continue;
                    Integer priceDb = price.intValue();
                    BigDecimal otherprice = obj.getBigDecimal("otherPrice");
                    if (otherprice != null && otherprice.doubleValue() > 0) {
                        priceDb += otherprice.intValue();
                    }
                    Long num = obj.getLong("number");
                    if (num == null) continue;
                    priceAll += (priceDb * num.longValue());
                }
                od.setPriceAll(priceAll + "");
                Long atv = od.getActivity();
                if (atv != null && atv.longValue() > 0) {
                    SalesPromotion salesPromotion = salesPromotionService.getById(atv);
                    if (salesPromotion != null) {
                        od.setSalesName(salesPromotion.getSalesName());
//                        od.setSalesReduction(""+salesPromotion.getSalesReduction());
                    }
                }
            }
        }
        return getDataTable(list);
    }

    /**
     * 查询sh posorder列表
     */
    @PreAuthorize("@ss.hasPermi('system:order:shlist1')")
    @GetMapping("/shlist1")
    public TableDataInfo shlist1(PosOrder posOrder) {
        startPage();
        String[] dr = posOrder.getDateRange();
        if (dr != null && dr.length == 2) {
            posOrder.setCretimStart(dr[0]);
            posOrder.setCretimEnd(dr[1]);
        }
        List<PosOrder> list = posOrderService.selectPosOrderShList(posOrder);
        if (list != null && list.size() > 0) {
            for (PosOrder od : list) {
                //查询用户留言
                PosAppeal posAppeal = new PosAppeal();
                posAppeal.setDdId(od.getDdId());
                posAppeal.setUserType("0");
                List<PosAppeal> aplist = posAppealService.selectPosAppealList(posAppeal);
                int s = 0;
                if (aplist != null) s = aplist.size();
                od.setAppealCount(s + "");
            }
        }
        return getDataTable(list);
    }

    /**
     * 查询sh posorder列表
     */
    @PreAuthorize("@ss.hasPermi('system:order:shlist2')")
    @GetMapping("/shlist2")
    public TableDataInfo shlist2(PosOrder posOrder) {
        startPage();
        String[] dr = posOrder.getDateRange();
        if (dr != null && dr.length == 2) {
            posOrder.setCretimStart(dr[0]);
            posOrder.setCretimEnd(dr[1]);
        }
        List<PosOrder> list = posOrderService.selectPosOrderShList(posOrder);
        if (list != null && list.size() > 0) {
            for (PosOrder od : list) {
                //查询用户留言
                PosAppeal posAppeal = new PosAppeal();
                posAppeal.setDdId(od.getDdId());
                posAppeal.setUserType("1");
                List<PosAppeal> aplist = posAppealService.selectPosAppealList(posAppeal);
                int s = 0;
                if (aplist != null) s = aplist.size();
                od.setAppealCount(s + "");
            }
        }
        return getDataTable(list);
    }

    /**
     * 查询sh posorder列表
     */
    @PreAuthorize("@ss.hasPermi('system:order:shlist3')")
    @GetMapping("/shlist3")
    public TableDataInfo shlist3(PosOrder posOrder) {
        startPage();
        String[] dr = posOrder.getDateRange();
        if (dr != null && dr.length == 2) {
            posOrder.setCretimStart(dr[0]);
            posOrder.setCretimEnd(dr[1]);
        }
        List<PosOrder> list = posOrderService.selectPosOrderShList(posOrder);
        if (list != null && list.size() > 0) {
            for (PosOrder od : list) {
                //查询用户留言
                PosAppeal posAppeal = new PosAppeal();
                posAppeal.setDdId(od.getDdId());
                posAppeal.setUserType("2");
                List<PosAppeal> aplist = posAppealService.selectPosAppealList(posAppeal);
                int s = 0;
                if (aplist != null) s = aplist.size();
                od.setAppealCount(s + "");
            }
        }
        return getDataTable(list);
    }

    /**
     * 导出posorder列表
     */
    @PreAuthorize("@ss.hasPermi('system:order:export')")
    @Log(title = "posorder", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, PosOrder posOrder) {
        List<PosOrder> list = posOrderService.selectPosOrderList(posOrder);
        if (list != null && list.size() > 0) {
            for (PosOrder od : list) {
                JSONArray foodArr = JSONArray.parseArray(od.getFood());
                long priceAll = 0L;
                for (int i = 0; i < foodArr.size(); i++) {
                    JSONObject obj = foodArr.getJSONObject(i);
                    BigDecimal price = obj.getBigDecimal("price");
                    if (price == null) continue;
                    Integer priceDb = price.intValue();
                    //商品规格价格
                    BigDecimal otherprice = obj.getBigDecimal("otherPrice");
                    if (otherprice != null && otherprice.doubleValue() > 0) {
                        priceDb += otherprice.intValue();
                    }
                    Long num = obj.getLong("number");
                    if (num == null) continue;
                    priceAll += (priceDb * num.longValue());
                }
                od.setPriceAll(priceAll + "");
                Long atv = od.getActivity();
                if (atv != null && atv.longValue() > 0) {
                    SalesPromotion salesPromotion = salesPromotionService.getById(atv);
                    if (salesPromotion != null) {
                        od.setSalesName(salesPromotion.getSalesName());
//                        od.setSalesReduction(""+salesPromotion.getSalesReduction());
                    }
                }
            }
        }
        ExcelUtil<PosOrder> util = new ExcelUtil<PosOrder>(PosOrder.class);
        util.exportExcel(response, list, MessageUtils.message("no.export.excel.posorder"));
    }

    /**
     * 获取posorder详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:order:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(posOrderService.selectPosOrderById(id));
    }

    /**
     * 新增posorder
     */
    @PreAuthorize("@ss.hasPermi('system:order:add')")
    @Log(title = "posorder", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody PosOrder posOrder) {
        return toAjax(posOrderService.insertPosOrder(posOrder));
    }

    /**
     * 修改posorder
     */
    @Transactional(rollbackFor = Exception.class)
    @PreAuthorize("@ss.hasPermi('system:order:edit')")
    @Log(title = "posorder", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody PosOrder posOrder) {
        //送达时间
        if (posOrder.getState() == 12) {
            posOrder.setSdTime(new Date());
        }
        if (posOrder.getState() == 7) {
            QueryWrapper<UserBilling> wrapper = new QueryWrapper<>();
            wrapper.eq("dd_id", posOrder.getId());
            List<UserBilling> billing = userBillingService.list(wrapper);
            for (int i = 0; i < billing.size(); i++) {
                UserBilling user = new UserBilling();
                user.setId(billing.get(i).getId());
                user.setState("1");
                userBillingService.saveOrUpdate(user);
            }
            //退款、作废退回积分
            if ((posOrder.getState() == 7 || posOrder.getState() == 11) && posOrder.getPoints() != null && posOrder.getPoints() > 0) {
                returnPoints(posOrder.getUserId(), Long.valueOf(posOrder.getDdId()), Long.valueOf(posOrder.getPoints()));
            }
            return toAjax(posOrderService.updatePosOrder(posOrder));
        } else {
            if (posOrder.getKefuState().intValue() == 1) {
                posOrder.setState(5L);
            }
            return toAjax(posOrderService.updatePosOrder(posOrder));
        }
    }


    /**
     * 订单取消、退款成功返回积分
     *
     * @param userId
     * @param ddId
     * @param points
     */
    public void returnPoints(Long userId, Long ddId, Long points) {
        LambdaQueryWrapper<UserWallet> walletQuery = new LambdaQueryWrapper<>();
        walletQuery.eq(UserWallet::getUserId, userId);
        walletQuery.isNull(UserWallet::getStoreId);
        UserWallet userWallet = userWalletService.getOne(walletQuery);
        PointsTransaction transaction = pointsTransactionService.getOne(new LambdaQueryWrapper<PointsTransaction>().eq(PointsTransaction::getDdId, ddId.toString()).eq(PointsTransaction::getType, "2"));
        //该订单不存在退回的积分记录
        if (ObjectUtil.isNotNull(userWallet) && transaction == null) {
            walletQuery.eq(UserWallet::getVersion, userWallet.getVersion());
            userWallet.setPointsWallet(userWallet.getPointsWallet() + points);
            userWallet.setVersion(userWallet.getVersion() + 1);
            boolean update = userWalletService.update(userWallet, walletQuery);
            createPointTransaction(userId, Long.valueOf(points), userWallet.getPointsWallet(), ddId.toString(), "2");
            if (!update) {
                throw new ServiceException(MessageUtils.message("no.points.update.fail"));
            }
        } else {
            throw new ServiceException(MessageUtils.message("no.points.insufficient"));
        }
    }


    /**
     * 删除posorder
     */
    @PreAuthorize("@ss.hasPermi('system:order:remove')")
    @Log(title = "posorder", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(posOrderService.deletePosOrderByIds(ids));
    }

    /**
     * 测试推送消息
     *
     * @param cid
     * @return
     */

    @Anonymous
    @RequestMapping(value = "/testPushMessage", method = {RequestMethod.GET})
    public AjaxResult testPushMessage(String cid, String title, String content, String body) {
        PayPush push = new PayPush();
        push.qspush(cid, title, content, body);
        return AjaxResult.success();
    }


    /**
     * 获取配送中的订单位置信息
     */
    @Anonymous
    @Auth
    @GetMapping("/getPsOrdersPosition")
    public AjaxResult getPsOrdersPosition(@RequestHeader String token) {
        JwtUtil jwtUtil = new JwtUtil();
        String id = jwtUtil.getusid(token);
        List<OrderPositionInfo> result = new ArrayList<>();
        QueryWrapper<PosOrder> wrapper = new QueryWrapper<>();

        wrapper.eq("user_id", id).apply("(pay_type!=1 and (state = 1 or state = 2 or state = 3 or state = 4) or (pay_type=1 and (state = 0 or state = 1 or state = 2 or state = 3 or state = 4)))").orderByDesc("cretim");
        List<PosOrder> list = posOrderService.list(wrapper);
        if (!list.isEmpty()) {
            List<Long> qsIds = list.stream().map(PosOrder::getQsId).collect(Collectors.toList());
            List<InfoUser> users = new ArrayList<>();
            if (!qsIds.isEmpty()) {
                LambdaQueryWrapper<InfoUser> userWrapper = new LambdaQueryWrapper<>();
                userWrapper.in(InfoUser::getUserId, qsIds);
                users = infoUserService.list(userWrapper);
            }
            List<Long> mdIds = list.stream().map(PosOrder::getMdId).collect(Collectors.toList());
            LambdaQueryWrapper<PosStore> mdWrapper = new LambdaQueryWrapper<PosStore>().in(PosStore::getId, mdIds);
            List<PosStore> stores = posStoreService.list(mdWrapper);
            List<RiderPosition> riderPositions = new ArrayList<>();
            if (!qsIds.isEmpty()) {
                riderPositions = riderPositionService.list(new LambdaQueryWrapper<RiderPosition>().in(RiderPosition::getRiderId, qsIds));
            }
            for (PosOrder posOrder : list) {
                OrderPositionInfo orderPositionInfo = new OrderPositionInfo();
                orderPositionInfo.setDdId(posOrder.getDdId());
                orderPositionInfo.setOrderState(posOrder.getState());
                orderPositionInfo.setDelryTime(posOrder.getDelryTime());
                orderPositionInfo.setYjsdTime(posOrder.getYjsdTime());
                orderPositionInfo.setDiningStatus(posOrder.getDiningStatus());
                orderPositionInfo.setPayType(posOrder.getPayType());

                if (posOrder.getQsId() != null) {
                    QsDto qsDto = new QsDto();
                    users.stream().filter(infoUser -> infoUser.getUserId().equals(posOrder.getQsId())).findFirst().ifPresent(user -> {
                        qsDto.setUserName(user.getUserName());
                        qsDto.setNickName(user.getNickName());
                    });
                    qsDto.setDelryTime(posOrder.getDelryTime());
                    orderPositionInfo.setQsInfo(qsDto);

                    PositionDto qsPosition = new PositionDto();
                    riderPositions.stream().filter(riderPosition -> riderPosition.getRiderId().equals(posOrder.getQsId())).findFirst().ifPresent(rPosition -> {
                        qsPosition.setLat(rPosition.getLatitude().toString());
                        qsPosition.setLng(rPosition.getLongitude().toString());
                    });
                    orderPositionInfo.setQsPosition(qsPosition);
                }
                PositionDto mdPosition = new PositionDto();
                stores.stream().filter(posStore -> posStore.getId().equals(Integer.valueOf(posOrder.getMdId().toString()))).findFirst().ifPresent(p -> {
                    mdPosition.setLat(p.getLatitude().toString());
                    mdPosition.setLng(p.getLongitude().toString());
                });
                orderPositionInfo.setMdPosition(mdPosition);

                Map map = JSON.parseObject(posOrder.getShAddress(), Map.class);
                PositionDto userPosition = new PositionDto();
                userPosition.setLat(map.get("latitude").toString());
                userPosition.setLng(map.get("longitude").toString());
                orderPositionInfo.setUserPosition(userPosition);

                result.add(orderPositionInfo);
            }
        }

        return AjaxResult.success(result);
    }


}
