支持多级分类,cate表添加pid字段

This commit is contained in:
taoser 2022-09-07 15:21:56 +08:00
parent 89ece07993
commit a3b4b8e16c
21 changed files with 468 additions and 160 deletions

View File

@ -470,7 +470,7 @@ abstract class BaseController
$uploads = new Uploads(); $uploads = new Uploads();
switch ($type){ switch ($type){
case 'image': case 'image':
$upRes = $uploads->put('file','article_pic',1024,'image'); $upRes = $uploads->put('file','article_pic',2048,'image');
break; break;
case 'zip': case 'zip':
$upRes = $uploads->put('file','article_zip',1024,'application|image'); $upRes = $uploads->put('file','article_zip',1024,'application|image');
@ -482,7 +482,7 @@ abstract class BaseController
$upRes = $uploads->put('file','article_audio',102400,'audio'); $upRes = $uploads->put('file','article_audio',102400,'audio');
break; break;
default: default:
$upRes = $uploads->put('file','article_file',1024,'image'); $upRes = $uploads->put('file','article_file',2048,'image');
break; break;
} }
return $upRes; return $upRes;

View File

@ -145,7 +145,7 @@ class Forum extends AdminController
$res['count']= count($list); $res['count']= count($list);
$res['data'] = []; $res['data'] = [];
foreach($list as $k=>$v){ foreach($list as $k=>$v){
$res['data'][] = ['sort'=>$v['sort'],'id' => $v['id'],'tags'=>$v['catename'],'ename'=>$v['ename'],'detpl'=>$v['detpl'],'icon'=>$v['icon'],'is_hot'=>$v['is_hot'],'desc'=>$v['desc']]; $res['data'][] = ['sort'=>$v['sort'],'id' => $v['id'],'pid'=>$v['pid'],'tags'=>$v['catename'],'ename'=>$v['ename'],'detpl'=>$v['detpl'],'icon'=>$v['icon'],'is_hot'=>$v['is_hot'],'desc'=>$v['desc']];
} }
} }
return json($res); return json($res);
@ -162,9 +162,9 @@ class Forum extends AdminController
{ {
$addOrEdit = !is_null(input('id'));//true是编辑false新增 $addOrEdit = !is_null(input('id'));//true是编辑false新增
$msg = $addOrEdit ? lang('edit') : lang('add'); $msg = $addOrEdit ? lang('edit') : lang('add');
if(Request::isAjax()){ if(Request::isAjax()) {
$data = Request::param(); $data = Request::param();
$list = Db::name('cate')->cache('catename')->save($data); $list = Db::name('cate')->cache('catename')->save($data);
if($list){ if($list){
return json(['code'=>0,'msg'=> $msg.'分类成功']); return json(['code'=>0,'msg'=> $msg.'分类成功']);
@ -172,11 +172,12 @@ class Forum extends AdminController
return json(['code'=>-1,'msg'=> $msg.'分类失败']); return json(['code'=>-1,'msg'=> $msg.'分类失败']);
} }
} }
$tplname = $addOrEdit ? Db::name('cate')->where('id',input('id'))->value('detpl') : '';
//详情模板 //详情模板
$sys = $this->getSystem(); $sys = $this->getSystem();
$template = Files::getDirName('../view/'.$sys['template'].'/index/article/'); $template = Files::getDirName('../view/'.$sys['template'].'/index/article/');
View::assign(['template'=>$template,'tplname'=>$tplname]); // 如果是新增pid=0,detpl默认第一个子模块如果是编辑查询出cate
$cate = $addOrEdit ? Db::name('cate')->field('detpl,pid')->find((int) input('id')) : ['pid'=>0,'detpl'=>$template[0]];
View::assign(['template'=>$template,'cate'=>$cate]);
return View::fetch(); return View::fetch();
} }
@ -544,6 +545,49 @@ class Forum extends AdminController
return $this->uploadFiles($type); return $this->uploadFiles($type);
} }
public function getCateTree()
{
//
$cate = Db::name('cate')->order(['id' => 'ASC','sort' => 'ASC'])->where(['delete_time'=>0])->select()->toArray();
$cateTree = array2tree($cate);
$count = count($cateTree);
$tree = [];
if($cateTree){
$tree = ['code'=>0,'msg'=>'','count'=>$count];
$res = []; //auth_rule储存数据表中的表结构
foreach($cateTree as $k => $v){
//第一层子权限
$children = [];
if(isset($v['children'])){
foreach($v['children'] as $m => $j){
//第二层子权限
$chichi = [];
if(isset($j['children'])){
//第三层子权限
foreach($j as $s){
if(isset($s['children'])){
$chichi[] = ['id'=>$s['id'],'catename'=>$s['catename'],'pid'=>$s['pid']]; //子数据的子数据
}
}
}
//if($j['level'] < 3){}
$children[] = ['id'=>$j['id'],'catename'=>$j['catename'],'pid'=>$j['pid'],'children'=>$chichi]; //子数据
}
}
$data[] = ['id'=>$v['id'],'catename'=>$v['catename'],'pid'=>$v['pid'],'children'=>$children];
}
//构造一个顶级菜单pid=0的数组。把权限放入顶级菜单下子权限中
$tree['data'][] = ['id'=>0,'catename'=>'顶级','pid'=>0,'children'=>$data];
}
return json($tree);
}
} }

View File

@ -7,7 +7,7 @@
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">上级菜单</label> <label class="layui-form-label">上级菜单</label>
<div class="layui-input-block"> <div class="layui-input-block">
<div id="menuSelectBox" class="ew-xmselect-tree"></div> <div id="menuSelectBox" class="ew-xmselect-tree"></div>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">

View File

@ -39,9 +39,9 @@
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">类型</label> <label class="layui-form-label">类型</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="radio" name="ishidden" lay-skin="primary" title="目录" value="-1" {if condition="$rules.ishidden == -1"}checked{/if}> <input type="radio" name="ishidden" lay-skin="primary" title="目录" value="-1" {if condition="$rules.ishidden == -1"} checked {/if}>
<input type="radio" name="ishidden" lay-skin="primary" title="菜单" value="1" {if condition="$rules.ishidden == 1"}checked{/if}> <input type="radio" name="ishidden" lay-skin="primary" title="菜单" value="1" {if condition="$rules.ishidden == 1"} checked {/if}>
<input type="radio" name="ishidden" lay-skin="primary" title="按钮" value="0" {if condition="$rules.ishidden == 0"}checked{/if}> <input type="radio" name="ishidden" lay-skin="primary" title="按钮" value="0" {if condition="$rules.ishidden == 0"} checked {/if}>
</div> </div>
</div> </div>
<div class="layui-form-item layui-hide"> <div class="layui-form-item layui-hide">
@ -63,7 +63,7 @@
var admin = layui.admin; var admin = layui.admin;
var xmSelect = layui.xmSelect; var xmSelect = layui.xmSelect;
var iconPicker = layui.iconPicker; var iconPicker = layui.iconPicker;
var initPid = "{$rules['pid']}";
//初始化图标选择 //初始化图标选择
iconPicker.render({ iconPicker.render({
@ -93,7 +93,7 @@
layVerify: 'required', layVerify: 'required',
layVerType: 'tips', layVerType: 'tips',
data: data, data: data,
initValue: [{$rules['pid']}], initValue: [initPid],
model: {label: {type: 'text'}}, model: {label: {type: 'text'}},
prop: { prop: {
name: 'title', name: 'title',

View File

@ -7,7 +7,6 @@
<body class="layui-hide"> <body class="layui-hide">
<div class="page-wrapper"> <div class="page-wrapper">
<div class="demo-side"> <div class="demo-side">
<table id="LAY-user-auth-rule"></table> <table id="LAY-user-auth-rule"></table>
</div> </div>

View File

@ -151,27 +151,31 @@ layui.config({
var keywords = this.content.join(','); var keywords = this.content.join(',');
$("input[name='keywords']").val(keywords); $("input[name='keywords']").val(keywords);
} }
}) })
// tag标签
$(function(){
//1.渲染标签 //1.渲染标签
var addTags = xmSelect.render({ var addTags = xmSelect.render({
el: '#tag', el: '#tag',
name: 'tagid', name: 'tagid',
layVerify: 'required', layVerify: 'required',
layVerType: 'msg', layVerType: 'msg',
paging: true, paging: true,
pageSize: 5, pageSize: 5,
data: [] data: []
}); });
//2.动态标签赋值 //2.动态标签赋值
$.get("{:url('tag/getAllTag')}",function(res){ $.get("{:url('tag/getAllTag')}",function(res){
if(res.code == 0){ if(res.code == 0){
addTags.update({ addTags.update({
data: res.data, data: res.data,
autoRow: true, autoRow: true,
}) })
} }
}); });
})
// 通过接口自动获取tag的内容 // 通过接口自动获取tag的内容
var conf = "{:empty(config('taoler.baidu.client_id'))}"; var conf = "{:empty(config('taoler.baidu.client_id'))}";

View File

@ -86,7 +86,7 @@
<script> <script>
//定义选择器 //定义选择器
var mytextareaid = 'textarea#L_content'; var mytextareaid = 'textarea#L_content';
var imagePrependUrl = "{domain}"; var imagePrependUrl = "{$domain}";
//定义文件上传接口接口 //定义文件上传接口接口
var taonyUploadUrl = "{:url('forum/uploads')}", var taonyUploadUrl = "{:url('forum/uploads')}",
taonyUploadImgage = "{:url('forum/uploads')}?type=image", taonyUploadImgage = "{:url('forum/uploads')}?type=image",

View File

@ -1,4 +1,5 @@
{extend name="public:base" /} {extend name="public:base" /}
{block name="css"}<link rel="stylesheet" href="/static/admin/tree/css/treeTable.css">{/block}
{block name="css"} {block name="css"}
<style type="text/css"> <style type="text/css">
.layui-table-body, .layui-table-box, .layui-table-cell{ .layui-table-body, .layui-table-box, .layui-table-cell{
@ -11,37 +12,44 @@ overflow: visible;
margin-left: -15px; margin-left: -15px;
margin-right: -15px; margin-right: -15px;
} }
</style> </style>
{/block} {/block}
{block name="body"} {block name="body"}
<div class="layui-fluid"> <div class="layui-fluid">
<div class="layui-card"> <div class="layui-card">
<div class="layui-card-header layuiadmin-card-header-auto"> <div class="layui-card-header layuiadmin-card-header-auto">
{if condition="checkRuleButton('forum/addtags')"} {if condition="checkRuleButton('forum/addtags')"}
<button class="layui-btn layuiadmin-btn-tags" data-type="add">添加</button> <button class="layui-btn layuiadmin-btn-tags" data-type="add">添加</button>
{/if} {/if}
</div> </div>
<div class="layui-card-body">
<table id="LAY-app-content-tags" lay-filter="LAY-app-content-tags"></table> <div class="page-wrapper">
<script type="text/html" id="inputSel"> <div class="demo-side">
<select name="detpl" lay-filter="detpl" id="{{d.id}}" > <table id="Article-cate-list"></table>
{volist name="template" id="vo"} </div>
<option value="{$vo}" {{# if (d.detpl == "{$vo}"){ }} selected {{# } }}>{$vo}</option> </div>
{/volist}
</select> <div class="layui-card-body">
</script> <script type="text/html" id="inputSel">
<script type="text/html" id="buttonHot"> <select name="detpl" lay-filter="detpl" id="{{d.id}}" >
{if condition="checkRuleButton('Forum/tagshot')"}<input type="checkbox" name="is_hot" lay-skin="primary" lay-filter="menu-show" {{# if(d.is_hot ==1){ }}checked value="0"{{# } else { }}value="1"{{# } }} id="{{d.id}}" > {volist name="template" id="vo"}
{else /}<input type="checkbox" title="禁用" disabled> {/if} <option value="{$vo}" {{# if (d.detpl == "{$vo}"){ }} selected {{# } }}>{$vo}</option>
{/volist}
</select>
</script> </script>
<script type="text/html" id="layuiadmin-app-cont-tagsbar"> <script type="text/html" id="buttonHot">
{if condition="checkRuleButton('forum/tagsform')"} {if condition="checkRuleButton('Forum/tagshot')"}<input type="checkbox" name="is_hot" lay-skin="primary" lay-filter="menu-show" {{# if(d.is_hot ==1){ }} checked value="0"{{# } else { }}value="1"{{# } }} id="{{d.id}}" >
{else /}<input type="checkbox" title="禁用" disabled> {/if}
</script>
<script type="text/html" id="layuiadmin-app-cont-tagsbar">
{if condition="checkRuleButton('forum/tagsform')"}
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i></a> <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i></a>
{else /}<a class="layui-btn layui-btn-disabled layui-btn-normal layui-btn-xs"><i class="layui-icon layui-icon-edit"></i></a>{/if} {else /}<a class="layui-btn layui-btn-disabled layui-btn-normal layui-btn-xs"><i class="layui-icon layui-icon-edit"></i></a>{/if}
{if condition="checkRuleButton('forum/tagsdelete')"} {if condition="checkRuleButton('forum/tagsdelete')"}
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i></a> <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i></a>
{else /}<a class="layui-btn layui-btn-disabled layui-btn-danger layui-btn-xs"><i class="layui-icon layui-icon-delete"></i></a>{/if} {else /}<a class="layui-btn layui-btn-disabled layui-btn-danger layui-btn-xs"><i class="layui-icon layui-icon-delete"></i></a>{/if}
</script> </script>
</div> </div>
</div> </div>
@ -60,29 +68,30 @@ overflow: visible;
forumTags = "{:url('Forum/tags')}", forumTags = "{:url('Forum/tags')}",
forumTagsDelete = "{:url('Forum/tagsdelete')}", forumTagsDelete = "{:url('Forum/tagsdelete')}",
forumTagsForm = "{:url('Forum/tagsform')}"; forumTagsForm = "{:url('Forum/tagsform')}";
layui.config({ layui.config({
base: '/static/admin/' //静态资源所在路径 base: '/static/admin/' //静态资源所在路径
}).extend({ }).extend({
index: 'lib/index' //主入口模块 index: 'lib/index' //主入口模块
}).use(['index', 'forum', 'table','form'], function(){ }).use(['index', 'forum', 'table','form'], function(){
var table = layui.table, var table = layui.table, form = layui.form;
form = layui.form;
var $ = layui.$, active = { var $ = layui.$, active = {
add: function(){ add: function(){
layer.open({ layer.open({
type: 2 type: 2
,title: '添加分类' ,title: '添加分类'
,content: 'tagsform.html' ,content: 'tagsform.html'
,area: ['400px', '450px'] ,area: ['400px', '550px']
,btn: ['确定', '取消'] ,btn: ['确定', '取消']
,yes: function(index, layero){ ,yes: function(index, layero){
var othis = layero.find('iframe').contents().find("#layuiadmin-app-form-tags") var othis = layero.find('iframe').contents().find("#layuiadmin-app-form-tags")
,pid = othis.find('input[name="pid"]').val()
,sort = othis.find('input[name="sort"]').val() ,sort = othis.find('input[name="sort"]').val()
,tags = othis.find('input[name="tags"]').val() ,tags = othis.find('input[name="tags"]').val()
,ename = othis.find('input[name="ename"]').val() ,ename = othis.find('input[name="ename"]').val()
,detpl = othis.find('select[name="detpl"]').val() ,detpl = othis.find('select[name="detpl"]').val()
,icon = othis.find('input[name="icon"]').val() ,icon = othis.find('input[name="icon"]').val()
,desc = othis.find('input[name="desc"]').val(); ,desc = othis.find('input[name="desc"]').val();
if(!tags.replace(/\s/g, '')) return; if(!tags.replace(/\s/g, '')) return;
@ -90,7 +99,7 @@ overflow: visible;
$.ajax({ $.ajax({
type:"post", type:"post",
url:"{:url('Forum/tagsform')}", url:"{:url('Forum/tagsform')}",
data:{"sort":sort,"catename":tags,"ename":ename,"detpl":detpl,"icon":icon,"desc":desc}, data:{pid:pid,"sort":sort,"catename":tags,"ename":ename,"detpl":detpl,"icon":icon,"desc":desc},
daType:"json", daType:"json",
success:function (data){ success:function (data){
if (data.code == 0) { if (data.code == 0) {

View File

@ -3,6 +3,12 @@
{block name="body"} {block name="body"}
<div class="layui-form" lay-filter="layuiadmin-form-tags" id="layuiadmin-app-form-tags" style="padding: 20px 30px 0 0 ; text-align: center;"> <div class="layui-form" lay-filter="layuiadmin-form-tags" id="layuiadmin-app-form-tags" style="padding: 20px 30px 0 0 ; text-align: center;">
<div class="layui-form-item">
<label class="layui-form-label">上级分类</label>
<div class="layui-input-block">
<div id="menuSelectBox" class="ew-xmselect-tree"></div>
</div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">分类名</label> <label class="layui-form-label">分类名</label>
<div class="layui-input-inline"> <div class="layui-input-inline">
@ -15,9 +21,9 @@
<label class="layui-form-label">详情页模板</label> <label class="layui-form-label">详情页模板</label>
<div class="layui-input-inline"> <div class="layui-input-inline">
<select name="detpl" lay-filter="detpl"> <select name="detpl" lay-filter="detpl">
{volist name="template" id="vo"} {volist name="template" id="vo"}
<option value="{$vo}" {if($vo == $tplname)}selected{/if}>{$vo}</option> <option value="{$vo}" {if($vo == $cate.detpl)} selected {/if} >{$vo}</option>
{/volist} {/volist}
</select> </select>
</div> </div>
<label class="layui-form-label">图标</label> <label class="layui-form-label">图标</label>
@ -43,10 +49,13 @@
base: '/static/admin/' //静态资源所在路径 base: '/static/admin/' //静态资源所在路径
}).extend({ }).extend({
index: 'lib/index' //主入口模块 index: 'lib/index' //主入口模块
}).use(['index', 'form', 'iconPicker'], function(){ }).use(['index', 'form','admin', 'iconPicker', 'xmSelect',], function(){
var $ = layui.$ var $ = layui.$
,form = layui.form ; ,form = layui.form ;
var admin = layui.admin;
var iconPicker = layui.iconPicker; var iconPicker = layui.iconPicker;
var xmSelect = layui.xmSelect;
var initPid = "{$cate.pid}";
//初始化图标选择 //初始化图标选择
iconPicker.render({ iconPicker.render({
@ -59,6 +68,91 @@
//console.log(data); //console.log(data);
} }
}); });
//分类菜单结构
admin.req({
type: "post",
url: "{:url('Forum/getCateTree')}",
data:{},
done:function(res){
var data = res.data;
// 渲染下拉树
xmSelect.render({
el: '#menuSelectBox',
name: 'pid',
height: '250px',
layVerify: 'required',
layVerType: 'tips',
data: data,
initValue: [initPid],
model: {label: {type: 'text'}},
prop: {
name: 'catename',
value: 'id'
},
radio: true,
clickClose: true,
tree: {
show: true,
indent: 15,
strict: false,
expandedKeys: true
},
tips: '请选择上级菜单'
});
// var demo4 = xmSelect.render({
// el: '#menuSelectBox',
// model: { label: { type: 'text' } },
// tree: {
// show: true,
// strict: false,
// expandedKeys: [ -1 ],
// },
// on: function(data){
// if(data.isAdd){
// return data.change.slice(0, 1)
// }
// },
// height: 'auto',
// })
// //这里模拟ajax
// setTimeout(function(){
// demo4.update({
// data: [
// {name: '销售员', value: -1, children: [
// {name: '张三', value: 100, children: []},
// {name: '李四1', value: 2},
// {name: '王五1', value: 3, disabled: true},
// ]},
// {name: '奖品', value: -2, children: [
// {name: '奖品3', value: -3, children: [
// {name: '苹果3', value: 14},
// {name: '香蕉3', value: 15},
// {name: '葡萄3', value: 16},
// ]},
// {name: '苹果2', value: 4, disabled: true},
// {name: '香蕉2', value: 5},
// {name: '葡萄2', value: 6},
// ]},
// ]
// })
// //设置默认值
// demo4.setValue([
// {name: '李四1', value: 2},
// {name: '苹果3', value: 14},
// ], null, true)
// }, 300)
}
});
}) })
</script> </script>
{/block} {/block}

View File

@ -70,6 +70,7 @@ class AdminController extends \app\BaseController
/** /**
* 获取角色菜单 * 获取角色菜单
* $type 1 admin后端权限,2 index前端权限
*/ */
protected function getMenus($type) protected function getMenus($type)
{ {

View File

@ -60,8 +60,10 @@ class BaseController extends BaseCtrl
protected function showNav() protected function showNav()
{ {
//1.查询分类表获取所有分类 //1.查询分类表获取所有分类
$cateList = Db::name('cate')->where(['status'=>1,'delete_time'=>0])->order('sort','asc')->cache('catename',3600)->select(); $cateList = Db::name('cate')->where(['status'=>1,'delete_time'=>0])->order('sort','asc')->cache('catename',3600)->select()->toArray();
$cateList = array2tree($cateList);
// $cateList = getTree($cateList);
// dump($cateList);
//2.将catelist变量赋给模板 公共模板nav.html //2.将catelist变量赋给模板 公共模板nav.html
View::assign('cateList',$cateList); View::assign('cateList',$cateList);
return $cateList; return $cateList;

View File

@ -364,7 +364,7 @@ class Article extends Model
$query->where('delete_time',0)->field('id,catename,ename'); $query->where('delete_time',0)->field('id,catename,ename');
}]) }])
->where(['status'=>1]) ->where(['status'=>1])
// ->where('article.id', '<>', $id) // ->where('article.id', '<>', $id)
->order('pv desc') ->order('pv desc')
->limit($limit) ->limit($limit)
->append(['url']) ->append(['url'])

View File

@ -307,14 +307,24 @@ class Article extends BaseController
// 子模块自定义自适应add.html模板 // 子模块自定义自适应add.html模板
$tpl = Db::name('cate')->where('ename', input('cate'))->value('detpl'); $cate = Db::name('cate')->field('id,detpl')->where('ename', input('cate'))->find();
// 子模块下有add.html模板
if(!empty($cate)) {
$cid = $cate['id'];
} else {
$cate['detpl'] = '';
$cid = '';
}
// 模板路径
$appName = $this->app->http->getName(); $appName = $this->app->http->getName();
$viewRoot = root_path() . config('view.view_dir_name') . DIRECTORY_SEPARATOR . $appName . DIRECTORY_SEPARATOR; $viewRoot = root_path() . config('view.view_dir_name') . DIRECTORY_SEPARATOR . $appName . DIRECTORY_SEPARATOR;
$view = 'article' . DIRECTORY_SEPARATOR . $tpl . DIRECTORY_SEPARATOR . 'add.html'; $view = 'article' . DIRECTORY_SEPARATOR . $cate['detpl'] . DIRECTORY_SEPARATOR . 'add.html';
$vfile = $viewRoot . $view; $vfile = $viewRoot . $view;
//子模块下存在add模板则调用否则调用article/add.html
$addTpl = is_file($vfile) ? $vfile : 'add'; $addTpl = is_file($vfile) ? $vfile : 'add';
View::assign(['jspage'=>'jie']); View::assign(['jspage'=>'jie','cid'=>$cid]);
return View::fetch($addTpl); return View::fetch($addTpl);
} }
@ -577,8 +587,10 @@ class Article extends BaseController
// $pats = '/(?<!\[)'.$key.'(?!\])/'; // $pats = '/(?<!\[)'.$key.'(?!\])/';
// $pats = '/(?<!<a\s?(.*)?)'.$key.'(?!<\/a>)/'; // $pats = '/(?<!<a\s?(.*)?)'.$key.'(?!<\/a>)/';
//$pats = '/'.$key.'(?!<\/a>)/'; //$pats = '/'.$key.'(?!<\/a>)/';
// 不匹配 $key</a>已经存在链接的情况
$pats = '/' . $value['name'] . '\s?(?!<\/a>|")/is'; //1.不匹配 $key</a>已经存在链接的情况
//2.或不匹配 alt="$key等等等" $key后面有"这种情况
$pats = '/' . $value['name'] . '\s?(?!<\/a>|\s?\S*")/is';
preg_match($pats,$content,$arr); preg_match($pats,$content,$arr);
@ -610,6 +622,50 @@ class Article extends BaseController
} }
} }
public function getCateTree()
{
//
$cate = Db::name('cate')->order(['id' => 'ASC','sort' => 'ASC'])->where(['delete_time'=>0])->select()->toArray();
$cateTree = array2tree($cate);
$count = count($cateTree);
$tree = [];
if($cateTree){
$tree = ['code'=>0,'msg'=>'','count'=>$count];
$res = []; //auth_rule储存数据表中的表结构
foreach($cateTree as $k => $v){
//第一层子权限
$children = [];
if(isset($v['children'])){
foreach($v['children'] as $m => $j){
//第二层子权限
$chichi = [];
if(isset($j['children'])){
//第三层子权限
foreach($j as $s){
if(isset($s['children'])){
$chichi[] = ['id'=>$s['id'],'catename'=>$s['catename'],'pid'=>$s['pid']]; //子数据的子数据
}
}
}
//if($j['level'] < 3){}
$children[] = ['id'=>$j['id'],'catename'=>$j['catename'],'pid'=>$j['pid'],'children'=>$chichi]; //子数据
}
}
$data[] = ['id'=>$v['id'],'catename'=>$v['catename'],'pid'=>$v['pid'],'children'=>$children];
}
//构造一个顶级菜单pid=0的数组。把权限放入顶级菜单下子权限中
//$tree['data'][] = ['id'=>0,'catename'=>'顶级','pid'=>0,'children'=>$data];
$tree['data'] = $data;
}
return json($tree);
}
} }

View File

@ -56,6 +56,7 @@ Route::group('art',function () use($detail_as,$cate_as){
Route::rule('delete/[:id]','Article/delete'); Route::rule('delete/[:id]','Article/delete');
Route::rule('tags','Article/tags')->allowCrossDomain(); Route::rule('tags','Article/tags')->allowCrossDomain();
Route::rule('edit/[:id]','Article/edit'); Route::rule('edit/[:id]','Article/edit');
Route::get('article/catetree','Article/getCateTree');
}); });
//tag //tag

View File

@ -1,8 +1,9 @@
 
layui.define(['table', 'form'], function(exports){ layui.define(['table', 'form', 'treeTable'], function(exports){
var $ = layui.$ var $ = layui.$
,table = layui.table ,table = layui.table
,form = layui.form; ,form = layui.form;
var treeTable = layui.treeTable;
//帖子管理 //帖子管理
var forms = table.render({ var forms = table.render({
@ -189,26 +190,39 @@ var forms = table.render({
} }
}); });
//帖子分类管理 // 渲染分类表格
table.render({ var insTb = treeTable.render({
elem: '#LAY-app-content-tags' elem: '#Article-cate-list',
,url: forumTags //帖子分类接口 url: forumTags,
,cols: [[ //toolbar: 'default',
{field: 'sort', title: '排序', width: 80, sort: true} //height: 'full-200',
,{field: 'id', title: 'ID',width: 60} tree: {
,{field: 'tags', title: '分类名', width: 100} iconIndex: 2,
,{field: 'ename', title: 'EN别名', width: 100} isPidData: true,
,{field: 'detpl',title: '模板', align: 'center',width: 100,templet: '#inputSel'} idName: 'id',
,{title: '图标', align: 'center',width: 50,templet: '<p><i class="layui-icon {{d.icon}}"></i></p>'} pidName: 'pid'
,{field: 'is_hot', title: '热门', align: 'center',width: 50, templet: '#buttonHot'} },
,{field: 'desc', title: '描述', minWidth: 200} defaultToolbar: ['filter', 'print', 'exports'],
,{title: '操作', width: 100, align: 'center', toolbar: '#layuiadmin-app-cont-tagsbar'} cols: [
]] [
,text: '对不起,加载出现异常!' {type: 'numbers'},
}); {type: 'checkbox'}
,{field: 'tags', title: '分类名', minWidth: 200}
,{field: 'ename', title: 'EN别名', width: 100}
,{field: 'detpl',title: '模板', align: 'center',width: 100,templet: '#inputSel'}
,{title: '图标', align: 'center',width: 50,templet: '<p><i class="layui-icon {{d.icon}}"></i></p>'}
,{field: 'is_hot', title: '热门', align: 'center',width: 50, templet: '#buttonHot'}
,{field: 'desc', title: '描述', minWidth: 200}
,{field: 'id', title: 'ID',width: 60}
,{field: 'sort', title: '排序', width: 80, sort: true}
,{title: '操作', width: 120, align: 'center', toolbar: '#layuiadmin-app-cont-tagsbar'}
]
],
style: 'margin-top:0;'
});
//监听工具条 //监听工具条
table.on('tool(LAY-app-content-tags)', function(obj){ treeTable.on('tool(Article-cate-list)', function(obj){
var data = obj.data; var data = obj.data;
if(obj.event === 'del'){ if(obj.event === 'del'){
layer.confirm('确定删除此分类?', function(index){ layer.confirm('确定删除此分类?', function(index){
@ -249,6 +263,7 @@ var forms = table.render({
,yes: function(index, layero){ ,yes: function(index, layero){
//获取iframe元素的值 //获取iframe元素的值
var othis = layero.find('iframe').contents().find("#layuiadmin-app-form-tags") var othis = layero.find('iframe').contents().find("#layuiadmin-app-form-tags")
,pid = othis.find('input[name="pid"]').val()
,sort = othis.find('input[name="sort"]').val() ,sort = othis.find('input[name="sort"]').val()
,tags = othis.find('input[name="tags"]').val() ,tags = othis.find('input[name="tags"]').val()
,ename = othis.find('input[name="ename"]').val() ,ename = othis.find('input[name="ename"]').val()
@ -261,7 +276,7 @@ var forms = table.render({
$.ajax({ $.ajax({
type:"post", type:"post",
url:forumTagsForm, url:forumTagsForm,
data:{"id":data.id,"sort":sort,"catename":tags,"ename":ename,"detpl":detpl,"icon":icon,"desc":desc}, data:{"id":data.id,"pid":pid,"sort":sort,"catename":tags,"ename":ename,"detpl":detpl,"icon":icon,"desc":desc},
daType:"json", daType:"json",
success:function (data){ success:function (data){
if (data.code == 0) { if (data.code == 0) {
@ -288,15 +303,17 @@ var forms = table.render({
,sort: sort ,sort: sort
}); });
*/ */
treeTable.reload('Article-cate-list'); //数据刷新
layer.close(index); layer.close(index);
} }
,success: function(layero, index){ ,success: function(layero, index){
//给iframe元素赋值 //给iframe元素赋值
var othis = layero.find('iframe').contents().find("#layuiadmin-app-form-tags").click(); var othis = layero.find('iframe').contents().find("#layuiadmin-app-form-tags").click();
othis.find('input[name="sort"]').val(data.sort) othis.find('input[name="pid"]').val(data.pid)
,othis.find('input[name="sort"]').val(data.sort)
,othis.find('input[name="tags"]').val(data.tags) ,othis.find('input[name="tags"]').val(data.tags)
,othis.find('input[name="ename"]').val(data.ename) ,othis.find('input[name="ename"]').val(data.ename)
,othis.find('input[name="icon"]').val(data.icon) ,othis.find('input[name="icon"]').val(data.icon)
,othis.find('input[name="desc"]').val(data.desc); ,othis.find('input[name="desc"]').val(data.desc);
} }
}); });

View File

@ -195,12 +195,12 @@ pre{position: relative; margin: 10px 0; padding: 15px; line-height: 20px; border
.fly-nav-msg:hover{color:#fff;} .fly-nav-msg:hover{color:#fff;}
.fly-header .layui-nav{padding: 0; background: none;} .fly-header .layui-nav{padding: 0; background: none;}
.fly-header .fly-nav a{padding: 0 25px 0 60px;} .fly-header .fly-nav a{padding: 0 25px 0 40px;}
.fly-header .fly-nav-user li a{padding: 0 10px;} .fly-header .fly-nav-user li a{padding: 0 10px;}
.fly-header .fly-nav-user li .fly-nav-avatar{padding-right: 0;} .fly-header .fly-nav-user li .fly-nav-avatar{padding-right: 0;}
.fly-header .fly-nav-user a.iconfont{color: #A9B7B7;} .fly-header .fly-nav-user a.iconfont{color: #A9B7B7;}
.fly-header>.layui-nav-item a{color: rgba(255,255,255,0.5);} .fly-header>.layui-nav-item a{color: rgba(255,255,255,0.5);}
.fly-header .layui-this a{color: #fff;} .fly-header .layui-this>a{color: #00AF83;}
.fly-header .layui-nav .layui-this:after, .fly-header .layui-nav .layui-this:after,
.fly-header .layui-nav .layui-nav-bar, .fly-header .layui-nav .layui-nav-bar,
.fly-header .fly-nav-user .layui-nav-more{display: none !important;} .fly-header .fly-nav-user .layui-nav-more{display: none !important;}
@ -536,7 +536,7 @@ body .layui-edit-face .layui-layer-content{padding:0; background-color:#fff; co
/*标题颜色展示方式*/ /*标题颜色展示方式*/
.layui-colorpicker.layui-colorpicker-xs {width: 30px;height: 20px;line-height: 16px;border: 0px solid #e6e6e6;padding: 0;vertical-align: top;border-radius: 0;} .layui-colorpicker.layui-colorpicker-xs {width: 30px;height: 20px;line-height: 16px;border: 0px solid #e6e6e6;padding: 0;vertical-align: top;border-radius: 0;}
.layui-colorpicker-trigger-span {display: block;height: 100%;box-sizing: border-box;border: 1px solid rgba(2, 0, 0, 0.24);border-radius: 2px;text-align: center;} .layui-colorpicker-trigger-span {display: block;height: 100%;box-sizing: border-box;border: 1px solid rgba(2, 0, 0, 0.24);border-radius: 2px;text-align: center;}
.layui-icon-down:before {font-size: 12px;content: "高亮";} /* .layui-icon-down:before {font-size: 12px;content: "高亮";} */
/*扫码阅读*/ /*扫码阅读*/
.detail_qrcode{position: absolute;top: 7px;right: 7px;width: 30px;height: 30px;background: url("/static/res/images/detail_qrcode.png") no-repeat;background-size: 30px 30px;} .detail_qrcode{position: absolute;top: 7px;right: 7px;width: 30px;height: 30px;background: url("/static/res/images/detail_qrcode.png") no-repeat;background-size: 30px 30px;}

View File

@ -18,12 +18,7 @@
<div class="layui-col-md3"> <div class="layui-col-md3">
<label class="layui-form-label">{:lang('special column')}</label> <label class="layui-form-label">{:lang('special column')}</label>
<div class="layui-input-block"> <div class="layui-input-block">
<select lay-verify="required" name="cate_id" lay-filter="column"> <div id="CateId" class="xm-select-demo"></div>
<option></option>
{volist name="cateList" id="cate"}
<option value="{$cate.id}" {if($Request.param.cate == $cate.ename)} selected {/if}>{:cookie('think_lang') == 'en-us' ? $cate.ename : $cate.catename}</option>
{/volist}
</select>
</div> </div>
</div> </div>
<div class="layui-col-md8"> <div class="layui-col-md8">
@ -175,26 +170,63 @@
var othis = $(this), html = othis.html(); var othis = $(this), html = othis.html();
othis.attr(fly.content(html)); othis.attr(fly.content(html));
}) })
} }
//1.渲染标签 // 分类选择
var addTags = xmSelect.render({ $(function(){
el: '#tag', //这里模拟ajax
name: 'tagid', $.get("{:url('article/getCateTree')}",function(res){
layVerify: '', var cid = "{$cid}";
layVerType: 'msg', var data = res.data;
paging: true, // 渲染下拉树
pageSize: 5, xmSelect.render({
data: [] el: '#CateId',
name: 'cate_id',
height: '250px',
layVerify: 'required',
layVerType: 'tips',
data: data,
initValue: [cid],
model: {label: {type: 'text'}},
prop: {
name: 'catename',
value: 'id'
},
radio: true,
clickClose: true,
tree: {
show: true,
indent: 15,
strict: false,
expandedKeys: true
},
tips: '请选择'
});
});
}); });
//2.动态标签赋值
$.get("{:url('get_all_tag')}",function(res){ // tag标签
if(res.code == 0){ $(function(){
addTags.update({ //1.渲染标签
data: res.data, var addTags = xmSelect.render({
autoRow: true, el: '#tag',
}) name: 'tagid',
} layVerify: '',
layVerType: 'msg',
paging: true,
pageSize: 5,
data: []
});
//2.动态标签赋值
$.get("{:url('get_all_tag')}",function(res){
if(res.code == 0){
addTags.update({
data: res.data,
autoRow: true,
})
}
});
}); });
// 通过标题内容自动获取tag的内容 // 通过标题内容自动获取tag的内容

View File

@ -20,12 +20,7 @@
<div class="layui-col-md3"> <div class="layui-col-md3">
<label class="layui-form-label">{:lang('special column')}</label> <label class="layui-form-label">{:lang('special column')}</label>
<div class="layui-input-block"> <div class="layui-input-block">
<select lay-verify="required" name="cate_id" lay-filter="column"> <div id="CateId" class="xm-select-demo"></div>
<option></option>
{volist name="cateList" id="cate"}
<option value="{$cate.id}" {if $article.cate_id == $cate.id}selected{/if}>{:cookie('think_lang') == 'en-us' ? $cate.ename : $cate.catename}</option>
{/volist}
</select>
</div> </div>
</div> </div>
<div class="layui-col-md8"> <div class="layui-col-md8">
@ -148,35 +143,71 @@
{:hook('taonyeditor')} {:hook('taonyeditor')}
<script src="/static/xm-select.js"></script> <script src="/static/xm-select.js"></script>
<script> <script>
var artId = "{$article.id}"; var cateId = "{$article.cate.id}";
// 分类选择
//1.渲染标签 $(function(){
var addTags = xmSelect.render({ //这里模拟ajax
el: '#tag', $.get("{:url('article/getCateTree')}",function(res){
name: 'tagid', var data = res.data;
layVerify: '', // 渲染下拉树
layVerType: 'msg', xmSelect.render({
paging: true, el: '#CateId',
pageSize: 5, name: 'id',
data: [] height: '250px',
}); layVerify: 'required',
//2.动态赋值 layVerType: 'tips',
$.get("{:url('get_art_tag')}",{id:artId},function(res){ data: data,
if(res.code == 0){ initValue: [cateId],
addTags.setValue( model: {label: {type: 'text'}},
res.data prop: {
) name: 'catename',
} value: 'id'
}); },
//3.动态标签赋值 radio: true,
$.get("{:url('get_all_tag')}",function(res){ clickClose: true,
if(res.code == 0){ tree: {
addTags.update({ show: true,
data: res.data, indent: 15,
autoRow: true, strict: false,
expandedKeys: true
},
tips: '请选择'
});
});
});
// tag标签
$(function(){
//1.渲染标签
var addTags = xmSelect.render({
el: '#tag',
name: 'tagid',
layVerify: '',
layVerType: 'msg',
paging: true,
pageSize: 5,
data: []
});
//2.动态赋值
$.get("{:url('get_art_tag')}",{id:artId},function(res){
if(res.code == 0){
addTags.setValue(
res.data
)
}
});
//3.动态标签赋值
$.get("{:url('get_all_tag')}",function(res){
if(res.code == 0){
addTags.update({
data: res.data,
autoRow: true,
})
}
});
}) })
}
});
</script> </script>
<script> <script>
layui.use(['fly','plyr'], function(){ layui.use(['fly','plyr'], function(){

View File

@ -17,7 +17,7 @@
{block name="content"} {block name="content"}
<div class="layui-container"> <div class="layui-container">
<div class="layui-row layui-col-space15"> <div class="layui-row layui-col-space15">
<div class="layui-col-md9 content detail"> <div class="layui-col-md8 content detail">
<div class="fly-panel detail-box"> <div class="fly-panel detail-box">
{//标题} {//标题}
<h1 style="color:{$article.title_color ?? '#333'};">{$article.title}</h1> <h1 style="color:{$article.title_color ?? '#333'};">{$article.title}</h1>
@ -140,7 +140,7 @@
</div> </div>
</div> </div>
{//右栏} {//右栏}
<div class="layui-col-md3"> <div class="layui-col-md4">
<div class="fly-panel"> <div class="fly-panel">
<div class="fly-panel-main wenda-user"> <div class="fly-panel-main wenda-user">
<div class="user-img"> <div class="user-img">

View File

@ -72,6 +72,7 @@
}).extend({ }).extend({
fly: 'index' fly: 'index'
}).use('fly'); }).use('fly');
var element = layui.element;
</script> </script>
{block name="script"} {/block} {block name="script"} {/block}
</body> </body>

View File

@ -7,12 +7,29 @@
{//移动端LOGO} {//移动端LOGO}
<a class="fly-logo layui-hide-md layui-hide-sm" href="{$Request.domain}" style="padding-left:50%; margin-left:-60px;"><img src="{$Request.domain}{$sysInfo.m_logo}" style="height:37px;" alt="logo"></a> <a class="fly-logo layui-hide-md layui-hide-sm" href="{$Request.domain}" style="padding-left:50%; margin-left:-60px;"><img src="{$Request.domain}{$sysInfo.m_logo}" style="height:37px;" alt="logo"></a>
<ul class="layui-nav fly-nav layui-hide-xs"> <ul class="layui-nav fly-nav layui-hide-xs">
{//导航nav}
{volist name="cateList" id="cate"}
<li class="layui-nav-item {if($cate.ename eq $Request.param.ename)} layui-this {/if}" >
<a href="{$Request.domain}{:url('cate',['ename' => $cate.ename])}">{:cookie('think_lang') == 'en-us' ? $cate.ename : $cate.catename}{if condition="$cate.is_hot eq 1"}<span class="layui-badge-dot"></span>{/if}</a>
{notempty name="cate.children"}
<dl class="layui-nav-child"> <!-- 二级菜单 -->
{volist name="cate.children" id="vo2"}
<dd><a href="{$Request.domain}{:url('cate',['ename' => $vo2.ename])}">{$vo2.catename}</a></dd>
{/volist}
</dl>
{/notempty}
</li>
{/volist}
{// 后台自定义头部链接}
{volist name="headlinks" id="vo"} {volist name="headlinks" id="vo"}
<li class="layui-nav-item"> <li class="layui-nav-item">
<a href="{$vo.slid_href}"><i class="layui-icon {$vo.slid_img}"></i>{$vo.slid_name}</a> <a href="{$vo.slid_href}"><i class="layui-icon {$vo.slid_img}"></i>{$vo.slid_name}</a>
</li> </li>
{/volist} {/volist}
</ul> </ul>
{//头部右栏} {//头部右栏}
<ul class="layui-nav fly-nav-user" msg-url="{:url('message/nums')}" readMsg-url="{:url('Message/read')}" userlogin="{:url('user_login')}"> <ul class="layui-nav fly-nav-user" msg-url="{:url('message/nums')}" readMsg-url="{:url('Message/read')}" userlogin="{:url('user_login')}">
{if session('?user_id')} {if session('?user_id')}