承接 selli/ticketing 相关项目开发

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

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

selli/ticketing

Composer 安装命令:

composer require selli/ticketing

包简介

The agnostic, headless, multi-tenant ticketing domain engine for Laravel. Attach tickets to anything — your models, your UI, your tenant.

README 文档

README

Latest Version on Packagist GitHub Tests Action Status Total Downloads

The agnostic, headless, multi-tenant ticketing domain engine for Laravel. Attach tickets to anything — your models, your UI, your tenant.

selli/ticketing is not a help-desk app and not a UI. It is the reusable domain layer you build any ticketing mechanism on — customer support, technical interventions, internal requests, incident management, work queues — in days instead of weeks. A ticket can be about any Eloquent model in your app (an order, a device, a contract), about a service, or about nothing at all. The link to your domain happens by contract (Ticketable), never by coupling to your schema.

Headless by design: zero UI, zero forced user model, multi-tenant by default, workflow configurable per ticket type. The same engine serves a Filament back-office, an Inertia/Vue front-end, a mobile API or a queued job without changes.

📖 Full documentation: laravel-ticketing.selli.io

Features

  • Config-driven workflow per ticket type, with guards and a Spatie state-class bridge — validated at boot.
  • SLA & escalation — first-response / next-response / resolution targets on business hours, with a pausing clock.
  • Routing & assignment — teams, pluggable strategies (round-robin, least-busy, skill-based, custom) and data-driven routing rules.
  • Collaboration — attachments (signed URLs), @mentions, canned responses, macros, merge/split, tags.
  • CSAT with stateless, signed rating links.
  • Automation — a data-driven trigger→conditions→actions rule engine, plus SSRF-guarded outbound webhooks.
  • Notifications — mail, database (in-app bell), broadcast and Slack, with per-user/per-tenant preferences.
  • Channels — an opt-in versioned REST API, email-to-ticket (threading, anti-loop, idempotent), and realtime broadcasting over Reverb.
  • Security — agnostic authorization policies, an immutable audit trail, and GDPR anonymisation / export / retention.

Installation

composer require selli/ticketing
php artisan ticketing:install   # publishes config + migrations, offers to migrate
php artisan ticketing:demo      # seeds a working example ticket

Quick start

Make any model the subject of tickets:

use Selli\Ticketing\Concerns\HasTickets;
use Selli\Ticketing\Contracts\Ticketable;

class Order extends Model implements Ticketable
{
    use HasTickets; // tickets() relation + openTicket() helper
}

Open and work tickets through the facade or the host helper:

use Selli\Ticketing\Facades\Ticketing;
use Selli\Ticketing\Enums\Priority;
use Selli\Ticketing\Enums\MessageVisibility;

// A free-standing request
$ticket = Ticketing::open(
    type: 'support',
    title: 'Login is broken',
    requester: $user,
    priority: Priority::High,
);

// A ticket about any host entity
$ticket = $order->openTicket(type: 'incident', title: 'Missing shipment', requester: $user);

// Conversation, with public/internal visibility
Ticketing::for($ticket)->postMessage($agent, 'Looking into it', MessageVisibility::Internal);
Ticketing::for($ticket)->postMessage($agent, 'Refund issued', MessageVisibility::Public);

Actors are agnostic too — implement CanRequestTickets and/or CanActOnTickets on whichever model(s) represent your requesters and agents (even two different populations such as Customer and Operator).

Multi-tenancy

Tenancy is structural, not an afterthought. Every table carries a tenant column, every read is scoped by a global scope, every write is auto-assigned to the current tenant. With no tenant resolved the scope fails closed — only shared (null-tenant) rows are visible, never another tenant's data.

use Selli\Ticketing\Tenancy\TenantContext;

// CLI / queues / email: act explicitly as a tenant
app(TenantContext::class)->forTenant($tenantId, function () {
    Ticketing::open(type: 'support', title: '...', requester: $requester);
});

Bind your own TenantResolver (or a bridge to stancl/spatie tenancy) to inherit the current tenant from your existing infrastructure.

Architecture at a glance

  • Three-level APITicketing facade for common cases, Action classes for fine control and testing, domain events for extension.
  • Everything is an eventTicketOpened, MessagePosted, … are the primary extension hooks. Automations, notifications, audit and integrations attach here.
  • Override-friendly — every model is resolved from the container and replaceable: Ticketing::useTicketModel(MyTicket::class).
  • Immutable audit trailticket_activities is append-only; updates/deletes throw.
  • Config-validated at boot — a workflow that references a missing state fails fast, not at runtime.

Testing

composer test            # Pest
composer test-coverage   # Pest with a 90% minimum
composer analyse         # PHPStan (Larastan) level 6
composer format          # Laravel Pint

Changelog

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

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-29

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固