diff --git a/app/admin/controller/Cms/Theme/ThemeController.php b/app/admin/controller/Cms/Theme/ThemeController.php
index d22e5f7..5334058 100644
--- a/app/admin/controller/Cms/Theme/ThemeController.php
+++ b/app/admin/controller/Cms/Theme/ThemeController.php
@@ -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,请先选择租户'
]);
}
diff --git a/app/index/controller/Index.php b/app/index/controller/Index.php
index d5f0303..da279d2 100644
--- a/app/index/controller/Index.php
+++ b/app/index/controller/Index.php
@@ -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/)
diff --git a/app/index/route/app.php b/app/index/route/app.php
index 35ad6a4..deb3285 100644
--- a/app/index/route/app.php
+++ b/app/index/route/app.php
@@ -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');
diff --git a/app/service/ThemeService.php b/app/service/ThemeService.php
index 5f18640..0fe8d23 100644
--- a/app/service/ThemeService.php
+++ b/app/service/ThemeService.php
@@ -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
]);
diff --git a/public/themes/template3/about.html b/public/themes/template3/about.php
similarity index 55%
rename from public/themes/template3/about.html
rename to public/themes/template3/about.php
index ea8a19b..4b45e63 100644
--- a/public/themes/template3/about.html
+++ b/public/themes/template3/about.php
@@ -1,91 +1,18 @@
-
-
-
-
-
-
-
- About - Nova Bootstrap Template
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
About
+
关于我们
- Home
- About
+ 主页
+ 关于我们
@@ -98,7 +25,7 @@
-
+
@@ -128,7 +55,7 @@
-
+
@@ -205,7 +132,7 @@
-
+
@@ -237,7 +164,7 @@
-
+
@@ -255,7 +182,7 @@
-
+
@@ -273,7 +200,7 @@
-
+
@@ -291,7 +218,7 @@
-
+
@@ -314,90 +241,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/public/themes/template3/blog-details.html b/public/themes/template3/blog-details.php
similarity index 59%
rename from public/themes/template3/blog-details.html
rename to public/themes/template3/blog-details.php
index 273c389..3191a90 100644
--- a/public/themes/template3/blog-details.html
+++ b/public/themes/template3/blog-details.php
@@ -1,91 +1,18 @@
-
-
-
-
-
-
-
-
Blog Details - Nova Bootstrap Template
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
Blog Details
+
博客详情
- Home
- Blog Details
+ 主页
+ 博客详情
@@ -103,16 +30,16 @@
-
+
Dolorum optio tempore voluptas dignissimos cumque fuga qui quibusdam quia
@@ -144,7 +71,7 @@
Quia et suscipit non sequi. Maxime sed odit. Beatae nesciunt nesciunt accusamus quia aut ratione aspernatur dolor. Sint harum eveniet dicta exercitationem minima. Exercitationem omnis asperiores natus aperiam dolor consequatur id ex sed. Quibusdam rerum dolores sint consequatur quidem ea.
Beatae minima sunt libero soluta sapiente in rem assumenda. Et qui odit voluptatem. Cum quibusdam voluptatem voluptatem accusamus mollitia aut atque aut.
-
+
Ut repellat blanditiis est dolore sunt dolorum quae.
@@ -181,13 +108,13 @@
-
+
Jane Smith
Itaque quidem optio quia voluptatibus dolorem dolor. Modi eum sed possimus accusantium. Quas repellat voluptatem officia numquam sint aspernatur voluptas. Esse et accusantium ut unde voluptas.
@@ -207,7 +134,7 @@
Georgia Reader Reply
@@ -221,7 +148,7 @@Aron Alvarado Reply
@@ -233,7 +160,7 @@Lynda Small Reply
@@ -249,7 +176,7 @@Sianna Ramsay Reply
@@ -267,7 +194,7 @@Nolan Davidson Reply
@@ -282,7 +209,7 @@Kay Duggan Reply
@@ -304,29 +231,29 @@ @@ -343,7 +270,7 @@Search
+搜索