素材中心代码

This commit is contained in:
李志强 2025-06-16 17:35:31 +08:00
parent d7695dab77
commit 19dda20812
4 changed files with 504 additions and 0 deletions

View File

@ -612,4 +612,145 @@ class YunzeradminController extends Base
}
return json(['code' => 1, 'msg' => '请求方法无效']);
}
//素材中心
public function materialcenter()
{
return View::fetch();
}
// 内容推送列表
public function materialcenterlist()
{
if (Request::isGet()) {
$page = intval(input('post.page', 1));
$limit = intval(input('post.limit', 10));
$query = ContentPush::where('delete_time', null)
->field('id, title, type, status, sort, create_time, update_time');
// 获取总记录数
$count = $query->count();
// 获取分页数据
$lists = $query->order(['sort DESC', 'id DESC'])
->page($page, $limit)
->select()
->toArray();
// 处理数据
foreach ($lists as &$item) {
$item['create_time'] = is_numeric($item['create_time']) ? date('Y-m-d H:i:s', $item['create_time']) : $item['create_time'];
$item['update_time'] = is_numeric($item['update_time']) ? date('Y-m-d H:i:s', $item['update_time']) : $item['update_time'];
}
return json([
'code' => 0,
'msg' => '',
'count' => $count,
'data' => $lists
]);
}
return json(['code' => 1, 'msg' => '请求方法无效']);
}
// 添加内容推送
public function materialcenteradd()
{
if (Request::isPost()) {
$data = [
'title' => input('post.title'),
'content' => input('post.content'),
'image' => input('post.image'),
'url' => input('post.url'),
'type' => input('post.type', 1),
'status' => input('post.status', 1),
'sort' => input('post.sort', 0),
'create_time' => time()
];
$res = ContentPush::insert($data);
if (!$res) {
Log::record('添加内容推送', 0, '添加内容推送失败', '内容推送管理');
return json(['code' => 1, 'msg' => '添加内容推送失败']);
}
Log::record('添加内容推送', 1, '', '内容推送管理');
return json(['code' => 0, 'msg' => '添加成功']);
}
return json(['code' => 1, 'msg' => '请求方法无效']);
}
// 编辑内容推送
public function materialcenteredit()
{
if (Request::isPost()) {
$id = input('post.id');
if (empty($id)) {
Log::record('编辑内容推送', 0, 'ID不能为空', '内容推送管理');
return json(['code' => 1, 'msg' => 'ID不能为空']);
}
$data = [
'title' => input('post.title'),
'content' => input('post.content'),
'image' => input('post.image'),
'url' => input('post.url'),
'type' => input('post.type', 1),
'status' => input('post.status', 1),
'sort' => input('post.sort', 0),
'update_time' => time()
];
$res = ContentPush::where('id', $id)->update($data);
if ($res === false) {
Log::record('编辑内容推送', 0, '更新内容推送失败', '内容推送管理');
return json(['code' => 1, 'msg' => '更新内容推送失败']);
}
Log::record('编辑内容推送', 1, '', '内容推送管理');
return json(['code' => 0, 'msg' => '更新成功']);
}
return json(['code' => 1, 'msg' => '请求方法无效']);
}
// 删除内容推送
public function materialcenterdel()
{
if (Request::isPost()) {
$id = input('post.id');
if (empty($id)) {
Log::record('删除内容推送', 0, 'ID不能为空', '内容推送管理');
return json(['code' => 1, 'msg' => 'ID不能为空']);
}
$res = ContentPush::where('id', $id)->update(['delete_time' => time()]);
if (!$res) {
Log::record('删除内容推送', 0, '删除内容推送失败', '内容推送管理');
return json(['code' => 1, 'msg' => '删除内容推送失败']);
}
Log::record('删除内容推送', 1, '', '内容推送管理');
return json(['code' => 0, 'msg' => '删除成功']);
}
return json(['code' => 1, 'msg' => '请求方法无效']);
}
// 修改内容推送状态
public function materialcenterstatus()
{
if (Request::isPost()) {
$id = input('post.id');
$status = input('post.status');
if (empty($id)) {
Log::record('修改内容推送状态', 0, 'ID不能为空', '内容推送管理');
return json(['code' => 1, 'msg' => 'ID不能为空']);
}
$res = ContentPush::where('id', $id)->update(['status' => $status]);
if ($res === false) {
Log::record('修改内容推送状态', 0, '更新状态失败', '内容推送管理');
return json(['code' => 1, 'msg' => '更新状态失败']);
}
Log::record('修改内容推送状态', 1, '', '内容推送管理');
return json(['code' => 0, 'msg' => '更新成功']);
}
return json(['code' => 1, 'msg' => '请求方法无效']);
}
}

View File

@ -0,0 +1,363 @@
{include file="public/header" /}
<div class="material-tabs">
<div class="tabs-header">
<div class="tab active" data-type="image">图片</div>
<div class="tab" data-type="video">视频</div>
<div class="tab" data-type="file">文件</div>
</div>
<div class="tabs-content">
<!-- 图片Tab内容 -->
<div class="tab-panel" id="tab-image" style="display:block;">
<div class="material-center">
<!-- 左侧分组树 -->
<div class="sidebar">
<ul class="group-list" id="groupList">
<li class="active">全部</li>
<!-- ... -->
</ul>
<div class="sidebar-header">
<button class="layui-btn layui-btn-normal" onclick="addGroup()">添加分组</button>
</div>
</div>
<!-- 右侧内容 -->
<div class="main-content">
<div class="toolbar">
<div class="material-actions">
<button class="layui-btn layui-btn-normal" id="uploadBtn">上传</button>
<button class="layui-btn layui-btn-danger" id="batchDeleteBtn">批量删除</button>
</div>
<button class="layui-btn" onclick="moveMaterial()">移动</button>
<label class="select-all">
<input type="checkbox" id="selectAll" /> 全选
</label>
</div>
<div class="image-grid" id="imageGrid">
<div class="image-item">
<input type="checkbox" class="img-checkbox" />
<img src="https://placekitten.com/120/120" alt="示例图片" />
<div class="img-name">示例图片.jpg</div>
<div class="img-actions">
<button class="layui-btn layui-btn-xs" onclick="renameImg(this)">重命名</button>
<button class="layui-btn layui-btn-xs layui-btn-primary" onclick="viewImg(this)">查看</button>
<button class="layui-btn layui-btn-xs layui-btn-warm" onclick="copyUrl(this)">地址</button>
</div>
</div>
<!-- ... -->
</div>
<div class="pagination">
<button class="layui-btn layui-btn-xs">上一页</button>
<span>1 / 10</span>
<button class="layui-btn layui-btn-xs">下一页</button>
</div>
</div>
</div>
</div>
<!-- 视频Tab内容 -->
<div class="tab-panel" id="tab-video" style="display:none;">
<div class="material-center">
<div style="padding:40px;text-align:center;color:#bbb;">这里是视频管理内容</div>
</div>
</div>
<!-- 文件Tab内容 -->
<div class="tab-panel" id="tab-file" style="display:none;">
<div class="material-center">
<div style="padding:40px;text-align:center;color:#bbb;">这里是文件管理内容</div>
</div>
</div>
</div>
</div>
<script>
// Tab切换
document.querySelectorAll('.material-tabs .tab').forEach(function (tab) {
tab.onclick = function () {
document.querySelectorAll('.material-tabs .tab').forEach(t => t.classList.remove('active'));
tab.classList.add('active');
var type = tab.getAttribute('data-type');
document.querySelectorAll('.tab-panel').forEach(panel => panel.style.display = 'none');
document.getElementById('tab-' + type).style.display = 'block';
}
});
// 分组高亮切换
document.getElementById('groupList').addEventListener('click', function (e) {
if (e.target.tagName === 'LI' || e.target.closest('li')) {
document.querySelectorAll('#groupList li').forEach(li => li.classList.remove('active'));
(e.target.tagName === 'LI' ? e.target : e.target.closest('li')).classList.add('active');
// TODO: 根据分组加载图片
}
});
// 其它功能函数(示例)
function addGroup() {
alert('添加分组功能待实现');
}
function uploadMaterial() {
alert('上传功能待实现');
}
function batchDelete() {
alert('批量删除功能待实现');
}
function moveMaterial() {
alert('移动功能待实现');
}
</script>
<style>
.material-tabs {
width: 100%;
height: 100vh;
background: #f6f7fb;
display: flex;
flex-direction: column;
}
.tabs-header {
display: flex;
border-bottom: 2px solid #e6e6e6;
background: #fff;
padding-left: 32px;
height: 52px;
align-items: center;
}
.tab {
padding: 0 32px;
height: 52px;
line-height: 52px;
font-size: 16px;
color: #666;
cursor: pointer;
position: relative;
transition: color 0.2s;
}
.tab.active {
color: #409eff;
font-weight: bold;
}
.tab.active::after {
content: '';
position: absolute;
left: 16px;
right: 16px;
bottom: 0;
height: 3px;
background: #409eff;
border-radius: 2px 2px 0 0;
}
.tabs-content {
flex: 1;
width: 100%;
overflow: auto;
background: #f6f7fb;
}
.tab-panel {
width: 100%;
/* height: 100%; */
display: none;
}
.tab-panel:target,
.tab-panel.active {
display: block;
}
.material-center {
display: flex;
height: 100%;
background: #fafbfc;
font-family: "Microsoft YaHei", Arial, sans-serif;
}
.sidebar {
width: 220px;
background: #fff;
border-right: 1px solid #e6e6e6;
display: flex;
flex-direction: column;
padding: 0;
}
.sidebar-header {
display: flex;
font-size: 16px;
font-weight: bold;
color: #333;
border-top: 1px solid #f0f0f0;
justify-content: center;
padding: 20px 0;
}
.add-group-btn {
background: #409eff;
color: #fff;
border: none;
border-radius: 50%;
width: 26px;
height: 26px;
font-size: 18px;
cursor: pointer;
transition: background 0.2s;
}
.add-group-btn:hover {
background: #66b1ff;
}
.group-list {
list-style: none;
margin: 0;
padding: 10px 0 0 0;
flex: 1;
}
.group-list li {
padding: 10px 24px;
color: #444;
cursor: pointer;
display: flex;
align-items: center;
border-radius: 4px 0 0 4px;
transition: background 0.2s, color 0.2s;
font-size: 15px;
}
.group-list li .iconfont {
font-size: 16px;
margin-right: 8px;
color: #b2b2b2;
}
.group-list li.active,
.group-list li:hover {
background: #f2f6fc;
color: #409eff;
}
.main-content {
flex: 1;
padding: 32px 36px;
display: flex;
flex-direction: column;
min-width: 0;
}
.toolbar {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 18px;
}
.select-all {
margin-left: auto;
font-size: 14px;
color: #888;
user-select: none;
}
.image-grid {
display: flex;
flex-wrap: wrap;
gap: 22px;
min-height: 320px;
}
.image-item {
width: 140px;
background: #fff;
border: 1px solid #eaeaea;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
display: flex;
flex-direction: column;
align-items: center;
padding: 14px 8px 10px 8px;
position: relative;
cursor: pointer;
transition: box-shadow 0.2s, border 0.2s;
}
.image-item:hover {
border: 1px solid #409eff;
box-shadow: 0 4px 16px rgba(64, 158, 255, 0.10);
}
.image-item img {
width: 120px;
height: 120px;
object-fit: cover;
border-radius: 4px;
margin-bottom: 8px;
background: #f5f7fa;
border: 1px solid #f0f0f0;
}
.img-name {
font-size: 14px;
color: #666;
text-align: center;
margin-bottom: 6px;
word-break: break-all;
height: 32px;
line-height: 16px;
overflow: hidden;
}
.img-checkbox {
position: absolute;
top: 12px;
left: 12px;
transform: scale(1.2);
}
.img-actions {
display: none;
margin-top: 6px;
text-align: center;
gap: 4px;
}
.image-item.active .img-actions {
display: flex;
justify-content: center;
}
.img-actions .layui-btn-xs {
margin: 0 2px;
font-size: 12px;
padding: 0 10px;
}
.pagination {
margin-top: 28px;
text-align: center;
font-size: 15px;
color: #888;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
}
@media (max-width: 900px) {
.main-content {
padding: 12px 4px;
}
.image-item {
width: 100px;
padding: 8px 4px 8px 4px;
}
.image-item img {
width: 80px;
height: 80px;
}
}
</style>
{include file="public/tail" /}