新增模板,修复模板选择bug

This commit is contained in:
2026-03-19 15:47:01 +08:00
parent bf21006d4e
commit a7908e0677
22 changed files with 964 additions and 2301 deletions
@@ -7,6 +7,7 @@ namespace app\admin\controller\Cms\Theme;
use app\admin\BaseController;
use app\service\ThemeService;
use think\facade\Request;
use app\model\Cms\TemplateSiteConfig;
/**
@@ -30,11 +31,15 @@ class ThemeController extends BaseController
*/
public function index()
{
$tid = Request::get('tid', 0, 'int');
$tid = $this->getTenantId();
$themes = $this->themeService->getThemeList();
$currentTheme = $this->themeService->getCurrentTheme($tid);
$theme_useing = TemplateSiteConfig::where('tid', $tid)
->where('key', 'current_theme')
->value('value');
return json([
'code' => 200,
'msg' => 'success',
@@ -51,14 +56,13 @@ class ThemeController extends BaseController
*/
public function switch()
{
// 从当前登录用户获取tid,而不是从前端参数
$tid = $this->getTenantId();
$tid = Request::post('tid', 0, 'int');
$themeKey = Request::post('theme_key', '');
if (empty($tid) || $tid == 0) {
return json([
'code' => 401,
'msg' => '未获取到租户ID,请重新登录'
'msg' => '未获取到租户ID,请先选择租户'
]);
}
+115
View File
@@ -74,6 +74,121 @@ class Index extends BaseController
return view('index/index');
}
/**
* 通用页面渲染
* 根据页面名称(如 about, blog, portfolio 等)渲染对应模板
* @param string $page 页面名称
* @return \think\response|\think\response\View
*/
public function page(string $page = 'index')
{
$request = $this->request ?? Request::instance();
// 获取租户ID
$tid = $request->tenantId ?? 0;
if ($tid == 0) {
$headerTid = $request->header('X-Tenant-Id');
$tid = $headerTid ? (int) $headerTid : 0;
}
if ($tid === 0) {
die('tenantId未获取到,请检查域名解析');
}
// 获取租户选择的模板
$themeKey = 'default';
if ($tid > 0) {
$config = TemplateSiteConfig::where('tid', $tid)
->where('key', 'current_theme')
->withoutField('delete_time')
->find();
$themeKey = $config['value'] ?? 'default';
}
// 模板路径
$themeBasePath = root_path() . 'public' . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . $themeKey;
$themeUrlPath = '/themes/' . $themeKey . '/';
// 安全检查:只允许字母、数字、中划线
$page = preg_replace('/[^a-zA-Z0-9\-]/', '', $page);
if (empty($page)) {
$page = 'index';
}
// 查找 PHP 模板(优先)或 HTML 模板
$templateFile = $themeBasePath . DIRECTORY_SEPARATOR . $page . '.php';
$templateHtmlFile = $themeBasePath . DIRECTORY_SEPARATOR . $page . '.html';
if (is_file($templateFile)) {
return $this->renderPhpTemplate($templateFile, $themeUrlPath);
} elseif (is_file($templateHtmlFile)) {
$content = file_get_contents($templateHtmlFile);
$content = $this->fixTemplateAssets($content, $themeUrlPath);
return response($content, 200, ['Content-Type' => 'text/html; charset=utf-8']);
}
// 模板不存在
return response('页面不存在', 404, ['Content-Type' => 'text/html; charset=utf-8']);
}
/**
* 文章详情页
* @param int $id 文章ID
* @return \think\response
*/
public function articleDetail(int $id = 0)
{
$request = $this->request ?? Request::instance();
// 获取租户ID
$tid = $request->tenantId ?? 0;
if ($tid == 0) {
$headerTid = $request->header('X-Tenant-Id');
$tid = $headerTid ? (int) $headerTid : 0;
}
if ($tid === 0) {
die('tenantId未获取到,请检查域名解析');
}
// 获取租户选择的模板
$themeKey = 'default';
if ($tid > 0) {
$config = TemplateSiteConfig::where('tid', $tid)
->where('key', 'current_theme')
->withoutField('delete_time')
->find();
$themeKey = $config['value'] ?? 'default';
}
// 模板路径
$themeBasePath = root_path() . 'public' . DIRECTORY_SEPARATOR . 'themes' . DIRECTORY_SEPARATOR . $themeKey;
$themeUrlPath = '/themes/' . $themeKey . '/';
// 查找文章详情模板
$templateFile = $themeBasePath . DIRECTORY_SEPARATOR . 'article_detail.php';
$templateHtmlFile = $themeBasePath . DIRECTORY_SEPARATOR . 'article_detail.html';
$blogDetailsFile = $themeBasePath . DIRECTORY_SEPARATOR . 'blog-details.php';
$blogDetailsHtmlFile = $themeBasePath . DIRECTORY_SEPARATOR . 'blog-details.html';
// 优先使用 article_detail 模板
if (is_file($templateFile)) {
return $this->renderPhpTemplate($templateFile, $themeUrlPath);
} elseif (is_file($templateHtmlFile)) {
$content = file_get_contents($templateHtmlFile);
$content = $this->fixTemplateAssets($content, $themeUrlPath);
return response($content, 200, ['Content-Type' => 'text/html; charset=utf-8']);
} elseif (is_file($blogDetailsFile)) {
return $this->renderPhpTemplate($blogDetailsFile, $themeUrlPath);
} elseif (is_file($blogDetailsHtmlFile)) {
$content = file_get_contents($blogDetailsHtmlFile);
$content = $this->fixTemplateAssets($content, $themeUrlPath);
return response($content, 200, ['Content-Type' => 'text/html; charset=utf-8']);
}
return response('文章不存在', 404, ['Content-Type' => 'text/html; charset=utf-8']);
}
/**
* 修复模板中的资源路径
* 将相对路径 (assets/, css/, js/, images/) 转换为绝对路径 (/themes/xxx/)
+5
View File
@@ -5,6 +5,11 @@ use think\facade\Route;
Route::get('/', 'app\index\controller\Index@index');
Route::get('index/index', 'app\index\controller\Index@index');
// --- 模板通用页面路由 ---
Route::get('article_detail/:id', 'app\index\controller\Index@articleDetail');
Route::get(':page', 'app\index\controller\Index@page')
->pattern(['page' => 'about|blog|blog-details|contact|portfolio|portfolio-details|service-details|services|team|articles']);
// --- 模板初始化接口 ---
Route::get('init', 'app\index\controller\Index@init');
+20 -26
View File
@@ -7,7 +7,6 @@ namespace app\service;
use think\facade\Db;
use think\facade\Config;
use app\model\Cms\TemplateSiteConfig;
use app\model\Cms\TemplateThemeData;
/**
* 模板服务类
@@ -120,19 +119,12 @@ class ThemeService
* @param int $tid 租户ID
* @return string
*/
public function getCurrentTheme(int $tid = 0): string
public function getCurrentTheme(int $tid)
{
try {
$where = [['key', '=', 'current_theme'], ['delete_time', '=', null]];
if ($tid > 0) {
$where[] = ['tid', '=', $tid];
}
$config = TemplateSiteConfig::where($where)
->find();
return $config['value'] ?? 'default';
} catch (\Exception $e) {
return 'default';
}
// 直接通过 tid 查询对应的 value
$value = TemplateSiteConfig::where('tid', $tid)->value('value');
return $value;
}
/**
@@ -175,6 +167,7 @@ class ThemeService
]);
} else {
TemplateSiteConfig::insert([
'tid' => $tid,
'key' => 'current_theme',
'value' => $themeKey,
'create_time' => $now,
@@ -199,17 +192,18 @@ class ThemeService
$themeKey = $themeKey ?? $this->getCurrentTheme($tid);
try {
$where = [['theme_key', '=', $themeKey], ['delete_time', '=', null]];
if ($tid > 0) {
$where[] = ['tid', '=', $tid];
}
$themeData = TemplateThemeData::where($where)
$configData = TemplateSiteConfig::where($where)
->select()
->toArray();
$data = [];
foreach ($themeData as $item) {
$data[$item['field_key']] = $item['field_value'];
foreach ($configData as $item) {
// 去掉 field_ 前缀
$fieldKey = substr($item['key'], 6);
$data[$fieldKey] = $item['value'];
}
return [
@@ -237,32 +231,32 @@ class ThemeService
public function saveThemeField(int $tid, string $themeKey, string $fieldKey, $fieldValue): bool
{
try {
// 使用 TemplateSiteConfig 表,key 格式为 field_xxx
$configKey = 'field_' . $fieldKey;
$where = [
['theme_key', '=', $themeKey],
['field_key', '=', $fieldKey],
['key', '=', $configKey],
['delete_time', '=', null]
];
if ($tid > 0) {
$where[] = ['tid', '=', $tid];
}
$existing = TemplateThemeData::where($where)
$existing = TemplateSiteConfig::where($where)
->find();
$value = is_array($fieldValue) ? json_encode($fieldValue, JSON_UNESCAPED_UNICODE) : $fieldValue;
$now = date('Y-m-d H:i:s');
if ($existing) {
TemplateThemeData::where('id', $existing['id'])
TemplateSiteConfig::where('id', $existing['id'])
->update([
'field_value' => $value,
'value' => $value,
'update_time' => $now
]);
} else {
TemplateThemeData::insert([
TemplateSiteConfig::insert([
'tid' => $tid,
'theme_key' => $themeKey,
'field_key' => $fieldKey,
'field_value' => $value,
'key' => $configKey,
'value' => $value,
'create_time' => $now,
'update_time' => $now
]);