package-development

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Package Development in Bagisto

Bagisto包开发

Overview

概述

A package is a self-contained module that encapsulates specific features or functionality in Bagisto. This comprehensive skill covers all aspects of package development from structure to advanced features.
包是Bagisto中封装特定功能的独立模块。本技能全面涵盖了包开发从结构到高级功能的所有方面。

When to Apply

适用场景

Activate this skill when:
  • Creating new packages for Bagisto
  • Setting up package directory structure
  • Creating database migrations
  • Building Eloquent models with contracts and proxies
  • Implementing repositories for data access
  • Creating routes for admin/shop sections
  • Building controllers with dependency injection
  • Creating Blade views with Bagisto layouts
  • Adding multi-language support
  • Creating admin DataGrid tables
  • Setting up admin navigation menus
  • Implementing permission-based access control
  • Creating configurable settings for admin

在以下场景启用本技能:
  • 为Bagisto创建新包
  • 设置包目录结构
  • 创建数据库迁移
  • 构建带契约和代理的Eloquent模型
  • 实现数据访问仓库
  • 为后台/前台区域创建路由
  • 构建依赖注入的控制器
  • 创建基于Bagisto布局的Blade视图
  • 添加多语言支持
  • 创建后台DataGrid表格
  • 设置后台导航菜单
  • 实现基于权限的访问控制
  • 为后台创建可配置设置

@core: Package Development - Core

@core: 包开发 - 核心

Package Structure

包结构

Standard Directory Structure

标准目录结构

packages/Webkul/{PackageName}/
├── src/
│   ├── Config/
│   │   ├── admin-menu.php
│   │   ├── acl.php
│   │   └── system.php
│   ├── Database/
│   │   ├── Migrations/
│   │   ├── Seeders/
│   │   └── Factories/
│   ├── Http/
│   │   ├── Controllers/
│   │   │   ├── Admin/
│   │   │   └── Shop/
│   │   ├── Middleware/
│   │   └── Requests/
│   ├── Models/
│   │   └── {Package}Proxy.php
│   ├── Repositories/
│   │   └── {Package}Repository.php
│   ├── Resources/
│   │   ├── views/
│   │   └── lang/
│   ├── Providers/
│   │   ├── {Package}ServiceProvider.php
│   │   └── ModuleServiceProvider.php
│   ├── DataGrids/
│   │   └── Admin/
│   └── manifest.php
└── composer.json
packages/Webkul/{PackageName}/
├── src/
│   ├── Config/
│   │   ├── admin-menu.php
│   │   ├── acl.php
│   │   └── system.php
│   ├── Database/
│   │   ├── Migrations/
│   │   ├── Seeders/
│   │   └── Factories/
│   ├── Http/
│   │   ├── Controllers/
│   │   │   ├── Admin/
│   │   │   └── Shop/
│   │   ├── Middleware/
│   │   └── Requests/
│   ├── Models/
│   │   └── {Package}Proxy.php
│   ├── Repositories/
│   │   └── {Package}Repository.php
│   ├── Resources/
│   │   ├── views/
│   │   └── lang/
│   ├── Providers/
│   │   ├── {Package}ServiceProvider.php
│   │   └── ModuleServiceProvider.php
│   ├── DataGrids/
│   │   └── Admin/
│   └── manifest.php
└── composer.json

Using Package Generator

使用包生成器

Installation

安装

bash
composer require bagisto/bagisto-package-generator
bash
composer require bagisto/bagisto-package-generator

Creating a Package

创建包

bash
undefined
bash
undefined

If package directory doesn't exist

如果包目录不存在

php artisan package:make Webkul/RMA
php artisan package:make Webkul/RMA

If package directory already exists

如果包目录已存在

php artisan package:make Webkul/RMA --force
undefined
php artisan package:make Webkul/RMA --force
undefined

Making Models

创建模型

bash
php artisan package:make-model ReturnRequest Webkul/RMA
bash
php artisan package:make-model ReturnRequest Webkul/RMA

Making Repositories

创建仓库

bash
php artisan package:make-repository ReturnRequestRepository Webkul/RMA
bash
php artisan package:make-repository ReturnRequestRepository Webkul/RMA

Making Migrations

创建迁移

bash
php artisan package:make-migration CreateRmaRequestsTable Webkul/RMA
bash
php artisan package:make-migration CreateRmaRequestsTable Webkul/RMA

Manual Setup

手动设置

Create Package Directory

创建包目录

bash
mkdir -p packages/Webkul/RMA/src/Providers
bash
mkdir -p packages/Webkul/RMA/src/Providers

Create Service Provider

创建服务提供者

File:
packages/Webkul/RMA/src/Providers/RMAServiceProvider.php
php
<?php

namespace Webkul\RMA\Providers;

use Illuminate\Support\ServiceProvider;

class RMAServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        //
    }

    public function boot(): void
    {
        //
    }
}
文件路径:
packages/Webkul/RMA/src/Providers/RMAServiceProvider.php
php
<?php

namespace Webkul\RMA\Providers;

use Illuminate\Support\ServiceProvider;

class RMAServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        //
    }

    public function boot(): void
    {
        //
    }
}

Registering Your Package

注册你的包

Update Composer Autoloader

更新Composer自动加载

In root
composer.json
:
json
{
    "autoload": {
        "psr-4": {
            "Webkul\\RMA\\": "packages/Webkul/RMA/src"
        }
    }
}
Then run:
bash
composer dump-autoload
在根目录的
composer.json
中:
json
{
    "autoload": {
        "psr-4": {
            "Webkul\\RMA\\": "packages/Webkul/RMA/src"
        }
    }
}
然后运行:
bash
composer dump-autoload

Register Service Provider

注册服务提供者

In
bootstrap/providers.php
:
php
<?php

return [
    App\Providers\AppServiceProvider::class,
    
    // ... other providers ...
    
    Webkul\RMA\Providers\RMAServiceProvider::class,
];
bootstrap/providers.php
中:
php
<?php

return [
    App\Providers\AppServiceProvider::class,
    
    // ... 其他服务提供者 ...
    
    Webkul\RMA\Providers\RMAServiceProvider::class,
];

Clear Cache

清除缓存

bash
php artisan optimize:clear
bash
php artisan optimize:clear

Service Provider Methods

服务提供者方法

Loading Migrations

加载迁移

php
public function boot(): void
{
    $this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
}
php
public function boot(): void
{
    $this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
}

Loading Routes

加载路由

php
public function boot(): void
{
    $this->loadRoutesFrom(__DIR__ . '/../Routes/admin-routes.php');
    $this->loadRoutesFrom(__DIR__ . '/../Routes/shop-routes.php');
}
php
public function boot(): void
{
    $this->loadRoutesFrom(__DIR__ . '/../Routes/admin-routes.php');
    $this->loadRoutesFrom(__DIR__ . '/../Routes/shop-routes.php');
}

Loading Views

加载视图

php
public function boot(): void
{
    $this->loadViewsFrom(__DIR__ . '/../Resources/views', 'rma');
}
php
public function boot(): void
{
    $this->loadViewsFrom(__DIR__ . '/../Resources/views', 'rma');
}

Loading Translations

加载翻译

php
public function boot(): void
{
    $this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'rma');
}
php
public function boot(): void
{
    $this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'rma');
}

Merging Config

合并配置

php
public function register(): void
{
    $this->mergeConfigFrom(
        dirname(__DIR__) . '/Config/admin-menu.php',
        'menu.admin'
    );

    $this->mergeConfigFrom(
        dirname(__DIR__) . '/Config/acl.php',
        'acl'
    );

    $this->mergeConfigFrom(
        dirname(__DIR__) . '/Config/system.php',
        'core'
    );
}
php
public function register(): void
{
    $this->mergeConfigFrom(
        dirname(__DIR__) . '/Config/admin-menu.php',
        'menu.admin'
    );

    $this->mergeConfigFrom(
        dirname(__DIR__) . '/Config/acl.php',
        'acl'
    );

    $this->mergeConfigFrom(
        dirname(__DIR__) . '/Config/system.php',
        'core'
    );
}

Concord Model Registration

Concord模型注册

Create ModuleServiceProvider

创建ModuleServiceProvider

File:
packages/Webkul/RMA/src/Providers/ModuleServiceProvider.php
php
<?php

namespace Webkul\RMA\Providers;

use Konekt\Concord\BaseModuleServiceProvider;

class ModuleServiceProvider extends BaseModuleServiceProvider
{
    protected $models = [
        \Webkul\RMA\Models\ReturnRequest::class,
    ];
}
文件路径:
packages/Webkul/RMA/src/Providers/ModuleServiceProvider.php
php
<?php

namespace Webkul\RMA\Providers;

use Konekt\Concord\BaseModuleServiceProvider;

class ModuleServiceProvider extends BaseModuleServiceProvider
{
    protected $models = [
        \Webkul\RMA\Models\ReturnRequest::class,
    ];
}

Register in concord.php

在concord.php中注册

In
config/concord.php
:
php
<?php

return [
    'modules' => [
        // Other service providers...
        \Webkul\RMA\Providers\ModuleServiceProvider::class,
    ],
];

config/concord.php
中:
php
<?php

return [
    'modules' => [
        // 其他服务提供者...
        \Webkul\RMA\Providers\ModuleServiceProvider::class,
    ],
];

@data: Package Development - Data Layer

@data: 包开发 - 数据层

Migrations

迁移

Creating Migrations

创建迁移

bash
undefined
bash
undefined

Using Bagisto generator

使用Bagisto生成器

php artisan package:make-migration CreateRmaRequestsTable Webkul/RMA
php artisan package:make-migration CreateRmaRequestsTable Webkul/RMA

Using Laravel artisan

使用Laravel artisan

php artisan make:migration CreateRmaRequestsTable --path=packages/Webkul/RMA/src/Database/Migrations
undefined
php artisan make:migration CreateRmaRequestsTable --path=packages/Webkul/RMA/src/Database/Migrations
undefined

Basic Migration Structure

基础迁移结构

php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('rma_requests', function (Blueprint $table) {
            $table->id();
            $table->unsignedInteger('customer_id');
            $table->unsignedInteger('order_id');
            $table->string('product_sku');
            $table->string('product_name');
            $table->integer('product_quantity');
            $table->string('status')->default('pending');
            $table->string('reason')->nullable();
            $table->text('admin_notes')->nullable();
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('rma_requests');
    }
};
php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('rma_requests', function (Blueprint $table) {
            $table->id();
            $table->unsignedInteger('customer_id');
            $table->unsignedInteger('order_id');
            $table->string('product_sku');
            $table->string('product_name');
            $table->integer('product_quantity');
            $table->string('status')->default('pending');
            $table->string('reason')->nullable();
            $table->text('admin_notes')->nullable();
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('rma_requests');
    }
};

Running Migrations

运行迁移

bash
undefined
bash
undefined

Run all migrations

运行所有迁移

php artisan migrate
php artisan migrate

Run specific package migrations

运行特定包的迁移

php artisan migrate --path=packages/Webkul/RMA/src/Database/Migrations
php artisan migrate --path=packages/Webkul/RMA/src/Database/Migrations

Check migration status

检查迁移状态

php artisan migrate:status
undefined
php artisan migrate:status
undefined

Models

模型

Bagisto Model Architecture

Bagisto模型架构

Bagisto uses a three-component model system:
  1. Contract - Interface defining the public API
  2. Model - Eloquent model implementation
  3. Proxy - Runtime model resolution via Concord
Bagisto使用三组件模型系统:
  1. 契约(Contract) - 定义公共API的接口
  2. 模型(Model) - Eloquent模型实现
  3. 代理(Proxy) - 通过Concord进行运行时模型解析

Creating Model Components

创建模型组件

bash
undefined
bash
undefined

Using Bagisto generator (creates all three)

使用Bagisto生成器(创建全部三个组件)

php artisan package:make-model ReturnRequest Webkul/RMA
undefined
php artisan package:make-model ReturnRequest Webkul/RMA
undefined

Contract

契约

File:
packages/Webkul/RMA/src/Contracts/ReturnRequest.php
php
<?php

namespace Webkul\RMA\Contracts;

interface ReturnRequest
{
}
文件路径:
packages/Webkul/RMA/src/Contracts/ReturnRequest.php
php
<?php

namespace Webkul\RMA\Contracts;

interface ReturnRequest
{
}

Model Proxy

模型代理

File:
packages/Webkul/RMA/src/Models/ReturnRequestProxy.php
php
<?php

namespace Webkul\RMA\Models;

use Konekt\Concord\Proxies\ModelProxy;

class ReturnRequestProxy extends ModelProxy
{
}
文件路径:
packages/Webkul/RMA/src/Models/ReturnRequestProxy.php
php
<?php

namespace Webkul\RMA\Models;

use Konekt\Concord\Proxies\ModelProxy;

class ReturnRequestProxy extends ModelProxy
{
}

Base Model

基础模型

File:
packages/Webkul/RMA/src/Models/ReturnRequest.php
php
<?php

namespace Webkul\RMA\Models;

use Illuminate\Database\Eloquent\Model;
use Webkul\RMA\Contracts\ReturnRequest as ReturnRequestContract;

class ReturnRequest extends Model implements ReturnRequestContract
{
    protected $table = 'rma_requests';

    protected $fillable = [
        'customer_id',
        'order_id',
        'product_sku',
        'product_name',
        'product_quantity',
        'status',
        'reason',
        'admin_notes',
    ];
}
文件路径:
packages/Webkul/RMA/src/Models/ReturnRequest.php
php
<?php

namespace Webkul\RMA\Models;

use Illuminate\Database\Eloquent\Model;
use Webkul\RMA\Contracts\ReturnRequest as ReturnRequestContract;

class ReturnRequest extends Model implements ReturnRequestContract
{
    protected $table = 'rma_requests';

    protected $fillable = [
        'customer_id',
        'order_id',
        'product_sku',
        'product_name',
        'product_quantity',
        'status',
        'reason',
        'admin_notes',
    ];
}

Model Properties

模型属性

PropertyPurpose
$table
Database table name (use package prefix)
$fillable
Mass-assignable fields
$guarded
Fields that cannot be mass-assigned
$dates
Date columns
$casts
Type casting
$with
Eager loading relationships
属性用途
$table
数据库表名(使用包前缀)
$fillable
可批量赋值字段
$guarded
不可批量赋值字段
$dates
日期列
$casts
类型转换
$with
预加载关联

Repositories

仓库

Repository Pattern

仓库模式

Bagisto uses the Prettus L5 Repository package for data access abstraction.
Bagisto使用Prettus L5 Repository包进行数据访问抽象。

Creating Repositories

创建仓库

bash
php artisan package:make-repository ReturnRequestRepository Webkul/RMA
bash
php artisan package:make-repository ReturnRequestRepository Webkul/RMA

Basic Repository Structure

基础仓库结构

File:
packages/Webkul/RMA/src/Repositories/ReturnRequestRepository.php
php
<?php

namespace Webkul\RMA\Repositories;

use Webkul\Core\Eloquent\Repository;

class ReturnRequestRepository extends Repository
{
    public function model(): string
    {
        return 'Webkul\RMA\Contracts\ReturnRequest';
    }
}
文件路径:
packages/Webkul/RMA/src/Repositories/ReturnRequestRepository.php
php
<?php

namespace Webkul\RMA\Repositories;

use Webkul\Core\Eloquent\Repository;

class ReturnRequestRepository extends Repository
{
    public function model(): string
    {
        return 'Webkul\RMA\Contracts\ReturnRequest';
    }
}

Available Repository Methods

可用仓库方法

Basic CRUD

基础CRUD

php
// Create
$returnRequest = $repository->create([
    'customer_id' => 1,
    'order_id' => 123,
    'product_sku' => 'SAMPLE-001',
    'status' => 'pending',
]);

// Read
$all = $repository->all();
$find = $repository->find($id);
$findOrFail = $repository->findOrFail($id);
$first = $repository->findWhere(['status' => 'pending'])->first();

// Update
$repository->update(['status' => 'approved'], $id);

// Delete
$repository->delete($id);
php
// 创建
$returnRequest = $repository->create([
    'customer_id' => 1,
    'order_id' => 123,
    'product_sku' => 'SAMPLE-001',
    'status' => 'pending',
]);

// 读取
$all = $repository->all();
$find = $repository->find($id);
$findOrFail = $repository->findOrFail($id);
$first = $repository->findWhere(['status' => 'pending'])->first();

// 更新
$repository->update(['status' => 'approved'], $id);

// 删除
$repository->delete($id);

Advanced Queries

高级查询

php
// Where conditions
$results = $repository->findWhere([
    'status' => 'pending',
    'customer_id' => 456,
]);

// Where in
$results = $repository->findWhereIn('id', [1, 2, 3]);

// Where between
$results = $repository->findWhereBetween('created_at', ['2024-01-01', '2024-12-31']);

// Pagination
$paginator = $repository->paginate(15);

// Eager loading
$withRelations = $repository->with(['customer', 'order'])->find($id);
php
// 条件查询
$results = $repository->findWhere([
    'status' => 'pending',
    'customer_id' => 456,
]);

// In查询
$results = $repository->findWhereIn('id', [1, 2, 3]);

// 范围查询
$results = $repository->findWhereBetween('created_at', ['2024-01-01', '2024-12-31']);

// 分页
$paginator = $repository->paginate(15);

// 预加载关联
$withRelations = $repository->with(['customer', 'order'])->find($id);

Custom Repository Methods

自定义仓库方法

php
<?php

namespace Webkul\RMA\Repositories;

use Webkul\Core\Eloquent\Repository;

class ReturnRequestRepository extends Repository
{
    public function model(): string
    {
        return 'Webkul\RMA\Contracts\ReturnRequest';
    }

    public function getPendingForCustomer(int $customerId)
    {
        return $this->findWhere([
            'customer_id' => $customerId,
            'status' => 'pending'
        ]);
    }

    public function getStats(): array
    {
        return [
            'total' => $this->count(),
            'pending' => $this->findWhere(['status' => 'pending'])->count(),
            'approved' => $this->findWhere(['status' => 'approved'])->count(),
        ];
    }

    public function getRecent(int $limit = 10)
    {
        return $this->orderBy('created_at', 'desc')
            ->limit($limit)
            ->get();
    }
}

php
<?php

namespace Webkul\RMA\Repositories;

use Webkul\Core\Eloquent\Repository;

class ReturnRequestRepository extends Repository
{
    public function model(): string
    {
        return 'Webkul\RMA\Contracts\ReturnRequest';
    }

    public function getPendingForCustomer(int $customerId)
    {
        return $this->findWhere([
            'customer_id' => $customerId,
            'status' => 'pending'
        ]);
    }

    public function getStats(): array
    {
        return [
            'total' => $this->count(),
            'pending' => $this->findWhere(['status' => 'pending'])->count(),
            'approved' => $this->findWhere(['status' => 'approved'])->count(),
        ];
    }

    public function getRecent(int $limit = 10)
    {
        return $this->orderBy('created_at', 'desc')
            ->limit($limit)
            ->get();
    }
}

@ui: Package Development - UI Layer

@ui: 包开发 - UI层

Routes

路由

Admin Routes

后台路由

File:
packages/Webkul/RMA/src/Routes/admin-routes.php
php
<?php

use Illuminate\Support\Facades\Route;
use Webkul\RMA\Http\Controllers\Admin\ReturnRequestController;

Route::group([
    'middleware' => ['web', 'admin'],
    'prefix' => config('app.admin_url')
], function () {
    Route::prefix('rma/return-requests')->group(function () {
        Route::get('', [ReturnRequestController::class, 'index'])
            ->name('admin.rma.return-requests.index');

        Route::get('{id}', [ReturnRequestController::class, 'show'])
            ->name('admin.rma.return-requests.show');

        Route::post('', [ReturnRequestController::class, 'store'])
            ->name('admin.rma.return-requests.store');

        Route::put('{id}', [ReturnRequestController::class, 'update'])
            ->name('admin.rma.return-requests.update');

        Route::delete('{id}', [ReturnRequestController::class, 'destroy'])
            ->name('admin.rma.return-requests.destroy');

        Route::post('mass-delete', [ReturnRequestController::class, 'massDestroy'])
            ->name('admin.rma.return-requests.mass-delete');
    });
});
文件路径:
packages/Webkul/RMA/src/Routes/admin-routes.php
php
<?php

use Illuminate\Support\Facades\Route;
use Webkul\RMA\Http\Controllers\Admin\ReturnRequestController;

Route::group([
    'middleware' => ['web', 'admin'],
    'prefix' => config('app.admin_url')
], function () {
    Route::prefix('rma/return-requests')->group(function () {
        Route::get('', [ReturnRequestController::class, 'index'])
            ->name('admin.rma.return-requests.index');

        Route::get('{id}', [ReturnRequestController::class, 'show'])
            ->name('admin.rma.return-requests.show');

        Route::post('', [ReturnRequestController::class, 'store'])
            ->name('admin.rma.return-requests.store');

        Route::put('{id}', [ReturnRequestController::class, 'update'])
            ->name('admin.rma.return-requests.update');

        Route::delete('{id}', [ReturnRequestController::class, 'destroy'])
            ->name('admin.rma.return-requests.destroy');

        Route::post('mass-delete', [ReturnRequestController::class, 'massDestroy'])
            ->name('admin.rma.return-requests.mass-delete');
    });
});

Shop Routes

前台路由

File:
packages/Webkul/RMA/src/Routes/shop-routes.php
php
<?php

use Illuminate\Support\Facades\Route;
use Webkul\RMA\Http\Controllers\Shop\ReturnRequestController;

Route::group([
    'middleware' => ['web', 'locale', 'theme', 'currency']
], function () {
    Route::prefix('rma/return-requests')->group(function () {
        Route::get('', [ReturnRequestController::class, 'index'])
            ->name('shop.rma.return-requests.index');

        Route::post('', [ReturnRequestController::class, 'store'])
            ->name('shop.rma.return-requests.store');
    });
});
文件路径:
packages/Webkul/RMA/src/Routes/shop-routes.php
php
<?php

use Illuminate\Support\Facades\Route;
use Webkul\RMA\Http\Controllers\Shop\ReturnRequestController;

Route::group([
    'middleware' => ['web', 'locale', 'theme', 'currency']
], function () {
    Route::prefix('rma/return-requests')->group(function () {
        Route::get('', [ReturnRequestController::class, 'index'])
            ->name('shop.rma.return-requests.index');

        Route::post('', [ReturnRequestController::class, 'store'])
            ->name('shop.rma.return-requests.store');
    });
});

Route Middleware

路由中间件

MiddlewarePurpose
web
Session handling, CSRF protection
admin
Admin authentication
locale
Language handling
theme
Theme resolution
currency
Currency handling
中间件用途
web
会话处理、CSRF保护
admin
后台身份验证
locale
语言处理
theme
主题解析
currency
货币处理

Controllers

控制器

Base Controller

基础控制器

File:
packages/Webkul/RMA/src/Http/Controllers/Controller.php
php
<?php

namespace Webkul\RMA\Http\Controllers;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;

class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
文件路径:
packages/Webkul/RMA/src/Http/Controllers/Controller.php
php
<?php

namespace Webkul\RMA\Http\Controllers;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;

class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}

Admin Controller

后台控制器

File:
packages/Webkul/RMA/src/Http/Controllers/Admin/ReturnRequestController.php
php
<?php

namespace Webkul\RMA\Http\Controllers\Admin;

use Webkul\RMA\Http\Controllers\Controller;
use Webkul\RMA\Repositories\ReturnRequestRepository;
use Webkul\RMA\DataGrids\Admin\ReturnRequestDataGrid;

class ReturnRequestController extends Controller
{
    public function __construct(
        protected ReturnRequestRepository $returnRequestRepository
    ) {}

    public function index()
    {
        if (request()->ajax()) {
            return datagrid(ReturnRequestDataGrid::class)->process();
        }

        return view('rma::admin.return-requests.index');
    }

    public function show(int $id)
    {
        $returnRequest = $this->returnRequestRepository->findOrFail($id);

        return view('rma::admin.return-requests.show', compact('returnRequest'));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'customer_id' => 'required|integer',
            'order_id' => 'required|integer',
            'product_sku' => 'required|string',
            'product_name' => 'required|string',
            'product_quantity' => 'required|integer|min:1',
            'reason' => 'nullable|string',
        ]);

        $this->returnRequestRepository->create($data);

        return redirect()->route('admin.rma.return-requests.index')
            ->with('success', 'Return request created successfully.');
    }

    public function update(Request $request, int $id)
    {
        $data = $request->validate([
            'status' => 'required|string|in:pending,approved,rejected',
            'admin_notes' => 'nullable|string',
        ]);

        $this->returnRequestRepository->update($data, $id);

        return redirect()->back()->with('success', 'Return request updated.');
    }

    public function destroy(int $id)
    {
        $this->returnRequestRepository->delete($id);

        return redirect()->back()->with('success', 'Return request deleted.');
    }

    public function massDestroy()
    {
        $indices = request()->input('indices');

        foreach ($indices as $index) {
            $this->returnRequestRepository->delete($index);
        }

        return response()->json(['message' => 'Selected records deleted.']);
    }
}
文件路径:
packages/Webkul/RMA/src/Http/Controllers/Admin/ReturnRequestController.php
php
<?php

namespace Webkul\RMA\Http\Controllers\Admin;

use Webkul\RMA\Http\Controllers\Controller;
use Webkul\RMA\Repositories\ReturnRequestRepository;
use Webkul\RMA\DataGrids\Admin\ReturnRequestDataGrid;

class ReturnRequestController extends Controller
{
    public function __construct(
        protected ReturnRequestRepository $returnRequestRepository
    ) {}

    public function index()
    {
        if (request()->ajax()) {
            return datagrid(ReturnRequestDataGrid::class)->process();
        }

        return view('rma::admin.return-requests.index');
    }

    public function show(int $id)
    {
        $returnRequest = $this->returnRequestRepository->findOrFail($id);

        return view('rma::admin.return-requests.show', compact('returnRequest'));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'customer_id' => 'required|integer',
            'order_id' => 'required|integer',
            'product_sku' => 'required|string',
            'product_name' => 'required|string',
            'product_quantity' => 'required|integer|min:1',
            'reason' => 'nullable|string',
        ]);

        $this->returnRequestRepository->create($data);

        return redirect()->route('admin.rma.return-requests.index')
            ->with('success', '退货申请创建成功。');
    }

    public function update(Request $request, int $id)
    {
        $data = $request->validate([
            'status' => 'required|string|in:pending,approved,rejected',
            'admin_notes' => 'nullable|string',
        ]);

        $this->returnRequestRepository->update($data, $id);

        return redirect()->back()->with('success', '退货申请已更新。');
    }

    public function destroy(int $id)
    {
        $this->returnRequestRepository->delete($id);

        return redirect()->back()->with('success', '退货申请已删除。');
    }

    public function massDestroy()
    {
        $indices = request()->input('indices');

        foreach ($indices as $index) {
            $this->returnRequestRepository->delete($index);
        }

        return response()->json(['message' => '选中记录已删除。']);
    }
}

Shop Controller

前台控制器

File:
packages/Webkul/RMA/src/Http/Controllers/Shop/ReturnRequestController.php
php
<?php

namespace Webkul\RMA\Http\Controllers\Shop;

use Webkul\RMA\Http\Controllers\Controller;
use Webkul\RMA\Repositories\ReturnRequestRepository;

class ReturnRequestController extends Controller
{
    public function __construct(
        protected ReturnRequestRepository $returnRequestRepository
    ) {}

    public function index()
    {
        $returnRequests = $this->returnRequestRepository->findWhere([
            'customer_id' => auth()->id()
        ]);

        return view('rma::shop.return-requests.index', compact('returnRequests'));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'order_id' => 'required|integer',
            'product_sku' => 'required|string',
            'product_name' => 'required|string',
            'product_quantity' => 'required|integer|min:1',
            'reason' => 'required|string',
        ]);

        $data['customer_id'] = auth()->id();
        $data['status'] = 'pending';

        $this->returnRequestRepository->create($data);

        return redirect()->back()->with('success', 'Return request submitted.');
    }
}
文件路径:
packages/Webkul/RMA/src/Http/Controllers/Shop/ReturnRequestController.php
php
<?php

namespace Webkul\RMA\Http\Controllers\Shop;

use Webkul\RMA\Http\Controllers\Controller;
use Webkul\RMA\Repositories\ReturnRequestRepository;

class ReturnRequestController extends Controller
{
    public function __construct(
        protected ReturnRequestRepository $returnRequestRepository
    ) {}

    public function index()
    {
        $returnRequests = $this->returnRequestRepository->findWhere([
            'customer_id' => auth()->id()
        ]);

        return view('rma::shop.return-requests.index', compact('returnRequests'));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'order_id' => 'required|integer',
            'product_sku' => 'required|string',
            'product_name' => 'required|string',
            'product_quantity' => 'required|integer|min:1',
            'reason' => 'required|string',
        ]);

        $data['customer_id'] = auth()->id();
        $data['status'] = 'pending';

        $this->returnRequestRepository->create($data);

        return redirect()->back()->with('success', '退货申请已提交。');
    }
}

Views

视图

Admin Layout

后台布局

blade
<x-admin::layouts>
    <x-slot:title>
        @lang('rma::app.admin.return-requests.title')
    </x-slot:title>

    <!-- Content here -->
</x-admin::layouts>
blade
<x-admin::layouts>
    <x-slot:title>
        @lang('rma::app.admin.return-requests.title')
    </x-slot:title>

    <!-- 内容区域 -->
</x-admin::layouts>

Shop Layout

前台布局

blade
<x-shop::layouts>
    <x-slot:title>
        @lang('rma::app.shop.return-requests.title')
    </x-slot:title>

    <!-- Content here -->
</x-shop::layouts>
blade
<x-shop::layouts>
    <x-slot:title>
        @lang('rma::app.shop.return-requests.title')
    </x-slot:title>

    <!-- 内容区域 -->
</x-shop::layouts>

Admin Index View

后台列表视图

File:
packages/Webkul/RMA/src/Resources/views/admin/return-requests/index.blade.php
blade
<x-admin::layouts>
    <x-slot:title>
        @lang('rma::app.admin.return-requests.title')
    </x-slot:title>

    <div class="flex gap-4 justify-between items-center max-sm:flex-wrap">
        <p class="text-xl text-gray-800 dark:text-white font-bold">
            @lang('rma::app.admin.return-requests.title')
        </p>
    </div>

    <x-admin::datagrid :src="route('admin.rma.return-requests.index')" />
</x-admin::layouts>
文件路径:
packages/Webkul/RMA/src/Resources/views/admin/return-requests/index.blade.php
blade
<x-admin::layouts>
    <x-slot:title>
        @lang('rma::app.admin.return-requests.title')
    </x-slot:title>

    <div class="flex gap-4 justify-between items-center max-sm:flex-wrap">
        <p class="text-xl text-gray-800 dark:text-white font-bold">
            @lang('rma::app.admin.return-requests.title')
        </p>
    </div>

    <x-admin::datagrid :src="route('admin.rma.return-requests.index')" />
</x-admin::layouts>

Admin Detail View

后台详情视图

File:
packages/Webkul/RMA/src/Resources/views/admin/return-requests/show.blade.php
blade
<x-admin::layouts>
    <x-slot:title>
        @lang('rma::app.admin.return-requests.show.title')
    </x-slot:title>

    <div class="flex gap-4 justify-between items-center max-sm:flex-wrap">
        <p class="text-xl text-gray-800 dark:text-white font-bold">
            @lang('rma::app.admin.return-requests.show.title') #{{ $returnRequest->id }}
        </p>
    </div>

    <div class="flex gap-2.5 mt-3.5 max-xl:flex-wrap">
        <div class="flex flex-col gap-2 flex-1 max-xl:flex-auto">
            <div class="p-4 bg-white dark:bg-gray-900 rounded box-shadow">
                <p class="text-base text-gray-800 dark:text-white font-semibold mb-4">
                    @lang('rma::app.admin.return-requests.show.general-info')
                </p>

                <div class="grid grid-cols-2 gap-4">
                    <div>
                        <p class="text-gray-600 dark:text-gray-300 font-semibold">
                            @lang('rma::app.admin.return-requests.show.product-name'):
                        </p>
                        <p class="text-gray-800 dark:text-white">
                            {{ $returnRequest->product_name }}
                        </p>
                    </div>

                    <div>
                        <p class="text-gray-600 dark:text-gray-300 font-semibold">
                            @lang('rma::app.admin.return-requests.show.status'):
                        </p>
                        <span class="badge label-info">
                            {{ ucfirst($returnRequest->status) }}
                        </span>
                    </div>
                </div>
            </div>
        </div>
    </div>
</x-admin::layouts>

文件路径:
packages/Webkul/RMA/src/Resources/views/admin/return-requests/show.blade.php
blade
<x-admin::layouts>
    <x-slot:title>
        @lang('rma::app.admin.return-requests.show.title')
    </x-slot:title>

    <div class="flex gap-4 justify-between items-center max-sm:flex-wrap">
        <p class="text-xl text-gray-800 dark:text-white font-bold">
            @lang('rma::app.admin.return-requests.show.title') #{{ $returnRequest->id }}
        </p>
    </div>

    <div class="flex gap-2.5 mt-3.5 max-xl:flex-wrap">
        <div class="flex flex-col gap-2 flex-1 max-xl:flex-auto">
            <div class="p-4 bg-white dark:bg-gray-900 rounded box-shadow">
                <p class="text-base text-gray-800 dark:text-white font-semibold mb-4">
                    @lang('rma::app.admin.return-requests.show.general-info')
                </p>

                <div class="grid grid-cols-2 gap-4">
                    <div>
                        <p class="text-gray-600 dark:text-gray-300 font-semibold">
                            @lang('rma::app.admin.return-requests.show.product-name'):
                        </p>
                        <p class="text-gray-800 dark:text-white">
                            {{ $returnRequest->product_name }}
                        </p>
                    </div>

                    <div>
                        <p class="text-gray-600 dark:text-gray-300 font-semibold">
                            @lang('rma::app.admin.return-requests.show.status'):
                        </p>
                        <span class="badge label-info">
                            {{ ucfirst($returnRequest->status) }}
                        </span>
                    </div>
                </div>
            </div>
        </div>
    </div>
</x-admin::layouts>

@features: Package Development - Features

@features: 包开发 - 功能特性

Localization

本地化

Creating Translation Files

创建翻译文件

File:
packages/Webkul/RMA/src/Resources/lang/en/app.php
php
<?php

return [
    'admin' => [
        'return-requests' => [
            'title' => 'RMA Listing',
            'datagrid' => [
                'id' => 'ID',
                'product-name' => 'Product Name',
                'status' => 'Status',
                'view' => 'View',
            ],
        ],
    ],
];
文件路径:
packages/Webkul/RMA/src/Resources/lang/en/app.php
php
<?php

return [
    'admin' => [
        'return-requests' => [
            'title' => 'RMA Listing',
            'datagrid' => [
                'id' => 'ID',
                'product-name' => 'Product Name',
                'status' => 'Status',
                'view' => 'View',
            ],
        ],
    ],
];

Loading Translations

加载翻译

In service provider
boot()
method:
php
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'rma');
在服务提供者的
boot()
方法中:
php
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'rma');

Using Translations

使用翻译

blade
<!-- In Blade templates -->
@lang('rma::app.admin.return-requests.title')
php
// In controllers/code
trans('rma::app.admin.return-requests.title')
__('rma::app.admin.return-requests.title')
blade
<!-- 在Blade模板中 -->
@lang('rma::app.admin.return-requests.title')
php
// 在控制器/代码中
trans('rma::app.admin.return-requests.title')
__('rma::app.admin.return-requests.title')

Publishing Translations (Optional)

发布翻译(可选)

php
public function boot(): void
{
    $this->publishes([
        __DIR__ . '/../Resources/lang' => resource_path('lang/vendor/rma'),
    ], 'rma-translations');
}
Users can then run:
bash
php artisan vendor:publish --tag=rma-translations
php
public function boot(): void
{
    $this->publishes([
        __DIR__ . '/../Resources/lang' => resource_path('lang/vendor/rma'),
    ], 'rma-translations');
}
用户可运行以下命令发布:
bash
php artisan vendor:publish --tag=rma-translations

DataGrid

DataGrid

Creating DataGrid

创建DataGrid

File:
packages/Webkul/RMA/src/DataGrids/Admin/ReturnRequestDataGrid.php
php
<?php

namespace Webkul\RMA\DataGrids\Admin;

use Illuminate\Support\Facades\DB;
use Webkul\DataGrid\DataGrid;

class ReturnRequestDataGrid extends DataGrid
{
    public function prepareQueryBuilder()
    {
        $queryBuilder = DB::table('rma_requests')
            ->select('id', 'product_name', 'status', 'created_at');

        return $queryBuilder;
    }

    public function prepareColumns()
    {
        $this->addColumn([
            'index' => 'id',
            'label' => trans('rma::app.admin.return-requests.datagrid.id'),
            'type' => 'integer',
            'sortable' => true,
            'filterable' => false,
        ]);

        $this->addColumn([
            'index' => 'product_name',
            'label' => trans('rma::app.admin.return-requests.datagrid.product-name'),
            'type' => 'string',
            'sortable' => true,
            'filterable' => true,
        ]);

        $this->addColumn([
            'index' => 'status',
            'label' => trans('rma::app.admin.return-requests.datagrid.status'),
            'type' => 'string',
            'sortable' => true,
            'filterable' => true,
            'filterable_type' => 'dropdown',
            'filterable_options' => [
                ['label' => 'Pending', 'value' => 'pending'],
                ['label' => 'Approved', 'value' => 'approved'],
                ['label' => 'Rejected', 'value' => 'rejected'],
            ],
            'closure' => function ($row) {
                return "<span class='badge label-info'>" . ucfirst($row->status) . "</span>";
            },
        ]);
    }

    public function prepareActions()
    {
        $this->addAction([
            'icon' => 'icon-view',
            'title' => trans('rma::app.admin.return-requests.datagrid.view'),
            'method' => 'GET',
            'url' => function ($row) {
                return route('admin.rma.return-requests.show', $row->id);
            },
        ]);
    }

    public function prepareMassActions()
    {
        $this->addMassAction([
            'icon' => 'icon-delete',
            'title' => trans('rma::app.admin.return-requests.datagrid.mass-delete'),
            'method' => 'POST',
            'url' => route('admin.rma.return-requests.mass-delete'),
        ]);
    }
}
文件路径:
packages/Webkul/RMA/src/DataGrids/Admin/ReturnRequestDataGrid.php
php
<?php

namespace Webkul\RMA\DataGrids\Admin;

use Illuminate\Support\Facades\DB;
use Webkul\DataGrid\DataGrid;

class ReturnRequestDataGrid extends DataGrid
{
    public function prepareQueryBuilder()
    {
        $queryBuilder = DB::table('rma_requests')
            ->select('id', 'product_name', 'status', 'created_at');

        return $queryBuilder;
    }

    public function prepareColumns()
    {
        $this->addColumn([
            'index' => 'id',
            'label' => trans('rma::app.admin.return-requests.datagrid.id'),
            'type' => 'integer',
            'sortable' => true,
            'filterable' => false,
        ]);

        $this->addColumn([
            'index' => 'product_name',
            'label' => trans('rma::app.admin.return-requests.datagrid.product-name'),
            'type' => 'string',
            'sortable' => true,
            'filterable' => true,
        ]);

        $this->addColumn([
            'index' => 'status',
            'label' => trans('rma::app.admin.return-requests.datagrid.status'),
            'type' => 'string',
            'sortable' => true,
            'filterable' => true,
            'filterable_type' => 'dropdown',
            'filterable_options' => [
                ['label' => 'Pending', 'value' => 'pending'],
                ['label' => 'Approved', 'value' => 'approved'],
                ['label' => 'Rejected', 'value' => 'rejected'],
            ],
            'closure' => function ($row) {
                return "<span class='badge label-info'>" . ucfirst($row->status) . "</span>";
            },
        ]);
    }

    public function prepareActions()
    {
        $this->addAction([
            'icon' => 'icon-view',
            'title' => trans('rma::app.admin.return-requests.datagrid.view'),
            'method' => 'GET',
            'url' => function ($row) {
                return route('admin.rma.return-requests.show', $row->id);
            },
        ]);
    }

    public function prepareMassActions()
    {
        $this->addMassAction([
            'icon' => 'icon-delete',
            'title' => trans('rma::app.admin.return-requests.datagrid.mass-delete'),
            'method' => 'POST',
            'url' => route('admin.rma.return-requests.mass-delete'),
        ]);
    }
}

Column Options

列选项

OptionPurpose
index
Database column name
label
Column header text
type
Data type (string, integer, date, etc.)
sortable
Enable sorting
filterable
Enable filtering
filterable_type
Filter type (dropdown, date_range)
closure
Custom formatting function
选项用途
index
数据库列名
label
列标题文本
type
数据类型(字符串、整数、日期等)
sortable
启用排序
filterable
启用筛选
filterable_type
筛选类型(下拉框、日期范围)
closure
自定义格式化函数

Using DataGrid in Controller

在控制器中使用DataGrid

php
public function index()
{
    if (request()->ajax()) {
        return datagrid(ReturnRequestDataGrid::class)->process();
    }

    return view('rma::admin.return-requests.index');
}
php
public function index()
{
    if (request()->ajax()) {
        return datagrid(ReturnRequestDataGrid::class)->process();
    }

    return view('rma::admin.return-requests.index');
}

Displaying DataGrid in View

在视图中显示DataGrid

blade
<x-admin::datagrid :src="route('admin.rma.return-requests.index')" />
blade
<x-admin::datagrid :src="route('admin.rma.return-requests.index')" />

Admin Menu

后台菜单

Creating Menu Configuration

创建菜单配置

File:
packages/Webkul/RMA/src/Config/admin-menu.php
php
<?php

return [
    [
        'key' => 'rma',
        'name' => 'rma::app.admin.menu.rma',
        'route' => 'admin.rma.return-requests.index',
        'sort' => 100,
        'icon' => 'icon-rma',
    ],
    [
        'key' => 'rma.return-requests',
        'name' => 'rma::app.admin.menu.return-requests',
        'route' => 'admin.rma.return-requests.index',
        'sort' => 1,
    ],
];
文件路径:
packages/Webkul/RMA/src/Config/admin-menu.php
php
<?php

return [
    [
        'key' => 'rma',
        'name' => 'rma::app.admin.menu.rma',
        'route' => 'admin.rma.return-requests.index',
        'sort' => 100,
        'icon' => 'icon-rma',
    ],
    [
        'key' => 'rma.return-requests',
        'name' => 'rma::app.admin.menu.return-requests',
        'route' => 'admin.rma.return-requests.index',
        'sort' => 1,
    ],
];

Registering Menu

注册菜单

In service provider
register()
method:
php
$this->mergeConfigFrom(
    dirname(__DIR__) . '/Config/admin-menu.php',
    'menu.admin'
);
在服务提供者的
register()
方法中:
php
$this->mergeConfigFrom(
    dirname(__DIR__) . '/Config/admin-menu.php',
    'menu.admin'
);

Access Control List (ACL)

访问控制列表(ACL)

Creating ACL Configuration

创建ACL配置

File:
packages/Webkul/RMA/src/Config/acl.php
php
<?php

return [
    [
        'key' => 'rma',
        'name' => 'rma::app.admin.acl.rma',
        'route' => 'admin.rma.return-requests.index',
        'sort' => 1,
    ],
    [
        'key' => 'rma.return-requests',
        'name' => 'rma::app.admin.acl.return-requests',
        'route' => 'admin.rma.return-requests.index',
        'sort' => 1,
    ],
    [
        'key' => 'rma.return-requests.view',
        'name' => 'rma::app.admin.acl.view',
        'route' => 'admin.rma.return-requests.show',
        'sort' => 1,
    ],
];
文件路径:
packages/Webkul/RMA/src/Config/acl.php
php
<?php

return [
    [
        'key' => 'rma',
        'name' => 'rma::app.admin.acl.rma',
        'route' => 'admin.rma.return-requests.index',
        'sort' => 1,
    ],
    [
        'key' => 'rma.return-requests',
        'name' => 'rma::app.admin.acl.return-requests',
        'route' => 'admin.rma.return-requests.index',
        'sort' => 1,
    ],
    [
        'key' => 'rma.return-requests.view',
        'name' => 'rma::app.admin.acl.view',
        'route' => 'admin.rma.return-requests.show',
        'sort' => 1,
    ],
];

Registering ACL

注册ACL

In service provider
register()
method:
php
$this->mergeConfigFrom(
    dirname(__DIR__) . '/Config/acl.php',
    'acl'
);
在服务提供者的
register()
方法中:
php
$this->mergeConfigFrom(
    dirname(__DIR__) . '/Config/acl.php',
    'acl'
);

Checking Permissions

检查权限

php
// In controller
if (! bouncer()->hasPermission('rma')) {
    abort(401, 'Unauthorized access.');
}
blade
<!-- In Blade -->
@if (bouncer()->hasPermission('rma'))
    <!-- Show content -->
@endif
php
// 在控制器中
if (! bouncer()->hasPermission('rma')) {
    abort(401, '未授权访问。');
}
blade
<!-- 在Blade模板中 -->
@if (bouncer()->hasPermission('rma'))
    <!-- 显示内容 -->
@endif

System Configuration

系统配置

Creating Configuration

创建配置

File:
packages/Webkul/RMA/src/Config/system.php
php
<?php

return [
    [
        'key' => 'rma',
        'name' => 'rma::app.admin.system.rma',
        'info' => 'rma::app.admin.system.rma-info',
        'sort' => 1,
    ],
    [
        'key' => 'rma.settings',
        'name' => 'rma::app.admin.system.general-settings',
        'info' => 'rma::app.admin.system.general-settings-info',
        'icon' => 'settings/settings.svg',
        'sort' => 1,
    ],
    [
        'key' => 'rma.settings.general',
        'name' => 'rma::app.admin.system.rma-configuration',
        'info' => 'rma::app.admin.system.rma-configuration-info',
        'sort' => 1,
        'fields' => [
            [
                'name' => 'enable',
                'title' => 'rma::app.admin.system.enable-rma',
                'type' => 'boolean',
            ],
            [
                'name' => 'allow_partial_returns',
                'title' => 'rma::app.admin.system.allow-partial-returns',
                'type' => 'boolean',
            ],
            [
                'name' => 'max_return_days',
                'title' => 'rma::app.admin.system.max-return-days',
                'type' => 'number',
                'validation' => 'numeric|min:1',
            ],
            [
                'name' => 'default_status',
                'title' => 'rma::app.admin.system.default-status',
                'type' => 'select',
                'options' => [
                    ['title' => 'Pending', 'value' => 'pending'],
                    ['title' => 'Approved', 'value' => 'approved'],
                ],
            ],
        ],
    ],
];
文件路径:
packages/Webkul/RMA/src/Config/system.php
php
<?php

return [
    [
        'key' => 'rma',
        'name' => 'rma::app.admin.system.rma',
        'info' => 'rma::app.admin.system.rma-info',
        'sort' => 1,
    ],
    [
        'key' => 'rma.settings',
        'name' => 'rma::app.admin.system.general-settings',
        'info' => 'rma::app.admin.system.general-settings-info',
        'icon' => 'settings/settings.svg',
        'sort' => 1,
    ],
    [
        'key' => 'rma.settings.general',
        'name' => 'rma::app.admin.system.rma-configuration',
        'info' => 'rma::app.admin.system.rma-configuration-info',
        'sort' => 1,
        'fields' => [
            [
                'name' => 'enable',
                'title' => 'rma::app.admin.system.enable-rma',
                'type' => 'boolean',
            ],
            [
                'name' => 'allow_partial_returns',
                'title' => 'rma::app.admin.system.allow-partial-returns',
                'type' => 'boolean',
            ],
            [
                'name' => 'max_return_days',
                'title' => 'rma::app.admin.system.max-return-days',
                'type' => 'number',
                'validation' => 'numeric|min:1',
            ],
            [
                'name' => 'default_status',
                'title' => 'rma::app.admin.system.default-status',
                'type' => 'select',
                'options' => [
                    ['title' => 'Pending', 'value' => 'pending'],
                    ['title' => 'Approved', 'value' => 'approved'],
                ],
            ],
        ],
    ],
];

Registering Configuration

注册配置

In service provider
register()
method:
php
$this->mergeConfigFrom(
    dirname(__DIR__) . '/Config/system.php',
    'core'
);
在服务提供者的
register()
方法中:
php
$this->mergeConfigFrom(
    dirname(__DIR__) . '/Config/system.php',
    'core'
);

Field Types

字段类型

TypePurpose
text
Text input
password
Password input
number
Numeric input
boolean
Enable/disable switch
select
Dropdown select
multiselect
Multi-select dropdown
textarea
Text area
editor
Rich text editor (TinyMCE)
image
Image upload
file
File upload
country
Country dropdown
state
State dropdown (depends on country)
color
Color picker
类型用途
text
文本输入框
password
密码输入框
number
数字输入框
boolean
启用/禁用开关
select
下拉选择框
multiselect
多选下拉框
textarea
文本域
editor
富文本编辑器(TinyMCE)
image
图片上传
file
文件上传
country
国家下拉框
state
州/省下拉框(依赖国家)
color
颜色选择器

Dependent Fields

依赖字段

php
[
    'name' => 'enable_policy',
    'title' => 'Enable Return Policy',
    'type' => 'boolean',
], [
    'name' => 'max_return_days',
    'title' => 'Maximum Return Days',
    'type' => 'number',
    'depends' => 'enable_policy:1',  // Show only when enable_policy is 1
],
php
[
    'name' => 'enable_policy',
    'title' => '启用退货政策',
    'type' => 'boolean',
], [
    'name' => 'max_return_days',
    'title' => '最大退货天数',
    'type' => 'number',
    'depends' => 'enable_policy:1',  // 仅当enable_policy为1时显示
],

Using Configuration Values

使用配置值

php
// In controller
$isEnabled = core()->getConfigData('rma.settings.general.enable');
$maxDays = core()->getConfigData('rma.settings.general.max_return_days');
blade
<!-- In Blade -->
@if (core()->getConfigData('rma.settings.general.enable'))
    <!-- Show RMA content -->
@endif

php
// 在控制器中
$isEnabled = core()->getConfigData('rma.settings.general.enable');
$maxDays = core()->getConfigData('rma.settings.general.max_return_days');
blade
<!-- 在Blade模板中 -->
@if (core()->getConfigData('rma.settings.general.enable'))
    <!-- 显示RMA内容 -->
@endif

Key Files Reference

关键文件参考

FilePurpose
src/Providers/ServiceProvider.php
Main service provider
src/Providers/ModuleServiceProvider.php
Concord model registration
src/manifest.php
Package metadata
src/Database/Migrations/
Migration files
src/Contracts/
Model contract interfaces
src/Models/
Eloquent models
src/Models/*Proxy.php
Concord model proxies
src/Repositories/
Repository classes
src/Routes/admin-routes.php
Admin routes
src/Routes/shop-routes.php
Shop routes
src/Http/Controllers/
Controllers
src/Resources/views/
Blade templates
src/Resources/lang/
Translation files
src/DataGrids/Admin/
DataGrid classes
src/Config/admin-menu.php
Menu configuration
src/Config/acl.php
ACL permissions
src/Config/system.php
System configuration
文件用途
src/Providers/ServiceProvider.php
主服务提供者
src/Providers/ModuleServiceProvider.php
Concord模型注册
src/manifest.php
包元数据
src/Database/Migrations/
迁移文件
src/Contracts/
模型契约接口
src/Models/
Eloquent模型
src/Models/*Proxy.php
Concord模型代理
src/Repositories/
仓库类
src/Routes/admin-routes.php
后台路由
src/Routes/shop-routes.php
前台路由
src/Http/Controllers/
控制器
src/Resources/views/
Blade模板
src/Resources/lang/
翻译文件
src/DataGrids/Admin/
DataGrid类
src/Config/admin-menu.php
菜单配置
src/Config/acl.php
ACL权限
src/Config/system.php
系统配置

Common Pitfalls

常见陷阱

  • Forgetting to run
    composer dump-autoload
    after adding package
  • Not registering service provider in
    bootstrap/providers.php
  • Not clearing cache after changes
  • Incorrect namespace in PSR-4 autoloading
  • Not using package prefix for table names
  • Not registering models in ModuleServiceProvider
  • Not merging config in service provider
  • Using hardcoded text instead of translation keys
  • Not checking permissions in controllers/views
  • 添加包后忘记运行
    composer dump-autoload
  • 未在
    bootstrap/providers.php
    中注册服务提供者
  • 修改后未清除缓存
  • PSR-4自动加载中的命名空间错误
  • 表名未使用包前缀
  • 未在ModuleServiceProvider中注册模型
  • 未在服务提供者中合并配置
  • 使用硬编码文本而非翻译键
  • 未在控制器/视图中检查权限