影刀RPA实操指南:校园图书馆与后勤管理系统自动化方案

0 阅读12分钟

影刀RPA实操指南:校园图书馆与后勤管理系统自动化方案

去年帮某大学图书馆做自动化项目,场景很有意思——图书馆系统分散在三个平台:借还书用图书馆管理系统(ILAS)、入馆统计用闸机系统、设备报修用学校后勤OA。三套系统之间完全没有数据流转,导致逾期催还靠人工打电话、入馆数据分析没人做、报修单处理周期长达一周。我用影刀RPA搭了借还管理→逾期催还→入馆统计→新书编目→设备报修派单→教务通知发布的完整方案,图书馆2个全职工作人员的工作量减到0.5人。

一、业务痛点与校园场景特殊性

在这里插入图片描述

校园场景和电商/制造业完全不同,核心差异:

维度电商/制造校园图书馆
数据源Web/App/API图书馆系统+闸机+OA+教务系统,四套互不联通
用户群体消费者/操作员学生/教师/管理员,有学期周期性
时效要求实时学期性要求(开学高峰/期末考试周特殊处理)
系统类型互联网/工业系统校园内网老系统,Web界面老旧
操作权限企业账号学生借阅证号+教师工号,权限分层

痛点清单

  1. 图书逾期催还靠人工逐个打电话,每天50+逾期记录,根本催不完

  2. 入馆人次数据在闸机系统里,没人导出来做统计分析

  3. 新书到馆后编目入库全靠手工录入书目信息,一本书10分钟

  4. 设备报修提交到后勤OA后没人主动跟踪,修不修看运气

  5. 在这里插入图片描述

  6. 教务处通知要图书馆手动转发到学生群,经常漏发

二、影刀RPA流程架构

子流程功能执行频率
sub_overdue_check检查逾期借阅记录每日9:00
sub_overdue_notify逾期催还通知(短信/飞书/邮件)逾期检测后立即
sub_gate_statistics闸机入馆人次统计+报表每日22:00

[video(video-pDIMi8cU-1785257982713)(type-csdn)(url-live.csdn.net/v/embed/525…)]

| sub_new_book_catalog | 新书信息采集+自动编目 | 每周一9:00 | | sub_repair_dispatch | 设备报修单自动派单+跟踪 | 每2小时 | | sub_notice_publish | 教务通知自动转发到学生群 | 实时监控 |

三、逾期借阅检测与催还通知

在这里插入图片描述

3.1 影刀Web界面操作(图书馆ILAS系统)

ILAS系统是老旧的图书馆管理系统,只有Web界面无API:

  1. 打开网页指令 → ILAS系统http://library-ilas/patron/overdue
  2. 等待指令(元素出现) → 等待逾期记录表格table#overdue-table
  3. 获取相似元素列表指令 → 抓取所有逾期记录行tr.overdue-row
  4. 循环指令(For列表) → 遍历每行:
    • 获取元素文本指令 → 借阅证号td:nth-child(1)(如STU20260001)
    • 获取元素文本指令 → 读者姓名td:nth-child(2)
    • 获取元素文本指令 → 书名td:nth-child(3)
    • 获取元素文本指令 → 逾期天数td:nth-child(7)
    • 获取元素文本指令 → 手机号td:nth-child(9)
    • 数据存入影刀列表变量overdue_list

3.2 Python节点处理(逾期分级通知)

在这里插入图片描述

# -*- coding: utf-8 -*-
#影刀Python节点:逾期催还分级通知
import json
import requests
from datetime import datetime

FEISHU_WEBHOOK = "https://open.feishu.cn/open-apis/bot/v2/hook/your-hook-id"
SMS_API_BASE = "http://sms-gateway/api/v1"  # 校园短信网关
EMAIL_API_BASE = "http://email-gateway/api/v1"  # 校园邮件系统

# 逾期分级通知策略
OVERDUE_POLICY = {
    "1-7天":   {"channel": "飞书", "template": "温馨提示:您借阅的图书已逾期{days}天,请尽快归还"},
    "8-30天":  {"channel": "短信+飞书", "template": "提醒:您借阅的《{book}》已逾期{days}天,请立即归还,否则产生滞纳金"},
    "30天以上": {"channel": "短信+飞书+邮件", "template": "严重逾期:您借阅的《{book}》已逾期{days}天,请立即归还!逾期30天以上将暂停借阅权限"}
}

def send_overdue_notifications(overdue_list):
    """根据逾期天数分级发送催还通知"""
    results = {"feishu_count": 0, "sms_count": 0, "email_count": 0}

    for record in overdue_list:
        reader_name = record.get("reader_name", "")
        reader_id = record.get("reader_id", "")
        book_title = record.get("book_title", "")
        overdue_days = int(record.get("overdue_days", 0))
        phone = record.get("phone", "")
        email = record.get("email", f"{reader_id}@campus.edu.cn")

        # 根据逾期天数选择通知渠道
        if overdue_days <= 7:
            channel = "飞书"
        elif overdue_days <= 30:
            channel = "短信+飞书"
        else:
            channel = "短信+飞书+邮件"

        message = f"提醒:您借阅的《{book_title}》已逾期{overdue_days}天,请尽快归还至图书馆。"

        # ---- 飞书通知 ----
        if "飞书" in channel:
            card = {
                "config": {"wide_screen_mode": True},
                "header": {"title": {"tag": "plain_text", "content": "📚 图书逾期催还提醒"}, "template": "orange"},
                "elements": [{"tag": "markdown", "content": f"**读者**:{reader_name}{reader_id})\n**书名**:《{book_title}》\n**逾期天数**:{overdue_days}天\n\n请尽快归还,避免产生滞纳金"}]
            }
            try:
                requests.post(FEISHU_WEBHOOK, json={"msg_type": "interactive", "card": card}, timeout=10)
                results["feishu_count"] += 1
            except:
                pass

        # ---- 短信通知 ----
        if "短信" in channel and phone:
            try:
                requests.post(
                    f"{SMS_API_BASE}/send",
                    json={"phone": phone, "content": message},
                    timeout=10
                )
                results["sms_count"] += 1
            except:
                pass

        # ---- 邮件通知 ----
        if "邮件" in channel:
            try:
                requests.post(
                    f"{EMAIL_API_BASE}/send",
                    json={"to": email, "subject": "图书严重逾期催还通知", "body": message},
                    timeout=10
                )
                results["email_count"] += 1
            except:
                pass

    print(f"[INFO] 催还通知发送完成:飞书{results['feishu_count']}条,短信{results['sms_count']}条,邮件{results['email_count']}条")
    return {"status": "success", "results": results}

四、入馆人次统计与报表

# -*- coding: utf-8 -*-
#影刀Python节点:闸机入馆人次统计
import json
import requests
from datetime import datetime, timedelta
import openpyxl

GATE_API_BASE = "http://gate-system/api/v1"  # 闸机系统接口(如果无API则用影刀Web操作)
FEISHU_WEBHOOK = "https://open.feishu.cn/open-apis/bot/v2/hook/your-hook-id"

def generate_gate_daily_report(date=None):
    """统计当日入馆人次并推送飞书日报"""
    if date is None:
        date = datetime.now().strftime("%Y-%m-%d")

    # Step1: 获取闸机进出记录
    try:
        resp = requests.get(
            f"{GATE_API_BASE}/records",
            params={"date": date, "type": "enter"},
            timeout=15
        )
        records = resp.json().get("data", [])
    except Exception as e:
        return {"status": "error", "message": str(e)}

    # Step2: 分时段统计入馆人次
    hourly_stats = {}  # key=时段(如09-10), value=人次
    total_count = 0
    student_count = 0
    teacher_count = 0

    for record in records:
        enter_time = record.get("enter_time", "")
        hour = int(enter_time.split(" ")[1].split(":")[0]) if enter_time else 0
        time_slot = f"{hour:02d}-{(hour+1):02d}"
        hourly_stats[time_slot] = hourly_stats.get(time_slot, 0) + 1
        total_count += 1

        reader_type = record.get("reader_type", "")
        if reader_type == "student":
            student_count += 1
        elif reader_type == "teacher":
            teacher_count += 1

    # Step3: 生成飞书日报卡片
    hourly_text = "\n".join(
        [f"{slot}: {count}人次" for slot, count in sorted(hourly_stats.items())]
    )

    card = {
        "config": {"wide_screen_mode": True},
        "header": {
            "title": {"tag": "plain_text", "content": f"📊 图书馆入馆日报 {date}"},
            "template": "green" if total_count >= 500 else "blue"
        },
        "elements": [
            {"tag": "markdown", "content": f"**总入馆人次**:{total_count}人\n**学生**:{student_count}人\n**教师**:{teacher_count}人"},
            {"tag": "markdown", "content": f"**分时段统计**:\n{hourly_text}"},
            {"tag": "markdown", "content": f"\n高峰时段:{max(hourly_stats, key=hourly_stats.get) if hourly_stats else '无数据'}"}
        ]
    }
    requests.post(FEISHU_WEBHOOK, json={"msg_type": "interactive", "card": card}, timeout=10)

    # Step4: 同时生成Excel周报数据(追加写入)
    return {"status": "success", "total_count": total_count, "hourly_stats": hourly_stats}

五、新书编目自动化

在这里插入图片描述

新书到馆后,编目员需要从ISBN查询书目信息然后录入ILAS。影刀可以自动从国家图书馆ISBN接口查询:

# -*- coding: utf-8 -*-
#影刀Python节点:ISBN书目信息自动查询与编目
import json
import requests

# 国家图书馆ISBN查询API(实际用OpenISBN或豆瓣图书API)
ISBN_API_BASE = "https://api.openisbn.com/v1"  # ISBN查询接口

def query_book_info(isbn_list):
    """根据ISBN列表批量查询书目信息,返回编目所需字段"""
    book_info_list = []

    for isbn in isbn_list:
        try:
            resp = requests.get(
                f"{ISBN_API_BASE}/book/{isbn}",
                timeout=10
            )
            data = resp.json()

            book_info = {
                "isbn": isbn,                       # ISBN号
                "title": data.get("title", ""),     # 书名
                "author": data.get("author", ""),   # 作者
                "publisher": data.get("publisher", ""), # 出版社
                "publish_date": data.get("publish_date", ""), # 出版日期
                "category": data.get("category", ""),  # 分类号(中图法分类)
                "price": data.get("price", ""),     # 价格
                "pages": data.get("pages", ""),     # 页数
                "summary": data.get("summary", ""), # 内容摘要(前200字)
            }
            book_info_list.append(book_info)
            print(f"[INFO] ISBN {isbn}书目信息已获取:《{book_info['title']}》")

        except Exception as e:
            book_info_list.append({"isbn": isbn, "status": "error", "message": str(e)})
            print(f"[WARN] ISBN {isbn}查询失败: {e}")

    success_count = sum(1 for b in book_info_list if b.get("status") != "error")
    print(f"[INFO] 书目查询完成:成功{success_count}/{len(isbn_list)}本")
    return {"status": "success", "books": book_info_list}

影刀ILAS编目录入操作

获取书目信息后,影刀自动在ILAS系统录入:

在这里插入图片描述

  1. 打开网页指令 → ILAS新书编目页面http://library-ilas/catalog/new
  2. 输入文本指令 → ISBN号填入input#isbn
  3. 点击元素指令 → 点击"查询书目"按钮button#query-isbn
  4. 等待指令(3秒) → 等待书目信息自动填充
  5. 如果自动填充不完整,逐字段输入文本指令 → 书名input#title、作者input#author、出版社input#publisher
  6. 输入文本指令 → 分类号填入input#category(从API获取的中图法分类)
  7. 输入文本指令 → 馆藏位置填入input#location(默认"A区书架")
  8. 点击元素指令 → 点击"保存编目"按钮button#save-catalog
  9. 等待指令(元素出现) → 等待"编目成功"提示

六、设备报修自动派单与跟踪

图书馆设备(自助借还机、空调、照明)报修到后勤OA后无人跟踪,影刀实现自动派单:

[video(video-eYkwEogo-1785257989362)(type-csdn)(url-live.csdn.net/v/embed/524…)] 在这里插入图片描述

# -*- coding: utf-8 -*-
#影刀Python节点:报修单自动派单与跟踪
import json
import requests

OA_API_BASE = "http://oa-server/api/v1"  # 后勤OA接口
FEISHU_WEBHOOK = "https://open.feishu.cn/open-apis/bot/v2/hook/your-hook-id"

# 报修类型与维修人员映射
REPAIR_DISPATCH_MAP = {
    "自助借还机故障": {"team": "信息化中心", "priority": "urgent", "sla_hours": 4},
    "空调故障": {"team": "后勤维修组", "priority": "normal", "sla_hours": 24},
    "照明故障": {"team": "后勤维修组", "priority": "normal", "sla_hours": 48},
    "网络故障": {"team": "信息化中心", "priority": "urgent", "sla_hours": 2},
}

def dispatch_repair_orders():
    """从OA获取未派单的报修记录,自动分配维修团队并跟踪"""
    headers = {"Authorization": f"Bearer {OA_API_KEY}", "Content-Type": "application/json"}

    # Step1: 获取未派单的报修记录
    try:
        resp = requests.get(
            f"{OA_API_BASE}/repair/orders",
            headers=headers,
            params={"status": "undispatched"},
            timeout=10
        )
        orders = resp.json().get("data", [])
    except Exception as e:
        return {"status": "error", "message": str(e)}

    # Step2: 自动派单
    dispatched_count = 0
    for order in orders:
        repair_type = order.get("repair_type", "")
        dispatch_info = REPAIR_DISPATCH_MAP.get(repair_type, {"team": "后勤维修组", "priority": "normal", "sla_hours": 48})

        # 更新OA报修单:分配维修团队+设置优先级+SLA时限
        update_data = {
            "dispatch_team": dispatch_info["team"],
            "priority": dispatch_info["priority"],
            "sla_deadline": dispatch_info["sla_hours"],  # SLA响应时限(小时)
            "status": "dispatched"
        }
        try:
            requests.patch(
                f"{OA_API_BASE}/repair/orders/{order['order_id']}",
                headers=headers,
                json=update_data,
                timeout=10
            )
            dispatched_count += 1
        except:
            pass

    # Step3: 飞书推送派单通知给维修团队
    if dispatched_count > 0:
        card = {
            "config": {"wide_screen_mode": True},
            "header": {"title": {"tag": "plain_text", "content": f"🔧 图书馆设备报修派单({dispatched_count}条)"}, "template": "blue"},
            "elements": [{"tag": "markdown", "content": f"已自动派单{dispatched_count}条报修记录至对应维修团队"}]
        }
        requests.post(FEISHU_WEBHOOK, json={"msg_type": "interactive", "card": card}, timeout=10)

    # Step4: 检查已派单但超SLA未完成的报修,推送催修告警
    try:
        resp = requests.get(
            f"{OA_API_BASE}/repair/orders",
            headers=headers,
            params={"status": "dispatched", "sla_overdue": True},
            timeout=10
        )
        overdue_orders = resp.json().get("data", [])
        if overdue_orders:
            overdue_text = "\n".join(
                [f"· {o['order_id']}{o['repair_type']},已超SLA{o['sla_overdue_hours']}小时" for o in overdue_orders]
            )
            card = {
                "config": {"wide_screen_mode": True},
                "header": {"title": {"tag": "plain_text", "content": "⚠ 报修超SLA催修通知"}, "template": "red"},
                "elements": [{"tag": "markdown", "content": overdue_text}]
            }
            requests.post(FEISHU_WEBHOOK, json={"msg_type": "interactive", "card": card}, timeout=10)
    except:
        pass

    return {"status": "success", "dispatched_count": dispatched_count}

七、教务通知自动转发

# -*- coding: utf-8 -*-
#影刀Python节点:教务通知自动转发到学生飞书群
import json
import requests
from datetime import datetime

OA_API_BASE = "http://oa-server/api/v1"
FEISHU_WEBHOOK_STUDENT = "https://open.feishu.cn/open-apis/bot/v2/hook/student-group-hook"

def publish_notice_to_student_group():
    """从OA获取最新教务通知,转发到学生飞书群"""
    headers = {"Authorization": f"Bearer {OA_API_KEY}", "Content-Type": "application/json"}

    # 查询今日教务通知(图书馆相关)
    try:
        resp = requests.get(
            f"{OA_API_BASE}/notices",
            headers=headers,
            params={"category": "library", "date": datetime.now().strftime("%Y-%m-%d")},
            timeout=10
        )
        notices = resp.json().get("data", [])
    except:
        return {"status": "error", "message": "OA通知获取失败"}

    for notice in notices:
        title = notice.get("title", "")
        content = notice.get("content", "")
        publisher = notice.get("publisher", "")

        card = {
            "config": {"wide_screen_mode": True},
            "header": {"title": {"tag": "plain_text", "content": f"📢 {title}"},
                       "template": "turquoise"},
            "elements": [
                {"tag": "markdown", "content": content},
                {"tag": "markdown", "content": f"\n发布方:{publisher}\n发布时间:{notice.get('publish_time', '')}"}
            ]
        }
        requests.post(FEISHU_WEBHOOK_STUDENT, json={"msg_type": "interactive", "card": card}, timeout=10)

    return {"status": "success", "published_count": len(notices)}

八、常见问题速查

#现象原因解决方式
1ILAS系统逾期记录抓取不完整表格分页显示,影刀只抓了第一页影刀流程增加翻页逻辑:点击"下一页"按钮→继续抓取→直到最后一页
2短信催还通知发送失败校园短信网关余额不足或接口异常检查短信网关余额;备选方案改用飞书私信通知(需获取学生飞书open_id)
3ISBN查询API返回空结果ISBN号输入错误或该书未被收录影刀流程增加ISBN校验(13位数字+校验位计算);未收录的书标记为"手工编目"
4ILAS编目页面元素定位不稳定ILAS系统DOM结构不规范,ID随机用影刀相对定位(从已知元素向相邻元素偏移);或改用XPath定位特定属性组合
在这里插入图片描述

| 5 | 入馆日报高峰时段统计为空 | 闸机系统API返回时间格式不一致 | Python节点统一时间格式解析:检测2026-07-01 09:3009:30两种格式 | | 6 | 报修单派单后维修团队不响应 | OA系统通知不到位 | 影刀流程同时推送飞书告警到维修团队群+图书馆管理员群,双重催修 | | 7 | 学期开学高峰期逾期催还量大 | 新学期开学前大量借阅集中逾期 | 开学前2周提高催还频率:从每日一次改为每日2次(上午+下午) |

九、推荐资源

  • ILAS图书馆系统:国内高校主流图书馆管理系统,有Web界面但无开放API
  • OpenISBN API:ISBN书目信息查询接口,免费额度100次/天
  • 中图法分类:中国图书馆分类法,新书编目必填的分类号体系
  • 影刀Web操作:校园老旧系统必须用Web界面操作,元素定位技巧很重要
  • 飞书群机器人open.feishu.cn/document/ho…

十、内容标签

影刀RPA 图书馆自动化 逾期催还 入馆统计 新书编目 ISBN查询 设备报修 OA系统 教务通知 校园管理

在这里插入图片描述


作者:林焱 | 影刀RPA深度使用者,两年以上实操经验,专注IoT/MES/新能源行业自动化方案 在这里插入图片描述