Merge branch 'master' of https://git.yunzer.cn/yunzerwebsite/yunzer
This commit is contained in:
commit
ade061223e
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
/.idea
|
||||
/.vscode
|
||||
/vendor
|
||||
/runtime
|
||||
*.log
|
||||
|
||||
@ -23,12 +23,12 @@ class ResourcesController extends BaseController
|
||||
'name' => input('post.name'),
|
||||
'uploader' => input('post.uploader')
|
||||
];
|
||||
$page = (int)input('post.page', 1);
|
||||
$limit = (int)input('post.limit', 10);
|
||||
$page = (int) input('post.page', 1);
|
||||
$limit = (int) input('post.limit', 10);
|
||||
|
||||
$query = Resource::where('delete_time', null)
|
||||
->where('status', 1);
|
||||
|
||||
|
||||
// 分类筛选
|
||||
if (!empty($params['category'])) {
|
||||
$cateInfo = ResourceCategory::where('name', $params['category'])
|
||||
@ -36,20 +36,20 @@ class ResourcesController extends BaseController
|
||||
->where('status', 1)
|
||||
->field('id')
|
||||
->find();
|
||||
|
||||
|
||||
if ($cateInfo) {
|
||||
$query = $query->where('cate', (int)$cateInfo['id']);
|
||||
$query = $query->where('cate', (int) $cateInfo['id']);
|
||||
}
|
||||
}
|
||||
|
||||
// 名称搜索
|
||||
if (!empty($params['name'])) {
|
||||
$query = $query->where('name', 'like', '%'.$params['name'].'%');
|
||||
$query = $query->where('name', 'like', '%' . $params['name'] . '%');
|
||||
}
|
||||
|
||||
// 上传者搜索
|
||||
if (!empty($params['uploader'])) {
|
||||
$query = $query->where('uploader', 'like', '%'.$params['uploader'].'%');
|
||||
$query = $query->where('uploader', 'like', '%' . $params['uploader'] . '%');
|
||||
}
|
||||
|
||||
$count = $query->count();
|
||||
@ -59,7 +59,7 @@ class ResourcesController extends BaseController
|
||||
->select()
|
||||
->each(function ($item) {
|
||||
// 获取分类信息
|
||||
$cateInfo = ResourceCategory::where('id', (int)$item['cate'])
|
||||
$cateInfo = ResourceCategory::where('id', (int) $item['cate'])
|
||||
->field('name, icon')
|
||||
->find();
|
||||
if ($cateInfo) {
|
||||
@ -68,7 +68,7 @@ class ResourcesController extends BaseController
|
||||
$item['icon'] = $cateInfo['icon'];
|
||||
}
|
||||
}
|
||||
$item['create_time'] = date('Y-m-d H:i:s', (int)$item['create_time']);
|
||||
$item['create_time'] = date('Y-m-d H:i:s', (int) $item['create_time']);
|
||||
return $item;
|
||||
});
|
||||
|
||||
@ -85,7 +85,7 @@ class ResourcesController extends BaseController
|
||||
->order('sort asc, id asc')
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
|
||||
$categories = $this->buildParentChild($allCategories);
|
||||
|
||||
View::assign([
|
||||
@ -104,12 +104,13 @@ class ResourcesController extends BaseController
|
||||
'cate' => input('post.cate'),
|
||||
'icon' => input('post.icon'),
|
||||
'url' => input('post.url'),
|
||||
'fileurl' => input('post.fileurl'),
|
||||
'code' => input('post.code'),
|
||||
'uploader' => input('post.uploader'),
|
||||
'desc' => input('post.desc'),
|
||||
'content' => input('post.content'),
|
||||
'number' => input('post.number'),
|
||||
'status' => input('post.status', 2),
|
||||
'status' => input('post.status', 1),
|
||||
|
||||
'create_time' => time()
|
||||
];
|
||||
@ -376,7 +377,7 @@ class ResourcesController extends BaseController
|
||||
$resource = Resource::where('id', $id)
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
|
||||
|
||||
if (!$resource) {
|
||||
Log::record('获取资源详情', 0, '资源不存在', '资源管理');
|
||||
return json(['code' => 1, 'msg' => '资源不存在']);
|
||||
@ -403,42 +404,42 @@ class ResourcesController extends BaseController
|
||||
$total = Resource::where('delete_time', null)
|
||||
->where('status', '<>', 3)
|
||||
->count();
|
||||
|
||||
|
||||
// 获取今日新增资源数
|
||||
$today = strtotime(date('Y-m-d'));
|
||||
$todayNew = Resource::where('delete_time', null)
|
||||
->where('status', '<>', 3)
|
||||
->where('create_time', '>=', $today)
|
||||
->count();
|
||||
|
||||
|
||||
// 获取最近7天的资源数据
|
||||
$dates = [];
|
||||
$counts = [];
|
||||
$totalCounts = []; // 存储每天的总资源数
|
||||
|
||||
|
||||
for ($i = 6; $i >= 0; $i--) {
|
||||
$date = date('Y-m-d', strtotime("-$i days"));
|
||||
$start = strtotime($date);
|
||||
$end = $start + 86400;
|
||||
|
||||
|
||||
// 获取当天新增资源数
|
||||
$count = Resource::where('delete_time', null)
|
||||
->where('status', '<>', 3)
|
||||
->where('create_time', '>=', $start)
|
||||
->where('create_time', '<', $end)
|
||||
->count();
|
||||
|
||||
|
||||
// 获取截至当天的总资源数
|
||||
$totalCount = Resource::where('delete_time', null)
|
||||
->where('status', '<>', 3)
|
||||
->where('create_time', '<', $end)
|
||||
->count();
|
||||
|
||||
|
||||
$dates[] = $date;
|
||||
$counts[] = $count;
|
||||
$totalCounts[] = $totalCount;
|
||||
}
|
||||
|
||||
|
||||
return json([
|
||||
'code' => 0,
|
||||
'msg' => '获取成功',
|
||||
@ -469,7 +470,7 @@ class ResourcesController extends BaseController
|
||||
'title' => $item['name'],
|
||||
'children' => []
|
||||
];
|
||||
|
||||
|
||||
// 查找子分类
|
||||
foreach ($lists as $subItem) {
|
||||
if ($subItem['cid'] == $item['id']) {
|
||||
@ -480,7 +481,7 @@ class ResourcesController extends BaseController
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$tree[] = $node;
|
||||
}
|
||||
}
|
||||
|
||||
1
app/controller/StorageController.php
Normal file
1
app/controller/StorageController.php
Normal file
@ -0,0 +1 @@
|
||||
|
||||
@ -142,6 +142,16 @@ class ArticlesController extends BaseController
|
||||
|
||||
$id = Request::param('id/d', 0);
|
||||
|
||||
// 检查文章是否存在
|
||||
$article = Articles::where('id', $id)
|
||||
->where('delete_time', null)
|
||||
->where('status', 2)
|
||||
->find();
|
||||
|
||||
if (!$article) {
|
||||
return json(['code' => 0, 'msg' => '文章不存在或已被删除']);
|
||||
}
|
||||
|
||||
// 更新点赞数
|
||||
$result = Articles::where('id', $id)
|
||||
->where('delete_time', null)
|
||||
@ -149,7 +159,15 @@ class ArticlesController extends BaseController
|
||||
->update();
|
||||
|
||||
if ($result) {
|
||||
return json(['code' => 1, 'msg' => '点赞成功']);
|
||||
// 返回更新后的点赞数
|
||||
$newLikes = $article['likes'] + 1;
|
||||
return json([
|
||||
'code' => 1,
|
||||
'msg' => '点赞成功',
|
||||
'data' => [
|
||||
'likes' => $newLikes
|
||||
]
|
||||
]);
|
||||
} else {
|
||||
return json(['code' => 0, 'msg' => '点赞失败']);
|
||||
}
|
||||
|
||||
@ -4,10 +4,11 @@
|
||||
*/
|
||||
namespace app\index\controller;
|
||||
use app\index\controller\BaseController;
|
||||
use think\Response;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
use think\facade\Request;
|
||||
use app\index\model\Resources\Resources;
|
||||
use app\index\model\Resources\Resources;
|
||||
use app\index\model\Resources\ResourcesCategory;
|
||||
use app\index\model\Attachments;
|
||||
|
||||
@ -67,16 +68,16 @@ class ProgramController extends BaseController
|
||||
{
|
||||
$id = Request::param('id/d', 0);
|
||||
$program = Resources::where('id', $id)->find();
|
||||
|
||||
|
||||
if (!$program) {
|
||||
return json(['code' => 0, 'msg' => '程序不存在或已被删除']);
|
||||
}
|
||||
|
||||
|
||||
// 如果size没有,从附件表中获取
|
||||
if (empty($program['size']) && !empty($program['fileurl'])) {
|
||||
$attachment = Attachments::where('src', $program['fileurl'])
|
||||
->find();
|
||||
|
||||
|
||||
if ($attachment && !empty($attachment['size'])) {
|
||||
$size = $attachment['size'];
|
||||
// 转换文件大小为合适的单位
|
||||
@ -90,26 +91,37 @@ class ProgramController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
// 如果size存在,确保转换为合适的单位
|
||||
if (!empty($program['size']) && is_numeric($program['size'])) {
|
||||
$size = $program['size'];
|
||||
if ($size >= 1073741824) {
|
||||
$program['size'] = round($size / 1073741824, 2) . 'GB';
|
||||
} elseif ($size >= 1048576) {
|
||||
$program['size'] = round($size / 1048576, 2) . 'MB';
|
||||
} else {
|
||||
$program['size'] = round($size / 1024, 2) . 'KB';
|
||||
}
|
||||
}
|
||||
|
||||
// 获取分类名称
|
||||
$cateName = ResourcesCategory::where('id', $program['cate'])
|
||||
->value('name');
|
||||
|
||||
|
||||
// 获取上一个和下一个程序
|
||||
$prevProgram = Resources::where('id', '<', $id)
|
||||
->where('delete_time', null)
|
||||
->where('status', 1)
|
||||
->order('id DESC')
|
||||
->find();
|
||||
|
||||
|
||||
$nextProgram = Resources::where('id', '>', $id)
|
||||
->where('delete_time', null)
|
||||
->where('status', 1)
|
||||
->order('id ASC')
|
||||
->find();
|
||||
|
||||
|
||||
// 获取相关程序(同分类的其他程序)
|
||||
$relatedPrograms = Db::table('yz_resources')
|
||||
->alias('p')
|
||||
$relatedPrograms = Resources::alias('p')
|
||||
->join('yz_resources_category c', 'p.cate = c.id')
|
||||
->where('p.cate', $program['cate'])
|
||||
->where('p.id', '<>', $id)
|
||||
@ -119,7 +131,7 @@ class ProgramController extends BaseController
|
||||
'p.id',
|
||||
'p.title',
|
||||
'p.desc',
|
||||
'IF(p.icon IS NULL OR p.icon = "", c.icon, p.icon) as icon'
|
||||
'COALESCE(p.icon, c.icon) as icon'
|
||||
])
|
||||
->order('p.id DESC')
|
||||
->limit(3)
|
||||
@ -140,7 +152,7 @@ class ProgramController extends BaseController
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
// 非 AJAX 请求返回视图
|
||||
View::assign([
|
||||
'program' => $program,
|
||||
@ -156,34 +168,37 @@ class ProgramController extends BaseController
|
||||
// 程序下载
|
||||
public function download()
|
||||
{
|
||||
if (!Request::isAjax()) {
|
||||
return json(['code' => 0, 'msg' => '非法请求']);
|
||||
}
|
||||
|
||||
$id = Request::param('id/d', 0);
|
||||
$program = Resources::where('id', $id)
|
||||
->where('delete_time', null)
|
||||
->where('status', 1)
|
||||
->find();
|
||||
|
||||
if (!$program) {
|
||||
return json(['code' => 0, 'msg' => '程序不存在或已被删除']);
|
||||
}
|
||||
|
||||
// 更新下载次数
|
||||
$result = Resources::where('id', $id)
|
||||
->where('delete_time', null)
|
||||
->inc('downloads', 1)
|
||||
->update();
|
||||
Resources::where('id', $id)->inc('downloads')->update();
|
||||
|
||||
if ($result) {
|
||||
return json(['code' => 1, 'msg' => '下载成功']);
|
||||
} else {
|
||||
return json(['code' => 0, 'msg' => '下载失败']);
|
||||
}
|
||||
return json([
|
||||
'code' => 1,
|
||||
'msg' => '获取成功',
|
||||
'data' => [
|
||||
'fileurl' => $program['fileurl']
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
// 获取访问统计
|
||||
public function viewStats()
|
||||
{
|
||||
$id = Request::param('id/d', 0);
|
||||
|
||||
|
||||
// 获取总访问量
|
||||
$totalViews = Resources::where('id', $id)
|
||||
->value('views');
|
||||
|
||||
|
||||
return json([
|
||||
'code' => 1,
|
||||
'data' => [
|
||||
@ -215,10 +230,10 @@ class ProgramController extends BaseController
|
||||
|
||||
// 更新访问次数
|
||||
Resources::where('id', $id)->inc('views')->update();
|
||||
|
||||
|
||||
// 获取更新后的访问次数
|
||||
$newViews = Resources::where('id', $id)->value('views');
|
||||
|
||||
|
||||
return json(['code' => 1, 'msg' => '更新成功', 'data' => ['views' => $newViews]]);
|
||||
} catch (\Exception $e) {
|
||||
return json(['code' => 0, 'msg' => '更新失败:' . $e->getMessage()]);
|
||||
|
||||
53
app/index/controller/StorageController.php
Normal file
53
app/index/controller/StorageController.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace app\index\controller;
|
||||
use think\facade\Request;
|
||||
use think\facade\Filesystem;
|
||||
use think\Response;
|
||||
|
||||
use app\index\model\Resources\Resources;
|
||||
|
||||
class StorageController extends BaseController
|
||||
{
|
||||
/**
|
||||
* 处理文件下载
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function download()
|
||||
{
|
||||
// 获取请求的文件路径
|
||||
$path = Request::pathinfo();
|
||||
|
||||
// 移除 'storage/' 前缀
|
||||
$path = str_replace('storage/', '', $path);
|
||||
|
||||
// 构建完整的文件路径
|
||||
$filePath = public_path() . 'storage/' . $path;
|
||||
|
||||
// 检查文件是否存在
|
||||
if (!file_exists($filePath)) {
|
||||
return Response::create('文件不存在', 'html', 404);
|
||||
}
|
||||
|
||||
// 获取文件信息
|
||||
$fileInfo = pathinfo($filePath);
|
||||
$fileName = $fileInfo['basename'];
|
||||
$fileSize = filesize($filePath);
|
||||
$fileType = mime_content_type($filePath);
|
||||
|
||||
// 设置响应头
|
||||
$headers = [
|
||||
'Content-Type' => $fileType,
|
||||
'Content-Disposition' => 'attachment; filename="' . $fileName . '"',
|
||||
'Content-Length' => $fileSize,
|
||||
'Cache-Control' => 'no-cache, must-revalidate',
|
||||
'Pragma' => 'no-cache',
|
||||
'Expires' => '0'
|
||||
];
|
||||
|
||||
// 读取文件内容
|
||||
$content = file_get_contents($filePath);
|
||||
|
||||
// 返回文件下载响应
|
||||
return Response::create($content, 'file', 200, $headers);
|
||||
}
|
||||
}
|
||||
@ -30,12 +30,12 @@
|
||||
</div>
|
||||
|
||||
<div class="article-actions">
|
||||
<div class="action-item like-btn">
|
||||
<div class="action-item like-btn" id="likeBtn">
|
||||
<i class="fa fa-thumbs-up"></i>
|
||||
<span class="action-text">点赞</span>
|
||||
<span class="action-count" id="articleLikes">0</span>
|
||||
</div>
|
||||
<div class="action-item share-btn">
|
||||
<div class="action-item share-btn" id="shareBtn">
|
||||
<i class="fa fa-share-alt"></i>
|
||||
<span class="action-text">分享</span>
|
||||
</div>
|
||||
@ -432,31 +432,31 @@
|
||||
function renderArticleDetail(data) {
|
||||
// 渲染分类链接
|
||||
document.getElementById('cateLink').textContent = data.cateName;
|
||||
|
||||
|
||||
// 渲染文章标题
|
||||
document.getElementById('articleTitle').textContent = data.article.title;
|
||||
|
||||
|
||||
// 渲染文章元信息
|
||||
document.getElementById('articleAuthor').textContent = data.article.author;
|
||||
document.getElementById('articleDate').textContent = formatDate(data.article.create_time);
|
||||
document.getElementById('articleViews').textContent = data.article.views;
|
||||
|
||||
|
||||
// 渲染文章内容
|
||||
document.getElementById('articleContent').innerHTML = data.article.content;
|
||||
|
||||
|
||||
// 渲染标签
|
||||
const tagsContainer = document.getElementById('articleTags');
|
||||
if (data.article.tags && data.article.tags.length > 0) {
|
||||
tagsContainer.innerHTML = data.article.tags.map(tag =>
|
||||
tagsContainer.innerHTML = data.article.tags.map(tag =>
|
||||
`<span class="tag-item">${tag}</span>`
|
||||
).join('');
|
||||
} else {
|
||||
tagsContainer.innerHTML = '<span class="no-tags">暂无标签</span>';
|
||||
}
|
||||
|
||||
|
||||
// 渲染点赞数
|
||||
document.getElementById('articleLikes').textContent = data.article.likes || 0;
|
||||
|
||||
|
||||
// 渲染上一篇
|
||||
const prevArticle = document.getElementById('prevArticle');
|
||||
if (data.prevArticle) {
|
||||
@ -468,7 +468,7 @@
|
||||
} else {
|
||||
prevArticle.innerHTML = '<span class="disabled"><i class="fa fa-arrow-left"></i> 没有上一篇了</span>';
|
||||
}
|
||||
|
||||
|
||||
// 渲染下一篇
|
||||
const nextArticle = document.getElementById('nextArticle');
|
||||
if (data.nextArticle) {
|
||||
@ -480,7 +480,7 @@
|
||||
} else {
|
||||
nextArticle.innerHTML = '<span class="disabled">没有下一篇了 <i class="fa fa-arrow-right"></i></span>';
|
||||
}
|
||||
|
||||
|
||||
// 渲染相关文章
|
||||
const relatedArticles = document.getElementById('relatedArticles');
|
||||
if (data.relatedArticles && data.relatedArticles.length > 0) {
|
||||
@ -503,7 +503,7 @@
|
||||
}
|
||||
|
||||
// 页面加载完成后执行
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// 获取文章ID
|
||||
const articleId = new URLSearchParams(window.location.search).get('id');
|
||||
if (!articleId) {
|
||||
@ -518,12 +518,12 @@
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
console.log('Response status:', response.status);
|
||||
console.log('Response headers:', response.headers);
|
||||
// console.log('Response status:', response.status);
|
||||
// console.log('Response headers:', response.headers);
|
||||
return response.json();
|
||||
})
|
||||
.then(result => {
|
||||
console.log('API response:', result);
|
||||
// console.log('API response:', result);
|
||||
if (result.code === 1) {
|
||||
renderArticleDetail(result.data);
|
||||
// 更新访问次数
|
||||
@ -543,44 +543,69 @@
|
||||
});
|
||||
|
||||
// 点赞功能
|
||||
const likeBtn = document.querySelector('.like-btn');
|
||||
const likeBtn = document.getElementById('likeBtn');
|
||||
if (likeBtn) {
|
||||
likeBtn.addEventListener('click', function() {
|
||||
// 检查是否已经点赞
|
||||
if (likeBtn.classList.contains('liked')) {
|
||||
likeBtn.style.pointerEvents = 'none'; // 禁用点击
|
||||
likeBtn.style.cursor = 'default'; // 改变鼠标样式
|
||||
return;
|
||||
}
|
||||
|
||||
likeBtn.addEventListener('click', function () {
|
||||
// 立即禁用按钮,防止重复点击
|
||||
likeBtn.style.pointerEvents = 'none';
|
||||
likeBtn.style.cursor = 'default';
|
||||
|
||||
fetch('/index/articles/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);
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('点赞请求失败:', error);
|
||||
});
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 1) {
|
||||
const countElement = document.getElementById('articlesLikes');
|
||||
if (countElement) {
|
||||
let count = parseInt(countElement.textContent) || 0;
|
||||
countElement.textContent = count + 1;
|
||||
}
|
||||
// 添加点赞状态
|
||||
likeBtn.classList.add('liked');
|
||||
likeBtn.querySelector('i').style.color = '#f57005';
|
||||
layer.msg('点赞成功', {icon: 1});
|
||||
} else {
|
||||
// 如果请求失败,恢复按钮状态
|
||||
likeBtn.style.pointerEvents = 'auto';
|
||||
likeBtn.style.cursor = 'pointer';
|
||||
layer.msg('点赞失败:' + data.msg, {icon: 2});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
// 如果请求失败,恢复按钮状态
|
||||
likeBtn.style.pointerEvents = 'auto';
|
||||
likeBtn.style.cursor = 'pointer';
|
||||
console.error('点赞请求失败:', error);
|
||||
layer.msg('点赞失败,请稍后重试', {icon: 2});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 返回顶部功能
|
||||
const goToTop = document.getElementById('goToTop');
|
||||
|
||||
|
||||
// 监听滚动事件
|
||||
window.addEventListener('scroll', function() {
|
||||
window.addEventListener('scroll', function () {
|
||||
if (window.pageYOffset > 300) {
|
||||
goToTop.classList.add('show');
|
||||
} else {
|
||||
goToTop.classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 点击返回顶部
|
||||
goToTop.addEventListener('click', function() {
|
||||
goToTop.addEventListener('click', function () {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
@ -599,18 +624,42 @@
|
||||
id: articleId
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.code === 1) {
|
||||
// 更新成功,更新页面上的访问次数显示
|
||||
const viewsElement = document.getElementById('articleViews');
|
||||
if (viewsElement) {
|
||||
viewsElement.textContent = result.data.views;
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.code === 1) {
|
||||
// 更新成功,更新页面上的访问次数显示
|
||||
const viewsElement = document.getElementById('articleViews');
|
||||
if (viewsElement) {
|
||||
viewsElement.textContent = result.data.views;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('更新访问次数失败:', error);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('更新访问次数失败:', error);
|
||||
});
|
||||
}
|
||||
|
||||
// 分享功能
|
||||
const shareBtn = document.getElementById('shareBtn');
|
||||
if (shareBtn) {
|
||||
shareBtn.addEventListener('click', function () {
|
||||
// 获取当前页面URL
|
||||
const currentUrl = window.location.href;
|
||||
|
||||
// 创建临时输入框
|
||||
const tempInput = document.createElement('input');
|
||||
tempInput.value = currentUrl;
|
||||
document.body.appendChild(tempInput);
|
||||
|
||||
// 选择并复制文本
|
||||
tempInput.select();
|
||||
document.execCommand('copy');
|
||||
|
||||
// 移除临时输入框
|
||||
document.body.removeChild(tempInput);
|
||||
|
||||
// 提示用户复制成功
|
||||
alert('链接已复制到剪贴板');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
<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>
|
||||
<a href="index.html"><img src="__IMAGES__/logo1.png" width="186" alt="Logo"></a>
|
||||
</div>
|
||||
<div class="main-menu__nav">
|
||||
<ul class="main-menu__list">
|
||||
@ -70,7 +70,7 @@
|
||||
<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>
|
||||
<a href="index.html"><img src="__IMAGES__/logo1.png" width="150" alt="Logo"></a>
|
||||
</div>
|
||||
<div class="sticky-nav__menu">
|
||||
<ul>
|
||||
|
||||
@ -18,7 +18,8 @@
|
||||
<span class="program-author"><i class="fa fa-user"></i> <span id="programAuthor"></span></span>
|
||||
<span class="program-date"><i class="fa fa-calendar"></i> <span id="programDate"></span></span>
|
||||
<span class="program-views"><i class="fa-solid fa-eye"></i> <span id="programViews"></span> 浏览</span>
|
||||
<span class="program-downloads"><i class="fa-solid fa-download"></i> <span id="programDownloads"></span> 下载</span>
|
||||
<span class="program-downloads"><i class="fa-solid fa-download"></i> <span id="programDownloads"></span>
|
||||
下载</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -44,12 +45,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="program-content">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="program-actions">
|
||||
<div class="action-item download-btn" id="downloadBtn">
|
||||
<i class="fa fa-download"></i>
|
||||
<span class="action-text">立即下载</span>
|
||||
</div>
|
||||
<div class="action-item share-btn">
|
||||
<div class="action-item share-btn" id="shareBtn">
|
||||
<i class="fa fa-share-alt"></i>
|
||||
<span class="action-text">分享</span>
|
||||
</div>
|
||||
@ -203,6 +208,11 @@
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
.program-navigation a {
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.prev-program,
|
||||
.next-program {
|
||||
max-width: 45%;
|
||||
@ -358,25 +368,25 @@
|
||||
function renderProgramDetail(data) {
|
||||
// 渲染分类链接
|
||||
document.getElementById('cateLink').textContent = data.cateName;
|
||||
|
||||
|
||||
// 渲染程序标题
|
||||
document.getElementById('programTitle').textContent = data.program.title;
|
||||
|
||||
|
||||
// 渲染程序元信息
|
||||
document.getElementById('programAuthor').textContent = data.program.author;
|
||||
document.getElementById('programDate').textContent = formatDate(data.program.create_time);
|
||||
document.getElementById('programViews').textContent = data.program.views;
|
||||
document.getElementById('programDownloads').textContent = data.program.downloads;
|
||||
|
||||
|
||||
// 渲染程序内容
|
||||
document.getElementById('programContent').innerHTML = data.program.content;
|
||||
|
||||
|
||||
// 渲染程序信息
|
||||
document.getElementById('programSize').textContent = data.program.size || '未知';
|
||||
document.getElementById('programEnvironment').textContent = data.program.environment || '通用';
|
||||
document.getElementById('programUpdateTime').textContent = formatDate(data.program.update_time);
|
||||
document.getElementById('programVersion').textContent = data.program.version || '1.0.0';
|
||||
|
||||
|
||||
// 渲染上一个程序
|
||||
const prevProgram = document.getElementById('prevProgram');
|
||||
if (data.prevProgram) {
|
||||
@ -388,7 +398,7 @@
|
||||
} else {
|
||||
prevProgram.innerHTML = '<span class="disabled"><i class="fa fa-arrow-left"></i> 没有上一个了</span>';
|
||||
}
|
||||
|
||||
|
||||
// 渲染下一个程序
|
||||
const nextProgram = document.getElementById('nextProgram');
|
||||
if (data.nextProgram) {
|
||||
@ -400,7 +410,7 @@
|
||||
} else {
|
||||
nextProgram.innerHTML = '<span class="disabled">没有下一个了 <i class="fa fa-arrow-right"></i></span>';
|
||||
}
|
||||
|
||||
|
||||
// 渲染相关程序
|
||||
const relatedPrograms = document.getElementById('relatedPrograms');
|
||||
if (data.relatedPrograms && data.relatedPrograms.length > 0) {
|
||||
@ -423,7 +433,7 @@
|
||||
}
|
||||
|
||||
// 页面加载完成后执行
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// 获取程序ID
|
||||
const programId = new URLSearchParams(window.location.search).get('id');
|
||||
if (!programId) {
|
||||
@ -437,72 +447,63 @@
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.code === 1) {
|
||||
renderProgramDetail(result.data);
|
||||
// 更新访问次数
|
||||
updateProgramViews(programId);
|
||||
} else {
|
||||
alert(result.msg || '获取程序详情失败');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取程序详情失败:', error);
|
||||
alert('获取程序详情失败,请检查网络连接或刷新页面重试');
|
||||
});
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.code === 1) {
|
||||
renderProgramDetail(result.data);
|
||||
// 更新访问次数
|
||||
updateProgramViews(programId);
|
||||
// 初始化分享功能
|
||||
initShareFunction();
|
||||
} else {
|
||||
alert(result.msg || '获取程序详情失败');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取程序详情失败:', error);
|
||||
alert('获取程序详情失败,请检查网络连接或刷新页面重试');
|
||||
});
|
||||
|
||||
// 下载功能
|
||||
const downloadBtn = document.getElementById('downloadBtn');
|
||||
if (downloadBtn) {
|
||||
downloadBtn.addEventListener('click', function() {
|
||||
downloadBtn.addEventListener('click', function () {
|
||||
fetch('/index/program/download?id=' + programId, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 1) {
|
||||
const downloadsElement = document.getElementById('programDownloads');
|
||||
let downloads = parseInt(downloadsElement.textContent);
|
||||
downloadsElement.textContent = downloads + 1;
|
||||
|
||||
// 获取当前域名
|
||||
const domain = window.location.origin;
|
||||
// 拼接完整的下载地址
|
||||
if (data.data && data.data.fileurl) {
|
||||
const downloadUrl = domain + data.data.fileurl;
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 1 && data.data && data.data.fileurl) {
|
||||
const downloadUrl = window.location.origin + data.data.fileurl;
|
||||
window.location.href = downloadUrl;
|
||||
} else {
|
||||
alert('下载地址不存在');
|
||||
}
|
||||
} else {
|
||||
alert('下载失败:' + data.msg);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('下载请求失败:', error);
|
||||
alert('下载请求失败,请稍后重试');
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('下载请求失败:', error);
|
||||
alert('下载请求失败,请稍后重试');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 返回顶部功能
|
||||
const goToTop = document.getElementById('goToTop');
|
||||
|
||||
|
||||
// 监听滚动事件
|
||||
window.addEventListener('scroll', function() {
|
||||
window.addEventListener('scroll', function () {
|
||||
if (window.pageYOffset > 300) {
|
||||
goToTop.classList.add('show');
|
||||
} else {
|
||||
goToTop.classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 点击返回顶部
|
||||
goToTop.addEventListener('click', function() {
|
||||
goToTop.addEventListener('click', function () {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
@ -522,19 +523,45 @@
|
||||
id: programId
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.code === 1) {
|
||||
// 更新成功,更新页面上的访问次数显示
|
||||
const viewsElement = document.getElementById('programViews');
|
||||
if (viewsElement) {
|
||||
viewsElement.textContent = result.data.views;
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.code === 1) {
|
||||
// 更新成功,更新页面上的访问次数显示
|
||||
const viewsElement = document.getElementById('programViews');
|
||||
if (viewsElement) {
|
||||
viewsElement.textContent = result.data.views;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('更新访问次数失败:', error);
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('更新访问次数失败:', error);
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化分享功能
|
||||
function initShareFunction() {
|
||||
const shareBtn = document.getElementById('shareBtn');
|
||||
if (shareBtn) {
|
||||
shareBtn.addEventListener('click', function () {
|
||||
// 获取当前页面URL
|
||||
const currentUrl = window.location.href;
|
||||
|
||||
// 创建临时输入框
|
||||
const tempInput = document.createElement('input');
|
||||
tempInput.value = currentUrl;
|
||||
document.body.appendChild(tempInput);
|
||||
|
||||
// 选择并复制文本
|
||||
tempInput.select();
|
||||
document.execCommand('copy');
|
||||
|
||||
// 移除临时输入框
|
||||
document.body.removeChild(tempInput);
|
||||
|
||||
// 提示用户复制成功
|
||||
layer.msg('链接已复制到剪贴板');
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{include file="component/foot" /}
|
||||
@ -1,8 +1,11 @@
|
||||
location ~* (runtime|application)/{
|
||||
return 403;
|
||||
}
|
||||
location / {
|
||||
if (!-e $request_filename){
|
||||
rewrite ^(.*)$ /index.php?s=$1 last; break;
|
||||
if (!-e $request_filename) {
|
||||
rewrite ^(.*)$ /index.php?s=$1 last;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
# 处理 storage 目录的请求
|
||||
location /storage/ {
|
||||
try_files $uri $uri/ /index.php?s=$uri&$args;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
850
runtime/admin/temp/1c825d7302c9198f86d61f24e6c74d99.php
Normal file
850
runtime/admin/temp/1c825d7302c9198f86d61f24e6c74d99.php
Normal file
@ -0,0 +1,850 @@
|
||||
<?php /*a:3:{s:61:"E:\Demos\DemoOwns\PHP\yunzer\app\admin\view\index\welcome.php";i:1747701414;s:61:"E:\Demos\DemoOwns\PHP\yunzer\app\admin\view\public\header.php";i:1746849526;s:59:"E:\Demos\DemoOwns\PHP\yunzer\app\admin\view\public\tail.php";i:1746709977;}*/ ?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><?php echo htmlentities((string) $config['admin_name']); ?></title>
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css" media="all"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/moban.css" media="all"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/wangeditor.css" media="all"/>
|
||||
<style type="text/css">
|
||||
.header span{background:#009688;margin-left:30px;padding:10px;color:#ffffff;}
|
||||
.header div{border-bottom:solid 2px #009688;margin-top: 8px;}
|
||||
.header button{float:right;margin-top:-5px;}
|
||||
.pagination {
|
||||
display: inline-block;
|
||||
padding-left: 0;
|
||||
margin: 20px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.pagination > li {
|
||||
display: inline;
|
||||
}
|
||||
.pagination > li > a,
|
||||
.pagination > li > span {
|
||||
position: relative;
|
||||
float: left;
|
||||
padding: 6px 12px;
|
||||
margin-left: -1px;
|
||||
line-height: 1.42857143;
|
||||
color: #337ab7;
|
||||
text-decoration: none;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.pagination > li:first-child > a,
|
||||
.pagination > li:first-child > span {
|
||||
margin-left: 0;
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.pagination > li:last-child > a,
|
||||
.pagination > li:last-child > span {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
.pagination > li > a:hover,
|
||||
.pagination > li > span:hover,
|
||||
.pagination > li > a:focus,
|
||||
.pagination > li > span:focus {
|
||||
z-index: 2;
|
||||
color: #23527c;
|
||||
background-color: #eee;
|
||||
border-color: #ddd;
|
||||
}
|
||||
.pagination > .active > a,
|
||||
.pagination > .active > span,
|
||||
.pagination > .active > a:hover,
|
||||
.pagination > .active > span:hover,
|
||||
.pagination > .active > a:focus,
|
||||
.pagination > .active > span:focus {
|
||||
z-index: 3;
|
||||
color: #fff;
|
||||
cursor: default;
|
||||
background-color: #337ab7;
|
||||
border-color: #337ab7;
|
||||
}
|
||||
.pagination > .disabled > span,
|
||||
.pagination > .disabled > span:hover,
|
||||
.pagination > .disabled > span:focus,
|
||||
.pagination > .disabled > a,
|
||||
.pagination > .disabled > a:hover,
|
||||
.pagination > .disabled > a:focus {
|
||||
color: #777;
|
||||
cursor: not-allowed;
|
||||
background-color: #fff;
|
||||
border-color: #ddd;
|
||||
}
|
||||
.close-img { background: url(/static/images/close_img.png); background-size: 20px 20px; width:20px; height: 20px; position: absolute; right: 5px; top: 5px; z-index: 2;}
|
||||
</style>
|
||||
<script type="text/javascript" src="/static/layui/layui.js"></script>
|
||||
<script type="text/javascript">
|
||||
layui.use(['layer','form','table','laydate','element','upload'],function(){
|
||||
layer = layui.layer; // layui 弹框
|
||||
form = layui.form; // layui form表单
|
||||
table = layui.table; // layui 表格
|
||||
laydate = layui.laydate; // layui 时间框
|
||||
element = layui.element; // layui element
|
||||
upload = layui.upload; // layui 上传
|
||||
$ = layui.jquery; // layui jquery
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<body style="padding:10px; box-sizing: border-box;">
|
||||
<script src="/static/js/jquery.min.js"></script>
|
||||
<style>
|
||||
.dashboard-container {
|
||||
padding: 24px;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
/* background-color: #f5f7fa; */
|
||||
/* min-height: calc(100vh - 60px); */
|
||||
}
|
||||
.welcome-header {
|
||||
background: linear-gradient(135deg, #3881fd 0%, #2c5fd9 100%);
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
color: white;
|
||||
margin-bottom: 24px;
|
||||
box-shadow: 0 4px 20px rgba(56, 129, 253, 0.15);
|
||||
}
|
||||
.welcome-header h1 {
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.welcome-header p {
|
||||
font-size: 15px;
|
||||
opacity: 0.9;
|
||||
margin: 0;
|
||||
}
|
||||
.stats-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: 24px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.stat-card {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.stat-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 4px;
|
||||
height: 100%;
|
||||
background: #3881fd;
|
||||
}
|
||||
.stat-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
.stat-card .stat-value {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
margin: 12px 0;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
.stat-card .stat-title {
|
||||
color: #64748b;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.stat-card .stat-icon {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-size: 48px;
|
||||
opacity: 0.1;
|
||||
}
|
||||
.quick-actions {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
.quick-actions h2 {
|
||||
color: #1e293b;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.quick-actions h2::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 4px;
|
||||
height: 18px;
|
||||
background: #3881fd;
|
||||
margin-right: 8px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.action-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.action-button {
|
||||
background: #f8fafc;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
color: #1e293b;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
.action-button:hover {
|
||||
background: #3881fd;
|
||||
color: white;
|
||||
border-color: #3881fd;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.action-button i {
|
||||
margin-right: 8px;
|
||||
}
|
||||
.recent-activity {
|
||||
margin-top: 24px;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
.activity-list {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.activity-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
}
|
||||
.activity-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.activity-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 8px;
|
||||
background: #f1f5f9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 12px;
|
||||
}
|
||||
.activity-content {
|
||||
flex: 1;
|
||||
}
|
||||
.activity-title {
|
||||
font-weight: 500;
|
||||
color: #9b9b9b;
|
||||
}
|
||||
.activity-time {
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
}
|
||||
.charts-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
||||
gap: 24px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
.chart-card {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
.chart-card h2 {
|
||||
color: #1e293b;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.chart-card h2::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 4px;
|
||||
height: 18px;
|
||||
background: #3881fd;
|
||||
margin-right: 8px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.chart-container {
|
||||
height: 300px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="dashboard-container">
|
||||
<div class="welcome-header">
|
||||
<h1>欢迎使用<?php echo htmlentities((string) $config['admin_name']); ?></h1>
|
||||
<p>今天是 <span id="current-time"></span>,祝您工作愉快</p>
|
||||
</div>
|
||||
|
||||
<div class="stats-container">
|
||||
<div class="stat-card">
|
||||
<div class="stat-title">用户总数</div>
|
||||
<div class="stat-value"><?php echo htmlentities((string) number_format($todayStats['total_users'])); ?></div>
|
||||
<div class="stat-icon">👥</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-title">今日访问</div>
|
||||
<div class="stat-value"><?php echo htmlentities((string) number_format($todayStats['daily_visits'])); ?></div>
|
||||
<div class="stat-icon">📊</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-title">文章总数</div>
|
||||
<div class="stat-value"><?php echo htmlentities((string) number_format($todayStats['total_articles'])); ?></div>
|
||||
<div class="stat-icon">📝</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-title">资源总数</div>
|
||||
<div class="stat-value"><?php echo htmlentities((string) number_format($todayStats['total_resources'])); ?></div>
|
||||
<div class="stat-icon">📦</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="quick-actions">
|
||||
<h2>快捷操作</h2>
|
||||
<div class="action-buttons">
|
||||
<a href="<?php echo url('user/index'); ?>" class="action-button">
|
||||
<i class="fas fa-users"></i>用户管理
|
||||
</a>
|
||||
<a href="<?php echo url('content/publish'); ?>" class="action-button">
|
||||
<i class="fas fa-edit"></i>内容发布
|
||||
</a>
|
||||
<a href="<?php echo url('statistics/index'); ?>" class="action-button">
|
||||
<i class="fas fa-chart-bar"></i>数据统计
|
||||
</a>
|
||||
<a href="<?php echo url('system/settings'); ?>" class="action-button">
|
||||
<i class="fas fa-cog"></i>系统设置
|
||||
</a>
|
||||
<a href="<?php echo url('system/clear_cache'); ?>" class="action-button">
|
||||
<i class="fas fa-broom"></i>清除缓存
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="recent-activity">
|
||||
<h2>最近动态</h2>
|
||||
<div class="activity-list">
|
||||
<?php if(is_array($recentActivities) || $recentActivities instanceof \think\Collection || $recentActivities instanceof \think\Paginator): $i = 0; $__LIST__ = $recentActivities;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$activity): $mod = ($i % 2 );++$i;?>
|
||||
<div class="activity-item">
|
||||
<div class="activity-icon"><?php echo htmlentities((string) (isset($activity['icon']) && ($activity['icon'] !== '')?$activity['icon']:'📌')); ?></div>
|
||||
<div class="activity-content">
|
||||
<div class="activity-title"><?php echo htmlentities((string) $activity['content']); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; endif; else: echo "" ;endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="charts-container">
|
||||
<div class="chart-card">
|
||||
<h2>访问趋势</h2>
|
||||
<div id="visitTrend" class="chart-container"></div>
|
||||
</div>
|
||||
<div class="chart-card">
|
||||
<h2>用户增长</h2>
|
||||
<div id="userGrowth" class="chart-container"></div>
|
||||
</div>
|
||||
<div class="chart-card">
|
||||
<h2>资源统计</h2>
|
||||
<div id="resourceStats" class="chart-container"></div>
|
||||
</div>
|
||||
<div class="chart-card">
|
||||
<h2>文章统计</h2>
|
||||
<div id="articleStats" class="chart-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script src="/static/js/echarts.min.js"></script>
|
||||
<script>
|
||||
function updateTime() {
|
||||
var now = new Date();
|
||||
var year = now.getFullYear();
|
||||
var month = now.getMonth() + 1;
|
||||
var date = now.getDate();
|
||||
var hours = now.getHours();
|
||||
var minutes = now.getMinutes();
|
||||
var seconds = now.getSeconds();
|
||||
|
||||
var padZero = function(num) {
|
||||
return num < 10 ? '0' + num : num;
|
||||
};
|
||||
|
||||
var timeString = year + '年' +
|
||||
padZero(month) + '月' +
|
||||
padZero(date) + '日 ' +
|
||||
padZero(hours) + ':' +
|
||||
padZero(minutes) + ':' +
|
||||
padZero(seconds);
|
||||
|
||||
document.getElementById('current-time').innerHTML = timeString;
|
||||
}
|
||||
|
||||
// 获取用户统计数据
|
||||
function getUserCounts() {
|
||||
fetch('<?php echo url("users/counts"); ?>')
|
||||
.then(response => response.json())
|
||||
.then(res => {
|
||||
console.log('用户统计接口返回数据:', res);
|
||||
if (res.code === 0 && res.data) {
|
||||
// 更新用户总数
|
||||
document.querySelector('.stat-card:nth-child(1) .stat-value').textContent = res.data.total.toLocaleString();
|
||||
|
||||
// 更新用户增长图表
|
||||
if (window.userChart) {
|
||||
window.userChart.setOption({
|
||||
xAxis: {
|
||||
data: res.data.dates
|
||||
},
|
||||
series: [{
|
||||
name: '新增用户',
|
||||
data: res.data.counts
|
||||
}, {
|
||||
name: '总用户数',
|
||||
data: res.data.totalCounts
|
||||
}]
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.warn('用户统计接口返回异常:', res);
|
||||
document.querySelector('.stat-card:nth-child(1) .stat-value').textContent = '0';
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取用户统计失败:', error);
|
||||
document.querySelector('.stat-card:nth-child(1) .stat-value').textContent = '0';
|
||||
});
|
||||
}
|
||||
|
||||
// 获取文章统计数据
|
||||
function getArticleCounts() {
|
||||
fetch('<?php echo url("articles/counts"); ?>')
|
||||
.then(response => response.json())
|
||||
.then(res => {
|
||||
console.log('文章统计接口返回数据:', res);
|
||||
if (res.code === 0 && res.data) {
|
||||
// 更新文章总数
|
||||
document.querySelector('.stat-card:nth-child(3) .stat-value').textContent = res.data.total.toLocaleString();
|
||||
|
||||
// 更新文章统计图表
|
||||
if (window.articleChart) {
|
||||
window.articleChart.setOption({
|
||||
xAxis: {
|
||||
data: res.data.dates
|
||||
},
|
||||
series: [{
|
||||
name: '新增文章',
|
||||
data: res.data.counts
|
||||
}, {
|
||||
name: '总文章数',
|
||||
data: res.data.totalCounts
|
||||
}]
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.warn('文章统计接口返回异常:', res);
|
||||
document.querySelector('.stat-card:nth-child(3) .stat-value').textContent = '0';
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取文章统计失败:', error);
|
||||
document.querySelector('.stat-card:nth-child(3) .stat-value').textContent = '0';
|
||||
});
|
||||
}
|
||||
|
||||
// 获取资源统计数据
|
||||
function getResourcesCounts() {
|
||||
fetch('<?php echo url("resources/counts"); ?>')
|
||||
.then(response => response.json())
|
||||
.then(res => {
|
||||
console.log('资源统计接口返回数据:', res);
|
||||
if (res.code === 0 && res.data) {
|
||||
// 更新资源总数
|
||||
document.querySelector('.stat-card:nth-child(4) .stat-value').textContent = res.data.total.toLocaleString();
|
||||
|
||||
// 更新资源统计图表
|
||||
if (window.resourceChart) {
|
||||
window.resourceChart.setOption({
|
||||
xAxis: {
|
||||
data: res.data.dates
|
||||
},
|
||||
series: [{
|
||||
name: '新增资源',
|
||||
data: res.data.counts
|
||||
}, {
|
||||
name: '总资源数',
|
||||
data: res.data.totalCounts
|
||||
}]
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.warn('资源统计接口返回异常:', res);
|
||||
document.querySelector('.stat-card:nth-child(4) .stat-value').textContent = '0';
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取资源统计失败:', error);
|
||||
document.querySelector('.stat-card:nth-child(4) .stat-value').textContent = '0';
|
||||
});
|
||||
}
|
||||
|
||||
updateTime();
|
||||
setInterval(updateTime, 1000);
|
||||
|
||||
// 页面加载完成后获取统计数据
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
getUserCounts();
|
||||
getArticleCounts();
|
||||
getResourcesCounts();
|
||||
});
|
||||
|
||||
// 访问趋势图表
|
||||
function initVisitTrend() {
|
||||
var chart = echarts.init(document.getElementById('visitTrend'));
|
||||
var option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['访问量', '独立访客']
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['visitTrend']['dates'])); ?>,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#e2e8f0'
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#e2e8f0'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#f1f5f9'
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: '访问量',
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['visitTrend']['visits'])); ?>,
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
areaStyle: {
|
||||
opacity: 0.1
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#3881fd'
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3
|
||||
}
|
||||
}, {
|
||||
name: '独立访客',
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['visitTrend']['uvs'])); ?>,
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
itemStyle: {
|
||||
color: '#10b981'
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3
|
||||
}
|
||||
}]
|
||||
};
|
||||
chart.setOption(option);
|
||||
}
|
||||
|
||||
// 用户增长图表
|
||||
function initUserGrowth() {
|
||||
var chart = echarts.init(document.getElementById('userGrowth'));
|
||||
var option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
label: {
|
||||
backgroundColor: '#6a7985'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['新增用户', '总用户数']
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['userGrowth']['dates'])); ?>
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '新增用户',
|
||||
type: 'bar',
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['userGrowth']['newUsers'])); ?>,
|
||||
itemStyle: {
|
||||
color: '#3881fd'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '总用户数',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['userGrowth']['totalUsers'])); ?>,
|
||||
itemStyle: {
|
||||
color: '#10b981'
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
chart.setOption(option);
|
||||
}
|
||||
|
||||
// 资源统计图表
|
||||
function initResourceStats() {
|
||||
var chart = echarts.init(document.getElementById('resourceStats'));
|
||||
var option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
label: {
|
||||
backgroundColor: '#6a7985'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['新增资源', '总资源数', '下载量']
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['resourceStats']['dates'])); ?>
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '新增资源',
|
||||
type: 'bar',
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['resourceStats']['newResources'])); ?>,
|
||||
itemStyle: {
|
||||
color: '#3881fd'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '总资源数',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['resourceStats']['totalResources'])); ?>,
|
||||
itemStyle: {
|
||||
color: '#10b981'
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '下载量',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['resourceStats']['downloads'])); ?>,
|
||||
itemStyle: {
|
||||
color: '#f59e0b'
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
chart.setOption(option);
|
||||
}
|
||||
|
||||
// 文章统计图表
|
||||
function initArticleStats() {
|
||||
var chart = echarts.init(document.getElementById('articleStats'));
|
||||
var option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
label: {
|
||||
backgroundColor: '#6a7985'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['新增文章', '总文章数', '浏览量']
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['articleStats']['dates'])); ?>
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '新增文章',
|
||||
type: 'bar',
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['articleStats']['newArticles'])); ?>,
|
||||
itemStyle: {
|
||||
color: '#3881fd'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '总文章数',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['articleStats']['totalArticles'])); ?>,
|
||||
itemStyle: {
|
||||
color: '#10b981'
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '浏览量',
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
data: <?php echo htmlentities((string) json_encode($chartData['articleStats']['views'])); ?>,
|
||||
itemStyle: {
|
||||
color: '#f59e0b'
|
||||
},
|
||||
lineStyle: {
|
||||
width: 3
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
chart.setOption(option);
|
||||
}
|
||||
|
||||
// 初始化所有图表
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// 确保ECharts已加载
|
||||
if (typeof echarts === 'undefined') {
|
||||
console.error('ECharts未加载');
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化图表
|
||||
try {
|
||||
initVisitTrend();
|
||||
initUserGrowth();
|
||||
initResourceStats();
|
||||
initArticleStats();
|
||||
|
||||
// 监听窗口大小变化,重绘图表
|
||||
window.addEventListener('resize', function() {
|
||||
var charts = document.querySelectorAll('.chart-container');
|
||||
charts.forEach(function(chart) {
|
||||
var instance = echarts.getInstanceByDom(chart);
|
||||
if (instance) {
|
||||
instance.resize();
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('初始化图表失败:', error);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
<script type="text/javascript">
|
||||
// 显示图片
|
||||
function show_img(obj){
|
||||
var imgurl = $(obj).attr('src');
|
||||
var res = getMousePos();
|
||||
var html = '<div style="background:#fff;position:absolute;width:200px;border:solid 1px #cdcdcd;border-radius:6px;padding:2px;left:'+res.x+'px;top:'+res.y+'px;z-index:1000" id="preview">\
|
||||
<img style="width:100%;border-radius:6px;" src="'+imgurl+'">\
|
||||
</div>';
|
||||
$('body').append(html);
|
||||
}
|
||||
// 隐藏图片
|
||||
function hide_img(){
|
||||
$('#preview').remove();
|
||||
}
|
||||
// 图片位置计算
|
||||
function getMousePos(event) {
|
||||
var e = event || window.event;
|
||||
var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
|
||||
var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
var x = e.pageX || e.clientX + scrollX;
|
||||
var y = e.pageY || e.clientY + scrollY;
|
||||
return { 'x': x, 'y': y };
|
||||
}
|
||||
// 删除图片
|
||||
function deleteImage(path,obj){
|
||||
$(obj).closest('.upload_pic_li').remove();
|
||||
}
|
||||
</script>
|
||||
300
runtime/admin/temp/4362e65c6d8297a2ebddffccccfcd7f3.php
Normal file
300
runtime/admin/temp/4362e65c6d8297a2ebddffccccfcd7f3.php
Normal file
@ -0,0 +1,300 @@
|
||||
<?php /*a:2:{s:63:"E:\Demos\DemoOwns\PHP\yunzer\app\admin\view\resources\lists.php";i:1747702165;s:61:"E:\Demos\DemoOwns\PHP\yunzer\app\admin\view\public\header.php";i:1746849526;}*/ ?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><?php echo htmlentities((string) $config['admin_name']); ?></title>
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css" media="all"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/moban.css" media="all"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/wangeditor.css" media="all"/>
|
||||
<style type="text/css">
|
||||
.header span{background:#009688;margin-left:30px;padding:10px;color:#ffffff;}
|
||||
.header div{border-bottom:solid 2px #009688;margin-top: 8px;}
|
||||
.header button{float:right;margin-top:-5px;}
|
||||
.pagination {
|
||||
display: inline-block;
|
||||
padding-left: 0;
|
||||
margin: 20px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.pagination > li {
|
||||
display: inline;
|
||||
}
|
||||
.pagination > li > a,
|
||||
.pagination > li > span {
|
||||
position: relative;
|
||||
float: left;
|
||||
padding: 6px 12px;
|
||||
margin-left: -1px;
|
||||
line-height: 1.42857143;
|
||||
color: #337ab7;
|
||||
text-decoration: none;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.pagination > li:first-child > a,
|
||||
.pagination > li:first-child > span {
|
||||
margin-left: 0;
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.pagination > li:last-child > a,
|
||||
.pagination > li:last-child > span {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
.pagination > li > a:hover,
|
||||
.pagination > li > span:hover,
|
||||
.pagination > li > a:focus,
|
||||
.pagination > li > span:focus {
|
||||
z-index: 2;
|
||||
color: #23527c;
|
||||
background-color: #eee;
|
||||
border-color: #ddd;
|
||||
}
|
||||
.pagination > .active > a,
|
||||
.pagination > .active > span,
|
||||
.pagination > .active > a:hover,
|
||||
.pagination > .active > span:hover,
|
||||
.pagination > .active > a:focus,
|
||||
.pagination > .active > span:focus {
|
||||
z-index: 3;
|
||||
color: #fff;
|
||||
cursor: default;
|
||||
background-color: #337ab7;
|
||||
border-color: #337ab7;
|
||||
}
|
||||
.pagination > .disabled > span,
|
||||
.pagination > .disabled > span:hover,
|
||||
.pagination > .disabled > span:focus,
|
||||
.pagination > .disabled > a,
|
||||
.pagination > .disabled > a:hover,
|
||||
.pagination > .disabled > a:focus {
|
||||
color: #777;
|
||||
cursor: not-allowed;
|
||||
background-color: #fff;
|
||||
border-color: #ddd;
|
||||
}
|
||||
.close-img { background: url(/static/images/close_img.png); background-size: 20px 20px; width:20px; height: 20px; position: absolute; right: 5px; top: 5px; z-index: 2;}
|
||||
</style>
|
||||
<script type="text/javascript" src="/static/layui/layui.js"></script>
|
||||
<script type="text/javascript">
|
||||
layui.use(['layer','form','table','laydate','element','upload'],function(){
|
||||
layer = layui.layer; // layui 弹框
|
||||
form = layui.form; // layui form表单
|
||||
table = layui.table; // layui 表格
|
||||
laydate = layui.laydate; // layui 时间框
|
||||
element = layui.element; // layui element
|
||||
upload = layui.upload; // layui 上传
|
||||
$ = layui.jquery; // layui jquery
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<body style="padding:10px; box-sizing: border-box;">
|
||||
<div class="config-container">
|
||||
<!-- 页面头部样式 -->
|
||||
<div class="config-header" style="display: flex;flex-direction: column;flex-wrap: wrap;align-items: flex-start;">
|
||||
<div class="maintitle">
|
||||
<i class="layui-icon layui-icon-file"></i>
|
||||
<span>资源列表</span>
|
||||
</div>
|
||||
<div style="display: flex;align-items: flex-start;flex-direction: column;gap: 15px;margin-bottom: 10px;">
|
||||
<div class="shaixuan">
|
||||
<label>筛选:</label>
|
||||
<div class="layui-form" style="display: flex; gap: 10px;">
|
||||
<div class="layui-input-inline">
|
||||
<select id="categoryFilter" lay-filter="categoryFilter" lay-verify="">
|
||||
<option value="">全部分类</option>
|
||||
<?php if(is_array($categories) || $categories instanceof \think\Collection || $categories instanceof \think\Paginator): $i = 0; $__LIST__ = $categories;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$category): $mod = ($i % 2 );++$i;?>
|
||||
<optgroup label="<?php echo htmlentities((string) $category['name']); ?>">
|
||||
<?php if(is_array($category['children']) || $category['children'] instanceof \think\Collection || $category['children'] instanceof \think\Paginator): $i = 0; $__LIST__ = $category['children'];if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$subCategory): $mod = ($i % 2 );++$i;?>
|
||||
<option value="<?php echo htmlentities((string) $subCategory['id']); ?>"><?php echo htmlentities((string) $subCategory['name']); ?></option>
|
||||
<?php endforeach; endif; else: echo "" ;endif; ?>
|
||||
</optgroup>
|
||||
<?php endforeach; endif; else: echo "" ;endif; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" id="nameSearch" placeholder="搜索资源名称" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-input-inline">
|
||||
<input type="text" id="uploaderSearch" placeholder="搜索上传者" class="layui-input">
|
||||
</div>
|
||||
<button type="button" class="layui-btn layui-btn-normal" onclick="doSearch()">
|
||||
<i class="layui-icon layui-icon-search"></i>搜索
|
||||
</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary layui-border-blue" onclick="doRefresh()">
|
||||
<i class="layui-icon layui-icon-refresh"></i>重置
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" class="layui-btn layui-btn-normal" onclick="add()">
|
||||
<i class="layui-icon layui-icon-add-1"></i>添加资源
|
||||
</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary layui-border-blue" onclick="refresh()">
|
||||
<i class="layui-icon layui-icon-refresh"></i>刷新
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table id="resourceTable" lay-filter="resourceTable"></table>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="iconTemplate">
|
||||
{{# if(d.icon){ }}
|
||||
<img src="{{ d.icon }}" style="max-width: 50px; max-height: 50px;">
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="statusTemplate">
|
||||
{{# if(d.status == '0'){ }}
|
||||
<span style="color:red;">未审核</span>
|
||||
{{# } else if(d.status == '1'){ }}
|
||||
<span style="color:orange;">已审核</span>
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="operationBar">
|
||||
<button type="button" class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">
|
||||
<i class="layui-icon layui-icon-edit"></i>编辑
|
||||
</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary layui-btn-xs" lay-event="del">
|
||||
<i class="layui-icon layui-icon-delete"></i>删除
|
||||
</button>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
layui.use(['layer', 'form', 'table'], function () {
|
||||
var layer = layui.layer;
|
||||
var $ = layui.jquery;
|
||||
var form = layui.form;
|
||||
var table = layui.table;
|
||||
|
||||
// 初始化表格
|
||||
table.render({
|
||||
elem: '#resourceTable',
|
||||
url: '/admin/resources/lists',
|
||||
method: 'post',
|
||||
cols: [[
|
||||
{ field: 'id', title: 'ID', align: 'center', width: 80 },
|
||||
{ field: 'title', title: '资源名称' },
|
||||
{ field: 'cate', title: '分类', align: 'center', width: 120 },
|
||||
{ field: 'icon', title: '图标', templet: '#iconTemplate', align: 'center', width: 100 },
|
||||
{ field: 'uploader', title: '上传者', align: 'center', width: 100 },
|
||||
{ field: 'desc', title: '描述', width: 200 },
|
||||
{ field: 'status', title: '状态', templet: '#statusTemplate', align: 'center', width: 80 },
|
||||
{ title: '操作', toolbar: '#operationBar', align: 'center', width: 150, fixed: 'right' }
|
||||
]],
|
||||
page: true,
|
||||
limit: 10,
|
||||
limits: [10, 50, 100],
|
||||
//height: 'full-220'
|
||||
});
|
||||
|
||||
// 监听工具条事件
|
||||
table.on('tool(resourceTable)', function (obj) {
|
||||
var data = obj.data;
|
||||
if (obj.event === 'edit') {
|
||||
edit(data.id);
|
||||
} else if (obj.event === 'del') {
|
||||
del(data.id);
|
||||
}
|
||||
});
|
||||
|
||||
// 监听分类筛选变化
|
||||
form.on('select(categoryFilter)', function (data) {
|
||||
filterByCategory(data.value);
|
||||
});
|
||||
});
|
||||
|
||||
function filterByCategory(categoryId) {
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
function doSearch() {
|
||||
var nameKeyword = $('#nameSearch').val().trim();
|
||||
var uploaderKeyword = $('#uploaderSearch').val().trim();
|
||||
|
||||
if (!nameKeyword && !uploaderKeyword && !$('#categoryFilter').val()) {
|
||||
layer.msg('请输入搜索条件', { icon: 0 });
|
||||
return;
|
||||
}
|
||||
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
function doRefresh() {
|
||||
// 清空搜索条件
|
||||
$('#nameSearch').val('');
|
||||
$('#uploaderSearch').val('');
|
||||
$('#categoryFilter').val('');
|
||||
layui.form.render('select'); // 重新渲染select
|
||||
|
||||
// 重新加载表格,不带任何筛选条件
|
||||
layui.table.reload('resourceTable', {
|
||||
where: {},
|
||||
page: {
|
||||
curr: 1
|
||||
}
|
||||
});
|
||||
|
||||
layer.msg('已重置', { icon: 1 });
|
||||
}
|
||||
|
||||
function reloadTable() {
|
||||
var categoryId = $('#categoryFilter').val();
|
||||
var categoryName = '';
|
||||
if (categoryId) {
|
||||
var selectedOption = $('#categoryFilter option[value="' + categoryId + '"]');
|
||||
if (selectedOption.length > 0) {
|
||||
categoryName = selectedOption.text().trim();
|
||||
}
|
||||
}
|
||||
var nameKeyword = $('#nameSearch').val().trim();
|
||||
var uploaderKeyword = $('#uploaderSearch').val().trim();
|
||||
|
||||
layui.table.reload('resourceTable', {
|
||||
where: {
|
||||
category: categoryName,
|
||||
name: nameKeyword,
|
||||
uploader: uploaderKeyword
|
||||
},
|
||||
page: {
|
||||
curr: 1
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function add() {
|
||||
window.location.href = '/admin/resources/add';
|
||||
}
|
||||
|
||||
function edit(id) {
|
||||
window.location.href = '/admin/resources/edit?id=' + id;
|
||||
}
|
||||
|
||||
function del(id) {
|
||||
layer.confirm('确定要删除该资源吗?', {
|
||||
btn: ['确定', '取消']
|
||||
}, function () {
|
||||
$.post('/admin/resources/delete', { id: id }, function (res) {
|
||||
if (res.code == 0) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
setTimeout(function () {
|
||||
layui.table.reload('resourceTable');
|
||||
}, 1000);
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
layui.table.reload('resourceTable');
|
||||
}
|
||||
</script>
|
||||
426
runtime/admin/temp/606cb5a28477c3a4a33c90fc473c4624.php
Normal file
426
runtime/admin/temp/606cb5a28477c3a4a33c90fc473c4624.php
Normal file
@ -0,0 +1,426 @@
|
||||
<?php /*a:2:{s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\admin\view\resources\edit.php";i:1747445574;s:61:"E:\Demos\DemoOwns\PHP\yunzer\app\admin\view\public\header.php";i:1746849526;}*/ ?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><?php echo htmlentities((string) $config['admin_name']); ?></title>
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css" media="all"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/moban.css" media="all"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/wangeditor.css" media="all"/>
|
||||
<style type="text/css">
|
||||
.header span{background:#009688;margin-left:30px;padding:10px;color:#ffffff;}
|
||||
.header div{border-bottom:solid 2px #009688;margin-top: 8px;}
|
||||
.header button{float:right;margin-top:-5px;}
|
||||
.pagination {
|
||||
display: inline-block;
|
||||
padding-left: 0;
|
||||
margin: 20px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.pagination > li {
|
||||
display: inline;
|
||||
}
|
||||
.pagination > li > a,
|
||||
.pagination > li > span {
|
||||
position: relative;
|
||||
float: left;
|
||||
padding: 6px 12px;
|
||||
margin-left: -1px;
|
||||
line-height: 1.42857143;
|
||||
color: #337ab7;
|
||||
text-decoration: none;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.pagination > li:first-child > a,
|
||||
.pagination > li:first-child > span {
|
||||
margin-left: 0;
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.pagination > li:last-child > a,
|
||||
.pagination > li:last-child > span {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
.pagination > li > a:hover,
|
||||
.pagination > li > span:hover,
|
||||
.pagination > li > a:focus,
|
||||
.pagination > li > span:focus {
|
||||
z-index: 2;
|
||||
color: #23527c;
|
||||
background-color: #eee;
|
||||
border-color: #ddd;
|
||||
}
|
||||
.pagination > .active > a,
|
||||
.pagination > .active > span,
|
||||
.pagination > .active > a:hover,
|
||||
.pagination > .active > span:hover,
|
||||
.pagination > .active > a:focus,
|
||||
.pagination > .active > span:focus {
|
||||
z-index: 3;
|
||||
color: #fff;
|
||||
cursor: default;
|
||||
background-color: #337ab7;
|
||||
border-color: #337ab7;
|
||||
}
|
||||
.pagination > .disabled > span,
|
||||
.pagination > .disabled > span:hover,
|
||||
.pagination > .disabled > span:focus,
|
||||
.pagination > .disabled > a,
|
||||
.pagination > .disabled > a:hover,
|
||||
.pagination > .disabled > a:focus {
|
||||
color: #777;
|
||||
cursor: not-allowed;
|
||||
background-color: #fff;
|
||||
border-color: #ddd;
|
||||
}
|
||||
.close-img { background: url(/static/images/close_img.png); background-size: 20px 20px; width:20px; height: 20px; position: absolute; right: 5px; top: 5px; z-index: 2;}
|
||||
</style>
|
||||
<script type="text/javascript" src="/static/layui/layui.js"></script>
|
||||
<script type="text/javascript">
|
||||
layui.use(['layer','form','table','laydate','element','upload'],function(){
|
||||
layer = layui.layer; // layui 弹框
|
||||
form = layui.form; // layui form表单
|
||||
table = layui.table; // layui 表格
|
||||
laydate = layui.laydate; // layui 时间框
|
||||
element = layui.element; // layui element
|
||||
upload = layui.upload; // layui 上传
|
||||
$ = layui.jquery; // layui jquery
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<body style="padding:10px; box-sizing: border-box;">
|
||||
<div class="config-container">
|
||||
<div class="config-header" style="display:flex;justify-content: space-between;">
|
||||
<div>
|
||||
<span>编辑资源</span>
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" class="layui-btn layui-btn-primary layui-btn-sm" onclick="goBack()">
|
||||
<i class="layui-icon layui-icon-return"></i>返回
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<form class="layui-form" action="" method="post">
|
||||
<input type="hidden" name="id" value="<?php echo htmlentities((string) (isset($resource['id']) && ($resource['id'] !== '')?$resource['id']:'')); ?>">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">资源名称</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" required lay-verify="required" placeholder="请输入资源名称" autocomplete="off"
|
||||
class="layui-input" value="<?php echo htmlentities((string) (isset($resource['title']) && ($resource['title'] !== '')?$resource['title']:'')); ?>" lay-affix="clear">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类</label>
|
||||
<div class="layui-input-block">
|
||||
<select name="cate" lay-verify="required">
|
||||
<option value="">请选择分类</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">描述</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="desc" placeholder="请输入资源描述" class="layui-textarea" lay-affix="clear"><?php echo htmlentities((string) (isset($resource['desc']) && ($resource['desc'] !== '')?$resource['desc']:'')); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">上传者</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="uploader" required lay-verify="required" placeholder="请输入上传者"
|
||||
autocomplete="off" class="layui-input" value="<?php echo htmlentities((string) (isset($resource['uploader']) && ($resource['uploader'] !== '')?$resource['uploader']:'')); ?>" lay-affix="clear">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">资源图标</label>
|
||||
<div class="layui-input-block">
|
||||
<button type="button" class="layui-btn" id="upload-btn">
|
||||
<i class="layui-icon layui-icon-upload"></i> 图标上传
|
||||
</button>
|
||||
<div style="width: 120px;">
|
||||
<div class="layui-upload-list">
|
||||
<img class="layui-upload-img" id="upload-img"
|
||||
style="width: 118px; height: 118px;object-fit: cover;">
|
||||
<div id="upload-text"></div>
|
||||
</div>
|
||||
<div class="layui-progress layui-progress-big" lay-showPercent="yes" lay-filter="icon-progress">
|
||||
<div class="layui-progress-bar" lay-percent=""></div>
|
||||
</div>
|
||||
<input type="hidden" name="icon" id="icon" value="">
|
||||
</div>
|
||||
<div class="layui-form-mid layui-word-aux">建议尺寸:128px * 128px</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">资源文件</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="fileurl" required placeholder="本地资源地址" autocomplete="off"
|
||||
class="layui-input" value="<?php echo htmlentities((string) (isset($resource['fileurl']) && ($resource['fileurl'] !== '')?$resource['fileurl']:'')); ?>" style="margin-bottom: 10px;" lay-affix="clear">
|
||||
<div class="layui-upload-drag" style="display: block;" id="ID-upload-demo-drag">
|
||||
<i class="layui-icon layui-icon-upload"></i>
|
||||
<div>点击上传,或将文件拖拽到此处</div>
|
||||
<div class="layui-hide" id="ID-upload-demo-preview">
|
||||
<hr>
|
||||
<div class="file-info">
|
||||
<i class="layui-icon layui-icon-file"></i>
|
||||
<span class="file-name"></span>
|
||||
<span class="file-size"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-progress layui-progress-big" lay-showPercent="yes" lay-filter="file-progress" style="margin-top: 10px;">
|
||||
<div class="layui-progress-bar" lay-percent=""></div>
|
||||
</div>
|
||||
<input type="hidden" name="file" id="file" value="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">资源链接</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="url" required placeholder="百度网盘、115网盘、蓝奏云等" autocomplete="off"
|
||||
class="layui-input" value="<?php echo htmlentities((string) (isset($resource['url']) && ($resource['url'] !== '')?$resource['url']:'')); ?>" lay-affix="clear">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分享码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="code" required placeholder="请输入分享码" autocomplete="off"
|
||||
class="layui-input" value="<?php echo htmlentities((string) (isset($resource['code']) && ($resource['code'] !== '')?$resource['code']:'')); ?>" lay-affix="clear">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">排序</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="number" name="sort" value="<?php echo htmlentities((string) (isset($resource['sort']) && ($resource['sort'] !== '')?$resource['sort']:'0')); ?>" class="layui-input" placeholder="数字越大越靠前" lay-affix="clear">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<button class="layui-btn" lay-submit lay-filter="formSubmit">立即提交</button>
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
layui.use(['form', 'layer'], function () {
|
||||
var form = layui.form;
|
||||
var layer = layui.layer;
|
||||
var $ = layui.$;
|
||||
var upload = layui.upload;
|
||||
var element = layui.element;
|
||||
|
||||
// 获取资源详情
|
||||
var resourceId = $('input[name="id"]').val();
|
||||
var resourceData = null;
|
||||
|
||||
if (resourceId) {
|
||||
$.get('<?php echo url("resources/get"); ?>', {id: resourceId}, function(res) {
|
||||
if (res.code == 0) {
|
||||
resourceData = res.data;
|
||||
console.log('Resource data:', resourceData); // 调试输出
|
||||
|
||||
// 设置表单值
|
||||
$('input[name="title"]').val(resourceData.title || '');
|
||||
$('select[name="cate"]').val(resourceData.cate || '');
|
||||
form.render('select'); // 重新渲染select以显示选中值
|
||||
$('textarea[name="desc"]').val(resourceData.desc || '');
|
||||
$('input[name="uploader"]').val(resourceData.uploader || '');
|
||||
$('input[name="url"]').val(resourceData.url || '');
|
||||
$('input[name="code"]').val(resourceData.code || '');
|
||||
$('input[name="sort"]').val(resourceData.sort || '0');
|
||||
$('input[name="icon"]').val(resourceData.icon || '');
|
||||
$('input[name="file"]').val(resourceData.file || '');
|
||||
|
||||
// 设置图标预览
|
||||
if (resourceData.icon) {
|
||||
$('#upload-img').attr('src', resourceData.icon);
|
||||
}
|
||||
|
||||
// 设置文件预览
|
||||
if (resourceData.file) {
|
||||
$('#ID-upload-demo-preview').show();
|
||||
$('.file-name').text(resourceData.file_name || '已上传文件');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 图标上传
|
||||
var iconUpload = upload.render({
|
||||
elem: '#upload-btn',
|
||||
url: '<?php echo url("index/upload_img"); ?>',
|
||||
before: function (obj) {
|
||||
obj.preview(function (index, file, result) {
|
||||
$('#upload-img').attr('src', result);
|
||||
});
|
||||
element.progress('icon-progress', '0%');
|
||||
layer.msg('图标上传中', { icon: 16, time: 0 });
|
||||
},
|
||||
done: function (res) {
|
||||
if (res.code > 0) {
|
||||
return layer.msg('图标上传失败');
|
||||
}
|
||||
$('#icon').val(res.data);
|
||||
$('#upload-text').html('');
|
||||
layer.msg('图标上传成功', { icon: 1 });
|
||||
},
|
||||
uploadError: function () {
|
||||
var demoText = $('#upload-text');
|
||||
demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
|
||||
demoText.find('.demo-reload').on('click', function () {
|
||||
iconUpload.upload();
|
||||
});
|
||||
},
|
||||
progress: function (n, elem, e) {
|
||||
element.progress('icon-progress', n + '%');
|
||||
if (n == 100) {
|
||||
layer.msg('图标上传完毕', { icon: 1 });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 文件上传
|
||||
var fileUpload = upload.render({
|
||||
elem: '#ID-upload-demo-drag',
|
||||
url: '<?php echo url("index/upload_file"); ?>',
|
||||
accept: 'file',
|
||||
exts: 'doc|docx|xls|xlsx|ppt|pptx|pdf|txt|zip|rar|7z',
|
||||
before: function (obj) {
|
||||
obj.preview(function (index, file, result) {
|
||||
$('#ID-upload-demo-preview').show();
|
||||
$('.file-name').text(file.name);
|
||||
$('.file-size').text(formatFileSize(file.size));
|
||||
});
|
||||
element.progress('file-progress', '0%');
|
||||
layer.msg('文件上传中', { icon: 16, time: 0 });
|
||||
},
|
||||
done: function (res) {
|
||||
if (res.code > 0) {
|
||||
return layer.msg('文件上传失败');
|
||||
}
|
||||
$('#file').val(res.data.src);
|
||||
$('input[name="fileurl"]').val(res.data.src);
|
||||
layer.msg('文件上传成功', { icon: 1 });
|
||||
},
|
||||
uploadError: function () {
|
||||
layer.msg('文件上传失败', { icon: 2 });
|
||||
},
|
||||
progress: function (n, elem, e) {
|
||||
element.progress('file-progress', n + '%');
|
||||
if (n == 100) {
|
||||
layer.msg('文件上传完毕', { icon: 1 });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 格式化文件大小
|
||||
function formatFileSize(bytes) {
|
||||
if (bytes === 0) return '0 B';
|
||||
const k = 1024;
|
||||
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||||
}
|
||||
|
||||
// 获取分类列表
|
||||
$.get('<?php echo url("resources/getcate"); ?>', function (res) {
|
||||
if (res.code == 0) {
|
||||
var html = '<option value="">请选择分类</option>';
|
||||
res.data.forEach(function (item) {
|
||||
html += '<option value="' + item.id + '">' + item.name + '</option>';
|
||||
if (item.children && item.children.length > 0) {
|
||||
item.children.forEach(function (child) {
|
||||
html += '<option value="' + child.id + '">├─ ' + child.name + '</option>';
|
||||
});
|
||||
}
|
||||
});
|
||||
$('select[name="cate"]').html(html);
|
||||
|
||||
// 如果有资源数据,设置分类值
|
||||
if (resourceData && resourceData.cate) {
|
||||
console.log('Setting cate value:', resourceData.cate); // 调试输出
|
||||
setTimeout(function() {
|
||||
$('select[name="cate"]').val(resourceData.cate);
|
||||
form.render('select');
|
||||
}, 100);
|
||||
}
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
});
|
||||
|
||||
// 表单提交
|
||||
form.on('submit(formSubmit)', function (data) {
|
||||
var loadIndex = layer.load(2);
|
||||
$.ajax({
|
||||
url: '<?php echo url("resources/edit"); ?>',
|
||||
type: 'POST',
|
||||
data: data.field,
|
||||
success: function (res) {
|
||||
layer.close(loadIndex);
|
||||
if (res.code == 0) {
|
||||
layer.msg(res.msg, { icon: 1 });
|
||||
setTimeout(function () {
|
||||
window.location.href = '<?php echo url("resources/lists"); ?>';
|
||||
}, 1000);
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// 重置按钮点击事件
|
||||
$('button[type="reset"]').on('click', function() {
|
||||
// 重新加载分类列表
|
||||
$.get('<?php echo url("resources/getcate"); ?>', function (res) {
|
||||
if (res.code == 0) {
|
||||
var html = '<option value="">请选择分类</option>';
|
||||
res.data.forEach(function (item) {
|
||||
html += '<option value="' + item.id + '">' + item.name + '</option>';
|
||||
if (item.children && item.children.length > 0) {
|
||||
item.children.forEach(function (child) {
|
||||
html += '<option value="' + child.id + '">├─ ' + child.name + '</option>';
|
||||
});
|
||||
}
|
||||
});
|
||||
$('select[name="cate"]').html(html);
|
||||
|
||||
// 如果有资源数据,设置分类值
|
||||
if (resourceData && resourceData.cate) {
|
||||
setTimeout(function() {
|
||||
$('select[name="cate"]').val(resourceData.cate);
|
||||
form.render('select');
|
||||
}, 100);
|
||||
} else {
|
||||
form.render('select');
|
||||
}
|
||||
} else {
|
||||
layer.msg(res.msg, { icon: 2 });
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
//返回资源列表
|
||||
function goBack() {
|
||||
window.location.href = '<?php echo url("resources/lists"); ?>';
|
||||
}
|
||||
</script>
|
||||
425
runtime/admin/temp/7013e3bcaaaa1c5a1494af79f99ce42f.php
Normal file
425
runtime/admin/temp/7013e3bcaaaa1c5a1494af79f99ce42f.php
Normal file
@ -0,0 +1,425 @@
|
||||
<?php /*a:1:{s:59:"E:\Demos\DemoOwns\PHP\yunzer\app\admin\view\index\index.php";i:1747638193;}*/ ?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title><?php echo htmlentities((string) $config['admin_name']); ?></title>
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" type="text/css" href="/static/third/layui/css/layui.css" media="all">
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/index.css" media="all">
|
||||
<script type="text/javascript" src="/static/third/layui/layui.js"></script>
|
||||
<script type="text/javascript" src="/static/js/admin.js"></script>
|
||||
<style>
|
||||
.layadmin-side-shrink .layui-layout-admin .layui-logo {
|
||||
width: 60px;
|
||||
background-image: url("/static/images/logob32.jpg");
|
||||
}
|
||||
.main-content {
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
}
|
||||
#mainWorkspace {
|
||||
height: 100%;
|
||||
}
|
||||
#mainTabs.layui-tab {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
}
|
||||
.layui-tab-content {
|
||||
padding: 0;
|
||||
height: calc(100% - 41px);
|
||||
}
|
||||
.layui-tab-item {
|
||||
height: 100%;
|
||||
}
|
||||
.main-iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
/* background-color: #f2f2f2; */
|
||||
}
|
||||
.layui-tab-title {
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 2px 0 rgba(0,0,0,.1);
|
||||
}
|
||||
.layui-tab-title .layui-this:after {
|
||||
border-bottom-color: #009688;
|
||||
}
|
||||
#LAY_app_body {
|
||||
overflow: hidden;
|
||||
}
|
||||
.layui-tab-content .layui-tab-item {
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body layadmin-themealias="default" class="layui-layout-body">
|
||||
<div id="LAY_app" class="layadmin-tabspage-none">
|
||||
<div class="layui-layout layui-layout-admin">
|
||||
<div class="layui-header">
|
||||
<!-- 头部区域 -->
|
||||
<div style="display: flex;align-items: center;height:70px;">
|
||||
<ul class="layui-nav layui-layout-left">
|
||||
<li class="layui-nav-item layadmin-flexible" lay-unselect onclick="shrink()">
|
||||
<a href="javascript:;" layadmin-event="flexible" title="侧边伸缩">
|
||||
<i class="layui-icon layui-icon-shrink-right" id="LAY_app_flexible"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="layui-nav layui-layout-right" lay-filter="layadmin-layout-right">
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect title="前端站点" onclick="gotoFront()">
|
||||
<a href="javascript:;" layadmin-event="gotoFront">
|
||||
<i class="layui-icon layui-icon-website"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item layui-hide-xs" lay-unselect title="全屏" onclick="fullScreen()">
|
||||
<a href="javascript:;" layadmin-event="fullscreen">
|
||||
<i class="layui-icon layui-icon-screen-full"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a href="javascript:;">
|
||||
<cite><?php echo htmlentities((string) $aUser['name']); ?></cite>
|
||||
</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd><a lay-href="" onclick="menuFire('yunzeradmin/admininfo',1)">个人中心</a></dd>
|
||||
<hr>
|
||||
<dd layadmin-event="logout" style="text-align:center;" onclick="logout()">
|
||||
<a>退出</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 侧边菜单 -->
|
||||
<div class="layui-side layui-side-menu">
|
||||
<div class="layui-side-scroll">
|
||||
<!-- <div class="layui-logo" lay-href="" style="display: flex;align-items: center;">
|
||||
<img src="/static/images/logo-l-w.png" alt="<?php echo htmlentities((string) $config['admin_name']); ?>"
|
||||
style="max-width: 100%; max-height: 100%;">
|
||||
</div> -->
|
||||
<ul class="layui-nav layui-nav-tree" lay-shrink="all" id="LAY-system-side-menu"
|
||||
lay-filter="layadmin-system-side-menu">
|
||||
<!-- 固定的工作台菜单项 -->
|
||||
<li class="layui-nav-item" data-name="index/welcome">
|
||||
<a href="javascript:;" lay-tips="工作台" lay-direction="2"
|
||||
onclick="menuFire('index/welcome',1)">
|
||||
<i class="layui-icon layui-icon-home" style="margin-top: -20px;"></i>
|
||||
<cite>工作台</cite>
|
||||
</a>
|
||||
</li>
|
||||
<!-- 下面是原有的菜单循环 -->
|
||||
<?php if(is_array($menu) || $menu instanceof \think\Collection || $menu instanceof \think\Paginator): $i = 0; $__LIST__ = $menu;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$vo): $mod = ($i % 2 );++$i;?>
|
||||
<li data-name="<?php echo htmlentities((string) $vo['src']); ?>" data-jump="" class="layui-nav-item">
|
||||
<!-- 修改一级菜单的点击事件,只有当有src时才跳转 -->
|
||||
<a href="javascript:;" lay-tips="<?php echo htmlentities((string) $vo['label']); ?>" lay-direction="2" <?php if(isset($vo['src']) &&
|
||||
$vo['src']): ?>onclick="menuFire('<?php echo htmlentities((string) $vo['src']); ?>',1)" <?php endif; ?>>
|
||||
<i class="layui-icon layui-icons <?php echo htmlentities((string) $vo['icon_class']); ?>"></i>
|
||||
<cite><?php echo htmlentities((string) $vo['label']); ?></cite>
|
||||
</a>
|
||||
<?php if((isset($vo['children']) && $vo['children'])): ?>
|
||||
<dl class="layui-nav-child">
|
||||
<?php if(is_array($vo['children']) || $vo['children'] instanceof \think\Collection || $vo['children'] instanceof \think\Paginator): $i = 0; $__LIST__ = $vo['children'];if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$cvo): $mod = ($i % 2 );++$i;?>
|
||||
<dd data-name="" data-jump="/">
|
||||
<?php if($cvo['type'] == 1): ?>
|
||||
<a href="javascript:;" onclick="menuFire('<?php echo htmlentities((string) $cvo['src']); ?>',1)">
|
||||
<i class="layui-icon layui-icons <?php echo htmlentities((string) $cvo['icon_class']); ?>"></i><?php echo htmlentities((string) $cvo['label']); ?>
|
||||
</a>
|
||||
<?php elseif($cvo['type'] == 2): ?>
|
||||
<a href="<?php echo htmlentities((string) $cvo['src']); ?>" target="_blank">
|
||||
<i class="layui-icon layui-icons <?php echo htmlentities((string) $cvo['icon_class']); ?>"></i><?php echo htmlentities((string) $cvo['label']); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</dd>
|
||||
<?php endforeach; endif; else: echo "" ;endif; ?>
|
||||
</dl>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; endif; else: echo "" ;endif; ?>
|
||||
</ul>
|
||||
<div style="position: absolute;bottom:20px;width:200px;display:flex;justify-content: center;">
|
||||
<a style="color:#848484" href="https://www.yunzer.cn/">POWER BY 云泽网</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 主体内容 -->
|
||||
<div class="layui-body" id="LAY_app_body">
|
||||
<div class="main-content">
|
||||
<!-- 默认工作台界面 -->
|
||||
<div id="mainWorkspace">
|
||||
<iframe src="<?php echo htmlentities((string) $config['admin_route']); ?>index/welcome" class="main-iframe" frameborder="0" scrolling="0"></iframe>
|
||||
</div>
|
||||
<!-- 动态标签页 -->
|
||||
<div id="mainTabs" class="layui-tab" lay-allowClose="true" lay-filter="mainTabs" style="margin-top: 10px;">
|
||||
<ul class="layui-tab-title"></ul>
|
||||
<div class="layui-tab-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 辅助元素,一般用于移动设备下遮罩 -->
|
||||
<div class="layadmin-body-shade" layadmin-event="shade" onclick="shrink()"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 辅助元素,一般用于移动设备下遮罩 -->
|
||||
<div class="layadmin-body-shade" layadmin-event="shade"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
layui.use(['element', 'layer', 'jquery'], function () {
|
||||
var element = layui.element;
|
||||
$ = layui.jquery;
|
||||
layer = layui.layer;
|
||||
setter = layui.setter;
|
||||
|
||||
// 保存标签状态
|
||||
function saveTabState(layid, title, url) {
|
||||
var tabState = {
|
||||
layid: layid,
|
||||
title: title,
|
||||
url: url
|
||||
};
|
||||
sessionStorage.setItem('currentTab', JSON.stringify(tabState));
|
||||
}
|
||||
|
||||
// 恢复标签状态
|
||||
function restoreTabState() {
|
||||
var tabState = sessionStorage.getItem('currentTab');
|
||||
if (tabState) {
|
||||
try {
|
||||
var tab = JSON.parse(tabState);
|
||||
if (tab.url && tab.title) {
|
||||
addTab(tab.title, tab.url, tab.layid);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to restore tab state:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 在页面加载完成后执行
|
||||
$(document).ready(function () {
|
||||
// 获取URL参数
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
var page = urlParams.get('page');
|
||||
|
||||
if (page) {
|
||||
// 如果有page参数,加载对应页面到iframe
|
||||
$('iframe').attr('src', "<?php echo htmlentities((string) $config['admin_route']); ?>" + page);
|
||||
} else {
|
||||
// 否则加载默认页面
|
||||
$('iframe').attr('src', "<?php echo htmlentities((string) $config['admin_route']); ?>index/welcome");
|
||||
}
|
||||
|
||||
// 恢复标签状态
|
||||
restoreTabState();
|
||||
});
|
||||
|
||||
// 添加或切换到标签页
|
||||
window.addTab = function(title, url, id) {
|
||||
var element = layui.element;
|
||||
var $ = layui.jquery;
|
||||
var layid = id || url.replace(/\//g, '_');
|
||||
|
||||
// 如果是首页/工作台,直接显示主工作区
|
||||
if(url.indexOf('index/welcome') > -1 || url.indexOf('welcome') > -1) {
|
||||
$('#mainTabs').hide();
|
||||
$('#mainWorkspace').show();
|
||||
$('#mainWorkspace iframe').attr('src', url);
|
||||
sessionStorage.removeItem('currentTab');
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示标签区域
|
||||
$('#mainWorkspace').hide();
|
||||
$('#mainTabs').show();
|
||||
|
||||
// 如果标签已存在,直接切换
|
||||
if($('.layui-tab-title li[lay-id="'+ layid +'"]').length > 0) {
|
||||
element.tabChange('mainTabs', layid);
|
||||
saveTabState(layid, title, url);
|
||||
return;
|
||||
}
|
||||
|
||||
// 添加新标签
|
||||
element.tabAdd('mainTabs', {
|
||||
title: title,
|
||||
content: '<iframe src="' + url + '" class="main-iframe" frameborder="0"></iframe>',
|
||||
id: layid
|
||||
});
|
||||
|
||||
// 切换到新标签页
|
||||
element.tabChange('mainTabs', layid);
|
||||
|
||||
// 保存当前标签状态
|
||||
saveTabState(layid, title, url);
|
||||
};
|
||||
|
||||
// 监听标签切换事件
|
||||
element.on('tab(mainTabs)', function(data){
|
||||
var layid = $(this).attr('lay-id');
|
||||
// 确保当前标签页内容可见
|
||||
$('.layui-tab-content .layui-tab-item').eq(data.index).addClass('layui-show')
|
||||
.siblings().removeClass('layui-show');
|
||||
|
||||
// 更新保存的标签状态
|
||||
var title = $(this).text();
|
||||
var url = $('.layui-tab-content .layui-tab-item').eq(data.index).find('iframe').attr('src');
|
||||
saveTabState(layid, title, url);
|
||||
});
|
||||
|
||||
// 监听标签删除事件
|
||||
element.on('tabDelete(mainTabs)', function(data){
|
||||
// 如果没有标签了,显示工作台
|
||||
if($('.layui-tab-title li').length === 0) {
|
||||
$('#mainTabs').hide();
|
||||
$('#mainWorkspace').show();
|
||||
sessionStorage.removeItem('currentTab');
|
||||
}
|
||||
});
|
||||
|
||||
// 左侧菜单点击事件
|
||||
$('.left-nav #nav li').click(function (event) {
|
||||
if ($(this).children('.sub-menu').length) {
|
||||
if ($(this).hasClass('open')) {
|
||||
$(this).removeClass('open');
|
||||
$(this).find('.nav_right').html('');
|
||||
$(this).children('.sub-menu').stop().slideUp();
|
||||
$(this).siblings().children('.sub-menu').slideUp();
|
||||
} else {
|
||||
$(this).addClass('open');
|
||||
$(this).children('a').find('.nav_right').html('');
|
||||
$(this).children('.sub-menu').stop().slideDown();
|
||||
$(this).siblings().children('.sub-menu').stop().slideUp();
|
||||
$(this).siblings().find('.nav_right').html('');
|
||||
$(this).siblings().removeClass('open');
|
||||
}
|
||||
} else {
|
||||
var url = $(this).children('a').attr('_href');
|
||||
var title = $(this).children('a').html();
|
||||
title = title.replace(/<[^>]+>/g, "").trim(); // 移除HTML标签
|
||||
|
||||
if (url) {
|
||||
window.addTab(title, url);
|
||||
}
|
||||
}
|
||||
event.stopPropagation();
|
||||
})
|
||||
|
||||
// 修改resetMainHeight函数
|
||||
function resetMainHeight(iframe) {
|
||||
if (!iframe) return;
|
||||
try {
|
||||
// 获取视口高度
|
||||
var clientHeight = document.documentElement.clientHeight;
|
||||
// 计算iframe应该的高度(减去头部和tab标签的高度)
|
||||
var iframeHeight = clientHeight - 60 - 40; // 60px是头部高度,40px是tab标签高度
|
||||
$(iframe).css({
|
||||
'height': iframeHeight + 'px',
|
||||
'width': '100%',
|
||||
'display': 'block'
|
||||
});
|
||||
} catch(e) {
|
||||
console.error('Reset iframe height failed:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// 在窗口大小改变时重置所有iframe高度
|
||||
$(window).on('resize', function() {
|
||||
$('.main-iframe').each(function() {
|
||||
resetMainHeight(this);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// 菜单点击
|
||||
function menuFire(obj, num) {
|
||||
if (num == 1) {
|
||||
var title = '';
|
||||
// 获取菜单标题
|
||||
$('.layui-nav-item a').each(function() {
|
||||
if($(this).attr('onclick') && $(this).attr('onclick').indexOf(obj) > -1) {
|
||||
title = $(this).text().trim();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// 如果没找到标题,使用子菜单查找
|
||||
if(!title) {
|
||||
$('.layui-nav-child a').each(function() {
|
||||
if($(this).attr('onclick') && $(this).attr('onclick').indexOf(obj) > -1) {
|
||||
title = $(this).text().trim();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 添加或切换到标签页
|
||||
window.addTab(title || '新页面', "<?php echo htmlentities((string) $config['admin_route']); ?>" + obj, obj.replace(/\//g, '_'));
|
||||
|
||||
// 更新浏览器URL,但保持在index页面
|
||||
window.history.pushState({}, '', "<?php echo htmlentities((string) $config['admin_route']); ?>index/index?page=" + obj);
|
||||
|
||||
// 如果是子菜单,确保父菜单展开
|
||||
if (obj.indexOf('/') > -1) {
|
||||
var parentMenu = obj.split('/')[0];
|
||||
$('.layui-nav-item').each(function () {
|
||||
var menuSrc = $(this).find('a').attr('onclick');
|
||||
if (menuSrc && menuSrc.indexOf(parentMenu) > -1) {
|
||||
$(this).addClass('layui-nav-itemed');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
var width = screen();
|
||||
if (width < 2) {
|
||||
shrink();
|
||||
}
|
||||
}
|
||||
|
||||
// 监听浏览器前进后退按钮
|
||||
window.addEventListener('popstate', function (event) {
|
||||
// 获取URL参数
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
var page = urlParams.get('page');
|
||||
|
||||
if (page) {
|
||||
// 如果有page参数,通过标签系统加载页面
|
||||
var title = '新页面';
|
||||
window.addTab(title, "<?php echo htmlentities((string) $config['admin_route']); ?>" + page, page.replace(/\//g, '_'));
|
||||
} else {
|
||||
// 否则加载默认页面
|
||||
element.tabChange('mainTabs', 'welcome');
|
||||
}
|
||||
});
|
||||
|
||||
// 退出
|
||||
function logout() {
|
||||
layer.confirm('确定要退出吗?', {
|
||||
icon: 3,
|
||||
btn: ['确定', '取消']
|
||||
}, function () {
|
||||
$.get("<?php echo htmlentities((string) $config['admin_route']); ?>login/logout", function (res) {
|
||||
if (res.code > 0) {
|
||||
layer.msg(res.msg, { 'icon': 2 });
|
||||
} else {
|
||||
layer.msg(res.msg, { 'icon': 1 });
|
||||
setTimeout(function () { window.location.href = "<?php echo htmlentities((string) $config['admin_route']); ?>login/index"; }, 1000);
|
||||
}
|
||||
}, 'json');
|
||||
});
|
||||
}
|
||||
|
||||
//跳转前端站点
|
||||
function gotoFront() {
|
||||
window.open("//<?php echo htmlentities((string) $config['admin_domain']); ?>", "_blank");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
131
runtime/admin/temp/edac869d5bb28e1f3cea77aed4c26bb2.php
Normal file
131
runtime/admin/temp/edac869d5bb28e1f3cea77aed4c26bb2.php
Normal file
@ -0,0 +1,131 @@
|
||||
<?php /*a:1:{s:59:"E:\Demos\DemoOwns\PHP\yunzer\app\admin\view\login\index.php";i:1747615358;}*/ ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<title>后台管理系统</title>
|
||||
<meta name="renderer" content="yz">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||
<link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css">
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/login.css">
|
||||
<script type="text/javascript" src="/static/layui/layui.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="layadmin-user-login layadmin-user-display-show" id="LAY-user-login">
|
||||
<div class="layadmin-user-login-main">
|
||||
<div class="layadmin-user-login-box layadmin-user-login-header">
|
||||
<img src="/static/images/logo.png" />
|
||||
<h2>后台管理系统</h2>
|
||||
</div>
|
||||
<div class="layadmin-user-login-box layadmin-user-login-body layui-form">
|
||||
<form class="layui-form login-form">
|
||||
<div class="layui-form-item">
|
||||
<label class="layadmin-user-login-icon layui-icon layui-icon-username" for="account"></label>
|
||||
<input type="text" id="account" name="account" placeholder="邮箱" class="layui-input"
|
||||
value="">
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layadmin-user-login-icon layui-icon layui-icon-password" for="password"></label>
|
||||
<input type="password" name="password" lay-affix="eye" class="layui-input" placeholder="密码" class="layui-input"
|
||||
value="">
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-xs7">
|
||||
<label class="layadmin-user-login-icon layui-icon layui-icon-vercode"
|
||||
for="code"></label>
|
||||
<input type="text" name="code" placeholder="图形验证码" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-col-xs5">
|
||||
<div style="margin-left:10px;">
|
||||
<img src="<?php echo captcha_src(); ?>?t=<?php echo time(); ?>" class="layadmin-user-login-codeimg" id="img"
|
||||
onclick="reloadImg()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item" style="margin-bottom: 20px;">
|
||||
<input type="checkbox" name="remember" lay-skin="primary" title="记住密码">
|
||||
</div>
|
||||
</form>
|
||||
<div class="layui-form-item">
|
||||
<button class="layui-btn layui-btn-fluid" onclick="login()">登 陆</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<script type="text/javascript">
|
||||
layui.use(['layer', 'form'], function () {
|
||||
var form = layui.form;
|
||||
layer = layui.layer;
|
||||
$ = layui.jquery;
|
||||
// 用户名控件获取焦点
|
||||
$('#account').focus();
|
||||
// 回车登录
|
||||
$('input').keydown(function (e) {
|
||||
if (e.keyCode == 13) {
|
||||
login();
|
||||
}
|
||||
});
|
||||
});
|
||||
// 重新生成验证码
|
||||
function reloadImg() {
|
||||
var timestamp = new Date().getTime();
|
||||
$('#img').attr('src', '<?php echo captcha_src(); ?>?t=' + timestamp);
|
||||
}
|
||||
|
||||
// 登录处理函数
|
||||
function login() {
|
||||
var account = $('input[name="account"]').val();
|
||||
var password = $('input[name="password"]').val();
|
||||
var code = $('input[name="code"]').val();
|
||||
var remember = $('input[name="remember"]:checked').val();
|
||||
|
||||
if (!account) {
|
||||
layer.msg('邮箱不能为空');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!password) {
|
||||
layer.msg('密码不能为空');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!code) {
|
||||
layer.msg('验证码不能为空');
|
||||
return false;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: 'post',
|
||||
url: '<?php echo url("login"); ?>',
|
||||
data: {
|
||||
account: account,
|
||||
password: password,
|
||||
code: code,
|
||||
remember: remember
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(res) {
|
||||
if (res.code == 0) {
|
||||
layer.msg(res.msg, {icon: 1, time: 1000}, function() {
|
||||
window.location.href = '<?php echo url("Index/index"); ?>';
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.msg, {icon: 2});
|
||||
reloadImg();
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
layer.msg('网络错误,请重试', {icon: 2});
|
||||
reloadImg();
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@ -1,4 +1,4 @@
|
||||
<?php /*a:5:{s:63:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\articles\detail.php";i:1747646466;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\head.php";i:1747617129;s:71:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\header-simple.php";i:1747445574;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\footer.php";i:1747617266;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\foot.php";i:1747616844;}*/ ?>
|
||||
<?php /*a:5:{s:63:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\articles\detail.php";i:1747711602;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\head.php";i:1747617129;s:71:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\header-simple.php";i:1747705841;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\footer.php";i:1747617266;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\foot.php";i:1747616844;}*/ ?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
<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>
|
||||
<a href="index.html"><img src="/static/images/logo1.png" width="186" alt="Logo"></a>
|
||||
</div>
|
||||
<div class="main-menu__nav">
|
||||
<ul class="main-menu__list">
|
||||
@ -90,7 +90,7 @@
|
||||
<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>
|
||||
<a href="index.html"><img src="/static/images/logo1.png" width="150" alt="Logo"></a>
|
||||
</div>
|
||||
<div class="sticky-nav__menu">
|
||||
<ul>
|
||||
@ -475,12 +475,12 @@
|
||||
</div>
|
||||
|
||||
<div class="article-actions">
|
||||
<div class="action-item like-btn">
|
||||
<div class="action-item like-btn" id="likeBtn">
|
||||
<i class="fa fa-thumbs-up"></i>
|
||||
<span class="action-text">点赞</span>
|
||||
<span class="action-count" id="articleLikes">0</span>
|
||||
</div>
|
||||
<div class="action-item share-btn">
|
||||
<div class="action-item share-btn" id="shareBtn">
|
||||
<i class="fa fa-share-alt"></i>
|
||||
<span class="action-text">分享</span>
|
||||
</div>
|
||||
@ -932,31 +932,31 @@
|
||||
function renderArticleDetail(data) {
|
||||
// 渲染分类链接
|
||||
document.getElementById('cateLink').textContent = data.cateName;
|
||||
|
||||
|
||||
// 渲染文章标题
|
||||
document.getElementById('articleTitle').textContent = data.article.title;
|
||||
|
||||
|
||||
// 渲染文章元信息
|
||||
document.getElementById('articleAuthor').textContent = data.article.author;
|
||||
document.getElementById('articleDate').textContent = formatDate(data.article.create_time);
|
||||
document.getElementById('articleViews').textContent = data.article.views;
|
||||
|
||||
|
||||
// 渲染文章内容
|
||||
document.getElementById('articleContent').innerHTML = data.article.content;
|
||||
|
||||
|
||||
// 渲染标签
|
||||
const tagsContainer = document.getElementById('articleTags');
|
||||
if (data.article.tags && data.article.tags.length > 0) {
|
||||
tagsContainer.innerHTML = data.article.tags.map(tag =>
|
||||
tagsContainer.innerHTML = data.article.tags.map(tag =>
|
||||
`<span class="tag-item">${tag}</span>`
|
||||
).join('');
|
||||
} else {
|
||||
tagsContainer.innerHTML = '<span class="no-tags">暂无标签</span>';
|
||||
}
|
||||
|
||||
|
||||
// 渲染点赞数
|
||||
document.getElementById('articleLikes').textContent = data.article.likes || 0;
|
||||
|
||||
|
||||
// 渲染上一篇
|
||||
const prevArticle = document.getElementById('prevArticle');
|
||||
if (data.prevArticle) {
|
||||
@ -968,7 +968,7 @@
|
||||
} else {
|
||||
prevArticle.innerHTML = '<span class="disabled"><i class="fa fa-arrow-left"></i> 没有上一篇了</span>';
|
||||
}
|
||||
|
||||
|
||||
// 渲染下一篇
|
||||
const nextArticle = document.getElementById('nextArticle');
|
||||
if (data.nextArticle) {
|
||||
@ -980,7 +980,7 @@
|
||||
} else {
|
||||
nextArticle.innerHTML = '<span class="disabled">没有下一篇了 <i class="fa fa-arrow-right"></i></span>';
|
||||
}
|
||||
|
||||
|
||||
// 渲染相关文章
|
||||
const relatedArticles = document.getElementById('relatedArticles');
|
||||
if (data.relatedArticles && data.relatedArticles.length > 0) {
|
||||
@ -1003,7 +1003,7 @@
|
||||
}
|
||||
|
||||
// 页面加载完成后执行
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// 获取文章ID
|
||||
const articleId = new URLSearchParams(window.location.search).get('id');
|
||||
if (!articleId) {
|
||||
@ -1018,12 +1018,12 @@
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
console.log('Response status:', response.status);
|
||||
console.log('Response headers:', response.headers);
|
||||
// console.log('Response status:', response.status);
|
||||
// console.log('Response headers:', response.headers);
|
||||
return response.json();
|
||||
})
|
||||
.then(result => {
|
||||
console.log('API response:', result);
|
||||
// console.log('API response:', result);
|
||||
if (result.code === 1) {
|
||||
renderArticleDetail(result.data);
|
||||
// 更新访问次数
|
||||
@ -1043,44 +1043,69 @@
|
||||
});
|
||||
|
||||
// 点赞功能
|
||||
const likeBtn = document.querySelector('.like-btn');
|
||||
const likeBtn = document.getElementById('likeBtn');
|
||||
if (likeBtn) {
|
||||
likeBtn.addEventListener('click', function() {
|
||||
// 检查是否已经点赞
|
||||
if (likeBtn.classList.contains('liked')) {
|
||||
likeBtn.style.pointerEvents = 'none'; // 禁用点击
|
||||
likeBtn.style.cursor = 'default'; // 改变鼠标样式
|
||||
return;
|
||||
}
|
||||
|
||||
likeBtn.addEventListener('click', function () {
|
||||
// 立即禁用按钮,防止重复点击
|
||||
likeBtn.style.pointerEvents = 'none';
|
||||
likeBtn.style.cursor = 'default';
|
||||
|
||||
fetch('/index/articles/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);
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('点赞请求失败:', error);
|
||||
});
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 1) {
|
||||
const countElement = document.getElementById('articlesLikes');
|
||||
if (countElement) {
|
||||
let count = parseInt(countElement.textContent) || 0;
|
||||
countElement.textContent = count + 1;
|
||||
}
|
||||
// 添加点赞状态
|
||||
likeBtn.classList.add('liked');
|
||||
likeBtn.querySelector('i').style.color = '#f57005';
|
||||
layer.msg('点赞成功', {icon: 1});
|
||||
} else {
|
||||
// 如果请求失败,恢复按钮状态
|
||||
likeBtn.style.pointerEvents = 'auto';
|
||||
likeBtn.style.cursor = 'pointer';
|
||||
layer.msg('点赞失败:' + data.msg, {icon: 2});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
// 如果请求失败,恢复按钮状态
|
||||
likeBtn.style.pointerEvents = 'auto';
|
||||
likeBtn.style.cursor = 'pointer';
|
||||
console.error('点赞请求失败:', error);
|
||||
layer.msg('点赞失败,请稍后重试', {icon: 2});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 返回顶部功能
|
||||
const goToTop = document.getElementById('goToTop');
|
||||
|
||||
|
||||
// 监听滚动事件
|
||||
window.addEventListener('scroll', function() {
|
||||
window.addEventListener('scroll', function () {
|
||||
if (window.pageYOffset > 300) {
|
||||
goToTop.classList.add('show');
|
||||
} else {
|
||||
goToTop.classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 点击返回顶部
|
||||
goToTop.addEventListener('click', function() {
|
||||
goToTop.addEventListener('click', function () {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
@ -1099,18 +1124,42 @@
|
||||
id: articleId
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.code === 1) {
|
||||
// 更新成功,更新页面上的访问次数显示
|
||||
const viewsElement = document.getElementById('articleViews');
|
||||
if (viewsElement) {
|
||||
viewsElement.textContent = result.data.views;
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.code === 1) {
|
||||
// 更新成功,更新页面上的访问次数显示
|
||||
const viewsElement = document.getElementById('articleViews');
|
||||
if (viewsElement) {
|
||||
viewsElement.textContent = result.data.views;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('更新访问次数失败:', error);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('更新访问次数失败:', error);
|
||||
});
|
||||
}
|
||||
|
||||
// 分享功能
|
||||
const shareBtn = document.getElementById('shareBtn');
|
||||
if (shareBtn) {
|
||||
shareBtn.addEventListener('click', function () {
|
||||
// 获取当前页面URL
|
||||
const currentUrl = window.location.href;
|
||||
|
||||
// 创建临时输入框
|
||||
const tempInput = document.createElement('input');
|
||||
tempInput.value = currentUrl;
|
||||
document.body.appendChild(tempInput);
|
||||
|
||||
// 选择并复制文本
|
||||
tempInput.select();
|
||||
document.execCommand('copy');
|
||||
|
||||
// 移除临时输入框
|
||||
document.body.removeChild(tempInput);
|
||||
|
||||
// 提示用户复制成功
|
||||
alert('链接已复制到剪贴板');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<?php /*a:5:{s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\program\detail.php";i:1747445574;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\head.php";i:1747616759;s:71:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\header-simple.php";i:1747445574;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\footer.php";i:1747616057;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\foot.php";i:1747615919;}*/ ?>
|
||||
<?php /*a:5:{s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\program\detail.php";i:1747709473;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\head.php";i:1747617129;s:71:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\header-simple.php";i:1747705841;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\footer.php";i:1747617266;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\foot.php";i:1747616844;}*/ ?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
<script src="/static/layui/layui.js" charset="utf-8"></script>
|
||||
<script src="/static/js/bootstrap.bundle.js"></script>
|
||||
<script charset="UTF-8" id="LA_COLLECT" src="//www.yunzer.cn/static/js/js-sdk-pro.min.js"></script>
|
||||
<script charset="UTF-8" id="LA_COLLECT" src="//www.yunzer.cn/plugins/js-sdk-pro.min.js"></script>
|
||||
<script>LA.init({ id: "KoyzaWWEcLvPzkQn", ck: "KoyzaWWEcLvPzkQn", autoTrack: true, prefix: 'event' })</script>
|
||||
</head>
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
<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>
|
||||
<a href="index.html"><img src="/static/images/logo1.png" width="186" alt="Logo"></a>
|
||||
</div>
|
||||
<div class="main-menu__nav">
|
||||
<ul class="main-menu__list">
|
||||
@ -90,7 +90,7 @@
|
||||
<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>
|
||||
<a href="index.html"><img src="/static/images/logo1.png" width="150" alt="Logo"></a>
|
||||
</div>
|
||||
<div class="sticky-nav__menu">
|
||||
<ul>
|
||||
@ -463,7 +463,8 @@
|
||||
<span class="program-author"><i class="fa fa-user"></i> <span id="programAuthor"></span></span>
|
||||
<span class="program-date"><i class="fa fa-calendar"></i> <span id="programDate"></span></span>
|
||||
<span class="program-views"><i class="fa-solid fa-eye"></i> <span id="programViews"></span> 浏览</span>
|
||||
<span class="program-downloads"><i class="fa-solid fa-download"></i> <span id="programDownloads"></span> 下载</span>
|
||||
<span class="program-downloads"><i class="fa-solid fa-download"></i> <span id="programDownloads"></span>
|
||||
下载</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -489,12 +490,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="program-content">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="program-actions">
|
||||
<div class="action-item download-btn" id="downloadBtn">
|
||||
<i class="fa fa-download"></i>
|
||||
<span class="action-text">立即下载</span>
|
||||
</div>
|
||||
<div class="action-item share-btn">
|
||||
<div class="action-item share-btn" id="shareBtn">
|
||||
<i class="fa fa-share-alt"></i>
|
||||
<span class="action-text">分享</span>
|
||||
</div>
|
||||
@ -573,7 +578,7 @@
|
||||
</div>
|
||||
<div class="tongji">
|
||||
<script id="LA-DATA-WIDGET" crossorigin="anonymous" charset="UTF-8"
|
||||
src="https://v6-widget.51.la/v6/KoyzaWWEcLvPzkQn/quote.js?theme=0&f=12"></script>
|
||||
src="https://v6-widget.51.la/v6/KoyzaWWEcLvPzkQn/quote.js?theme=#1690FF,#FFFFFF,#999999,#FFFFFF,#FFFFFF,#1690FF,12&f=12"></script>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -703,6 +708,11 @@
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
.program-navigation a {
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.prev-program,
|
||||
.next-program {
|
||||
max-width: 45%;
|
||||
@ -858,25 +868,25 @@
|
||||
function renderProgramDetail(data) {
|
||||
// 渲染分类链接
|
||||
document.getElementById('cateLink').textContent = data.cateName;
|
||||
|
||||
|
||||
// 渲染程序标题
|
||||
document.getElementById('programTitle').textContent = data.program.title;
|
||||
|
||||
|
||||
// 渲染程序元信息
|
||||
document.getElementById('programAuthor').textContent = data.program.author;
|
||||
document.getElementById('programDate').textContent = formatDate(data.program.create_time);
|
||||
document.getElementById('programViews').textContent = data.program.views;
|
||||
document.getElementById('programDownloads').textContent = data.program.downloads;
|
||||
|
||||
|
||||
// 渲染程序内容
|
||||
document.getElementById('programContent').innerHTML = data.program.content;
|
||||
|
||||
|
||||
// 渲染程序信息
|
||||
document.getElementById('programSize').textContent = data.program.size || '未知';
|
||||
document.getElementById('programEnvironment').textContent = data.program.environment || '通用';
|
||||
document.getElementById('programUpdateTime').textContent = formatDate(data.program.update_time);
|
||||
document.getElementById('programVersion').textContent = data.program.version || '1.0.0';
|
||||
|
||||
|
||||
// 渲染上一个程序
|
||||
const prevProgram = document.getElementById('prevProgram');
|
||||
if (data.prevProgram) {
|
||||
@ -888,7 +898,7 @@
|
||||
} else {
|
||||
prevProgram.innerHTML = '<span class="disabled"><i class="fa fa-arrow-left"></i> 没有上一个了</span>';
|
||||
}
|
||||
|
||||
|
||||
// 渲染下一个程序
|
||||
const nextProgram = document.getElementById('nextProgram');
|
||||
if (data.nextProgram) {
|
||||
@ -900,7 +910,7 @@
|
||||
} else {
|
||||
nextProgram.innerHTML = '<span class="disabled">没有下一个了 <i class="fa fa-arrow-right"></i></span>';
|
||||
}
|
||||
|
||||
|
||||
// 渲染相关程序
|
||||
const relatedPrograms = document.getElementById('relatedPrograms');
|
||||
if (data.relatedPrograms && data.relatedPrograms.length > 0) {
|
||||
@ -923,7 +933,7 @@
|
||||
}
|
||||
|
||||
// 页面加载完成后执行
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// 获取程序ID
|
||||
const programId = new URLSearchParams(window.location.search).get('id');
|
||||
if (!programId) {
|
||||
@ -937,72 +947,63 @@
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.code === 1) {
|
||||
renderProgramDetail(result.data);
|
||||
// 更新访问次数
|
||||
updateProgramViews(programId);
|
||||
} else {
|
||||
alert(result.msg || '获取程序详情失败');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取程序详情失败:', error);
|
||||
alert('获取程序详情失败,请检查网络连接或刷新页面重试');
|
||||
});
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.code === 1) {
|
||||
renderProgramDetail(result.data);
|
||||
// 更新访问次数
|
||||
updateProgramViews(programId);
|
||||
// 初始化分享功能
|
||||
initShareFunction();
|
||||
} else {
|
||||
alert(result.msg || '获取程序详情失败');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('获取程序详情失败:', error);
|
||||
alert('获取程序详情失败,请检查网络连接或刷新页面重试');
|
||||
});
|
||||
|
||||
// 下载功能
|
||||
const downloadBtn = document.getElementById('downloadBtn');
|
||||
if (downloadBtn) {
|
||||
downloadBtn.addEventListener('click', function() {
|
||||
downloadBtn.addEventListener('click', function () {
|
||||
fetch('/index/program/download?id=' + programId, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 1) {
|
||||
const downloadsElement = document.getElementById('programDownloads');
|
||||
let downloads = parseInt(downloadsElement.textContent);
|
||||
downloadsElement.textContent = downloads + 1;
|
||||
|
||||
// 获取当前域名
|
||||
const domain = window.location.origin;
|
||||
// 拼接完整的下载地址
|
||||
if (data.data && data.data.fileurl) {
|
||||
const downloadUrl = domain + data.data.fileurl;
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 1 && data.data && data.data.fileurl) {
|
||||
const downloadUrl = window.location.origin + data.data.fileurl;
|
||||
window.location.href = downloadUrl;
|
||||
} else {
|
||||
alert('下载地址不存在');
|
||||
}
|
||||
} else {
|
||||
alert('下载失败:' + data.msg);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('下载请求失败:', error);
|
||||
alert('下载请求失败,请稍后重试');
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('下载请求失败:', error);
|
||||
alert('下载请求失败,请稍后重试');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 返回顶部功能
|
||||
const goToTop = document.getElementById('goToTop');
|
||||
|
||||
|
||||
// 监听滚动事件
|
||||
window.addEventListener('scroll', function() {
|
||||
window.addEventListener('scroll', function () {
|
||||
if (window.pageYOffset > 300) {
|
||||
goToTop.classList.add('show');
|
||||
} else {
|
||||
goToTop.classList.remove('show');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 点击返回顶部
|
||||
goToTop.addEventListener('click', function() {
|
||||
goToTop.addEventListener('click', function () {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
@ -1022,22 +1023,47 @@
|
||||
id: programId
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.code === 1) {
|
||||
// 更新成功,更新页面上的访问次数显示
|
||||
const viewsElement = document.getElementById('programViews');
|
||||
if (viewsElement) {
|
||||
viewsElement.textContent = result.data.views;
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
if (result.code === 1) {
|
||||
// 更新成功,更新页面上的访问次数显示
|
||||
const viewsElement = document.getElementById('programViews');
|
||||
if (viewsElement) {
|
||||
viewsElement.textContent = result.data.views;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('更新访问次数失败:', error);
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('更新访问次数失败:', error);
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化分享功能
|
||||
function initShareFunction() {
|
||||
const shareBtn = document.getElementById('shareBtn');
|
||||
if (shareBtn) {
|
||||
shareBtn.addEventListener('click', function () {
|
||||
// 获取当前页面URL
|
||||
const currentUrl = window.location.href;
|
||||
|
||||
// 创建临时输入框
|
||||
const tempInput = document.createElement('input');
|
||||
tempInput.value = currentUrl;
|
||||
document.body.appendChild(tempInput);
|
||||
|
||||
// 选择并复制文本
|
||||
tempInput.select();
|
||||
document.execCommand('copy');
|
||||
|
||||
// 移除临时输入框
|
||||
document.body.removeChild(tempInput);
|
||||
|
||||
// 提示用户复制成功
|
||||
layer.msg('链接已复制到剪贴板');
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
<script charset="UTF-8" id="LA_COLLECT" src="//sdk.51.la/js-sdk-pro.min.js"></script>
|
||||
<script>LA.init({id:"KoyzaWWEcLvPzkQn",ck:"KoyzaWWEcLvPzkQn",autoTrack:true,hashMode:true})</script>
|
||||
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user