更新模板功能

This commit is contained in:
2026-03-12 17:53:36 +08:00
parent 1f8d876cef
commit bf21006d4e
168 changed files with 82346 additions and 229 deletions
+427
View File
@@ -0,0 +1,427 @@
<?php
// 1. 引入 ThinkPHP 环境
$rootPath = dirname(__DIR__, 3) . DIRECTORY_SEPARATOR;
require_once $rootPath . 'vendor/autoload.php';
use think\facade\Db;
use think\App;
// 初始化应用
$app = new App($rootPath);
$app->initialize();
// 获取基础环境信息
$host = $_SERVER['HTTP_HOST'] ?? '';
$scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
$baseUrl = $scheme . '://' . $host;
$themeBase = '/themes/default';
// 获取文章 ID
$articleId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
// 辅助处理函数
function formatImageUrl($path, $baseUrl)
{
if (empty($path)) return '';
if (preg_match('/^https?:\/\//', $path)) return $path;
return $baseUrl . (strpos($path, '/') === 0 ? '' : '/') . $path;
}
try {
// 1. 获取租户 ID
$tenantDomain = Db::name('mete_tenant_domain')
->where('full_domain', $host)
->where('status', 1)
->whereNull('delete_time')
->find();
$tid = $tenantDomain ? (int)$tenantDomain['tid'] : 0;
if ($tid === 0 || $articleId === 0) {
die("未找到相关内容");
}
// 2. 获取站点基础信息
$setting = Db::name('mete_system_site_setting')->where('tid', $tid)->whereNull('delete_time')->find();
$tenant = Db::name('mete_tenant')->where('id', $tid)->whereNull('delete_time')->find();
$siteInfo = array_merge($tenant ?: [], $setting ?: []);
// 3. 获取文章详细数据
$article = Db::name('mete_articles')
->where('id', $articleId)
->where('tid', $tid)
->whereNull('delete_time')
->find();
if (!$article) {
die("文章不存在或已删除");
}
// 更新阅读数 (可选)
Db::name('mete_articles')->where('id', $articleId)->inc('views')->update();
} catch (\Exception $e) {
die("系统错误: " . $e->getMessage());
}
?>
<!DOCTYPE html>
<html class="no-js" lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<title><?php echo htmlspecialchars($article['title']); ?> - <?php echo $siteInfo['sitename']; ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="<?php echo $themeBase; ?>/assets/css/bootstrap-5.0.0-beta1.min.css" />
<link rel="stylesheet" href="<?php echo $themeBase; ?>/assets/css/LineIcons.2.0.css" />
<link rel="stylesheet" href="<?php echo $themeBase; ?>/assets/css/animate.css" />
<link rel="stylesheet" href="<?php echo $themeBase; ?>/assets/css/lindy-uikit.css" />
<link rel="stylesheet" href="<?php echo $themeBase; ?>/assets/css/all.min.css" />
<style>
:root {
--ink: #0f172a;
--muted: #475569;
--line: rgba(15, 23, 42, 0.10);
--card: rgba(255, 255, 255, 0.86);
--accent: #5864FF;
--accent2: #22c55e;
--shadow: 0 16px 50px rgba(2, 6, 23, 0.12);
}
body {
color: var(--ink);
background:
radial-gradient(1100px 420px at 12% 0%, rgba(88, 100, 255, 0.20), transparent 55%),
radial-gradient(900px 380px at 86% 10%, rgba(34, 197, 94, 0.12), transparent 55%),
linear-gradient(180deg, #fbfdff 0%, #f6f8ff 100%);
}
/* 顶部简洁导航 */
.navbar-brand img {
max-width: 260px;
}
.article-topbar {
margin-top: 18px;
border: 1px solid var(--line);
border-radius: 16px;
background: var(--card);
backdrop-filter: blur(10px);
box-shadow: 0 10px 30px rgba(2, 6, 23, 0.06);
}
.article-topbar .navbar {
padding: 12px 14px;
}
.article-topbar .back-link {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 10px 12px;
border-radius: 999px;
border: 1px solid var(--line);
color: var(--ink);
background: rgba(255, 255, 255, 0.55);
text-decoration: none;
transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}
.article-topbar .back-link:hover {
transform: translateY(-1px);
box-shadow: 0 10px 25px rgba(2, 6, 23, 0.10);
background: rgba(255, 255, 255, 0.75);
}
.article-topbar .back-link i {
color: var(--accent);
}
.breadcrumb-area {
padding: 18px 0;
background: transparent;
font-size: 14px;
}
.breadcrumb {
margin: 0;
padding: 12px 16px;
border: 1px solid var(--line);
border-radius: 14px;
background: var(--card);
backdrop-filter: blur(10px);
box-shadow: 0 10px 30px rgba(2, 6, 23, 0.06);
}
.breadcrumb-area a {
color: var(--accent);
text-decoration: none;
}
.breadcrumb-area a:hover {
text-decoration: underline;
}
.article-header {
padding: 46px 0 18px;
background: transparent;
}
.article-title {
font-size: 34px;
font-weight: 800;
color: var(--ink);
line-height: 1.25;
letter-spacing: -0.02em;
margin: 0 0 16px;
}
.article-meta {
display: flex;
gap: 14px;
justify-content: center;
flex-wrap: wrap;
color: var(--muted);
font-size: 14px;
}
.article-meta span {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
border: 1px solid var(--line);
border-radius: 999px;
background: rgba(255, 255, 255, 0.70);
backdrop-filter: blur(8px);
}
.article-meta i {
color: var(--accent);
}
.article-content {
padding: 22px 0 70px;
line-height: 1.85;
font-size: 16px;
color: var(--ink);
}
.article-content .col-lg-10 {
background: var(--card);
border: 1px solid var(--line);
border-radius: 18px;
box-shadow: var(--shadow);
padding: 26px 22px;
backdrop-filter: blur(12px);
}
.article-content img {
max-width: 100% !important;
height: auto !important;
border-radius: 14px;
margin: 18px 0;
box-shadow: 0 14px 40px rgba(2, 6, 23, 0.10);
}
/* 富文本排版:标题/段落/链接/列表/引用/代码 */
.content-text {
color: var(--ink);
/* border-top: 1px solid #efefef; */
padding: 60px;
}
.content-text p {
margin: 0 0 14px;
color: #1f2937;
display: flex;
justify-content: center;
}
.content-text a {
color: var(--accent);
text-decoration: underline;
text-underline-offset: 3px;
}
.content-text a:hover {
color: #3b49ff;
}
.content-text h1,
.content-text h2,
.content-text h3,
.content-text h4 {
color: var(--ink);
font-weight: 800;
margin: 26px 0 12px;
line-height: 1.25;
}
.content-text h2 {
font-size: 22px;
}
.content-text h3 {
font-size: 18px;
}
.content-text ul,
.content-text ol {
margin: 10px 0 18px 1.1rem;
}
.content-text li {
margin: 6px 0;
color: #1f2937;
}
.content-text blockquote {
margin: 18px 0;
padding: 14px 16px;
border-left: 4px solid var(--accent);
background: rgba(88, 100, 255, 0.07);
border-radius: 12px;
color: var(--muted);
}
.content-text hr {
border: 0;
border-top: 1px solid var(--line);
margin: 24px 0;
}
.content-text code {
padding: 2px 6px;
border-radius: 8px;
background: rgba(15, 23, 42, 0.06);
color: #0b1220;
font-size: 0.92em;
}
.content-text pre {
margin: 16px 0 22px;
padding: 16px 16px;
border-radius: 14px;
background: #0b1220;
color: #e5e7eb;
overflow: auto;
box-shadow: 0 18px 60px rgba(2, 6, 23, 0.25);
}
.content-text pre code {
background: transparent;
color: inherit;
padding: 0;
font-size: 0.92em;
}
.content-text p img {
display: flex;
align-items: center;
justify-content: center;
}
footer {
background: rgba(2, 6, 23, 0.92);
padding: 44px 0;
color: rgba(226, 232, 240, 0.86);
}
footer p {
margin: 0;
}
@media (max-width: 576px) {
.article-title {
font-size: 26px;
}
.article-content .col-lg-10 {
padding: 18px 14px;
border-radius: 16px;
}
.breadcrumb {
border-radius: 12px;
}
}
</style>
</head>
<body>
<div class="container">
<div class="article-topbar">
<nav class="navbar navbar-expand-lg">
<a class="navbar-brand" href="/">
<img src="<?php echo formatImageUrl($siteInfo['logo'] ?? '', $baseUrl); ?>" alt="Logo" />
</a>
<div class="ms-auto">
<a class="back-link" href="/">
<i class="lni lni-arrow-left"></i>
返回首页
</a>
</div>
</nav>
</div>
</div>
<div class="breadcrumb-area">
<div class="container">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/">首页</a></li>
<li class="breadcrumb-item active" aria-current="page">文章详情</li>
</ol>
</nav>
</div>
</div>
<section class="article-header">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-10 text-center">
<h1 class="article-title"><?php echo htmlspecialchars($article['title']); ?></h1>
<div class="article-meta">
<span><i class="lni lni-calendar"></i> <?php echo date('Y-m-d', strtotime($article['publish_date'])); ?></span>
<span><i class="lni lni-eye"></i> 阅读: <?php echo $article['views']; ?></span>
<span><i class="lni lni-user"></i> 管理员</span>
</div>
</div>
</div>
</div>
</section>
<section class="article-content">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-10">
<!-- <?php if (!empty($article['image'])): ?>
<div class="text-center mb-40">
<img src="<?php echo formatImageUrl($article['image'], $baseUrl); ?>" style="width: 100%;">
</div>
<?php endif; ?> -->
<div class="content-text">
<?php
// 替换内容中的相对图片路径为绝对路径
$content = $article['content'];
$content = str_replace('src="/uploads/', 'src="' . $baseUrl . '/uploads/', $content);
echo $content;
?>
</div>
</div>
</div>
</div>
</section>
<footer>
<div class="container text-center">
<p>Copyright © 2026 <?php echo $siteInfo['companyname']; ?> | <?php echo $siteInfo['icp']; ?></p>
</div>
</footer>
<script src="<?php echo $themeBase; ?>/assets/js/bootstrap-5.0.0-beta1.min.js"></script>
</body>
</html>
+406
View File
@@ -0,0 +1,406 @@
<?php
// 文章列表(每页 10 条,支持翻页)
$rootPath = dirname(__DIR__, 3) . DIRECTORY_SEPARATOR;
require_once $rootPath . 'vendor/autoload.php';
use think\facade\Db;
use think\App;
$app = new App($rootPath);
$app->initialize();
$host = $_SERVER['HTTP_HOST'] ?? '';
$scheme = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
$baseUrl = $scheme . '://' . $host;
$themeBase = '/themes/default';
function formatImageUrl($path, $baseUrl) {
if (empty($path)) return '';
if (preg_match('/^https?:\/\//', $path)) return $path;
return $baseUrl . (strpos($path, '/') === 0 ? '' : '/') . $path;
}
function stripHtmlText($html) {
if (empty($html)) return '';
$text = preg_replace('/<[^>]+>/', ' ', $html);
$text = preg_replace('/\s+/', ' ', $text);
return trim($text);
}
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
if ($page < 1) $page = 1;
$pageSize = 10;
try {
$tenantDomain = Db::name('mete_tenant_domain')
->where('full_domain', $host)
->where('status', 1)
->whereNull('delete_time')
->find();
$tid = $tenantDomain ? (int)$tenantDomain['tid'] : 0;
if ($tid === 0) {
die("未找到相关内容");
}
$setting = Db::name('mete_system_site_setting')->where('tid', $tid)->whereNull('delete_time')->find();
$tenant = Db::name('mete_tenant')->where('id', $tid)->whereNull('delete_time')->find();
$siteInfo = array_merge($tenant ?: [], $setting ?: []);
$baseQuery = Db::name('mete_articles')
->where('tid', $tid)
->whereNull('delete_time');
// 如果存在 status 字段,通常用 2 表示已发布;不存在也不影响(交给数据库报错会影响页面)
// 为避免因不同库结构导致报错,这里不强依赖 status 过滤。
$total = (int)$baseQuery->count();
$totalPages = (int)max(1, ceil($total / $pageSize));
if ($page > $totalPages) $page = $totalPages;
$offset = ($page - 1) * $pageSize;
$articles = $baseQuery
->order('publish_date', 'desc')
->limit($offset, $pageSize)
->select()
->toArray();
} catch (\Exception $e) {
die("系统错误: " . $e->getMessage());
}
?>
<!DOCTYPE html>
<html class="no-js" lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<title><?php echo htmlspecialchars(($siteInfo['sitename'] ?? '') ?: '新闻中心'); ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="<?php echo $themeBase; ?>/assets/css/bootstrap-5.0.0-beta1.min.css" />
<link rel="stylesheet" href="<?php echo $themeBase; ?>/assets/css/LineIcons.2.0.css" />
<link rel="stylesheet" href="<?php echo $themeBase; ?>/assets/css/animate.css" />
<link rel="stylesheet" href="<?php echo $themeBase; ?>/assets/css/lindy-uikit.css" />
<link rel="stylesheet" href="<?php echo $themeBase; ?>/assets/css/all.min.css" />
<style>
:root{
--ink:#0f172a;
--muted:#475569;
--line:rgba(15,23,42,.10);
--card:rgba(255,255,255,.86);
--accent:#5864FF;
--shadow:0 16px 50px rgba(2,6,23,.12);
}
body{
color:var(--ink);
background:
radial-gradient(1100px 420px at 12% 0%, rgba(88,100,255,.20), transparent 55%),
radial-gradient(900px 380px at 86% 10%, rgba(34,197,94,.12), transparent 55%),
linear-gradient(180deg, #fbfdff 0%, #f6f8ff 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
}
.topbar{
margin-top:18px;
border:1px solid var(--line);
border-radius:16px;
background:var(--card);
backdrop-filter: blur(10px);
box-shadow: 0 10px 30px rgba(2,6,23,.06);
}
.topbar .navbar{ padding: 12px 14px; }
.navbar-brand img{ max-width: 260px; }
.back-link{
display:inline-flex;
align-items:center;
gap:8px;
padding:10px 12px;
border-radius:999px;
border:1px solid var(--line);
color:var(--ink);
background:rgba(255,255,255,.55);
text-decoration:none;
transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}
.back-link:hover{
transform: translateY(-1px);
box-shadow: 0 10px 25px rgba(2,6,23,.10);
background: rgba(255,255,255,.75);
}
.back-link i{ color: var(--accent); }
.page-head{
padding: 34px 0 10px;
text-align:center;
}
.page-title{
font-size: 34px;
font-weight: 800;
letter-spacing: -0.02em;
margin: 0 0 10px;
}
.page-subtitle{
color: var(--muted);
margin: 0;
}
.list-wrap{
padding: 10px 0 70px;
flex: 1;
}
.list-card{
background: var(--card);
border: 1px solid var(--line);
border-radius: 18px;
box-shadow: var(--shadow);
padding: 18px;
backdrop-filter: blur(12px);
}
.news-grid{
display:grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 16px;
}
@media (max-width: 992px){
.news-grid{ grid-template-columns: 1fr; }
.page-title{ font-size: 28px; }
}
.news-item{
display:flex;
gap: 14px;
padding: 14px;
border: 1px solid rgba(15,23,42,.08);
border-radius: 16px;
background: rgba(255,255,255,.70);
text-decoration:none;
color: inherit;
transition: transform .14s ease, box-shadow .14s ease, background .14s ease;
overflow:hidden;
}
.news-item:hover{
transform: translateY(-2px);
box-shadow: 0 16px 45px rgba(2,6,23,.12);
background: rgba(255,255,255,.82);
}
.thumb{
width: 160px;
height: 108px;
border-radius: 14px;
overflow:hidden;
flex: 0 0 auto;
background: rgba(15,23,42,.06);
border: 1px solid rgba(15,23,42,.08);
}
.thumb img{
width:100%;
height:100%;
object-fit: cover;
display:block;
}
@media (max-width: 576px){
.thumb{ width: 120px; height: 86px; }
}
.news-body{ min-width: 0; flex: 1; }
.news-title{
font-size: 16px;
font-weight: 800;
line-height: 1.35;
margin: 0 0 8px;
display:-webkit-box;
line-clamp: 2;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow:hidden;
}
.news-desc{
margin: 0 0 10px;
color: var(--muted);
font-size: 14px;
line-height: 1.55;
display:-webkit-box;
line-clamp: 2;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow:hidden;
}
.news-meta{
display:flex;
gap: 12px;
flex-wrap: wrap;
color: var(--muted);
font-size: 13px;
align-items:center;
}
.news-meta i{ color: var(--accent); }
.pager{
display:flex;
justify-content:center;
margin-top: 22px;
}
.pagination{
gap: 8px;
flex-wrap: wrap;
}
.page-link{
border-radius: 12px !important;
border: 1px solid rgba(15,23,42,.10);
color: var(--ink);
background: rgba(255,255,255,.65);
box-shadow: 0 10px 25px rgba(2,6,23,.06);
}
.page-item.active .page-link{
background: var(--accent);
border-color: var(--accent);
color: #fff;
box-shadow: 0 18px 50px rgba(88,100,255,.30);
}
.page-item.disabled .page-link{
background: rgba(255,255,255,.45);
color: rgba(71,85,105,.6);
}
footer{
background: rgba(2,6,23,.92);
padding: 44px 0;
color: rgba(226,232,240,.86);
}
footer p{ margin: 0; }
</style>
</head>
<body>
<div class="container">
<div class="topbar">
<nav class="navbar navbar-expand-lg">
<a class="navbar-brand" href="/">
<img src="<?php echo formatImageUrl($siteInfo['logo'] ?? '', $baseUrl); ?>" alt="Logo" />
</a>
<div class="ms-auto">
<a class="back-link" href="/#newsCenter">
<i class="lni lni-arrow-left"></i>
返回首页
</a>
</div>
</nav>
</div>
</div>
<section class="page-head">
<div class="container">
<h1 class="page-title">新闻中心</h1>
<p class="page-subtitle">最新动态与行业资讯,持续更新。</p>
</div>
</section>
<section class="list-wrap">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-10">
<div class="list-card">
<?php if (empty($articles)): ?>
<div class="text-center py-5" style="color: var(--muted);">
暂无文章
</div>
<?php else: ?>
<div class="news-grid">
<?php foreach ($articles as $a): ?>
<?php
$title = $a['title'] ?? '未命名';
$publishDate = !empty($a['publish_date']) ? date('Y-m-d', strtotime($a['publish_date'])) : '';
$views = $a['views'] ?? ($a['pv'] ?? 0);
$desc = $a['summary'] ?? ($a['description'] ?? '');
if (empty($desc) && !empty($a['content'])) $desc = stripHtmlText($a['content']);
if (mb_strlen($desc) > 120) $desc = mb_substr($desc, 0, 120) . '…';
$thumb = $a['thumb'] ?? ($a['image'] ?? '');
$thumbUrl = $thumb ? formatImageUrl($thumb, $baseUrl) : '';
$id = (int)($a['id'] ?? 0);
?>
<a class="news-item" href="/news/article_detail.php?id=<?php echo $id; ?>">
<div class="thumb" aria-hidden="true">
<?php if ($thumbUrl): ?>
<img src="<?php echo htmlspecialchars($thumbUrl); ?>" alt="<?php echo htmlspecialchars($title); ?>">
<?php endif; ?>
</div>
<div class="news-body">
<h3 class="news-title"><?php echo htmlspecialchars($title); ?></h3>
<p class="news-desc"><?php echo htmlspecialchars($desc ?: '暂无摘要'); ?></p>
<div class="news-meta">
<?php if ($publishDate): ?>
<span><i class="lni lni-calendar"></i> <?php echo htmlspecialchars($publishDate); ?></span>
<?php endif; ?>
<span><i class="lni lni-eye"></i> <?php echo (int)$views; ?></span>
</div>
</div>
</a>
<?php endforeach; ?>
</div>
<div class="pager">
<nav aria-label="Page navigation">
<ul class="pagination">
<?php
$mkUrl = function($p){
return '/news?page=' . (int)$p;
};
$prev = max(1, $page - 1);
$next = min($totalPages, $page + 1);
$window = 2;
$start = max(1, $page - $window);
$end = min($totalPages, $page + $window);
?>
<li class="page-item <?php echo $page <= 1 ? 'disabled' : ''; ?>">
<a class="page-link" href="<?php echo $page <= 1 ? '#' : $mkUrl($prev); ?>" tabindex="-1">上一页</a>
</li>
<?php if ($start > 1): ?>
<li class="page-item"><a class="page-link" href="<?php echo $mkUrl(1); ?>">1</a></li>
<?php if ($start > 2): ?>
<li class="page-item disabled"><span class="page-link">…</span></li>
<?php endif; ?>
<?php endif; ?>
<?php for ($p = $start; $p <= $end; $p++): ?>
<li class="page-item <?php echo $p === $page ? 'active' : ''; ?>">
<a class="page-link" href="<?php echo $mkUrl($p); ?>"><?php echo (int)$p; ?></a>
</li>
<?php endfor; ?>
<?php if ($end < $totalPages): ?>
<?php if ($end < $totalPages - 1): ?>
<li class="page-item disabled"><span class="page-link">…</span></li>
<?php endif; ?>
<li class="page-item"><a class="page-link" href="<?php echo $mkUrl($totalPages); ?>"><?php echo (int)$totalPages; ?></a></li>
<?php endif; ?>
<li class="page-item <?php echo $page >= $totalPages ? 'disabled' : ''; ?>">
<a class="page-link" href="<?php echo $page >= $totalPages ? '#' : $mkUrl($next); ?>">下一页</a>
</li>
</ul>
</nav>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</section>
<footer>
<div class="container text-center">
<p>Copyright © 2026 <?php echo htmlspecialchars($siteInfo['companyname'] ?? ''); ?> | <?php echo htmlspecialchars($siteInfo['icp'] ?? ''); ?></p>
</div>
</footer>
<script src="<?php echo $themeBase; ?>/assets/js/bootstrap-5.0.0-beta1.min.js"></script>
</body>
</html>
@@ -1129,7 +1129,7 @@ p {
FOOTER-4 CSS
================================ */
.footer-style-4 {
background: #F3F3F3;
background: #000;
padding-top: 80px;
}
@@ -1164,7 +1164,7 @@ p {
.footer-style-4 .widget-wrapper .footer-widget h6 {
font-weight: 600;
color: #585978;
color: #fff;
margin-bottom: 35px;
margin-top: 10px;
}
@@ -1172,7 +1172,7 @@ p {
.footer-style-4 .widget-wrapper .footer-widget .links li a {
font-size: 16px;
line-height: 32px;
color: #585978;
color: #fff;
}
.footer-style-4 .widget-wrapper .footer-widget .links li a:hover {
@@ -1199,7 +1199,7 @@ p {
.footer-style-4 .widget-wrapper .footer-widget .download-app li a .text {
font-size: 14px;
font-weight: 500;
color: #585978;
color: #fff;
}
.footer-style-4 .widget-wrapper .footer-widget .download-app li a .text b {
+254 -165
View File
@@ -19,91 +19,126 @@ $host = $_SERVER['HTTP_HOST'] ?? '';
// 查询域名对应的租户ID
$tenantDomain = TenantDomain::where('full_domain', $host)
->where('status', 1)
->whereNull('delete_time')
->find();
->where('status', 1)
->whereNull('delete_time')
->find();
$tid = $tenantDomain ? (int)$tenantDomain['tid'] : 0;
$tid = $tenantDomain ? (int) $tenantDomain['tid'] : 0;
// 获取 Banner 数据
$banners = [];
if ($tid > 0) {
$banners = Banner::where('tid', $tid)
->whereNull('delete_time')
->order('sort', 'asc')
->order('id', 'desc')
->select()
->toArray();
$banners = Banner::where('tid', $tid)
->whereNull('delete_time')
->order('sort', 'asc')
->order('id', 'desc')
->select()
->toArray();
// 处理图片路径
foreach ($banners as &$banner) {
if (!empty($banner['image'])) {
if (!preg_match('/^https?:\/\//', $banner['image'])) {
$scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$banner['image'] = $scheme . '://' . $host .
(strpos($banner['image'], '/') === 0 ? '' : '/') . $banner['image'];
}
}
// 处理图片路径
foreach ($banners as &$banner) {
if (!empty($banner['image'])) {
if (!preg_match('/^https?:\/\//', $banner['image'])) {
$scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$banner['image'] = $scheme . '://' . $host .
(strpos($banner['image'], '/') === 0 ? '' : '/') . $banner['image'];
}
}
}
}
// 获取新闻数据
$articles = [];
if ($tid > 0) {
$articles = Articles::where('tid', $tid)
->where('delete_time', null)
->where('status', 2)
->order('publish_date', 'desc')
->limit(8)
->select()
->toArray();
$articles = Articles::where('tid', $tid)
->where('delete_time', null)
->where('status', 2)
->order('publish_date', 'desc')
->limit(8)
->select()
->toArray();
// 处理图片:如果文章image为空,则取分类的image
foreach ($articles as &$article) {
if (empty($article['image']) && !empty($article['cate'])) {
$category = ArticlesCategory::where('id', $article['cate'])
->where('delete_time', null)
->find();
if ($category && !empty($category['image'])) {
$article['image'] = $category['image'];
}
}
// 处理图片路径
if (!empty($article['image']) && !preg_match('/^https?:\/\//', $article['image'])) {
$scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$article['image'] = $scheme . '://' . $host .
(strpos($article['image'], '/') === 0 ? '' : '/') . $article['image'];
}
if (!empty($article['thumb']) && !preg_match('/^https?:\/\//', $article['thumb'])) {
$scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$article['thumb'] = $scheme . '://' . $host .
(strpos($article['thumb'], '/') === 0 ? '' : '/') . $article['thumb'];
}
// 处理图片:如果文章image为空,则取分类的image
foreach ($articles as &$article) {
if (empty($article['image']) && !empty($article['cate'])) {
$category = ArticlesCategory::where('id', $article['cate'])
->where('delete_time', null)
->find();
if ($category && !empty($category['image'])) {
$article['image'] = $category['image'];
}
}
// 处理图片路径
if (!empty($article['image']) && !preg_match('/^https?:\/\//', $article['image'])) {
$scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$article['image'] = $scheme . '://' . $host .
(strpos($article['image'], '/') === 0 ? '' : '/') . $article['image'];
}
if (!empty($article['thumb']) && !preg_match('/^https?:\/\//', $article['thumb'])) {
$scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$article['thumb'] = $scheme . '://' . $host .
(strpos($article['thumb'], '/') === 0 ? '' : '/') . $article['thumb'];
}
}
}
// 获取企业联系信息
// 获取企业联系信息和站点设置
$companyInfo = [];
if ($tid > 0) {
$companyInfo = Tenant::where('id', $tid)
->where('delete_time', null)
->field('contact_phone, contact_email, address, worktime')
->find();
}else{
// 获取租户信息
$tenant = Tenant::where('id', $tid)
->where('delete_time', null)
->field('contact_phone, contact_email, address, worktime')
->find();
// 获取站点设置
$siteSetting = \app\model\System\SystemSiteSetting::where('tid', $tid)
->where('delete_time', null)
->find();
$companyInfo = array_merge(
$tenant ? $tenant->toArray() : [],
$siteSetting ? $siteSetting->toArray() : []
);
} else {
$companyInfo = [
'contact_phone' => '-',
'contact_email' => '-',
'address' => '-',
'worktime' => '-'
'sitename' => '',
'logo' => '',
'logow' => '',
'ico' => '',
'description' => '',
'contact_phone' => '-',
'contact_email' => '-',
'address' => '-',
'worktime' => '-'
];
}
// 处理图片路径
if (!empty($companyInfo['logo']) && !preg_match('/^https?:\/\//', $companyInfo['logo'])) {
$scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$companyInfo['logo'] = $scheme . '://' . $host .
(strpos($companyInfo['logo'], '/') === 0 ? '' : '/') . $companyInfo['logo'];
}
if (!empty($companyInfo['logow']) && !preg_match('/^https?:\/\//', $companyInfo['logow'])) {
$scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$companyInfo['logow'] = $scheme . '://' . $host .
(strpos($companyInfo['logow'], '/') === 0 ? '' : '/') . $companyInfo['logow'];
}
if (!empty($companyInfo['ico']) && !preg_match('/^https?:\/\//', $companyInfo['ico'])) {
$scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
$companyInfo['ico'] = $scheme . '://' . $host .
(strpos($companyInfo['ico'], '/') === 0 ? '' : '/') . $companyInfo['ico'];
}
// 辅助函数:去除 HTML 标签
function stripHtml($html) {
if (empty($html)) return '';
$text = preg_replace('/<[^>]+>/', ' ', $html);
$text = preg_replace('/\s+/', ' ', $text);
return trim($text);
function stripHtml($html)
{
if (empty($html))
return '';
$text = preg_replace('/<[^>]+>/', ' ', $html);
$text = preg_replace('/\s+/', ' ', $text);
return trim($text);
}
?>
<!DOCTYPE html>
@@ -112,8 +147,11 @@ function stripHtml($html) {
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<title>Nova - Bootstrap 5 Template</title>
<meta name="description" content="" />
<title><?php echo !empty($companyInfo['sitename']) ? $companyInfo['sitename'] : '实例 - 云泽网模板'; ?></title>
<?php if (!empty($companyInfo['ico'])): ?>
<link rel="icon" href="<?php echo $companyInfo['ico']; ?>" type="image/x-icon" />
<?php endif; ?>
<meta name="description" content="<?php echo !empty($companyInfo['description']) ? $companyInfo['description'] : ''; ?>" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="assets/css/bootstrap-5.0.0-beta1.min.css" />
<link rel="stylesheet" href="assets/css/LineIcons.2.0.css" />
@@ -157,10 +195,12 @@ function stripHtml($html) {
<div class="row align-items-center">
<div class="col-lg-12">
<nav class="navbar navbar-expand-lg">
<a class="navbar-brand" href="index.html">
<img src="assets/img/logo/logo.svg" alt="Logo" />
<a class="navbar-brand" href="index.php">
<img src="<?php echo !empty($companyInfo['logo']) ? $companyInfo['logo'] : 'assets/img/logo/logo.svg'; ?>" alt="Logo" />
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent6" aria-controls="navbarSupportedContent6" aria-expanded="false" aria-label="Toggle navigation">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent6" aria-controls="navbarSupportedContent6"
aria-expanded="false" aria-label="Toggle navigation">
<span class="toggler-icon"></span>
<span class="toggler-icon"></span>
<span class="toggler-icon"></span>
@@ -172,17 +212,17 @@ function stripHtml($html) {
<a class="page-scroll active" href="#home">主页</a>
</li>
<li class="nav-item">
<a class="page-scroll" href="#feature">新闻中心</a>
<a class="page-scroll" href="#newsCenter">新闻中心</a>
</li>
<li class="nav-item">
<a class="page-scroll" href="#about">关于我们</a>
<a class="page-scroll" href="#aboutUs">关于我们</a>
</li>
<li class="nav-item">
<a class="page-scroll" href="#pricing">Pricing</a>
<a class="page-scroll" href="#services">特色业务</a>
</li>
<li class="nav-item">
<a class="page-scroll" href="#contact">联系我们</a>
<a class="page-scroll" href="#contactUs">联系我们</a>
</li>
</ul>
</div>
@@ -202,12 +242,15 @@ function stripHtml($html) {
<div class="swiper-button-prev"></div>
</div>
</section>
<section id="feature" class="feature-section feature-style-5">
<section id="newsCenter" class="feature-section feature-style-5">
<div class="container">
<div class="row justify-content-center">
<div class="col-xxl-5 col-xl-5 col-lg-7 col-md-8">
<div class="section-title text-center mb-60">
<div class="section-title text-center mb-60" style="display: flex;align-items: center;justify-content: center;">
<h3 class="mb-15 wow fadeInUp" data-wow-delay=".2s">新闻中心</h3>
<a href="/news/index.php" target="_blank">
<span style="font-size: 14px;margin-left: 50px;">Read More</span>
</a>
</div>
</div>
</div>
@@ -218,30 +261,18 @@ function stripHtml($html) {
</div>
</section>
<section id="about" class="about-section about-style-4">
<section id="aboutUs" class="about-section about-style-4">
<div class="container">
<div class="row align-items-center">
<div class="col-xl-5 col-lg-6">
<div class="about-content-wrapper">
<div class="section-title mb-30">
<h3 class="mb-25 wow fadeInUp" data-wow-delay=".2s">The future of designing starts here</h3>
<p class="wow fadeInUp" data-wow-delay=".3s">Stop wasting time and money designing and managing a website that doesnt get results. Happiness guaranteed,</p>
<h3 class="mb-25 wow fadeInUp" data-wow-delay=".2s">关于我们</h3>
<p class="wow fadeInUp" data-wow-delay=".3s">
<?php echo !empty($companyInfo['companyintroduction']) ? $companyInfo['companyintroduction'] : ''; ?>
</p>
</div>
<ul>
<li class="wow fadeInUp" data-wow-delay=".35s">
<i class="lni lni-checkmark-circle"></i>
Stop wasting time and money designing and managing a website that doesnt get results.
</li>
<li class="wow fadeInUp" data-wow-delay=".4s">
<i class="lni lni-checkmark-circle"></i>
Stop wasting time and money designing and managing.
</li>
<li class="wow fadeInUp" data-wow-delay=".45s">
<i class="lni lni-checkmark-circle"></i>
Stop wasting time and money designing and managing a website that doesnt get results.
</li>
</ul>
<a href="#0" class="button button-lg radius-10 wow fadeInUp" data-wow-delay=".5s">Learn More</a>
<!-- <a href="#0" class="button button-lg radius-10 wow fadeInUp" data-wow-delay=".5s">Learn More</a> -->
</div>
</div>
<div class="col-xl-7 col-lg-6">
@@ -252,13 +283,14 @@ function stripHtml($html) {
</div>
</div>
</section>
<section id="pricing" class="pricing-section pricing-style-4 bg-light">
<section id="services" class="pricing-section pricing-style-4 bg-light">
<div class="container">
<div class="row align-items-center">
<div class="col-xl-5 col-lg-6">
<div class="section-title mb-60">
<h3 class="mb-15 wow fadeInUp" data-wow-delay=".2s">特色业务</h3>
<p class="wow fadeInUp" data-wow-delay=".4s">我们始终以专业、高效、创新为核心,深耕行业多年,形成了独具优势的特色业务体系。凭借成熟的服务流程、过硬的技术实力与丰富的实战经验,为客户提供一站式、定制化解决方案。</p>
<p class="wow fadeInUp" data-wow-delay=".4s">
我们始终以专业、高效、创新为核心,深耕行业多年,形成了独具优势的特色业务体系。凭借成熟的服务流程、过硬的技术实力与丰富的实战经验,为客户提供一站式、定制化解决方案。</p>
</div>
</div>
<div class="col-xl-7 col-lg-6">
@@ -313,7 +345,7 @@ function stripHtml($html) {
</div>
</div>
</section>
<section id="contact" class="contact-section contact-style-3">
<section id="contactUs" class="contact-section contact-style-3">
<div class="container">
<div class="row justify-content-center">
<div class="col-xxl-5 col-xl-5 col-lg-7 col-md-10">
@@ -360,7 +392,8 @@ function stripHtml($html) {
</div>
<div class="col-md-12">
<div class="form-button">
<button type="submit" class="button" id="submitBtn"> <i class="lni lni-telegram-original"></i> 提交</button>
<button type="submit" class="button" id="submitBtn"> <i class="lni lni-telegram-original"></i>
提交</button>
</div>
</div>
</div>
@@ -384,29 +417,29 @@ function stripHtml($html) {
};
fetch('/index/requirement', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(res => res.json())
.then(result => {
if (result.code === 200) {
alert('提交成功!我们会尽快与您联系。');
document.getElementById('requirementForm').reset();
} else {
alert(result.msg || '提交失败,请稍后重试');
}
})
.catch(err => {
console.error('提交失败:', err);
alert('提交失败,请稍后重试');
})
.finally(() => {
submitBtn.disabled = false;
submitBtn.innerHTML = '<i class="lni lni-telegram-original"></i> 提交';
});
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(res => res.json())
.then(result => {
if (result.code === 200) {
alert('提交成功!我们会尽快与您联系。');
document.getElementById('requirementForm').reset();
} else {
alert(result.msg || '提交失败,请稍后重试');
}
})
.catch(err => {
console.error('提交失败:', err);
alert('提交失败,请稍后重试');
})
.finally(() => {
submitBtn.disabled = false;
submitBtn.innerHTML = '<i class="lni lni-telegram-original"></i> 提交';
});
});
</script>
@@ -416,52 +449,52 @@ function stripHtml($html) {
<div class="left-wrapper">
<div class="row">
<?php if (!empty($companyInfo['contact_phone'])): ?>
<div class="col-lg-12 col-md-6">
<div class="single-item">
<div class="icon">
<i class="lni lni-phone"></i>
</div>
<div class="text">
<p>+86 <?php echo htmlspecialchars($companyInfo['contact_phone']); ?></p>
<div class="col-lg-12 col-md-6">
<div class="single-item">
<div class="icon">
<i class="lni lni-phone"></i>
</div>
<div class="text">
<p>+86 <?php echo htmlspecialchars($companyInfo['contact_phone']); ?></p>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if (!empty($companyInfo['contact_email'])): ?>
<div class="col-lg-12 col-md-6">
<div class="single-item">
<div class="icon">
<i class="lni lni-envelope"></i>
</div>
<div class="text">
<p><?php echo htmlspecialchars($companyInfo['contact_email']); ?></p>
<div class="col-lg-12 col-md-6">
<div class="single-item">
<div class="icon">
<i class="lni lni-envelope"></i>
</div>
<div class="text">
<p><?php echo htmlspecialchars($companyInfo['contact_email']); ?></p>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if (!empty($companyInfo['address'])): ?>
<div class="col-lg-12 col-md-6">
<div class="single-item">
<div class="icon">
<i class="lni lni-map-marker"></i>
</div>
<div class="text">
<p><?php echo htmlspecialchars($companyInfo['address']); ?></p>
<div class="col-lg-12 col-md-6">
<div class="single-item">
<div class="icon">
<i class="lni lni-map-marker"></i>
</div>
<div class="text">
<p><?php echo htmlspecialchars($companyInfo['address']); ?></p>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if (!empty($companyInfo['worktime'])): ?>
<div class="col-lg-12 col-md-6">
<div class="single-item">
<div class="icon">
<i class="lni lni-timer"></i>
</div>
<div class="text">
<p><?php echo htmlspecialchars($companyInfo['worktime']); ?></p>
<div class="col-lg-12 col-md-6">
<div class="single-item">
<div class="icon">
<i class="lni lni-timer"></i>
</div>
<div class="text">
<p><?php echo htmlspecialchars($companyInfo['worktime']); ?></p>
</div>
</div>
</div>
</div>
<?php endif; ?>
</div>
@@ -492,9 +525,11 @@ function stripHtml($html) {
<div class="col-xl-3 col-lg-4 col-md-6">
<div class="footer-widget wow fadeInUp" data-wow-delay=".2s">
<div class="logo">
<a href="#0"> <img src="assets/img/logo/logo.svg" alt=""> </a>
<a href="#0"> <img src="<?php echo !empty($companyInfo['logow']) ? $companyInfo['logow'] : 'assets/img/logo/logo.svg'; ?>" alt=""> </a>
</div>
<p class="desc">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Facilisis nulla placerat amet amet congue.</p>
<p class="desc">
<?php echo !empty($companyInfo['description']) ? $companyInfo['description'] : ''; ?>
</p>
<ul class="socials">
<li> <a href="#0"> <i class="fa-brands fa-qq"></i> </a> </li>
<li> <a href="#0"> <i class="fa-brands fa-weixin"></i> </a> </li>
@@ -506,11 +541,11 @@ function stripHtml($html) {
<div class="footer-widget wow fadeInUp" data-wow-delay=".3s">
<h6>快捷链接</h6>
<ul class="links">
<li> <a href="#0">主页</a> </li>
<li> <a href="#0">关于我们</a> </li>
<li> <a href="#0">服务</a> </li>
<li> <a href="#0">客户评价</a> </li>
<li> <a href="#0">联系</a> </li>
<li> <a href="#home">主页</a> </li>
<li> <a href="#newsCenter">新闻中心</a> </li>
<li> <a href="#aboutUs">关于我们</a> </li>
<li> <a href="#services">特色业务</a> </li>
<li> <a href="#contactUs">联系我们</a> </li>
</ul>
</div>
</div>
@@ -564,6 +599,16 @@ function stripHtml($html) {
<script>
// API 接口地址配置
const API_BASE_URL = 'https://api.yunzer.cn';
// 主题 URL 前缀:优先从当前脚本路径推断;若脚本被路由到 /news 等,则回退到 /themes/default
const THEME_BASE_PATH = <?php
$scriptName = str_replace('\\', '/', $_SERVER['SCRIPT_NAME'] ?? '');
if ($scriptName && strpos($scriptName, '/themes/') !== false) {
$basePath = rtrim(dirname($scriptName), '/');
} else {
$basePath = '/themes/default';
}
echo json_encode($basePath);
?>;
// 加载 Banner 轮播图
function loadBanners() {
@@ -660,21 +705,39 @@ function stripHtml($html) {
return API_BASE_URL + (imagePath.startsWith('/') ? imagePath : '/' + imagePath);
}
// 加载友情链接
function loadFriendlinks() {
// 加载首页数据
function loadHomeData() {
const container = document.getElementById('friendlink-container');
if (!container) return;
fetch(API_BASE_URL + '/friendlinks')
fetch(API_BASE_URL + '/homeData')
.then(res => res.json())
.then(result => {
if (result.code !== 200 || !result.data || result.data.length === 0) {
if (result.code !== 200 || !result.data || !result.data.links || result.data.links.length === 0) {
container.innerHTML = '<div class="col-12 text-center"><p>暂无友情链接</p></div>';
return;
}
// 更新站点信息
if (result.data.normal) {
const n = result.data.normal;
if (n.sitename) document.title = n.sitename;
if (n.ico) {
const favicon = document.querySelector('link[rel="icon"]');
if (favicon) {
favicon.href = API_BASE_URL + (n.ico.startsWith('/') ? n.ico : '/' + n.ico);
} else {
const newFavicon = document.createElement('link');
newFavicon.rel = 'icon';
newFavicon.href = API_BASE_URL + (n.ico.startsWith('/') ? n.ico : '/' + n.ico);
newFavicon.type = 'image/x-icon';
document.head.appendChild(newFavicon);
}
}
}
let html = '';
result.data.forEach((item) => {
result.data.links.forEach((item) => {
const logoUrl = item.link_logo ? (item.link_logo.startsWith('http') ? item.link_logo : API_BASE_URL + item.link_logo) : '';
const linkName = item.link_name || '';
const linkUrl = item.link_url || '#';
@@ -697,13 +760,15 @@ function stripHtml($html) {
});
}
// 页面加载完成后执行
document.addEventListener('DOMContentLoaded', function() {
// 加载 Banner 轮播图
loadBanners();
// 加载友情链接
loadFriendlinks();
// 加载首页数据
loadHomeData();
// 加载新闻数据
const container = document.getElementById('news-container');
@@ -718,9 +783,16 @@ function stripHtml($html) {
return;
}
const newsList = result.list;
const showCount = 8; // 初始显示数量
const hasMore = newsList.length > showCount;
let html = '';
result.list.forEach((item, i) => {
// 只显示前 showCount 个新闻
const displayNews = hasMore ? newsList.slice(0, showCount) : newsList;
displayNews.forEach((item, i) => {
const title = item.title || '无标题';
let desc = item.summary || item.description || '';
// 去除 HTML 标签后截取
@@ -736,6 +808,7 @@ function stripHtml($html) {
'<div class="news-thumb-placeholder">暂无图片</div>';
html += '<div class="col-lg-3 col-md-6 mb-4">' +
'<a href="/news/article_detail.php?id=' + item.id + '" target="_blank" class="news-item-link">' +
'<div class="news-card wow fadeInUp" data-wow-delay=".2s">' +
'<div class="news-thumb-wrap">' +
thumbHtml +
@@ -745,9 +818,17 @@ function stripHtml($html) {
'<p class="news-desc">' + desc + '</p>' +
'</div>' +
'</div>' +
'</a>' +
'</div>';
});
// 如果有更多新闻,添加查看更多按钮
if (hasMore) {
html += '<div class="col-12 text-center mt-4">' +
'<a href="/news" class="btn btn-primary">查看更多</a>' +
'</div>';
}
container.innerHTML = html;
})
.catch(err => {
@@ -759,6 +840,14 @@ function stripHtml($html) {
<!-- Banner 轮播图样式 -->
<style>
.desc {
color: #fff;
}
.logo img {
width: 300px;
}
.banner-swiper {
width: 100%;
}