10soo / tpinit
ThinkPHP 8.x 脚手架工具:代码生成器 + 基类控制器 + 公共服务库
Requires
- php: >=8.1
- guzzlehttp/guzzle: ^7.10
- phpoffice/phpspreadsheet: ^5.3
- qiniu/php-sdk: ^7.14
- topthink/framework: ^8.0
- topthink/think-migration: ^3.0
Requires (Dev)
- mockery/mockery: ^1.6
- phpunit/phpunit: ^10.0
This package is not auto-updated.
Last update: 2025-12-22 09:45:00 UTC
README
下一代 ThinkPHP 脚手架工具:代码生成器 + 基类控制器 + 公共服务库
简介
TpInit 是一个为 ThinkPHP 8.x 设计的全功能脚手架工具包,旨在提升开发效率,减少重复工作。它整合了三大核心功能:
- 📊 Excel 驱动的代码生成器:从 Excel 生成 Model、Migration、SQL、Controller、Service、Validate
- 🎯 现代化基类控制器:内置用户注入、布局模板、统一响应格式
- 🛠️ 实用服务层:图片处理、分页、URL 生成、七牛云、加密等常用服务
核心特性
✅ 代码生成器
- 从 Excel 定义表结构,一键生成全套代码(Model/Controller/Service/Validate/Migration/SQL)
- 支持字段类型、索引、关联关系、验证规则等完整定义
- 交互式命令行向导,无需记忆复杂参数
- 自定义代码保护,重新生成不会覆盖业务代码
- 支持软删除、时间戳、多态关联等高级特性
✅ 基类控制器
- BaseWebController:布局模板、用户自动注入、全局变量
- BaseApiController:统一 JSON 响应、跨域支持、参数验证
- 内置
success()/fail()快速响应方法 - 自动注入
$this->user当前登录用户 - 自动获取
$this->reqId请求参数
✅ 服务层
- ImageService:图片 CDN、尺寸裁剪(支持七牛云)
- PaginationService:统一分页查询
- UrlService:详情页、栏目页 URL 生成
- QiniuService:七牛云上传、Token 生成
- CryptoService:SHA1、密码哈希、加密解密
- UploadService:本地文件上传
- TreeService:树形结构处理(O(n) 高性能算法)
- ExcelService:Excel 导入导出
- HttpService:HTTP 客户端封装
- RedisService:分布式锁、原子缓存
目录结构
src/
├── Command/ # 命令行工具
│ ├── Generate.php # 代码生成命令
│ ├── Install.php # 安装命令
│ └── ExcelDemo.php # Excel 示例生成
├── Config/ # 配置文件
│ └── tpinit.php # 默认配置
├── Controller/ # 基类控制器
│ ├── BaseApiController.php
│ └── BaseWebController.php
├── Generator/ # 代码生成器
│ ├── ModelGenerator.php
│ ├── ControllerGenerator.php
│ ├── ServiceGenerator.php
│ ├── ValidateGenerator.php
│ ├── MigrationGenerator.php
│ └── SqlGenerator.php
├── Helpers/ # 辅助函数
│ └── functions.php # 全局辅助函数
├── Parser/ # Excel 解析器
├── Schema/ # 数据库结构定义
├── Service/ # 公共服务层
│ ├── CryptoService.php # 加密服务
│ ├── ExcelService.php # Excel 处理
│ ├── HttpService.php # HTTP 请求
│ ├── ImageService.php # 图片处理
│ ├── PaginationService.php # 分页服务
│ ├── QiniuService.php # 七牛云服务
│ ├── RedisService.php # Redis 工具
│ ├── TreeService.php # 树形结构(O(n)算法)
│ ├── UploadService.php # 本地上传
│ └── UrlService.php # URL 生成
├── Support/ # 内部支持类
└── Traits/ # 通用 Traits
安装
环境要求
- PHP >= 8.1
- ThinkPHP >= 8.0
- Composer
1. 使用 Composer 安装
composer require 10soo/tpinit
2. 安装配置文件
php think tpinit:install
此命令将:
- 复制配置文件到
config/tpinit.php - 创建必要的目录(
think/、database/migrations/)
快速开始
第一步:生成示例 Excel
php think tpinit:excel-demo
这将在 think/db.xlsx 生成一个包含示例表结构的 Excel 文件。
第二步:编辑 Excel 定义表结构
打开 think/db.xlsx,按照以下格式定义表结构:
| 表名 | 表注释 | 字段名 | 类型 | 主键 | 自增 | 可空 | 默认值 | 注释 | 索引 | 关联 | 验证 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| user | 用户表 | username | varchar(50) | 用户名 | unique | required|max:50 | |||||
| varchar(100) | Y | 邮箱 | index | ||||||||
| password | varchar(255) | 密码 | required | ||||||||
| status | tinyint(1) | 1 | 状态 | ||||||||
| article | 文章表 | title | varchar(200) | 标题 | required | ||||||
| content | text | 内容 | |||||||||
| user_id | bigint | 作者 ID | index | @user |
关联语法说明:
@表名: 一对一关联 (hasOne)@表名@: 一对多关联 (hasMany)&表名: 多态一对一 (morphOne)&表名&: 多态一对多 (morphMany)
第三步:生成代码
# 交互式向导(推荐新手使用)
php think tpinit:generate
# 生成所有类型
php think tpinit:generate
# 仅生成指定类型
php think tpinit:generate --only=model,service,validate
# 仅生成 API 风格的 Controller
php think tpinit:generate --only=controller --preset=api
# Dry Run 模式(预览不写文件)
php think tpinit:generate --dry-run
# 强制覆盖已存在文件
php think tpinit:generate --force
第四步:运行迁移
# 执行数据库迁移
php think migrate:run
详细使用指南
💡 更详细的服务层使用文档请查看 USAGE.md
1. 基类控制器
Web 控制器示例
适用于传统的 MVC 项目,支持模板渲染。
<?php
namespace app\controller;
use TpInit\Controller\BaseWebController;
use app\model\User;
use app\model\Article;
class IndexController extends BaseWebController
{
// 设置布局模板
protected string $layout = '_web';
protected function initialize(): void
{
parent::initialize();
// $this->user 已自动注入当前登录用户(来自 session)
// $this->reqId 已自动从 GET/POST 获取 id 参数
// $this->controller、$this->action、$this->url 已自动设置
}
/**
* 首页
*/
public function index()
{
// 设置全局变量(会自动传递给视图)
$this->globals['title'] = '首页';
$this->globals['users'] = User::where('status', 1)->select();
// 自动套用 layout 模板渲染当前 action 对应的视图
return $this->view();
}
/**
* 文章列表
*/
public function articleList()
{
// 使用内置的辅助函数进行分页
$list = pageList(Article::class, ['status' => 1], 'id desc', 15);
$this->globals['list'] = $list;
return $this->view();
}
/**
* 保存用户
*/
public function save()
{
$data = $this->request->post();
$user = User::create($data);
if ($user) {
// 统一的成功响应
return $this->success('创建成功', [
'id' => $user->id,
'redirect' => '/user/list'
]);
}
// 统一的失败响应
return $this->fail('创建失败');
}
}
API 控制器示例
适用于前后端分离项目,返回 JSON 格式数据。
<?php
namespace app\controller\api;
use TpInit\Controller\BaseApiController;
use app\model\User;
use app\validate\UserValidate;
class UserController extends BaseApiController
{
// 启用跨域支持
protected bool $enableCors = true;
// 允许的跨域域名(* 表示所有域名)
protected array $allowOrigins = ['*'];
/**
* 用户列表(带分页)
*/
public function index()
{
$list = User::where('status', 1)
->order('id', 'desc')
->paginate(15);
// 返回带分页信息的标准格式
// 返回格式: {code:1, msg:'', data:{list:[...], total:100, per_page:15, ...}}
return $this->paginate($list);
}
/**
* 创建用户
*/
public function save()
{
// 方式1: 使用控制器内置验证
$data = $this->validate([
'username' => 'require|max:50',
'email' => 'require|email',
'password' => 'require|min:6',
]);
// 方式2: 使用验证器类
// validate(UserValidate::class);
// $data = $this->request->post();
$user = User::create($data);
// 返回格式: {code:1, msg:'创建成功', data:{id:1, username:'...', ...}}
return $this->success('创建成功', $user);
}
/**
* 更新用户
*/
public function update()
{
// $this->reqId 已自动获取 id 参数
$user = User::find($this->reqId);
if (!$user) {
// 返回格式: {code:0, msg:'用户不存在', data:null}
return $this->fail('用户不存在');
}
$data = $this->validate([
'username' => 'max:50',
'email' => 'email',
]);
$user->save($data);
return $this->success('更新成功', $user);
}
/**
* 删除用户
*/
public function delete()
{
$user = User::find($this->reqId);
if (!$user) {
return $this->fail('用户不存在');
}
$user->delete();
return $this->success('删除成功');
}
}
2. 服务层使用
图片服务 (ImageService)
use TpInit\Service\ImageService;
$imageService = new ImageService();
// 基础用法:获取图片 URL(自动添加 CDN 域名)
$url = $imageService->url('uploads/avatar.jpg');
// 返回: https://cdn.example.com/uploads/avatar.jpg
// 获取指定尺寸的缩略图(七牛云裁剪)
$thumbnail = $imageService->url('uploads/avatar.jpg', '200x200');
// 返回: https://cdn.example.com/uploads/avatar.jpg?imageView2/1/w/200/h/200
// 使用辅助函数(推荐)
$url = image('uploads/avatar.jpg');
$thumbnail = image('uploads/avatar.jpg', '300x300');
分页服务 (PaginationService)
use TpInit\Service\PaginationService;
use app\model\Article;
$paginationService = new PaginationService();
// 通用分页查询
$list = $paginationService->paginate(
Article::class, // Model 类名
['status' => 1], // 查询条件
['id' => 'desc'], // 排序
15 // 每页数量
);
// 使用辅助函数(推荐)
$list = pageList(Article::class, ['status' => 1], 'id desc', 15);
// 在控制器中使用
foreach ($list as $article) {
echo $article->title;
}
URL 服务 (UrlService)
use TpInit\Service\UrlService;
$urlService = new UrlService();
// 详情页 URL
$url = $urlService->show(['id' => 1, 'cate_id' => 5]);
// 返回: /public/details?id=1&cate_id=5
// 栏目 URL(需要 Cate 模型实现 recUrl 方法)
$cateUrl = $urlService->category(5);
// 完整 URL(带域名)
$fullUrl = $urlService->full('api/user/info', ['id' => 1], true);
// 返回: https://example.com/api/user/info?id=1
// 使用辅助函数(推荐)
$url = show(['id' => 1]);
$cateUrl = cateUrl(5);
加密服务 (CryptoService)
use TpInit\Service\CryptoService;
$cryptoService = new CryptoService();
// SHA1 加密
$hash = $cryptoService->sha1('password123');
// SHA1 加盐加密
$hash = $cryptoService->sha1('password123', 'my-salt');
// 密码哈希(推荐用于用户密码)
$hash = $cryptoService->passwordHash('password123');
// 验证密码
$isValid = $cryptoService->passwordVerify('password123', $hash);
// 生成随机字符串
$token = $cryptoService->random(32);
// 使用辅助函数
$hash = sha1Encrypt('password123');
3. 辅助函数
// ========== 图片处理 ==========
$url = image('uploads/avatar.jpg'); // 获取图片 URL
$thumbnail = image('uploads/avatar.jpg', '300x200'); // 获取缩略图
// ========== 分页查询 ==========
$list = pageList(Article::class, ['status' => 1], 'id desc', 15);
// ========== URL 生成 ==========
$detailUrl = show(['id' => 1]); // 详情页 URL
$cateUrl = cateUrl(5); // 栏目 URL
// ========== 工具函数 ==========
if (isWx()) { // 判断微信客户端
echo '在微信中打开';
}
$hash = sha1Encrypt('password'); // SHA1 加密
// ========== 服务获取 ==========
$imageService = tpinit_service('ImageService'); // 获取服务实例
$qiniuService = tpinit_service('QiniuService');
// ========== 配置获取 ==========
$cdnDomain = tpinit_config('image.cdn_domain'); // 获取配置值
$bucket = tpinit_config('qiniu.bucket');
配置说明
编辑 config/tpinit.php 进行配置:
<?php
return [
// Excel 相关配置
'excel' => [
'path' => 'think/db.xlsx', // Excel 文件路径
'sheet_name' => 'Sheet1', // 工作表名称
'start_row' => 2, // 数据起始行
],
// 代码生成配置
'generate' => [
'model_path' => 'app/model', // Model 生成路径
'controller_path' => 'app/controller', // Controller 生成路径
'service_path' => 'app/service', // Service 生成路径
'validate_path' => 'app/validate', // Validate 生成路径
'migration_path' => 'database/migrations', // Migration 生成路径
'sql_path' => 'database', // SQL 生成路径
'force_overwrite' => false, // 是否强制覆盖
'backup_old_files' => true, // 是否备份旧文件
],
// 控制器配置
'controller' => [
'layout' => '_web', // 默认布局模板
'session_user_key' => 'user', // Session 中用户信息的键名
'auto_assign_user' => true, // 是否自动注入用户
'response_format' => [
'success_code' => 1, // 成功响应码
'fail_code' => 0, // 失败响应码
],
],
// 图片服务配置
'image' => [
'driver' => 'qiniu', // 驱动: local | qiniu
'cdn_domain' => 'https://cdn.example.com', // CDN 域名
],
// URL 服务配置
'url' => [
'detail_route' => 'public/details', // 详情页路由
'category_model' => '\\app\\model\\Cate', // 栏目模型
],
// 七牛云配置
'qiniu' => [
'access_key' => '', // AccessKey
'secret_key' => '', // SecretKey
'bucket' => '', // 存储空间名称
'domain' => '', // CDN 域名
],
// 上传配置
'upload' => [
'disk' => 'public', // 存储磁盘
'max_size' => 10 * 1024 * 1024, // 最大文件大小(字节)
'ext' => 'jpg,png,gif,pdf,doc,docx', // 允许的扩展名
],
];
命令行工具
tpinit:install
安装配置文件和必要目录
php think tpinit:install
tpinit:excel-demo
生成示例 Excel 文件
php think tpinit:excel-demo
# 指定生成路径
php think tpinit:excel-demo --path=database/demo.xlsx
tpinit:generate
从 Excel 生成代码
# 交互式模式(推荐)
php think tpinit:generate
# 生成所有类型
php think tpinit:generate
# 指定 Excel 文件
php think tpinit:generate --excel=database/tables.xlsx
# 仅生成指定类型
php think tpinit:generate --only=model,service,validate
# 仅生成 Controller(指定预设)
php think tpinit:generate --only=controller --preset=api
# Dry Run 模式(预览不写文件)
php think tpinit:generate --dry-run
# 强制覆盖已存在文件
php think tpinit:generate --force
可用选项:
| 选项 | 说明 | 示例 |
|---|---|---|
--excel | Excel 文件路径 | --excel=database/tables.xlsx |
--only | 仅生成指定类型(逗号分隔) | --only=model,service |
--preset | Controller 预设模板 (default|api|web) | --preset=api |
--dry-run | Dry Run 模式(只预览不写文件) | --dry-run |
--force | 强制覆盖已存在文件 | --force |
可生成的类型:
model- Model 模型migration- 数据库迁移sql- SQL 文件controller- 控制器service- 服务层validate- 验证器
高级用法
自定义代码保护
生成的 Model、Controller、Service 包含自定义代码保护区:
<?php
namespace app\model;
use think\Model;
class User extends Model
{
// ... 自动生成的代码 ...
// ---------- Custom code below ----------
// 这里的代码重新生成时不会被覆盖
public function getStatusTextAttr(): string
{
return $this->status ? '正常' : '禁用';
}
public function articles()
{
return $this->hasMany(Article::class);
}
}
重新生成时,// ---------- Custom code below ---------- 下方的代码会被保留。
扩展自定义生成器
创建自己的代码生成器:
<?php
namespace app\generator;
use TpInit\Generator\AbstractGenerator;
use TpInit\Schema\Table;
class MyGenerator extends AbstractGenerator
{
protected function generateCode(Table $table): string
{
// 生成自定义代码
$className = $this->formatClassName($table->name);
return <<<PHP
<?php
namespace app\\custom;
class {$className}
{
// 自定义生成的代码
}
PHP;
}
protected function getOutputPath(Table $table): string
{
return "app/custom/{$this->formatClassName($table->name)}.php";
}
}
常见问题
Q: 生成的代码中文乱码?
A: 确保 Excel 文件使用 UTF-8 编码保存。可以使用 Excel 另存为 CSV 时选择 UTF-8 编码。
Q: 重新生成会覆盖我的代码吗?
A: 不会。自定义代码保护区(// ---------- Custom code below ---------- 下方)的代码不会被覆盖。如果担心,可以先使用 --dry-run 预览。
Q: 如何使用多态关联?
A: 在 Excel 关联列中使用 &表名& 语法。多态关联的表必须包含 xxx_type 和 xxx_id 字段,例如:
commentable_type varchar(50)
commentable_id bigint
Q: 支持 ThinkPHP 6 吗?
A: 主要针对 ThinkPHP 8.x 设计,ThinkPHP 6 未充分测试但理论上兼容。建议升级到 ThinkPHP 8。
Q: 如何自定义响应格式?
A: 编辑 config/tpinit.php 的 controller.response_format 配置:
'response_format' => [
'success_code' => 200,
'fail_code' => 400,
],
Q: tpinit:install 命令做了什么?
A: 该命令会:
- 复制
src/Config/tpinit.php到config/tpinit.php - 创建
think/目录(存放 Excel 文件) - 创建
database/migrations/目录(存放迁移文件)
Q: 如何配置七牛云?
A: 在 config/tpinit.php 中配置:
'qiniu' => [
'access_key' => 'your-access-key',
'secret_key' => 'your-secret-key',
'bucket' => 'your-bucket',
'domain' => 'https://cdn.example.com',
],
更新日志
查看 CHANGELOG.md 了解版本更新历史。
贡献指南
欢迎贡献代码! 请遵循以下步骤:
- Fork 本仓库
- 创建特性分支:
git checkout -b feature/your-feature - 提交更改:
git commit -m 'Add some feature' - 推送分支:
git push origin feature/your-feature - 提交 Pull Request
开发规范:
- 遵循 PSR-12 编码规范
- 添加必要的注释和文档
- 编写单元测试
- 提交前运行
composer test
开源协议
致谢
- ThinkPHP - 优秀的 PHP 框架
- PhpSpreadsheet - Excel 处理库
- Qiniu - 七牛云对象存储
- 社区贡献者们 ❤️
相关链接
享受编码! 让 TpInit 成为你的开发加速器 🚀