ITPub博客

首页 > 人工智能 > 深度学习 > .NET 传统信息系统无缝集成飞书审批流

.NET 传统信息系统无缝集成飞书审批流

投稿 深度学习 作者:ecclw459 时间:2026-01-07 18:12:18 0 删除 编辑

本文将带你走一条渐进式改造之路:保持 .NET 系统作为业务核心,将飞书审批作为移动门户,通过 API 实现无缝协同。从原理、设计到编码,完整呈现如何让传统系统焕发新生,实现移动化、实时化的现代化升级。

无论你是开发者、架构师还是技术管理者,都能收获一套可落地、可扩展的集成方案和直接复用的代码实践。

当传统业务遇上现代协同,为何必须"破壁"?

我们正在解决什么?

传统 .NET 系统的局限

许多企业拥有多年累积的 .NET 业务系统,这些系统在企业运营中扮演着核心角色。然而,随着移动办公和现代协同工具的普及,这些传统系统正面临着严峻的挑战:

痛点 具体表现 业务影响
审批流程封闭 审批只能在桌面端完成,无法随时随地处理 移动办公受阻,响应迟缓
通知方式滞后 依赖邮件或站内消息推送 审批人及时性差,流程延误
数据孤岛严重 审批数据与业务数据分离 无法形成完整的业务闭环
用户体验陈旧 界面风格陈旧,交互体验差 用户满意度低,使用意愿下降

飞书审批的赋能价值

飞书审批作为企业级的审批协作平台,为我们提供了一个理想的"流程协作中心":

飞书审批平台

移动优先

即时强通知

流程可视化

完善审计日志

随时随地处理审批

App推送/短信提醒

拖拽式流程配置

完整操作痕迹追溯

我们的核心目标

通过本文的实践,我们将建立  ".NET 系统为业务核心,飞书审批为流程门户" 的现代化混合架构:

架构愿景:将飞书审批作为统一的移动审批门户,保持 .NET 系统作为业务逻辑和数据存储的核心,通过 API 实时同步,形成优势互补的协同体系。

你将收获什么?

  • ✅  一套端到端的集成方法论,覆盖从原理、设计到部署的全流程
  • ✅  清晰的 .NET 侧架构蓝图,包含关键的技术选型与设计决策
  • ✅  可直接复用的 C# 核心代码与实践中总结的"避坑指南"
  • ✅  一个完整的"请假审批"实战案例,助你从零到一完成验证

飞书审批开放平台如何与我们"对话"?

双向集成的关键流程

飞书审批与 .NET 系统的集成是一个 双向数据流的过程:

飞书App飞书API.NET系统用户飞书App飞书API.NET系统用户流程输出:发起审批流程输入:回调通知1. 提交请假申请2. 保存业务数据(状态:审批中)3. 调用 CreateInstanceAsync4. 返回 instance_code5. 关联业务ID与instance_code6. 在飞书App中审批7. 审批完成8. Webhook回调事件9. 根据instance_code更新业务状态

流程输出(发起阶段)

当用户在 .NET 系统发起审批时,系统会:

  1. 保存业务数据,状态标记为"审批中"
  2. 调用飞书 API  CreateInstanceAsync 创建审批实例
  3. 接收返回的  instance_code,持久化到关联表

流程输入(回调阶段)

当审批人在飞书 App 完成审批后:

  1. 飞书服务器主动回调 .NET 系统的 Webhook 接口
  2. .NET 系统解析事件,提取  instance_code 和  status
  3. 根据关联表查询对应的业务记录
  4. 更新业务状态,完成闭环

必须理解的三个核心概念

审批定义(approval_code)

审批定义是审批流程的"蓝图",在飞书管理后台配置:

// 示例:请假审批的审批定义var approvalCode = "7C468A54-8745-2245-9675-08B7C63E7A85";

定义包含:

  • 表单结构(请假类型、开始时间、结束时间、请假事由等)
  • 审批流程(直属主管审批 → 人事审批)
  • 权限设置(谁可以发起、谁可以审批)

审批实例(instance_code)

审批实例是依据审批定义发起的一次具体审批任务:

// 创建审批实例时返回public record CreateInstancesResult{    /// <summary>
    /// 审批实例 Code
    /// </summary>
    [JsonPropertyName("instance_code")]    public string InstanceCode { get; set; } = string.Empty;
}

关键属性:

  • 唯一标识一次审批流程
  • 包含该次审批的所有表单数据
  • 拥有独立的状态(审批中、通过、拒绝、撤回等)

身份映射(免登)

实现 .NET 系统用户与飞书用户的关联:

映射关系

通过飞书App审批

回调instance_code

.NET系统用户
UserId: 1001

飞书用户
OpenId: ou_3cda9c...

审批完成

实现方式:

  1. 在 .NET 系统的用户表中添加  FeishuOpenId 字段
  2. 用户次登录时进行飞书免登录认证,获取并存储  open_id
  3. 发起审批时,使用  open_id 指定审批发起人

构建稳健、可扩展的 .NET 侧集成层

技术栈推荐

层次 技术选型 说明
应用框架 .NET 6/8/10 长期支持版本,性能优异
飞书 SDK Mud.Feishu 高度封装的飞书 API 客户端
Webhook 处理 Mud.Feishu.Webhook 飞书事件回调处理组件
认证授权 ASP.NET Core Identity / JWT 内部系统身份管理
异步解耦 RabbitMQ / Hangfire 回调消息队列处理,提升可靠性
数据存储 SQL Server / PostgreSQL 业务数据 + 审批关联表

分层架构图

基础设施层

领域层 (业务逻辑)

应用层 (API)

表示层 (UI)

Web 前端 / 移动端

LeaveController

FeishuWebhookController

ILeaveService

ApprovalIntegrationService

IApprovalService

Mud.Feishu HTTP客户端

Mud.Feishu.Webhook处理器

数据仓储
EF Core

关键设计:领域层抽象

在领域层引入  IApprovalService 接口,将飞书集成细节与核心业务逻辑解耦:

/// <summary>/// 审批服务抽象接口 - 解耦飞书实现细节/// </summary>public interface IApprovalService{    /// <summary>
    /// 发起审批
    /// </summary>
    Task<string> CreateApprovalAsync(ApprovalRequest request);    /// <summary>
    /// 处理审批结果回调
    /// </summary>
    Task HandleApprovalCallbackAsync(ApprovalCallbackEvent callbackEvent);
}/// <summary>/// 飞书审批服务实现///gov.www.yc.jrzb2.info </summary>public class FeishuApprovalService : IApprovalService{    private readonly IFeishuTenantV4Approval _approvalApi;    private readonly IApprovalRecordRepository _repository;    public FeishuApprovalService(
        IFeishuTenantV4Approval approvalApi,
        IApprovalRecordRepository repository)
    {
        _approvalApi = approvalApi;
        _repository = repository;
    }    public async Task<string> CreateApprovalAsync(ApprovalRequest request)
    {        // 调用飞书 API
        var result = await _approvalApi.CreateInstanceAsync(...);        return result.Data?.InstanceCode ?? string.Empty;
    }
}

优势:

  • 业务逻辑不依赖具体飞书实现
  • 便于单元测试(可 Mock 接口)
  • 未来可轻松切换到其他审批平台

实战:手把手完成"请假审批"集成

第一步:飞书平台侧配置(审批流出口)

创建企业自建应用

登录飞书开放平台( https://open.feishu.cn),进入应用管理:

创建自建应用

获取App ID

获取App Secret

配置到.NET系统

关键配置:

  • 记录  App ID 和  App Secret
  • 配置应用权限:审批相关权限( approval:approval:read,  approval:instance:read,  approval:instance:create)

配置审批定义

在飞书管理后台创建"请假审批"模板:

审批定义配置

表单设置

流程设置

权限设置

请假类型
开始时间
结束时间
请假天数
请假事由

直属主管审批
→ 人事审批

全员可发起

记录关键信息:

  • approval_code:审批定义的唯一标识
  • 表单控件的  id:用于程序填充表单数据

配置事件订阅

在飞书开放平台配置 Webhook:

配置项 值
请求网址 https://your-domain.com/api/feishu/webhook
验证 Token your_verification_token(自定义)
加密 Key your_encrypt_key(自定义)
订阅事件 approval_instance(审批实例状态变更)

第二步:.NET 侧基础搭建(集成基石)

封装飞书 API 客户端

基于  MudFeishu SDK 封装审批服务:

/// <summary>/// 飞书审批服务封装/// </summary>public class FeishuApprovalClient{    private readonly IFeishuTenantV4Approval _approvalApi;    private readonly ILogger<FeishuApprovalClient> _logger;    public FeishuApprovalClient(
        IFeishuTenantV4Approval approvalApi,
        ILogger<FeishuApprovalClient> logger)
    {
        _approvalApi = approvalApi;
        _logger = logger;
    }    /// <summary>
    /// 创建审批实例
    /// </summary>
    public async Task<string> CreateInstanceAsync(CreateInstanceRequest request)
    {        var result = await _approvalApi.CreateInstanceAsync(request);        if (result == null || result.Code != 0)
        {
            _logger.LogError("创建审批实例失败: {Msg}", result?.Msg);            throw new InvalidOperationException($"创建审批实例失败: {result?.Msg}");
        }
        _logger.LogInformation("创建审批实例成功: {InstanceCode}", result.Data?.InstanceCode);        return result.Data?.InstanceCode ?? string.Empty;
    }    /// <summary>
    /// 获取审批实例详情
    /// </summary>
    public async Task<GetApprovalInstanceResult?> GetInstanceAsync(string instanceCode)
    {        var result = await _approvalApi.GetInstanceByIdAsync(instanceCode);        if (result == null || result.Code != 0)
        {
            _logger.LogError("获取审批实例失败: {Msg}", result?.Msg);            return null;
        }        return result.Data;soccer.xj.zuq8.info
    }
}

设计数据关联表

在业务数据库中添加审批关联表:

-- 审批关联表CREATE TABLE ApprovalRecords (
    Id BIGINT PRIMARY KEY IDENTITY(1,1),
    BusinessType NVARCHAR(50) NOT NULL,          -- 业务类型:LeaveRequest, PurchaseRequest...
    BusinessId BIGINT NOT NULL,                   -- 业务ID
    InstanceCode NVARCHAR(64) NOT NULL,           -- 飞书审批实例Code
    ApprovalCode NVARCHAR(64) NOT NULL,            -- 审批定义Code
    Status NVARCHAR(20) NOT NULL,                  -- 状态:PENDING, APPROVED, REJECTED...
    CallbackData NVARCHAR(MAX),                   -- 回调数据(JSON)
    CreatedTime DATETIME2 NOT NULL DEFAULT GETUTCDATE(),
    UpdatedTime DATETIME2 NOT NULL DEFAULT GETUTCDATE(),    CONSTRAINT UK_ApprovalRecords_Business UNIQUE(BusinessType, BusinessId)
);CREATE INDEX IX_ApprovalRecords_InstanceCode ON ApprovalRecords(InstanceCode);CREATE INDEX IX_ApprovalRecords_Status ON ApprovalRecords(Status);

对应的实体类:

/// <summary>/// 审批关联记录/// </summary>public class ApprovalRecord{    public long Id { get; set; }    public string BusinessType { get; set; } = string.Empty;  // "LeaveRequest"
    public long BusinessId { get; set; }                       // 请假申请ID
    public string InstanceCode { get; set; } = string.Empty;   // 飞书实例Code
    public string ApprovalCode { get; set; } = string.Empty;    // 审批定义Code
    public string Status { get; set; } = string.Empty;         // PENDING/APPROVED/REJECTED
    public string? CallbackData { get; set; }                  // JSON格式
    public DateTime CreatedTime { get; set; }    public DateTime UpdatedTime { get; set; }
}

第三步:核心业务流程编码(双向联通)

场景:用户提交请假单,发起审批

流程图:

飞书API数据库LeaveServiceLeaveController用户飞书API数据库LeaveServiceLeaveController用户提交请假申请SubmitLeaveRequest(request)保存请假记录(状态:审批中)构造表单数据CreateInstanceAsync(approvalCode, form)instance_code保存ApprovalRecord关联提交成功等待审批

代码实现:

/// <summary>/// 请假服务/// </summary>public class LeaveService{    private readonly ILeaveRequestRepository _leaveRepo;    private readonly IApprovalRecordRepository _approvalRepo;    private readonly FeishuApprovalClient _feishuClient;    private readonly ILogger<LeaveService> _logger;    public LeaveService(
        ILeaveRequestRepository leaveRepo,
        IApprovalRecordRepository approvalRepo,
        FeishuApprovalClient feishuClient,
        ILogger<LeaveService> logger)
    {
        _leaveRepo = leaveRepo;
        _approvalRepo = approvalRepo;
        _feishuClient = feishuClient;
        _logger = logger;
    }    /// <summary>
    /// 提交请假申请并发起审批
    /// </summary>
    public async Task<long> SubmitLeaveRequestAsync(SubmitLeaveRequestDto dto)
    {        // 1. 保存请假业务数据
        var leaveRequest = new LeaveRequest
        {
            UserId = dto.UserId,gov.
            LeaveType = dto.LeaveType,
            StartTime = dto.StartTime,
            EndTime = dto.EndTime,
            Days = dto.Days,
            Reason = dto.Reason,
            Status = LeaveStatus.Pending,  // 审批中
            CreatedTime = DateTime.UtcNow
        };        await _leaveRepo.AddAsync(leaveRequest);        await _leaveRepo.SaveChangesAsync();        // 2. 构造飞书审批表单数据
        var form = new List<object>
        {            new { id = "leave_type", type = "select", value = dto.LeaveType },            new { id = "start_time", type = "date", value = dto.StartTime.ToString("yyyy-MM-dd") },            new { id = "end_time", type = "date", value = dto.EndTime.ToString("yyyy-MM-dd") },            new { id = "days", type = "number", value = dto.Days.ToString() },            new { id = "reason", type = "textarea", value = dto.Reason }
        };        // 3. 调用飞书API创建审批实例
        var request = new CreateInstanceRequest
        {
            ApprovalCode = "7C468A54-8745-2245-9675-08B7C63E7A85",  // 请假审批定义Code
            UserId = dto.FeishuUserId,  // 飞书用户ID
            Form = JsonSerializer.Serialize(form),
            Uuid = Guid.NewGuid().ToString()  // 幂等ID
        };        string instanceCode;        try
        {
            instanceCode = await _feishuClient.CreateInstanceAsync(request);
        }        catch (Exception ex)
        {
            _logger.LogError(ex, "创建飞书审批实例失败");            // 回滚业务数据
            leaveRequest.Status = LeaveStatus.Failed;            await _leaveRepo.SaveChangesAsync();            throw;
        }        // 4. 保存审批关联记录
        var approvalRecord = new ApprovalRecord
        {
            BusinessType = "LeaveRequest",
            BusinessId = leaveRequest.Id,
            InstanceCode = instanceCode,
            ApprovalCode = request.ApprovalCode,
            Status = "PENDING",blog.fovkj.com
            CreatedTime = DateTime.UtcNow,
            UpdatedTime = DateTime.UtcNow
        };        await _approvalRepo.AddAsync(approvalRecord);        await _approvalRepo.SaveChangesAsync();
        _logger.LogInformation("请假申请已提交并创建审批: LeaveId={LeaveId}, InstanceCode={InstanceCode}",
            leaveRequest.Id, instanceCode);        return leaveRequest.Id;
    }
}


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048957/viewspace-3107306/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2026-01-07

  • 博文量
    108
  • 访问量
    102111