承接 codewithathis/paperless-ngx 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

codewithathis/paperless-ngx

Composer 安装命令:

composer require codewithathis/paperless-ngx

包简介

A Laravel package for managing Paperless-ngx via its API, providing easy integration, document upload, search, tagging, and workflow automation.

README 文档

README

A comprehensive Laravel package for integrating with Paperless-ngx document management system. This package provides authentication, document management, search capabilities, and bulk operations through a clean Laravel interface.

Features

  • Authentication Support: Token-based and Basic authentication
  • Document Management: Upload, download, update, delete documents
  • Search & Filtering: Full-text search with various filters
  • Bulk Operations: Bulk edit and download documents
  • Metadata Management: Tags, correspondents, document types, storage paths
  • Custom Fields: Support for custom field operations
  • Share Links: Create and manage document share links
  • Statistics: Get system statistics and user profile
  • Error Handling: Comprehensive error handling and logging
  • Configuration: Flexible configuration system
  • Facade Support: Easy access via Laravel Facade
  • Artisan Commands: Built-in testing and management commands

Requirements

  • PHP 8.2 or newer (including PHP 8.4)
  • Laravel 10, 11, or 12

The supported integration surface is PaperlessService, the Paperless facade, configuration keys, and Artisan commands. Classes under Codewithathis\PaperlessNgx\Http and Codewithathis\PaperlessNgx\Api are internal implementation details and may change without a major release.

Installation

Via Composer

composer require codewithathis/paperless-ngx

Manual Installation

  1. Add to your composer.json:
{
    "require": {
        "codewithathis/paperless-ngx": "^2.0"
    }
}
  1. Run composer install:
composer install
  1. Publish Configuration:
php artisan vendor:publish --provider="Codewithathis\PaperlessNgx\PaperlessServiceProvider" --tag="paperless-config"
  1. Environment Variables

Add the following variables to your .env file:

# Paperless-ngx Configuration
PAPERLESS_BASE_URL=http://your-paperless-instance.com
PAPERLESS_TOKEN=your_api_token_here
PAPERLESS_USERNAME=your_username
PAPERLESS_PASSWORD=your_password
# token | basic | auto — default auto; see Configuration > Authentication
PAPERLESS_AUTH_METHOD=auto

# Optional Settings
PAPERLESS_PAGE_SIZE=25
PAPERLESS_TIMEOUT=30
PAPERLESS_API_VERSION=9
PAPERLESS_MAX_FILE_SIZE=52428800
PAPERLESS_LOGGING_ENABLED=true
PAPERLESS_LOG_LEVEL=error

Configuration

The package can be configured through the config/paperless.php file. Key configuration options:

Authentication

auth.method controls how requests are signed when using the service container defaults:

  • token — send the API token only (even if username/password are also set in .env).
  • basic — HTTP Basic auth with username/password only.
  • auto — legacy behaviour: Basic auth when both username and password are set; otherwise the token.

Runtime setToken() / setBasicAuth() on PaperlessService override the above for that instance.

'auth' => [
    'token' => env('PAPERLESS_TOKEN', null),
    'username' => env('PAPERLESS_USERNAME', null),
    'password' => env('PAPERLESS_PASSWORD', null),
    'method' => env('PAPERLESS_AUTH_METHOD', 'auto'),
],

Document Upload Settings

'upload' => [
    'max_file_size' => env('PAPERLESS_MAX_FILE_SIZE', 50 * 1024 * 1024),
    'allowed_mime_types' => [
        'application/pdf',
        'image/jpeg',
        'image/png',
        'image/tiff',
        // ... more types
    ],
    'auto_ocr' => env('PAPERLESS_AUTO_OCR', true),
    'auto_tag' => env('PAPERLESS_AUTO_TAG', false),
],

Usage

Basic Usage

Using Dependency Injection

use Codewithathis\PaperlessNgx\PaperlessService;

class DocumentController extends Controller
{
    public function __construct(private PaperlessService $paperlessService)
    {
    }

    public function index()
    {
        $documents = $this->paperlessService->getDocuments();
        return response()->json($documents);
    }
}

Using the Facade

use Codewithathis\PaperlessNgx\Facades\Paperless;

// Test connection
$isConnected = Paperless::testConnection();

// Get documents
$documents = Paperless::getDocuments(['title__icontains' => 'invoice']);

// Upload document
$documentId = Paperless::uploadDocument($file, [
    'title' => 'Invoice #123',
    'correspondent' => 1,
    'tags' => [1, 2, 3],
]);
// Returns ['task_id' => '...'] — poll with getTaskByUUID() until consumption completes

Authentication

Token Authentication (Recommended)

// Set token
$paperlessService->setToken('your_api_token');

// Or in constructor
$paperlessService = new PaperlessService(
    'http://your-paperless-instance.com',
    'your_api_token'
);

Basic Authentication

// Set credentials
$paperlessService->setBasicAuth('username', 'password');

// Or in constructor
$paperlessService = new PaperlessService(
    'http://your-paperless-instance.com',
    null,
    'username',
    'password'
);

Document Operations

Upload Document

use Illuminate\Http\UploadedFile;

$file = $request->file('document');
$metadata = [
    'title' => 'Invoice #123',
    'correspondent' => 1,
    'document_type' => 2,
    'tags' => [1, 2, 3],
    'storage_path' => 1,
    'archive_serial_number' => 1001,
];

$documentId = $paperlessService->uploadDocument($file, $metadata);
// Returns array with task_id — poll getTaskByUUID($result['task_id']) for the document id

Get Documents with Filters

$filters = [
    'title__icontains' => 'invoice',
    'correspondent__id' => 1,
    'tags__id__in' => [1, 2, 3],
    'created__gte' => '2024-01-01',
    'created__lte' => '2024-12-31',
];

$documents = $paperlessService->getDocuments($filters, 1, 25);

Update Document

$data = [
    'title' => 'Updated Invoice Title',
    'correspondent' => 2,
    'tags' => [1, 4, 5],
];

$document = $paperlessService->updateDocument(123, $data);

Download Document

// Download processed version
$content = $paperlessService->downloadDocument(123);

// Download original version
$originalContent = $paperlessService->downloadDocument(123, true);

Delete Document

$deleted = $paperlessService->deleteDocument(123);

Search Operations

Search Documents

// Search in database only
$results = $paperlessService->searchDocuments('invoice', true);

// Search in full content
$results = $paperlessService->searchDocuments('invoice', false);

Get Search Autocomplete

$suggestions = $paperlessService->getSearchAutocomplete('inv', 10);

Bulk Operations

Bulk Edit Documents

Paperless expects method and parameters in the bulk edit payload:

$documentIds = [1, 2, 3, 4, 5];

// Low-level API (any supported method)
$result = $paperlessService->bulkEditDocuments($documentIds, [
    'method' => 'modify_tags',
    'parameters' => [
        'add_tags' => [1, 2],
        'remove_tags' => [3],
    ],
]);

// Convenience helpers
$paperlessService->bulkAddTag($documentIds, 5);
$paperlessService->bulkSetCorrespondent($documentIds, 1);

Bulk Download Documents

$documentIds = [1, 2, 3, 4, 5];
$downloadInfo = $paperlessService->bulkDownloadDocuments($documentIds);

Metadata Management

Tags

// Get all tags
$tags = $paperlessService->getTags();

// Create tag
$tag = $paperlessService->createTag([
    'name' => 'Important',
    'color' => '#ff0000',
]);

// Update tag
$updatedTag = $paperlessService->updateTag(1, [
    'name' => 'Very Important',
    'color' => '#00ff00',
]);

// Delete tag
$deleted = $paperlessService->deleteTag(1);

Correspondents

// Get correspondents
$correspondents = $paperlessService->getCorrespondents();

// Create correspondent
$correspondent = $paperlessService->createCorrespondent([
    'name' => 'ABC Company',
    'matching_algorithm' => 1,
    'match' => 'ABC',
]);

// Update correspondent
$updatedCorrespondent = $paperlessService->updateCorrespondent(1, [
    'name' => 'ABC Corporation',
]);

// Delete correspondent
$deleted = $paperlessService->deleteCorrespondent(1);

Document Types

// Get document types
$documentTypes = $paperlessService->getDocumentTypes();

// Create document type
$documentType = $paperlessService->createDocumentType([
    'name' => 'Invoice',
    'matching_algorithm' => 1,
    'match' => 'invoice',
]);

// Update document type
$updatedDocumentType = $paperlessService->updateDocumentType(1, [
    'name' => 'Invoice Document',
]);

// Delete document type
$deleted = $paperlessService->deleteDocumentType(1);

Document Notes

// Get document notes
$notes = $paperlessService->getDocumentNotes(123);

// Add note
$note = $paperlessService->addDocumentNote(123, 'This is an important document');

// Delete note
$deleted = $paperlessService->deleteDocumentNote(123, 1);

Document History

// Get document history
$history = $paperlessService->getDocumentHistory(123);

Share Links

// Get document share links
$shareLinks = $paperlessService->getDocumentShareLinks(123);

// Create share link
$shareLink = $paperlessService->createShareLink([
    'document' => 123,
    'expiration' => '2024-12-31',
]);

// Update share link
$updatedShareLink = $paperlessService->updateShareLink(1, [
    'expiration' => '2024-06-30',
]);

// Delete share link
$deleted = $paperlessService->deleteShareLink(1);

Statistics

// Get system statistics
$statistics = $paperlessService->getStatistics();

Tasks

$tasks = $paperlessService->getTasks(['acknowledged' => 'false']);
$task = $paperlessService->getTaskByUUID($taskId);
$paperlessService->acknowledgeTasks([1, 2]);

Workflows, Mail, Users & Admin

$workflows = $paperlessService->getWorkflows();
$accounts = $paperlessService->getMailAccounts();
$users = $paperlessService->getUsers();
$logs = $paperlessService->getLogs();
$config = $paperlessService->getConfig();

Trash

$trashed = $paperlessService->getTrash();
$paperlessService->trashAction([123], 'restore');
$paperlessService->trashAction(null, 'empty'); // empty all trashed docs

API Versioning

// Via .env: PAPERLESS_API_VERSION=9
// Or at runtime:
$paperlessService->setApiVersion(9);

System Information

// Get system status
$status = $paperlessService->getStatus();

// Get remote version
$version = $paperlessService->getRemoteVersion();

// Get user profile
$profile = $paperlessService->getProfile();

// Generate auth token
$token = $paperlessService->generateAuthToken();

Artisan Commands

The package includes several Artisan commands for testing and management:

Test Connection

php artisan paperless:test

Test with File Upload

php artisan paperless:test --upload=/path/to/document.pdf

Test Search

php artisan paperless:test --search="invoice"

Error Handling

The service includes comprehensive error handling with custom exception classes:

Custom Exceptions

  • PaperlessApiException - For API-related errors (HTTP status codes, response data, unique constraint violations)
  • PaperlessConnectionException - For connection issues (timeout, DNS, SSL, network)
  • PaperlessValidationException - For validation failures (metadata, field validation)
  • PaperlessFileException - For file-related errors (size, type, permissions, corruption)

Basic Error Handling

use Codewithathis\PaperlessNgx\Exceptions\PaperlessApiException;
use Codewithathis\PaperlessNgx\Exceptions\PaperlessConnectionException;

try {
    $documents = $paperlessService->getDocuments();
} catch (PaperlessApiException $e) {
    // Handle API errors (4xx, 5xx status codes)
    $statusCode = $e->getStatusCode();
    $responseData = $e->getResponseData();
    
    if ($e->isAuthenticationError()) {
        return response()->json(['error' => 'Authentication failed'], 401);
    }
    
    return response()->json(['error' => $e->getMessage()], $statusCode);
} catch (PaperlessConnectionException $e) {
    // Handle connection issues
    return response()->json(['error' => 'Service unavailable'], 503);
}

Using the Exception Handler

use Codewithathis\PaperlessNgx\Exceptions\PaperlessExceptionHandler;

try {
    $result = $paperlessService->uploadDocument($file, $metadata);
} catch (PaperlessException $e) {
    $errorResponse = PaperlessExceptionHandler::handle($e);
    $httpStatusCode = PaperlessExceptionHandler::getHttpStatusCode($e);
    
    return response()->json($errorResponse, $httpStatusCode);
}

For detailed exception handling examples, see EXCEPTION_HANDLING_EXAMPLES.md.

Logging

The service logs all API interactions when logging is enabled:

'logging' => [
    'enabled' => env('PAPERLESS_LOGGING_ENABLED', true),
    'level' => env('PAPERLESS_LOG_LEVEL', 'error'),
    'channel' => env('PAPERLESS_LOG_CHANNEL', 'paperless'),
],

Caching

The service supports caching for improved performance:

'cache' => [
    'enabled' => env('PAPERLESS_CACHE_ENABLED', true),
    'ttl' => env('PAPERLESS_CACHE_TTL', 3600),
    'prefix' => env('PAPERLESS_CACHE_PREFIX', 'paperless'),
],

Security

Security settings for SSL verification and timeouts:

'security' => [
    'verify_ssl' => env('PAPERLESS_VERIFY_SSL', true),
    'allow_self_signed' => env('PAPERLESS_ALLOW_SELF_SIGNED', false),
    'timeout' => env('PAPERLESS_REQUEST_TIMEOUT', 30),
],

Testing

Test the connection to your Paperless-ngx instance:

// Test connection
$isConnected = $paperlessService->testConnection();

if ($isConnected) {
    echo "Successfully connected to Paperless-ngx";
} else {
    echo "Failed to connect to Paperless-ngx";
}

Examples

Complete Document Management Workflow

use Codewithathis\PaperlessNgx\PaperlessService;
use Illuminate\Http\UploadedFile;

class DocumentService
{
    public function __construct(private PaperlessService $paperlessService)
    {
    }

    public function processInvoice(UploadedFile $file, array $data)
    {
        try {
            // 1. Upload document
            $documentId = $this->paperlessService->uploadDocument($file, [
                'title' => $data['title'],
                'correspondent' => $data['correspondent_id'],
                'document_type' => $data['document_type_id'],
                'tags' => $data['tag_ids'],
            ]);

            // 2. Add note
            $this->paperlessService->addDocumentNote($documentId, 'Processed automatically');

            // 3. Get document details
            $document = $this->paperlessService->getDocument($documentId);

            return [
                'success' => true,
                'document_id' => $documentId,
                'document' => $document,
            ];
        } catch (Exception $e) {
            Log::error('Failed to process invoice', [
                'error' => $e->getMessage(),
                'file' => $file->getClientOriginalName(),
            ]);

            return [
                'success' => false,
                'error' => $e->getMessage(),
            ];
        }
    }

    public function searchInvoices(string $query)
    {
        $filters = [
            'title__icontains' => $query,
            'document_type__name__icontains' => 'invoice',
        ];

        return $this->paperlessService->getDocuments($filters);
    }

    public function bulkTagDocuments(array $documentIds, array $tagIds)
    {
        return $this->paperlessService->bulkEditDocuments($documentIds, [
            'method' => 'modify_tags',
            'parameters' => ['add_tags' => $tagIds],
        ]);
    }
}

Using with Laravel Jobs

use Codewithathis\PaperlessNgx\PaperlessService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class ProcessDocumentJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(
        private string $filePath,
        private array $metadata
    ) {
    }

    public function handle(PaperlessService $paperlessService)
    {
        $file = new UploadedFile($this->filePath, basename($this->filePath));
        
        $documentId = $paperlessService->uploadDocument($file, $this->metadata);
        
        // Process the uploaded document
        Log::info('Document uploaded successfully', ['document_id' => $documentId]);
    }
}

Troubleshooting

Common Issues

  1. Authentication Failed

    • Verify your API token or credentials
    • Check if the Paperless-ngx instance is accessible
    • Ensure the authentication method is correctly configured
  2. Upload Fails

    • Check file size limits
    • Verify supported file types
    • Ensure proper permissions on the Paperless-ngx instance
  3. Connection Timeout

    • Increase timeout settings in configuration
    • Check network connectivity
    • Verify Paperless-ngx instance is running
  4. SSL Certificate Issues

    • Set PAPERLESS_VERIFY_SSL=false for self-signed certificates
    • Update SSL certificates on your Paperless-ngx instance

Debug Mode

Enable debug logging to troubleshoot issues:

PAPERLESS_LOGGING_ENABLED=true
PAPERLESS_LOG_LEVEL=debug

Package Structure

codewithathis/paperless-ngx/
├── src/
│   ├── PaperlessService.php
│   ├── PaperlessServiceProvider.php
│   ├── Api/                    # Internal API resource classes
│   ├── Http/
│   │   └── PaperlessApiClient.php
│   ├── Facades/
│   │   └── Paperless.php
│   ├── Exceptions/
│   └── Commands/
│       └── TestPaperlessConnection.php
├── config/
│   └── paperless.php
├── tests/
├── composer.json
└── README.md

Requirements

  • PHP 8.2 or newer (including PHP 8.4)
  • Laravel 10, 11, or 12

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Testing

# Run the test command
php artisan paperless:test

# Test with file upload
php artisan paperless:test --upload=/path/to/test.pdf

# Test search functionality
php artisan paperless:test --search="invoice"

Changelog

Please see CHANGELOG for more information on what has changed recently.

License

This package is open-sourced software licensed under the MIT license.

Support

If you encounter any issues or have questions, please:

  1. Check the troubleshooting section
  2. Search existing issues
  3. Create a new issue with detailed information

Credits

codewithathis/paperless-ngx 适用场景与选型建议

codewithathis/paperless-ngx 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 27 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 08 月 08 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「api」 「laravel」 「integration」 「document-management」 「paperless」 「paperless-ngx」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 codewithathis/paperless-ngx 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 codewithathis/paperless-ngx 我们能提供哪些服务?
定制开发 / 二次开发

基于 codewithathis/paperless-ngx 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 27
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 34
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-08-08