// +---------------------------------------------------------------------- declare (strict_types = 1); namespace ywxapp\model; use think\Model; class Attachment extends BaseModel { // 设置字段信息 protected $schema = [ //文件ID 'id' => 'int', //所属用户ID 'uid' => 'int', //所属模块 (admin, index, api) 'module' => 'string', //文件相对路径 (如: 2026/01/21/filename.jpg) 'path' => 'string', //文件访问URL (全路径) 'url' => 'string', //原始文件名 'original' => 'string', //存储文件名 (不含路径) 'name' => 'string', //文件大小 (字节) 'size' => 'int', //文件后缀 'ext' => 'string', //MIME类型 'mime' => 'string', //存储引擎 (local, alioss, qcos, qiniu) 'storage' => 'string', //驱动特定信息 (如OSS的ETag, Bucket等) 'driver_info' => 'json', //是否为图片 'is_image' => 'bool', //图片宽度 'width' => 'int', //图片高度 'height' => 'int', //上传者IP 'upload_ip' => 'string', //创建时间 'create_at' => 'int', //更新时间 'update_at' => 'int', ]; // 自动写入时间戳 protected $autoWriteTimestamp = 'int'; protected $createTime = 'create_at'; protected $updateTime = 'update_at'; // 隐藏字段 protected $hidden = ['upload_ip', 'driver_info']; /** * 关联用户模型(如果存在) * @return \think\model\relation\BelongsTo */ public function user() { return $this->belongsTo(MemberUser::class, 'uid', 'uid'); } // /** // * 获取完整URL(如果数据库里的URL是相对路径,自动补全域名) // * @param string $value // * @return string // */ // public function getUrlAttr($value) // { // if ($value && ! str_starts_with($value, 'http')) { // return Request::domain() . '/' . ltrim($value, '/'); // } // return $value; // } /** * 运行时自愈:确保 attachment 主表存在(install.sql 为事实源)。 */ public static function ensureSchema(): void { BaseModel::ensureTableFromInstall(BaseModel::currentPrefix(), 'attachment'); } /** * 初始化:自愈建表,避免远程库缺失 wxapp_attachment 导致 1146。 */ protected function initialize() { parent::initialize(); self::ensureSchema(); } /** * 格式化文件大小 * @return string */ public function getFormattedSizeAttr(): string { $bytes = $this->getData('file_size'); if ($bytes >= 1024 * 1024 * 1024) { return number_format($bytes / (1024 * 1024 * 1024), 2) . ' GB'; } elseif ($bytes >= 1024 * 1024) { return number_format($bytes / (1024 * 1024), 2) . ' MB'; } elseif ($bytes >= 1024) { return number_format($bytes / 1024, 2) . ' KB'; } else { return $bytes . ' B'; } } /** * 设置驱动信息(自动JSON编码) * @param mixed $value * @return void */ public function setDriverInfoAttr($value) { $this->setAttr('driver_info', json_encode($value, JSON_UNESCAPED_UNICODE)); } /** * 获取驱动信息(自动JSON解码) * @param string $value * @return array */ public function getDriverInfoAttr($value) { return $value ? json_decode($value, true) : []; } }