更新后端资源发布
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
/**
|
||||
* 商业使用授权协议
|
||||
*
|
||||
* Copyright (c) 2025 [云泽网]. 保留所有权利.
|
||||
*
|
||||
* 本软件仅供评估使用。任何商业用途必须获得书面授权许可。
|
||||
* 未经授权商业使用本软件属于侵权行为,将承担法律责任。
|
||||
*
|
||||
* 授权购买请联系: 357099073@qq.com
|
||||
* 官方网站: https://www.yunzer.cn
|
||||
*
|
||||
* 评估用户须知:
|
||||
* 1. 禁止移除版权声明
|
||||
* 2. 禁止用于生产环境
|
||||
* 3. 禁止转售或分发
|
||||
*/
|
||||
|
||||
/**
|
||||
* 游戏下载控制器
|
||||
*/
|
||||
namespace app\index\controller;
|
||||
use app\index\controller\BaseController;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
use think\facade\Request;
|
||||
use app\index\model\Resources\Resources;
|
||||
use app\index\model\Resources\ResourcesCategory;
|
||||
use app\index\model\Attachments;
|
||||
|
||||
class ResourcesController extends BaseController
|
||||
{
|
||||
//资源中心
|
||||
public function index()
|
||||
{
|
||||
// 获取所有顶级分类
|
||||
$parentCategories = ResourcesCategory::where('cid', 0)
|
||||
->where('status', 1)
|
||||
->order('sort', 'asc')
|
||||
->select();
|
||||
|
||||
// 获取每个顶级分类下的子分类
|
||||
$categories = [];
|
||||
foreach ($parentCategories as $parent) {
|
||||
$subCategories = ResourcesCategory::where('cid', $parent->id)
|
||||
->where('status', 1)
|
||||
->order('sort', 'asc')
|
||||
->select();
|
||||
|
||||
// 获取每个子分类下的资源数量
|
||||
foreach ($subCategories as &$subCategory) {
|
||||
$subCategory['resource_count'] = Resources::where('cate', $subCategory->id)
|
||||
->where('status', 1)
|
||||
->count();
|
||||
}
|
||||
|
||||
$categories[] = [
|
||||
'parent' => $parent,
|
||||
'subCategories' => $subCategories
|
||||
];
|
||||
}
|
||||
|
||||
// 将数据传递给视图
|
||||
View::assign('categories', $categories);
|
||||
|
||||
return View::fetch();
|
||||
}
|
||||
|
||||
// 游戏列表页
|
||||
public function list()
|
||||
{
|
||||
$cid = input('cid/d', 0);
|
||||
$page = input('page/d', 1);
|
||||
|
||||
// 获取分类信息
|
||||
$category = ResourcesCategory::where('id', $cid)
|
||||
->where('status', 1)
|
||||
->find();
|
||||
|
||||
if (!$category) {
|
||||
$this->error('分类不存在');
|
||||
}
|
||||
|
||||
// 获取该分类下的资源,带分页
|
||||
$resources = Resources::where('cate', $cid)
|
||||
->where('status', 1)
|
||||
->order('sort', 'asc')
|
||||
->paginate([
|
||||
'list_rows' => 20,
|
||||
'page' => $page,
|
||||
'query' => Request::instance()->param()
|
||||
]);
|
||||
|
||||
// 将数据传递给视图
|
||||
View::assign('category', $category);
|
||||
View::assign('data', $resources);
|
||||
|
||||
return View::fetch('list');
|
||||
}
|
||||
|
||||
// 游戏详情页
|
||||
public function detail()
|
||||
{
|
||||
$id = Request::param('id/d', 0);
|
||||
$game = Resources::where('id', $id)->find();
|
||||
|
||||
if (!$game) {
|
||||
return json(['code' => 0, 'msg' => '游戏不存在或已被删除']);
|
||||
}
|
||||
|
||||
// 如果size没有,从附件表中获取
|
||||
if (empty($game['size']) && !empty($game['fileurl'])) {
|
||||
$attachment = Attachments::where('src', $game['fileurl'])
|
||||
->find();
|
||||
|
||||
if ($attachment && !empty($attachment['size'])) {
|
||||
$size = $attachment['size'];
|
||||
// 转换文件大小为合适的单位
|
||||
if ($size >= 1073741824) { // 1GB = 1024MB = 1024*1024KB = 1024*1024*1024B
|
||||
$game['size'] = round($size / 1073741824, 2) . 'GB';
|
||||
} elseif ($size >= 1048576) { // 1MB = 1024KB = 1024*1024B
|
||||
$game['size'] = round($size / 1048576, 2) . 'MB';
|
||||
} else {
|
||||
$game['size'] = round($size / 1024, 2) . 'KB';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取分类名称
|
||||
$cateName = ResourcesCategory::where('id', $game['cate'])
|
||||
->value('name');
|
||||
|
||||
// 获取上一个和下一个游戏
|
||||
$prevGame = Resources::where('id', '<', $id)
|
||||
->where('delete_time', null)
|
||||
->where('status', 1)
|
||||
->where('cate', $game['cate'])
|
||||
->field(['id', 'title'])
|
||||
->order('id DESC')
|
||||
->find();
|
||||
|
||||
$nextGame = Resources::where('id', '>', $id)
|
||||
->where('delete_time', null)
|
||||
->where('status', 1)
|
||||
->where('cate', $game['cate'])
|
||||
->field(['id', 'title'])
|
||||
->order('id ASC')
|
||||
->find();
|
||||
|
||||
// 获取相关游戏(同分类的其他游戏)
|
||||
$relatedGames = Db::table('yz_resources')
|
||||
->alias('g')
|
||||
->join('yz_resources_category c', 'g.cate = c.id')
|
||||
->where('g.cate', $game['cate'])
|
||||
->where('g.id', '<>', $id)
|
||||
->where('g.delete_time', null)
|
||||
->where('g.status', 1)
|
||||
->field([
|
||||
'g.id',
|
||||
'g.title',
|
||||
'IF(g.icon IS NULL OR g.icon = "", c.icon, g.icon) as icon'
|
||||
])
|
||||
->order('g.id DESC')
|
||||
->limit(3)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
// 如果是 AJAX 请求,返回 JSON 数据
|
||||
if (Request::isAjax()) {
|
||||
return json([
|
||||
'code' => 1,
|
||||
'msg' => '获取成功',
|
||||
'data' => [
|
||||
'game' => $game,
|
||||
'cateName' => $cateName,
|
||||
'prevGame' => $prevGame,
|
||||
'nextGame' => $nextGame,
|
||||
'relatedGames' => $relatedGames
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
// 非 AJAX 请求返回视图
|
||||
View::assign([
|
||||
'game' => $game,
|
||||
'cateName' => $cateName,
|
||||
'prevGame' => $prevGame,
|
||||
'nextGame' => $nextGame,
|
||||
'relatedGames' => $relatedGames
|
||||
]);
|
||||
|
||||
return View::fetch('detail');
|
||||
}
|
||||
|
||||
// 游戏下载
|
||||
public function downloadurl()
|
||||
{
|
||||
if (!Request::isAjax()) {
|
||||
return json(['code' => 0, 'msg' => '非法请求']);
|
||||
}
|
||||
|
||||
$id = Request::param('id/d', 0);
|
||||
|
||||
// 获取游戏信息
|
||||
$game = Resources::where('id', $id)
|
||||
->where('delete_time', null)
|
||||
->find();
|
||||
|
||||
if (!$game) {
|
||||
return json(['code' => 0, 'msg' => '游戏不存在']);
|
||||
}
|
||||
|
||||
// 更新下载次数
|
||||
$result = Resources::where('id', $id)
|
||||
->where('delete_time', null)
|
||||
->inc('downloads', 1)
|
||||
->update();
|
||||
|
||||
if ($result) {
|
||||
return json([
|
||||
'code' => 1,
|
||||
'msg' => '下载成功',
|
||||
'data' => [
|
||||
'url' => $game['url']
|
||||
]
|
||||
]);
|
||||
} else {
|
||||
return json(['code' => 0, 'msg' => '下载失败']);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取访问统计
|
||||
public function viewStats()
|
||||
{
|
||||
$id = Request::param('id/d', 0);
|
||||
|
||||
// 获取总访问量
|
||||
$totalViews = Resources::where('id', $id)
|
||||
->value('views');
|
||||
|
||||
return json([
|
||||
'code' => 1,
|
||||
'data' => [
|
||||
'total' => $totalViews
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新游戏访问次数
|
||||
*/
|
||||
public function updateViews()
|
||||
{
|
||||
if (!Request::isPost()) {
|
||||
return json(['code' => 0, 'msg' => '非法请求']);
|
||||
}
|
||||
|
||||
$id = Request::post('id');
|
||||
if (!$id) {
|
||||
return json(['code' => 0, 'msg' => '参数错误']);
|
||||
}
|
||||
|
||||
try {
|
||||
// 更新访问次数
|
||||
$game = Resources::where('id', $id)->find();
|
||||
if (!$game) {
|
||||
return json(['code' => 0, 'msg' => '游戏不存在']);
|
||||
}
|
||||
|
||||
// 更新访问次数
|
||||
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()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="more-btn" onclick="window.open('/index/articles/index?cateid=1', '_blank')">更多</div>
|
||||
<div class="more-btn" onclick="window.open('/index/articles/index?cateid=3', '_blank')">更多</div>
|
||||
</div>
|
||||
<div class="product-list" id="webArticlesList">
|
||||
<!-- 文章将通过JavaScript动态加载 -->
|
||||
@@ -56,7 +56,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="more-btn" onclick="window.open('/index/program/index?cateid=2', '_blank')">更多</div>
|
||||
<div class="more-btn" onclick="window.open('/index/resources/index?cateid=2', '_blank')">更多</div>
|
||||
</div>
|
||||
<div class="product-list" id="resourcesDownloadList">
|
||||
<!-- 文章将通过JavaScript动态加载 -->
|
||||
@@ -77,7 +77,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="more-btn" onclick="window.open('/index/program/index?cateid=1', '_blank')">更多</div>
|
||||
<div class="more-btn" onclick="window.open('/index/resources/index?cateid=1', '_blank')">更多</div>
|
||||
</div>
|
||||
<div class="product-list" id="programDownloadList">
|
||||
<!-- 程序将通过JavaScript动态加载 -->
|
||||
@@ -98,7 +98,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="more-btn" onclick="window.open('/index/game/index?cateid=8', '_blank')">更多</div>
|
||||
<div class="more-btn" onclick="window.open('/index/resources/index?cateid=8', '_blank')">更多</div>
|
||||
</div>
|
||||
<div class="product-list" id="gameDownloadList">
|
||||
<!-- 游戏将通过JavaScript动态加载 -->
|
||||
|
||||
+177
-359
@@ -1,8 +1,8 @@
|
||||
{include file="component/head" /}
|
||||
{include file="component/header-simple" /}
|
||||
|
||||
<!-- 简约现代文章中心 -->
|
||||
<div class="modern-games-page">
|
||||
<!-- 简约现代资源中心 -->
|
||||
<div class="modern-resources-page">
|
||||
<!-- 简约标题区 -->
|
||||
<div class="modern-header">
|
||||
<div class="container">
|
||||
@@ -13,175 +13,52 @@
|
||||
|
||||
<!-- 主要内容区 -->
|
||||
<div class="container">
|
||||
<div class="modern-layout">
|
||||
<!-- 侧边分类导航 -->
|
||||
<aside class="modern-sidebar">
|
||||
<div class="sidebar-card">
|
||||
<h3 class="sidebar-title">
|
||||
<i class="layui-icon layui-icon-list"></i>
|
||||
<span>分类导航</span>
|
||||
</h3>
|
||||
<ul class="category-menu">
|
||||
{volist name="cate.subCategories" id="subCategory"}
|
||||
<li class="menu-item {$cate.id == $subCategory.id ? 'active' : ''}" data-cateid="{$subCategory.id}">
|
||||
<span>{$subCategory.name}</span>
|
||||
<i class="layui-icon layui-icon-right"></i>
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
{volist name="categories" id="category"}
|
||||
<div class="category-section">
|
||||
<div class="category-header">
|
||||
<div class="category-info">
|
||||
<h2 class="category-title">{$category.parent.name}</h2>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 文章内容区 -->
|
||||
<main class="modern-main">
|
||||
<!-- 文章列表 -->
|
||||
<div class="game-grid" id="gameList">
|
||||
{volist name="cate.subCategories" id="subCategory"}
|
||||
{if $cate.id == $subCategory.id}
|
||||
{if !empty($subCategory.list)}
|
||||
{volist name="subCategory.list" id="game"}
|
||||
<game class="game-card">
|
||||
<div class="card-image">
|
||||
<img src="{$game.icon|default=$subCategory.icon|default='/static/images/default-game.jpg'}" alt="{$game.title}">
|
||||
<div class="image-overlay"></div>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="meta-info">
|
||||
<span class="category-tag">{$subCategory.name}</span>
|
||||
<time class="publish-date">{$game.create_time|date="Y-m-d"}</time>
|
||||
</div>
|
||||
<h3 class="game-title">{$game.title}</h3>
|
||||
<div class="card-footer">
|
||||
<div class="stats">
|
||||
<span class="views"><i class="layui-icon layui-icon-eye"></i> {$game.views|default=0}</span>
|
||||
<span class="likes"><i class="layui-icon layui-icon-praise"></i> {$game.likes|default=0}</span>
|
||||
</div>
|
||||
<a href="/index/game/detail?id={$game.id}" class="read-more">阅读更多</a>
|
||||
</div>
|
||||
</div>
|
||||
</game>
|
||||
{/volist}
|
||||
{else}
|
||||
<div class="empty-state">
|
||||
<div class="empty-icon">
|
||||
<div class="category-count">
|
||||
<span class="count-badge">{$category.subCategories|count} 个分类</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resource-grid">
|
||||
{volist name="category.subCategories" id="subCategory"}
|
||||
<a href="/index/resources/list?cid={$subCategory.id}" class="resource-card">
|
||||
<div class="card-image">
|
||||
<img src="{$subCategory.icon|default='/static/images/default-resource.jpg'}" alt="{$subCategory.name}">
|
||||
<div class="image-overlay"></div>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="meta-info">
|
||||
</div>
|
||||
<h3 class="resource-title">{$subCategory.name}</h3>
|
||||
<div class="card-footer">
|
||||
<div class="resource-stats">
|
||||
<span class="stat-item">
|
||||
<i class="layui-icon layui-icon-template-1"></i>
|
||||
</div>
|
||||
<h4>暂无文章</h4>
|
||||
<p>当前分类下没有找到相关文章</p>
|
||||
<span>{$subCategory.resource_count} 个资源</span>
|
||||
</span>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{/volist}
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="modern-pagination" id="pagination"></div>
|
||||
</main>
|
||||
<div class="view-more">
|
||||
<span>查看资源</span>
|
||||
<i class="layui-icon layui-icon-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
layui.use(['laypage', 'jquery'], function(){
|
||||
var laypage = layui.laypage;
|
||||
var $ = layui.jquery;
|
||||
|
||||
// 分类切换
|
||||
$('.menu-item').on('click', function() {
|
||||
var cateid = $(this).data('cateid');
|
||||
var $menuItems = $('.menu-item');
|
||||
|
||||
// 更新选中状态
|
||||
$menuItems.removeClass('active');
|
||||
$(this).addClass('active');
|
||||
|
||||
// 加载文章
|
||||
loadArticles(cateid, 1);
|
||||
});
|
||||
|
||||
// 页面加载完成后,自动触发第一个分类的点击事件
|
||||
$(document).ready(function() {
|
||||
var $firstMenuItem = $('.menu-item').first();
|
||||
if ($firstMenuItem.length > 0) {
|
||||
$firstMenuItem.click();
|
||||
}
|
||||
});
|
||||
|
||||
// 加载文章函数
|
||||
function loadArticles(cateid, page) {
|
||||
$.ajax({
|
||||
url: '/index/game/list',
|
||||
type: 'POST',
|
||||
data: {
|
||||
cate: cateid,
|
||||
page: page
|
||||
},
|
||||
beforeSend: function() {
|
||||
$('#gameList').html('<div class="loading-state"><i class="layui-icon layui-icon-loading"></i>加载中...</div>');
|
||||
},
|
||||
success: function(res) {
|
||||
if(res.code === 1) {
|
||||
var html = '';
|
||||
if(res.data.games && res.data.games.length > 0) {
|
||||
res.data.games.forEach(function(game) {
|
||||
html += `<game class="game-card">
|
||||
<div class="card-image">
|
||||
<img src="${game.icon || game.category_icon || '/static/images/default-game.jpg'}" alt="${game.title}">
|
||||
<div class="image-overlay"></div>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="meta-info">
|
||||
<span class="category-tag">${game.category_name || '未分类'}</span>
|
||||
<time class="publish-date">${game.create_time || ''}</time>
|
||||
</div>
|
||||
<h3 class="game-title">${game.title}</h3>
|
||||
<div class="card-footer">
|
||||
<div class="stats">
|
||||
<span class="views"><i class="layui-icon layui-icon-eye"></i> ${game.views || 0}</span>
|
||||
<span class="likes"><i class="layui-icon layui-icon-praise"></i> ${game.likes || 0}</span>
|
||||
</div>
|
||||
<a href="/index/game/detail?id=${game.id}" class="read-more">阅读更多</a>
|
||||
</div>
|
||||
</div>
|
||||
</game>`;
|
||||
});
|
||||
} else {
|
||||
html = `<div class="empty-state">
|
||||
<div class="empty-icon">
|
||||
<i class="layui-icon layui-icon-template-1"></i>
|
||||
</div>
|
||||
<h4>暂无文章</h4>
|
||||
<p>当前分类下没有找到相关文章</p>
|
||||
</div>`;
|
||||
}
|
||||
$('#gameList').html(html);
|
||||
|
||||
// 渲染分页
|
||||
laypage.render({
|
||||
elem: 'pagination',
|
||||
count: res.data.total || 0,
|
||||
limit: res.data.per_page || 12,
|
||||
curr: res.data.current_page || 1,
|
||||
theme: '#1E9FFF',
|
||||
layout: ['prev', 'page', 'next'],
|
||||
jump: function(obj, first) {
|
||||
if(!first) {
|
||||
loadArticles(cateid, obj.curr);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
{include file="component/footer" /}
|
||||
|
||||
<style>
|
||||
/* 基础样式重置 */
|
||||
.modern-games-page {
|
||||
.modern-resources-page {
|
||||
font-family: 'Helvetica Neue', Arial, 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
@@ -193,9 +70,24 @@
|
||||
.modern-header {
|
||||
background: linear-gradient(135deg, #1E9FFF 0%, #0d8aff 100%);
|
||||
color: white;
|
||||
padding: 80px 0 60px;
|
||||
padding: 150px 0;
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modern-header::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: url('/static/images/pattern.png') repeat;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
.modern-title {
|
||||
@@ -203,6 +95,7 @@
|
||||
font-weight: 300;
|
||||
margin-bottom: 15px;
|
||||
letter-spacing: 1px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.modern-subtitle {
|
||||
@@ -210,117 +103,89 @@
|
||||
font-weight: 300;
|
||||
opacity: 0.9;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 布局结构 */
|
||||
.modern-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 260px 1fr;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
/* 侧边栏样式 */
|
||||
.modern-sidebar {
|
||||
position: sticky;
|
||||
top: 30px;
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.sidebar-card {
|
||||
/* 分类区块样式 */
|
||||
.category-section {
|
||||
margin-bottom: 60px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 15px rgba(0, 0, 0, 0.03);
|
||||
overflow: hidden;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
.sidebar-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 500;
|
||||
padding: 20px;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #555;
|
||||
.category-header {
|
||||
margin-bottom: 30px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.sidebar-title i {
|
||||
margin-right: 10px;
|
||||
font-size: 1.2rem;
|
||||
color: #1E9FFF;
|
||||
}
|
||||
|
||||
.category-menu {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
padding: 15px 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
border-left: 3px solid transparent;
|
||||
}
|
||||
|
||||
.menu-item:hover {
|
||||
background-color: #f8fafd;
|
||||
color: #1E9FFF;
|
||||
.category-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.menu-item.active {
|
||||
background-color: #f0f7ff;
|
||||
border-left-color: #1E9FFF;
|
||||
.category-title {
|
||||
font-size: 1.8rem;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.category-subtitle {
|
||||
font-size: 1rem;
|
||||
color: #666;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.category-count {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.count-badge {
|
||||
background: #f0f7ff;
|
||||
color: #1E9FFF;
|
||||
padding: 6px 12px;
|
||||
border-radius: 20px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.menu-item i {
|
||||
font-size: 0.9rem;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.menu-item.active i,
|
||||
.menu-item:hover i {
|
||||
color: #1E9FFF;
|
||||
}
|
||||
|
||||
/* 主内容区样式 */
|
||||
.modern-main {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* 文章网格布局 */
|
||||
.game-grid {
|
||||
/* 资源网格布局 */
|
||||
.resource-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20px;
|
||||
margin-bottom: 40px;
|
||||
gap: 25px;
|
||||
}
|
||||
|
||||
/* 文章卡片样式 */
|
||||
.game-card {
|
||||
/* 资源卡片样式 */
|
||||
.resource-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 3px 15px rgba(0, 0, 0, 0.03);
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.game-card:hover {
|
||||
.resource-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 5px 25px rgba(0, 0, 0, 0.08);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.08);
|
||||
border-color: #e6f7ff;
|
||||
}
|
||||
|
||||
.card-image {
|
||||
height: 180px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.card-image img {
|
||||
@@ -339,7 +204,28 @@
|
||||
background: linear-gradient(to top, rgba(0, 0, 0, 0.3), transparent);
|
||||
}
|
||||
|
||||
.game-card:hover .card-image img {
|
||||
.status-badge {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
padding: 4px 12px;
|
||||
border-radius: 20px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.status-badge.active {
|
||||
background: rgba(82, 196, 26, 0.9);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.status-badge.inactive {
|
||||
background: rgba(255, 77, 79, 0.9);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.resource-card:hover .card-image img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
@@ -358,36 +244,21 @@
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.category-tag {
|
||||
.resource-number {
|
||||
background: #f0f7ff;
|
||||
color: #1E9FFF;
|
||||
padding: 3px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.game-title {
|
||||
font-size: 1rem;
|
||||
.resource-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 500;
|
||||
margin: 0 0 10px;
|
||||
margin: 0 0 15px;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.game-excerpt {
|
||||
font-size: 0.9rem;
|
||||
color: #666;
|
||||
margin: 0 0 20px;
|
||||
flex: 1;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
@@ -395,134 +266,63 @@
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: auto;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.stats {
|
||||
.resource-stats {
|
||||
font-size: 0.85rem;
|
||||
color: #999;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.stats i {
|
||||
margin-right: 3px;
|
||||
.stat-item i {
|
||||
font-size: 1rem;
|
||||
color: #1E9FFF;
|
||||
}
|
||||
|
||||
.read-more {
|
||||
.view-more {
|
||||
color: #1E9FFF;
|
||||
font-size: 0.9rem;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s ease;
|
||||
display: inline-flex;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.read-more:hover {
|
||||
color: #0d8aff;
|
||||
text-decoration: underline;
|
||||
.view-more i {
|
||||
font-size: 0.8rem;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
/* 分页样式 */
|
||||
.modern-pagination {
|
||||
text-align: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.layui-laypage a,
|
||||
.layui-laypage span {
|
||||
border-radius: 4px !important;
|
||||
margin: 0 3px !important;
|
||||
}
|
||||
|
||||
.layui-laypage a {
|
||||
color: #666 !important;
|
||||
}
|
||||
|
||||
.layui-laypage .layui-laypage-curr .layui-laypage-em {
|
||||
background-color: #1E9FFF !important;
|
||||
}
|
||||
|
||||
/* 空状态样式 */
|
||||
.empty-state {
|
||||
grid-column: 1 / -1;
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 3px 15px rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
font-size: 3rem;
|
||||
color: #ddd;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.empty-icon i {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.empty-state h4 {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 400;
|
||||
color: #666;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.empty-state p {
|
||||
color: #999;
|
||||
font-size: 0.95rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.loading-state {
|
||||
grid-column: 1 / -1;
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.loading-state i {
|
||||
font-size: 1.5rem;
|
||||
margin-right: 10px;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
.resource-card:hover .view-more i {
|
||||
transform: translateX(3px);
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 992px) {
|
||||
.modern-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.modern-sidebar {
|
||||
position: static;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.game-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
@media (max-width: 1200px) {
|
||||
.resource-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.modern-header {
|
||||
padding: 60px 0 40px;
|
||||
@media (max-width: 992px) {
|
||||
.resource-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.modern-title {
|
||||
font-size: 2rem;
|
||||
.category-section {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.game-grid {
|
||||
.resource-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@@ -533,6 +333,24 @@
|
||||
.modern-subtitle {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.category-title {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.category-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.category-count {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
h2{
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,53 +1,44 @@
|
||||
<div class="container py-5">
|
||||
<div class="row g-4">
|
||||
<!-- 左侧分类列表 -->
|
||||
<div class="col-lg-3">
|
||||
<div class="category-sidebar">
|
||||
<div class="sidebar-header">
|
||||
<i class="layui-icon layui-icon-app"></i>
|
||||
<span>文章分类</span>
|
||||
</div>
|
||||
<div class="category-list">
|
||||
{volist name="categories" id="cate"}
|
||||
<div class="category-item {$category.id == $cate.id ? 'active' : ''}" data-cateid="{$cate.id}">{$cate.name}</div>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{include file="component/head" /}
|
||||
{include file="component/header-simple" /}
|
||||
|
||||
<!-- 简约现代资源列表页 -->
|
||||
<div class="modern-resources-page">
|
||||
<!-- 简约标题区 -->
|
||||
<div class="modern-header">
|
||||
<div class="container">
|
||||
<h1 class="modern-title">{$category.name}</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧文章列表 -->
|
||||
<div class="col-lg-9">
|
||||
{if $category}
|
||||
<div class="category-header mb-4">
|
||||
<h2 class="category-title">{$category.name}</h2>
|
||||
<p class="category-desc">{$category.desc|default=''}</p>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="article-list">
|
||||
{volist name="games" id="article"}
|
||||
<div class="article-item">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4">
|
||||
<div class="article-image">
|
||||
<img src="{$article.image|default='/static/images/default.jpg'}" alt="{$article.title}">
|
||||
</div>
|
||||
<!-- 主要内容区 -->
|
||||
<div class="container">
|
||||
<div class="modern-layout">
|
||||
<!-- 资源列表网格 -->
|
||||
<div class="resource-grid" id="resourceList">
|
||||
{volist name="data" id="resource"}
|
||||
<div class="resource-card">
|
||||
<div class="card-image">
|
||||
<img src="{$resource.icon|default='/static/images/default-resource.jpg'}"
|
||||
alt="{$resource.name}">
|
||||
<div class="image-overlay"></div>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="meta-info">
|
||||
<span class="resource-number">{$resource.number}</span>
|
||||
<time class="create-date">{$resource.create_time|date="Y-m-d"}</time>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="article-content">
|
||||
<h3 class="article-title">
|
||||
<a href="/index/game/detail?id={$article.id}">{$article.title}</a>
|
||||
</h3>
|
||||
<p class="article-desc">{$article.desc|default=''}</p>
|
||||
<div class="article-meta">
|
||||
<div class="article-stats">
|
||||
<span><i class="layui-icon layui-icon-eye"></i> {$article.views|default=0}</span>
|
||||
<span><i class="layui-icon layui-icon-praise"></i> {$article.likes|default=0}</span>
|
||||
<span><i class="layui-icon layui-icon-date"></i> {$article.create_time|date="Y-m-d"}</span>
|
||||
</div>
|
||||
<a href="/index/game/detail?id={$article.id}" class="btn-detail">查看详情</a>
|
||||
</div>
|
||||
<h3 class="resource-title">{$resource.name}</h3>
|
||||
<div class="card-footer">
|
||||
<div class="resource-stats">
|
||||
<span class="stat-item">
|
||||
<i class="layui-icon layui-icon-template-1"></i>
|
||||
<span>资源详情</span>
|
||||
</span>
|
||||
</div>
|
||||
<a href="/index/resources/detail?id={$resource.id}" class="view-more">
|
||||
<span>查看详情</span>
|
||||
<i class="layui-icon layui-icon-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,22 +46,252 @@
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="mt-5">
|
||||
{$games|raw}
|
||||
<div class="pagination-container">
|
||||
{$page|raw}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
layui.use(['layer'], function () {
|
||||
var layer = layui.layer;
|
||||
var $ = layui.$;
|
||||
<style>
|
||||
/* 基础样式重置 */
|
||||
.modern-resources-page {
|
||||
font-family: 'Helvetica Neue', Arial, 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
background-color: #f9fafc;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
// 分类切换
|
||||
$('.category-item').on('click', function() {
|
||||
var cateid = $(this).data('cateid');
|
||||
window.location.href = '/index/game/list?cate=' + cateid;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
/* 标题区样式 */
|
||||
.modern-header {
|
||||
background: linear-gradient(135deg, #1E9FFF 0%, #0d8aff 100%);
|
||||
color: white;
|
||||
padding: 150px 0;
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modern-header::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: url('/static/images/pattern.png') repeat;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
.modern-title {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 300;
|
||||
margin-bottom: 15px;
|
||||
letter-spacing: 1px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.modern-subtitle {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 300;
|
||||
opacity: 0.9;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 资源网格布局 */
|
||||
.resource-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 25px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
/* 资源卡片样式 */
|
||||
.resource-card {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 3px 15px rgba(0, 0, 0, 0.03);
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.resource-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.08);
|
||||
border-color: #e6f7ff;
|
||||
}
|
||||
|
||||
.card-image {
|
||||
height: 180px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.card-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform 0.5s ease;
|
||||
}
|
||||
|
||||
.image-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(to top, rgba(0, 0, 0, 0.3), transparent);
|
||||
}
|
||||
|
||||
.resource-card:hover .card-image img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 20px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.meta-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
font-size: 0.85rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.resource-number {
|
||||
background: #f0f7ff;
|
||||
color: #1E9FFF;
|
||||
padding: 3px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.resource-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 500;
|
||||
margin: 0 0 15px;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: auto;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.resource-stats {
|
||||
font-size: 0.85rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.stat-item i {
|
||||
font-size: 1rem;
|
||||
color: #1E9FFF;
|
||||
}
|
||||
|
||||
.view-more {
|
||||
color: #1E9FFF;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.view-more i {
|
||||
font-size: 0.8rem;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.resource-card:hover .view-more i {
|
||||
transform: translateX(3px);
|
||||
}
|
||||
|
||||
/* 分页样式 */
|
||||
.pagination-container {
|
||||
text-align: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.pagination-container .pagination {
|
||||
display: inline-flex;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.pagination-container .pagination a,
|
||||
.pagination-container .pagination span {
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
background: white;
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.pagination-container .pagination a:hover {
|
||||
background: #f0f7ff;
|
||||
color: #1E9FFF;
|
||||
border-color: #e6f7ff;
|
||||
}
|
||||
|
||||
.pagination-container .pagination .active {
|
||||
background: #1E9FFF;
|
||||
color: white;
|
||||
border-color: #1E9FFF;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 1200px) {
|
||||
.resource-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 992px) {
|
||||
.resource-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.resource-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.modern-title {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.modern-subtitle {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
{include file="component/foot" /}
|
||||
Reference in New Issue
Block a user