Просмотр исходного кода

feat(order): 添加客户订单流程管理功能

- 新增客户订单流程相关实体类和业务对象
- 实现客户订单流程、流程关联、流程节点等服务接口
- 添加客户订单流程管理的数据库映射和XML配置文件
- 创建全局CORS配置支持跨域请求
- 配置Satoken的Cookie域名和安全设置
- 移除产品控制器中的多余空行优化代码格式
肖路 1 месяц назад
Родитель
Сommit
3b64f2b428
33 измененных файлов с 2299 добавлено и 1 удалено
  1. 6 0
      ruoyi-common/ruoyi-common-satoken/src/main/resources/common-satoken.yml
  2. 27 0
      ruoyi-gateway/src/main/java/org/dromara/gateway/filter/GlobalCorsConfig.java
  3. 127 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/pc/PcOrderFlowController.java
  4. 61 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderCustomerFlow.java
  5. 71 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderCustomerFlowLink.java
  6. 61 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderCustomerFlowNode.java
  7. 76 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderCustomerFlowNodeLink.java
  8. 59 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderCustomerFlowBo.java
  9. 71 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderCustomerFlowLinkBo.java
  10. 59 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderCustomerFlowNodeBo.java
  11. 76 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderCustomerFlowNodeLinkBo.java
  12. 63 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderCustomerFlowSaveBo.java
  13. 80 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderCustomerFlowLinkVo.java
  14. 86 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderCustomerFlowNodeLinkVo.java
  15. 69 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderCustomerFlowNodeVo.java
  16. 81 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderCustomerFlowVo.java
  17. 15 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderCustomerFlowLinkMapper.java
  18. 15 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderCustomerFlowMapper.java
  19. 15 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderCustomerFlowNodeLinkMapper.java
  20. 15 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderCustomerFlowNodeMapper.java
  21. 70 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderCustomerFlowLinkService.java
  22. 70 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderCustomerFlowNodeLinkService.java
  23. 70 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderCustomerFlowNodeService.java
  24. 90 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderCustomerFlowService.java
  25. 139 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderCustomerFlowLinkServiceImpl.java
  26. 139 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderCustomerFlowNodeLinkServiceImpl.java
  27. 137 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderCustomerFlowNodeServiceImpl.java
  28. 423 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderCustomerFlowServiceImpl.java
  29. 7 0
      ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderCustomerFlowLinkMapper.xml
  30. 7 0
      ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderCustomerFlowMapper.xml
  31. 7 0
      ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderCustomerFlowNodeLinkMapper.xml
  32. 7 0
      ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderCustomerFlowNodeMapper.xml
  33. 0 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/pc/IndexProductController.java

+ 6 - 0
ruoyi-common/ruoyi-common-satoken/src/main/resources/common-satoken.yml

@@ -11,3 +11,9 @@ sa-token:
   is-read-cookie: false
   # token前缀
   token-prefix: "Bearer"
+  cookie:
+    domain: .xiaoluwebsite.xyz
+    path: /
+    secure: true
+    httpOnly: false
+    sameSite: None

+ 27 - 0
ruoyi-gateway/src/main/java/org/dromara/gateway/filter/GlobalCorsConfig.java

@@ -0,0 +1,27 @@
+package org.dromara.gateway.filter;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.reactive.CorsWebFilter;
+import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
+
+@Configuration
+public class GlobalCorsConfig {
+
+    @Bean
+    public CorsWebFilter corsWebFilter() {
+        CorsConfiguration config = new CorsConfiguration();
+        config.setAllowCredentials(true); // 【关键】
+
+        // 添加允许的源 (生产环境建议动态获取或配置列表)
+        config.addAllowedOriginPattern("https://*.xiaoluwebsite.xyz");
+        config.addAllowedHeader("*");
+        config.addAllowedMethod("*");
+
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        source.registerCorsConfiguration("/**", config);
+
+        return new CorsWebFilter(source);
+    }
+}

+ 127 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/pc/PcOrderFlowController.java

@@ -0,0 +1,127 @@
+package org.dromara.order.controller.pc;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.order.domain.OrderCustomerFlow;
+import org.dromara.order.domain.bo.OrderCustomerFlowBo;
+import org.dromara.order.domain.bo.OrderCustomerFlowLinkBo;
+import org.dromara.order.domain.bo.OrderCustomerFlowSaveBo;
+import org.dromara.order.domain.vo.OrderCustomerFlowVo;
+import org.dromara.order.service.IOrderCustomerFlowService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * PC端 - 订单流程
+ *
+ * @author Claude
+ * @date 2026-02-25
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/pcOrderFlow")
+public class PcOrderFlowController extends BaseController {
+
+    //客户订单流程
+    private final IOrderCustomerFlowService orderCustomerFlowService;
+
+    /**
+    * 获取流程列表
+    * */
+    @GetMapping("/list")
+    public TableDataInfo<OrderCustomerFlowVo> list(OrderCustomerFlowBo bo, PageQuery pageQuery) {
+        return orderCustomerFlowService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 获取流程详细信息
+     *
+     * @param id 主键
+     */
+    @GetMapping("/{id}")
+    public R<OrderCustomerFlowVo> getInfo(@PathVariable("id") Long id) {
+        return R.ok(orderCustomerFlowService.queryById(id));
+    }
+
+
+    /**
+     * 新增客户订单流程(包含节点)
+     */
+    @Log(title = "客户订单流程", businessType = BusinessType.INSERT)
+    @PostMapping("/save")
+    public R<String> addFlowWithNodes(@Validated(AddGroup.class) @RequestBody OrderCustomerFlowSaveBo bo) {
+        bo.setUserId(LoginHelper.getUserId());
+        bo.setCustomerId(LoginHelper.getLoginUser().getCustomerId());
+        boolean result = orderCustomerFlowService.saveFlowWithNodes(bo);
+        return result ? R.ok("保存成功") : R.fail("保存失败");
+    }
+
+    /**
+     * 编辑客户订单流程(包含节点)
+     */
+    @Log(title = "客户订单流程", businessType = BusinessType.UPDATE)
+    @PutMapping("/save")
+    public R<String> editFlowWithNodes(@Validated(EditGroup.class) @RequestBody OrderCustomerFlowSaveBo bo) {
+        boolean result = orderCustomerFlowService.saveFlowWithNodes(bo);
+        return result ? R.ok("更新成功") : R.fail("更新失败");
+    }
+
+    /**
+     * 删除客户订单流程
+     *
+     * @param id 客户订单流程主键
+     */
+    @Log(title = "客户订单流程", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{id}")
+    public R<Void> remove(@PathVariable Long id) {
+        return toAjax(orderCustomerFlowService.deleteWithValidByIds(List.of(id), true));
+    }
+
+    /**
+    * 审核订单流程
+    * */
+    @Log(title = "客户订单流程", businessType = BusinessType.UPDATE)
+    @PutMapping("/audit")
+    public R<String> auditOrderFlow(@Validated @RequestBody OrderCustomerFlowLinkBo bo) {
+        orderCustomerFlowService.auditOrderFlow(bo);
+        return R.ok("审核成功");
+    }
+
+    /**
+    * 开启流程
+    * */
+    @Log(title = "客户订单流程", businessType = BusinessType.UPDATE)
+    @PutMapping("/startFlow/{id}")
+    public R<String> startOrderFlow(@PathVariable Long id) {
+        orderCustomerFlowService.update(Wrappers.lambdaUpdate(OrderCustomerFlow.class)
+            .set(OrderCustomerFlow::getStatus, "0")
+            .eq(OrderCustomerFlow::getId, id)
+        );
+        return R.ok("开启成功");
+    }
+
+    /**
+    * 关闭流程
+    * */
+    @Log(title = "客户订单流程", businessType = BusinessType.UPDATE)
+    @PutMapping("/closeFlow/{id}")
+    public R<String> closeOrderFlow(@PathVariable Long id) {
+        orderCustomerFlowService.update(Wrappers.lambdaUpdate(OrderCustomerFlow.class)
+            .set(OrderCustomerFlow::getStatus, "1")
+            .eq(OrderCustomerFlow::getId, id)
+        );
+        return R.ok("关闭成功");
+    }
+}

+ 61 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderCustomerFlow.java

@@ -0,0 +1,61 @@
+package org.dromara.order.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 客户订单流程对象 order_customer_flow
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("order_customer_flow")
+public class OrderCustomerFlow extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 流程名称
+     */
+    private String flowName;
+
+    /**
+     * 客户id
+     */
+    private Long customerId;
+
+    /**
+     * 流程所有者id
+     */
+    private Long userId;
+
+    /**
+     * 状态 0启用,1关闭
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 71 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderCustomerFlowLink.java

@@ -0,0 +1,71 @@
+package org.dromara.order.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 客户订单流程关联对象 order_customer_flow_link
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("order_customer_flow_link")
+public class OrderCustomerFlowLink extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 订单id
+     */
+    private Long orderId;
+
+    /**
+     * 流程id
+     */
+    private Long flowId;
+
+    /**
+     * 当前所在节点id
+     */
+    private Long nodeId;
+
+    /**
+     * 当前流程处理者id
+     */
+    private Long handlerId;
+
+    /**
+     * 审核状态 0待审核 1已通过 2已驳回
+     */
+    private Long reviewStatus;
+
+    /**
+     * 驳回原因
+     */
+    private String reason;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 61 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderCustomerFlowNode.java

@@ -0,0 +1,61 @@
+package org.dromara.order.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 客户订单流程节点对象 order_customer_flow_node
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("order_customer_flow_node")
+public class OrderCustomerFlowNode extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 流程id
+     */
+    private Long flowId;
+
+    /**
+     * 节点类型(0开始节点 1中间节点 2结束节点)
+     */
+    private Long nodeType;
+
+    /**
+     * 处理人id
+     */
+    private Long handlerId;
+
+    /**
+     * 节点顺序(开始节点默认是0,结束节点最大)
+     */
+    private Long sort;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 76 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderCustomerFlowNodeLink.java

@@ -0,0 +1,76 @@
+package org.dromara.order.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 客户订单流程节点管理对象 order_customer_flow_node_link
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("order_customer_flow_node_link")
+public class OrderCustomerFlowNodeLink extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 订单id
+     */
+    private Long orderId;
+
+    /**
+     * 流程id
+     */
+    private Long flowId;
+
+    /**
+     * 节点类型(0开始节点 1中间节点 2结束节点)
+     */
+    private Long nodeType;
+
+    /**
+     * 处理者id
+     */
+    private Long handlerId;
+
+    /**
+    * 节点顺序(开始节点默认是0,结束节点最大)
+    * */
+    private Long sort;
+
+    /**
+     * 审核状态 0待审核 1已通过 2已驳回
+     */
+    private Long reviewStatus;
+
+    /**
+     * 驳回原因
+     */
+    private String reason;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 59 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderCustomerFlowBo.java

@@ -0,0 +1,59 @@
+package org.dromara.order.domain.bo;
+
+import org.dromara.order.domain.OrderCustomerFlow;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 客户订单流程业务对象 order_customer_flow
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = OrderCustomerFlow.class, reverseConvertGenerate = false)
+public class OrderCustomerFlowBo extends BaseEntity {
+
+    /**
+     * 
+     */
+    private Long id;
+
+    /**
+     * 流程名称
+     */
+    //@NotBlank(message = "流程名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String flowName;
+
+    /**
+     * 客户id
+     */
+    //@NotNull(message = "客户id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long customerId;
+
+    /**
+     * 流程所有者id
+     */
+    //@NotNull(message = "流程所有者id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long userId;
+
+    /**
+     * 状态 0启用,1关闭
+     */
+    //@NotBlank(message = "状态 0启用,1关闭不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String status;
+
+    /**
+     * 备注
+     */
+    //@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String remark;
+
+
+}

+ 71 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderCustomerFlowLinkBo.java

@@ -0,0 +1,71 @@
+package org.dromara.order.domain.bo;
+
+import org.dromara.order.domain.OrderCustomerFlowLink;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 客户订单流程关联业务对象 order_customer_flow_link
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = OrderCustomerFlowLink.class, reverseConvertGenerate = false)
+public class OrderCustomerFlowLinkBo extends BaseEntity {
+
+    /**
+     * 
+     */
+    private Long id;
+
+    /**
+     * 订单id
+     */
+    //@NotNull(message = "订单id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long orderId;
+
+    /**
+     * 流程id
+     */
+    //@NotNull(message = "流程id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long flowId;
+
+    /**
+     * 当前所在节点id
+     */
+    //@NotNull(message = "当前所在节点id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long nodeId;
+
+    /**
+     * 当前流程处理者id
+     */
+    //@NotNull(message = "当前流程处理者id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long handlerId;
+
+    /**
+     * 审核状态 0待审核 1已通过 2已驳回
+     */
+    //@NotNull(message = "审核状态 0待审核 1已通过 2已驳回不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long reviewStatus;
+
+    /**
+     * 驳回原因
+     */
+    //@NotBlank(message = "驳回原因不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String reason;
+
+    /**
+     * 备注
+     */
+    //@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String remark;
+
+
+}

+ 59 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderCustomerFlowNodeBo.java

@@ -0,0 +1,59 @@
+package org.dromara.order.domain.bo;
+
+import org.dromara.order.domain.OrderCustomerFlowNode;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 客户订单流程节点业务对象 order_customer_flow_node
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = OrderCustomerFlowNode.class, reverseConvertGenerate = false)
+public class OrderCustomerFlowNodeBo extends BaseEntity {
+
+    /**
+     * 
+     */
+    private Long id;
+
+    /**
+     * 流程id
+     */
+    //@NotNull(message = "流程id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long flowId;
+
+    /**
+     * 节点类型(0开始节点 1中间节点 2结束节点)
+     */
+    //@NotNull(message = "节点类型(0开始节点 1中间节点 2结束节点)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long nodeType;
+
+    /**
+     * 处理人id
+     */
+    //@NotNull(message = "处理人id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long handlerId;
+
+    /**
+     * 节点顺序(开始节点默认是0,结束节点最大)
+     */
+    //@NotNull(message = "节点顺序(开始节点默认是0,结束节点最大)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long sort;
+
+    /**
+     * 备注
+     */
+    //@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String remark;
+
+
+}

+ 76 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderCustomerFlowNodeLinkBo.java

@@ -0,0 +1,76 @@
+package org.dromara.order.domain.bo;
+
+import org.dromara.order.domain.OrderCustomerFlowNodeLink;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 客户订单流程节点管理业务对象 order_customer_flow_node_link
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = OrderCustomerFlowNodeLink.class, reverseConvertGenerate = false)
+public class OrderCustomerFlowNodeLinkBo extends BaseEntity {
+
+    /**
+     *
+     */
+    private Long id;
+
+    /**
+     * 订单id
+     */
+    //@NotNull(message = "订单id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long orderId;
+
+    /**
+     * 流程id
+     */
+    //@NotNull(message = "流程id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long flowId;
+
+    /**
+     * 节点类型(0开始节点 1中间节点 2结束节点)
+     */
+    //@NotNull(message = "节点类型(0开始节点 1中间节点 2结束节点)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long nodeType;
+
+    /**
+     * 处理者id
+     */
+    //@NotNull(message = "处理者id不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long handlerId;
+
+    /**
+     * 节点顺序(开始节点默认是0,结束节点最大)
+     * */
+    private Long sort;
+
+    /**
+     * 审核状态 0待审核 1已通过 2已驳回
+     */
+    //@NotNull(message = "审核状态 0待审核 1已通过 2已驳回不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long reviewStatus;
+
+    /**
+     * 驳回原因
+     */
+    //@NotBlank(message = "驳回原因不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String reason;
+
+    /**
+     * 备注
+     */
+    //@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String remark;
+
+
+}

+ 63 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderCustomerFlowSaveBo.java

@@ -0,0 +1,63 @@
+package org.dromara.order.domain.bo;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.Valid;
+
+import java.util.List;
+
+/**
+ * 客户订单流程保存业务对象(包含流程和节点信息)
+ *
+ * @author Claude
+ * @date 2026-02-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class OrderCustomerFlowSaveBo extends BaseEntity {
+
+    /**
+     * 流程ID(编辑时必填)
+     */
+    @NotNull(message = "流程ID不能为空", groups = {EditGroup.class})
+    private Long id;
+
+    /**
+     * 流程名称
+     */
+    @NotBlank(message = "流程名称不能为空", groups = {AddGroup.class, EditGroup.class})
+    private String flowName;
+
+    /**
+     * 客户id
+     */
+    private Long customerId;
+
+    /**
+     * 流程所有者id
+     */
+    private Long userId;
+
+    /**
+     * 状态 0启用,1关闭
+     */
+    private String status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 流程节点列表
+     */
+    @Valid
+    private List<OrderCustomerFlowNodeBo> flowNodes;
+
+}

+ 80 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderCustomerFlowLinkVo.java

@@ -0,0 +1,80 @@
+package org.dromara.order.domain.vo;
+
+import org.dromara.order.domain.OrderCustomerFlowLink;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 客户订单流程关联视图对象 order_customer_flow_link
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = OrderCustomerFlowLink.class)
+public class OrderCustomerFlowLinkVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 订单id
+     */
+    @ExcelProperty(value = "订单id")
+    private Long orderId;
+
+    /**
+     * 流程id
+     */
+    @ExcelProperty(value = "流程id")
+    private Long flowId;
+
+    /**
+     * 当前所在节点id
+     */
+    @ExcelProperty(value = "当前所在节点id")
+    private Long nodeId;
+
+    /**
+     * 当前流程处理者id
+     */
+    @ExcelProperty(value = "当前流程处理者id")
+    private Long handlerId;
+
+    /**
+     * 审核状态 0待审核 1已通过 2已驳回
+     */
+    @ExcelProperty(value = "审核状态 0待审核 1已通过 2已驳回")
+    private Long reviewStatus;
+
+    /**
+     * 驳回原因
+     */
+    @ExcelProperty(value = "驳回原因")
+    private String reason;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 86 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderCustomerFlowNodeLinkVo.java

@@ -0,0 +1,86 @@
+package org.dromara.order.domain.vo;
+
+import org.dromara.order.domain.OrderCustomerFlowNodeLink;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 客户订单流程节点管理视图对象 order_customer_flow_node_link
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = OrderCustomerFlowNodeLink.class)
+public class OrderCustomerFlowNodeLinkVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 订单id
+     */
+    @ExcelProperty(value = "订单id")
+    private Long orderId;
+
+    /**
+     * 流程id
+     */
+    @ExcelProperty(value = "流程id")
+    private Long flowId;
+
+    /**
+     * 节点顺序(开始节点默认是0,结束节点最大)
+     * */
+    private Long sort;
+
+    /**
+     * 节点类型(0开始节点 1中间节点 2结束节点)
+     */
+    @ExcelProperty(value = "节点类型", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=开始节点,1=中间节点,2=结束节点")
+    private Long nodeType;
+
+    /**
+     * 处理者id
+     */
+    @ExcelProperty(value = "处理者id")
+    private Long handlerId;
+
+    /**
+     * 审核状态 0待审核 1已通过 2已驳回
+     */
+    @ExcelProperty(value = "审核状态 0待审核 1已通过 2已驳回")
+    private Long reviewStatus;
+
+    /**
+     * 驳回原因
+     */
+    @ExcelProperty(value = "驳回原因")
+    private String reason;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 69 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderCustomerFlowNodeVo.java

@@ -0,0 +1,69 @@
+package org.dromara.order.domain.vo;
+
+import org.dromara.order.domain.OrderCustomerFlowNode;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 客户订单流程节点视图对象 order_customer_flow_node
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = OrderCustomerFlowNode.class)
+public class OrderCustomerFlowNodeVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 流程id
+     */
+    @ExcelProperty(value = "流程id")
+    private Long flowId;
+
+    /**
+     * 节点类型(0开始节点 1中间节点 2结束节点)
+     */
+    @ExcelProperty(value = "节点类型", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=开始节点,1=中间节点,2=结束节点")
+    private Long nodeType;
+
+    /**
+     * 处理人id
+     */
+    @ExcelProperty(value = "处理人id")
+    private Long handlerId;
+
+    /**
+     * 节点顺序(开始节点默认是0,结束节点最大)
+     */
+    @ExcelProperty(value = "节点顺序(开始节点默认是0,结束节点最大)")
+    private Long sort;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 81 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderCustomerFlowVo.java

@@ -0,0 +1,81 @@
+package org.dromara.order.domain.vo;
+
+import org.dromara.order.domain.OrderCustomerFlow;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.order.domain.OrderCustomerFlowNode;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 客户订单流程视图对象 order_customer_flow
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = OrderCustomerFlow.class)
+public class OrderCustomerFlowVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 流程名称
+     */
+    @ExcelProperty(value = "流程名称")
+    private String flowName;
+
+    /**
+     * 客户id
+     */
+    @ExcelProperty(value = "客户id")
+    private Long customerId;
+
+    /**
+     * 流程所有者id
+     */
+    @ExcelProperty(value = "流程所有者id")
+    private Long userId;
+
+    /**
+     * 状态 0启用,1关闭
+     */
+    @ExcelProperty(value = "状态 0启用,1关闭")
+    private String status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+    /**
+     * 创建时间
+     */
+    @ExcelProperty(value = "创建时间")
+    private Date createTime;
+
+    /**
+    * 节点列表
+    * */
+    @ExcelProperty(value = "节点列表")
+    private List<OrderCustomerFlowNode> flowNodes;
+
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderCustomerFlowLinkMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.order.mapper;
+
+import org.dromara.order.domain.OrderCustomerFlowLink;
+import org.dromara.order.domain.vo.OrderCustomerFlowLinkVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 客户订单流程关联Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+public interface OrderCustomerFlowLinkMapper extends BaseMapperPlus<OrderCustomerFlowLink, OrderCustomerFlowLinkVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderCustomerFlowMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.order.mapper;
+
+import org.dromara.order.domain.OrderCustomerFlow;
+import org.dromara.order.domain.vo.OrderCustomerFlowVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 客户订单流程Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+public interface OrderCustomerFlowMapper extends BaseMapperPlus<OrderCustomerFlow, OrderCustomerFlowVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderCustomerFlowNodeLinkMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.order.mapper;
+
+import org.dromara.order.domain.OrderCustomerFlowNodeLink;
+import org.dromara.order.domain.vo.OrderCustomerFlowNodeLinkVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 客户订单流程节点管理Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+public interface OrderCustomerFlowNodeLinkMapper extends BaseMapperPlus<OrderCustomerFlowNodeLink, OrderCustomerFlowNodeLinkVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/mapper/OrderCustomerFlowNodeMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.order.mapper;
+
+import org.dromara.order.domain.OrderCustomerFlowNode;
+import org.dromara.order.domain.vo.OrderCustomerFlowNodeVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 客户订单流程节点Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+public interface OrderCustomerFlowNodeMapper extends BaseMapperPlus<OrderCustomerFlowNode, OrderCustomerFlowNodeVo> {
+
+}

+ 70 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderCustomerFlowLinkService.java

@@ -0,0 +1,70 @@
+package org.dromara.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.order.domain.OrderCustomerFlowLink;
+import org.dromara.order.domain.vo.OrderCustomerFlowLinkVo;
+import org.dromara.order.domain.bo.OrderCustomerFlowLinkBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 客户订单流程关联Service接口
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+public interface IOrderCustomerFlowLinkService extends IService<OrderCustomerFlowLink>{
+
+    /**
+     * 查询客户订单流程关联
+     *
+     * @param id 主键
+     * @return 客户订单流程关联
+     */
+    OrderCustomerFlowLinkVo queryById(Long id);
+
+    /**
+     * 分页查询客户订单流程关联列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户订单流程关联分页列表
+     */
+    TableDataInfo<OrderCustomerFlowLinkVo> queryPageList(OrderCustomerFlowLinkBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的客户订单流程关联列表
+     *
+     * @param bo 查询条件
+     * @return 客户订单流程关联列表
+     */
+    List<OrderCustomerFlowLinkVo> queryList(OrderCustomerFlowLinkBo bo);
+
+    /**
+     * 新增客户订单流程关联
+     *
+     * @param bo 客户订单流程关联
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(OrderCustomerFlowLinkBo bo);
+
+    /**
+     * 修改客户订单流程关联
+     *
+     * @param bo 客户订单流程关联
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(OrderCustomerFlowLinkBo bo);
+
+    /**
+     * 校验并批量删除客户订单流程关联信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderCustomerFlowNodeLinkService.java

@@ -0,0 +1,70 @@
+package org.dromara.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.order.domain.OrderCustomerFlowNodeLink;
+import org.dromara.order.domain.vo.OrderCustomerFlowNodeLinkVo;
+import org.dromara.order.domain.bo.OrderCustomerFlowNodeLinkBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 客户订单流程节点管理Service接口
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+public interface IOrderCustomerFlowNodeLinkService extends IService<OrderCustomerFlowNodeLink>{
+
+    /**
+     * 查询客户订单流程节点管理
+     *
+     * @param id 主键
+     * @return 客户订单流程节点管理
+     */
+    OrderCustomerFlowNodeLinkVo queryById(Long id);
+
+    /**
+     * 分页查询客户订单流程节点管理列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户订单流程节点管理分页列表
+     */
+    TableDataInfo<OrderCustomerFlowNodeLinkVo> queryPageList(OrderCustomerFlowNodeLinkBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的客户订单流程节点管理列表
+     *
+     * @param bo 查询条件
+     * @return 客户订单流程节点管理列表
+     */
+    List<OrderCustomerFlowNodeLinkVo> queryList(OrderCustomerFlowNodeLinkBo bo);
+
+    /**
+     * 新增客户订单流程节点管理
+     *
+     * @param bo 客户订单流程节点管理
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(OrderCustomerFlowNodeLinkBo bo);
+
+    /**
+     * 修改客户订单流程节点管理
+     *
+     * @param bo 客户订单流程节点管理
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(OrderCustomerFlowNodeLinkBo bo);
+
+    /**
+     * 校验并批量删除客户订单流程节点管理信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderCustomerFlowNodeService.java

@@ -0,0 +1,70 @@
+package org.dromara.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.order.domain.OrderCustomerFlowNode;
+import org.dromara.order.domain.vo.OrderCustomerFlowNodeVo;
+import org.dromara.order.domain.bo.OrderCustomerFlowNodeBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 客户订单流程节点Service接口
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+public interface IOrderCustomerFlowNodeService extends IService<OrderCustomerFlowNode>{
+
+    /**
+     * 查询客户订单流程节点
+     *
+     * @param id 主键
+     * @return 客户订单流程节点
+     */
+    OrderCustomerFlowNodeVo queryById(Long id);
+
+    /**
+     * 分页查询客户订单流程节点列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户订单流程节点分页列表
+     */
+    TableDataInfo<OrderCustomerFlowNodeVo> queryPageList(OrderCustomerFlowNodeBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的客户订单流程节点列表
+     *
+     * @param bo 查询条件
+     * @return 客户订单流程节点列表
+     */
+    List<OrderCustomerFlowNodeVo> queryList(OrderCustomerFlowNodeBo bo);
+
+    /**
+     * 新增客户订单流程节点
+     *
+     * @param bo 客户订单流程节点
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(OrderCustomerFlowNodeBo bo);
+
+    /**
+     * 修改客户订单流程节点
+     *
+     * @param bo 客户订单流程节点
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(OrderCustomerFlowNodeBo bo);
+
+    /**
+     * 校验并批量删除客户订单流程节点信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 90 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderCustomerFlowService.java

@@ -0,0 +1,90 @@
+package org.dromara.order.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.order.domain.OrderCustomerFlow;
+import org.dromara.order.domain.bo.OrderCustomerFlowLinkBo;
+import org.dromara.order.domain.vo.OrderCustomerFlowVo;
+import org.dromara.order.domain.bo.OrderCustomerFlowBo;
+import org.dromara.order.domain.bo.OrderCustomerFlowSaveBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 客户订单流程Service接口
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+public interface IOrderCustomerFlowService extends IService<OrderCustomerFlow>{
+
+    /**
+     * 查询客户订单流程
+     *
+     * @param id 主键
+     * @return 客户订单流程
+     */
+    OrderCustomerFlowVo queryById(Long id);
+
+    /**
+     * 分页查询客户订单流程列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户订单流程分页列表
+     */
+    TableDataInfo<OrderCustomerFlowVo> queryPageList(OrderCustomerFlowBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的客户订单流程列表
+     *
+     * @param bo 查询条件
+     * @return 客户订单流程列表
+     */
+    List<OrderCustomerFlowVo> queryList(OrderCustomerFlowBo bo);
+
+    /**
+     * 新增客户订单流程
+     *
+     * @param bo 客户订单流程
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(OrderCustomerFlowBo bo);
+
+    /**
+     * 修改客户订单流程
+     *
+     * @param bo 客户订单流程
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(OrderCustomerFlowBo bo);
+
+    /**
+     * 保存编辑客户订单流程(包括流程和节点)
+     *
+     * @param bo 客户订单流程保存对象
+     * @return 是否保存成功
+     */
+    Boolean saveFlowWithNodes(OrderCustomerFlowSaveBo bo);
+
+    /**
+     * 校验并批量删除客户订单流程信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+    /**
+    * 初始化订单流程
+     * @param orderId 订单ID
+    * */
+    void initOrderFlow(Long orderId);
+
+    /**
+    * 审核订单流程
+    * */
+    void auditOrderFlow(OrderCustomerFlowLinkBo bo);
+}

+ 139 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderCustomerFlowLinkServiceImpl.java

@@ -0,0 +1,139 @@
+package org.dromara.order.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.order.domain.bo.OrderCustomerFlowLinkBo;
+import org.dromara.order.domain.vo.OrderCustomerFlowLinkVo;
+import org.dromara.order.domain.OrderCustomerFlowLink;
+import org.dromara.order.mapper.OrderCustomerFlowLinkMapper;
+import org.dromara.order.service.IOrderCustomerFlowLinkService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 客户订单流程关联Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class OrderCustomerFlowLinkServiceImpl  extends ServiceImpl<OrderCustomerFlowLinkMapper, OrderCustomerFlowLink> implements IOrderCustomerFlowLinkService {
+
+    private final OrderCustomerFlowLinkMapper baseMapper;
+
+    /**
+     * 查询客户订单流程关联
+     *
+     * @param id 主键
+     * @return 客户订单流程关联
+     */
+    @Override
+    public OrderCustomerFlowLinkVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询客户订单流程关联列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户订单流程关联分页列表
+     */
+    @Override
+    public TableDataInfo<OrderCustomerFlowLinkVo> queryPageList(OrderCustomerFlowLinkBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<OrderCustomerFlowLink> lqw = buildQueryWrapper(bo);
+        Page<OrderCustomerFlowLinkVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的客户订单流程关联列表
+     *
+     * @param bo 查询条件
+     * @return 客户订单流程关联列表
+     */
+    @Override
+    public List<OrderCustomerFlowLinkVo> queryList(OrderCustomerFlowLinkBo bo) {
+        LambdaQueryWrapper<OrderCustomerFlowLink> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<OrderCustomerFlowLink> buildQueryWrapper(OrderCustomerFlowLinkBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<OrderCustomerFlowLink> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(OrderCustomerFlowLink::getId);
+        lqw.eq(bo.getOrderId() != null, OrderCustomerFlowLink::getOrderId, bo.getOrderId());
+        lqw.eq(bo.getFlowId() != null, OrderCustomerFlowLink::getFlowId, bo.getFlowId());
+        lqw.eq(bo.getNodeId() != null, OrderCustomerFlowLink::getNodeId, bo.getNodeId());
+        lqw.eq(bo.getHandlerId() != null, OrderCustomerFlowLink::getHandlerId, bo.getHandlerId());
+        lqw.eq(bo.getReviewStatus() != null, OrderCustomerFlowLink::getReviewStatus, bo.getReviewStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getReason()), OrderCustomerFlowLink::getReason, bo.getReason());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), OrderCustomerFlowLink::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增客户订单流程关联
+     *
+     * @param bo 客户订单流程关联
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(OrderCustomerFlowLinkBo bo) {
+        OrderCustomerFlowLink add = MapstructUtils.convert(bo, OrderCustomerFlowLink.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改客户订单流程关联
+     *
+     * @param bo 客户订单流程关联
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(OrderCustomerFlowLinkBo bo) {
+        OrderCustomerFlowLink update = MapstructUtils.convert(bo, OrderCustomerFlowLink.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(OrderCustomerFlowLink entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除客户订单流程关联信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 139 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderCustomerFlowNodeLinkServiceImpl.java

@@ -0,0 +1,139 @@
+package org.dromara.order.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.order.domain.bo.OrderCustomerFlowNodeLinkBo;
+import org.dromara.order.domain.vo.OrderCustomerFlowNodeLinkVo;
+import org.dromara.order.domain.OrderCustomerFlowNodeLink;
+import org.dromara.order.mapper.OrderCustomerFlowNodeLinkMapper;
+import org.dromara.order.service.IOrderCustomerFlowNodeLinkService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 客户订单流程节点管理Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class OrderCustomerFlowNodeLinkServiceImpl  extends ServiceImpl<OrderCustomerFlowNodeLinkMapper, OrderCustomerFlowNodeLink> implements IOrderCustomerFlowNodeLinkService {
+
+    private final OrderCustomerFlowNodeLinkMapper baseMapper;
+
+    /**
+     * 查询客户订单流程节点管理
+     *
+     * @param id 主键
+     * @return 客户订单流程节点管理
+     */
+    @Override
+    public OrderCustomerFlowNodeLinkVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询客户订单流程节点管理列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户订单流程节点管理分页列表
+     */
+    @Override
+    public TableDataInfo<OrderCustomerFlowNodeLinkVo> queryPageList(OrderCustomerFlowNodeLinkBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<OrderCustomerFlowNodeLink> lqw = buildQueryWrapper(bo);
+        Page<OrderCustomerFlowNodeLinkVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的客户订单流程节点管理列表
+     *
+     * @param bo 查询条件
+     * @return 客户订单流程节点管理列表
+     */
+    @Override
+    public List<OrderCustomerFlowNodeLinkVo> queryList(OrderCustomerFlowNodeLinkBo bo) {
+        LambdaQueryWrapper<OrderCustomerFlowNodeLink> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<OrderCustomerFlowNodeLink> buildQueryWrapper(OrderCustomerFlowNodeLinkBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<OrderCustomerFlowNodeLink> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(OrderCustomerFlowNodeLink::getId);
+        lqw.eq(bo.getOrderId() != null, OrderCustomerFlowNodeLink::getOrderId, bo.getOrderId());
+        lqw.eq(bo.getFlowId() != null, OrderCustomerFlowNodeLink::getFlowId, bo.getFlowId());
+        lqw.eq(bo.getNodeType() != null, OrderCustomerFlowNodeLink::getNodeType, bo.getNodeType());
+        lqw.eq(bo.getHandlerId() != null, OrderCustomerFlowNodeLink::getHandlerId, bo.getHandlerId());
+        lqw.eq(bo.getReviewStatus() != null, OrderCustomerFlowNodeLink::getReviewStatus, bo.getReviewStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getReason()), OrderCustomerFlowNodeLink::getReason, bo.getReason());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), OrderCustomerFlowNodeLink::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增客户订单流程节点管理
+     *
+     * @param bo 客户订单流程节点管理
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(OrderCustomerFlowNodeLinkBo bo) {
+        OrderCustomerFlowNodeLink add = MapstructUtils.convert(bo, OrderCustomerFlowNodeLink.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改客户订单流程节点管理
+     *
+     * @param bo 客户订单流程节点管理
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(OrderCustomerFlowNodeLinkBo bo) {
+        OrderCustomerFlowNodeLink update = MapstructUtils.convert(bo, OrderCustomerFlowNodeLink.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(OrderCustomerFlowNodeLink entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除客户订单流程节点管理信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 137 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderCustomerFlowNodeServiceImpl.java

@@ -0,0 +1,137 @@
+package org.dromara.order.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.order.domain.bo.OrderCustomerFlowNodeBo;
+import org.dromara.order.domain.vo.OrderCustomerFlowNodeVo;
+import org.dromara.order.domain.OrderCustomerFlowNode;
+import org.dromara.order.mapper.OrderCustomerFlowNodeMapper;
+import org.dromara.order.service.IOrderCustomerFlowNodeService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 客户订单流程节点Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class OrderCustomerFlowNodeServiceImpl  extends ServiceImpl<OrderCustomerFlowNodeMapper, OrderCustomerFlowNode> implements IOrderCustomerFlowNodeService {
+
+    private final OrderCustomerFlowNodeMapper baseMapper;
+
+    /**
+     * 查询客户订单流程节点
+     *
+     * @param id 主键
+     * @return 客户订单流程节点
+     */
+    @Override
+    public OrderCustomerFlowNodeVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询客户订单流程节点列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户订单流程节点分页列表
+     */
+    @Override
+    public TableDataInfo<OrderCustomerFlowNodeVo> queryPageList(OrderCustomerFlowNodeBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<OrderCustomerFlowNode> lqw = buildQueryWrapper(bo);
+        Page<OrderCustomerFlowNodeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的客户订单流程节点列表
+     *
+     * @param bo 查询条件
+     * @return 客户订单流程节点列表
+     */
+    @Override
+    public List<OrderCustomerFlowNodeVo> queryList(OrderCustomerFlowNodeBo bo) {
+        LambdaQueryWrapper<OrderCustomerFlowNode> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<OrderCustomerFlowNode> buildQueryWrapper(OrderCustomerFlowNodeBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<OrderCustomerFlowNode> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(OrderCustomerFlowNode::getId);
+        lqw.eq(bo.getFlowId() != null, OrderCustomerFlowNode::getFlowId, bo.getFlowId());
+        lqw.eq(bo.getNodeType() != null, OrderCustomerFlowNode::getNodeType, bo.getNodeType());
+        lqw.eq(bo.getHandlerId() != null, OrderCustomerFlowNode::getHandlerId, bo.getHandlerId());
+        lqw.eq(bo.getSort() != null, OrderCustomerFlowNode::getSort, bo.getSort());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), OrderCustomerFlowNode::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增客户订单流程节点
+     *
+     * @param bo 客户订单流程节点
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(OrderCustomerFlowNodeBo bo) {
+        OrderCustomerFlowNode add = MapstructUtils.convert(bo, OrderCustomerFlowNode.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改客户订单流程节点
+     *
+     * @param bo 客户订单流程节点
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(OrderCustomerFlowNodeBo bo) {
+        OrderCustomerFlowNode update = MapstructUtils.convert(bo, OrderCustomerFlowNode.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(OrderCustomerFlowNode entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除客户订单流程节点信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 423 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderCustomerFlowServiceImpl.java

@@ -0,0 +1,423 @@
+package org.dromara.order.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.order.domain.OrderCustomerFlowLink;
+import org.dromara.order.domain.OrderCustomerFlowNodeLink;
+import org.dromara.order.domain.bo.OrderCustomerFlowLinkBo;
+import org.dromara.order.service.IOrderCustomerFlowLinkService;
+import org.dromara.order.service.IOrderCustomerFlowNodeLinkService;
+import org.springframework.stereotype.Service;
+import org.dromara.order.domain.bo.OrderCustomerFlowBo;
+import org.dromara.order.domain.bo.OrderCustomerFlowSaveBo;
+import org.dromara.order.domain.bo.OrderCustomerFlowNodeBo;
+import org.dromara.order.domain.bo.OrderCustomerFlowNodeLinkBo;
+import org.dromara.order.domain.vo.OrderCustomerFlowVo;
+import org.dromara.order.domain.OrderCustomerFlow;
+import org.dromara.order.domain.OrderCustomerFlowNode;
+import org.dromara.order.domain.OrderCustomerFlowLink;
+import org.dromara.order.domain.OrderCustomerFlowNodeLink;
+import org.dromara.order.mapper.OrderCustomerFlowMapper;
+import org.dromara.order.mapper.OrderCustomerFlowNodeMapper;
+import org.dromara.order.service.IOrderCustomerFlowService;
+import org.dromara.order.service.IOrderCustomerFlowNodeService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+import java.util.Objects;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * 客户订单流程Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-02-25
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class OrderCustomerFlowServiceImpl  extends ServiceImpl<OrderCustomerFlowMapper, OrderCustomerFlow> implements IOrderCustomerFlowService {
+
+    private final OrderCustomerFlowMapper baseMapper;
+
+    private final IOrderCustomerFlowNodeService nodeService;
+
+    private final IOrderCustomerFlowLinkService linkService;
+
+    private final IOrderCustomerFlowNodeLinkService nodeLinkService;
+
+
+
+
+    /**
+     * 查询客户订单流程
+     *
+     * @param id 主键
+     * @return 客户订单流程
+     */
+    @Override
+    public OrderCustomerFlowVo queryById(Long id){
+        OrderCustomerFlowVo orderCustomerFlowVo = baseMapper.selectVoById(id);
+        List<OrderCustomerFlowNode> orderCustomerFlowNodes = nodeService.list(Wrappers.lambdaQuery(OrderCustomerFlowNode.class).eq(OrderCustomerFlowNode::getFlowId, orderCustomerFlowVo.getId()));
+        orderCustomerFlowVo.setFlowNodes(orderCustomerFlowNodes);
+        return orderCustomerFlowVo;
+    }
+
+    /**
+     * 分页查询客户订单流程列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户订单流程分页列表
+     */
+    @Override
+    public TableDataInfo<OrderCustomerFlowVo> queryPageList(OrderCustomerFlowBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<OrderCustomerFlow> lqw = buildQueryWrapper(bo);
+        Page<OrderCustomerFlowVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的客户订单流程列表
+     *
+     * @param bo 查询条件
+     * @return 客户订单流程列表
+     */
+    @Override
+    public List<OrderCustomerFlowVo> queryList(OrderCustomerFlowBo bo) {
+        LambdaQueryWrapper<OrderCustomerFlow> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<OrderCustomerFlow> buildQueryWrapper(OrderCustomerFlowBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<OrderCustomerFlow> lqw = Wrappers.lambdaQuery();
+        lqw.like(StringUtils.isNotBlank(bo.getFlowName()), OrderCustomerFlow::getFlowName, bo.getFlowName());
+        lqw.eq(bo.getCustomerId() != null, OrderCustomerFlow::getCustomerId, bo.getCustomerId());
+        lqw.eq(bo.getUserId() != null, OrderCustomerFlow::getUserId, bo.getUserId());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), OrderCustomerFlow::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), OrderCustomerFlow::getPlatformCode, bo.getPlatformCode());
+        lqw.orderByDesc(OrderCustomerFlow::getUpdateTime);
+        return lqw;
+    }
+
+    /**
+     * 新增客户订单流程
+     *
+     * @param bo 客户订单流程
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(OrderCustomerFlowBo bo) {
+        OrderCustomerFlow add = MapstructUtils.convert(bo, OrderCustomerFlow.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改客户订单流程
+     *
+     * @param bo 客户订单流程
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(OrderCustomerFlowBo bo) {
+        OrderCustomerFlow update = MapstructUtils.convert(bo, OrderCustomerFlow.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(OrderCustomerFlow entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 保存编辑客户订单流程(包括流程和节点)
+     *
+     * @param bo 客户订单流程保存对象
+     * @return 是否保存成功
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean saveFlowWithNodes(OrderCustomerFlowSaveBo bo) {
+        if (bo == null) {
+            return false;
+        }
+
+        boolean isNew = bo.getId() == null || bo.getId() <= 0;
+
+        // 1. 保存或更新流程主表
+        OrderCustomerFlowBo flowBo = new OrderCustomerFlowBo();
+        flowBo.setId(bo.getId());
+        flowBo.setFlowName(bo.getFlowName());
+        flowBo.setCustomerId(bo.getCustomerId());
+        flowBo.setUserId(bo.getUserId());
+        flowBo.setStatus(bo.getStatus());
+        flowBo.setRemark(bo.getRemark());
+
+        boolean flowSuccess;
+        if (isNew) {
+            flowSuccess = this.insertByBo(flowBo);
+            if (flowSuccess) {
+                bo.setId(flowBo.getId()); // 回填ID
+            }
+        } else {
+            flowSuccess = this.updateByBo(flowBo);
+        }
+
+
+        Long flowId = flowBo.getId();
+
+        // 2. 处理节点信息
+        List<OrderCustomerFlowNodeBo> nodeBos = bo.getFlowNodes();
+        if (nodeBos != null && !nodeBos.isEmpty()) {
+            // 如果是更新操作,先删除原有的节点
+            if (!isNew) {
+                LambdaQueryWrapper<OrderCustomerFlowNode> deleteWrapper = Wrappers.lambdaQuery();
+                deleteWrapper.eq(OrderCustomerFlowNode::getFlowId, flowId);
+                nodeService.remove(deleteWrapper);
+            }
+
+            // 批量插入新节点
+            for (OrderCustomerFlowNodeBo nodeBo : nodeBos) {
+                nodeBo.setFlowId(flowId);
+                nodeService.insertByBo(nodeBo);
+            }
+        } else if (!isNew) {
+            // 如果是更新且没有提供节点,则删除原有节点
+            LambdaQueryWrapper<OrderCustomerFlowNode> deleteWrapper = Wrappers.lambdaQuery();
+            deleteWrapper.eq(OrderCustomerFlowNode::getFlowId, flowId);
+            nodeService.remove(deleteWrapper);
+        }
+
+        return true;
+    }
+
+    /**
+     * 校验并批量删除客户订单流程信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+
+    /**
+     * 初始化订单流程
+     *
+     * @param orderId 订单ID
+     */
+    @Override
+    public void initOrderFlow(Long orderId) {
+        //查询默认开启的流程
+        OrderCustomerFlow flow = baseMapper.selectOne(
+            new LambdaQueryWrapper<OrderCustomerFlow>().eq(OrderCustomerFlow::getStatus, "0")
+                .orderByDesc(OrderCustomerFlow::getUpdateTime)
+                .last("limit 1")
+        );
+        if (flow == null) {
+            return;
+        }
+        //查询流程节点
+        List<OrderCustomerFlowNode> orderCustomerFlowNodes = nodeService.list(
+            new LambdaQueryWrapper<OrderCustomerFlowNode>().eq(OrderCustomerFlowNode::getFlowId, flow.getId())
+        );
+        if (ObjectUtil.isEmpty(orderCustomerFlowNodes)){
+            return;
+        }
+        //
+        Long firstNodeId = null;
+        //先初始化流程节点
+        for (OrderCustomerFlowNode orderCustomerFlowNode : orderCustomerFlowNodes) {
+            OrderCustomerFlowNodeLink nodeLink = BeanUtil.toBean(orderCustomerFlowNode, OrderCustomerFlowNodeLink.class);
+            nodeLink.setId(null);
+            nodeLink.setOrderId(orderId);
+            nodeLink.setFlowId(flow.getId());
+            nodeLinkService.save(nodeLink);
+            if (orderCustomerFlowNode.getNodeType() == 0){
+                firstNodeId = nodeLink.getId();
+            }
+        }
+        OrderCustomerFlowLink flowLink = new OrderCustomerFlowLink();
+        flowLink.setOrderId(orderId);
+        flowLink.setFlowId(flow.getId());
+        flowLink.setNodeId(firstNodeId);
+        linkService.save(flowLink);
+    }
+
+    /**
+     * 审核订单流程
+     *
+     * @param bo 审核信息
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void auditOrderFlow(OrderCustomerFlowLinkBo bo) {
+        // 参数校验
+        if (bo == null || bo.getOrderId() == null || bo.getNodeId() == null || bo.getReviewStatus() == null) {
+            throw new IllegalArgumentException("审核参数不完整");
+        }
+
+        // 1. 查询当前流程链接信息
+        OrderCustomerFlowLink currentLink = linkService.getOne(
+            new LambdaQueryWrapper<OrderCustomerFlowLink>()
+                .eq(OrderCustomerFlowLink::getOrderId, bo.getOrderId())
+                .eq(OrderCustomerFlowLink::getNodeId, bo.getNodeId())
+        );
+
+        if (currentLink == null) {
+            throw new RuntimeException("未找到对应的流程节点信息");
+        }
+
+        // 2. 查询当前节点链接信息
+        OrderCustomerFlowNodeLink currentNodeLink = nodeLinkService.getOne(
+            new LambdaQueryWrapper<OrderCustomerFlowNodeLink>()
+                .eq(OrderCustomerFlowNodeLink::getOrderId, bo.getOrderId())
+                .eq(OrderCustomerFlowNodeLink::getId, bo.getNodeId())
+        );
+
+        if (currentNodeLink == null) {
+            throw new RuntimeException("未找到对应的节点链接信息");
+        }
+
+        // 3. 直接更新节点链接表的审核状态
+        OrderCustomerFlowNodeLink updateNodeLink = new OrderCustomerFlowNodeLink();
+        updateNodeLink.setId(currentNodeLink.getId());
+        updateNodeLink.setReviewStatus(bo.getReviewStatus());
+        updateNodeLink.setReason(bo.getReason());
+        updateNodeLink.setRemark(bo.getRemark());
+
+        boolean nodeUpdateSuccess = nodeLinkService.updateById(updateNodeLink);
+        if (!nodeUpdateSuccess) {
+            throw new RuntimeException("更新节点审核状态失败");
+        }
+
+        // 4. 根据审核结果处理流程流转
+        if (bo.getReviewStatus() == 1) { // 审核通过
+            handleAuditPass(bo, currentLink, currentNodeLink);
+        } else if (bo.getReviewStatus() == 2) { // 审核驳回
+            handleAuditReject(bo, currentLink, currentNodeLink);
+        } else {
+            throw new IllegalArgumentException("无效的审核状态");
+        }
+
+        // 5. 更新流程链接表的当前节点信息
+        OrderCustomerFlowLink updateLink = new OrderCustomerFlowLink();
+        updateLink.setId(currentLink.getId());
+        updateLink.setReviewStatus(bo.getReviewStatus());
+        updateLink.setReason(bo.getReason());
+        updateLink.setRemark(bo.getRemark());
+
+        linkService.updateById(updateLink);
+    }
+
+    /**
+     * 处理审核通过逻辑
+     */
+    private void handleAuditPass(OrderCustomerFlowLinkBo bo, OrderCustomerFlowLink currentLink, OrderCustomerFlowNodeLink currentNodeLink) {
+        Long orderId = currentLink.getOrderId();
+
+        // 查询流程的所有节点,按排序字段排列
+        List<OrderCustomerFlowNodeLink> flowNodes = nodeLinkService.list(
+            new LambdaQueryWrapper<OrderCustomerFlowNodeLink>()
+                .eq(OrderCustomerFlowNodeLink::getOrderId, orderId)
+                .orderByAsc(OrderCustomerFlowNodeLink::getSort)
+        );
+
+
+
+        if (ObjectUtil.isEmpty(flowNodes)) {
+            throw new RuntimeException("流程节点配置异常");
+        }
+
+        // 找到当前节点在流程中的位置
+        // 注意:这里应该通过nodeId而不是直接比较id
+        int currentIndex = -1;
+        for (int i = 0; i < flowNodes.size(); i++) {
+            if (flowNodes.get(i).getId().equals(currentLink.getNodeId())) {
+                currentIndex = i;
+                break;
+            }
+        }
+
+        if (currentIndex == -1) {
+            throw new RuntimeException("无法定位当前节点在流程中的位置");
+        }
+
+        // 将当前节点的链接信息更新
+        OrderCustomerFlowNodeLink node = flowNodes.get(currentIndex);
+        node.setReviewStatus(1L); // 待审核状态
+        nodeLinkService.updateById(node);
+
+        // 如果不是最后一个节点,移动到下一个节点
+        if (currentIndex < flowNodes.size() - 1) {
+
+            // 更新流程链接表指向新的节点
+            OrderCustomerFlowNodeLink nextNode = flowNodes.get(currentIndex + 1);
+
+            OrderCustomerFlowLink updateLink = new OrderCustomerFlowLink();
+            updateLink.setId(currentLink.getId());
+            updateLink.setNodeId(nextNode.getId());
+            updateLink.setHandlerId(nextNode.getHandlerId());
+            updateLink.setReviewStatus(0L); // 待审核
+
+            linkService.updateById(updateLink);
+        } else {
+            // 已经是最后一个节点,流程结束
+            OrderCustomerFlowLink updateLink = new OrderCustomerFlowLink();
+            updateLink.setId(currentLink.getId());
+            updateLink.setReviewStatus(1L); // 流程完成
+
+            linkService.updateById(updateLink);
+        }
+    }
+
+    /**
+     * 处理审核驳回逻辑
+     */
+    private void handleAuditReject(OrderCustomerFlowLinkBo bo, OrderCustomerFlowLink currentLink, OrderCustomerFlowNodeLink currentNodeLink) {
+        Long orderId = currentLink.getOrderId();
+        Long nodeId = currentLink.getNodeId();
+        linkService.update(Wrappers.lambdaUpdate(OrderCustomerFlowLink.class)
+            .set(OrderCustomerFlowLink::getReviewStatus, 2L)
+            .set(OrderCustomerFlowLink::getReason, bo.getReason())
+            .eq(OrderCustomerFlowLink::getOrderId, orderId)
+            .eq(OrderCustomerFlowLink::getNodeId, nodeId)
+        );
+        nodeLinkService.update(Wrappers.lambdaUpdate(OrderCustomerFlowNodeLink.class)
+            .set(OrderCustomerFlowNodeLink::getReviewStatus, 2L)
+            .set(OrderCustomerFlowNodeLink::getReason, bo.getReason())
+            .eq(OrderCustomerFlowNodeLink::getId, currentNodeLink.getId())
+        );
+        // 驳回时保持在当前节点,但可以记录驳回信息
+        // 这里可以根据业务需求决定是否需要特殊的驳回处理逻辑
+        // 比如:驳回到指定节点、重新提交等
+
+        log.info("订单{}的节点{}被驳回,驳回原因:{}",
+                 currentLink.getOrderId(), currentLink.getNodeId(), bo.getReason());
+    }
+}

+ 7 - 0
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderCustomerFlowLinkMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.order.mapper.OrderCustomerFlowLinkMapper">
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderCustomerFlowMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.order.mapper.OrderCustomerFlowMapper">
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderCustomerFlowNodeLinkMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.order.mapper.OrderCustomerFlowNodeLinkMapper">
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderCustomerFlowNodeMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.order.mapper.OrderCustomerFlowNodeMapper">
+
+</mapper>

+ 0 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/pc/IndexProductController.java

@@ -273,7 +273,6 @@ public class IndexProductController {
     * */
     @GetMapping("/getBrandByCategoryList")
     public TableDataInfo<ProductBrandVo> getBrandByCategoryList(Long categoryId,String name,String initial,PageQuery pageQuery) {
-
         return productBrandService.getBrandByCategoryList(categoryId,name,initial,pageQuery);
     }