From 04a7dd0bd678d463fc2770ff27aac22c3e2628d0 Mon Sep 17 00:00:00 2001 From: "925116093-qq.com" <925116093@qq.com> Date: Tue, 12 Aug 2025 17:26:10 +0800 Subject: [PATCH] 2025008071805 --- .../controller/AppleMemberController.java | 10 +- .../controller/AppleOrderController.java | 87 +- .../system/controller/AppletController.java | 39 +- .../controller/GoodsOrderController.java | 38 +- .../system/controller/OrderController.java | 120 +- .../com/ruoyi/system/domain/GoodsOrder.java | 48 +- .../java/com/ruoyi/system/domain/Order.java | 10 + .../com/ruoyi/system/domain/OrderComment.java | 10 +- .../com/ruoyi/system/domain/OrderLog.java | 33 + .../system/mapper/OrderCommentMapper.java | 4 +- .../ruoyi/system/mapper/OrderLogMapper.java | 6 + .../com/ruoyi/system/mapper/OrderMapper.java | 8 + .../system/service/IOrderCommentService.java | 4 +- .../system/service/IOrderLogService.java | 2 +- .../ruoyi/system/service/IOrderService.java | 8 + .../service/impl/OrderCommentServiceImpl.java | 8 +- .../service/impl/OrderLogServiceImpl.java | 3 + .../system/service/impl/OrderServiceImpl.java | 8 + .../mapper/system/GoodsOrderMapper.xml | 14 +- .../mapper/system/OrderCommentMapper.xml | 16 +- .../mapper/system/OrderLogMapper.xml | 22 +- .../resources/mapper/system/OrderMapper.xml | 42 + ruoyi-ui/src/api/system/Order.js | 54 + .../src/views/system/GoodsOrder/index.vue | 633 ++--- ruoyi-ui/src/views/system/Order/index.vue | 2251 +++++++++++++---- 25 files changed, 2695 insertions(+), 783 deletions(-) diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleMemberController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleMemberController.java index 408477c..a8d0f08 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleMemberController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleMemberController.java @@ -600,7 +600,7 @@ public class AppleMemberController extends BaseController { } // 5. 检查是否已经评价过 - int count = orderCommentService.selectCountOrderCommentByOid(order.getId()); + int count = orderCommentService.selectCountOrderCommentByOid(order.getOrderId()); if (count > 0) { return AppletControllerUtil.appletWarning("请勿重复提交"); } @@ -679,7 +679,7 @@ public class AppleMemberController extends BaseController { } // 5. 检查是否已经评价过 - int count = orderCommentService.selectCountOrderCommentByOid(goodsOrder.getId()); + int count = orderCommentService.selectCountOrderCommentByOid(goodsOrder.getMainOrderId()); if (count > 0) { return AppletControllerUtil.appletWarning("请勿重复提交"); } @@ -697,7 +697,7 @@ public class AppleMemberController extends BaseController { // 7. 构建评价数据 OrderComment comment = new OrderComment(); comment.setOid(goodsOrder.getId()); - comment.setOrderId(goodsOrder.getOrderId()); + comment.setOrderId(goodsOrder.getMainOrderId()); comment.setProductId(goodsOrder.getProductId()); comment.setContent(content); comment.setNum(Long.valueOf(num)); @@ -720,7 +720,7 @@ public class AppleMemberController extends BaseController { if (result > 0) { com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject(); jsonObject.put("name", "用户已评价"); - OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getOrderId(), "已评价", "4", jsonObject, 2L); + OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getMainOrderId(), "已评价", "4", jsonObject, 2L); com.alibaba.fastjson.JSONObject jsonObject1 = new com.alibaba.fastjson.JSONObject(); Map logContent1 = new HashMap<>(); logContent1.put("text", content); @@ -728,7 +728,7 @@ public class AppleMemberController extends BaseController { logContent1.put("labels", params.get("labels")); logContent1.put("num", num); jsonObject1= com.alibaba.fastjson.JSONObject.parseObject(JSON.toJSONString(logContent1)); - OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getOrderId(), "已完成", "5", jsonObject1, 2L); + OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getMainOrderId(), "已完成", "5", jsonObject1, 2L); goodsOrder.setStatus(5L); // 订单状态改为已收货 goodsOrderService.updateGoodsOrder(goodsOrder); return AjaxResult.success(); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleOrderController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleOrderController.java index 6de4f1f..653674b 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleOrderController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppleOrderController.java @@ -2233,6 +2233,17 @@ public class AppleOrderController extends BaseController { orderMap.put("orcerCrateTime", sdf.format(order.getCreatedAt())); orderMap.put("num", order.getNum()); orderMap.put("statusText", getOrderStatusText(order.getStatus())); + + String firstOrderId = OrderUtil.findUserFirstOrderId(order.getUid()); + if (firstOrderId != null){ + if (firstOrderId.equals(order.getOrderId())){ + orderMap.put("isFirst", true); + }else{ + orderMap.put("isFirst", false); + } + }else{ + orderMap.put("isFirst", false); + } // 订单类型 orderMap.put("bigtype", getOrderBigType(order.getBigtype())); orderMap.put("bigtypeText", getOrderBigTypeText(order.getBigtype())); @@ -2351,6 +2362,7 @@ public class AppleOrderController extends BaseController { @RequestParam(value = "limit", defaultValue = "10") int limit, @RequestParam(value = "dayDate", required = false) String dayDate, @RequestParam(value = "day", required = false) String day, + @RequestParam(value = "orderid", required = false) String orderid, HttpServletRequest request) { try { int pageNum=page; @@ -2373,6 +2385,10 @@ public class AppleOrderController extends BaseController { // 3. 构建查询条件 Order queryOrder = new Order(); + queryOrder.setWorkerdel(2L); + if (StringUtils.isNotBlank(orderid)) { + queryOrder.setOrderId(orderid); + } // 直接用dayDate字符串查 if (StringUtils.isNotBlank(dayDate)) { queryOrder.setDayDate(dayDate); @@ -2438,6 +2454,17 @@ public class AppleOrderController extends BaseController { orderMap.put("orcerCrateTime", sdf.format(order.getCreatedAt())); orderMap.put("num", order.getNum()); orderMap.put("statusText", getOrderStatusText(order.getStatus())); + String firstOrderId = OrderUtil.findUserFirstOrderId(order.getUid()); + if (firstOrderId != null){ + if (order.getOrderId().equals(firstOrderId)){ + orderMap.put("isFirst", true); + } else{ + orderMap.put("isFirst", false); + } + }else{ + orderMap.put("isFirst", false); + } + // 订单类型 orderMap.put("bigtype", getOrderBigType(order.getBigtype())); orderMap.put("bigtypeText", getOrderBigTypeText(order.getBigtype())); @@ -2798,6 +2825,11 @@ public class AppleOrderController extends BaseController { commentData.put("numType", comment.getNumType()); commentData.put("content", comment.getContent()); commentData.put("createdAt",comment.getCreatedAt() != null ? sdf.format(comment.getCreatedAt()) : ""); + if (org.apache.commons.lang3.StringUtils.isNotBlank(comment.getAdminhf())){ + commentData.put("admin",comment.getAdminhf()); + }else{ + commentData.put("admin",null); + } if (comment.getImages()!=null){ commentData.put("image",JSONArray.parseArray(comment.getImages())); }else{ @@ -3642,6 +3674,28 @@ public class AppleOrderController extends BaseController { return AppletControllerUtil.appletSuccess("评论删除成功"); } + + + /** + * 评论删除接口 + * @param id 评论ID + * @return 操作结果 + */ + @GetMapping("/api/worker/order/del/{id}") + public AjaxResult apiworkerorderdel(@PathVariable("id") Long id) { + try { + Order order = orderService.selectOrderById(id); + if (order != null){ + order.setWorkerdel(2L); + orderService.updateOrder(order); + } + } catch (Exception e) { + logger.error("评论失败:", e); + return AppletControllerUtil.appletError("评论失败:" + e.getMessage()); + } + return AppletControllerUtil.appletSuccess("评论成功"); + } + /** * 拼团预约接口 * @param params {id, address_id, make_time} @@ -4229,7 +4283,7 @@ public class AppleOrderController extends BaseController { // 7. 添加订单日志 com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject(); jsonObject.put("name", "用户确认收货"); - OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getOrderId(), "确认收货", "3", jsonObject, 2L); + OrderUtil.addgoodsorderlog(goodsOrder.getId(), goodsOrder.getMainOrderId(), "确认收货", "3", jsonObject, 2L); Map result = new HashMap<>(); result.put("message", "确认收货成功"); @@ -4323,6 +4377,12 @@ public class AppleOrderController extends BaseController { jsonObject.put("num",commentDATA.getNum()); jsonObject.put("status",commentDATA.getStatus()); jsonObject.put("text",commentDATA.getContent()); + + if (StringUtils.isNotBlank(commentDATA.getAdminhf())){ + jsonObject.put("admin",commentDATA.getAdminhf()); + }else{ + jsonObject.put("admin",null); + } if (commentDATA.getImages()!=null){ jsonObject.put("image",JSONArray.parseArray(commentDATA.getImages())); } @@ -5373,9 +5433,32 @@ public class AppleOrderController extends BaseController { return AppletControllerUtil.appletError("获取文章失败:" + e.getMessage()); } } - + + //根据经纬度获取当前位置 +// public static String getAddressByLocation(double longitude, double latitude) { + @PostMapping("/api/public/get/adressname") + public AjaxResult getArticleByadressname(@RequestBody Map params) { + + logger.info("=== 开始获取分类文章 ==="); + logger.info("请求参数: {}", params); + + // 获取参数 + String longitude = null; + if (params.get("longitude") != null) { + longitude = params.get("longitude").toString(); + } + // 获取参数 + String latitude = null; + if (params.get("latitude") != null) { + latitude = params.get("latitude").toString(); + } + // GaoDeMapUtil.getAddressByLocation(Double.parseDouble(longitude), Double.parseDouble(latitude)); + String result = GaoDeMapUtil.getAddressByLocation(Double.parseDouble(longitude), Double.parseDouble(latitude)); + + return AppletControllerUtil.appletSuccess(result); + } @PostMapping("/api/service/order/rework/lst") public AjaxResult getReworkList(@RequestBody Map params, HttpServletRequest request) { try { diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppletController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppletController.java index 0a20c71..3894178 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppletController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/AppletController.java @@ -2092,7 +2092,7 @@ public class AppletController extends BaseController { } goodsOrder = orderList.get(0); } - int count = orderCommentService.selectCountOrderCommentByOid(goodsOrder.getId()); + int count = orderCommentService.selectCountOrderCommentByOid(goodsOrder.getOrderId()); if (count > 0) { return AppletControllerUtil.appletWarning("请勿重复提交"); } @@ -4450,6 +4450,11 @@ public class AppletController extends BaseController { jsonObject.put("num",commentDATA.getNum()); jsonObject.put("status",commentDATA.getStatus()); jsonObject.put("text",commentDATA.getContent()); + if (org.apache.commons.lang3.StringUtils.isNotBlank(commentDATA.getAdminhf())){ + jsonObject.put("admin",commentDATA.getAdminhf()); + }else{ + jsonObject.put("admin",null); + } if (commentDATA.getImages()!=null){ jsonObject.put("image",JSONArray.parseArray(commentDATA.getImages())); } @@ -4576,7 +4581,7 @@ public class AppletController extends BaseController { orderdata.put("goodsid", order.getProductId()); orderdata.put("xiadanshijian",order.getCreatedAt() != null ? dateFormat.format(order.getCreatedAt()) : null); Map shifuMap = new HashMap<>(); - if (order.getWorkerId() != null){ + if (order.getWorkerId() != null&&order.getIsAccept()==1){ Users workerInfo = usersService.selectUsersById(order.getWorkerId()); shifuMap.put("worker_image", AppletControllerUtil.buildImageUrl(workerInfo.getAvatar())); shifuMap.put("worker_name", workerInfo.getName()); @@ -4700,6 +4705,11 @@ public class AppletController extends BaseController { jsonObject.put("num",commentDATA.getNum()); jsonObject.put("status",commentDATA.getStatus()); jsonObject.put("text",commentDATA.getContent()); + if (org.apache.commons.lang3.StringUtils.isNotBlank(commentDATA.getAdminhf())){ + jsonObject.put("admin",commentDATA.getAdminhf()); + }else{ + jsonObject.put("admin",null); + } if (commentDATA.getImages()!=null){ jsonObject.put("image",JSONArray.parseArray(commentDATA.getImages())); } @@ -5862,7 +5872,9 @@ public class AppletController extends BaseController { if (phoneTwo.length() != 2) { return AppletControllerUtil.appletWarning("请输入手机号后两位"); } - + String latitude = params.get("latitude").toString(); + String longitude = params.get("longitude").toString(); + String addressName = params.get("addressName").toString(); // 2. 获取当前登录师傅ID(token在header) String token = request.getHeader("token"); Map userValidation = AppletLoginUtil.validateUserToken(token, usersService); @@ -5915,6 +5927,9 @@ public class AppletController extends BaseController { orderLog.setOid(order.getId()); orderLog.setOrderId(order.getOrderId()); orderLog.setWorkerId(workerId); + orderLog.setLatitude(latitude); + orderLog.setLongitude(longitude); + orderLog.setAddressName(addressName); orderLog.setWorkerLogId(workerId); orderLog.setTitle("师傅到达"); orderLog.setType(new BigDecimal("5.0")); @@ -6264,6 +6279,7 @@ public class AppletController extends BaseController { } BigDecimal reductionPrice = BigDecimal.ZERO; String reduction = params.get("reduction").toString(); + String reamk = params.get("reamk").toString(); if (reduction != null && !reduction.trim().isEmpty()) { reductionPrice = new BigDecimal(reduction); // totalPrice = totalPrice.subtract(reductionPrice); @@ -6286,6 +6302,9 @@ public class AppletController extends BaseController { resultJson.put("deposit", depositproject); // basic resultJson.put("basic", params.get("basic")); + if (StringUtils.isNotBlank(reamk)){ + resultJson.put("reamk", reamk); + } // craft List> craftListNew = new ArrayList<>(); @@ -6622,6 +6641,10 @@ public class AppletController extends BaseController { if (order == null) { return AppletControllerUtil.appletError("订单不存在"); } + String reamk = params.get("reamk").toString(); + String latitude = params.get("latitude").toString(); + String longitude = params.get("longitude").toString(); + String addressName = params.get("addressName").toString(); PayBeforeUtil payBeforeUtil = new PayBeforeUtil(); String priceDifferenceprice= params.get("priceDifferenceprice").toString(); // int paynum=usersPayBeforService.countByLastOrderIdAndStatus(order.getOrderId()); @@ -6636,7 +6659,12 @@ public class AppletController extends BaseController { // } // 2. 组装日志内容 Map logContent = new LinkedHashMap<>(); - logContent.put("name", "师傅服务完成"); + if (StringUtils.isNotBlank(reamk)) { + logContent.put("name","师傅服务完成--"+ reamk); + }else{ + logContent.put("name", "师傅服务完成"); + } + logContent.put("image", params.get("image")); String contentStr = com.alibaba.fastjson2.JSONObject.toJSONString(logContent); // 3. 写入订单日志 @@ -6645,6 +6673,9 @@ public class AppletController extends BaseController { log.setOrderId(order.getOrderId()); log.setLogOrderId(GenerateCustomCode.generCreateOrder("DSB")); log.setTitle("服务完成"); + log.setLatitude(latitude); + log.setLongitude(longitude); + log.setAddressName(addressName); log.setType(new java.math.BigDecimal(7)); log.setContent(contentStr); log.setWorkerId(order.getWorkerId()); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/GoodsOrderController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/GoodsOrderController.java index 609a5af..7c0384e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/GoodsOrderController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/GoodsOrderController.java @@ -79,10 +79,18 @@ public class GoodsOrderController extends BaseController if(serviceGoods!=null){ goodsOrderdata.setProductName(serviceGoods.getTitle()); } - + if(goodsOrderdata.getAddressId()!=null){ + UserAddress userAddress=userAddressService.selectUserAddressById(goodsOrderdata.getAddressId()); + if (userAddress != null){ + goodsOrderdata.setLatitude(userAddress.getLatitude()); + goodsOrderdata.setLongitude(userAddress.getLongitude()); + goodsOrderdata.setAdressinfo(userAddress.getAddressInfo()+userAddress.getInfo()); + } +} Users users=usersService.selectUsersById(goodsOrderdata.getUid()); if(users !=null){ goodsOrderdata.setUname(users.getName()); + goodsOrderdata.setUphone(users.getPhone()); } @@ -194,7 +202,30 @@ public class GoodsOrderController extends BaseController @GetMapping(value = "/{id}") public AjaxResult getInfo(@PathVariable("id") Long id) { - return success(goodsOrderService.selectGoodsOrderById(id)); + GoodsOrder goodsOrderdata =goodsOrderService.selectGoodsOrderById(id); + if(goodsOrderdata.getAddressId()!=null){ + UserAddress userAddress=userAddressService.selectUserAddressById(goodsOrderdata.getAddressId()); + if (userAddress != null){ + goodsOrderdata.setLatitude(userAddress.getLatitude()); + goodsOrderdata.setLongitude(userAddress.getLongitude()); + goodsOrderdata.setAdressinfo(userAddress.getAddressInfo()+userAddress.getInfo()); + } + //ISiteDeliveryService siteDeliveryService; + if (goodsOrderdata.getDeliveryId()!=null){ + SiteDelivery siteDelivery=siteDeliveryService.selectSiteDeliveryById(goodsOrderdata.getDeliveryId()); + if(siteDelivery!=null){ + goodsOrderdata.setDeliveryName(siteDelivery.getTitle()); + } + } + + Users users=usersService.selectUsersById(goodsOrderdata.getUid()); + if(users !=null){ + goodsOrderdata.setUname(users.getName()); + goodsOrderdata.setUphone(users.getPhone()); + } + } + + return success(goodsOrderdata); } /** @@ -210,8 +241,10 @@ public class GoodsOrderController extends BaseController if (userAddress!=null){ goodsOrder.setName(userAddress.getName()); goodsOrder.setPhone(userAddress.getPhone()); + goodsOrder.setAddress(userAddress.getAddressName()); } + } if (goodsOrder.getProductId()!=null){ ServiceGoods serviceGoods=serviceGoodsService.selectServiceGoodsById(goodsOrder.getProductId()); @@ -476,6 +509,7 @@ public class GoodsOrderController extends BaseController goodsOrderdata.setDeliveryId(goodsOrder.getDeliveryId()); goodsOrderdata.setDeliveryNum(goodsOrder.getDeliveryNum()); goodsOrderdata.setSendTime(goodsOrder.getSendTime()); + goodsOrderdata.setMark(goodsOrder.getMark()); goodsOrderdata.setStatus(3L); // 设置为已发货状态 count+= goodsOrderService.updateGoodsOrder(goodsOrderdata); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/controller/OrderController.java b/ruoyi-system/src/main/java/com/ruoyi/system/controller/OrderController.java index aae4de7..c03e66e 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/controller/OrderController.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/controller/OrderController.java @@ -80,7 +80,7 @@ public class OrderController extends BaseController { orderdata.setUname(users.getName()); } orderdata.setThjl(orderCallService.selectCountOrderCallByOid(orderdata.getId())); - orderdata.setFwpj(orderCommentService.selectCountOrderCommentByOid(orderdata.getId())); + orderdata.setFwpj(orderCommentService.selectCountOrderCommentByOid(orderdata.getOrderId())); orderdata.setLywj(orderSoundService.selectCountOrderSoundByOid(orderdata.getId())); orderdata.setJdjl(orderLogService.selectCountOrderLogByOrderId(orderdata.getOrderId())); orderdata.setTzjl(notifyOrderService.selectNotifyOrderCountByOid(orderdata.getId())); @@ -240,7 +240,7 @@ public class OrderController extends BaseController { System.out.println("=== 获取接单记录 ==="); System.out.println("订单ID: " + orderId); - List list = orderLogService.selectOrderLogByOrderId(orderId); + List list = orderLogService.selectOrderLogByOrderIdASC(orderId); System.out.println("查询到的日志记录数量: " + (list != null ? list.size() : "null")); if (list != null && !list.isEmpty()) { @@ -334,7 +334,7 @@ public class OrderController extends BaseController { Order data = orderService.selectOrderByOrderId(orderId); ; if (data != null) { - List list = orderCommentService.selectOrderCommentByOid(data.getId()); + List list = orderCommentService.selectOrderCommentByOid(data.getOrderId()); for (OrderComment orderCommentdata : list) { Users users = usersService.selectUsersById(orderCommentdata.getUid()); if (users != null) { @@ -438,4 +438,118 @@ public class OrderController extends BaseController { List list = usersService.selectUsersList(users); return AjaxResult.success(list); } + + /** + * 更换师傅接口 + */ + @PreAuthorize("@ss.hasPermi('system:Order:edit')") + @Log(title = "更换师傅", businessType = BusinessType.UPDATE) + @PostMapping("/change-worker") + public AjaxResult changeWorker(@RequestBody Map params) { + try { + String orderId = params.get("orderId").toString(); + + // 这里调用具体的业务逻辑,您来实现 + // 例如:调用DispatchUtil进行重新派单 + + return success("更换师傅成功"); + } catch (Exception e) { + return error("更换师傅失败:" + e.getMessage()); + } + } + + /** + * 出发上门接口 + */ + @PreAuthorize("@ss.hasPermi('system:Order:edit')") + @Log(title = "出发上门", businessType = BusinessType.UPDATE) + @PostMapping("/departure") + public AjaxResult departure(@RequestBody Map params) { + try { + String orderId = params.get("orderId").toString(); + + // 这里调用具体的业务逻辑,您来实现 + // 例如:更新订单状态为出发上门,记录出发时间等 + + return success("出发上门成功"); + } catch (Exception e) { + return error("出发上门失败:" + e.getMessage()); + } + } + + /** + * 确认到达接口 + */ + @PreAuthorize("@ss.hasPermi('system:Order:edit')") + @Log(title = "确认到达", businessType = BusinessType.UPDATE) + @PostMapping("/confirm-arrival") + public AjaxResult confirmArrival(@RequestBody Map params) { + try { + String orderId = params.get("orderId").toString(); + + // 这里调用具体的业务逻辑,您来实现 + // 例如:更新订单状态为已到达,记录到达时间等 + + return success("确认到达成功"); + } catch (Exception e) { + return error("确认到达失败:" + e.getMessage()); + } + } + + /** + * 结束订单接口 + */ + @PreAuthorize("@ss.hasPermi('system:Order:edit')") + @Log(title = "结束订单", businessType = BusinessType.UPDATE) + @PostMapping("/end-order") + public AjaxResult endOrder(@RequestBody Map params) { + try { + String orderId = params.get("orderId").toString(); + + // 这里调用具体的业务逻辑,您来实现 + // 例如:更新订单状态为已结束,记录结束时间等 + + return success("订单已结束"); + } catch (Exception e) { + return error("结束订单失败:" + e.getMessage()); + } + } + + /** + * 开始服务接口 + */ + @PreAuthorize("@ss.hasPermi('system:Order:edit')") + @Log(title = "开始服务", businessType = BusinessType.UPDATE) + @PostMapping("/start-service") + public AjaxResult startService(@RequestBody Map params) { + try { + String orderId = params.get("orderId").toString(); + + // 这里调用具体的业务逻辑,您来实现 + // 例如:更新订单状态为服务中,记录开始时间等 + + return success("开始服务成功"); + } catch (Exception e) { + return error("开始服务失败:" + e.getMessage()); + } + } + + /** + * 项目报价接口 + */ + @PreAuthorize("@ss.hasPermi('system:Order:edit')") + @Log(title = "项目报价", businessType = BusinessType.UPDATE) + @PostMapping("/project-quote") + public AjaxResult projectQuote(@RequestBody Map params) { + try { + String orderId = params.get("orderId").toString(); + + // 这里调用具体的业务逻辑,您来实现 + // 例如:创建项目报价,更新订单状态等 + + return success("项目报价成功"); + } catch (Exception e) { + return error("项目报价失败:" + e.getMessage()); + } + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/GoodsOrder.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/GoodsOrder.java index 8a1873e..a1a7f3d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/GoodsOrder.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/GoodsOrder.java @@ -148,8 +148,14 @@ public class GoodsOrder extends BaseEntity /** 多规格产品 */ @Excel(name = "多规格产品") private String sku; + private String deliveryName; - + /** 纬度 */ + private String latitude; + private String uphone; + private String adressinfo; + /** 经度 */ + private String longitude; private BigDecimal payPriceMin; private BigDecimal payPriceMax; private BigDecimal returnrealmoney; @@ -677,6 +683,46 @@ public class GoodsOrder extends BaseEntity this.ismany = ismany; } + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + + public String getAdressinfo() { + return adressinfo; + } + + public void setAdressinfo(String adressinfo) { + this.adressinfo = adressinfo; + } + + public String getUphone() { + return uphone; + } + + public void setUphone(String uphone) { + this.uphone = uphone; + } + + public String getDeliveryName() { + return deliveryName; + } + + public void setDeliveryName(String deliveryName) { + this.deliveryName = deliveryName; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/Order.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/Order.java index e785962..825b16d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/Order.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/Order.java @@ -211,6 +211,8 @@ public class Order extends BaseEntity private Long baojiayh; + private Long workerdel; + private List ids; /** 录音文件 */ @Excel(name = "订单类别 1预约 2报价 3一口价 4拼团 5普通订单") @@ -967,6 +969,14 @@ public class Order extends BaseEntity this.qiangdan = qiangdan; } + public Long getWorkerdel() { + return workerdel; + } + + public void setWorkerdel(Long workerdel) { + this.workerdel = workerdel; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/OrderComment.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/OrderComment.java index c0b10c6..37a39ed 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/OrderComment.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/OrderComment.java @@ -52,7 +52,7 @@ public class OrderComment extends BaseEntity /** 评价内容 */ @Excel(name = "评价内容") private String content; - + private String adminhf; /** 评分 */ @Excel(name = "评分") private Long num; @@ -225,6 +225,14 @@ public class OrderComment extends BaseEntity this.labels = labels; } + public String getAdminhf() { + return adminhf; + } + + public void setAdminhf(String adminhf) { + this.adminhf = adminhf; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/OrderLog.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/OrderLog.java index 06a727c..7ca1ef3 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/OrderLog.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/OrderLog.java @@ -133,6 +133,14 @@ public class OrderLog extends BaseEntity private Long ordertype; + /** 纬度 */ + private String latitude; + + /** 经度 */ + private String longitude; + + /** 地图点选地址名称 */ + private String addressName; /** $column.columnComment */ @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") @@ -449,6 +457,31 @@ public class OrderLog extends BaseEntity this.ordertype = ordertype; } + + public String getAddressName() { + return addressName; + } + + public void setAddressName(String addressName) { + this.addressName = addressName; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderCommentMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderCommentMapper.java index 413a934..d728b12 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderCommentMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderCommentMapper.java @@ -20,11 +20,11 @@ public interface OrderCommentMapper public OrderComment selectOrderCommentById(Long id); - public int selectCountOrderCommentByOid(Long id); + public int selectCountOrderCommentByOid(String orderId); - public List selectOrderCommentByOid(Long id); + public List selectOrderCommentByOid(String orderId); /** * 查询订单评价列表 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderLogMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderLogMapper.java index 2bfa52e..538c710 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderLogMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderLogMapper.java @@ -31,6 +31,10 @@ public interface OrderLogMapper public int updateOrderLogEnd(Long id); public List selectOrderLogByOrderId(String orderId); + + public List selectOrderLogByOrderIdASC(String orderId); + + /** * 查询订单服务记录列表 * @@ -39,6 +43,8 @@ public interface OrderLogMapper */ public List selectOrderLogList(OrderLog orderLog); + + /** * 新增订单服务记录 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderMapper.java index e93cc7b..2e35e19 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/OrderMapper.java @@ -180,4 +180,12 @@ public interface OrderMapper * @return 预约用户列表 */ public List> selectOrderUsersByMakeTimeAndHour(Map params); + + /** + * 查找用户首次下单的订单ID + * + * @param userId 用户ID + * @return 首次下单的订单ID,如果没有找到返回null + */ + public String selectUserFirstOrderId(@Param("userId") Long userId); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderCommentService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderCommentService.java index 081dec4..03954a9 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderCommentService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderCommentService.java @@ -18,8 +18,8 @@ public interface IOrderCommentService * @return 订单评价 */ public OrderComment selectOrderCommentById(Long id); - public int selectCountOrderCommentByOid(Long id); - public List selectOrderCommentByOid(Long id); + public int selectCountOrderCommentByOid(String orderId); + public List selectOrderCommentByOid(String orderId); /** * 查询订单评价列表 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderLogService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderLogService.java index b0d0450..082ac63 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderLogService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderLogService.java @@ -45,7 +45,7 @@ public interface IOrderLogService * @return 订单服务记录列表 */ public List selectOrderLogByOrderId(String orderId); - + public List selectOrderLogByOrderIdASC(String orderId); /** * 查询订单服务记录列表 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderService.java index 93d330a..870a56d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IOrderService.java @@ -178,4 +178,12 @@ public interface IOrderService * @return 预约用户列表 */ public List> selectOrderUsersByMakeTimeAndHour(Map params); + + /** + * 查找用户首次下单的订单ID + * + * @param userId 用户ID + * @return 首次下单的订单ID,如果没有找到返回null + */ + public String selectUserFirstOrderId(Long userId); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderCommentServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderCommentServiceImpl.java index a7766c5..72ff1b1 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderCommentServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderCommentServiceImpl.java @@ -31,12 +31,12 @@ public class OrderCommentServiceImpl implements IOrderCommentService return orderCommentMapper.selectOrderCommentById(id); } - public List selectOrderCommentByOid(Long id){ - return orderCommentMapper.selectOrderCommentByOid(id); + public List selectOrderCommentByOid(String orderId){ + return orderCommentMapper.selectOrderCommentByOid(orderId); } - public int selectCountOrderCommentByOid(Long id){ - return orderCommentMapper.selectCountOrderCommentByOid(id); + public int selectCountOrderCommentByOid(String orderId){ + return orderCommentMapper.selectCountOrderCommentByOid(orderId); } /** diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderLogServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderLogServiceImpl.java index c46fa0a..ff2db5d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderLogServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderLogServiceImpl.java @@ -71,7 +71,10 @@ public class OrderLogServiceImpl implements IOrderLogService } + public List selectOrderLogByOrderIdASC(String orderId) { + return orderLogMapper.selectOrderLogByOrderIdASC(orderId); + } /** * 查询订单服务记录列表 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderServiceImpl.java index 97711a2..b8eef72 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/OrderServiceImpl.java @@ -217,4 +217,12 @@ public class OrderServiceImpl implements IOrderService public List> selectOrderUsersByMakeTimeAndHour(Map params) { return orderMapper.selectOrderUsersByMakeTimeAndHour(params); } + + /** + * 查找用户首次下单的订单ID + */ + @Override + public String selectUserFirstOrderId(Long userId) { + return orderMapper.selectUserFirstOrderId(userId); + } } diff --git a/ruoyi-system/src/main/resources/mapper/system/GoodsOrderMapper.xml b/ruoyi-system/src/main/resources/mapper/system/GoodsOrderMapper.xml index 8a89b81..c29ce84 100644 --- a/ruoyi-system/src/main/resources/mapper/system/GoodsOrderMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/GoodsOrderMapper.xml @@ -82,9 +82,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and uid = #{uid} and status = #{status} and product_id = #{productId} - and order_id = #{orderId} - and transaction_id = #{transactionId} - and main_order_id = #{mainOrderId} + and order_id like concat('%', #{orderId}, '%') + + + and main_order_id like concat('%', #{mainOrderId}, '%') ORDER BY CASE @@ -115,9 +116,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and uid = #{uid} and status = #{status} and product_id = #{productId} - and order_id = #{orderId} - and transaction_id = #{transactionId} - and main_order_id = #{mainOrderId} + and order_id like concat('%', #{orderId}, '%') + + + and main_order_id like concat('%', #{mainOrderId}, '%') GROUP BY main_order_id diff --git a/ruoyi-system/src/main/resources/mapper/system/OrderCommentMapper.xml b/ruoyi-system/src/main/resources/mapper/system/OrderCommentMapper.xml index 74874da..9730abf 100644 --- a/ruoyi-system/src/main/resources/mapper/system/OrderCommentMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/OrderCommentMapper.xml @@ -17,19 +17,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + - select id, oid, order_id, product_id, uid, images, content, num, num_type, status,labels, worker_id, created_at, updated_at from order_comment + select id, oid, order_id, adminhf,product_id, uid, images, content, num, num_type, status,labels, worker_id, created_at, updated_at from order_comment - + select count(0) from order_comment where order_id= #{orderId} - + select * from order_comment where order_id= #{orderId} @@ -120,6 +122,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select * from order_log where order_id = #{orderId} order by id DESC + + @@ -154,7 +160,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" cj_money, cj_paid, ordertype, - + latitude, + longitude, + address_name, created_at, updated_at @@ -187,7 +195,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{cjMoney}, #{cjPaid}, #{ordertype}, - + #{latitude}, + #{longitude}, + #{addressName}, NOW(), NOW() @@ -234,7 +244,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" cj_money = #{cjMoney}, cj_paid = #{cjPaid}, ordertype = #{ordertype}, - + latitude = #{latitude}, + longitude = #{longitude}, + address_name = #{addressName}, updated_at = NOW() diff --git a/ruoyi-system/src/main/resources/mapper/system/OrderMapper.xml b/ruoyi-system/src/main/resources/mapper/system/OrderMapper.xml index b310b54..fe481e4 100644 --- a/ruoyi-system/src/main/resources/mapper/system/OrderMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/OrderMapper.xml @@ -22,6 +22,7 @@ + @@ -78,6 +79,7 @@ + @@ -95,6 +97,7 @@ create_type, create_phone, uid, + workerdel, cartid, odertype, product_id, @@ -237,6 +240,11 @@ and cartid = #{cartid} + + and workerdel IS NULL + + + @@ -284,6 +292,29 @@ and uid = #{uid} + + + + + insert into order_data @@ -431,6 +462,9 @@ bigtype, + + workerdel, + created_at, updated_at @@ -580,6 +614,10 @@ #{bigtype}, + + #{workerdel}, + + NOW(), NOW() @@ -733,6 +771,10 @@ cartid = #{cartid}, + + workerdel = #{workerdel}, + + updated_at = NOW() where id = #{id} diff --git a/ruoyi-ui/src/api/system/Order.js b/ruoyi-ui/src/api/system/Order.js index b16aec7..db5fd0a 100644 --- a/ruoyi-ui/src/api/system/Order.js +++ b/ruoyi-ui/src/api/system/Order.js @@ -203,3 +203,57 @@ export function getCanDoWorkerList(params) { params: params }) } + +// 更换师傅 +export function changeWorker(orderId) { + return request({ + url: '/system/Order/change-worker', + method: 'post', + data: { orderId: orderId } + }) +} + +// 出发上门 +export function departureService(orderId) { + return request({ + url: '/system/Order/departure', + method: 'post', + data: { orderId: orderId } + }) +} + +// 确认到达 +export function confirmArrival(orderId) { + return request({ + url: '/system/Order/confirm-arrival', + method: 'post', + data: { orderId: orderId } + }) +} + +// 结束订单 +export function endOrder(orderId) { + return request({ + url: '/system/Order/end-order', + method: 'post', + data: { orderId: orderId } + }) +} + +// 开始服务 +export function startService(orderId) { + return request({ + url: '/system/Order/start-service', + method: 'post', + data: { orderId: orderId } + }) +} + +// 项目报价 +export function projectQuote(orderId) { + return request({ + url: '/system/Order/project-quote', + method: 'post', + data: { orderId: orderId } + }) +} diff --git a/ruoyi-ui/src/views/system/GoodsOrder/index.vue b/ruoyi-ui/src/views/system/GoodsOrder/index.vue index 06b7d91..6082f4e 100644 --- a/ruoyi-ui/src/views/system/GoodsOrder/index.vue +++ b/ruoyi-ui/src/views/system/GoodsOrder/index.vue @@ -457,178 +457,144 @@ - - + +
- 主订单信息 + 基本信息
+ + + + + + + + + + + + + + + + {{ item.title }} + ¥{{ item.price }} + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + 收货信息 + + + 刷新地址 + +
- - - - - - - - - - - + - + - - - - - - - - - - - - - -
- - - -
- - - 商品信息列表 - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + +
- +
@@ -637,63 +603,43 @@
- - - - - - - - - - - -
- - ¥{{ totalSubOrdersPrice.toFixed(2) }} + + {{ form.num || 0 }} +
+
+ +
+ + ¥{{ form.goodPrice ? form.goodPrice.toFixed(2) : '0.00' }}
- - ¥{{ form.payPrice ? form.payPrice.toFixed(2) : '0.00' }} + + ¥{{ form.totalPrice ? form.totalPrice.toFixed(2) : '0.00' }} +
+
+ +
+ + 待支付
- - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + +
@@ -955,49 +901,49 @@ - - - - - - - - - + + - - + + + - - - - + + + + + + + + + - - + + @@ -1666,16 +1612,22 @@ export default { { required: true, message: "用户不能为空", trigger: "blur" } ], productId: [ - { required: true, message: "商品不能为空", trigger: "blur" } + { required: true, message: "服务商品不能为空", trigger: "change" } + ], + appointmentTime: [ + { required: true, message: "预约时间不能为空", trigger: "change" } ], name: [ - { required: true, message: "姓名不能为空", trigger: "blur" } + { required: true, message: "收货人姓名不能为空", trigger: "blur" } ], phone: [ - { required: true, message: "电话不能为空", trigger: "blur" } + { required: true, message: "联系电话不能为空", trigger: "blur" } + ], + addressId: [ + { required: true, message: "收货地址不能为空", trigger: "change" } ], address: [ - { required: true, message: "地址不能为空", trigger: "blur" } + { required: true, message: "详细地址不能为空", trigger: "blur" } ], num: [ { required: true, message: "数量不能为空", trigger: "blur" } @@ -1689,9 +1641,6 @@ export default { status: [ { required: true, message: "订单状态 1:待支付 2:已支付,待发货3:待收货 4:待评价 5:已收货 6:取消 20:申请退款 21:同意退款 22:驳回退款不能为空", trigger: "change" } ], - addressId: [ - { required: true, message: "关联地址不能为空", trigger: "blur" } - ], deliveryId: [ { validator: (rule, value, callback) => { @@ -1861,7 +1810,14 @@ export default { { required: true, message: '请选择发货时间', trigger: 'change' } ] }, - batchShipProducts: [] + batchShipProducts: [], + // 新增订单相关 + submitLoading: false, + pickerOptions: { + disabledDate(time) { + return time.getTime() < Date.now() - 8.64e7; // 不能选择过去的日期 + } + }, } }, created() { @@ -2001,15 +1957,17 @@ export default { reset() { this.form = { id: null, - type: 2, + type: 1, // 默认为服务项目 mainOrderId: null, orderId: null, transactionId: null, uid: null, productId: null, + productName: null, name: null, phone: null, address: null, + addressId: null, num: 1, totalPrice: 0, goodPrice: 0, @@ -2018,13 +1976,13 @@ export default { deduction: 0, postage: 0, payTime: null, - status: null, + status: 1, // 默认为待支付 deliveryId: null, deliveryNum: null, sendTime: null, mark: null, - addressId: null, sku: null, + appointmentTime: null, // 预约时间 createdAt: null, updatedAt: null, deletedAt: null @@ -2088,7 +2046,8 @@ export default { //获取报价材料列表 generateCode(){ generateCode().then(response => { - this.form.orderId=response.msg; + this.form.mainOrderId = response.msg; + this.form.orderId = response.msg; }) }, /** 新增按钮操作 */ @@ -2096,13 +2055,13 @@ export default { // 先关闭所有其他对话框 this.closeAllDialogs() - this.generateCode() this.reset() + this.generateCode() // 确保主对话框能正常打开 this.$nextTick(() => { this.open = true - this.title = "添加商品订单" + this.title = "新增服务订单" this.ensureDialogState() }) }, @@ -2119,52 +2078,80 @@ export default { this.loadMainOrderData(row); } else { // 单个订单修改 - getGoodsOrder(id).then(response => { - this.form = response.data + getGoodsOrder(id).then(response => { + this.form = response.data this.subOrdersList = [{ ...response.data, totalPrice: response.data.totalPrice || 0 }]; this.calculateSubOrdersSummary(); - // 如果有用户ID,获取对应的地址列表 - if (this.form.uid) { - this.getUserAddressList(this.form.uid) - } + // 如果有用户ID,获取对应的地址列表 + if (this.form.uid) { + this.getUserAddressList(this.form.uid) + } - // 确保主对话框能正常打开 - this.$nextTick(() => { - this.open = true - this.title = "修改商品订单" - this.ensureDialogState() - }) - }).catch(error => { - console.error('获取订单详情失败:', error) - this.$modal.msgError('获取订单详情失败') + // 确保主对话框能正常打开 + this.$nextTick(() => { + this.open = true + this.title = "修改商品订单" + this.ensureDialogState() }) + }).catch(error => { + console.error('获取订单详情失败:', error) + this.$modal.msgError('获取订单详情失败') + }) } }, /** 提交按钮 */ submitForm() { this.$refs["form"].validate(valid => { if (valid) { + this.submitLoading = true; + if (this.form.id != null) { + // 修改订单 updateGoodsOrder(this.form).then(response => { - this.$modal.msgSuccess("修改成功") - this.open = false - this.reset() - this.getList() - }) + this.$modal.msgSuccess("修改成功"); + this.open = false; + this.reset(); + this.getList(); + }).catch(error => { + console.error('修改订单失败:', error); + this.$modal.msgError('修改失败,请重试'); + }).finally(() => { + this.submitLoading = false; + }); } else { - addGoodsOrder(this.form).then(response => { - this.$modal.msgSuccess("新增成功") - this.open = false - this.reset() - this.getList() - }) + // 新增订单 - 设置默认值 + const newOrder = { + ...this.form, + type: 1, // 1:服务项目 + status: 1, // 1:待支付 + orderId: this.form.mainOrderId, // 使用主订单号作为订单号 + transactionId: '', // 微信支付单号,支付时填写 + servicePrice: 0, // 服务费 + postage: 0, // 邮费 + payPrice: this.form.totalPrice, // 支付金额等于总金额 + deduction: 0, // 抵扣金额 + createdAt: new Date().toISOString().slice(0, 19).replace('T', ' '), // 创建时间 + updatedAt: new Date().toISOString().slice(0, 19).replace('T', ' ') // 更新时间 + }; + + addGoodsOrder(newOrder).then(response => { + this.$modal.msgSuccess("新增订单成功"); + this.open = false; + this.reset(); + this.getList(); + }).catch(error => { + console.error('新增订单失败:', error); + this.$modal.msgError('新增订单失败,请重试'); + }).finally(() => { + this.submitLoading = false; + }); } } - }) + }); }, /** 删除按钮操作 */ handleDelete(row) { @@ -2414,20 +2401,20 @@ export default { } // 设置单个发货表单数据 - this.shipForm = { - id: row.id, - orderId: row.orderId, - productName: row.productName, - name: row.name, - phone: row.phone, - address: row.address, - deliveryId: null, - deliveryNum: '', - sendTime: '', - mark: '' - }; + this.shipForm = { + id: row.id, + orderId: row.orderId, + productName: row.productName, + name: row.name, + phone: row.phone, + address: row.address, + deliveryId: null, + deliveryNum: '', + sendTime: '', + mark: '' + }; - this.shipDialogVisible = true; + this.shipDialogVisible = true; } catch (error) { console.error('获取发货数据失败:', error); @@ -2578,7 +2565,7 @@ export default { } // 调用API获取预支付数据 - getPrePaymentByOrderId(row.orderId).then(response => { + getPrePaymentByOrderId(row.mainOrderId).then(response => { if (response.code === 200) { this.prePaymentData = response.data; this.prePaymentDialogVisible = true; @@ -2946,7 +2933,7 @@ export default { /** 获取商品图片 */ async getProductImage(productId) { if (!productId) { - return ''; + return ''; } try { @@ -3119,8 +3106,8 @@ export default { if (subOrders.length === 0) { this.$modal.msgError('未找到主订单下的子订单数据'); - return; - } + return; + } // 获取主订单的基本信息(使用第一个子订单的信息) const firstOrder = subOrders[0]; @@ -3279,7 +3266,7 @@ export default { if (!productId) { return null; } - + try { const response = await getProductInfo(productId); return response.data || null; @@ -3288,6 +3275,57 @@ export default { return null; } }, + + /** 处理商品选择变化 */ + handleProductSelectChange(productId) { + if (productId) { + // 获取商品信息并设置价格 + const selectedProduct = this.goodsDataList.find(item => item.id === productId); + if (selectedProduct) { + this.form.goodPrice = selectedProduct.price; + this.form.productName = selectedProduct.title; + this.calculateTotalPrice(); + } + } else { + // 清空商品相关信息 + this.form.goodPrice = 0; + this.form.productName = ''; + this.form.totalPrice = 0; + } + }, + + /** 计算总价格 */ + calculateTotalPrice() { + if (this.form.goodPrice && this.form.num) { + this.form.totalPrice = this.form.goodPrice * this.form.num; + } else { + this.form.totalPrice = 0; + } + }, + + /** 处理地址选择变化 */ + handleAddressSelectChange(addressId) { + if (addressId) { + const selectedAddress = this.userAddressList.find(item => item.id === addressId); + if (selectedAddress) { + this.form.name = selectedAddress.name; + this.form.phone = selectedAddress.phone; + this.form.address = selectedAddress.addressName; + } + } else { + // 清空地址相关信息 + this.form.name = ''; + this.form.phone = ''; + this.form.address = ''; + } + }, + + /** 刷新用户地址列表 */ + refreshUserAddress() { + if (this.form.uid) { + this.getUserAddressList(this.form.uid); + } + }, }, watch: { 'form.status'(newVal, oldVal) { @@ -3799,4 +3837,31 @@ export default { .product-image { text-align: center; } + +/* 新增订单样式 */ +.el-form-item.is-required .el-form-item__label:before { + content: '*'; + color: #f56c6c; + margin-right: 4px; +} + +.el-form-item.is-required .el-form-item__label { + font-weight: 500; +} + +.appointment-time-picker { + width: 100%; +} + +.user-select-wrapper { + width: 100%; +} + +.product-select-wrapper { + width: 100%; +} + +.address-select-wrapper { + width: 100%; +} diff --git a/ruoyi-ui/src/views/system/Order/index.vue b/ruoyi-ui/src/views/system/Order/index.vue index 9c407c6..c84964a 100644 --- a/ruoyi-ui/src/views/system/Order/index.vue +++ b/ruoyi-ui/src/views/system/Order/index.vue @@ -173,14 +173,13 @@ 订单处理 + >查看详情 @@ -340,13 +339,11 @@ > + >查看详情 - + - - + +
订单基本信息
- + + + - - + + {{ orderProcessForm.orderId || '未设置' }} - - - - + + {{ orderProcessForm.num || '0' }} - - - - - - - - + + ¥{{ orderProcessForm.deduction || '0.00' }} - - + + {{ orderProcessForm.userName || '未设置' }} - + + + - - + + ¥{{ orderProcessForm.totalPrice || '0.00' }} - - + + {{ orderProcessForm.appointmentAddress || '未设置' }} - - + + {{ orderProcessForm.userPhone || '未设置' }} - - + + ¥{{ orderProcessForm.payPrice || '0.00' }} - + + + - - + + {{ orderProcessForm.createdAt || '未设置' }} - - + + {{ getStatusLabel(orderProcessForm.status) }} - - + + {{ getJsonStatusLabel(orderProcessForm.jsonStatus) }} - - + + {{ orderProcessForm.productName || '未设置' }} -
-
- - - - -
- 接单记录流程 -
-
-
-
- - 刷新接单记录 - - - 测试数据 - - - 测试API - -
-
- 共 {{ orderProcessForm.receiveRecords.length }} 条记录 - 订单号: {{ orderProcessForm.orderId }} -
-
- - - -
- {{ record.workerName || '系统' }} - - {{ record.title || '未知状态' }} - -
-
-

{{ record.content }}

-
- - ¥{{ record.price }} - - - 定金: ¥{{ record.deposit }} - -
-
-
-
- - - -
- - -
-

调试信息:

-

订单ID: {{ orderProcessForm.orderId }}

-

接单记录数组: {{ JSON.stringify(orderProcessForm.receiveRecords) }}

-

数组长度: {{ orderProcessForm.receiveRecords.length }}

-

数组类型: {{ Array.isArray(orderProcessForm.receiveRecords) ? 'Array' : typeof orderProcessForm.receiveRecords }}

-
-
-
-
- - - - -
- 师傅信息 -
- - - - - - - - - - - - - - - - - - - -
-
- - - - -
- 服务时间 -
- - - - - - - - - - - - - - - - - -
-
- - - - -
- 暂停信息 -
- - - - - - - - - - - - -
-
- - - - -
- 取消/结束信息 -
- - - - - - - - - - - - -
-
- - - - -
- 备注信息 -
- + + + - - + +
+
+ +
+ +
+
+
+ +
+
+
+ + + + + +
+ {{ orderProcessForm.mark }} +
+
+
+
+ + + + + + +
+ + + + + + +
+ + + 订单进度 + +
+ + 刷新 + + + 导出 + +
+
+ +
+
+
+ +
+ +
+ + +
+
+ {{ record.title || '未知操作' }} + {{ formatTimelineTime(record.createdAt) }} +
+
+
{{ getContentDescription(record.content) }}
+ + +
+
+ + 报价详情 +
+
+
{{ formatJson(record.quote) }}
+
+
+ + +
+ +
+ +
+
+
+ + +
+ + + + 派单 + + + + + + 更换师傅 + + + + + 接单 + + + + + 出发上门 + + + + + 确认到达 + + + +
+ + + 结束订单 + + + + + 开始服务 + + + + + 项目报价 + +
+ + + + 完成服务 + +
+
+
+ + +
+
+
+
+ +
+ + 刷新数据 + +
+
+
+ +
+ +
+ + + + +
+ +
+
+ +
+

订单信息

+ + +
+ + {{ dispatchForm.orderId }} +
+
+ +
+ + {{ dispatchForm.name }} +
+
+ +
+ + {{ dispatchForm.phone }} +
+
+ +
+ + {{ dispatchForm.address }} +
+
+ +
+ + {{ dispatchForm.productName }} +
+
+ +
+ + ¥{{ (dispatchForm.payPrice || 0).toFixed(2) }} +
+
+
+
+ + +
+

选择工人

+ + + + + + + + + + + + + + + + + 搜索 + 重置 + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
@@ -1912,7 +2068,13 @@ import { getUserAddressList, getPaymentDetails, refundPayment, - dispatchOrder + dispatchOrder, + changeWorker, + departureService, + confirmArrival, + endOrder, + startService, + projectQuote } from "@/api/system/Order" import CallRecord from './components/CallRecord' import AudioRecord from './components/AudioRecord' @@ -1920,6 +2082,7 @@ import ReceiveRecord from './components/ReceiveRecord' import NotifyRecord from './components/NotifyRecord' import CommentRecord from './components/CommentRecord' import EditInfo from './components/EditInfo' +import Pagination from '@/components/Pagination' export default { name: "Order", @@ -1930,7 +2093,8 @@ export default { ReceiveRecord, NotifyRecord, CommentRecord, - EditInfo + EditInfo, + Pagination }, data() { return { @@ -1971,6 +2135,36 @@ export default { open: false, // 是否显示订单处理弹出层 orderProcessOpen: false, + // 派单弹窗可见性 + dispatchDialogVisible: false, + // 派单表单数据 + dispatchForm: { + id: null, + orderId: null, + name: null, + phone: null, + address: null, + productName: null, + payPrice: null, + workerId: null, + workerName: '' + }, + // 工人查询参数 + workerQueryParams: { + pageNum: 1, + pageSize: 10, + name: '', + phone: '', + status: '' + }, + // 工人列表 + workerList: [], + // 工人总数 + workerTotal: 0, + // 工人加载状态 + workerLoading: false, + // 派单加载状态 + dispatchLoading: false, // 当前编辑的行 currentEditRow: null, currentPhoneEditRow: null, @@ -2418,22 +2612,36 @@ export default { }, /** 订单处理按钮操作 */ handleOrderProcess(row) { + // 确保所有日期字段都有有效值,避免ElDatePicker错误 + const safeDateField = (value) => { + return (value === null || value === undefined || value === '') ? '' : value; + }; + + // 添加调试日志 + console.log('=== 订单处理数据调试 ===') + console.log('原始行数据:', row) + console.log('fileData字段:', row.fileData) + console.log('mark字段:', row.mark) + console.log('fileData类型:', typeof row.fileData) + console.log('mark类型:', typeof row.mark) + this.orderProcessForm = { id: row.id, orderId: row.orderId, status: row.status, jsonStatus: row.jsonStatus, workerId: row.workerId, - departureTime: row.departureTime, - arrivalTime: row.arrivalTime, - startTime: row.startTime, - pauseTime: row.pauseTime, + departureTime: safeDateField(row.departureTime), + arrivalTime: safeDateField(row.arrivalTime), + startTime: safeDateField(row.startTime), + pauseTime: safeDateField(row.pauseTime), pauseReason: row.pauseReason, - completeTime: row.completeTime, - nextServiceTime: row.nextServiceTime, - cancelTime: row.cancelTime, + completeTime: safeDateField(row.completeTime), + nextServiceTime: safeDateField(row.nextServiceTime), + cancelTime: safeDateField(row.cancelTime), cancelReason: row.cancelReason, mark: row.mark, + fileData: row.fileData, servicePhotos: row.servicePhotos || [], // 订单基本信息 userName: row.uname || row.name, @@ -2456,6 +2664,12 @@ export default { remark: null } } + + // 添加调试日志 + console.log('设置后的orderProcessForm:', this.orderProcessForm) + console.log('设置后的fileData:', this.orderProcessForm.fileData) + console.log('设置后的mark:', this.orderProcessForm.mark) + this.orderProcessTitle = `订单处理 - ${row.orderId}` this.orderProcessOpen = true this.loadWorkerList() @@ -2500,22 +2714,81 @@ export default { console.log('接单记录API响应:', response) console.log('响应状态码:', response.status) console.log('响应数据:', response.data) - - if (response.data.code === 200) { - this.orderProcessForm.receiveRecords = response.data.data || [] - console.log('接单记录数据:', this.orderProcessForm.receiveRecords) - console.log('接单记录数量:', this.orderProcessForm.receiveRecords.length) - console.log('接单记录类型:', typeof this.orderProcessForm.receiveRecords) - - // 检查数组是否为空 - if (this.orderProcessForm.receiveRecords.length === 0) { - console.warn('接单记录数组为空') + console.log('响应数据结构分析:') + console.log('- response.code:', response.code) + console.log('- response.data:', response.data) + console.log('- response.data.code:', response.data.code) + console.log('- response.data.data:', response.data.data) + + // 根据实际API响应结构调整判断逻辑 + let records = [] + if (response.code === 200) { + // 如果response.code是200,直接使用response.data + records = response.data || [] + console.log('使用response.code判断,接单记录:', records) + } else if (response.data && response.data.code === 200) { + // 如果response.data.code是200,使用response.data.data + records = response.data.data || [] + console.log('使用response.data.code判断,接单记录:', records) + } else if (Array.isArray(response.data)) { + // 如果response.data直接是数组,直接使用 + records = response.data + console.log('response.data直接是数组,接单记录:', records) } else { - console.log('第一条记录:', this.orderProcessForm.receiveRecords[0]) - console.log('记录字段:', Object.keys(this.orderProcessForm.receiveRecords[0])) - } + console.error('接单记录API返回错误,无法解析数据结构:', response) + this.orderProcessForm.receiveRecords = [] + return + } + + // 处理接单记录数据 + if (Array.isArray(records) && records.length > 0) { + const processedRecords = records.map(record => { + // 解析content字段(JSON字符串) + let contentName = '未知操作' + let contentImage = [] + + if (record.content) { + try { + const contentData = JSON.parse(record.content) + if (Array.isArray(contentData)) { + // 如果content是数组,取第一个元素 + contentName = contentData[0]?.name || '未知操作' + contentImage = contentData[0]?.image || [] + } else if (typeof contentData === 'object') { + // 如果content是对象 + contentName = contentData.name || '未知操作' + contentImage = contentData.image || [] + } + } catch (e) { + // 如果解析失败,直接使用原始内容 + contentName = record.content + } + } + + return { + ...record, + title: record.title || '未知操作', + contentName: contentName, + contentImage: contentImage, + workerName: record.workerName || '系统', + price: record.price || 0, + deposit: record.deposit || 0, + createdAt: record.createdAt || record.createTime || new Date().toISOString() + } + }) + + console.log('处理后的接单记录:', processedRecords) + this.$set(this.orderProcessForm, 'receiveRecords', processedRecords) + this.$forceUpdate() + + // 验证数据是否正确设置 + this.$nextTick(() => { + console.log('数据设置后的验证:') + console.log('- receiveRecords长度:', this.orderProcessForm.receiveRecords.length) + console.log('- 第一条记录:', this.orderProcessForm.receiveRecords[0]) + }) } else { - console.error('接单记录API返回错误:', response.data) + console.warn('接单记录为空或格式不正确') this.orderProcessForm.receiveRecords = [] } }).catch(error => { @@ -2588,12 +2861,9 @@ export default { }, /** 手动测试API调用 */ - async testApiCall() { - console.log('=== 手动测试API调用 ===') - const orderId = this.orderProcessForm.orderId - + async testApiCall(orderId) { if (!orderId) { - console.error('订单ID为空,无法测试') + console.error('订单号为空,无法测试API') return } @@ -2604,12 +2874,33 @@ export default { console.log('API响应成功:', response) console.log('响应状态:', response.status) console.log('响应数据:', response.data) - - if (response.data.code === 200) { - const records = response.data.data || [] + console.log('响应数据结构分析:') + console.log('- response.code:', response.code) + console.log('- response.data:', response.data) + console.log('- response.data.code:', response.data.code) + console.log('- response.data.data:', response.data.data) + + // 根据实际API响应结构调整判断逻辑 + let records = [] + if (response.code === 200) { + // 如果response.code是200,直接使用response.data + records = response.data || [] + console.log('使用response.code判断,接单记录:', records) + } else if (response.data && response.data.code === 200) { + // 如果response.data.code是200,使用response.data.data + records = response.data.data || [] + console.log('使用response.data.code判断,接单记录:', records) + } else if (Array.isArray(response.data)) { + // 如果response.data直接是数组,直接使用 + records = response.data + console.log('response.data直接是数组,接单记录:', records) + } else { + console.error('API返回错误,无法解析数据结构:', response) + return + } + + if (Array.isArray(records) && records.length > 0) { console.log('接单记录数量:', records.length) - - if (records.length > 0) { console.log('第一条记录:', records[0]) console.log('记录字段:', Object.keys(records[0])) } else { @@ -2617,9 +2908,6 @@ export default { console.warn('1. 数据库中该订单没有日志记录') console.warn('2. 订单号不匹配') console.warn('3. 数据库查询条件不正确') - } - } else { - console.error('API返回错误:', response.data) } } catch (error) { console.error('API调用失败:', error) @@ -2650,14 +2938,116 @@ export default { }, /** 获取状态标签类型 */ - getStatusTagType(title) { - if (!title) return 'info' - if (title.includes('订单生成') || title.includes('创建')) return 'primary' - if (title.includes('支付成功') || title.includes('接单')) return 'success' - if (title.includes('出发') || title.includes('到达')) return 'warning' - if (title.includes('开始服务')) return 'info' - if (title.includes('服务完成') || title.includes('完成')) return 'danger' - return 'info' + getStatusTagType(status) { + if (!status) return 'info' + const statusMap = { + 1: 'warning', // 待支付 + 2: 'primary', // 待服务 + 3: 'success', // 服务中 + 4: 'success', // 已完成 + 5: 'danger', // 已取消 + 6: 'info', // 已退款 + 7: 'info' // 已结束 + } + return statusMap[status] || 'info' + }, + + /** 获取进度标签类型 */ + getProgressTagType(jsonStatus) { + if (!jsonStatus) return 'info' + const progressMap = { + 1: 'info', // 未开始 + 2: 'primary', // 进行中 + 3: 'success', // 已完成 + 8: 'warning', // 已暂停 + 9: 'success' // 已恢复 + } + return progressMap[jsonStatus] || 'info' + }, + + /** 获取订单状态标签 */ + getStatusLabel(status) { + if (!status) return '未知状态' + const statusMap = { + 1: '待支付', + 2: '待服务', + 3: '服务中', + 4: '已完成', + 5: '已取消', + 6: '已退款', + 7: '已结束' + } + return statusMap[status] || `状态${status}` + }, + + /** 获取服务进度标签 */ + getJsonStatusLabel(jsonStatus) { + if (!jsonStatus) return '未设置' + const jsonStatusMap = { + 1: '未开始', + 2: '进行中', + 3: '已完成', + 8: '已暂停', + 9: '已恢复' + } + return jsonStatusMap[jsonStatus] || `进度${jsonStatus}` + }, + + /** 获取师傅姓名 */ + getWorkerName(workerId) { + if (!workerId) return '未分配' + const worker = this.workerList.find(w => w.id === workerId) + return worker ? worker.name : `师傅${workerId}` + }, + + /** 导出订单数据 */ + exportOrderData() { + const orderData = { + 订单号: this.orderProcessForm.orderId, + 订单状态: this.getStatusLabel(this.orderProcessForm.status), + 服务进度: this.getJsonStatusLabel(this.orderProcessForm.jsonStatus), + 下单时间: this.orderProcessForm.createdAt, + 用户姓名: this.orderProcessForm.userName, + 用户电话: this.orderProcessForm.userPhone, + 服务名称: this.orderProcessForm.productName, + 预约数量: this.orderProcessForm.num, + 预约时间: this.orderProcessForm.appointmentTime, + 预约地点: this.orderProcessForm.appointmentAddress, + 订单总价: this.orderProcessForm.totalPrice, + 支付金额: this.orderProcessForm.payPrice, + 师傅姓名: this.getWorkerName(this.orderProcessForm.workerId), + 出发时间: this.orderProcessForm.departureTime || '未设置', + 到达时间: this.orderProcessForm.arrivalTime || '未设置', + 开始时间: this.orderProcessForm.startTime || '未设置', + 完成时间: this.orderProcessForm.completeTime || '未设置', + 备注: this.orderProcessForm.mark || '无' + } + + // 创建CSV内容 + let csvContent = '订单详情\n' + for (const [key, value] of Object.entries(orderData)) { + csvContent += `${key},${value}\n` + } + + // 添加接单记录 + if (this.orderProcessForm.receiveRecords.length > 0) { + csvContent += '\n接单记录\n' + csvContent += '时间,状态,内容,师傅,价格,定金\n' + this.orderProcessForm.receiveRecords.forEach(record => { + csvContent += `${this.formatTimelineTime(record.createdAt)},${record.title},${record.content},${record.workerName || '系统'},${record.price || 0},${record.deposit || 0}\n` + }) + } + + // 下载文件 + const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }) + const link = document.createElement('a') + const url = URL.createObjectURL(blob) + link.setAttribute('href', url) + link.setAttribute('download', `订单详情_${this.orderProcessForm.orderId}_${new Date().toISOString().slice(0, 10)}.csv`) + link.style.visibility = 'hidden' + document.body.appendChild(link) + link.click() + document.body.removeChild(link) }, /** 订单处理提交 */ @@ -2927,6 +3317,19 @@ export default { const id = row.id || this.ids; getOrder(id).then(response => { this.form = response.data; + + // 确保所有日期字段都有有效值,避免ElDatePicker错误 + const dateFields = [ + 'nextServiceTime', 'cancelTime', 'pauseTime', 'departureTime', + 'arrivalTime', 'startTime', 'completeTime', 'makeTime', 'payTime' + ]; + + dateFields.forEach(field => { + if (this.form[field] === null || this.form[field] === undefined || this.form[field] === '') { + this.form[field] = ''; + } + }); + // 处理文件数据回显 if (this.form.fileData) { try { @@ -4155,6 +4558,416 @@ export default { throw error; }); }, + + /** 查看订单详情 */ + handleViewOrderDetail(row) { + this.orderProcessForm = { + id: row.id, + orderId: row.orderId, + status: row.status, + jsonStatus: row.jsonStatus, + workerId: row.workerId, + departureTime: row.departureTime, + arrivalTime: row.arrivalTime, + startTime: row.startTime, + pauseTime: row.pauseTime, + pauseReason: row.pauseReason, + completeTime: row.completeTime, + nextServiceTime: row.nextServiceTime, + cancelTime: row.cancelTime, + cancelReason: row.cancelReason, + mark: row.mark, + fileData: row.fileData, + servicePhotos: row.servicePhotos || [], + // 订单基本信息 + userName: row.uname || row.name, + userPhone: row.phone || row.userPhone, + productName: row.productName, + num: row.num, + appointmentTime: row.makeTime ? this.formatAppointmentTime(row.makeTime, row.makeHour) : '未设置', + appointmentAddress: row.address, + totalPrice: row.totalPrice, + payPrice: row.payPrice, + createdAt: this.formatCreatedTime(row.createdAt), + // 接单记录 + receiveRecords: [], + orderLog: { + workerId: row.workerId, + workerName: row.workerName, + price: row.totalPrice || 0, + deposit: row.deposit || 0, + content: "", + remark: null + } + } + this.orderProcessOpen = true + this.loadWorkerList() + this.loadReceiveRecords(row.orderId) + }, + + /** 获取时间轴节点样式类 */ + getTimelineNodeClass(title) { + if (!title) return 'timeline-node-default' + if (title.includes('订单生成') || title.includes('创建')) return 'timeline-node-primary' + if (title.includes('支付成功') || title.includes('接单') || title.includes('派单')) return 'timeline-node-success' + if (title.includes('出发') || title.includes('到达')) return 'timeline-node-warning' + if (title.includes('开始服务')) return 'timeline-node-info' + if (title.includes('服务完成') || title.includes('完成')) return 'timeline-node-danger' + return 'timeline-node-default' + }, + + /** 获取时间轴图标 */ + getTimelineIcon(title) { + if (!title) return 'el-icon-info' + if (title.includes('订单生成') || title.includes('创建')) return 'el-icon-plus' + if (title.includes('支付成功') || title.includes('接单') || title.includes('派单')) return 'el-icon-check' + if (title.includes('出发') || title.includes('到达')) return 'el-icon-location' + if (title.includes('开始服务')) return 'el-icon-video-play' + if (title.includes('服务完成') || title.includes('完成')) return 'el-icon-circle-check' + return 'el-icon-info' + }, + + /** 获取内容描述 */ + getContentDescription(content) { + if (!content) return '无描述信息' + + try { + const contentData = JSON.parse(content) + if (Array.isArray(contentData)) { + return contentData[0]?.name || content + } else if (typeof contentData === 'object') { + return contentData.name || content + } + } catch (e) { + // 如果解析失败,直接返回原始内容 + } + + return content + }, + + /** 获取文件列表 */ + getFileList() { + if (!this.orderProcessForm.fileData) { + return [] + } + + try { + let files + if (typeof this.orderProcessForm.fileData === 'string') { + try { + files = JSON.parse(this.orderProcessForm.fileData) + } catch (e) { + // 如果不是JSON,按逗号分割 + files = this.orderProcessForm.fileData.split(',').filter(Boolean) + } + } else if (Array.isArray(this.orderProcessForm.fileData)) { + files = this.orderProcessForm.fileData + } else { + files = [] + } + + return Array.isArray(files) ? files : [] + } catch (e) { + console.error('解析文件数据失败:', e) + return [] + } + }, + + /** 判断是否为图片文件 */ + isImage(fileUrl) { + if (!fileUrl || typeof fileUrl !== 'string') return false + const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'] + const lowerUrl = fileUrl.toLowerCase() + return imageExtensions.some(ext => lowerUrl.includes(ext)) + }, + + /** 获取商品列表 */ + getProductList() { + // 这里可以根据实际数据结构来获取商品列表 + // 暂时返回模拟数据 + if (this.orderProcessForm.products && this.orderProcessForm.products.length > 0) { + return this.orderProcessForm.products + } + + // 如果没有商品数据,返回默认商品信息 + return [ + { + id: 1, + name: this.orderProcessForm.productName || '商品名称', + spec: '规格信息', + quantity: this.orderProcessForm.num || 1, + price: this.orderProcessForm.totalPrice || '0.00', + subtotal: this.orderProcessForm.totalPrice || '0.00', + status: 'pending', + image: '/static/images/default-product.png' + } + ] + }, + + /** 获取商品状态标签类型 */ + getProductStatusType(status) { + if (!status) return 'info' + const statusMap = { + 'pending': 'warning', // 待发货 + 'shipped': 'primary', // 已发货 + 'received': 'success', // 已收货 + 'refund': 'danger', // 退款中 + 'completed': 'success' // 已完成 + } + return statusMap[status] || 'info' + }, + + /** 获取商品状态标签文本 */ + getProductStatusLabel(status) { + if (!status) return '未知状态' + const statusMap = { + 'pending': '待发货', + 'shipped': '已发货', + 'received': '已收货', + 'refund': '退款中', + 'completed': '已完成' + } + return statusMap[status] || '未知状态' + }, + + /** 增加商品数量 */ + increaseQuantity(product) { + if (product.quantity < 99) { + product.quantity++ + this.updateProductSubtotal(product) + } + }, + + /** 减少商品数量 */ + decreaseQuantity(product) { + if (product.quantity > 1) { + product.quantity-- + this.updateProductSubtotal(product) + } + }, + + /** 更新商品小计 */ + updateProductSubtotal(product) { + const price = parseFloat(product.price) || 0 + const quantity = product.quantity || 1 + product.subtotal = (price * quantity).toFixed(2) + }, + + /** 从时间轴处理派单 */ + handleDispatchFromTimeline(record) { + // 设置派单表单数据 + this.dispatchForm = { + id: this.orderProcessForm.id, + orderId: this.orderProcessForm.orderId, + name: this.orderProcessForm.userName, + phone: this.orderProcessForm.userPhone, + address: this.orderProcessForm.appointmentAddress, + productName: this.orderProcessForm.productName, + payPrice: this.orderProcessForm.payPrice, + workerId: null, + workerName: '' + }; + + this.dispatchDialogVisible = true; + // 自动加载工人列表 + this.getWorkerList(); + }, + + /** 搜索工人 */ + searchWorkers() { + this.workerQueryParams.pageNum = 1; + this.getWorkerList(); + }, + + /** 重置工人搜索 */ + resetWorkerSearch() { + this.workerQueryParams = { + pageNum: 1, + pageSize: 10, + name: '', + phone: '', + status: '' + }; + this.getWorkerList(); + }, + + /** 调用派单接口 */ + processDispatch(worker) { + if (!this.dispatchForm.workerId) { + this.$message.error('请先选择工人'); + return; + } + + this.dispatchLoading = true; + const params = { + orderId: this.dispatchForm.id, + receiveType: 3, // 固定为指定工人 + workerId: this.dispatchForm.workerId + }; + + return dispatchOrder(params).then(response => { + this.$modal.msgSuccess(`派单成功!已派单给工人:${worker.name}`); + this.dispatchDialogVisible = false; + // 刷新接单记录 + this.loadReceiveRecords(this.orderProcessForm.orderId); + this.dispatchLoading = false; + return response; + }).catch(error => { + console.error('派单失败:', error); + this.$modal.msgError('派单失败:' + (error.message || '未知错误')); + this.dispatchLoading = false; + throw error; + }); + }, + + /** 接单操作 */ + handleAcceptOrder(record) { + this.$modal.confirm('确认接单吗?').then(() => { + // 这里调用接单接口 + this.$modal.msgSuccess('接单成功'); + // 刷新接单记录 + this.loadReceiveRecords(this.orderProcessForm.orderId); + }).catch(() => { + // 用户取消 + }); + }, + + /** 开始服务操作 */ + handleStartService(record) { + this.$modal.confirm('确认开始服务吗?').then(() => { + // 这里调用开始服务接口 + this.$modal.msgSuccess('开始服务成功'); + // 刷新接单记录 + this.loadReceiveRecords(this.orderProcessForm.orderId); + }).catch(() => { + // 用户取消 + }); + }, + + /** 暂停服务操作 */ + handlePauseService(record) { + this.$modal.confirm('确认暂停服务吗?').then(() => { + // 这里调用暂停服务接口 + this.$modal.msgSuccess('暂停服务成功'); + // 刷新接单记录 + this.loadReceiveRecords(this.orderProcessForm.orderId); + }).catch(() => { + // 用户取消 + }); + }, + + /** 完成服务操作 */ + handleCompleteService(record) { + this.$modal.confirm('确认完成服务吗?').then(() => { + // 这里调用完成服务接口 + this.$modal.msgSuccess('完成服务成功'); + // 刷新接单记录 + this.loadReceiveRecords(this.orderProcessForm.orderId); + }).catch(() => { + // 用户取消 + }); + }, + + /** 更换师傅操作 */ + handleChangeWorker(record) { + this.$modal.confirm('确认更换师傅吗?').then(() => { + // 调用更换师傅接口 + this.changeWorker(this.orderProcessForm.orderId).then(response => { + this.$modal.msgSuccess('更换师傅成功'); + // 刷新接单记录 + this.loadReceiveRecords(this.orderProcessForm.orderId); + }).catch(error => { + this.$modal.msgError('更换师傅失败:' + (error.message || '未知错误')); + }); + }).catch(() => { + // 用户取消 + }); + }, + + /** 出发上门操作 */ + handleDeparture(record) { + this.$modal.confirm('确认出发上门吗?').then(() => { + // 调用出发上门接口 + this.departureService(this.orderProcessForm.orderId).then(response => { + this.$modal.msgSuccess('出发上门成功'); + // 刷新接单记录 + this.loadReceiveRecords(this.orderProcessForm.orderId); + }).catch(error => { + this.$modal.msgError('出发上门失败:' + (error.message || '未知错误')); + }); + }).catch(() => { + // 用户取消 + }); + }, + + /** 确认到达操作 */ + handleConfirmArrival(record) { + this.$modal.confirm('确认已到达服务地点吗?').then(() => { + // 调用确认到达接口 + this.confirmArrival(this.orderProcessForm.orderId).then(response => { + this.$modal.msgSuccess('确认到达成功'); + // 刷新接单记录 + this.loadReceiveRecords(this.orderProcessForm.orderId); + }).catch(error => { + this.$modal.msgError('确认到达失败:' + (error.message || '未知错误')); + }); + }).catch(() => { + // 用户取消 + }); + }, + + /** 结束订单操作 */ + handleEndOrder(record) { + this.$modal.confirm('确认结束订单吗?此操作不可撤销。').then(() => { + // 调用结束订单接口 + this.endOrder(this.orderProcessForm.orderId).then(response => { + this.$modal.msgSuccess('订单已结束'); + // 刷新接单记录 + this.loadReceiveRecords(this.orderProcessForm.orderId); + }).catch(error => { + this.$modal.msgError('结束订单失败:' + (error.message || '未知错误')); + }); + }).catch(() => { + // 用户取消 + }); + }, + + /** 项目报价操作 */ + handleProjectQuote(record) { + this.$modal.confirm('确认进行项目报价吗?').then(() => { + // 调用项目报价接口 + this.projectQuote(this.orderProcessForm.orderId).then(response => { + this.$modal.msgSuccess('项目报价成功'); + // 刷新接单记录 + this.loadReceiveRecords(this.orderProcessForm.orderId); + }).catch(error => { + this.$modal.msgError('项目报价失败:' + (error.message || '未知错误')); + }); + }).catch(() => { + // 用户取消 + }); + }, + + /** 判断字符串是否为JSON格式 */ + isJsonString(str) { + if (!str || typeof str !== 'string') return false; + try { + JSON.parse(str); + return true; + } catch (e) { + return false; + } + }, + + /** 格式化JSON字符串 */ + formatJson(jsonString) { + try { + const obj = JSON.parse(jsonString); + return JSON.stringify(obj, null, 2); + } catch (e) { + return jsonString; // 如果解析失败,返回原字符串 + } + }, }, computed: { imageListOnly() { @@ -4879,123 +5692,14 @@ export default { } } -// 接单记录流程样式 -.process-timeline { - padding: 20px 0; - - .timeline-header-actions { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 20px; - padding: 0 20px; - - .left-actions { - display: flex; - gap: 10px; - } - - .right-info { - display: flex; - flex-direction: column; - align-items: flex-end; - gap: 5px; - - .record-count { - color: #606266; - font-size: 14px; - font-weight: 500; - } - - .order-id-info { - color: #909399; - font-size: 12px; - } - } - } - - .el-timeline { - padding-left: 20px; - - .el-timeline-item { - .el-timeline-item__node { - width: 16px; - height: 16px; - } - - .el-timeline-item__timestamp { - font-size: 12px; - color: #909399; - margin-bottom: 8px; - } - } - } - - .timeline-card { - margin-bottom: 0; - border: 1px solid #e4e7ed; - border-radius: 6px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); - - .el-card__body { - padding: 16px; - } - - .timeline-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 12px; - - .worker-name { - font-weight: 600; - color: #303133; - font-size: 14px; - } - } - - .timeline-content { - .content-text { - margin: 0 0 8px 0; - color: #606266; - font-size: 14px; - line-height: 1.5; - } - - .remark-text { - margin: 0 0 12px 0; - color: #909399; - font-size: 13px; - font-style: italic; - } - - .timeline-details { - display: flex; - flex-wrap: wrap; - gap: 16px; - - .detail-item { - display: flex; - align-items: center; - color: #606266; - font-size: 13px; - - i { - margin-right: 4px; - color: #909399; - } - } - } - } - } - - .el-empty { - padding: 40px 0; - - .el-empty__description { - color: #909399; - font-size: 14px; - } +// 旧的接单记录流程样式已删除,使用新的订单进度时间轴样式 + +.el-empty { + padding: 40px 0; + + .el-empty__description { + color: #909399; + font-size: 14px; } } @@ -5008,7 +5712,7 @@ export default { font-weight: 600; color: #606266; } - + .el-input.is-disabled { .el-input__inner { background-color: #f5f7fa; @@ -5020,5 +5724,642 @@ export default { } } } + +/* 订单进度时间轴样式 */ +.order-timeline { + padding: 20px 0; +} + +.timeline-container { + position: relative; +} + +.timeline-item { + position: relative; + display: flex; + align-items: flex-start; + margin-bottom: 30px; +} + +.timeline-item:last-child { + margin-bottom: 0; +} + +/* 时间轴节点 */ +.timeline-node { + width: 40px; + height: 40px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin-right: 20px; + flex-shrink: 0; + position: relative; + z-index: 2; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +.timeline-node i { + font-size: 18px; + color: white; +} + +.timeline-node-primary { + background: linear-gradient(135deg, #409EFF, #36a3f7); +} + +.timeline-node-success { + background: linear-gradient(135deg, #67C23A, #5daf34); +} + +.timeline-node-warning { + background: linear-gradient(135deg, #E6A23C, #d49426); +} + +.timeline-node-info { + background: linear-gradient(135deg, #909399, #7a7d83); +} + +.timeline-node-danger { + background: linear-gradient(135deg, #F56C6C, #e64242); +} + +.timeline-node-default { + background: linear-gradient(135deg, #909399, #7a7d83); +} + +/* 时间轴内容 */ +.timeline-content { + flex: 1; + background: white; + border-radius: 8px; + padding: 16px; + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); + border: 1px solid #ebeef5; +} + +.timeline-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12px; +} + +.timeline-title { + font-size: 16px; + font-weight: 600; + color: #303133; +} + +.timeline-time { + font-size: 12px; + color: #909399; + background: #f5f7fa; + padding: 4px 8px; + border-radius: 12px; +} + +.timeline-body { + color: #606266; + line-height: 1.6; +} + +.timeline-description { + margin-bottom: 12px; + font-size: 14px; +} + +/* 时间轴图片 */ +.timeline-images { + display: flex; + gap: 8px; + flex-wrap: wrap; +} + +.timeline-image { + width: 80px; + height: 80px; + border-radius: 6px; + border: 1px solid #ebeef5; + object-fit: cover; +} + +/* 连接线 */ +.timeline-connector { + position: absolute; + left: 20px; + top: 40px; + width: 2px; + height: 30px; + background: linear-gradient(to bottom, #e4e7ed, #c0c4cc); + z-index: 1; +} + +/* 无记录状态 */ +.no-records { + text-align: center; + padding: 40px 20px; +} + +/* 响应式设计 */ +@media (max-width: 768px) { + .timeline-item { + flex-direction: column; + align-items: center; + text-align: center; + } + + .timeline-node { + margin-right: 0; + margin-bottom: 15px; + } + + .timeline-content { + width: 100%; + text-align: left; + } + + .timeline-header { + flex-direction: column; + align-items: flex-start; + gap: 8px; + } + + .timeline-connector { + left: 50%; + transform: translateX(-50%); + } +} + +/* 订单信息文字样式 */ +.order-info-text { + display: inline-block; + padding: 8px 12px; + background-color: #f5f7fa; + border: 1px solid #e4e7ed; + border-radius: 4px; + color: #606266; + font-size: 14px; + line-height: 1.4; + min-height: 20px; + word-break: break-all; + white-space: pre-wrap; +} + +.order-info-text:empty::before { + content: '未设置'; + color: #c0c4cc; + font-style: italic; +} + +/* 附件和备注信息样式 */ +.file-list { + display: flex; + flex-direction: column; + gap: 12px; +} + +.file-item { + display: flex; + align-items: center; + padding: 12px; + background: #f8f9fa; + border: 1px solid #e9ecef; + border-radius: 6px; + transition: all 0.3s ease; +} + +.file-item:hover { + background: #e9ecef; + border-color: #dee2e6; +} + +.file-image { + width: 60px; + height: 60px; + border-radius: 4px; + border: 1px solid #dee2e6; + object-fit: cover; + margin-right: 12px; +} + +.file-icon { + width: 60px; + height: 60px; + border-radius: 4px; + background: #6c757d; + color: white; + display: flex; + align-items: center; + justify-content: center; + margin-right: 12px; + font-size: 24px; +} + +.file-info { + flex: 1; + display: flex; + flex-direction: column; + gap: 4px; +} + +.file-name { + font-weight: 600; + color: #495057; + font-size: 14px; +} + +.file-url { + color: #6c757d; + font-size: 12px; + word-break: break-all; + line-height: 1.4; +} + +.mark-content { + padding: 12px 16px; + background: #f8f9fa; + border: 1px solid #e9ecef; + border-radius: 6px; + color: #495057; + font-size: 14px; + line-height: 1.6; + min-height: 20px; + white-space: pre-wrap; + word-break: break-word; +} + +/* 订单详情对话框美化样式 */ +.order-detail-dialog { + .el-dialog__body { + padding: 20px 30px; + max-height: 80vh; + overflow-y: auto; + } + + .el-dialog__footer { + padding: 15px 30px; + border-top: 1px solid #e4e7ed; + background: #f8f9fa; + } +} + +.order-detail-form { + .el-form-item { + margin-bottom: 20px; + } +} + +/* 信息行样式 */ +.info-row { + margin-bottom: 20px; + + &:last-child { + margin-bottom: 0; + } +} + +/* 订单信息文字样式 */ +.order-info-text { + display: inline-block; + padding: 8px 12px; + background: #f5f7fa; + border: 1px solid #e4e7ed; + border-radius: 4px; + color: #606266; + font-size: 14px; + line-height: 1.4; + min-height: 20px; + word-break: break-all; + white-space: pre-wrap; +} + +/* 附件和备注样式 */ +.file-list { + .file-item { + padding: 12px; + background: #f8f9fa; + border: 1px solid #e4e7ed; + border-radius: 6px; + margin-bottom: 10px; + + &:last-child { + margin-bottom: 0; + } + } + + .file-image { + width: 60px; + height: 60px; + border-radius: 4px; + border: 1px solid #e4e7ed; + } + + .file-icon { + width: 60px; + height: 60px; + border-radius: 4px; + font-size: 24px; + display: flex; + align-items: center; + justify-content: center; + background: #f5f7fa; + border: 1px solid #e4e7ed; + color: #909399; + } + + .file-info { + margin-top: 8px; + + .file-name { + display: block; + font-weight: 600; + color: #303133; + margin-bottom: 4px; + } + + .file-url { + display: block; + font-size: 12px; + color: #909399; + word-break: break-all; + } + } +} + +.mark-content { + padding: 12px 16px; + background: #f8f9fa; + border: 1px solid #e4e7ed; + border-radius: 6px; + color: #606266; + font-size: 14px; + line-height: 1.6; + min-height: 20px; + white-space: pre-wrap; + word-break: break-word; +} + +/* 响应式优化 */ +@media (max-width: 1200px) { + .order-detail-dialog { + .el-dialog { + width: 95% !important; + } + } + + .info-row { + .el-col { + margin-bottom: 15px; + } + } +} + +@media (max-width: 768px) { + .order-detail-dialog { + .el-dialog__body { + padding: 15px 20px; + } + + .el-dialog__footer { + padding: 10px 20px; + } + } + + .card-title { + font-size: 14px; + + i { + font-size: 16px; + } + } + + .order-info-text { + padding: 8px 12px; + font-size: 13px; + } +} + +/* 简洁的订单基本信息样式 */ +.simple-text { + display: inline-block; + padding: 6px 10px; + background: #f8f9fa; + border: 1px solid #e4e7ed; + border-radius: 4px; + color: #606266; + font-size: 14px; + line-height: 1.3; + min-height: 18px; + word-break: break-all; + white-space: pre-wrap; +} + +/* 简洁的附件样式 */ +.simple-file-list { + display: flex; + flex-wrap: wrap; + gap: 12px; + + .simple-file-item { + flex-shrink: 0; + } + + .simple-file-image { + width: 60px; + height: 60px; + border-radius: 6px; + border: 2px solid #e4e7ed; + cursor: pointer; + transition: border-color 0.2s ease; + + &:hover { + border-color: #409eff; + } + } + + .simple-file-icon { + width: 60px; + height: 60px; + border-radius: 6px; + font-size: 24px; + display: flex; + align-items: center; + justify-content: center; + background: #f5f7fa; + border: 2px solid #e4e7ed; + color: #909399; + } + } + +/* 简洁的备注样式 */ +.simple-mark-content { + color: #666; + font-size: 14px; + line-height: 1.5; + padding: 8px 12px; + background-color: #f8f9fa; + border-radius: 4px; + border-left: 3px solid #e9ecef; +} + +/* 派单相关样式 */ +.timeline-actions { + margin-top: 12px; + padding-top: 12px; + border-top: 1px solid #f0f0f0; +} + +.dispatch-content { + padding: 20px 0; +} + +.order-info-section { + margin-bottom: 30px; + padding: 20px; + background-color: #f8f9fa; + border-radius: 8px; +} + +.order-info-section h4 { + margin: 0 0 20px 0; + color: #333; + font-size: 16px; + font-weight: 600; +} + +.info-item { + margin-bottom: 15px; + display: flex; + align-items: center; +} + +.info-item label { + font-weight: 600; + color: #666; + min-width: 80px; + margin-right: 10px; +} + +.info-item span { + color: #333; + flex: 1; +} + +.amount-highlight { + color: #e6a23c; + font-weight: 600; + font-size: 16px; +} + +.worker-selection-section { + padding: 20px; + background-color: #fff; + border-radius: 8px; + border: 1px solid #e9ecef; +} + +.worker-selection-section h4 { + margin: 0 0 20px 0; + color: #333; + font-size: 16px; + font-weight: 600; +} + +.selected-worker-banner { + margin-bottom: 20px; +} + +.dispatch-content .el-table { + margin-top: 20px; +} + +.dispatch-content .el-table .el-button { + margin: 0; +} + +/* 多个操作按钮的样式 */ +.timeline-actions-multiple { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-top: 12px; + padding-top: 12px; + border-top: 1px solid #f0f0f0; +} + +.timeline-actions-multiple .el-button { + flex-shrink: 0; +} + +/* 响应式调整 */ +@media (max-width: 768px) { + .timeline-actions-multiple { + flex-direction: column; + gap: 6px; + } + + .timeline-actions-multiple .el-button { + width: 100%; + margin-right: 0 !important; + } +} + +/* 报价数据样式 */ +.timeline-quote { + margin-top: 12px; + padding: 12px; + background-color: #f8f9fa; + border-radius: 6px; + border-left: 3px solid #28a745; +} + +.quote-header { + display: flex; + align-items: center; + margin-bottom: 8px; + font-weight: 600; + color: #28a745; +} + +.quote-header i { + margin-right: 6px; + font-size: 16px; +} + +.quote-content { + background-color: #fff; + border: 1px solid #e9ecef; + border-radius: 4px; + padding: 8px; + max-height: 200px; + overflow-y: auto; +} + +.quote-content pre { + margin: 0; + font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; + font-size: 12px; + line-height: 1.4; + color: #495057; + white-space: pre-wrap; + word-break: break-word; +} + +/* 响应式调整 */ +@media (max-width: 768px) { + .timeline-quote { + padding: 8px; + } + + .quote-content { + max-height: 150px; + } + + .quote-content pre { + font-size: 11px; + } +}