Bläddra i källkod

下单流程基本走完

Huanyi 1 månad sedan
förälder
incheckning
44e6f35512
24 ändrade filer med 446 tillägg och 23 borttagningar
  1. 2 0
      ruoyi-api/yingpaipay-api-archieves/src/main/java/org/dromara/api/RemoteCustomerService.java
  2. 2 0
      ruoyi-api/yingpaipay-api-fulfiller/src/main/java/org/dromara/fulfiller/api/RemoteFulfillerService.java
  3. 3 3
      ruoyi-common/ruoyi-common-dubbo/src/main/java/org/dromara/common/dubbo/config/CustomBeanFactoryPostProcessor.java
  4. 12 0
      ruoyi-modules/yingpaipay-archieves/src/main/java/org/dromara/archieves/dubbo/RemoteCustomerServiceImpl.java
  5. 5 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/controller/FlfFulfillerController.java
  6. 1 1
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/FlfBalanceLog.java
  7. 32 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/dubbo/RemoteFulfillerServiceImpl.java
  8. 2 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfFulfillerService.java
  9. 6 0
      ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfFulfillerServiceImpl.java
  10. 21 4
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/controller/SysSubOrderController.java
  11. 4 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/SysSubOrder.java
  12. 20 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/bo/SysSubOrderClockInBo.java
  13. 10 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/bo/SysSubOrderConfirmBo.java
  14. 20 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/bo/SysSubOrderListOnMyOrderBo.java
  15. 12 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/bo/SysSubOrderNursingSummaryBo.java
  16. 53 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/vo/SysSubOrderListOnMyOrderPageVo.java
  17. 4 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/vo/SysSubOrderListPageVo.java
  18. 2 1
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/vo/SysSubOrderLogVo.java
  19. 5 4
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/enums/OrderStatusEnum.java
  20. 9 4
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/ISysSubOrderService.java
  21. 8 0
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/impl/SysOrderServiceImpl.java
  22. 28 2
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/impl/SysSubOrderLogServiceImpl.java
  23. 181 4
      ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/impl/SysSubOrderServiceImpl.java
  24. 4 0
      script/sql/business/update.sql

+ 2 - 0
ruoyi-api/yingpaipay-api-archieves/src/main/java/org/dromara/api/RemoteCustomerService.java

@@ -12,4 +12,6 @@ public interface RemoteCustomerService {
     List<RemoteCustomerVo> getByIds(List<Long> customerIds);
 
     List<RemoteCustomerVo> selectListByName(String name);
+
+    List<Long> getIdsByNameAndPhone(String content);
 }

+ 2 - 0
ruoyi-api/yingpaipay-api-fulfiller/src/main/java/org/dromara/fulfiller/api/RemoteFulfillerService.java

@@ -32,4 +32,6 @@ public interface RemoteFulfillerService {
     FulfillerLoginUser getFulfillerById(Long id) throws UserException;
 
     List<RemoteFulfillerVo> getByIds(List<Long> fulfillerIds);
+
+    boolean settlement(Long fulfiller, Long price, String orderCode);
 }

+ 3 - 3
ruoyi-common/ruoyi-common-dubbo/src/main/java/org/dromara/common/dubbo/config/CustomBeanFactoryPostProcessor.java

@@ -64,9 +64,9 @@ public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
 
         // 创建临时的 InetUtils 实例
         try (InetUtils inetUtils = new InetUtils(properties)) {
-//            String ip = "127.0.0.1";
-           String ip = "192.168.0.102";
-//           String ip = "192.168.1.118";
+//          String ip = "127.0.0.1";
+//          String ip = "192.168.0.102";
+           String ip = "192.168.1.118";
             // 获取第一个非回环地址
             InetAddress address = inetUtils.findFirstNonLoopbackAddress();
             if (address != null) {

+ 12 - 0
ruoyi-modules/yingpaipay-archieves/src/main/java/org/dromara/archieves/dubbo/RemoteCustomerServiceImpl.java

@@ -79,4 +79,16 @@ public class RemoteCustomerServiceImpl implements RemoteCustomerService {
         });
         return vos;
     }
+
+    @Override
+    public List<Long> getIdsByNameAndPhone(String content) {
+        List<Long> ids = new ArrayList<>();
+        baseMapper.selectList(
+                Wrappers.lambdaQuery(UsrCustomer.class)
+                    .select(UsrCustomer::getId)
+                    .like(UsrCustomer::getName, content).or().like(UsrCustomer::getPhone, content)
+            )
+            .forEach(e -> ids.add(e.getId()));
+        return ids;
+    }
 }

+ 5 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/controller/FlfFulfillerController.java

@@ -280,4 +280,9 @@ public class FlfFulfillerController extends BaseController {
         return fulfillerService.pageOnOrder(content, pageQuery);
     }
 
+    @GetMapping("/listAllOnOrder")
+    public R<List<FlfFulfillerOnOrderVo>> listAllOnOrder() {
+        return R.ok(fulfillerService.listAllOnOrder());
+    }
+
 }

+ 1 - 1
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/domain/FlfBalanceLog.java

@@ -37,7 +37,7 @@ public class FlfBalanceLog implements Serializable {
     private String type;
 
     /**
-     * 资金类型 (reward:奖励, punish:惩罚, salary:工资发放, withdraw:提现, other:其他)
+     * 资金类型 (reward:奖励, punish:惩罚, salary:工资发放, withdraw:提现, order:订单完成, other:其他)
      */
     private String subType;
 

+ 32 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/dubbo/RemoteFulfillerServiceImpl.java

@@ -10,12 +10,15 @@ import org.dromara.common.tenant.helper.TenantHelper;
 import org.dromara.fulfiller.api.RemoteFulfillerService;
 import org.dromara.fulfiller.api.domain.vo.RemoteFulfillerVo;
 import org.dromara.fulfiller.api.model.FulfillerLoginUser;
+import org.dromara.fulfiller.domain.FlfBalanceLog;
 import org.dromara.fulfiller.domain.FlfFulfiller;
+import org.dromara.fulfiller.mapper.FlfBalanceLogMapper;
 import org.dromara.fulfiller.mapper.FlfFulfillerMapper;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -30,6 +33,7 @@ import java.util.List;
 public class RemoteFulfillerServiceImpl implements RemoteFulfillerService {
 
     private final FlfFulfillerMapper fulfillerMapper;
+    private final FlfBalanceLogMapper balanceLogMapper;
 
     @Override
     public FulfillerLoginUser getFulfillerByPhone(String phone) throws UserException {
@@ -91,6 +95,34 @@ public class RemoteFulfillerServiceImpl implements RemoteFulfillerService {
         return vos;
     }
 
+    @Override
+    public boolean settlement(Long fulfiller, Long price, String orderCode) {
+
+        FlfFulfiller flfFulfiller = fulfillerMapper.selectById(fulfiller);
+        flfFulfiller.setBalance(flfFulfiller.getBalance() + price);
+
+        boolean flag = fulfillerMapper.updateById(flfFulfiller) == 0;
+        if (flag) {
+            throw new RuntimeException("新增余额失败");
+        }
+
+        FlfBalanceLog balanceLog = new FlfBalanceLog();
+        balanceLog.setFulfillerId(fulfiller);
+        balanceLog.setType("add");
+        balanceLog.setSubType("order");
+        balanceLog.setAmount(price);
+        balanceLog.setBalanceAfter(flfFulfiller.getBalance());
+        balanceLog.setReason("完成订单 " + orderCode);
+        balanceLog.setOperatorId(fulfiller);
+        balanceLog.setCreateTime(new Date());
+        boolean balanceFlag = balanceLogMapper.insert(balanceLog) == 0;
+        if (balanceFlag) {
+            throw new RuntimeException("记录日志失败");
+        }
+
+        return true;
+    }
+
     /**
      * 手动转换 FlfFulfiller → FulfillerLoginUser(避免跨模块 MapStruct 转换器缺失)
      */

+ 2 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/IFlfFulfillerService.java

@@ -128,4 +128,6 @@ public interface IFlfFulfillerService {
     Boolean updateAuthInfoByUserId(Long userId, java.util.Map<String, String> params);
 
     TableDataInfo<FlfFulfillerOnOrderVo> pageOnOrder(String content, PageQuery pageQuery);
+
+    List<FlfFulfillerOnOrderVo> listAllOnOrder();
 }

+ 6 - 0
ruoyi-modules/yingpaipay-fulfiller/src/main/java/org/dromara/fulfiller/service/impl/FlfFulfillerServiceImpl.java

@@ -40,8 +40,11 @@ import org.dromara.fulfiller.mapper.SysTagRelMapper;
 import org.dromara.fulfiller.service.IFlfFulfillerService;
 
 import org.dromara.service.api.RemoteSysServiceService;
+import org.dromara.resource.api.RemoteFileService;
+import org.dromara.resource.api.domain.RemoteFile;
 import org.dromara.system.api.RemoteAreaStationService;
 
+
 import java.util.Collections;
 import java.util.List;
 import java.util.*;
@@ -72,6 +75,9 @@ public class FlfFulfillerServiceImpl implements IFlfFulfillerService {
     @DubboReference
     private RemoteSysServiceService remoteSysServiceService;
 
+    @DubboReference
+    private RemoteFileService remoteFileService;
+
     @Override
     public FlfFulfillerVo queryById(Long id) {
         FlfFulfillerVo vo = baseMapper.selectVoById(id);

+ 21 - 4
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/controller/SysSubOrderController.java

@@ -7,10 +7,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.web.core.BaseController;
 import org.dromara.order.domain.bo.*;
-import org.dromara.order.domain.vo.SysSubOrderCountVo;
-import org.dromara.order.domain.vo.SysSubOrderListPageVo;
-import org.dromara.order.domain.vo.SysSubOrderPendingAcceptPageVo;
-import org.dromara.order.domain.vo.SysSubOrderVo;
+import org.dromara.order.domain.vo.*;
 import org.dromara.order.service.ISysSubOrderService;
 import org.springframework.web.bind.annotation.*;
 
@@ -68,4 +65,24 @@ public class SysSubOrderController extends BaseController {
         return toAjax(subOrderService.remark(bo));
     }
 
+    @GetMapping("/listOnMyOrder")
+    public TableDataInfo<SysSubOrderListOnMyOrderPageVo> listOnMyOrder(SysSubOrderListOnMyOrderBo bo, PageQuery pageQuery) {
+        return subOrderService.listOnMyOrder(bo, pageQuery);
+    }
+
+    @PutMapping("/clockIn")
+    public R<Void> clockIn(@RequestBody SysSubOrderClockInBo bo) {
+        return toAjax(subOrderService.clockIn(bo));
+    }
+
+    @PutMapping("/confirm")
+    public R<Void> confirm(@RequestBody SysSubOrderConfirmBo bo) {
+        return toAjax(subOrderService.confirm(bo));
+    }
+
+    @PutMapping("/nursingSummary")
+    public R<Void> nursingSummary(@RequestBody SysSubOrderNursingSummaryBo bo) {
+        return toAjax(subOrderService.nursingSummary(bo));
+    }
+
 }

+ 4 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/SysSubOrder.java

@@ -147,4 +147,8 @@ public class SysSubOrder extends TenantEntity {
 
     private String groupPurchasePackageName;
 
+    private String nursingSummary;
+
+    private Date nursingSummaryTime;
+
 }

+ 20 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/bo/SysSubOrderClockInBo.java

@@ -0,0 +1,20 @@
+package org.dromara.order.domain.bo;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class SysSubOrderClockInBo {
+
+    private Long orderId;
+
+    private List<Long> photos;
+
+    private String content;
+
+    private Integer type;
+
+    private String title;
+
+}

+ 10 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/bo/SysSubOrderConfirmBo.java

@@ -0,0 +1,10 @@
+package org.dromara.order.domain.bo;
+
+import lombok.Data;
+
+@Data
+public class SysSubOrderConfirmBo {
+
+    private Long id;
+
+}

+ 20 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/bo/SysSubOrderListOnMyOrderBo.java

@@ -0,0 +1,20 @@
+package org.dromara.order.domain.bo;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class SysSubOrderListOnMyOrderBo {
+
+    private Integer status;
+
+    private String content;
+
+    private Long service;
+
+    private Date startServiceTime;
+
+    private Date endServiceTime;
+
+}

+ 12 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/bo/SysSubOrderNursingSummaryBo.java

@@ -0,0 +1,12 @@
+package org.dromara.order.domain.bo;
+
+import lombok.Data;
+
+@Data
+public class SysSubOrderNursingSummaryBo {
+
+    private Long orderId;
+
+    private String content;
+
+}

+ 53 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/vo/SysSubOrderListOnMyOrderPageVo.java

@@ -0,0 +1,53 @@
+package org.dromara.order.domain.vo;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class SysSubOrderListOnMyOrderPageVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    private Long service;
+
+    private Long price;
+
+    private Date serviceTime;
+
+    private Long pet;
+
+    private String petName;
+
+    private String breed;
+
+    private Long store;
+
+    private String storeName;
+
+    private String storeAreaCode;
+
+    private String storeAddress;
+
+    private Long customer;
+
+    private String customerName;
+
+    private String customerPhone;
+
+    private String fromCode;
+
+    private String fromAddress;
+
+    private String toCode;
+
+    private String toAddress;
+
+    private String remark;
+
+}

+ 4 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/vo/SysSubOrderListPageVo.java

@@ -65,4 +65,8 @@ public class SysSubOrderListPageVo implements Serializable {
 
     private String remark;
 
+    private String nursingSummary;
+
+    private Date nursingSummaryTime;
+
 }

+ 2 - 1
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/domain/vo/SysSubOrderLogVo.java

@@ -11,7 +11,7 @@ import lombok.Data;
 import java.io.Serial;
 import java.io.Serializable;
 import java.util.Date;
-
+import java.util.List;
 
 
 /**
@@ -82,5 +82,6 @@ public class SysSubOrderLogVo implements Serializable {
     @ExcelProperty(value = "上传图片")
     private String photos;
 
+    private List<String> photoUrls;
 
 }

+ 5 - 4
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/enums/OrderStatusEnum.java

@@ -13,10 +13,11 @@ public enum OrderStatusEnum {
 
     PENDING_DISPATCH(0, "待派单", "#f56c6c"),
     PENDING_ACCEPT(1, "待接单", "#e6a23c"),
-    IN_SERVICE(2, "服务中", "#49a3ff"),
-    PENDING_CONFIRM(3, "待商家确认", "#bf24e8"),
-    COMPLETED(4, "已完成", "#67c23a"),
-    CANCELLED(5, "已取消", "#909399"),
+    PENDING_SERVICE(2, "待服务", "#49a3ff"),
+    IN_SERVICE(3, "服务中", "#49a3ff"),
+    PENDING_CONFIRM(4, "待商家确认", "#bf24e8"),
+    COMPLETED(5, "已完成", "#67c23a"),
+    CANCELLED(6, "已取消", "#909399"),
     ;
 
     private final Integer value;

+ 9 - 4
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/ISysSubOrderService.java

@@ -3,10 +3,7 @@ package org.dromara.order.service;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.order.domain.bo.*;
-import org.dromara.order.domain.vo.SysSubOrderCountVo;
-import org.dromara.order.domain.vo.SysSubOrderListPageVo;
-import org.dromara.order.domain.vo.SysSubOrderPendingAcceptPageVo;
-import org.dromara.order.domain.vo.SysSubOrderVo;
+import org.dromara.order.domain.vo.*;
 
 public interface ISysSubOrderService {
     TableDataInfo<SysSubOrderListPageVo> list(SysSubOrderListPageBo bo, PageQuery pageQuery);
@@ -26,4 +23,12 @@ public interface ISysSubOrderService {
     boolean remark(SysSubOrderRemarkBo bo);
 
     SysSubOrderCountVo count();
+
+    boolean clockIn(SysSubOrderClockInBo bo);
+
+    TableDataInfo<SysSubOrderListOnMyOrderPageVo> listOnMyOrder(SysSubOrderListOnMyOrderBo bo, PageQuery pageQuery);
+
+    boolean confirm(SysSubOrderConfirmBo bo);
+
+    boolean nursingSummary(SysSubOrderNursingSummaryBo bo);
 }

+ 8 - 0
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/impl/SysOrderServiceImpl.java

@@ -80,6 +80,14 @@ public class SysOrderServiceImpl implements ISysOrderService {
             subOrder.setRemark(order.getRemark());
             subOrder.setTenantId(order.getTenantId());
             subOrder.setPlatformId(PlatformUtils.getId());
+            subOrder.setNursingSummary("""
+                1. 精神/身体状态:
+                2. 进食/饮水:
+                3. 排泄情况:
+                4. 卫生情况:
+                5. 互动情况:
+                6. 特殊情况/备注:
+                """);
             subOrders.add(subOrder);
 
         });

+ 28 - 2
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/impl/SysSubOrderLogServiceImpl.java

@@ -1,14 +1,18 @@
 package org.dromara.order.service.impl;
 
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
+import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.order.domain.SysSubOrderLog;
 import org.dromara.order.domain.vo.SysSubOrderLogVo;
 import org.dromara.order.mapper.SysSubOrderLogMapper;
 import org.dromara.order.service.ISysSubOrderLogService;
+import org.dromara.resource.api.RemoteFileService;
+import org.dromara.resource.api.domain.RemoteFile;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
+import java.util.*;
 
 @Service
 @RequiredArgsConstructor
@@ -16,11 +20,33 @@ public class SysSubOrderLogServiceImpl implements ISysSubOrderLogService {
 
     private final SysSubOrderLogMapper baseMapper;
 
+    @DubboReference
+    private final RemoteFileService remoteFileService;
+
     @Override
     public List<SysSubOrderLogVo> list(Long orderId) {
-        return baseMapper.selectVoList(
+
+        List<SysSubOrderLogVo> vos = baseMapper.selectVoList(
             Wrappers.lambdaQuery(SysSubOrderLog.class)
                 .eq(SysSubOrderLog::getSubOrderId, orderId)
         );
+
+        List<Long> ossIds = new ArrayList<>();
+        Map<Long, RemoteFile> ossMap = new HashMap<>();
+        vos.forEach(e -> {
+            if (StringUtils.isNotBlank(e.getPhotos())) {
+                ossIds.addAll(Arrays.stream(e.getPhotos().split(",")).map(Long::parseLong).toList());
+            }
+        });
+        remoteFileService.selectByIds(ossIds).forEach(e -> ossMap.put(e.getOssId(), e));
+
+        vos.forEach(e -> {
+            if (StringUtils.isNotBlank(e.getPhotos())) {
+                List<String> urls = Arrays.stream(e.getPhotos().split(",")).map(id -> ossMap.get(Long.parseLong(id)).getUrl()).toList();
+                e.setPhotoUrls(urls);
+            }
+        });
+
+        return vos;
     }
 }

+ 181 - 4
ruoyi-modules/yingpaipay-order/src/main/java/org/dromara/order/service/impl/SysSubOrderServiceImpl.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import lombok.RequiredArgsConstructor;
 import org.apache.dubbo.config.annotation.DubboReference;
+import org.apache.seata.spring.annotation.GlobalTransactional;
 import org.dromara.api.RemoteCustomerService;
 import org.dromara.api.RemotePetService;
 import org.dromara.api.domain.vo.RemoteCustomerVo;
@@ -24,10 +25,7 @@ import org.dromara.order.domain.SysOrder;
 import org.dromara.order.domain.SysSubOrder;
 import org.dromara.order.domain.SysSubOrderLog;
 import org.dromara.order.domain.bo.*;
-import org.dromara.order.domain.vo.SysSubOrderCountVo;
-import org.dromara.order.domain.vo.SysSubOrderListPageVo;
-import org.dromara.order.domain.vo.SysSubOrderPendingAcceptPageVo;
-import org.dromara.order.domain.vo.SysSubOrderVo;
+import org.dromara.order.domain.vo.*;
 import org.dromara.order.enums.OrderLogActionTypeEnum;
 import org.dromara.order.enums.OrderLogActionerTypeEnum;
 import org.dromara.order.enums.OrderLogTypeEnum;
@@ -45,6 +43,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.*;
+import java.util.stream.Collectors;
 
 @Service
 @RequiredArgsConstructor
@@ -145,6 +144,8 @@ public class SysSubOrderServiceImpl implements ISysSubOrderService {
             }
             vo.setPrice(e.getPrice());
             vo.setRemark(e.getRemark());
+            vo.setNursingSummary(e.getNursingSummary());
+            vo.setNursingSummaryTime(e.getNursingSummaryTime());
             return vo;
         }));
     }
@@ -275,6 +276,8 @@ public class SysSubOrderServiceImpl implements ISysSubOrderService {
             }
             vo.setPrice(e.getPrice());
             vo.setRemark(e.getRemark());
+            vo.setNursingSummary(e.getNursingSummary());
+            vo.setNursingSummaryTime(e.getNursingSummaryTime());
             return vo;
         }));
 
@@ -393,4 +396,178 @@ public class SysSubOrderServiceImpl implements ISysSubOrderService {
         vo.setPunishment(0L);
         return vo;
     }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public boolean clockIn(SysSubOrderClockInBo bo) {
+
+        SysSubOrder subOrder = baseMapper.selectById(bo.getOrderId());
+        if (subOrder.getStatus().equals(OrderStatusEnum.PENDING_SERVICE.getValue())) {
+            subOrder.setStatus(OrderStatusEnum.IN_SERVICE.getValue());
+            boolean flag = baseMapper.updateById(subOrder) == 0;
+            if (flag) {
+                throw new RuntimeException("修改订单状态失败");
+            }
+        }
+
+        if (bo.getType().equals(OrderLogActionTypeEnum.FINISH_SERVICE.getValue())) {
+            subOrder.setStatus(OrderStatusEnum.PENDING_CONFIRM.getValue());
+            boolean flag = baseMapper.updateById(subOrder) == 0;
+            if (flag) {
+                throw new RuntimeException("修改订单状态失败");
+            }
+
+        }
+
+        SysSubOrderLog log = new SysSubOrderLog();
+        log.setSubOrderId(subOrder.getId());
+        log.setActioner(LoginHelper.getUserId());
+        log.setActionerType(OrderLogActionerTypeEnum.FULFILLER.getValue());
+        log.setLogType(OrderLogTypeEnum.FULFILLER.getValue());
+        log.setActionType(bo.getType());
+        log.setTitle(bo.getTitle());
+        log.setContent(bo.getContent());
+        log.setPhotos(bo.getPhotos().stream().map(String::valueOf).collect(Collectors.joining(",")));
+        log.setTenantId(subOrder.getTenantId());
+        boolean flag = subOrderLogMapper.insert(log) == 0;
+        if (flag) {
+            throw new RuntimeException("记录服务进度失败");
+        }
+
+        if (bo.getType().equals(OrderLogActionTypeEnum.FINISH_SERVICE.getValue())) {
+            SysSubOrderLog waitingLog = new SysSubOrderLog();
+            waitingLog.setSubOrderId(subOrder.getId());
+            waitingLog.setActioner(LoginHelper.getUserId());
+            waitingLog.setActionerType(OrderLogActionerTypeEnum.FULFILLER.getValue());
+            waitingLog.setLogType(OrderLogTypeEnum.FULFILLER.getValue());
+            waitingLog.setActionType(OrderLogActionTypeEnum.WAITING_FOR_CONFIRM.getValue());
+            waitingLog.setTitle("待商家确认");
+            waitingLog.setContent("履约者已提交完成信息,等待商家确认订单");
+            waitingLog.setTenantId(subOrder.getTenantId());
+            boolean waitingLogFlag = subOrderLogMapper.insert(waitingLog) == 0;
+            if (waitingLogFlag) {
+                throw new RuntimeException("记录服务进度(待上架确认)失败");
+            }
+        }
+
+        if (bo.getType().equals(OrderLogActionTypeEnum.ARRIVE_LOCK_ON.getValue())) {
+            SysSubOrderLog systemLog = new SysSubOrderLog();
+            systemLog.setSubOrderId(subOrder.getId());
+            systemLog.setActioner(LoginHelper.getUserId());
+            systemLog.setActionerType(OrderLogActionerTypeEnum.SYS_USER.getValue());
+            systemLog.setLogType(OrderLogTypeEnum.ORDER.getValue());
+            systemLog.setActionType(OrderLogActionTypeEnum.ARRIVED.getValue());
+            systemLog.setTitle(OrderLogActionTypeEnum.ARRIVED.getLabel());
+            systemLog.setContent("履约者已打卡");
+            systemLog.setTenantId(subOrder.getTenantId());
+            boolean systemFlag = subOrderLogMapper.insert(systemLog) == 0;
+            if (systemFlag) {
+                throw new RuntimeException("记录订单日志失败");
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public TableDataInfo<SysSubOrderListOnMyOrderPageVo> listOnMyOrder(SysSubOrderListOnMyOrderBo bo, PageQuery pageQuery) {
+
+        LambdaQueryWrapper<SysSubOrder> wrapper = Wrappers.lambdaQuery(SysSubOrder.class)
+            .eq(SysSubOrder::getStatus, bo.getStatus())
+            .ge(bo.getStartServiceTime() != null, SysSubOrder::getServiceTime, bo.getStartServiceTime())
+            .le(bo.getEndServiceTime() != null, SysSubOrder::getServiceTime, bo.getEndServiceTime())
+            .orderByDesc(SysSubOrder::getId);
+
+        if (StringUtils.isNotBlank(bo.getContent())) {
+            List<Long> ids = remoteCustomerService.getIdsByNameAndPhone(bo.getContent());
+            wrapper.in(SysSubOrder::getUsrCustomer, WrapperUtils.convertIds(ids));
+        }
+
+        Page<SysSubOrder> page = baseMapper.selectPage(pageQuery.build(), wrapper);
+
+        List<Long> petIds = new ArrayList<>();
+        List<Long> customerIds = new ArrayList<>();
+        Map<Long, RemotePetVo> petMap = new HashMap<>();
+        Map<Long, RemoteCustomerVo> customerMap = new HashMap<>();
+        page.getRecords().forEach(e -> {
+            petIds.add(e.getUsrPet());
+            customerIds.add(e.getUsrCustomer());
+        });
+        remotePetService.getByIds(petIds).forEach(e -> petMap.put(e.getId(), e));
+        remoteCustomerService.getByIds(customerIds).forEach(e -> customerMap.put(e.getId(), e));
+
+        return TableDataInfo.build(page.convert(e -> {
+            SysSubOrderListOnMyOrderPageVo vo = new SysSubOrderListOnMyOrderPageVo();
+            vo.setId(e.getId());
+            vo.setService(e.getService());
+            vo.setPrice(e.getPrice());
+            vo.setServiceTime(e.getServiceTime());
+            vo.setPet(e.getUsrPet());
+            RemotePetVo pet = petMap.get(e.getUsrPet());
+            if (pet != null) {
+                vo.setPetName(pet.getName());
+                vo.setBreed(pet.getBreed());
+            }
+            vo.setStore(e.getStore());
+//            vo.setStoreName();
+//            vo.setStoreAreaCode();
+//            vo.setStoreAddress();
+            vo.setCustomer(e.getUsrCustomer());
+            RemoteCustomerVo customer = customerMap.get(e.getUsrCustomer());
+            if (customer != null) {
+                vo.setCustomerName(customer.getName());
+                vo.setCustomerPhone(customer.getAddress());
+            }
+            vo.setFromCode(e.getFromCode());
+            vo.setFromAddress(e.getFromAddress());
+            vo.setToCode(e.getToCode());
+            vo.setToAddress(e.getToAddress());
+            vo.setRemark(e.getRemark());
+            return vo;
+        }));
+    }
+
+    @GlobalTransactional(rollbackFor = Exception.class)
+    @Override
+    public boolean confirm(SysSubOrderConfirmBo bo) {
+
+        SysSubOrder subOrder = baseMapper.selectById(bo.getId());
+        subOrder.setStatus(OrderStatusEnum.COMPLETED.getValue());
+        boolean flag = baseMapper.updateById(subOrder) == 0;
+        if (flag) {
+            throw new RuntimeException("修改订单状态失败");
+        }
+
+        SysSubOrderLog log = new SysSubOrderLog();
+        log.setSubOrderId(subOrder.getId());
+        log.setActioner(LoginHelper.getUserId());
+        log.setActionerType(OrderLogActionerTypeEnum.SYS_USER.getValue());
+        log.setLogType(OrderLogTypeEnum.FULFILLER.getValue());
+        log.setActionType(OrderLogActionTypeEnum.FINISH.getValue());
+        log.setTitle(OrderLogActionTypeEnum.FINISH.getLabel());
+        log.setContent("用户/商家已确认,服务圆满结束");
+        log.setTenantId(subOrder.getTenantId());
+        boolean logFlag = subOrderLogMapper.insert(log) == 0;
+        if (logFlag) {
+            throw new RuntimeException("新增日志失败");
+        }
+
+        // 履约者拿到佣金
+        boolean fulfillerFlag = remoteFulfillerService.settlement(subOrder.getFulfiller(), subOrder.getPrice(), subOrder.getCode());
+        if (!fulfillerFlag) {
+            throw new RuntimeException("履约者新增佣金失败");
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean nursingSummary(SysSubOrderNursingSummaryBo bo) {
+        return baseMapper.update(
+            Wrappers.lambdaUpdate(SysSubOrder.class)
+                .eq(SysSubOrder::getId, bo.getOrderId())
+                .set(SysSubOrder::getNursingSummary, bo.getContent())
+                .set(SysSubOrder::getNursingSummaryTime, new Date())
+        ) > 0;
+    }
 }

+ 4 - 0
script/sql/business/update.sql

@@ -192,3 +192,7 @@ insert into sys_dict_data values(144, '000000', 23, '中华田园猫',     '中
 # 2026/02/28
 -- 门店信息加入区域编码
 ALTER TABLE `pet_system`.`sys_store` ADD COLUMN `area_code` varchar(255) NOT NULL COMMENT '区域编码';
+
+# 2026/03/09
+ALTER TABLE `pet_system`.`sys_sub_order` ADD  COLUMN `nursing_sammary` varchar(512) COMMENT '护理小结';
+ALTER TABLE `pet_system`.`sys_sub_order` ADD  COLUMN `nursing_sammary_time` datetime COMMENT '护理小结提交时间';