Laravel启动器

starter-framework — Laravel 启动器模板

作者 milkmeowo

面向 Laravel 与 Lumen 的 RESTful API 启动器,集成 Dingo API、l5-repository、Laravel Passport 等组件,并提供生成实体代码的 Artisan 命令。

看看你的网站会是什么样

浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。

1 个预览视图
作者提供的预览
作者提供的预览

来自项目 README 的原始预览。

目前有 1 张原始预览,可打开完整图片查看设计细节。

截图用于了解视觉与布局,交互效果请以实际项目为准。

采集于 2026-10-03查看来源

值得关注的模板亮点

从已有项目资料中,快速了解它的特点。

01

同时支持 Laravel 与 Lumen 的 RESTful API 启动器

02

集成 Dingo API,并提供 Passport 与改进 OAuth2 认证 Provider

03

基于 l5-repository 的 Repository 设计模式与 BaseEloquent 实现

04

starter:entity 命令可批量生成 Controller、Model、Repository、迁移等文件

05

模型内置 created_by、updated_by、created_ip 等记录追踪字段

06

集成 ide-helper、clockwork 与 CORS 支持

模板详细介绍

starter-framework 是一个以 Composer 包形式发布的 Laravel / Lumen 启动器,定位是快速搭建面向 Web 与移动端的 RESTful API 后端层。它通过统一的接口组织方式,把认证、响应转换、数据仓储等常见 API 关注点集中到一套可复用的结构里。

在认证方面,项目使用 Laravel Passport 保护受保护资源,并在 Dingo API 的 auth 配置中提供 Passport 与改进后的 OAuth2 认证 Provider。数据访问层采用 Repository 设计模式,基于 l5-repository,并扩展了 BaseEloquent,支持观察者事件、缓存与软删除。

项目提供 starter:entity 命令,可按实体名一次性生成 Controller、Model、Presenter、Transformer、Repository 接口与 Eloquent 实现、Criteria、Validator、迁移、Seeder,并把 RESTful 路由注入到带有 //:end-routes: 占位符的 routes/api.php。生成的 Controller 默认包含 index、store、show、update、destroy 以及 trashedIndex、trashedShow、restore 等动作。

模型层内置记录追踪事件,可自动写入 created_by、updated_by、created_ip、updated_ip、deleted_by、deleted_ip 等字段,并支持软删除与恢复。项目同时集成了 ide-helper、clockwork 与 CORS 支持,以上能力均声明同时适用于 Laravel 和 Lumen。

使用限制方面,项目需要手动注册 ServiceProvider、发布配置文件,并把 config/auth.php 中 api guard 的 driver 改为 passport;Lumen 还需要在 bootstrap/app.php 中启用 Facades 与 Eloquent。仓库资料未说明具体框架版本要求,也未提供除 README 之外的完整使用文档。

Laravel启动器

适合你的项目吗?

适用场景

  • 为 Web 与移动端提供统一 RESTful API 后端层
  • 在 Laravel 或 Lumen 项目中快速搭建带 Passport 认证的 API 骨架
  • 按实体批量生成 Controller、Model、Repository、迁移与 Seeder
  • 需要软删除、回收站列表与恢复接口的 API 项目
  • 需要自动记录创建人、更新人及 IP 等审计字段的后台接口

适合人群

  • 使用 Laravel 或 Lumen 构建 RESTful API 的开发者
  • 希望采用 Repository 模式组织数据访问层的团队
  • 需要 Passport 认证与 Dingo API 路由能力的项目
  • 希望通过 Artisan 命令减少重复 CRUD 代码的开发者

上手与定制指南

结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。

  1. 1

    通过 composer require milkmeowo/starter-framework 安装

  2. 2

    在 Laravel 的 providers 数组或 Lumen 的 bootstrap/app.php 中注册对应 ServiceProvider

  3. 3

    发布或手动复制 vendor/milkmeowo/starter-framework/config 下的配置文件

  4. 4

    将 config/auth.php 中 api guard 的 driver 改为 passport

  5. 5

    执行 php artisan migrate 与 php artisan passport:install 完成 Passport 初始化

查看仓库使用说明

授权与来源资料

使用条件与限制

免费使用 · 保留许可声明

本次收录的是公开仓库中采用 MIT 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。

使用时需要遵守

  • 允许免费使用、修改、商用和分发该版本代码。
  • 分发代码副本或实质性部分时,保留原作者版权声明和完整 MIT 许可声明。
  • 代码按现状提供;担保与责任限制以原许可证及适用法律为准。

额外费用与待核对事项

  • 项目依赖 Laravel Passport 进行受保护资源的认证,使用前需执行 php artisan migrate 与 php artisan passport:install 初始化 Passport 加密密钥与相关数据表。
  • 必须手动将 config/auth.php 中 api guard 的 driver 改为 passport,否则 API 认证无法按预期工作。
  • 在 Lumen 中使用时需修改 bootstrap/app.php,启用 Facades 与 Eloquent 并注册 LumenServiceProvider。
  • 需手动复制 vendor/milkmeowo/starter-framework/config 下的配置文件到项目 config 目录,或使用 php artisan vendor:publish 发布。
  • ide-helper 的 ServiceProvider 仅在 APP_ENV 不等于 production 时注册,生产环境不应启用。
  • Clockwork 的 ServiceProvider 仅在 APP_DEBUG 为 true 且 APP_ENV 不等于 production 时注册,生产环境不应启用。
  • 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 MIT 许可判断。
  • 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
查看原文依据

Permission is hereby granted, free of charge

许可证原文

It utilized Laravel Passport to authenticate protected resources.

README 原文

and change `config/auth.php` api guards driver to passport

README 原文

Modify the bootstrap flow (bootstrap/app.php file)

README 原文

then copy config files into your project.you can finish this manually

README 原文

Register service provider when `APP_ENV != production`

README 原文

Register service provider when `APP_DUBUG = true` and `APP_ENV != production`

README 原文
https://github.com/milkmeowo/starter-framework/blob/master/LICENSEhttps://github.com/milkmeowo/starter-framework/blob/master/README.md

DeepSeek 根据仓库许可证和 README 整理 ·2026-10-03。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。

项目核对记录与介绍依据

模板资料

来源平台
GitHub
资料与维护参考分
资料一般 · 56 / 100
技术栈
Laravel
网站类型
启动器
这个分数如何计算

本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。

这个项目需要核对什么

记录的仓库更新时间
2022-09-03
截图检查日期
2026-10-03

目前没有记录演示链接。请依据仓库说明在本地评估;仅凭截图无法确认交互行为。

目录记录的主要技术栈是 Laravel。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。

查看具体选型方法 →

介绍的制作与核对状态

介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。

审核声明: [email protected] · 2026-10-04

查看当时使用的来源资料

SHA-256: d828eda5b8303183e43cd7de23fdb68764bd83f29a640144e1da1ee99c66fe1d

2026-10-03T19:28:54.484Z

来源文件 / 仓库
# starter-framework

[![Latest Stable Version](https://poser.pugx.org/milkmeowo/starter-framework/v/stable)](https://packagist.org/packages/milkmeowo/starter-framework)
[![Latest Unstable Version](https://poser.pugx.org/milkmeowo/starter-framework/v/unstable)](https://packagist.org/packages/milkmeowo/starter-framework)
[![Total Downloads](https://poser.pugx.org/milkmeowo/starter-framework/downloads)](https://packagist.org/packages/milkmeowo/starter-framework)
[![StyleCI](https://styleci.io/repos/78735158/shield?branch=master)](https://styleci.io/repos/78735158)
[![Code Climate](https://codeclimate.com/github/milkmeowo/starter-framework/badges/gpa.svg)](https://codeclimate.com/github/milkmeowo/starter-framework)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/milkmeowo/starter-framework/badges/quality-score.png?b=develop)](https://scrutinizer-ci.com/g/milkmeowo/starter-framework/?branch=develop)
[![Build Status](https://scrutinizer-ci.com/g/milkmeowo/starter-framework/badges/build.png?b=develop)](https://scrutinizer-ci.com/g/milkmeowo/starter-framework/build-status/develop)
[![Analytics](https://ga-beacon.appspot.com/UA-93763118-1/milkmeowo/starter-framework/readme)](https://packagist.org/packages/milkmeowo/starter-framework)
[![License](https://poser.pugx.org/milkmeowo/starter-framework/license)](https://packagist.org/packages/milkmeowo/starter-framework)

# Overview
This package is suitable for Restful API oriented projects

The Restful APIs as a backend layer which provide simple unified interfaces for frontend: Web and Mobile apps.

It utilized Laravel Passport to authenticate protected resources.

It is fully utilised Repository Design pattern.

# Features

* Dingo Api Support
* l5-Repository Support
* Laravel Passport Support
* ide-helper Support
* clockwork support
* Cors support
* All of the above are supported for laravel & lumen

# Getting started

## Installation via Composer

```
composer require milkmeowo/starter-framework
```

## Register the ServiceProvider

Register the starter-framework service provider by adding it to the providers array.

**Laravel**

```
'providers' => array(
    ...
    Milkmeowo\Framework\Base\Providers\LaravelServiceProvider::class,
)
```

**Lumen**

Modify the bootstrap flow (bootstrap/app.php file)


```
// Enable Facades
$app->withFacades();

// Enable Eloquent
$app->withEloquent();

$providers = [
    ...
    Milkmeowo\Framework\Base\Providers\LumenServiceProvider::class,
];

array_walk($providers, function ($provider) use ($app) {
    $app->register($provider);
});
```

## Publish the configure

then copy config files into your project.you can finish this manually

```
cp -R vendor/milkmeowo/starter-framework/config ./config
```

or for **Laravel** you can use
```
php artisan vendor:publish
```
and change `config/auth.php` api guards driver to passport

```
 'guards' => [
        ...
        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],
```

## Migrate and install Laravel Passport
```
# Create new tables for Passport
php artisan migrate

# Install encryption keys and other necessary stuff for Passport
php artisan passport:install
```

# Packages Documents

## Dingo
![](https://cloud.githubusercontent.com/assets/829059/9216039/82be51cc-40f6-11e5-88f5-f0cbd07bcc39.png)

**improve**

> Exception Handle Register

add `src/Framework/Dingo/Providers/ExceptionHandlerServiceProvider` to register the common Exception handle

* Illuminate\Auth\Access\AuthorizationException
* Illuminate\Auth\AuthenticationException
* Illuminate\Database\Eloquent\ModelNotFoundException
* Illuminate\Http\Exception\HttpResponseException
* League\OAuth2\Server\Exception\OAuthServerException
* Prettus\Validator\Exceptions\ValidatorException

> ResponseWasMorphed Event Listener

fire `src/Framework/Dingo/Listeners/AddPaginationLinksToResponse`

> Auth Providers

add `Passport` and `improved Oauth2` Auth Providers

you can use with config 
```
// file config/api.php

...
    'auth' => [
        Milkmeowo\Framework\Dingo\Auth\Providers\OAuth2::class,
        Milkmeowo\Framework\Dingo\Auth\Providers\Passport::class,
    ],
...
```

**reference:** 

[Dingo Api](https://github.com/dingo/api)

[Dingo Api Wiki documentation](https://github.com/dingo/api/wiki)

[dingo-api-wiki-zh](https://github.com/liyu001989/dingo-api-wiki-zh).

## l5-Repository
<img src="http://oomusou.io/images/laravel/laravel-architecture/arch002.svg" width="700">

**improve**

> artisan command

```
// example for generate Post Entity Repository
php artisan starter:entity Post
```
auto generate below files

```
modified:   routes/api.php
modified:   app/Providers/RepositoryServiceProvider.php

     add:   app/Api/Controllers/V1/PostsController.php
     add:   app/Models/Post.php
     add:   app/Presenters/PostPresenter.php
     add:   app/Repositories/Criteria/PostCriteria.php
     add:   app/Repositories/Eloquent/PostRepositoryEloquent.php
     add:   app/Repositories/Interfaces/PostRepository.php
     add:   app/Transformers/PostTransformer.php
     add:   app/Validators/PostValidator.php
     add:   database/migrations/2017_01_12_091412_create_posts_table.php
     add:   database/seeds/PostSeeder.php
```

* **Controller**(`index` `store` `show` `update` `destory` `trashedIndex` `trashedShow` `restore`)
* **Models**(BaseModel with ObserveEvent auto track record modify with `create(update/delete)_at(by/ip)`)
* **Presenter**
* **Transformer**(`league/fractal`)
* **Repositories/Criteria**
* **Repositories/Eloquent**(BaseEloquent with ObserverEvents,Cacheable,SoftDeletes Support)
* **Repositories/Interfaces**
* **Validator**(prettus/laravel-validator support)
* **migrations**(new blueprint methods **recordStamps**[`create(update)_at(by/ip)`] **softDeletesRecordStamps**[`delete_at(by/ip)`])
* **Seeder**
* **append Route**(file `routes/api.php(web.php)` with placeholder `//:end-routes:` can auto-inject Restful api)
* **bind Repository Interface and Eloquent**


> Routes Endpoint

files `routes/api.php` with placeholder `//:end-routes:`
```
<?php

$api = app('Dingo\Api\Routing\Router');

// v1 version API
// choose version add this in header    Accept:application/vnd.lumen.v1+json
$api->version('v1', [
    'namespace' => 'App\Api\Controllers\V1',
], function ($api) {
    
    /*
    |------------------------------------------------
    | User Routes
    |------------------------------------------------
    */

    // trashed listing
    $api->get('/users/trashed', ['as' => 'users.trashed.index', 'uses' => 'UsersController@trashedIndex']);

    // show trashed special resource
    $api->get('/users/trashed/{id}', ['as' => 'users.trashed.show', 'uses' => 'UsersController@trashedShow']);

    // restore
    $api->put('/users/{id}/restore', ['as' => 'users.restore', 'uses' => 'UsersController@restore']);

    // listing
    $api->get('/users', ['as' => 'users.index', 'uses' => 'UsersController@index']);

    // create
    $api->post('/users', ['as' => 'users.store', 'uses' => 'UsersController@store']);

    // show
    $api->get('/users/{id}', ['as' => 'users.show', 'uses' => 'UsersController@show']);

    // update
    $api->put('/users/{id}', ['as' => 'users.update', 'uses' => 'UsersController@update']);

    // delete
    $api->delete('/users/{id}', ['as' => 'users.destroy', 'uses' => 'UsersController@destroy']);

    //:end-routes:
});
```


Verb      | URI                  | Action       | Route Name
----------|-----------------------|--------------|---------------------
GET       | `/users`              | index        | users.index
GET       | `/users/trashed`      | trashedIndex | users.trashed.index
POST      | `/users`              | store        | users.store
GET       | `/users/{id}`         | show         | users.show
GET       | `/users/trashed/{id}` | trashedShow  | users.trashed.show
PUT       | `/users/{id}`         | update       | users.update
PUT       | `/users/{id}/restore` | restore      | users.restore
DELETE    | `/users/{id}`         | destroy      | users.destroy

> ObserveEvent

`Models` and `Repositories/Eloquent` has listen below methods events with $priority = 99

* onCreating()
* onCreated()
* onUpdating()
* onUpdated()
* onSaving()
* onSaved()
* onDeleting()
* onDeleted()
* onRestoring()
* onRestored()

**Models** also has default record track event listen 

fields                |    default            |    description 
:--------------------:|:---------------------:|:-----------------:
  $autoRelatedUserId  |  protect / true       | Indicates if the model should be auto set user_id.
  $userstamps         |  protect / true       | Indicates if the model should be recorded users.
  $ipstamps           |  protect / true       | Indicates if the model should be recorded ips.
  RELATED_USER_ID     |  const / 'user_id'    | The name of the "related user id" column.
  CREATED_BY          |  const / 'created_by' | The name of the "created by" column.
  UPDATED_BY          |  const / 'updated_by' | The name of the "updated by" column.
  CREATED_IP          |  const / 'created_ip' | The name of the "created ip" column.
  UPDATED_IP          |  const / 'updated_ip' | The name of the "updated ip" column.
  DELETED_IP          |  const / 'deleted_ip' | The name of the "deleted ip" column.
  DELETED_BY          |  const / 'deleted_by' | The name of the "deleted by" column.

* onCreating()

```
    // auto set related user id
    if ($this->autoRelatedUserId && empty($this->{static::RELATED_USER_ID}) && $this->hasTableColumn(static::RELATED_USER_ID)) {
        $user_id = $this->getAuthUserId();
        if ($user_id > 0) {
            $this->{static::RELATED_USER_ID} = $user_id;
        }
    }
```

* onSaving()

```
    // update ipstamps if true
    if ($this->ipstamps) {
        $this->updateIps();
    
    // update userstamps if true
    if ($this->userstamps) {
        $this->updateUsers();
    }
    
    protected function updateIps()
    {
        $ip = smart_get_client_ip();

        if (! $this->isDirty(static::UPDATED_IP) && $this->hasTableColumn(static::UPDATED_IP)) {
            $this->{static::UPDATED_IP} = $ip;
        }

        if (! $this->exists && ! $this->isDirty(static::CREATED_IP) && $this->hasTableColumn(static::CREATED_IP)) {
            $this->{static::CREATED_IP} = $ip;
        }
    }
    
    protected function updateUsers()
    {
        $user_id = $this->getAuthUserId();
        if (! ($user_id > 0)) {
            return;
        }

        if (! $this->isDirty(static::UPDATED_BY) && $this->hasTableColumn(static::UPDATED_BY)) {
            $this->{static::UPDATED_BY} = $user_id;
        }

        if (! $this->exists && ! $this->isDirty(static::CREATED_BY) && $this->hasTableColumn(static::CREATED_BY)) {
            $this->{static::CREATED_BY} = $user_id;
        }
    }
```

* onDeleting()
```
    if (static::usingSoftDeletes()) {
        if ($this->hasTableColumn(static::DELETED_BY)) {
            $this->{static::DELETED_BY} = $this->getAuthUserId();
        }

        if ($this->hasTableColumn(static::DELETED_IP)) {
            $this->{static::DELETED_IP} = smart_get_client_ip();
        }

        $this->flushEventListeners();
        $this->save();
    }
```

* onRestoring()
```
    if ($this->hasTableColumn(static::DELETED_BY)) {
        $this->{static::DELETED_BY} = null;
    }
    if ($this->hasTableColumn(static::DELETED_IP)) {
        $this->{static::DELETED_IP} = null;
    }
```

> Repositories/Eloquent

* [Cacheable](https://github.com/andersao/l5-repository#cache)

* SoftDeletes Support
  * withTrashed
  * withoutTrashed
  * onlyTrashed
  * restore
  * restoreWhere
  * ForceDelete
  * forceDeleteWhere


**reference:** 

[l5-repository](https://github.com/prettus/l5-repository)

[l5-repository Usage](https://github.com/andersao/l5-repository#usage)

[prettus/laravel-validator](https://github.com/prettus/laravel-validator)

[league/fractal](http://fractal.thephpleague.com/)

[Laravel 的中大型專案架構](http://oomusou.io/laravel/laravel-architecture/).

## Illuminate Database

**improve**

* support fulltext index
* add a set of blueprint methods
  * add ipStamps(`create_ip` `update_ip`)
  * add userStamps(`create_by` `update_by`)
  * add recordStamps(`timestamps` `ipStamps` `userStamps`)
  * add softDeletesStamps(`delete_ip` `delete_by`)
  * add softDeletesRecordStamps(`softDeletes` `softDeletesStamps`)
  * add dropIpStamps
  * add dropUserStamps
  * add dropRecordStamps
  * add dropSoftDeletesStamps
  * add dropSoftDeletesRecordStamps
  
```
<?php

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

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            
            $table->recordStamps();
            
            $table->softDeletesRecordStamps();
            
            $table->text('content')->fulltext()
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('users');
    }
}

``` 

## laravel passport
<p align="center"><img src="https://laravel.com/assets/img/components/logo-passport.svg"></p>

**Laravel**

**reference:** 

[Laravel Passport](https://github.com/laravel/passport)

[Official Documentation](http://laravel.com/docs/master/passport).

**Lumen**

> Installed routes

Adding this service provider, will mount the following routes:

Verb | Path | NamedRoute | Controller | Action | Middleware
--- | --- | --- | --- | --- | ---
POST   | /oauth/token                             |            | \Laravel\Passport\Http\Controllers\AccessTokenController           | issueToken | -
GET    | /oauth/tokens                            |            | \Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController | forUser    | auth
DELETE | /oauth/tokens/{token_id}                 |            | \Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController | destroy    | auth
POST   | /oauth/token/refresh                     |            | \Laravel\Passport\Http\Controllers\TransientTokenController        | refresh    | auth
GET    | /oauth/clients                           |            | \Laravel\Passport\Http\Controllers\ClientController                | forUser    | auth
POST   | /oauth/clients                           |            | \Laravel\Passport\Http\Controllers\ClientController                | store      | auth
PUT    | /oauth/clients/{client_id}               |            | \Laravel\Passport\Http\Controllers\ClientController                | update     | auth
DELETE | /oauth/clients/{client_id}               |            | \Laravel\Passport\Http\Controllers\ClientController                | destroy    | auth
GET    | /oauth/scopes                            |            | \Laravel\Passport\Http\Controllers\ScopeController                 | all        | auth
GET    | /oauth/personal-access-tokens            |            | \Laravel\Passport\Http\Controllers\PersonalAccessTokenController   | forUser    | auth
POST   | /oauth/personal-access-tokens            |            | \Laravel\Passport\Http\Controllers\PersonalAccessTokenController   | store      | auth
DELETE | /oauth/personal-access-tokens/{token_id} |            | \Laravel\Passport\Http\Controllers\PersonalAccessTokenController   | destroy    | auth

Please note that some of the Laravel Passport's routes had to 'go away' because they are web-related and rely on sessions (eg. authorise pages). Lumen is an
API framework so only API-related routes are present.

**reference:** 

[Lumen Passport](https://github.com/dusterio/lumen-passport)

## Ide-helper
> Register service provider when `APP_ENV != production`

**Automatic phpDoc generation for Laravel Facades**


```
php artisan ide-helper:generate
```

**Automatic phpDocs for models**

```
php artisan ide-helper:models
```

**PhpStorm Meta for Container instances**

```
php artisan ide-helper:meta
```

**reference:** 

[IDE Helper Generator](https://github.com/barryvdh/laravel-ide-helper)

## Clockwork

> Register service provider when `APP_DUBUG = true` and `APP_ENV != production`

**reference:** 

[Clockwork](https://github.com/itsgoingd/clockwork)

## Cors

**Usage**

The ServiceProvider adds a route middleware you can use, called `cors`. You can apply this to a route or group to add CORS support.

```php
Route::group(['middleware' => 'cors'], function(Router $router){
    $router->get('api', 'ApiController@index');
});
```

If you want CORS to apply for all your routes, add it as global middleware in `app/http/Kernel.php`:

```php
protected $middleware = [
    ....
    \Barryvdh\Cors\HandleCors::class
];
```


**reference:** 

[barryvdh/laravel-cors](https://github.com/barryvdh/laravel-cors)

## License

The starter-framework is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).
反馈内容错误

看看同类模板

对比同技术栈与用途的模板,找到更适合的视觉与内容结构。