首页
/ 移动端秒级管理文档:Paperless-ngx API实战指南

移动端秒级管理文档:Paperless-ngx API实战指南

2026-02-05 05:20:33作者:晏闻田Solitary

你是否还在为纸质文档堆积如山而烦恼?是否希望在手机上随时检索、管理重要文件?本文将带你从零开始构建一个基于React Native的Paperless-ngx移动端应用,通过API集成实现文档的无缝管理。读完本文,你将掌握:

  • Paperless-ngx API的核心认证与文档操作
  • React Native环境搭建与API请求封装
  • 移动端文档列表、详情、上传功能实现
  • 离线同步与性能优化技巧

API基础:认证与核心端点

Paperless-ngx提供功能完备的REST API,所有操作都需要通过认证。官方推荐使用Token认证方式,在用户中心获取令牌后,即可通过HTTP头部进行授权:

Authorization: Token <your_token_here>

文档操作的核心端点包括:

  • 获取文档列表GET /api/documents/,支持分页和搜索参数
  • 获取单文档详情GET /api/documents/{id}/
  • 上传新文档POST /api/documents/post_document/,支持表单数据提交
  • 批量操作POST /api/documents/bulk_edit/,支持修改标签、合并文档等操作

详细API规范可参考官方文档,其中批量编辑功能支持设置发件人、文档类型、标签等元数据,例如设置文档类型的请求体格式如下:

{
  "documents": [1, 2, 3],
  "method": "set_document_type",
  "parameters": {"document_type": 42}
}

React Native项目初始化

首先创建React Native项目并安装必要依赖:

npx react-native init PaperlessMobile
cd PaperlessMobile
npm install axios react-navigation react-native-fast-image

项目结构采用功能模块化设计:

src/
├── api/           # API请求封装
├── components/    # UI组件
├── screens/       # 页面屏幕
├── hooks/         # 自定义钩子
└── utils/         # 工具函数

API客户端封装

src/api/client.js中封装API请求基础配置,处理认证和错误:

import axios from 'axios';

const API_BASE_URL = 'http://your-paperless-instance/api';
const TOKEN = 'your_auth_token';

const apiClient = axios.create({
  baseURL: API_BASE_URL,
  headers: {
    'Authorization': `Token ${TOKEN}`,
    'Content-Type': 'application/json',
  },
});

// 请求拦截器处理认证过期
apiClient.interceptors.response.use(
  response => response,
  error => {
    if (error.response?.status === 401) {
      // 处理令牌过期逻辑
    }
    return Promise.reject(error);
  }
);

export default apiClient;

核心功能实现:文档列表与详情

文档列表页面

使用FlatList组件实现文档列表,支持下拉刷新和无限滚动加载:

import React, { useState, useEffect } from 'react';
import { FlatList, View, Text, RefreshControl } from 'react-native';
import apiClient from '../api/client';

const DocumentListScreen = () => {
  const [documents, setDocuments] = useState([]);
  const [loading, setLoading] = useState(false);
  const [page, setPage] = useState(1);

  const fetchDocuments = async () => {
    setLoading(true);
    try {
      const response = await apiClient.get(`/documents/?page=${page}`);
      setDocuments(prev => page === 1 ? response.data.results : [...prev, ...response.data.results]);
      setPage(prev => prev + 1);
    } catch (error) {
      console.error('Failed to fetch documents:', error);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchDocuments();
  }, []);

  return (
    <FlatList
      data={documents}
      keyExtractor={item => item.id.toString()}
      renderItem={({ item }) => (
        <View style={{ padding: 16, borderBottomWidth: 1 }}>
          <Text style={{ fontSize: 18 }}>{item.title}</Text>
          <Text>{item.correspondent?.name}</Text>
          <Text>{new Date(item.created).toLocaleDateString()}</Text>
        </View>
      )}
      onEndReached={fetchDocuments}
      onEndReachedThreshold={0.5}
      refreshControl={
        <RefreshControl refreshing={loading} onRefresh={() => { setPage(1); fetchDocuments(); }} />
      }
    />
  );
};

export default DocumentListScreen;

Paperless-ngx的Web界面采用响应式设计,移动端浏览器也能获得良好体验,但原生应用可提供更优的性能和离线支持。下图展示了Web端文档列表在移动设备上的显示效果:

移动端文档列表

文档详情与预览

实现文档详情页面,通过API获取完整元数据并预览文档内容:

const DocumentDetailScreen = ({ route }) => {
  const { id } = route.params;
  const [document, setDocument] = useState(null);

  useEffect(() => {
    const fetchDocument = async () => {
      try {
        const response = await apiClient.get(`/documents/${id}/`);
        setDocument(response.data);
      } catch (error) {
        console.error('Failed to fetch document:', error);
      }
    };

    fetchDocument();
  }, [id]);

  if (!document) return <ActivityIndicator size="large" />;

  return (
    <ScrollView style={{ padding: 16 }}>
      <Text style={{ fontSize: 24, fontWeight: 'bold' }}>{document.title}</Text>
      <View style={{ flexDirection: 'row', marginVertical: 8 }}>
        <Tag color={document.tags[0]?.color}>{document.tags[0]?.name}</Tag>
      </View>
      <Text>发件人: {document.correspondent?.name}</Text>
      <Text>类型: {document.document_type?.name}</Text>
      <Text>创建日期: {new Date(document.created).toLocaleString()}</Text>
      <Pdf
        source={{ uri: `${API_BASE_URL}/documents/${id}/preview/` }}
        style={{ width: '100%', height: 400, marginTop: 16 }}
      />
    </ScrollView>
  );
};

文档上传功能

利用React Native的文件选择器和表单数据提交实现文档上传:

import DocumentPicker from 'react-native-document-picker';

const uploadDocument = async () => {
  try {
    const result = await DocumentPicker.pick({
      type: [DocumentPicker.types.pdf],
    });

    const formData = new FormData();
    formData.append('document', {
      uri: result.uri,
      type: result.type,
      name: result.name,
    });
    formData.append('title', '移动端上传文档');
    formData.append('tags', 1);
    formData.append('tags', 3);

    const response = await apiClient.post('/documents/post_document/', formData, {
      headers: { 'Content-Type': 'multipart/form-data' },
    });
    
    // 上传成功后获取任务ID,轮询检查处理状态
    const taskId = response.data;
    checkTaskStatus(taskId);
    
  } catch (error) {
    if (DocumentPicker.isCancel(error)) {
      // 用户取消选择
    } else {
      console.error('Upload error:', error);
    }
  }
};

上传文档时可通过表单字段设置元数据,包括标题、创建日期、发件人ID等。上传成功后API会返回任务UUID,可通过/api/tasks/?task_id={uuid}端点查询处理进度。

高级功能:离线同步与批量操作

离线数据同步

使用AsyncStorage缓存文档列表和详情,实现基本的离线访问能力:

// 缓存文档列表
const cacheDocuments = async (documents) => {
  try {
    await AsyncStorage.setItem('cachedDocuments', JSON.stringify(documents));
    await AsyncStorage.setItem('cacheTimestamp', Date.now().toString());
  } catch (error) {
    console.error('Failed to cache documents:', error);
  }
};

// 获取缓存数据(如果未过期)
const getCachedDocuments = async () => {
  try {
    const timestamp = await AsyncStorage.getItem('cacheTimestamp');
    if (!timestamp || Date.now() - parseInt(timestamp) > 3600000) {
      return null; // 缓存过期(1小时)
    }
    const documents = await AsyncStorage.getItem('cachedDocuments');
    return documents ? JSON.parse(documents) : null;
  } catch (error) {
    console.error('Failed to get cached documents:', error);
    return null;
  }
};

批量操作实现

通过API的批量编辑端点实现多文档同时操作:

// 批量设置文档标签
const batchAddTags = async (documentIds, tagId) => {
  try {
    await apiClient.post('/documents/bulk_edit/', {
      "documents": documentIds,
      "method": "add_tag",
      "parameters": { "tag": tagId }
    });
    // 操作成功后刷新文档列表
    fetchDocuments();
  } catch (error) {
    console.error('Batch operation failed:', error);
  }
};

Paperless-ngx支持丰富的批量操作,包括修改发件人、文档类型、存储路径,以及合并、拆分文档等高级功能。移动端可通过勾选框选择多个文档,底部弹出操作菜单:

批量编辑界面

性能优化与最佳实践

  1. 图片压缩:上传前压缩图片,减少带宽占用和处理时间
  2. 分页加载:使用API的分页功能,避免一次性加载过多数据
  3. 图片懒加载:文档缩略图使用懒加载,提高列表滚动流畅度
  4. 请求节流:搜索输入时添加防抖,避免频繁API调用
  5. 错误处理:完善的错误提示和重试机制,提升用户体验

总结与扩展方向

本文介绍了基于React Native和Paperless-ngx API构建移动端应用的核心步骤,包括认证授权、文档CRUD、上传处理和离线缓存。你可以进一步扩展:

  • 实现OCR文字识别结果预览
  • 添加自定义字段编辑功能
  • 集成推送通知提醒新文档
  • 开发文档扫描功能(调用设备相机)

Paperless-ngx的API提供了完整的权限控制机制,可通过set_permissions参数管理文档访问权限。建议在生产环境中使用HTTPS确保数据传输安全,并定期更新API Token。

通过移动端应用,你可以随时随地管理个人和家庭文档,让纸质文件真正实现数字化、智能化管理。立即动手尝试,开启无纸办公新体验!

项目示例代码已开源,可通过https://gitcode.com/GitHub_Trending/pa/paperless-ngx获取完整实现。更多API细节请参考官方文档

登录后查看全文
热门项目推荐
相关项目推荐