oa流程到达某个节点之后触发自定义动作(外部接口)

第一种方案(推荐)

在归档节点前添加自定义附加操作就可以(oa前台直接调用外部接口即可)
第二种方案(不推荐,用来扩展思路)

数据库轮询版

一、数据库轮询版-整体思路

核心思想(非常重要)

不要直接扫"已结束流程"

而是:

👉 "找出『刚刚结束』、且『还没通知过』的流程实例"

所以一定要有 去重标记


总体架构

markdown 复制代码
Spring Boot 定时任务
        ↓
查询 OA 数据库
        ↓
找出【厂外调拨流程】中
【审批完成 & 未通知】的 requestId
        ↓
发送飞书群通知
        ↓
记录通知日志(防重复)

二、你必须知道的 3 张关键表(e-cology 9)

⚠️ 表名在不同客户可能略有差异,但 下面这几张 90% 都存在


1️⃣ workflow_requestbase(流程实例主表)

这是最重要的。

常用字段:

字段 含义
requestid 流程实例 ID
workflowid 流程模板 ID
currentstatus 流程状态
lastoperatedate 最后操作日期
lastoperatetime 最后操作时间

currentstatus 常见值(经验)

含义
0 运行中
1 正常结束(审批通过)
2 强制结束
3 退回

👉 你只要 currentstatus = 1


2️⃣ workflow_base(流程模板表)

用来确认流程名(可选)

字段 含义
id workflowId
workflowname 流程名称

3️⃣ 你自己建的表(强烈推荐)

oa_notify_log(防重复)

sql 复制代码
create table oa_notify_log (
  request_id int primary key,
  workflow_id int,
  notify_time datetime
);

这是整个方案是否"能长期用"的关键


三、SQL:找出「刚刚审批完成」的流程

核心 SQL(重点看)

sql 复制代码
select r.requestid,
       r.workflowid,
       r.lastoperatedate,
       r.lastoperatetime
from workflow_requestbase r
where r.workflowid = 456            -- 厂外调拨流程ID
  and r.currentstatus = '1'         -- 审批通过
  and not exists (
      select 1
      from oa_notify_log n
      where n.request_id = r.requestid
  )

📌 解释

  • 只查你关心的流程
  • 只要"审批通过"的
  • 排除已经通知过的

四、Spring Boot 3 实现(完整可用示例)

1️⃣ 定时任务配置

less 复制代码
@EnableScheduling
@Configuration
public class ScheduleConfig {
}

2️⃣ 定时扫描任务

typescript 复制代码
@Component
public class OaWorkflowScanJob {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private FeishuService feishuService;

    @Scheduled(cron = "0 */1 * * * ?") // 每 1 分钟扫一次
    public void scanFinishedWorkflow() {

        String sql = """
            select requestid
            from workflow_requestbase
            where workflowid = ?
              and currentstatus = '1'
              and not exists (
                select 1 from oa_notify_log
                where request_id = workflow_requestbase.requestid
              )
        """;

        List<Integer> requestIds =
            jdbcTemplate.queryForList(sql, Integer.class, 456);

        for (Integer requestId : requestIds) {
            try {
                // 1. 发送飞书
                feishuService.send(buildMsg(requestId));

                // 2. 记录已通知
                saveNotifyLog(requestId);

            } catch (Exception e) {
                // 失败不写 log,下次还会再发
                e.printStackTrace();
            }
        }
    }

    private void saveNotifyLog(Integer requestId) {
        jdbcTemplate.update(
            "insert into oa_notify_log(request_id, workflow_id, notify_time) values (?, ?, getdate())",
            requestId, 456
        );
    }

    private String buildMsg(Integer requestId) {
        return "【厂外调拨流程】审批已通过\n流程ID:" + requestId;
    }
}

3️⃣ 飞书发送(简版)

typescript 复制代码
@Service
public class FeishuService {

    private static final String WEBHOOK =
        "https://open.feishu.cn/open-apis/bot/v2/hook/xxxx";

    private final RestTemplate restTemplate = new RestTemplate();

    public void send(String text) {
        Map<String, Object> body = Map.of(
            "msg_type", "text",
            "content", Map.of("text", text)
        );
        restTemplate.postForObject(WEBHOOK, body, String.class);
    }
}

五、你这个方案一定要加的 4 个"保险"

✅ 1️⃣ 必须用 oa_notify_log

否则 一定会重复发


✅ 2️⃣ 定时频率不要太高

  • 推荐:1~3 分钟
  • 不要秒级

✅ 3️⃣ 只认 currentstatus = 1

不要自己猜其他状态


✅ 4️⃣ 飞书失败不要写 log

让下次定时任务补发


六、这个方案的"客观缺点"(我必须告诉你)

说明
延迟 最快 1 分钟
强制结束要额外判断 currentstatus = 2
表结构升级风险
并发高时压力大

👉 但在"不能用 Action"的前提下,这是最稳的一种

相关推荐
2301_818732063 分钟前
项目启动报错,错误指向xml 已解决
xml·java·数据库·后端·springboot
小王不爱笑13243 分钟前
SpringBoot 整合 Ollama + 本地 DeepSeek 模型
java·spring boot·后端
短剑重铸之日2 小时前
《设计模式》第七篇:适配器模式
java·后端·设计模式·适配器模式
树码小子3 小时前
SpringIoC & DI (1):IOC介绍 & Spring IoC使用 & DI
java·后端·spring
墨染青竹梦悠然5 小时前
基于Django+vue的图书借阅管理系统
前端·vue.js·后端·python·django·毕业设计·毕设
怪兽毕设5 小时前
基于Django的洗衣服务平台设计与实现
后端·python·django·洗衣服务平台
程序员泠零澪回家种桔子5 小时前
微服务日志治理:ELK 栈实战指南
后端·elk·微服务·云原生·架构
qq_12498707535 小时前
基于html的书城阅读器系统的设计与实现(源码+论文+部署+安装)
前端·vue.js·spring boot·后端·mysql·信息可视化·html
CodeToGym6 小时前
【全栈进阶】Spring Boot 整合 WebSocket 实战:从实时告警到金融行情推送
java·后端·spring
Leinwin6 小时前
Moltbot 部署至 Azure Web App 完整指南:从本地到云端的安全高效跃迁
后端·python·flask