本次提交新增了以下核心内容: 1. 后端管理模块:包含字体同步、插件元数据、插件用户设置、稍后读消息/共享列表的控制器、模型、验证器与多语言配置 2. Flutter数据同步模块:统一的事件总线与兼容层,替代分散的StreamController 3. 鸿蒙端路由适配:完整的路由定义、构建器与占位组件 4. 后端API接口:字体同步与插件更新的服务端API,支持自动建表与跨域请求 5. 鸿蒙权限校验脚本:用于校验module.json5与string.json的权限声明一致性
153 lines
6.2 KiB
PHP
153 lines
6.2 KiB
PHP
<?php
|
||
|
||
namespace app\api\controller;
|
||
|
||
use app\common\controller\Api;
|
||
use think\Db;
|
||
use think\Config;
|
||
use think\exception\HttpResponseException;
|
||
|
||
/**
|
||
* 字体同步 — 服务端API
|
||
* 创建时间: 2026-06-01
|
||
* 更新时间: 2026-06-01
|
||
* 作用: 替代Supabase字体表,提供在线字体列表查询
|
||
* 上次更新: v1.0 初始版本
|
||
*/
|
||
class FontSync extends Api
|
||
{
|
||
protected $noNeedLogin = ['list', 'install'];
|
||
protected $noNeedRight = '*';
|
||
|
||
public function _initialize()
|
||
{
|
||
header('Access-Control-Allow-Origin: *');
|
||
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
|
||
header('Access-Control-Allow-Headers: Content-Type, Authorization, Token');
|
||
if ($this->request->method() === 'OPTIONS') {
|
||
http_response_code(204);
|
||
exit;
|
||
}
|
||
parent::_initialize();
|
||
$this->ensureTable();
|
||
}
|
||
|
||
// ─── 自动建表 ──────────────────────────────────────────
|
||
|
||
private function ensureTable()
|
||
{
|
||
static $created = false;
|
||
if ($created) return;
|
||
$created = true;
|
||
|
||
$prefix = Config::get('database.prefix') ?: 'tool_';
|
||
|
||
$sql = "CREATE TABLE IF NOT EXISTS `{$prefix}fonts` (
|
||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||
`font_key` varchar(128) NOT NULL DEFAULT '' COMMENT '字体唯一标识',
|
||
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '字体名称',
|
||
`family` varchar(256) NOT NULL DEFAULT '' COMMENT 'CSS font-family',
|
||
`style` varchar(64) NOT NULL DEFAULT 'normal' COMMENT 'normal/italic',
|
||
`weight` varchar(32) NOT NULL DEFAULT '400' COMMENT '字重',
|
||
`url` varchar(512) NOT NULL DEFAULT '' COMMENT '字体文件URL',
|
||
`format` varchar(32) NOT NULL DEFAULT 'woff2' COMMENT '字体格式: woff2/woff/ttf/otf',
|
||
`category` varchar(64) NOT NULL DEFAULT 'sans-serif' COMMENT '分类: serif/sans-serif/monospace/cursive',
|
||
`is_active` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否启用',
|
||
`sort_order` int(11) NOT NULL DEFAULT 0 COMMENT '排序权重',
|
||
`preview_text` varchar(256) NOT NULL DEFAULT '' COMMENT '预览文字',
|
||
`created_at` int(11) unsigned NOT NULL DEFAULT 0,
|
||
`updated_at` int(11) unsigned NOT NULL DEFAULT 0,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_font_key` (`font_key`),
|
||
KEY `idx_active_sort` (`is_active`, `sort_order`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='在线字体'";
|
||
|
||
try {
|
||
Db::execute($sql);
|
||
} catch (\Exception $e) {
|
||
}
|
||
}
|
||
|
||
// ─── 字体列表 ──────────────────────────────────────────
|
||
|
||
/**
|
||
* 获取在线字体列表
|
||
* GET /api/font_sync/list
|
||
* 无需登录
|
||
*/
|
||
public function list()
|
||
{
|
||
try {
|
||
$fonts = Db::name('fonts')
|
||
->where('is_active', 1)
|
||
->order('sort_order', 'asc')
|
||
->select();
|
||
|
||
$list = [];
|
||
foreach ($fonts as $font) {
|
||
$list[] = [
|
||
'font_key' => $font['font_key'],
|
||
'name' => $font['name'],
|
||
'family' => $font['family'],
|
||
'style' => $font['style'],
|
||
'weight' => $font['weight'],
|
||
'url' => $font['url'],
|
||
'format' => $font['format'],
|
||
'category' => $font['category'],
|
||
'preview_text' => $font['preview_text'],
|
||
'sort_order' => intval($font['sort_order']),
|
||
];
|
||
}
|
||
|
||
$this->success('获取成功', [
|
||
'fonts' => $list,
|
||
'count' => count($list),
|
||
]);
|
||
} catch (HttpResponseException $e) {
|
||
throw $e;
|
||
} catch (\Exception $e) {
|
||
$this->error('获取字体列表失败: ' . $e->getMessage(), null, 500);
|
||
}
|
||
}
|
||
|
||
// ─── 安装接口 ──────────────────────────────────────────
|
||
|
||
/**
|
||
* 安装/升级数据库表
|
||
* POST /api/font_sync/install
|
||
*/
|
||
public function install()
|
||
{
|
||
$prefix = Config::get('database.prefix') ?: 'tool_';
|
||
|
||
$sql = "CREATE TABLE IF NOT EXISTS `{$prefix}fonts` (
|
||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||
`font_key` varchar(128) NOT NULL DEFAULT '' COMMENT '字体唯一标识',
|
||
`name` varchar(256) NOT NULL DEFAULT '' COMMENT '字体名称',
|
||
`family` varchar(256) NOT NULL DEFAULT '' COMMENT 'CSS font-family',
|
||
`style` varchar(64) NOT NULL DEFAULT 'normal' COMMENT 'normal/italic',
|
||
`weight` varchar(32) NOT NULL DEFAULT '400' COMMENT '字重',
|
||
`url` varchar(512) NOT NULL DEFAULT '' COMMENT '字体文件URL',
|
||
`format` varchar(32) NOT NULL DEFAULT 'woff2' COMMENT '字体格式: woff2/woff/ttf/otf',
|
||
`category` varchar(64) NOT NULL DEFAULT 'sans-serif' COMMENT '分类: serif/sans-serif/monospace/cursive',
|
||
`is_active` tinyint(1) NOT NULL DEFAULT 1 COMMENT '是否启用',
|
||
`sort_order` int(11) NOT NULL DEFAULT 0 COMMENT '排序权重',
|
||
`preview_text` varchar(256) NOT NULL DEFAULT '' COMMENT '预览文字',
|
||
`created_at` int(11) unsigned NOT NULL DEFAULT 0,
|
||
`updated_at` int(11) unsigned NOT NULL DEFAULT 0,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_font_key` (`font_key`),
|
||
KEY `idx_active_sort` (`is_active`, `sort_order`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='在线字体'";
|
||
|
||
try {
|
||
Db::execute($sql);
|
||
$this->success('安装完成', ['table' => $prefix . 'fonts', 'created' => true]);
|
||
} catch (HttpResponseException $e) {
|
||
throw $e;
|
||
} catch (\Exception $e) {
|
||
$this->error('安装失败: ' . $e->getMessage(), null, 500);
|
||
}
|
||
}
|
||
}
|