feat: 公共表更名 common/member 前缀 + 插件命令自动加载 + 版本 1.1.1

- 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
This commit is contained in:
ywxapp
2026-08-20 20:19:15 +08:00
parent 303f548664
commit 1d49e6f5ee
395 changed files with 13342 additions and 2012 deletions
-69
View File
@@ -1,69 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | YwxApp [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: ywxapp<admin@ywxapp.cn>
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
class AddonModel extends BaseModel
{
// -- 插件主表
// CREATE TABLE `addon` (
// `id` int unsigned AUTO_INCREMENT PRIMARY KEY,
// `name` varchar(50) NOT NULL COMMENT '标识符',
// `title` varchar(100) NOT NULL COMMENT '名称',
// `version` varchar(20) NOT NULL COMMENT '版本号',
// `price` decimal(10,2) NOT NULL COMMENT '价格',
// `file_path` varchar(255) NOT NULL COMMENT '存储路径(非公开)',
// `file_hash` varchar(64) NOT NULL COMMENT 'SHA256校验值',
// `status` tinyint DEFAULT 1 COMMENT '1上架 0下架'
// );
protected function getOptions(): array
{
return [
'strict' => true,
'name' => 'addon',
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'schema' => [
'id' => 'int',
'name' => 'string',
'title' => 'string',
'version' => 'string',
'price' => 'float',
'description' => 'string',
'author' => 'string',
'status' => 'tinyint',
'config' => 'text',
'file_path' => 'string',
'file_hash' => 'string',
'sort' => 'int',
'create_at' => 'int',
'update_at' => 'int',
]
];
}
// // 获取已安装插件列表
// public function getInstalledaddon(): array
// {
// return $this->where('status', '<>', self::STATUS_DISABLE)->order('create_at', 'desc')->select()->toArray();
// }
// // 检查插件是否已安装
// public function isInstalled(string $name): bool
// {
// return $this->where('name', $name)->count() > 0;
// }
}
-1
View File
@@ -24,7 +24,6 @@ class BackendAdmin extends BaseModel
{
return [
'strict' => false,
'name' => 'backend_admin',
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
+11 -3
View File
@@ -1,4 +1,13 @@
<?php
/*
* @Author: YwxApp <ywx@ywxapp.cn>
* @Date: 2026-08-06 22:05:48
* @LastEditors: YwxApp <ywx@ywxapp.cn>
* @LastEditTime: 2026-08-19 20:51:06
* @Description:
* @FilePath: \ywxapp_dev\ywxapp\model\BackendLog.php
* @CustomString: Copyright (c) 2026 YwxApp
*/
// +----------------------------------------------------------------------
// | YwxApp [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
@@ -15,8 +24,7 @@ use ywxapp\model\BaseModel;
*
* @author ywxapp <admin@ywxapp.cn>
*/
class BackendLog extends BaseModel{
protected $name = 'backend_log';
class BackendLog extends BaseModel{
protected $updateTime = false;
/**
* 获取用户的角色
@@ -31,7 +39,7 @@ class BackendLog extends BaseModel{
public function roles()
{
return $this->belongsToMany(Role::class, 'access', 'rid','aid');
return $this->belongsToMany(BackendRole::class, 'access', 'rid','aid');
}
+1 -2
View File
@@ -23,8 +23,7 @@ class BackendPower extends BaseModel
protected function getOptions(): array
{
return [
'strict' => false,
'name' => 'backend_power',
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
+16 -17
View File
@@ -11,6 +11,7 @@ namespace ywxapp\model;
use think\model\concern\SoftDelete;
use ywxapp\model\BaseModel;
/**
* BackendRole 类
*
@@ -19,24 +20,22 @@ use ywxapp\model\BaseModel;
class BackendRole extends BaseModel
{
use SoftDelete;
// 设置表名(think-orm 4.0:name 不带前缀,自动拼 wxapp_)
protected $name = 'backend_role';
// 设置主键
protected $pk = 'id';
// 自动时间戳
protected $autoWriteTimestamp = 'int';
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
protected $deleteTime = 'delete_at';
// 隐藏字段
protected $hidden = ['password', 'delete_at'];
// 只读字段
protected $readonly = ['id'];
protected function getOptions(): array
{
return [
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'deleteTime' => 'delete_at',
'defaultSoftDelete' => 0,
'append' => ['target'],
'hidden' => ['password', 'delete_at'],
'readonly' => ['id'],
];
}
// 角色拥有的用户
public function admins()
{
return $this->belongsToMany(BackendAdmin::class, BackendRoleAccess::class, 'admin_id', 'role_id');
@@ -52,7 +51,7 @@ class BackendRole extends BaseModel
}
// 【推荐】角色 → 菜单模型(通过中间表 role_permissions 关联 menus)
public function menus()
{
return $this->belongsToMany(BackendPower::class, BackendRolePower::class, 'power_id', 'role_id', 'permission');
+17 -16
View File
@@ -4,34 +4,35 @@
* @Date: 2026-08-06 22:05:48
* @LastEditors: YwxApp <ywx@ywxapp.cn>
* @LastEditTime: 2026-08-10 09:44:50
* @Description:
* @Description: ywxapp/model/BackendPower.php
* @FilePath: \ywxapp_dev\ywxapp\model\BackendRoleAccess.php
* @CustomString: Copyright (c) 2026 YwxApp
*/
// +----------------------------------------------------------------------
// | YwxApp [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: ywxapp<admin@ywxapp.cn>
// +----------------------------------------------------------------------
namespace ywxapp\model;
use think\model\Pivot;
use ywxapp\model\BaseModel;
/**
* BackendRoleAccess 类
*
* @author ywxapp <admin@ywxapp.cn>
*/
class BackendRoleAccess extends Pivot{
protected $name = 'backend_role_access';
// 自动时间戳 (create_at 已统一为 int 时间戳)
protected $autoWriteTimestamp = 'int';
protected $createTime = 'create_at';
protected $updateTime = false;
class BackendRoleAccess extends Pivot
{
protected function getOptions(): array
{
return [
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'defaultSoftDelete' => 0,
'append' => ['target'],
'hidden' => ['create_at'],
];
}
/**
* 表结构自愈:建表 + 关键列兜底(install.sql 为事实源)。
@@ -41,4 +42,4 @@ class BackendRoleAccess extends Pivot{
{
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'backend_role_access');
}
}
}
+13 -8
View File
@@ -17,14 +17,19 @@ use think\model\Pivot;
* @author ywxapp <admin@ywxapp.cn>
*/
class BackendRolePower extends Pivot
{
// 设置表名
protected $name = 'backend_role_power';
protected $pk = ['role_id', 'power_id'];
// 自动时间戳
protected $autoWriteTimestamp = 'int';
protected $createTime = 'create_at';
protected $updateTime = false;
{
protected function getOptions(): array
{
return [
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => false,
'defaultSoftDelete' => 0,
'append' => ['target'],
'hidden' => ['create_at', 'update_at', 'delete_at'],
];
}
/**
+1 -1
View File
@@ -23,7 +23,7 @@ use think\Model;
*/
class BaseModel extends Model
{
protected $autoWriteTimestamp = 'int';
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
-48
View File
@@ -1,48 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | YwxApp [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: ywxapp<admin@ywxapp.cn>
// +----------------------------------------------------------------------
namespace ywxapp\model;
/**
* 聊天
*/
class Chat extends BaseModel
{
// 设置表名(think-orm 4.0:name 不带前缀,自动拼 wxapp_)
protected $name = 'chat';
protected $schema = [
'id' => 'int',
'from_uid' => 'int',
'to_uid' => 'int',
'type' => 'int',
'content' => 'string',
'create_at' => 'int',
'update_at' => 'int',
];
}
// CREATE TABLE `chat_users` (
// `id` int(11) NOT NULL AUTO_INCREMENT,
// `username` varchar(50) NOT NULL,
// `password` varchar(255) NOT NULL,
// `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
// PRIMARY KEY (`id`)
// );
// CREATE TABLE `chat_messages` (
// `id` int(11) NOT NULL AUTO_INCREMENT,
// `from_user_id` int(11) NOT NULL,
// `to_user_id` int(11) NOT NULL,
// `message` text NOT NULL,
// `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
// PRIMARY KEY (`id`)
// );
-18
View File
@@ -1,18 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | YwxApp [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: ywxapp<admin@ywxapp.cn>
// +----------------------------------------------------------------------
namespace ywxapp\model;
/**
* 聊天消息
*/
class ChatMessage extends \ywxapp\BaseController
{
}
@@ -4,9 +4,8 @@ namespace ywxapp\model;
use think\facade\Db;
use ywxapp\model\BaseModel;
class Ad extends BaseModel
{
protected $name = 'ad';
class CommonAd extends BaseModel
{
// 广告类型
const TYPE_IMAGE = 1; // 图片
@@ -29,7 +28,6 @@ class Ad extends BaseModel
public function getOptions(): array
{
return [
'name' => 'ad',
'strict' => true,
'autoWriteTimestamp' => true,
'createTime' => 'create_at',
@@ -82,9 +80,9 @@ class Ad extends BaseModel
try {
$p = self::currentPrefix();
$prefix = $p;
$table = $prefix . 'ad';
// 缺表建表(install.sql L638 同款 DDL,运行时前缀兜底)
BaseModel::ensureTable($table, "CREATE TABLE IF NOT EXISTS `{$p}ad` (
$table = $prefix . 'common_ad';
// 缺表建表(install.sql 同款 DDL,运行时前缀兜底)
BaseModel::ensureTable($table, "CREATE TABLE IF NOT EXISTS `{$p}common_ad` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) NOT NULL DEFAULT '' COMMENT '广告标题',
`type` tinyint(1) NOT NULL DEFAULT 1 COMMENT '类型 1图片2文字3代码',
@@ -116,7 +114,7 @@ class Ad extends BaseModel
public static function getByPosition(string $position): array
{
self::ensureSchema();
$rows = Db::name('ad')
$rows = Db::name('common_ad')
->where('status', 1)
->where('position', $position)
->where('delete_at', 0)
@@ -140,7 +138,7 @@ class Ad extends BaseModel
self::ensureSchema();
$positions = array_keys(self::positionList());
$slots = array_fill_keys($positions, []);
$rows = Db::name('ad')
$rows = Db::name('common_ad')
->where('status', 1)
->where('position', 'in', $positions)
->where('delete_at', 0)
+48
View File
@@ -0,0 +1,48 @@
<?php
/*
* @Author: YwxApp <ywx@ywxapp.cn>
* @Date: 2026-08-06 22:05:48
* @LastEditors: YwxApp <ywx@ywxapp.cn>
* @LastEditTime: 2026-08-19 20:51:29
* @Description:
* @FilePath: \ywxapp_dev\ywxapp\model\AddonModel.php
* @CustomString: Copyright (c) 2026 YwxApp
*/
declare(strict_types=1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
class CommonAddon extends BaseModel
{
protected function getOptions(): array
{
return [
'strict' => true,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'schema' => [
'id' => 'int',
'name' => 'string',
'title' => 'string',
'version' => 'string',
'price' => 'float',
'description' => 'string',
'author' => 'string',
'status' => 'tinyint',
'config' => 'text',
'file_path' => 'string',
'file_hash' => 'string',
'sort' => 'int',
'create_at' => 'int',
'update_at' => 'int',
]
];
}
}
@@ -13,8 +13,9 @@ namespace ywxapp\model;
use think\Model;
class Attachment extends BaseModel
{
class CommonAttachment extends BaseModel
{
// 设置字段信息
protected $schema = [
//文件ID
@@ -90,7 +91,7 @@ class Attachment extends BaseModel
*/
public static function ensureSchema(): void
{
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'attachment');
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'common_attachment');
}
/**
@@ -1,5 +1,15 @@
<?php
/*
* @Author: YwxApp <ywx@ywxapp.cn>
* @Date: 2026-08-07 10:22:47
* @LastEditors: YwxApp <ywx@ywxapp.cn>
* @LastEditTime: 2026-08-20 00:36:36
* @Description:
* @FilePath: \ywxapp_dev\ywxapp\model\CommonCard.php
* @CustomString: Copyright (c) 2026 YwxApp
*/
declare(strict_types=1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
@@ -10,18 +20,23 @@ use think\model\concern\SoftDelete;
/**
* 充值卡密
*/
class Card extends BaseModel
class CommonCard extends BaseModel
{
use SoftDelete;
protected $name = 'card';
protected $deleteTime = 'delete_at';
protected $defaultSoftDelete = 0;
// 时间戳自动写入
protected $autoWriteTimestamp = true;
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
protected function getOptions(): array
{
return [
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'deleteTime' => 'delete_at',
'defaultSoftDelete' => 0,
'append' => ['target'],
'hidden' => ['create_at', 'update_at', 'delete_at'],
'readonly' => ['id'],
];
}
// 卡密状态
const STATUS_UNSOLD = 0; // 未售
@@ -33,7 +48,7 @@ class Card extends BaseModel
*/
public static function ensureSchema(): void
{
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'card');
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'common_card');
}
/**
@@ -88,9 +103,9 @@ class Card extends BaseModel
$card->save();
// 2) 会员钱包加余额 + 累计充值(无钱包则自动创建)
$wallet = Db::name('member_wallets')->where('uid', $uid)->find();
$wallet = Db::name('member_wallet')->where('uid', $uid)->find();
if (empty($wallet)) {
Db::name('member_wallets')->insert([
Db::name('member_wallet')->insert([
'uid' => $uid,
'balance' => $amount,
'total_recharge' => $amount,
@@ -98,7 +113,7 @@ class Card extends BaseModel
'update_at' => time(),
]);
} else {
Db::name('member_wallets')
Db::name('member_wallet')
->where('uid', $uid)
->inc('balance', $amount)
->inc('total_recharge', $amount)
@@ -14,15 +14,27 @@ namespace ywxapp\model;
*
* @author ywxapp <admin@ywxapp.cn>
*/
class Configure extends BaseModel
class CommonConfigure extends BaseModel
{
protected function getOptions(): array
{
return [
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'deleteTime' => 'delete_at',
'defaultSoftDelete' => 0,
'append' => ['target'],
'hidden' => ['create_at', 'update_at', 'delete_at'],
'readonly' => ['id'],
];
}
public function getTitleAttr($value)
{
return lang($value);
}
public function getGroupAttr($value)
{
return lang($value);
@@ -33,7 +45,7 @@ class Configure extends BaseModel
*/
public static function ensureSchema(): void
{
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'configure');
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'common_configure');
}
/**
@@ -14,8 +14,21 @@ namespace ywxapp\model;
*
* @author ywxapp <admin@ywxapp.cn>
*/
class Email extends BaseModel{
class CommonEmail extends BaseModel{
// 设置表名(think-orm 4.0:name 不带前缀,自动拼 wxapp_)
protected $name = 'email';
protected function getOptions(): array
{
return [
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'deleteTime' => 'delete_at',
'defaultSoftDelete' => 0,
'append' => ['target'],
'hidden' => ['create_at', 'update_at', 'delete_at'],
'readonly' => ['id'],
];
}
}
@@ -1,5 +1,16 @@
<?php
/*
* @Author: YwxApp <ywx@ywxapp.cn>
* @Date: 2026-08-07 10:22:47
* @LastEditors: YwxApp <ywx@ywxapp.cn>
* @LastEditTime: 2026-08-19 21:08:06
* @Description:
* @FilePath: \ywxapp_dev\ywxapp\model\Help.php
* @CustomString: Copyright (c) 2026 YwxApp
*/
declare(strict_types=1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
@@ -9,25 +20,29 @@ use think\model\concern\SoftDelete;
/**
* 站点帮助
*/
class Help extends BaseModel
class CommonHelp extends BaseModel
{
use SoftDelete;
protected $name = 'help';
protected $deleteTime = 'delete_at';
protected $defaultSoftDelete = 0;
// 时间戳自动写入
protected $autoWriteTimestamp = true;
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
protected function getOptions(): array
{
return [
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'deleteTime' => 'delete_at',
'defaultSoftDelete' => 0,
'readonly' => ['id'],
];
}
/**
* 运行时自愈:确保 help 主表存在(install.sql 已含 category/view_count 等列,为事实源)。
*/
public static function ensureSchema(): void
{
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'help');
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'common_help');
}
/**
@@ -39,4 +54,4 @@ class Help extends BaseModel
parent::initialize();
self::ensureSchema();
}
}
}
@@ -14,7 +14,7 @@ use think\model\concern\SoftDelete;
use ywxapp\model\BaseModel;
class Links extends BaseModel
class CommonLinks extends BaseModel
{
use SoftDelete;
@@ -29,7 +29,6 @@ class Links extends BaseModel
{
return [
'strict' => true,
'name' => 'links',
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
@@ -41,7 +40,7 @@ class Links extends BaseModel
*/
public static function ensureSchema(): void
{
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'links');
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'common_links');
}
/**
@@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
@@ -10,18 +12,24 @@ use think\model\concern\SoftDelete;
/**
* 勋章中心
*/
class Medal extends BaseModel
class CommonMedal extends BaseModel
{
use SoftDelete;
protected $name = 'medal';
protected $deleteTime = 'delete_at';
protected $defaultSoftDelete = 0;
// 时间戳自动写入
protected $autoWriteTimestamp = true;
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
protected function getOptions(): array
{
return [
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'deleteTime' => 'delete_at',
'defaultSoftDelete' => 0,
'append' => ['target'],
'hidden' => ['create_at', 'update_at', 'delete_at'],
'readonly' => ['id'],
];
}
/**
* 控制器初始化(模型实例方法,非静态)
@@ -74,7 +82,7 @@ class Medal extends BaseModel
}
return Db::name('member_medal')
->alias('um')
->join('medal m', 'm.id = um.medal_id')
->join('common_medal m', 'm.id = um.medal_id')
->where('um.uid', $uid)
->where('m.delete_at', 0)
->field('m.id,m.title,m.image,m.description,um.create_at')
@@ -89,7 +97,7 @@ class Medal extends BaseModel
public static function ensureSchema(): void
{
$prefix = BaseModel::currentPrefix();
BaseModel::ensureTableFromInstall($prefix, 'medal');
BaseModel::ensureTableFromInstall($prefix, 'common_medal');
BaseModel::ensureTableFromInstall($prefix, 'member_medal');
}
}
}
+133
View File
@@ -0,0 +1,133 @@
<?php
// +----------------------------------------------------------------------
// | YwxApp [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: ywxapp<admin@ywxapp.cn>
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace ywxapp\model;
use think\model\concern\SoftDelete;
/**
* 前台主导航菜单模型(支持两级下拉).
*/
class CommonNavMenu extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_at';
protected function getOptions(): array
{
return [
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'deleteTime' => 'delete_at',
'defaultSoftDelete' => 0,
'append' => ['target'],
'hidden' => ['create_at', 'update_at', 'delete_at'],
'readonly' => ['id'],
];
}
/**
* 运行时自愈:确保 common_nav_menu 主表存在(install.sql 为事实源),
* 老库补充 app 字段(跨应用链接,见 ensureColumn).
*/
public static function ensureSchema(): void
{
$prefix = BaseModel::currentPrefix();
BaseModel::ensureTableFromInstall($prefix, 'common_nav_menu');
BaseModel::ensureColumn(
$prefix . 'common_nav_menu',
'app',
"varchar(30) NOT NULL DEFAULT '' COMMENT '所属应用(跨应用链接用,空=当前应用)' AFTER `url`"
);
}
protected function initialize()
{
parent::initialize();
self::ensureSchema();
}
/**
* 获取启用的导航树(两级:父 + 子)。
* @return array [{id,title,url,icon,child:[...]}]
*/
public static function getNavTree(): array
{
$list = self::where('status', 1)
->where('delete_at', 0)
->order('sort', 'asc')
->order('id', 'asc')
->field('id,parent_id,title,url,app,icon,sort')
->select()
->toArray();
$parents = [];
$childrenMap = [];
foreach ($list as $item) {
$item['ctrl'] = strtolower(strtok($item['url'], '/') ?: '');
if ((int) $item['parent_id'] === 0) {
$item['child'] = [];
$parents[] = $item;
} else {
$childrenMap[$item['parent_id']][] = $item;
}
}
foreach ($parents as &$p) {
if (isset($childrenMap[$p['id']])) {
$p['child'] = $childrenMap[$p['id']];
}
}
return $parents;
}
/**
* 后台列表:返回两级扁平树(含隐藏项).
*
* @param string $title 可选:按菜单名称模糊筛选(命中子项时自动带上其父级)
*/
public static function getAdminTree(string $title = ''): array
{
$query = self::where('delete_at', 0);
if ($title !== '') {
$matchIds = self::where('delete_at', 0)->whereLike('title', "%{$title}%")->column('id');
if (empty($matchIds)) {
return [];
}
$parentIds = self::where('delete_at', 0)->whereIn('parent_id', $matchIds)->column('parent_id');
$ids = array_values(array_unique(array_merge($matchIds, $parentIds)));
$query->whereIn('id', $ids);
}
$list = $query->order('sort', 'asc')
->order('id', 'asc')
->field('id,parent_id,title,url,app,icon,sort,status')
->select()
->toArray();
$parents = [];
$childrenMap = [];
foreach ($list as $item) {
$item['ctrl'] = strtolower(strtok($item['url'], '/') ?: '');
if ((int) $item['parent_id'] === 0) {
$item['child'] = [];
$parents[] = $item;
} else {
$childrenMap[$item['parent_id']][] = $item;
}
}
foreach ($parents as &$p) {
if (isset($childrenMap[$p['id']])) {
$p['child'] = $childrenMap[$p['id']];
}
}
return $parents;
}
}
@@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
@@ -8,13 +10,10 @@ use think\model\concern\SoftDelete;
/**
* 站点公告
*/
class Notice extends BaseModel
class CommonNotice extends BaseModel
{
use SoftDelete;
protected $deleteTime = 'delete_at';
protected $defaultSoftDelete = 0;
// 类型:1系统维护 2活动公告 3版本更新 4其他
public const TYPE_MAINTAIN = 1;
public const TYPE_ACTIVITY = 2;
@@ -35,9 +34,6 @@ class Notice extends BaseModel
'delete_at' => 'integer',
];
// 只读字段
protected $readonly = ['view_count'];
/**
* 模型配置(BaseModel::applyOptions 约定)
*/
@@ -45,10 +41,10 @@ class Notice extends BaseModel
{
return [
'strict' => true,
'name' => 'notice',
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'readonly' => ['view_count']
];
}
@@ -121,9 +117,9 @@ class Notice extends BaseModel
try {
$p = self::currentPrefix();
$prefix = $p;
$table = $prefix . 'notice';
// 缺表建表(install.sql L618 同款 DDL,运行时前缀兜底)
self::ensureTable($table, "CREATE TABLE IF NOT EXISTS `{$p}notice` (
$table = $prefix . 'common_notice';
// 缺表建表(install.sql 同款 DDL,运行时前缀兜底)
self::ensureTable($table, "CREATE TABLE IF NOT EXISTS `{$p}common_notice` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) NOT NULL DEFAULT '' COMMENT '公告标题',
`content` text COMMENT '公告内容',
@@ -152,4 +148,4 @@ class Notice extends BaseModel
// 忽略自愈失败,由业务暴露
}
}
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
declare (strict_types = 1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
// use think\model\concern\SoftDelete;
/**
* @mixin \think\Model
*/
class CommonProp extends BaseModel
{
//use SoftDelete;
protected function getOptions(): array
{
return [
'strict' => true,
'autoWriteTimestamp' => 'int',
'readonly' => ['uid'],
'createTime' => 'create_at',
'updateTime' => 'update_at',
//'deleteTime' => 'delete_at',
//'hidden' => ['password', 'delete_at'],
//'append' => ['status_text', 'last_login'],
];
}
}
@@ -8,19 +8,25 @@ use think\model\concern\SoftDelete;
/**
* 电子商务
*/
class Shop extends BaseModel
class CommonShop extends BaseModel
{
use SoftDelete;
protected $name = 'shop';
protected $deleteTime = 'delete_at';
protected $defaultSoftDelete = 0;
// 时间戳自动写入
protected $autoWriteTimestamp = true;
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
/**
* 模型配置(BaseModel::applyOptions 约定)
*/
protected function getOptions(): array
{
return [
'strict' => true,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'deleteTime' => 'delete_at',
'defaultSoftDelete' => 0,
'readonly' => ['view_count']
];
}
/**
* 运行时自愈:确保 shop 主表存在(install.sql 为事实源)。
*/
@@ -8,18 +8,25 @@ use think\model\concern\SoftDelete;
/**
* 短信服务
*/
class Sms extends BaseModel
class CommonSms extends BaseModel
{
use SoftDelete;
protected $name = 'sms';
protected $deleteTime = 'delete_at';
protected $defaultSoftDelete = 0;
// 时间戳自动写入
protected $autoWriteTimestamp = true;
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
/**
* 模型配置(BaseModel::applyOptions 约定)
*/
protected function getOptions(): array
{
return [
'strict' => true,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'deleteTime' => 'delete_at',
'defaultSoftDelete' => 0,
'readonly' => ['view_count']
];
}
/**
* 运行时自愈:确保 sms 主表存在(install.sql 为事实源),并幂等补 delete_at 软删除列。
@@ -27,8 +34,8 @@ class Sms extends BaseModel
public static function ensureSchema(): void
{
$prefix = BaseModel::currentPrefix();
BaseModel::ensureTableFromInstall($prefix, 'sms');
self::ensureColumn($prefix . 'sms', 'delete_at', "int NOT NULL DEFAULT 0 COMMENT '删除时间(软删除)'");
BaseModel::ensureTableFromInstall($prefix, 'common_sms');
self::ensureColumn($prefix . 'common_sms', 'delete_at', "int NOT NULL DEFAULT 0 COMMENT '删除时间(软删除)'");
}
/**
+28
View File
@@ -0,0 +1,28 @@
<?php
declare (strict_types = 1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
// use think\model\concern\SoftDelete;
/**
* @mixin \think\Model
*/
class CommonSmsTemplate extends BaseModel
{
//use SoftDelete;
protected function getOptions(): array
{
return [
'strict' => true,
'name' => 'sms_template',
'autoWriteTimestamp' => 'int',
'readonly' => ['uid'],
'createTime' => 'create_at',
'updateTime' => 'update_at',
//'deleteTime' => 'delete_at',
//'hidden' => ['password', 'delete_at'],
//'append' => ['status_text', 'last_login'],
];
}
}
@@ -3,7 +3,7 @@ declare(strict_types=1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
use ywxapp\model\Medal;
use ywxapp\model\CommonMedal;
use think\facade\Db;
use think\model\concern\SoftDelete;
@@ -11,18 +11,25 @@ use think\model\concern\SoftDelete;
/**
* 站点任务
*/
class Task extends BaseModel
class CommonTask extends BaseModel
{
use SoftDelete;
protected $name = 'task';
protected $deleteTime = 'delete_at';
protected $defaultSoftDelete = 0;
// 时间戳自动写入
protected $autoWriteTimestamp = true;
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
/**
* 模型配置(BaseModel::applyOptions 约定)
*/
protected function getOptions(): array
{
return [
'strict' => true,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'deleteTime' => 'delete_at',
'defaultSoftDelete' => 0,
'readonly' => ['view_count']
];
}
// 奖励类型
const REWARD_SCORE = 1; // 积分
@@ -100,19 +107,19 @@ class Task extends BaseModel
// 发放奖励
switch ((int) $task['reward_type']) {
case self::REWARD_SCORE:
[$ok, $msg] = \ywxapp\model\Score::change($uid, \ywxapp\model\Score::TYPE_GAIN, $num, '完成任务:' . $task['title']);
[$ok, $msg] = \ywxapp\model\MebmberScore::change($uid, \ywxapp\model\MebmberScore::TYPE_GAIN, $num, '完成任务:' . $task['title']);
if (! $ok) {
throw new \Exception($msg);
}
break;
case self::REWARD_COIN:
Db::name('member_wallets')->where('uid', $uid)->inc('coins', $num)->update();
Db::name('member_wallet')->where('uid', $uid)->inc('coins', $num)->update();
Db::name('member_bill')->insert([
'uid' => $uid,
'currency' => 2, // 2=金币
'type' => 1, // 1=收入
'amount' => $num,
'balance' => Db::name('member_wallets')->where('uid', $uid)->value('coins') ?: $num,
'balance' => Db::name('member_wallet')->where('uid', $uid)->value('coins') ?: $num,
'remark' => '完成任务:' . $task['title'],
'create_at' => time(),
]);
@@ -127,7 +134,7 @@ class Task extends BaseModel
break;
case self::REWARD_MEDAL:
// reward_num 存勋章ID
$grant = Medal::grant($uid, $num);
$grant = CommonMedal::grant($uid, $num);
if (!$grant[0]) {
throw new \Exception($grant[1]);
}
@@ -159,10 +166,10 @@ class Task extends BaseModel
public static function ensureSchema(): void
{
$prefix = BaseModel::currentPrefix();
BaseModel::ensureTableFromInstall($prefix, 'task');
BaseModel::ensureTableFromInstall($prefix, 'common_task');
BaseModel::ensureTableFromInstall($prefix, 'member_prop');
BaseModel::ensureTableFromInstall($prefix, 'member_task');
BaseModel::ensureColumn("{$prefix}member", 'score', "int unsigned NOT NULL DEFAULT 0 COMMENT '积分(做任务/互动获得)'");
BaseModel::ensureColumn("{$prefix}task", 'prop_num', "int NOT NULL DEFAULT 1 COMMENT '道具数量(奖励类型为道具时生效)'");
BaseModel::ensureColumn("{$prefix}member_user", 'score', "int unsigned NOT NULL DEFAULT 0 COMMENT '积分(做任务/互动获得)'");
BaseModel::ensureColumn("{$prefix}common_task", 'prop_num', "int NOT NULL DEFAULT 1 COMMENT '道具数量(奖励类型为道具时生效)'");
}
}
@@ -1,4 +1,13 @@
<?php
/*
* @Author: YwxApp <ywx@ywxapp.cn>
* @Date: 2026-08-07 22:53:48
* @LastEditors: YwxApp <ywx@ywxapp.cn>
* @LastEditTime: 2026-08-19 21:12:33
* @Description:
* @FilePath: \ywxapp_dev\ywxapp\model\Score.php
* @CustomString: Copyright (c) 2026 YwxApp
*/
declare(strict_types=1);
namespace ywxapp\model;
@@ -10,17 +19,23 @@ use think\model\concern\SoftDelete;
/**
* 积分规则 & 积分流水
*/
class Score extends BaseModel
class MebmberScore extends BaseModel
{
use SoftDelete;
protected $name = 'score_rule';
protected $deleteTime = 'delete_at';
protected $defaultSoftDelete = 0;
protected $autoWriteTimestamp = true;
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
/**
* 模型配置(BaseModel::applyOptions 约定)
*/
protected function getOptions(): array
{
return [
'strict' => true,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'readonly' => ['view_count']
];
}
// 规则类型
const TYPE_GAIN = 1; // 获取
@@ -40,9 +55,9 @@ class Score extends BaseModel
public static function ensureSchema(): void
{
$prefix = BaseModel::currentPrefix();
BaseModel::ensureTableFromInstall($prefix, 'score_rule');
BaseModel::ensureTableFromInstall($prefix, 'score_log');
BaseModel::ensureColumn("{$prefix}member", 'score', "int unsigned NOT NULL DEFAULT 0 COMMENT '积分(做任务/互动获得)'");
BaseModel::ensureTableFromInstall($prefix, 'member_score_rule');
BaseModel::ensureTableFromInstall($prefix, 'member_score_log');
BaseModel::ensureColumn("{$prefix}member_user", 'score', "int unsigned NOT NULL DEFAULT 0 COMMENT '积分(做任务/互动获得)'");
}
/**
@@ -66,7 +81,7 @@ class Score extends BaseModel
Db::startTrans();
try {
$user = Db::name('member')->where('uid', $uid)->lock(true)->find();
$user = Db::name('member_user')->where('uid', $uid)->lock(true)->find();
if (!$user) {
throw new \Exception('用户不存在');
}
@@ -77,9 +92,9 @@ class Score extends BaseModel
? $user['score'] - $value
: $user['score'] + $value;
Db::name('member')->where('uid', $uid)->update(['score' => $balance]);
Db::name('member_user')->where('uid', $uid)->update(['score' => $balance]);
Db::name('score_log')->insert([
Db::name('member_score_log')->insert([
'uid' => $uid,
'rule_id' => $ruleId,
'type' => $type,
@@ -103,7 +118,7 @@ class Score extends BaseModel
public static function logList(int $uid = 0, int $page = 1, int $limit = 15): array
{
self::ensureSchema();
$query = Db::name('score_log');
$query = Db::name('member_score_log');
if ($uid > 0) {
$query->where('uid', $uid);
}
+27
View File
@@ -0,0 +1,27 @@
<?php
declare (strict_types = 1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
// use think\model\concern\SoftDelete;
/**
* @mixin \think\Model
*/
class MemberBill extends BaseModel
{
//use SoftDelete;
protected function getOptions(): array
{
return [
'strict' => true,
'autoWriteTimestamp' => 'int',
'readonly' => ['uid'],
'createTime' => 'create_at',
'updateTime' => 'update_at',
//'deleteTime' => 'delete_at',
//'hidden' => ['password', 'delete_at'],
//'append' => ['status_text', 'last_login'],
];
}
}
+1 -2
View File
@@ -23,8 +23,7 @@ class MemberGroup extends BaseModel
protected function getOptions(): array
{
return [
'strict' => false,
'name' => 'member_group',
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
+1 -2
View File
@@ -22,8 +22,7 @@ class MemberGroupAccess extends Pivot
protected function getOptions(): array
{
return [
'strict' => false,
'name' => 'member_group_access',
'strict' => false,
'autoWriteTimestamp' => 'int', // create_at 已统一为 int 时间戳
'createTime' => 'create_at',
'updateTime' => false,
+2 -6
View File
@@ -20,14 +20,10 @@ class MemberGroupRule extends Model
protected function getOptions(): array
{
return [
'strict' => false,
'name' => 'member_group_rule',
'strict' => false,
'autoWriteTimestamp' => 'int', // create_at 已统一为 int 时间戳
'createTime' => 'create_at',
'updateTime' => false,
// 'deleteTime' => 'delete_at',
// 'defaultSoftDelete' => 0,
// 'dateFormat' => 'Y-m-d H:i:s',
'updateTime' => false,
'append' => ['is_parent'],
'hidden' => ['password', 'create_at', 'update_at', 'delete_at'],
'readonly' => ['id'],
+2 -6
View File
@@ -19,14 +19,10 @@ use ywxapp\model\BaseModel;
protected function getOptions(): array
{
return [
'strict' => false,
'name' => 'member_log',
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => false,
// 'deleteTime' => 'delete_at',
// 'defaultSoftDelete' => 0,
// 'dateFormat' => 'Y-m-d H:i:s',
'updateTime' => false,
'append' => ['is_parent'],
'hidden' => ['password', 'create_at', 'update_at', 'delete_at'],
'readonly' => ['id'],
+27
View File
@@ -0,0 +1,27 @@
<?php
declare (strict_types = 1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
// use think\model\concern\SoftDelete;
/**
* @mixin \think\Model
*/
class MemberMedal extends BaseModel
{
//use SoftDelete;
protected function getOptions(): array
{
return [
'strict' => true,
'autoWriteTimestamp' => 'int',
'readonly' => ['uid'],
'createTime' => 'create_at',
'updateTime' => 'update_at',
//'deleteTime' => 'delete_at',
//'hidden' => ['password', 'delete_at'],
//'append' => ['status_text', 'last_login'],
];
}
}
-4
View File
@@ -19,13 +19,9 @@ class MemberProfile extends BaseModel
{
return [
'strict' => false,
'name' => 'member_profile',
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
// 'deleteTime' => 'delete_at',
// 'defaultSoftDelete' => 0,
// 'dateFormat' => 'Y-m-d H:i:s',
'append' => ['is_parent', 'age', 'is_online'],
'hidden' => ['create_at', 'update_at', 'delete_at'],
'readonly' => ['uid'],
+45
View File
@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 用户持有道具(member_prop)
*/
class MemberProp extends BaseModel
{
use SoftDelete;
/**
* 模型配置(BaseModel::applyOptions 约定)
*/
protected function getOptions(): array
{
return [
'strict' => true,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'readonly' => ['view_count']
];
}
/**
* 运行时自愈:确保 member_prop 表存在(install.sql 为事实源)。
*/
public static function ensureSchema(): void
{
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'member_prop');
}
/**
* 初始化:自愈建表,避免远程库缺失 member_prop 导致 1146。
*/
protected function initialize()
{
parent::initialize();
self::ensureSchema();
}
}
-2
View File
@@ -24,13 +24,11 @@ class MemberRule extends BaseModel
{
return [
'strict' => false,
'name' => 'member_rule',
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
'deleteTime' => 'delete_at',
'defaultSoftDelete' => 0,
// 'dateFormat' => 'Y-m-d H:i:s',
'append' => ['is_parent' ],
'hidden' => ['password', 'create_at', 'update_at', 'delete_at'],
'readonly' => ['id'],
@@ -18,25 +18,21 @@ use ywxapp\model\BaseModel;
*
* @author ywxapp <admin@ywxapp.cn>
*/
class ScoreLog extends BaseModel
class MemberScoreLog extends BaseModel
{
protected function initialize()
{
parent::initialize();
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'score_log');
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'member_score_log');
}
protected function getOptions(): array
{
return [
'strict' => false,
'name' => 'score_log',
'strict' => false,
'autoWriteTimestamp' => 'int',
'createTime' => 'create_at',
'updateTime' => 'update_at',
// 'deleteTime' => 'delete_at',
// 'defaultSoftDelete' => 0,
// 'dateFormat' => 'Y-m-d H:i:s',
'updateTime' => 'update_at',
'append' => ['is_parent'],
'hidden' => ['password', 'create_at', 'update_at', 'delete_at'],
'readonly' => ['id'],
@@ -49,6 +45,6 @@ class ScoreLog extends BaseModel
*/
public static function ensureSchema(): void
{
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'score_log');
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'member_score_log');
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
declare (strict_types = 1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
// use think\model\concern\SoftDelete;
/**
* @mixin \think\Model
*/
class MemberTask extends BaseModel
{
//use SoftDelete;
protected function getOptions(): array
{
return [
'strict' => true,
'autoWriteTimestamp' => 'int',
'readonly' => ['uid'],
'createTime' => 'create_at',
'updateTime' => 'update_at',
//'deleteTime' => 'delete_at',
//'hidden' => ['password', 'delete_at'],
//'append' => ['status_text', 'last_login'],
];
}
}
+10 -21
View File
@@ -26,7 +26,6 @@ class MemberUser extends BaseModel
{
return [
'strict' => true,
'name' => 'member_user',
'autoWriteTimestamp' => 'int',
'readonly' => ['uid'],
'createTime' => 'create_at',
@@ -82,31 +81,21 @@ class MemberUser extends BaseModel
->column('rid');
}
// 密码加密
// 密码加密:bcrypt 自带盐,无需独立 salt 列
// 兼容旧账户(若库里是 password_hash(value.salt) 的老哈希,
// 这里统一改为 password_hash(value),老账户需要先重置密码)。
public function setPasswordAttr($value)
{
$this->salt = $this->generateSalt();
return password_hash($value . $this->salt, PASSWORD_DEFAULT);
return password_hash($value, PASSWORD_DEFAULT);
}
// 生成随机盐
protected function generateSalt($length = 6)
{
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_[]{}<>~`+=,.;:/?|';
$salt = '';
for ($i = 0; $i < $length; $i++) {
$salt .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $salt;
}
// 验证密码
// 验证密码:bcrypt 哈希内已含盐,直接验证即可
public function checkPassword($password)
{
return password_verify($password . $this->salt, $this->password);
if (empty($this->password)) {
return false;
}
return password_verify($password, $this->password);
}
// 获取状态文本
@@ -194,7 +183,7 @@ class MemberUser extends BaseModel
public static function ensureSchema(): void
{
$prefix = BaseModel::currentPrefix();
foreach (['member', 'member_bill', 'member_group', 'member_group_access', 'member_group_rule', 'member_log', 'member_profile', 'member_rule', 'member_wallets'] as $t) {
foreach (['member_user', 'member_bill', 'member_group', 'member_group_access', 'member_group_rule', 'member_log', 'member_profile', 'member_rule', 'member_wallet'] as $t) {
BaseModel::ensureTableFromInstall($prefix, $t);
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
declare (strict_types = 1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
// use think\model\concern\SoftDelete;
/**
* @mixin \think\Model
*/
class MemberWallet extends BaseModel
{
//use SoftDelete;
protected function getOptions(): array
{
return [
'strict' => true,
'autoWriteTimestamp' => 'int',
'readonly' => ['uid'],
'createTime' => 'create_at',
'updateTime' => 'update_at',
//'deleteTime' => 'delete_at',
//'hidden' => ['password', 'delete_at'],
//'append' => ['status_text', 'last_login'],
];
}
}
-40
View File
@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace ywxapp\model;
use ywxapp\model\BaseModel;
use think\model\concern\SoftDelete;
/**
* 道具中心
*/
class Prop extends BaseModel
{
use SoftDelete;
protected $name = 'prop';
protected $deleteTime = 'delete_at';
protected $defaultSoftDelete = 0;
// 时间戳自动写入
protected $autoWriteTimestamp = true;
protected $createTime = 'create_at';
protected $updateTime = 'update_at';
/**
* 运行时自愈:确保 prop 主表存在(install.sql 为事实源)。
*/
public static function ensureSchema(): void
{
BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'prop');
}
/**
* 初始化:自愈建表,避免远程库缺失 wxapp_prop 导致 1146。
*/
protected function initialize()
{
parent::initialize();
self::ensureSchema();
}
}