本次实操选择完全免费、适合政府/事业单位内网/低权限环境部署的工具——Seafile 社区版 11.0.10,搭配轻量表单工具简道云免费版(每月5000条提交),满足“申请受理→调查取证→审理决定→归档查询”全流程基础需求。
202X年度XX区行政复议待归档库
├─受理编号文件夹(格式:[年份]XX复受字第XXX号)
│ ├─01-申请材料
│ │ ├─复议申请书.pdf
│ │ ├─申请人身份证明.pdf
│ │ └─原行政行为材料.pdf
│ ├─02-调查取证材料
│ ├─03-审理材料
│ └─04-决定与送达材料

若无需自动同步,档案管理员可手动将简道云附件下载后按编号文件夹分类上传Seafile;若需自动同步,使用简道云简道云API连接器(免费版每月500次调用)+ Python 轻量脚本实现:
pip install requests seafile-api
import requests
import time
from seafileapi import Seafile
简道云参数
JDY_APP_ID = "你的简道云应用ID(应用设置→基本信息)"
JDY_ENTRY_ID = "你的登记表表单ID(表单设置→基本信息)"
JDY_API_KEY = "你的简道云API密钥(应用设置→API)"
Seafile参数
SEAFILE_URL = "http://[本机固定IP]:8000"
SEAFILE_ADMIN_EMAIL = "你的Seafile管理员邮箱"
SEAFILE_ADMIN_PASSWORD = "你的Seafile管理员密码"
SEAFILE_REPO_NAME = "202X年度XX区行政复议待归档库"
SEAFILE_REPO_PASSWORD = "你的加密库密码"
获取简道云已归档表单数据
def get_jdy_archived_data():
url = f"https://api.jiandaoyun.com/api/v5/app/{JDY_APP_ID}/entry/{JDY_ENTRY_ID}/data"
headers = {
"Authorization": f"Bearer {JDY_API_KEY}",
"Content-Type": "application/json"
}
params = {
"filter": {
"status": "archived"
},
"limit": 10
}
response = requests.get(url, headers=headers, params=params)
return response.json().get("data", [])
下载简道云附件到本地临时文件夹
def download_jdy_attachments(attachments, temp_dir="temp"):
import os
if not os.path.exists(temp_dir):
os.makedirs(temp_dir)
local_files = []
for att in attachments:
att_url = att["url"]
att_name = att["name"]
att_path = os.path.join(temp_dir, att_name)
with requests.get(att_url, stream=True) as r:
r.raise_for_status()
with open(att_path, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
local_files.append(att_path)
return local_files
上传到Seafile对应文件夹
def upload_to_seafile(repo, folder_name, local_files):
try:
创建子目录结构
base_path = folder_name
for sub_dir in ["01-申请材料", "02-调查取证材料", "03-审理材料", "04-决定与送达材料"]:
sub_path = f"{base_path}/{sub_dir}"
try:
repo.get_dir(sub_path)
except:
repo.create_dir(sub_path)
上传附件到对应子目录(根据附件上传的节点推断,或在简道云添加“附件分类”字段)
for local_file in local_files:
file_name = os.path.basename(local_file)
默认先上传到01-申请材料,后续可优化分类逻辑
upload_path = f"{base_path}/01-申请材料/{file_name}"
repo.upload_file(upload_path, local_file)
return True
except Exception as e:
print(f"上传失败:{e}")
return False
主循环
def main():
连接Seafile
seafile = Seafile(SEAFILE_URL)
seafile.login(SEAFILE_ADMIN_EMAIL, SEAFILE_ADMIN_PASSWORD)
获取加密库
repo = None
for r in seafile.list_repos():
if r.name == SEAFILE_REPO_NAME:
repo = r
repo.decrypt(SEAFILE_REPO_PASSWORD)
break
if not repo:
print("未找到指定加密库")
return
每5分钟检查一次
while True:
archived_data = get_jdy_archived_data()
for data in archived_data:
folder_name = data["受理编号"]
attachments = data.get("上传附件", [])
if attachments:
检查Seafile是否已存在该文件夹
try:
repo.get_dir(folder_name)
continue
except:
pass
local_files = download_jdy_attachments(attachments)
if upload_to_seafile(repo, folder_name, local_files):
print(f"成功同步:{folder_name}")
清理临时文件
import shutil
shutil.rmtree("temp")
time.sleep(300)
if __name__ == "__main__":
main()