欢迎光临
我们一直在努力

影刀RPA进阶教程:低代码平台与RPA混合开发搭建业务系统实战

影刀RPA进阶教程:低代码平台与RPA混合开发搭建业务系统实战

痛点切入

中小企业信息化的最大困局:买不起商业软件,雇不起开发团队。

一个典型的场景:公司需要一个供应商管理系统,IT预算只有5万。买SAP要50万起,自研前端+后端+数据库最少两个程序员三个月。最后只能继续用Excel,每月靠行政手动更新几十个表格,表格一多就乱、一乱就错。

直到我们发现了一条新路:低代码平台搭壳,RPA做采集和操作。

低代码平台(明道云/简道云/轻流/得帆)负责数据管理、表单、流程审批、报表展示。影刀RPA负责对接老旧系统(那些没有API的ERP、网页版进销存),做数据采集和写入。两者配合,搭建速度极快,成本低到可以忽略。

本文通过一个真实的供应商管理系统案例,展示如何搭建这套混合架构。


在这里插入图片描述

架构设计

┌─────────────────────────────────────────────────┐
│ 低代码平台(明道云) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ 供应商表单 │ │ 合同管理 │ │ 绩效评分看板 │ │
│ └──────────┘ └──────────┘ └───────────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ 审批流程 │ │ 数据报表 │ │ 自动通知提醒 │ │
│ └──────────┘ └──────────┘ └───────────────┘ │
│ │
│ ▲ API接收 │ API调用 ▼ │
└─────────┼─────────────────┼────────────────────┘
│ │
┌─────────▼─────────────────▼────────────────────┐
│ RPA层(影刀RPA) │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 数据采集流程 │ │ 数据回写流程 │ │
│ │ ERP → 低代码 │ │ 低代码 → ERP │ │
│ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 定时同步任务 │ │ 异常处理流程 │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────┘
│ ▲
▼ │
┌─────────────────────────────────────────────────┐
│ 老旧系统(没有API) │
│ 财务ERP │ 进销存系统 │ 网页版审批平台 │
└─────────────────────────────────────────────────┘

分工原则:

  • 低代码平台负责:数据模型、表单UI、审批流、权限管理、报表Dashboard
  • RPA负责:对接无API的老旧系统、批量数据导入导出、跨系统操作串联

完整案例:供应商管理系统

系统需求

  • 供应商信息管理(新增、编辑、查询、导出)
  • 合同管理(合同上传、到期提醒、续签审批)
  • 供应商绩效评分(自动采集ERP中的交货及时率、合格率)
  • 数据大屏(供应商分布、绩效排名、合同到期预警)
  • 第一步:在明道云中搭建数据模型

    在这里插入图片描述

    表结构设计:

    1. 供应商信息表 (supplier)
    – 供应商编号 (文本, 唯一)
    – 供应商名称 (文本, 必填)
    – 供应商类别 (单选: 原材料/辅料/服务/其他)
    – 联系人 (文本)
    – 联系电话 (电话)
    – 地址 (地址)
    – 状态 (单选: 正常/停用/黑名单)
    – 创建时间 (日期时间, 自动生成)

    2. 合同表 (contract)
    – 关联供应商 (关联记录 → supplier)
    – 合同编号 (文本, 唯一)
    – 合同名称 (文本)
    – 合同金额 (数字)
    – 签订日期 (日期)
    – 到期日期 (日期)
    – 合同附件 (附件)
    – 续签状态 (单选: 正常/即将到期/已到期/已续签)

    3. 绩效评分表 (performance)
    – 关联供应商 (关联记录 → supplier)
    – 评分周期 (文本, 如 "2024-Q1")
    – 交货及时率 (数字, %)
    – 产品合格率 (数字, %)
    – 服务满意度 (数字, 1-5)
    – 综合评分 (公式: 自动计算)
    – 评分来源 (单选: 自动采集/人工评分)

    在明道云操作:应用管理 → 新建工作表 → 按上述字段逐个添加 → 设置关联关系。

    第二步:配置审批流程

    在明道云工作流中创建"合同续签审批"流程:

    触发器:合同表.到期日期 < TODAY() + 30天 且 续签状态 = "正常"
    │
    ▼
    通知节点:发送通知给采购主管
    │
    ▼
    填写节点:采购主管填写续签意见和金额
    │
    ▼
    审批节点:部门经理审批 (金额<10万自动通过)
    │
    ├── 通过 → 更新合同.续签状态 = "已续签" → 通知供应商联系人
    │
    └── 拒绝 → 更新合同.续签状态 = "即将到期" → 通知采购主管重新谈判

    第三步:RPA数据采集流程

    这是混合架构最核心的部分。老旧ERP系统没有API,影刀RPA通过Selenium自动化操作网页来提取数据。

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    """
    影刀RPA + 明道云 — 供应商绩效数据采集
    用途:从ERP系统采集供应商交货数据,同步到明道云
    作者:林焱
    """

    import requests
    import json
    from datetime import datetime, timedelta
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait, Select
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.common.exceptions import TimeoutException

    class MingdaoAPIClient:
    """
    明道云API客户端

    前提:在明道云中创建API密钥(应用管理 → API文档 → 获取API Key)
    """

    def __init__(self, app_key, app_secret, host="https://api.mingdao.com"):
    self.app_key = app_key
    self.app_secret = app_secret
    self.host = host
    self.access_token = None
    self._authenticate()

    def _authenticate(self):
    """获取访问令牌"""
    url = f"{self.host}/oauth2/token"
    data = {
    "grant_type": "client_credentials",
    "client_id": self.app_key,
    "client_secret": self.app_secret
    }
    resp = requests.post(url, data=data)
    if resp.status_code == 200:
    self.access_token = resp.json()["access_token"]
    print("[明道云] 认证成功")
    else:
    raise Exception(f"认证失败: {resp.text}")

    def _headers(self):
    """请求头"""
    return {
    "Authorization": f"Bearer {self.access_token}",
    "Content-Type": "application/json"
    }

    def get_worksheet_rows(self, worksheet_id, view_id=None, filter_json=None):
    """
    查询工作表数据

    参数:
    worksheet_id: 工作表ID
    view_id: 视图ID(可选)
    filter_json: 过滤条件(可选)
    """
    url = f"{self.host}/api/v2/open/worksheet/getFilterRows"
    params = {
    "worksheetId": worksheet_id,
    "pageSize": 500,
    "pageIndex": 1
    }
    if view_id:
    params["viewId"] = view_id
    if filter_json:
    params["filter"] = json.dumps(filter_json, ensure_ascii=False)

    resp = requests.post(url, headers=self._headers(), json=params)
    if resp.status_code == 200:
    data = resp.json()
    return data.get("data", {}).get("rows", [])
    else:
    print(f"[明道云] 查询失败: {resp.text}")
    return []

    def add_worksheet_row(self, worksheet_id, row_data):
    """
    新增工作表行

    参数:
    worksheet_id: 工作表ID
    row_data: 行数据字典
    例如: {
    "supplier_name": "XX科技",
    "delivery_rate": 95.5,
    "quality_rate": 98.2
    }
    """
    url = f"{self.host}/api/v2/open/worksheet/addRow"
    controls = []
    for field_name, value in row_data.items():
    controls.append({
    "controlId": field_name, # 明道云的字段控件ID
    "value": str(value) if value is not None else ""
    })

    payload = {
    "worksheetId": worksheet_id,
    "controls": controls
    }

    resp = requests.post(url, headers=self._headers(), json=payload)
    if resp.status_code == 200:
    result = resp.json()
    return result.get("data", {}).get("rowId")
    else:
    print(f"[明道云] 新增失败: {resp.text}")
    return None

    def update_worksheet_row(self, worksheet_id, row_id, update_data):
    """
    更新工作表行

    参数:
    worksheet_id: 工作表ID
    row_id: 行ID
    update_data: 要更新的字段
    """
    url = f"{self.host}/api/v2/open/worksheet/editRow"
    controls = []
    for field_name, value in update_data.items():
    controls.append({
    "controlId": field_name,
    "value": str(value) if value is not None else ""
    })

    payload = {
    "worksheetId": worksheet_id,
    "rowId": row_id,
    "controls": controls
    }

    resp = requests.post(url, headers=self._headers(), json=payload)
    return resp.status_code == 200

    class ERPSupplierDataCollector:
    """
    从老旧ERP网页采集供应商绩效数据

    这个ERP是10年前的Java Web系统,没有任何API,
    只能通过网页操作来提取数据。
    """

    def __init__(self):
    self.driver = None

    def start(self):
    """启动浏览器并登录ERP"""
    from selenium.webdriver.chrome.options import Options
    options = Options()
    options.add_argument('–disable-gpu')
    options.add_argument('–window-size=1366,768')
    self.driver = webdriver.Chrome(options=options)

    def login_erp(self, username, password):
    """登录ERP系统"""
    self.driver.get("http://erp.internal/login")
    # 填写用户名
    self.driver.find_element(By.ID, "username").send_keys(username)
    # 填写密码
    self.driver.find_element(By.ID, "password").send_keys(password)
    # 选择数据权限(某些ERP登录时需要选择公司/部门)
    select = Select(self.driver.find_element(By.ID, "company"))
    select.select_by_visible_text("总公司")
    # 点击登录
    self.driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()
    # 等待登录成功(首页加载完成)
    WebDriverWait(self.driver, 15).until(
    EC.presence_of_element_located((By.ID, "mainMenu"))
    )
    print("[ERP] 登录成功")

    def collect_supplier_performance(self, period):
    """
    采集指定周期的供应商绩效数据

    参数:
    period: 统计周期,如 "2024-Q1"
    返回:
    [{"supplier_code": "S001", "delivery_rate": 95.5, …}, …]
    """
    # 步骤1:导航到供应商绩效报表页面
    # ERP的导航菜单通常是多层iframe嵌套的树形菜单
    menu_frame = self.driver.find_element(By.NAME, "menuFrame")
    self.driver.switch_to.frame(menu_frame)
    self.driver.find_element(By.LINK_TEXT, "供应商管理").click()
    self.driver.find_element(By.LINK_TEXT, "绩效考核报表").click()
    self.driver.switch_to.default_content()

    # 步骤2:在主内容区操作
    content_frame = self.driver.find_element(By.NAME, "contentFrame")
    self.driver.switch_to.frame(content_frame)

    # 步骤3:设置查询条件
    # 选择统计周期
    period_select = Select(self.driver.find_element(By.ID, "period"))
    period_select.select_by_visible_text(period)
    # 点击查询按钮
    self.driver.find_element(By.ID, "btnSearch").click()

    # 步骤4:等待报表数据加载
    WebDriverWait(self.driver, 30).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, "#reportTable tbody tr"))
    )
    print(f"[ERP] 报表数据已加载")

    # 步骤5:提取表格数据
    rows = self.driver.find_elements(By.CSS_SELECTOR, "#reportTable tbody tr")
    results = []
    for row in rows:
    cells = row.find_elements(By.TAG_NAME, "td")
    if len(cells) < 5:
    continue

    # 解析每一列的数据
    supplier_code = cells[0].text.strip()
    supplier_name = cells[1].text.strip()

    # 处理百分比格式(ERP中可能是"95.5%")
    delivery_rate_str = cells[2].text.strip().replace('%', '')
    quality_rate_str = cells[3].text.strip().replace('%', '')

    try:
    delivery_rate = float(delivery_rate_str)
    quality_rate = float(quality_rate_str)
    except ValueError:
    print(f"[ERP] 解析失败: {supplier_code} {delivery_rate_str}/{quality_rate_str}")
    continue

    # 跳过无效数据
    if delivery_rate <= 0 and quality_rate <= 0:
    continue

    results.append({
    "supplier_code": supplier_code,
    "supplier_name": supplier_name,
    "delivery_rate": delivery_rate,
    "quality_rate": quality_rate,
    "period": period,
    "collected_at": datetime.now().isoformat()
    })

    self.driver.switch_to.default_content()
    print(f"[ERP] 采集完成: {len(results)} 条供应商数据")
    return results

    def stop(self):
    """关闭浏览器"""
    if self.driver:
    self.driver.quit()

    class SupplierDataSync:
    """
    供应商数据同步器
    负责协调ERP采集和明道云写入
    """

    def __init__(self, mingdao_client: MingdaoAPIClient):
    self.mingdao = mingdao_client
    self.collector = ERPSupplierDataCollector()

    def sync_performance_data(self, period: str):
    """
    同步供应商绩效数据
    完整流程:ERP采集 → 匹配明道云供应商 → 写入绩效表
    """

    print(f"\\n[同步] 开始同步供应商绩效数据 – {period}")

    # 阶段1:从ERP采集数据
    try:
    self.collector.start()
    self.collector.login_erp("rpa_bot", "rpa_pass_2024")
    erp_data = self.collector.collect_supplier_performance(period)
    finally:
    self.collector.stop()

    if not erp_data:
    print("[同步] 未采集到数据,终止")
    return {"total": 0, "synced": 0, "skipped": 0}

    # 阶段2:从明道云读取供应商列表(用于匹配)
    suppliers = self.mingdao.get_worksheet_rows(
    worksheet_id="supplier_worksheet_id" # 替换为实际ID
    )

    # 构建供应商编号 -> 明道云行ID的映射
    supplier_map = {}
    for row in suppliers:
    code = row.get("supplier_code") # 字段控件ID
    if code:
    supplier_map[code] = row.get("rowId")

    # 阶段3:写入绩效数据
    synced = 0
    skipped = 0
    for item in erp_data:
    supplier_code = item["supplier_code"]

    # 检查供应商是否已在明道云中
    if supplier_code not in supplier_map:
    print(f"[同步] 跳过未知供应商: {supplier_code} – {item['supplier_name']}")
    skipped += 1
    continue

    # 构建写入数据
    row_data = {
    "supplier_relation": supplier_map[supplier_code], # 关联供应商记录
    "period": period,
    "delivery_rate": item["delivery_rate"],
    "quality_rate": item["quality_rate"],
    "data_source": "自动采集"
    }

    # 写入明道云绩效表
    row_id = self.mingdao.add_worksheet_row(
    worksheet_id="performance_worksheet_id", # 替换为实际ID
    row_data=row_data
    )
    if row_id:
    synced += 1
    print(f"[同步] {supplier_code}: 绩效数据已写入 (rowId={row_id})")
    else:
    skipped += 1

    result = {"total": len(erp_data), "synced": synced, "skipped": skipped}
    print(f"[同步] 完成: 采集{result['total']}条 → 同步{result['synced']}条 → 跳过{result['skipped']}条")
    return result

    # ===== 在影刀RPA流程中的使用 =====
    # 影刀流程编排:
    # 1. Python节点:初始化
    mingdao = MingdaoAPIClient(
    app_key="your_app_key",
    app_secret="your_app_secret"
    )
    sync = SupplierDataSync(mingdao)

    # 2. Python节点:执行同步
    result = sync.sync_performance_data("2024-Q1")

    # 3. Python节点:将结果写入影刀变量
    # 影刀变量: sync_result = json.dumps(result)

    第四步:配置明道云工作流自动处理

    在这里插入图片描述

    当RPA写入绩效数据后,明道云自动触发:

    触发器:performance表.新增记录 且 data_source = "自动采集"
    │
    ▼
    查询节点:查询 supplier 表中对应的供应商记录
    │
    ▼
    条件分支节点:
    ├── delivery_rate >= 95 且 quality_rate >= 98
    │ → 更新 supplier.状态 = "正常"
    │
    ├── delivery_rate < 80 或 quality_rate < 85
    │ → 更新 supplier.状态 = "观察中"
    │ → 发送飞书通知给采购主管
    │
    └── delivery_rate < 60 或 quality_rate < 70
    → 更新 supplier.状态 = "黑名单"
    → 创建审批任务:供应商淘汰审批

    第五步:数据大屏与报表

    在明道云中创建仪表盘(数据大屏):

    布局设计:
    ┌─────────────────────────────────────────────┐
    │ 供应商管理数据大屏 – 实时 │
    ├─────────────────────┬───────────────────────┤
    │ 供应商总数: 156 │ 正常: 142 观察中: 9 │
    │ 即将到期合同: 3 │ 黑名单: 5 │
    ├─────────────────────┴───────────────────────┤
    │ [供应商绩效排名 TOP10 柱状图] │
    │ │
    ├─────────────────────────────────────────────┤
    │ [供应商类别分布 饼图] [合同到期预警 甘特图] │
    │ │
    └─────────────────────────────────────────────┘

    明道云仪表盘配置步骤:

  • 进入应用 → 仪表盘 → 新建仪表盘
  • 添加统计数字组件 → 数据源选择 supplier 表
  • 添加柱状图 → 数据源选择 performance 表 → X轴=供应商名称, Y轴=综合评分
  • 添加饼图 → 数据源选择 supplier 表 → 按"供应商类别"分组统计
  • 设置自动刷新间隔:5分钟

  • 常见问题速查

    在这里插入图片描述

    Q1: 明道云API返回的数据中文乱码

    现象:通过API读取的中文字段显示乱码。

    原因:明道云API默认使用UTF-8,但如果ERP系统使用了GBK编码,中间转换可能出现问题。

    解决:

    # 在使用明道云API前确保正确编码
    resp = requests.post(url, headers={"Content-Type": "application/json; charset=utf-8"}, json=payload)
    resp.encoding = 'utf-8'

    # 从ERP采集时也要注意
    text = driver.find_element(By.ID, "name").text
    # Selenium自动处理编码,但如果遇到乱码:
    text = text.encode('latin1').decode('gbk')

    Q2: ERP系统太老,页面加载极慢

    现象:登录ERP后等30秒页面才加载完,RPA经常超时。

    原因:老系统服务器性能不足,前端大量使用过时的技术(如大量嵌套table布局)。

    解决:
    在这里插入图片描述

    # 1. 增加通用等待超时
    driver.set_page_load_timeout(60)

    # 2. 用显式等待替代固定sleep
    # 不好
    time.sleep(30)
    # 好
    WebDriverWait(driver, 60).until(
    EC.presence_of_element_located((By.ID, "reportTable"))
    )

    # 3. 如果页面有加载动画,等待动画消失
    WebDriverWait(driver, 60).until_not(
    EC.presence_of_element_located((By.CSS_SELECTOR, ".loading-spinner"))
    )

    Q3: 同步时发现ERP和明道云供应商名称不一致

    现象:同一个供应商在ERP叫"XX科技有限公司",在明道云叫"XX科技",匹配失败。

    原因:两个系统独立维护,名称标准不统一。

    解决:使用供应商编号(唯一键)做匹配,而不是名称:

    # 用编号匹配(推荐)
    supplier_map = {row["code"]: row["rowId"] for row in suppliers}

    # 如果实在没有编号,用模糊匹配兜底
    from difflib import SequenceMatcher
    def fuzzy_match(name, candidates, threshold=0.8):
    for candidate in candidates:
    ratio = SequenceMatcher(None, name, candidate["name"]).ratio()
    if ratio >= threshold:
    return candidate
    return None

    Q4: 明道云API调用频率限制

    现象:批量写入时报 Too Many Requests。

    原因:明道云免费版API调用频率限制为100次/分钟。

    解决:
    在这里插入图片描述

    import time
    def rate_limited_add(api, worksheet_id, rows, rate_limit=80):
    """带限速的批量写入"""
    for i, row in enumerate(rows):
    api.add_worksheet_row(worksheet_id, row)
    if (i + 1) % rate_limit == 0:
    print(f"已处理 {i+1}/{len(rows)},限速等待60秒…")
    time.sleep(60)

    Q5: RPA流程中断后数据不同步

    现象:RPA同步到一半中断了,ERP和明道云数据不一致。

    原因:没有事务机制,部分数据已写入明道云。

    解决:增量同步 + 幂等设计:

    # 1. 用batch_id标记每次同步
    batch_id = f"sync_{datetime.now().strftime('%Y%m%d%H%M%S')}"

    # 2. 写入时带上batch_id
    row_data["sync_batch_id"] = batch_id

    # 3. 同步前查询上次成功同步的时间戳
    last_sync = get_last_sync_time()
    erp_data = collector.collect_supplier_performance(
    period,
    from_date=last_sync # 只采集上次同步之后的数据
    )

    # 4. 写入前检查是否已存在(幂等)
    existing = api.get_worksheet_rows(
    worksheet_id="performance",
    filter_json={"sync_batch_id": batch_id}
    )
    if existing:
    print("该批次已同步过,跳过")


    推荐资源

    • 明道云开放平台:https://open.mingdao.com — API文档
    • 简道云开放平台:https://www.jiandaoyun.com/open — 简道云API(类似方案)
    • 影刀RPA + 简道云案例:影刀官方社区 → 搜索"简道云"
    • 得帆云:https://www.definesys.com — 企业级低代码平台

    在这里插入图片描述

    内容标签

    #影刀RPA #低代码 #明道云 #混合开发 #企业信息化 #数据同步


    作者:林焱

    赞(0)
    未经允许不得转载:171主机测评 » 影刀RPA进阶教程:低代码平台与RPA混合开发搭建业务系统实战
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址