package com.ruoyi.app.order; import cn.hutool.core.util.ObjectUtil; 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.order.dto.AdminOrderActionRequest; import com.ruoyi.app.order.dto.AdminOrderStatusContext; import com.ruoyi.app.pay.LinePayService; import com.ruoyi.app.pay.LinePayRefundService; import com.ruoyi.app.order.dto.AdminOrderStatusUpdateRequest; 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.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.exception.ServiceException; 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.domain.vo.PosOrderInvoiceVo; import com.ruoyi.system.mapper.PosFoodMapper; import com.ruoyi.system.mapper.PosOrderMapper; import com.ruoyi.system.mapper.PosOrderPromotionMapper; import com.ruoyi.system.mapper.UserBillingMapper; import com.ruoyi.system.omgpay.domain.OmgPaymentAttempt; import com.ruoyi.system.omgpay.service.IOmgPaymentAttemptService; import com.ruoyi.system.service.*; import com.ruoyi.system.utils.Auth; import com.ruoyi.system.utils.GetArea; import com.ruoyi.system.utils.JwtUtil; import com.ruoyi.system.utils.OrderLogHelper; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.core.domain.entity.SysUser; import lombok.SneakyThrows; 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 jakarta.validation.Valid; import java.math.BigDecimal; import java.text.DecimalFormat; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; /** * 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 IPointsTransactionService pointsTransactionService; @Autowired private PushEventService pushEventService; @Autowired private DeliveryOrderNotificationService deliveryOrderNotificationService; @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; @Autowired private OrderService orderService; @Autowired private PosOrderShOprateController shOprateController; @Autowired private OrderLogHelper orderLogHelper; @Autowired private PosOrderPromotionMapper posOrderPromotionMapper; @Autowired private OrderInvoiceService orderInvoiceService; @Autowired private OrderLifecycleService orderLifecycleService; @Autowired private LinePayService linePayService; @Autowired private LinePayRefundService linePayRefundService; @Autowired private com.ruoyi.app.pay.LinePayOrderGuard linePayOrderGuard; @Autowired private IPosOrderLinePaymentService linePaymentService; @Autowired private IOmgPaymentAttemptService omgPaymentAttemptService; //查询用户足迹 @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 palist = new Page<>(page, size); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.select().orderByDesc("cretim"); queryWrapper.eq("user_id", id); IPage list = userFootprintService.page(palist, queryWrapper); List footprints = list.getRecords(); // 收集所有门店ID(Integer类型) List storeIds = footprints.stream() .map(UserFootprint::getMdId) .toList(); // 使用MyBatis Plus一次性查询所有门店的商品(避免N+1查询问题) Map> foodMap = new java.util.HashMap<>(); if (!storeIds.isEmpty()) { // 将Integer类型的门店ID转换为Long类型用于查询(因为mdid是Long类型) List storeIdsLong = storeIds.stream() .map(x -> x) .collect(Collectors.toList()); // 使用MyBatis Plus的Mapper方法,在数据库查询时就限制每个门店只返回6条商品 List allFoods = posFoodMapper.selectFoodsByStoreIdsWithLimit(storeIdsLong, "3", 6); // 按门店ID分组(查询结果已经限制为每个门店最多6条) foodMap = allFoods.stream() .collect(Collectors.groupingBy(food -> food.getMdid().intValue())); } // 转换为StoreOutput并设置每个门店的商品列表(每个门店最多6条) List 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 foodList = foodMap.getOrDefault(store.getId(), new ArrayList<>()); storeOutput.setFoodList(foodList); storeOutputList.add(storeOutput); } } Page 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); PosOrder persisted = posOrder.getId() == null ? null : posOrderService.getById(posOrder.getId()); boolean actualLineOrder = persisted != null && linePaymentService != null && !linePaymentService.getByDdId(String.valueOf(persisted.getDdId())).isEmpty(); if (actualLineOrder) { throw new ServiceException(lineMessage("line.pay.legacy.endpoint.disabled", "LINE Pay order must use the dedicated order operation endpoint")); } if (posOrder.getState() != null) { if (posOrder.getId() != null && posOrder.getState() != 0L) { linePayOrderGuard.requirePaidBeforeAccept(persisted); } //状态为送达,设置送达时间 if (posOrder.getState() == 12) { posOrder.setSdTime(new Date()); } System.out.println("修改订单状态信息:" + JSON.toJSONString(posOrder)); //设置支付类型为货到付款 if (!actualLineOrder && 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); } //作废退回积分 if (posOrder.getState() == 10 && order.getPoints() != null && order.getPoints() > 0) { returnPoints(order.getUserId(), Long.valueOf(order.getDdId()), Long.valueOf(order.getPoints())); } if (org) { // 平台管理员修改订单状态,添加操作日志 SysUser adminUser = SecurityUtils.getLoginUser().getUser(); String adminName = adminUser != null ? adminUser.getNickName() : ""; PosOrder beforeOrder = posOrderService.getById(posOrder.getId()); String logDdId = beforeOrder != null ? String.valueOf(beforeOrder.getDdId()) : ""; orderLogHelper.log(logDdId, 1, adminUser != null ? adminUser.getUserId() : null, adminName, "平台管理员" + adminName + "修改订单状态: " + (posOrder.getState() != null ? posOrder.getState() : "")); 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 wrapper = new QueryWrapper<>(); wrapper.eq("qs_id", qsId); wrapper.in("state", 3, 4); List 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) { // 平台管理员修改订单状态(骑手操作),添加操作日志 SysUser adminUser = SecurityUtils.getLoginUser().getUser(); String adminName = adminUser != null ? adminUser.getNickName() : ""; PosOrder beforeOrder = posOrderService.getById(posOrder.getId()); String logDdId = beforeOrder != null ? String.valueOf(beforeOrder.getDdId()) : ""; orderLogHelper.log(logDdId, 1, adminUser != null ? adminUser.getUserId() : null, adminName, "平台管理员" + adminName + "修改订单状态: " + (posOrder.getState() != null ? posOrder.getState() : "")); //到付订单,设置用户账单为完成 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 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()); // 平台管理员修改订单状态(商家接单),添加操作日志 SysUser adminUser = SecurityUtils.getLoginUser().getUser(); String adminName = adminUser != null ? adminUser.getNickName() : ""; PosOrder beforeOrder = posOrderService.getById(posOrder.getId()); String logDdId = beforeOrder != null ? String.valueOf(beforeOrder.getDdId()) : ""; orderLogHelper.log(logDdId, 1, adminUser != null ? adminUser.getUserId() : null, adminName, "平台管理员" + adminName + "修改订单状态: " + (posOrder.getState() != null ? posOrder.getState() : "")); 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()); // 平台管理员修改订单状态(商家接单),添加操作日志 SysUser adminUser = SecurityUtils.getLoginUser().getUser(); String adminName = adminUser != null ? adminUser.getNickName() : ""; PosOrder beforeOrder = posOrderService.getById(posOrder.getId()); String logDdId = beforeOrder != null ? String.valueOf(beforeOrder.getDdId()) : ""; orderLogHelper.log(logDdId, 1, adminUser != null ? adminUser.getUserId() : null, adminName, "平台管理员" + adminName + "修改订单状态: " + (posOrder.getState() != null ? posOrder.getState() : "")); 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()); // 平台管理员修改订单状态(订单完成),添加操作日志 SysUser adminUser = SecurityUtils.getLoginUser().getUser(); String adminName = adminUser != null ? adminUser.getNickName() : ""; PosOrder beforeOrder = posOrderService.getById(posOrder.getId()); String logDdId = beforeOrder != null ? String.valueOf(beforeOrder.getDdId()) : ""; orderLogHelper.log(logDdId, 1, adminUser != null ? adminUser.getUserId() : null, adminName, "平台管理员" + adminName + "修改订单状态: " + (posOrder.getState() != null ? posOrder.getState() : "")); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("dd_id", order.getDdId()); UserBilling billing = userBillingService.getOne(wrapper); if (billing == null) { orderService.setSanghuBilling(order); orderService.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()); // 平台管理员修改订单状态(同意退款),添加操作日志 SysUser adminUser = SecurityUtils.getLoginUser().getUser(); String adminName = adminUser != null ? adminUser.getNickName() : ""; PosOrder beforeOrder = posOrderService.getById(posOrder.getId()); String logDdId = beforeOrder != null ? String.valueOf(beforeOrder.getDdId()) : ""; orderLogHelper.log(logDdId, 1, adminUser != null ? adminUser.getUserId() : null, adminName, "平台管理员" + adminName + "修改订单状态: " + (posOrder.getState() != null ? posOrder.getState() : "")); if (order.getPoints() != null && order.getPoints() > 0) { returnPoints(order.getUserId(), Long.valueOf(order.getDdId()), Long.valueOf(order.getPoints())); } if (org) { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("dd_id", posOrder.getId()); List 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 query = new QueryWrapper<>(); query.eq("user_id", id); query.eq("collect_payment", "1"); query.notIn("state", 5, 10, 11); List 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) { shOprateController.chuCan(ordera, posOrder); PosOrder order = posOrderService.getById(posOrder.getId()); // 平台管理员修改订单状态(无状态变更),添加操作日志 SysUser adminUser = SecurityUtils.getLoginUser().getUser(); String adminName = adminUser != null ? adminUser.getNickName() : ""; PosOrder beforeOrder = posOrderService.getById(posOrder.getId()); String logDdId = beforeOrder != null ? String.valueOf(beforeOrder.getDdId()) : ""; orderLogHelper.log(logDdId, 1, adminUser != null ? adminUser.getUserId() : null, adminName, "平台管理员" + adminName + "修改订单状态: " + (posOrder.getState() != null ? posOrder.getState() : "")); return success(MessageUtils.message("no.modify.success"), posOrder.getId()); } else { return error(); } } /** * 获取预计送达时间 * * @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); } //后台查询详情 @GetMapping("/getorderhout") public AjaxResult getorderhout(@RequestParam String id) { PosOrder orlist = posOrderService.getById(id); // 自动序列化所有PosOrder字段,新增字段无需手动添加 JSONObject org = JSON.parseObject( JSON.toJSONStringWithDateFormat(orlist, "yyyy-MM-dd HH:mm:ss") ); // 以下为非PosOrder字段或需要特殊处理的字段 org.put("shanghu", infoUserService.getById(orlist.getShId())); org.put("store", posStoreService.getById(orlist.getMdId())); org.put("shaddress", orlist.getShAddress() == null ? infoAddressService.getById(orlist.getShdzId()) : JSONObject.parseObject(orlist.getShAddress())); org.put("user", infoUserService.getById(orlist.getUserId())); org.put("qsuser", infoUserService.getById(orlist.getQsId())); QueryWrapper query = new QueryWrapper<>(); query.eq("rider_id", orlist.getQsId()); org.put("RiderPosition", orlist.getQsId() == null ? null : riderPositionService.getOne(query)); org.put("food", JSONArray.parseArray(orlist.getFood())); // 已支付订单附带支付商交易单号,供平台到支付商后台按单号查询交易详情 org.put("payTrade", buildPayTrade(orlist)); return success(org); } /** * 已支付订单的支付商交易单号信息,供平台在支付商后台按单号查询交易详情。 * OMG 返回 MerchantTradeNo(支付商侧查询键)与网关 TradeNo; * LINE Pay 返回 lineOrderId 与 transactionId;其他渠道(到付等)返回 null。 */ private JSONObject buildPayTrade(PosOrder order) { // 已退款订单同样需要单号到支付商侧核对退款,因此仅排除未支付 if (order.getPayStatus() == null || order.getPayStatus() == 0L) { return null; } JSONObject trade = new JSONObject(); if (OrderLifecycleService.PAY_TYPE_OMG.equals(order.getPayType())) { OmgPaymentAttempt attempt = omgPaymentAttemptService.selectPaidByDdId(order.getDdId()); if (attempt == null) { return null; } trade.put("channel", "OMG"); trade.put("merchantTradeNo", attempt.getMerchantTradeNo()); trade.put("gatewayTradeNo", attempt.getTradeNo()); } else if (LinePayService.PAY_TYPE_LINE.equals(order.getPayType())) { PosOrderLinePayment paid = linePaymentService.getByDdId(order.getDdId()).stream() .filter(payment -> "PAID".equals(payment.getStatus())) .max(Comparator.comparing(PosOrderLinePayment::getId)) .orElse(null); if (paid == null) { return null; } trade.put("channel", "LINE Pay"); trade.put("lineOrderId", paid.getLineOrderId()); trade.put("transactionId", paid.getTransactionId()); } else { return null; } return trade; } /** * 通过订单号查询订单详情 * * @param ddid * @return */ //查询订单详情 @Anonymous @Auth @GetMapping("/getorderxq") public AjaxResult getorderxq(@RequestParam String ddid) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("dd_id", ddid); PosOrder orlist = posOrderService.getOne(queryWrapper); // 自动序列化所有PosOrder字段,新增字段无需手动添加 JSONObject org = JSON.parseObject( JSON.toJSONStringWithDateFormat(orlist, "yyyy-MM-dd HH:mm:ss") ); // 以下为非PosOrder字段或需要特殊处理的字段 org.put("shanghu", infoUserService.getById(orlist.getShId())); org.put("store", posStoreService.getById(orlist.getMdId())); org.put("shaddress", orlist.getShAddress() == null ? infoAddressService.getById(orlist.getShdzId()) : JSONObject.parseObject(orlist.getShAddress())); org.put("user", infoUserService.getById(orlist.getUserId())); InfoUser qsUser = infoUserService.getById(orlist.getQsId()); setQsStar(qsUser); org.put("qsuser", orlist.getQsId() == null ? null : qsUser); QueryWrapper query = new QueryWrapper<>(); query.eq("rider_id", orlist.getQsId()); org.put("RiderPosition", orlist.getQsId() == null ? null : riderPositionService.getOne(query)); org.put("food", JSONArray.parseArray(orlist.getFood())); Long count = posOrderRatingService.getBaseMapper().selectCount(new QueryWrapper().eq("dd_id", ddid)); org.put("isCommented", count > 0); // 查询促销快照明细 List promotions = posOrderPromotionMapper.selectByOrderId(orlist.getId()); org.put("promotions", promotions); return success(org); } /** * 设置骑手星级 * * @param infoUser */ private void setQsStar(InfoUser infoUser) { if (infoUser != null) { QueryWrapper 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 = 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 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); } // 循环外统一查询,避免N+1问题 Set allUserIds = orlist.stream().flatMap(o -> Stream.of(o.getShId(), o.getUserId())).filter(Objects::nonNull).collect(Collectors.toSet()); Set mdIds = orlist.stream().map(PosOrder::getMdId).filter(Objects::nonNull).collect(Collectors.toSet()); Set shdzIds = orlist.stream().filter(o -> o.getShAddress() == null && o.getShdzId() != null).map(PosOrder::getShdzId).collect(Collectors.toSet()); Map userMap = allUserIds.isEmpty() ? Collections.emptyMap() : infoUserService.listByIds(allUserIds).stream().collect(Collectors.toMap(InfoUser::getUserId, u -> u)); Map storeMap = mdIds.isEmpty() ? Collections.emptyMap() : posStoreService.listByIds(mdIds).stream().collect(Collectors.toMap(PosStore::getId, s -> s)); Map addressMap = shdzIds.isEmpty() ? Collections.emptyMap() : infoAddressService.listByIds(shdzIds).stream().collect(Collectors.toMap(InfoAddress::getId, a -> a)); DecimalFormat jl = new DecimalFormat("#.0"); for (PosOrder order : orlist) { // 自动序列化所有PosOrder字段,新增字段无需手动添加 JSONObject org = JSON.parseObject( JSON.toJSONStringWithDateFormat(order, "yyyy-MM-dd HH:mm:ss") ); // 以下为非PosOrder字段或需要特殊处理的字段 org.put("shanghu", userMap.get(order.getShId())); org.put("store", storeMap.get(order.getMdId().intValue())); org.put("shaddress", order.getShAddress() == null ? addressMap.get(order.getShdzId()) : JSONObject.parseObject(order.getShAddress())); org.put("user", userMap.get(order.getUserId())); org.put("jvli", jl.format(order.getJvli())); org.put("juli", jl.format(order.getJuli())); org.put("food", JSONArray.parseArray(order.getFood())); 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 orlist = posOrderMapper.getQsOrderList(id, longitude, latitude, (page - 1) * size, size, state); // 循环外统一查询,避免N+1问题 Set allUserIds = orlist.stream().flatMap(o -> Stream.of(o.getShId(), o.getUserId(), o.getQsId())).filter(Objects::nonNull).collect(Collectors.toSet()); Set mdIds = orlist.stream().map(PosOrder::getMdId).filter(Objects::nonNull).collect(Collectors.toSet()); Set shdzIds = orlist.stream().filter(o -> o.getShAddress() == null && o.getShdzId() != null).map(PosOrder::getShdzId).collect(Collectors.toSet()); Map userMap = allUserIds.isEmpty() ? Collections.emptyMap() : infoUserService.listByIds(allUserIds).stream().collect(Collectors.toMap(InfoUser::getUserId, u -> u)); Map storeMap = mdIds.isEmpty() ? Collections.emptyMap() : posStoreService.listByIds(mdIds).stream().collect(Collectors.toMap(PosStore::getId, s -> s)); Map addressMap = shdzIds.isEmpty() ? Collections.emptyMap() : infoAddressService.listByIds(shdzIds).stream().collect(Collectors.toMap(InfoAddress::getId, a -> a)); JSONArray arr = new JSONArray(); DecimalFormat jl = new DecimalFormat("#.0"); for (PosOrder order : orlist) { // 自动序列化所有PosOrder字段,新增字段无需手动添加 JSONObject org = JSON.parseObject( JSON.toJSONStringWithDateFormat(order, "yyyy-MM-dd HH:mm:ss") ); // 以下为非PosOrder字段或需要特殊处理的字段 org.put("shanghu", userMap.get(order.getShId())); org.put("store", storeMap.get(order.getMdId().intValue())); org.put("shaddress", order.getShAddress() == null ? addressMap.get(order.getShdzId()) : JSONObject.parseObject(order.getShAddress())); org.put("user", userMap.get(order.getUserId())); org.put("qishou", userMap.get(order.getQsId())); org.put("jvli", jl.format(order.getJvli())); org.put("qsjvli", jl.format(order.getJuli())); org.put("food", JSONArray.parseArray(order.getFood())); org.put("sqImg", org.remove("qsImg")); 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,@RequestParam(defaultValue = "")String type) { JwtUtil jwtUtil = new JwtUtil(); String id = jwtUtil.getusid(token); IPage palist = new Page<>(page, size); QueryWrapper 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); queryWrapper.eq(!StringUtils.isEmpty(type),"type",type); 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 list = posOrderService.page(palist, queryWrapper); List orlist = list.getRecords(); // 循环外统一查询,避免N+1问题 Set allUserIds = orlist.stream().flatMap(o -> Stream.of(o.getShId(), o.getUserId())).filter(Objects::nonNull).collect(Collectors.toSet()); Set mdIds = orlist.stream().map(PosOrder::getMdId).filter(Objects::nonNull).collect(Collectors.toSet()); Set shdzIds = orlist.stream().filter(o -> o.getShAddress() == null && o.getShdzId() != null).map(PosOrder::getShdzId).collect(Collectors.toSet()); Map userMap = allUserIds.isEmpty() ? Collections.emptyMap() : infoUserService.listByIds(allUserIds).stream().collect(Collectors.toMap(InfoUser::getUserId, u -> u)); Map storeMap = mdIds.isEmpty() ? Collections.emptyMap() : posStoreService.listByIds(mdIds).stream().collect(Collectors.toMap(PosStore::getId, s -> s)); Map addressMap = shdzIds.isEmpty() ? Collections.emptyMap() : infoAddressService.listByIds(shdzIds).stream().collect(Collectors.toMap(InfoAddress::getId, a -> a)); JSONArray arr = new JSONArray(); for (PosOrder order : orlist) { // 自动序列化所有PosOrder字段,新增字段无需手动添加 JSONObject org = JSON.parseObject( JSON.toJSONStringWithDateFormat(order, "yyyy-MM-dd HH:mm:ss") ); // 以下为非PosOrder字段或需要特殊处理的字段 org.put("shanghu", userMap.get(order.getShId())); org.put("store", storeMap.get(order.getMdId().intValue())); org.put("shaddress", order.getShAddress() == null ? addressMap.get(order.getShdzId()) : JSONObject.parseObject(order.getShAddress())); org.put("user", userMap.get(order.getUserId())); org.put("food", JSONArray.parseArray(order.getFood())); 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,@RequestParam(defaultValue = "")String type) { JwtUtil jwtUtil = new JwtUtil(); String id = jwtUtil.getusid(token); IPage palist = new Page<>(page, size); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.select().orderByDesc("cretim"); queryWrapper.eq("user_id", id); queryWrapper.eq(!StringUtils.isEmpty(type),"type",type); 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 list = posOrderService.page(palist, queryWrapper); List orlist = list.getRecords(); List parentDdIds = orlist.stream().map(PosOrder::getParentDdId).collect(Collectors.toList()); List orderParents = new ArrayList<>(); if (!parentDdIds.isEmpty()) { orderParents = orderParentService.list(new LambdaQueryWrapper<>(OrderParent.class).in(OrderParent::getDdId, parentDdIds)); } // 循环外统一查询,避免N+1问题 Set allUserIds = orlist.stream().flatMap(o -> Stream.of(o.getShId(), o.getUserId())).filter(Objects::nonNull).collect(Collectors.toSet()); Set mdIds = orlist.stream().map(PosOrder::getMdId).filter(Objects::nonNull).collect(Collectors.toSet()); Set shdzIds = orlist.stream().filter(o -> o.getShAddress() == null && o.getShdzId() != null).map(PosOrder::getShdzId).collect(Collectors.toSet()); Map userMap = allUserIds.isEmpty() ? Collections.emptyMap() : infoUserService.listByIds(allUserIds).stream().collect(Collectors.toMap(InfoUser::getUserId, u -> u)); Map storeMap = mdIds.isEmpty() ? Collections.emptyMap() : posStoreService.listByIds(mdIds).stream().collect(Collectors.toMap(PosStore::getId, s -> s)); Map addressMap = shdzIds.isEmpty() ? Collections.emptyMap() : infoAddressService.listByIds(shdzIds).stream().collect(Collectors.toMap(InfoAddress::getId, a -> a)); Map orderParentMap = orderParents.stream().collect(Collectors.toMap(OrderParent::getDdId, p -> p)); JSONArray arr = new JSONArray(); for (PosOrder order : orlist) { // 自动序列化所有PosOrder字段,新增字段无需手动添加 JSONObject org = JSON.parseObject( JSON.toJSONStringWithDateFormat(order, "yyyy-MM-dd HH:mm:ss") ); // 以下为非PosOrder字段或需要特殊处理的字段 org.put("ddId", order.getDdId() == null ? null : order.getDdId().toString()); org.put("shanghu", userMap.get(order.getShId())); org.put("store", storeMap.get(order.getMdId().intValue())); org.put("shaddress", order.getShAddress() == null ? addressMap.get(order.getShdzId()) : JSONObject.parseObject(order.getShAddress())); org.put("user", userMap.get(order.getUserId())); org.put("food", JSONArray.parseArray(order.getFood())); org.put("parentRemarks", ""); if (StringUtils.isNotEmpty(order.getParentDdId())) { OrderParent parent = orderParentMap.get(order.getParentDdId()); if (parent != null) org.put("parentRemarks", parent.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(); DateUtil dateUtil = new DateUtil(); String id = jwtUtil.getusid(token); QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("md_id", orderDTO.getMdId()); List 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 query = new QueryWrapper<>(); query.eq("user_id", id); query.eq("collect_payment", "1"); query.notIn("state", 5, 10, 11); List 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 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 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 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 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 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.setAfterSaleStatus(0L); posOrder.setDeliveryStatus(Long.valueOf(0L).equals(orderDTO.getType()) ? 0L : null); posOrder.setPayStatus(Long.valueOf(0L).equals(orderDTO.getType()) && "1".equals(orderDTO.getCollectPayment()) ? 1L : 0L); // 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 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 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 querywra = new QueryWrapper<>(); querywra.eq("dd_id", posOrder.getDdId()); PosOrder order = posOrderService.getOne(querywra); //货到付款、类型外卖,推送给骑手有新订单了 if (order.getCollectPayment().equals("1") && order.getType() == 0) { sendHdfkMessage(order); } //存在使用优惠券的话,核销优惠券 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 map) { for (Map.Entry entry : map.entrySet()) { Long key = entry.getKey(); Long value = entry.getValue(); // 使用数据库原子UPSERT,避免并发下的竞态问题 foodStatisticsService.increaseNumber(key, value); } } /** * 货到付款发送推送 * * @param order */ private void sendHdfkMessage(PosOrder order) { deliveryOrderNotificationService.notifyOrderAvailable(order); } //核销积分 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 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 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 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 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 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 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 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 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 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 util = new ExcelUtil(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)); } @PreAuthorize("@ss.hasPermi('system:order:edit')") @GetMapping("/{id}/status-context") public AjaxResult getStatusContext(@PathVariable Long id) { return success(orderLifecycleService.getStatusContext(id)); } @PreAuthorize("@ss.hasPermi('system:order:linePaymentReconcile')") @RepeatSubmit(interval = 2000, message = "查询过于频繁") @PostMapping("/{id}/line-payment/reconcile") public AjaxResult adminReconcileLinePayment(@PathVariable Long id) { AdminOrderStatusContext context = orderLifecycleService.getStatusContext(id); if (context.getLinePaymentId() == null) { throw new ServiceException("LINE Pay 流水不存在"); } String status = linePayService.reconcilePayment(context.getLinePaymentId(), "ADMIN"); Map data = new LinkedHashMap<>(); data.put("status", status); data.put("context", orderLifecycleService.getStatusContext(id)); return success("LINE Pay 状态查询完成", data); } @PreAuthorize("@ss.hasPermi('system:order:lineRefund')") @RepeatSubmit(interval = 2000, message = "请求过于频繁") @PostMapping("/{id}/line-refund") public AjaxResult adminRefundLinePayment(@PathVariable Long id) { Long paymentId = orderLifecycleService.reserveLineRefund(id, "ADMIN"); String status = linePayRefundService.requestFullRefund(paymentId, "ADMIN"); Map data = new LinkedHashMap<>(); data.put("status", status); data.put("context", orderLifecycleService.getStatusContext(id)); return success("LINE Pay 退款处理完成", data); } private String lineMessage(String key, String fallback) { try { return MessageUtils.message(key); } catch (RuntimeException ignored) { return fallback; } } @PreAuthorize("@ss.hasPermi('system:order:edit')") @RepeatSubmit(interval = 1000, message = "请求过于频繁") @PutMapping("/{id}/status") public AjaxResult adminUpdateStatus(@PathVariable Long id, @Valid @RequestBody AdminOrderStatusUpdateRequest request) { SysUser operator = currentAdmin(); return success("修改成功", orderLifecycleService.updateStatus(id, request, operator == null ? null : operator.getUserId(), operatorName(operator))); } @PreAuthorize("@ss.hasPermi('system:order:edit')") @RepeatSubmit(interval = 1000, message = "请求过于频繁") @PostMapping("/{id}/offline-payment/confirm") public AjaxResult adminConfirmOfflinePayment(@PathVariable Long id, @Valid @RequestBody AdminOrderActionRequest request) { SysUser operator = currentAdmin(); return success("已确认线下收款", orderLifecycleService.confirmOfflinePayment(id, request, operator == null ? null : operator.getUserId(), operatorName(operator))); } @PreAuthorize("@ss.hasPermi('system:order:edit')") @RepeatSubmit(interval = 1000, message = "请求过于频繁") @PostMapping("/{id}/offline-refund/confirm") public AjaxResult adminConfirmOfflineRefund(@PathVariable Long id, @Valid @RequestBody AdminOrderActionRequest request) { SysUser operator = currentAdmin(); return success("已确认线下退款", orderLifecycleService.confirmOfflineRefund(id, request, operator == null ? null : operator.getUserId(), operatorName(operator))); } /** * 新增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 == null || posOrder.getId() == null) { return error("订单ID不能为空"); } if (posOrder.getState() != null || posOrder.getDeliveryStatus() != null || posOrder.getPayStatus() != null || posOrder.getAfterSaleStatus() != null || posOrder.getSdTime() != null) { return error("订单状态请使用状态专用操作"); } return toAjax(posOrderService.updatePosOrder(posOrder)); } private SysUser currentAdmin() { return SecurityUtils.getLoginUser() == null ? null : SecurityUtils.getLoginUser().getUser(); } private String operatorName(SysUser operator) { return operator == null || operator.getNickName() == null ? "" : operator.getNickName(); } /** * 订单取消、退款成功返回积分 * * @param userId * @param ddId * @param points */ public void returnPoints(Long userId, Long ddId, Long points) { LambdaQueryWrapper walletQuery = new LambdaQueryWrapper<>(); walletQuery.eq(UserWallet::getUserId, userId); walletQuery.isNull(UserWallet::getStoreId); UserWallet userWallet = userWalletService.getOne(walletQuery); PointsTransaction transaction = pointsTransactionService.getOne(new LambdaQueryWrapper().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 result = new ArrayList<>(); QueryWrapper 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 list = posOrderService.list(wrapper); if (!list.isEmpty()) { List qsIds = list.stream().map(PosOrder::getQsId).collect(Collectors.toList()); List users = new ArrayList<>(); if (!qsIds.isEmpty()) { LambdaQueryWrapper userWrapper = new LambdaQueryWrapper<>(); userWrapper.in(InfoUser::getUserId, qsIds); users = infoUserService.list(userWrapper); } List mdIds = list.stream().map(PosOrder::getMdId).collect(Collectors.toList()); LambdaQueryWrapper mdWrapper = new LambdaQueryWrapper().in(PosStore::getId, mdIds); List stores = posStoreService.list(mdWrapper); List riderPositions = new ArrayList<>(); if (!qsIds.isEmpty()) { riderPositions = riderPositionService.list(new LambdaQueryWrapper().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); } }