📏 模块规范与最佳实践

为保证多客怪兽SAAS框架的代码质量和可维护性,所有模块开发必须遵循统一的开发规范。

命名规范

  1. 模块目录名:可以使用自定义前缀加小写字母,如gs_example,也可以不使用前缀直接使用,如:shopask,名称需要为英文,不可以使用中文拼音,例如:shangdianwenda
  2. 类名:使用大驼峰命名法(PascalCase),如PluginListenBaseModel
  3. 方法名:在common.phpGlobal.php中尽可能使用小驼峰命名法(camelCase),如getShopUser()addUser()
  4. 模型文件名:使用大驼峰命名法(PascalCase),文件名采用数据库表名,例如:GsExampleUser
  5. 控制器文件名:使用大驼峰命名法(PascalCase),可不需要添加模块标识,如:admin/UserMoney.phpapp/UserData.php
  6. 配置键:使用小写字母和下划线,如authroutesurl

数据表命名

数据表名应当使用__PREFIX__作为前缀占位符,后接模块名和表名,如:

  • __PREFIX__gs_example_user
  • __PREFIX__gs_example_activity

这样在安装时会自动替换为实际的表前缀。

目录组织

  1. 按照功能职责明确划分目录,保持目录结构清晰
  2. 相关功能文件放在同一目录下,避免散乱
  3. 控制器按照访问端(admin、api、h5)进行分组
  4. 视图文件按照控制器分组,保持结构一致

代码复用

  1. 将通用功能封装为工具类或助手函数
  2. 使用继承和组合实现代码复用
  3. 利用Trait实现多重继承
  4. 抽象公共逻辑到基类中

接口规范

// 正确响应
return $this-success();
// 错误响应
return $this-error();

模型开发规范

1. 模型命名与创建

  • 模型类名必须使用大驼峰命名法(PascalCase)
  • 模型文件名与数据库表名保持一致,例如表名为gs_example_user,则模型文件名为GsExampleUser.php
  • 基础模型命名规则为{模块名}BaseModel,如GoReviewBaseModel
  • 业务模型继承模块的基础模型类,命名规则为{模块名}{业务实体},如GoReviewUser
  • 推荐使用开发者工具自动创建模型类

2. 模型文件结构

<?php
class 模型类名 extends 基类
{
    // 模型代码
}

3. 基础模型规范

  • 创建模块基础模型类,其他模型继承此基类
  • 定义全局查询范围,处理平台ID和应用ID
  • 实现数据处理钩子,保证关键字段自动填充
<?php
namespace addons\gs_example\model;

use think\Model;

class BaseGsExampleModel extends Model
{
    // 自动写入时间戳
    protected $autoWriteTimestamp = true;
    
    // 软删除
    use \think\model\concern\SoftDelete;
    protected $deleteTime = 'delete_time';
    
    // 定义全局的查询范围
    protected $globalScope = ['default'];
    
    // 定义查询范围
    public function scopeDefault($query)
    {
        // 添加平台ID为查询条件
        if (get_plaid()) {
            $query->where(['plaid' => get_plaid()]);
        }
        
        // 添加小程序ID为查询条件
        if (get_appid()) {
            $query->where(['appid' => get_appid()]);
        }
    }
    
    // 数据新增前执行
    public static function onBeforeInsert(Model $model)
    {
        $model->appid = get_appid();
        $model->plaid = get_plaid();
    }
}

4. 业务模型规范

<?php
namespace addons\gs_example\model;

class GsExampleUser extends BaseGsExampleModel
{
}

控制器开发规范

1. 控制器命名规范

  • 基础控制器命名为Base{模块名}Controller,如BaseGoReviewController
  • 业务控制器直接使用业务名称,如UserOrder
  • 不同端的控制器放在相应目录下:admin/app/h5/api/ 可自定义

2. 控制器目录结构

controller/
├── admin/            // 后台管理控制器
│   ├── User.php
│   ├── Order.php
│   └── ...
├── app/              // 前端应用控制器
│   ├── BaseGoReviewController.php
│   ├── User.php
│   └── ...
├── h5/               // 前端页面控制器
│   ├── User.php
│   └── ...
├── api/              // API接口控制器 
│   └── ...
└── Index.php         // 默认控制器

4. 控制器基类

  • 后台基础控制器继承hiduoke\controller\AddonsController
  • 前端基础控制器继承hiduoke\controller\FrontendController
  • 在基类中定义公共方法、中间件和通用属性

5. 后台控制器规范

  • 使用protected $model属性定义关联模型
  • initialize方法中初始化模型实例
  • 参考Fastadmin实现CRUDtrait文件:hiduoke/traits/Backend.php
<?php
namespace addons\gs_example\controller\admin;

use addons\gs_example\model\GsExampleUser;
use hiduoke\services\form\DataTable;
use hiduoke\services\form\DataForm;
use hiduoke\controller\AddonsController;

class User extends AddonsController
{
    /**
     * @var GsExampleUser
     */
    protected $model;
    // 设置关联查询
    protected array $withJoinTable = ['industry'];
    // 设置快捷搜索字段
    protected string|array $quickSearchField = [];
    /**
     * 控制器初始化
     */
    public function initialize(): void
    {
        parent::initialize();
        $this->model = new GsExampleUser();
        // 判断请求控制器方法
        if($this->request->action() == "index" && !$this->request->param("select")){
            // 定义全局的查询范围带有alias
            $this->model->setGlobalScope(['alias']);
        }
    }
}

安全规范

  1. 输入验证:所有用户输入必须经过验证和过滤
  2. SQL注入防护:使用参数化查询或ORM
  3. XSS防护:输出时进行HTML转义
  4. CSRF防护:使用CSRF Token
  5. 敏感数据:密码必须加密存储
  6. 文件上传:严格限制文件类型和大小

性能规范

  1. 数据库优化:合理使用索引,避免大事务
  2. 缓存使用:适当使用缓存减少数据库查询
  3. 延迟加载:只在需要时加载数据
  4. 异步处理:耗时操作使用队列异步处理
  5. 前端优化:减少HTTP请求,压缩资源,使用CDN

遵循以上规范,将有助于保持代码质量,提高团队协作效率,同时降低维护成本。