Browse Source

Merge branch 'cpq-dev' of wangfan/adweb3-server into master

chenpeiqing 1 week ago
parent
commit
ae9e5cbac1
14 changed files with 921 additions and 20 deletions
  1. 22 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/enquiry/controller/AdwebEnquiryController.java
  2. 7 2
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/enquiry/dto/result/EnquiryListDto.java
  3. 3 3
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/enquiry/entity/AdwebEnquiry.java
  4. 1 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/enquiry/mapper/xml/AdwebEnquiryMapper.xml
  5. 14 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/enquiry/service/impl/AdwebEnquiryServiceImpl.java
  6. 2 5
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/product/service/IAdwebProductService.java
  7. 12 8
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/product/service/impl/AdwebProductServiceImpl.java
  8. 9 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/site/controller/AdwebSiteController.java
  9. 374 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/workflow/controller/ExecuteNodeController.java
  10. 110 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/workflow/entity/ExecuteNode.java
  11. 59 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/workflow/mapper/ExecuteNodeMapper.java
  12. 46 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/workflow/service/IExecuteNodeService.java
  13. 261 0
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/workflow/service/impl/ExecuteNodeServiceImpl.java
  14. 1 2
      jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mq/ProductReceiver.java

+ 22 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/enquiry/controller/AdwebEnquiryController.java

@@ -32,6 +32,7 @@ import org.jeecg.common.system.vo.LoginUser;
 import org.jeecg.common.util.FastJsonUtil;
 import org.jeecg.config.shiro.IgnoreAuth;
 import org.jeecg.modules.adweb.common.constant.AdwebConstant;
+import org.jeecg.modules.adweb.common.constant.NumConstant;
 import org.jeecg.modules.adweb.common.util.AwsTranslateUtils;
 import org.jeecg.modules.adweb.common.util.DateUtil;
 import org.jeecg.modules.adweb.enquiry.constant.EnquirySendStatus;
@@ -52,6 +53,7 @@ import org.jeecg.modules.adweb.site.entity.AdwebSite;
 import org.jeecg.modules.adweb.site.service.IAdwebSiteService;
 import org.jeecg.modules.adweb.site.service.ISiteUserPermissionService;
 import org.jeecg.modules.adweb.system.service.SysAdwebApi;
+import org.jeecg.modules.adweb.workflow.service.IExecuteNodeService;
 import org.jeecg.modules.system.entity.SysUser;
 import org.jeecg.modules.system.service.ISysDictService;
 import org.jeecg.modules.system.service.ISysUserService;
@@ -96,6 +98,8 @@ public class AdwebEnquiryController extends JeecgController<AdwebEnquiry, IAdweb
 
   @Resource private IAdwebMatomoService adwebMatomoService;
 
+  @Resource private IExecuteNodeService nodeService;
+
   /**
    * 分页列表查询
    *
@@ -210,6 +214,8 @@ public class AdwebEnquiryController extends JeecgController<AdwebEnquiry, IAdweb
         sysDictService.queryDictItemsByCode(AdwebConstant.ENQUIRY_EFFECTIVE);
     AtomicInteger atomicInteger = new AtomicInteger();
 
+    int verifySteps = Math.toIntExact(nodeService.getEnquiryVerifyTemplateFlowCount());
+
     enquiryList.forEach(
         enquiry -> {
           // 来源页面如果以 / 结尾,去掉最后一个字符
@@ -270,6 +276,22 @@ public class AdwebEnquiryController extends JeecgController<AdwebEnquiry, IAdweb
             }
             enquiry.setContext(context);
           }
+
+          // 设置审核进度, 如已经是有效询盘,直接审核进度设为100
+          if (enquiry.getUserEffective() != null && enquiry.getUserEffective() == 1) {
+            enquiry.setVerifyProgress(NumConstant.ONE_HUNDRED);
+          }
+
+          if (enquiry.getUserEffective() != null && enquiry.getUserEffective() == 2) {
+
+            // 审核进度为null或者0时,审核进度为0
+            if (enquiry.getVerifyNum() != null) {
+              enquiry.setVerifyProgress(
+                  enquiry.getVerifyNum() * NumConstant.ONE_HUNDRED / verifySteps);
+            } else {
+              enquiry.setVerifyProgress(NumConstant.ZERO);
+            }
+          }
         });
   }
 

+ 7 - 2
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/enquiry/dto/result/EnquiryListDto.java

@@ -2,10 +2,9 @@ package org.jeecg.modules.adweb.enquiry.dto.result;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import lombok.Data;
-
 import java.util.Date;
 import java.util.List;
+import lombok.Data;
 
 @Data
 public class EnquiryListDto {
@@ -83,6 +82,8 @@ public class EnquiryListDto {
 
   private String principalUid;
 
+  private String uid;
+
   private String principalName;
 
   /** 特殊字段名 */
@@ -97,4 +98,8 @@ public class EnquiryListDto {
   private String pluginName;
 
   private String wasteEnquiryType;
+
+  private Integer verifyNum;
+
+  private Integer verifyProgress;
 }

+ 3 - 3
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/enquiry/entity/AdwebEnquiry.java

@@ -243,9 +243,9 @@ public class AdwebEnquiry implements Serializable {
   private Integer pushStatus;
 
   /** 推送错误次数 */
-  @Excel(name = "推送错误次数", width = 15)
-  @Schema(description = "推送错误次数")
-  private Integer pushErrorNum;
+  @Excel(name = "审核通过次数", width = 15)
+  @Schema(description = "审核通过次数")
+  private Integer verifyNum;
 
   /** 姓名 */
   @Excel(name = "姓名", width = 15)

+ 1 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/enquiry/mapper/xml/AdwebEnquiryMapper.xml

@@ -39,6 +39,7 @@
         t1.read_status,
         t1.visit_id,
         t1.special_field,
+        t1.verify_num AS verifyNum,
         t1.cart_items as cartItems,
         t1.effective_reason effectiveReason,
         t1.plugin_name pluginName,

+ 14 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/enquiry/service/impl/AdwebEnquiryServiceImpl.java

@@ -42,6 +42,7 @@ import org.jeecg.modules.adweb.enquiry.service.*;
 import org.jeecg.modules.adweb.site.entity.AdwebSite;
 import org.jeecg.modules.adweb.site.service.IAdwebSiteService;
 import org.jeecg.modules.adweb.site.service.ISiteUserPermissionService;
+import org.jeecg.modules.adweb.subscription.mapper.UserPlanSubscriptionMapper;
 import org.jeecg.modules.adweb.system.entity.SysException;
 import org.jeecg.modules.adweb.system.service.IMasterSubAccountRelationService;
 import org.jeecg.modules.adweb.system.service.ISysExceptionService;
@@ -50,6 +51,7 @@ import org.jeecg.modules.adweb.userCountry.entity.AdwebCountry;
 import org.jeecg.modules.adweb.userCountry.entity.AdwebUserCountry;
 import org.jeecg.modules.adweb.userCountry.service.IAdwebCountryService;
 import org.jeecg.modules.adweb.userCountry.service.IAdwebUserCountryService;
+import org.jeecg.modules.adweb.workflow.service.IExecuteNodeService;
 import org.jeecg.modules.message.websocket.WebSocket;
 import org.jeecg.modules.system.entity.SysDictItem;
 import org.jeecg.modules.system.entity.SysUser;
@@ -127,6 +129,10 @@ public class AdwebEnquiryServiceImpl extends ServiceImpl<AdwebEnquiryMapper, Adw
 
   @Resource private ISubUserEmailService subUserEmailService;
 
+  @Resource private UserPlanSubscriptionMapper userPlanSubscriptionMapper;
+
+  @Resource private IExecuteNodeService executeNodeService;
+
   private static final byte[] redisKey = EnquiryConstants.ENQUIRY_EMAIL.getBytes();
 
   private static final byte[] siteRedisKey = EnquiryConstants.ENQUIRY_SITE.getBytes();
@@ -395,6 +401,14 @@ public class AdwebEnquiryServiceImpl extends ServiceImpl<AdwebEnquiryMapper, Adw
 
     // 发送询盘邮件
     sendValidateEmail(target, adwebSite, principalEmailMap);
+
+    // 如果站点套餐是苏豪全托管,则创建有效询盘审核流程
+    Map<String, String> subscribePlan =
+        userPlanSubscriptionMapper.getSubscribePlanBySiteId(adwebSite.getId());
+
+    if ("苏豪通全托管".equals(subscribePlan.get("planName")) && target.getUserEffective() == 1) {
+      executeNodeService.copyEnquiryVerifyFlow(target.getId().toString());
+    }
   }
 
   /** 设置询盘负责人 */

+ 2 - 5
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/product/service/IAdwebProductService.java

@@ -6,12 +6,9 @@ import org.jeecg.modules.adweb.product.entity.AdwebProduct;
 import org.jeecg.modules.adweb.site.entity.AdwebSite;
 
 /**
- * @Description: wp站点产品
- * @Author: jeecg-boot
- * @Date: 2024-12-06
- * @Version: V1.0
+ * @Description: wp站点产品 @Author: jeecg-boot @Date: 2024-12-06 @Version: V1.0
  */
 public interface IAdwebProductService extends IService<AdwebProduct> {
 
-    void addOrUpdateProduct(ProductDTO productDTO, AdwebSite adwebSites);
+  void addOrUpdateProduct(ProductDTO productDTO, AdwebSite adwebSite);
 }

+ 12 - 8
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/product/service/impl/AdwebProductServiceImpl.java

@@ -43,21 +43,25 @@ public class AdwebProductServiceImpl extends ServiceImpl<AdwebProductMapper, Adw
    * @param adwebSites
    */
   @Override
-  public void addOrUpdateProduct(ProductDTO productDTO, AdwebSite adwebSites) {
+  public void addOrUpdateProduct(ProductDTO productDTO, AdwebSite adwebSite) {
     // 产品同步时,update 有可能是新增或者更新,根据数据库中记录进行再次判断
     if ("update".equals(productDTO.getActionType())
         || "delete".equals(productDTO.getActionType())) {
-      handleUpdate(productDTO, adwebSites);
+      handleUpdate(productDTO, adwebSite);
     } else {
-      handleAdd(productDTO, adwebSites);
+      handleAdd(productDTO, adwebSite);
     }
 
-    Sohoeb2bOrder siteOrderPost = sohoeb2bOrderService.getBySiteCode(adwebSites.getCode());
-    // 属于苏豪租户的站点 向苏豪接口发送产品信息
-    if ("江苏苏豪纺织集团有限公司".equals(adwebSites.getChannelProviderName()) && siteOrderPost != null) {
-      if (StringUtils.isNotBlank(siteOrderPost.getOrderUrl())) {
-        pushSohoeB2BProduct(productDTO, adwebSites);
+    try {
+      Sohoeb2bOrder siteOrderPost = sohoeb2bOrderService.getBySiteCode(adwebSite.getCode());
+      // 属于苏豪租户的站点 向苏豪接口发送产品信息
+      if ("江苏苏豪纺织集团有限公司".equals(adwebSite.getChannelProviderName()) && siteOrderPost != null) {
+        if (StringUtils.isNotBlank(siteOrderPost.getOrderUrl())) {
+          pushSohoeB2BProduct(productDTO, adwebSite);
+        }
       }
+    } catch (Exception e) {
+      log.error("推送产品到苏豪失败:{}", adwebSite.getName(), e);
     }
   }
 

+ 9 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/site/controller/AdwebSiteController.java

@@ -286,6 +286,15 @@ public class AdwebSiteController extends JeecgController<AdwebSite, IAdwebSiteSe
     return Result.ok(siteList);
   }
 
+  @GetMapping("/getSubscribePlanBySite")
+  public Result<?> getSubscribePlanBySite(
+      @RequestParam(name = "siteId", required = true) String siteId) {
+    Map<String, String> subscribePlan =
+        userPlanSubscriptionMapper.getSubscribePlanBySiteId(Integer.valueOf(siteId));
+
+    return Result.OK(subscribePlan);
+  }
+
   /**
    * 更新site表现阶段
    *

+ 374 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/workflow/controller/ExecuteNodeController.java

@@ -0,0 +1,374 @@
+package org.jeecg.modules.adweb.workflow.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.modules.adweb.common.constant.NumConstant;
+import org.jeecg.modules.adweb.enquiry.entity.AdwebEnquiry;
+import org.jeecg.modules.adweb.enquiry.service.IAdwebEnquiryService;
+import org.jeecg.modules.adweb.site.entity.AdwebSite;
+import org.jeecg.modules.adweb.site.service.IAdwebSiteService;
+import org.jeecg.modules.adweb.workflow.entity.ExecuteNode;
+import org.jeecg.modules.adweb.workflow.service.IExecuteNodeService;
+import org.jeecg.modules.system.entity.SysUser;
+import org.jeecg.modules.system.service.ISysUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+
+/**
+ * @Description: adweb_execute_node @Author: jeecg-boot @Date: 2025-03-21 @Version: V1.0
+ */
+@Tag(name = "adweb_execute_node")
+@RestController
+@RequestMapping("/adweb/executeNode")
+@Slf4j
+public class ExecuteNodeController extends JeecgController<ExecuteNode, IExecuteNodeService> {
+
+  @Autowired private IExecuteNodeService executeNodeService;
+
+  @Autowired private IAdwebSiteService siteService;
+
+  @Autowired private IAdwebEnquiryService adwebEnquiryService;
+
+  @Autowired private ISysUserService sysUserService;
+
+  /**
+   * 分页列表查询
+   *
+   * @param executeNode
+   * @param pageNo
+   * @param pageSize
+   * @param req
+   * @return
+   */
+  @AutoLog(value = "adweb_execute_node-分页列表查询")
+  @Operation(summary = "adweb_execute_node-分页列表查询")
+  @GetMapping(value = "/list")
+  public Result<?> queryPageList(
+      ExecuteNode executeNode,
+      @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+      @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+      HttpServletRequest req) {
+    QueryWrapper<ExecuteNode> queryWrapper =
+        QueryGenerator.initQueryWrapper(executeNode, req.getParameterMap());
+    Page<ExecuteNode> page = new Page<ExecuteNode>(pageNo, pageSize);
+    IPage<ExecuteNode> pageList = executeNodeService.page(page, queryWrapper);
+    return Result.OK(pageList);
+  }
+
+  /**
+   * 添加
+   *
+   * @param executeNode
+   * @return
+   */
+  @AutoLog(value = "adweb_execute_node-添加")
+  @Operation(summary = "adweb_execute_node-添加")
+  @PostMapping(value = "/add")
+  public Result<?> add(@RequestBody ExecuteNode executeNode) {
+    executeNodeService.save(executeNode);
+    return Result.OK("添加成功!");
+  }
+
+  /**
+   * 编辑
+   *
+   * @param executeNode
+   * @return
+   */
+  @AutoLog(value = "adweb_execute_node-编辑")
+  @Operation(summary = "adweb_execute_node-编辑")
+  @PutMapping(value = "/edit")
+  public Result<?> edit(@RequestBody ExecuteNode executeNode) {
+    executeNodeService.updateById(executeNode);
+    return Result.OK("编辑成功!");
+  }
+
+  /**
+   * 通过id删除
+   *
+   * @param id
+   * @return
+   */
+  @AutoLog(value = "adweb_execute_node-通过id删除")
+  @Operation(summary = "adweb_execute_node-通过id删除")
+  @DeleteMapping(value = "/delete")
+  public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
+    executeNodeService.removeById(id);
+    return Result.OK("删除成功!");
+  }
+
+  /**
+   * 批量删除
+   *
+   * @param ids
+   * @return
+   */
+  @AutoLog(value = "adweb_execute_node-批量删除")
+  @Operation(summary = "adweb_execute_node-批量删除")
+  @DeleteMapping(value = "/deleteBatch")
+  public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+    this.executeNodeService.removeByIds(Arrays.asList(ids.split(",")));
+    return Result.OK("批量删除成功!");
+  }
+
+  /**
+   * 通过id查询
+   *
+   * @param id
+   * @return
+   */
+  @AutoLog(value = "adweb_execute_node-通过id查询")
+  @Operation(summary = "adweb_execute_node-通过id查询")
+  @GetMapping(value = "/queryById")
+  public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
+    ExecuteNode executeNode = executeNodeService.getById(id);
+    if (executeNode == null) {
+      return Result.error("未找到对应数据");
+    }
+    return Result.OK(executeNode);
+  }
+
+  /**
+   * 导出excel
+   *
+   * @param request
+   * @param executeNode
+   */
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, ExecuteNode executeNode) {
+    return super.exportXls(request, executeNode, ExecuteNode.class, "adweb_execute_node");
+  }
+
+  /**
+   * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+    return super.importExcel(request, response, ExecuteNode.class);
+  }
+
+  /**
+   * 通过siteCode查询建站执行流程
+   *
+   * @param siteCode 站点code @Author: luxiaoxiao @Date: 2021/10/28
+   */
+  @GetMapping(value = "/querySiteBuildFlow")
+  @Operation(summary = "通过siteCode查询建站执行流程")
+  public Result<?> querySiteBuildFlow(
+      @RequestParam(name = "siteCode", required = true) String siteCode) {
+    List<ExecuteNode> list = executeNodeService.getSiteBuildFlow(siteCode);
+    if (CollectionUtils.isEmpty(list)) {
+      return Result.error("未找到对应数据");
+    }
+    return Result.OK(list);
+  }
+
+  /**
+   * 通过询盘ID查出审核流程
+   *
+   * @param enquiryId 询盘ID @Author: chenpeiqing @Date: 2025/03/24
+   */
+  @GetMapping(value = "/queryEnquiryVerifyFlow")
+  @Operation(summary = "通过询盘ID查出审核流程")
+  public Result<?> queryEnquiryVerifyFlow(
+      @RequestParam(name = "enquiryId", required = true) String enquiryId) {
+    List<ExecuteNode> list = executeNodeService.getEnquiryVerifyFlow(enquiryId);
+    if (CollectionUtils.isEmpty(list)) {
+
+      // 如果询盘审核流程不存在创建审核流程,该逻辑为了兼容旧询盘数据,正常情况下,凡是查询盘的审核流程都已经有,所以这里就不做处理了
+      // 询盘审核流程,在MQ消费插入询盘时自动创建
+      executeNodeService.copyEnquiryVerifyFlow(enquiryId);
+      list = executeNodeService.getEnquiryVerifyFlow(enquiryId);
+    }
+
+    // 设置审核人
+    for (ExecuteNode executeNode : list) {
+      if (StringUtils.isNotBlank(executeNode.getFinUid())) {
+        SysUser user = sysUserService.getById(executeNode.getFinUid());
+        if (user != null) {
+          executeNode.setFinName(user.getRealname());
+        }
+      }
+    }
+
+    return Result.OK(list);
+  }
+
+  /** 查询建站模板流程 @Author: luxiaoxiao @Date: 2021/10/28 */
+  @GetMapping(value = "/querySiteBuildTemplateFlow")
+  @Operation(summary = "查询建站模板流程")
+  public Result<?> querySiteBuildTemplateFlow() {
+    List<ExecuteNode> list = executeNodeService.getSiteBuildTemplateFlow();
+    if (CollectionUtils.isEmpty(list)) {
+      return Result.error("未找到对应数据");
+    }
+    return Result.OK(list);
+  }
+
+  /** 查询建站模板流程 @Author: luxiaoxiao @Date: 2021/10/28 */
+  @GetMapping(value = "/queryEnquiryVerifyTemplateFlow")
+  @Operation(summary = "查询询盘蛇和模板流程")
+  public Result<?> queryEnquiryVerifyTemplateFlow() {
+    List<ExecuteNode> list = executeNodeService.getEnquiryVerifyTemplateFlow();
+    if (CollectionUtils.isEmpty(list)) {
+      return Result.error("未找到对应数据");
+    }
+    return Result.OK(list);
+  }
+
+  /** 通过planId查询SEO优化模板流程 @Author: luxiaoxiao @Date: 2021/10/28 */
+  @GetMapping(value = "/querySEOTemplateFlow")
+  @Operation(summary = "查询SEO优化模板流程")
+  public Result<?> querySEOTemplateFlow() {
+    List<ExecuteNode> list = executeNodeService.getSEOTemplateFlow();
+    if (CollectionUtils.isEmpty(list)) {
+      return Result.error("未找到对应数据");
+    }
+    return Result.OK(list);
+  }
+
+  /** 保存流程,hostId不能为空 @Author: luxiaoxiao @Date: 2021/10/28 */
+  @PostMapping(value = "/saveFlowTemplate")
+  @Operation(summary = "保存流程模板")
+  public Result<?> saveTemplate(@RequestBody List<ExecuteNode> nodeList) {
+    boolean result = executeNodeService.saveTemplate(nodeList);
+    return result ? Result.OK() : Result.error("操作失败");
+  }
+
+  /**
+   * 流程完成与撤销,同时更新site表现阶段
+   *
+   * @param executeNode @Author: jerry @Date: 2021/12/03
+   */
+  @RequestMapping(value = "/finishOrRollbackStep")
+  public Result<?> finishOrRollbackStep(@RequestBody ExecuteNode executeNode) {
+    // 更新节点数据
+    LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+    UpdateWrapper<ExecuteNode> updateWrapper = new UpdateWrapper<>();
+    updateWrapper.eq("id", executeNode.getId());
+    updateWrapper.set("status", executeNode.getStatus());
+    if (executeNode.getStatus() == 0) {
+      updateWrapper.set("fin_time", null);
+      updateWrapper.set("fin_uid", null);
+    }
+    if (executeNode.getStatus() == 1) {
+      updateWrapper.set(
+          "fin_time", executeNode.getFinTime() == null ? new Date() : executeNode.getFinTime());
+      updateWrapper.set("fin_uid", sysUser.getId());
+    }
+    boolean res = executeNodeService.update(updateWrapper);
+    if (!res) {
+      return Result.error("操作失败!");
+    }
+
+    executeNode = executeNodeService.getById(executeNode.getId());
+
+    // 更新流程步骤和状态
+    UpdateWrapper<AdwebSite> siteUpdateWrapper = new UpdateWrapper<>();
+    siteUpdateWrapper.eq("code", executeNode.getHostId());
+    // SEO流程
+    if (executeNode.getNodeType().equals(NumConstant.TWO)) {
+      List<ExecuteNode> unfinishedList =
+          executeNodeService.getSeoUnfinishedNode(executeNode.getHistoryId());
+      if (CollectionUtils.isNotEmpty(unfinishedList)) {
+        siteUpdateWrapper
+            .set("seo_flow_status", 0)
+            .set("seo_current_step", unfinishedList.get(0).getName());
+      } else {
+        siteUpdateWrapper.set("seo_flow_status", 1).set("seo_current_step", "已完成");
+      }
+    }
+    // 建站流程
+    if (executeNode.getNodeType().equals(NumConstant.ONE)) {
+      List<ExecuteNode> unfinishedList =
+          executeNodeService.getSiteUnfinishedNode(executeNode.getHostId());
+      if (CollectionUtils.isNotEmpty(unfinishedList)) {
+        siteUpdateWrapper
+            .set("site_flow_status", 0)
+            .set("site_current_step", unfinishedList.get(0).getName());
+      } else {
+        siteUpdateWrapper.set("site_flow_status", 1).set("site_current_step", "已完成");
+      }
+    }
+    siteService.update(siteUpdateWrapper);
+    return Result.OK();
+  }
+
+  /**
+   * 流程完成与撤销,同时更新询盘表现阶段
+   *
+   * @param executeNode @Author: jerry @Date: 2021/12/03
+   */
+  @RequestMapping(value = "/finishOrRollbackEnquiryVerifyStep")
+  public Result<?> finishOrRollbackEnquiryVerifyStep(@RequestBody ExecuteNode executeNode) {
+
+    if (executeNode.getStepCount() == null) {
+      return Result.error("当前审核步骤长度为空!");
+    }
+
+    Integer stepCount = executeNode.getStepCount();
+
+    // 更新节点数据
+    LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+    UpdateWrapper<ExecuteNode> updateWrapper = new UpdateWrapper<>();
+    updateWrapper.eq("id", executeNode.getId());
+    updateWrapper.set("status", executeNode.getStatus());
+    updateWrapper.set("description", executeNode.getDescription());
+    if (executeNode.getStatus() == 0) {
+      updateWrapper.set("fin_time", null);
+      updateWrapper.set("fin_uid", null);
+    }
+    if (executeNode.getStatus() == 1) {
+      updateWrapper.set(
+          "fin_time", executeNode.getFinTime() == null ? new Date() : executeNode.getFinTime());
+      updateWrapper.set("fin_uid", sysUser.getId());
+    }
+    boolean res = executeNodeService.update(updateWrapper);
+    if (!res) {
+      return Result.error("操作失败!");
+    }
+
+    executeNode = executeNodeService.getById(executeNode.getId());
+
+    // 更新流程步骤和状态
+    UpdateWrapper<AdwebEnquiry> enquiryUpdateWrapper = new UpdateWrapper<>();
+    enquiryUpdateWrapper.eq("id", executeNode.getHostId());
+    // 询盘审核流程
+    if (executeNode.getNodeType().equals(NumConstant.FOUR)) {
+      List<ExecuteNode> unfinishedList =
+          executeNodeService.getEnquiryVerifyUnfinishedNode(executeNode.getHostId());
+      if (CollectionUtils.isNotEmpty(unfinishedList)) {
+        enquiryUpdateWrapper.set("verify_num", stepCount - unfinishedList.size());
+      } else {
+        enquiryUpdateWrapper.set("verify_num", stepCount); // 设置审核步骤完成
+        enquiryUpdateWrapper.set("user_Effective", 1); // 设置为有效询盘
+      }
+    }
+
+    adwebEnquiryService.update(enquiryUpdateWrapper);
+    return Result.OK();
+  }
+}

+ 110 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/workflow/entity/ExecuteNode.java

@@ -0,0 +1,110 @@
+package org.jeecg.modules.adweb.workflow.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * @Description: adweb_execute_node @Author: chenpeiqing @Date: 2025-03-21 @Version: V1.0
+ */
+@Data
+@TableName("adweb_execute_node")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@Schema(description = "adweb_execute_node")
+public class ExecuteNode implements Serializable {
+  private static final long serialVersionUID = 1L;
+
+  /** id */
+  @TableId(type = IdType.AUTO)
+  @Schema(description = "id")
+  private Integer id;
+
+  /** 1代表模板,2代表流程 */
+  @Excel(name = "1代表模板,2代表流程", width = 15)
+  @Schema(description = "1代表模板,2代表流程")
+  private Integer type;
+
+  /** 营销方案id或站点id */
+  @Excel(name = "营销方案id或站点id", width = 15)
+  @Schema(description = "营销方案id或站点id")
+  private String hostId;
+
+  /** 节点类型,1站点流程节点、2SEO流程节点 */
+  @Excel(name = "节点类型,1站点流程节点、2SEO流程节点", width = 15)
+  @Schema(description = "节点类型,1站点流程节点、2SEO流程节点")
+  private Integer nodeType;
+
+  /** 节点名称 */
+  @Excel(name = "节点名称", width = 15)
+  @Schema(description = "节点名称")
+  private String name;
+
+  /** 时间描述 */
+  @Excel(name = "时间描述", width = 15)
+  @Schema(description = "时间描述")
+  private String timeDesc;
+
+  /** 节点描述 */
+  @Excel(name = "节点描述", width = 15)
+  @Schema(description = "节点描述")
+  private String description;
+
+  /** 比重,总和为100 */
+  @Excel(name = "比重,总和为1", width = 15)
+  @Schema(description = "比重,总和为100")
+  private Integer proportion;
+
+  /** 排序 */
+  @Excel(name = "排序", width = 15)
+  @Schema(description = "排序")
+  private Double sort;
+
+  /** 1表示完成,0表示未完成,模板的节点此列可以为null */
+  @Excel(name = "1表示完成,0表示未完成,模板的节点此列可以为null", width = 15)
+  @Schema(description = "1表示完成,0表示未完成,模板的节点此列可以为null")
+  private Integer status;
+
+  /** 完成时间 */
+  @Excel(name = "完成时间", width = 15, format = "yyyy-MM-dd HH:mm:ss")
+  @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+  @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+  @Schema(description = "完成时间")
+  private Date finTime;
+
+  /** 完成人 */
+  @Excel(name = "完成人", width = 15)
+  @Schema(description = "完成人")
+  private String finUid;
+
+  /** 0未删除,1已删除 */
+  @Excel(name = "0未删除,1已删除", width = 15)
+  @Schema(description = "0未删除,1已删除")
+  private Integer delFlag;
+
+  /** 创建时间 */
+  @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
+  @DateTimeFormat(pattern = "yyyy-MM-dd")
+  @Schema(description = "创建时间")
+  private Date createTime;
+
+  private String historyId;
+
+  // 步骤数量
+  @TableField(exist = false)
+  private Integer stepCount;
+
+  // 审核人名称
+  @TableField(exist = false)
+  private String finName;
+}

+ 59 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/workflow/mapper/ExecuteNodeMapper.java

@@ -0,0 +1,59 @@
+package org.jeecg.modules.adweb.workflow.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Insert;
+import org.jeecg.modules.adweb.workflow.entity.ExecuteNode;
+
+/**
+ * @Description: adweb_execute_node @Author: jeecg-boot @Date: 2021-11-12 @Version: V1.0
+ */
+public interface ExecuteNodeMapper extends BaseMapper<ExecuteNode> {
+
+  /** 拷贝流程-审核询盘 @Author: chenpeiqing @Date: 2025/03/24 */
+  @Insert(
+      "INSERT INTO adweb_execute_node ( type, host_id, node_type, NAME, time_desc, description, proportion, sort, STATUS, fin_time, fin_uid, del_flag, create_time ) \n"
+          + "SELECT\n"
+          + "\t2 type,\n"
+          + "\t'${enquiryId}' host_id,\n"
+          + "\t4 node_type,\n"
+          + "\tNAME,\n"
+          + "\ttime_desc,\n"
+          + "\tdescription,\n"
+          + "\tproportion,\n"
+          + "\tsort,\n"
+          + "\t0 `status`,\n"
+          + "\tfin_time,\n"
+          + "\tfin_uid,\n"
+          + "\tdel_flag,\n"
+          + "\tNOW() create_time \n"
+          + "FROM\n"
+          + "\tadweb_execute_node \n"
+          + "WHERE\n"
+          + "\thost_id = #{hostId} \n"
+          + "\tAND del_flag = 0")
+  void copyEnquiryVerifyFlow(String enquiryId, String hostId);
+
+  /** 拷贝流程-创建站点 @Author: luxiaoxiao @Date: 2021/11/15 */
+  @Insert(
+      "INSERT INTO adweb_execute_node ( type, host_id, node_type, NAME, time_desc, description, proportion, sort, STATUS, fin_time, fin_uid, del_flag, create_time ) \n"
+          + "SELECT\n"
+          + "\t2 type,\n"
+          + "\t'${siteCode}' host_id,\n"
+          + "\t1 node_type,\n"
+          + "\tNAME,\n"
+          + "\ttime_desc,\n"
+          + "\tdescription,\n"
+          + "\tproportion,\n"
+          + "\tsort,\n"
+          + "\t0 `status`,\n"
+          + "\tfin_time,\n"
+          + "\tfin_uid,\n"
+          + "\tdel_flag,\n"
+          + "\tNOW() create_time \n"
+          + "FROM\n"
+          + "\tadweb_execute_node \n"
+          + "WHERE\n"
+          + "\thost_id = #{hostId} \n"
+          + "\tAND del_flag = 0")
+  void copySiteFlow(String siteCode, String hostId);
+}

+ 46 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/workflow/service/IExecuteNodeService.java

@@ -0,0 +1,46 @@
+package org.jeecg.modules.adweb.workflow.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+import org.jeecg.modules.adweb.workflow.entity.ExecuteNode;
+
+/**
+ * @Description: adweb_execute_node @Author: jeecg-boot @Date: 2021-11-12 @Version: V1.0
+ */
+public interface IExecuteNodeService extends IService<ExecuteNode> {
+
+  /** 判断站点是否具有建站流程 @Author: luxiaoxiao @Date: 2021/11/15 */
+  boolean haveSiteBuildFlow(String siteCode);
+
+  /** 获取建站流程 @Author: luxiaoxiao @Date: 2021/11/15 */
+  List<ExecuteNode> getSiteBuildFlow(String siteCode);
+
+  List<ExecuteNode> getEnquiryVerifyFlow(String siteCode);
+
+  /** 获取建站模板流程 @Author: luxiaoxiao @Date: 2021/11/15 */
+  List<ExecuteNode> getSiteBuildTemplateFlow();
+
+  List<ExecuteNode> getEnquiryVerifyTemplateFlow();
+
+  Long getEnquiryVerifyTemplateFlowCount();
+
+  /** 获取SEO优化模板流程 @Author: luxiaoxiao @Date: 2021/11/15 */
+  List<ExecuteNode> getSEOTemplateFlow();
+
+  /** 保存流程模板 @Author: luxiaoxiao @Date: 2021/11/15 */
+  boolean saveTemplate(List<ExecuteNode> nodeList);
+
+  /** 获取未完成的SEO节点 */
+  List<ExecuteNode> getSeoUnfinishedNode(String historyId);
+
+  /** 获取未完成的建站节点 */
+  List<ExecuteNode> getSiteUnfinishedNode(String siteCode);
+
+  List<ExecuteNode> getEnquiryVerifyUnfinishedNode(String enquiryId);
+
+  /** 给站点创建建站流程 @Author: luxiaoxiao @Date: 2021/11/16 */
+  boolean copySiteFlow(String siteCode);
+
+  /** 给站点创建建站流程 @Author: luxiaoxiao @Date: 2021/11/16 */
+  void copyEnquiryVerifyFlow(String enquiryId);
+}

+ 261 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/workflow/service/impl/ExecuteNodeServiceImpl.java

@@ -0,0 +1,261 @@
+package org.jeecg.modules.adweb.workflow.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import java.util.Date;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.jeecg.common.exception.JeecgBootException;
+import org.jeecg.modules.adweb.site.entity.AdwebSite;
+import org.jeecg.modules.adweb.site.service.IAdwebSiteService;
+import org.jeecg.modules.adweb.workflow.entity.ExecuteNode;
+import org.jeecg.modules.adweb.workflow.mapper.ExecuteNodeMapper;
+import org.jeecg.modules.adweb.workflow.service.IExecuteNodeService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Description: adweb_execute_node @Author: jeecg-boot @Date: 2021-11-12 @Version: V1.0
+ */
+@Service
+public class ExecuteNodeServiceImpl extends ServiceImpl<ExecuteNodeMapper, ExecuteNode>
+    implements IExecuteNodeService {
+
+  @Autowired private IAdwebSiteService adwebSiteService;
+
+  @Autowired private ExecuteNodeMapper executeNodeMapper;
+
+  /** 建站流程模板对应的hostCode */
+  private final String SITE_BUILD_CODE = "SITE_BUILD_CODE";
+
+  /** SEO优化流程模板对应的hostCode */
+  private final String SEO_OPTIMIZE_CODE = "SEO_OPTIMIZE_CODE";
+
+  private final String ENQUIRY_VERIFY_CODE = "ENQUIRY_VERIFY_CODE";
+
+  private final Integer FLOW_IS_DELETE = 0;
+
+  private final Integer FLOW_NOT_DELETE = 0;
+
+  private final Integer Flow_TYPE_TEMPLATE = 1;
+
+  private final Integer Flow_TYPE_PROCESS = 2;
+
+  private final Integer Flow_NODE_TYPE_SITE_BUILD = 1;
+
+  private final Integer Flow_NODE_TYPE_SEO_OPTIMIZE = 2;
+
+  private final Integer Flow_NODE_TYPE_TEMPLATE = 3;
+
+  private final Integer Flow_NODE_TYPE_ENQUIRY_VERIFY = 4;
+
+  /** 判断站点是否具有建站流程 @Author: luxiaoxiao @Date: 2021/11/15 */
+  @Override
+  public boolean haveSiteBuildFlow(String siteCode) {
+    QueryWrapper<AdwebSite> siteQueryWrapper = new QueryWrapper<>();
+    siteQueryWrapper.eq("code", siteCode);
+    //        siteQueryWrapper.eq("status", 1);
+    List<AdwebSite> siteList = adwebSiteService.list(siteQueryWrapper);
+    if (siteList.size() == 0) {
+      return false;
+    }
+    Integer siteFlowStatus = siteList.get(0).getSiteFlowStatus();
+    if (siteFlowStatus == null) {
+      return false;
+    }
+    if (siteFlowStatus == 1 || siteFlowStatus == 0) {
+      return true;
+    }
+    return false;
+  }
+
+  /** 获取建站流程 @Author: luxiaoxiao @Date: 2021/11/15 */
+  @Override
+  public List<ExecuteNode> getSiteBuildFlow(String siteCode) {
+    if (!haveSiteBuildFlow(siteCode)) {
+      return null;
+    }
+
+    QueryWrapper<ExecuteNode> nodeQueryWrapper = new QueryWrapper<>();
+    nodeQueryWrapper.eq("type", Flow_TYPE_PROCESS);
+    nodeQueryWrapper.eq("host_id", siteCode);
+    nodeQueryWrapper.eq("node_type", Flow_NODE_TYPE_SITE_BUILD);
+    nodeQueryWrapper.eq("del_flag", FLOW_NOT_DELETE);
+    nodeQueryWrapper.orderByAsc("sort");
+    return list(nodeQueryWrapper);
+  }
+
+  public List<ExecuteNode> getEnquiryVerifyFlow(String enquiryId) {
+    QueryWrapper<ExecuteNode> nodeQueryWrapper = new QueryWrapper<>();
+    nodeQueryWrapper.eq("type", Flow_TYPE_PROCESS);
+    nodeQueryWrapper.eq("host_id", enquiryId);
+    nodeQueryWrapper.eq("node_type", Flow_NODE_TYPE_ENQUIRY_VERIFY);
+    nodeQueryWrapper.eq("del_flag", FLOW_NOT_DELETE);
+    nodeQueryWrapper.orderByAsc("sort");
+    return list(nodeQueryWrapper);
+  }
+
+  /** 获取建站模板流程 @Author: luxiaoxiao @Date: 2021/11/15 */
+  @Override
+  public List<ExecuteNode> getSiteBuildTemplateFlow() {
+    QueryWrapper<ExecuteNode> nodeQueryWrapper = new QueryWrapper<>();
+    nodeQueryWrapper.eq("type", Flow_TYPE_TEMPLATE);
+    nodeQueryWrapper.eq("host_id", SITE_BUILD_CODE);
+    nodeQueryWrapper.eq("node_type", Flow_NODE_TYPE_TEMPLATE);
+    nodeQueryWrapper.eq("del_flag", FLOW_NOT_DELETE);
+    nodeQueryWrapper.orderByAsc("sort");
+    return list(nodeQueryWrapper);
+  }
+
+  @Override
+  public List<ExecuteNode> getEnquiryVerifyTemplateFlow() {
+    QueryWrapper<ExecuteNode> nodeQueryWrapper = new QueryWrapper<>();
+    nodeQueryWrapper.eq("type", Flow_TYPE_TEMPLATE);
+    nodeQueryWrapper.eq("host_id", ENQUIRY_VERIFY_CODE);
+    nodeQueryWrapper.eq("node_type", Flow_NODE_TYPE_TEMPLATE);
+    nodeQueryWrapper.eq("del_flag", FLOW_NOT_DELETE);
+    nodeQueryWrapper.orderByAsc("sort");
+    return list(nodeQueryWrapper);
+  }
+
+  @Override
+  public Long getEnquiryVerifyTemplateFlowCount() {
+    QueryWrapper<ExecuteNode> nodeQueryWrapper = new QueryWrapper<>();
+    nodeQueryWrapper.eq("type", Flow_TYPE_TEMPLATE);
+    nodeQueryWrapper.eq("host_id", ENQUIRY_VERIFY_CODE);
+    nodeQueryWrapper.eq("node_type", Flow_NODE_TYPE_TEMPLATE);
+    nodeQueryWrapper.eq("del_flag", FLOW_NOT_DELETE);
+    return count(nodeQueryWrapper);
+  }
+
+  /** 获取SEO优化模板流程 @Author: luxiaoxiao @Date: 2021/11/15 */
+  @Override
+  public List<ExecuteNode> getSEOTemplateFlow() {
+    QueryWrapper<ExecuteNode> nodeQueryWrapper = new QueryWrapper<>();
+    nodeQueryWrapper.eq("type", Flow_TYPE_TEMPLATE);
+    nodeQueryWrapper.eq("host_id", SEO_OPTIMIZE_CODE);
+    nodeQueryWrapper.eq("node_type", Flow_NODE_TYPE_TEMPLATE);
+    nodeQueryWrapper.eq("del_flag", FLOW_NOT_DELETE);
+    nodeQueryWrapper.orderByAsc("sort");
+    return list(nodeQueryWrapper);
+  }
+
+  /** 保存流程模板 @Author: luxiaoxiao @Date: 2021/11/15 */
+  @Override
+  public boolean saveTemplate(List<ExecuteNode> nodeList) {
+    if (CollectionUtils.isEmpty(nodeList)) {
+      return false;
+    }
+
+    int totalProportion = 0;
+    for (ExecuteNode node : nodeList) {
+      if (node.getProportion() != null) {
+        totalProportion += node.getProportion();
+      }
+    }
+    if (totalProportion != 100) {
+      throw new JeecgBootException("权重相加不为100!");
+    }
+
+    ExecuteNode node = nodeList.get(0);
+    String hostId = node.getHostId();
+    if (StringUtils.isEmpty(hostId)) {
+      throw new JeecgBootException("缺少hostId");
+    }
+    UpdateWrapper<ExecuteNode> updateWrapper = new UpdateWrapper<>();
+    updateWrapper.eq("host_id", hostId);
+    updateWrapper.eq("del_flag", FLOW_NOT_DELETE);
+    updateWrapper.set("del_flag", 1);
+    update(updateWrapper);
+
+    Date now = new Date();
+    for (int i = 0; i < nodeList.size(); i++) {
+      ExecuteNode executeNode = nodeList.get(i);
+      executeNode.setId(null);
+      executeNode.setType(1);
+      executeNode.setHostId(hostId);
+      executeNode.setNodeType(3);
+      executeNode.setStatus(null);
+      executeNode.setFinTime(null);
+      executeNode.setFinUid(null);
+      executeNode.setDelFlag(0);
+      executeNode.setCreateTime(now);
+      executeNode.setSort(Double.parseDouble(i + ""));
+    }
+    return saveBatch(nodeList);
+  }
+
+  /** 获取未完成的SEO节点 */
+  @Override
+  public List<ExecuteNode> getSeoUnfinishedNode(String historyId) {
+    QueryWrapper<ExecuteNode> executeNodeQueryWrapper = new QueryWrapper<>();
+    executeNodeQueryWrapper.eq("history_id", historyId);
+    executeNodeQueryWrapper.eq("node_type", Flow_NODE_TYPE_SEO_OPTIMIZE);
+    executeNodeQueryWrapper.eq("del_flag", FLOW_NOT_DELETE);
+    executeNodeQueryWrapper.eq("status", 0);
+    executeNodeQueryWrapper.orderByAsc("sort");
+    return this.list(executeNodeQueryWrapper);
+  }
+
+  /** 获取未完成的建站节点 */
+  @Override
+  public List<ExecuteNode> getSiteUnfinishedNode(String siteCode) {
+    QueryWrapper<ExecuteNode> executeNodeQueryWrapper = new QueryWrapper<>();
+    executeNodeQueryWrapper.eq("host_id", siteCode);
+    executeNodeQueryWrapper.eq("node_type", Flow_NODE_TYPE_SITE_BUILD);
+    executeNodeQueryWrapper.eq("del_flag", FLOW_NOT_DELETE);
+    executeNodeQueryWrapper.eq("status", 0);
+    executeNodeQueryWrapper.orderByAsc("sort");
+    return list(executeNodeQueryWrapper);
+  }
+
+  @Override
+  public List<ExecuteNode> getEnquiryVerifyUnfinishedNode(String enquiryId) {
+    QueryWrapper<ExecuteNode> executeNodeQueryWrapper = new QueryWrapper<>();
+    executeNodeQueryWrapper.eq("host_id", enquiryId);
+    executeNodeQueryWrapper.eq("node_type", Flow_NODE_TYPE_ENQUIRY_VERIFY);
+    executeNodeQueryWrapper.eq("del_flag", FLOW_NOT_DELETE);
+    executeNodeQueryWrapper.eq("status", 0);
+    executeNodeQueryWrapper.orderByAsc("sort");
+    return list(executeNodeQueryWrapper);
+  }
+
+  /** 给站点创建建站流程 @Author: luxiaoxiao @Date: 2021/11/16 */
+  @Override
+  public boolean copySiteFlow(String siteCode) {
+    executeNodeMapper.copySiteFlow(siteCode, SITE_BUILD_CODE);
+    ExecuteNode node = getFirstUnCompleteNode(siteCode, Flow_NODE_TYPE_SITE_BUILD);
+    if (node == null) {
+      return false;
+    }
+    UpdateWrapper<AdwebSite> updateWrapper = new UpdateWrapper<>();
+    updateWrapper.eq("code", siteCode);
+    updateWrapper.set("site_flow_status", 0);
+    updateWrapper.set("site_current_step", node.getName());
+    return adwebSiteService.update(updateWrapper);
+  }
+
+  @Override
+  public void copyEnquiryVerifyFlow(String enquiryId) {
+    executeNodeMapper.copyEnquiryVerifyFlow(enquiryId, ENQUIRY_VERIFY_CODE);
+    //    ExecuteNode node = getFirstUnCompleteNode(enquiryId, Flow_NODE_TYPE_ENQUIRY_VERIFY);
+    //    return node != null;
+  }
+
+  private ExecuteNode getFirstUnCompleteNode(String host_id, Integer nodeType) {
+    QueryWrapper<ExecuteNode> queryWrapper = new QueryWrapper<>();
+    queryWrapper.eq("host_id", host_id);
+    queryWrapper.eq("type", Flow_TYPE_PROCESS);
+    queryWrapper.eq("node_type", nodeType);
+    queryWrapper.eq("status", 0);
+    queryWrapper.eq("del_flag", 0);
+    queryWrapper.orderByAsc("sort");
+    List<ExecuteNode> list = list(queryWrapper);
+    if (CollectionUtils.isNotEmpty(list)) {
+      return list.get(0);
+    }
+    return null;
+  }
+}

+ 1 - 2
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/mq/ProductReceiver.java

@@ -70,6 +70,7 @@ public class ProductReceiver extends BaseRabbiMqHandler<List<ProductDTO>> {
               try {
                 adwebProductService.addOrUpdateProduct(product, adwebSite);
               } catch (Exception e) {
+                log.error("产品入库失败:{}", e.getMessage());
 
                 // 拉取产品失败时,发送告警到飞书
                 long endTimeEnquiry = System.currentTimeMillis();
@@ -103,8 +104,6 @@ public class ProductReceiver extends BaseRabbiMqHandler<List<ProductDTO>> {
                     className,
                     methodName,
                     String.valueOf(msg));
-
-                log.error("产品入库失败:{}", e.getMessage());
               }
             }
           }