增加文章详情以及相关策略

This commit is contained in:
云泽网 committed 2025-05-10 00:46:45 +08:00
1 parent d5da3a6ea8
commit 426e583fc9
13 files changed
+7846 -4132

No files matched your search

+232
View File
@@ -0,0 +1,232 @@
<?php
/**
* 文章控制器
*/
namespace app\index\controller;
use app\index\controller\Base;
use think\facade\Db;
use think\facade\View;
use think\facade\Request;
class Article extends Base
{
// 文章列表页
public function list()
{
// 获取分类ID
$cateId = Request::param('cate/d', 0);
// 构建查询条件
$where = [
['delete_time', '=', null],
['status', '=', 1]
];
if ($cateId > 0) {
$where[] = ['cate', '=', $cateId];
}
// 获取文章列表
$articles = Db::table('yz_article')
->where($where)
->order('id DESC')
->paginate([
'list_rows' => 10,
'query' => Request::instance()->param()
]);
// 获取分类信息
$category = null;
if ($cateId > 0) {
$category = Db::table('yz_article_category')
->where('id', $cateId)
->where('delete_time', null)
->where('status', 3)
->find();
}
// 获取所有分类
$categories = Db::table('yz_article_category')
->where('delete_time', null)
->where('status', 3)
->select()
->toArray();
// 将变量传递给视图
View::assign([
'articles' => $articles,
'category' => $category,
'categories' => $categories
]);
return view('list');
}
// 文章详情页
public function detail()
{
$id = Request::param('id/d', 0);
$article = Db::table('yz_article')->where('id', $id)->find();
if (!$article) {
return json(['code' => 0, 'msg' => '文章不存在或已被删除']);
}
// 获取分类名称
$cateName = Db::table('yz_article_category')
->where('id', $article['cate'])
->value('name');
// 获取上一篇和下一篇文章
$prevArticle = Db::table('yz_article')
->where('id', '<', $id)
->where('delete_time', null)
->where('status', '<>', 3)
->order('id DESC')
->find();
$nextArticle = Db::table('yz_article')
->where('id', '>', $id)
->where('delete_time', null)
->where('status', '<>', 3)
->order('id ASC')
->find();
// 获取相关文章(同分类的其他文章)
$relatedArticles = Db::table('yz_article')
->where('cate', $article['cate'])
->where('id', '<>', $id)
->where('delete_time', null)
->where('status', '<>', 3)
->order('id DESC')
->limit(3)
->select()
->toArray();
// 获取评论列表
// $comments = Db::table('yz_article_comment')
// ->where('article_id', $id)
// ->where('delete_time', null)
// ->order('id DESC')
// ->select()
// ->toArray();
// 更新浏览量(使用Cookie和IP双重验证)
$ip = Request::ip();
$cookieKey = 'article_view_' . $id;
$viewCookie = Request::cookie($cookieKey);
View::assign([
'article' => $article,
'cateName' => $cateName,
'prevArticle' => $prevArticle,
'nextArticle' => $nextArticle,
'relatedArticles' => $relatedArticles,
// 'comments' => $comments
]);
return View::fetch();
}
// 文章点赞
public function like()
{
if (!Request::isAjax()) {
return json(['code' => 0, 'msg' => '非法请求']);
}
$id = Request::param('id/d', 0);
// 更新点赞数
$result = Db::table('yz_article')
->where('id', $id)
->where('delete_time', null)
->inc('likes', 1)
->update();
if ($result) {
return json(['code' => 1, 'msg' => '点赞成功']);
} else {
return json(['code' => 0, 'msg' => '点赞失败']);
}
}
// 提交评论
public function comment()
{
if (!Request::isAjax() || !Request::isPost()) {
return json(['code' => 0, 'msg' => '非法请求']);
}
$articleId = Request::param('article_id/d', 0);
$content = Request::param('content/s', '');
$parentId = Request::param('parent_id/d', 0);
if (empty($content)) {
return json(['code' => 0, 'msg' => '评论内容不能为空']);
}
// 检查文章是否存在
$article = Db::table('yz_article')
->where('id', $articleId)
->where('delete_time', null)
->where('status', 3)
->find();
if (!$article) {
return json(['code' => 0, 'msg' => '文章不存在或已被删除']);
}
// 添加评论
// $data = [
// 'article_id' => $articleId,
// 'content' => $content,
// 'parent_id' => $parentId,
// 'user_id' => $this->getUserId(),
// 'user_name' => $this->getUserName(),
// 'status' => 1,
// 'create_time' => time()
// ];
// $result = Db::table('yz_article_comment')->insert($data);
// if ($result) {
// return json(['code' => 1, 'msg' => '评论成功']);
// } else {
// return json(['code' => 0, 'msg' => '评论失败']);
// }
}
// 获取当前用户ID(示例方法,实际应根据您的用户系统实现)
private function getUserId()
{
// 这里应该返回当前登录用户的ID
return 1; // 示例返回值
}
// 获取当前用户名(示例方法,实际应根据您的用户系统实现)
private function getUserName()
{
// 这里应该返回当前登录用户的用户名
return '游客'; // 示例返回值
}
// 获取访问统计
public function viewStats()
{
$id = Request::param('id/d', 0);
// 获取总访问量
$totalViews = Db::table('yz_article')
->where('id', $id)
->value('views');
return json([
'code' => 1,
'data' => [
'total' => $totalViews
]
]);
}
}
+533
View File
@@ -0,0 +1,533 @@
{include file="component/head" /}
{include file="component/header-simple" /}
<div class="main">
<div class="location">
<div class="container">
<div class="location-item">
<a href="{:url('index/index/index')}">首页</a>
<span>></span>
<a href="{:url('index/article/index')}">技术文章</a>
</div>
</div>
</div>
<div class="article-detail-container">
<div class="article-header">
<h1 class="article-title">{$article.title}</h1>
<div class="article-meta">
<span class="article-author"><i class="fa fa-user"></i> {$article.author}</span>
<span class="article-date"><i class="fa fa-calendar"></i> {$article.create_time|date='Y-m-d H:i'}</span>
<span class="article-category"><i class="fa fa-folder"></i> {$cateName}</span>
<span class="article-views"><i class="fa fa-eye"></i> {$article.views} 阅读</span>
</div>
</div>
<div class="article-content">
{$article.content|raw}
</div>
<div class="article-tags">
<span class="tag-label">标签:</span>
{if !empty($article.tags)}
{foreach $article.tags as $tag}
<span class="tag-item">{$tag}</span>
{/foreach}
{else}
<span class="no-tags">暂无标签</span>
{/if}
</div>
<div class="article-actions">
<div class="action-item like-btn">
<i class="fa fa-thumbs-up"></i>
<span class="action-text">点赞</span>
<span class="action-count">{$article.likes|default=0}</span>
</div>
<div class="action-item share-btn">
<i class="fa fa-share-alt"></i>
<span class="action-text">分享</span>
</div>
</div>
<div class="article-navigation">
<div class="prev-article">
{if !empty($prevArticle)}
<a href="{:url('index/article/index', ['id' => $prevArticle.id])}">
<i class="fa fa-arrow-left"></i> 上一篇:{$prevArticle.title}
</a>
{else}
<span class="disabled"><i class="fa fa-arrow-left"></i> 没有上一篇了</span>
{/if}
</div>
<div class="next-article">
{if !empty($nextArticle)}
<a href="{:url('index/article/index', ['id' => $nextArticle.id])}">
下一篇:{$nextArticle.title} <i class="fa fa-arrow-right"></i>
</a>
{else}
<span class="disabled">没有下一篇了 <i class="fa fa-arrow-right"></i></span>
{/if}
</div>
</div>
<div class="related-articles">
<h3 class="related-title">相关推荐</h3>
<div class="related-list">
{if !empty($relatedArticles)}
{foreach $relatedArticles as $related}
<div class="related-item">
<a href="{:url('index/article/index', ['id' => $related.id])}">
<div class="related-image">
<img src="{$related.image}" alt="{$related.title}">
</div>
<div class="related-info">
<div class="related-item-title">{$related.title}</div>
<div class="related-item-desc">{$related.desc}</div>
</div>
</a>
</div>
{/foreach}
{else}
<div class="no-related">暂无相关文章</div>
{/if}
</div>
</div>
<!-- <div class="article-comments">
<h3 class="comments-title">评论区</h3>
<div class="comment-form">
<textarea placeholder="请输入您的评论..." class="comment-textarea"></textarea>
<button class="comment-submit">发表评论</button>
</div>
<div class="comment-list">
{if !empty($comments)}
{foreach $comments as $comment}
<div class="comment-item">
<div class="comment-avatar">
<img src="{$comment.avatar|default='/static/images/default-avatar.png'}" alt="用户头像">
</div>
<div class="comment-content">
<div class="comment-user">{$comment.username}</div>
<div class="comment-text">{$comment.content}</div>
<div class="comment-footer">
<span class="comment-time">{$comment.create_time|date='Y-m-d H:i'}</span>
<span class="comment-reply">回复</span>
</div>
</div>
</div>
{/foreach}
{else}
<div class="no-comments">暂无评论,快来抢沙发吧!</div>
{/if}
</div>
</div> -->
</div>
</div>
<!-- 返回顶部按钮 -->
<div class="go-to-top" id="goToTop">
<i class="layui-icon-up"></i>
</div>
{include file="component/footer" /}
<style>
.location {
max-width: 1000px;
margin: 30px auto;
}
.article-detail-container {
max-width: 1000px;
margin: 30px auto;
padding: 50px;
background: #fff;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
.article-header {
margin-bottom: 30px;
border-bottom: 1px solid #eee;
padding-bottom: 20px;
}
.article-title {
font-size: 28px;
font-weight: 700;
color: #333;
margin-bottom: 15px;
line-height: 1.4;
}
.article-meta {
display: flex;
flex-wrap: wrap;
gap: 20px;
color: #666;
font-size: 14px;
}
.article-meta span {
display: flex;
align-items: center;
}
.article-meta i {
margin-right: 5px;
}
.article-content {
line-height: 1.8;
color: #333;
font-size: 16px;
margin-bottom: 30px;
}
.article-content img {
max-width: 100%;
height: auto;
margin: 15px 0;
border-radius: 4px;
}
.article-tags {
margin: 20px 0;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.tag-label {
font-weight: bold;
margin-right: 10px;
}
.tag-item {
background: #f2f2f2;
padding: 4px 10px;
border-radius: 15px;
font-size: 12px;
margin-right: 8px;
color: #666;
}
.article-actions {
display: flex;
justify-content: center;
gap: 40px;
margin: 30px 0;
padding: 20px 0;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
}
.action-item {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
}
.action-item i {
font-size: 24px;
color: #666;
margin-bottom: 5px;
}
.action-text {
font-size: 14px;
color: #666;
}
.action-count {
font-size: 12px;
color: #999;
margin-top: 3px;
}
.article-navigation {
display: flex;
justify-content: space-between;
margin: 30px 0;
}
.prev-article,
.next-article {
max-width: 45%;
}
.prev-article a,
.next-article a {
color: #333;
text-decoration: none;
}
.prev-article a:hover,
.next-article a:hover {
color: #f57005;
}
.disabled {
color: #999;
}
.related-articles {
margin: 40px 0;
}
.related-title {
font-size: 20px;
font-weight: 600;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.related-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.related-item {
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: transform 0.3s;
}
.related-item:hover {
transform: translateY(-5px);
}
.related-item a {
text-decoration: none;
color: inherit;
}
.related-image img {
width: 100%;
height: 150px;
object-fit: cover;
}
.related-info {
padding: 10px;
}
.related-item-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 5px;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.related-item-desc {
font-size: 12px;
color: #666;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.article-comments {
margin-top: 40px;
}
.comments-title {
font-size: 20px;
font-weight: 600;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.comment-form {
margin-bottom: 30px;
}
.comment-textarea {
width: 100%;
height: 100px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
resize: none;
margin-bottom: 10px;
}
.comment-submit {
background: #f57005;
color: white;
border: none;
padding: 8px 20px;
border-radius: 4px;
cursor: pointer;
float: right;
}
.comment-item {
display: flex;
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 1px solid #eee;
}
.comment-avatar img {
width: 50px;
height: 50px;
border-radius: 50%;
margin-right: 15px;
}
.comment-content {
flex: 1;
}
.comment-user {
font-weight: 600;
margin-bottom: 5px;
}
.comment-text {
line-height: 1.6;
margin-bottom: 10px;
}
.comment-footer {
display: flex;
justify-content: space-between;
color: #999;
font-size: 12px;
}
.comment-reply {
cursor: pointer;
color: #f57005;
}
.no-comments,
.no-related,
.no-tags {
color: #999;
text-align: center;
padding: 20px;
}
@media (max-width: 768px) {
.article-title {
font-size: 24px;
}
.related-list {
grid-template-columns: repeat(1, 1fr);
}
.article-meta {
gap: 10px;
}
}
/* 返回顶部按钮样式 */
.go-to-top {
position: fixed;
right: 30px;
bottom: 30px;
width: 40px;
height: 40px;
background: #f57005;
color: #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
z-index: 1000;
}
.go-to-top.show {
opacity: 1;
visibility: visible;
}
.go-to-top:hover {
background: #e66600;
transform: translateY(-3px);
}
.go-to-top i {
font-size: 18px;
}
@media (max-width: 768px) {
.go-to-top {
right: 20px;
bottom: 20px;
width: 36px;
height: 36px;
}
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
// 点赞功能
const likeBtn = document.querySelector('.like-btn');
if (likeBtn) {
likeBtn.addEventListener('click', function () {
const articleId = '{$article.id}';
fetch('/index/article/like?id=' + articleId, {
method: 'POST'
})
.then(response => response.json())
.then(data => {
if (data.code === 1) {
const countElement = this.querySelector('.action-count');
let count = parseInt(countElement.textContent);
countElement.textContent = count + 1;
this.classList.add('liked');
this.style.color = '#f57005';
} else {
alert('点赞失败:' + data.msg);
}
})
.catch(error => {
console.error('点赞请求失败:', error);
});
});
}
// 返回顶部功能
const goToTop = document.getElementById('goToTop');
// 监听滚动事件
window.addEventListener('scroll', function() {
if (window.pageYOffset > 300) {
goToTop.classList.add('show');
} else {
goToTop.classList.remove('show');
}
});
// 点击返回顶部
goToTop.addEventListener('click', function() {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
});
</script>
{include file="component/foot" /}
+3
View File
@@ -0,0 +1,3 @@
</body>
</html>
+14
View File
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{$config['admin_name']}</title>
<link rel="stylesheet" href="__LAYUI__/css/layui.css">
<link rel="stylesheet" href="__CSS__/style.css">
<link rel="stylesheet" href="__CSS__/bootstrap.min.css">
<script src="__LAYUI__/layui.js" charset="utf-8"></script>
</head>
<body>
+114
View File
@@ -0,0 +1,114 @@
<div style="display: flex;flex-direction: column;">
<div class="topbar-one">
<div class="container">
<div style="width: 70%;">
<ul class="list-unstyled topbar-one__info">
<li class="topbar-one__info__item"><span class="topbar-one__info__icon fas fa-phone-alt"></span><a
href="tel:629-555-0129">(629) 555-0129</a></li>
<li class="topbar-one__info__item"><span class="topbar-one__info__icon fas fa-envelope"></span><a
href="mailto:info@example.com">info@example.com</a></li>
</ul>
</div>
<div class="topbar-one__social" style="width: 30%;">
<a href="https://facebook.com"><i class="fab fa-facebook-f"></i></a>
<a href="https://twitter.com"><i class="fab fa-twitter"></i></a>
<a href="https://instagram.com"><i class="fab fa-instagram"></i></a>
<a href="https://www.youtube.com/"><i class="fab fa-linkedin"></i></a>
</div>
</div>
</div>
<!-- 导航栏 -->
<div class="main-menu">
<div class="container">
<div class="main-menu__logo">
<a href="index.html"><img src="__IMAGES__/logo.png" width="186" alt="Logo"></a>
</div>
<div class="main-menu__nav">
<ul class="main-menu__list">
<li><a href="index.html">首页</a></li>
<li><a href="about.html">关于我们</a></li>
<li><a href="products.html">产品服务</a></li>
<li><a href="contact.html">联系我们</a></li>
</ul>
</div>
<div class="main-menu__right">
<a href="#" class="main-menu__search"><i class="layui-icon layui-icon-search"></i></a>
<a href="login.html" class="main-menu__login"><i class="layui-icon layui-icon-username"></i></a>
</div>
</div>
</div>
</div>
<!-- 固定导航 -->
<div class="sticky-nav" style="display: none;">
<div class="container">
<div class="sticky-nav__logo">
<a href="index.html"><img src="__IMAGES__/logo.png" width="150" alt="Logo"></a>
</div>
<div class="sticky-nav__menu">
<ul>
<li><a href="index.html">首页</a></li>
<li><a href="about.html">关于我们</a></li>
<li><a href="products.html">产品服务</a></li>
<li><a href="contact.html">联系我们</a></li>
</ul>
</div>
<div class="sticky-nav__right">
<a href="#" class="main-menu__search"><i class="layui-icon layui-icon-search"></i></a>
<a href="login.html" class="main-menu__login"><i class="layui-icon layui-icon-username"></i></a>
</div>
</div>
</div>
<script>
layui.use(['carousel', 'form'], function () {
var carousel = layui.carousel
, form = layui.form;
//图片轮播
carousel.render({
elem: '#test10'
, width: '100%'
, height: '86vh'
, interval: 4000
});
var $ = layui.$, active = {
set: function (othis) {
var THIS = 'layui-bg-normal'
, key = othis.data('key')
, options = {};
othis.css('background-color', '#5FB878').siblings().removeAttr('style');
options[key] = othis.data('value');
ins3.reload(options);
}
};
//监听开关
form.on('switch(autoplay)', function () {
ins3.reload({
autoplay: this.checked
});
});
$('.demoSet').on('keyup', function () {
var value = this.value
, options = {};
if (!/^\d+$/.test(value)) return;
options[this.name] = value;
ins3.reload(options);
});
// 监听滚动事件
$(window).scroll(function () {
var scrollTop = $(window).scrollTop();
if (scrollTop > 150) { // 当滚动超过150px时显示固定导航
$('.sticky-nav').fadeIn();
} else {
$('.sticky-nav').fadeOut();
}
});
});
</script>
+2 -2
View File
@@ -91,7 +91,7 @@
<div class="tab-content active" data-tab="all">
{foreach $articleList as $cateName => $articles}
{foreach $articles as $article}
<div class="opencourse product-item">
<div class="opencourse product-item" onclick="window.open('{:url('article/detail')}?id={$article.id}', '_blank')">
<div class="video">
<img src="{$article.image}" alt="" class="cover">
</div>
@@ -111,7 +111,7 @@
{foreach $articleList as $cateName => $articles}
<div class="tab-content" data-tab="{$cateName}">
{foreach $articles as $article}
<div class="opencourse product-item">
<div class="opencourse product-item" onclick="window.open('{:url('article/detail')}?id={$article.id}', '_blank')">
<div class="video">
<img src="{$article.image}" alt="" class="cover">
</div>
@@ -0,0 +1,17 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class CreateArticleViewTable extends Migrator
{
public function change()
{
$table = $this->table('yz_article_view', ['engine' => 'InnoDB', 'collation' => 'utf8mb4_unicode_ci']);
$table
->addColumn('article_id', 'integer', ['signed' => false, 'null' => false, 'comment' => '文章ID'])
->addColumn('ip', 'string', ['limit' => 50, 'null' => false, 'comment' => '访问IP'])
->addColumn('view_time', 'integer', ['signed' => false, 'null' => false, 'comment' => '访问时间'])
->addIndex(['article_id', 'ip', 'view_time'], ['name' => 'idx_article_ip_time'])
->create();
}
}
+6170 -4125
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -1 +1 @@
blockquote,body,button,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,input,li,ol,p,pre,td,textarea,th,ul{margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}a:active,a:hover{outline:0}img{display:inline-block;border:none;vertical-align:middle}li{list-style:none}table{border-collapse:collapse;border-spacing:0}h1,h2,h3,h4,h5,h6{font-weight:700}h5,h6{font-size:100%}button,input,select,textarea{font-size:100%}button,input,optgroup,option,select,textarea{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;outline:0}pre{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word}body{line-height:1.6;color:rgba(0,0,0,.85);font-size:14px;font-family:Helvetica Neue,Helvetica,PingFang SC,Tahoma,Arial,sans-serif}hr{height:0;line-height:0;margin:10px 0;padding:0;border:none;border-bottom:1px solid #eee;clear:both;overflow:hidden;background:0 0}a{color:#333;text-decoration:none}a cite{font-style:normal}.layui-border-box,.layui-border-box *{box-sizing:border-box}.layui-box,.layui-box *{box-sizing:content-box}.layui-clear{clear:both}.layui-clear:after{content:'\20';clear:both;display:block;height:0}.layui-clear-space{word-spacing:-5px}.layui-inline{position:relative;display:inline-block;vertical-align:middle}.layui-edge{position:relative;display:inline-block;vertical-align:middle;width:0;height:0;border-width:6px;border-style:dashed;border-color:transparent;overflow:hidden}.layui-edge-top{top:-4px;border-bottom-color:#999;border-bottom-style:solid}.layui-edge-right{border-left-color:#999;border-left-style:solid}.layui-edge-bottom{top:2px;border-top-color:#999;border-top-style:solid}.layui-edge-left{border-right-color:#999;border-right-style:solid}.layui-elip,.layui-ellip{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-disabled,.layui-icon,.layui-unselect{user-select:none}.layui-disabled,.layui-disabled:hover{color:#d2d2d2!important;cursor:not-allowed!important}.layui-circle{border-radius:100%}.layui-show{display:block!important}.layui-hide{display:none!important}.layui-show-v{visibility:visible!important}.layui-hide-v{visibility:hidden!important}@font-face{font-family:layui-icon;src:url(../font/iconfont.eot?v=293);src:url(../font/iconfont.eot?v=293#iefix) format('embedded-opentype'),url(../font/iconfont.woff2?v=293) format('woff2'),url(../font/iconfont.woff?v=293) format('woff'),url(../font/iconfont.ttf?v=293) format('truetype'),url(../font/iconfont.svg?v=293#layui-icon) format('svg')}.layui-icon{font-family:layui-icon!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.layui-icon-sound:before{content:"\e69d"}.layui-icon-bot:before{content:"\e7d6"}.layui-icon-leaf:before{content:"\e701"}.layui-icon-folder:before{content:"\eabe"}.layui-icon-folder-open:before{content:"\eac1"}.layui-icon-gitee:before{content:"\e69b"}.layui-icon-github:before{content:"\e6a7"}.layui-icon-disabled:before{content:"\e6cc"}.layui-icon-moon:before{content:"\e6c2"}.layui-icon-error:before{content:"\e693"}.layui-icon-success:before{content:"\e697"}.layui-icon-question:before{content:"\e699"}.layui-icon-lock:before{content:"\e69a"}.layui-icon-eye:before{content:"\e695"}.layui-icon-eye-invisible:before{content:"\e696"}.layui-icon-backspace:before{content:"\e694"}.layui-icon-tips-fill:before{content:"\eb2e"}.layui-icon-test:before{content:"\e692"}.layui-icon-clear:before{content:"\e788"}.layui-icon-heart-fill:before{content:"\e68f"}.layui-icon-light:before{content:"\e748"}.layui-icon-music:before{content:"\e690"}.layui-icon-time:before{content:"\e68d"}.layui-icon-ie:before{content:"\e7bb"}.layui-icon-firefox:before{content:"\e686"}.layui-icon-at:before{content:"\e687"}.layui-icon-bluetooth:before{content:"\e689"}.layui-icon-chrome:before{content:"\e68a"}.layui-icon-edge:before{content:"\e68b"}.layui-icon-heart:before{content:"\e68c"}.layui-icon-key:before{content:"\e683"}.layui-icon-android:before{content:"\e684"}.layui-icon-mike:before{content:"\e6dc"}.layui-icon-mute:before{content:"\e685"}.layui-icon-gift:before{content:"\e627"}.layui-icon-windows:before{content:"\e67f"}.layui-icon-ios:before{content:"\e680"}.layui-icon-logout:before{content:"\e682"}.layui-icon-wifi:before{content:"\e7e0"}.layui-icon-rss:before{content:"\e808"}.layui-icon-email:before{content:"\e618"}.layui-icon-reduce-circle:before{content:"\e616"}.layui-icon-transfer:before{content:"\e691"}.layui-icon-service:before{content:"\e626"}.layui-icon-addition:before{content:"\e624"}.layui-icon-subtraction:before{content:"\e67e"}.layui-icon-slider:before{content:"\e714"}.layui-icon-print:before{content:"\e66d"}.layui-icon-export:before{content:"\e67d"}.layui-icon-cols:before{content:"\e610"}.layui-icon-screen-full:before{content:"\e622"}.layui-icon-screen-restore:before{content:"\e758"}.layui-icon-rate-half:before{content:"\e6c9"}.layui-icon-rate-solid:before{content:"\e67a"}.layui-icon-rate:before{content:"\e67b"}.layui-icon-cellphonLine truncated
blockquote,body,button,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,input,li,ol,p,pre,td,textarea,th,ul{margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}a:active,a:hover{outline:0}img{display:inline-block;border:none;vertical-align:middle}li{list-style:none}table{border-collapse:collapse;border-spacing:0}h1,h2,h3,h4,h5,h6{font-weight:700}h5,h6{font-size:100%}button,input,select,textarea{font-size:100%}button,input,optgroup,option,select,textarea{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;outline:0}pre{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word}body{line-height:1.6;color:rgba(0,0,0,.85);font-size:14px;font-family:Helvetica Neue,Helvetica,PingFang SC,Tahoma,Arial,sans-serif}hr{height:0;line-height:0;margin:10px 0;padding:0;border:none;border-bottom:1px solid #eee;clear:both;overflow:hidden;background:0 0}a{color:#333;text-decoration:none}a cite{font-style:normal}.layui-border-box,.layui-border-box *{box-sizing:border-box}.layui-box,.layui-box *{box-sizing:content-box}.layui-clear{clear:both}.layui-clear:after{content:'\20';clear:both;display:block;height:0}.layui-clear-space{word-spacing:-5px}.layui-inline{position:relative;display:inline-block;vertical-align:middle}.layui-edge{position:relative;display:inline-block;vertical-align:middle;width:0;height:0;border-width:6px;border-style:dashed;border-color:transparent;overflow:hidden}.layui-edge-top{top:-4px;border-bottom-color:#999;border-bottom-style:solid}.layui-edge-right{border-left-color:#999;border-left-style:solid}.layui-edge-bottom{top:2px;border-top-color:#999;border-top-style:solid}.layui-edge-left{border-right-color:#999;border-right-style:solid}.layui-elip,.layui-ellip{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-disabled,.layui-icon,.layui-unselect{user-select:none}.layui-disabled,.layui-disabled:hover{color:#d2d2d2!important;cursor:not-allowed!important}.layui-circle{border-radius:100%}.layui-show{display:block!important}.layui-hide{display:none!important}.layui-show-v{visibility:visible!important}.layui-hide-v{visibility:hidden!important}@font-face{font-family:layui-icon;src:url(../font/iconfont.eot?v=293);src:url(../font/iconfont.eot?v=293#iefix) format('embedded-opentype'),url(../font/iconfont.woff2?v=293) format('woff2'),url(../font/iconfont.woff?v=293) format('woff'),url(../font/iconfont.ttf?v=293) format('truetype'),url(../font/iconfont.svg?v=293#layui-icon) format('svg')}.layui-icon{font-family:layui-icon!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.layui-icon-sound:before{content:"\e69d"}.layui-icon-bot:before{content:"\e7d6"}.layui-icon-leaf:before{content:"\e701"}.layui-icon-folder:before{content:"\eabe"}.layui-icon-folder-open:before{content:"\eac1"}.layui-icon-gitee:before{content:"\e69b"}.layui-icon-github:before{content:"\e6a7"}.layui-icon-disabled:before{content:"\e6cc"}.layui-icon-moon:before{content:"\e6c2"}.layui-icon-error:before{content:"\e693"}.layui-icon-success:before{content:"\e697"}.layui-icon-question:before{content:"\e699"}.layui-icon-lock:before{content:"\e69a"}.layui-icon-eye:before{content:"\e695"}.layui-icon-eye-invisible:before{content:"\e696"}.layui-icon-backspace:before{content:"\e694"}.layui-icon-tips-fill:before{content:"\eb2e"}.layui-icon-test:before{content:"\e692"}.layui-icon-clear:before{content:"\e788"}.layui-icon-heart-fill:before{content:"\e68f"}.layui-icon-light:before{content:"\e748"}.layui-icon-music:before{content:"\e690"}.layui-icon-time:before{content:"\e68d"}.layui-icon-ie:before{content:"\e7bb"}.layui-icon-firefox:before{content:"\e686"}.layui-icon-at:before{content:"\e687"}.layui-icon-bluetooth:before{content:"\e689"}.layui-icon-chrome:before{content:"\e68a"}.layui-icon-edge:before{content:"\e68b"}.layui-icon-heart:before{content:"\e68c"}.layui-icon-key:before{content:"\e683"}.layui-icon-android:before{content:"\e684"}.layui-icon-mike:before{content:"\e6dc"}.layui-icon-mute:before{content:"\e685"}.layui-icon-gift:before{content:"\e627"}.layui-icon-windows:before{content:"\e67f"}.layui-icon-ios:before{content:"\e680"}.layui-icon-logout:before{content:"\e682"}.layui-icon-wifi:before{content:"\e7e0"}.layui-icon-rss:before{content:"\e808"}.layui-icon-email:before{content:"\e618"}.layui-icon-reduce-circle:before{content:"\e616"}.layui-icon-transfer:before{content:"\e691"}.layui-icon-service:before{content:"\e626"}.layui-icon-addition:before{content:"\e624"}.layui-icon-subtraction:before{content:"\e67e"}.layui-icon-slider:before{content:"\e714"}.layui-icon-print:before{content:"\e66d"}.layui-icon-export:before{content:"\e67d"}.layui-icon-cols:before{content:"\e610"}.layui-icon-screen-full:before{content:"\e622"}.layui-icon-screen-restore:before{content:"\e758"}.layui-icon-rate-half:before{content:"\e6c9"}.layui-icon-rate-solid:before{content:"\e67a"}.layui-icon-rate:before{content:"\e67b"}.layui-icon-cellphonLine truncated
+1 -1
View File
@@ -1 +1 @@
/** v2.11.0 | MIT Licensed */;!function(h){"use strict";var e,d=h.document,v=h.location,m={timeout:10,debug:!1,version:!1},g={modules:{},status:{},event:{},callback:{}},r=function(){this.v="2.11.0"},t=h.LAYUI_GLOBAL||{},b=(e=d.currentScript&&"SCRIPT"===d.currentScript.tagName.toUpperCase()?d.currentScript.src:function(){for(var e,t=d.getElementsByTagName("script"),n=t.length-1,r=n;0<r;r--)if("interactive"===t[r].readyState){e=t[r].src;break}return e||t[n].src}(),m.dir=t.dir||e.substring(0,e.lastIndexOf("/")+1)),j=function(e,t){t=t||"log",h.console&&console[t]&&console[t]("layui error hint: "+e)},E=m.builtin={lay:"lay",layer:"layer",laydate:"laydate",laypage:"laypage",laytpl:"laytpl",form:"form",upload:"upload",dropdown:"dropdown",transfer:"transfer",tree:"tree",table:"table",treeTable:"treeTable",tabs:"tabs",element:"element",rate:"rate",colorpicker:"colorpicker",slider:"slider",carousel:"carousel",flow:"flow",util:"util",code:"code",jquery:"jquery",component:"component",all:"all","layui.all":"layui.all"},N=("function"!=typeof Object.assign&&(Object.assign=function(e){var t=Object(e);if(!(arguments.length<2))for(var n=1;n<arguments.length;n++){var r=arguments[n];if(r!==undefined&&null!==r)for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(t[o]=r[o])}return t}),function(e,t,n){var r=function(e){"load"!==e.type&&!/^(complete|loaded)$/.test((e.currentTarget||e.srcElement).readyState)||(a(),"function"!=typeof t)||t(e)},o=function(e){a(),"function"==typeof n&&n(e)},a=function(){e.detachEvent?e.detachEvent("onreadystatechange",r):(e.removeEventListener("load",r,!1),e.removeEventListener("error",o,!1))};!e.attachEvent||e.attachEvent.toString&&e.attachEvent.toString().indexOf("[native code")<0?(e.addEventListener("load",r,!1),e.addEventListener("error",o,!1)):e.attachEvent("onreadystatechange",r)}),l=(r.prototype.cache=Object.assign(m,g),r.prototype.config=function(e){return Object.assign(m,e),this},r.prototype.define=function(e,r){return"function"==typeof e&&(r=e,e=[]),this.use(e,function(){var n=function(e,t){layui[e]=t,g.status[e]=!0};return"function"==typeof r&&r(function(e,t){n(e,t),g.callback[e]=function(){r(n)}}),this},null,"define"),this},r.prototype.use=function(n,e,t,r){var o,a,i,u,c,l,s,p,f=this,y=m.dir=m.dir||b;return n="string"==typeof n?[n]:"function"==typeof n?(e=n,["all"]):n,m.host||(m.host=(y.match(/\/\/([\s\S]+?)\//)||["//"+v.host+"/"])[0]),n&&(h.jQuery&&jQuery.fn.on&&(f.each(n,function(e,t){"jquery"===t&&n.splice(e,1)}),layui.jquery=layui.$=h.jQuery),t=t||[],o=n[0],a=f.modules[o],i="object"==typeof a,u=function(){t.push(layui[o]),1<n.length?f.use(n.slice(1),e,t,r):"function"==typeof e&&(layui.jquery&&"function"==typeof layui.jquery&&"define"!==r?layui.jquery(function(){e.apply(layui,t)}):e.apply(layui,t))},c=function(){var e=0;!function t(){return++e>1e3*m.timeout/5?j(o+" is not a valid module","error"):void((i?layui[o]=h[a.api]:g.status[o])?u():setTimeout(t,5))}()},0===n.length||layui["layui.all"]&&E[o]?u():(p=i?a.src:a,y=(E[o]?y+"modules/":p?"":m.base)+(p=(p=p||o).replace(/\s/g,"").replace(/\.js[^\/\.]*$/,""))+".js",!g.modules[o]&&layui[o]&&(g.modules[o]=y),g.modules[o]?c():(l=d.getElementsByTagName("head")[0],(s=d.createElement("script"))["async"]=!0,s.charset="utf-8",s.src=y+((p=!0===m.version?m.v||(new Date).getTime():m.version||"")?"?v="+p:""),l.appendChild(s),N(s,function(){l.removeChild(s),c()},function(){l.removeChild(s)}),g.modules[o]=y))),f},r.prototype.modules=Object.assign({},E),r.prototype.extend=function(e){var t,n,r=m.base||"",o=/^\{\/\}/;for(t in e=e||{})this[t]||this.modules[t]?j("the "+t+" module already exists, extend failure"):("string"==typeof(n=e[t])&&(n=((r=o.test(n)?"":r)+n).replace(o,"")),this.modules[t]=n);return this},r.prototype.disuse=function(e){var n=this;return e=n.isArray(e)?e:[e],n.each(e,function(e,t){delete n[t],delete E[t],delete n.modules[t],delete g.status[t],delete g.modules[t]}),n},r.prototype.getStyle=function(e,t){e=e.currentStyle||h.getComputedStyle(e,null);return e.getPropertyValue?e.getPropertyValue(t):e.getAttribute(t.replace(/-(\w)/g,function(e,t){return t?t.toUpperCase():""}))},r.prototype.link=function(n,r,o){var a,i=this,e=d.getElementsByTagName("head")[0],t="function"==typeof r;if("string"==typeof r&&(o=r),"object"==typeof n)return a="array"===i.type(o),i.each(n,function(e,t){i.link(t,e===n.length-1&&r,a&&o[e])});o="layuicss-"+(o=o||n.replace(/^(#|(http(s?)):\/\/|\/\/)|\.|\/|\?.+/g,""));var u=d.getElementById(o);return u||((u=d.createElement("link")).href=n+(m.debug?"?v="+(new Date).getTime():""),u.rel="stylesheet",u.id=o,e.appendChild(u)),"complete"===u.__lay_readyState__?t&&r(u):N(u,function(){u.__lay_readyState__="complete",t&&r(u)},function(){j(n+" load error","error"),e.removeChild(u)}),i},r.prototype.addcss=function(e,t,n){return layui.link(m.dir+"css/"+e,t,n)},r.prototype.factory=function(e){if(layui[e])return"function"==typeof m.callback[e]?m.callback[e]:null},r.prototype.img=function(e,t,n){var r=new Image;if(r.src=e,r.completLine truncated
/** v2.11.1 | MIT Licensed */;!function(h){"use strict";var e,d=h.document,v=h.location,m={timeout:10,debug:!1,version:!1},g={modules:{},status:{},event:{},callback:{}},r=function(){this.v="2.11.1"},t=h.LAYUI_GLOBAL||{},b=(e=d.currentScript&&"SCRIPT"===d.currentScript.tagName.toUpperCase()?d.currentScript.src:function(){for(var e,t=d.getElementsByTagName("script"),n=t.length-1,r=n;0<r;r--)if("interactive"===t[r].readyState){e=t[r].src;break}return e||t[n].src}(),m.dir=t.dir||e.substring(0,e.lastIndexOf("/")+1)),j=function(e,t){t=t||"log",h.console&&console[t]&&console[t]("layui error hint: "+e)},E=m.builtin={lay:"lay",layer:"layer",laydate:"laydate",laypage:"laypage",laytpl:"laytpl",form:"form",upload:"upload",dropdown:"dropdown",transfer:"transfer",tree:"tree",table:"table",treeTable:"treeTable",tabs:"tabs",element:"element",rate:"rate",colorpicker:"colorpicker",slider:"slider",carousel:"carousel",flow:"flow",util:"util",code:"code",jquery:"jquery",component:"component",all:"all","layui.all":"layui.all"},N=("function"!=typeof Object.assign&&(Object.assign=function(e){var t=Object(e);if(!(arguments.length<2))for(var n=1;n<arguments.length;n++){var r=arguments[n];if(r!==undefined&&null!==r)for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(t[o]=r[o])}return t}),function(e,t,n){var r=function(e){"load"!==e.type&&!/^(complete|loaded)$/.test((e.currentTarget||e.srcElement).readyState)||(a(),"function"!=typeof t)||t(e)},o=function(e){a(),"function"==typeof n&&n(e)},a=function(){e.detachEvent?e.detachEvent("onreadystatechange",r):(e.removeEventListener("load",r,!1),e.removeEventListener("error",o,!1))};!e.attachEvent||e.attachEvent.toString&&e.attachEvent.toString().indexOf("[native code")<0?(e.addEventListener("load",r,!1),e.addEventListener("error",o,!1)):e.attachEvent("onreadystatechange",r)}),l=(r.prototype.cache=Object.assign(m,g),r.prototype.config=function(e){return Object.assign(m,e),this},r.prototype.define=function(e,r){return"function"==typeof e&&(r=e,e=[]),this.use(e,function(){var n=function(e,t){layui[e]=t,g.status[e]=!0};return"function"==typeof r&&r(function(e,t){n(e,t),g.callback[e]=function(){r(n)}}),this},null,"define"),this},r.prototype.use=function(n,e,t,r){var o,a,i,u,c,l,s,p,f=this,y=m.dir=m.dir||b;return n="string"==typeof n?[n]:"function"==typeof n?(e=n,["all"]):n,m.host||(m.host=(y.match(/\/\/([\s\S]+?)\//)||["//"+v.host+"/"])[0]),n&&(h.jQuery&&jQuery.fn.on&&(f.each(n,function(e,t){"jquery"===t&&n.splice(e,1)}),layui.jquery=layui.$=h.jQuery),t=t||[],o=n[0],a=f.modules[o],i="object"==typeof a,u=function(){t.push(layui[o]),1<n.length?f.use(n.slice(1),e,t,r):"function"==typeof e&&(layui.jquery&&"function"==typeof layui.jquery&&"define"!==r?layui.jquery(function(){e.apply(layui,t)}):e.apply(layui,t))},c=function(){var e=0;!function t(){return++e>1e3*m.timeout/5?j(o+" is not a valid module","error"):void((i?layui[o]=h[a.api]:g.status[o])?u():setTimeout(t,5))}()},0===n.length||layui["layui.all"]&&E[o]?u():(p=i?a.src:a,y=(E[o]?y+"modules/":p?"":m.base)+(p=(p=p||o).replace(/\s/g,"").replace(/\.js[^\/\.]*$/,""))+".js",!g.modules[o]&&layui[o]&&(g.modules[o]=y),g.modules[o]?c():(l=d.getElementsByTagName("head")[0],(s=d.createElement("script"))["async"]=!0,s.charset="utf-8",s.src=y+((p=!0===m.version?m.v||(new Date).getTime():m.version||"")?"?v="+p:""),l.appendChild(s),N(s,function(){l.removeChild(s),c()},function(){l.removeChild(s)}),g.modules[o]=y))),f},r.prototype.modules=Object.assign({},E),r.prototype.extend=function(e){var t,n,r=m.base||"",o=/^\{\/\}/;for(t in e=e||{})this[t]||this.modules[t]?j("the "+t+" module already exists, extend failure"):("string"==typeof(n=e[t])&&(n=((r=o.test(n)?"":r)+n).replace(o,"")),this.modules[t]=n);return this},r.prototype.disuse=function(e){var n=this;return e=n.isArray(e)?e:[e],n.each(e,function(e,t){delete n[t],delete E[t],delete n.modules[t],delete g.status[t],delete g.modules[t]}),n},r.prototype.getStyle=function(e,t){e=e.currentStyle||h.getComputedStyle(e,null);return e.getPropertyValue?e.getPropertyValue(t):e.getAttribute(t.replace(/-(\w)/g,function(e,t){return t?t.toUpperCase():""}))},r.prototype.link=function(n,r,o){var a,i=this,e=d.getElementsByTagName("head")[0],t="function"==typeof r;if("string"==typeof r&&(o=r),"object"==typeof n)return a="array"===i.type(o),i.each(n,function(e,t){i.link(t,e===n.length-1&&r,a&&o[e])});o="layuicss-"+(o=o||n.replace(/^(#|(http(s?)):\/\/|\/\/)|\.|\/|\?.+/g,""));var u=d.getElementById(o);return u||((u=d.createElement("link")).href=n+(m.debug?"?v="+(new Date).getTime():""),u.rel="stylesheet",u.id=o,e.appendChild(u)),"complete"===u.__lay_readyState__?t&&r(u):N(u,function(){u.__lay_readyState__="complete",t&&r(u)},function(){j(n+" load error","error"),e.removeChild(u)}),i},r.prototype.addcss=function(e,t,n){return layui.link(m.dir+"css/"+e,t,n)},r.prototype.factory=function(e){if(layui[e])return"function"==typeof m.callback[e]?m.callback[e]:null},r.prototype.img=function(e,t,n){var r=new Image;if(r.src=e,r.completLine truncated
@@ -1,4 +1,4 @@
<?php /*a:4:{s:49:"E:\Demo\PHP\yunzer\app\index\view\index\index.php";i:1746796639;s:54:"E:\Demo\PHP\yunzer\app\index\view\component\header.php";i:1746796639;s:52:"E:\Demo\PHP\yunzer\app\index\view\component\main.php";i:1746805815;s:54:"E:\Demo\PHP\yunzer\app\index\view\component\footer.php";i:1746796639;}*/ ?>
<?php /*a:4:{s:49:"E:\Demo\PHP\yunzer\app\index\view\index\index.php";i:1746796639;s:54:"E:\Demo\PHP\yunzer\app\index\view\component\header.php";i:1746796639;s:52:"E:\Demo\PHP\yunzer\app\index\view\component\main.php";i:1746806638;s:54:"E:\Demo\PHP\yunzer\app\index\view\component\footer.php";i:1746796639;}*/ ?>
<!DOCTYPE html>
<html>
@@ -264,7 +264,7 @@ layui.use(['carousel', 'form'], function(){
<!-- 全部文章 -->
<div class="tab-content active" data-tab="all">
<?php foreach($articleList as $cateName => $articles): foreach($articles as $article): ?>
<div class="opencourse product-item">
<div class="opencourse product-item" onclick="window.open('<?php echo url('article/detail'); ?>?id=<?php echo htmlentities((string) $article['id']); ?>', '_blank')">
<div class="video">
<img src="<?php echo htmlentities((string) $article['image']); ?>" alt="" class="cover">
</div>
@@ -284,7 +284,7 @@ layui.use(['carousel', 'form'], function(){
<?php foreach($articleList as $cateName => $articles): ?>
<div class="tab-content" data-tab="<?php echo htmlentities((string) $cateName); ?>">
<?php foreach($articles as $article): ?>
<div class="opencourse product-item">
<div class="opencourse product-item" onclick="window.open('<?php echo url('article/detail'); ?>?id=<?php echo htmlentities((string) $article['id']); ?>', '_blank')">
<div class="video">
<img src="<?php echo htmlentities((string) $article['image']); ?>" alt="" class="cover">
</div>
@@ -0,0 +1,49 @@
<?php /*a:1:{s:46:"E:\Demo\PHP\yunzer\app/tpl/think_exception.tpl";i:1745855804;}*/ ?>
<html lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>跳转提示</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">
*{box-sizing:border-box;margin:0;padding:0;font-family:Lantinghei SC,Open Sans,Arial,Hiragino Sans GB,Microsoft YaHei,"微软雅黑",STHeiti,WenQuanYi Micro Hei,SimSun,sans-serif;-webkit-font-smoothing:antialiased}
body{padding:70px 0;background:#edf1f4;font-weight:400;font-size:1pc;-webkit-text-size-adjust:none;color:#333}
a{outline:0;color:#3498db;text-decoration:none;cursor:pointer}
.system-message{margin:20px 5%;padding:40px 20px;background:#fff;box-shadow:1px 1px 1px hsla(0,0%,39%,.1);text-align:center}
.system-message h1{margin:0;margin-bottom:9pt;color:#444;font-weight:400;font-size:40px}
.system-message .jump,.system-message .image{margin:20px 0;padding:0;padding:10px 0;font-weight:400}
.system-message .jump{font-size:14px}
.system-message .jump a{color:#333}
.system-message p{font-size:9pt;line-height:20px}
.system-message .btn{display:inline-block;margin-right:10px;width:138px;height:2pc;border:1px solid #44a0e8;border-radius:30px;color:#44a0e8;text-align:center;font-size:1pc;line-height:2pc;margin-bottom:5px;}
.success .btn{border-color:#69bf4e;color:#69bf4e}
.error .btn{border-color:#ff8992;color:#ff8992}
.info .btn{border-color:#3498db;color:#3498db}
.copyright p{width:100%;color:#919191;text-align:center;font-size:10px}
.system-message .btn-grey{border-color:#bbb;color:#bbb}
.clearfix:after{clear:both;display:block;visibility:hidden;height:0;content:"."}
@media (max-width:768px){body {padding:20px 0;}}
@media (max-width:480px){.system-message h1{font-size:30px;}}
</style>
</head>
<body>
<div class="system-message">
<?php
switch ($code){
case 1:
?>
<h2>
<?php
echo (strip_tags($msg));
break;
case 0:
?>
<h2>
<?php
echo (strip_tags($msg));
break;
}
?>
</h2>
</div>
</body>
</html>
@@ -0,0 +1,707 @@
<?php /*a:5:{s:52:"E:\Demo\PHP\yunzer\app\index\view\article\detail.php";i:1746808591;s:52:"E:\Demo\PHP\yunzer\app\index\view\component\head.php";i:1746808024;s:61:"E:\Demo\PHP\yunzer\app\index\view\component\header-simple.php";i:1746808182;s:54:"E:\Demo\PHP\yunzer\app\index\view\component\footer.php";i:1746796639;s:52:"E:\Demo\PHP\yunzer\app\index\view\component\foot.php";i:1746808046;}*/ ?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo htmlentities((string) $config['admin_name']); ?></title>
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/css/style.css">
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
<script src="/static/layui/layui.js" charset="utf-8"></script>
</head>
<body>
<div style="display: flex;flex-direction: column;">
<div class="topbar-one">
<div class="container">
<div style="width: 70%;">
<ul class="list-unstyled topbar-one__info">
<li class="topbar-one__info__item"><span class="topbar-one__info__icon fas fa-phone-alt"></span><a
href="tel:629-555-0129">(629) 555-0129</a></li>
<li class="topbar-one__info__item"><span class="topbar-one__info__icon fas fa-envelope"></span><a
href="mailto:info@example.com">info@example.com</a></li>
</ul>
</div>
<div class="topbar-one__social" style="width: 30%;">
<a href="https://facebook.com"><i class="fab fa-facebook-f"></i></a>
<a href="https://twitter.com"><i class="fab fa-twitter"></i></a>
<a href="https://instagram.com"><i class="fab fa-instagram"></i></a>
<a href="https://www.youtube.com/"><i class="fab fa-linkedin"></i></a>
</div>
</div>
</div>
<!-- 导航栏 -->
<div class="main-menu">
<div class="container">
<div class="main-menu__logo">
<a href="index.html"><img src="/static/images/logo.png" width="186" alt="Logo"></a>
</div>
<div class="main-menu__nav">
<ul class="main-menu__list">
<li><a href="index.html">首页</a></li>
<li><a href="about.html">关于我们</a></li>
<li><a href="products.html">产品服务</a></li>
<li><a href="contact.html">联系我们</a></li>
</ul>
</div>
<div class="main-menu__right">
<a href="#" class="main-menu__search"><i class="layui-icon layui-icon-search"></i></a>
<a href="login.html" class="main-menu__login"><i class="layui-icon layui-icon-username"></i></a>
</div>
</div>
</div>
</div>
<!-- 固定导航 -->
<div class="sticky-nav" style="display: none;">
<div class="container">
<div class="sticky-nav__logo">
<a href="index.html"><img src="/static/images/logo.png" width="150" alt="Logo"></a>
</div>
<div class="sticky-nav__menu">
<ul>
<li><a href="index.html">首页</a></li>
<li><a href="about.html">关于我们</a></li>
<li><a href="products.html">产品服务</a></li>
<li><a href="contact.html">联系我们</a></li>
</ul>
</div>
<div class="sticky-nav__right">
<a href="#" class="main-menu__search"><i class="layui-icon layui-icon-search"></i></a>
<a href="login.html" class="main-menu__login"><i class="layui-icon layui-icon-username"></i></a>
</div>
</div>
</div>
<script>
layui.use(['carousel', 'form'], function () {
var carousel = layui.carousel
, form = layui.form;
//图片轮播
carousel.render({
elem: '#test10'
, width: '100%'
, height: '86vh'
, interval: 4000
});
var $ = layui.$, active = {
set: function (othis) {
var THIS = 'layui-bg-normal'
, key = othis.data('key')
, options = {};
othis.css('background-color', '#5FB878').siblings().removeAttr('style');
options[key] = othis.data('value');
ins3.reload(options);
}
};
//监听开关
form.on('switch(autoplay)', function () {
ins3.reload({
autoplay: this.checked
});
});
$('.demoSet').on('keyup', function () {
var value = this.value
, options = {};
if (!/^\d+$/.test(value)) return;
options[this.name] = value;
ins3.reload(options);
});
// 监听滚动事件
$(window).scroll(function () {
var scrollTop = $(window).scrollTop();
if (scrollTop > 150) { // 当滚动超过150px时显示固定导航
$('.sticky-nav').fadeIn();
} else {
$('.sticky-nav').fadeOut();
}
});
});
</script>
<div class="main">
<div class="location">
<div class="container">
<div class="location-item">
<a href="<?php echo url('index/index/index'); ?>">首页</a>
<span>></span>
<a href="<?php echo url('index/article/index'); ?>">技术文章</a>
</div>
</div>
</div>
<div class="article-detail-container">
<div class="article-header">
<h1 class="article-title"><?php echo htmlentities((string) $article['title']); ?></h1>
<div class="article-meta">
<span class="article-author"><i class="fa fa-user"></i> <?php echo htmlentities((string) $article['author']); ?></span>
<span class="article-date"><i class="fa fa-calendar"></i> <?php echo htmlentities((string) date('Y-m-d H:i',!is_numeric($article['create_time'])? strtotime($article['create_time']) : $article['create_time'])); ?></span>
<span class="article-category"><i class="fa fa-folder"></i> <?php echo htmlentities((string) $cateName); ?></span>
<span class="article-views"><i class="fa fa-eye"></i> <?php echo htmlentities((string) $article['views']); ?> 阅读</span>
</div>
</div>
<div class="article-content">
<?php echo $article['content']; ?>
</div>
<div class="article-tags">
<span class="tag-label">标签:</span>
<?php if(!empty($article['tags'])): foreach($article['tags'] as $tag): ?>
<span class="tag-item"><?php echo htmlentities((string) $tag); ?></span>
<?php endforeach; else: ?>
<span class="no-tags">暂无标签</span>
<?php endif; ?>
</div>
<div class="article-actions">
<div class="action-item like-btn">
<i class="fa fa-thumbs-up"></i>
<span class="action-text">点赞</span>
<span class="action-count"><?php echo htmlentities((string) (isset($article['likes']) && ($article['likes'] !== '')?$article['likes']:0)); ?></span>
</div>
<div class="action-item share-btn">
<i class="fa fa-share-alt"></i>
<span class="action-text">分享</span>
</div>
</div>
<div class="article-navigation">
<div class="prev-article">
<?php if(!empty($prevArticle)): ?>
<a href="<?php echo url('index/article/index', ['id' => $prevArticle['id']]); ?>">
<i class="fa fa-arrow-left"></i> 上一篇:<?php echo htmlentities((string) $prevArticle['title']); ?>
</a>
<?php else: ?>
<span class="disabled"><i class="fa fa-arrow-left"></i> 没有上一篇了</span>
<?php endif; ?>
</div>
<div class="next-article">
<?php if(!empty($nextArticle)): ?>
<a href="<?php echo url('index/article/index', ['id' => $nextArticle['id']]); ?>">
下一篇:<?php echo htmlentities((string) $nextArticle['title']); ?> <i class="fa fa-arrow-right"></i>
</a>
<?php else: ?>
<span class="disabled">没有下一篇了 <i class="fa fa-arrow-right"></i></span>
<?php endif; ?>
</div>
</div>
<div class="related-articles">
<h3 class="related-title">相关推荐</h3>
<div class="related-list">
<?php if(!empty($relatedArticles)): foreach($relatedArticles as $related): ?>
<div class="related-item">
<a href="<?php echo url('index/article/index', ['id' => $related['id']]); ?>">
<div class="related-image">
<img src="<?php echo htmlentities((string) $related['image']); ?>" alt="<?php echo htmlentities((string) $related['title']); ?>">
</div>
<div class="related-info">
<div class="related-item-title"><?php echo htmlentities((string) $related['title']); ?></div>
<div class="related-item-desc"><?php echo htmlentities((string) $related['desc']); ?></div>
</div>
</a>
</div>
<?php endforeach; else: ?>
<div class="no-related">暂无相关文章</div>
<?php endif; ?>
</div>
</div>
<!-- <div class="article-comments">
<h3 class="comments-title">评论区</h3>
<div class="comment-form">
<textarea placeholder="请输入您的评论..." class="comment-textarea"></textarea>
<button class="comment-submit">发表评论</button>
</div>
<div class="comment-list">
<?php if(!empty($comments)): foreach($comments as $comment): ?>
<div class="comment-item">
<div class="comment-avatar">
<img src="<?php echo htmlentities((string) (isset($comment['avatar']) && ($comment['avatar'] !== '')?$comment['avatar']:'/static/images/default-avatar.png')); ?>" alt="用户头像">
</div>
<div class="comment-content">
<div class="comment-user"><?php echo htmlentities((string) $comment['username']); ?></div>
<div class="comment-text"><?php echo htmlentities((string) $comment['content']); ?></div>
<div class="comment-footer">
<span class="comment-time"><?php echo htmlentities((string) date('Y-m-d H:i',!is_numeric($comment['create_time'])? strtotime($comment['create_time']) : $comment['create_time'])); ?></span>
<span class="comment-reply">回复</span>
</div>
</div>
</div>
<?php endforeach; else: ?>
<div class="no-comments">暂无评论,快来抢沙发吧!</div>
<?php endif; ?>
</div>
</div> -->
</div>
</div>
<!-- 返回顶部按钮 -->
<div class="go-to-top" id="goToTop">
<i class="layui-icon-up"></i>
</div>
<footer class="footer" style="background-image: url(/static/images/footer-bg-1.png)">
<div class="container">
<div class="row" style="width: 100%;">
<div class="row-main">
<div class="mr-20">
<img src="/static/images/logo-l-w.png" alt="" height="70">
<p class="text-white-50 my-4 f18" style="width: 400px;">美天智能科技,这里是介绍!</p>
</div>
<div style="display: flex; justify-content: space-between;width: 100%;margin-right: 200px;">
<div>
<h4 class="text-white f-20 font-weight-normal mb-3">关于我们</h4>
<ul class="list-unstyled footer-sub-menu">
<li><a href="#" class="footer-link">概况</a></li>
<li><a href="#" class="footer-link">资讯</a></li>
<li><a href="#" class="footer-link">加入我们</a></li>
<li><a href="#" class="footer-link">联系我们</a></li>
</ul>
</div>
<div>
<h4 class="text-white f-20 font-weight-normal mb-3">商务合作</h4>
<ul class="list-unstyled footer-sub-menu">
<li><a href="#" class="footer-link">商务合作</a></li>
</ul>
</div>
<div>
<h4 class="text-white f-20 font-weight-normal mb-3">服务支持</h4>
<ul class="list-unstyled footer-sub-menu">
<li><a href="#" class="footer-link">常见问答</a></li>
<li><a href="#" class="footer-link">软件下载</a></li>
<li><a href="#" class="footer-link">服务政策</a></li>
<li><a href="#" class="footer-link">投诉建议</a></li>
</ul>
</div>
</div>
<div>
<div class="text-center">
<img src="/static/images/code.png" alt="微信二维码" class="img-fluid" style="max-width: 150px;">
<p class="text-white-50 mt-2">微信公众号</p>
</div>
</div>
</div>
</div>
</div>
</footer>
<section class="copyright text-center">
<div class="container wow fadeInUp animated" data-wow-delay="400ms"
style="visibility: visible; animation-delay: 400ms; animation-name: fadeInUp;">
<p class="copyright__text">Copyright <span class="dynamic-year">2025</span> | All Rights By <a
href="http://www.yunzer.cn">Yunzer</a></p>
</div>
</section>
<style>
.location {
max-width: 1000px;
margin: 30px auto;
}
.article-detail-container {
max-width: 1000px;
margin: 30px auto;
padding: 50px;
background: #fff;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
.article-header {
margin-bottom: 30px;
border-bottom: 1px solid #eee;
padding-bottom: 20px;
}
.article-title {
font-size: 28px;
font-weight: 700;
color: #333;
margin-bottom: 15px;
line-height: 1.4;
}
.article-meta {
display: flex;
flex-wrap: wrap;
gap: 20px;
color: #666;
font-size: 14px;
}
.article-meta span {
display: flex;
align-items: center;
}
.article-meta i {
margin-right: 5px;
}
.article-content {
line-height: 1.8;
color: #333;
font-size: 16px;
margin-bottom: 30px;
}
.article-content img {
max-width: 100%;
height: auto;
margin: 15px 0;
border-radius: 4px;
}
.article-tags {
margin: 20px 0;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.tag-label {
font-weight: bold;
margin-right: 10px;
}
.tag-item {
background: #f2f2f2;
padding: 4px 10px;
border-radius: 15px;
font-size: 12px;
margin-right: 8px;
color: #666;
}
.article-actions {
display: flex;
justify-content: center;
gap: 40px;
margin: 30px 0;
padding: 20px 0;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
}
.action-item {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
}
.action-item i {
font-size: 24px;
color: #666;
margin-bottom: 5px;
}
.action-text {
font-size: 14px;
color: #666;
}
.action-count {
font-size: 12px;
color: #999;
margin-top: 3px;
}
.article-navigation {
display: flex;
justify-content: space-between;
margin: 30px 0;
}
.prev-article,
.next-article {
max-width: 45%;
}
.prev-article a,
.next-article a {
color: #333;
text-decoration: none;
}
.prev-article a:hover,
.next-article a:hover {
color: #f57005;
}
.disabled {
color: #999;
}
.related-articles {
margin: 40px 0;
}
.related-title {
font-size: 20px;
font-weight: 600;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.related-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.related-item {
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: transform 0.3s;
}
.related-item:hover {
transform: translateY(-5px);
}
.related-item a {
text-decoration: none;
color: inherit;
}
.related-image img {
width: 100%;
height: 150px;
object-fit: cover;
}
.related-info {
padding: 10px;
}
.related-item-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 5px;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.related-item-desc {
font-size: 12px;
color: #666;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.article-comments {
margin-top: 40px;
}
.comments-title {
font-size: 20px;
font-weight: 600;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.comment-form {
margin-bottom: 30px;
}
.comment-textarea {
width: 100%;
height: 100px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
resize: none;
margin-bottom: 10px;
}
.comment-submit {
background: #f57005;
color: white;
border: none;
padding: 8px 20px;
border-radius: 4px;
cursor: pointer;
float: right;
}
.comment-item {
display: flex;
margin-bottom: 20px;
padding-bottom: 20px;
border-bottom: 1px solid #eee;
}
.comment-avatar img {
width: 50px;
height: 50px;
border-radius: 50%;
margin-right: 15px;
}
.comment-content {
flex: 1;
}
.comment-user {
font-weight: 600;
margin-bottom: 5px;
}
.comment-text {
line-height: 1.6;
margin-bottom: 10px;
}
.comment-footer {
display: flex;
justify-content: space-between;
color: #999;
font-size: 12px;
}
.comment-reply {
cursor: pointer;
color: #f57005;
}
.no-comments,
.no-related,
.no-tags {
color: #999;
text-align: center;
padding: 20px;
}
@media (max-width: 768px) {
.article-title {
font-size: 24px;
}
.related-list {
grid-template-columns: repeat(1, 1fr);
}
.article-meta {
gap: 10px;
}
}
/* 返回顶部按钮样式 */
.go-to-top {
position: fixed;
right: 30px;
bottom: 30px;
width: 40px;
height: 40px;
background: #f57005;
color: #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
z-index: 1000;
}
.go-to-top.show {
opacity: 1;
visibility: visible;
}
.go-to-top:hover {
background: #e66600;
transform: translateY(-3px);
}
.go-to-top i {
font-size: 18px;
}
@media (max-width: 768px) {
.go-to-top {
right: 20px;
bottom: 20px;
width: 36px;
height: 36px;
}
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
// 点赞功能
const likeBtn = document.querySelector('.like-btn');
if (likeBtn) {
likeBtn.addEventListener('click', function () {
const articleId = '<?php echo htmlentities((string) $article['id']); ?>';
fetch('/index/article/like?id=' + articleId, {
method: 'POST'
})
.then(response => response.json())
.then(data => {
if (data.code === 1) {
const countElement = this.querySelector('.action-count');
let count = parseInt(countElement.textContent);
countElement.textContent = count + 1;
this.classList.add('liked');
this.style.color = '#f57005';
} else {
alert('点赞失败:' + data.msg);
}
})
.catch(error => {
console.error('点赞请求失败:', error);
});
});
}
// 返回顶部功能
const goToTop = document.getElementById('goToTop');
// 监听滚动事件
window.addEventListener('scroll', function() {
if (window.pageYOffset > 300) {
goToTop.classList.add('show');
} else {
goToTop.classList.remove('show');
}
});
// 点击返回顶部
goToTop.addEventListener('click', function() {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
});
</script>
</body>
</html>