- 18 张公共表更名(addon/attachment/configure/links/spider_log/spider_stat/sms/notice/ad/task/prop/medal/help/card -> common_*,member_wallets->member_wallet,score_rule/score_log -> member_*,addon_config->common_addonconf),模型全部对齐新表名,Db 直引用清零 - Attachment 模型补 表名绑定,修复富文本上传查 wxapp_attachment 1146 隐患 - install.sql + 迁移 SQL:backend_admin/backend_role delete_at 默认 0,修复软删除(NULL != 0)误过滤导致后台菜单为空 - AppService::boot() 支持插件 info.php 声明 commands 自动注册插件命令(psr-4 自动加载,坏类名自动跳过) - 各插件(haonav/mqttbroker/wxchat/articles/blog/forum 等)字段与配置同步调整 - 框架版本 1.1.0 -> 1.1.1
101 lines
2.9 KiB
PHP
101 lines
2.9 KiB
PHP
<?php
|
||
|
||
declare (strict_types = 1);
|
||
|
||
namespace addon\download\model;
|
||
|
||
use ywxapp\model\BaseModel;
|
||
|
||
class Category extends BaseModel
|
||
{
|
||
protected function getOptions(): array
|
||
{
|
||
return [
|
||
'strict' => false,
|
||
'name' => 'download_category',
|
||
'autoRelation' => [],
|
||
'createTime' => 'create_at',
|
||
'updateTime' => 'update_at',
|
||
'dateFormat' => 'Y-m-d H:i:s',
|
||
];
|
||
}
|
||
|
||
/**
|
||
* 子分类(pid 指向自身)
|
||
*/
|
||
public function children()
|
||
{
|
||
return $this->hasMany(self::class, 'pid', 'id')
|
||
->where('status', 1)
|
||
->order('sort', 'desc');
|
||
}
|
||
|
||
/**
|
||
* 分类下的资源
|
||
*/
|
||
public function resources()
|
||
{
|
||
return $this->hasMany(Resource::class, 'cid', 'id')
|
||
->where('status', 1)
|
||
->where('is_audit', 1);
|
||
}
|
||
|
||
/**
|
||
* 平铺分类列表转带前缀的下拉选项(供新增/编辑表单的上级分类 select 使用)
|
||
* 直接复用父类 BaseModel::cateTree($cate, $name='title', $lefthtml='|— ', $pid=0, $level=0),
|
||
* 返回的 title 自带层级前缀,无需在子类重复声明(会与父类签名冲突 fatal error)。
|
||
*/
|
||
|
||
/**
|
||
* 将平铺分类列表转换为嵌套树(供 layui.treeTable 使用)
|
||
* 返回形如 [['id'=>..,'children'=>[...]], ...]
|
||
*/
|
||
public static function toNestedTree(array $list): array
|
||
{
|
||
$map = [];
|
||
foreach ($list as &$item) {
|
||
$item['children'] = [];
|
||
$map[$item['id']] = &$item;
|
||
}
|
||
unset($item);
|
||
$tree = [];
|
||
foreach ($list as &$item) {
|
||
if (!empty($item['pid']) && isset($map[$item['pid']])) {
|
||
$map[$item['pid']]['children'][] = &$item;
|
||
} else {
|
||
$tree[] = &$item;
|
||
}
|
||
}
|
||
unset($item);
|
||
// 清理空的 children,保持返回结构干净
|
||
return self::cleanEmptyChildren($tree);
|
||
}
|
||
|
||
protected static function cleanEmptyChildren(array $tree): array
|
||
{
|
||
foreach ($tree as &$node) {
|
||
if (!empty($node['children'])) {
|
||
$node['children'] = self::cleanEmptyChildren($node['children']);
|
||
} else {
|
||
unset($node['children']);
|
||
}
|
||
}
|
||
return $tree;
|
||
}
|
||
|
||
/**
|
||
* 删除前保护:存在子分类或资源时禁止删除
|
||
*/
|
||
public static function onBeforeDelete($model)
|
||
{
|
||
$childCount = self::where('pid', $model->id)->count();
|
||
if ($childCount > 0) {
|
||
throw new \think\Exception('该分类下还存在 ' . $childCount . ' 个子分类,请先处理子分类');
|
||
}
|
||
$resCount = \addon\download\model\Resource::where('cid', $model->id)->count();
|
||
if ($resCount > 0) {
|
||
throw new \think\Exception('该分类下还存在 ' . $resCount . ' 个资源,请先移走或删除这些资源');
|
||
}
|
||
}
|
||
}
|