This commit is contained in:
2025-05-16 10:21:44 +08:00
10 changed files with 1139 additions and 396 deletions
+371 -108
View File
@@ -1,8 +1,8 @@
{include file="public/header" /}
<div class="config-container">
<div class="config-header" style="display:flex;justify-content: space-between;">
<div>
<span>文章分类列表</span>
<div style="display: flex; align-items: center;">
<span>文章分类</span>
</div>
<div>
<button type="button" class="layui-btn layui-btn-primary layui-btn-sm" onclick="add()">
@@ -14,127 +14,390 @@
</div>
</div>
<table class="layui-table">
<thead>
<tr>
<th width="20">ID</th>
<th width="120">分类名称</th>
<th width="120">分类图片</th>
<th>描述</th>
<th width="80">排序</th>
<th width="80">状态</th>
<th width="180">创建时间</th>
<th width="240">操作</th>
</tr>
</thead>
<tbody>
{volist name="lists" id='vo'}
{if condition="$vo.cid eq 0"}
<tr>
<td>{$vo.id}</td>
<td>{$vo.name}</td>
<td><img src="{$vo.image}" style="width: 100px;height: auto;"></td>
<td></td>{$vo.desc}</td>
<td>{$vo.sort}</td>
<td>{$vo.status==1?'开启':'<span style="color:red;">禁用</span>'}</td>
<td>{$vo.create_time}</td>
<td>
<button type="button" class="layui-btn layui-btn-primary layui-btn-xs"
onclick="addchanel({$vo.id})">
<i class="layui-icon layui-icon-add-1"></i>添加子栏目
</button>
<button type="button" class="layui-btn layui-btn-primary layui-btn-xs" onclick="edit({$vo.id})">
<i class="layui-icon layui-icon-edit"></i>编辑
</button>
<button type="button" class="layui-btn layui-btn-primary layui-btn-xs" onclick="del({$vo.id})">
<i class="layui-icon layui-icon-delete"></i>删除
</button>
</td>
</tr>
{volist name="lists" id='sub'}
{if condition="$sub.cid eq $vo.id"}
<tr>
<td>{$sub.id}</td>
<td style="padding-left: 30px;">├─ {$sub.name}</td>
<td><img src="{$sub.image}" style="width: 100px;height: auto;"></td>
<td>{$sub.desc}</td>
<td>{$sub.sort}</td>
<td>{$sub.status==1?'开启':'<span style="color:red;">禁用</span>'}</td>
<td>{$sub.create_time}</td>
<td>
<button type="button" class="layui-btn layui-btn-primary layui-btn-xs" onclick="edit({$sub.id})">
<i class="layui-icon layui-icon-edit"></i>编辑
</button>
<button type="button" class="layui-btn layui-btn-primary layui-btn-xs" onclick="del({$sub.id})">
<i class="layui-icon layui-icon-delete"></i>删除
</button>
</td>
</tr>
{/if}
{/volist}
{/if}
{/volist}
</tbody>
</table>
<div class="layui-row" style="margin-top: 15px;">
<div class="layui-col-md6">
<div class="layui-card">
<div class="layui-card-header">分类列表</div>
<div class="layui-card-body">
<div id="categoryList"></div>
</div>
</div>
</div>
<div class="layui-col-md4"">
<div class="layui-card">
<div class="layui-card-header">分类信息</div>
<div class="layui-card-body">
<div id="defaultTip" style="text-align: center; padding: 50px 0; color: #999;">
<i class="layui-icon layui-icon-face-surprised" style="font-size: 30px;"></i>
<p style="margin-top: 10px;">请选择左侧分类</p>
</div>
<form class="layui-form" lay-filter="categoryForm" style="display: none;">
<input type="hidden" name="id" id="categoryId">
<div class="layui-form-item">
<label class="layui-form-label">分类名称</label>
<div class="layui-input-block">
<input type="text" name="name" required lay-verify="required" placeholder="请输入分类名称"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">父级分类</label>
<div class="layui-input-block">
<select name="cid" lay-verify="required">
<option value="0">顶级分类</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">封面图片</label>
<div class="layui-input-block">
<input type="text" name="image" placeholder="请输入图片地址" autocomplete="off"
class="layui-input" id="imageInput">
<div class="layui-upload" style="margin-top: 20px;">
<div>
<button type="button" class="layui-btn" id="uploadImage">上传图片</button>
<span style="color: #999; margin-left: 10px;">建议尺寸:250px*140px</span>
</div>
<div class="layui-upload-list">
<img class="layui-upload-img" id="imagePreview" style="margin-top: 10px;">
<i class="layui-icon layui-icon-close delete-image"
style="display: none; position: absolute; top: 0; right: 0; cursor: pointer; color: #FF5722;"></i>
</div>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">排序</label>
<div class="layui-input-block">
<input type="number" name="sort" value="0" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="status" value="1" title="正常" checked>
<input type="radio" name="status" value="0" title="禁用">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="saveCategory">保存</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<button type="button" class="layui-btn layui-btn-danger" id="deleteBtn"
style="display: none;">删除</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
layui.use(['layer'], function () {
layer = layui.layer;
$ = layui.jquery;
});
layui.use(['layer', 'form', 'util', 'upload'], function () {
var layer = layui.layer;
var $ = layui.jquery;
var form = layui.form;
var util = layui.util;
var upload = layui.upload;
function add() {
layer.open({
type: 2,
title: '添加分类',
shadeClose: true,
shade: 0.8,
area: ['800px', '600px'],
content: '{:url("article/cateadd")}'
});
}
// 初始化分类列表
function initCategoryList() {
$.ajax({
url: '/admin/article/articlecate',
type: 'POST',
success: function (res) {
if (res.code === 0) {
var html = '';
res.data.forEach(function (item) {
html += renderCategory(item);
});
$('#categoryList').html(html);
bindEvents();
} else {
layer.msg('获取分类数据失败', { icon: 2 });
}
},
error: function () {
layer.msg('请求失败,请重试', { icon: 2 });
}
});
}
function edit(id) {
layer.open({
type: 2,
title: '编辑分类',
shadeClose: true,
shade: 0.8,
area: ['800px', '800px'],
content: '{:url("article/cateedit")}?id=' + id
});
}
// 渲染分类
function renderCategory(category, level = 0) {
var html = '<div class="category-item" data-id="' + category.id + '">';
html += '<div class="category-header">';
html += '<span class="category-name">' + category.title + '</span>';
html += '<div class="category-actions">';
// 只有一级分类才显示添加按钮
if (level === 0) {
html += '<i class="layui-icon layui-icon-add-1 add-child" title="添加子分类"></i>';
}
html += '</div>';
html += '</div>';
function del(id) {
layer.confirm('确定要删除该分类吗?', {
btn: ['确定', '取消']
}, function () {
$.post('{:url("article/catedel")}', { id: id }, function (res) {
if (res.code == 0) {
if (category.children && category.children.length > 0) {
html += '<div class="category-children">';
category.children.forEach(function (child) {
html += renderCategory(child, level + 1);
});
html += '</div>';
}
html += '</div>';
return html;
}
// 绑定事件
function bindEvents() {
// 点击分类
$('.category-name').off('click').on('click', function () {
var id = $(this).closest('.category-item').data('id');
loadCategoryInfo(id);
});
// 点击添加子分类
$('.add-child').off('click').on('click', function (e) {
e.stopPropagation();
var id = $(this).closest('.category-item').data('id');
$('#categoryId').val('');
$('select[name="cid"]').val(id);
$('#deleteBtn').hide();
form.render();
});
}
// 加载分类信息
function loadCategoryInfo(id) {
$('#defaultTip').hide();
$('form.layui-form').show();
$.get('/admin/article/cateedit?id=' + id, function (res) {
if (res.code === 0) {
// 更新父级分类选项
var $select = $('select[name="cid"]');
$select.empty();
$select.append('<option value="0">顶级分类</option>');
res.data.parentOptions.forEach(function (item) {
$select.append('<option value="' + item.id + '">' + item.name + '</option>');
});
// 填充表单数据
form.val('categoryForm', res.data.info);
// 显示图片预览
if (res.data.info.image) {
$('#imagePreview').attr('src', res.data.info.image);
$('.delete-image').show();
} else {
$('#imagePreview').attr('src', '');
$('.delete-image').hide();
}
// 显示删除按钮
$('#deleteBtn').show();
// 重新渲染表单
form.render();
}
});
}
// 初始化
initCategoryList();
// 默认显示提示信息
$('#defaultTip').show();
$('form.layui-form').hide();
// 监听表单提交
form.on('submit(saveCategory)', function (data) {
var url = data.field.id ? '/admin/article/cateedit' : '/admin/article/cateadd';
$.post(url, data.field, function (res) {
if (res.code === 0) {
layer.msg(res.msg, { icon: 1 });
setTimeout(function () {
window.location.reload();
}, 1000);
initCategoryList();
} else {
layer.msg(res.msg, { icon: 2 });
}
});
return false;
});
}
function addchanel(id) {
layer.open({
type: 2,
title: '添加子栏目',
shadeClose: true,
shade: 0.8,
area: ['800px', '600px'],
content: '{:url("article/cateadd")}?cid=' + id
// 监听删除按钮点击
$('#deleteBtn').on('click', function () {
var id = $('input[name="id"]').val();
if (!id) return;
layer.confirm('确定要删除该分类吗?', {
btn: ['确定', '取消']
}, function () {
$.post('/admin/article/catedel', { id: id }, function (res) {
if (res.code == 0) {
layer.msg(res.msg, { icon: 1 });
initCategoryList();
// 重置表单
form.val('categoryForm', {
id: '',
name: '',
cid: '0',
image: '',
sort: 0,
status: 1
});
$('#imagePreview').attr('src', '');
$('#deleteBtn').hide();
form.render();
} else {
layer.msg(res.msg, { icon: 2 });
}
});
});
});
// 图片上传
upload.render({
elem: '#uploadImage',
url: '/admin/upload/image', // 替换为实际的上传接口
accept: 'images',
acceptMime: 'image/*',
done: function (res) {
if (res.code === 0) {
$('#imageInput').val(res.data.url);
$('#imagePreview').attr('src', res.data.url);
layer.msg('上传成功');
} else {
layer.msg('上传失败');
}
}
});
// 监听图片输入框变化
$('#imageInput').on('input', function () {
var url = $(this).val();
if (url) {
$('#imagePreview').attr('src', url);
$('.delete-image').show();
} else {
$('#imagePreview').attr('src', '');
$('.delete-image').hide();
}
});
// 监听图片删除按钮点击
$(document).on('click', '.delete-image', function () {
$('#imageInput').val('');
$('#imagePreview').attr('src', '');
$(this).hide();
});
});
function add() {
$('#defaultTip').hide();
$('form.layui-form').show();
// 重置表单
layui.form.val('categoryForm', {
id: '',
name: '',
cid: '0',
image: '',
sort: 0,
status: 1
});
$('#imagePreview').attr('src', '');
$('.delete-image').hide();
$('#deleteBtn').hide();
layui.form.render();
}
function refresh() {
window.location.reload();
initCategoryList();
}
</script>
</script>
<style>
.category-item {
margin: 5px 0;
}
.category-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 10px;
background-color: #f8f8f8;
border-radius: 2px;
cursor: pointer;
}
.category-header:hover {
background-color: #f2f2f2;
}
.category-name {
flex: 1;
font-size: 14px;
}
.category-actions {
display: none;
}
.category-header:hover .category-actions {
display: block;
}
.category-children {
margin-left: 20px;
padding-left: 10px;
border-left: 1px solid #e6e6e6;
}
.add-child {
color: #1E9FFF;
font-size: 14px;
cursor: pointer;
margin-left: 10px;
}
.add-child:hover {
color: #0C7CD5;
}
.layui-upload-list {
margin-top: 10px;
position: relative;
display: inline-block;
}
.delete-image {
position: absolute;
top: 0;
right: 0;
cursor: pointer;
color: #FF5722;
font-size: 20px;
background: rgba(255, 255, 255, 0.8);
border-radius: 50%;
padding: 2px;
}
.delete-image:hover {
color: #FF0000;
}
.layui-card {
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
}
.layui-col-md4{
width: 40%;
}
.layui-col-md6{
width: 60%;
}
</style>
+114 -55
View File
@@ -1,8 +1,25 @@
{include file="public/header" /}
<div class="config-container">
<div class="config-header" style="display:flex;justify-content: space-between;">
<div>
<div style="display: flex; align-items: center;">
<span>文章列表</span>
<div class="shaixuan">
<label>筛选:</label>
<div class="layui-form">
<div class="layui-input-inline">
<select id="categoryFilter" lay-filter="categoryFilter" lay-verify="">
<option value="">全部分类</option>
{volist name="categories" id="category"}
<optgroup label="{$category.name}">
{volist name="category.children" id="subCategory"}
<option value="{$subCategory.id}">{$subCategory.name}</option>
{/volist}
</optgroup>
{/volist}
</select>
</div>
</div>
</div>
</div>
<div>
<button type="button" class="layui-btn layui-btn-primary layui-btn-sm" onclick="add()">
@@ -14,77 +31,119 @@
</div>
</div>
<table class="layui-table">
<thead>
<tr>
<th width="20">ID</th>
<th>标题</th>
<th>分类</th>
<th>封面</th>
<th>作者</th>
<th>状态</th>
<th>发布时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{volist name="lists" id='vo'}
<tr>
<td>{$vo.id}</td>
<td>{$vo.title}</td>
<td>{$vo.cate}</td>
<td>
{if condition="$vo.image"}
<img src="{$vo.image}" style="max-width: 50px; max-height: 50px;">
{/if}
</td>
<td>{$vo.author}</td>
<td>
{switch name="vo.status"}
{case value="0"}<span style="color:red;">草稿</span>{/case}
{case value="1"}<span style="color:orange;">待审核</span>{/case}
{case value="2"}<span style="color:green;">已发布</span>{/case}
{case value="3"}<span style="color:gray;">隐藏</span>{/case}
{/switch}
</td>
<td>{$vo.publishdate}</td>
<td>
<button type="button" class="layui-btn layui-btn-primary layui-btn-xs" onclick="edit({$vo.id})">
<i class="layui-icon layui-icon-edit"></i>编辑
</button>
<button type="button" class="layui-btn layui-btn-primary layui-btn-xs" onclick="del({$vo.id})">
<i class="layui-icon layui-icon-delete"></i>删除
</button>
</td>
</tr>
{/volist}
</tbody>
</table>
<table id="articleTable" lay-filter="articleTable"></table>
</div>
<script type="text/html" id="imageTemplate">
{{# if(d.image){ }}
<img src="{{ d.image }}" 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>
{{# } else if(d.status === 2){ }}
<span style="color:green;">已发布</span>
{{# } else if(d.status === 3){ }}
<span style="color:gray;">隐藏</span>
{{# } }}
</script>
<script type="text/html" id="operationBar">
<button type="button" class="layui-btn layui-btn-primary 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'], function () {
layer = layui.layer;
$ = layui.jquery;
layui.use(['layer', 'form', 'table'], function () {
var layer = layui.layer;
var $ = layui.jquery;
var form = layui.form;
var table = layui.table;
// 初始化表格
table.render({
elem: '#articleTable',
url: '/admin/article/articlelist',
method: 'post',
cols: [[
{field: 'id', title: 'ID', align:'center', width: 80},
{field: 'title', title: '标题'},
{field: 'cate', title: '分类', align:'center', width: 180},
{field: 'image', title: '封面', templet: '#imageTemplate', align:'center', width: 180},
{field: 'author', title: '作者', align:'center', width: 120},
{field: 'status', title: '状态', templet: '#statusTemplate', align:'center', width: 80},
{field: 'publishdate', title: '发布时间', align:'center', width: 180},
{title: '操作', toolbar: '#operationBar', align:'center', width: 150}
]],
page: true,
limit: 20,
limits: [10, 20, 30, 50],
//height: 'full-220'
});
// 监听工具条事件
table.on('tool(articleTable)', 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) {
if (!categoryId) {
layui.table.reload('articleTable', {
where: {},
page: {
curr: 1
}
});
return;
}
var categoryName = $('#categoryFilter option[value="' + categoryId + '"]').text();
layui.table.reload('articleTable', {
where: {
category: categoryName
},
page: {
curr: 1
}
});
}
function add() {
window.location.href = '{:url("article/add")}';
window.location.href = '/admin/article/add';
}
function edit(id) {
window.location.href = '{:url("article/edit")}?id=' + id;
window.location.href = '/admin/article/edit?id=' + id;
}
function del(id) {
layer.confirm('确定要删除该文章吗?', {
btn: ['确定', '取消']
}, function () {
$.post('{:url("article/delete")}', { id: id }, function (res) {
$.post('/admin/article/delete', { id: id }, function (res) {
if (res.code == 0) {
layer.msg(res.msg, { icon: 1 });
setTimeout(function () {
window.location.reload();
layui.table.reload('articleTable');
}, 1000);
} else {
layer.msg(res.msg, { icon: 2 });
@@ -94,6 +153,6 @@
}
function refresh() {
window.location.reload();
layui.table.reload('articleTable');
}
</script>
+2 -2
View File
@@ -24,11 +24,11 @@
<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="357099073@qq.com">
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" class="layui-input" placeholder="密码" class="layui-input"
<input type="password" name="password" lay-affix="eye" class="layui-input" placeholder="密码" class="layui-input"
value="">
</div>
<div class="layui-form-item">